From 6f56acafb25ed0e0b1518f636ccf7096ab3f8aa1 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Fri, 9 Sep 2011 00:05:15 +0200 Subject: [PATCH 0001/4858] First implementation of the CLI, focussed on plugin actions --- engine/command.php | 26 +++++++ engine/config.php | 18 +++++ library/commands/plugins.php | 143 +++++++++++++++++++++++++++++++++++ wp | 36 +++++++++ 4 files changed, 223 insertions(+) create mode 100644 engine/command.php create mode 100644 engine/config.php create mode 100644 library/commands/plugins.php create mode 100755 wp diff --git a/engine/command.php b/engine/command.php new file mode 100644 index 0000000000..22825a74c5 --- /dev/null +++ b/engine/command.php @@ -0,0 +1,26 @@ +$sub_command($args); + } + else { + $this->help($args); + } + } + + public function help() { + print_r(get_class_methods($this)); + } + + protected function parse_args() { + + } + + protected function _echo($string) { + echo $string."\n"; + } +} \ No newline at end of file diff --git a/engine/config.php b/engine/config.php new file mode 100644 index 0000000000..a940cd171f --- /dev/null +++ b/engine/config.php @@ -0,0 +1,18 @@ +parse_name($name); + + $details = $this->get_details($file); + + $this->_echo('Plugin '.$name.' details:'); + $this->_echo(' Active: '.((int) is_plugin_active($file))); + if(is_multisite()) { + $this->_echo(' Network: '.((int) is_plugin_active_for_network($file))); + } + $this->_echo(' Version: '.$details['Version']); + } + } + + function activate($args) { + if(!empty($args)) { + $name = $args[0]; + $file = $this->parse_name($name); + + if(is_plugin_active($file)) { + $this->_echo('The plugin is already active: '.$name); + } + elseif(activate_plugin($file) === null) { + $this->_echo('Plugin activated: '.$name); + } + } + } + + function deactivate($args) { + if(!empty($args)) { + $name = $args[0]; + $file = $this->parse_name($name); + + if(is_plugin_inactive($file)) { + $this->_echo('The plugin is already deactivate: '.$name); + } + elseif(deactivate_plugins($file) === null) { + $this->_echo('Plugin deactivated: '.$name); + } + } + } + + function install($args) { + if(!empty($args)) { + $name = $args[0]; + + $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); + $status = install_plugin_install_status($api); + echo 'Updating '.$name.": "; + ob_start('strip_tags'); + + switch($status['status']) { + case 'update_available': + case 'install': + $upgrader = new Plugin_Upgrader(); + $upgrader->install($api->download_link); + break; + case 'newer_installed': + $this->_echo(sprintf('Newer Version (%s) Installed', $status['version'])); + break; + case 'latest_installed': + $this->_echo('Latest Version Installed'); + $file = $this->parse_name($name); + + if(is_plugin_inactive($file)) { + $this->_echo('If you want to activate the plugin, run \'wp plugins activate '.$name.'\''); + } + break; + } + } + } + + function delete($args) { + if(!empty($args)) { + $name = $args[0]; + $file = $this->parse_name($name); + + $success = delete_plugins(array($file)); + } + } + + function update($args) { + if(!empty($args)) { + $name = $args[0]; + $file = $this->parse_name($name); + + wp_update_plugins(); + + echo 'Updating '.$name.": "; + ob_start('strip_tags'); + $success = wp_update_plugin($file); + } + else { + echo 'Usage: wp plugins update .'."\n"; + } + } + + private function get_details($file) { + $plugin_folder = get_plugins( '/' . plugin_basename(dirname($file))); + $plugin_file = basename(($file)); + + return $plugin_folder[$plugin_file]; + } +} \ No newline at end of file diff --git a/wp b/wp new file mode 100755 index 0000000000..a5f066cf4a --- /dev/null +++ b/wp @@ -0,0 +1,36 @@ +#!/usr/bin/env php + Date: Fri, 9 Sep 2011 23:08:16 +0200 Subject: [PATCH 0002/4858] * New command for core actions * Updated the plugin commands * Added a Wordpress Uprade skin: CLI_Upgrade_Skin to prevent the output buffer to be flushed --- engine/functions.php | 71 ++++++++++++++++++++++++++++++++++++ library/commands/core.php | 28 ++++++++++++++ library/commands/plugins.php | 30 ++++++++++----- wp | 8 ++-- 4 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 engine/functions.php create mode 100644 library/commands/core.php diff --git a/engine/functions.php b/engine/functions.php new file mode 100644 index 0000000000..e0744a4e02 --- /dev/null +++ b/engine/functions.php @@ -0,0 +1,71 @@ +get_error_code() ) { + foreach ( $errors->get_error_messages() as $message ) { + if ( $errors->get_error_data() ) + return $message . ' ' . $errors->get_error_data(); + else + return $message; + } + } +} + +class CLI_Upgrader_Skin { + var $upgrader; + var $done_header = false; + var $result = false; + + function __construct($args = array()) { + $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false ); + $this->options = wp_parse_args($args, $defaults); + } + + function set_upgrader(&$upgrader) { + if ( is_object($upgrader) ) + $this->upgrader =& $upgrader; + $this->add_strings(); + } + + function add_strings() {} + + function set_result($result) { + $this->result = $result; + } + + function request_filesystem_credentials($error = false) { + $url = $this->options['url']; + $context = $this->options['context']; + if ( !empty($this->options['nonce']) ) + $url = wp_nonce_url($url, $this->options['nonce']); + return request_filesystem_credentials($url, '', $error, $context); //Possible to bring inline, Leaving as is for now. + } + + function header() {} + function footer() {} + + function error($errors) { + $this->feedback(error_to_string($errors)); + } + + function feedback($string) { + if ( isset( $this->upgrader->strings[$string] ) ) + $string = $this->upgrader->strings[$string]; + + if ( strpos($string, '%') !== false ) { + $args = func_get_args(); + $args = array_splice($args, 1); + if ( !empty($args) ) + $string = vsprintf($string, $args); + } + if ( empty($string) ) + return; + + echo $string; + } + function before() {} + function after() {} +} \ No newline at end of file diff --git a/library/commands/core.php b/library/commands/core.php new file mode 100644 index 0000000000..7b49a74453 --- /dev/null +++ b/library/commands/core.php @@ -0,0 +1,28 @@ +upgrade($current); + $feedback = ob_get_clean(); + $this->_echo($feedback); + + // Borrowed verbatim from wp-admin/update-core.php + if(is_wp_error($result) ) { + $this->_echo(error_to_string($result)); + if('up_to_date' != $result->get_error_code()) { + $this->_echo('Installation Failed'); + } + } + else { + $this->_echo('WordPress upgraded successfully'); + } + } +} \ No newline at end of file diff --git a/library/commands/plugins.php b/library/commands/plugins.php index 987d25f40f..0bd2ed65cd 100644 --- a/library/commands/plugins.php +++ b/library/commands/plugins.php @@ -5,8 +5,6 @@ require_once(ABSPATH.'wp-admin/includes/plugin.php'); require_once(ABSPATH.'wp-admin/includes/plugin-install.php'); -require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); - /** * Returns current plugin version. @@ -86,13 +84,18 @@ function install($args) { $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); $status = install_plugin_install_status($api); echo 'Updating '.$name.": "; - ob_start('strip_tags'); - + switch($status['status']) { case 'update_available': case 'install': - $upgrader = new Plugin_Upgrader(); - $upgrader->install($api->download_link); + ob_start(); + if(!class_exists('Plugin_Upgrader')) { + require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); + } + $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); + $result = $upgrader->install($api->download_link); + $feedback = ob_get_clean(); + $this->_echo($feedback); break; case 'newer_installed': $this->_echo(sprintf('Newer Version (%s) Installed', $status['version'])); @@ -126,11 +129,20 @@ function update($args) { wp_update_plugins(); echo 'Updating '.$name.": "; - ob_start('strip_tags'); - $success = wp_update_plugin($file); + ob_start(); + + if(!class_exists('Plugin_Upgrader')) { + require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); + } + + $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); + $success = $upgrader->upgrade($file); + + $feedback = ob_get_clean(); + $this->_echo($feedback); } else { - echo 'Usage: wp plugins update .'."\n"; + $this->_echo('Usage: wp plugins update .'); } } diff --git a/wp b/wp index a5f066cf4a..4ebd1399a9 100755 --- a/wp +++ b/wp @@ -15,11 +15,13 @@ class WP_CLI { include 'engine/command.php'; include 'engine/config.php'; -include 'library/commands/plugins.php'; +include 'engine/functions.php'; -// Start output buffering to stop WordPress from spitting out its usual output. +foreach (glob('library/commands/*.php') as $filename) { + include $filename; +} -//print_r($GLOBALS['argv']); +// Start output buffering to stop WordPress from spitting out its usual output. // Remove the first entry $arguments = array_shift($GLOBALS['argv']); From d5719fe30803df956989a2de1162606a2cc9afb5 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Fri, 9 Sep 2011 23:17:04 +0200 Subject: [PATCH 0003/4858] - Implemented a script to find the right php cli - Moved some things around --- engine/command.php | 12 +++-- wp | 131 ++++++++++++++++++++++++++++++++------------- wp.php | 30 +++++++++++ 3 files changed, 131 insertions(+), 42 deletions(-) create mode 100755 wp.php diff --git a/engine/command.php b/engine/command.php index 22825a74c5..c33d1d9968 100644 --- a/engine/command.php +++ b/engine/command.php @@ -1,5 +1,13 @@ /dev/null), then the +# error message is suppressed, but tput cols becomes confused about the +# terminal and prints out the default value (80). +if [ -z $COLUMNS ] && [ -n "$TERM" ] && [ "$TERM" != dumb ] ; then + # Note to cygwin users: install the ncurses package to get tput command. + if COLUMNS=$(tput cols); then + export COLUMNS + fi +fi + +if [ ! -z "$WP_CLI_PHP" ] ; then + # Use the WP_CLI_PHP environment variable if it is available. + php="$WP_CLI_PHP" +else + # Default to using the php that we find on the PATH. + # Note that we need the full path to php here for Dreamhost, which behaves oddly. See http://drupal.org/node/662926 + php=`which php` + + # We check for a command line (cli) version of php, and if found use that. + which php-cli >/dev/null 2>&1 + if [ "$?" = 0 ] ; then + php=`which php-cli` + fi + + # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. + for amp_php in /Applications/MAMP/bin/php5/bin/php /Applications/MAMP/bin/php5.2/bin/php /Applications/MAMP/bin/php5.3/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + if [ -x $amp_php ]; then + php=$amp_php + fi + done +fi + +# Check to see if the user has provided a php.ini file or wp-cli.ini file in any conf dir +# Last found wins, so search in reverse priority order +for conf_dir in $(dirname "$SELF_PATH") /etc/wp-cli $HOME/.wp-cli ; do + if [ -f $conf_dir/php.ini ] ; then + wp_cli_php_ini=$conf_dir/php.ini + fi + if [ -f $conf_dir/wp-cli.ini ] ; then + wp_cli_php_override=$conf_dir/wp-cli.ini + fi +done + +# Add in the php file location and/or the php override variables as appropriate +if [ "x$wp_cli_php_ini" != "x" ] ; then + php="$php --php-ini $wp_cli_php_ini" +fi +if [ "x$wp_cli_php_override" != "x" ] ; then + wp_cli_override_vars=`grep '^[a-z_A-Z0-9]\+ *=' $wp_cli_php_override | sed -e 's|\([^ =]*\) *= *\(.*\)|\1="\2"|' -e 's| ||g' -e 's|^|-d |' | tr '\n\r' ' '` + php="$php $wp_cli_override_vars" +fi + +# Pass in the path to php so that wp-cli knows which one +# to use if it re-launches itself to run subcommands +exec $php "$SCRIPT_PATH" "$@" \ No newline at end of file diff --git a/wp.php b/wp.php new file mode 100755 index 0000000000..a5ec58840e --- /dev/null +++ b/wp.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php + Date: Sat, 10 Sep 2011 11:42:51 +0200 Subject: [PATCH 0004/4858] New general structure Changed the structure to look more like a native Wordpress folder. --- .../command.php => class-wp-cli-command.php | 10 +-- class-wp-cli.php | 9 +++ {library/commands => commands}/core.php | 4 +- {library/commands => commands}/plugins.php | 48 ++++++------- engine/functions.php | 71 ------------------- wp | 4 +- engine/config.php => wp-cli.php | 30 +++++++- wp.php | 30 -------- 8 files changed, 67 insertions(+), 139 deletions(-) rename engine/command.php => class-wp-cli-command.php (68%) create mode 100644 class-wp-cli.php rename {library/commands => commands}/core.php (88%) rename {library/commands => commands}/plugins.php (95%) delete mode 100644 engine/functions.php rename engine/config.php => wp-cli.php (50%) mode change 100644 => 100755 delete mode 100755 wp.php diff --git a/engine/command.php b/class-wp-cli-command.php similarity index 68% rename from engine/command.php rename to class-wp-cli-command.php index c33d1d9968..a4e3660f76 100644 --- a/engine/command.php +++ b/class-wp-cli-command.php @@ -1,14 +1,6 @@ parse_name($name); + $file = $this->parse_name($name); $details = $this->get_details($file); $this->_echo('Plugin '.$name.' details:'); @@ -152,4 +132,24 @@ private function get_details($file) { return $plugin_folder[$plugin_file]; } + + private function parse_name($name) { + $plugins = get_plugins('/'.$name); + + if(!empty($plugins)) { + $keys = array_keys($plugins); + $file = $name.'/'.$keys[0]; + } + else { + $plugins = get_plugins(); + if(isset($plugins[$name.'.php'])) { + $file = $name.'.php'; + } + else { + die('This plugin does not exists: '.$name."\n"); + } + } + + return $file; + } } \ No newline at end of file diff --git a/engine/functions.php b/engine/functions.php deleted file mode 100644 index e0744a4e02..0000000000 --- a/engine/functions.php +++ /dev/null @@ -1,71 +0,0 @@ -get_error_code() ) { - foreach ( $errors->get_error_messages() as $message ) { - if ( $errors->get_error_data() ) - return $message . ' ' . $errors->get_error_data(); - else - return $message; - } - } -} - -class CLI_Upgrader_Skin { - var $upgrader; - var $done_header = false; - var $result = false; - - function __construct($args = array()) { - $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false ); - $this->options = wp_parse_args($args, $defaults); - } - - function set_upgrader(&$upgrader) { - if ( is_object($upgrader) ) - $this->upgrader =& $upgrader; - $this->add_strings(); - } - - function add_strings() {} - - function set_result($result) { - $this->result = $result; - } - - function request_filesystem_credentials($error = false) { - $url = $this->options['url']; - $context = $this->options['context']; - if ( !empty($this->options['nonce']) ) - $url = wp_nonce_url($url, $this->options['nonce']); - return request_filesystem_credentials($url, '', $error, $context); //Possible to bring inline, Leaving as is for now. - } - - function header() {} - function footer() {} - - function error($errors) { - $this->feedback(error_to_string($errors)); - } - - function feedback($string) { - if ( isset( $this->upgrader->strings[$string] ) ) - $string = $this->upgrader->strings[$string]; - - if ( strpos($string, '%') !== false ) { - $args = func_get_args(); - $args = array_splice($args, 1); - if ( !empty($args) ) - $string = vsprintf($string, $args); - } - if ( empty($string) ) - return; - - echo $string; - } - function before() {} - function after() {} -} \ No newline at end of file diff --git a/wp b/wp index b8f52543f7..5a949ca978 100755 --- a/wp +++ b/wp @@ -6,7 +6,7 @@ # And 0.09% to the author of this project: # https://github.com/88mph/wpadmin/blob/master/wpadmin.php # -# This is a wrapper script that will run wp.php with the most appropriate +# This is a wrapper script that will run wp-cli.php with the most appropriate # php executable it can find on your system. # @@ -27,7 +27,7 @@ done cd "$ORIGDIR" # Build the path to wp-cli.php. -SCRIPT_PATH=$(dirname "$SELF_PATH")/wp.php +SCRIPT_PATH=$(dirname "$SELF_PATH")/wp-cli.php case $(uname -a) in CYGWIN*) SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; diff --git a/engine/config.php b/wp-cli.php old mode 100644 new mode 100755 similarity index 50% rename from engine/config.php rename to wp-cli.php index a940cd171f..40df98f260 --- a/engine/config.php +++ b/wp-cli.php @@ -1,7 +1,15 @@ +#!/usr/bin/env php Date: Sat, 10 Sep 2011 14:51:26 +0200 Subject: [PATCH 0005/4858] Documentation and command line tools - Documented all functions and classes - Added php-cli-tools to interact with the cli --- .gitignore | 1 + .gitmodules | 3 + class-wp-cli-command.php | 77 +++++++- class-wp-cli.php | 183 ++++++++++++++++++- commands/{ => internals}/core.php | 27 ++- commands/internals/home.php | 47 +++++ commands/internals/plugins.php | 288 ++++++++++++++++++++++++++++++ commands/plugins.php | 155 ---------------- php-cli-tools | 1 + wp-cli.php | 55 ++++-- 10 files changed, 656 insertions(+), 181 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules rename commands/{ => internals}/core.php (50%) create mode 100644 commands/internals/home.php create mode 100644 commands/internals/plugins.php delete mode 100644 commands/plugins.php create mode 160000 php-cli-tools diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..e43b0f9889 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..a2f6eaebb7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "php-cli-tools"] + path = php-cli-tools + url = git://github.com/jlogsdon/php-cli-tools.git diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index a4e3660f76..73eea5fd43 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -1,22 +1,87 @@ $sub_command($args); } + // Otherwise, show the help for this command else { $this->help($args); } } - public function help() { - print_r(get_class_methods($this)); + /** + * General help function for this command + * + * @param Array $args + * @return void + * @author Andreas Creten + */ + public function help($args = array()) { + // Get the cli arguments + $arguments = $GLOBALS['argv']; + + // Remove the first entry + array_shift($arguments); + + // Get the command + $used_command = array_shift($arguments); + + // Show the list of sub-commands for this command + WP_CLI::line('Example usage:'); + WP_CLI::out(' wp '.$used_command); + $methods = WP_CLI_Command::getMethods($this); + if(!empty($methods)) { + WP_CLI::out(' ['.implode('|', $methods).']'); + } + WP_CLI::line(' ...'); + WP_CLI::line(); + + // Send a warning to the user because there is no custom help function defined in the command + // Make usure there always is a help method in your command class + WP_CLI::warning('The command has no dedicated help function, ask the creator to fix it.'); } - protected function _echo($string) { - echo $string."\n"; + /** + * Get the filtered list of methods for a class + * + * @param string $class + * @return Array The list of methods + * @author Andreas Creten + */ + static function getMethods($class) { + // Methods that don't need to be included in the method list + $blacklist = array('__construct', 'getMethods'); + + // Get all the methods of the class + $methods = get_class_methods($class); + + // Remove the blacklisted methods + foreach($blacklist as $method) { + $in_array = array_search($method, $methods); + if($in_array !== false) { + unset($methods[$in_array]); + } + } + + // Only return the values, to fill up the gaps + return array_values($methods); } } \ No newline at end of file diff --git a/class-wp-cli.php b/class-wp-cli.php index 02aa50124f..7f9c08d63b 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -1,9 +1,190 @@ get_error_code()){ + foreach($errors->get_error_messages() as $message){ + if($errors->get_error_data() ) + return $message . ' ' . $errors->get_error_data(); + else + return $message; + } + } + } + + /** + * Display the help function for the wp-cli + * + * @return void + * @author Andreas Creten + */ + static function generalHelp() { + self::line('Example usage:'); + foreach(self::$commands as $name => $command) { + self::out(' wp '.$name); + $methods = WP_CLI_Command::getMethods($command); + if(!empty($methods)) { + self::out(' ['.implode('|', $methods).']'); + } + self::line(' ...'); + } + } +} + +/** + * A Upgrader Skin for Wordpress that only generates plain-text + * + * @package wp-cli + * @author Andreas Creten + */ +class CLI_Upgrader_Skin { + var $upgrader; + var $done_header = false; + var $result = false; + + function __construct($args = array()) { + $defaults = array('url' => '', 'nonce' => '', 'title' => '', 'context' => false); + $this->options = wp_parse_args($args, $defaults); + } + + function set_upgrader(&$upgrader) { + if(is_object($upgrader)) { + $this->upgrader =& $upgrader; + } + + $this->add_strings(); + } + + function add_strings() {} + + function set_result($result) { + $this->result = $result; + } + + function request_filesystem_credentials($error = false) { + $url = $this->options['url']; + $context = $this->options['context']; + if(!empty($this->options['nonce'])) { + $url = wp_nonce_url($url, $this->options['nonce']); + } + + return request_filesystem_credentials($url, '', $error, $context); //Possible to bring inline, Leaving as is for now. + } + + function header() {} + function footer() {} + + function error($errors) { + $this->feedback(WP_CLI::errorToString($errors)); + } + + function feedback($string) { + if(isset( $this->upgrader->strings[$string])) + $string = $this->upgrader->strings[$string]; + + if(strpos($string, '%') !== false) { + $args = func_get_args(); + $args = array_splice($args, 1); + if(!empty($args)) { + $string = vsprintf($string, $args); + } + + } + if(empty($string)) { + return; + } + + echo $string; + } + + function before() {} + function after() {} } \ No newline at end of file diff --git a/commands/core.php b/commands/internals/core.php similarity index 50% rename from commands/core.php rename to commands/internals/core.php index d485daf231..17e83a0c50 100644 --- a/commands/core.php +++ b/commands/internals/core.php @@ -1,10 +1,26 @@ upgrade($current); $feedback = ob_get_clean(); - $this->_echo($feedback); // Borrowed verbatim from wp-admin/update-core.php if(is_wp_error($result) ) { - $this->_echo(error_to_string($result)); if('up_to_date' != $result->get_error_code()) { - $this->_echo('Installation Failed'); + WP_CLI::error('Installation failed ('.WP_CLI::errorToString($result).').'); + } + else { + WP_CLI::success(WP_CLI::errorToString($result)); } } else { - $this->_echo('WordPress upgraded successfully'); + WP_CLI::success('WordPress upgraded successfully.'); } } } \ No newline at end of file diff --git a/commands/internals/home.php b/commands/internals/home.php new file mode 100644 index 0000000000..203a8d9992 --- /dev/null +++ b/commands/internals/home.php @@ -0,0 +1,47 @@ +check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name); + + // Get the plugin details + $details = $this->get_details($file); + + // Display the plugin details + WP_CLI::line('Plugin %2'.$name.'%n details:'); + WP_CLI::line(' Active: '.((int) is_plugin_active($file))); + if(is_multisite()) { + WP_CLI::line(' Network: '.((int) is_plugin_active_for_network($file))); + } + WP_CLI::line(' Version: '.$details['Version']); + } + + /** + * Activate a plugin + * + * @param string $args + * @return void + * @author Andreas Creten + */ + function activate($args) { + // Get the plugin name from the arguments + $name = $this->check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name); + + // Check if the plugin is already active + if(is_plugin_active($file)) { + WP_CLI::error('The plugin is already active: '.$name); + } + // Try to activate the plugin + elseif(activate_plugin($file) === null) { + WP_CLI::success('Plugin activated: '.$name); + } + else { + WP_CLI::error('The plugin could not be activated: '.$name); + } + } + + /** + * Deactivate a plugin + * + * @param string $args + * @return void + * @author Andreas Creten + */ + function deactivate($args) { + // Get the plugin name from the arguments + $name = $this->check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name); + + // Check if the plugin is already deactivated + if(is_plugin_inactive($file)) { + WP_CLI::error('The plugin is already deactivated: '.$name); + } + // Try to deactivate the plugin + elseif(deactivate_plugins($file) === null) { + WP_CLI::success('Plugin deactivated: '.$name); + } + else { + WP_CLI::error('Could not deactivate this plugin: '.$name); + } + } + + /** + * Install a new plugin + * + * @param string $args + * @return void + * @author Andreas Creten + */ + function install($args) { + // Get the plugin name from the arguments + $name = $this->check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name, false); + + // Force Wordpress to update the plugin list + wp_update_plugins(); + + // Get plugin info from the Wordpress servers + $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); + $status = install_plugin_install_status($api); + + WP_CLI::line('Installing '.$api->name.' ('.$api->version.')'); + + // Check what to do + switch($status['status']) { + case 'update_available': + case 'install': + if(!class_exists('Plugin_Upgrader')) { + require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); + } + + // Install the plugin + ob_start('strip_tags'); + $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); + $result = $upgrader->install($api->download_link); + $feedback = ob_get_clean(); + + if($result !== null) { + WP_CLI::error($result); + } + else { + WP_CLI::line(); + WP_CLI::line(str_replace(array('…', 'Plugin installed successfully.'), array(" ...\n", ''), html_entity_decode($feedback))); + WP_CLI::success('The plugin is successfully installed'); + } + break; + case 'newer_installed': + WP_CLI::error(sprintf('Newer version (%s) installed', $status['version'])); + break; + case 'latest_installed': + WP_CLI::error('Latest version already installed'); + + if(is_plugin_inactive($file)) { + WP_CLI::warning('If you want to activate the plugin, run: %2wp plugins activate '.$name.'%n'); + } + break; + } + } + + /** + * Delete a plugin + * + * @param string $args + * @return void + * @author Andreas Creten + */ + function delete($args) { + // Get the plugin name from the arguments + $name = $this->check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name); + + if(delete_plugins(array($file))) { + WP_CLI::success('The plugin is successfully deleted.'); + } + else { + WP_CLI::error('There was an error while deleting the plugin.'); + } + } + + /** + * Update a plugin + * + * @param string $args + * @return void + * @author Andreas Creten + */ + function update($args) { + // Get the plugin name from the arguments + $name = $this->check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name); + + // Force Wordpress to update the plugin list + wp_update_plugins(); + + if(!class_exists('Plugin_Upgrader')) { + require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); + } + + WP_CLI::line('Updating '.$name); + + // Upgrading the plugin + ob_start('strip_tags'); + $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); + $result = $upgrader->upgrade($file); + $feedback = ob_get_clean(); + + if($result !== null) { + WP_CLI::error($feedback); + } + else { + WP_CLI::line(); + WP_CLI::line(html_entity_decode($feedback)); + WP_CLI::success('The plugin is successfully updated.'); + } + } + + /* PRIVATES */ + + /** + * Get the details of a plugin + * + * @param string $file + * @return array + * @author Andreas Creten + */ + private function get_details($file) { + $plugin_folder = get_plugins( '/' . plugin_basename(dirname($file))); + $plugin_file = basename(($file)); + + return $plugin_folder[$plugin_file]; + } + + /** + * Parse the name of a plugin to a filename, check if it exists + * + * @param string $name + * @param string $exit + * @return mixed + * @author Andreas Creten + */ + private function parse_name($name, $exit = true) { + $plugins = get_plugins('/'.$name); + + if(!empty($plugins)) { + $keys = array_keys($plugins); + $file = $name.'/'.$keys[0]; + } + else { + $plugins = get_plugins(); + if(isset($plugins[$name.'.php'])) { + $file = $name.'.php'; + } + else { + if($exit) { + WP_CLI::error('The plugin \''.$name.'\' could not be found.'); + exit(); + } + + return false; + } + } + + return $file; + } + + /** + * Check if there is a name set in the arguments, if not show the help function + * + * @param string $args + * @param string $exit + * @return void + * @author Andreas Creten + */ + private function check_name($args, $exit = true) { + if(empty($args)) { + WP_CLI::error('Please specify a plugin.'); + WP_CLI::line(); + $this->help(); + + if($exit) { + exit(); + } + } + + return $args[0]; + } +} \ No newline at end of file diff --git a/commands/plugins.php b/commands/plugins.php deleted file mode 100644 index 25e91dcf25..0000000000 --- a/commands/plugins.php +++ /dev/null @@ -1,155 +0,0 @@ -parse_name($name); - $details = $this->get_details($file); - - $this->_echo('Plugin '.$name.' details:'); - $this->_echo(' Active: '.((int) is_plugin_active($file))); - if(is_multisite()) { - $this->_echo(' Network: '.((int) is_plugin_active_for_network($file))); - } - $this->_echo(' Version: '.$details['Version']); - } - } - - function activate($args) { - if(!empty($args)) { - $name = $args[0]; - $file = $this->parse_name($name); - - if(is_plugin_active($file)) { - $this->_echo('The plugin is already active: '.$name); - } - elseif(activate_plugin($file) === null) { - $this->_echo('Plugin activated: '.$name); - } - } - } - - function deactivate($args) { - if(!empty($args)) { - $name = $args[0]; - $file = $this->parse_name($name); - - if(is_plugin_inactive($file)) { - $this->_echo('The plugin is already deactivate: '.$name); - } - elseif(deactivate_plugins($file) === null) { - $this->_echo('Plugin deactivated: '.$name); - } - } - } - - function install($args) { - if(!empty($args)) { - $name = $args[0]; - - $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); - $status = install_plugin_install_status($api); - echo 'Updating '.$name.": "; - - switch($status['status']) { - case 'update_available': - case 'install': - ob_start(); - if(!class_exists('Plugin_Upgrader')) { - require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); - } - $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); - $result = $upgrader->install($api->download_link); - $feedback = ob_get_clean(); - $this->_echo($feedback); - break; - case 'newer_installed': - $this->_echo(sprintf('Newer Version (%s) Installed', $status['version'])); - break; - case 'latest_installed': - $this->_echo('Latest Version Installed'); - $file = $this->parse_name($name); - - if(is_plugin_inactive($file)) { - $this->_echo('If you want to activate the plugin, run \'wp plugins activate '.$name.'\''); - } - break; - } - } - } - - function delete($args) { - if(!empty($args)) { - $name = $args[0]; - $file = $this->parse_name($name); - - $success = delete_plugins(array($file)); - } - } - - function update($args) { - if(!empty($args)) { - $name = $args[0]; - $file = $this->parse_name($name); - - wp_update_plugins(); - - echo 'Updating '.$name.": "; - ob_start(); - - if(!class_exists('Plugin_Upgrader')) { - require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); - } - - $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); - $success = $upgrader->upgrade($file); - - $feedback = ob_get_clean(); - $this->_echo($feedback); - } - else { - $this->_echo('Usage: wp plugins update .'); - } - } - - private function get_details($file) { - $plugin_folder = get_plugins( '/' . plugin_basename(dirname($file))); - $plugin_file = basename(($file)); - - return $plugin_folder[$plugin_file]; - } - - private function parse_name($name) { - $plugins = get_plugins('/'.$name); - - if(!empty($plugins)) { - $keys = array_keys($plugins); - $file = $name.'/'.$keys[0]; - } - else { - $plugins = get_plugins(); - if(isset($plugins[$name.'.php'])) { - $file = $name.'.php'; - } - else { - die('This plugin does not exists: '.$name."\n"); - } - } - - return $file; - } -} \ No newline at end of file diff --git a/php-cli-tools b/php-cli-tools new file mode 160000 index 0000000000..1fd565ce6c --- /dev/null +++ b/php-cli-tools @@ -0,0 +1 @@ +Subproject commit 1fd565ce6c989c1e1faf8571e2af6da7d88b8b32 diff --git a/wp-cli.php b/wp-cli.php index 40df98f260..014749e0ad 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -5,16 +5,22 @@ die('Only cli access'); } +// Define the Wordpress location define('WP_ROOT', '../wordpress/'); +// Set a constant that can be used to check if we are running wp-cli or not +define('WP_CLI', true); + +// Include the wp-cli classes include 'class-wp-cli.php'; include 'class-wp-cli-command.php'; -// Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php - -// Does the user have access to read the directory? If so, allow them to use the -// command line tool. +// Include the command line tools, taken from here: https://github.com/jlogsdon/php-cli-tools +include 'php-cli-tools/lib/cli/cli.php'; +\cli\register_autoload(); +// Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php +// Does the user have access to read the directory? If so, allow them to use the command line tool. if(true == is_readable(WP_ROOT . 'wp-load.php')){ // Load WordPress libs. require_once(WP_ROOT . 'wp-load.php'); @@ -22,25 +28,46 @@ require_once(ABSPATH . 'wp-admin/includes/admin.php'); } else { - die("Either this is not a WordPress document root or you do not have permission to administer this site. \n"); + WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); + exit(); +} + +// Load all internal commands +foreach (glob('commands/internals/*.php') as $filename) { + include $filename; +} + +// Load all plugin commands +foreach (glob('commands/plugins/*.php') as $filename) { + include $filename; } -foreach (glob('library/commands/*.php') as $filename) { +// Load all theme commands +foreach (glob('commands/themes/*.php') as $filename) { include $filename; } -// Start output buffering to stop WordPress from spitting out its usual output. +// Get the cli arguments +$arguments = $GLOBALS['argv']; // Remove the first entry -$arguments = array_shift($GLOBALS['argv']); +array_shift($arguments); // Get the command -$command = array_shift($GLOBALS['argv']); +$command = array_shift($arguments); -// -if(isset(WP_CLI::$commands[$command])) { - new WP_CLI::$commands[$command]($GLOBALS['argv']); +// Check if there are commands installed +if(empty(WP_CLI::$commands)) { + WP_CLI::error('No commands installed'); + WP_CLI::line(); + WP_CLI::line('Visit the wp-cli page on github on more information on how to install commands.'); + exit(); } -else { - echo 'Unknown command'."\n"; +// Try to load the class, otherwise it's an Unknown command +elseif(isset(WP_CLI::$commands[$command])) { + new WP_CLI::$commands[$command]($arguments); } +// Show the general help for wp-cli +else { + WP_CLI::generalHelp(); +} \ No newline at end of file From 5c08e34e2adef786d85db8ea827420a33d2b2ce9 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Sat, 10 Sep 2011 15:04:57 +0200 Subject: [PATCH 0006/4858] Readme & config --- README.md | 38 ++++++++++++++++++++++++++++++++++ commands/internals/plugins.php | 4 ++-- wp-cli.php | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..99ab42b265 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +WP-CLI: Wordpress Command Line Tools +============================ + +What is wp-cli +-------------- + +A command line tool to do maintenance work on a Wordpress install from the command line. + +Installing +---------- + +Installing wp-cli is extremely simple: place the wp-cli folder in your Wordpress root, (on the same level as wp-admin and wp-content). +That's it! + +Usage +----- + +In your terminal, go into the wp-cli folder. + +Type the following command: +`./wp help` + +This will show you an output similar to this: +`Example usage: + wp google-sitemap [build|help] ... + wp core [update|help] ... + wp home [help] ... + wp plugins [status|activate|deactivate|install|delete|update|help] ...` + +Adding commands +--------------- + +Adding commands to wp-cli is very easy. You can even add them from within your own plugin. + +Requirements +------------ + + * PHP >= 5.3 \ No newline at end of file diff --git a/commands/internals/plugins.php b/commands/internals/plugins.php index 8ed09e6bee..4a8a2e5607 100644 --- a/commands/internals/plugins.php +++ b/commands/internals/plugins.php @@ -137,7 +137,7 @@ function install($args) { } else { WP_CLI::line(); - WP_CLI::line(str_replace(array('…', 'Plugin installed successfully.'), array(" ...\n", ''), html_entity_decode($feedback))); + WP_CLI::line(strip_tags(str_replace(array('…', 'Plugin installed successfully.'), array(" ...\n", ''), html_entity_decode($feedback)))); WP_CLI::success('The plugin is successfully installed'); } break; @@ -210,7 +210,7 @@ function update($args) { } else { WP_CLI::line(); - WP_CLI::line(html_entity_decode($feedback)); + WP_CLI::line(html_entity_decode(strip_tags($feedback))); WP_CLI::success('The plugin is successfully updated.'); } } diff --git a/wp-cli.php b/wp-cli.php index 014749e0ad..5bd1bdf541 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -6,7 +6,7 @@ } // Define the Wordpress location -define('WP_ROOT', '../wordpress/'); +define('WP_ROOT', '../'); // Set a constant that can be used to check if we are running wp-cli or not define('WP_CLI', true); From b388fde1ef01d0661c4f15bdd6b2c56debabcab6 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Sat, 10 Sep 2011 15:20:26 +0200 Subject: [PATCH 0007/4858] License and read me update --- LICENSE | 19 +++++++++++++++++++ README.md | 26 +++++++++++++++++++++----- commands/internals/home.php | 3 +-- commands/internals/plugins.php | 31 +++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..8a2f6b51ef --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Andreas Creten + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 99ab42b265..93c773951b 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,31 @@ Usage In your terminal, go into the wp-cli folder. -Type the following command: -`./wp help` +Typing the following command: `./wp help`, will show you an output similar to this: -This will show you an output similar to this: -`Example usage: +``` +Example usage: wp google-sitemap [build|help] ... wp core [update|help] ... wp home [help] ... - wp plugins [status|activate|deactivate|install|delete|update|help] ...` + wp plugins [status|activate|deactivate|install|delete|update|help] ... +``` + +So this tells us that there are 4 commands installed: google-sitemap, core, home and pluggins. +Between brackets you can see their sub command. + +Let's for example try to update the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly` + +Output: +``` +Installing Hello Dolly (1.5) + +Downloading install package from http://downloads.wordpress.org/plugin/hello-dolly.1.5.zip ... +Unpacking the package ... +Installing the plugin ... + +Success: The plugin is successfully installed +``` Adding commands --------------- diff --git a/commands/internals/home.php b/commands/internals/home.php index 203a8d9992..f5b8ff28ac 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -36,8 +36,7 @@ function __construct($args) { * @param string $args * @return void * @author Andreas Creten - **/ - + */ public function help($args = array()) { WP_CLI::line('This command has no arguments, when called it will open the wp-cli homepage in your browser.'); WP_CLI::line(); diff --git a/commands/internals/plugins.php b/commands/internals/plugins.php index 4a8a2e5607..df34ddbd89 100644 --- a/commands/internals/plugins.php +++ b/commands/internals/plugins.php @@ -285,4 +285,35 @@ private function check_name($args, $exit = true) { return $args[0]; } + + /** + * Help function for this command + * + * @param string $args + * @return void + * @author Andreas Creten + */ + public function help($args = array()) { + // Get the cli arguments + $arguments = $GLOBALS['argv']; + + // Remove the first entry + array_shift($arguments); + + // Get the command + $used_command = array_shift($arguments); + + // Show the list of sub-commands for this command + WP_CLI::line('Example usage:'); + + $methods = WP_CLI_Command::getMethods($this); + foreach ($methods as $method) { + if($method != 'help') { + WP_CLI::line(' wp '.$used_command.' '.$method.' '); + } + else { + WP_CLI::line(' wp '.$used_command.' '.$method); + } + } + } } \ No newline at end of file From d17ab796f2086e3df856ed7a8b0e3d824c7bddaa Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Sat, 10 Sep 2011 15:23:00 +0200 Subject: [PATCH 0008/4858] Readme update --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 93c773951b..de8593f7ce 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,10 @@ A command line tool to do maintenance work on a Wordpress install from the comma Installing ---------- -Installing wp-cli is extremely simple: place the wp-cli folder in your Wordpress root, (on the same level as wp-admin and wp-content). -That's it! +Installing wp-cli is extremely simple: + +1. Place the `wp-cli` folder in your Wordpress root (on the same level as `wp-admin` and `wp-content`). +1. That's it! Usage ----- @@ -33,6 +35,7 @@ Between brackets you can see their sub command. Let's for example try to update the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly` Output: + ``` Installing Hello Dolly (1.5) From f59b5c726cbce3f8804086ebf95835b88894646b Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Sat, 10 Sep 2011 15:23:59 +0200 Subject: [PATCH 0009/4858] Readme update --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index de8593f7ce..5e02d4c557 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ Example usage: wp plugins [status|activate|deactivate|install|delete|update|help] ... ``` -So this tells us that there are 4 commands installed: google-sitemap, core, home and pluggins. -Between brackets you can see their sub command. +So this tells us that there are 4 commands installed: google-sitemap, core, home and plugins. +Between brackets you can see their sub commands. -Let's for example try to update the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly` +Let's for example try to update the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. Output: ``` From 8fe9f26a4df9ef08b98605a4431310669e9d49c7 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Sat, 10 Sep 2011 15:43:59 +0200 Subject: [PATCH 0010/4858] Edited gitignore, struggling with submodules --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e43b0f9889..c1468184d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +php-cli-tools/ \ No newline at end of file From 661de01fcea4bac15b295628d4161e40d80ef0d5 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 09:53:03 +0200 Subject: [PATCH 0011/4858] Example and README update --- README.md | 46 +++++++++- class-wp-cli-command.php | 152 ++++++++++++++++----------------- class-wp-cli.php | 123 +++++++++++++------------- commands/community/example.php | 76 +++++++++++++++++ 4 files changed, 258 insertions(+), 139 deletions(-) create mode 100644 commands/community/example.php diff --git a/README.md b/README.md index 5e02d4c557..f82212d55f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ Installing ---------- Installing wp-cli is extremely simple: - + +1. Download the latest version or clone wp-cli from Github and init and update the submodules 1. Place the `wp-cli` folder in your Wordpress root (on the same level as `wp-admin` and `wp-content`). 1. That's it! @@ -32,7 +33,6 @@ Example usage: So this tells us that there are 4 commands installed: google-sitemap, core, home and plugins. Between brackets you can see their sub commands. - Let's for example try to update the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. Output: @@ -51,6 +51,48 @@ Adding commands Adding commands to wp-cli is very easy. You can even add them from within your own plugin. +Each command has its own class, the methods of that class are the sub commands of the command. The base class for the commands is the abstract `WP_CLI_Command`, it handles some essential functionality (like default help for your command). + +You can add new commands to the `commands/community` in the wp-cli plugin, they will be auto-loaded on startup. You can also add commands from within your plugins by just calling the wp-cli hooks from there. + +A wp-cli class is structured like this: + +``` php +$sub_command($args); - } - // Otherwise, show the help for this command - else { - $this->help($args); - } - } - - /** - * General help function for this command - * - * @param Array $args - * @return void - * @author Andreas Creten - */ - public function help($args = array()) { - // Get the cli arguments - $arguments = $GLOBALS['argv']; - - // Remove the first entry - array_shift($arguments); + /** + * Construct for this class, transfers the cli arguments to the right class + * + * @param Array $args + * @author Andreas Creten + */ + function __construct($args = array()) { + // The first command is the sub command + $sub_command = array_shift($args); + + // If the method exists, try to load it + if(method_exists($this, $sub_command)) { + $this->$sub_command($args); + } + // Otherwise, show the help for this command + else { + $this->help($args); + } + } + + /** + * General help function for this command + * + * @param Array $args + * @return void + * @author Andreas Creten + */ + public function help($args = array()) { + // Get the cli arguments + $arguments = $GLOBALS['argv']; + + // Remove the first entry + array_shift($arguments); - // Get the command - $used_command = array_shift($arguments); - - // Show the list of sub-commands for this command - WP_CLI::line('Example usage:'); - WP_CLI::out(' wp '.$used_command); - $methods = WP_CLI_Command::getMethods($this); - if(!empty($methods)) { - WP_CLI::out(' ['.implode('|', $methods).']'); - } - WP_CLI::line(' ...'); - WP_CLI::line(); - - // Send a warning to the user because there is no custom help function defined in the command - // Make usure there always is a help method in your command class - WP_CLI::warning('The command has no dedicated help function, ask the creator to fix it.'); - } - - /** - * Get the filtered list of methods for a class - * - * @param string $class - * @return Array The list of methods - * @author Andreas Creten - */ - static function getMethods($class) { - // Methods that don't need to be included in the method list - $blacklist = array('__construct', 'getMethods'); - - // Get all the methods of the class - $methods = get_class_methods($class); - - // Remove the blacklisted methods - foreach($blacklist as $method) { - $in_array = array_search($method, $methods); - if($in_array !== false) { - unset($methods[$in_array]); - } - } - - // Only return the values, to fill up the gaps - return array_values($methods); - } + // Get the command + $used_command = array_shift($arguments); + + // Show the list of sub-commands for this command + WP_CLI::line('Example usage:'); + WP_CLI::out(' wp '.$used_command); + $methods = WP_CLI_Command::getMethods($this); + if(!empty($methods)) { + WP_CLI::out(' ['.implode('|', $methods).']'); + } + WP_CLI::line(' ...'); + WP_CLI::line(); + + // Send a warning to the user because there is no custom help function defined in the command + // Make usure there always is a help method in your command class + WP_CLI::warning('The command has no dedicated help function, ask the creator to fix it.'); + } + + /** + * Get the filtered list of methods for a class + * + * @param string $class + * @return Array The list of methods + * @author Andreas Creten + */ + static function getMethods($class) { + // Methods that don't need to be included in the method list + $blacklist = array('__construct', 'getMethods'); + + // Get all the methods of the class + $methods = get_class_methods($class); + + // Remove the blacklisted methods + foreach($blacklist as $method) { + $in_array = array_search($method, $methods); + if($in_array !== false) { + unset($methods[$in_array]); + } + } + + // Only return the values, to fill up the gaps + return array_values($methods); + } } \ No newline at end of file diff --git a/class-wp-cli.php b/class-wp-cli.php index 7f9c08d63b..32ab17950d 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -87,17 +87,17 @@ static function warning($message, $label = 'Warning') { * @author Andreas Creten */ static function errorToString($errors) { - if(is_string($errors)){ - return $errors; - } - elseif(is_wp_error($errors) && $errors->get_error_code()){ - foreach($errors->get_error_messages() as $message){ - if($errors->get_error_data() ) - return $message . ' ' . $errors->get_error_data(); - else - return $message; - } - } + if(is_string($errors)){ + return $errors; + } + elseif(is_wp_error($errors) && $errors->get_error_code()){ + foreach($errors->get_error_messages() as $message){ + if($errors->get_error_data() ) + return $message . ' ' . $errors->get_error_data(); + else + return $message; + } + } } /** @@ -109,7 +109,7 @@ static function errorToString($errors) { static function generalHelp() { self::line('Example usage:'); foreach(self::$commands as $name => $command) { - self::out(' wp '.$name); + self::out(' wp '.$name); $methods = WP_CLI_Command::getMethods($command); if(!empty($methods)) { self::out(' ['.implode('|', $methods).']'); @@ -126,65 +126,66 @@ static function generalHelp() { * @author Andreas Creten */ class CLI_Upgrader_Skin { - var $upgrader; - var $done_header = false; - var $result = false; - - function __construct($args = array()) { - $defaults = array('url' => '', 'nonce' => '', 'title' => '', 'context' => false); - $this->options = wp_parse_args($args, $defaults); - } + var $upgrader; + var $done_header = false; + var $result = false; - function set_upgrader(&$upgrader) { - if(is_object($upgrader)) { + function __construct($args = array()) { + $defaults = array('url' => '', 'nonce' => '', 'title' => '', 'context' => false); + $this->options = wp_parse_args($args, $defaults); + } + + function set_upgrader(&$upgrader) { + if(is_object($upgrader)) { $this->upgrader =& $upgrader; } - $this->add_strings(); - } - - function add_strings() {} - - function set_result($result) { - $this->result = $result; - } - - function request_filesystem_credentials($error = false) { - $url = $this->options['url']; - $context = $this->options['context']; - if(!empty($this->options['nonce'])) { + $this->add_strings(); + } + + function add_strings() {} + + function set_result($result) { + $this->result = $result; + } + + function request_filesystem_credentials($error = false) { + $url = $this->options['url']; + $context = $this->options['context']; + if(!empty($this->options['nonce'])) { $url = wp_nonce_url($url, $this->options['nonce']); } - - return request_filesystem_credentials($url, '', $error, $context); //Possible to bring inline, Leaving as is for now. - } - - function header() {} - function footer() {} - - function error($errors) { - $this->feedback(WP_CLI::errorToString($errors)); - } - - function feedback($string) { - if(isset( $this->upgrader->strings[$string])) - $string = $this->upgrader->strings[$string]; + + // Possible to bring inline, Leaving as is for now. + return request_filesystem_credentials($url, '', $error, $context); + } + + function header() {} + function footer() {} + + function error($errors) { + $this->feedback(WP_CLI::errorToString($errors)); + } - if(strpos($string, '%') !== false) { - $args = func_get_args(); - $args = array_splice($args, 1); - if(!empty($args)) { + function feedback($string) { + if(isset( $this->upgrader->strings[$string])) + $string = $this->upgrader->strings[$string]; + + if(strpos($string, '%') !== false) { + $args = func_get_args(); + $args = array_splice($args, 1); + if(!empty($args)) { $string = vsprintf($string, $args); } - - } - if(empty($string)) { + + } + if(empty($string)) { return; } - - echo $string; - } + + echo $string; + } - function before() {} - function after() {} + function before() {} + function after() {} } \ No newline at end of file diff --git a/commands/community/example.php b/commands/community/example.php new file mode 100644 index 0000000000..3e669233a3 --- /dev/null +++ b/commands/community/example.php @@ -0,0 +1,76 @@ +'); + } + else { + WP_CLI::line(' wp '.$used_command.' '.$method); + } + } + } +} \ No newline at end of file From 3e00376b4fe2b172f9229cf071f466333c52bfac Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 10:02:07 +0200 Subject: [PATCH 0012/4858] Another readme/example update --- README.md | 9 +++++---- commands/community/example.php | 5 ++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f82212d55f..0872603f38 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,7 @@ Installing ---------- Installing wp-cli is extremely simple: - -1. Download the latest version or clone wp-cli from Github and init and update the submodules + 1. Place the `wp-cli` folder in your Wordpress root (on the same level as `wp-admin` and `wp-content`). 1. That's it! @@ -53,7 +52,7 @@ Adding commands to wp-cli is very easy. You can even add them from within your o Each command has its own class, the methods of that class are the sub commands of the command. The base class for the commands is the abstract `WP_CLI_Command`, it handles some essential functionality (like default help for your command). -You can add new commands to the `commands/community` in the wp-cli plugin, they will be auto-loaded on startup. You can also add commands from within your plugins by just calling the wp-cli hooks from there. +You can add new commands to the `commands/community` folder in the wp-cli plugin, they will be auto-loaded on startup. You can also add commands from within your plugins by just calling the wp-cli hooks from there. A wp-cli class is structured like this: @@ -89,10 +88,12 @@ To register this class under the `example` command, add the following line to th WP_CLI::addCommand('example', 'ExampleCommand'); ``` -This will register the comand `wp example`, and the subcommand `wp example example`. If you run `wp example example`, the text `Success: Success message` will be printed to the command line and the script will end. +This will register the comand `wp example` and the subcommand `wp example example`. If you run `wp example example`, the text `Success: Success message` will be printed to the command line and the script will end. You can take a look at the example command file in `commands/community/example.php` for more details. For the ways to interact with the command line, you should take a look at the WP_CLI class in the `class-wp-cli.php` file. +**Please share the commands you make, issue a pull request to get them included in wp-cli by default.** + Requirements ------------ diff --git a/commands/community/example.php b/commands/community/example.php index 3e669233a3..8a08c01e26 100644 --- a/commands/community/example.php +++ b/commands/community/example.php @@ -20,7 +20,10 @@ class ExampleCommand extends WP_CLI_Command { */ function example($args) { // Print a string - WP_CLI::line('Prints a string -- '); + WP_CLI::out('Prints a string -- '); + + // Print a second string + WP_CLI::out('Prints a second string -- '); // Print a single line WP_CLI::line('Prints out a line'); From 0149f7895460ea7fb604d6fc8caa77f234d12dbb Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 11:56:32 +0200 Subject: [PATCH 0013/4858] Readme update --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0872603f38..4335701597 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Example usage: So this tells us that there are 4 commands installed: google-sitemap, core, home and plugins. Between brackets you can see their sub commands. -Let's for example try to update the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. +Let's for example try to install the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. Output: ``` @@ -92,6 +92,15 @@ This will register the comand `wp example` and the subcommand `wp example exampl You can take a look at the example command file in `commands/community/example.php` for more details. For the ways to interact with the command line, you should take a look at the WP_CLI class in the `class-wp-cli.php` file. +If you want to register the command from within your plugin you might want to add a check to see if wp-cli is active to your plugin. By doing this you can implement the wp-cli by default, even if wp-cli is not installed on the Wordpress installation. You can use the `WP_CLI` constant to check if wp-cli is running: + +```php + Date: Wed, 28 Sep 2011 11:57:48 +0200 Subject: [PATCH 0014/4858] Readme update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4335701597..9a23eb4216 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ This will register the comand `wp example` and the subcommand `wp example exampl You can take a look at the example command file in `commands/community/example.php` for more details. For the ways to interact with the command line, you should take a look at the WP_CLI class in the `class-wp-cli.php` file. -If you want to register the command from within your plugin you might want to add a check to see if wp-cli is active to your plugin. By doing this you can implement the wp-cli by default, even if wp-cli is not installed on the Wordpress installation. You can use the `WP_CLI` constant to check if wp-cli is running: +If you want to register the command from within your plugin you might want to add a check to see if wp-cli is running. By doing this you can implement your wp-cli command by default, even if wp-cli is not installed on the Wordpress installation. You can use the `WP_CLI` constant to check if wp-cli is running: ```php Date: Wed, 28 Sep 2011 19:52:34 +0200 Subject: [PATCH 0015/4858] Option command Add, update, delete and get option values. --- commands/internals/option.php | 135 ++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 commands/internals/option.php diff --git a/commands/internals/option.php b/commands/internals/option.php new file mode 100644 index 0000000000..e5583948d1 --- /dev/null +++ b/commands/internals/option.php @@ -0,0 +1,135 @@ + '); + WP_CLI::line(' wp option update '); + WP_CLI::line(' wp option delete '); + WP_CLI::line(' wp option get '); + WP_CLI::line(''); + WP_CLI::line('%9--- DETAILS ---%n'); + WP_CLI::line(''); + WP_CLI::line('Adding a new option:'); + WP_CLI::line(' wp option add '); + WP_CLI::line(''); + WP_CLI::line('Updating an option:'); + WP_CLI::line(' wp option update '); + WP_CLI::line(''); + WP_CLI::line('Deleting an option:'); + WP_CLI::line(' wp option delete '); + WP_CLI::line(''); + WP_CLI::line('Get the value of an option:'); + WP_CLI::line(' wp option get '); + } +} \ No newline at end of file From 7d8d0aef709bae8a3d0049ac97e5e17d9f695ab1 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 20:26:44 +0200 Subject: [PATCH 0016/4858] Theme command Get list of installed themes, get details of a theme. Activation of a theme is work in progress. --- class-wp-cli-command.php | 12 +++++ commands/internals/theme.php | 94 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 commands/internals/theme.php diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 18aa2f5f2d..44f652e3dd 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -21,6 +21,11 @@ function __construct($args = array()) { if(method_exists($this, $sub_command)) { $this->$sub_command($args); } + // If a dummy method exists, use it. This if for reserved keywords in php (like list, isset) + elseif(method_exists($this, '_'.$sub_command)) { + $sub_command = '_'.$sub_command; + $this->$sub_command($args); + } // Otherwise, show the help for this command else { $this->help($args); @@ -81,6 +86,13 @@ static function getMethods($class) { } } + // Fix dummy function names + foreach($methods as $key => $method) { + if(strpos($method, '_') === 0) { + $methods[$key] = substr($method, 1, strlen($method)); + } + } + // Only return the values, to fill up the gaps return array_values($methods); } diff --git a/commands/internals/theme.php b/commands/internals/theme.php new file mode 100644 index 0000000000..78c1a8f7a7 --- /dev/null +++ b/commands/internals/theme.php @@ -0,0 +1,94 @@ + $theme) { + WP_CLI::line(' - '.$theme['Stylesheet']); + } + } + + /** + * Get theme details + * + * @param string $args + * @return void + * @author Andreas Creten + **/ + public function details($args = array()) { + // Get the info of the theme + $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + + // Get the current theme + $theme_name = get_current_theme(); + + WP_CLI::line('Theme %2'.$details['Name'].'%n details:'); + WP_CLI::line(' Active: '.((int) ($details['Name'] == $theme_name))); + WP_CLI::line(' Version: '.$details['Version']); + WP_CLI::line(' Author: '.strip_tags($details['Author'])); + //WP_CLI::line(' Description: '.strip_tags($details['Description'])); + } + + /** + * Activate a theme + * + * @param string $args + * @return void + * @author Andreas Creten + **/ + public function activate($args = array()) { + WP_CLI::warning('This command is not ready yet!'); + + // Get the info of the theme + $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + + // Switch to the theme + switch_theme($args[0], WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + + // Get the current theme + $theme_name = get_current_theme(); + } + + /** + * Help function for this command + * + * @param string $args + * @return void + * @author Andreas Creten + */ + public function help($args = array()) { + WP_CLI::line('Example usage:'); + WP_CLI::line(' wp theme list'); + WP_CLI::line(' wp theme details '); + WP_CLI::line(''); + WP_CLI::line('%9--- DETAILS ---%n'); + WP_CLI::line(''); + WP_CLI::line('Get a list of the installed themes:'); + WP_CLI::line(' wp theme list'); + WP_CLI::line(''); + WP_CLI::line('Get the details for a theme:'); + WP_CLI::line(' wp theme details '); + } +} \ No newline at end of file From 70aae1e32c5af514fd88de493cd106c4ccea0647 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 20:32:14 +0200 Subject: [PATCH 0017/4858] Readme update --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9a23eb4216..8f045d6d88 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,12 @@ Typing the following command: `./wp help`, will show you an output similar to t ``` Example usage: - wp google-sitemap [build|help] ... - wp core [update|help] ... - wp home [help] ... - wp plugins [status|activate|deactivate|install|delete|update|help] ... + wp google-sitemap [build|help] ... + wp core [update|help] ... + wp home [help] ... + wp option [add|update|delete|get|help] ... + wp plugins [status|activate|deactivate|install|delete|update|help] ... + wp theme [list|details|activate|help] ... ``` So this tells us that there are 4 commands installed: google-sitemap, core, home and plugins. From a0f5cdc9597b85c3d58fc3a36e697c5b19dc7784 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 20:35:54 +0200 Subject: [PATCH 0018/4858] Readme update --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 8f045d6d88..09bf1f91f3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,15 @@ Installing wp-cli is extremely simple: 1. Place the `wp-cli` folder in your Wordpress root (on the same level as `wp-admin` and `wp-content`). 1. That's it! +Commands +-------- + +- `wp core` - Update the Wordpress core +- `wp home` - Open the wp-cli project on Github +- `wp option ...` - Manipulate the Wordpress options +- `wp plugins ...` - Do cool things with the installed plugins +- `wp theme ...` - Get details on the installed and current theme + Usage ----- From beb0a897f82a665ff9b46be4edbcd414f34a3082 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 21:07:28 +0200 Subject: [PATCH 0019/4858] Readme fix --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 09bf1f91f3..1dd422fd0b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Example usage: wp theme [list|details|activate|help] ... ``` -So this tells us that there are 4 commands installed: google-sitemap, core, home and plugins. +So this tells us which commandsa are installed: eg. google-sitemap, core, home, ... Between brackets you can see their sub commands. Let's for example try to install the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. @@ -114,6 +114,14 @@ if(defined('WP_CLI') && WP_CLI) { **Please share the commands you make, issue a pull request to get them included in wp-cli by default.** +Todo +---- + +Commands to be written: +- User management +- Post management (not sure yet if we really need this) + + Requirements ------------ From d5f6608ef227631e98fabbe1b33801487d75c098 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 22:08:56 +0300 Subject: [PATCH 0020/4858] Edited README.md via GitHub --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1dd422fd0b..63b26371ac 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Example usage: wp theme [list|details|activate|help] ... ``` -So this tells us which commandsa are installed: eg. google-sitemap, core, home, ... +So this tells us which commands are installed: eg. google-sitemap, core, home, ... Between brackets you can see their sub commands. Let's for example try to install the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. @@ -118,6 +118,7 @@ Todo ---- Commands to be written: + - User management - Post management (not sure yet if we really need this) From d113d8398b50d117b92faa40c4171525aa282943 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 23:01:43 +0200 Subject: [PATCH 0021/4858] Fix for home command on linux (fixes #1) --- commands/internals/home.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/commands/internals/home.php b/commands/internals/home.php index f5b8ff28ac..dd02b70206 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -19,8 +19,20 @@ class HomeCommand extends WP_CLI_Command { */ function __construct($args) { if(empty($args)) { + // Check if the x-www-browser command exists + $result = exec('which x-www-browser'); + // Open the wp-cli page in the browser - exec('open https://github.com/andreascreten/wp-cli'); + if(exec('which x-www-browser')) { + system('x-www-browser http://github.comandreascreten/wp-cli'); + } + elseif(exec('which open')) { + system('open https://github.com/andreascreten/wp-cli'); + } + else { + WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: https://github.com/andreascreten/wp-cli'); + return; + } WP_CLI::success('The wp-cli homepage should be opening in your browser.'); } From 4bc6e8f8f3cad383ddf0c89971b3dcad4919f11e Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 23:04:29 +0200 Subject: [PATCH 0022/4858] Changed Wordpress to WordPress Matt apparently is as hard as me on this. It should be WordPress, not Wordpress. --- README.md | 16 ++++++++-------- class-wp-cli.php | 2 +- commands/internals/core.php | 4 ++-- commands/internals/plugins.php | 6 +++--- wp-cli.php | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 63b26371ac..11bbadb264 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,25 @@ -WP-CLI: Wordpress Command Line Tools +WP-CLI: WordPress Command Line Tools ============================ What is wp-cli -------------- -A command line tool to do maintenance work on a Wordpress install from the command line. +A command line tool to do maintenance work on a WordPress install from the command line. Installing ---------- Installing wp-cli is extremely simple: -1. Place the `wp-cli` folder in your Wordpress root (on the same level as `wp-admin` and `wp-content`). +1. Place the `wp-cli` folder in your WordPress root (on the same level as `wp-admin` and `wp-content`). 1. That's it! Commands -------- -- `wp core` - Update the Wordpress core +- `wp core` - Update the WordPress core - `wp home` - Open the wp-cli project on Github -- `wp option ...` - Manipulate the Wordpress options +- `wp option ...` - Manipulate the WordPress options - `wp plugins ...` - Do cool things with the installed plugins - `wp theme ...` - Get details on the installed and current theme @@ -43,13 +43,13 @@ Example usage: So this tells us which commands are installed: eg. google-sitemap, core, home, ... Between brackets you can see their sub commands. -Let's for example try to install the hello dolly plugin from Wordpress: `./wp plugins install hello-dolly`. +Let's for example try to install the hello dolly plugin from WordPress: `./wp plugins install hello-dolly`. Output: ``` Installing Hello Dolly (1.5) -Downloading install package from http://downloads.wordpress.org/plugin/hello-dolly.1.5.zip ... +Downloading install package from http://downloads.WordPress.org/plugin/hello-dolly.1.5.zip ... Unpacking the package ... Installing the plugin ... @@ -103,7 +103,7 @@ This will register the comand `wp example` and the subcommand `wp example exampl You can take a look at the example command file in `commands/community/example.php` for more details. For the ways to interact with the command line, you should take a look at the WP_CLI class in the `class-wp-cli.php` file. -If you want to register the command from within your plugin you might want to add a check to see if wp-cli is running. By doing this you can implement your wp-cli command by default, even if wp-cli is not installed on the Wordpress installation. You can use the `WP_CLI` constant to check if wp-cli is running: +If you want to register the command from within your plugin you might want to add a check to see if wp-cli is running. By doing this you can implement your wp-cli command by default, even if wp-cli is not installed on the WordPress installation. You can use the `WP_CLI` constant to check if wp-cli is running: ```php parse_name($name, false); - // Force Wordpress to update the plugin list + // Force WordPress to update the plugin list wp_update_plugins(); - // Get plugin info from the Wordpress servers + // Get plugin info from the WordPress servers $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); $status = install_plugin_install_status($api); @@ -190,7 +190,7 @@ function update($args) { // Get the plugin file name $file = $this->parse_name($name); - // Force Wordpress to update the plugin list + // Force WordPress to update the plugin list wp_update_plugins(); if(!class_exists('Plugin_Upgrader')) { diff --git a/wp-cli.php b/wp-cli.php index 5bd1bdf541..6f2d434d40 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -5,7 +5,7 @@ die('Only cli access'); } -// Define the Wordpress location +// Define the WordPress location define('WP_ROOT', '../'); // Set a constant that can be used to check if we are running wp-cli or not From 9e37e9415b31161937b346cf2cc7db524f1a70c3 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 23:07:04 +0200 Subject: [PATCH 0023/4858] Fix for repo url on Linux (fixes #1) --- commands/internals/home.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/internals/home.php b/commands/internals/home.php index dd02b70206..26f172b510 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -24,7 +24,7 @@ function __construct($args) { // Open the wp-cli page in the browser if(exec('which x-www-browser')) { - system('x-www-browser http://github.comandreascreten/wp-cli'); + system('x-www-browser http://github.com/andreascreten/wp-cli'); } elseif(exec('which open')) { system('open https://github.com/andreascreten/wp-cli'); From 354c1824942436e15cf9e0fe310719c823f82d54 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Wed, 28 Sep 2011 23:10:53 +0200 Subject: [PATCH 0024/4858] Removed unused var --- commands/internals/home.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/commands/internals/home.php b/commands/internals/home.php index 26f172b510..ea4eacc159 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -19,18 +19,18 @@ class HomeCommand extends WP_CLI_Command { */ function __construct($args) { if(empty($args)) { - // Check if the x-www-browser command exists - $result = exec('which x-www-browser'); + // The url for the wp-cli repository + $repository_url = 'http://github.com/andreascreten/wp-cli'; // Open the wp-cli page in the browser if(exec('which x-www-browser')) { - system('x-www-browser http://github.com/andreascreten/wp-cli'); + system('x-www-browser '.$repository_url); } elseif(exec('which open')) { - system('open https://github.com/andreascreten/wp-cli'); + system('open '.$repository_url); } else { - WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: https://github.com/andreascreten/wp-cli'); + WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: '.$repository_url); return; } From 9a3fcf0347e30bcbb5c3081602099d89d393568f Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 00:08:09 +0200 Subject: [PATCH 0025/4858] Command updates and renames - Renamed the plugins command to plugin - Updated the example and the readme - Renamed the theme/list command to theme/status - Added extra functionality to the plugin/status command (asked in #2) --- README.md | 6 +- commands/community/example.php | 2 +- .../internals/{plugins.php => plugin.php} | 64 +++++++++++++------ commands/internals/theme.php | 14 +++- 4 files changed, 58 insertions(+), 28 deletions(-) rename commands/internals/{plugins.php => plugin.php} (82%) diff --git a/README.md b/README.md index 11bbadb264..03aea47280 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Commands - `wp core` - Update the WordPress core - `wp home` - Open the wp-cli project on Github - `wp option ...` - Manipulate the WordPress options -- `wp plugins ...` - Do cool things with the installed plugins +- `wp plugin ...` - Do cool things with the installed plugins - `wp theme ...` - Get details on the installed and current theme Usage @@ -36,7 +36,7 @@ Example usage: wp core [update|help] ... wp home [help] ... wp option [add|update|delete|get|help] ... - wp plugins [status|activate|deactivate|install|delete|update|help] ... + wp plugin [status|activate|deactivate|install|delete|update|help] ... wp theme [list|details|activate|help] ... ``` @@ -84,7 +84,7 @@ class ExampleCommand extends WP_CLI_Command { * @return void * @author Andreas Creten */ - function example($args) { + function example($args = array()) { // Print a success message WP_CLI::success('Success message'); } diff --git a/commands/community/example.php b/commands/community/example.php index 8a08c01e26..2f292e44ae 100644 --- a/commands/community/example.php +++ b/commands/community/example.php @@ -18,7 +18,7 @@ class ExampleCommand extends WP_CLI_Command { * @return void * @author Andreas Creten */ - function example($args) { + function example($args = array()) { // Print a string WP_CLI::out('Prints a string -- '); diff --git a/commands/internals/plugins.php b/commands/internals/plugin.php similarity index 82% rename from commands/internals/plugins.php rename to commands/internals/plugin.php index 52ba177e60..0c496d18a6 100644 --- a/commands/internals/plugins.php +++ b/commands/internals/plugin.php @@ -1,20 +1,20 @@ check_name($args); - - // Get the plugin file name - $file = $this->parse_name($name); - - // Get the plugin details - $details = $this->get_details($file); - - // Display the plugin details - WP_CLI::line('Plugin %2'.$name.'%n details:'); - WP_CLI::line(' Active: '.((int) is_plugin_active($file))); - if(is_multisite()) { - WP_CLI::line(' Network: '.((int) is_plugin_active_for_network($file))); + if(!empty($args)) { + // Get the plugin name from the arguments + $name = $this->check_name($args); + + // Get the plugin file name + $file = $this->parse_name($name); + + // Get the plugin details + $details = $this->get_details($file); + + // Display the plugin details + WP_CLI::line('Plugin %2'.$name.'%n details:'); + WP_CLI::line(' Active: '.((int) is_plugin_active($file))); + if(is_multisite()) { + WP_CLI::line(' Network: '.((int) is_plugin_active_for_network($file))); + } + WP_CLI::line(' Version: '.$details['Version']); + } + else { + // Get the list of plugins + $plugins = get_plugins(); + + // Print the header + WP_CLI::line('Installed plugins:'); + + // Show the list if themes + foreach ($plugins as $file => $plugin) { + // Check plugin status + $network = is_plugin_active_for_network($file); + $status = is_plugin_active($file); + + WP_CLI::line(' '.($status ? '%g'.($network ? '%bN' : '').'A' : 'I').' '.$plugin['Name'].'%n'); + } + + // Print the footer + WP_CLI::line(); + WP_CLI::line('Codes: I = Inactive, A = Active, NA = Network Active'); } - WP_CLI::line(' Version: '.$details['Version']); } /** @@ -76,7 +98,7 @@ function activate($args) { * @author Andreas Creten */ function deactivate($args) { - // Get the plugin name from the arguments + // Get the plugin name from the arguments $name = $this->check_name($args); // Get the plugin file name @@ -148,7 +170,7 @@ function install($args) { WP_CLI::error('Latest version already installed'); if(is_plugin_inactive($file)) { - WP_CLI::warning('If you want to activate the plugin, run: %2wp plugins activate '.$name.'%n'); + WP_CLI::warning('If you want to activate the plugin, run: %2wp plugin activate '.$name.'%n'); } break; } @@ -309,7 +331,7 @@ public function help($args = array()) { $methods = WP_CLI_Command::getMethods($this); foreach ($methods as $method) { if($method != 'help') { - WP_CLI::line(' wp '.$used_command.' '.$method.' '); + WP_CLI::line(' wp '.$used_command.' '.$method.' hello-dolly'); } else { WP_CLI::line(' wp '.$used_command.' '.$method); diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 78c1a8f7a7..a58a02fff3 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -12,22 +12,30 @@ */ class ThemeCommand extends WP_CLI_Command { /** - * List all themes + * Get the status of all themes * * @param string $args * @return void * @author Andreas Creten **/ - public function _list($args = array()) { + public function status($args = array()) { // Get the list of themes $themes = get_themes(); + // Print the header WP_CLI::line('Installed themes:'); + // Get the current theme + $theme_name = get_current_theme(); + // Show the list if themes foreach ($themes as $key => $theme) { - WP_CLI::line(' - '.$theme['Stylesheet']); + WP_CLI::line(' '.($theme['Name'] == $theme_name ? '%gA' : 'I').' '.$theme['Stylesheet'].'%n'); } + + // Print the footer + WP_CLI::line(); + WP_CLI::line('Codes: I = Inactive, A = Active'); } /** From 4317fa96ed8576a388dd6e225ec87a7ebe0af580 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 00:32:34 +0200 Subject: [PATCH 0026/4858] Updates on plugin status Implemented suggestions from #2 --- commands/internals/plugin.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 0c496d18a6..4d5075ff60 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -45,6 +45,12 @@ function status($args) { // Get the list of plugins $plugins = get_plugins(); + // Get list of mu plugins + $mu_plugins = get_mu_plugins(); + + // Merge the two plugin arrays + $plugins = array_merge($plugins, $mu_plugins); + // Print the header WP_CLI::line('Installed plugins:'); @@ -53,13 +59,15 @@ function status($args) { // Check plugin status $network = is_plugin_active_for_network($file); $status = is_plugin_active($file); + $must_use = isset($mu_plugins[$file]); + $name = dirname($file) ? dirname($file) : str_replace('.php', '', basename($file)); - WP_CLI::line(' '.($status ? '%g'.($network ? '%bN' : '').'A' : 'I').' '.$plugin['Name'].'%n'); + WP_CLI::line(' '.($must_use ? '%cM' : ($status ? ($network ? '%bN' : '%gA') : 'I')).' '.$name.'%n'); } // Print the footer WP_CLI::line(); - WP_CLI::line('Codes: I = Inactive, A = Active, NA = Network Active'); + WP_CLI::line('Codes: M = Must Use, I = Inactive, A = Active, N = Network Active'); } } From b481335b4ec1ac31f710567a286fc911b18666e7 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 04:25:57 +0300 Subject: [PATCH 0027/4858] s/list/status for theme command in readme and usage example --- README.md | 4 ++-- commands/internals/theme.php | 34 +++++++++++++++++----------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 03aea47280..e92a396438 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Example usage: wp home [help] ... wp option [add|update|delete|get|help] ... wp plugin [status|activate|deactivate|install|delete|update|help] ... - wp theme [list|details|activate|help] ... + wp theme [status|details|activate|help] ... ``` So this tells us which commands are installed: eg. google-sitemap, core, home, ... @@ -126,4 +126,4 @@ Commands to be written: Requirements ------------ - * PHP >= 5.3 \ No newline at end of file + * PHP >= 5.3 diff --git a/commands/internals/theme.php b/commands/internals/theme.php index a58a02fff3..fe65b728aa 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -21,23 +21,23 @@ class ThemeCommand extends WP_CLI_Command { public function status($args = array()) { // Get the list of themes $themes = get_themes(); - + // Print the header WP_CLI::line('Installed themes:'); - + // Get the current theme $theme_name = get_current_theme(); - + // Show the list if themes foreach ($themes as $key => $theme) { WP_CLI::line(' '.($theme['Name'] == $theme_name ? '%gA' : 'I').' '.$theme['Stylesheet'].'%n'); } - + // Print the footer WP_CLI::line(); WP_CLI::line('Codes: I = Inactive, A = Active'); } - + /** * Get theme details * @@ -48,17 +48,17 @@ public function status($args = array()) { public function details($args = array()) { // Get the info of the theme $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); - + // Get the current theme $theme_name = get_current_theme(); - + WP_CLI::line('Theme %2'.$details['Name'].'%n details:'); WP_CLI::line(' Active: '.((int) ($details['Name'] == $theme_name))); WP_CLI::line(' Version: '.$details['Version']); WP_CLI::line(' Author: '.strip_tags($details['Author'])); //WP_CLI::line(' Description: '.strip_tags($details['Description'])); } - + /** * Activate a theme * @@ -67,18 +67,18 @@ public function details($args = array()) { * @author Andreas Creten **/ public function activate($args = array()) { - WP_CLI::warning('This command is not ready yet!'); - + WP_CLI::warning('This command is not ready yet!'); + // Get the info of the theme $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); - + // Switch to the theme switch_theme($args[0], WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); - + // Get the current theme $theme_name = get_current_theme(); } - + /** * Help function for this command * @@ -88,15 +88,15 @@ public function activate($args = array()) { */ public function help($args = array()) { WP_CLI::line('Example usage:'); - WP_CLI::line(' wp theme list'); + WP_CLI::line(' wp theme status'); WP_CLI::line(' wp theme details '); WP_CLI::line(''); WP_CLI::line('%9--- DETAILS ---%n'); WP_CLI::line(''); - WP_CLI::line('Get a list of the installed themes:'); - WP_CLI::line(' wp theme list'); + WP_CLI::line('Get a status of the installed themes:'); + WP_CLI::line(' wp theme status'); WP_CLI::line(''); WP_CLI::line('Get the details for a theme:'); WP_CLI::line(' wp theme details '); } -} \ No newline at end of file +} From 028a3c089a64ff9a50498fa883f6cda1c8f80cc9 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 04:32:59 +0300 Subject: [PATCH 0028/4858] replace Codes with Legend and order statuses alphabetically --- commands/internals/plugin.php | 122 +++++++++++++++++----------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 4d5075ff60..e8299c08e0 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -18,13 +18,13 @@ class PluginCommand extends WP_CLI_Command { /** * Get the status of one plugin * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ function status($args) { if(!empty($args)) { - // Get the plugin name from the arguments + // Get the plugin name from the arguments $name = $this->check_name($args); // Get the plugin file name @@ -44,13 +44,13 @@ function status($args) { else { // Get the list of plugins $plugins = get_plugins(); - + // Get list of mu plugins $mu_plugins = get_mu_plugins(); - + // Merge the two plugin arrays $plugins = array_merge($plugins, $mu_plugins); - + // Print the header WP_CLI::line('Installed plugins:'); @@ -61,30 +61,30 @@ function status($args) { $status = is_plugin_active($file); $must_use = isset($mu_plugins[$file]); $name = dirname($file) ? dirname($file) : str_replace('.php', '', basename($file)); - + WP_CLI::line(' '.($must_use ? '%cM' : ($status ? ($network ? '%bN' : '%gA') : 'I')).' '.$name.'%n'); } // Print the footer WP_CLI::line(); - WP_CLI::line('Codes: M = Must Use, I = Inactive, A = Active, N = Network Active'); + WP_CLI::line('Legend: A = Active, I = Inactive, M = Must Use, N = Network Active'); } } - + /** * Activate a plugin * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ function activate($args) { - // Get the plugin name from the arguments + // Get the plugin name from the arguments $name = $this->check_name($args); - + // Get the plugin file name $file = $this->parse_name($name); - + // Check if the plugin is already active if(is_plugin_active($file)) { WP_CLI::error('The plugin is already active: '.$name); @@ -97,21 +97,21 @@ function activate($args) { WP_CLI::error('The plugin could not be activated: '.$name); } } - + /** * Deactivate a plugin * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ function deactivate($args) { // Get the plugin name from the arguments $name = $this->check_name($args); - + // Get the plugin file name $file = $this->parse_name($name); - + // Check if the plugin is already deactivated if(is_plugin_inactive($file)) { WP_CLI::error('The plugin is already deactivated: '.$name); @@ -124,30 +124,30 @@ function deactivate($args) { WP_CLI::error('Could not deactivate this plugin: '.$name); } } - + /** * Install a new plugin * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ function install($args) { - // Get the plugin name from the arguments + // Get the plugin name from the arguments $name = $this->check_name($args); - + // Get the plugin file name $file = $this->parse_name($name, false); - + // Force WordPress to update the plugin list wp_update_plugins(); - + // Get plugin info from the WordPress servers $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); $status = install_plugin_install_status($api); - + WP_CLI::line('Installing '.$api->name.' ('.$api->version.')'); - + // Check what to do switch($status['status']) { case 'update_available': @@ -155,13 +155,13 @@ function install($args) { if(!class_exists('Plugin_Upgrader')) { require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); } - + // Install the plugin ob_start('strip_tags'); $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); $result = $upgrader->install($api->download_link); $feedback = ob_get_clean(); - + if($result !== null) { WP_CLI::error($result); } @@ -176,28 +176,28 @@ function install($args) { break; case 'latest_installed': WP_CLI::error('Latest version already installed'); - + if(is_plugin_inactive($file)) { WP_CLI::warning('If you want to activate the plugin, run: %2wp plugin activate '.$name.'%n'); } break; } } - + /** * Delete a plugin * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ function delete($args) { - // Get the plugin name from the arguments + // Get the plugin name from the arguments $name = $this->check_name($args); - + // Get the plugin file name $file = $this->parse_name($name); - + if(delete_plugins(array($file))) { WP_CLI::success('The plugin is successfully deleted.'); } @@ -205,36 +205,36 @@ function delete($args) { WP_CLI::error('There was an error while deleting the plugin.'); } } - + /** * Update a plugin * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ function update($args) { - // Get the plugin name from the arguments + // Get the plugin name from the arguments $name = $this->check_name($args); - + // Get the plugin file name $file = $this->parse_name($name); - + // Force WordPress to update the plugin list wp_update_plugins(); - + if(!class_exists('Plugin_Upgrader')) { require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); } - + WP_CLI::line('Updating '.$name); - + // Upgrading the plugin ob_start('strip_tags'); $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); $result = $upgrader->upgrade($file); $feedback = ob_get_clean(); - + if($result !== null) { WP_CLI::error($feedback); } @@ -244,28 +244,28 @@ function update($args) { WP_CLI::success('The plugin is successfully updated.'); } } - + /* PRIVATES */ - + /** * Get the details of a plugin * - * @param string $file + * @param string $file * @return array * @author Andreas Creten */ private function get_details($file) { $plugin_folder = get_plugins( '/' . plugin_basename(dirname($file))); $plugin_file = basename(($file)); - + return $plugin_folder[$plugin_file]; } - + /** * Parse the name of a plugin to a filename, check if it exists * - * @param string $name - * @param string $exit + * @param string $name + * @param string $exit * @return mixed * @author Andreas Creten */ @@ -286,19 +286,19 @@ private function parse_name($name, $exit = true) { WP_CLI::error('The plugin \''.$name.'\' could not be found.'); exit(); } - + return false; } } - + return $file; } - + /** * Check if there is a name set in the arguments, if not show the help function * - * @param string $args - * @param string $exit + * @param string $args + * @param string $exit * @return void * @author Andreas Creten */ @@ -307,35 +307,35 @@ private function check_name($args, $exit = true) { WP_CLI::error('Please specify a plugin.'); WP_CLI::line(); $this->help(); - + if($exit) { exit(); } } - + return $args[0]; } - + /** * Help function for this command * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ public function help($args = array()) { // Get the cli arguments $arguments = $GLOBALS['argv']; - + // Remove the first entry array_shift($arguments); // Get the command $used_command = array_shift($arguments); - + // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - + $methods = WP_CLI_Command::getMethods($this); foreach ($methods as $method) { if($method != 'help') { @@ -346,4 +346,4 @@ public function help($args = array()) { } } } -} \ No newline at end of file +} From e1d515dba8a5e1fd51c787f6793571b5b4845bf9 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 04:49:16 +0300 Subject: [PATCH 0029/4858] fix mu plugin names --- commands/internals/plugin.php | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index e8299c08e0..bcfe840efc 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -54,20 +54,31 @@ function status($args) { // Print the header WP_CLI::line('Installed plugins:'); - // Show the list if themes foreach ($plugins as $file => $plugin) { - // Check plugin status - $network = is_plugin_active_for_network($file); - $status = is_plugin_active($file); - $must_use = isset($mu_plugins[$file]); - $name = dirname($file) ? dirname($file) : str_replace('.php', '', basename($file)); + if ( false === strpos( $file, '/' ) ) + $name = str_replace('.php', '', basename($file)); + else + $name = dirname($file); - WP_CLI::line(' '.($must_use ? '%cM' : ($status ? ($network ? '%bN' : '%gA') : 'I')).' '.$name.'%n'); + $line = ' '; + + if ( isset($mu_plugins[$file]) ) + $line .= '%cM'; + elseif ( is_plugin_active_for_network($file) ) + $line .= '%bN'; + elseif ( is_plugin_active($file) ) + $line .= '%gA'; + else + $line .= 'I'; + + $line .= ' '.$name.'%n'; + + WP_CLI::line( $line ); } // Print the footer WP_CLI::line(); - WP_CLI::line('Legend: A = Active, I = Inactive, M = Must Use, N = Network Active'); + WP_CLI::line('Legend: %gA%n = Active, I = Inactive, M = Must Use, N = Network Active'); } } From 48a1d67ae9abefeaebd33ea435b91f2b830ed774 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 04:55:42 +0300 Subject: [PATCH 0030/4858] color code legend line too --- commands/internals/plugin.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index bcfe840efc..265ee071cc 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -78,7 +78,19 @@ function status($args) { // Print the footer WP_CLI::line(); - WP_CLI::line('Legend: %gA%n = Active, I = Inactive, M = Must Use, N = Network Active'); + + $legend = array( + '%gA' => 'Active', + 'I' => 'Inactive', + '%cM' => 'Must Use', + '%bN' => 'Network Active', + ); + + $legend_line = array(); + foreach ( $legend as $key => $title ) + $legend_line[] = "$key = $title%n"; + + WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } } From 0d5334d206f60974146bba748d93d852ae192033 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 04:58:38 +0300 Subject: [PATCH 0031/4858] don't show N in legend unless it's a multisite install --- commands/internals/plugin.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 265ee071cc..4b47ed6808 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -80,12 +80,14 @@ function status($args) { WP_CLI::line(); $legend = array( - '%gA' => 'Active', 'I' => 'Inactive', + '%gA' => 'Active', '%cM' => 'Must Use', - '%bN' => 'Network Active', ); + if ( is_multisite() ) + $legend['%bN'] = 'Network Active'; + $legend_line = array(); foreach ( $legend as $key => $title ) $legend_line[] = "$key = $title%n"; From e39f87e73ed9e24dbffd84399c1c4e4cdca82898 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 05:21:57 +0300 Subject: [PATCH 0032/4858] add update available notification --- commands/internals/plugin.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 4b47ed6808..091b10b414 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -54,13 +54,20 @@ function status($args) { // Print the header WP_CLI::line('Installed plugins:'); + $update_plugins = get_site_transient( 'update_plugins' ); + if ( isset( $update_plugins->response ) ) + $update_plugins = array_keys( $update_plugins->response ); + else + $update_plugins = array(); + foreach ($plugins as $file => $plugin) { if ( false === strpos( $file, '/' ) ) $name = str_replace('.php', '', basename($file)); else $name = dirname($file); - $line = ' '; + $line = ' '; + $line .= in_array( $file, $update_plugins ) ? '%yU%n' : ' '; if ( isset($mu_plugins[$file]) ) $line .= '%cM'; @@ -88,6 +95,8 @@ function status($args) { if ( is_multisite() ) $legend['%bN'] = 'Network Active'; + $legend['%yU'] = 'Update Available'; + $legend_line = array(); foreach ( $legend as $key => $title ) $legend_line[] = "$key = $title%n"; From e3eb8b362aeaf67ba61bab8d1690a12bb7f57a5f Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 05:40:46 +0300 Subject: [PATCH 0033/4858] color code theme status legend too --- class-wp-cli.php | 74 +++++++++++++++++++++-------------- commands/internals/plugin.php | 6 +-- commands/internals/theme.php | 16 +++++--- 3 files changed, 56 insertions(+), 40 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 4c5764bc33..44258a2f45 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -13,76 +13,90 @@ class WP_CLI { * Add a command to the wp-cli list of commands * * @param string $name The name of the command that will be used in the cli - * @param string $class The class to manage the command + * @param string $class The class to manage the command * @return void * @author Andreas Creten */ public function addCommand($name, $class) { self::$commands[$name] = $class; } - + /** * Display a message in the cli * - * @param string $message + * @param string $message * @return void * @author Andreas Creten */ static function out($message) { \cli\out($message); } - + /** * Display a message in the CLI and end with a newline * - * @param string $message + * @param string $message * @return void * @author Andreas Creten */ static function line($message = '') { \cli\line($message); } - + /** * Display an error in the CLI and end with a newline * - * @param string $message - * @param string $label + * @param string $message + * @param string $label * @return void * @author Andreas Creten */ static function error($message, $label = 'Error') { \cli\line('%R'.$label.': %n'.self::errorToString($message)); } - + /** * Display a success in the CLI and end with a newline * - * @param string $message - * @param string $label + * @param string $message + * @param string $label * @return void * @author Andreas Creten */ static function success($message, $label = 'Success') { \cli\line('%G'.$label.': %n'.$message); } - + /** * Display a warning in the CLI and end with a newline * - * @param string $message - * @param string $label + * @param string $message + * @param string $label * @return void * @author Andreas Creten */ static function warning($message, $label = 'Warning') { \cli\line('%C'.$label.': %n'.$message); } - + + /** + * Display a legend + * + * @param array( code => title ) $legend + * @return void + */ + static function legend($legend) { + $legend_line = array(); + foreach ( $legend as $key => $title ) + $legend_line[] = "$key = $title%n"; + + WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); + } + /** * Convert a wp_error into a String * - * @param mixed $errors + * @param mixed $errors * @return string * @author Andreas Creten */ @@ -99,7 +113,7 @@ static function errorToString($errors) { } } } - + /** * Display the help function for the wp-cli * @@ -134,35 +148,35 @@ function __construct($args = array()) { $defaults = array('url' => '', 'nonce' => '', 'title' => '', 'context' => false); $this->options = wp_parse_args($args, $defaults); } - + function set_upgrader(&$upgrader) { if(is_object($upgrader)) { $this->upgrader =& $upgrader; } - + $this->add_strings(); } - + function add_strings() {} - + function set_result($result) { $this->result = $result; } - + function request_filesystem_credentials($error = false) { $url = $this->options['url']; $context = $this->options['context']; if(!empty($this->options['nonce'])) { $url = wp_nonce_url($url, $this->options['nonce']); } - + // Possible to bring inline, Leaving as is for now. return request_filesystem_credentials($url, '', $error, $context); } - + function header() {} function footer() {} - + function error($errors) { $this->feedback(WP_CLI::errorToString($errors)); } @@ -170,22 +184,22 @@ function error($errors) { function feedback($string) { if(isset( $this->upgrader->strings[$string])) $string = $this->upgrader->strings[$string]; - + if(strpos($string, '%') !== false) { $args = func_get_args(); $args = array_splice($args, 1); if(!empty($args)) { $string = vsprintf($string, $args); } - + } if(empty($string)) { return; } - + echo $string; } - + function before() {} function after() {} -} \ No newline at end of file +} diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 091b10b414..991699c3e8 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -97,11 +97,7 @@ function status($args) { $legend['%yU'] = 'Update Available'; - $legend_line = array(); - foreach ( $legend as $key => $title ) - $legend_line[] = "$key = $title%n"; - - WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); + WP_CLI::legend( $legend ); } } diff --git a/commands/internals/theme.php b/commands/internals/theme.php index fe65b728aa..dd06096fe6 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -14,7 +14,7 @@ class ThemeCommand extends WP_CLI_Command { /** * Get the status of all themes * - * @param string $args + * @param string $args * @return void * @author Andreas Creten **/ @@ -35,13 +35,19 @@ public function status($args = array()) { // Print the footer WP_CLI::line(); - WP_CLI::line('Codes: I = Inactive, A = Active'); + + $legend = array( + 'I' => 'Inactive', + '%gA' => 'Active', + ); + + WP_CLI::legend( $legend ); } /** * Get theme details * - * @param string $args + * @param string $args * @return void * @author Andreas Creten **/ @@ -62,7 +68,7 @@ public function details($args = array()) { /** * Activate a theme * - * @param string $args + * @param string $args * @return void * @author Andreas Creten **/ @@ -82,7 +88,7 @@ public function activate($args = array()) { /** * Help function for this command * - * @param string $args + * @param string $args * @return void * @author Andreas Creten */ From 1dc94fb625b570f7b2cbcf6dc9d06d1ceacb79eb Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 05:58:15 +0300 Subject: [PATCH 0034/4858] display update notification for themes --- class-wp-cli.php | 47 ++++++++++++++++++++++++----------- commands/internals/plugin.php | 11 +------- commands/internals/theme.php | 13 +++++++--- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 44258a2f45..b678223e1c 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -79,20 +79,6 @@ static function warning($message, $label = 'Warning') { \cli\line('%C'.$label.': %n'.$message); } - /** - * Display a legend - * - * @param array( code => title ) $legend - * @return void - */ - static function legend($legend) { - $legend_line = array(); - foreach ( $legend as $key => $title ) - $legend_line[] = "$key = $title%n"; - - WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); - } - /** * Convert a wp_error into a String * @@ -131,6 +117,39 @@ static function generalHelp() { self::line(' ...'); } } + + /** + * Display a legend + * + * @param array( code => title ) $legend + * @return void + */ + static function legend($legend) { + $legend['%yU'] = 'Update Available'; + + $legend_line = array(); + foreach ( $legend as $key => $title ) + $legend_line[] = "$key = $title%n"; + + WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); + } + + /** + * Return the beginning of the status line for a certain plugin or theme + * + * @param string $item The plugin or theme name + * @param string $key The transient key + * + * @return string + */ + static function get_update_status( $item, $key ) { + $update_list = get_site_transient( $key ); + + if ( isset( $update_list->response[ $item ] ) ) + return ' %yU%n'; + + return ' '; + } } /** diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 991699c3e8..125c0f1597 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -54,20 +54,13 @@ function status($args) { // Print the header WP_CLI::line('Installed plugins:'); - $update_plugins = get_site_transient( 'update_plugins' ); - if ( isset( $update_plugins->response ) ) - $update_plugins = array_keys( $update_plugins->response ); - else - $update_plugins = array(); - foreach ($plugins as $file => $plugin) { if ( false === strpos( $file, '/' ) ) $name = str_replace('.php', '', basename($file)); else $name = dirname($file); - $line = ' '; - $line .= in_array( $file, $update_plugins ) ? '%yU%n' : ' '; + $line = WP_CLI::get_update_status( $file, 'update_plugins' ); if ( isset($mu_plugins[$file]) ) $line .= '%cM'; @@ -95,8 +88,6 @@ function status($args) { if ( is_multisite() ) $legend['%bN'] = 'Network Active'; - $legend['%yU'] = 'Update Available'; - WP_CLI::legend( $legend ); } } diff --git a/commands/internals/theme.php b/commands/internals/theme.php index dd06096fe6..a1e590cc15 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -25,12 +25,19 @@ public function status($args = array()) { // Print the header WP_CLI::line('Installed themes:'); - // Get the current theme $theme_name = get_current_theme(); - // Show the list if themes foreach ($themes as $key => $theme) { - WP_CLI::line(' '.($theme['Name'] == $theme_name ? '%gA' : 'I').' '.$theme['Stylesheet'].'%n'); + $line = WP_CLI::get_update_status( $theme['Stylesheet'], 'update_themes' ); + + if ( $theme['Name'] == $theme_name ) + $line .= '%gA'; + else + $line .= 'I'; + + $line .= ' ' . $theme['Stylesheet'].'%n'; + + WP_CLI::line( $line ); } // Print the footer From 170256ba10b43faf268c19366b4113c4cf8792ff Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 07:43:12 +0200 Subject: [PATCH 0035/4858] Removed the @author tags from the method command blocks (fixes #5) --- class-wp-cli-command.php | 3 --- class-wp-cli.php | 8 -------- commands/community/example.php | 2 -- commands/internals/core.php | 1 - commands/internals/home.php | 2 -- commands/internals/option.php | 5 ----- commands/internals/plugin.php | 10 ---------- commands/internals/theme.php | 4 ---- 8 files changed, 35 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 44f652e3dd..cbf7c225ec 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -11,7 +11,6 @@ abstract class WP_CLI_Command { * Construct for this class, transfers the cli arguments to the right class * * @param Array $args - * @author Andreas Creten */ function __construct($args = array()) { // The first command is the sub command @@ -37,7 +36,6 @@ function __construct($args = array()) { * * @param Array $args * @return void - * @author Andreas Creten */ public function help($args = array()) { // Get the cli arguments @@ -69,7 +67,6 @@ public function help($args = array()) { * * @param string $class * @return Array The list of methods - * @author Andreas Creten */ static function getMethods($class) { // Methods that don't need to be included in the method list diff --git a/class-wp-cli.php b/class-wp-cli.php index b678223e1c..5ba54be8d6 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -15,7 +15,6 @@ class WP_CLI { * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command * @return void - * @author Andreas Creten */ public function addCommand($name, $class) { self::$commands[$name] = $class; @@ -26,7 +25,6 @@ public function addCommand($name, $class) { * * @param string $message * @return void - * @author Andreas Creten */ static function out($message) { \cli\out($message); @@ -37,7 +35,6 @@ static function out($message) { * * @param string $message * @return void - * @author Andreas Creten */ static function line($message = '') { \cli\line($message); @@ -49,7 +46,6 @@ static function line($message = '') { * @param string $message * @param string $label * @return void - * @author Andreas Creten */ static function error($message, $label = 'Error') { \cli\line('%R'.$label.': %n'.self::errorToString($message)); @@ -61,7 +57,6 @@ static function error($message, $label = 'Error') { * @param string $message * @param string $label * @return void - * @author Andreas Creten */ static function success($message, $label = 'Success') { \cli\line('%G'.$label.': %n'.$message); @@ -73,7 +68,6 @@ static function success($message, $label = 'Success') { * @param string $message * @param string $label * @return void - * @author Andreas Creten */ static function warning($message, $label = 'Warning') { \cli\line('%C'.$label.': %n'.$message); @@ -84,7 +78,6 @@ static function warning($message, $label = 'Warning') { * * @param mixed $errors * @return string - * @author Andreas Creten */ static function errorToString($errors) { if(is_string($errors)){ @@ -104,7 +97,6 @@ static function errorToString($errors) { * Display the help function for the wp-cli * * @return void - * @author Andreas Creten */ static function generalHelp() { self::line('Example usage:'); diff --git a/commands/community/example.php b/commands/community/example.php index 2f292e44ae..8105888534 100644 --- a/commands/community/example.php +++ b/commands/community/example.php @@ -16,7 +16,6 @@ class ExampleCommand extends WP_CLI_Command { * * @param string $args * @return void - * @author Andreas Creten */ function example($args = array()) { // Print a string @@ -51,7 +50,6 @@ function example($args = array()) { * * @param string $args * @return void - * @author Andreas Creten */ public function help($args = array()) { // Get the cli arguments diff --git a/commands/internals/core.php b/commands/internals/core.php index 02c87144b3..6b17113b1c 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -16,7 +16,6 @@ class CoreCommand extends WP_CLI_Command { * * @param string $args * @return void - * @author Andreas Creten */ function update($args) { WP_CLI::line('Updating the WordPress core.'); diff --git a/commands/internals/home.php b/commands/internals/home.php index ea4eacc159..13c20f1e32 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -15,7 +15,6 @@ class HomeCommand extends WP_CLI_Command { * Overwrite the construct to have a command without subcommand * * @param string $args - * @author Andreas Creten */ function __construct($args) { if(empty($args)) { @@ -47,7 +46,6 @@ function __construct($args) { * * @param string $args * @return void - * @author Andreas Creten */ public function help($args = array()) { WP_CLI::line('This command has no arguments, when called it will open the wp-cli homepage in your browser.'); diff --git a/commands/internals/option.php b/commands/internals/option.php index e5583948d1..1281b181f6 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -16,7 +16,6 @@ class OptionCommand extends WP_CLI_Command { * * @param string $args * @return void - * @author Andreas Creten **/ public function add($args = array()) { // Check if the required arguments are there @@ -39,7 +38,6 @@ public function add($args = array()) { * * @param string $args * @return void - * @author Andreas Creten **/ public function update($args = array()) { // Check if the required arguments are there @@ -62,7 +60,6 @@ public function update($args = array()) { * * @param string $args * @return void - * @author Andreas Creten **/ public function delete($args = array()) { // Check if the required arguments are there @@ -85,7 +82,6 @@ public function delete($args = array()) { * * @param string $args * @return void - * @author Andreas Creten **/ public function get($args = array()) { // Check if the required arguments are there @@ -109,7 +105,6 @@ public function get($args = array()) { * * @param string $args * @return void - * @author Andreas Creten */ public function help($args = array()) { WP_CLI::line('Example usage:'); diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 125c0f1597..962d113594 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -20,7 +20,6 @@ class PluginCommand extends WP_CLI_Command { * * @param string $args * @return void - * @author Andreas Creten */ function status($args) { if(!empty($args)) { @@ -97,7 +96,6 @@ function status($args) { * * @param string $args * @return void - * @author Andreas Creten */ function activate($args) { // Get the plugin name from the arguments @@ -124,7 +122,6 @@ function activate($args) { * * @param string $args * @return void - * @author Andreas Creten */ function deactivate($args) { // Get the plugin name from the arguments @@ -151,7 +148,6 @@ function deactivate($args) { * * @param string $args * @return void - * @author Andreas Creten */ function install($args) { // Get the plugin name from the arguments @@ -210,7 +206,6 @@ function install($args) { * * @param string $args * @return void - * @author Andreas Creten */ function delete($args) { // Get the plugin name from the arguments @@ -232,7 +227,6 @@ function delete($args) { * * @param string $args * @return void - * @author Andreas Creten */ function update($args) { // Get the plugin name from the arguments @@ -273,7 +267,6 @@ function update($args) { * * @param string $file * @return array - * @author Andreas Creten */ private function get_details($file) { $plugin_folder = get_plugins( '/' . plugin_basename(dirname($file))); @@ -288,7 +281,6 @@ private function get_details($file) { * @param string $name * @param string $exit * @return mixed - * @author Andreas Creten */ private function parse_name($name, $exit = true) { $plugins = get_plugins('/'.$name); @@ -321,7 +313,6 @@ private function parse_name($name, $exit = true) { * @param string $args * @param string $exit * @return void - * @author Andreas Creten */ private function check_name($args, $exit = true) { if(empty($args)) { @@ -342,7 +333,6 @@ private function check_name($args, $exit = true) { * * @param string $args * @return void - * @author Andreas Creten */ public function help($args = array()) { // Get the cli arguments diff --git a/commands/internals/theme.php b/commands/internals/theme.php index a1e590cc15..383b0dd85b 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -16,7 +16,6 @@ class ThemeCommand extends WP_CLI_Command { * * @param string $args * @return void - * @author Andreas Creten **/ public function status($args = array()) { // Get the list of themes @@ -56,7 +55,6 @@ public function status($args = array()) { * * @param string $args * @return void - * @author Andreas Creten **/ public function details($args = array()) { // Get the info of the theme @@ -77,7 +75,6 @@ public function details($args = array()) { * * @param string $args * @return void - * @author Andreas Creten **/ public function activate($args = array()) { WP_CLI::warning('This command is not ready yet!'); @@ -97,7 +94,6 @@ public function activate($args = array()) { * * @param string $args * @return void - * @author Andreas Creten */ public function help($args = array()) { WP_CLI::line('Example usage:'); From ef88fa7c71e9cf3ed554d92c3e6de2a631bb4e5b Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 07:55:39 +0200 Subject: [PATCH 0036/4858] Added contributors to the readme file --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index e92a396438..ce8332476c 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,11 @@ Commands to be written: - User management - Post management (not sure yet if we really need this) +Contributors +------------ + +- Andreas Creten ([@andreascreten](http://twitter.com/andreascreten)) +- Silviu-Cristian Burcă ([@scribu](http://twitter.com/scribu)) Requirements ------------ From 475589a2eed3c734fcb655438f54aae737c1191d Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 09:28:31 +0200 Subject: [PATCH 0037/4858] PHP version check and globalization - The wp shell script now checks the PHP version needed for wp-cli - Globalized the wp-cli.php script so that it can be called from anywhere on your filesystem (related to #3) --- wp | 16 ++++++++++++++++ wp-cli.php | 20 +++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/wp b/wp index 5a949ca978..5a73490617 100755 --- a/wp +++ b/wp @@ -10,6 +10,9 @@ # php executable it can find on your system. # +# Set the required PHP version +CHECK_VERSION='5.3.0' + # Get the absolute path of this executable ORIGDIR=$(pwd) SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0") @@ -88,6 +91,19 @@ if [ "x$wp_cli_php_override" != "x" ] ; then php="$php $wp_cli_override_vars" fi +# Get the php version +PHP_VERSION=$($php -r echo\ phpversion\(\)\;) + +# Format version numbers +CURRENT_NUMBER=$(echo "$PHP_VERSION" | tr -d '.') +NEW_NUMBER=$(echo "$CHECK_VERSION" | tr -d '.') + +# Compare version numbers and exit if needed +if [ "$CURRENT_NUMBER" -lt "$NEW_NUMBER" ] ; then + echo "Error: PHP version $CHECK_VERSION is required to run wp-cli. You are running version $PHP_VERSION."; + exit +fi + # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands exec $php "$SCRIPT_PATH" "$@" \ No newline at end of file diff --git a/wp-cli.php b/wp-cli.php index 6f2d434d40..d70853bb37 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -6,17 +6,20 @@ } // Define the WordPress location -define('WP_ROOT', '../'); +define('WP_ROOT', $_SERVER['PWD'] . '/'); + +// Define the wp-cli location +define('WP_CLI_ROOT', __DIR__ . '/'); // Set a constant that can be used to check if we are running wp-cli or not define('WP_CLI', true); // Include the wp-cli classes -include 'class-wp-cli.php'; -include 'class-wp-cli-command.php'; +include WP_CLI_ROOT.'class-wp-cli.php'; +include WP_CLI_ROOT.'class-wp-cli-command.php'; // Include the command line tools, taken from here: https://github.com/jlogsdon/php-cli-tools -include 'php-cli-tools/lib/cli/cli.php'; +include WP_CLI_ROOT.'php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); // Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php @@ -33,17 +36,12 @@ } // Load all internal commands -foreach (glob('commands/internals/*.php') as $filename) { +foreach (glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename) { include $filename; } // Load all plugin commands -foreach (glob('commands/plugins/*.php') as $filename) { - include $filename; -} - -// Load all theme commands -foreach (glob('commands/themes/*.php') as $filename) { +foreach (glob(WP_CLI_ROOT.'/commands/community/*.php') as $filename) { include $filename; } From 17b81c36d6d30ef4d0cea918a7fc2100fa754e9a Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 09:40:34 +0200 Subject: [PATCH 0038/4858] Allow the script to be called from one level deeper in the WordPress tree --- wp-cli.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wp-cli.php b/wp-cli.php index d70853bb37..d3e2e525fe 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -6,7 +6,12 @@ } // Define the WordPress location -define('WP_ROOT', $_SERVER['PWD'] . '/'); +if(is_readable($_SERVER['PWD'] . '/../wp-load.php')) { + define('WP_ROOT', $_SERVER['PWD'] . '/../'); +} +else { + define('WP_ROOT', $_SERVER['PWD'] . '/'); +} // Define the wp-cli location define('WP_CLI_ROOT', __DIR__ . '/'); From b6ad93d2cfa11a49842f538f756c726047d0f7e0 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 15:09:22 +0300 Subject: [PATCH 0039/4858] Edited README.md via GitHub --- README.md | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ce8332476c..0a365ce9a1 100644 --- a/README.md +++ b/README.md @@ -9,26 +9,15 @@ A command line tool to do maintenance work on a WordPress install from the comma Installing ---------- -Installing wp-cli is extremely simple: - -1. Place the `wp-cli` folder in your WordPress root (on the same level as `wp-admin` and `wp-content`). -1. That's it! - -Commands --------- - -- `wp core` - Update the WordPress core -- `wp home` - Open the wp-cli project on Github -- `wp option ...` - Manipulate the WordPress options -- `wp plugin ...` - Do cool things with the installed plugins -- `wp theme ...` - Get details on the installed and current theme +1. Clone the project: `git clone https://github.com/andreascreten/wp-cli.git` +1. Make a symlink to the executable: `ln -s /path-to-wp-cli-dir/wp ~/bin/` Usage ----- -In your terminal, go into the wp-cli folder. +In your terminal, go into the wp root folder. -Typing the following command: `./wp help`, will show you an output similar to this: +Typing the following command: `wp help`, will show you an output similar to this: ``` Example usage: @@ -43,7 +32,7 @@ Example usage: So this tells us which commands are installed: eg. google-sitemap, core, home, ... Between brackets you can see their sub commands. -Let's for example try to install the hello dolly plugin from WordPress: `./wp plugins install hello-dolly`. +Let's for example try to install the hello dolly plugin from WordPress: `wp plugins install hello-dolly`. Output: ``` From 451fb8e0d6366c5d11681ae0b787722c2f221fa7 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 15:14:19 +0300 Subject: [PATCH 0040/4858] more readme modifications --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0a365ce9a1..f65fe95880 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Installing Usage ----- -In your terminal, go into the wp root folder. +In your terminal, go into the WordPress root folder. Typing the following command: `wp help`, will show you an output similar to this: @@ -32,7 +32,8 @@ Example usage: So this tells us which commands are installed: eg. google-sitemap, core, home, ... Between brackets you can see their sub commands. -Let's for example try to install the hello dolly plugin from WordPress: `wp plugins install hello-dolly`. +Let's for example try to install the hello dolly plugin from wordpress.org: `wp plugin install hello-dolly`. + Output: ``` @@ -115,7 +116,7 @@ Contributors ------------ - Andreas Creten ([@andreascreten](http://twitter.com/andreascreten)) -- Silviu-Cristian Burcă ([@scribu](http://twitter.com/scribu)) +- Cristi Burcă ([@scribu](http://twitter.com/scribu)) Requirements ------------ From a353401f8de6bf7a29f61163d6ace9c0c75b00e3 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 15:35:06 +0300 Subject: [PATCH 0041/4858] add command descriptions to generalHelp() --- class-wp-cli.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/class-wp-cli.php b/class-wp-cli.php index 5ba54be8d6..6362b1d555 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -108,6 +108,30 @@ static function generalHelp() { } self::line(' ...'); } + + self::block( << help' for more information on a specific command. +EOB + ); + } + + /** + * Display multiple lines of content + * + * @param string $content + * @return void + */ + function block( $content ) { + foreach ( explode( "\n", $content ) as $line ) + self::line( $line ); } /** From 4ec29dab989bec7f74e148307a137f474f7a8ec5 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 15:37:07 +0300 Subject: [PATCH 0042/4858] use /usr/local/bin/ instead of ~/bin --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f65fe95880..80f2bfec92 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Installing ---------- 1. Clone the project: `git clone https://github.com/andreascreten/wp-cli.git` -1. Make a symlink to the executable: `ln -s /path-to-wp-cli-dir/wp ~/bin/` +1. Make a symlink to the executable: `sudo ln -s /path-to-wp-cli-dir/wp /usr/local/bin/` Usage ----- From 368f28131039b7f5d2d3e6359f9a2fb07f70e316 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 15:23:10 +0200 Subject: [PATCH 0043/4858] Removed todo's from readme --- README.md | 8 -------- wp-cli.php | 18 +++++++++--------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 80f2bfec92..85ac2a962d 100644 --- a/README.md +++ b/README.md @@ -104,14 +104,6 @@ if(defined('WP_CLI') && WP_CLI) { **Please share the commands you make, issue a pull request to get them included in wp-cli by default.** -Todo ----- - -Commands to be written: - -- User management -- Post management (not sure yet if we really need this) - Contributors ------------ diff --git a/wp-cli.php b/wp-cli.php index d3e2e525fe..24e4e71e14 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -7,10 +7,10 @@ // Define the WordPress location if(is_readable($_SERVER['PWD'] . '/../wp-load.php')) { - define('WP_ROOT', $_SERVER['PWD'] . '/../'); + define('WP_ROOT', $_SERVER['PWD'] . '/../'); } else { - define('WP_ROOT', $_SERVER['PWD'] . '/'); + define('WP_ROOT', $_SERVER['PWD'] . '/'); } // Define the wp-cli location @@ -30,24 +30,24 @@ // Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php // Does the user have access to read the directory? If so, allow them to use the command line tool. if(true == is_readable(WP_ROOT . 'wp-load.php')){ - // Load WordPress libs. - require_once(WP_ROOT . 'wp-load.php'); - require_once(ABSPATH . WPINC . '/template-loader.php'); - require_once(ABSPATH . 'wp-admin/includes/admin.php'); + // Load WordPress libs. + require_once(WP_ROOT . 'wp-load.php'); + require_once(ABSPATH . WPINC . '/template-loader.php'); + require_once(ABSPATH . 'wp-admin/includes/admin.php'); } else { WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); - exit(); + exit(); } // Load all internal commands foreach (glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename) { - include $filename; + include $filename; } // Load all plugin commands foreach (glob(WP_CLI_ROOT.'/commands/community/*.php') as $filename) { - include $filename; + include $filename; } // Get the cli arguments From 3f75fded92b59cfbf6d4cc511b8ecd7fea92f8d5 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Sep 2011 18:46:45 +0300 Subject: [PATCH 0044/4858] more robust PHP version handling --- wp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wp b/wp index 5a73490617..91c73f6d4d 100755 --- a/wp +++ b/wp @@ -92,7 +92,9 @@ if [ "x$wp_cli_php_override" != "x" ] ; then fi # Get the php version -PHP_VERSION=$($php -r echo\ phpversion\(\)\;) +PHP_VERSION=$($php -r 'echo phpversion();') +# Keep only major version number +PHP_VERSION=${PHP_VERSION%%-*} # Format version numbers CURRENT_NUMBER=$(echo "$PHP_VERSION" | tr -d '.') @@ -106,4 +108,4 @@ fi # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands -exec $php "$SCRIPT_PATH" "$@" \ No newline at end of file +exec $php "$SCRIPT_PATH" "$@" From 0323047dd34b02f9fbbe3d10ba159d4e65d84dff Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 29 Sep 2011 19:05:10 +0200 Subject: [PATCH 0045/4858] Basic code completion (related to #6) --- wp-cli-completion.bash | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 wp-cli-completion.bash diff --git a/wp-cli-completion.bash b/wp-cli-completion.bash new file mode 100644 index 0000000000..54e522acb7 --- /dev/null +++ b/wp-cli-completion.bash @@ -0,0 +1,15 @@ +# Very basic code completion +# +# Code taken from here: http://www.debian-administration.org/article/317/An_introduction_to_bash_completion_part_2 +_wp() +{ + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + opts="core plugin option theme home help" + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 +} +complete -F _wp wp \ No newline at end of file From 468d6a0f78a428cf6293f9b5ee24feec97f1b4a7 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 05:31:31 +0300 Subject: [PATCH 0046/4858] use out() instead of block() --- class-wp-cli.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 6362b1d555..355867cd02 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -109,7 +109,7 @@ static function generalHelp() { self::line(' ...'); } - self::block( << help' for more information on a specific command. + EOB ); } - /** - * Display multiple lines of content - * - * @param string $content - * @return void - */ - function block( $content ) { - foreach ( explode( "\n", $content ) as $line ) - self::line( $line ); - } - /** * Display a legend * From f6abf48a7b422b84da8944762912833e1fce1b80 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 05:43:32 +0300 Subject: [PATCH 0047/4858] check if there are any commands before doing anything with the args --- wp-cli.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/wp-cli.php b/wp-cli.php index 24e4e71e14..75955e333f 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -50,6 +50,14 @@ include $filename; } +// Check if there are commands installed +if(empty(WP_CLI::$commands)) { + WP_CLI::error('No commands installed'); + WP_CLI::line(); + WP_CLI::line('Visit the wp-cli page on github on more information on how to install commands.'); + exit(); +} + // Get the cli arguments $arguments = $GLOBALS['argv']; @@ -59,18 +67,11 @@ // Get the command $command = array_shift($arguments); -// Check if there are commands installed -if(empty(WP_CLI::$commands)) { - WP_CLI::error('No commands installed'); - WP_CLI::line(); - WP_CLI::line('Visit the wp-cli page on github on more information on how to install commands.'); - exit(); -} // Try to load the class, otherwise it's an Unknown command -elseif(isset(WP_CLI::$commands[$command])) { +if(isset(WP_CLI::$commands[$command])) { new WP_CLI::$commands[$command]($arguments); } // Show the general help for wp-cli else { WP_CLI::generalHelp(); -} \ No newline at end of file +} From 859ca444f4f9cc814e62062216b6e6cf5a357eca Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 06:32:49 +0300 Subject: [PATCH 0048/4858] introduce WP_CLI::parse_args() --- class-wp-cli.php | 22 ++++++++++++++++++++++ wp-cli.php | 34 +++++++++++++++------------------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 355867cd02..6c9accd2ed 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -93,6 +93,28 @@ static function errorToString($errors) { } } + /** + * Splits regular arguments from associative arguments. + * + * @return array + */ + static function parse_args( $arguments ) { + $global_arg_names = array( 'blog' ); + + $regular_args = array(); + $assoc_args = array(); + + foreach ( $arguments as $arg ) { + if ( preg_match( '/^--(\w+)=(\w+)/', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = $matches[2]; + } else { + $regular_args[] = $arg; + } + } + + return array( $regular_args, $assoc_args ); + } + /** * Display the help function for the wp-cli * diff --git a/wp-cli.php b/wp-cli.php index 75955e333f..9e68630400 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -28,18 +28,16 @@ \cli\register_autoload(); // Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php -// Does the user have access to read the directory? If so, allow them to use the command line tool. -if(true == is_readable(WP_ROOT . 'wp-load.php')){ - // Load WordPress libs. - require_once(WP_ROOT . 'wp-load.php'); - require_once(ABSPATH . WPINC . '/template-loader.php'); - require_once(ABSPATH . 'wp-admin/includes/admin.php'); -} -else { +if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); exit(); } +// Load WordPress libs. +require_once(WP_ROOT . 'wp-load.php'); +require_once(ABSPATH . WPINC . '/template-loader.php'); +require_once(ABSPATH . 'wp-admin/includes/admin.php'); + // Load all internal commands foreach (glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename) { include $filename; @@ -59,19 +57,17 @@ } // Get the cli arguments -$arguments = $GLOBALS['argv']; +$arguments = array_slice( $GLOBALS['argv'], 1 ); -// Remove the first entry -array_shift($arguments); +list( $arguments, $assoc_args ) = WP_CLI::parse_args( $arguments ); -// Get the command -$command = array_shift($arguments); +// Get the top-level command +$command = array_shift( $arguments ); -// Try to load the class, otherwise it's an Unknown command -if(isset(WP_CLI::$commands[$command])) { - new WP_CLI::$commands[$command]($arguments); -} -// Show the general help for wp-cli -else { +if ( !isset( WP_CLI::$commands[$command] ) ) { WP_CLI::generalHelp(); + exit(); } + +new WP_CLI::$commands[$command]( $arguments, $assoc_args ); + From 4d700f9bf16f993dab0b54da9763a207ee0bbec9 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 07:15:23 +0300 Subject: [PATCH 0049/4858] handle --blog parameter --- class-wp-cli.php | 2 +- wp-cli.php | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 6c9accd2ed..765636ba14 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -105,7 +105,7 @@ static function parse_args( $arguments ) { $assoc_args = array(); foreach ( $arguments as $arg ) { - if ( preg_match( '/^--(\w+)=(\w+)/', $arg, $matches ) ) { + if ( preg_match( '|^--(\w+)=(.+)|', $arg, $matches ) ) { $assoc_args[ $matches[1] ] = $matches[2]; } else { $regular_args[] = $arg; diff --git a/wp-cli.php b/wp-cli.php index 9e68630400..dfff9bb00e 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -33,7 +33,21 @@ exit(); } -// Load WordPress libs. +// Get the cli arguments +list( $arguments, $assoc_args ) = WP_CLI::parse_args( array_slice( $GLOBALS['argv'], 1 ) ); + +// Handle --blog parameter +if ( isset( $assoc_args['blog'] ) ) { + list( $domain, $path ) = explode( '/', $assoc_args['blog'], 2 ); + + unset( $assoc_args['blog'] ); + + $_SERVER['HTTP_HOST'] = $domain; + + $_SERVER['REQUEST_URI'] = '/' . $path; +} + +// Load WordPress libs require_once(WP_ROOT . 'wp-load.php'); require_once(ABSPATH . WPINC . '/template-loader.php'); require_once(ABSPATH . 'wp-admin/includes/admin.php'); @@ -56,11 +70,6 @@ exit(); } -// Get the cli arguments -$arguments = array_slice( $GLOBALS['argv'], 1 ); - -list( $arguments, $assoc_args ) = WP_CLI::parse_args( $arguments ); - // Get the top-level command $command = array_shift( $arguments ); From 720aa412db23c121c0c285af945c600b7fd496ef Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 07:27:38 +0300 Subject: [PATCH 0050/4858] don't include template-loader.php; it's not needed --- wp-cli.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wp-cli.php b/wp-cli.php index dfff9bb00e..2d833b0b31 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -49,7 +49,6 @@ // Load WordPress libs require_once(WP_ROOT . 'wp-load.php'); -require_once(ABSPATH . WPINC . '/template-loader.php'); require_once(ABSPATH . 'wp-admin/includes/admin.php'); // Load all internal commands From 441ae704dc50a19675c99eb68228bc072a6d0596 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 17:22:31 +0300 Subject: [PATCH 0051/4858] look for a wp-cli-blog file when --blog is not set --- wp-cli.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/wp-cli.php b/wp-cli.php index 2d833b0b31..71dd9de363 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -38,9 +38,14 @@ // Handle --blog parameter if ( isset( $assoc_args['blog'] ) ) { - list( $domain, $path ) = explode( '/', $assoc_args['blog'], 2 ); - + $blog = $assoc_args['blog']; unset( $assoc_args['blog'] ); +} elseif ( is_readable( WP_ROOT . '/wp-cli-blog' ) ) { + $blog = file_get_contents( WP_ROOT . '/wp-cli-blog' ); +} + +if ( isset( $blog ) ) { + list( $domain, $path ) = explode( '/', $blog, 2 ); $_SERVER['HTTP_HOST'] = $domain; From 0760b36679b435aa5d7803f19886443e6cc0f848 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 17:29:36 +0300 Subject: [PATCH 0052/4858] add multisite section to readme --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 85ac2a962d..50c4eec9ce 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,33 @@ Installing the plugin ... Success: The plugin is successfully installed ``` +Multisite +--------- + +On a multisite installation, you need to pass a --blog parameter, so that WP knows which site it's supposed to be operating on: + +``` +wp theme status --blog=localhost/wp/test +``` + +If you have a subdomain installation, it would look like this: + +``` +wp theme status --blog=test.example.com +``` + +If you're usually working on the same site most of the time, you can put the url of that site in a file called 'wp-cli-blog' in your root WP dir: + +``` +echo 'test.example.com' > wp-cli-blog +``` + +Then, you can call `wp` without the --blog parameter again: + +``` +wp theme status +``` + Adding commands --------------- From 287a5ada50f5575ed3f231e5e1c91fcb4b16e801 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 22:06:28 +0300 Subject: [PATCH 0053/4858] pass assoc args to sub-command handlers --- class-wp-cli-command.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index cbf7c225ec..d29f688ad5 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -12,41 +12,41 @@ abstract class WP_CLI_Command { * * @param Array $args */ - function __construct($args = array()) { + function __construct( $args, $assoc_args ) { // The first command is the sub command $sub_command = array_shift($args); - + // If the method exists, try to load it if(method_exists($this, $sub_command)) { - $this->$sub_command($args); + $this->$sub_command($args, $assoc_args); } // If a dummy method exists, use it. This if for reserved keywords in php (like list, isset) elseif(method_exists($this, '_'.$sub_command)) { $sub_command = '_'.$sub_command; - $this->$sub_command($args); + $this->$sub_command($args, $assoc_args); } // Otherwise, show the help for this command else { $this->help($args); } } - + /** * General help function for this command * - * @param Array $args + * @param Array $args * @return void */ public function help($args = array()) { // Get the cli arguments $arguments = $GLOBALS['argv']; - + // Remove the first entry array_shift($arguments); // Get the command $used_command = array_shift($arguments); - + // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); WP_CLI::out(' wp '.$used_command); @@ -56,12 +56,12 @@ public function help($args = array()) { } WP_CLI::line(' ...'); WP_CLI::line(); - + // Send a warning to the user because there is no custom help function defined in the command // Make usure there always is a help method in your command class WP_CLI::warning('The command has no dedicated help function, ask the creator to fix it.'); } - + /** * Get the filtered list of methods for a class * @@ -71,10 +71,10 @@ public function help($args = array()) { static function getMethods($class) { // Methods that don't need to be included in the method list $blacklist = array('__construct', 'getMethods'); - + // Get all the methods of the class $methods = get_class_methods($class); - + // Remove the blacklisted methods foreach($blacklist as $method) { $in_array = array_search($method, $methods); @@ -82,15 +82,15 @@ static function getMethods($class) { unset($methods[$in_array]); } } - + // Fix dummy function names foreach($methods as $key => $method) { if(strpos($method, '_') === 0) { $methods[$key] = substr($method, 1, strlen($method)); } } - + // Only return the values, to fill up the gaps return array_values($methods); } -} \ No newline at end of file +} From 1951deeb73466b64a735fac91ba1956079c0e5da Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 22:37:46 +0300 Subject: [PATCH 0054/4858] don't use raw argv global in WP_CLI_Command::help() --- class-wp-cli-command.php | 26 +++++++++----------------- wp-cli.php | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index d29f688ad5..be5fa5f6e8 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -7,12 +7,13 @@ * @author Andreas Creten */ abstract class WP_CLI_Command { + /** * Construct for this class, transfers the cli arguments to the right class * * @param Array $args */ - function __construct( $args, $assoc_args ) { + function __construct( $command, $args, $assoc_args ) { // The first command is the sub command $sub_command = array_shift($args); @@ -27,29 +28,22 @@ function __construct( $args, $assoc_args ) { } // Otherwise, show the help for this command else { - $this->help($args); + $this->help($command, $sub_command); } } /** * General help function for this command * - * @param Array $args + * @param string $command + * @param string $sub_command * @return void */ - public function help($args = array()) { - // Get the cli arguments - $arguments = $GLOBALS['argv']; - - // Remove the first entry - array_shift($arguments); - - // Get the command - $used_command = array_shift($arguments); - + public function help( $command, $sub_command = false ) { // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - WP_CLI::out(' wp '.$used_command); + WP_CLI::out(' wp '.$command); + $methods = WP_CLI_Command::getMethods($this); if(!empty($methods)) { WP_CLI::out(' ['.implode('|', $methods).']'); @@ -57,9 +51,7 @@ public function help($args = array()) { WP_CLI::line(' ...'); WP_CLI::line(); - // Send a warning to the user because there is no custom help function defined in the command - // Make usure there always is a help method in your command class - WP_CLI::warning('The command has no dedicated help function, ask the creator to fix it.'); + WP_CLI::warning('The command has no dedicated help function; ask the creator to fix it.'); } /** diff --git a/wp-cli.php b/wp-cli.php index 71dd9de363..7789d561e9 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -82,5 +82,5 @@ exit(); } -new WP_CLI::$commands[$command]( $arguments, $assoc_args ); +new WP_CLI::$commands[$command]( $command, $arguments, $assoc_args ); From 61c9991348a4f84cdb10cb1831ff89ab3be15b3e Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 22:42:39 +0300 Subject: [PATCH 0055/4858] add generate command --- commands/internals/generate.php | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 commands/internals/generate.php diff --git a/commands/internals/generate.php b/commands/internals/generate.php new file mode 100644 index 0000000000..09a7cc1efe --- /dev/null +++ b/commands/internals/generate.php @@ -0,0 +1,52 @@ + 100, + 'type' => 'post', + 'status' => 'publish' + ); + + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + if ( !post_type_exists( $type ) ) { + WP_CLI::warning( "Invalid post type: $type" ); + exit; + } + + // Get the total number of posts + $total = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = %s", $type ) ); + + $label = get_post_type_object( $type )->labels->singular_name; + + $limit = $count + $total; + + for ( $i = $count; $i < $limit; $i++ ) { + wp_insert_post( array( + 'post_type' => $type, + 'post_title' => "$label $i", + 'post_status' => $status + ) ); + } + } +} From 1a442c868d1dd3ba721bb0c59414d565fb657815 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 2 Oct 2011 22:50:24 +0300 Subject: [PATCH 0056/4858] start at $total not at $count --- commands/internals/generate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 09a7cc1efe..28554a594f 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -41,7 +41,7 @@ public function posts( $args, $assoc_args ) { $limit = $count + $total; - for ( $i = $count; $i < $limit; $i++ ) { + for ( $i = $total; $i < $limit; $i++ ) { wp_insert_post( array( 'post_type' => $type, 'post_title' => "$label $i", From b50f3fa8f923c0b4fd7799ddd8f8e28a0535ddb4 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 00:38:32 +0300 Subject: [PATCH 0057/4858] formatting in bash completion --- wp-cli-completion.bash | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/wp-cli-completion.bash b/wp-cli-completion.bash index 54e522acb7..ed3a37ce9a 100644 --- a/wp-cli-completion.bash +++ b/wp-cli-completion.bash @@ -1,15 +1,14 @@ # Very basic code completion # # Code taken from here: http://www.debian-administration.org/article/317/An_introduction_to_bash_completion_part_2 -_wp() -{ - local cur prev opts - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="core plugin option theme home help" - - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 +_wp() { + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + opts="core plugin option theme home help" + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 } -complete -F _wp wp \ No newline at end of file +complete -F _wp wp From fb0ec6a44f7d7c0567de7a93f3e3e170ae0665ac Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 00:50:34 +0300 Subject: [PATCH 0058/4858] forgot that the help method could be called explicitly --- class-wp-cli-command.php | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index be5fa5f6e8..ca8b915664 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -8,28 +8,34 @@ */ abstract class WP_CLI_Command { + /** + * Keeps a reference to the current command name + * + * @param string + */ + protected $command; + /** * Construct for this class, transfers the cli arguments to the right class * * @param Array $args */ function __construct( $command, $args, $assoc_args ) { + $this->command = $command; + // The first command is the sub command $sub_command = array_shift($args); - // If the method exists, try to load it - if(method_exists($this, $sub_command)) { - $this->$sub_command($args, $assoc_args); - } - // If a dummy method exists, use it. This if for reserved keywords in php (like list, isset) - elseif(method_exists($this, '_'.$sub_command)) { - $sub_command = '_'.$sub_command; - $this->$sub_command($args, $assoc_args); - } - // Otherwise, show the help for this command - else { - $this->help($command, $sub_command); - } + if ( !method_exists($this, $sub_command) ) { + // This if for reserved keywords in php (like list, isset) + $sub_command = '_'.$sub_command; + } + + if ( !method_exists($this, $sub_command) ) { + $sub_command = 'help'; + } + + $this->$sub_command($args, $assoc_args); } /** @@ -39,10 +45,10 @@ function __construct( $command, $args, $assoc_args ) { * @param string $sub_command * @return void */ - public function help( $command, $sub_command = false ) { + public function help( $args, $assoc_args ) { // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - WP_CLI::out(' wp '.$command); + WP_CLI::out(' wp '.$this->command); $methods = WP_CLI_Command::getMethods($this); if(!empty($methods)) { From a27dd0e8c40a1292b9554533c2ed8723e6126bb4 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 01:23:59 +0300 Subject: [PATCH 0059/4858] introduce mandatory get_description() method to WP_CLI_Command class --- class-wp-cli-command.php | 53 +++++++++++++++++---------------- class-wp-cli.php | 14 +-------- commands/community/example.php | 31 +++++++++++-------- commands/internals/core.php | 15 ++++++---- commands/internals/generate.php | 4 +++ commands/internals/home.php | 17 +++++++---- commands/internals/option.php | 25 +++++++++------- commands/internals/plugin.php | 5 ++++ commands/internals/theme.php | 5 ++++ 9 files changed, 97 insertions(+), 72 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index ca8b915664..0095ebecab 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -8,6 +8,13 @@ */ abstract class WP_CLI_Command { + /** + * Return a short description for the command. + * + * @return string + */ + abstract public static function get_description(); + /** * Keeps a reference to the current command name * @@ -41,11 +48,15 @@ function __construct( $command, $args, $assoc_args ) { /** * General help function for this command * - * @param string $command - * @param string $sub_command + * @param string $args + * @param string $assoc_args * @return void */ - public function help( $args, $assoc_args ) { + public function help( $args = array(), $assoc_args = array() ) { + // Shot the command description + WP_CLI::line( $this->get_description() ); + WP_CLI::line(); + // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); WP_CLI::out(' wp '.$this->command); @@ -56,8 +67,6 @@ public function help( $args, $assoc_args ) { } WP_CLI::line(' ...'); WP_CLI::line(); - - WP_CLI::warning('The command has no dedicated help function; ask the creator to fix it.'); } /** @@ -67,28 +76,22 @@ public function help( $args, $assoc_args ) { * @return Array The list of methods */ static function getMethods($class) { - // Methods that don't need to be included in the method list - $blacklist = array('__construct', 'getMethods'); - - // Get all the methods of the class - $methods = get_class_methods($class); - - // Remove the blacklisted methods - foreach($blacklist as $method) { - $in_array = array_search($method, $methods); - if($in_array !== false) { - unset($methods[$in_array]); - } - } + $reflection = new ReflectionClass( $class ); + + $methods = array(); + + foreach ( $reflection->getMethods() as $method ) { + if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() ) { + $name = $method->name; + + if ( strpos($name, '_') === 0 ) { + $name = substr( $method, 1 ); + } - // Fix dummy function names - foreach($methods as $key => $method) { - if(strpos($method, '_') === 0) { - $methods[$key] = substr($method, 1, strlen($method)); - } + $methods[] = $name; + } } - // Only return the values, to fill up the gaps - return array_values($methods); + return $methods; } } diff --git a/class-wp-cli.php b/class-wp-cli.php index 765636ba14..5037f8ba0c 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -131,19 +131,7 @@ static function generalHelp() { self::line(' ...'); } - self::out( << help' for more information on a specific command. - -EOB - ); + self::line( "See 'wp help' for more information on a specific command." ); } /** diff --git a/commands/community/example.php b/commands/community/example.php index 8105888534..f4bfa44cad 100644 --- a/commands/community/example.php +++ b/commands/community/example.php @@ -11,59 +11,64 @@ * @author Andreas Creten */ class ExampleCommand extends WP_CLI_Command { + + public static function get_description() { + return 'An example command.'; + } + /** * Example method * - * @param string $args + * @param string $args * @return void */ function example($args = array()) { // Print a string WP_CLI::out('Prints a string -- '); - + // Print a second string WP_CLI::out('Prints a second string -- '); - + // Print a single line WP_CLI::line('Prints out a line'); - + // Run through the commands foreach ($args as $arg) { WP_CLI::line($arg); } - + // Print an error message WP_CLI::error('Error message'); // Result: Error: Error message - + // Print a warning message WP_CLI::warning('Warning message'); // Result: Warning: Warning message - + // Print a success message WP_CLI::success('Success message'); // Result: Success: Success message } - + /** * Help function for this command * - * @param string $args + * @param string $args * @return void */ public function help($args = array()) { // Get the cli arguments $arguments = $GLOBALS['argv']; - + // Remove the first entry array_shift($arguments); // Get the command $used_command = array_shift($arguments); - + // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - + $methods = WP_CLI_Command::getMethods($this); foreach ($methods as $method) { if($method != 'help') { @@ -74,4 +79,4 @@ public function help($args = array()) { } } } -} \ No newline at end of file +} diff --git a/commands/internals/core.php b/commands/internals/core.php index 6b17113b1c..62cd85d10e 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -11,15 +11,20 @@ * @author Andreas Creten */ class CoreCommand extends WP_CLI_Command { + + public static function get_description() { + return 'Update the WordPress core.'; + } + /** * Update the WordPress core * - * @param string $args + * @param string $args * @return void */ function update($args) { WP_CLI::line('Updating the WordPress core.'); - + if(!class_exists('Core_Upgrader')) { require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); } @@ -27,7 +32,7 @@ function update($args) { $upgrader = new Core_Upgrader(new CLI_Upgrader_Skin); $result = $upgrader->upgrade($current); $feedback = ob_get_clean(); - + // Borrowed verbatim from wp-admin/update-core.php if(is_wp_error($result) ) { if('up_to_date' != $result->get_error_code()) { @@ -36,9 +41,9 @@ function update($args) { else { WP_CLI::success(WP_CLI::errorToString($result)); } - } + } else { WP_CLI::success('WordPress upgraded successfully.'); } } -} \ No newline at end of file +} diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 28554a594f..a3d12bedfc 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -12,6 +12,10 @@ */ class GenerateCommand extends WP_CLI_Command { + public static function get_description() { + return 'Generate a certain number of objects.'; + } + /** * Generate posts * diff --git a/commands/internals/home.php b/commands/internals/home.php index 13c20f1e32..2636f78ec9 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -11,16 +11,21 @@ * @author Andreas Creten */ class HomeCommand extends WP_CLI_Command { + + public static function get_description() { + return 'Open the wp-cli project on Github.'; + } + /** * Overwrite the construct to have a command without subcommand * - * @param string $args + * @param string $args */ function __construct($args) { if(empty($args)) { // The url for the wp-cli repository $repository_url = 'http://github.com/andreascreten/wp-cli'; - + // Open the wp-cli page in the browser if(exec('which x-www-browser')) { system('x-www-browser '.$repository_url); @@ -32,7 +37,7 @@ function __construct($args) { WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: '.$repository_url); return; } - + WP_CLI::success('The wp-cli homepage should be opening in your browser.'); } else { @@ -40,11 +45,11 @@ function __construct($args) { parent::__construct($args); } } - + /** * Help function for this command * - * @param string $args + * @param string $args * @return void */ public function help($args = array()) { @@ -53,4 +58,4 @@ public function help($args = array()) { WP_CLI::line('Example usage:'); WP_CLI::line(' wp home'); } -} \ No newline at end of file +} diff --git a/commands/internals/option.php b/commands/internals/option.php index 1281b181f6..388aa3b75c 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -11,10 +11,15 @@ * @author Andreas Creten */ class OptionCommand extends WP_CLI_Command { + + public static function get_description() { + return 'Manipulate the WordPress options.'; + } + /** * Add an option * - * @param string $args + * @param string $args * @return void **/ public function add($args = array()) { @@ -32,11 +37,11 @@ public function add($args = array()) { WP_CLI::error('This command needs exactly two arguments.'); } } - + /** * Update an option * - * @param string $args + * @param string $args * @return void **/ public function update($args = array()) { @@ -54,11 +59,11 @@ public function update($args = array()) { WP_CLI::error('This command needs exactly two arguments.'); } } - + /** * Delete an option * - * @param string $args + * @param string $args * @return void **/ public function delete($args = array()) { @@ -76,11 +81,11 @@ public function delete($args = array()) { WP_CLI::error('This command needs exactly one argument.'); } } - + /** * Get an option * - * @param string $args + * @param string $args * @return void **/ public function get($args = array()) { @@ -99,11 +104,11 @@ public function get($args = array()) { WP_CLI::error('This command needs exactly one argument.'); } } - + /** * Help function for this command * - * @param string $args + * @param string $args * @return void */ public function help($args = array()) { @@ -127,4 +132,4 @@ public function help($args = array()) { WP_CLI::line('Get the value of an option:'); WP_CLI::line(' wp option get '); } -} \ No newline at end of file +} diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 962d113594..28c5204cab 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -15,6 +15,11 @@ * @author Andreas Creten */ class PluginCommand extends WP_CLI_Command { + + public static function get_description() { + return 'Do cool things with plugins.'; + } + /** * Get the status of one plugin * diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 383b0dd85b..04364dbef6 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -11,6 +11,11 @@ * @author Andreas Creten */ class ThemeCommand extends WP_CLI_Command { + + public static function get_description() { + return 'Do cool things with themes.'; + } + /** * Get the status of all themes * From 43560c51e6eeef6c9ddd7b2f5d83dc8973a96ffd Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 01:33:16 +0300 Subject: [PATCH 0060/4858] rename getMethods() to get_methods() --- class-wp-cli-command.php | 12 ++++++------ class-wp-cli.php | 4 +--- commands/community/example.php | 2 +- commands/internals/plugin.php | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 0095ebecab..a76a4d4b11 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -25,7 +25,7 @@ abstract public static function get_description(); /** * Construct for this class, transfers the cli arguments to the right class * - * @param Array $args + * @param array $args */ function __construct( $command, $args, $assoc_args ) { $this->command = $command; @@ -61,7 +61,7 @@ public function help( $args = array(), $assoc_args = array() ) { WP_CLI::line('Example usage:'); WP_CLI::out(' wp '.$this->command); - $methods = WP_CLI_Command::getMethods($this); + $methods = WP_CLI_Command::get_methods($this); if(!empty($methods)) { WP_CLI::out(' ['.implode('|', $methods).']'); } @@ -70,12 +70,12 @@ public function help( $args = array(), $assoc_args = array() ) { } /** - * Get the filtered list of methods for a class + * Get the filtered list of methods for a class. * * @param string $class - * @return Array The list of methods + * @return array The list of methods */ - static function getMethods($class) { + static function get_methods($class) { $reflection = new ReflectionClass( $class ); $methods = array(); @@ -84,7 +84,7 @@ static function getMethods($class) { if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() ) { $name = $method->name; - if ( strpos($name, '_') === 0 ) { + if ( strpos( $name, '_' ) === 0 ) { $name = substr( $method, 1 ); } diff --git a/class-wp-cli.php b/class-wp-cli.php index 5037f8ba0c..0af7061c6b 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -124,14 +124,12 @@ static function generalHelp() { self::line('Example usage:'); foreach(self::$commands as $name => $command) { self::out(' wp '.$name); - $methods = WP_CLI_Command::getMethods($command); + $methods = WP_CLI_Command::get_methods($command); if(!empty($methods)) { self::out(' ['.implode('|', $methods).']'); } self::line(' ...'); } - - self::line( "See 'wp help' for more information on a specific command." ); } /** diff --git a/commands/community/example.php b/commands/community/example.php index f4bfa44cad..655709a0a9 100644 --- a/commands/community/example.php +++ b/commands/community/example.php @@ -69,7 +69,7 @@ public function help($args = array()) { // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - $methods = WP_CLI_Command::getMethods($this); + $methods = WP_CLI_Command::get_methods($this); foreach ($methods as $method) { if($method != 'help') { WP_CLI::line(' wp '.$used_command.' '.$method.' '); diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 28c5204cab..7f1a12848a 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -352,7 +352,7 @@ public function help($args = array()) { // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - $methods = WP_CLI_Command::getMethods($this); + $methods = WP_CLI_Command::get_methods($this); foreach ($methods as $method) { if($method != 'help') { WP_CLI::line(' wp '.$used_command.' '.$method.' hello-dolly'); From 4107bed87af03f13d13ccdf8bd4ec1369dec0e3b Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 01:44:46 +0300 Subject: [PATCH 0061/4858] move most of constructor into a dispatch() method --- class-wp-cli-command.php | 12 ++++++++++++ commands/internals/home.php | 15 ++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index a76a4d4b11..602ce6643c 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -25,11 +25,23 @@ abstract public static function get_description(); /** * Construct for this class, transfers the cli arguments to the right class * + * @param string $command * @param array $args + * @param array $assoc_args */ function __construct( $command, $args, $assoc_args ) { $this->command = $command; + $this->dispatch( $args, $assoc_args ); + } + + /** + * Transfers the handling to the appropriate method + * + * @param array $args + * @param array $assoc_args + */ + protected function dispatch( $args, $assoc_args ) { // The first command is the sub command $sub_command = array_shift($args); diff --git a/commands/internals/home.php b/commands/internals/home.php index 2636f78ec9..d70cf29756 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -17,11 +17,12 @@ public static function get_description() { } /** - * Overwrite the construct to have a command without subcommand - * - * @param string $args + * Overwrite the dispatch method to have a command without sub-commands. + * + * @param array $args + * @param array $assoc_args */ - function __construct($args) { + protected function dispatch( $args, $assoc_args ) { if(empty($args)) { // The url for the wp-cli repository $repository_url = 'http://github.com/andreascreten/wp-cli'; @@ -42,18 +43,18 @@ function __construct($args) { } else { // Call the parent constructor - parent::__construct($args); + parent::dispatch( $args, $assoc_args ); } } /** - * Help function for this command + * Help function for this command. * * @param string $args * @return void */ public function help($args = array()) { - WP_CLI::line('This command has no arguments, when called it will open the wp-cli homepage in your browser.'); + WP_CLI::line('This command has no arguments; when called it will open the wp-cli homepage in your browser.'); WP_CLI::line(); WP_CLI::line('Example usage:'); WP_CLI::line(' wp home'); From 0c0222a60074d43123ba74aadcdc000e05309dfb Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 01:51:37 +0300 Subject: [PATCH 0062/4858] update plugin help method --- class-wp-cli-command.php | 2 +- commands/internals/plugin.php | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 602ce6643c..bb9db4c55c 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -67,7 +67,7 @@ protected function dispatch( $args, $assoc_args ) { public function help( $args = array(), $assoc_args = array() ) { // Shot the command description WP_CLI::line( $this->get_description() ); - WP_CLI::line(); + WP_CLI::line(); // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 7f1a12848a..ff10e1de0d 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -340,25 +340,19 @@ private function check_name($args, $exit = true) { * @return void */ public function help($args = array()) { - // Get the cli arguments - $arguments = $GLOBALS['argv']; - - // Remove the first entry - array_shift($arguments); - - // Get the command - $used_command = array_shift($arguments); + // Shot the command description + WP_CLI::line( $this->get_description() ); + WP_CLI::line(); // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - $methods = WP_CLI_Command::get_methods($this); - foreach ($methods as $method) { + foreach (WP_CLI_Command::get_methods($this) as $method) { if($method != 'help') { - WP_CLI::line(' wp '.$used_command.' '.$method.' hello-dolly'); + WP_CLI::line(' wp '.$this->command.' '.$method.' hello-dolly'); } else { - WP_CLI::line(' wp '.$used_command.' '.$method); + WP_CLI::line(' wp '.$this->command.' '.$method); } } } From fd0a37b45324d2bd0f17b3c749f735337edd1841 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 01:56:48 +0300 Subject: [PATCH 0063/4858] make get_description() method optional --- README.md | 1 - class-wp-cli-command.php | 18 +++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 50c4eec9ce..1d83505b84 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,6 @@ class ExampleCommand extends WP_CLI_Command { * * @param string $args * @return void - * @author Andreas Creten */ function example($args = array()) { // Print a success message diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index bb9db4c55c..83ce288fce 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -13,7 +13,9 @@ abstract class WP_CLI_Command { * * @return string */ - abstract public static function get_description(); + public static function get_description() { + return false; + } /** * Keeps a reference to the current command name @@ -65,16 +67,18 @@ protected function dispatch( $args, $assoc_args ) { * @return void */ public function help( $args = array(), $assoc_args = array() ) { - // Shot the command description - WP_CLI::line( $this->get_description() ); - WP_CLI::line(); + $desc = $this->get_description(); + if ( $desc ) { + WP_CLI::line( $desc ); + WP_CLI::line(); + } // Show the list of sub-commands for this command - WP_CLI::line('Example usage:'); - WP_CLI::out(' wp '.$this->command); + WP_CLI::line( 'Example usage:' ); + WP_CLI::out( ' wp '.$this->command ); $methods = WP_CLI_Command::get_methods($this); - if(!empty($methods)) { + if ( !empty( $methods ) ) { WP_CLI::out(' ['.implode('|', $methods).']'); } WP_CLI::line(' ...'); From ff99eb5b130906f3dc99be866317d4d7cef19d24 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 3 Oct 2011 10:06:43 +0100 Subject: [PATCH 0064/4858] Spelling mistake. --- commands/community/example.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/community/example.php b/commands/community/example.php index 655709a0a9..56e420ce80 100644 --- a/commands/community/example.php +++ b/commands/community/example.php @@ -7,7 +7,7 @@ * Implement example command * * @package wp-cli - * @subpackage commands/cummunity + * @subpackage commands/community * @author Andreas Creten */ class ExampleCommand extends WP_CLI_Command { From dd4661d36cf43595d85d19ea79ab0cce14897f04 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 17:22:41 +0300 Subject: [PATCH 0065/4858] make wp theme activate work --- commands/internals/theme.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 04364dbef6..488d974dff 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -78,20 +78,32 @@ public function details($args = array()) { /** * Activate a theme * - * @param string $args + * @param array $args * @return void **/ public function activate($args = array()) { - WP_CLI::warning('This command is not ready yet!'); + if ( empty( $args ) ) { + WP_CLI::line('usage: wp theme activate '); + exit; + } - // Get the info of the theme - $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + $theme = array_shift( $args ); - // Switch to the theme - switch_theme($args[0], WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + $stylesheet = WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'; - // Get the current theme - $theme_name = get_current_theme(); + if ( !is_readable( $stylesheet ) ) { + WP_CLI::warning( 'theme not found' ); + exit; + } + + $details = get_theme_data( $stylesheet ); + + $child = $theme; + $parent = $details['Template']; + if ( empty( $parent ) ) + $parent = $child; + + switch_theme( $parent, $child ); } /** From 1c4a5feb414ce6b3b30ac67443a566f9ba3d668d Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 18:05:05 +0300 Subject: [PATCH 0066/4858] check if parent theme is valid --- commands/internals/theme.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 488d974dff..5c1223d530 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -87,9 +87,9 @@ public function activate($args = array()) { exit; } - $theme = array_shift( $args ); + $child = array_shift( $args ); - $stylesheet = WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'; + $stylesheet = $this->get_stylesheet_path( $child ); if ( !is_readable( $stylesheet ) ) { WP_CLI::warning( 'theme not found' ); @@ -98,14 +98,22 @@ public function activate($args = array()) { $details = get_theme_data( $stylesheet ); - $child = $theme; $parent = $details['Template']; - if ( empty( $parent ) ) + + if ( empty( $parent ) ) { $parent = $child; + } elseif ( !is_readable( $this->get_stylesheet_path ( $parent ) ) ) { + WP_CLI::warning( 'parent theme not found' ); + exit; + } switch_theme( $parent, $child ); } + protected function get_stylesheet_path( $theme ) { + return WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'; + } + /** * Help function for this command * From 9d222c3355b54d4186fd7b6a07f6582e55b2628b Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 3 Oct 2011 23:41:52 +0300 Subject: [PATCH 0067/4858] add --version flag --- class-wp-cli.php | 6 +++--- wp-cli.php | 30 +++++++++++++++++++----------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 0af7061c6b..5e7778e2c9 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -99,13 +99,13 @@ static function errorToString($errors) { * @return array */ static function parse_args( $arguments ) { - $global_arg_names = array( 'blog' ); - $regular_args = array(); $assoc_args = array(); foreach ( $arguments as $arg ) { - if ( preg_match( '|^--(\w+)=(.+)|', $arg, $matches ) ) { + if ( preg_match( '|^--(\w+)$|', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = true; + } elseif ( preg_match( '|^--(\w+)=(.+)|', $arg, $matches ) ) { $assoc_args[ $matches[1] ] = $matches[2]; } else { $regular_args[] = $arg; diff --git a/wp-cli.php b/wp-cli.php index 7789d561e9..9a6b4f0b8e 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -5,13 +5,7 @@ die('Only cli access'); } -// Define the WordPress location -if(is_readable($_SERVER['PWD'] . '/../wp-load.php')) { - define('WP_ROOT', $_SERVER['PWD'] . '/../'); -} -else { - define('WP_ROOT', $_SERVER['PWD'] . '/'); -} +define( 'WP_CLI_VERSION', '0.1' ); // Define the wp-cli location define('WP_CLI_ROOT', __DIR__ . '/'); @@ -23,19 +17,33 @@ include WP_CLI_ROOT.'class-wp-cli.php'; include WP_CLI_ROOT.'class-wp-cli-command.php'; -// Include the command line tools, taken from here: https://github.com/jlogsdon/php-cli-tools +// Include the command line tools include WP_CLI_ROOT.'php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); +// Get the cli arguments +list( $arguments, $assoc_args ) = WP_CLI::parse_args( array_slice( $GLOBALS['argv'], 1 ) ); + +// Handle --version parameter +if ( isset( $assoc_args['version'] ) ) { + WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); + exit; +} + +// Define the WordPress location +if(is_readable($_SERVER['PWD'] . '/../wp-load.php')) { + define('WP_ROOT', $_SERVER['PWD'] . '/../'); +} +else { + define('WP_ROOT', $_SERVER['PWD'] . '/'); +} + // Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); exit(); } -// Get the cli arguments -list( $arguments, $assoc_args ) = WP_CLI::parse_args( array_slice( $GLOBALS['argv'], 1 ) ); - // Handle --blog parameter if ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; From 9a57d334a1abe510a7590af787e43c86fededda9 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 00:05:43 +0300 Subject: [PATCH 0068/4858] installation instructions: need to fetch the submodules too --- README.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1d83505b84..a11b1520f4 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,30 @@ A command line tool to do maintenance work on a WordPress install from the comma Installing ---------- -1. Clone the project: `git clone https://github.com/andreascreten/wp-cli.git` -1. Make a symlink to the executable: `sudo ln -s /path-to-wp-cli-dir/wp /usr/local/bin/` +1. Clone the project: + +``` +git clone https://github.com/andreascreten/wp-cli.git +cd wp-cli +git submodule update --init +``` + +Make a symlink to the executable: + +``` +sudo ln -s /path-to-wp-cli-dir/wp /usr/local/bin/ +``` Usage ----- -In your terminal, go into the WordPress root folder. +Go into a WordPress root folder: + +``` +cd /var/www/wp/ # your path might be something else +``` -Typing the following command: `wp help`, will show you an output similar to this: +Typing the following command: `wp help` will show you an output similar to this: ``` Example usage: From 93a91c380db482f1a3bafedae89cf7616f337221 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 00:07:23 +0300 Subject: [PATCH 0069/4858] more install instructions cleanup --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a11b1520f4..c3f27e1932 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A command line tool to do maintenance work on a WordPress install from the comma Installing ---------- -1. Clone the project: +Clone the project: ``` git clone https://github.com/andreascreten/wp-cli.git @@ -29,10 +29,10 @@ Usage Go into a WordPress root folder: ``` -cd /var/www/wp/ # your path might be something else +cd /var/www/wp/ ``` -Typing the following command: `wp help` will show you an output similar to this: +Typing `wp help` should show you an output similar to this: ``` Example usage: @@ -47,7 +47,11 @@ Example usage: So this tells us which commands are installed: eg. google-sitemap, core, home, ... Between brackets you can see their sub commands. -Let's for example try to install the hello dolly plugin from wordpress.org: `wp plugin install hello-dolly`. +Let's for example try to install the hello dolly plugin from wordpress.org: + +``` +wp plugin install hello-dolly +``` Output: From 365e1799200b3f33f3bd1061c8b0c5dd88b55200 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 00:14:49 +0300 Subject: [PATCH 0070/4858] remove repetition from wp-cli description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c3f27e1932..00a419ef19 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ WP-CLI: WordPress Command Line Tools What is wp-cli -------------- -A command line tool to do maintenance work on a WordPress install from the command line. +A tool to control WordPress installations from the command line. Installing ---------- From a62175a3ce6be0919389f81a9a986a5ca537733e Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 01:30:26 +0300 Subject: [PATCH 0071/4858] dynamically fetch the list of commands. see #6 --- wp-cli-completion.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wp-cli-completion.bash b/wp-cli-completion.bash index ed3a37ce9a..16d83a1058 100644 --- a/wp-cli-completion.bash +++ b/wp-cli-completion.bash @@ -6,7 +6,8 @@ _wp() { COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="core plugin option theme home help" + + opts=$(wp help | awk '/wp / {print $2}') COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 From 5c28d7178715e48bb3c50e64ca6846fac19ccc01 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 01:48:43 +0300 Subject: [PATCH 0072/4858] add instructions for installing completion file. see #6 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 00a419ef19..ef6681ca56 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,12 @@ Make a symlink to the executable: sudo ln -s /path-to-wp-cli-dir/wp /usr/local/bin/ ``` +Make a symlink to the autocomplete file (Linux): + +``` +sudo ln -s /path-to-wp-cli-dir/wp-cli-completion.bash /etc/bash_completion.d/wp +``` + Usage ----- From 1d7534091ad5ec33bbbc35c628efc11bb6357f73 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Tue, 4 Oct 2011 01:16:49 +0200 Subject: [PATCH 0073/4858] Added the community command super-cache (for the WP Super Cache plugin) Also added support for --help in the cli, it does exactly the same as the normal help. --- class-wp-cli-command.php | 7 +- commands/community/wp-super-cache.php | 167 ++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 commands/community/wp-super-cache.php diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 83ce288fce..6539265b4a 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -47,15 +47,18 @@ protected function dispatch( $args, $assoc_args ) { // The first command is the sub command $sub_command = array_shift($args); + // Assosciative arguments keys + $assoc_keys = array_keys($assoc_args); + if ( !method_exists($this, $sub_command) ) { // This if for reserved keywords in php (like list, isset) $sub_command = '_'.$sub_command; } - if ( !method_exists($this, $sub_command) ) { + if ( !method_exists($this, $sub_command) || in_array( 'help', $assoc_keys ) ) { $sub_command = 'help'; } - + $this->$sub_command($args, $assoc_args); } diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php new file mode 100644 index 0000000000..10d0862809 --- /dev/null +++ b/commands/community/wp-super-cache.php @@ -0,0 +1,167 @@ + time() - 3600 * 24 ) { + global $super_cache_enabled; + WP_CLI::line( 'Cache status: ' . ($super_cache_enabled ? '%gOn%n' : '%rOff%n') ); + WP_CLI::line( 'Cache content on ' . date('r', $cache_stats['generated'] ) . ': ' ); + WP_CLI::line(); + WP_CLI::line( ' WordPress cache:' ); + WP_CLI::line( ' Cached: ' . $cache_stats[ 'wpcache' ][ 'cached' ] ); + WP_CLI::line( ' Expired: ' . $cache_stats[ 'wpcache' ][ 'expired' ] ); + WP_CLI::line(); + WP_CLI::line( ' WP Super Cache:' ); + WP_CLI::line( ' Cached: ' . $cache_stats[ 'supercache' ][ 'cached' ] ); + WP_CLI::line( ' Expired: ' . $cache_stats[ 'supercache' ][ 'expired' ] ); + } else { + WP_CLI::error('The WP Super Cache stats are too old to work with (older than 24 hours).'); + } + } else { + WP_CLI::error('No WP Super Cache stats found.'); + } + } + + /** + * Enable the WP Super Cache + * + * @param array $args + * @param array $vars + * @return void + * @author Andreas Creten + */ + function enable( $args = array(), $vars = array() ) { + if ( function_exists( 'wp_super_cache_enable' ) ) { + global $super_cache_enabled; + wp_super_cache_enable(); + if($super_cache_enabled) { + WP_CLI::success( 'The WP Super Cache is enabled.' ); + } else { + WP_CLI::error('The WP Super Cache is not enabled, check its settings page for more info.'); + } + } else { + WP_CLI::error('The WP Super Cache could not be found, is it installed?'); + } + } + + /** + * Disable the WP Super Cache + * + * @param array $args + * @param array $vars + * @return void + * @author Andreas Creten + */ + function disable( $args = array(), $vars = array() ) { + if ( function_exists( 'wp_super_cache_disable' ) ) { + global $super_cache_enabled; + wp_super_cache_disable(); + if(!$super_cache_enabled) { + WP_CLI::success( 'The WP Super Cache is disabled.' ); + } else { + WP_CLI::error('The WP Super Cache is still enabled, check its settings page for more info.'); + } + } else { + WP_CLI::error('The WP Super Cache could not be found, is it installed?'); + } + } + + /** + * Help function for this command + * + * @param string $args + * @return void + */ + public function help($args = array()) { + // Shot the command description + WP_CLI::line( $this->get_description() ); + WP_CLI::line(); + + // Show the list of sub-commands for this command + WP_CLI::line('Example usage:'); + WP_CLI::line(' wp wp-super-cache clean [--post_id=] [--permalink=]'); + WP_CLI::line(' wp wp-super-cache status'); + WP_CLI::line(' wp wp-super-cache enable'); + WP_CLI::line(' wp wp-super-cache disable'); + WP_CLI::line(); + WP_CLI::line('%9--- DETAILS ---%n'); + WP_CLI::line(); + WP_CLI::line('Remove the whole cache content:'); + WP_CLI::line(' wp wp-super-cache clean'); + WP_CLI::line(); + WP_CLI::line('Remove the caches for one blog post based on the id:'); + WP_CLI::line(' wp wp-super-cache clean --post_id=1'); + WP_CLI::line(); + WP_CLI::line('Remove the caches for one blog post based on the permalink:'); + WP_CLI::line(' wp wp-super-cache clean --permalink=http://example.com'); + WP_CLI::line(); + WP_CLI::line('Get details on the WP Super Cache content:'); + WP_CLI::line(' wp wp-super-cache status'); + WP_CLI::line(); + WP_CLI::line('Enable the WP Super Cache:'); + WP_CLI::line(' wp wp-super-cache enable'); + WP_CLI::line(); + WP_CLI::line('Disable the WP Super Cache:'); + WP_CLI::line(' wp wp-super-cache disable'); + } +} From b80620de67fcbf96fcac380940c96971a610b5e1 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Tue, 4 Oct 2011 01:31:38 +0200 Subject: [PATCH 0074/4858] Added the community command google-sitemap (for the Google Sitemap Generator plugin) --- class-wp-cli-command.php | 5 +- .../community/google-sitemap-generator.php | 52 +++++++++++++++++++ commands/community/wp-super-cache.php | 9 ++-- 3 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 commands/community/google-sitemap-generator.php diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 6539265b4a..e6a6dee478 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -47,15 +47,12 @@ protected function dispatch( $args, $assoc_args ) { // The first command is the sub command $sub_command = array_shift($args); - // Assosciative arguments keys - $assoc_keys = array_keys($assoc_args); - if ( !method_exists($this, $sub_command) ) { // This if for reserved keywords in php (like list, isset) $sub_command = '_'.$sub_command; } - if ( !method_exists($this, $sub_command) || in_array( 'help', $assoc_keys ) ) { + if ( !method_exists($this, $sub_command) || isset( $assoc_args[ 'help' ] ) ) { $sub_command = 'help'; } diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php new file mode 100644 index 0000000000..7a47c2f6c3 --- /dev/null +++ b/commands/community/google-sitemap-generator.php @@ -0,0 +1,52 @@ +get_description() ); + WP_CLI::line(); + + // Show the list of sub-commands for this command + WP_CLI::line('Example usage:'); + WP_CLI::line(' wp google-sitemap rebuild'); + WP_CLI::line(); + WP_CLI::line('%9--- DETAILS ---%n'); + WP_CLI::line(); + WP_CLI::line('Rebuild the Google sitemaps:'); + WP_CLI::line(' wp google-sitemap rebuild'); + } +} \ No newline at end of file diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index 10d0862809..dd9d0c47ad 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -1,7 +1,9 @@ Date: Tue, 4 Oct 2011 02:42:50 +0300 Subject: [PATCH 0075/4858] remove example.php command; don't need it actually available --- commands/community/example.php | 82 ---------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 commands/community/example.php diff --git a/commands/community/example.php b/commands/community/example.php deleted file mode 100644 index 56e420ce80..0000000000 --- a/commands/community/example.php +++ /dev/null @@ -1,82 +0,0 @@ -'); - } - else { - WP_CLI::line(' wp '.$used_command.' '.$method); - } - } - } -} From 3e9074e2d6f93444a79fa7ae7b5ddeff5c294894 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 03:05:22 +0300 Subject: [PATCH 0076/4858] provide completions for sub-commands. see #6 --- wp-cli-completion.bash | 7 +++++-- wp-cli.php | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/wp-cli-completion.bash b/wp-cli-completion.bash index 16d83a1058..5e376f5ff3 100644 --- a/wp-cli-completion.bash +++ b/wp-cli-completion.bash @@ -7,9 +7,12 @@ _wp() { cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - opts=$(wp help | awk '/wp / {print $2}') + if [[ 'wp' = $prev ]]; then + opts=$(wp --completions | cut -d ' ' -f 1) + else + opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2-) + fi COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 } complete -F _wp wp diff --git a/wp-cli.php b/wp-cli.php index 9a6b4f0b8e..241d08e93a 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -82,6 +82,14 @@ exit(); } +// Handle --completions parameter +if ( isset( $assoc_args['completions'] ) ) { + foreach ( WP_CLI::$commands as $name => $command ) { + WP_CLI::line( $name . ' ' . implode( ' ', WP_CLI_Command::get_methods($command) ) ); + } + exit; +} + // Get the top-level command $command = array_shift( $arguments ); From 097b8d909f555d27e95f960bc5221d83f3190157 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 03:38:33 +0300 Subject: [PATCH 0077/4858] faster way to fetch php version --- wp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wp b/wp index 91c73f6d4d..b8336b6dad 100755 --- a/wp +++ b/wp @@ -92,9 +92,7 @@ if [ "x$wp_cli_php_override" != "x" ] ; then fi # Get the php version -PHP_VERSION=$($php -r 'echo phpversion();') -# Keep only major version number -PHP_VERSION=${PHP_VERSION%%-*} +PHP_VERSION=$(php -v | awk '/^PHP / {print $2}' | cut -d '-' -f 1) # Format version numbers CURRENT_NUMBER=$(echo "$PHP_VERSION" | tr -d '.') From 4d7628f9e24ce7ab82ea7e51a1f7cd948582b9e5 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 03:59:37 +0300 Subject: [PATCH 0078/4858] convert newlines to spaces. see #6 --- wp-cli-completion.bash | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wp-cli-completion.bash b/wp-cli-completion.bash index 5e376f5ff3..d04b8e0893 100644 --- a/wp-cli-completion.bash +++ b/wp-cli-completion.bash @@ -8,11 +8,11 @@ _wp() { prev="${COMP_WORDS[COMP_CWORD-1]}" if [[ 'wp' = $prev ]]; then - opts=$(wp --completions | cut -d ' ' -f 1) + opts=$(wp --completions | cut -d ' ' -f 1 | tr '\n' ' ') else - opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2-) + opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2- | tr '\n' ' ') fi - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) } complete -F _wp wp From bd762babc93a0892cc9b9adb470e444bc37d5b56 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 04:05:38 +0300 Subject: [PATCH 0079/4858] remove unneeded assignment of COMPREPLY --- wp-cli-completion.bash | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wp-cli-completion.bash b/wp-cli-completion.bash index d04b8e0893..39ec5b6493 100644 --- a/wp-cli-completion.bash +++ b/wp-cli-completion.bash @@ -1,11 +1,12 @@ -# Very basic code completion -# -# Code taken from here: http://www.debian-administration.org/article/317/An_introduction_to_bash_completion_part_2 +#!bash +# +# bash completion support for the wp command +# _wp() { local cur prev opts - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" + + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} if [[ 'wp' = $prev ]]; then opts=$(wp --completions | cut -d ' ' -f 1 | tr '\n' ' ') From 2a52e2cf011e42d68837617748bfe98adce8cec7 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Tue, 4 Oct 2011 09:02:27 +0200 Subject: [PATCH 0080/4858] Added the community command total-cache (for the W3 Total Cache plugin) --- .../community/google-sitemap-generator.php | 2 +- commands/community/w3-total-cache.php | 121 ++++++++++++++++++ commands/community/wp-super-cache.php | 10 +- 3 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 commands/community/w3-total-cache.php diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index 7a47c2f6c3..c5d7dbaa46 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -6,7 +6,7 @@ } /** - * The WP Super Cache plugin + * Manage the Google XML Sitemap plugin * * @package wp-cli * @subpackage commands/community diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php new file mode 100644 index 0000000000..98d0fcca1d --- /dev/null +++ b/commands/community/w3-total-cache.php @@ -0,0 +1,121 @@ +get_description() ); + WP_CLI::line(); + + // Show the list of sub-commands for this command + WP_CLI::line('Example usage:'); + WP_CLI::line(' wp total-cache flush [post|database|minify|object] [--post_id=] [--permalink=]'); + WP_CLI::line(); + WP_CLI::line('%9--- DETAILS ---%n'); + WP_CLI::line(); + WP_CLI::line('Remove all post/page caches:'); + WP_CLI::line(' wp total-cache flush'); + WP_CLI::line(); + WP_CLI::line('Remove the caches for one blog post based on the id:'); + WP_CLI::line(' wp total-cache flush --post_id=1'); + WP_CLI::line(); + WP_CLI::line('Remove the caches for one blog post based on the permalink:'); + WP_CLI::line(' wp total-cache flush --permalink=http://example.com'); + WP_CLI::line(); + WP_CLI::line('Remove the database cache:'); + WP_CLI::line(' wp total-cache flush database'); + WP_CLI::line(); + WP_CLI::line('Remove the object cache:'); + WP_CLI::line(' wp total-cache flush object'); + WP_CLI::line(); + WP_CLI::line('Remove the minify cache:'); + WP_CLI::line(' wp total-cache flush minify'); + } +} diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index dd9d0c47ad..c782386989 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -25,7 +25,7 @@ public static function get_description() { * @param array $vars * @return void */ - function clear( $args = array(), $vars = array() ) { + function flush( $args = array(), $vars = array() ) { if ( function_exists( 'wp_cache_clear_cache' ) ) { if ( isset($vars['post_id']) ) { if ( is_numeric( $vars['post_id'] ) ) { @@ -138,7 +138,7 @@ public function help($args = array()) { // Show the list of sub-commands for this command WP_CLI::line('Example usage:'); - WP_CLI::line(' wp wp-super-cache clean [--post_id=] [--permalink=]'); + WP_CLI::line(' wp wp-super-cache flush [--post_id=] [--permalink=]'); WP_CLI::line(' wp wp-super-cache status'); WP_CLI::line(' wp wp-super-cache enable'); WP_CLI::line(' wp wp-super-cache disable'); @@ -146,13 +146,13 @@ public function help($args = array()) { WP_CLI::line('%9--- DETAILS ---%n'); WP_CLI::line(); WP_CLI::line('Remove the whole cache content:'); - WP_CLI::line(' wp wp-super-cache clean'); + WP_CLI::line(' wp wp-super-cache flush'); WP_CLI::line(); WP_CLI::line('Remove the caches for one blog post based on the id:'); - WP_CLI::line(' wp wp-super-cache clean --post_id=1'); + WP_CLI::line(' wp wp-super-cache flush --post_id=1'); WP_CLI::line(); WP_CLI::line('Remove the caches for one blog post based on the permalink:'); - WP_CLI::line(' wp wp-super-cache clean --permalink=http://example.com'); + WP_CLI::line(' wp wp-super-cache flush --permalink=http://example.com'); WP_CLI::line(); WP_CLI::line('Get details on the WP Super Cache content:'); WP_CLI::line(' wp wp-super-cache status'); From 0d7d3599e85b471da41f71b1ae88e59bb8d77865 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Tue, 4 Oct 2011 09:22:33 +0200 Subject: [PATCH 0081/4858] Updated plugin status command to add more details for a single plugin (fixes #11) --- class-wp-cli.php | 4 +-- commands/internals/plugin.php | 46 +++++++++++++++++++++++++---------- commands/internals/theme.php | 6 ++++- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/class-wp-cli.php b/class-wp-cli.php index 5e7778e2c9..2903390699 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -160,9 +160,9 @@ static function get_update_status( $item, $key ) { $update_list = get_site_transient( $key ); if ( isset( $update_list->response[ $item ] ) ) - return ' %yU%n'; + return true; - return ' '; + return false; } } diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index ff10e1de0d..b850d25c73 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -26,24 +26,40 @@ public static function get_description() { * @param string $args * @return void */ - function status($args) { - if(!empty($args)) { + function status( $args = array(), $vars = array() ) { + // Force WordPress to update the plugin list + wp_update_plugins(); + + if(!empty( $args )) { // Get the plugin name from the arguments - $name = $this->check_name($args); + $name = $this->check_name( $args ); // Get the plugin file name - $file = $this->parse_name($name); + $file = $this->parse_name( $name ); + + // Get list of mu plugins + $mu_plugins = get_mu_plugins(); // Get the plugin details - $details = $this->get_details($file); - + $details = $this->get_details( $file ); + + // Get the plugin status + if ( isset( $mu_plugins[ $file ] ) ) + $status = '%cMust Use'; + elseif ( is_plugin_active_for_network( $file ) ) + $status = '%bNetwork Activated'; + elseif ( is_plugin_active( $file ) ) + $status = '%gYes'; + else + $status = '%rNo'; + // Display the plugin details - WP_CLI::line('Plugin %2'.$name.'%n details:'); - WP_CLI::line(' Active: '.((int) is_plugin_active($file))); - if(is_multisite()) { - WP_CLI::line(' Network: '.((int) is_plugin_active_for_network($file))); - } - WP_CLI::line(' Version: '.$details['Version']); + WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); + WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + WP_CLI::line( ' Active: ' . $status .'%n' ); + WP_CLI::line( ' Version: ' . $details[ 'Version' ] . ( WP_CLI::get_update_status( $file, 'update_plugins' ) ? ' (%gUpdate available%n)' : '' ) ); + WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); + WP_CLI::line( ' Author: ' . $details[ 'Author' ]); } else { // Get the list of plugins @@ -64,7 +80,11 @@ function status($args) { else $name = dirname($file); - $line = WP_CLI::get_update_status( $file, 'update_plugins' ); + if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { + $line = ' %yU%n'; + } else { + $line = ' '; + } if ( isset($mu_plugins[$file]) ) $line .= '%cM'; diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 5c1223d530..22c6f6b960 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -32,7 +32,11 @@ public function status($args = array()) { $theme_name = get_current_theme(); foreach ($themes as $key => $theme) { - $line = WP_CLI::get_update_status( $theme['Stylesheet'], 'update_themes' ); + if ( WP_CLI::get_update_status( $theme['Stylesheet'], 'update_themes' ) ) { + $line = ' %yU%n'; + } else { + $line = ' '; + } if ( $theme['Name'] == $theme_name ) $line .= '%gA'; From 5090932a9d3d526697a56f077c71e08eaab04f14 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 4 Oct 2011 21:30:00 +0300 Subject: [PATCH 0082/4858] add `wp generate users` command --- commands/internals/generate.php | 47 +++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/commands/internals/generate.php b/commands/internals/generate.php index a3d12bedfc..0d1d654ae6 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -19,7 +19,8 @@ public static function get_description() { /** * Generate posts * - * @param string $args + * @param array $args + * @param array $assoc_args * @return void **/ public function posts( $args, $assoc_args ) { @@ -34,7 +35,7 @@ public function posts( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); if ( !post_type_exists( $type ) ) { - WP_CLI::warning( "Invalid post type: $type" ); + WP_CLI::warning( 'invalid post type.' ); exit; } @@ -53,4 +54,46 @@ public function posts( $args, $assoc_args ) { ) ); } } + + /** + * Generate users + * + * @param array $args + * @param array $assoc_args + * @return void + **/ + public function users( $args, $assoc_args ) { + global $blog_id; + + $defaults = array( + 'count' => 100, + 'role' => get_option('default_role'), + ); + + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + if ( is_null( get_role( $role ) ) ) { + WP_CLI::warning( "invalid role." ); + exit; + } + + $user_count = count_users(); + + $total = $user_count['total_users']; + + $limit = $count + $total; + + for ( $i = $total; $i < $limit; $i++ ) { + $login = sprintf( 'user_%d_%d', $blog_id, $i ); + $name = "User $i"; + + $r = wp_insert_user( array( + 'user_login' => $login, + 'user_pass' => $login, + 'nickname' => $name, + 'display_name' => $name, + 'role' => $role + ) ); + } + } } From 57725ff57d73112a397941fe58142f2e9d362b41 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 5 Oct 2011 08:05:35 +0300 Subject: [PATCH 0083/4858] plugin.php cleanup * silence plugin sub-commands which don't involve HTTP requests * don't error if plugin is already (de)activated * remove some obvious comments * coding standards --- commands/internals/plugin.php | 210 ++++++++++++++-------------------- 1 file changed, 89 insertions(+), 121 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index b850d25c73..4cab54c2e3 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -1,9 +1,7 @@ check_name( $args ); - // Get the plugin file name $file = $this->parse_name( $name ); - - // Get list of mu plugins + $mu_plugins = get_mu_plugins(); - // Get the plugin details $details = $this->get_details( $file ); - + // Get the plugin status if ( isset( $mu_plugins[ $file ] ) ) $status = '%cMust Use'; @@ -52,7 +46,7 @@ function status( $args = array(), $vars = array() ) { $status = '%gYes'; else $status = '%rNo'; - + // Display the plugin details WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); @@ -62,13 +56,10 @@ function status( $args = array(), $vars = array() ) { WP_CLI::line( ' Author: ' . $details[ 'Author' ]); } else { - // Get the list of plugins $plugins = get_plugins(); - // Get list of mu plugins $mu_plugins = get_mu_plugins(); - // Merge the two plugin arrays $plugins = array_merge($plugins, $mu_plugins); // Print the header @@ -122,23 +113,15 @@ function status( $args = array(), $vars = array() ) { * @param string $args * @return void */ - function activate($args) { - // Get the plugin name from the arguments - $name = $this->check_name($args); + function activate( $args ) { + $name = $this->check_name( $args ); - // Get the plugin file name - $file = $this->parse_name($name); + $file = $this->parse_name( $name ); - // Check if the plugin is already active - if(is_plugin_active($file)) { - WP_CLI::error('The plugin is already active: '.$name); - } - // Try to activate the plugin - elseif(activate_plugin($file) === null) { - WP_CLI::success('Plugin activated: '.$name); - } - else { - WP_CLI::error('The plugin could not be activated: '.$name); + activate_plugin( $file ); + + if ( !is_plugin_active( $file ) ) { + WP_CLI::error( 'Could not activate this plugin: ' . $name ); } } @@ -148,23 +131,15 @@ function activate($args) { * @param string $args * @return void */ - function deactivate($args) { - // Get the plugin name from the arguments - $name = $this->check_name($args); + function deactivate( $args ) { + $name = $this->check_name( $args ); - // Get the plugin file name - $file = $this->parse_name($name); + $file = $this->parse_name( $name ); - // Check if the plugin is already deactivated - if(is_plugin_inactive($file)) { - WP_CLI::error('The plugin is already deactivated: '.$name); - } - // Try to deactivate the plugin - elseif(deactivate_plugins($file) === null) { - WP_CLI::success('Plugin deactivated: '.$name); - } - else { - WP_CLI::error('Could not deactivate this plugin: '.$name); + deactivate_plugins( $file ); + + if ( !is_plugin_inactive( $file ) ) { + WP_CLI::error( 'Could not deactivate this plugin: '.$name ); } } @@ -174,54 +149,54 @@ function deactivate($args) { * @param string $args * @return void */ - function install($args) { + function install( $args ) { // Get the plugin name from the arguments - $name = $this->check_name($args); + $name = $this->check_name( $args ); // Get the plugin file name - $file = $this->parse_name($name, false); + $file = $this->parse_name( $name, false ); // Force WordPress to update the plugin list wp_update_plugins(); // Get plugin info from the WordPress servers - $api = plugins_api('plugin_information', array('slug' => stripslashes($name))); - $status = install_plugin_install_status($api); + $api = plugins_api( 'plugin_information', array( 'slug' => stripslashes( $name ) ) ); + $status = install_plugin_install_status( $api ); - WP_CLI::line('Installing '.$api->name.' ('.$api->version.')'); + WP_CLI::line( 'Installing '.$api->name.' ('.$api->version.')' ); // Check what to do - switch($status['status']) { - case 'update_available': - case 'install': - if(!class_exists('Plugin_Upgrader')) { - require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); - } + switch ( $status['status'] ) { + case 'update_available': + case 'install': + if ( !class_exists( 'Plugin_Upgrader' ) ) { + require_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' ); + } - // Install the plugin - ob_start('strip_tags'); - $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); - $result = $upgrader->install($api->download_link); - $feedback = ob_get_clean(); + // Install the plugin + ob_start( 'strip_tags' ); + $upgrader = new Plugin_Upgrader( new CLI_Upgrader_Skin ); + $result = $upgrader->install( $api->download_link ); + $feedback = ob_get_clean(); - if($result !== null) { - WP_CLI::error($result); - } - else { - WP_CLI::line(); - WP_CLI::line(strip_tags(str_replace(array('…', 'Plugin installed successfully.'), array(" ...\n", ''), html_entity_decode($feedback)))); - WP_CLI::success('The plugin is successfully installed'); - } + if ( $result !== null ) { + WP_CLI::error( $result ); + } + else { + WP_CLI::line(); + WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin installed successfully.' ), array( " ...\n", '' ), html_entity_decode( $feedback ) ) ) ); + WP_CLI::success( 'The plugin is successfully installed' ); + } break; - case 'newer_installed': - WP_CLI::error(sprintf('Newer version (%s) installed', $status['version'])); + case 'newer_installed': + WP_CLI::error( sprintf( 'Newer version ( %s ) installed', $status['version'] ) ); break; - case 'latest_installed': - WP_CLI::error('Latest version already installed'); + case 'latest_installed': + WP_CLI::error( 'Latest version already installed' ); - if(is_plugin_inactive($file)) { - WP_CLI::warning('If you want to activate the plugin, run: %2wp plugin activate '.$name.'%n'); - } + if ( is_plugin_inactive( $file ) ) { + WP_CLI::warning( 'If you want to activate the plugin, run: %2wp plugin activate '.$name.'%n' ); + } break; } } @@ -232,18 +207,13 @@ function install($args) { * @param string $args * @return void */ - function delete($args) { - // Get the plugin name from the arguments - $name = $this->check_name($args); + function delete( $args ) { + $name = $this->check_name( $args ); - // Get the plugin file name - $file = $this->parse_name($name); + $file = $this->parse_name( $name ); - if(delete_plugins(array($file))) { - WP_CLI::success('The plugin is successfully deleted.'); - } - else { - WP_CLI::error('There was an error while deleting the plugin.'); + if ( !delete_plugins( array( $file ) ) ) { + WP_CLI::error( 'There was an error while deleting the plugin.' ); } } @@ -253,35 +223,33 @@ function delete($args) { * @param string $args * @return void */ - function update($args) { - // Get the plugin name from the arguments - $name = $this->check_name($args); + function update( $args ) { + $name = $this->check_name( $args ); - // Get the plugin file name - $file = $this->parse_name($name); + $file = $this->parse_name( $name ); // Force WordPress to update the plugin list wp_update_plugins(); - if(!class_exists('Plugin_Upgrader')) { - require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); + if ( !class_exists( 'Plugin_Upgrader' ) ) { + require_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' ); } - WP_CLI::line('Updating '.$name); + WP_CLI::line( 'Updating '.$name ); // Upgrading the plugin - ob_start('strip_tags'); - $upgrader = new Plugin_Upgrader(new CLI_Upgrader_Skin); - $result = $upgrader->upgrade($file); + ob_start( 'strip_tags' ); + $upgrader = new Plugin_Upgrader( new CLI_Upgrader_Skin ); + $result = $upgrader->upgrade( $file ); $feedback = ob_get_clean(); - if($result !== null) { - WP_CLI::error($feedback); + if ( $result !== null ) { + WP_CLI::error( $feedback ); } else { WP_CLI::line(); - WP_CLI::line(html_entity_decode(strip_tags($feedback))); - WP_CLI::success('The plugin is successfully updated.'); + WP_CLI::line( html_entity_decode( strip_tags( $feedback ) ) ); + WP_CLI::success( 'The plugin is successfully updated.' ); } } @@ -293,9 +261,9 @@ function update($args) { * @param string $file * @return array */ - private function get_details($file) { - $plugin_folder = get_plugins( '/' . plugin_basename(dirname($file))); - $plugin_file = basename(($file)); + private function get_details( $file ) { + $plugin_folder = get_plugins( '/' . plugin_basename( dirname( $file ) ) ); + $plugin_file = basename( ( $file ) ); return $plugin_folder[$plugin_file]; } @@ -307,21 +275,21 @@ private function get_details($file) { * @param string $exit * @return mixed */ - private function parse_name($name, $exit = true) { - $plugins = get_plugins('/'.$name); + private function parse_name( $name, $exit = true ) { + $plugins = get_plugins( '/'.$name ); - if(!empty($plugins)) { - $keys = array_keys($plugins); + if ( !empty( $plugins ) ) { + $keys = array_keys( $plugins ); $file = $name.'/'.$keys[0]; } else { $plugins = get_plugins(); - if(isset($plugins[$name.'.php'])) { + if ( isset( $plugins[$name.'.php'] ) ) { $file = $name.'.php'; } else { - if($exit) { - WP_CLI::error('The plugin \''.$name.'\' could not be found.'); + if ( $exit ) { + WP_CLI::error( 'The plugin \''.$name.'\' could not be found.' ); exit(); } @@ -339,13 +307,13 @@ private function parse_name($name, $exit = true) { * @param string $exit * @return void */ - private function check_name($args, $exit = true) { - if(empty($args)) { - WP_CLI::error('Please specify a plugin.'); + private function check_name( $args, $exit = true ) { + if ( empty( $args ) ) { + WP_CLI::error( 'Please specify a plugin.' ); WP_CLI::line(); $this->help(); - if($exit) { + if ( $exit ) { exit(); } } @@ -359,20 +327,20 @@ private function check_name($args, $exit = true) { * @param string $args * @return void */ - public function help($args = array()) { + public function help( $args = array() ) { // Shot the command description WP_CLI::line( $this->get_description() ); WP_CLI::line(); // Show the list of sub-commands for this command - WP_CLI::line('Example usage:'); + WP_CLI::line( 'Example usage:' ); - foreach (WP_CLI_Command::get_methods($this) as $method) { - if($method != 'help') { - WP_CLI::line(' wp '.$this->command.' '.$method.' hello-dolly'); + foreach ( WP_CLI_Command::get_methods( $this ) as $method ) { + if ( $method != 'help' ) { + WP_CLI::line( ' wp '.$this->command.' '.$method.' hello-dolly' ); } else { - WP_CLI::line(' wp '.$this->command.' '.$method); + WP_CLI::line( ' wp '.$this->command.' '.$method ); } } } From 899ab3c3767ebb09a30830b14a03cbfcf0e46f9e Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 5 Oct 2011 15:25:09 +0100 Subject: [PATCH 0084/4858] Same spelling mistake as before. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef6681ca56..680af9b74c 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ A wp-cli class is structured like this: * Implement example command * * @package wp-cli - * @subpackage commands/cummunity + * @subpackage commands/community * @author Andreas Creten */ class ExampleCommand extends WP_CLI_Command { From d1581b182b6b3e0073d01ff473263dff33892e36 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 19:50:41 +0300 Subject: [PATCH 0085/4858] add wp plugin toggle command --- commands/internals/plugin.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 4cab54c2e3..9bb0c23b01 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -122,6 +122,8 @@ function activate( $args ) { if ( !is_plugin_active( $file ) ) { WP_CLI::error( 'Could not activate this plugin: ' . $name ); + } else { + WP_CLI::line( 'Plugin activated.' ); } } @@ -140,6 +142,26 @@ function deactivate( $args ) { if ( !is_plugin_inactive( $file ) ) { WP_CLI::error( 'Could not deactivate this plugin: '.$name ); + } else { + WP_CLI::line( 'Plugin deactivated.' ); + } + } + + /** + * Toggle a plugin's activation state + * + * @param string $args + * @return void + */ + function toggle( $args ) { + $name = $this->check_name( $args ); + + $file = $this->parse_name( $name ); + + if ( is_plugin_active( $file ) ) { + $this->deactivate( $args ); + } else { + $this->activate( $args ); } } From b065aa849e480e3f81313fa03a919c2299563241 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 19:51:07 +0300 Subject: [PATCH 0086/4858] some code cleanup in parse_name() --- commands/internals/plugin.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 9bb0c23b01..50c0602542 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -29,7 +29,7 @@ function status( $args = array(), $vars = array() ) { wp_update_plugins(); if ( !empty( $args ) ) { - $name = $this->check_name( $args ); + $name = $args[0]; $file = $this->parse_name( $name ); @@ -298,20 +298,17 @@ private function get_details( $file ) { * @return mixed */ private function parse_name( $name, $exit = true ) { - $plugins = get_plugins( '/'.$name ); + $plugins = get_plugins( '/' . $name ); if ( !empty( $plugins ) ) { - $keys = array_keys( $plugins ); - $file = $name.'/'.$keys[0]; + $file = $name . '/' . key( $plugins ); } else { + $file = $name . '.php'; $plugins = get_plugins(); - if ( isset( $plugins[$name.'.php'] ) ) { - $file = $name.'.php'; - } - else { + if ( !isset( $plugins[$file] ) ) { if ( $exit ) { - WP_CLI::error( 'The plugin \''.$name.'\' could not be found.' ); + WP_CLI::error( "The plugin '$name' could not be found." ); exit(); } From aaa8a2885a96ec64623ae5a90ba87777848d7cb8 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 19:52:45 +0300 Subject: [PATCH 0087/4858] $args is always an array --- class-wp-cli-command.php | 2 +- .../community/google-sitemap-generator.php | 2 +- commands/community/w3-total-cache.php | 2 +- commands/community/wp-super-cache.php | 2 +- commands/internals/core.php | 2 +- commands/internals/home.php | 2 +- commands/internals/option.php | 10 +++++----- commands/internals/plugin.php | 18 +++++++++--------- commands/internals/theme.php | 6 +++--- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index e6a6dee478..e8c75c43c5 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -62,7 +62,7 @@ protected function dispatch( $args, $assoc_args ) { /** * General help function for this command * - * @param string $args + * @param array $args * @param string $assoc_args * @return void */ diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index c5d7dbaa46..6f6b905265 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -32,7 +32,7 @@ function rebuild( $args = array(), $vars = array() ) { /** * Help function for this command * - * @param string $args + * @param array $args * @return void */ public function help($args = array()) { diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php index 98d0fcca1d..c3dfe9960b 100644 --- a/commands/community/w3-total-cache.php +++ b/commands/community/w3-total-cache.php @@ -86,7 +86,7 @@ function flush( $args = array(), $vars = array() ) { /** * Help function for this command * - * @param string $args + * @param array $args * @return void */ public function help($args = array()) { diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index c782386989..a24c4ff57f 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -128,7 +128,7 @@ function disable( $args = array(), $vars = array() ) { /** * Help function for this command * - * @param string $args + * @param array $args * @return void */ public function help($args = array()) { diff --git a/commands/internals/core.php b/commands/internals/core.php index 62cd85d10e..a496f7aef2 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -19,7 +19,7 @@ public static function get_description() { /** * Update the WordPress core * - * @param string $args + * @param array $args * @return void */ function update($args) { diff --git a/commands/internals/home.php b/commands/internals/home.php index d70cf29756..7e34a80b19 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -50,7 +50,7 @@ protected function dispatch( $args, $assoc_args ) { /** * Help function for this command. * - * @param string $args + * @param array $args * @return void */ public function help($args = array()) { diff --git a/commands/internals/option.php b/commands/internals/option.php index 388aa3b75c..69b325e749 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -19,7 +19,7 @@ public static function get_description() { /** * Add an option * - * @param string $args + * @param array $args * @return void **/ public function add($args = array()) { @@ -41,7 +41,7 @@ public function add($args = array()) { /** * Update an option * - * @param string $args + * @param array $args * @return void **/ public function update($args = array()) { @@ -63,7 +63,7 @@ public function update($args = array()) { /** * Delete an option * - * @param string $args + * @param array $args * @return void **/ public function delete($args = array()) { @@ -85,7 +85,7 @@ public function delete($args = array()) { /** * Get an option * - * @param string $args + * @param array $args * @return void **/ public function get($args = array()) { @@ -108,7 +108,7 @@ public function get($args = array()) { /** * Help function for this command * - * @param string $args + * @param array $args * @return void */ public function help($args = array()) { diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 50c0602542..d789a6b04f 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -21,7 +21,7 @@ public static function get_description() { /** * Get the status of one plugin * - * @param string $args + * @param array $args * @return void */ function status( $args = array(), $vars = array() ) { @@ -110,7 +110,7 @@ function status( $args = array(), $vars = array() ) { /** * Activate a plugin * - * @param string $args + * @param array $args * @return void */ function activate( $args ) { @@ -130,7 +130,7 @@ function activate( $args ) { /** * Deactivate a plugin * - * @param string $args + * @param array $args * @return void */ function deactivate( $args ) { @@ -150,7 +150,7 @@ function deactivate( $args ) { /** * Toggle a plugin's activation state * - * @param string $args + * @param array $args * @return void */ function toggle( $args ) { @@ -168,7 +168,7 @@ function toggle( $args ) { /** * Install a new plugin * - * @param string $args + * @param array $args * @return void */ function install( $args ) { @@ -226,7 +226,7 @@ function install( $args ) { /** * Delete a plugin * - * @param string $args + * @param array $args * @return void */ function delete( $args ) { @@ -242,7 +242,7 @@ function delete( $args ) { /** * Update a plugin * - * @param string $args + * @param array $args * @return void */ function update( $args ) { @@ -322,7 +322,7 @@ private function parse_name( $name, $exit = true ) { /** * Check if there is a name set in the arguments, if not show the help function * - * @param string $args + * @param array $args * @param string $exit * @return void */ @@ -343,7 +343,7 @@ private function check_name( $args, $exit = true ) { /** * Help function for this command * - * @param string $args + * @param array $args * @return void */ public function help( $args = array() ) { diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 22c6f6b960..22c8a50f26 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -19,7 +19,7 @@ public static function get_description() { /** * Get the status of all themes * - * @param string $args + * @param array $args * @return void **/ public function status($args = array()) { @@ -62,7 +62,7 @@ public function status($args = array()) { /** * Get theme details * - * @param string $args + * @param array $args * @return void **/ public function details($args = array()) { @@ -121,7 +121,7 @@ protected function get_stylesheet_path( $theme ) { /** * Help function for this command * - * @param string $args + * @param array $args * @return void */ public function help($args = array()) { From 58bd416cce6539c9e9c2139bb27af7e5e676042e Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 20:53:56 +0300 Subject: [PATCH 0088/4858] when plugin name is missing, show simple usage example instead of generic help --- commands/internals/plugin.php | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index d789a6b04f..6e3379665f 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -114,7 +114,7 @@ function status( $args = array(), $vars = array() ) { * @return void */ function activate( $args ) { - $name = $this->check_name( $args ); + $name = $this->check_name( $args, __FUNCTION__ ); $file = $this->parse_name( $name ); @@ -134,7 +134,7 @@ function activate( $args ) { * @return void */ function deactivate( $args ) { - $name = $this->check_name( $args ); + $name = $this->check_name( $args, __FUNCTION__ ); $file = $this->parse_name( $name ); @@ -154,7 +154,7 @@ function deactivate( $args ) { * @return void */ function toggle( $args ) { - $name = $this->check_name( $args ); + $name = $this->check_name( $args, __FUNCTION__ ); $file = $this->parse_name( $name ); @@ -172,10 +172,8 @@ function toggle( $args ) { * @return void */ function install( $args ) { - // Get the plugin name from the arguments - $name = $this->check_name( $args ); + $name = $this->check_name( $args, __FUNCTION__ ); - // Get the plugin file name $file = $this->parse_name( $name, false ); // Force WordPress to update the plugin list @@ -230,7 +228,7 @@ function install( $args ) { * @return void */ function delete( $args ) { - $name = $this->check_name( $args ); + $name = $this->check_name( $args, __FUNCTION__ ); $file = $this->parse_name( $name ); @@ -246,7 +244,7 @@ function delete( $args ) { * @return void */ function update( $args ) { - $name = $this->check_name( $args ); + $name = $this->check_name( $args, __FUNCTION__ ); $file = $this->parse_name( $name ); @@ -320,21 +318,16 @@ private function parse_name( $name, $exit = true ) { } /** - * Check if there is a name set in the arguments, if not show the help function + * Check if there is a name set in the arguments; if not show usage example * * @param array $args - * @param string $exit - * @return void + * @param string $sub_command + * @return string */ - private function check_name( $args, $exit = true ) { + private function check_name( $args, $sub_command ) { if ( empty( $args ) ) { - WP_CLI::error( 'Please specify a plugin.' ); - WP_CLI::line(); - $this->help(); - - if ( $exit ) { - exit(); - } + WP_CLI::line( "usage: wp plugin $sub_command " ); + exit; } return $args[0]; From c80bed8c22f49b1bca8cbfb06a2bae69e90e1d03 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 21:06:49 +0300 Subject: [PATCH 0089/4858] merge check_name() into parse_name() --- commands/internals/plugin.php | 62 +++++++++++------------------------ 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 6e3379665f..4ad7e57870 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -29,9 +29,7 @@ function status( $args = array(), $vars = array() ) { wp_update_plugins(); if ( !empty( $args ) ) { - $name = $args[0]; - - $file = $this->parse_name( $name ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $mu_plugins = get_mu_plugins(); @@ -114,9 +112,7 @@ function status( $args = array(), $vars = array() ) { * @return void */ function activate( $args ) { - $name = $this->check_name( $args, __FUNCTION__ ); - - $file = $this->parse_name( $name ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); activate_plugin( $file ); @@ -134,9 +130,7 @@ function activate( $args ) { * @return void */ function deactivate( $args ) { - $name = $this->check_name( $args, __FUNCTION__ ); - - $file = $this->parse_name( $name ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); deactivate_plugins( $file ); @@ -154,9 +148,7 @@ function deactivate( $args ) { * @return void */ function toggle( $args ) { - $name = $this->check_name( $args, __FUNCTION__ ); - - $file = $this->parse_name( $name ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); if ( is_plugin_active( $file ) ) { $this->deactivate( $args ); @@ -172,9 +164,7 @@ function toggle( $args ) { * @return void */ function install( $args ) { - $name = $this->check_name( $args, __FUNCTION__ ); - - $file = $this->parse_name( $name, false ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__, false ); // Force WordPress to update the plugin list wp_update_plugins(); @@ -228,9 +218,7 @@ function install( $args ) { * @return void */ function delete( $args ) { - $name = $this->check_name( $args, __FUNCTION__ ); - - $file = $this->parse_name( $name ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); if ( !delete_plugins( array( $file ) ) ) { WP_CLI::error( 'There was an error while deleting the plugin.' ); @@ -244,9 +232,7 @@ function delete( $args ) { * @return void */ function update( $args ) { - $name = $this->check_name( $args, __FUNCTION__ ); - - $file = $this->parse_name( $name ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); // Force WordPress to update the plugin list wp_update_plugins(); @@ -291,11 +277,19 @@ private function get_details( $file ) { /** * Parse the name of a plugin to a filename, check if it exists * - * @param string $name - * @param string $exit - * @return mixed + * @param array $args + * @param string $sub_command + * @param bool $exit + * @return array */ - private function parse_name( $name, $exit = true ) { + private function parse_name( $args, $sub_command, $exit = true ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp plugin $sub_command " ); + exit; + } + + $name = $args[0]; + $plugins = get_plugins( '/' . $name ); if ( !empty( $plugins ) ) { @@ -314,23 +308,7 @@ private function parse_name( $name, $exit = true ) { } } - return $file; - } - - /** - * Check if there is a name set in the arguments; if not show usage example - * - * @param array $args - * @param string $sub_command - * @return string - */ - private function check_name( $args, $sub_command ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp plugin $sub_command " ); - exit; - } - - return $args[0]; + return array( $file, $name ); } /** From 9c336a0b967512d7c6ed0925693f23caff0d49de Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 21:14:02 +0300 Subject: [PATCH 0090/4858] rename `wp theme details` to `wp theme status` to match wp plugin status --- commands/internals/plugin.php | 130 ++++++++++++++++++---------------- commands/internals/theme.php | 43 ++++++----- 2 files changed, 88 insertions(+), 85 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 4ad7e57870..847e1d49d1 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -19,90 +19,94 @@ public static function get_description() { } /** - * Get the status of one plugin + * Get the status of one or all plugins * * @param array $args * @return void */ function status( $args = array(), $vars = array() ) { - // Force WordPress to update the plugin list - wp_update_plugins(); + if ( empty( $args ) ) { + $this->list_plugins(); + return; + } - if ( !empty( $args ) ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - $mu_plugins = get_mu_plugins(); + $mu_plugins = get_mu_plugins(); + + $details = $this->get_details( $file ); + + // Get the plugin status + if ( isset( $mu_plugins[ $file ] ) ) + $status = '%cMust Use'; + elseif ( is_plugin_active_for_network( $file ) ) + $status = '%bNetwork Activated'; + elseif ( is_plugin_active( $file ) ) + $status = '%gYes'; + else + $status = '%rNo'; + + // Display the plugin details + WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); + WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + WP_CLI::line( ' Active: ' . $status .'%n' ); + WP_CLI::line( ' Version: ' . $details[ 'Version' ] . ( WP_CLI::get_update_status( $file, 'update_plugins' ) ? ' (%gUpdate available%n)' : '' ) ); + WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); + WP_CLI::line( ' Author: ' . $details[ 'Author' ]); + } - $details = $this->get_details( $file ); + private function list_plugins() { + // Force WordPress to update the plugin list + wp_update_plugins(); - // Get the plugin status - if ( isset( $mu_plugins[ $file ] ) ) - $status = '%cMust Use'; - elseif ( is_plugin_active_for_network( $file ) ) - $status = '%bNetwork Activated'; - elseif ( is_plugin_active( $file ) ) - $status = '%gYes'; - else - $status = '%rNo'; - - // Display the plugin details - WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); - WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); - WP_CLI::line( ' Active: ' . $status .'%n' ); - WP_CLI::line( ' Version: ' . $details[ 'Version' ] . ( WP_CLI::get_update_status( $file, 'update_plugins' ) ? ' (%gUpdate available%n)' : '' ) ); - WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); - WP_CLI::line( ' Author: ' . $details[ 'Author' ]); - } - else { - $plugins = get_plugins(); + $plugins = get_plugins(); - $mu_plugins = get_mu_plugins(); + $mu_plugins = get_mu_plugins(); - $plugins = array_merge($plugins, $mu_plugins); + $plugins = array_merge($plugins, $mu_plugins); - // Print the header - WP_CLI::line('Installed plugins:'); + // Print the header + WP_CLI::line('Installed plugins:'); - foreach ($plugins as $file => $plugin) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace('.php', '', basename($file)); - else - $name = dirname($file); + foreach ($plugins as $file => $plugin) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace('.php', '', basename($file)); + else + $name = dirname($file); - if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { - $line = ' %yU%n'; - } else { - $line = ' '; - } + if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { + $line = ' %yU%n'; + } else { + $line = ' '; + } - if ( isset($mu_plugins[$file]) ) - $line .= '%cM'; - elseif ( is_plugin_active_for_network($file) ) - $line .= '%bN'; - elseif ( is_plugin_active($file) ) - $line .= '%gA'; - else - $line .= 'I'; + if ( isset($mu_plugins[$file]) ) + $line .= '%cM'; + elseif ( is_plugin_active_for_network($file) ) + $line .= '%bN'; + elseif ( is_plugin_active($file) ) + $line .= '%gA'; + else + $line .= 'I'; - $line .= ' '.$name.'%n'; + $line .= ' '.$name.'%n'; - WP_CLI::line( $line ); - } + WP_CLI::line( $line ); + } - // Print the footer - WP_CLI::line(); + // Print the footer + WP_CLI::line(); - $legend = array( - 'I' => 'Inactive', - '%gA' => 'Active', - '%cM' => 'Must Use', - ); + $legend = array( + 'I' => 'Inactive', + '%gA' => 'Active', + '%cM' => 'Must Use', + ); - if ( is_multisite() ) - $legend['%bN'] = 'Network Active'; + if ( is_multisite() ) + $legend['%bN'] = 'Network Active'; - WP_CLI::legend( $legend ); - } + WP_CLI::legend( $legend ); } /** diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 22c8a50f26..43e9d1f5c1 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -17,12 +17,31 @@ public static function get_description() { } /** - * Get the status of all themes + * Get the status of one or all themes * * @param array $args * @return void **/ - public function status($args = array()) { + public function status( $args = array() ) { + if ( empty( $args ) ) { + $this->list_themes(); + return; + } + + // Get the info of the theme + $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + + // Get the current theme + $theme_name = get_current_theme(); + + WP_CLI::line('Theme %2'.$details['Name'].'%n details:'); + WP_CLI::line(' Active: '.((int) ($details['Name'] == $theme_name))); + WP_CLI::line(' Version: '.$details['Version']); + WP_CLI::line(' Author: '.strip_tags($details['Author'])); + //WP_CLI::line(' Description: '.strip_tags($details['Description'])); + } + + private function list_themes() { // Get the list of themes $themes = get_themes(); @@ -59,26 +78,6 @@ public function status($args = array()) { WP_CLI::legend( $legend ); } - /** - * Get theme details - * - * @param array $args - * @return void - **/ - public function details($args = array()) { - // Get the info of the theme - $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); - - // Get the current theme - $theme_name = get_current_theme(); - - WP_CLI::line('Theme %2'.$details['Name'].'%n details:'); - WP_CLI::line(' Active: '.((int) ($details['Name'] == $theme_name))); - WP_CLI::line(' Version: '.$details['Version']); - WP_CLI::line(' Author: '.strip_tags($details['Author'])); - //WP_CLI::line(' Description: '.strip_tags($details['Description'])); - } - /** * Activate a theme * From c5bc34aa949ad30848fa8711f96748cdfb1e9112 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 21:27:24 +0300 Subject: [PATCH 0091/4858] use helper function for determining plugin status --- commands/internals/plugin.php | 53 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 847e1d49d1..1ceb566438 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -18,6 +18,8 @@ public static function get_description() { return 'Do cool things with plugins.'; } + private $mu_plugins; + /** * Get the status of one or all plugins * @@ -25,6 +27,8 @@ public static function get_description() { * @return void */ function status( $args = array(), $vars = array() ) { + $this->mu_plugins = get_mu_plugins(); + if ( empty( $args ) ) { $this->list_plugins(); return; @@ -32,24 +36,13 @@ function status( $args = array(), $vars = array() ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - $mu_plugins = get_mu_plugins(); - $details = $this->get_details( $file ); - // Get the plugin status - if ( isset( $mu_plugins[ $file ] ) ) - $status = '%cMust Use'; - elseif ( is_plugin_active_for_network( $file ) ) - $status = '%bNetwork Activated'; - elseif ( is_plugin_active( $file ) ) - $status = '%gYes'; - else - $status = '%rNo'; - - // Display the plugin details + $status = $this->get_status( $file, true ); + WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); - WP_CLI::line( ' Active: ' . $status .'%n' ); + WP_CLI::line( ' Status: ' . $status .'%n' ); WP_CLI::line( ' Version: ' . $details[ 'Version' ] . ( WP_CLI::get_update_status( $file, 'update_plugins' ) ? ' (%gUpdate available%n)' : '' ) ); WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); WP_CLI::line( ' Author: ' . $details[ 'Author' ]); @@ -61,9 +54,7 @@ private function list_plugins() { $plugins = get_plugins(); - $mu_plugins = get_mu_plugins(); - - $plugins = array_merge($plugins, $mu_plugins); + $plugins = array_merge( $plugins, $this->mu_plugins ); // Print the header WP_CLI::line('Installed plugins:'); @@ -80,16 +71,7 @@ private function list_plugins() { $line = ' '; } - if ( isset($mu_plugins[$file]) ) - $line .= '%cM'; - elseif ( is_plugin_active_for_network($file) ) - $line .= '%bN'; - elseif ( is_plugin_active($file) ) - $line .= '%gA'; - else - $line .= 'I'; - - $line .= ' '.$name.'%n'; + $line .= $this->get_status( $file ) . " $name%n"; WP_CLI::line( $line ); } @@ -109,6 +91,23 @@ private function list_plugins() { WP_CLI::legend( $legend ); } + private function get_status( $file, $long = false ) { + if ( isset( $this->mu_plugins[ $file ] ) ) { + $line = '%c'; + $line .= $long ? 'Must Use' : 'M'; + } elseif ( is_plugin_active_for_network( $file ) ) { + $line = '%b'; + $line .= $long ? 'Network Active' : 'N'; + } elseif ( is_plugin_active( $file ) ) { + $line = '%g'; + $line .= $long ? 'Active' : 'A'; + } else { + $line = $long ? 'Inactive' : 'I'; + } + + return $line; + } + /** * Activate a plugin * From de970025ba79285cebdb5bdc6a158581f0f2364c Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 21:36:45 +0300 Subject: [PATCH 0092/4858] use bold text for theme name, as for plugins --- commands/internals/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 43e9d1f5c1..e1b7979f45 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -34,7 +34,7 @@ public function status( $args = array() ) { // Get the current theme $theme_name = get_current_theme(); - WP_CLI::line('Theme %2'.$details['Name'].'%n details:'); + WP_CLI::line('Theme %9'.$details['Name'].'%n details:'); WP_CLI::line(' Active: '.((int) ($details['Name'] == $theme_name))); WP_CLI::line(' Version: '.$details['Version']); WP_CLI::line(' Author: '.strip_tags($details['Author'])); From bfed58d9769a2db7594893ffdc5a7f7482cf7f98 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 6 Oct 2011 22:04:01 +0300 Subject: [PATCH 0093/4858] make `wp theme status` more similar to `wp plugin status` --- commands/internals/plugin.php | 11 +++++--- commands/internals/theme.php | 50 ++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 1ceb566438..543094f5d7 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -40,12 +40,17 @@ function status( $args = array(), $vars = array() ) { $status = $this->get_status( $file, true ); + $version = $details[ 'Version' ]; + + if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) + $version .= ' (%gUpdate available%n)'; + WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); - WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); WP_CLI::line( ' Status: ' . $status .'%n' ); - WP_CLI::line( ' Version: ' . $details[ 'Version' ] . ( WP_CLI::get_update_status( $file, 'update_plugins' ) ? ' (%gUpdate available%n)' : '' ) ); + WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + WP_CLI::line( ' Version: ' . $version ); + WP_CLI::line( ' Author: ' . $details[ 'Author' ] ); WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); - WP_CLI::line( ' Author: ' . $details[ 'Author' ]); } private function list_plugins() { diff --git a/commands/internals/theme.php b/commands/internals/theme.php index e1b7979f45..92bbd0d3b8 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -28,41 +28,36 @@ public function status( $args = array() ) { return; } - // Get the info of the theme - $details = get_theme_data(WP_CONTENT_DIR.'/themes/'.$args[0].'/style.css'); + $name = $args[0]; - // Get the current theme - $theme_name = get_current_theme(); + $details = get_theme_data( $this->get_stylesheet_path( $name ) ); - WP_CLI::line('Theme %9'.$details['Name'].'%n details:'); - WP_CLI::line(' Active: '.((int) ($details['Name'] == $theme_name))); - WP_CLI::line(' Version: '.$details['Version']); - WP_CLI::line(' Author: '.strip_tags($details['Author'])); - //WP_CLI::line(' Description: '.strip_tags($details['Description'])); + $status = $this->get_status( $details['Name'], true ); + + $version = $details[ 'Version' ]; + + if ( WP_CLI::get_update_status( $name, 'update_themes' ) ) + $version .= ' (%gUpdate available%n)'; + + WP_CLI::line( 'Theme %9' . $name . '%n details:' ); + WP_CLI::line( ' Status: ' . $status .'%n' ); + WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + WP_CLI::line( ' Version: ' . $version ); + WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } private function list_themes() { - // Get the list of themes - $themes = get_themes(); - // Print the header - WP_CLI::line('Installed themes:'); - - $theme_name = get_current_theme(); + WP_CLI::line( 'Installed themes:' ); - foreach ($themes as $key => $theme) { + foreach ( get_themes() as $theme ) { if ( WP_CLI::get_update_status( $theme['Stylesheet'], 'update_themes' ) ) { $line = ' %yU%n'; } else { $line = ' '; } - if ( $theme['Name'] == $theme_name ) - $line .= '%gA'; - else - $line .= 'I'; - - $line .= ' ' . $theme['Stylesheet'].'%n'; + $line .= $this->get_status( $theme['Name'] ) . ' ' . $theme['Stylesheet'] . '%n'; WP_CLI::line( $line ); } @@ -78,6 +73,17 @@ private function list_themes() { WP_CLI::legend( $legend ); } + private function get_status( $theme_name, $long = false ) { + if ( get_current_theme() == $theme_name ) { + $line = '%g'; + $line .= $long ? 'Active' : 'A'; + } else { + $line = $long ? 'Inactive' : 'I'; + } + + return $line; + } + /** * Activate a theme * From 1a0df2276870f23b6dbe8170ef72f95e6c889af1 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 03:39:12 +0300 Subject: [PATCH 0094/4858] deprecate get_description() method in favor of dedicated help methods --- class-wp-cli-command.php | 16 +++------------- commands/internals/core.php | 18 ++++++++++++++---- commands/internals/generate.php | 27 +++++++++++++++++++++++---- commands/internals/home.php | 15 +++++++-------- commands/internals/option.php | 31 ++++++++----------------------- commands/internals/plugin.php | 33 ++++++++++++++------------------- commands/internals/theme.php | 24 +++++++++--------------- 7 files changed, 78 insertions(+), 86 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index e8c75c43c5..d1808bbef6 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -8,15 +8,6 @@ */ abstract class WP_CLI_Command { - /** - * Return a short description for the command. - * - * @return string - */ - public static function get_description() { - return false; - } - /** * Keeps a reference to the current command name * @@ -55,7 +46,7 @@ protected function dispatch( $args, $assoc_args ) { if ( !method_exists($this, $sub_command) || isset( $assoc_args[ 'help' ] ) ) { $sub_command = 'help'; } - + $this->$sub_command($args, $assoc_args); } @@ -67,9 +58,8 @@ protected function dispatch( $args, $assoc_args ) { * @return void */ public function help( $args = array(), $assoc_args = array() ) { - $desc = $this->get_description(); - if ( $desc ) { - WP_CLI::line( $desc ); + if ( method_exists( $this, 'get_description' ) ) { + WP_CLI::line( $this->get_description() ); WP_CLI::line(); } diff --git a/commands/internals/core.php b/commands/internals/core.php index a496f7aef2..d1af5d6b38 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -12,10 +12,6 @@ */ class CoreCommand extends WP_CLI_Command { - public static function get_description() { - return 'Update the WordPress core.'; - } - /** * Update the WordPress core * @@ -46,4 +42,18 @@ function update($args) { WP_CLI::success('WordPress upgraded successfully.'); } } + + /** + * Help function for this command + * + * @param array $args + * @return void + */ + public function help( $args = array() ) { + WP_CLI::line( 'usage: wp core update' ); + + WP_CLI::sub_commands( array( + 'update' => 'update the WordPress core files from wordpress.org', + ) ); + } } diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 0d1d654ae6..9329e04012 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -12,10 +12,6 @@ */ class GenerateCommand extends WP_CLI_Command { - public static function get_description() { - return 'Generate a certain number of objects.'; - } - /** * Generate posts * @@ -96,4 +92,27 @@ public function users( $args, $assoc_args ) { ) ); } } + + /** + * Help function for this command + * + * @param array $args + * @return void + */ + public function help( $args = array() ) { + WP_CLI::out( << [--count=100] + +Available object types: + posts generate some posts + --count number of users to generate (default: 100) + --type post type (default: 'post') + --status post status (default: 'publish') + users generate some users + --count number of users to generate (default: 100) + --role user role (default: default_role option) + +EOB + ); + } } diff --git a/commands/internals/home.php b/commands/internals/home.php index 7e34a80b19..6bab53e12a 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -12,10 +12,6 @@ */ class HomeCommand extends WP_CLI_Command { - public static function get_description() { - return 'Open the wp-cli project on Github.'; - } - /** * Overwrite the dispatch method to have a command without sub-commands. * @@ -54,9 +50,12 @@ protected function dispatch( $args, $assoc_args ) { * @return void */ public function help($args = array()) { - WP_CLI::line('This command has no arguments; when called it will open the wp-cli homepage in your browser.'); - WP_CLI::line(); - WP_CLI::line('Example usage:'); - WP_CLI::line(' wp home'); + WP_CLI::out( << '); - WP_CLI::line(' wp option update '); - WP_CLI::line(' wp option delete '); - WP_CLI::line(' wp option get '); - WP_CLI::line(''); - WP_CLI::line('%9--- DETAILS ---%n'); - WP_CLI::line(''); - WP_CLI::line('Adding a new option:'); - WP_CLI::line(' wp option add '); - WP_CLI::line(''); - WP_CLI::line('Updating an option:'); - WP_CLI::line(' wp option update '); - WP_CLI::line(''); - WP_CLI::line('Deleting an option:'); - WP_CLI::line(' wp option delete '); - WP_CLI::line(''); - WP_CLI::line('Get the value of an option:'); - WP_CLI::line(' wp option get '); + WP_CLI::out( << + or: wp option add + or: wp option update + or: wp option delete + +EOB + ); } } diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 543094f5d7..fe800e2dc2 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -14,10 +14,6 @@ */ class PluginCommand extends WP_CLI_Command { - public static function get_description() { - return 'Do cool things with plugins.'; - } - private $mu_plugins; /** @@ -326,20 +322,19 @@ private function parse_name( $args, $sub_command, $exit = true ) { * @return void */ public function help( $args = array() ) { - // Shot the command description - WP_CLI::line( $this->get_description() ); - WP_CLI::line(); - - // Show the list of sub-commands for this command - WP_CLI::line( 'Example usage:' ); - - foreach ( WP_CLI_Command::get_methods( $this ) as $method ) { - if ( $method != 'help' ) { - WP_CLI::line( ' wp '.$this->command.' '.$method.' hello-dolly' ); - } - else { - WP_CLI::line( ' wp '.$this->command.' '.$method ); - } - } + WP_CLI::out( << [] + +Available sub-commands: + status display status of all installed plugins or of a particular plugin + activate activate a particular plugin + deactivate deactivate a particular plugin + toggle toggle activation state of a particular plugin + install install a plugin from wordpress.org + update update a plugin from wordpress.org + delete delete a plugin + +EOB + ); } } diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 92bbd0d3b8..ed8373ccef 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -12,10 +12,6 @@ */ class ThemeCommand extends WP_CLI_Command { - public static function get_description() { - return 'Do cool things with themes.'; - } - /** * Get the status of one or all themes * @@ -130,16 +126,14 @@ protected function get_stylesheet_path( $theme ) { * @return void */ public function help($args = array()) { - WP_CLI::line('Example usage:'); - WP_CLI::line(' wp theme status'); - WP_CLI::line(' wp theme details '); - WP_CLI::line(''); - WP_CLI::line('%9--- DETAILS ---%n'); - WP_CLI::line(''); - WP_CLI::line('Get a status of the installed themes:'); - WP_CLI::line(' wp theme status'); - WP_CLI::line(''); - WP_CLI::line('Get the details for a theme:'); - WP_CLI::line(' wp theme details '); + WP_CLI::out( << [] + +Available sub-commands: + status display status of all installed themes or of a particular theme + activate activate a particular theme + +EOB + ); } } From fe72efd28ce903a6f4c0c965c7b138cbda02480d Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 03:44:00 +0300 Subject: [PATCH 0095/4858] make GenerateCommand::help() output more compact --- commands/internals/generate.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 9329e04012..89e6761506 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -101,17 +101,8 @@ public function users( $args, $assoc_args ) { */ public function help( $args = array() ) { WP_CLI::out( << [--count=100] - -Available object types: - posts generate some posts - --count number of users to generate (default: 100) - --type post type (default: 'post') - --status post status (default: 'publish') - users generate some users - --count number of users to generate (default: 100) - --role user role (default: default_role option) - +usage: wp generate posts [--count=100] [--type=post] [--status=publish] + or: wp generate users [--count=100] [--role=] EOB ); } From e32684ccffd17159f1eb6dafb5cf8e8193da8d13 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 04:18:59 +0300 Subject: [PATCH 0096/4858] introduce help command. fixes #22 --- class-wp-cli-command.php | 2 +- class-wp-cli.php | 17 ------------ commands/internals/generate.php | 1 + commands/internals/help.php | 49 +++++++++++++++++++++++++++++++++ wp-cli.php | 4 +-- 5 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 commands/internals/help.php diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index d1808bbef6..4ec9adae52 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -87,7 +87,7 @@ static function get_methods($class) { $methods = array(); foreach ( $reflection->getMethods() as $method ) { - if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() ) { + if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() && 'help' != $method->name ) { $name = $method->name; if ( strpos( $name, '_' ) === 0 ) { diff --git a/class-wp-cli.php b/class-wp-cli.php index 2903390699..1c463c5ade 100644 --- a/class-wp-cli.php +++ b/class-wp-cli.php @@ -115,23 +115,6 @@ static function parse_args( $arguments ) { return array( $regular_args, $assoc_args ); } - /** - * Display the help function for the wp-cli - * - * @return void - */ - static function generalHelp() { - self::line('Example usage:'); - foreach(self::$commands as $name => $command) { - self::out(' wp '.$name); - $methods = WP_CLI_Command::get_methods($command); - if(!empty($methods)) { - self::out(' ['.implode('|', $methods).']'); - } - self::line(' ...'); - } - } - /** * Display a legend * diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 89e6761506..8cfc085c0d 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -103,6 +103,7 @@ public function help( $args = array() ) { WP_CLI::out( <<] + EOB ); } diff --git a/commands/internals/help.php b/commands/internals/help.php new file mode 100644 index 0000000000..547f867440 --- /dev/null +++ b/commands/internals/help.php @@ -0,0 +1,49 @@ +generalHelp(); + } else { + $command = $args[0]; + if ( 'help' == $command || !isset( WP_CLI::$commands[$command] ) ) { + $this->generalHelp(); + } else { + new WP_CLI::$commands[$command]( $command, array( 'help' ), array() ); + } + } + } + + private function generalHelp() { + WP_CLI::line('Example usage:'); + foreach ( WP_CLI::$commands as $name => $command ) { + if ( 'help' == $name ) + continue; + + WP_CLI::out( ' wp ' . $name ); + $methods = WP_CLI_Command::get_methods( $command ); + if( !empty( $methods ) ) { + WP_CLI::out( ' [' . implode( '|', $methods ) . ']' ); + } + WP_CLI::line(' ...'); + } + WP_CLI::line(' wp --version'); + WP_CLI::line(); + WP_CLI::line( "See 'wp help ' for more information on a specific command." ); + } +} diff --git a/wp-cli.php b/wp-cli.php index 241d08e93a..f188f5f803 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -94,8 +94,8 @@ $command = array_shift( $arguments ); if ( !isset( WP_CLI::$commands[$command] ) ) { - WP_CLI::generalHelp(); - exit(); + WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); + exit; } new WP_CLI::$commands[$command]( $command, $arguments, $assoc_args ); From b60273e6a39bed830d88e9b32a407a0b341e7ecd Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 06:02:44 +0300 Subject: [PATCH 0097/4858] default to 'help' command again when no arguments are passed --- wp-cli.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wp-cli.php b/wp-cli.php index f188f5f803..4cf9cb71d0 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -91,7 +91,10 @@ } // Get the top-level command -$command = array_shift( $arguments ); +if ( empty( $arguments ) ) + $command = 'help'; +else + $command = array_shift( $arguments ); if ( !isset( WP_CLI::$commands[$command] ) ) { WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); From 5d2676d83372948309fc7dafdc60b7a2a0eb3a4c Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 06:07:52 +0300 Subject: [PATCH 0098/4858] move bash scripts to bin directory --- README.md | 4 ++-- wp => bin/wp | 8 ++++---- wp-cli-completion.bash => bin/wp-cli-completion.bash | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename wp => bin/wp (96%) rename wp-cli-completion.bash => bin/wp-cli-completion.bash (100%) mode change 100644 => 100755 diff --git a/README.md b/README.md index 680af9b74c..e2e148c1a2 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,13 @@ git submodule update --init Make a symlink to the executable: ``` -sudo ln -s /path-to-wp-cli-dir/wp /usr/local/bin/ +sudo ln -s /path-to-wp-cli-dir/bin/wp /usr/local/bin/ ``` Make a symlink to the autocomplete file (Linux): ``` -sudo ln -s /path-to-wp-cli-dir/wp-cli-completion.bash /etc/bash_completion.d/wp +sudo ln -s /path-to-wp-cli-dir/bin/wp-cli-completion.bash /etc/bash_completion.d/wp ``` Usage diff --git a/wp b/bin/wp similarity index 96% rename from wp rename to bin/wp index b8336b6dad..dd4fd48d98 100755 --- a/wp +++ b/bin/wp @@ -1,13 +1,13 @@ #!/usr/bin/env sh # -# This script has been adapted from the drush wrapper script +# This script has been adapted from the drush wrapper script # and 99.9% of all credit should go to the authors of that project: # http://drupal.org/project/drush # And 0.09% to the author of this project: # https://github.com/88mph/wpadmin/blob/master/wpadmin.php -# +# # This is a wrapper script that will run wp-cli.php with the most appropriate -# php executable it can find on your system. +# php executable it can find on your system. # # Set the required PHP version @@ -30,7 +30,7 @@ done cd "$ORIGDIR" # Build the path to wp-cli.php. -SCRIPT_PATH=$(dirname "$SELF_PATH")/wp-cli.php +SCRIPT_PATH=$(dirname "$SELF_PATH")/../wp-cli.php case $(uname -a) in CYGWIN*) SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; diff --git a/wp-cli-completion.bash b/bin/wp-cli-completion.bash old mode 100644 new mode 100755 similarity index 100% rename from wp-cli-completion.bash rename to bin/wp-cli-completion.bash From ed8e6f198f2c041972b302128ce18c355f2d459b Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 06:28:58 +0300 Subject: [PATCH 0099/4858] don't need #!bash in completion script --- bin/wp-cli-completion.bash | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) mode change 100755 => 100644 bin/wp-cli-completion.bash diff --git a/bin/wp-cli-completion.bash b/bin/wp-cli-completion.bash old mode 100755 new mode 100644 index 39ec5b6493..2e7e420258 --- a/bin/wp-cli-completion.bash +++ b/bin/wp-cli-completion.bash @@ -1,7 +1,5 @@ -#!bash -# -# bash completion support for the wp command -# +# bash completion for the wp command + _wp() { local cur prev opts From 30e51c29cfef3688faddf9ccc7673d41eeccb4f6 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 07:38:13 +0300 Subject: [PATCH 0100/4858] add build-deb bash script --- bin/build-deb | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 bin/build-deb diff --git a/bin/build-deb b/bin/build-deb new file mode 100755 index 0000000000..0470829587 --- /dev/null +++ b/bin/build-deb @@ -0,0 +1,72 @@ +#!/bin/bash + +# script for generating a .deb file + +SOURCE_DIR=$(pwd) + +ROOT_DIR='usr/share/php/wp-cli' + +rm -rf /tmp/wp-cli + +mkdir -p /tmp/wp-cli/DEBIAN + +cd /tmp/wp-cli + +mkdir -p $ROOT_DIR + +rsync -r --exclude='*.git*' $SOURCE_DIR/* $ROOT_DIR/ + +# remove junk files +find . -name "*~" -exec rm {} \; +find . -name "*.swp" -exec rm {} \; + +# reset permsissions and ownership +chown -R root . +chgrp -R root . +find . -type f -exec chmod 644 {} \; +find . -type d -exec chmod 755 {} \; + +# use a simple bash wrapper for the command, since we know where everything is +mkdir -p usr/bin + +cat > usr/bin/wp < DEBIAN/control <= 5.3) +Installed-Size: 150 +Maintainer: Cristi Burca +Description: WordPress command-line interface + A tool for controlling WordPress installations via the command-line. +EOT + +cat > DEBIAN/postinst < DEBIAN/postinst < Date: Fri, 7 Oct 2011 07:42:50 +0300 Subject: [PATCH 0101/4858] add link to .deb download. see #7 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e2e148c1a2..c2d64e1bf7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ A tool to control WordPress installations from the command line. Installing ---------- +If you're on Ubuntu or Debian, just use the [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) + Clone the project: ``` From 678a05368b0903a38743b26034c32cb727ea2362 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Fri, 7 Oct 2011 10:35:21 +0200 Subject: [PATCH 0102/4858] Pushed to version 0.2 --- bin/build-deb | 2 +- wp-cli.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/build-deb b/bin/build-deb index 0470829587..4a0a53830e 100755 --- a/bin/build-deb +++ b/bin/build-deb @@ -43,7 +43,7 @@ mv $ROOT_DIR/LICENSE usr/share/doc/wp-cli/copyright cat > DEBIAN/control < Date: Fri, 7 Oct 2011 15:00:16 +0100 Subject: [PATCH 0103/4858] Removed deprecated description function. --- commands/community/google-sitemap-generator.php | 6 +----- commands/community/w3-total-cache.php | 6 +----- commands/community/wp-super-cache.php | 6 +----- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index c5d7dbaa46..4485fadb14 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -14,10 +14,6 @@ */ class GoogleSitemapGeneratorCommand extends WP_CLI_Command { - public static function get_description() { - return 'Generate Google Sitemaps.'; - } - /** * Re-generate the sitemap * @@ -37,7 +33,7 @@ function rebuild( $args = array(), $vars = array() ) { */ public function help($args = array()) { // Shot the command description - WP_CLI::line( $this->get_description() ); + WP_CLI::line( 'Generate Google Sitemaps.' ); WP_CLI::line(); // Show the list of sub-commands for this command diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php index 98d0fcca1d..a0c7913f42 100644 --- a/commands/community/w3-total-cache.php +++ b/commands/community/w3-total-cache.php @@ -14,10 +14,6 @@ */ class W3TotalCacheCommand extends WP_CLI_Command { - public static function get_description() { - return 'Manage the W3 Total Cache.'; - } - /** * Clear something from the cache * @@ -91,7 +87,7 @@ function flush( $args = array(), $vars = array() ) { */ public function help($args = array()) { // Shot the command description - WP_CLI::line( $this->get_description() ); + WP_CLI::line( 'Manage the W3 Total Cache.' ); WP_CLI::line(); // Show the list of sub-commands for this command diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index c782386989..08cc90fc01 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -14,10 +14,6 @@ */ class WPSuperCacheCommand extends WP_CLI_Command { - public static function get_description() { - return 'Manage the WP Super Cache.'; - } - /** * Clear something from the cache * @@ -133,7 +129,7 @@ function disable( $args = array(), $vars = array() ) { */ public function help($args = array()) { // Shot the command description - WP_CLI::line( $this->get_description() ); + WP_CLI::line( 'Manage the WP Super Cache.' ); WP_CLI::line(); // Show the list of sub-commands for this command From 6569531912a3b451b602e7ac7937a5982ef58e53 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 7 Oct 2011 15:31:21 +0100 Subject: [PATCH 0104/4858] Reformed documentation. --- commands/community/w3-total-cache.php | 38 ++++++++----------------- commands/community/wp-super-cache.php | 41 +++++++-------------------- 2 files changed, 23 insertions(+), 56 deletions(-) diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php index a38c528e69..8d6da3bc95 100644 --- a/commands/community/w3-total-cache.php +++ b/commands/community/w3-total-cache.php @@ -86,32 +86,18 @@ function flush( $args = array(), $vars = array() ) { * @return void */ public function help($args = array()) { - // Shot the command description - WP_CLI::line( 'Manage the W3 Total Cache.' ); - WP_CLI::line(); + // Show the command description + WP_CLI::out( <<] [--permalink=] - // Show the list of sub-commands for this command - WP_CLI::line('Example usage:'); - WP_CLI::line(' wp total-cache flush [post|database|minify|object] [--post_id=] [--permalink=]'); - WP_CLI::line(); - WP_CLI::line('%9--- DETAILS ---%n'); - WP_CLI::line(); - WP_CLI::line('Remove all post/page caches:'); - WP_CLI::line(' wp total-cache flush'); - WP_CLI::line(); - WP_CLI::line('Remove the caches for one blog post based on the id:'); - WP_CLI::line(' wp total-cache flush --post_id=1'); - WP_CLI::line(); - WP_CLI::line('Remove the caches for one blog post based on the permalink:'); - WP_CLI::line(' wp total-cache flush --permalink=http://example.com'); - WP_CLI::line(); - WP_CLI::line('Remove the database cache:'); - WP_CLI::line(' wp total-cache flush database'); - WP_CLI::line(); - WP_CLI::line('Remove the object cache:'); - WP_CLI::line(' wp total-cache flush object'); - WP_CLI::line(); - WP_CLI::line('Remove the minify cache:'); - WP_CLI::line(' wp total-cache flush minify'); +Avaliable sub-commands: + flush Flushes whole cache + --post_id= Flush specific ID + --permalink= Flush specific permalink + database Flushes database cache + object Flush object cache + minify Flush minify cache +EOB + ); } } diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index 1369a849ac..4a664c7e03 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -128,35 +128,16 @@ function disable( $args = array(), $vars = array() ) { * @return void */ public function help($args = array()) { - // Shot the command description - WP_CLI::line( 'Manage the WP Super Cache.' ); - WP_CLI::line(); + // Show the command description + WP_CLI::out( << - // Show the list of sub-commands for this command - WP_CLI::line('Example usage:'); - WP_CLI::line(' wp wp-super-cache flush [--post_id=] [--permalink=]'); - WP_CLI::line(' wp wp-super-cache status'); - WP_CLI::line(' wp wp-super-cache enable'); - WP_CLI::line(' wp wp-super-cache disable'); - WP_CLI::line(); - WP_CLI::line('%9--- DETAILS ---%n'); - WP_CLI::line(); - WP_CLI::line('Remove the whole cache content:'); - WP_CLI::line(' wp wp-super-cache flush'); - WP_CLI::line(); - WP_CLI::line('Remove the caches for one blog post based on the id:'); - WP_CLI::line(' wp wp-super-cache flush --post_id=1'); - WP_CLI::line(); - WP_CLI::line('Remove the caches for one blog post based on the permalink:'); - WP_CLI::line(' wp wp-super-cache flush --permalink=http://example.com'); - WP_CLI::line(); - WP_CLI::line('Get details on the WP Super Cache content:'); - WP_CLI::line(' wp wp-super-cache status'); - WP_CLI::line(); - WP_CLI::line('Enable the WP Super Cache:'); - WP_CLI::line(' wp wp-super-cache enable'); - WP_CLI::line(); - WP_CLI::line('Disable the WP Super Cache:'); - WP_CLI::line(' wp wp-super-cache disable'); - } +Avaliable sub-commands: + flush Flushes whole cache, or post with given permalink or ID --post_id= --permalink= + status shows status of WP Super Cache + enable enables WP Super Cache + disable Disables WP Super Cache +EOB + ); + } } From 474c2990329a82cf4977e2c8ca3ef5fcc1e6d9d8 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 7 Oct 2011 15:32:26 +0100 Subject: [PATCH 0105/4858] Added additional details. --- commands/community/wp-super-cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index 4a664c7e03..ae60e0c9d3 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -130,7 +130,7 @@ function disable( $args = array(), $vars = array() ) { public function help($args = array()) { // Show the command description WP_CLI::out( << +usage: wp super-cache [flush|status|enable|disable] --post_id= --permalink= Avaliable sub-commands: flush Flushes whole cache, or post with given permalink or ID --post_id= --permalink= From 5f7dcff4b5cb95b12fb07d3b1ca3a3b05c2131fd Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 7 Oct 2011 15:35:52 +0100 Subject: [PATCH 0106/4858] Reformatted help command. --- .../community/google-sitemap-generator.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index 2df220283b..b75966434f 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -32,17 +32,13 @@ function rebuild( $args = array(), $vars = array() ) { * @return void */ public function help($args = array()) { - // Shot the command description - WP_CLI::line( 'Generate Google Sitemaps.' ); - WP_CLI::line(); + // Show the command description + WP_CLI::out( << Date: Fri, 7 Oct 2011 15:38:37 +0100 Subject: [PATCH 0107/4858] Consistency of capitalisation. --- commands/community/google-sitemap-generator.php | 2 +- commands/community/w3-total-cache.php | 12 ++++++------ commands/community/wp-super-cache.php | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index b75966434f..80ac37e3d8 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -37,7 +37,7 @@ public function help($args = array()) { usage: wp google-sitemap [rebuild] Avaliable sub-commands: - rebuild Rebuild Google sitemap + rebuild rebuild Google sitemap EOB ); } diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php index 8d6da3bc95..c7d4a48e76 100644 --- a/commands/community/w3-total-cache.php +++ b/commands/community/w3-total-cache.php @@ -91,12 +91,12 @@ public function help($args = array()) { usage: wp total-cache flush [post|database|minify|object] [--post_id=] [--permalink=] Avaliable sub-commands: - flush Flushes whole cache - --post_id= Flush specific ID - --permalink= Flush specific permalink - database Flushes database cache - object Flush object cache - minify Flush minify cache + flush flushes whole cache + --post_id= flush specific ID + --permalink= flush specific permalink + database flushes database cache + object flush object cache + minify flush minify cache EOB ); } diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index ae60e0c9d3..ac780064c5 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -133,10 +133,10 @@ public function help($args = array()) { usage: wp super-cache [flush|status|enable|disable] --post_id= --permalink= Avaliable sub-commands: - flush Flushes whole cache, or post with given permalink or ID --post_id= --permalink= + flush flushes whole cache, or post with given permalink or ID --post_id= --permalink= status shows status of WP Super Cache enable enables WP Super Cache - disable Disables WP Super Cache + disable disables WP Super Cache EOB ); } From fffda6326c33c4ff592d11050adf82745b2a2c7e Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 19:40:16 +0300 Subject: [PATCH 0108/4858] don't even look for get_description() anymore --- class-wp-cli-command.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 4ec9adae52..e1ea58a37a 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -51,23 +51,17 @@ protected function dispatch( $args, $assoc_args ) { } /** - * General help function for this command + * General help function for the current command * * @param array $args - * @param string $assoc_args * @return void */ - public function help( $args = array(), $assoc_args = array() ) { - if ( method_exists( $this, 'get_description' ) ) { - WP_CLI::line( $this->get_description() ); - WP_CLI::line(); - } - + public function help( $args = array() ) { // Show the list of sub-commands for this command WP_CLI::line( 'Example usage:' ); WP_CLI::out( ' wp '.$this->command ); - $methods = WP_CLI_Command::get_methods($this); + $methods = self::get_methods($this); if ( !empty( $methods ) ) { WP_CLI::out(' ['.implode('|', $methods).']'); } From 59cad8224925c7bf87a4349be7618aeae7761aa6 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 19:42:46 +0300 Subject: [PATCH 0109/4858] rename get_methods() to get_subcommands() --- class-wp-cli-command.php | 6 +++--- commands/internals/help.php | 2 +- wp-cli.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index e1ea58a37a..ada3571dc8 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -61,7 +61,7 @@ public function help( $args = array() ) { WP_CLI::line( 'Example usage:' ); WP_CLI::out( ' wp '.$this->command ); - $methods = self::get_methods($this); + $methods = self::get_subcommands($this); if ( !empty( $methods ) ) { WP_CLI::out(' ['.implode('|', $methods).']'); } @@ -70,12 +70,12 @@ public function help( $args = array() ) { } /** - * Get the filtered list of methods for a class. + * Get the list of subcommands for a class. * * @param string $class * @return array The list of methods */ - static function get_methods($class) { + static function get_subcommands($class) { $reflection = new ReflectionClass( $class ); $methods = array(); diff --git a/commands/internals/help.php b/commands/internals/help.php index 547f867440..dda5cc8054 100644 --- a/commands/internals/help.php +++ b/commands/internals/help.php @@ -36,7 +36,7 @@ private function generalHelp() { continue; WP_CLI::out( ' wp ' . $name ); - $methods = WP_CLI_Command::get_methods( $command ); + $methods = WP_CLI_Command::get_subcommands( $command ); if( !empty( $methods ) ) { WP_CLI::out( ' [' . implode( '|', $methods ) . ']' ); } diff --git a/wp-cli.php b/wp-cli.php index 5d24c4cb06..4922200bdb 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -85,7 +85,7 @@ // Handle --completions parameter if ( isset( $assoc_args['completions'] ) ) { foreach ( WP_CLI::$commands as $name => $command ) { - WP_CLI::line( $name . ' ' . implode( ' ', WP_CLI_Command::get_methods($command) ) ); + WP_CLI::line( $name . ' ' . implode( ' ', WP_CLI_Command::get_subcommands($command) ) ); } exit; } From 5d1af832430d5949f87813814b08463929c0c2d2 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 19:48:06 +0300 Subject: [PATCH 0110/4858] fix some comments --- class-wp-cli-command.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index ada3571dc8..93d754b2c8 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -16,7 +16,7 @@ abstract class WP_CLI_Command { protected $command; /** - * Construct for this class, transfers the cli arguments to the right class + * Constructor * * @param string $command * @param array $args @@ -35,19 +35,18 @@ function __construct( $command, $args, $assoc_args ) { * @param array $assoc_args */ protected function dispatch( $args, $assoc_args ) { - // The first command is the sub command - $sub_command = array_shift($args); + $sub_command = array_shift( $args ); - if ( !method_exists($this, $sub_command) ) { + if ( !method_exists( $this, $sub_command ) ) { // This if for reserved keywords in php (like list, isset) $sub_command = '_'.$sub_command; } - if ( !method_exists($this, $sub_command) || isset( $assoc_args[ 'help' ] ) ) { + if ( !method_exists( $this, $sub_command ) || isset( $assoc_args[ 'help' ] ) ) { $sub_command = 'help'; } - $this->$sub_command($args, $assoc_args); + $this->$sub_command( $args, $assoc_args ); } /** From 9023fc1bf1269979e9ac17e2bd7a2d21091ba86c Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 19:53:11 +0300 Subject: [PATCH 0111/4858] fix help method for the command --- commands/internals/core.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/commands/internals/core.php b/commands/internals/core.php index d1af5d6b38..3abffb8732 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -50,10 +50,12 @@ function update($args) { * @return void */ public function help( $args = array() ) { - WP_CLI::line( 'usage: wp core update' ); + WP_CLI::out( << 'update the WordPress core files from wordpress.org', - ) ); +Update the WordPress core files from wordpress.org + +EOB + ); } } From 2a4efd68736cbcbce1423bf15ec3357266507d16 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 19:58:17 +0300 Subject: [PATCH 0112/4858] use WP_CLI::line() instead of WP_CLI::out() for help commands --- .../community/google-sitemap-generator.php | 9 +++---- commands/community/w3-total-cache.php | 27 +++++++++---------- commands/community/wp-super-cache.php | 27 +++++++++---------- commands/internals/core.php | 3 +-- commands/internals/generate.php | 3 +-- commands/internals/home.php | 3 +-- commands/internals/option.php | 3 +-- commands/internals/plugin.php | 3 +-- commands/internals/theme.php | 3 +-- 9 files changed, 36 insertions(+), 45 deletions(-) diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index 80ac37e3d8..494cd5e01b 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -32,13 +32,12 @@ function rebuild( $args = array(), $vars = array() ) { * @return void */ public function help($args = array()) { - // Show the command description - WP_CLI::out( <<] [--permalink=] -Avaliable sub-commands: - flush flushes whole cache - --post_id= flush specific ID - --permalink= flush specific permalink - database flushes database cache - object flush object cache - minify flush minify cache +Available sub-commands: + flush flushes whole cache + --post_id= flush specific ID + --permalink= flush specific permalink + database flushes database cache + object flush object cache + minify flush minify cache EOB - ); + ); } } diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index ac780064c5..64e77f942e 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -29,12 +29,12 @@ function flush( $args = array(), $vars = array() ) { } else { WP_CLI::error('This is not a valid post id.'); } - + wp_cache_post_change( $vars['post_id'] ); } elseif ( isset( $vars['permalink'] ) ) { $id = url_to_postid( $vars['permalink'] ); - + if ( is_numeric( $id ) ) { wp_cache_post_change( $id ); } else { @@ -47,7 +47,7 @@ function flush( $args = array(), $vars = array() ) { WP_CLI::error('The WP Super Cache could not be found, is it installed?'); } } - + /** * Get the status of the cache * @@ -57,7 +57,7 @@ function flush( $args = array(), $vars = array() ) { */ function status( $args = array(), $vars = array() ) { $cache_stats = get_option( 'supercache_stats' ); - + if ( !empty( $cache_stats ) ) { if ( $cache_stats['generated'] > time() - 3600 * 24 ) { global $super_cache_enabled; @@ -78,7 +78,7 @@ function status( $args = array(), $vars = array() ) { WP_CLI::error('No WP Super Cache stats found.'); } } - + /** * Enable the WP Super Cache * @@ -99,7 +99,7 @@ function enable( $args = array(), $vars = array() ) { WP_CLI::error('The WP Super Cache could not be found, is it installed?'); } } - + /** * Disable the WP Super Cache * @@ -128,16 +128,15 @@ function disable( $args = array(), $vars = array() ) { * @return void */ public function help($args = array()) { - // Show the command description - WP_CLI::out( << --permalink= -Avaliable sub-commands: - flush flushes whole cache, or post with given permalink or ID --post_id= --permalink= - status shows status of WP Super Cache - enable enables WP Super Cache - disable disables WP Super Cache +Available sub-commands: + flush flushes whole cache, or post with given permalink or ID --post_id= --permalink= + status shows status of WP Super Cache + enable enables WP Super Cache + disable disables WP Super Cache EOB - ); + ); } } diff --git a/commands/internals/core.php b/commands/internals/core.php index 3abffb8732..2febca34a2 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -50,11 +50,10 @@ function update($args) { * @return void */ public function help( $args = array() ) { - WP_CLI::out( <<] - EOB ); } diff --git a/commands/internals/home.php b/commands/internals/home.php index 6bab53e12a..a226fe6083 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -50,11 +50,10 @@ protected function dispatch( $args, $assoc_args ) { * @return void */ public function help($args = array()) { - WP_CLI::out( << or: wp option add or: wp option update or: wp option delete - EOB ); } diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index fe800e2dc2..e426799cc3 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -322,7 +322,7 @@ private function parse_name( $args, $sub_command, $exit = true ) { * @return void */ public function help( $args = array() ) { - WP_CLI::out( << [] Available sub-commands: @@ -333,7 +333,6 @@ public function help( $args = array() ) { install install a plugin from wordpress.org update update a plugin from wordpress.org delete delete a plugin - EOB ); } diff --git a/commands/internals/theme.php b/commands/internals/theme.php index ed8373ccef..e2f1af9b49 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -126,13 +126,12 @@ protected function get_stylesheet_path( $theme ) { * @return void */ public function help($args = array()) { - WP_CLI::out( << [] Available sub-commands: status display status of all installed themes or of a particular theme activate activate a particular theme - EOB ); } From 48a8887d46be25e0c0ad326975729ec816c17331 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 7 Oct 2011 20:42:50 +0300 Subject: [PATCH 0113/4858] make help method static; revert to __construct() instead of dispatch() --- class-wp-cli-command.php | 45 ++----------------- .../community/google-sitemap-generator.php | 5 +-- commands/community/w3-total-cache.php | 5 +-- commands/community/wp-super-cache.php | 5 +-- commands/internals/core.php | 5 +-- commands/internals/generate.php | 5 +-- commands/internals/help.php | 33 +++++++++----- commands/internals/home.php | 13 +++--- commands/internals/option.php | 5 +-- commands/internals/plugin.php | 5 +-- commands/internals/theme.php | 5 +-- wp-cli.php | 2 +- 12 files changed, 39 insertions(+), 94 deletions(-) diff --git a/class-wp-cli-command.php b/class-wp-cli-command.php index 93d754b2c8..b86d8ec390 100644 --- a/class-wp-cli-command.php +++ b/class-wp-cli-command.php @@ -8,33 +8,13 @@ */ abstract class WP_CLI_Command { - /** - * Keeps a reference to the current command name - * - * @param string - */ - protected $command; - - /** - * Constructor - * - * @param string $command - * @param array $args - * @param array $assoc_args - */ - function __construct( $command, $args, $assoc_args ) { - $this->command = $command; - - $this->dispatch( $args, $assoc_args ); - } - /** * Transfers the handling to the appropriate method * * @param array $args * @param array $assoc_args */ - protected function dispatch( $args, $assoc_args ) { + public function __construct( $args, $assoc_args ) { $sub_command = array_shift( $args ); if ( !method_exists( $this, $sub_command ) ) { @@ -49,38 +29,19 @@ protected function dispatch( $args, $assoc_args ) { $this->$sub_command( $args, $assoc_args ); } - /** - * General help function for the current command - * - * @param array $args - * @return void - */ - public function help( $args = array() ) { - // Show the list of sub-commands for this command - WP_CLI::line( 'Example usage:' ); - WP_CLI::out( ' wp '.$this->command ); - - $methods = self::get_subcommands($this); - if ( !empty( $methods ) ) { - WP_CLI::out(' ['.implode('|', $methods).']'); - } - WP_CLI::line(' ...'); - WP_CLI::line(); - } - /** * Get the list of subcommands for a class. * * @param string $class * @return array The list of methods */ - static function get_subcommands($class) { + static function get_subcommands( $class ) { $reflection = new ReflectionClass( $class ); $methods = array(); foreach ( $reflection->getMethods() as $method ) { - if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() && 'help' != $method->name ) { + if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() ) { $name = $method->name; if ( strpos( $name, '_' ) === 0 ) { diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index 494cd5e01b..a5a1d33037 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -27,11 +27,8 @@ function rebuild( $args = array(), $vars = array() ) { /** * Help function for this command - * - * @param array $args - * @return void */ - public function help($args = array()) { + public static function help() { WP_CLI::line( <<] [--permalink=] diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index 64e77f942e..231e4de8ab 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -123,11 +123,8 @@ function disable( $args = array(), $vars = array() ) { /** * Help function for this command - * - * @param array $args - * @return void */ - public function help($args = array()) { + public static function help() { WP_CLI::line( << --permalink= diff --git a/commands/internals/core.php b/commands/internals/core.php index 2febca34a2..319266bec2 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -45,11 +45,8 @@ function update($args) { /** * Help function for this command - * - * @param array $args - * @return void */ - public function help( $args = array() ) { + public static function help() { WP_CLI::line( <<] diff --git a/commands/internals/help.php b/commands/internals/help.php index dda5cc8054..fab8542d75 100644 --- a/commands/internals/help.php +++ b/commands/internals/help.php @@ -12,38 +12,49 @@ class HelpCommand extends WP_CLI_Command { /** - * Overwrite the dispatch method to have a command without sub-commands. + * Overwrite the constructor to have a command without sub-commands. * * @param array $args */ - protected function dispatch( $args ) { + public function __construct( $args ) { if ( empty( $args ) ) { - $this->generalHelp(); + $this->general_help(); } else { $command = $args[0]; if ( 'help' == $command || !isset( WP_CLI::$commands[$command] ) ) { $this->generalHelp(); } else { - new WP_CLI::$commands[$command]( $command, array( 'help' ), array() ); + $class = WP_CLI::$commands[$command]; + + if ( method_exists( $class, 'help' ) ) { + $class::help(); + } else { + WP_CLI::line( 'Example usage:' ); + $this->single_command_help( $command, $class ); + } } } } - private function generalHelp() { + private function general_help() { WP_CLI::line('Example usage:'); foreach ( WP_CLI::$commands as $name => $command ) { if ( 'help' == $name ) continue; - WP_CLI::out( ' wp ' . $name ); - $methods = WP_CLI_Command::get_subcommands( $command ); - if( !empty( $methods ) ) { - WP_CLI::out( ' [' . implode( '|', $methods ) . ']' ); - } - WP_CLI::line(' ...'); + $this->single_command_help( $name, $command ); } WP_CLI::line(' wp --version'); WP_CLI::line(); WP_CLI::line( "See 'wp help ' for more information on a specific command." ); } + + private function single_command_help( $name, $command ) { + WP_CLI::out( ' wp ' . $name ); + $methods = WP_CLI_Command::get_subcommands( $command ); + if ( !empty( $methods ) ) { + WP_CLI::out( ' [' . implode( '|', $methods ) . ']' ); + } + WP_CLI::line(' ...'); + } } diff --git a/commands/internals/home.php b/commands/internals/home.php index a226fe6083..14e4e17348 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -13,12 +13,12 @@ class HomeCommand extends WP_CLI_Command { /** - * Overwrite the dispatch method to have a command without sub-commands. + * Overwrite the constructor to have a command without sub-commands. * * @param array $args * @param array $assoc_args */ - protected function dispatch( $args, $assoc_args ) { + public function __construct( $args, $assoc_args ) { if(empty($args)) { // The url for the wp-cli repository $repository_url = 'http://github.com/andreascreten/wp-cli'; @@ -39,17 +39,14 @@ protected function dispatch( $args, $assoc_args ) { } else { // Call the parent constructor - parent::dispatch( $args, $assoc_args ); + parent::__construct( $args, $assoc_args ); } } /** - * Help function for this command. - * - * @param array $args - * @return void + * Help function for this command */ - public function help($args = array()) { + public static function help() { WP_CLI::line( << or: wp option add diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index e426799cc3..f27ffb8613 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -317,11 +317,8 @@ private function parse_name( $args, $sub_command, $exit = true ) { /** * Help function for this command - * - * @param array $args - * @return void */ - public function help( $args = array() ) { + public static function help() { WP_CLI::line( << [] diff --git a/commands/internals/theme.php b/commands/internals/theme.php index e2f1af9b49..bd9a38ebe0 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -121,11 +121,8 @@ protected function get_stylesheet_path( $theme ) { /** * Help function for this command - * - * @param array $args - * @return void */ - public function help($args = array()) { + public static function help() { WP_CLI::line( << [] diff --git a/wp-cli.php b/wp-cli.php index 4922200bdb..a597bc0b81 100755 --- a/wp-cli.php +++ b/wp-cli.php @@ -101,5 +101,5 @@ exit; } -new WP_CLI::$commands[$command]( $command, $arguments, $assoc_args ); +new WP_CLI::$commands[$command]( $arguments, $assoc_args ); From af3fbcea29e7ad4a2306e21ea27df15243df4848 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 03:30:24 +0300 Subject: [PATCH 0114/4858] move php files to a 'core' dir and build-deb to a 'utils' dir. see #7 --- bin/wp | 2 +- bin/{wp-cli-completion.bash => wp-completion.bash} | 0 class-wp-cli-command.php => core/class-wp-cli-command.php | 0 class-wp-cli.php => core/class-wp-cli.php | 0 wp-cli.php => core/wp-cli.php | 6 +++--- {bin => utils}/build-deb | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename bin/{wp-cli-completion.bash => wp-completion.bash} (100%) rename class-wp-cli-command.php => core/class-wp-cli-command.php (100%) rename class-wp-cli.php => core/class-wp-cli.php (100%) rename wp-cli.php => core/wp-cli.php (94%) rename {bin => utils}/build-deb (100%) diff --git a/bin/wp b/bin/wp index dd4fd48d98..9c0894e5c9 100755 --- a/bin/wp +++ b/bin/wp @@ -30,7 +30,7 @@ done cd "$ORIGDIR" # Build the path to wp-cli.php. -SCRIPT_PATH=$(dirname "$SELF_PATH")/../wp-cli.php +SCRIPT_PATH=$(dirname "$SELF_PATH")/../core/wp-cli.php case $(uname -a) in CYGWIN*) SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; diff --git a/bin/wp-cli-completion.bash b/bin/wp-completion.bash similarity index 100% rename from bin/wp-cli-completion.bash rename to bin/wp-completion.bash diff --git a/class-wp-cli-command.php b/core/class-wp-cli-command.php similarity index 100% rename from class-wp-cli-command.php rename to core/class-wp-cli-command.php diff --git a/class-wp-cli.php b/core/class-wp-cli.php similarity index 100% rename from class-wp-cli.php rename to core/class-wp-cli.php diff --git a/wp-cli.php b/core/wp-cli.php similarity index 94% rename from wp-cli.php rename to core/wp-cli.php index a597bc0b81..f0ae07d244 100755 --- a/wp-cli.php +++ b/core/wp-cli.php @@ -8,14 +8,14 @@ define( 'WP_CLI_VERSION', '0.2' ); // Define the wp-cli location -define('WP_CLI_ROOT', __DIR__ . '/'); +define( 'WP_CLI_ROOT', realpath( __DIR__ . '/..' ) . '/' ); // Set a constant that can be used to check if we are running wp-cli or not define('WP_CLI', true); // Include the wp-cli classes -include WP_CLI_ROOT.'class-wp-cli.php'; -include WP_CLI_ROOT.'class-wp-cli-command.php'; +include WP_CLI_ROOT.'core/class-wp-cli.php'; +include WP_CLI_ROOT.'core/class-wp-cli-command.php'; // Include the command line tools include WP_CLI_ROOT.'php-cli-tools/lib/cli/cli.php'; diff --git a/bin/build-deb b/utils/build-deb similarity index 100% rename from bin/build-deb rename to utils/build-deb From 77ea557ddc25814eb54c33ec6fda3f8375fa62ce Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 03:33:01 +0300 Subject: [PATCH 0115/4858] remove .gitignore; use your personal .gitignore file for excluding temporary files --- .gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c1468184d4..0000000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.DS_Store -php-cli-tools/ \ No newline at end of file From 78738a02596c0fe6f108d609d4765638f0ad794b Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 04:43:25 +0300 Subject: [PATCH 0116/4858] update build-deb; change wp-cli version to '0.2-alpha'. see #7 --- core/wp-cli.php | 11 +++++------ utils/build-deb | 50 ++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/core/wp-cli.php b/core/wp-cli.php index f0ae07d244..9fb6888acc 100755 --- a/core/wp-cli.php +++ b/core/wp-cli.php @@ -1,11 +1,10 @@ -#!/usr/bin/env php usr/bin/wp < DEBIAN/control < DEBIAN/postinst < DEBIAN/postinst < Date: Sun, 9 Oct 2011 04:48:36 +0300 Subject: [PATCH 0117/4858] update installation instructions --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c2d64e1bf7..b008fffc1a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,11 @@ A tool to control WordPress installations from the command line. Installing ---------- -If you're on Ubuntu or Debian, just use the [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) +**Via package manager:** + +Ubuntu, Debian: [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) + +**From source:** Clone the project: @@ -28,7 +32,7 @@ sudo ln -s /path-to-wp-cli-dir/bin/wp /usr/local/bin/ Make a symlink to the autocomplete file (Linux): ``` -sudo ln -s /path-to-wp-cli-dir/bin/wp-cli-completion.bash /etc/bash_completion.d/wp +sudo ln -s /path-to-wp-cli-dir/bin/wp-completion.bash /etc/bash_completion.d/wp ``` Usage From f28bd2951fef413cfcd133609d9eabe9ab57fb75 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 15:58:35 +0300 Subject: [PATCH 0118/4858] plugin command fixes. closes #25 --- commands/internals/plugin.php | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index f27ffb8613..9d2d4a78e2 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -168,7 +168,7 @@ function toggle( $args ) { * @return void */ function install( $args ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__, false ); + $name = $args[0]; // Force WordPress to update the plugin list wp_update_plugins(); @@ -193,10 +193,7 @@ function install( $args ) { $result = $upgrader->install( $api->download_link ); $feedback = ob_get_clean(); - if ( $result !== null ) { - WP_CLI::error( $result ); - } - else { + if ( $result ) { WP_CLI::line(); WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin installed successfully.' ), array( " ...\n", '' ), html_entity_decode( $feedback ) ) ) ); WP_CLI::success( 'The plugin is successfully installed' ); @@ -207,10 +204,6 @@ function install( $args ) { break; case 'latest_installed': WP_CLI::error( 'Latest version already installed' ); - - if ( is_plugin_inactive( $file ) ) { - WP_CLI::warning( 'If you want to activate the plugin, run: %2wp plugin activate '.$name.'%n' ); - } break; } } @@ -286,7 +279,7 @@ private function get_details( $file ) { * @param bool $exit * @return array */ - private function parse_name( $args, $sub_command, $exit = true ) { + private function parse_name( $args, $sub_command ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp plugin $sub_command " ); exit; @@ -301,15 +294,13 @@ private function parse_name( $args, $sub_command, $exit = true ) { } else { $file = $name . '.php'; - $plugins = get_plugins(); - if ( !isset( $plugins[$file] ) ) { - if ( $exit ) { - WP_CLI::error( "The plugin '$name' could not be found." ); - exit(); - } - - return false; - } + } + + $plugins = get_plugins(); + + if ( !isset( $plugins[$file] ) ) { + WP_CLI::error( "The plugin '$name' could not be found." ); + exit(); } return array( $file, $name ); From 4a70fec820288c48630c41230678b4c0b292e513 Mon Sep 17 00:00:00 2001 From: Bartosz Romanowski Date: Sun, 9 Oct 2011 14:25:40 +0300 Subject: [PATCH 0119/4858] Workaround for an invalid plugin status returned from the 'install_plugin_install_status' when trying to install a non-existing plugin. --- commands/internals/plugin.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 9d2d4a78e2..264e3a06f7 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -179,6 +179,11 @@ function install( $args ) { WP_CLI::line( 'Installing '.$api->name.' ('.$api->version.')' ); + if ( stripslashes( $name ) != $api->slug ) { + WP_CLI::error( 'Can\'t find the plugin in the WordPress.org plugins repository.' ); + exit(); + } + // Check what to do switch ( $status['status'] ) { case 'update_available': From 5fa68d75943aacbb8907d3dd7c766f6ea16fe6dd Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 16:16:22 +0300 Subject: [PATCH 0120/4858] check for null response from plugins_api() instead of attempting to match the slug. see #26 --- commands/internals/plugin.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 264e3a06f7..0f9a722835 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -175,15 +175,15 @@ function install( $args ) { // Get plugin info from the WordPress servers $api = plugins_api( 'plugin_information', array( 'slug' => stripslashes( $name ) ) ); - $status = install_plugin_install_status( $api ); - - WP_CLI::line( 'Installing '.$api->name.' ('.$api->version.')' ); - - if ( stripslashes( $name ) != $api->slug ) { + if ( !$api ) { WP_CLI::error( 'Can\'t find the plugin in the WordPress.org plugins repository.' ); exit(); } + $status = install_plugin_install_status( $api ); + + WP_CLI::line( 'Installing '.$api->name.' ('.$api->version.')' ); + // Check what to do switch ( $status['status'] ) { case 'update_available': From bb4229024ecf50f30d555888acaa77dc565f8dbd Mon Sep 17 00:00:00 2001 From: Bartosz Romanowski Date: Sun, 9 Oct 2011 14:34:02 +0300 Subject: [PATCH 0121/4858] Fixed messages formatting for plugin updates. --- commands/internals/plugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 0f9a722835..3526e8bedb 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -200,7 +200,7 @@ function install( $args ) { if ( $result ) { WP_CLI::line(); - WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin installed successfully.' ), array( " ...\n", '' ), html_entity_decode( $feedback ) ) ) ); + WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin installed successfully.' ), array( "...\n", '' ), html_entity_decode( $feedback ) ) ) ); WP_CLI::success( 'The plugin is successfully installed' ); } break; @@ -256,7 +256,7 @@ function update( $args ) { } else { WP_CLI::line(); - WP_CLI::line( html_entity_decode( strip_tags( $feedback ) ) ); + WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin updates successfully.' ), array( "...\n", '' ), html_entity_decode( $feedback ) ) ) ); WP_CLI::success( 'The plugin is successfully updated.' ); } } From 07b87f982949f100131baa03dfc5e3844ab64256 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 17:20:13 +0300 Subject: [PATCH 0122/4858] defer to github for listing contributors and their impact --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b008fffc1a..cf567622a4 100644 --- a/README.md +++ b/README.md @@ -164,8 +164,8 @@ if(defined('WP_CLI') && WP_CLI) { Contributors ------------ -- Andreas Creten ([@andreascreten](http://twitter.com/andreascreten)) -- Cristi Burcă ([@scribu](http://twitter.com/scribu)) +- [Contributor list](https://github.com/andreascreten/wp-cli/contributors) +- [Contributor impact](https://github.com/andreascreten/wp-cli/graphs/impact) Requirements ------------ From b8552745b66d59e2b0a2bc89bb2e32fcb1c52283 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 17:24:39 +0300 Subject: [PATCH 0123/4858] merge Requirements section into Installing --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cf567622a4..e87889b794 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Ubuntu, Debian: [.deb package](https://github.com/downloads/andreascreten/wp-cli **From source:** +First, make sure you have `php-cli` version 5.3 or newer installed. + Clone the project: ``` @@ -166,8 +168,3 @@ Contributors - [Contributor list](https://github.com/andreascreten/wp-cli/contributors) - [Contributor impact](https://github.com/andreascreten/wp-cli/graphs/impact) - -Requirements ------------- - - * PHP >= 5.3 From c69832bd5df0ecd168ef4d5ea9a04f1563e1e1bc Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 21:44:03 +0300 Subject: [PATCH 0124/4858] simplify HomeCommand::__construct() --- commands/internals/home.php | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/commands/internals/home.php b/commands/internals/home.php index 14e4e17348..e625144757 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -19,28 +19,22 @@ class HomeCommand extends WP_CLI_Command { * @param array $assoc_args */ public function __construct( $args, $assoc_args ) { - if(empty($args)) { - // The url for the wp-cli repository - $repository_url = 'http://github.com/andreascreten/wp-cli'; + // The url for the wp-cli repository + $repository_url = 'http://github.com/andreascreten/wp-cli'; - // Open the wp-cli page in the browser - if(exec('which x-www-browser')) { - system('x-www-browser '.$repository_url); - } - elseif(exec('which open')) { - system('open '.$repository_url); - } - else { - WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: '.$repository_url); - return; - } - - WP_CLI::success('The wp-cli homepage should be opening in your browser.'); + // Open the wp-cli page in the browser + if(exec('which x-www-browser')) { + system('x-www-browser '.$repository_url); + } + elseif(exec('which open')) { + system('open '.$repository_url); } else { - // Call the parent constructor - parent::__construct( $args, $assoc_args ); + WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: '.$repository_url); + return; } + + WP_CLI::success('The wp-cli homepage should be opening in your browser.'); } /** From 7bba53b0ac335ea17609feff44b2a38fa5291b3a Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 21:45:51 +0300 Subject: [PATCH 0125/4858] introduce default_subcommand property. fixes #29 --- commands/internals/plugin.php | 2 ++ commands/internals/theme.php | 2 ++ core/class-wp-cli-command.php | 17 +++++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 3526e8bedb..886d4c3e89 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -14,6 +14,8 @@ */ class PluginCommand extends WP_CLI_Command { + protected $default_subcommand = 'status'; + private $mu_plugins; /** diff --git a/commands/internals/theme.php b/commands/internals/theme.php index bd9a38ebe0..2c63467414 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -12,6 +12,8 @@ */ class ThemeCommand extends WP_CLI_Command { + protected $default_subcommand = 'status'; + /** * Get the status of one or all themes * diff --git a/core/class-wp-cli-command.php b/core/class-wp-cli-command.php index b86d8ec390..291b342d82 100644 --- a/core/class-wp-cli-command.php +++ b/core/class-wp-cli-command.php @@ -8,6 +8,8 @@ */ abstract class WP_CLI_Command { + protected $default_subcommand = 'help'; + /** * Transfers the handling to the appropriate method * @@ -15,18 +17,21 @@ abstract class WP_CLI_Command { * @param array $assoc_args */ public function __construct( $args, $assoc_args ) { - $sub_command = array_shift( $args ); + if ( empty( $args ) ) + $subcommand = $this->default_subcommand; + else + $subcommand = array_shift( $args ); - if ( !method_exists( $this, $sub_command ) ) { + if ( !method_exists( $this, $subcommand ) ) { // This if for reserved keywords in php (like list, isset) - $sub_command = '_'.$sub_command; + $subcommand = '_'.$subcommand; } - if ( !method_exists( $this, $sub_command ) || isset( $assoc_args[ 'help' ] ) ) { - $sub_command = 'help'; + if ( !method_exists( $this, $subcommand ) || isset( $assoc_args[ 'help' ] ) ) { + $subcommand = 'help'; } - $this->$sub_command( $args, $assoc_args ); + $this->$subcommand( $args, $assoc_args ); } /** From c811b3d54a62e0231404c4a90cd4d845de6d5aa8 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 23:22:20 +0300 Subject: [PATCH 0126/4858] show usage when plugin install has no args. see #25 --- commands/internals/plugin.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 886d4c3e89..8814f0518c 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -170,6 +170,11 @@ function toggle( $args ) { * @return void */ function install( $args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp plugin install " ); + exit; + } + $name = $args[0]; // Force WordPress to update the plugin list From 60123b03305ac4ce7cff820023f6263207da835b Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 23:24:05 +0300 Subject: [PATCH 0127/4858] s/sub_command/subcommand/g --- commands/internals/plugin.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 8814f0518c..1a7ac33f85 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -287,13 +287,13 @@ private function get_details( $file ) { * Parse the name of a plugin to a filename, check if it exists * * @param array $args - * @param string $sub_command + * @param string $subcommand * @param bool $exit * @return array */ - private function parse_name( $args, $sub_command ) { + private function parse_name( $args, $subcommand ) { if ( empty( $args ) ) { - WP_CLI::line( "usage: wp plugin $sub_command " ); + WP_CLI::line( "usage: wp plugin $subcommand " ); exit; } From dc596e0742a1a1d7ce6a5025e3009c75535f7de6 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 23:41:17 +0300 Subject: [PATCH 0128/4858] add --activate flag to `wp plugin install` command; introduce WP_CLI::compose_args(). fixes #30 --- commands/internals/plugin.php | 8 ++++++-- core/class-wp-cli.php | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 1a7ac33f85..4b6ae2a6c4 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -167,9 +167,9 @@ function toggle( $args ) { * Install a new plugin * * @param array $args - * @return void + * @param array $assoc_args */ - function install( $args ) { + function install( $args, $assoc_args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp plugin install " ); exit; @@ -209,6 +209,10 @@ function install( $args ) { WP_CLI::line(); WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin installed successfully.' ), array( "...\n", '' ), html_entity_decode( $feedback ) ) ) ); WP_CLI::success( 'The plugin is successfully installed' ); + + if ( isset( $assoc_args['activate'] ) ) { + system( "wp plugin activate " . WP_CLI::compose_args( $args, $assoc_args ) ); + } } break; case 'newer_installed': diff --git a/core/class-wp-cli.php b/core/class-wp-cli.php index 1c463c5ade..6387daa5f7 100644 --- a/core/class-wp-cli.php +++ b/core/class-wp-cli.php @@ -94,8 +94,9 @@ static function errorToString($errors) { } /** - * Splits regular arguments from associative arguments. + * Splits a string into positional and associative arguments. * + * @param string * @return array */ static function parse_args( $arguments ) { @@ -115,6 +116,25 @@ static function parse_args( $arguments ) { return array( $regular_args, $assoc_args ); } + /** + * Composes positional and associative arguments into a string + * + * @param array + * @return string + */ + static function compose_args( $args, $assoc_args = array() ) { + $str = implode( ' ', $args ); + + foreach ( $assoc_args as $key => $value ) { + if ( true == $value ) + $str .= " --$key"; + else + $str .= " --$key=$value"; + } + + return $str; + } + /** * Display a legend * From 28037b6086b890e5f9cafb95eb8e2679d61cde2c Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 9 Oct 2011 23:45:02 +0300 Subject: [PATCH 0129/4858] use WP_CLI::success() in wp plugin (de)activate for consistency --- commands/internals/plugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 4b6ae2a6c4..66627833dd 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -125,7 +125,7 @@ function activate( $args ) { if ( !is_plugin_active( $file ) ) { WP_CLI::error( 'Could not activate this plugin: ' . $name ); } else { - WP_CLI::line( 'Plugin activated.' ); + WP_CLI::success( "Plugin '$name' activated." ); } } @@ -143,7 +143,7 @@ function deactivate( $args ) { if ( !is_plugin_inactive( $file ) ) { WP_CLI::error( 'Could not deactivate this plugin: '.$name ); } else { - WP_CLI::line( 'Plugin deactivated.' ); + WP_CLI::success( "Plugin '$name' deactivated." ); } } From 8ca86ddd71ee1abdec90b2a09d1560310a652ea9 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Mon, 10 Oct 2011 09:09:25 +0200 Subject: [PATCH 0130/4858] Updated the core to comply with the coding standards Also updated the README with install details for Mac. --- README.md | 2 ++ core/class-wp-cli.php | 74 +++++++++++++++++++++---------------------- core/wp-cli.php | 10 +++--- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index e87889b794..b14e390606 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Installing Ubuntu, Debian: [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) +On Mac, install [Homebrew](http://mxcl.github.com/homebrew/) and run `brew install wp-cli`. + **From source:** First, make sure you have `php-cli` version 5.3 or newer installed. diff --git a/core/class-wp-cli.php b/core/class-wp-cli.php index 6387daa5f7..47a7985e87 100644 --- a/core/class-wp-cli.php +++ b/core/class-wp-cli.php @@ -16,7 +16,7 @@ class WP_CLI { * @param string $class The class to manage the command * @return void */ - public function addCommand($name, $class) { + public function addCommand( $name, $class ) { self::$commands[$name] = $class; } @@ -26,7 +26,7 @@ public function addCommand($name, $class) { * @param string $message * @return void */ - static function out($message) { + static function out( $message ) { \cli\out($message); } @@ -36,7 +36,7 @@ static function out($message) { * @param string $message * @return void */ - static function line($message = '') { + static function line( $message = '' ) { \cli\line($message); } @@ -47,8 +47,8 @@ static function line($message = '') { * @param string $label * @return void */ - static function error($message, $label = 'Error') { - \cli\line('%R'.$label.': %n'.self::errorToString($message)); + static function error( $message, $label = 'Error' ) { + \cli\line( '%R' . $label . ': %n' . self::errorToString( $message ) ); } /** @@ -58,8 +58,8 @@ static function error($message, $label = 'Error') { * @param string $label * @return void */ - static function success($message, $label = 'Success') { - \cli\line('%G'.$label.': %n'.$message); + static function success( $message, $label = 'Success' ) { + \cli\line( '%G' . $label . ': %n' . $message ); } /** @@ -69,8 +69,8 @@ static function success($message, $label = 'Success') { * @param string $label * @return void */ - static function warning($message, $label = 'Warning') { - \cli\line('%C'.$label.': %n'.$message); + static function warning( $message, $label = 'Warning' ) { + \cli\line( '%C' . $label . ': %n' . $message ); } /** @@ -79,13 +79,12 @@ static function warning($message, $label = 'Warning') { * @param mixed $errors * @return string */ - static function errorToString($errors) { - if(is_string($errors)){ + static function errorToString( $errors ) { + if( is_string( $errors ) ) { return $errors; - } - elseif(is_wp_error($errors) && $errors->get_error_code()){ - foreach($errors->get_error_messages() as $message){ - if($errors->get_error_data() ) + } elseif( is_wp_error( $errors ) && $errors->get_error_code() ) { + foreach( $errors->get_error_messages() as $message ) { + if( $errors->get_error_data() ) return $message . ' ' . $errors->get_error_data(); else return $message; @@ -141,8 +140,8 @@ static function compose_args( $args, $assoc_args = array() ) { * @param array( code => title ) $legend * @return void */ - static function legend($legend) { - $legend['%yU'] = 'Update Available'; + static function legend( $legend ) { + $legend[ '%yU' ] = 'Update Available'; $legend_line = array(); foreach ( $legend as $key => $title ) @@ -180,13 +179,13 @@ class CLI_Upgrader_Skin { var $done_header = false; var $result = false; - function __construct($args = array()) { - $defaults = array('url' => '', 'nonce' => '', 'title' => '', 'context' => false); - $this->options = wp_parse_args($args, $defaults); + function __construct( $args = array() ) { + $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false ); + $this->options = wp_parse_args( $args, $defaults ); } - function set_upgrader(&$upgrader) { - if(is_object($upgrader)) { + function set_upgrader( &$upgrader ) { + if( is_object( $upgrader ) ) { $this->upgrader =& $upgrader; } @@ -195,41 +194,42 @@ function set_upgrader(&$upgrader) { function add_strings() {} - function set_result($result) { + function set_result( $result ) { $this->result = $result; } - function request_filesystem_credentials($error = false) { + function request_filesystem_credentials( $error = false ) { $url = $this->options['url']; $context = $this->options['context']; - if(!empty($this->options['nonce'])) { - $url = wp_nonce_url($url, $this->options['nonce']); + if( !empty( $this->options['nonce'] ) ) { + $url = wp_nonce_url( $url, $this->options['nonce']) ; } // Possible to bring inline, Leaving as is for now. - return request_filesystem_credentials($url, '', $error, $context); + return request_filesystem_credentials( $url, '', $error, $context ); } function header() {} function footer() {} - function error($errors) { - $this->feedback(WP_CLI::errorToString($errors)); + function error( $errors ) { + $this->feedback( WP_CLI::errorToString($errors) ); } - function feedback($string) { - if(isset( $this->upgrader->strings[$string])) + function feedback( $string ) { + if(isset( $this->upgrader->strings[$string] ) ) $string = $this->upgrader->strings[$string]; - if(strpos($string, '%') !== false) { + if( strpos( $string, '%' ) !== false ) { $args = func_get_args(); - $args = array_splice($args, 1); - if(!empty($args)) { - $string = vsprintf($string, $args); + $args = array_splice( $args, 1 ); + if( !empty( $args ) ) { + $string = vsprintf( $string, $args ); } } - if(empty($string)) { + + if( empty( $string ) ) { return; } @@ -238,4 +238,4 @@ function feedback($string) { function before() {} function after() {} -} +} \ No newline at end of file diff --git a/core/wp-cli.php b/core/wp-cli.php index 9fb6888acc..438c30a1d8 100755 --- a/core/wp-cli.php +++ b/core/wp-cli.php @@ -13,11 +13,13 @@ define('WP_CLI', true); // Include the wp-cli classes - include WP_CLI_ROOT.'core/class-wp-cli.php'; - include WP_CLI_ROOT.'core/class-wp-cli-command.php'; +include WP_CLI_ROOT . 'core/class-wp-cli.php'; +include WP_CLI_ROOT . 'core/class-wp-cli-command.php'; - // Include the command line tools - include WP_CLI_ROOT.'php-cli-tools/lib/cli/cli.php'; +// Include the command line tools +include WP_CLI_ROOT . 'php-cli-tools/lib/cli/cli.php'; + +// Register the cli tools autoload \cli\register_autoload(); // Get the cli arguments From 4acde50032e48417233a82bb595c4b3e9c03108f Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Mon, 10 Oct 2011 15:09:27 +0300 Subject: [PATCH 0131/4858] Edited README.md via GitHub --- README.md | 56 +++---------------------------------------------------- 1 file changed, 3 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index b14e390606..3e20deaab9 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,8 @@ Installing **Via package manager:** -Ubuntu, Debian: [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) - -On Mac, install [Homebrew](http://mxcl.github.com/homebrew/) and run `brew install wp-cli`. +* Ubuntu, Debian: [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) +* Mac: install [Homebrew](http://mxcl.github.com/homebrew/) and run `brew install wp-cli`. **From source:** @@ -112,56 +111,7 @@ Adding commands --------------- Adding commands to wp-cli is very easy. You can even add them from within your own plugin. - -Each command has its own class, the methods of that class are the sub commands of the command. The base class for the commands is the abstract `WP_CLI_Command`, it handles some essential functionality (like default help for your command). - -You can add new commands to the `commands/community` folder in the wp-cli plugin, they will be auto-loaded on startup. You can also add commands from within your plugins by just calling the wp-cli hooks from there. - -A wp-cli class is structured like this: - -``` php - Date: Mon, 10 Oct 2011 00:42:42 +0100 Subject: [PATCH 0132/4858] Add version command --- commands/internals/version.php | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 commands/internals/version.php diff --git a/commands/internals/version.php b/commands/internals/version.php new file mode 100644 index 0000000000..dc0a99eaee --- /dev/null +++ b/commands/internals/version.php @@ -0,0 +1,58 @@ + + */ +class VersionCommand extends WP_CLI_Command { + + var $default_subcommand = 'core'; + + public function core( $args = array() ) { + global $wp_version; + $color = '%G'; + $version_text = $wp_version; + $version_types = array( + '-RC' => array( 'release candidate', '%y' ), + '-beta' => array( 'beta', '%B' ), + '-' => array( 'in development', '%R' ), + ); + foreach( $version_types as $needle => $type ) { + if ( stristr( $wp_version, $needle ) ) { + list( $version_text, $color ) = $type; + $version_text = "$color$wp_version%n (stability: $version_text)"; + break; + } + } + WP_CLI::line( "WordPress version:\t$version_text" ); + } + + public function extra( $args = array() ) { + global $wp_version, $wp_db_version, $tinymce_version, $manifest_version; + $this->core( $args ); + WP_CLI::line(); + WP_CLI::line( "Database revision:\t$wp_db_version" ); + + preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); + $human_readable_tiny_mce = $match? $match[1] . '.' . $match[2] : ''; + WP_CLI::line( "TinyMCE version:\t" . ( $human_readable_tiny_mce? "$human_readable_tiny_mce ($tinymce_version)" : $tinymce_version ) ); + + WP_CLI::line( "Manifest revision:\t$manifest_version" ); + } + + public static function help() { + WP_CLI::line( << + +Available sub-commands: + core WordPress core version + extra Detailed version information +EOB + ); + } +} \ No newline at end of file From 4e3979f290909b84eb6cd3573da9928adbd718d8 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 12 Oct 2011 22:18:26 +0300 Subject: [PATCH 0133/4858] replace @author with @maintainer; keep only for community commands --- commands/community/google-sitemap-generator.php | 2 +- commands/community/w3-total-cache.php | 2 +- commands/community/wp-super-cache.php | 2 +- commands/internals/core.php | 1 - commands/internals/generate.php | 1 - commands/internals/home.php | 1 - commands/internals/option.php | 1 - commands/internals/plugin.php | 1 - commands/internals/theme.php | 1 - commands/internals/version.php | 1 - core/class-wp-cli-command.php | 1 - core/class-wp-cli.php | 2 -- 12 files changed, 3 insertions(+), 13 deletions(-) diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index a5a1d33037..c9e8eb006c 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -10,7 +10,7 @@ * * @package wp-cli * @subpackage commands/community - * @author Andreas Creten + * @maintainer Andreas Creten */ class GoogleSitemapGeneratorCommand extends WP_CLI_Command { diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php index 75f5b00eec..62d5ee15da 100644 --- a/commands/community/w3-total-cache.php +++ b/commands/community/w3-total-cache.php @@ -10,7 +10,7 @@ * * @package wp-cli * @subpackage commands/community - * @author Andreas Creten + * @maintainer Andreas Creten */ class W3TotalCacheCommand extends WP_CLI_Command { diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index 231e4de8ab..6751fde068 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -10,7 +10,7 @@ * * @package wp-cli * @subpackage commands/community - * @author Andreas Creten + * @maintainer Andreas Creten */ class WPSuperCacheCommand extends WP_CLI_Command { diff --git a/commands/internals/core.php b/commands/internals/core.php index 319266bec2..3229eafe30 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -8,7 +8,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Andreas Creten */ class CoreCommand extends WP_CLI_Command { diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 65953a6ab8..4fbac253c9 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -8,7 +8,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Cristi Burca */ class GenerateCommand extends WP_CLI_Command { diff --git a/commands/internals/home.php b/commands/internals/home.php index e625144757..fc6b0acc10 100644 --- a/commands/internals/home.php +++ b/commands/internals/home.php @@ -8,7 +8,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Andreas Creten */ class HomeCommand extends WP_CLI_Command { diff --git a/commands/internals/option.php b/commands/internals/option.php index 4910539040..a87866cbab 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -8,7 +8,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Andreas Creten */ class OptionCommand extends WP_CLI_Command { diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 66627833dd..a8417428ce 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -10,7 +10,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Andreas Creten */ class PluginCommand extends WP_CLI_Command { diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 2c63467414..74b784dddf 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -8,7 +8,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Andreas Creten */ class ThemeCommand extends WP_CLI_Command { diff --git a/commands/internals/version.php b/commands/internals/version.php index dc0a99eaee..29bb4383e8 100644 --- a/commands/internals/version.php +++ b/commands/internals/version.php @@ -7,7 +7,6 @@ * * @package wp-cli * @subpackage commands/internals - * @author Nikolay Bachiyski */ class VersionCommand extends WP_CLI_Command { diff --git a/core/class-wp-cli-command.php b/core/class-wp-cli-command.php index 291b342d82..abbbc16166 100644 --- a/core/class-wp-cli-command.php +++ b/core/class-wp-cli-command.php @@ -4,7 +4,6 @@ * Base class for WP-CLI commands * * @package wp-cli - * @author Andreas Creten */ abstract class WP_CLI_Command { diff --git a/core/class-wp-cli.php b/core/class-wp-cli.php index 47a7985e87..2c5c3a043e 100644 --- a/core/class-wp-cli.php +++ b/core/class-wp-cli.php @@ -4,7 +4,6 @@ * Wrapper class for WP-CLI * * @package wp-cli - * @author Andreas Creten */ class WP_CLI { static $commands = array(); @@ -172,7 +171,6 @@ static function get_update_status( $item, $key ) { * A Upgrader Skin for WordPress that only generates plain-text * * @package wp-cli - * @author Andreas Creten */ class CLI_Upgrader_Skin { var $upgrader; From 3eef8c0009cee8f97414d241ca01f981f72769f6 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 12 Oct 2011 22:28:04 +0300 Subject: [PATCH 0134/4858] make `version` a subcommand of `core`. see #31 --- commands/internals/core.php | 34 ++++++++++++++++++++ commands/internals/version.php | 57 ---------------------------------- 2 files changed, 34 insertions(+), 57 deletions(-) delete mode 100644 commands/internals/version.php diff --git a/commands/internals/core.php b/commands/internals/core.php index 3229eafe30..52e61cb80e 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -11,6 +11,40 @@ */ class CoreCommand extends WP_CLI_Command { + /** + * Display the WordPress version. + */ + public function version( $args = array(), $assoc_args = array() ) { + global $wp_version, $wp_db_version, $tinymce_version, $manifest_version; + + $color = '%G'; + $version_text = $wp_version; + $version_types = array( + '-RC' => array( 'release candidate', '%y' ), + '-beta' => array( 'beta', '%B' ), + '-' => array( 'in development', '%R' ), + ); + foreach( $version_types as $needle => $type ) { + if ( stristr( $wp_version, $needle ) ) { + list( $version_text, $color ) = $type; + $version_text = "$color$wp_version%n (stability: $version_text)"; + break; + } + } + WP_CLI::line( "WordPress version:\t$version_text" ); + + if ( isset( $assoc_args['extra'] ) ) { + WP_CLI::line(); + WP_CLI::line( "Database revision:\t$wp_db_version" ); + + preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); + $human_readable_tiny_mce = $match? $match[1] . '.' . $match[2] : ''; + WP_CLI::line( "TinyMCE version:\t" . ( $human_readable_tiny_mce? "$human_readable_tiny_mce ($tinymce_version)" : $tinymce_version ) ); + + WP_CLI::line( "Manifest revision:\t$manifest_version" ); + } + } + /** * Update the WordPress core * diff --git a/commands/internals/version.php b/commands/internals/version.php deleted file mode 100644 index 29bb4383e8..0000000000 --- a/commands/internals/version.php +++ /dev/null @@ -1,57 +0,0 @@ - array( 'release candidate', '%y' ), - '-beta' => array( 'beta', '%B' ), - '-' => array( 'in development', '%R' ), - ); - foreach( $version_types as $needle => $type ) { - if ( stristr( $wp_version, $needle ) ) { - list( $version_text, $color ) = $type; - $version_text = "$color$wp_version%n (stability: $version_text)"; - break; - } - } - WP_CLI::line( "WordPress version:\t$version_text" ); - } - - public function extra( $args = array() ) { - global $wp_version, $wp_db_version, $tinymce_version, $manifest_version; - $this->core( $args ); - WP_CLI::line(); - WP_CLI::line( "Database revision:\t$wp_db_version" ); - - preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); - $human_readable_tiny_mce = $match? $match[1] . '.' . $match[2] : ''; - WP_CLI::line( "TinyMCE version:\t" . ( $human_readable_tiny_mce? "$human_readable_tiny_mce ($tinymce_version)" : $tinymce_version ) ); - - WP_CLI::line( "Manifest revision:\t$manifest_version" ); - } - - public static function help() { - WP_CLI::line( << - -Available sub-commands: - core WordPress core version - extra Detailed version information -EOB - ); - } -} \ No newline at end of file From 93797635ac67280c5caf111a12fa18ed5b70e6cd Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 12 Oct 2011 22:36:40 +0300 Subject: [PATCH 0135/4858] update `core` help. see #31 --- commands/internals/core.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/commands/internals/core.php b/commands/internals/core.php index 52e61cb80e..869a463920 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -82,8 +82,7 @@ function update($args) { public static function help() { WP_CLI::line( << Date: Thu, 13 Oct 2011 03:58:33 +0300 Subject: [PATCH 0136/4858] delete '@return void' lines --- commands/community/google-sitemap-generator.php | 1 - commands/community/w3-total-cache.php | 1 - commands/community/wp-super-cache.php | 4 ---- commands/internals/core.php | 1 - commands/internals/generate.php | 2 -- commands/internals/option.php | 4 ---- commands/internals/plugin.php | 6 ------ commands/internals/theme.php | 2 -- core/class-wp-cli.php | 7 ------- 9 files changed, 28 deletions(-) diff --git a/commands/community/google-sitemap-generator.php b/commands/community/google-sitemap-generator.php index c9e8eb006c..1bcad0c2e4 100644 --- a/commands/community/google-sitemap-generator.php +++ b/commands/community/google-sitemap-generator.php @@ -19,7 +19,6 @@ class GoogleSitemapGeneratorCommand extends WP_CLI_Command { * * @param array $args * @param array $vars - * @return void */ function rebuild( $args = array(), $vars = array() ) { do_action( 'sm_rebuild' ); diff --git a/commands/community/w3-total-cache.php b/commands/community/w3-total-cache.php index 62d5ee15da..4f0344c7b6 100644 --- a/commands/community/w3-total-cache.php +++ b/commands/community/w3-total-cache.php @@ -19,7 +19,6 @@ class W3TotalCacheCommand extends WP_CLI_Command { * * @param array $args * @param array $vars - * @return void */ function flush( $args = array(), $vars = array() ) { if ( function_exists( 'w3tc_pgcache_flush' ) ) { diff --git a/commands/community/wp-super-cache.php b/commands/community/wp-super-cache.php index 6751fde068..54f7cb0635 100644 --- a/commands/community/wp-super-cache.php +++ b/commands/community/wp-super-cache.php @@ -19,7 +19,6 @@ class WPSuperCacheCommand extends WP_CLI_Command { * * @param array $args * @param array $vars - * @return void */ function flush( $args = array(), $vars = array() ) { if ( function_exists( 'wp_cache_clear_cache' ) ) { @@ -53,7 +52,6 @@ function flush( $args = array(), $vars = array() ) { * * @param array $args * @param array $vars - * @return void */ function status( $args = array(), $vars = array() ) { $cache_stats = get_option( 'supercache_stats' ); @@ -84,7 +82,6 @@ function status( $args = array(), $vars = array() ) { * * @param array $args * @param array $vars - * @return void */ function enable( $args = array(), $vars = array() ) { if ( function_exists( 'wp_super_cache_enable' ) ) { @@ -105,7 +102,6 @@ function enable( $args = array(), $vars = array() ) { * * @param array $args * @param array $vars - * @return void */ function disable( $args = array(), $vars = array() ) { if ( function_exists( 'wp_super_cache_disable' ) ) { diff --git a/commands/internals/core.php b/commands/internals/core.php index 869a463920..5f378e0983 100644 --- a/commands/internals/core.php +++ b/commands/internals/core.php @@ -49,7 +49,6 @@ public function version( $args = array(), $assoc_args = array() ) { * Update the WordPress core * * @param array $args - * @return void */ function update($args) { WP_CLI::line('Updating the WordPress core.'); diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 4fbac253c9..263eb8d01c 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -16,7 +16,6 @@ class GenerateCommand extends WP_CLI_Command { * * @param array $args * @param array $assoc_args - * @return void **/ public function posts( $args, $assoc_args ) { global $wpdb; @@ -55,7 +54,6 @@ public function posts( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - * @return void **/ public function users( $args, $assoc_args ) { global $blog_id; diff --git a/commands/internals/option.php b/commands/internals/option.php index a87866cbab..8e97061842 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -15,7 +15,6 @@ class OptionCommand extends WP_CLI_Command { * Add an option * * @param array $args - * @return void **/ public function add($args = array()) { // Check if the required arguments are there @@ -37,7 +36,6 @@ public function add($args = array()) { * Update an option * * @param array $args - * @return void **/ public function update($args = array()) { // Check if the required arguments are there @@ -59,7 +57,6 @@ public function update($args = array()) { * Delete an option * * @param array $args - * @return void **/ public function delete($args = array()) { // Check if the required arguments are there @@ -81,7 +78,6 @@ public function delete($args = array()) { * Get an option * * @param array $args - * @return void **/ public function get($args = array()) { // Check if the required arguments are there diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index a8417428ce..475f635b59 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -21,7 +21,6 @@ class PluginCommand extends WP_CLI_Command { * Get the status of one or all plugins * * @param array $args - * @return void */ function status( $args = array(), $vars = array() ) { $this->mu_plugins = get_mu_plugins(); @@ -114,7 +113,6 @@ private function get_status( $file, $long = false ) { * Activate a plugin * * @param array $args - * @return void */ function activate( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); @@ -132,7 +130,6 @@ function activate( $args ) { * Deactivate a plugin * * @param array $args - * @return void */ function deactivate( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); @@ -150,7 +147,6 @@ function deactivate( $args ) { * Toggle a plugin's activation state * * @param array $args - * @return void */ function toggle( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); @@ -227,7 +223,6 @@ function install( $args, $assoc_args ) { * Delete a plugin * * @param array $args - * @return void */ function delete( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); @@ -241,7 +236,6 @@ function delete( $args ) { * Update a plugin * * @param array $args - * @return void */ function update( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 74b784dddf..b6024a320c 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -17,7 +17,6 @@ class ThemeCommand extends WP_CLI_Command { * Get the status of one or all themes * * @param array $args - * @return void **/ public function status( $args = array() ) { if ( empty( $args ) ) { @@ -85,7 +84,6 @@ private function get_status( $theme_name, $long = false ) { * Activate a theme * * @param array $args - * @return void **/ public function activate($args = array()) { if ( empty( $args ) ) { diff --git a/core/class-wp-cli.php b/core/class-wp-cli.php index 2c5c3a043e..a70b2926d0 100644 --- a/core/class-wp-cli.php +++ b/core/class-wp-cli.php @@ -13,7 +13,6 @@ class WP_CLI { * * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command - * @return void */ public function addCommand( $name, $class ) { self::$commands[$name] = $class; @@ -23,7 +22,6 @@ public function addCommand( $name, $class ) { * Display a message in the cli * * @param string $message - * @return void */ static function out( $message ) { \cli\out($message); @@ -33,7 +31,6 @@ static function out( $message ) { * Display a message in the CLI and end with a newline * * @param string $message - * @return void */ static function line( $message = '' ) { \cli\line($message); @@ -44,7 +41,6 @@ static function line( $message = '' ) { * * @param string $message * @param string $label - * @return void */ static function error( $message, $label = 'Error' ) { \cli\line( '%R' . $label . ': %n' . self::errorToString( $message ) ); @@ -55,7 +51,6 @@ static function error( $message, $label = 'Error' ) { * * @param string $message * @param string $label - * @return void */ static function success( $message, $label = 'Success' ) { \cli\line( '%G' . $label . ': %n' . $message ); @@ -66,7 +61,6 @@ static function success( $message, $label = 'Success' ) { * * @param string $message * @param string $label - * @return void */ static function warning( $message, $label = 'Warning' ) { \cli\line( '%C' . $label . ': %n' . $message ); @@ -137,7 +131,6 @@ static function compose_args( $args, $assoc_args = array() ) { * Display a legend * * @param array( code => title ) $legend - * @return void */ static function legend( $legend ) { $legend[ '%yU' ] = 'Update Available'; From e9389c26237542958eae72c56de1b0aa96389da2 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 13 Oct 2011 04:12:05 +0300 Subject: [PATCH 0137/4858] implement wp plugin path. closes #35 --- commands/internals/plugin.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 475f635b59..2bfd282b64 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -158,6 +158,26 @@ function toggle( $args ) { } } + /** + * Get a plugin path + * + * @param array $args + * @param array $assoc_args + */ + function path( $args, $assoc_args ) { + if ( empty( $args ) ) { + $path = WP_PLUGIN_DIR; + } else { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + $path = untrailingslashit( WP_PLUGIN_DIR ) . '/' . $file; + + if ( isset( $assoc_args['directory'] ) ) + $path = dirname( $path ); + } + + WP_CLI::line( $path ); + } + /** * Install a new plugin * @@ -321,12 +341,15 @@ private function parse_name( $args, $subcommand ) { public static function help() { WP_CLI::line( << [] + or: wp plugin path [] [--directory] + or: wp plugin install [--activate] Available sub-commands: status display status of all installed plugins or of a particular plugin activate activate a particular plugin deactivate deactivate a particular plugin toggle toggle activation state of a particular plugin + path print path to the plugin's file install install a plugin from wordpress.org update update a plugin from wordpress.org delete delete a plugin From 6a75cfe1da1edc31e007f5186a4a47f5d6f3ac87 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 13 Oct 2011 04:37:55 +0300 Subject: [PATCH 0138/4858] implement `wp theme path`. see #35 --- commands/internals/plugin.php | 8 ++--- commands/internals/theme.php | 56 ++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 2bfd282b64..906a712b8a 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -165,11 +165,11 @@ function toggle( $args ) { * @param array $assoc_args */ function path( $args, $assoc_args ) { - if ( empty( $args ) ) { - $path = WP_PLUGIN_DIR; - } else { + $path = untrailingslashit( WP_PLUGIN_DIR ); + + if ( !empty( $args ) ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - $path = untrailingslashit( WP_PLUGIN_DIR ) . '/' . $file; + $path .= '/' . $file; if ( isset( $assoc_args['directory'] ) ) $path = dirname( $path ); diff --git a/commands/internals/theme.php b/commands/internals/theme.php index b6024a320c..4f3ff1a3cc 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -85,33 +85,59 @@ private function get_status( $theme_name, $long = false ) { * * @param array $args **/ - public function activate($args = array()) { - if ( empty( $args ) ) { - WP_CLI::line('usage: wp theme activate '); + public function activate( $args = array() ) { + list( $stylesheet, $child ) = $this->parse_name( $args, __FUNCTION__ ); + + $details = get_theme_data( $stylesheet ); + + $parent = $details['Template']; + + if ( empty( $parent ) ) { + $parent = $child; + } elseif ( !is_readable( $this->get_stylesheet_path( $parent ) ) ) { + WP_CLI::warning( 'parent theme not found' ); exit; } - $child = array_shift( $args ); + switch_theme( $parent, $child ); + } - $stylesheet = $this->get_stylesheet_path( $child ); + /** + * Get a theme path + * + * @param array $args + * @param array $assoc_args + */ + function path( $args, $assoc_args ) { + if ( empty( $args ) ) { + $path = WP_CONTENT_DIR . '/themes'; + } else { + list( $stylesheet, $name ) = $this->parse_name( $args, __FUNCTION__ ); + $path = $stylesheet; - if ( !is_readable( $stylesheet ) ) { - WP_CLI::warning( 'theme not found' ); + if ( isset( $assoc_args['directory'] ) ) + $path = dirname( $path ); + } + + WP_CLI::line( $path ); + } + + protected function parse_name( $args, $subcommand ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp theme $subcommand " ); exit; } - $details = get_theme_data( $stylesheet ); + $name = $args[0]; - $parent = $details['Template']; + $stylesheet = $this->get_stylesheet_path( $name ); - if ( empty( $parent ) ) { - $parent = $child; - } elseif ( !is_readable( $this->get_stylesheet_path ( $parent ) ) ) { - WP_CLI::warning( 'parent theme not found' ); + if ( !is_readable( $stylesheet ) ) { + WP_CLI::error( "The theme '$name' could not be found." ); exit; } - switch_theme( $parent, $child ); + return array( $stylesheet, $name ); } protected function get_stylesheet_path( $theme ) { @@ -124,10 +150,12 @@ protected function get_stylesheet_path( $theme ) { public static function help() { WP_CLI::line( << [] + or: wp theme path [] [--directory] Available sub-commands: status display status of all installed themes or of a particular theme activate activate a particular theme + path print path to the theme's stylesheet EOB ); } From 53e31d5940287ed2319b001ecd49b047311da6ec Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 14 Oct 2011 00:47:18 +0300 Subject: [PATCH 0139/4858] fix warning when --blog does not contain trailing slash --- core/wp-cli.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/wp-cli.php b/core/wp-cli.php index 438c30a1d8..b31ffcc8f4 100755 --- a/core/wp-cli.php +++ b/core/wp-cli.php @@ -54,6 +54,9 @@ } if ( isset( $blog ) ) { + if ( false === strpos( $blog, '/' ) ) + $blog .= '/'; + list( $domain, $path ) = explode( '/', $blog, 2 ); $_SERVER['HTTP_HOST'] = $domain; From 23a6b63eed527443c70026b1ecb0622ba486c166 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 14 Oct 2011 00:50:24 +0300 Subject: [PATCH 0140/4858] put Status after Name. just seems more natural --- commands/internals/plugin.php | 2 +- commands/internals/theme.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/internals/plugin.php b/commands/internals/plugin.php index 906a712b8a..04ff2470df 100644 --- a/commands/internals/plugin.php +++ b/commands/internals/plugin.php @@ -42,8 +42,8 @@ function status( $args = array(), $vars = array() ) { $version .= ' (%gUpdate available%n)'; WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); - WP_CLI::line( ' Status: ' . $status .'%n' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + WP_CLI::line( ' Status: ' . $status .'%n' ); WP_CLI::line( ' Version: ' . $version ); WP_CLI::line( ' Author: ' . $details[ 'Author' ] ); WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); diff --git a/commands/internals/theme.php b/commands/internals/theme.php index 4f3ff1a3cc..70c55ebf8d 100644 --- a/commands/internals/theme.php +++ b/commands/internals/theme.php @@ -36,8 +36,8 @@ public function status( $args = array() ) { $version .= ' (%gUpdate available%n)'; WP_CLI::line( 'Theme %9' . $name . '%n details:' ); - WP_CLI::line( ' Status: ' . $status .'%n' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + WP_CLI::line( ' Status: ' . $status .'%n' ); WP_CLI::line( ' Version: ' . $version ); WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } From a442200f4443b93521b305a9c648ea8c31ef1c1e Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 19 Oct 2011 03:53:37 +0300 Subject: [PATCH 0141/4858] allow wp generate users --role=none --- commands/internals/generate.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/commands/internals/generate.php b/commands/internals/generate.php index 263eb8d01c..e4aa158033 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -65,7 +65,9 @@ public function users( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - if ( is_null( get_role( $role ) ) ) { + if ( 'none' == $role ) + $role = false; + elseif ( is_null( get_role( $role ) ) ) { WP_CLI::warning( "invalid role." ); exit; } From 2649a4ea20ec20b17571eb7a1fe2cb383424b88f Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 19 Oct 2011 06:02:56 +0300 Subject: [PATCH 0142/4858] explicitly delete capabilites when role=none --- commands/internals/generate.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/commands/internals/generate.php b/commands/internals/generate.php index e4aa158033..d38efbc0d1 100644 --- a/commands/internals/generate.php +++ b/commands/internals/generate.php @@ -65,9 +65,9 @@ public function users( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - if ( 'none' == $role ) + if ( 'none' == $role ) { $role = false; - elseif ( is_null( get_role( $role ) ) ) { + } elseif ( is_null( get_role( $role ) ) ) { WP_CLI::warning( "invalid role." ); exit; } @@ -82,13 +82,18 @@ public function users( $args, $assoc_args ) { $login = sprintf( 'user_%d_%d', $blog_id, $i ); $name = "User $i"; - $r = wp_insert_user( array( + $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' ); + } } } From cd673787a7a95729317de3293498a5b4a7d96f59 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 25 Oct 2011 20:45:47 +0300 Subject: [PATCH 0143/4858] improve `wp option get` output. see #37 --- commands/internals/option.php | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/commands/internals/option.php b/commands/internals/option.php index 8e97061842..1cabe89150 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -80,19 +80,22 @@ public function delete($args = array()) { * @param array $args **/ public function get($args = array()) { - // Check if the required arguments are there - if(count($args) == 1) { - // Try to get the option - $option = get_option($args[0]); - if($option) { - WP_CLI::success('The value of option %9'.$args[0].'%n is \'%9'.$option.'%n\'.'); - } - else { - WP_CLI::error('Option %9'.$args[0].'%n could not be found. Does it exist?'); - } + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp option get " ); + exit; } - else { - WP_CLI::error('This command needs exactly one argument.'); + + $key = $args[0]; + + $value = get_option( $key ); + + if ( false === $value ) + return; + + if ( is_array( $value ) || is_object( $value ) ) { + WP_CLI::line( var_export( $value ) ); + } else { + WP_CLI::line( $value ); } } From a53adfd5b5bcbafe7c9bdc678a42957b153cd7df Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 25 Oct 2011 21:12:45 +0300 Subject: [PATCH 0144/4858] clean up the rest of the option subcommands. see #37 --- commands/internals/option.php | 70 ++++++++++++++++------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/commands/internals/option.php b/commands/internals/option.php index 1cabe89150..8dc34c7f39 100644 --- a/commands/internals/option.php +++ b/commands/internals/option.php @@ -16,19 +16,16 @@ class OptionCommand extends WP_CLI_Command { * * @param array $args **/ - public function add($args = array()) { - // Check if the required arguments are there - if(count($args) == 2) { - // Try to add the option - if(add_option($args[0], $args[1])) { - WP_CLI::success('Added option %9'.$args[0].'%n to \'%9'.$args[1].'%n\'.'); - } - else { - WP_CLI::error('Option %9'.$args[0].'%n could not be added. Does it already exist?'); - } + public function add( $args ) { + if ( count( $args ) < 2 ) { + WP_CLI::line( "usage: wp option add " ); + exit; } - else { - WP_CLI::error('This command needs exactly two arguments.'); + + list( $key, $value ) = $args; + + if ( !add_option( $key, $value ) ) { + WP_CLI::error( "Could not add option '$key'. Does it already exist?" ); } } @@ -37,19 +34,19 @@ public function add($args = array()) { * * @param array $args **/ - public function update($args = array()) { - // Check if the required arguments are there - if(count($args) == 2) { - // Try to update the option - if(update_option($args[0], $args[1])) { - WP_CLI::success('Updated option %9'.$args[0].'%n to \'%9'.$args[1].'%n\'.'); - } - else { - WP_CLI::error('Option %9'.$args[0].'%n could not be updated. Does it exist? Is the value already \'%9'.$args[1].'%n\'?'); - } + public function update( $args ) { + if ( count( $args ) < 2 ) { + WP_CLI::line( "usage: wp option update " ); + exit; } - else { - WP_CLI::error('This command needs exactly two arguments.'); + + list( $key, $value ) = $args; + + if ( $value === get_option( $key ) ) + return; + + if ( !update_option( $key, $value ) ) { + WP_CLI::error( "Could not update option '$key'." ); } } @@ -58,19 +55,16 @@ public function update($args = array()) { * * @param array $args **/ - public function delete($args = array()) { - // Check if the required arguments are there - if(count($args) == 1) { - // Try to delete the option - if(delete_option($args[0])) { - WP_CLI::success('Deleted option %9'.$args[0].'%n.'); - } - else { - WP_CLI::error('Option %9'.$args[0].'%n could not be deleted. Does it exist?'); - } + public function delete( $args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp option get " ); + exit; } - else { - WP_CLI::error('This command needs exactly one argument.'); + + list( $key ) = $args; + + if ( !delete_option( $key ) ) { + WP_CLI::error( "Could not delete '$key' option. Does it exist?" ); } } @@ -79,13 +73,13 @@ public function delete($args = array()) { * * @param array $args **/ - public function get($args = array()) { + public function get( $args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp option get " ); exit; } - $key = $args[0]; + list( $key ) = $args; $value = get_option( $key ); From 4b907b2d5ff6f96162516d5ced2e51ffbfd6ea21 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Oct 2011 17:09:16 +0300 Subject: [PATCH 0145/4858] use --recurse-submodules option --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 3e20deaab9..95aafc3119 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,7 @@ First, make sure you have `php-cli` version 5.3 or newer installed. Clone the project: ``` -git clone https://github.com/andreascreten/wp-cli.git -cd wp-cli -git submodule update --init +git clone --recurse-submodules https://github.com/andreascreten/wp-cli.git ``` Make a symlink to the executable: From 42c8cfdbb5498b9c05db23c6aec6bdad5a5123b6 Mon Sep 17 00:00:00 2001 From: Edgar Marca Date: Thu, 27 Oct 2011 11:21:03 -0500 Subject: [PATCH 0146/4858] SQL command for wp-cli --- commands/internals/sql.php | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 commands/internals/sql.php diff --git a/commands/internals/sql.php b/commands/internals/sql.php new file mode 100644 index 0000000000..2b2c7d3e61 --- /dev/null +++ b/commands/internals/sql.php @@ -0,0 +1,63 @@ + STDIN, 1 => STDOUT, 2 => STDERR), $pipes) ); + } + + /** + * Exports the wordpress DB as SQL using mysqldump or equivalent. + * @param string $args + * @return void + */ + function dump( $args, $assoc_args ) { + if ( !isset($assoc_args['file']) ) { + $result_file = sprintf('%s.sql', DB_NAME); + } else { + $result_file = $assoc_args['file']; + } + + $exec = sprintf('mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD); + exec($exec); + } + +} From b22dc21ebb12bd146094c5a7308e052e65f1bc29 Mon Sep 17 00:00:00 2001 From: Edgar Marca Date: Thu, 27 Oct 2011 11:40:10 -0500 Subject: [PATCH 0147/4858] Following wordpress coding standards --- commands/internals/sql.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index 2b2c7d3e61..4cef97a388 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -9,7 +9,7 @@ // Add the command to the wp-cli -WP_CLI::addCommand('sql', 'SqlCommand'); +WP_CLI::addCommand( 'sql', 'SqlCommand' ); /** * Implement sql command @@ -39,9 +39,9 @@ function connect( $args = array() ) { * @return void */ function cli() { - $exec = sprintf('mysql --user=%s --password=%s', DB_USER, DB_PASSWORD); + $exec = sprintf( 'mysql --user=%s --password=%s', DB_USER, DB_PASSWORD ); - proc_close( proc_open($exec , array(0 => STDIN, 1 => STDOUT, 2 => STDERR), $pipes) ); + proc_close( proc_open( $exec , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); } /** @@ -50,14 +50,14 @@ function cli() { * @return void */ function dump( $args, $assoc_args ) { - if ( !isset($assoc_args['file']) ) { - $result_file = sprintf('%s.sql', DB_NAME); + if ( !isset( $assoc_args['file'] ) ) { + $result_file = sprintf( '%s.sql', DB_NAME ); } else { $result_file = $assoc_args['file']; } - $exec = sprintf('mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD); - exec($exec); + $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD ); + exec( $exec ); } } From 5befc322dee420e1f41f6257264e78d73cb6ba1e Mon Sep 17 00:00:00 2001 From: Edgar Marca Date: Thu, 27 Oct 2011 12:09:43 -0500 Subject: [PATCH 0148/4858] Add query sub command --- commands/internals/sql.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index 4cef97a388..70d95f07d7 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -60,4 +60,21 @@ function dump( $args, $assoc_args ) { exec( $exec ); } + /** + * Execute a query against the site database. + * @param string $args + * @return void + */ + + function query( $args, $assoc_args ) { + if ( !$args[0] ) { + WP_CLI::line( 'Please add a query.' ); + } + + $query = $args[0]; + $connect = 'mysql --database=' . DB_NAME . ' --user=' . DB_USER . ' --password=' . DB_PASSWORD; + $exec = sprintf( 'mysql --database=%s --user=%s --password=%s --execute="%s"', DB_NAME, DB_USER, DB_PASSWORD, $query ); + $result = exec( $exec ); + WP_CLI::line( $result ); + } } From 8829097e079d338928024e98a9a15469f0f9fd1d Mon Sep 17 00:00:00 2001 From: Edgar Marca Date: Thu, 27 Oct 2011 12:14:34 -0500 Subject: [PATCH 0149/4858] Remove TODO text --- commands/internals/sql.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index 70d95f07d7..d16ba6f816 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -1,12 +1,4 @@ Date: Thu, 27 Oct 2011 13:26:26 -0500 Subject: [PATCH 0150/4858] Add private function that return the string connection --- commands/internals/sql.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index d16ba6f816..50fe8b45ad 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -14,6 +14,18 @@ class SqlCommand extends WP_CLI_Command { protected $default_subcommand = 'cli'; + /** + * return a string to connecting to the DB. + * + * @param void + * @return string $connect + */ + protected function connect_string() { + $connect = sprintf( 'mysql --database=%s --user=%s --password=%s', + DB_NAME, DB_USER, DB_PASSWORD); + return $connect; + } + /** * A string for connecting to the DB. * @@ -21,7 +33,7 @@ class SqlCommand extends WP_CLI_Command { * @return void */ function connect( $args = array() ) { - $connect = 'mysql --database=' . DB_NAME . ' --user=' . DB_USER . ' --password=' . DB_PASSWORD; + $connect = $this->connect_string(); WP_CLI::line( $connect ); } @@ -31,7 +43,7 @@ function connect( $args = array() ) { * @return void */ function cli() { - $exec = sprintf( 'mysql --user=%s --password=%s', DB_USER, DB_PASSWORD ); + $exec = $this->connect_string(); proc_close( proc_open( $exec , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); } @@ -49,6 +61,7 @@ function dump( $args, $assoc_args ) { } $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD ); + exec( $exec ); } @@ -64,8 +77,10 @@ function query( $args, $assoc_args ) { } $query = $args[0]; - $connect = 'mysql --database=' . DB_NAME . ' --user=' . DB_USER . ' --password=' . DB_PASSWORD; - $exec = sprintf( 'mysql --database=%s --user=%s --password=%s --execute="%s"', DB_NAME, DB_USER, DB_PASSWORD, $query ); + + $exec = $this->connect_string(); + $exec .= sprintf(' --execute="%s"', $query); + $result = exec( $exec ); WP_CLI::line( $result ); } From 829667a20c346a4ca893cf209f79bce6aae84df9 Mon Sep 17 00:00:00 2001 From: Edgar Marca Date: Thu, 27 Oct 2011 13:31:55 -0500 Subject: [PATCH 0151/4858] Add help --- commands/internals/sql.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index 50fe8b45ad..f12e545868 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -84,4 +84,17 @@ function query( $args, $assoc_args ) { $result = exec( $exec ); WP_CLI::line( $result ); } + + /** + * Help function for this command + */ + public static function help() { + WP_CLI::line( << Date: Thu, 27 Oct 2011 23:29:28 +0300 Subject: [PATCH 0152/4858] some string fixes. see #38 --- commands/internals/sql.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index f12e545868..915bde7e03 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -29,7 +29,7 @@ protected function connect_string() { /** * A string for connecting to the DB. * - * @param string $args + * @param string $args * @return void */ function connect( $args = array() ) { @@ -38,19 +38,19 @@ function connect( $args = array() ) { } /** - * Open a SQL command-line interface using Wordpress's credentials. - * @param string $args + * Open a SQL command-line interface using WordPress's credentials. + * @param string $args * @return void */ function cli() { $exec = $this->connect_string(); proc_close( proc_open( $exec , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); - } + } /** - * Exports the wordpress DB as SQL using mysqldump or equivalent. - * @param string $args + * Exports the WordPress DB as SQL using mysqldump or equivalent. + * @param string $args * @return void */ function dump( $args, $assoc_args ) { @@ -63,11 +63,11 @@ function dump( $args, $assoc_args ) { $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD ); exec( $exec ); - } - + } + /** * Execute a query against the site database. - * @param string $args + * @param string $args * @return void */ @@ -90,10 +90,10 @@ function query( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( << Date: Thu, 27 Oct 2011 23:34:52 +0300 Subject: [PATCH 0153/4858] internal commands don't have a single maintainer; they're public property. see #38 --- commands/internals/sql.php | 1 - 1 file changed, 1 deletion(-) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index 915bde7e03..436d76c5a3 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -8,7 +8,6 @@ * * @package wp-cli * @subpackage commands/internals - * @maintainer Edgar Marca (http://twitter.com/matiskay) **/ class SqlCommand extends WP_CLI_Command { From c9fa9f9f73d53c22111ef021ddb8cea54234b934 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 27 Oct 2011 23:43:32 +0300 Subject: [PATCH 0154/4858] fix indentation. #38 --- commands/internals/sql.php | 141 +++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/commands/internals/sql.php b/commands/internals/sql.php index 436d76c5a3..8e76699d55 100644 --- a/commands/internals/sql.php +++ b/commands/internals/sql.php @@ -13,76 +13,77 @@ class SqlCommand extends WP_CLI_Command { protected $default_subcommand = 'cli'; - /** - * return a string to connecting to the DB. - * - * @param void - * @return string $connect - */ - protected function connect_string() { - $connect = sprintf( 'mysql --database=%s --user=%s --password=%s', - DB_NAME, DB_USER, DB_PASSWORD); - return $connect; - } - - /** - * A string for connecting to the DB. - * - * @param string $args - * @return void - */ - function connect( $args = array() ) { - $connect = $this->connect_string(); - WP_CLI::line( $connect ); - } - - /** - * Open a SQL command-line interface using WordPress's credentials. - * @param string $args - * @return void - */ - function cli() { - $exec = $this->connect_string(); - - proc_close( proc_open( $exec , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); - } - - /** - * Exports the WordPress DB as SQL using mysqldump or equivalent. - * @param string $args - * @return void - */ - function dump( $args, $assoc_args ) { - if ( !isset( $assoc_args['file'] ) ) { - $result_file = sprintf( '%s.sql', DB_NAME ); - } else { - $result_file = $assoc_args['file']; - } - - $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD ); - - exec( $exec ); - } - - /** - * Execute a query against the site database. - * @param string $args - * @return void - */ - - function query( $args, $assoc_args ) { - if ( !$args[0] ) { - WP_CLI::line( 'Please add a query.' ); - } - - $query = $args[0]; - - $exec = $this->connect_string(); - $exec .= sprintf(' --execute="%s"', $query); - - $result = exec( $exec ); - WP_CLI::line( $result ); - } + /** + * return a string to connecting to the DB. + * + * @param void + * @return string $connect + */ + protected function connect_string() { + $connect = sprintf( 'mysql --database=%s --user=%s --password=%s', + DB_NAME, DB_USER, DB_PASSWORD); + return $connect; + } + + /** + * A string for connecting to the DB. + * + * @param string $args + * @return void + */ + function connect( $args = array() ) { + $connect = $this->connect_string(); + WP_CLI::line( $connect ); + } + + /** + * Open a SQL command-line interface using WordPress's credentials. + * @param string $args + * @return void + */ + function cli() { + $exec = $this->connect_string(); + + proc_close( proc_open( $exec , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); + } + + /** + * Exports the WordPress DB as SQL using mysqldump or equivalent. + * @param string $args + * @return void + */ + function dump( $args, $assoc_args ) { + if ( !isset( $assoc_args['file'] ) ) { + $result_file = sprintf( '%s.sql', DB_NAME ); + } else { + $result_file = $assoc_args['file']; + } + + $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD ); + + exec( $exec ); + } + + /** + * Execute a query against the site database. + * @param string $args + * @return void + */ + + function query( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp sql query " ); + exit; + } + + $query = $args[0]; + + $exec = $this->connect_string(); + $exec .= sprintf(' --execute="%s"', $query); + + $result = exec( $exec ); + WP_CLI::line( $result ); + } /** * Help function for this command From bfd5a9d26a78e75571f89b5949fc704ac92b6def Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 5 Nov 2011 22:48:00 +0200 Subject: [PATCH 0155/4858] tentative 0.2 version --- core/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/wp-cli.php b/core/wp-cli.php index b31ffcc8f4..293ffe1c28 100755 --- a/core/wp-cli.php +++ b/core/wp-cli.php @@ -4,7 +4,7 @@ die('Only cli access'); } -define( 'WP_CLI_VERSION', '0.2-alpha' ); +define( 'WP_CLI_VERSION', '0.2' ); // Define the wp-cli location define( 'WP_CLI_ROOT', realpath( __DIR__ . '/..' ) . '/' ); From 9f1289be7eac653afa0b64fb4734d489fe3d6a63 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 01:02:22 +0200 Subject: [PATCH 0156/4858] re-organize files --- .gitmodules | 4 ++-- LICENSE => LICENSE.txt | 0 README.md | 4 ++-- {bin => src/bin}/wp | 2 +- {bin => src/bin}/wp-completion.bash | 0 {core => src/php}/class-wp-cli-command.php | 0 {core => src/php}/class-wp-cli.php | 0 .../php/commands}/community/google-sitemap-generator.php | 0 {commands => src/php/commands}/community/w3-total-cache.php | 0 {commands => src/php/commands}/community/wp-super-cache.php | 0 {commands => src/php/commands}/internals/core.php | 0 {commands => src/php/commands}/internals/generate.php | 0 {commands => src/php/commands}/internals/help.php | 0 {commands => src/php/commands}/internals/home.php | 0 {commands => src/php/commands}/internals/option.php | 0 {commands => src/php/commands}/internals/plugin.php | 0 {commands => src/php/commands}/internals/sql.php | 0 {commands => src/php/commands}/internals/theme.php | 0 php-cli-tools => src/php/php-cli-tools | 0 {core => src/php}/wp-cli.php | 6 +++--- 20 files changed, 8 insertions(+), 8 deletions(-) rename LICENSE => LICENSE.txt (100%) rename {bin => src/bin}/wp (98%) rename {bin => src/bin}/wp-completion.bash (100%) rename {core => src/php}/class-wp-cli-command.php (100%) rename {core => src/php}/class-wp-cli.php (100%) rename {commands => src/php/commands}/community/google-sitemap-generator.php (100%) rename {commands => src/php/commands}/community/w3-total-cache.php (100%) rename {commands => src/php/commands}/community/wp-super-cache.php (100%) rename {commands => src/php/commands}/internals/core.php (100%) rename {commands => src/php/commands}/internals/generate.php (100%) rename {commands => src/php/commands}/internals/help.php (100%) rename {commands => src/php/commands}/internals/home.php (100%) rename {commands => src/php/commands}/internals/option.php (100%) rename {commands => src/php/commands}/internals/plugin.php (100%) rename {commands => src/php/commands}/internals/sql.php (100%) rename {commands => src/php/commands}/internals/theme.php (100%) rename php-cli-tools => src/php/php-cli-tools (100%) rename {core => src/php}/wp-cli.php (94%) diff --git a/.gitmodules b/.gitmodules index a2f6eaebb7..44afb303c6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "php-cli-tools"] - path = php-cli-tools +[submodule "src/php/php-cli-tools"] + path = src/php/php-cli-tools url = git://github.com/jlogsdon/php-cli-tools.git diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/README.md b/README.md index 95aafc3119..acd340c9f8 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,13 @@ git clone --recurse-submodules https://github.com/andreascreten/wp-cli.git Make a symlink to the executable: ``` -sudo ln -s /path-to-wp-cli-dir/bin/wp /usr/local/bin/ +sudo ln -s /path-to-wp-cli-dir/src/bin/wp /usr/local/bin/ ``` Make a symlink to the autocomplete file (Linux): ``` -sudo ln -s /path-to-wp-cli-dir/bin/wp-completion.bash /etc/bash_completion.d/wp +sudo ln -s /path-to-wp-cli-dir/src/bin/wp-completion.bash /etc/bash_completion.d/wp ``` Usage diff --git a/bin/wp b/src/bin/wp similarity index 98% rename from bin/wp rename to src/bin/wp index 9c0894e5c9..fed73b5e67 100755 --- a/bin/wp +++ b/src/bin/wp @@ -30,7 +30,7 @@ done cd "$ORIGDIR" # Build the path to wp-cli.php. -SCRIPT_PATH=$(dirname "$SELF_PATH")/../core/wp-cli.php +SCRIPT_PATH=$(dirname "$SELF_PATH")/../php/wp-cli.php case $(uname -a) in CYGWIN*) SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; diff --git a/bin/wp-completion.bash b/src/bin/wp-completion.bash similarity index 100% rename from bin/wp-completion.bash rename to src/bin/wp-completion.bash diff --git a/core/class-wp-cli-command.php b/src/php/class-wp-cli-command.php similarity index 100% rename from core/class-wp-cli-command.php rename to src/php/class-wp-cli-command.php diff --git a/core/class-wp-cli.php b/src/php/class-wp-cli.php similarity index 100% rename from core/class-wp-cli.php rename to src/php/class-wp-cli.php diff --git a/commands/community/google-sitemap-generator.php b/src/php/commands/community/google-sitemap-generator.php similarity index 100% rename from commands/community/google-sitemap-generator.php rename to src/php/commands/community/google-sitemap-generator.php diff --git a/commands/community/w3-total-cache.php b/src/php/commands/community/w3-total-cache.php similarity index 100% rename from commands/community/w3-total-cache.php rename to src/php/commands/community/w3-total-cache.php diff --git a/commands/community/wp-super-cache.php b/src/php/commands/community/wp-super-cache.php similarity index 100% rename from commands/community/wp-super-cache.php rename to src/php/commands/community/wp-super-cache.php diff --git a/commands/internals/core.php b/src/php/commands/internals/core.php similarity index 100% rename from commands/internals/core.php rename to src/php/commands/internals/core.php diff --git a/commands/internals/generate.php b/src/php/commands/internals/generate.php similarity index 100% rename from commands/internals/generate.php rename to src/php/commands/internals/generate.php diff --git a/commands/internals/help.php b/src/php/commands/internals/help.php similarity index 100% rename from commands/internals/help.php rename to src/php/commands/internals/help.php diff --git a/commands/internals/home.php b/src/php/commands/internals/home.php similarity index 100% rename from commands/internals/home.php rename to src/php/commands/internals/home.php diff --git a/commands/internals/option.php b/src/php/commands/internals/option.php similarity index 100% rename from commands/internals/option.php rename to src/php/commands/internals/option.php diff --git a/commands/internals/plugin.php b/src/php/commands/internals/plugin.php similarity index 100% rename from commands/internals/plugin.php rename to src/php/commands/internals/plugin.php diff --git a/commands/internals/sql.php b/src/php/commands/internals/sql.php similarity index 100% rename from commands/internals/sql.php rename to src/php/commands/internals/sql.php diff --git a/commands/internals/theme.php b/src/php/commands/internals/theme.php similarity index 100% rename from commands/internals/theme.php rename to src/php/commands/internals/theme.php diff --git a/php-cli-tools b/src/php/php-cli-tools similarity index 100% rename from php-cli-tools rename to src/php/php-cli-tools diff --git a/core/wp-cli.php b/src/php/wp-cli.php similarity index 94% rename from core/wp-cli.php rename to src/php/wp-cli.php index 293ffe1c28..36f7fac15f 100755 --- a/core/wp-cli.php +++ b/src/php/wp-cli.php @@ -7,14 +7,14 @@ define( 'WP_CLI_VERSION', '0.2' ); // Define the wp-cli location -define( 'WP_CLI_ROOT', realpath( __DIR__ . '/..' ) . '/' ); +define( 'WP_CLI_ROOT', __DIR__ . '/' ); // Set a constant that can be used to check if we are running wp-cli or not define('WP_CLI', true); // Include the wp-cli classes -include WP_CLI_ROOT . 'core/class-wp-cli.php'; -include WP_CLI_ROOT . 'core/class-wp-cli-command.php'; +include WP_CLI_ROOT . 'class-wp-cli.php'; +include WP_CLI_ROOT . 'class-wp-cli-command.php'; // Include the command line tools include WP_CLI_ROOT . 'php-cli-tools/lib/cli/cli.php'; From 330600f13a09be4eaff50ce6187371b1afb06700 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 03:18:32 +0200 Subject: [PATCH 0157/4858] add pear package files --- .gitignore | 6 + build.local.xml | 6 + build.properties | 13 ++ build.xml | 440 +++++++++++++++++++++++++++++++++++++++++++++ package.xml | 71 ++++++++ src/php/wp-cli.php | 2 +- 6 files changed, 537 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 build.local.xml create mode 100644 build.properties create mode 100644 build.xml create mode 100644 package.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..e89c07b326 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.build +dist +.tmp +nbproject +review +vendor diff --git a/build.local.xml b/build.local.xml new file mode 100644 index 0000000000..90aa3bc92e --- /dev/null +++ b/build.local.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/build.properties b/build.properties new file mode 100644 index 0000000000..ea12db9df4 --- /dev/null +++ b/build.properties @@ -0,0 +1,13 @@ +project.name=wpcli +project.channel=andreascreten.github.com/wp-cli +project.majorVersion=1 +project.minorVersion=0 +project.patchLevel=0 +project.snapshot=false + +checkstyle.standard=Zend + +component.type=php-library +component.version=10 + +pear.local=/var/www/${project.channel} diff --git a/build.xml b/build.xml new file mode 100644 index 0000000000..a3b5079217 --- /dev/null +++ b/build.xml @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The code coverage report is in file://${project.review.codecoveragedir} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Populating vendor/ with dependencies + + + + Your vendor/ folder has been built. + You only need to run 'phing build-vendor' again if you change the + dependencies listed in your package.xml file. + + + + + + + Creating vendor/ as a sandboxed PEAR install folder + + + + + + + + + + + + + + + + + Building release directory + + + + + + + + + + + + + + + + + + + + Creating ${project.tarfile} PEAR package + + + + + + + + + + + + project.lastBuiltTarfile=${project.tarfile} + + + Your PEAR package is in ${project.tarfile} + + + + + + + + + + + Please run 'phing pear-package' first, then try again. + + + + + + + + + + Cannot find PEAR package file ${project.lastBuiltTarfile} + Run 'phing pear-package' to create a new PEAR package, then try again + + + + + + + + + + + + Please run 'phing pear-package' first, then try again. + + + + + + + + + + Cannot find PEAR package file ${project.lastBuiltTarfile} + Run 'phing pear-package' to create a new PEAR package, then try again + + + + + + + + + + + + Please run 'phing pear-package' first, then try again. + + + + + + + + + + + + + + + + + + Cannot find PEAR package file ${project.lastBuiltTarfile} + Run 'phing pear-package' to create a new PEAR package, then try again + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package.xml b/package.xml new file mode 100644 index 0000000000..aa11e65f2c --- /dev/null +++ b/package.xml @@ -0,0 +1,71 @@ + + + ${project.name} + ${project.channel} + WordPress CLI interface + + A tool for controlling WordPress through the command line. + + + Andreas Creten + andreascreten + + yes + + + scribu + scribu + mail@scribu.net + yes + + ${build.date} + + + ${project.version} + ${project.majorVersion}.${project.minorVersion} + + + ${project.stability} + stable + + GPL 2+ + + No notes. + + + +${contents} + + + + + + 5.3.0 + + + 1.9.4 + + + + + + + + X.Y.Z + X.Y + + + stable + stable + + Your release date + All rights reserved + + + + + + diff --git a/src/php/wp-cli.php b/src/php/wp-cli.php index 36f7fac15f..8fd82d2154 100755 --- a/src/php/wp-cli.php +++ b/src/php/wp-cli.php @@ -4,7 +4,7 @@ die('Only cli access'); } -define( 'WP_CLI_VERSION', '0.2' ); +define( 'WP_CLI_VERSION', '1.0.0' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 1313d6711fd67f922f30d328d68feebbcbe98dfd Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 14:05:23 +0200 Subject: [PATCH 0158/4858] fix pear package; set version to 0.3.0 --- build.properties | 4 ++-- src/bin/wp | 6 ++++- src/php/{ => wp-cli}/class-wp-cli-command.php | 0 src/php/{ => wp-cli}/class-wp-cli.php | 0 .../community/google-sitemap-generator.php | 0 .../commands/community/w3-total-cache.php | 0 .../commands/community/wp-super-cache.php | 0 .../{ => wp-cli}/commands/internals/core.php | 0 .../commands/internals/generate.php | 0 .../{ => wp-cli}/commands/internals/help.php | 0 .../{ => wp-cli}/commands/internals/home.php | 0 .../commands/internals/option.php | 0 .../commands/internals/plugin.php | 0 .../{ => wp-cli}/commands/internals/sql.php | 0 .../{ => wp-cli}/commands/internals/theme.php | 0 src/php/{ => wp-cli}/wp-cli.php | 4 ++-- utils/build-pear | 23 +++++++++++++++++++ {src/bin => utils}/wp-completion.bash | 0 18 files changed, 32 insertions(+), 5 deletions(-) rename src/php/{ => wp-cli}/class-wp-cli-command.php (100%) rename src/php/{ => wp-cli}/class-wp-cli.php (100%) rename src/php/{ => wp-cli}/commands/community/google-sitemap-generator.php (100%) rename src/php/{ => wp-cli}/commands/community/w3-total-cache.php (100%) rename src/php/{ => wp-cli}/commands/community/wp-super-cache.php (100%) rename src/php/{ => wp-cli}/commands/internals/core.php (100%) rename src/php/{ => wp-cli}/commands/internals/generate.php (100%) rename src/php/{ => wp-cli}/commands/internals/help.php (100%) rename src/php/{ => wp-cli}/commands/internals/home.php (100%) rename src/php/{ => wp-cli}/commands/internals/option.php (100%) rename src/php/{ => wp-cli}/commands/internals/plugin.php (100%) rename src/php/{ => wp-cli}/commands/internals/sql.php (100%) rename src/php/{ => wp-cli}/commands/internals/theme.php (100%) rename src/php/{ => wp-cli}/wp-cli.php (96%) create mode 100755 utils/build-pear rename {src/bin => utils}/wp-completion.bash (100%) diff --git a/build.properties b/build.properties index ea12db9df4..8079bf947f 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.name=wpcli project.channel=andreascreten.github.com/wp-cli -project.majorVersion=1 -project.minorVersion=0 +project.majorVersion=0 +project.minorVersion=3 project.patchLevel=0 project.snapshot=false diff --git a/src/bin/wp b/src/bin/wp index fed73b5e67..20e984096d 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -30,7 +30,11 @@ done cd "$ORIGDIR" # Build the path to wp-cli.php. -SCRIPT_PATH=$(dirname "$SELF_PATH")/../php/wp-cli.php +SCRIPT_PATH='@@PHP_DIR@@/wp-cli/wp-cli.php' +if [ ! -f $SCRIPT_PATH ]; then + SCRIPT_PATH=$(dirname "$SELF_PATH")/../php/wp-cli/wp-cli.php +fi + case $(uname -a) in CYGWIN*) SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; diff --git a/src/php/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php similarity index 100% rename from src/php/class-wp-cli-command.php rename to src/php/wp-cli/class-wp-cli-command.php diff --git a/src/php/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php similarity index 100% rename from src/php/class-wp-cli.php rename to src/php/wp-cli/class-wp-cli.php diff --git a/src/php/commands/community/google-sitemap-generator.php b/src/php/wp-cli/commands/community/google-sitemap-generator.php similarity index 100% rename from src/php/commands/community/google-sitemap-generator.php rename to src/php/wp-cli/commands/community/google-sitemap-generator.php diff --git a/src/php/commands/community/w3-total-cache.php b/src/php/wp-cli/commands/community/w3-total-cache.php similarity index 100% rename from src/php/commands/community/w3-total-cache.php rename to src/php/wp-cli/commands/community/w3-total-cache.php diff --git a/src/php/commands/community/wp-super-cache.php b/src/php/wp-cli/commands/community/wp-super-cache.php similarity index 100% rename from src/php/commands/community/wp-super-cache.php rename to src/php/wp-cli/commands/community/wp-super-cache.php diff --git a/src/php/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php similarity index 100% rename from src/php/commands/internals/core.php rename to src/php/wp-cli/commands/internals/core.php diff --git a/src/php/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php similarity index 100% rename from src/php/commands/internals/generate.php rename to src/php/wp-cli/commands/internals/generate.php diff --git a/src/php/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php similarity index 100% rename from src/php/commands/internals/help.php rename to src/php/wp-cli/commands/internals/help.php diff --git a/src/php/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php similarity index 100% rename from src/php/commands/internals/home.php rename to src/php/wp-cli/commands/internals/home.php diff --git a/src/php/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php similarity index 100% rename from src/php/commands/internals/option.php rename to src/php/wp-cli/commands/internals/option.php diff --git a/src/php/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php similarity index 100% rename from src/php/commands/internals/plugin.php rename to src/php/wp-cli/commands/internals/plugin.php diff --git a/src/php/commands/internals/sql.php b/src/php/wp-cli/commands/internals/sql.php similarity index 100% rename from src/php/commands/internals/sql.php rename to src/php/wp-cli/commands/internals/sql.php diff --git a/src/php/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php similarity index 100% rename from src/php/commands/internals/theme.php rename to src/php/wp-cli/commands/internals/theme.php diff --git a/src/php/wp-cli.php b/src/php/wp-cli/wp-cli.php similarity index 96% rename from src/php/wp-cli.php rename to src/php/wp-cli/wp-cli.php index 8fd82d2154..3276ecd098 100755 --- a/src/php/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,7 +4,7 @@ die('Only cli access'); } -define( 'WP_CLI_VERSION', '1.0.0' ); +define( 'WP_CLI_VERSION', '0.3.0' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); @@ -17,7 +17,7 @@ include WP_CLI_ROOT . 'class-wp-cli-command.php'; // Include the command line tools -include WP_CLI_ROOT . 'php-cli-tools/lib/cli/cli.php'; +include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; // Register the cli tools autoload \cli\register_autoload(); diff --git a/utils/build-pear b/utils/build-pear new file mode 100755 index 0000000000..0d8e51c7d9 --- /dev/null +++ b/utils/build-pear @@ -0,0 +1,23 @@ +#!/bin/bash + +# generate package +find -name '*~' -delete +phing pear-package + +version=$(cat dist/lastBuilt) +version="${version/*wpcli-/}" +version="${version/.tgz/}" + +#sudo phing install-system + +# update channel files +cd ../wp-cli-pages +pirum add . ../wp-cli/dist/wpcli-$version.tgz +pirum build . + +exit + +# push changes +git add -A +git ci -m "release $version" +git push origin gh-pages diff --git a/src/bin/wp-completion.bash b/utils/wp-completion.bash similarity index 100% rename from src/bin/wp-completion.bash rename to utils/wp-completion.bash From ad66023011928e0db28ec3e952dfa89a280ad6fe Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 14:12:26 +0200 Subject: [PATCH 0159/4858] add changelog --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index acd340c9f8..b40472cddb 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,25 @@ You can find more information about adding commands in the [Commands Cookbook](h **Please share the commands you make, issue a pull request to get them included in wp-cli by default.** +Changelog +--------------- + +**0.3** +- added `wp sql` +- improved `wp option` +- pear installer + +**0.2** +- added multisite support +- improved `wp plugin` and `wp theme` +- added `wp generate` +- added `wp core version` +- added `wp --version` +- added bash completion script + +**0.1** +- initial release + Contributors ------------ From bb26f6f2d28e0f30448c181647b418b31cfcfad1 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 14:39:51 +0200 Subject: [PATCH 0160/4858] update installation instructions --- README.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b40472cddb..f8028d9df3 100644 --- a/README.md +++ b/README.md @@ -9,32 +9,28 @@ A tool to control WordPress installations from the command line. Installing ---------- -**Via package manager:** +**Via PEAR:** -* Ubuntu, Debian: [.deb package](https://github.com/downloads/andreascreten/wp-cli/wp-cli_0.1.deb) -* Mac: install [Homebrew](http://mxcl.github.com/homebrew/) and run `brew install wp-cli`. +``` +pear config-set auto_discover 1 +sudo pear install andreascreten.github.com/wp-cli/wpcli +``` **From source:** -First, make sure you have `php-cli` version 5.3 or newer installed. - -Clone the project: - -``` -git clone --recurse-submodules https://github.com/andreascreten/wp-cli.git ``` +# Clone the project +git clone --recurse-submodules https://github.com/andreascreten/wp-cli.git ~/git/wp-cli -Make a symlink to the executable: +# Make a symlink to the binary +sudo ln -s ~/git/wp-cli/src/bin/wp /usr/bin/ -``` -sudo ln -s /path-to-wp-cli-dir/src/bin/wp /usr/local/bin/ +# Make a symlink to the bash completion file +sudo ln -s ~/git/wp-cli/utils/wp-completion.bash /etc/bash_completion.d/wp ``` -Make a symlink to the autocomplete file (Linux): +You can replace `~/git/wp-cli` with whatever you want. -``` -sudo ln -s /path-to-wp-cli-dir/src/bin/wp-completion.bash /etc/bash_completion.d/wp -``` Usage ----- From 8b6595b809e81dd40b178d588c8cc453aaa5bf87 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 14:43:19 +0200 Subject: [PATCH 0161/4858] fix changelog --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f8028d9df3..9d16f743c2 100644 --- a/README.md +++ b/README.md @@ -113,11 +113,13 @@ Changelog --------------- **0.3** + - added `wp sql` - improved `wp option` - pear installer **0.2** + - added multisite support - improved `wp plugin` and `wp theme` - added `wp generate` @@ -126,6 +128,7 @@ Changelog - added bash completion script **0.1** + - initial release Contributors From 9adf47d20dcc319d7d84da39edf31b0c155768a5 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 14:57:19 +0200 Subject: [PATCH 0162/4858] readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9d16f743c2..fc6f31878a 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,14 @@ Installing **Via PEAR:** -``` +```sh pear config-set auto_discover 1 sudo pear install andreascreten.github.com/wp-cli/wpcli ``` **From source:** -``` +```sh # Clone the project git clone --recurse-submodules https://github.com/andreascreten/wp-cli.git ~/git/wp-cli From 44ead87ef48a1619419f13e2cc65f4f0afac1500 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 15:02:02 +0200 Subject: [PATCH 0163/4858] use git read-only url in install instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc6f31878a..25ee163b71 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ sudo pear install andreascreten.github.com/wp-cli/wpcli ```sh # Clone the project -git clone --recurse-submodules https://github.com/andreascreten/wp-cli.git ~/git/wp-cli +git clone --recurse-submodules git://github.com/andreascreten/wp-cli.git ~/git/wp-cli # Make a symlink to the binary sudo ln -s ~/git/wp-cli/src/bin/wp /usr/bin/ From d3c21db7fafc545e18a0bfccb8d7d4fadc579a6f Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 6 Nov 2011 15:04:43 +0200 Subject: [PATCH 0164/4858] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 25ee163b71..a8a32e3375 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ sudo ln -s ~/git/wp-cli/utils/wp-completion.bash /etc/bash_completion.d/wp You can replace `~/git/wp-cli` with whatever you want. -Usage +Using ----- Go into a WordPress root folder: From 05dc7a0176469a5df16408590222304a6f47f039 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 8 Nov 2011 22:11:03 +0200 Subject: [PATCH 0165/4858] add usage example when --blog is used as a flag --- src/php/wp-cli/wp-cli.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3276ecd098..219f573824 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -49,6 +49,9 @@ if ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; unset( $assoc_args['blog'] ); + if ( true === $blog ) { + WP_CLI::line( 'usage: wp --blog=example.com' ); + } } elseif ( is_readable( WP_ROOT . '/wp-cli-blog' ) ) { $blog = file_get_contents( WP_ROOT . '/wp-cli-blog' ); } From 2dfe52377bd18f7991dd1aaeb73e64e9fd1b3245 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 8 Nov 2011 22:11:16 +0200 Subject: [PATCH 0166/4858] coding standards --- src/php/wp-cli/wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 219f573824..9c593e3d7e 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -72,12 +72,12 @@ require_once(ABSPATH . 'wp-admin/includes/admin.php'); // Load all internal commands -foreach (glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename) { +foreach ( glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename ) { include $filename; } // Load all plugin commands -foreach (glob(WP_CLI_ROOT.'/commands/community/*.php') as $filename) { +foreach ( glob(WP_CLI_ROOT.'/commands/community/*.php') as $filename ) { include $filename; } From 830eb61695e5a64af76e55ce5fadf087cdb7ee8d Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 10 Nov 2011 21:32:49 +0200 Subject: [PATCH 0167/4858] implement eval command; fixes #41 --- src/php/wp-cli/commands/internals/eval.php | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/eval.php diff --git a/src/php/wp-cli/commands/internals/eval.php b/src/php/wp-cli/commands/internals/eval.php new file mode 100644 index 0000000000..aab1a6eca3 --- /dev/null +++ b/src/php/wp-cli/commands/internals/eval.php @@ -0,0 +1,42 @@ +" ); + exit; + } + + $name = $args[0]; + eval( $args[0] ); + } + + /** + * Help function for this command + */ + public static function help() { + WP_CLI::line( << Date: Thu, 10 Nov 2011 21:34:49 +0200 Subject: [PATCH 0168/4858] bump version to 0.4.0-dev --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 9c593e3d7e..89df36ad81 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,7 +4,7 @@ die('Only cli access'); } -define( 'WP_CLI_VERSION', '0.3.0' ); +define( 'WP_CLI_VERSION', '0.4.0-dev' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From d3a844cb3078f1ddab00c216045ff80ebc30f241 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 10 Nov 2011 21:55:07 +0200 Subject: [PATCH 0169/4858] add eval-file command. see #41 --- .../wp-cli/commands/internals/eval-file.php | 46 +++++++++++++++++++ src/php/wp-cli/commands/internals/eval.php | 2 - 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/php/wp-cli/commands/internals/eval-file.php diff --git a/src/php/wp-cli/commands/internals/eval-file.php b/src/php/wp-cli/commands/internals/eval-file.php new file mode 100644 index 0000000000..d8ef5dc5aa --- /dev/null +++ b/src/php/wp-cli/commands/internals/eval-file.php @@ -0,0 +1,46 @@ +" ); + exit; + } + + foreach ( $args as $file ) { + if ( !file_exists( $file ) ) { + WP_CLI::error( "'$file' does not exist." ); + } else { + include( $file ); + } + } + } + + /** + * Help function for this command + */ + public static function help() { + WP_CLI::line( << Date: Thu, 10 Nov 2011 22:25:22 +0200 Subject: [PATCH 0170/4858] remove redundant comments --- src/php/wp-cli/commands/community/google-sitemap-generator.php | 1 - src/php/wp-cli/commands/community/w3-total-cache.php | 1 - src/php/wp-cli/commands/community/wp-super-cache.php | 1 - src/php/wp-cli/commands/internals/core.php | 1 - src/php/wp-cli/commands/internals/eval-file.php | 1 - src/php/wp-cli/commands/internals/eval.php | 1 - src/php/wp-cli/commands/internals/generate.php | 1 - src/php/wp-cli/commands/internals/help.php | 1 - src/php/wp-cli/commands/internals/home.php | 1 - src/php/wp-cli/commands/internals/option.php | 1 - src/php/wp-cli/commands/internals/sql.php | 1 - src/php/wp-cli/commands/internals/theme.php | 1 - 12 files changed, 12 deletions(-) diff --git a/src/php/wp-cli/commands/community/google-sitemap-generator.php b/src/php/wp-cli/commands/community/google-sitemap-generator.php index 1bcad0c2e4..a35acbcd1d 100644 --- a/src/php/wp-cli/commands/community/google-sitemap-generator.php +++ b/src/php/wp-cli/commands/community/google-sitemap-generator.php @@ -1,6 +1,5 @@ Date: Thu, 10 Nov 2011 22:32:05 +0200 Subject: [PATCH 0171/4858] fix indentation --- .../community/google-sitemap-generator.php | 6 +- .../commands/community/w3-total-cache.php | 86 +++++++++---------- .../commands/community/wp-super-cache.php | 12 +-- src/php/wp-cli/commands/internals/core.php | 2 +- .../wp-cli/commands/internals/eval-file.php | 6 +- src/php/wp-cli/commands/internals/eval.php | 6 +- .../wp-cli/commands/internals/generate.php | 2 +- src/php/wp-cli/commands/internals/help.php | 4 +- src/php/wp-cli/commands/internals/home.php | 6 +- src/php/wp-cli/commands/internals/option.php | 2 +- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/sql.php | 2 +- 12 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/php/wp-cli/commands/community/google-sitemap-generator.php b/src/php/wp-cli/commands/community/google-sitemap-generator.php index a35acbcd1d..268518701d 100644 --- a/src/php/wp-cli/commands/community/google-sitemap-generator.php +++ b/src/php/wp-cli/commands/community/google-sitemap-generator.php @@ -27,12 +27,12 @@ function rebuild( $args = array(), $vars = array() ) { * Help function for this command */ public static function help() { - WP_CLI::line( <<] [--permalink=] Available sub-commands: - flush flushes whole cache - --post_id= flush specific ID - --permalink= flush specific permalink - database flushes database cache - object flush object cache - minify flush minify cache + flush flushes whole cache + --post_id= flush specific ID + --permalink= flush specific permalink + database flushes database cache + object flush object cache + minify flush minify cache EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/community/wp-super-cache.php b/src/php/wp-cli/commands/community/wp-super-cache.php index f0ede07b04..3501658c47 100644 --- a/src/php/wp-cli/commands/community/wp-super-cache.php +++ b/src/php/wp-cli/commands/community/wp-super-cache.php @@ -124,11 +124,11 @@ public static function help() { usage: wp super-cache [flush|status|enable|disable] --post_id= --permalink= Available sub-commands: - flush flushes whole cache, or post with given permalink or ID --post_id= --permalink= - status shows status of WP Super Cache - enable enables WP Super Cache - disable disables WP Super Cache + flush flushes whole cache, or post with given permalink or ID --post_id= --permalink= + status shows status of WP Super Cache + enable enables WP Super Cache + disable disables WP Super Cache EOB - ); - } + ); + } } diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 1376541a91..3d0cf2b76d 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -82,6 +82,6 @@ public static function help() { usage: wp core update or: wp core version [--extra] EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/eval-file.php b/src/php/wp-cli/commands/internals/eval-file.php index ebf1cd36ae..b508b32db8 100644 --- a/src/php/wp-cli/commands/internals/eval-file.php +++ b/src/php/wp-cli/commands/internals/eval-file.php @@ -12,8 +12,8 @@ class EvalFileCommand extends WP_CLI_Command { /** * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args + * + * @param array $args * @param array $assoc_args */ public function __construct( $args, $assoc_args ) { @@ -40,6 +40,6 @@ public static function help() { Loads and executes a PHP file after bootstrapping WordPress. EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/eval.php b/src/php/wp-cli/commands/internals/eval.php index 62d23139c4..4d931abb2c 100644 --- a/src/php/wp-cli/commands/internals/eval.php +++ b/src/php/wp-cli/commands/internals/eval.php @@ -12,8 +12,8 @@ class EvalCommand extends WP_CLI_Command { /** * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args + * + * @param array $args * @param array $assoc_args */ public function __construct( $args, $assoc_args ) { @@ -34,6 +34,6 @@ public static function help() { Executes arbitrary PHP code after bootstrapping WordPress. EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 6f311a9dc1..7f81894006 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -104,6 +104,6 @@ public static function help() { usage: wp generate posts [--count=100] [--type=post] [--status=publish] or: wp generate users [--count=100] [--role=] EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 086f928850..4a8e68882c 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -12,8 +12,8 @@ class HelpCommand extends WP_CLI_Command { /** * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args + * + * @param array $args */ public function __construct( $args ) { if ( empty( $args ) ) { diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index f411cb3903..4f3304fc59 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -12,8 +12,8 @@ class HomeCommand extends WP_CLI_Command { /** * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args + * + * @param array $args * @param array $assoc_args */ public function __construct( $args, $assoc_args ) { @@ -44,6 +44,6 @@ public static function help() { Opens the wp-cli homepage in your browser. EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 145316e891..26be3b1cc1 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -102,6 +102,6 @@ public static function help() { or: wp option update or: wp option delete EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 04ff2470df..b3acf0d3dd 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -354,6 +354,6 @@ public static function help() { update update a plugin from wordpress.org delete delete a plugin EOB - ); + ); } } diff --git a/src/php/wp-cli/commands/internals/sql.php b/src/php/wp-cli/commands/internals/sql.php index 8e10609a0c..a3f2e8ffca 100644 --- a/src/php/wp-cli/commands/internals/sql.php +++ b/src/php/wp-cli/commands/internals/sql.php @@ -94,6 +94,6 @@ public static function help() { wp sql dump Exports the WordPress database as SQL using mysqldump or equivalent. wp sql query Execute a query against the WordPress database. EOB - ); + ); } } From 6f3602572a51b65f99d809b21369ad5549bbfd3e Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 10 Nov 2011 23:14:03 +0200 Subject: [PATCH 0172/4858] remove extra line endings from wp-cli-blog content --- src/php/wp-cli/wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 89df36ad81..8c3679bbef 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -52,8 +52,8 @@ if ( true === $blog ) { WP_CLI::line( 'usage: wp --blog=example.com' ); } -} elseif ( is_readable( WP_ROOT . '/wp-cli-blog' ) ) { - $blog = file_get_contents( WP_ROOT . '/wp-cli-blog' ); +} elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { + $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); } if ( isset( $blog ) ) { From b7f0934687acbe9107df7ccac0a147a1d4c2ee0d Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 20 Nov 2011 16:08:49 +0200 Subject: [PATCH 0173/4858] remove old build-deb script --- utils/build-deb | 70 ------------------------------------------------- 1 file changed, 70 deletions(-) delete mode 100755 utils/build-deb diff --git a/utils/build-deb b/utils/build-deb deleted file mode 100755 index 9a3c583fdb..0000000000 --- a/utils/build-deb +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -# script for generating a .deb file - -SOURCE_DIR=$(pwd) - -rm -rf /tmp/wp-cli - -mkdir -p /tmp/wp-cli/DEBIAN - -cd /tmp/wp-cli - -# copy php files -ROOT_DIR='usr/share/php/wp-cli' - -mkdir -p $ROOT_DIR -for dir in 'php-cli-tools' 'core' 'commands'; do - cp -r $SOURCE_DIR/$dir $ROOT_DIR/ -done - -rm -rf $ROOT_DIR/php-cli-tools/.git* - -# copy completion file -ROOT_DIR='etc/bash_completion.d' - -mkdir -p $ROOT_DIR -cp $SOURCE_DIR/bin/wp-completion.bash $ROOT_DIR/wp - -# copy license file -ROOT_DIR='usr/share/doc/wp-cli' - -mkdir -p $ROOT_DIR -cp $SOURCE_DIR/LICENSE $ROOT_DIR/copyright - -# remove junk files -for name in '*~' '*.swp'; do - find . -name $name -exec rm {} \; -done - -# reset permsissions and ownership -chown -R root . -chgrp -R root . -find . -type f -exec chmod 644 {} \; -find . -type d -exec chmod 755 {} \; - -# use a simple bash wrapper for the command, since we know where everything is -mkdir -p usr/bin - -cat > usr/bin/wp < DEBIAN/control <= 5.3) -Installed-Size: 150 -Maintainer: Cristi Burca -Description: WordPress command-line interface - A tool for controlling WordPress installations via the command-line. -EOT - -dpkg --build /tmp/wp-cli From 55dfda323cd6313e4a8d5a87fae256f7102ce3da Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 20 Nov 2011 16:17:20 +0200 Subject: [PATCH 0174/4858] add build-dev script --- README.md | 11 +++-------- utils/build-dev | 4 ++++ 2 files changed, 7 insertions(+), 8 deletions(-) create mode 100755 utils/build-dev diff --git a/README.md b/README.md index a8a32e3375..68a99dce46 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,12 @@ pear config-set auto_discover 1 sudo pear install andreascreten.github.com/wp-cli/wpcli ``` -**From source:** +**Via GIT:** ```sh -# Clone the project git clone --recurse-submodules git://github.com/andreascreten/wp-cli.git ~/git/wp-cli - -# Make a symlink to the binary -sudo ln -s ~/git/wp-cli/src/bin/wp /usr/bin/ - -# Make a symlink to the bash completion file -sudo ln -s ~/git/wp-cli/utils/wp-completion.bash /etc/bash_completion.d/wp +cd ~/git/wp-cli +sudo utils/build-dev ``` You can replace `~/git/wp-cli` with whatever you want. diff --git a/utils/build-dev b/utils/build-dev new file mode 100755 index 0000000000..c1a39ad875 --- /dev/null +++ b/utils/build-dev @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +ln -s $(pwd)/src/bin/wp /usr/bin/wp +ln -s $(pwd)/utils/wp-completion.bash /etc/bash_completion.d/wp From 0a3b579c14407fa75d8a41230d06f361c5b65cfc Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 20 Nov 2011 16:54:05 +0200 Subject: [PATCH 0175/4858] output errors to STDERR and exit with status 1 --- src/php/wp-cli/class-wp-cli.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index a70b2926d0..56967f960e 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -43,7 +43,8 @@ static function line( $message = '' ) { * @param string $label */ static function error( $message, $label = 'Error' ) { - \cli\line( '%R' . $label . ': %n' . self::errorToString( $message ) ); + \cli\err( '%R' . $label . ': %n' . self::errorToString( $message ) ); + exit(1); } /** @@ -219,7 +220,7 @@ function feedback( $string ) { } } - + if( empty( $string ) ) { return; } @@ -229,4 +230,4 @@ function feedback( $string ) { function before() {} function after() {} -} \ No newline at end of file +} From 14eae3f585cf19c0079f887bc2c9cf6e6995d849 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 8 Dec 2011 16:46:46 +0200 Subject: [PATCH 0176/4858] readme --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 68a99dce46..3583bdd8d4 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,7 @@ -WP-CLI: WordPress Command Line Tools -============================ - -What is wp-cli +What is wp-cli? -------------- -A tool to control WordPress installations from the command line. +A set of tools for controlling WordPress installations from the command line. Installing ---------- From 8e0076c634b659cf3776b4c984816572d3aeb689 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 11 Dec 2011 21:15:50 +0200 Subject: [PATCH 0177/4858] add --dev flag to wp plugin install. see #45 --- src/php/wp-cli/commands/internals/plugin.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index b3acf0d3dd..1cb45955e7 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -190,21 +190,28 @@ function install( $args, $assoc_args ) { exit; } - $name = $args[0]; + $slug = stripslashes( $args[0] ); // Force WordPress to update the plugin list wp_update_plugins(); // Get plugin info from the WordPress servers - $api = plugins_api( 'plugin_information', array( 'slug' => stripslashes( $name ) ) ); + $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( !$api ) { WP_CLI::error( 'Can\'t find the plugin in the WordPress.org plugins repository.' ); exit(); } + if ( isset( $assoc_args['dev'] ) ) { + list( $link ) = explode( $slug, $api->download_link ); + + $api->download_link = $link . $slug . '.zip'; + $api->version = 'Development Version'; + } + $status = install_plugin_install_status( $api ); - WP_CLI::line( 'Installing '.$api->name.' ('.$api->version.')' ); + WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); // Check what to do switch ( $status['status'] ) { @@ -231,7 +238,7 @@ function install( $args, $assoc_args ) { } break; case 'newer_installed': - WP_CLI::error( sprintf( 'Newer version ( %s ) installed', $status['version'] ) ); + WP_CLI::error( sprintf( 'Newer version (%s) installed', $status['version'] ) ); break; case 'latest_installed': WP_CLI::error( 'Latest version already installed' ); From d27f5b479aafb8ae63bbb460207724b8d0ab24a6 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 11 Dec 2011 21:21:54 +0200 Subject: [PATCH 0178/4858] document the --dev flag. see #45 --- src/php/wp-cli/commands/internals/plugin.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 1cb45955e7..24e78c00a7 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -349,16 +349,25 @@ public static function help() { WP_CLI::line( << [] or: wp plugin path [] [--directory] - or: wp plugin install [--activate] + or: wp plugin install [--activate] [--dev] Available sub-commands: status display status of all installed plugins or of a particular plugin + activate activate a particular plugin + deactivate deactivate a particular plugin + toggle toggle activation state of a particular plugin + path print path to the plugin's file + install install a plugin from wordpress.org + --activate activate the plugin after installing it + --dev install the development version + update update a plugin from wordpress.org + delete delete a plugin EOB ); From 51fff68164e696470d92984ad52f99c024b3d827 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 11 Dec 2011 21:25:19 +0200 Subject: [PATCH 0179/4858] document the --directory flag --- src/php/wp-cli/commands/internals/plugin.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 24e78c00a7..9e26f7b82d 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -361,10 +361,11 @@ public static function help() { toggle toggle activation state of a particular plugin path print path to the plugin's file + --directory get the path to the closest parent directory install install a plugin from wordpress.org - --activate activate the plugin after installing it - --dev install the development version + --activate activate the plugin after installing it + --dev install the development version update update a plugin from wordpress.org From da3ea7d2290ff3f3c2cae6e5723e0ee3e7cf7509 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 19 Dec 2011 18:48:14 +0200 Subject: [PATCH 0180/4858] make build-dev OS X compatible. fixes #48 --- utils/build-dev | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/utils/build-dev b/utils/build-dev index c1a39ad875..6b5d96744c 100755 --- a/utils/build-dev +++ b/utils/build-dev @@ -1,4 +1,10 @@ #!/usr/bin/env bash -ln -s $(pwd)/src/bin/wp /usr/bin/wp -ln -s $(pwd)/utils/wp-completion.bash /etc/bash_completion.d/wp +ln -sf $(pwd)/src/bin/wp /usr/bin/wp + +for dir in /etc/bash_completion.d /usr/local/etc/bash_completion.d; do + if [ -d $dir ]; then + ln -sf $(pwd)/utils/wp-completion.bash $dir/wp + break + fi +done From 2b6d6f8ee6d6c3756f984c7eae5f0a3356762e17 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 20 Dec 2011 11:03:22 +0000 Subject: [PATCH 0181/4858] Add installation commands --- .../wp-cli/commands/internals/installer.php | 49 +++++++++++++++++++ src/php/wp-cli/wp-cli.php | 6 +++ 2 files changed, 55 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/installer.php diff --git a/src/php/wp-cli/commands/internals/installer.php b/src/php/wp-cli/commands/internals/installer.php new file mode 100644 index 0000000000..9e6ad644a5 --- /dev/null +++ b/src/php/wp-cli/commands/internals/installer.php @@ -0,0 +1,49 @@ + --username= --password= --email_address= + or: wp installer is_installed +EOB + ); + } +} + diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 8c3679bbef..e22011e697 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -67,6 +67,12 @@ $_SERVER['REQUEST_URI'] = '/' . $path; } +// Set installer flag before loading any Wordpress libs +$installing = count( $arguments ) > 0 && $arguments[0] === "installer"; +if ( $installing ) { + define( 'WP_INSTALLING', true ); +} + // Load WordPress libs require_once(WP_ROOT . 'wp-load.php'); require_once(ABSPATH . 'wp-admin/includes/admin.php'); From cbd6cc9cb909d756e613b66bddacc2d0d1ace34a Mon Sep 17 00:00:00 2001 From: Thorsten Ott Date: Wed, 21 Dec 2011 02:05:08 +0200 Subject: [PATCH 0182/4858] Migrating https://github.com/tott/WordPress-CLI-Exporter to the WP-CLI framework This should address https://github.com/andreascreten/wp-cli/issues/44 --- src/php/wp-cli/commands/internals/export.php | 522 +++++++++++++++++++ 1 file changed, 522 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/export.php diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php new file mode 100644 index 0000000000..3e7e913560 --- /dev/null +++ b/src/php/wp-cli/commands/internals/export.php @@ -0,0 +1,522 @@ + --user= + wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + +Required parameters: + --path Full Path to directory where WXR export files should be stored + --user Username/ID the import should run as + +Optional filters: + --start_date Export only posts new than this date in format YYYY-MM-DD + --end_date Export only posts older than this date in format YYYY-MM-DD + --post_type Export only posts with this post_type + --author Export only posts by this author + --category Export only posts in this category + --post_status Export only posts with this post_status + --skip_comments Don't export comments +EOB + ); + } + + private function dispatch() { + WP_CLI::line(); + WP_CLI::line( 'Starting export processs' ); + WP_CLI::line(); + $this->export_wp( $this->export_args ); + } + + + /** + * Argument validation functions below + */ + + public function validate_arguments( $args, $assoc_args ) { + $defaults = array( + 'path' => NULL, + 'user' => NULL, + 'start_date' => NULL, + 'end_date' => NULL, + 'post_type' => NULL, + 'author' => NULL, + 'category' => NULL, + 'post_status' => NULL, + 'skip_comments' => NULL, + ); + + $args = wp_parse_args( $assoc_args, $defaults ); + + $has_errors = false; + + foreach( $defaults as $argument => $default_value ) { + if ( is_callable( array( &$this, 'check_' . $argument ) ) ) { + $result = call_user_func( array( &$this, 'check_' . $argument ), $args[$argument] ); + if ( false === $result && false === $has_errors ) + $has_errors = true; + } + } + + if ( true === $has_errors ) { + WP_CLI::error( 'There were errors. Please review the items listed above' ); + exit; + } + + $this->wxr_path = $assoc_args['path']; + + $this->dispatch(); + } + + private function check_path( $path ) { + if ( empty( $path ) ) { + $this->help(); + exit; + } + + if ( !is_dir( $path ) ) { + WP_CLI::error( sprintf( "The path %s does not exist", $path ) ); + exit; + } + + return true; + } + + private function check_user( $user ) { + if ( empty( $user ) ) { + $this->help(); + exit; + } + + if ( is_numeric( $user ) ) { + $user_id = (int) $user; + } else { + $user_id = (int) username_exists( $user ); + } + if ( !$user_id || !wp_set_current_user( $user_id ) ) { + WP_CLI::error( sprintf( "Could not get a user_id for this user: %s", var_export( $user_id, true ) ) ); + exit; + } + + $current_user = wp_get_current_user(); + $this->user_id = (int) $user_id; + + return true; + } + + private function check_start_date( $date ) { + if ( is_null( $date ) ) + return true; + + $time = strtotime( $date ); + if ( !empty( $date ) && !$time ) { + WP_CLI::warning( sprintf( "The start_date %s is invalid", $date ) ); + return false; + } + $this->export_args['start_date'] = date( 'Y-m-d', $time ); + return true; + } + + private function check_end_date( $date ) { + if ( is_null( $date ) ) + return true; + + $time = strtotime( $date ); + if ( !empty( $date ) && !$time ) { + WP_CLI::warning( sprintf( "The end_date %s is invalid", $date ) ); + return false; + } + $this->export_args['start_date'] = date( 'Y-m-d', $time ); + return true; + } + + private function check_post_type( $post_type ) { + if ( is_null( $post_type ) ) + return true; + + $post_types = get_post_types(); + if ( !in_array( $post_type, $post_types ) ) { + WP_CLI::warning( sprintf( 'The post type %s does not exists. Choose "all" or any of these existing post types instead: %s', $post_type, implode( ", ", $post_types ) ) ); + return false; + } + $this->export_args['content'] = $post_type; + return true; + } + + private function check_author( $author ) { + if ( is_null( $author ) ) + return true; + + $authors = get_users_of_blog(); + if ( empty( $authors ) || is_wp_error( $authors ) ) { + WP_CLI::warning( sprintf( "Could not find any authors in this blog" ) ); + return false; + } + $hit = false; + foreach( $authors as $user ) { + if ( $hit ) + break; + if ( (int) $author == $user->ID || $author == $user->user_login ) + $hit = $user->ID; + } + if ( false === $hit ) { + $authors_nice = array(); + foreach( $authors as $_author ) + $authors_nice[] = sprintf( '%s (%s)', $_author->user_login, $_author->display_name ); + WP_CLI::warning( sprintf( 'Could not find a matching author for %s. The following authors exist: %s', $author, implode( ", ", $authors_nice ) ) ); + return false; + } + + $this->export_args['author'] = $hit; + return true; + } + + private function check_category( $category ) { + if ( is_null( $category ) ) + return true; + + $term = category_exists( $category ); + if ( empty( $term ) || is_wp_error( $term ) ) { + WP_CLI::warning( sprintf( 'Could not find a category matching %s', $category ) ); + return false; + } + $this->export_args['category'] = $category; + return true; + } + + private function check_post_status( $status ) { + if ( is_null( $status ) ) + return true; + + $stati = get_post_statuses(); + if ( empty( $stati ) || is_wp_error( $stati ) ) { + WP_CLI::warning( sprintf( 'Could not find any post stati', $category ) ); + return false; + } + + if ( !isset( $stati[$status] ) ) { + WP_CLI::warning( sprintf( 'Could not find a post_status matching %s. Here is a list of available stati: %s', $status, implode( ", ", array_keys( $stati ) ) ) ); + return false; + } + $this->export_args['status'] = $status; + return true; + } + + private function check_skip_comments( $skip ) { + if ( is_null( $skip ) ) + return true; + + if ( (int) $skip <> 0 && (int) $skip <> 1 ) { + WP_CLI::warning( sprintf( 'skip_comments needs to be 0 (no) or 1 (yes)', $category ) ); + return false; + } + $this->export_args['skip_comments'] = $skip; + return true; + } + + + /** + * Workaround to prevent memory leaks from growing variables + */ + + private function stop_the_insanity() { + global $wpdb, $wp_object_cache; + $wpdb->queries = array(); // or define( 'WP_IMPORTING', true ); + if ( !is_object( $wp_object_cache ) ) + return; + $wp_object_cache->group_ops = array(); + $wp_object_cache->stats = array(); + $wp_object_cache->memcache_debug = array(); + $wp_object_cache->cache = array(); + $wp_object_cache->__remoteset(); // important + } + + /** + * Export function as it is defined in the original code of export_wp defined in wp-admin/includes/export.php + */ + + private function export_wp( $args = array() ) { + require_once ABSPATH . 'wp-admin/includes/export.php'; + + global $wpdb, $post; + // call export_wp as we need the functions defined in it. + $dummy_args = array( 'content' => 'i-do-not-exist' ); + ob_start(); + export_wp( $dummy_args ); + ob_end_clean(); + + /** + * This is mostly the original code of export_wp defined in wp-admin/includes/export.php + */ + $defaults = array( 'content' => 'all', 'author' => false, 'category' => false, + 'start_date' => false, 'end_date' => false, 'status' => false, 'skip_comments' => false, + ); + $args = wp_parse_args( $args, $defaults ); + + WP_CLI::line( "Exporting with export_wp with arguments: " . var_export( $args, true ) ); + + do_action( 'export_wp' ); + + $sitename = sanitize_key( get_bloginfo( 'name' ) ); + if ( ! empty( $sitename ) ) + $sitename .= '.'; + + $append = array( date( 'Y-m-d' ) ); + foreach( array_keys( $args ) as $arg_key ) { + if ( $defaults[$arg_key] <> $args[$arg_key] ) + $append[]= "$arg_key-" . (string) $args[$arg_key]; + } + $file_name_base = $sitename . 'wordpress.' . implode( ".", $append ); + + if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) { + $ptype = get_post_type_object( $args['content'] ); + if ( ! $ptype->can_export ) + $args['content'] = 'post'; + + $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['content'] ); + } else { + $post_types = get_post_types( array( 'can_export' => true ) ); + $esses = array_fill( 0, count( $post_types ), '%s' ); + $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (" . implode( ',', $esses ) . ')', $post_types ); + } + + if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] ); + else + $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'"; + + $join = ''; + if ( $args['category'] && 'post' == $args['content'] ) { + if ( $term = term_exists( $args['category'], 'category' ) ) { + $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)"; + $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] ); + } + } + + if ( 'post' == $args['content'] || 'page' == $args['content'] ) { + if ( $args['author'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); + + if ( $args['start_date'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); + + if ( $args['end_date'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime( '+1 month', strtotime( $args['end_date'] ) ) ) ); + } + + // grab a snapshot of post IDs, just in case it changes during the export + $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" ); + + // get the requested terms ready, empty unless posts filtered by category or all content + $cats = $tags = $terms = array(); + if ( isset( $term ) && $term ) { + $cat = get_term( $term['term_id'], 'category' ); + $cats = array( $cat->term_id => $cat ); + unset( $term, $cat ); + } else if ( 'all' == $args['content'] ) { + $categories = (array) get_categories( array( 'get' => 'all' ) ); + $tags = (array) get_tags( array( 'get' => 'all' ) ); + + $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); + $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); + + // put categories in order with no child going before its parent + while ( $cat = array_shift( $categories ) ) { + if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) ) + $cats[$cat->term_id] = $cat; + else + $categories[] = $cat; + } + + // put terms in order with no child going before its parent + while ( $t = array_shift( $custom_terms ) ) { + if ( $t->parent == 0 || isset( $terms[$t->parent] ) ) + $terms[$t->term_id] = $t; + else + $custom_terms[] = $t; + } + + unset( $categories, $custom_taxonomies, $custom_terms ); + } + + + WP_CLI::line( 'Exporting ' . count( $post_ids ) . ' items' ); + WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); + WP_CLI::line( 'Exporting ' . count( $tags ) . ' tags' ); + WP_CLI::line( 'Exporting ' . count( $terms ) . ' terms' ); + WP_CLI::line(); + + $progress = $this->progress_bar( 'exporting', count( $post_ids ) ); + + ob_start(); + echo '\n"; + +?> + + + + + + + + + + + + + + + + + + + + + + <?php bloginfo_rss( 'name' ); ?> + + + + + + + + + + + + term_id ?>slug; ?>parent ? $cats[$c->parent]->slug : ''; ?> + + + term_id ?>slug; ?> + + + term_id ?>taxonomy; ?>slug; ?>parent ? $terms[$t->parent]->slug : ''; ?> + + + + + +in_the_loop = true; // Fake being in the loop. + + // fetch 20 posts at a time rather than loading the entire table into memory + while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) { + + $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')'; + $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" ); + + // Begin Loop + foreach ( $posts as $post ) { + + $progress->tick(); + + setup_postdata( $post ); + $is_sticky = is_sticky( $post->ID ) ? 1 : 0; +?> + + <?php echo apply_filters( 'the_title_rss', $post->post_title ); ?> + + + + + + post_content ) ); ?> + post_excerpt ) ); ?> + ID; ?> + post_date; ?> + post_date_gmt; ?> + comment_status; ?> + ping_status; ?> + post_name; ?> + post_status; ?> + post_parent; ?> + menu_order; ?> + post_type; ?> + post_password; ?> + +post_type == 'attachment' ) : ?> + ID ); ?> + + +get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) ); + foreach ( $postmeta as $meta ) : if ( $meta->meta_key != '_edit_lock' ) : ?> + + meta_key; ?> + meta_value ); ?> + + + +get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); + foreach ( $comments as $c ) : ?> + + comment_ID; ?> + comment_author ); ?> + comment_author_email; ?> + comment_author_url ); ?> + comment_author_IP; ?> + comment_date; ?> + comment_date_gmt; ?> + comment_content ) ?> + comment_approved; ?> + comment_type; ?> + comment_parent; ?> + user_id; ?> +get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $c->comment_ID ) ); + foreach ( $c_meta as $meta ) : ?> + + meta_key; ?> + meta_value ); ?> + + + + + + + + + +wxr_path . $file_name_base . '.wxr'; + + if ( !file_exists( $full_path ) || is_writeable( $full_path ) ) { + WP_CLI::line( 'Writing to ' . $full_path ); + file_put_contents( $full_path, $result ); + } + } + + /** + * Implement progress bar + */ + private function progress_bar( $title, $total, $interval = 100 ) { + return new \cli\progress\Bar( $title, $total, $interval ); + } + +} \ No newline at end of file From 233c387f8b0b949d1a1ba9860be43dd10f5f215e Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 21 Dec 2011 03:52:25 +0200 Subject: [PATCH 0183/4858] fix allignment in export help method; see #44 --- src/php/wp-cli/commands/internals/export.php | 118 +++++++++---------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 3e7e913560..9ac6854879 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -10,15 +10,13 @@ */ class ExportCommand extends WP_CLI_Command { protected $default_subcommand = 'validate_arguments'; - + public $export_args = array(); - - public static function help() { - WP_CLI::warning( << --user= - wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + public static function help() { + WP_CLI::line( << --user= + or: wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 Required parameters: --path Full Path to directory where WXR export files should be stored @@ -42,12 +40,12 @@ private function dispatch() { WP_CLI::line(); $this->export_wp( $this->export_args ); } - - + + /** * Argument validation functions below */ - + public function validate_arguments( $args, $assoc_args ) { $defaults = array( 'path' => NULL, @@ -62,47 +60,47 @@ public function validate_arguments( $args, $assoc_args ) { ); $args = wp_parse_args( $assoc_args, $defaults ); - + $has_errors = false; - + foreach( $defaults as $argument => $default_value ) { if ( is_callable( array( &$this, 'check_' . $argument ) ) ) { $result = call_user_func( array( &$this, 'check_' . $argument ), $args[$argument] ); if ( false === $result && false === $has_errors ) $has_errors = true; } - } - + } + if ( true === $has_errors ) { WP_CLI::error( 'There were errors. Please review the items listed above' ); exit; } - + $this->wxr_path = $assoc_args['path']; - + $this->dispatch(); } - + private function check_path( $path ) { if ( empty( $path ) ) { $this->help(); exit; } - + if ( !is_dir( $path ) ) { WP_CLI::error( sprintf( "The path %s does not exist", $path ) ); exit; } - + return true; } - + private function check_user( $user ) { if ( empty( $user ) ) { $this->help(); exit; } - + if ( is_numeric( $user ) ) { $user_id = (int) $user; } else { @@ -115,14 +113,14 @@ private function check_user( $user ) { $current_user = wp_get_current_user(); $this->user_id = (int) $user_id; - + return true; } - + private function check_start_date( $date ) { if ( is_null( $date ) ) return true; - + $time = strtotime( $date ); if ( !empty( $date ) && !$time ) { WP_CLI::warning( sprintf( "The start_date %s is invalid", $date ) ); @@ -131,11 +129,11 @@ private function check_start_date( $date ) { $this->export_args['start_date'] = date( 'Y-m-d', $time ); return true; } - + private function check_end_date( $date ) { if ( is_null( $date ) ) return true; - + $time = strtotime( $date ); if ( !empty( $date ) && !$time ) { WP_CLI::warning( sprintf( "The end_date %s is invalid", $date ) ); @@ -144,11 +142,11 @@ private function check_end_date( $date ) { $this->export_args['start_date'] = date( 'Y-m-d', $time ); return true; } - + private function check_post_type( $post_type ) { if ( is_null( $post_type ) ) return true; - + $post_types = get_post_types(); if ( !in_array( $post_type, $post_types ) ) { WP_CLI::warning( sprintf( 'The post type %s does not exists. Choose "all" or any of these existing post types instead: %s', $post_type, implode( ", ", $post_types ) ) ); @@ -157,11 +155,11 @@ private function check_post_type( $post_type ) { $this->export_args['content'] = $post_type; return true; } - + private function check_author( $author ) { if ( is_null( $author ) ) return true; - + $authors = get_users_of_blog(); if ( empty( $authors ) || is_wp_error( $authors ) ) { WP_CLI::warning( sprintf( "Could not find any authors in this blog" ) ); @@ -181,15 +179,15 @@ private function check_author( $author ) { WP_CLI::warning( sprintf( 'Could not find a matching author for %s. The following authors exist: %s', $author, implode( ", ", $authors_nice ) ) ); return false; } - + $this->export_args['author'] = $hit; return true; } - + private function check_category( $category ) { if ( is_null( $category ) ) return true; - + $term = category_exists( $category ); if ( empty( $term ) || is_wp_error( $term ) ) { WP_CLI::warning( sprintf( 'Could not find a category matching %s', $category ) ); @@ -198,17 +196,17 @@ private function check_category( $category ) { $this->export_args['category'] = $category; return true; } - + private function check_post_status( $status ) { if ( is_null( $status ) ) return true; - + $stati = get_post_statuses(); if ( empty( $stati ) || is_wp_error( $stati ) ) { WP_CLI::warning( sprintf( 'Could not find any post stati', $category ) ); return false; } - + if ( !isset( $stati[$status] ) ) { WP_CLI::warning( sprintf( 'Could not find a post_status matching %s. Here is a list of available stati: %s', $status, implode( ", ", array_keys( $stati ) ) ) ); return false; @@ -216,11 +214,11 @@ private function check_post_status( $status ) { $this->export_args['status'] = $status; return true; } - + private function check_skip_comments( $skip ) { if ( is_null( $skip ) ) return true; - + if ( (int) $skip <> 0 && (int) $skip <> 1 ) { WP_CLI::warning( sprintf( 'skip_comments needs to be 0 (no) or 1 (yes)', $category ) ); return false; @@ -228,12 +226,12 @@ private function check_skip_comments( $skip ) { $this->export_args['skip_comments'] = $skip; return true; } - - + + /** * Workaround to prevent memory leaks from growing variables */ - + private function stop_the_insanity() { global $wpdb, $wp_object_cache; $wpdb->queries = array(); // or define( 'WP_IMPORTING', true ); @@ -245,21 +243,21 @@ private function stop_the_insanity() { $wp_object_cache->cache = array(); $wp_object_cache->__remoteset(); // important } - + /** * Export function as it is defined in the original code of export_wp defined in wp-admin/includes/export.php */ - + private function export_wp( $args = array() ) { require_once ABSPATH . 'wp-admin/includes/export.php'; - + global $wpdb, $post; // call export_wp as we need the functions defined in it. $dummy_args = array( 'content' => 'i-do-not-exist' ); ob_start(); export_wp( $dummy_args ); ob_end_clean(); - + /** * This is mostly the original code of export_wp defined in wp-admin/includes/export.php */ @@ -269,7 +267,7 @@ private function export_wp( $args = array() ) { $args = wp_parse_args( $args, $defaults ); WP_CLI::line( "Exporting with export_wp with arguments: " . var_export( $args, true ) ); - + do_action( 'export_wp' ); $sitename = sanitize_key( get_bloginfo( 'name' ) ); @@ -282,7 +280,7 @@ private function export_wp( $args = array() ) { $append[]= "$arg_key-" . (string) $args[$arg_key]; } $file_name_base = $sitename . 'wordpress.' . implode( ".", $append ); - + if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) { $ptype = get_post_type_object( $args['content'] ); if ( ! $ptype->can_export ) @@ -321,7 +319,7 @@ private function export_wp( $args = array() ) { // grab a snapshot of post IDs, just in case it changes during the export $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" ); - + // get the requested terms ready, empty unless posts filtered by category or all content $cats = $tags = $terms = array(); if ( isset( $term ) && $term ) { @@ -354,13 +352,13 @@ private function export_wp( $args = array() ) { unset( $categories, $custom_taxonomies, $custom_terms ); } - + WP_CLI::line( 'Exporting ' . count( $post_ids ) . ' items' ); WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); WP_CLI::line( 'Exporting ' . count( $tags ) . ' tags' ); WP_CLI::line( 'Exporting ' . count( $terms ) . ' terms' ); WP_CLI::line(); - + $progress = $this->progress_bar( 'exporting', count( $post_ids ) ); ob_start(); @@ -424,15 +422,15 @@ private function export_wp( $args = array() ) { // fetch 20 posts at a time rather than loading the entire table into memory while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) { - + $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')'; $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" ); // Begin Loop foreach ( $posts as $post ) { - + $progress->tick(); - + setup_postdata( $post ); $is_sticky = is_sticky( $post->ID ) ? 1 : 0; ?> @@ -503,20 +501,20 @@ private function export_wp( $args = array() ) { wxr_path . $file_name_base . '.wxr'; - + if ( !file_exists( $full_path ) || is_writeable( $full_path ) ) { WP_CLI::line( 'Writing to ' . $full_path ); file_put_contents( $full_path, $result ); } } - - /** - * Implement progress bar + + /** + * Implement progress bar */ private function progress_bar( $title, $total, $interval = 100 ) { return new \cli\progress\Bar( $title, $total, $interval ); } - -} \ No newline at end of file + +} From ca4c14c4ebf5e621526ccf5a21e6be571e8bda6a Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 21 Dec 2011 03:56:35 +0200 Subject: [PATCH 0184/4858] more specific warnings. see #44 --- src/php/wp-cli/commands/internals/export.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 9ac6854879..7ecaa5d479 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -72,7 +72,6 @@ public function validate_arguments( $args, $assoc_args ) { } if ( true === $has_errors ) { - WP_CLI::error( 'There were errors. Please review the items listed above' ); exit; } @@ -83,8 +82,8 @@ public function validate_arguments( $args, $assoc_args ) { private function check_path( $path ) { if ( empty( $path ) ) { - $this->help(); - exit; + WP_CLI::warning( 'missing --path parameter' ); + return false; } if ( !is_dir( $path ) ) { @@ -97,8 +96,8 @@ private function check_path( $path ) { private function check_user( $user ) { if ( empty( $user ) ) { - $this->help(); - exit; + WP_CLI::warning( 'missing --user parameter' ); + return false; } if ( is_numeric( $user ) ) { From 5d4cd7823d80a823c2a83f036a1a84aff0c656d3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 21 Dec 2011 14:06:04 +0000 Subject: [PATCH 0185/4858] Move installation commands to core --- src/php/wp-cli/commands/internals/core.php | 36 ++++++++++++++ .../wp-cli/commands/internals/installer.php | 49 ------------------- src/php/wp-cli/wp-cli.php | 5 +- 3 files changed, 40 insertions(+), 50 deletions(-) delete mode 100644 src/php/wp-cli/commands/internals/installer.php diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 3d0cf2b76d..e05284c6b3 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -2,6 +2,8 @@ WP_CLI::addCommand('core', 'CoreCommand'); +require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + /** * Implement core command * @@ -73,6 +75,38 @@ function update($args) { WP_CLI::success('WordPress upgraded successfully.'); } } + + public function install( $args, $assoc_args ) { + if ( is_blog_installed() ) { + WP_CLI::error( 'Wordpress is already installed.' ); + exit( 1 ); + } + $site_title = $assoc_args["site_title"]; + $username = $assoc_args["username"]; + $admin_email = $assoc_args["email_address"]; + $public = true; + $admin_password = $assoc_args["password"]; + + if ( ! $site_title || ! $username || ! $admin_email || ! $admin_password ) { + WP_CLI::error( 'Missing installation arguments' ); + exit( 1 ); + } + + $result = wp_install( $site_title, $username, $admin_email, $public, '', $admin_password ); + if ( is_wp_error( $result ) ) { + WP_CLI::error( 'Installation failed (' . WP_CLI::errorToString($result) . ').' ); + } else { + WP_CLI::success( 'WordPress installed successfully.' ); + } + } + + public function is_installed( $filename ) { + if ( is_blog_installed() ) { + exit( 0 ); + } else { + exit( 1 ); + } + } /** * Help function for this command @@ -81,6 +115,8 @@ public static function help() { WP_CLI::line( << --username= --password= --email_address= + or: wp core is_installed EOB ); } diff --git a/src/php/wp-cli/commands/internals/installer.php b/src/php/wp-cli/commands/internals/installer.php deleted file mode 100644 index 9e6ad644a5..0000000000 --- a/src/php/wp-cli/commands/internals/installer.php +++ /dev/null @@ -1,49 +0,0 @@ - --username= --password= --email_address= - or: wp installer is_installed -EOB - ); - } -} - diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index e22011e697..964d04d7f3 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -68,7 +68,10 @@ } // Set installer flag before loading any Wordpress libs -$installing = count( $arguments ) > 0 && $arguments[0] === "installer"; +$installing = count( $arguments ) >= 2 && + $arguments[0] === "core" && + ($arguments[1] === "install" || $arguments[1] == "is_installed"); + if ( $installing ) { define( 'WP_INSTALLING', true ); } From fef05208fd6f198ec3a7643a31329c72bc9dde1d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 21 Dec 2011 14:22:06 +0000 Subject: [PATCH 0186/4858] Add some documentation for the two installer commands --- src/php/wp-cli/commands/internals/core.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index e05284c6b3..2c544732d1 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -76,6 +76,9 @@ function update($args) { } } + /** + * Run wp_install. Assumes that wp-config.php is already in place. + */ public function install( $args, $assoc_args ) { if ( is_blog_installed() ) { WP_CLI::error( 'Wordpress is already installed.' ); @@ -100,7 +103,11 @@ public function install( $args, $assoc_args ) { } } - public function is_installed( $filename ) { + /** + * Determine if Wordpress is already installed. Exits with 0 if + * Wordpress is installed, 1 if not. + */ + public function is_installed() { if ( is_blog_installed() ) { exit( 0 ); } else { From efcb90d1e308089930af76e83317643ca9e59e6d Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 21 Dec 2011 19:07:36 +0200 Subject: [PATCH 0187/4858] add `wp plugin uninstall`. fixes #52 --- src/php/wp-cli/commands/internals/plugin.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 9e26f7b82d..205d162009 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -246,6 +246,17 @@ function install( $args, $assoc_args ) { } } + /** + * Uninstall a plugin + * + * @param array $args + */ + function uninstall( $args ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + uninstall_plugin( $file ); + } + /** * Delete a plugin * @@ -369,6 +380,8 @@ public static function help() { update update a plugin from wordpress.org + uninstall run the uninstallation procedure for a plugin + delete delete a plugin EOB ); From 0d2376a3e35a4234a4190870cd4203df2a91f01f Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 21 Dec 2011 20:05:44 +0200 Subject: [PATCH 0188/4858] don't attempt to uninstall active plugin. see #52 --- src/php/wp-cli/commands/internals/plugin.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 205d162009..cc68549d3b 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -254,6 +254,10 @@ function install( $args, $assoc_args ) { function uninstall( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + if ( is_plugin_active( $file ) ) { + WP_CLI::error( 'The plugin is active.' ); + } + uninstall_plugin( $file ); } From 30f56f51daf58ae3b873f246762840fdce9c30bf Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 22 Dec 2011 14:49:06 +0200 Subject: [PATCH 0189/4858] remove is_installed command. see #51 --- src/php/wp-cli/commands/internals/core.php | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 2c544732d1..22e4aac274 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -75,7 +75,7 @@ function update($args) { WP_CLI::success('WordPress upgraded successfully.'); } } - + /** * Run wp_install. Assumes that wp-config.php is already in place. */ @@ -89,12 +89,12 @@ public function install( $args, $assoc_args ) { $admin_email = $assoc_args["email_address"]; $public = true; $admin_password = $assoc_args["password"]; - + if ( ! $site_title || ! $username || ! $admin_email || ! $admin_password ) { WP_CLI::error( 'Missing installation arguments' ); exit( 1 ); } - + $result = wp_install( $site_title, $username, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::errorToString($result) . ').' ); @@ -103,18 +103,6 @@ public function install( $args, $assoc_args ) { } } - /** - * Determine if Wordpress is already installed. Exits with 0 if - * Wordpress is installed, 1 if not. - */ - public function is_installed() { - if ( is_blog_installed() ) { - exit( 0 ); - } else { - exit( 1 ); - } - } - /** * Help function for this command */ @@ -123,8 +111,8 @@ public static function help() { usage: wp core update or: wp core version [--extra] or: wp core install --site_title= --username= --password= --email_address= - or: wp core is_installed EOB ); } } + From 3224eee095ea943b40b536e720fb6be9f02473bf Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 22 Dec 2011 14:50:31 +0200 Subject: [PATCH 0190/4858] capital P dammit --- src/php/wp-cli/commands/internals/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 22e4aac274..bcb68ec4f6 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -81,9 +81,9 @@ function update($args) { */ public function install( $args, $assoc_args ) { if ( is_blog_installed() ) { - WP_CLI::error( 'Wordpress is already installed.' ); - exit( 1 ); + WP_CLI::error( 'WordPress is already installed.' ); } + $site_title = $assoc_args["site_title"]; $username = $assoc_args["username"]; $admin_email = $assoc_args["email_address"]; From b706d3128713d7a120abe6a819b0c0c415abda5b Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 22 Dec 2011 15:03:28 +0200 Subject: [PATCH 0191/4858] standardize parameter names; make admin name optional. see #51 --- src/php/wp-cli/commands/internals/core.php | 30 ++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index bcb68ec4f6..fcddfcc381 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -84,18 +84,28 @@ public function install( $args, $assoc_args ) { WP_CLI::error( 'WordPress is already installed.' ); } - $site_title = $assoc_args["site_title"]; - $username = $assoc_args["username"]; - $admin_email = $assoc_args["email_address"]; + extract( wp_parse_args( $assoc_args, array( + 'site_title' => '', + 'admin_name' => 'admin', + 'admin_email' => '', + 'admin_password' => '' + ) ), EXTR_SKIP ); + + $missing = false; + foreach ( array( 'site_title', 'admin_email', 'admin_password' ) as $required_arg ) { + if ( empty( $$required_arg ) ) { + WP_CLI::warning( "missing --$required_arg parameter" ); + $missing = true; + } + } + + if ( $missing ) + exit(1); + $public = true; - $admin_password = $assoc_args["password"]; - if ( ! $site_title || ! $username || ! $admin_email || ! $admin_password ) { - WP_CLI::error( 'Missing installation arguments' ); - exit( 1 ); - } + $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); - $result = wp_install( $site_title, $username, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::errorToString($result) . ').' ); } else { @@ -110,7 +120,7 @@ public static function help() { WP_CLI::line( << --username= --password= --email_address= + or: wp core install --site_title= [--admin_name=] --admin_password= --admin_email= EOB ); } From 159acd1ffa60f5d0ffac6fcb788cf498dbbe7d6a Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 22 Dec 2011 15:21:05 +0200 Subject: [PATCH 0192/4858] add necessary site_url parameter. see #51 --- src/php/wp-cli/class-wp-cli.php | 16 ++++++++++++++++ src/php/wp-cli/commands/internals/core.php | 8 ++++++-- src/php/wp-cli/wp-cli.php | 17 +++-------------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 56967f960e..d71b12feb4 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -143,6 +143,22 @@ static function legend( $legend ) { WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } + /** + * Sets the appropriate $_SERVER keys based on a given string + * + * @param string $url The URL + */ + static function set_url( $url ) { + if ( false === strpos( $url, '/' ) ) + $url .= '/'; + + list( $domain, $path ) = explode( '/', $url, 2 ); + + $_SERVER['HTTP_HOST'] = $domain; + + $_SERVER['REQUEST_URI'] = '/' . $path; + } + /** * Return the beginning of the status line for a certain plugin or theme * diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index fcddfcc381..4fff92ca6b 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -85,6 +85,7 @@ public function install( $args, $assoc_args ) { } extract( wp_parse_args( $assoc_args, array( + 'site_url' => defined( 'WP_SITEURL' ) ? WP_SITEURL : '', 'site_title' => '', 'admin_name' => 'admin', 'admin_email' => '', @@ -92,13 +93,16 @@ public function install( $args, $assoc_args ) { ) ), EXTR_SKIP ); $missing = false; - foreach ( array( 'site_title', 'admin_email', 'admin_password' ) as $required_arg ) { + foreach ( array( 'site_url', 'site_title', 'admin_email', 'admin_password' ) as $required_arg ) { if ( empty( $$required_arg ) ) { WP_CLI::warning( "missing --$required_arg parameter" ); $missing = true; } } + if ( $site_url ) + WP_CLI::set_url( $site_url ); + if ( $missing ) exit(1); @@ -120,7 +124,7 @@ public static function help() { WP_CLI::line( << [--admin_name=] --admin_password= --admin_email= + or: wp core install --site_url=example.com --site_title= [--admin_name=] --admin_password= --admin_email= EOB ); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 964d04d7f3..58b8a8f0b0 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -57,22 +57,11 @@ } if ( isset( $blog ) ) { - if ( false === strpos( $blog, '/' ) ) - $blog .= '/'; - - list( $domain, $path ) = explode( '/', $blog, 2 ); - - $_SERVER['HTTP_HOST'] = $domain; - - $_SERVER['REQUEST_URI'] = '/' . $path; + WP_CLI::set_url( $blog ); } -// Set installer flag before loading any Wordpress libs -$installing = count( $arguments ) >= 2 && - $arguments[0] === "core" && - ($arguments[1] === "install" || $arguments[1] == "is_installed"); - -if ( $installing ) { +// Set installer flag before loading any WP files +if ( $arguments[0] == 'core' && $arguments[1] == 'install' ) { define( 'WP_INSTALLING', true ); } From 23671f538e54fd74f03e9a3ae2db9eebf3a04939 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 22 Dec 2011 15:24:57 +0200 Subject: [PATCH 0193/4858] add preliminary changelog for 0.4 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 3583bdd8d4..6e35d9f959 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,14 @@ You can find more information about adding commands in the [Commands Cookbook](h Changelog --------------- +**0.4** + +- added `wp eval` and `wp eval-file` +- added `wp export` +- added `wp core install` +- added `--dev` flag to `wp plugin install` +- added `wp plugin uninstall` + **0.3** - added `wp sql` From 930f1f0cbf92f6dcfb5d8017745d2f1b2dd5432d Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 26 Dec 2011 15:12:26 +0200 Subject: [PATCH 0194/4858] prevent notice when checking for install sub-command --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 58b8a8f0b0..578f51d435 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -61,7 +61,7 @@ } // Set installer flag before loading any WP files -if ( $arguments[0] == 'core' && $arguments[1] == 'install' ) { +if ( count( $arguments ) >= 2 && $arguments[0] == 'core' && $arguments[1] == 'install' ) { define( 'WP_INSTALLING', true ); } From 01cc90655f154994c5595f62042c473f4570aeed Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 26 Dec 2011 16:26:05 +0200 Subject: [PATCH 0195/4858] require upgrade.php only when doing the upgrade --- src/php/wp-cli/commands/internals/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 4fff92ca6b..049c7fe0e4 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -2,8 +2,6 @@ WP_CLI::addCommand('core', 'CoreCommand'); -require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - /** * Implement core command * @@ -52,6 +50,8 @@ public function version( $args = array(), $assoc_args = array() ) { * @param array $args */ function update($args) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + WP_CLI::line('Updating the WordPress core.'); if(!class_exists('Core_Upgrader')) { From 3b0e12c8a6f1e08ad7c93c6a8517ee2b5bf97212 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 26 Dec 2011 16:44:35 +0200 Subject: [PATCH 0196/4858] load plugin files only when the plugin command is invoked --- src/php/wp-cli/commands/internals/plugin.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index cc68549d3b..c5e12664a8 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -2,9 +2,6 @@ WP_CLI::addCommand('plugin', 'PluginCommand'); -require_once(ABSPATH.'wp-admin/includes/plugin.php'); -require_once(ABSPATH.'wp-admin/includes/plugin-install.php'); - /** * Implement plugin command * @@ -17,6 +14,13 @@ class PluginCommand extends WP_CLI_Command { private $mu_plugins; + function __construct( $args, $assoc_args ) { + require_once ABSPATH.'wp-admin/includes/plugin.php'; + require_once ABSPATH.'wp-admin/includes/plugin-install.php'; + + parent::__construct( $args, $assoc_args ); + } + /** * Get the status of one or all plugins * From 9ac855708994aa9d474e58b3d8e8c62dcd8d9310 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 26 Dec 2011 18:07:23 +0300 Subject: [PATCH 0197/4858] move CLI_Upgrader_Skin to separate file; add get_upgrader() helper --- src/php/wp-cli/class-cli-upgrader-skin.php | 73 ++++++++++++++++++++ src/php/wp-cli/class-wp-cli.php | 73 ++------------------ src/php/wp-cli/commands/internals/core.php | 5 +- src/php/wp-cli/commands/internals/plugin.php | 11 +-- 4 files changed, 82 insertions(+), 80 deletions(-) create mode 100644 src/php/wp-cli/class-cli-upgrader-skin.php diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php new file mode 100644 index 0000000000..b9967c18cb --- /dev/null +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -0,0 +1,73 @@ + '', 'nonce' => '', 'title' => '', 'context' => false ); + $this->options = wp_parse_args( $args, $defaults ); + } + + function set_upgrader( &$upgrader ) { + if( is_object( $upgrader ) ) { + $this->upgrader =& $upgrader; + } + + $this->add_strings(); + } + + function add_strings() {} + + function set_result( $result ) { + $this->result = $result; + } + + function request_filesystem_credentials( $error = false ) { + $url = $this->options['url']; + $context = $this->options['context']; + if( !empty( $this->options['nonce'] ) ) { + $url = wp_nonce_url( $url, $this->options['nonce']) ; + } + + // Possible to bring inline, Leaving as is for now. + return request_filesystem_credentials( $url, '', $error, $context ); + } + + function header() {} + function footer() {} + + function error( $errors ) { + $this->feedback( WP_CLI::errorToString($errors) ); + } + + function feedback( $string ) { + if(isset( $this->upgrader->strings[$string] ) ) + $string = $this->upgrader->strings[$string]; + + if( strpos( $string, '%' ) !== false ) { + $args = func_get_args(); + $args = array_splice( $args, 1 ); + if( !empty( $args ) ) { + $string = vsprintf( $string, $args ); + } + + } + + if( empty( $string ) ) { + return; + } + + echo $string; + } + + function before() {} + function after() {} +} + diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index d71b12feb4..e75f6b86cc 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -175,75 +175,14 @@ static function get_update_status( $item, $key ) { return false; } -} - -/** - * A Upgrader Skin for WordPress that only generates plain-text - * - * @package wp-cli - */ -class CLI_Upgrader_Skin { - var $upgrader; - var $done_header = false; - var $result = false; - - function __construct( $args = array() ) { - $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false ); - $this->options = wp_parse_args( $args, $defaults ); - } - - function set_upgrader( &$upgrader ) { - if( is_object( $upgrader ) ) { - $this->upgrader =& $upgrader; - } - - $this->add_strings(); - } - - function add_strings() {} - - function set_result( $result ) { - $this->result = $result; - } - function request_filesystem_credentials( $error = false ) { - $url = $this->options['url']; - $context = $this->options['context']; - if( !empty( $this->options['nonce'] ) ) { - $url = wp_nonce_url( $url, $this->options['nonce']) ; - } - - // Possible to bring inline, Leaving as is for now. - return request_filesystem_credentials( $url, '', $error, $context ); - } - - function header() {} - function footer() {} - - function error( $errors ) { - $this->feedback( WP_CLI::errorToString($errors) ); - } - - function feedback( $string ) { - if(isset( $this->upgrader->strings[$string] ) ) - $string = $this->upgrader->strings[$string]; + static function get_upgrader( $class ) { + if ( !class_exists( 'WP_Upgrader' ) ) + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - if( strpos( $string, '%' ) !== false ) { - $args = func_get_args(); - $args = array_splice( $args, 1 ); - if( !empty( $args ) ) { - $string = vsprintf( $string, $args ); - } - - } + require WP_CLI_ROOT . '/class-cli-upgrader-skin.php'; - if( empty( $string ) ) { - return; - } - - echo $string; + return new $class( new CLI_Upgrader_Skin ); } - - function before() {} - function after() {} } + diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 049c7fe0e4..3d5e27a072 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -54,11 +54,8 @@ function update($args) { WP_CLI::line('Updating the WordPress core.'); - if(!class_exists('Core_Upgrader')) { - require_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php'); - } ob_start(); - $upgrader = new Core_Upgrader(new CLI_Upgrader_Skin); + $upgrader = WP_CLI::get_upgrader( 'Core_Upgrader' ); $result = $upgrader->upgrade($current); $feedback = ob_get_clean(); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index c5e12664a8..d2751b1005 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -221,13 +221,10 @@ function install( $args, $assoc_args ) { switch ( $status['status'] ) { case 'update_available': case 'install': - if ( !class_exists( 'Plugin_Upgrader' ) ) { - require_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' ); - } // Install the plugin ob_start( 'strip_tags' ); - $upgrader = new Plugin_Upgrader( new CLI_Upgrader_Skin ); + $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); $result = $upgrader->install( $api->download_link ); $feedback = ob_get_clean(); @@ -289,15 +286,11 @@ function update( $args ) { // Force WordPress to update the plugin list wp_update_plugins(); - if ( !class_exists( 'Plugin_Upgrader' ) ) { - require_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' ); - } - WP_CLI::line( 'Updating '.$name ); // Upgrading the plugin ob_start( 'strip_tags' ); - $upgrader = new Plugin_Upgrader( new CLI_Upgrader_Skin ); + $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); $result = $upgrader->upgrade( $file ); $feedback = ob_get_clean(); From 7e0f7de6857a5f5d636d28a165884003bbaeaa7b Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 28 Dec 2011 13:05:59 +0200 Subject: [PATCH 0198/4858] revamp plugin upgrader handling. fixes #53 --- src/php/wp-cli/class-cli-upgrader-skin.php | 66 ++++++-------------- src/php/wp-cli/commands/internals/plugin.php | 55 +++++----------- 2 files changed, 35 insertions(+), 86 deletions(-) diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index b9967c18cb..d59958c6b1 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -5,69 +5,41 @@ * * @package wp-cli */ -class CLI_Upgrader_Skin { - var $upgrader; - var $done_header = false; - var $result = false; +class CLI_Upgrader_Skin extends WP_Upgrader_Skin { - function __construct( $args = array() ) { - $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false ); - $this->options = wp_parse_args( $args, $defaults ); - } - - function set_upgrader( &$upgrader ) { - if( is_object( $upgrader ) ) { - $this->upgrader =& $upgrader; - } - - $this->add_strings(); - } - - function add_strings() {} - - function set_result( $result ) { - $this->result = $result; - } + function header() {} + function footer() {} + // TODO: show prompt function request_filesystem_credentials( $error = false ) { - $url = $this->options['url']; - $context = $this->options['context']; - if( !empty( $this->options['nonce'] ) ) { - $url = wp_nonce_url( $url, $this->options['nonce']) ; - } - - // Possible to bring inline, Leaving as is for now. - return request_filesystem_credentials( $url, '', $error, $context ); + $this->error( $error ); } - function header() {} - function footer() {} + function error( $error ) { + if ( !$error ) + return; - function error( $errors ) { - $this->feedback( WP_CLI::errorToString($errors) ); + // TODO: show all errors, not just the first one + WP_CLI::warning( WP_CLI::errorToString( $error ) ); } function feedback( $string ) { - if(isset( $this->upgrader->strings[$string] ) ) + if ( isset( $this->upgrader->strings[$string] ) ) $string = $this->upgrader->strings[$string]; - if( strpos( $string, '%' ) !== false ) { + if ( strpos($string, '%') !== false ) { $args = func_get_args(); - $args = array_splice( $args, 1 ); - if( !empty( $args ) ) { - $string = vsprintf( $string, $args ); - } - + $args = array_splice($args, 1); + if ( !empty($args) ) + $string = vsprintf($string, $args); } - if( empty( $string ) ) { + if ( empty($string) ) return; - } - echo $string; - } + $string = str_replace( '…', '...', strip_tags( $string ) ); - function before() {} - function after() {} + WP_CLI::line( $string ); + } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index d2751b1005..37f5dfea87 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -199,7 +199,6 @@ function install( $args, $assoc_args ) { // Force WordPress to update the plugin list wp_update_plugins(); - // Get plugin info from the WordPress servers $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( !$api ) { WP_CLI::error( 'Can\'t find the plugin in the WordPress.org plugins repository.' ); @@ -217,26 +216,18 @@ function install( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - // Check what to do switch ( $status['status'] ) { case 'update_available': case 'install': - - // Install the plugin - ob_start( 'strip_tags' ); $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); $result = $upgrader->install( $api->download_link ); - $feedback = ob_get_clean(); if ( $result ) { - WP_CLI::line(); - WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin installed successfully.' ), array( "...\n", '' ), html_entity_decode( $feedback ) ) ) ); - WP_CLI::success( 'The plugin is successfully installed' ); - if ( isset( $assoc_args['activate'] ) ) { system( "wp plugin activate " . WP_CLI::compose_args( $args, $assoc_args ) ); } } + break; case 'newer_installed': WP_CLI::error( sprintf( 'Newer version (%s) installed', $status['version'] ) ); @@ -247,6 +238,21 @@ function install( $args, $assoc_args ) { } } + /** + * Update a plugin + * + * @param array $args + */ + function update( $args ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + // Force WordPress to update the plugin list + wp_update_plugins(); + + $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); + $result = $upgrader->upgrade( $file ); + } + /** * Uninstall a plugin * @@ -275,35 +281,6 @@ function delete( $args ) { } } - /** - * Update a plugin - * - * @param array $args - */ - function update( $args ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - - // Force WordPress to update the plugin list - wp_update_plugins(); - - WP_CLI::line( 'Updating '.$name ); - - // Upgrading the plugin - ob_start( 'strip_tags' ); - $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); - $result = $upgrader->upgrade( $file ); - $feedback = ob_get_clean(); - - if ( $result !== null ) { - WP_CLI::error( $feedback ); - } - else { - WP_CLI::line(); - WP_CLI::line( strip_tags( str_replace( array( '…', 'Plugin updates successfully.' ), array( "...\n", '' ), html_entity_decode( $feedback ) ) ) ); - WP_CLI::success( 'The plugin is successfully updated.' ); - } - } - /* PRIVATES */ /** From a0b31ccd863b2e8c6137ac8bd36effca0e8fe50f Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 28 Dec 2011 13:32:54 +0200 Subject: [PATCH 0199/4858] load upgrade.php before calling wp_install() --- src/php/wp-cli/commands/internals/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 3d5e27a072..9426556a94 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -77,6 +77,8 @@ function update($args) { * Run wp_install. Assumes that wp-config.php is already in place. */ public function install( $args, $assoc_args ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + if ( is_blog_installed() ) { WP_CLI::error( 'WordPress is already installed.' ); } From b3055c2dd05f76e29a589dba82808dc9fc13724f Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 28 Dec 2011 14:09:09 +0200 Subject: [PATCH 0200/4858] fix wp core update. closes #43 --- src/php/wp-cli/commands/internals/core.php | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 9426556a94..f40a4c3188 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -50,26 +50,29 @@ public function version( $args = array(), $assoc_args = array() ) { * @param array $args */ function update($args) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + wp_version_check(); - WP_CLI::line('Updating the WordPress core.'); + $from_api = get_site_transient( 'update_core' ); - ob_start(); - $upgrader = WP_CLI::get_upgrader( 'Core_Upgrader' ); - $result = $upgrader->upgrade($current); - $feedback = ob_get_clean(); + if ( empty( $from_api->updates ) ) + $update = false; + else + list( $update ) = $from_api->updates; - // Borrowed verbatim from wp-admin/update-core.php - if(is_wp_error($result) ) { - if('up_to_date' != $result->get_error_code()) { - WP_CLI::error('Installation failed ('.WP_CLI::errorToString($result).').'); - } - else { - WP_CLI::success(WP_CLI::errorToString($result)); + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + $upgrader = WP_CLI::get_upgrader( 'Core_Upgrader' ); + $result = $upgrader->upgrade( $update ); + + if ( is_wp_error($result) ) { + $msg = WP_CLI::errorToString( $result ); + if ( 'up_to_date' != $result->get_error_code() ) { + WP_CLI::error( $msg ); + } else { + WP_CLI::success( $msg ); } - } - else { - WP_CLI::success('WordPress upgraded successfully.'); + } else { + WP_CLI::success('WordPress updated successfully.'); } } From 6cf1929a9e54d138eba1e490a6a31015fa1f1d19 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 28 Dec 2011 14:27:51 +0200 Subject: [PATCH 0201/4858] changelog --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6e35d9f959..1d6a9e0882 100644 --- a/README.md +++ b/README.md @@ -109,8 +109,10 @@ Changelog - added `wp eval` and `wp eval-file` - added `wp export` - added `wp core install` +- fixed `wp core update` - added `--dev` flag to `wp plugin install` - added `wp plugin uninstall` +- fixed `wp plugin install` and `wp plugin update` **0.3** From f214187b768f52e45054bed331fe1a526a50c090 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 28 Dec 2011 15:02:51 +0200 Subject: [PATCH 0202/4858] remove unlikely case when there are no commands at all --- src/php/wp-cli/wp-cli.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 578f51d435..e60b2a358c 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -1,7 +1,7 @@ $command ) { From 959ebd94778389b8e5a38f714212820a97e9150e Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 29 Dec 2011 16:47:22 +0200 Subject: [PATCH 0203/4858] release version 0.4.0 --- build.properties | 2 +- src/php/wp-cli/wp-cli.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.properties b/build.properties index 8079bf947f..27cb6bd81f 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.name=wpcli project.channel=andreascreten.github.com/wp-cli project.majorVersion=0 -project.minorVersion=3 +project.minorVersion=4 project.patchLevel=0 project.snapshot=false diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index e60b2a358c..e899113506 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,7 +4,7 @@ die( 'Only cli access' ); } -define( 'WP_CLI_VERSION', '0.4.0-dev' ); +define( 'WP_CLI_VERSION', '0.4.0' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 56f6b791e70e101b7d297e69e799ab0e0458df45 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 2 Jan 2012 17:50:55 +0200 Subject: [PATCH 0204/4858] replace old reference to generalHelp() with general_help() --- src/php/wp-cli/commands/internals/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 4a8e68882c..cc237c7911 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -21,7 +21,7 @@ public function __construct( $args ) { } else { $command = $args[0]; if ( 'help' == $command || !isset( WP_CLI::$commands[$command] ) ) { - $this->generalHelp(); + $this->general_help(); } else { $class = WP_CLI::$commands[$command]; From 6f8e3e535062cdd8e834e11cf8ca9c3ea35d4dd6 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 26 Jan 2012 07:37:19 +0100 Subject: [PATCH 0205/4858] Added requirements to the README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 1d6a9e0882..d9fa906e5c 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,11 @@ What is wp-cli? A set of tools for controlling WordPress installations from the command line. +Requirements +------------ + +PHP >= 5.3 + Installing ---------- From bb162f940d80d5a880232f16889093fd767f0956 Mon Sep 17 00:00:00 2001 From: Eric Lewis Date: Sun, 5 Feb 2012 19:51:14 -0500 Subject: [PATCH 0206/4858] Add "download" command. Downloads the current version of WP to the current working directory via SVN. I hardcoded the command instead of creating a subclass of WP_CLI because WP file check happens earlier than the subclasses are included. --- src/php/wp-cli/wp-cli.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index e899113506..a0051b1f99 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -39,6 +39,16 @@ define('WP_ROOT', $_SERVER['PWD'] . '/'); } +//Download fresh copy of WordPress via SVN +if ( $arguments[0] == "download" ) { + if ( ! file_exists( 'wp-load.php' ) && ! file_exists( '/../wp-load.php' ) ) { + cli\line("Downloading WordPress via SVN..."); + exec("svn export --force http://core.svn.wordpress.org/tags/3.3.1/ ./"); + WP_CLI::success('WordPress downloaded successfully.'); + exit; + } +} + // Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); From c491fd508f06cb1134e888bd05ae8307616df3cb Mon Sep 17 00:00:00 2001 From: Eric Lewis Date: Sun, 5 Feb 2012 22:12:02 -0500 Subject: [PATCH 0207/4858] Download WP via latest.zip link instead of SVN repo. --- src/php/wp-cli/wp-cli.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index a0051b1f99..31ca24f2b8 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -42,9 +42,15 @@ //Download fresh copy of WordPress via SVN if ( $arguments[0] == "download" ) { if ( ! file_exists( 'wp-load.php' ) && ! file_exists( '/../wp-load.php' ) ) { - cli\line("Downloading WordPress via SVN..."); - exec("svn export --force http://core.svn.wordpress.org/tags/3.3.1/ ./"); - WP_CLI::success('WordPress downloaded successfully.'); + cli\line("Downloading WordPress..."); + exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); + WP_CLI::success('WordPress downloaded.'); + cli\line("Unzipping..."); + exec("unzip /tmp/wordpress.zip"); + exec("rm /tmp/wordpress.zip"); + exec("mv wordpress/* ./"); + exec("rm -r wordpress"); + WP_CLI::success('WordPress unzipped.'); exit; } } From e3e03722fa7dc7a0750b98dc6077487c136171fb Mon Sep 17 00:00:00 2001 From: Eric Lewis Date: Sun, 5 Feb 2012 23:32:02 -0500 Subject: [PATCH 0208/4858] change call of \cli\line to the corresponding method line() within WP_CLI class. --- src/php/wp-cli/wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 31ca24f2b8..f234f732a6 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -42,12 +42,11 @@ //Download fresh copy of WordPress via SVN if ( $arguments[0] == "download" ) { if ( ! file_exists( 'wp-load.php' ) && ! file_exists( '/../wp-load.php' ) ) { - cli\line("Downloading WordPress..."); + WP_CLI::line("Downloading WordPress..."); exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); WP_CLI::success('WordPress downloaded.'); - cli\line("Unzipping..."); + WP_CLI::line("Unzipping..."); exec("unzip /tmp/wordpress.zip"); - exec("rm /tmp/wordpress.zip"); exec("mv wordpress/* ./"); exec("rm -r wordpress"); WP_CLI::success('WordPress unzipped.'); @@ -55,6 +54,7 @@ } } + // Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); From 426b5b973fe5268a8614e5f79112e95f901eea29 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 7 Feb 2012 02:17:01 +0200 Subject: [PATCH 0209/4858] integrate download command into existing check --- src/php/wp-cli/wp-cli.php | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index f234f732a6..0042bafb55 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -39,28 +39,23 @@ define('WP_ROOT', $_SERVER['PWD'] . '/'); } -//Download fresh copy of WordPress via SVN -if ( $arguments[0] == "download" ) { - if ( ! file_exists( 'wp-load.php' ) && ! file_exists( '/../wp-load.php' ) ) { +// Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php +if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { + // Download fresh copy of WordPress in the current dir + if ( isset( $arguments[0] ) && $arguments[0] == 'download' ) { WP_CLI::line("Downloading WordPress..."); exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); - WP_CLI::success('WordPress downloaded.'); - WP_CLI::line("Unzipping..."); exec("unzip /tmp/wordpress.zip"); exec("mv wordpress/* ./"); exec("rm -r wordpress"); - WP_CLI::success('WordPress unzipped.'); + WP_CLI::success('WordPress downloaded.'); + exit; + } else { + WP_CLI::error('This does not seem to be a WordPress install. Try running `wp download`.'); exit; } } - -// Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php -if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { - WP_CLI::error('Either this is not a WordPress document root or you do not have permission to administer this site.'); - exit(); -} - // Handle --blog parameter if ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; From 2136017fc0544eb16510d85982b5343c1c0d003b Mon Sep 17 00:00:00 2001 From: John Gray Date: Tue, 7 Feb 2012 12:01:39 -0600 Subject: [PATCH 0210/4858] use host in sql connect and dump commands --- src/php/wp-cli/commands/internals/sql.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/sql.php b/src/php/wp-cli/commands/internals/sql.php index a3f2e8ffca..1d6b2e907d 100644 --- a/src/php/wp-cli/commands/internals/sql.php +++ b/src/php/wp-cli/commands/internals/sql.php @@ -19,8 +19,8 @@ class SqlCommand extends WP_CLI_Command { * @return string $connect */ protected function connect_string() { - $connect = sprintf( 'mysql --database=%s --user=%s --password=%s', - DB_NAME, DB_USER, DB_PASSWORD); + $connect = sprintf( 'mysql --host=%s --database=%s --user=%s --password=%s', + DB_HOST, DB_NAME, DB_USER, DB_PASSWORD); return $connect; } @@ -58,7 +58,7 @@ function dump( $args, $assoc_args ) { $result_file = $assoc_args['file']; } - $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD ); + $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s --host=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD, DB_HOST ); exec( $exec ); } From ad9b35053de2774ec5c4d1362bd8914246aa7b89 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 7 Feb 2012 20:15:46 +0200 Subject: [PATCH 0211/4858] formatting fixes in sql.php --- src/php/wp-cli/commands/internals/sql.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/sql.php b/src/php/wp-cli/commands/internals/sql.php index 1d6b2e907d..b47cc97643 100644 --- a/src/php/wp-cli/commands/internals/sql.php +++ b/src/php/wp-cli/commands/internals/sql.php @@ -19,9 +19,8 @@ class SqlCommand extends WP_CLI_Command { * @return string $connect */ protected function connect_string() { - $connect = sprintf( 'mysql --host=%s --database=%s --user=%s --password=%s', - DB_HOST, DB_NAME, DB_USER, DB_PASSWORD); - return $connect; + return sprintf( 'mysql --host=%s --database=%s --user=%s --password=%s', + DB_HOST, DB_NAME, DB_USER, DB_PASSWORD ); } /** @@ -58,7 +57,8 @@ function dump( $args, $assoc_args ) { $result_file = $assoc_args['file']; } - $exec = sprintf( 'mysqldump %s --result-file %s --user=%s --password=%s --host=%s', DB_NAME, $result_file, DB_USER, DB_PASSWORD, DB_HOST ); + $exec = sprintf( 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', + DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); exec( $exec ); } From ca655b7f2dcf7901899612cf6eac69468211807d Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 7 Feb 2012 20:16:34 +0200 Subject: [PATCH 0212/4858] add success message to wp sql dump --- src/php/wp-cli/commands/internals/sql.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/sql.php b/src/php/wp-cli/commands/internals/sql.php index b47cc97643..ba84793289 100644 --- a/src/php/wp-cli/commands/internals/sql.php +++ b/src/php/wp-cli/commands/internals/sql.php @@ -61,6 +61,8 @@ function dump( $args, $assoc_args ) { DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); exec( $exec ); + + WP_CLI::success( sprintf( 'Dumped to %s', $result_file ) ); } /** From 044c07366cfe786d5392968a8c84fba092ceed37 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 7 Feb 2012 20:25:17 +0200 Subject: [PATCH 0213/4858] rename 'sql' command to 'db'. fixes #54 --- .../commands/internals/{sql.php => db.php} | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 deletions(-) rename src/php/wp-cli/commands/internals/{sql.php => db.php} (55%) diff --git a/src/php/wp-cli/commands/internals/sql.php b/src/php/wp-cli/commands/internals/db.php similarity index 55% rename from src/php/wp-cli/commands/internals/sql.php rename to src/php/wp-cli/commands/internals/db.php index ba84793289..01fb3028d3 100644 --- a/src/php/wp-cli/commands/internals/sql.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -1,22 +1,19 @@ connect_string(); - WP_CLI::line( $connect ); + function connect() { + WP_CLI::line( $this->connect_string() ); } /** * Open a SQL command-line interface using WordPress's credentials. - * @param string $args - * @return void */ function cli() { - $exec = $this->connect_string(); - - proc_close( proc_open( $exec , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); + proc_close( proc_open( $this->connect_string() , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); } /** - * Exports the WordPress DB as SQL using mysqldump or equivalent. - * @param string $args - * @return void + * Exports the WordPress DB as SQL using mysqldump. */ function dump( $args, $assoc_args ) { if ( !isset( $assoc_args['file'] ) ) { @@ -67,10 +54,7 @@ function dump( $args, $assoc_args ) { /** * Execute a query against the site database. - * @param string $args - * @return void */ - function query( $args, $assoc_args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp sql query " ); @@ -91,10 +75,10 @@ function query( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( << Date: Tue, 7 Feb 2012 20:27:18 +0200 Subject: [PATCH 0214/4858] add 'sql' alias for backwards compatibility. see #54 --- src/php/wp-cli/wp-cli.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 0042bafb55..5ba9ef2fae 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -104,6 +104,14 @@ else $command = array_shift( $arguments ); +// Translate aliases +$aliases = array( + 'sql' => 'db' +); + +if ( isset( $aliases[ $command ] ) ) + $command = $aliases[ $command ]; + if ( !isset( WP_CLI::$commands[$command] ) ) { WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); exit; From 136c62cfcd6ccd062b9fd0050dca8ba49b0a7d3e Mon Sep 17 00:00:00 2001 From: John Gray Date: Tue, 7 Feb 2012 18:42:10 -0600 Subject: [PATCH 0215/4858] list users with 'wp user all' --- src/php/wp-cli/commands/internals/user.php | 101 +++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/user.php diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php new file mode 100644 index 0000000000..e81d557772 --- /dev/null +++ b/src/php/wp-cli/commands/internals/user.php @@ -0,0 +1,101 @@ +setHeaders($fields); + + foreach ( $users as $user ) { + $line = array(); + + foreach ( $fields as $field ) { + $line[] = $user->$field; + } + + $table->addRow($line); + } + + $table->display(); + + $total = count_users(); + WP_CLI::line( 'Total: ' . $total['total_users'] . ' users' ); + } + + /** + * Create a user + * + * @param array $args + * @param array $assoc_args + **/ + public function users( $args, $assoc_args ) { + global $blog_id; + + $defaults = array( + 'count' => 100, + 'role' => get_option('default_role'), + ); + + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + if ( 'none' == $role ) { + $role = false; + } elseif ( is_null( get_role( $role ) ) ) { + WP_CLI::warning( "invalid role." ); + exit; + } + + $user_count = count_users(); + + $total = $user_count['total_users']; + + $limit = $count + $total; + + 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' ); + } + } + } + + /** + * Help function for this command + */ + public static function help() { + WP_CLI::line( <<] +EOB + ); + } +} From 620b55a18161c07d72e3f2ec66f0394bf869e18e Mon Sep 17 00:00:00 2001 From: John Gray Date: Tue, 7 Feb 2012 20:15:39 -0600 Subject: [PATCH 0216/4858] fix user count, add roles to list, add create subcommand --- src/php/wp-cli/commands/internals/user.php | 69 ++++++++++++---------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index e81d557772..23fb0c0c4c 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -18,11 +18,12 @@ class UserCommand extends WP_CLI_Command { public function all( $args, $assoc_args ) { global $blog_id; - $users = get_users("blog_id=$blog_id"); - $fields = array('ID', 'user_login', 'display_name', 'user_email', - 'user_registered', 'user_status'); $table = new \cli\Table(); - $table->setHeaders($fields); + $users = get_users("blog_id=$blog_id&fields=all_with_meta"); + $fields = array('ID', 'user_login', 'display_name', 'user_email', + 'user_registered'); + + $table->setHeaders( array_merge($fields, array('roles')) ); foreach ( $users as $user ) { $line = array(); @@ -30,14 +31,14 @@ public function all( $args, $assoc_args ) { foreach ( $fields as $field ) { $line[] = $user->$field; } + $line[] = implode( ',', $user->roles ); $table->addRow($line); } $table->display(); - $total = count_users(); - WP_CLI::line( 'Total: ' . $total['total_users'] . ' users' ); + WP_CLI::line( 'Total: ' . count($users) . ' users' ); } /** @@ -46,12 +47,20 @@ public function all( $args, $assoc_args ) { * @param array $args * @param array $assoc_args **/ - public function users( $args, $assoc_args ) { + public function create( $args, $assoc_args ) { global $blog_id; + $user_login = $args[0]; + $user_email = $args[1]; + + if ( ! $user_login || ! $user_email ) { + WP_CLI::error("Login and email required (see 'wp user help')."); + } + $defaults = array( - 'count' => 100, 'role' => get_option('default_role'), + 'user_pass' => wp_generate_password(), + 'user_registered' => strftime( "%F %T", time() ), ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); @@ -63,29 +72,25 @@ public function users( $args, $assoc_args ) { exit; } - $user_count = count_users(); - - $total = $user_count['total_users']; - - $limit = $count + $total; - - 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 - ) ); + $user_id = wp_insert_user( array( + 'user_email' => $user_email, + 'user_login' => $user_login, + 'user_pass' => $user_pass, + 'user_registered' => $user_registered, + 'display_name' => $display_name, + 'role' => $role, + ) ); + + if ( is_wp_error($user_id) ) { + WP_CLI::error( $user_id->get_error_message() ); + } else { + if ( false === $role ) { + delete_user_option( $user_id, 'capabilities' ); + delete_user_option( $user_id, 'user_level' ); + } + } - if ( false === $role ) { - delete_user_option( $user_id, 'capabilities' ); - delete_user_option( $user_id, 'user_level' ); - } - } + WP_CLI::line( "Created user $user_id" ); } /** @@ -93,8 +98,8 @@ public function users( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( <<] +usage: wp user all + or: wp user create [--role=] EOB ); } From 0d6ba8f92c9d0cc6a04d8b7c0a5c0fc518ca541b Mon Sep 17 00:00:00 2001 From: John Gray Date: Tue, 7 Feb 2012 20:34:59 -0600 Subject: [PATCH 0217/4858] delete subcommand --- src/php/wp-cli/commands/internals/user.php | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 23fb0c0c4c..8bae0ab106 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -41,6 +41,33 @@ public function all( $args, $assoc_args ) { WP_CLI::line( 'Total: ' . count($users) . ' users' ); } + /** + * Delete a user + * + * @param array $args + * @param array $assoc_args + **/ + public function delete( $args, $assoc_args ) { + global $blog_id; + + $user_id = $args[0]; + + if ( ! is_numeric($user_id) ) { + WP_CLI::error("User ID required (see 'wp user help')"); + } + + $defaults = array( 'reassign' => NULL ); + + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + if ( wp_delete_user( $user_id, $reassign ) ) { + WP_CLI::line( "Deleted user $user_id" ); + } else { + WP_CLI::error( "Failed deleting user $user_id" ); + } + + } + /** * Create a user * From 54fa4888ae850309557fd37bacaac624205d5419 Mon Sep 17 00:00:00 2001 From: John Gray Date: Tue, 7 Feb 2012 20:56:17 -0600 Subject: [PATCH 0218/4858] update subcommand --- src/php/wp-cli/commands/internals/user.php | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 8bae0ab106..0d4c41ec17 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -120,6 +120,34 @@ public function create( $args, $assoc_args ) { WP_CLI::line( "Created user $user_id" ); } + /** + * Update a user + * + * @param array $args + * @param array $assoc_args + **/ + public function update( $args, $assoc_args ) { + $user_id = $args[0]; + + if ( ! is_numeric($user_id) ) { + WP_CLI::error( "User ID required (see 'wp user help')" ); + } + + if ( ! count($assoc_args) ) { + WP_CLI::error( "Need some fields to update" ); + } + + $params = array_merge( array('ID' => $user_id), $assoc_args ); + + $updated_id = wp_update_user( $params ); + + if ( is_wp_error($updated_id) ) { + WP_CLI::error( $updated_id->get_error_message() ); + } else { + WP_CLI::line( "Updated user $updated_id" ); + } + } + /** * Help function for this command */ @@ -127,6 +155,8 @@ public static function help() { WP_CLI::line( << [--role=] + or: wp user update [--field_name=] + or: wp user delete [--reassign=] EOB ); } From f94c2b17fc1d3bce76750e76523f97bb542fbccd Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 8 Feb 2012 07:31:28 +0200 Subject: [PATCH 0219/4858] fix indentation --- src/php/wp-cli/class-wp-cli-command.php | 30 ++++++++++++------------- src/php/wp-cli/class-wp-cli.php | 1 + 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index abbbc16166..1213df53fc 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -11,8 +11,8 @@ abstract class WP_CLI_Command { /** * Transfers the handling to the appropriate method - * - * @param array $args + * + * @param array $args * @param array $assoc_args */ public function __construct( $args, $assoc_args ) { @@ -23,7 +23,7 @@ public function __construct( $args, $assoc_args ) { if ( !method_exists( $this, $subcommand ) ) { // This if for reserved keywords in php (like list, isset) - $subcommand = '_'.$subcommand; + $subcommand = '_' . $subcommand; } if ( !method_exists( $this, $subcommand ) || isset( $assoc_args[ 'help' ] ) ) { @@ -31,18 +31,18 @@ public function __construct( $args, $assoc_args ) { } $this->$subcommand( $args, $assoc_args ); - } - - /** - * Get the list of subcommands for a class. - * - * @param string $class - * @return array The list of methods - */ - static function get_subcommands( $class ) { + } + + /** + * Get the list of subcommands for a class. + * + * @param string $class + * @return array The list of methods + */ + static function get_subcommands( $class ) { $reflection = new ReflectionClass( $class ); - $methods = array(); + $methods = array(); foreach ( $reflection->getMethods() as $method ) { if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() ) { @@ -54,8 +54,8 @@ static function get_subcommands( $class ) { $methods[] = $name; } - } + } return $methods; - } + } } diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index e75f6b86cc..710756b03a 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -6,6 +6,7 @@ * @package wp-cli */ class WP_CLI { + static $commands = array(); /** From e693da9ca5a4d323e558230aff6d260f5f21d1d8 Mon Sep 17 00:00:00 2001 From: John Gray Date: Wed, 8 Feb 2012 09:30:44 -0600 Subject: [PATCH 0220/4858] add --role option to user list --- src/php/wp-cli/commands/internals/user.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 0d4c41ec17..654337b456 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -18,8 +18,17 @@ class UserCommand extends WP_CLI_Command { public function all( $args, $assoc_args ) { global $blog_id; + $params = array( + 'blog_id' => $blog_id, + 'fields' => 'all_with_meta', + ); + + if ( array_key_exists('role', $assoc_args) ) { + $params['role'] = $assoc_args['role']; + } + $table = new \cli\Table(); - $users = get_users("blog_id=$blog_id&fields=all_with_meta"); + $users = get_users( $params ); $fields = array('ID', 'user_login', 'display_name', 'user_email', 'user_registered'); @@ -153,7 +162,7 @@ public function update( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( <<] or: wp user create [--role=] or: wp user update [--field_name=] or: wp user delete [--reassign=] From 41aa6d5eafd99388b6a44f4d18f3577711e07839 Mon Sep 17 00:00:00 2001 From: John Gray Date: Wed, 8 Feb 2012 09:31:30 -0600 Subject: [PATCH 0221/4858] change all to list --- src/php/wp-cli/commands/internals/user.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 654337b456..fc694d0f04 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -15,7 +15,7 @@ class UserCommand extends WP_CLI_Command { * @param array $args * @param array $assoc_args **/ - public function all( $args, $assoc_args ) { + public function _list( $args, $assoc_args ) { global $blog_id; $params = array( @@ -162,7 +162,7 @@ public function update( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( <<] +usage: wp user list [--role=] or: wp user create [--role=] or: wp user update [--field_name=] or: wp user delete [--reassign=] From 582d4e271da529534dcaf0fb67949a9e8b8d4125 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 8 Feb 2012 18:59:04 +0200 Subject: [PATCH 0222/4858] fix get_subcommands() --- src/php/wp-cli/class-wp-cli-command.php | 2 +- src/php/wp-cli/commands/internals/help.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index 1213df53fc..85202d36df 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -49,7 +49,7 @@ static function get_subcommands( $class ) { $name = $method->name; if ( strpos( $name, '_' ) === 0 ) { - $name = substr( $method, 1 ); + $name = substr( $name, 1 ); } $methods[] = $name; diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index cc237c7911..0a8dd0151d 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -50,7 +50,9 @@ private function general_help() { private function single_command_help( $name, $command ) { WP_CLI::out( ' wp ' . $name ); + $methods = WP_CLI_Command::get_subcommands( $command ); + if ( !empty( $methods ) ) { WP_CLI::out( ' [' . implode( '|', $methods ) . ']' ); } From 870f7c4b2192fc0063710a129924411dbf01f15a Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 15 Feb 2012 19:44:14 +0200 Subject: [PATCH 0223/4858] `wp download` -> `wp core download` see #62 --- src/php/wp-cli/wp-cli.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 5ba9ef2fae..bba3b8d979 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -39,11 +39,9 @@ define('WP_ROOT', $_SERVER['PWD'] . '/'); } -// Taken from https://github.com/88mph/wpadmin/blob/master/wpadmin.php if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { - // Download fresh copy of WordPress in the current dir - if ( isset( $arguments[0] ) && $arguments[0] == 'download' ) { - WP_CLI::line("Downloading WordPress..."); + if ( array( 'core', 'download' ) == $arguments ) { + WP_CLI::line('Downloading WordPress...'); exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); exec("unzip /tmp/wordpress.zip"); exec("mv wordpress/* ./"); @@ -51,7 +49,7 @@ WP_CLI::success('WordPress downloaded.'); exit; } else { - WP_CLI::error('This does not seem to be a WordPress install. Try running `wp download`.'); + WP_CLI::error('This does not seem to be a WordPress install. Try running `wp core download`.'); exit; } } From 8329ba8af5168c2b2350995dc2b3620981025f9f Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 16 Feb 2012 22:45:44 +0200 Subject: [PATCH 0224/4858] first pass at `wp core config`. see #65 --- src/php/wp-cli/wp-cli.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index bba3b8d979..b82ee39dc1 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -54,6 +54,18 @@ } } +if ( array( 'core', 'config' ) == $arguments ) { + $_POST['dbname'] = $assoc_args['name']; + $_POST['uname'] = $assoc_args['user']; + $_POST['pwd'] = $assoc_args['pass']; + $_POST['dbhost'] = isset( $assoc_args['host'] ) ? $assoc_args['host'] : 'localhost'; + $_POST['prefix'] = isset( $assoc_args['prefix'] ) ? $assoc_args['prefix'] : ''; + + $_GET['step'] = 2; + require WP_ROOT . '/wp-admin/setup-config.php'; + exit; +} + // Handle --blog parameter if ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; From f9fd476f816b44d40f7565eee39c495a8aee2e28 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 18 Feb 2012 17:46:54 +0200 Subject: [PATCH 0225/4858] add theme delete subcommand. fixes #70 --- src/php/wp-cli/commands/internals/theme.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index ee9d18d622..76be9b5338 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -121,6 +121,21 @@ function path( $args, $assoc_args ) { WP_CLI::line( $path ); } + /** + * Delete a theme + * + * @param array $args + */ + function delete( $args ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + $r = delete_theme( $name ); + + if ( is_wp_error( $r ) ) { + WP_CLI::error( $r ); + } + } + protected function parse_name( $args, $subcommand ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp theme $subcommand " ); @@ -155,6 +170,7 @@ public static function help() { status display status of all installed themes or of a particular theme activate activate a particular theme path print path to the theme's stylesheet + delete delete a theme EOB ); } From e523df3c737ab307bc3b528ac0a0c201c6d636cf Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 18 Feb 2012 18:25:44 +0200 Subject: [PATCH 0226/4858] mysqldump, not mydbdump --- src/php/wp-cli/commands/internals/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 01fb3028d3..162d5bc226 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -77,7 +77,7 @@ public static function help() { WP_CLI::line( << Date: Sat, 18 Feb 2012 21:51:23 +0200 Subject: [PATCH 0227/4858] check is_plugin_active() before calling delete_plugins() --- src/php/wp-cli/commands/internals/plugin.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 37f5dfea87..dcca8a2f12 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -276,6 +276,10 @@ function uninstall( $args ) { function delete( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + if ( is_plugin_active( $file ) ) { + WP_CLI::error( 'The plugin is active.' ); + } + if ( !delete_plugins( array( $file ) ) ) { WP_CLI::error( 'There was an error while deleting the plugin.' ); } From e2728327ff9e065f08cc94054f00534a6dae534c Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 18 Feb 2012 22:46:54 +0200 Subject: [PATCH 0228/4858] add progress bars for `generate` command --- src/php/wp-cli/commands/internals/generate.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 7f81894006..2f732507d4 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -39,13 +39,19 @@ public function posts( $args, $assoc_args ) { $limit = $count + $total; + $notify = new \cli\progress\Bar( 'Generating posts', $count ); + for ( $i = $total; $i < $limit; $i++ ) { wp_insert_post( array( 'post_type' => $type, 'post_title' => "$label $i", 'post_status' => $status ) ); + + $notify->tick(); } + + $notify->finish(); } /** @@ -77,6 +83,8 @@ public function users( $args, $assoc_args ) { $limit = $count + $total; + $notify = new \cli\progress\Bar( 'Generating users', $count ); + for ( $i = $total; $i < $limit; $i++ ) { $login = sprintf( 'user_%d_%d', $blog_id, $i ); $name = "User $i"; @@ -93,7 +101,11 @@ public function users( $args, $assoc_args ) { delete_user_option( $user_id, 'capabilities' ); delete_user_option( $user_id, 'user_level' ); } + + $notify->tick(); } + + $notify->finish(); } /** From be5016fffbb739a9b278a1f2f784b1074590ca26 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 18 Feb 2012 22:49:37 +0200 Subject: [PATCH 0229/4858] uppercase progress bar message --- src/php/wp-cli/commands/internals/export.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 7ecaa5d479..1794c94615 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -358,7 +358,7 @@ private function export_wp( $args = array() ) { WP_CLI::line( 'Exporting ' . count( $terms ) . ' terms' ); WP_CLI::line(); - $progress = $this->progress_bar( 'exporting', count( $post_ids ) ); + $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); ob_start(); echo '\n"; @@ -508,12 +508,5 @@ private function export_wp( $args = array() ) { file_put_contents( $full_path, $result ); } } - - /** - * Implement progress bar - */ - private function progress_bar( $title, $total, $interval = 100 ) { - return new \cli\progress\Bar( $title, $total, $interval ); - } - } + From b099b2fb8ffc003e0aa3e483c9ed254de4642cc3 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 18 Feb 2012 23:05:24 +0200 Subject: [PATCH 0230/4858] call $progress->finish(); --- src/php/wp-cli/commands/internals/export.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 1794c94615..07b3114642 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -499,6 +499,8 @@ private function export_wp( $args = array() ) { finish(); + $result = ob_get_clean(); $full_path = $this->wxr_path . $file_name_base . '.wxr'; From 71465de750fe26c6e29dba803403de8769ff0b31 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 18 Feb 2012 23:07:25 +0200 Subject: [PATCH 0231/4858] processs -> process... --- src/php/wp-cli/commands/internals/export.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 07b3114642..62967b5866 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -34,18 +34,9 @@ public static function help() { ); } - private function dispatch() { - WP_CLI::line(); - WP_CLI::line( 'Starting export processs' ); - WP_CLI::line(); - $this->export_wp( $this->export_args ); - } - - /** * Argument validation functions below */ - public function validate_arguments( $args, $assoc_args ) { $defaults = array( 'path' => NULL, @@ -77,7 +68,9 @@ public function validate_arguments( $args, $assoc_args ) { $this->wxr_path = $assoc_args['path']; - $this->dispatch(); + WP_CLI::line( 'Starting export process...' ); + WP_CLI::line(); + $this->export_wp( $this->export_args ); } private function check_path( $path ) { From dc78b9f88ab7bcfd344b23865459ece794160969 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 19 Feb 2012 17:04:26 +0200 Subject: [PATCH 0232/4858] remove redundant text in `wp core version` --- src/php/wp-cli/commands/internals/core.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index f40a4c3188..651c4c47a5 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -30,10 +30,9 @@ public function version( $args = array(), $assoc_args = array() ) { break; } } - WP_CLI::line( "WordPress version:\t$version_text" ); - if ( isset( $assoc_args['extra'] ) ) { - WP_CLI::line(); + WP_CLI::line( "WordPress version:\t$version_text" ); + WP_CLI::line( "Database revision:\t$wp_db_version" ); preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); @@ -41,6 +40,8 @@ public function version( $args = array(), $assoc_args = array() ) { WP_CLI::line( "TinyMCE version:\t" . ( $human_readable_tiny_mce? "$human_readable_tiny_mce ($tinymce_version)" : $tinymce_version ) ); WP_CLI::line( "Manifest revision:\t$manifest_version" ); + } else { + WP_CLI::line( $version_text ); } } From 2d304217308bcb34c0e8bd0dc3a12db700ec325d Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 19 Feb 2012 21:40:18 +0200 Subject: [PATCH 0233/4858] user.php: indentation --- src/php/wp-cli/commands/internals/user.php | 208 ++++++++++----------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index fc694d0f04..562059cca9 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -9,73 +9,73 @@ * @subpackage commands/internals */ class UserCommand extends WP_CLI_Command { - /** - * List users - * - * @param array $args - * @param array $assoc_args - **/ - public function _list( $args, $assoc_args ) { - global $blog_id; - $params = array( - 'blog_id' => $blog_id, - 'fields' => 'all_with_meta', - ); + /** + * List users + * + * @param array $args + * @param array $assoc_args + **/ + public function _list( $args, $assoc_args ) { + global $blog_id; - if ( array_key_exists('role', $assoc_args) ) { - $params['role'] = $assoc_args['role']; - } + $params = array( + 'blog_id' => $blog_id, + 'fields' => 'all_with_meta', + ); - $table = new \cli\Table(); - $users = get_users( $params ); - $fields = array('ID', 'user_login', 'display_name', 'user_email', - 'user_registered'); + if ( array_key_exists('role', $assoc_args) ) { + $params['role'] = $assoc_args['role']; + } - $table->setHeaders( array_merge($fields, array('roles')) ); + $table = new \cli\Table(); + $users = get_users( $params ); + $fields = array('ID', 'user_login', 'display_name', 'user_email', + 'user_registered'); - foreach ( $users as $user ) { - $line = array(); + $table->setHeaders( array_merge($fields, array('roles')) ); - foreach ( $fields as $field ) { - $line[] = $user->$field; - } - $line[] = implode( ',', $user->roles ); + foreach ( $users as $user ) { + $line = array(); - $table->addRow($line); - } + foreach ( $fields as $field ) { + $line[] = $user->$field; + } + $line[] = implode( ',', $user->roles ); - $table->display(); + $table->addRow($line); + } - WP_CLI::line( 'Total: ' . count($users) . ' users' ); - } + $table->display(); - /** - * Delete a user - * - * @param array $args - * @param array $assoc_args - **/ - public function delete( $args, $assoc_args ) { - global $blog_id; + WP_CLI::line( 'Total: ' . count($users) . ' users' ); + } - $user_id = $args[0]; + /** + * Delete a user + * + * @param array $args + * @param array $assoc_args + **/ + public function delete( $args, $assoc_args ) { + global $blog_id; - if ( ! is_numeric($user_id) ) { - WP_CLI::error("User ID required (see 'wp user help')"); - } + $user_id = $args[0]; - $defaults = array( 'reassign' => NULL ); + if ( ! is_numeric($user_id) ) { + WP_CLI::error("User ID required (see 'wp user help')"); + } - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + $defaults = array( 'reassign' => NULL ); - if ( wp_delete_user( $user_id, $reassign ) ) { - WP_CLI::line( "Deleted user $user_id" ); - } else { - WP_CLI::error( "Failed deleting user $user_id" ); - } + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - } + if ( wp_delete_user( $user_id, $reassign ) ) { + WP_CLI::line( "Deleted user $user_id" ); + } else { + WP_CLI::error( "Failed deleting user $user_id" ); + } + } /** * Create a user @@ -86,17 +86,17 @@ public function delete( $args, $assoc_args ) { public function create( $args, $assoc_args ) { global $blog_id; - $user_login = $args[0]; - $user_email = $args[1]; + $user_login = $args[0]; + $user_email = $args[1]; - if ( ! $user_login || ! $user_email ) { - WP_CLI::error("Login and email required (see 'wp user help')."); - } + if ( ! $user_login || ! $user_email ) { + WP_CLI::error("Login and email required (see 'wp user help')."); + } $defaults = array( 'role' => get_option('default_role'), - 'user_pass' => wp_generate_password(), - 'user_registered' => strftime( "%F %T", time() ), + 'user_pass' => wp_generate_password(), + 'user_registered' => strftime( "%F %T", time() ), ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); @@ -108,54 +108,54 @@ public function create( $args, $assoc_args ) { exit; } - $user_id = wp_insert_user( array( - 'user_email' => $user_email, - 'user_login' => $user_login, - 'user_pass' => $user_pass, - 'user_registered' => $user_registered, - 'display_name' => $display_name, - 'role' => $role, - ) ); - - if ( is_wp_error($user_id) ) { - WP_CLI::error( $user_id->get_error_message() ); - } else { - if ( false === $role ) { - delete_user_option( $user_id, 'capabilities' ); - delete_user_option( $user_id, 'user_level' ); - } - } - - WP_CLI::line( "Created user $user_id" ); + $user_id = wp_insert_user( array( + 'user_email' => $user_email, + 'user_login' => $user_login, + 'user_pass' => $user_pass, + 'user_registered' => $user_registered, + 'display_name' => $display_name, + 'role' => $role, + ) ); + + if ( is_wp_error($user_id) ) { + WP_CLI::error( $user_id->get_error_message() ); + } else { + if ( false === $role ) { + delete_user_option( $user_id, 'capabilities' ); + delete_user_option( $user_id, 'user_level' ); + } + } + + WP_CLI::line( "Created user $user_id" ); } - /** - * Update a user - * - * @param array $args - * @param array $assoc_args - **/ - public function update( $args, $assoc_args ) { - $user_id = $args[0]; - - if ( ! is_numeric($user_id) ) { - WP_CLI::error( "User ID required (see 'wp user help')" ); - } - - if ( ! count($assoc_args) ) { - WP_CLI::error( "Need some fields to update" ); - } - - $params = array_merge( array('ID' => $user_id), $assoc_args ); - - $updated_id = wp_update_user( $params ); - - if ( is_wp_error($updated_id) ) { - WP_CLI::error( $updated_id->get_error_message() ); - } else { - WP_CLI::line( "Updated user $updated_id" ); - } - } + /** + * Update a user + * + * @param array $args + * @param array $assoc_args + **/ + public function update( $args, $assoc_args ) { + $user_id = $args[0]; + + if ( ! is_numeric($user_id) ) { + WP_CLI::error( "User ID required (see 'wp user help')" ); + } + + if ( ! count($assoc_args) ) { + WP_CLI::error( "Need some fields to update" ); + } + + $params = array_merge( array('ID' => $user_id), $assoc_args ); + + $updated_id = wp_update_user( $params ); + + if ( is_wp_error($updated_id) ) { + WP_CLI::error( $updated_id->get_error_message() ); + } else { + WP_CLI::line( "Updated user $updated_id" ); + } + } /** * Help function for this command From 180014c43903bb40c2bf69d48b3f7b2122252d56 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 19 Feb 2012 21:42:12 +0200 Subject: [PATCH 0234/4858] user.php: prevent notice when --display_name is not passed --- src/php/wp-cli/commands/internals/user.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 562059cca9..9ff4f1b1e4 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -97,6 +97,7 @@ public function create( $args, $assoc_args ) { 'role' => get_option('default_role'), 'user_pass' => wp_generate_password(), 'user_registered' => strftime( "%F %T", time() ), + 'display_name' => false, ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); From 005e7cbe2f7a09fa99d923b87649e6e2f259b0a8 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 19 Feb 2012 21:46:35 +0200 Subject: [PATCH 0235/4858] user.php: pass whole error object to WP_CLI::error --- src/php/wp-cli/commands/internals/user.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 9ff4f1b1e4..1d415c8c76 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -119,7 +119,7 @@ public function create( $args, $assoc_args ) { ) ); if ( is_wp_error($user_id) ) { - WP_CLI::error( $user_id->get_error_message() ); + WP_CLI::error( $user_id ); } else { if ( false === $role ) { delete_user_option( $user_id, 'capabilities' ); @@ -152,7 +152,7 @@ public function update( $args, $assoc_args ) { $updated_id = wp_update_user( $params ); if ( is_wp_error($updated_id) ) { - WP_CLI::error( $updated_id->get_error_message() ); + WP_CLI::error( $updated_id ); } else { WP_CLI::line( "Updated user $updated_id" ); } From 92b3be4ff84da2ab4c6c6877171ec9576e8b5386 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 19 Feb 2012 22:03:19 +0200 Subject: [PATCH 0236/4858] user.php: Use success() instead of line() and error() instead of warning() --- src/php/wp-cli/commands/internals/user.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 1d415c8c76..ea6bbf9484 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -71,7 +71,7 @@ public function delete( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); if ( wp_delete_user( $user_id, $reassign ) ) { - WP_CLI::line( "Deleted user $user_id" ); + WP_CLI::success( "Deleted user $user_id" ); } else { WP_CLI::error( "Failed deleting user $user_id" ); } @@ -105,8 +105,7 @@ public function create( $args, $assoc_args ) { if ( 'none' == $role ) { $role = false; } elseif ( is_null( get_role( $role ) ) ) { - WP_CLI::warning( "invalid role." ); - exit; + WP_CLI::error( "Invalid role." ); } $user_id = wp_insert_user( array( @@ -127,7 +126,7 @@ public function create( $args, $assoc_args ) { } } - WP_CLI::line( "Created user $user_id" ); + WP_CLI::success( "Created user $user_id" ); } /** @@ -154,7 +153,7 @@ public function update( $args, $assoc_args ) { if ( is_wp_error($updated_id) ) { WP_CLI::error( $updated_id ); } else { - WP_CLI::line( "Updated user $updated_id" ); + WP_CLI::success( "Updated user $updated_id" ); } } From 0eb538a48618a07bc1a55dc9e5a9c9ffd78cfb61 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 19 Feb 2012 22:07:12 +0200 Subject: [PATCH 0237/4858] user.php: dots --- src/php/wp-cli/commands/internals/user.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index ea6bbf9484..f5bb9846ec 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -71,9 +71,9 @@ public function delete( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); if ( wp_delete_user( $user_id, $reassign ) ) { - WP_CLI::success( "Deleted user $user_id" ); + WP_CLI::success( "Deleted user $user_id." ); } else { - WP_CLI::error( "Failed deleting user $user_id" ); + WP_CLI::error( "Failed deleting user $user_id." ); } } @@ -126,7 +126,7 @@ public function create( $args, $assoc_args ) { } } - WP_CLI::success( "Created user $user_id" ); + WP_CLI::success( "Created user $user_id." ); } /** @@ -139,21 +139,21 @@ public function update( $args, $assoc_args ) { $user_id = $args[0]; if ( ! is_numeric($user_id) ) { - WP_CLI::error( "User ID required (see 'wp user help')" ); + WP_CLI::error( "User ID required (see 'wp user help')." ); } - if ( ! count($assoc_args) ) { - WP_CLI::error( "Need some fields to update" ); + if ( empty( $assoc_args ) ) { + WP_CLI::error( "Need some fields to update." ); } - $params = array_merge( array('ID' => $user_id), $assoc_args ); + $params = array_merge( array( 'ID' => $user_id ), $assoc_args ); $updated_id = wp_update_user( $params ); - if ( is_wp_error($updated_id) ) { + if ( is_wp_error( $updated_id ) ) { WP_CLI::error( $updated_id ); } else { - WP_CLI::success( "Updated user $updated_id" ); + WP_CLI::success( "Updated user $updated_id." ); } } From aacdb13ca8b3f42e97e56f52a74c59530bcf6912 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 21 Feb 2012 16:07:33 +0200 Subject: [PATCH 0238/4858] handle options with % in them. fixes #71 --- src/php/wp-cli/commands/internals/option.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 26be3b1cc1..bb223dc7b8 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -86,9 +86,9 @@ public function get( $args ) { return; if ( is_array( $value ) || is_object( $value ) ) { - WP_CLI::line( var_export( $value ) ); + echo var_export( $value ) . "\n"; } else { - WP_CLI::line( $value ); + echo $value . "\n"; } } From ad1c72bd081fe3b7d8fd9fbaa97ca5663ada30be Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 23 Feb 2012 17:59:22 +0200 Subject: [PATCH 0239/4858] add --author param to wp generate posts. fixes #74 --- src/php/wp-cli/commands/internals/generate.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 2f732507d4..02f8485405 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -22,7 +22,8 @@ public function posts( $args, $assoc_args ) { $defaults = array( 'count' => 100, 'type' => 'post', - 'status' => 'publish' + 'status' => 'publish', + 'author' => false ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); @@ -32,6 +33,13 @@ public function posts( $args, $assoc_args ) { exit; } + if ( $author ) { + $author = get_user_by( 'login', $author ); + + if ( $author ) + $author = $author->ID; + } + // Get the total number of posts $total = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = %s", $type ) ); @@ -45,7 +53,8 @@ public function posts( $args, $assoc_args ) { wp_insert_post( array( 'post_type' => $type, 'post_title' => "$label $i", - 'post_status' => $status + 'post_status' => $status, + 'post_author' => $author ) ); $notify->tick(); @@ -113,7 +122,7 @@ public function users( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( <<] or: wp generate users [--count=100] [--role=] EOB ); From 80337a4f605cc8dd68c0c9722d2a1e8d0486e26e Mon Sep 17 00:00:00 2001 From: Chris Svajlenka Date: Wed, 29 Feb 2012 15:30:19 -0800 Subject: [PATCH 0240/4858] Added db import [--file] to import database files, as query will not run a file of queries. --- src/php/wp-cli/commands/internals/db.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 162d5bc226..6ae6686982 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -70,6 +70,21 @@ function query( $args, $assoc_args ) { WP_CLI::line( $result ); } + function import( $args, $assoc_args ) { + if ( !isset( $assoc_args['file'] ) ) { + $result_file = sprintf( '%s.sql', DB_NAME ); + } else { + $result_file = $assoc_args['file']; + } + + $exec = sprintf( 'mysql %s --user=%s --password=%s --host=%s < %s', + DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); + + exec( $exec ); + + WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); + } + /** * Help function for this command */ @@ -79,6 +94,7 @@ public static function help() { wp db connect Print a string for connecting to the database. wp db dump Exports the WordPress database using mysqldump. wp db query Execute a query against the WordPress database. +wp db import Import a database dumped via mysqldump. EOB ); } From 2908029eaa2748a7c5a33346c8d8196627daf880 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 1 Mar 2012 02:58:20 +0200 Subject: [PATCH 0241/4858] wp db dump -> wp db export. see #75 --- src/php/wp-cli/class-wp-cli-command.php | 5 +++++ src/php/wp-cli/commands/internals/db.php | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index 85202d36df..c21846b728 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -9,6 +9,8 @@ abstract class WP_CLI_Command { protected $default_subcommand = 'help'; + protected $aliases = array(); + /** * Transfers the handling to the appropriate method * @@ -21,6 +23,9 @@ public function __construct( $args, $assoc_args ) { else $subcommand = array_shift( $args ); + if ( isset( $this->aliases[ $subcommand ] ) ) + $subcommand = $this->aliases[ $subcommand ]; + if ( !method_exists( $this, $subcommand ) ) { // This if for reserved keywords in php (like list, isset) $subcommand = '_' . $subcommand; diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 6ae6686982..de88a992a8 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -12,6 +12,8 @@ class DBCommand extends WP_CLI_Command { protected $default_subcommand = 'cli'; + protected $aliases = array( 'dump' => 'export' ); + /** * Return a string for connecting to the DB. */ @@ -37,7 +39,7 @@ function cli() { /** * Exports the WordPress DB as SQL using mysqldump. */ - function dump( $args, $assoc_args ) { + function export( $args, $assoc_args ) { if ( !isset( $assoc_args['file'] ) ) { $result_file = sprintf( '%s.sql', DB_NAME ); } else { @@ -92,9 +94,9 @@ public static function help() { WP_CLI::line( << Date: Thu, 1 Mar 2012 09:21:49 +0100 Subject: [PATCH 0242/4858] Replaced the use of echo in the option command with WP_CLI::line --- src/php/wp-cli/commands/internals/option.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index bb223dc7b8..842c99a1ae 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -86,9 +86,9 @@ public function get( $args ) { return; if ( is_array( $value ) || is_object( $value ) ) { - echo var_export( $value ) . "\n"; + WP_CLI::line( var_export( $value, true ) ); } else { - echo $value . "\n"; + WP_CLI::line( $value ); } } @@ -102,6 +102,6 @@ public static function help() { or: wp option update or: wp option delete EOB - ); + ); } -} +} \ No newline at end of file From bd5ceb532708d8eaba23d8f977269519b81baecd Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 1 Mar 2012 09:23:03 +0100 Subject: [PATCH 0243/4858] Added --silent flag, see #63 --- src/php/wp-cli/class-wp-cli.php | 4 ++++ src/php/wp-cli/wp-cli.php | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 710756b03a..ae36ec8f62 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -25,6 +25,7 @@ public function addCommand( $name, $class ) { * @param string $message */ static function out( $message ) { + if ( WP_CLI_SILENT ) return; \cli\out($message); } @@ -34,6 +35,7 @@ static function out( $message ) { * @param string $message */ static function line( $message = '' ) { + if ( WP_CLI_SILENT ) return; \cli\line($message); } @@ -55,6 +57,7 @@ static function error( $message, $label = 'Error' ) { * @param string $label */ static function success( $message, $label = 'Success' ) { + if ( WP_CLI_SILENT ) return; \cli\line( '%G' . $label . ': %n' . $message ); } @@ -65,6 +68,7 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { + if ( WP_CLI_SILENT ) return; \cli\line( '%C' . $label . ': %n' . $message ); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index b82ee39dc1..f69163942c 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -81,6 +81,13 @@ WP_CLI::set_url( $blog ); } +// Implement --silent flag +if ( isset( $assoc_args['silent'] ) ) { + define('WP_CLI_SILENT', true); +} else { + define('WP_CLI_SILENT', false); +} + // Set installer flag before loading any WP files if ( count( $arguments ) >= 2 && $arguments[0] == 'core' && $arguments[1] == 'install' ) { define( 'WP_INSTALLING', true ); From 35270db9dd7a685eac549ca36c1b6efd2d8b4511 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 1 Mar 2012 10:03:09 +0100 Subject: [PATCH 0244/4858] Revert of echo replaced by WP_CLI::line in option command --- src/php/wp-cli/commands/internals/option.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 842c99a1ae..f8ad70e7e2 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -86,9 +86,9 @@ public function get( $args ) { return; if ( is_array( $value ) || is_object( $value ) ) { - WP_CLI::line( var_export( $value, true ) ); + echo var_export( $value ) . "\n"; } else { - WP_CLI::line( $value ); + echo $value . "\n"; } } From 8924c97ce92c256a0723fe59249d5ce35f4376c2 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 1 Mar 2012 10:10:47 +0100 Subject: [PATCH 0245/4858] Added --url global parameter, see #69 --- src/php/wp-cli/class-wp-cli.php | 18 ++++++++++-------- src/php/wp-cli/wp-cli.php | 12 ++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index ae36ec8f62..c77ab67aeb 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -154,14 +154,16 @@ static function legend( $legend ) { * @param string $url The URL */ static function set_url( $url ) { - if ( false === strpos( $url, '/' ) ) - $url .= '/'; - - list( $domain, $path ) = explode( '/', $url, 2 ); - - $_SERVER['HTTP_HOST'] = $domain; - - $_SERVER['REQUEST_URI'] = '/' . $path; + $url_parts = parse_url( $url ); + + if ( !isset( $url_parts['scheme'] ) ) { + $url_parts = parse_url( 'http://' . $url ); + } + + $_SERVER['HTTP_HOST'] = $url_parts['host']; + $_SERVER['REQUEST_URI'] = $url_parts['path'] . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); + $_SERVER['REQUEST_URL'] = $url_parts['path']; + $_SERVER['QUERY_STRING'] = $url_parts['query']; } /** diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index f69163942c..363ccc2609 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -66,6 +66,10 @@ exit; } +if ( isset( $assoc_args['url'] ) ) { + WP_CLI::set_url( $assoc_args['url'] ); +} + // Handle --blog parameter if ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; @@ -97,6 +101,14 @@ require_once(WP_ROOT . 'wp-load.php'); require_once(ABSPATH . 'wp-admin/includes/admin.php'); +// Load the right info into the global wp_query +if ( isset( $assoc_args['url'] ) ) { + if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { + $GLOBALS['wp']->parse_request(); + $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); + } +} + // Load all internal commands foreach ( glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename ) { include $filename; From 1f568eb9660245b633f66d0c46ffb9c1554c504a Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 1 Mar 2012 10:12:46 +0100 Subject: [PATCH 0246/4858] --url now supersedes --blog --- src/php/wp-cli/wp-cli.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 363ccc2609..76daa0bdc6 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -66,12 +66,10 @@ exit; } +// Handle --url and --blog parameters if ( isset( $assoc_args['url'] ) ) { - WP_CLI::set_url( $assoc_args['url'] ); -} - -// Handle --blog parameter -if ( isset( $assoc_args['blog'] ) ) { + $blog = $assoc_args['url']; +} elseif ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; unset( $assoc_args['blog'] ); if ( true === $blog ) { From 6c59680634c69b2bce471f70a0e6abf921b19fa4 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Thu, 1 Mar 2012 10:35:37 +0100 Subject: [PATCH 0247/4858] Auto-discovery for the current blog, see #42 --- src/php/wp-cli/wp-cli.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 76daa0bdc6..d6035675a6 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -79,6 +79,26 @@ $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); } +// Try to find the blog parameter in the wp-config file +if ( !isset( $blog ) ) { + if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { + $wp_config_file = file_get_contents( WP_ROOT . '/wp-config.php' ); + $hit = array(); + if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { + foreach( $matches[2] as $def_key => $def_name ) { + if ( 'DOMAIN_CURRENT_SITE' == $def_name ) + $hit['domain'] = $matches[5][$def_key]; + if ( 'PATH_CURRENT_SITE' == $def_name ) + $hit['path'] = $matches[5][$def_key]; + } + } + if ( !empty( $hit ) && isset( $hit['domain'] ) ) + $blog = $hit['domain']; + if ( !empty( $hit ) && isset( $hit['path'] ) ) + $blog .= $hit['path']; + } +} + if ( isset( $blog ) ) { WP_CLI::set_url( $blog ); } From 70bb55465ff1199b037107006523e0c78c50faea Mon Sep 17 00:00:00 2001 From: "John P. Bloch" Date: Thu, 1 Mar 2012 14:20:12 -0500 Subject: [PATCH 0248/4858] Add checks to see if WP_CLI_SILENT is defined before using it as if it were. --- src/php/wp-cli/class-wp-cli.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index c77ab67aeb..bd694b9a0f 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -25,7 +25,7 @@ public function addCommand( $name, $class ) { * @param string $message */ static function out( $message ) { - if ( WP_CLI_SILENT ) return; + if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; \cli\out($message); } @@ -35,7 +35,7 @@ static function out( $message ) { * @param string $message */ static function line( $message = '' ) { - if ( WP_CLI_SILENT ) return; + if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; \cli\line($message); } @@ -57,7 +57,7 @@ static function error( $message, $label = 'Error' ) { * @param string $label */ static function success( $message, $label = 'Success' ) { - if ( WP_CLI_SILENT ) return; + if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; \cli\line( '%G' . $label . ': %n' . $message ); } @@ -68,7 +68,7 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { - if ( WP_CLI_SILENT ) return; + if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; \cli\line( '%C' . $label . ': %n' . $message ); } From 89e05995d6ab624538da5175541c08606d4cfbdc Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 2 Mar 2012 14:46:44 +0200 Subject: [PATCH 0249/4858] bump version to 0.5.0-dev --- src/php/wp-cli/wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index d6035675a6..369a62ecd2 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,7 +4,7 @@ die( 'Only cli access' ); } -define( 'WP_CLI_VERSION', '0.4.0' ); +define( 'WP_CLI_VERSION', '0.5.0-dev' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); @@ -88,7 +88,7 @@ foreach( $matches[2] as $def_key => $def_name ) { if ( 'DOMAIN_CURRENT_SITE' == $def_name ) $hit['domain'] = $matches[5][$def_key]; - if ( 'PATH_CURRENT_SITE' == $def_name ) + if ( 'PATH_CURRENT_SITE' == $def_name ) $hit['path'] = $matches[5][$def_key]; } } From a2caf35787a3f9320432799d7b973661ad8b33d2 Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Fri, 2 Mar 2012 14:52:33 +0100 Subject: [PATCH 0250/4858] Fix for warnings caused by implementation of #69 --- src/php/wp-cli/class-wp-cli.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index bd694b9a0f..7a8d4b0848 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -160,10 +160,10 @@ static function set_url( $url ) { $url_parts = parse_url( 'http://' . $url ); } - $_SERVER['HTTP_HOST'] = $url_parts['host']; - $_SERVER['REQUEST_URI'] = $url_parts['path'] . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); - $_SERVER['REQUEST_URL'] = $url_parts['path']; - $_SERVER['QUERY_STRING'] = $url_parts['query']; + $_SERVER['HTTP_HOST'] = isset($url_parts['host']) ? $url_parts['host'] : ''; + $_SERVER['REQUEST_URI'] = (isset($url_parts['path']) ? $url_parts['path'] : '') . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); + $_SERVER['REQUEST_URL'] = isset($url_parts['path']) ? $url_parts['path'] : ''; + $_SERVER['QUERY_STRING'] = isset($url_parts['query']) ? $url_parts['query'] : ''; } /** From 443ec9c72d557f26fabea45323bec6282fb50b43 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 10 Mar 2012 16:04:59 +0200 Subject: [PATCH 0251/4858] only ignore files generated by build-pear --- .gitignore | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index e89c07b326..d9cdde38e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,2 @@ -.build -dist -.tmp -nbproject -review -vendor +/.build +/dist From 8a6960ca4c75cef3ce48587113c0e38b3f85cc63 Mon Sep 17 00:00:00 2001 From: Mike O'Malley Date: Sat, 10 Mar 2012 02:13:49 -0500 Subject: [PATCH 0252/4858] Add script to allow for non-root installation. sourcing build-local will set up your environment to run wp-cli, including support for bash completion without the need to run as root and modify /etc/bash_completion.d/ --- utils/build-local | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 utils/build-local diff --git a/utils/build-local b/utils/build-local new file mode 100755 index 0000000000..1adabb76fd --- /dev/null +++ b/utils/build-local @@ -0,0 +1,17 @@ +#!/bin/bash + +if [ "$BASH_SOURCE" = "$0" ]; then + echo "This file should not be executed. It should be sourced into your current shell like this:" + echo + echo "source $BASH_SOURCE" + echo + echo "Add the above line to your .bashrc or .bash_profile to have this environment set up" + echo "automatically when you log in." + exit 1 +fi + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +alias wp='$DIR/../src/bin/wp' + +. $DIR/wp-completion.bash From 298eb69ed1ef2a3dbac2a5a32b9579da6b82785a Mon Sep 17 00:00:00 2001 From: Mike O'Malley Date: Sat, 10 Mar 2012 02:17:49 -0500 Subject: [PATCH 0253/4858] set default table_prefix to "wp_" --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 369a62ecd2..11808c8917 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -59,7 +59,7 @@ $_POST['uname'] = $assoc_args['user']; $_POST['pwd'] = $assoc_args['pass']; $_POST['dbhost'] = isset( $assoc_args['host'] ) ? $assoc_args['host'] : 'localhost'; - $_POST['prefix'] = isset( $assoc_args['prefix'] ) ? $assoc_args['prefix'] : ''; + $_POST['prefix'] = isset( $assoc_args['prefix'] ) ? $assoc_args['prefix'] : 'wp_'; $_GET['step'] = 2; require WP_ROOT . '/wp-admin/setup-config.php'; From 8851d476d8a31a7a398cca0059d5ee8ae499c110 Mon Sep 17 00:00:00 2001 From: Mike O'Malley Date: Sat, 10 Mar 2012 02:18:24 -0500 Subject: [PATCH 0254/4858] Add support for --wproot It is no longer required to run wp from inside of the wordpress root directory. --- src/php/wp-cli/wp-cli.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 11808c8917..3428184227 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -34,8 +34,10 @@ // Define the WordPress location if ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { define('WP_ROOT', $_SERVER['PWD'] . '/../'); -} -else { +} elseif (isset($assoc_args['wproot'])) { + $root = (preg_match('@/$@', $assoc_args['wproot'])) ? $assoc_args['wproot'] : $assoc_args['wproot'] . "/"; + define('WP_ROOT', $root); +} else { define('WP_ROOT', $_SERVER['PWD'] . '/'); } From 4d1c7244e63d625191b4cda16019c9951ce3dd68 Mon Sep 17 00:00:00 2001 From: Mike O'Malley Date: Sat, 10 Mar 2012 02:23:20 -0500 Subject: [PATCH 0255/4858] change error to include new --wproot flag --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3428184227..bf8e9ffe88 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -51,7 +51,7 @@ WP_CLI::success('WordPress downloaded.'); exit; } else { - WP_CLI::error('This does not seem to be a WordPress install. Try running `wp core download`.'); + WP_CLI::error('This does not seem to be a WordPress install. Pass --wproot=`path/to/wordpress` or run `wp core download`.'); exit; } } From e0eed0d986bb0279011dab8bfcd1c1a03e77222a Mon Sep 17 00:00:00 2001 From: Mike O'Malley Date: Sat, 10 Mar 2012 02:23:49 -0500 Subject: [PATCH 0256/4858] add --path flag to allow wordpress installation somewhere other than ./ --- src/php/wp-cli/wp-cli.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index bf8e9ffe88..e4f97a25d7 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -43,10 +43,12 @@ if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { if ( array( 'core', 'download' ) == $arguments ) { + if (isset($assoc_args['path'])) $docroot = $assoc_args['path']; + else $docroot = './' WP_CLI::line('Downloading WordPress...'); exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); exec("unzip /tmp/wordpress.zip"); - exec("mv wordpress/* ./"); + exec("mv wordpress/* $docroot"); exec("rm -r wordpress"); WP_CLI::success('WordPress downloaded.'); exit; From 84c90cdd556b44fa8c957d2055db476de096a997 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 10 Mar 2012 16:12:23 +0200 Subject: [PATCH 0257/4858] rename --wproot to --path. see #80 --- src/php/wp-cli/wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index e4f97a25d7..09c3a9876e 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -34,8 +34,8 @@ // Define the WordPress location if ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { define('WP_ROOT', $_SERVER['PWD'] . '/../'); -} elseif (isset($assoc_args['wproot'])) { - $root = (preg_match('@/$@', $assoc_args['wproot'])) ? $assoc_args['wproot'] : $assoc_args['wproot'] . "/"; +} elseif (isset($assoc_args['path'])) { + $root = (preg_match('@/$@', $assoc_args['path'])) ? $assoc_args['path'] : $assoc_args['path'] . "/"; define('WP_ROOT', $root); } else { define('WP_ROOT', $_SERVER['PWD'] . '/'); @@ -53,7 +53,7 @@ WP_CLI::success('WordPress downloaded.'); exit; } else { - WP_CLI::error('This does not seem to be a WordPress install. Pass --wproot=`path/to/wordpress` or run `wp core download`.'); + WP_CLI::error('This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.'); exit; } } From 404362b1e1b790a2c08adaa937c042fc91023754 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Fri, 9 Mar 2012 17:02:46 -0800 Subject: [PATCH 0258/4858] Adds plugin update_all to internal commands --- src/php/wp-cli/class-cli-upgrader-skin.php | 2 + src/php/wp-cli/commands/internals/plugin.php | 44 ++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index d59958c6b1..98eb1d2752 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -9,6 +9,8 @@ class CLI_Upgrader_Skin extends WP_Upgrader_Skin { function header() {} function footer() {} + function bulk_header() {} + function bulk_footer() {} // TODO: show prompt function request_filesystem_credentials( $error = false ) { diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index dcca8a2f12..021cc24c5e 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -253,6 +253,48 @@ function update( $args ) { $result = $upgrader->upgrade( $file ); } + /** + * Update all plugins + * + * @param array $args + */ + function update_all( $args ) { + // Force WordPress to update plugin status transients + wp_update_plugins(); + $plugins = get_plugins(); + $plugins = array_merge( $plugins, get_mu_plugins() ); + + // Grab all Plugins that need Updates + $plugins_to_update = array(); + foreach ( $plugins as $file => $plugin ) { + if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { + $plugins_to_update[] = $file; + } + } + + if ( empty( $plugins_to_update ) ) { + WP_CLI::warning( 'Nothing to Update!' ); + return; + } + + // Update ALL THE THINGS + $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); + $result = $upgrader->bulk_upgrade( $plugins_to_update ); + + // Let the user know the results. + $num_to_update = count( $plugins_to_update ); + $num_updated = count( array_filter( $result ) ); + + $line = "Updated $num_updated/$num_to_update Plugins."; + if ( $num_to_update == $num_updated ) { + WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + WP_CLI::warning( $line ); + } else { + WP_CLI::error( $line ); + } + } + /** * Uninstall a plugin * @@ -362,6 +404,8 @@ public static function help() { update update a plugin from wordpress.org + update_all update all plugins from wordpress.org + uninstall run the uninstallation procedure for a plugin delete delete a plugin From 79a84852e403a15c86144cd76a6ca5d5d7a83378 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Sat, 10 Mar 2012 16:27:02 -0800 Subject: [PATCH 0259/4858] Move update_all into update with --all * Update all plugins with wp plugin update --all * List plugins with available updates with wp plugin update --- src/php/wp-cli/commands/internals/plugin.php | 72 ++++++++++++-------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 021cc24c5e..aa9f946f0f 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -242,56 +242,71 @@ function install( $args, $assoc_args ) { * Update a plugin * * @param array $args + * @param array $assoc_args */ - function update( $args ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - + function update( $args, $assoc_args ) { // Force WordPress to update the plugin list wp_update_plugins(); - $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); - $result = $upgrader->upgrade( $file ); - } + // If we have arguments and not updating all, update named plugin + if ( ! empty( $args ) && ! isset( $assoc_args['all'] ) ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - /** - * Update all plugins - * - * @param array $args - */ - function update_all( $args ) { - // Force WordPress to update plugin status transients - wp_update_plugins(); + $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); + $result = $upgrader->upgrade( $file ); + return; + } + + // If not, fall through and load plugin info. $plugins = get_plugins(); $plugins = array_merge( $plugins, get_mu_plugins() ); // Grab all Plugins that need Updates + // If we have no sub-arguments, add them to the output list. + $plugin_list = "Plugin Updates Available:"; $plugins_to_update = array(); foreach ( $plugins as $file => $plugin ) { if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { $plugins_to_update[] = $file; + + if ( empty( $assoc_args ) ) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace('.php', '', basename($file)); + else + $name = dirname($file); + + $plugin_list .= "\n\t%y$name%n"; + } } } if ( empty( $plugins_to_update ) ) { - WP_CLI::warning( 'Nothing to Update!' ); + WP_CLI::warning( 'No Plugin Updates Available.' ); return; } - // Update ALL THE THINGS - $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); - $result = $upgrader->bulk_upgrade( $plugins_to_update ); + // If --all, UPDATE ALL THE THINGS + if ( isset( $assoc_args['all'] ) ) + { + $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); + $result = $upgrader->bulk_upgrade( $plugins_to_update ); - // Let the user know the results. - $num_to_update = count( $plugins_to_update ); - $num_updated = count( array_filter( $result ) ); + // Let the user know the results. + $num_to_update = count( $plugins_to_update ); + $num_updated = count( array_filter( $result ) ); - $line = "Updated $num_updated/$num_to_update Plugins."; - if ( $num_to_update == $num_updated ) { - WP_CLI::success( $line ); - } else if ( $num_updated > 0 ) { - WP_CLI::warning( $line ); + $line = "Updated $num_updated/$num_to_update Plugins."; + if ( $num_to_update == $num_updated ) { + WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + WP_CLI::warning( $line ); + } else { + WP_CLI::error( $line ); + } + + // Else list plugins that require updates } else { - WP_CLI::error( $line ); + WP_CLI::line( $plugin_list ); } } @@ -403,8 +418,7 @@ public static function help() { --dev install the development version update update a plugin from wordpress.org - - update_all update all plugins from wordpress.org + --all update all plugins from wordpress.org uninstall run the uninstallation procedure for a plugin From b8421104efd4bbff24ade96c78c12783e6b74fef Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 14:37:45 +0200 Subject: [PATCH 0260/4858] force direct filesystem access. fixes #79 --- src/php/wp-cli/class-cli-upgrader-skin.php | 5 ----- src/php/wp-cli/wp-cli.php | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index 98eb1d2752..a6d748490a 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -12,11 +12,6 @@ function footer() {} function bulk_header() {} function bulk_footer() {} - // TODO: show prompt - function request_filesystem_credentials( $error = false ) { - $this->error( $error ); - } - function error( $error ) { if ( !$error ) return; diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 09c3a9876e..9900762e34 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -131,6 +131,9 @@ } } +// Set filesystem method +add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); + // Load all internal commands foreach ( glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename ) { include $filename; From 74810c2a0c094fb4862453fbdd8db6515c76df99 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 16:32:31 +0200 Subject: [PATCH 0261/4858] add missing semicolon --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 9900762e34..412c2a4bf9 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -44,7 +44,7 @@ if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { if ( array( 'core', 'download' ) == $arguments ) { if (isset($assoc_args['path'])) $docroot = $assoc_args['path']; - else $docroot = './' + else $docroot = './'; WP_CLI::line('Downloading WordPress...'); exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); exec("unzip /tmp/wordpress.zip"); From 7991478b2c847963b83bba2445f28eb49a5450ad Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 16:33:21 +0200 Subject: [PATCH 0262/4858] use require() when possible --- src/php/wp-cli/wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 412c2a4bf9..23b6eb9e4e 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -119,9 +119,9 @@ define( 'WP_INSTALLING', true ); } -// Load WordPress libs -require_once(WP_ROOT . 'wp-load.php'); -require_once(ABSPATH . 'wp-admin/includes/admin.php'); +// Load WordPress +require WP_ROOT . 'wp-load.php'; +require ABSPATH . 'wp-admin/includes/admin.php'; // Load the right info into the global wp_query if ( isset( $assoc_args['url'] ) ) { From 218b0eb50f6bbb5eef79f260852c8eee55b1fb43 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 16:39:22 +0200 Subject: [PATCH 0263/4858] rename set_url() to set_url_params() --- src/php/wp-cli/class-wp-cli.php | 2 +- src/php/wp-cli/commands/internals/core.php | 2 +- src/php/wp-cli/wp-cli.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 7a8d4b0848..4aa6bae2a1 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -153,7 +153,7 @@ static function legend( $legend ) { * * @param string $url The URL */ - static function set_url( $url ) { + static function set_url_params( $url ) { $url_parts = parse_url( $url ); if ( !isset( $url_parts['scheme'] ) ) { diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 651c4c47a5..afa6f07f96 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -104,7 +104,7 @@ public function install( $args, $assoc_args ) { } if ( $site_url ) - WP_CLI::set_url( $site_url ); + WP_CLI::set_url_params( $site_url ); if ( $missing ) exit(1); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 23b6eb9e4e..7e4ba3bb55 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -104,7 +104,7 @@ } if ( isset( $blog ) ) { - WP_CLI::set_url( $blog ); + WP_CLI::set_url_params( $blog ); } // Implement --silent flag From fef1b1e1a55ffcf565682796901eca719206b462 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 16:43:38 +0200 Subject: [PATCH 0264/4858] move URL seeking code to WP_CLI::_set_url() --- src/php/wp-cli/class-wp-cli.php | 45 +++++++++++++++++++++++++++++++-- src/php/wp-cli/wp-cli.php | 36 +------------------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 4aa6bae2a1..8310a80436 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -155,11 +155,11 @@ static function legend( $legend ) { */ static function set_url_params( $url ) { $url_parts = parse_url( $url ); - + if ( !isset( $url_parts['scheme'] ) ) { $url_parts = parse_url( 'http://' . $url ); } - + $_SERVER['HTTP_HOST'] = isset($url_parts['host']) ? $url_parts['host'] : ''; $_SERVER['REQUEST_URI'] = (isset($url_parts['path']) ? $url_parts['path'] : '') . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); $_SERVER['REQUEST_URL'] = isset($url_parts['path']) ? $url_parts['path'] : ''; @@ -191,5 +191,46 @@ static function get_upgrader( $class ) { return new $class( new CLI_Upgrader_Skin ); } + + /** + * Set url based on --url, --blog or wp-config.php + */ + static function _set_url() { + if ( isset( $assoc_args['url'] ) ) { + $blog = $assoc_args['url']; + } elseif ( isset( $assoc_args['blog'] ) ) { + $blog = $assoc_args['blog']; + unset( $assoc_args['blog'] ); + if ( true === $blog ) { + WP_CLI::line( 'usage: wp --blog=example.com' ); + } + } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { + $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); + } + + // Try to find the blog parameter in the wp-config file + if ( !isset( $blog ) ) { + if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { + $wp_config_file = file_get_contents( WP_ROOT . '/wp-config.php' ); + $hit = array(); + if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { + foreach( $matches[2] as $def_key => $def_name ) { + if ( 'DOMAIN_CURRENT_SITE' == $def_name ) + $hit['domain'] = $matches[5][$def_key]; + if ( 'PATH_CURRENT_SITE' == $def_name ) + $hit['path'] = $matches[5][$def_key]; + } + } + if ( !empty( $hit ) && isset( $hit['domain'] ) ) + $blog = $hit['domain']; + if ( !empty( $hit ) && isset( $hit['path'] ) ) + $blog .= $hit['path']; + } + } + + if ( isset( $blog ) ) { + WP_CLI::set_url_params( $blog ); + } + } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 7e4ba3bb55..e272c903bf 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -71,41 +71,7 @@ } // Handle --url and --blog parameters -if ( isset( $assoc_args['url'] ) ) { - $blog = $assoc_args['url']; -} elseif ( isset( $assoc_args['blog'] ) ) { - $blog = $assoc_args['blog']; - unset( $assoc_args['blog'] ); - if ( true === $blog ) { - WP_CLI::line( 'usage: wp --blog=example.com' ); - } -} elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { - $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); -} - -// Try to find the blog parameter in the wp-config file -if ( !isset( $blog ) ) { - if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { - $wp_config_file = file_get_contents( WP_ROOT . '/wp-config.php' ); - $hit = array(); - if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { - foreach( $matches[2] as $def_key => $def_name ) { - if ( 'DOMAIN_CURRENT_SITE' == $def_name ) - $hit['domain'] = $matches[5][$def_key]; - if ( 'PATH_CURRENT_SITE' == $def_name ) - $hit['path'] = $matches[5][$def_key]; - } - } - if ( !empty( $hit ) && isset( $hit['domain'] ) ) - $blog = $hit['domain']; - if ( !empty( $hit ) && isset( $hit['path'] ) ) - $blog .= $hit['path']; - } -} - -if ( isset( $blog ) ) { - WP_CLI::set_url_params( $blog ); -} +WP_CLI::_set_url(); // Implement --silent flag if ( isset( $assoc_args['silent'] ) ) { From cd1204f6a263523046636dfc4ff2b28bca65b971 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 16:46:03 +0200 Subject: [PATCH 0265/4858] WP_CLI_SILENT is always defined --- src/php/wp-cli/class-wp-cli.php | 8 ++++---- src/php/wp-cli/wp-cli.php | 6 +----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8310a80436..6ba659d791 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -25,7 +25,7 @@ public function addCommand( $name, $class ) { * @param string $message */ static function out( $message ) { - if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; + if ( WP_CLI_SILENT ) return; \cli\out($message); } @@ -35,7 +35,7 @@ static function out( $message ) { * @param string $message */ static function line( $message = '' ) { - if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; + if ( WP_CLI_SILENT ) return; \cli\line($message); } @@ -57,7 +57,7 @@ static function error( $message, $label = 'Error' ) { * @param string $label */ static function success( $message, $label = 'Success' ) { - if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; + if ( WP_CLI_SILENT ) return; \cli\line( '%G' . $label . ': %n' . $message ); } @@ -68,7 +68,7 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { - if ( defined( 'WP_CLI_SILENT' ) && WP_CLI_SILENT ) return; + if ( WP_CLI_SILENT ) return; \cli\line( '%C' . $label . ': %n' . $message ); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index e272c903bf..0ba5b669df 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -74,11 +74,7 @@ WP_CLI::_set_url(); // Implement --silent flag -if ( isset( $assoc_args['silent'] ) ) { - define('WP_CLI_SILENT', true); -} else { - define('WP_CLI_SILENT', false); -} +define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); // Set installer flag before loading any WP files if ( count( $arguments ) >= 2 && $arguments[0] == 'core' && $arguments[1] == 'install' ) { From bd9bef64dc7e5d2d03687fcbdc31c889c57ac2e5 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 17:14:05 +0200 Subject: [PATCH 0266/4858] move core download and core config to core.php --- src/php/wp-cli/commands/internals/core.php | 122 +++++++++++++-------- src/php/wp-cli/wp-cli.php | 26 ++--- 2 files changed, 85 insertions(+), 63 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index afa6f07f96..5084738772 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -10,6 +10,83 @@ */ class CoreCommand extends WP_CLI_Command { + /** + * Download the core files from wordpress.org + */ + public function download( $args, $assoc_args ) { + if ( is_readable( WP_ROOT . 'wp-load.php' ) ) + WP_CLI::error( 'WordPress files seem to already be present here.' ); + + if (isset($assoc_args['path'])) + $docroot = $assoc_args['path']; + else + $docroot = './'; + + WP_CLI::line('Downloading WordPress...'); + exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); + exec("unzip /tmp/wordpress.zip"); + exec("mv wordpress/* $docroot"); + exec("rm -r wordpress"); + WP_CLI::success('WordPress downloaded.'); + } + + /** + * Set up a wp-config.php file. + */ + public function config( $args, $assoc_args ) { + $_POST['dbname'] = $assoc_args['name']; + $_POST['uname'] = $assoc_args['user']; + $_POST['pwd'] = $assoc_args['pass']; + $_POST['dbhost'] = isset( $assoc_args['host'] ) ? $assoc_args['host'] : 'localhost'; + $_POST['prefix'] = isset( $assoc_args['prefix'] ) ? $assoc_args['prefix'] : 'wp_'; + + $_GET['step'] = 2; + require WP_ROOT . '/wp-admin/setup-config.php'; + } + + /** + * Run wp_install. Assumes that wp-config.php is already in place. + */ + public function install( $args, $assoc_args ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + if ( is_blog_installed() ) { + WP_CLI::error( 'WordPress is already installed.' ); + } + + extract( wp_parse_args( $assoc_args, array( + 'site_url' => defined( 'WP_SITEURL' ) ? WP_SITEURL : '', + 'site_title' => '', + 'admin_name' => 'admin', + 'admin_email' => '', + 'admin_password' => '' + ) ), EXTR_SKIP ); + + $missing = false; + foreach ( array( 'site_url', 'site_title', 'admin_email', 'admin_password' ) as $required_arg ) { + if ( empty( $$required_arg ) ) { + WP_CLI::warning( "missing --$required_arg parameter" ); + $missing = true; + } + } + + if ( $site_url ) + WP_CLI::set_url_params( $site_url ); + + if ( $missing ) + exit(1); + + $public = true; + + $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); + + if ( is_wp_error( $result ) ) { + WP_CLI::error( 'Installation failed (' . WP_CLI::errorToString($result) . ').' ); + } else { + WP_CLI::success( 'WordPress installed successfully.' ); + } + } + /** * Display the WordPress version. */ @@ -50,7 +127,7 @@ public function version( $args = array(), $assoc_args = array() ) { * * @param array $args */ - function update($args) { + function update( $args ) { wp_version_check(); $from_api = get_site_transient( 'update_core' ); @@ -77,49 +154,6 @@ function update($args) { } } - /** - * Run wp_install. Assumes that wp-config.php is already in place. - */ - public function install( $args, $assoc_args ) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - - if ( is_blog_installed() ) { - WP_CLI::error( 'WordPress is already installed.' ); - } - - extract( wp_parse_args( $assoc_args, array( - 'site_url' => defined( 'WP_SITEURL' ) ? WP_SITEURL : '', - 'site_title' => '', - 'admin_name' => 'admin', - 'admin_email' => '', - 'admin_password' => '' - ) ), EXTR_SKIP ); - - $missing = false; - foreach ( array( 'site_url', 'site_title', 'admin_email', 'admin_password' ) as $required_arg ) { - if ( empty( $$required_arg ) ) { - WP_CLI::warning( "missing --$required_arg parameter" ); - $missing = true; - } - } - - if ( $site_url ) - WP_CLI::set_url_params( $site_url ); - - if ( $missing ) - exit(1); - - $public = true; - - $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); - - if ( is_wp_error( $result ) ) { - WP_CLI::error( 'Installation failed (' . WP_CLI::errorToString($result) . ').' ); - } else { - WP_CLI::success( 'WordPress installed successfully.' ); - } - } - /** * Help function for this command */ diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 0ba5b669df..d066b335ff 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -43,14 +43,8 @@ if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { if ( array( 'core', 'download' ) == $arguments ) { - if (isset($assoc_args['path'])) $docroot = $assoc_args['path']; - else $docroot = './'; - WP_CLI::line('Downloading WordPress...'); - exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); - exec("unzip /tmp/wordpress.zip"); - exec("mv wordpress/* $docroot"); - exec("rm -r wordpress"); - WP_CLI::success('WordPress downloaded.'); + include WP_CLI_ROOT.'/commands/internals/core.php'; + new WP_CLI::$commands['core']( $arguments, $assoc_args ); exit; } else { WP_CLI::error('This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.'); @@ -59,21 +53,15 @@ } if ( array( 'core', 'config' ) == $arguments ) { - $_POST['dbname'] = $assoc_args['name']; - $_POST['uname'] = $assoc_args['user']; - $_POST['pwd'] = $assoc_args['pass']; - $_POST['dbhost'] = isset( $assoc_args['host'] ) ? $assoc_args['host'] : 'localhost'; - $_POST['prefix'] = isset( $assoc_args['prefix'] ) ? $assoc_args['prefix'] : 'wp_'; - - $_GET['step'] = 2; - require WP_ROOT . '/wp-admin/setup-config.php'; + include WP_CLI_ROOT.'/commands/internals/core.php'; + new WP_CLI::$commands['core']( $arguments, $assoc_args ); exit; } // Handle --url and --blog parameters WP_CLI::_set_url(); -// Implement --silent flag +// Check --silent flag define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); // Set installer flag before loading any WP files @@ -98,10 +86,10 @@ // Load all internal commands foreach ( glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename ) { - include $filename; + include_once $filename; } -// Load all plugin commands +// Load all community commands foreach ( glob(WP_CLI_ROOT.'/commands/community/*.php') as $filename ) { include $filename; } From 37656a3031d565b47e0f39310ae81901341707fc Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 17:14:50 +0200 Subject: [PATCH 0267/4858] define WP_CLI_SILENT earlier --- src/php/wp-cli/wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index d066b335ff..a0edf8a111 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -25,6 +25,9 @@ // Get the cli arguments list( $arguments, $assoc_args ) = WP_CLI::parse_args( array_slice( $GLOBALS['argv'], 1 ) ); +// Check --silent flag +define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); + // Handle --version parameter if ( isset( $assoc_args['version'] ) ) { WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); @@ -61,9 +64,6 @@ // Handle --url and --blog parameters WP_CLI::_set_url(); -// Check --silent flag -define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); - // Set installer flag before loading any WP files if ( count( $arguments ) >= 2 && $arguments[0] == 'core' && $arguments[1] == 'install' ) { define( 'WP_INSTALLING', true ); From e9222d9c5be00b349cb3d61e6f61da82da3f3117 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 17:28:18 +0200 Subject: [PATCH 0268/4858] use rtrim() instead of preg_match(). see #80 --- src/php/wp-cli/wp-cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index a0edf8a111..8a2636960b 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -36,12 +36,12 @@ // Define the WordPress location if ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { - define('WP_ROOT', $_SERVER['PWD'] . '/../'); -} elseif (isset($assoc_args['path'])) { - $root = (preg_match('@/$@', $assoc_args['path'])) ? $assoc_args['path'] : $assoc_args['path'] . "/"; - define('WP_ROOT', $root); + define( 'WP_ROOT', $_SERVER['PWD'] . '/../' ); +} elseif ( !empty( $assoc_args['path'] ) ) { + // trailingslashit() isn't available yet + define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); } else { - define('WP_ROOT', $_SERVER['PWD'] . '/'); + define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); } if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { From 10bdee6409fc2aaa1633ac25bd7b01bd836a6398 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 17:35:53 +0200 Subject: [PATCH 0269/4858] add _run_core_command() helper --- src/php/wp-cli/class-wp-cli.php | 8 ++++++++ src/php/wp-cli/wp-cli.php | 8 ++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 6ba659d791..5c16813f6e 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -232,5 +232,13 @@ static function _set_url() { WP_CLI::set_url_params( $blog ); } } + + static function _run_core_command( $arguments, $assoc_args ) { + array_shift( $arguments ); + + include WP_CLI_ROOT.'/commands/internals/core.php'; + new WP_CLI::$commands['core']( $arguments, $assoc_args ); + exit; + } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 8a2636960b..5eb1d9c684 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -46,9 +46,7 @@ if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { if ( array( 'core', 'download' ) == $arguments ) { - include WP_CLI_ROOT.'/commands/internals/core.php'; - new WP_CLI::$commands['core']( $arguments, $assoc_args ); - exit; + WP_CLI::_run_core_command( $arguments, $assoc_args ); } else { WP_CLI::error('This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.'); exit; @@ -56,9 +54,7 @@ } if ( array( 'core', 'config' ) == $arguments ) { - include WP_CLI_ROOT.'/commands/internals/core.php'; - new WP_CLI::$commands['core']( $arguments, $assoc_args ); - exit; + WP_CLI::_run_core_command( $arguments, $assoc_args ); } // Handle --url and --blog parameters From 5634673d59927d7c2aa2cd1aa629d7af364229fc Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 12 Mar 2012 17:53:56 +0200 Subject: [PATCH 0270/4858] load all commands only when needed --- src/php/wp-cli/class-wp-cli.php | 41 +++++++++++++++++++++++++++++---- src/php/wp-cli/wp-cli.php | 37 ++++------------------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 5c16813f6e..13997d183d 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -233,11 +233,44 @@ static function _set_url() { } } - static function _run_core_command( $arguments, $assoc_args ) { - array_shift( $arguments ); + static function load_all_commands() { + foreach ( array( 'internals', 'community' ) as $dir ) { + foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { + include $filename; + } + } + } + + static function run_command( $arguments, $assoc_args ) { + if ( empty( $arguments ) ) { + WP_CLI::load_all_commands(); + $command = 'help'; + } else { + $command = array_shift( $arguments ); + + $aliases = array( + 'sql' => 'db' + ); + + if ( isset( $aliases[ $command ] ) ) + $command = $aliases[ $command ]; + + foreach ( array( 'internals', 'community' ) as $dir ) { + $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + + if ( is_readable( $path ) ) { + include $path; + break; + } + } + } + + if ( !isset( WP_CLI::$commands[$command] ) ) { + WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); + exit; + } - include WP_CLI_ROOT.'/commands/internals/core.php'; - new WP_CLI::$commands['core']( $arguments, $assoc_args ); + new WP_CLI::$commands[$command]( $arguments, $assoc_args ); exit; } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 5eb1d9c684..3824c92dd9 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -46,7 +46,7 @@ if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { if ( array( 'core', 'download' ) == $arguments ) { - WP_CLI::_run_core_command( $arguments, $assoc_args ); + WP_CLI::run_command( $arguments, $assoc_args ); } else { WP_CLI::error('This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.'); exit; @@ -54,7 +54,7 @@ } if ( array( 'core', 'config' ) == $arguments ) { - WP_CLI::_run_core_command( $arguments, $assoc_args ); + WP_CLI::run_command( $arguments, $assoc_args ); } // Handle --url and --blog parameters @@ -80,42 +80,15 @@ // Set filesystem method add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); -// Load all internal commands -foreach ( glob(WP_CLI_ROOT.'/commands/internals/*.php') as $filename ) { - include_once $filename; -} - -// Load all community commands -foreach ( glob(WP_CLI_ROOT.'/commands/community/*.php') as $filename ) { - include $filename; -} - // Handle --completions parameter if ( isset( $assoc_args['completions'] ) ) { + WP_CLI::load_all_commands(); + foreach ( WP_CLI::$commands as $name => $command ) { WP_CLI::line( $name . ' ' . implode( ' ', WP_CLI_Command::get_subcommands($command) ) ); } exit; } -// Get the top-level command -if ( empty( $arguments ) ) - $command = 'help'; -else - $command = array_shift( $arguments ); - -// Translate aliases -$aliases = array( - 'sql' => 'db' -); - -if ( isset( $aliases[ $command ] ) ) - $command = $aliases[ $command ]; - -if ( !isset( WP_CLI::$commands[$command] ) ) { - WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); - exit; -} - -new WP_CLI::$commands[$command]( $arguments, $assoc_args ); +WP_CLI::run_command( $arguments, $assoc_args ); From ccfb07a5a9b833a90cfa9ec17f7e7020ff201dbb Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 13 Mar 2012 16:33:06 +0200 Subject: [PATCH 0271/4858] always load all commands when 'help' is involved. fixes #84 --- src/php/wp-cli/class-wp-cli.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 13997d183d..ab6e99f527 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -243,7 +243,6 @@ static function load_all_commands() { static function run_command( $arguments, $assoc_args ) { if ( empty( $arguments ) ) { - WP_CLI::load_all_commands(); $command = 'help'; } else { $command = array_shift( $arguments ); @@ -254,7 +253,12 @@ static function run_command( $arguments, $assoc_args ) { if ( isset( $aliases[ $command ] ) ) $command = $aliases[ $command ]; + } + if ( 'help' == $command ) { + self::load_all_commands(); + } + else { foreach ( array( 'internals', 'community' ) as $dir ) { $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; From 12e0debc3467fcb5275234b4691473489d1644ca Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 13 Mar 2012 16:36:48 +0200 Subject: [PATCH 0272/4858] show error when wp help receives an invalid parameter --- src/php/wp-cli/commands/internals/help.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 0a8dd0151d..64f67f2bfe 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -20,7 +20,11 @@ public function __construct( $args ) { $this->general_help(); } else { $command = $args[0]; - if ( 'help' == $command || !isset( WP_CLI::$commands[$command] ) ) { + + if ( !isset( WP_CLI::$commands[$command] ) ) { + WP_CLI::error( "'$command' is not a registered wp command." ); + } elseif ( 'help' == $command ) { + // prevent endless loop $this->general_help(); } else { $class = WP_CLI::$commands[$command]; From f99868242a6526ff1003f4b18162483a8539fefd Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 13 Mar 2012 16:58:51 +0200 Subject: [PATCH 0273/4858] plugin update strings. #82 --- src/php/wp-cli/commands/internals/plugin.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index aa9f946f0f..8d04e5c442 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -263,7 +263,7 @@ function update( $args, $assoc_args ) { // Grab all Plugins that need Updates // If we have no sub-arguments, add them to the output list. - $plugin_list = "Plugin Updates Available:"; + $plugin_list = "Available plugin updates:"; $plugins_to_update = array(); foreach ( $plugins as $file => $plugin ) { if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { @@ -281,13 +281,12 @@ function update( $args, $assoc_args ) { } if ( empty( $plugins_to_update ) ) { - WP_CLI::warning( 'No Plugin Updates Available.' ); + WP_CLI::line( 'No plugin updates available.' ); return; } // If --all, UPDATE ALL THE THINGS - if ( isset( $assoc_args['all'] ) ) - { + if ( isset( $assoc_args['all'] ) ) { $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); $result = $upgrader->bulk_upgrade( $plugins_to_update ); From 9e8c7ba682480bdcf7c2f87a4ad7bd70fd14ca1f Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 13 Mar 2012 17:22:56 +0200 Subject: [PATCH 0274/4858] split plugin update() into update_single() and update_multiple() --- src/php/wp-cli/commands/internals/plugin.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 8d04e5c442..d7c391a1df 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -248,16 +248,20 @@ function update( $args, $assoc_args ) { // Force WordPress to update the plugin list wp_update_plugins(); - // If we have arguments and not updating all, update named plugin - if ( ! empty( $args ) && ! isset( $assoc_args['all'] ) ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - - $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); - $result = $upgrader->upgrade( $file ); - return; + if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { + $this->update_single( $args, $assoc_args ); + } else { + $this->update_multiple( $args, $assoc_args ); } + } + + private function update_single( $args, $assoc_args ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + WP_CLI::get_upgrader( 'Plugin_Upgrader' )->upgrade( $file ); + } - // If not, fall through and load plugin info. + private function update_multiple( $args, $assoc_args ) { $plugins = get_plugins(); $plugins = array_merge( $plugins, get_mu_plugins() ); From 97bba512595ccbbed05f9aae533ce2849aa6cfb0 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 13 Mar 2012 17:24:01 +0200 Subject: [PATCH 0275/4858] must-use plugin updates are not supported, so let's not load them at all --- src/php/wp-cli/commands/internals/plugin.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index d7c391a1df..a5b4d05a9c 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -263,7 +263,6 @@ private function update_single( $args, $assoc_args ) { private function update_multiple( $args, $assoc_args ) { $plugins = get_plugins(); - $plugins = array_merge( $plugins, get_mu_plugins() ); // Grab all Plugins that need Updates // If we have no sub-arguments, add them to the output list. From 02022f8c892b3135def683bd20e513d90a93afe4 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 13 Mar 2012 17:34:35 +0200 Subject: [PATCH 0276/4858] fix _set_url() --- src/php/wp-cli/class-wp-cli.php | 12 ++++-------- src/php/wp-cli/wp-cli.php | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index ab6e99f527..a4d447ace8 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -192,12 +192,10 @@ static function get_upgrader( $class ) { return new $class( new CLI_Upgrader_Skin ); } - /** - * Set url based on --url, --blog or wp-config.php - */ - static function _set_url() { + static function _set_url( &$assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $blog = $assoc_args['url']; + unset( $assoc_args['url'] ); } elseif ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; unset( $assoc_args['blog'] ); @@ -206,10 +204,8 @@ static function _set_url() { } } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); - } - - // Try to find the blog parameter in the wp-config file - if ( !isset( $blog ) ) { + } else { + // Try to find the blog parameter in the wp-config file if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { $wp_config_file = file_get_contents( WP_ROOT . '/wp-config.php' ); $hit = array(); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3824c92dd9..61bc0bc792 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -58,7 +58,7 @@ } // Handle --url and --blog parameters -WP_CLI::_set_url(); +WP_CLI::_set_url( $assoc_args ); // Set installer flag before loading any WP files if ( count( $arguments ) >= 2 && $arguments[0] == 'core' && $arguments[1] == 'install' ) { From 0158f1ab4b8c8f9275639f7777b8e138b9701826 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Thu, 15 Mar 2012 14:56:06 -0700 Subject: [PATCH 0277/4858] Add whitespace to theme help to allow subcommands, and add path --directory help. --- src/php/wp-cli/commands/internals/theme.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 76be9b5338..9babbb815d 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -168,8 +168,12 @@ public static function help() { Available sub-commands: status display status of all installed themes or of a particular theme + activate activate a particular theme + path print path to the theme's stylesheet + --directory get the path to the closest parent directory + delete delete a theme EOB ); From 799834e0b5746696daf452761d91626e1985bb4d Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Thu, 15 Mar 2012 15:00:11 -0700 Subject: [PATCH 0278/4858] Add theme update functionality to themes internal --- src/php/wp-cli/commands/internals/theme.php | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 9babbb815d..35263029fd 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -121,6 +121,77 @@ function path( $args, $assoc_args ) { WP_CLI::line( $path ); } + /** + * Update a theme + * + * @param array $args + * @param array $assoc_args + */ + function update( $args, $assoc_args ) { + // Force WordPress to update the theme list + wp_update_themes(); + + // If we have arguments and not updating all, update named theme + if ( ! empty( $args ) && ! isset( $assoc_args['all'] ) ) { + list( $theme, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + $upgrader = WP_CLI::get_upgrader( 'Theme_Upgrader' ); + $result = $upgrader->upgrade( $name ); + return; + } + + // If not, fall through and load theme info. + $themes = get_themes(); + + // Grab all Themes that need Updates + // If we have no sub-arguments, add them to the output list. + $theme_list = "Available theme updates:"; + $themes_to_update = array(); + foreach ( $themes as $theme ) { + $file = $theme['Stylesheet']; + if ( WP_CLI::get_update_status( $file, 'update_themes' ) ) { + $themes_to_update[] = $file; + + if ( empty( $assoc_args ) ) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace('.php', '', basename($file)); + else + $name = dirname($file); + + $theme_list .= "\n\t%y$name%n"; + } + } + } + + if ( empty( $themes_to_update ) ) { + WP_CLI::line( 'No theme updates available.' ); + return; + } + + // If --all, UPDATE ALL THE THINGS + if ( isset( $assoc_args['all'] ) ) { + $upgrader = WP_CLI::get_upgrader( 'Theme_Upgrader' ); + $result = $upgrader->bulk_upgrade( $themes_to_update ); + + // Let the user know the results. + $num_to_update = count( $themes_to_update ); + $num_updated = count( array_filter( $result ) ); + + $line = "Updated $num_updated/$num_to_update Themes."; + if ( $num_to_update == $num_updated ) { + WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + WP_CLI::warning( $line ); + } else { + WP_CLI::error( $line ); + } + + // Else list themes that require updates + } else { + WP_CLI::line( $theme_list ); + } + } + /** * Delete a theme * @@ -174,6 +245,9 @@ public static function help() { path print path to the theme's stylesheet --directory get the path to the closest parent directory + update update a theme from wordpress.org + --all update all themes from wordpress.org + delete delete a theme EOB ); From 7cf4678b27f26d080d134b56cfab003c966c0c72 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Thu, 15 Mar 2012 16:34:04 -0700 Subject: [PATCH 0279/4858] Split theme update into update_single() and update_multiple() to match plugin update. --- src/php/wp-cli/commands/internals/theme.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 35263029fd..677c75f311 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -131,16 +131,20 @@ function update( $args, $assoc_args ) { // Force WordPress to update the theme list wp_update_themes(); - // If we have arguments and not updating all, update named theme - if ( ! empty( $args ) && ! isset( $assoc_args['all'] ) ) { - list( $theme, $name ) = $this->parse_name( $args, __FUNCTION__ ); - - $upgrader = WP_CLI::get_upgrader( 'Theme_Upgrader' ); - $result = $upgrader->upgrade( $name ); - return; + if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { + $this->update_single( $args, $assoc_args ); + } else { + $this->update_multiple( $args, $assoc_args ); } + } + + private function update_single( $args, $assoc_args ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + WP_CLI::get_upgrader( 'Theme_Upgrader' )->upgrade( $name ); + } - // If not, fall through and load theme info. + private function update_multiple( $args, $assoc_args ) { $themes = get_themes(); // Grab all Themes that need Updates From 127d288020129ae7e1c8c81b91a257c6b8a206d7 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 16 Mar 2012 02:18:03 +0200 Subject: [PATCH 0280/4858] s/--directory/--dir/g --- src/php/wp-cli/commands/internals/plugin.php | 6 +++--- src/php/wp-cli/commands/internals/theme.php | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index a5b4d05a9c..d894c734b2 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -175,7 +175,7 @@ function path( $args, $assoc_args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $path .= '/' . $file; - if ( isset( $assoc_args['directory'] ) ) + if ( isset( $assoc_args['dir'] ) ) $path = dirname( $path ); } @@ -400,7 +400,7 @@ private function parse_name( $args, $subcommand ) { public static function help() { WP_CLI::line( << [] - or: wp plugin path [] [--directory] + or: wp plugin path [] [--dir] or: wp plugin install [--activate] [--dev] Available sub-commands: @@ -413,7 +413,7 @@ public static function help() { toggle toggle activation state of a particular plugin path print path to the plugin's file - --directory get the path to the closest parent directory + --dir get the path to the closest parent directory install install a plugin from wordpress.org --activate activate the plugin after installing it diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 677c75f311..7017eb5975 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -114,7 +114,7 @@ function path( $args, $assoc_args ) { list( $stylesheet, $name ) = $this->parse_name( $args, __FUNCTION__ ); $path = $stylesheet; - if ( isset( $assoc_args['directory'] ) ) + if ( isset( $assoc_args['dir'] ) ) $path = dirname( $path ); } @@ -239,7 +239,7 @@ protected function get_stylesheet_path( $theme ) { public static function help() { WP_CLI::line( << [] - or: wp theme path [] [--directory] + or: wp theme path [] [--dir] Available sub-commands: status display status of all installed themes or of a particular theme @@ -247,10 +247,10 @@ public static function help() { activate activate a particular theme path print path to the theme's stylesheet - --directory get the path to the closest parent directory + --dir get the path to the closest parent directory - update update a theme from wordpress.org - --all update all themes from wordpress.org + update update a theme from wordpress.org + --all update all themes from wordpress.org delete delete a theme EOB From 9cf1c8af7964d0df5a8f0810ffe98a756ff42666 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 16 Mar 2012 03:03:43 +0200 Subject: [PATCH 0281/4858] add unfortunately named WP_CLI_Command_With_Upgrade class and make plugin and theme commands inherit from it --- .../class-wp-cli-command-with-upgrade.php | 87 ++++++++++++++++++ src/php/wp-cli/class-wp-cli.php | 17 ---- src/php/wp-cli/commands/internals/core.php | 3 +- src/php/wp-cli/commands/internals/plugin.php | 87 +++--------------- src/php/wp-cli/commands/internals/theme.php | 88 +++---------------- src/php/wp-cli/wp-cli.php | 1 + 6 files changed, 109 insertions(+), 174 deletions(-) create mode 100644 src/php/wp-cli/class-wp-cli-command-with-upgrade.php diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php new file mode 100644 index 0000000000..03c1aef42d --- /dev/null +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -0,0 +1,87 @@ +upgrade_refresh ); + + if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + WP_CLI::get_upgrader( $this->upgrader )->upgrade( $name ); + } else { + $this->update_multiple( $args, $assoc_args ); + } + } + + private function update_multiple( $args, $assoc_args ) { + // Grab all items that need updates + // If we have no sub-arguments, add them to the output list. + $item_list = "Available {$this->item_type} updates:"; + $items_to_update = array(); + foreach ( $this->get_item_list() as $file ) { + if ( $this->get_update_status( $file ) ) { + $items_to_update[] = $file; + + if ( empty( $assoc_args ) ) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace('.php', '', basename($file)); + else + $name = dirname($file); + + $item_list .= "\n\t%y$name%n"; + } + } + } + + if ( empty( $items_to_update ) ) { + WP_CLI::line( "No {$this->item_type} updates available." ); + return; + } + + // If --all, UPDATE ALL THE THINGS + if ( isset( $assoc_args['all'] ) ) { + $upgrader = WP_CLI::get_upgrader( $this->upgrader ); + $result = $upgrader->bulk_upgrade( $items_to_update ); + + // Let the user know the results. + $num_to_update = count( $items_to_update ); + $num_updated = count( array_filter( $result ) ); + + $line = "Updated $num_updated/$num_to_update {$this->item_type}s."; + if ( $num_to_update == $num_updated ) { + WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + WP_CLI::warning( $line ); + } else { + WP_CLI::error( $line ); + } + + // Else list items that require updates + } else { + WP_CLI::line( $item_list ); + } + } + + /** + * Check wether an item has an update available or not. + * + * @param string $item The plugin/theme theme path + * + * @return bool + */ + protected function get_update_status( $file ) { + $update_list = get_site_transient( $this->upgrade_transient ); + + return isset( $update_list->response[ $file ] ); + } +} + diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index a4d447ace8..4613ae3b86 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -166,23 +166,6 @@ static function set_url_params( $url ) { $_SERVER['QUERY_STRING'] = isset($url_parts['query']) ? $url_parts['query'] : ''; } - /** - * Return the beginning of the status line for a certain plugin or theme - * - * @param string $item The plugin or theme name - * @param string $key The transient key - * - * @return string - */ - static function get_update_status( $item, $key ) { - $update_list = get_site_transient( $key ); - - if ( isset( $update_list->response[ $item ] ) ) - return true; - - return false; - } - static function get_upgrader( $class ) { if ( !class_exists( 'WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 5084738772..680d8d4279 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -139,8 +139,7 @@ function update( $args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - $upgrader = WP_CLI::get_upgrader( 'Core_Upgrader' ); - $result = $upgrader->upgrade( $update ); + $result = WP_CLI::get_upgrader( 'Core_Upgrader' )->upgrade( $update ); if ( is_wp_error($result) ) { $msg = WP_CLI::errorToString( $result ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index d894c734b2..115549870f 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -8,9 +8,12 @@ * @package wp-cli * @subpackage commands/internals */ -class PluginCommand extends WP_CLI_Command { +class PluginCommand extends WP_CLI_Command_With_Upgrade { - protected $default_subcommand = 'status'; + protected $item_type = 'plugin'; + protected $upgrader = 'Plugin_Upgrader'; + protected $upgrade_refresh = 'wp_update_plugins'; + protected $upgrade_transient = 'update_plugins'; private $mu_plugins; @@ -42,7 +45,7 @@ function status( $args = array(), $vars = array() ) { $version = $details[ 'Version' ]; - if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) + if ( $this->get_update_status( $file ) ) $version .= ' (%gUpdate available%n)'; WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); @@ -70,7 +73,7 @@ private function list_plugins() { else $name = dirname($file); - if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { + if ( $this->get_update_status( $file ) ) { $line = ' %yU%n'; } else { $line = ' '; @@ -238,78 +241,8 @@ function install( $args, $assoc_args ) { } } - /** - * Update a plugin - * - * @param array $args - * @param array $assoc_args - */ - function update( $args, $assoc_args ) { - // Force WordPress to update the plugin list - wp_update_plugins(); - - if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { - $this->update_single( $args, $assoc_args ); - } else { - $this->update_multiple( $args, $assoc_args ); - } - } - - private function update_single( $args, $assoc_args ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - - WP_CLI::get_upgrader( 'Plugin_Upgrader' )->upgrade( $file ); - } - - private function update_multiple( $args, $assoc_args ) { - $plugins = get_plugins(); - - // Grab all Plugins that need Updates - // If we have no sub-arguments, add them to the output list. - $plugin_list = "Available plugin updates:"; - $plugins_to_update = array(); - foreach ( $plugins as $file => $plugin ) { - if ( WP_CLI::get_update_status( $file, 'update_plugins' ) ) { - $plugins_to_update[] = $file; - - if ( empty( $assoc_args ) ) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace('.php', '', basename($file)); - else - $name = dirname($file); - - $plugin_list .= "\n\t%y$name%n"; - } - } - } - - if ( empty( $plugins_to_update ) ) { - WP_CLI::line( 'No plugin updates available.' ); - return; - } - - // If --all, UPDATE ALL THE THINGS - if ( isset( $assoc_args['all'] ) ) { - $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); - $result = $upgrader->bulk_upgrade( $plugins_to_update ); - - // Let the user know the results. - $num_to_update = count( $plugins_to_update ); - $num_updated = count( array_filter( $result ) ); - - $line = "Updated $num_updated/$num_to_update Plugins."; - if ( $num_to_update == $num_updated ) { - WP_CLI::success( $line ); - } else if ( $num_updated > 0 ) { - WP_CLI::warning( $line ); - } else { - WP_CLI::error( $line ); - } - - // Else list plugins that require updates - } else { - WP_CLI::line( $plugin_list ); - } + protected function get_item_list() { + return array_keys( get_plugins() ); } /** @@ -367,7 +300,7 @@ private function get_details( $file ) { * @param bool $exit * @return array */ - private function parse_name( $args, $subcommand ) { + protected function parse_name( $args, $subcommand ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp plugin $subcommand " ); exit; diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 7017eb5975..e8856ada3a 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -8,9 +8,12 @@ * @package wp-cli * @subpackage commands/internals */ -class ThemeCommand extends WP_CLI_Command { +class ThemeCommand extends WP_CLI_Command_With_Upgrade { - protected $default_subcommand = 'status'; + protected $item_type = 'theme'; + protected $upgrader = 'Theme_Upgrader'; + protected $upgrade_refresh = 'wp_update_themes'; + protected $upgrade_transient = 'update_themes'; /** * Get the status of one or all themes @@ -29,9 +32,9 @@ public function status( $args = array() ) { $status = $this->get_status( $details['Name'], true ); - $version = $details[ 'Version' ]; + $version = $details['Version']; - if ( WP_CLI::get_update_status( $name, 'update_themes' ) ) + if ( $this->get_update_status( $details['Stylesheet'] ) ) $version .= ' (%gUpdate available%n)'; WP_CLI::line( 'Theme %9' . $name . '%n details:' ); @@ -46,7 +49,7 @@ private function list_themes() { WP_CLI::line( 'Installed themes:' ); foreach ( get_themes() as $theme ) { - if ( WP_CLI::get_update_status( $theme['Stylesheet'], 'update_themes' ) ) { + if ( $this->get_update_status( $theme['Stylesheet'] ) ) { $line = ' %yU%n'; } else { $line = ' '; @@ -121,79 +124,8 @@ function path( $args, $assoc_args ) { WP_CLI::line( $path ); } - /** - * Update a theme - * - * @param array $args - * @param array $assoc_args - */ - function update( $args, $assoc_args ) { - // Force WordPress to update the theme list - wp_update_themes(); - - if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { - $this->update_single( $args, $assoc_args ); - } else { - $this->update_multiple( $args, $assoc_args ); - } - } - - private function update_single( $args, $assoc_args ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - - WP_CLI::get_upgrader( 'Theme_Upgrader' )->upgrade( $name ); - } - - private function update_multiple( $args, $assoc_args ) { - $themes = get_themes(); - - // Grab all Themes that need Updates - // If we have no sub-arguments, add them to the output list. - $theme_list = "Available theme updates:"; - $themes_to_update = array(); - foreach ( $themes as $theme ) { - $file = $theme['Stylesheet']; - if ( WP_CLI::get_update_status( $file, 'update_themes' ) ) { - $themes_to_update[] = $file; - - if ( empty( $assoc_args ) ) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace('.php', '', basename($file)); - else - $name = dirname($file); - - $theme_list .= "\n\t%y$name%n"; - } - } - } - - if ( empty( $themes_to_update ) ) { - WP_CLI::line( 'No theme updates available.' ); - return; - } - - // If --all, UPDATE ALL THE THINGS - if ( isset( $assoc_args['all'] ) ) { - $upgrader = WP_CLI::get_upgrader( 'Theme_Upgrader' ); - $result = $upgrader->bulk_upgrade( $themes_to_update ); - - // Let the user know the results. - $num_to_update = count( $themes_to_update ); - $num_updated = count( array_filter( $result ) ); - - $line = "Updated $num_updated/$num_to_update Themes."; - if ( $num_to_update == $num_updated ) { - WP_CLI::success( $line ); - } else if ( $num_updated > 0 ) { - WP_CLI::warning( $line ); - } else { - WP_CLI::error( $line ); - } - - // Else list themes that require updates - } else { - WP_CLI::line( $theme_list ); - } + protected function get_item_list() { + return wp_list_pluck( get_themes(), 'Stylesheet' ); } /** diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 61bc0bc792..7e08f72d4e 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -15,6 +15,7 @@ // Include the wp-cli classes include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; +include WP_CLI_ROOT . 'class-wp-cli-command-with-upgrade.php'; // Include the command line tools include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; From 455f55ddb0c9dccd59553a6a9162c0bf7bdcb617 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 16 Mar 2012 17:34:28 +0200 Subject: [PATCH 0282/4858] attempt to use /usr/local/bin in build-dev. fixes #87 --- utils/build-dev | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/utils/build-dev b/utils/build-dev index 6b5d96744c..ea70e6be63 100755 --- a/utils/build-dev +++ b/utils/build-dev @@ -1,6 +1,11 @@ #!/usr/bin/env bash -ln -sf $(pwd)/src/bin/wp /usr/bin/wp +for dir in /usr/bin /usr/local/bin; do + if [ -d $dir ]; then + ln -sf $(pwd)/src/bin/wp $dir/wp + break + fi +done for dir in /etc/bash_completion.d /usr/local/etc/bash_completion.d; do if [ -d $dir ]; then From b4c5b3381f814385e9d2eb5d5f9120d6a1db1937 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 18 Mar 2012 21:31:36 +0200 Subject: [PATCH 0283/4858] make --user a global parameter. fixes #81 --- src/php/wp-cli/commands/internals/export.php | 24 -------------------- src/php/wp-cli/wp-cli.php | 14 ++++++++++++ 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 62967b5866..d74ab2077a 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -20,7 +20,6 @@ public static function help() { Required parameters: --path Full Path to directory where WXR export files should be stored - --user Username/ID the import should run as Optional filters: --start_date Export only posts new than this date in format YYYY-MM-DD @@ -40,7 +39,6 @@ public static function help() { public function validate_arguments( $args, $assoc_args ) { $defaults = array( 'path' => NULL, - 'user' => NULL, 'start_date' => NULL, 'end_date' => NULL, 'post_type' => NULL, @@ -87,28 +85,6 @@ private function check_path( $path ) { return true; } - private function check_user( $user ) { - if ( empty( $user ) ) { - WP_CLI::warning( 'missing --user parameter' ); - return false; - } - - if ( is_numeric( $user ) ) { - $user_id = (int) $user; - } else { - $user_id = (int) username_exists( $user ); - } - if ( !$user_id || !wp_set_current_user( $user_id ) ) { - WP_CLI::error( sprintf( "Could not get a user_id for this user: %s", var_export( $user_id, true ) ) ); - exit; - } - - $current_user = wp_get_current_user(); - $this->user_id = (int) $user_id; - - return true; - } - private function check_start_date( $date ) { if ( is_null( $date ) ) return true; diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 7e08f72d4e..adb97c0beb 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -78,6 +78,20 @@ } } +// Set the user +if ( isset( $assoc_args['user'] ) ) { + $user = $assoc_args['user']; + if ( is_numeric( $user ) ) { + $user_id = (int) $user; + } else { + $user_id = (int) username_exists( $user ); + } + if ( !$user_id || !wp_set_current_user( $user_id ) ) { + WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); + } + unset( $user); +} + // Set filesystem method add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); From 1f88e39224dacb9dbc978a6714870c0e08b2aec2 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 18 Mar 2012 21:36:41 +0200 Subject: [PATCH 0284/4858] document global parameters --- src/php/wp-cli/commands/internals/help.php | 8 ++++++-- src/php/wp-cli/wp-cli.php | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 64f67f2bfe..0028f3cba6 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -40,16 +40,20 @@ public function __construct( $args ) { } private function general_help() { - WP_CLI::line('Example usage:'); + WP_CLI::line( 'Available commands:' ); foreach ( WP_CLI::$commands as $name => $command ) { if ( 'help' == $name ) continue; $this->single_command_help( $name, $command ); } - WP_CLI::line(' wp --version'); WP_CLI::line(); WP_CLI::line( "See 'wp help ' for more information on a specific command." ); + WP_CLI::line(); + WP_CLI::line( 'Global parameters:' ); + WP_CLI::line( ' --user= set the current user' ); + WP_CLI::line( ' --url= set the current URL' ); + WP_CLI::line( ' --version print wp-cli version' ); } private function single_command_help( $name, $command ) { diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index adb97c0beb..51a5b8f5aa 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -89,7 +89,7 @@ if ( !$user_id || !wp_set_current_user( $user_id ) ) { WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); } - unset( $user); + unset( $user ); } // Set filesystem method From 826b2a957bd01e4c87f8db9f75eee3502608ddaa Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Sat, 24 Mar 2012 11:56:42 +0100 Subject: [PATCH 0285/4858] Updated reference to the repo to link to the newly created organisation --- README.md | 10 +++++----- build.properties | 2 +- src/php/wp-cli/commands/internals/home.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d9fa906e5c..b3aae8f4ba 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ Installing ```sh pear config-set auto_discover 1 -sudo pear install andreascreten.github.com/wp-cli/wpcli +sudo pear install wp-cli.github.com/wp-cli/wpcli ``` **Via GIT:** ```sh -git clone --recurse-submodules git://github.com/andreascreten/wp-cli.git ~/git/wp-cli +git clone --recurse-submodules git://github.com/wp-cli/wp-cli.git ~/git/wp-cli cd ~/git/wp-cli sudo utils/build-dev ``` @@ -102,7 +102,7 @@ Adding commands --------------- Adding commands to wp-cli is very easy. You can even add them from within your own plugin. -You can find more information about adding commands in the [Commands Cookbook](https://github.com/andreascreten/wp-cli/wiki/Commands-Cookbook) on our Wiki. +You can find more information about adding commands in the [Commands Cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook) on our Wiki. **Please share the commands you make, issue a pull request to get them included in wp-cli by default.** @@ -141,5 +141,5 @@ Changelog Contributors ------------ -- [Contributor list](https://github.com/andreascreten/wp-cli/contributors) -- [Contributor impact](https://github.com/andreascreten/wp-cli/graphs/impact) +- [Contributor list](https://github.com/wp-cli/wp-cli/contributors) +- [Contributor impact](https://github.com/wp-cli/wp-cli/graphs/impact) diff --git a/build.properties b/build.properties index 27cb6bd81f..8ad6b59308 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,5 @@ project.name=wpcli -project.channel=andreascreten.github.com/wp-cli +project.channel=wp-cli.github.com/wp-cli project.majorVersion=0 project.minorVersion=4 project.patchLevel=0 diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index 4f3304fc59..a8fd6d6313 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -18,7 +18,7 @@ class HomeCommand extends WP_CLI_Command { */ public function __construct( $args, $assoc_args ) { // The url for the wp-cli repository - $repository_url = 'http://github.com/andreascreten/wp-cli'; + $repository_url = 'http://github.com/wp-cli/wp-cli'; // Open the wp-cli page in the browser if(exec('which x-www-browser')) { From ebf89e659c5d66f00536acbac0e70d80e919ea7c Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 27 Mar 2012 13:00:28 +0300 Subject: [PATCH 0286/4858] update PEAR channel URL --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 8ad6b59308..431558f758 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,5 @@ project.name=wpcli -project.channel=wp-cli.github.com/wp-cli +project.channel=wp-cli.github.com/pear project.majorVersion=0 project.minorVersion=4 project.patchLevel=0 From 844ee1320b537de6bb5d062f98adbacd5a7de041 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 27 Mar 2012 13:14:35 +0300 Subject: [PATCH 0287/4858] update channel URL in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3aae8f4ba..199a9d87fd 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Installing ```sh pear config-set auto_discover 1 -sudo pear install wp-cli.github.com/wp-cli/wpcli +sudo pear install wp-cli.github.com/pear/wpcli ``` **Via GIT:** From 40ef80762266a36ec0b983908696eb09d5fc224e Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 27 Mar 2012 13:20:58 +0300 Subject: [PATCH 0288/4858] document --path global param --- src/php/wp-cli/commands/internals/help.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 0028f3cba6..4d6e28f137 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -53,6 +53,7 @@ private function general_help() { WP_CLI::line( 'Global parameters:' ); WP_CLI::line( ' --user= set the current user' ); WP_CLI::line( ' --url= set the current URL' ); + WP_CLI::line( ' --path= set the current path to the WP install' ); WP_CLI::line( ' --version print wp-cli version' ); } From 202c1506d68067bb1ef12ca3c513598b51430037 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 27 Mar 2012 13:25:40 +0300 Subject: [PATCH 0289/4858] 0.5.0 changelog --- README.md | 11 +++++++++++ src/php/wp-cli/wp-cli.php | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 199a9d87fd..3e6a32ad38 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,17 @@ You can find more information about adding commands in the [Commands Cookbook](h Changelog --------------- +**0.5** + +- added `wp user` +- added `wp core download` +- added `wp core config` +- added `wp plugin update --all` +- added `wp theme update` +- added `wp db import` +- added `--url` `--path` and `--user` global parameters +- various bugfixes + **0.4** - added `wp eval` and `wp eval-file` diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 51a5b8f5aa..60400ab3da 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,7 +4,7 @@ die( 'Only cli access' ); } -define( 'WP_CLI_VERSION', '0.5.0-dev' ); +define( 'WP_CLI_VERSION', '0.5.0' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 95e4276050e414d788b37ef0fe6dbffc71b37640 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 27 Mar 2012 13:37:18 +0300 Subject: [PATCH 0290/4858] fix build-pear --- utils/build-pear | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/utils/build-pear b/utils/build-pear index 0d8e51c7d9..2172050ecd 100755 --- a/utils/build-pear +++ b/utils/build-pear @@ -11,12 +11,10 @@ version="${version/.tgz/}" #sudo phing install-system # update channel files -cd ../wp-cli-pages +cd ../wp-cli-pear pirum add . ../wp-cli/dist/wpcli-$version.tgz pirum build . -exit - # push changes git add -A git ci -m "release $version" From 532b35d3393a0c830a8ea301649d6cc43a0e46eb Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 27 Mar 2012 13:37:36 +0300 Subject: [PATCH 0291/4858] update pear package to 0.5.0 --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 431558f758..2a40f3cd4e 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.name=wpcli project.channel=wp-cli.github.com/pear project.majorVersion=0 -project.minorVersion=4 +project.minorVersion=5 project.patchLevel=0 project.snapshot=false From 0e6302c3a67645296449814714c7cf20034ef73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=20Burc=C4=83?= Date: Wed, 28 Mar 2012 16:32:04 +0300 Subject: [PATCH 0292/4858] remove redundant quotes --- utils/build-local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/build-local b/utils/build-local index 1adabb76fd..edf89736e7 100755 --- a/utils/build-local +++ b/utils/build-local @@ -10,7 +10,7 @@ if [ "$BASH_SOURCE" = "$0" ]; then exit 1 fi -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DIR=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) alias wp='$DIR/../src/bin/wp' From 72b13453b1f77cfe1f24c32a113e9d47ccd5f4c2 Mon Sep 17 00:00:00 2001 From: Soulou Date: Tue, 10 Apr 2012 00:34:08 +0200 Subject: [PATCH 0293/4858] Quote the arguments when executing 'wp db cli|export|import' --- src/php/wp-cli/commands/internals/db.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index de88a992a8..6137de9b63 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -18,7 +18,7 @@ class DBCommand extends WP_CLI_Command { * Return a string for connecting to the DB. */ protected function connect_string() { - return sprintf( 'mysql --host=%s --database=%s --user=%s --password=%s', + return sprintf( 'mysql --host="%s" --database="%s" --user="%s" --password="%s"', DB_HOST, DB_NAME, DB_USER, DB_PASSWORD ); } @@ -46,7 +46,7 @@ function export( $args, $assoc_args ) { $result_file = $assoc_args['file']; } - $exec = sprintf( 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', + $exec = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); exec( $exec ); @@ -79,7 +79,7 @@ function import( $args, $assoc_args ) { $result_file = $assoc_args['file']; } - $exec = sprintf( 'mysql %s --user=%s --password=%s --host=%s < %s', + $exec = sprintf( 'mysql "%s" --user="%s" --password="%s" --host="%s" < "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); exec( $exec ); From d3d314f2c4300080874b33638507d1e7af91468b Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 04:32:08 +0300 Subject: [PATCH 0294/4858] update wp db help text --- src/php/wp-cli/commands/internals/db.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 6137de9b63..187b5d9294 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -92,11 +92,18 @@ function import( $args, $assoc_args ) { */ public static function help() { WP_CLI::line( << [] + +Available sub-commands: + cli Open a SQL command-line interface using the WordPress credentials. + + connect Print a string for connecting to the database. + + export Export the WordPress database using mysqldump. + + import Import a database exported via mysqldump. + + query Execute a query against the WordPress database. EOB ); } From feaa9a69d9338a9be0af57883c85b19311832ce1 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 04:40:53 +0300 Subject: [PATCH 0295/4858] make --file parameter positional. fixes #91 --- src/php/wp-cli/commands/internals/db.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 187b5d9294..21857e5485 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -40,18 +40,14 @@ function cli() { * Exports the WordPress DB as SQL using mysqldump. */ function export( $args, $assoc_args ) { - if ( !isset( $assoc_args['file'] ) ) { - $result_file = sprintf( '%s.sql', DB_NAME ); - } else { - $result_file = $assoc_args['file']; - } + $result_file = $this->get_file_name( $args ); $exec = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); exec( $exec ); - WP_CLI::success( sprintf( 'Dumped to %s', $result_file ) ); + WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } /** @@ -73,18 +69,21 @@ function query( $args, $assoc_args ) { } function import( $args, $assoc_args ) { - if ( !isset( $assoc_args['file'] ) ) { - $result_file = sprintf( '%s.sql', DB_NAME ); - } else { - $result_file = $assoc_args['file']; - } + $result_file = $this->get_file_name( $args ); $exec = sprintf( 'mysql "%s" --user="%s" --password="%s" --host="%s" < "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); exec( $exec ); - WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); + WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); + } + + private function get_file_name( $args ) { + if ( empty( $args ) ) + return sprintf( '%s.sql', DB_NAME ); + + return $args[0]; } /** From 48b34f16a9ba60fa68c53172a254bec26b254b66 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 04:43:05 +0300 Subject: [PATCH 0296/4858] move the export() method above the import() method --- src/php/wp-cli/commands/internals/db.php | 31 +++++++++++++----------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 21857e5485..034b72c573 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -36,20 +36,6 @@ function cli() { proc_close( proc_open( $this->connect_string() , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); } - /** - * Exports the WordPress DB as SQL using mysqldump. - */ - function export( $args, $assoc_args ) { - $result_file = $this->get_file_name( $args ); - - $exec = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', - DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - - exec( $exec ); - - WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); - } - /** * Execute a query against the site database. */ @@ -68,6 +54,23 @@ function query( $args, $assoc_args ) { WP_CLI::line( $result ); } + /** + * Exports the WordPress DB as SQL using mysqldump. + */ + function export( $args, $assoc_args ) { + $result_file = $this->get_file_name( $args ); + + $exec = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', + DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); + + exec( $exec ); + + WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); + } + + /** + * Imports a database from a file. + */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); From 06af4f573d9ba3c5da5a85fb75c07dbf86ed9ca9 Mon Sep 17 00:00:00 2001 From: "John P. Bloch" Date: Tue, 10 Apr 2012 13:52:58 -0300 Subject: [PATCH 0297/4858] Allow silent downloads with curl. --- src/php/wp-cli/commands/internals/core.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 680d8d4279..cc132d6eac 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -22,8 +22,12 @@ public function download( $args, $assoc_args ) { else $docroot = './'; + $silent = ''; + if( !empty( $assoc_args['silent'] ) ) + $silent = '--silent '; + WP_CLI::line('Downloading WordPress...'); - exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); + exec("curl {$silent}http://wordpress.org/latest.zip > /tmp/wordpress.zip"); exec("unzip /tmp/wordpress.zip"); exec("mv wordpress/* $docroot"); exec("rm -r wordpress"); From 4ebf481ff0987db0cd6041e04232d9fc40c4c90c Mon Sep 17 00:00:00 2001 From: Marco Solazzi Date: Tue, 10 Apr 2012 12:49:22 +0200 Subject: [PATCH 0298/4858] added --version parameter to install specific versions of core and plugins --- src/php/wp-cli/commands/internals/core.php | 13 ++++++++++++- src/php/wp-cli/commands/internals/plugin.php | 12 ++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 680d8d4279..d1aa583cd7 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -21,9 +21,20 @@ public function download( $args, $assoc_args ) { $docroot = $assoc_args['path']; else $docroot = './'; + + if (isset($assoc_args['version'])) { + $download_url = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; + } else { + $download_url = 'http://wordpress.org/latest.zip'; + } + $version_check_response = wp_remote_head($download_url); + if (!$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream') { + WP_CLI::error( 'Unable to download remote file ' . $download_url); + exit(); + } WP_CLI::line('Downloading WordPress...'); - exec("curl http://wordpress.org/latest.zip > /tmp/wordpress.zip"); + exec("curl {$download_url} > /tmp/wordpress.zip"); exec("unzip /tmp/wordpress.zip"); exec("mv wordpress/* $docroot"); exec("rm -r wordpress"); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 115549870f..d409c56a90 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -213,6 +213,18 @@ function install( $args, $assoc_args ) { $api->download_link = $link . $slug . '.zip'; $api->version = 'Development Version'; + } else if ( isset( $assoc_args['version'] ) ) { + list( $link ) = explode( $slug, $api->download_link ); + + $api->download_link = $link . $slug . '.' . $assoc_args['version'] .'.zip'; + $api->version = $assoc_args['version']; + + //check if the requested version exists + $version_check_response = wp_remote_head($api->download_link); + if (!$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream') { + WP_CLI::error( 'Can\'t find the requested plugin\'s version ' . $assoc_args['version'] . ' in the WordPress.org plugins repository.'); + exit(); + } } $status = install_plugin_install_status( $api ); From 8ea157269b0496dd55304f0a3dd6e7ff25e7b0f7 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 20:16:21 +0300 Subject: [PATCH 0299/4858] minor cleanup. see #92 --- src/php/wp-cli/commands/internals/core.php | 12 +++++++----- src/php/wp-cli/commands/internals/plugin.php | 14 +++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index d1aa583cd7..f4ca44f072 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -21,15 +21,16 @@ public function download( $args, $assoc_args ) { $docroot = $assoc_args['path']; else $docroot = './'; - - if (isset($assoc_args['version'])) { + + if ( isset( $assoc_args['version'] ) ) { $download_url = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; } else { $download_url = 'http://wordpress.org/latest.zip'; } - $version_check_response = wp_remote_head($download_url); - if (!$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream') { - WP_CLI::error( 'Unable to download remote file ' . $download_url); + + $version_check_response = wp_remote_head( $download_url ); + if ( !$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream' ) { + WP_CLI::error( 'Unable to download remote file ' . $download_url ); exit(); } @@ -171,6 +172,7 @@ public static function help() { WP_CLI::line( << [--admin_name=] --admin_password= --admin_email= EOB ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index d409c56a90..aa616164a9 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -218,12 +218,11 @@ function install( $args, $assoc_args ) { $api->download_link = $link . $slug . '.' . $assoc_args['version'] .'.zip'; $api->version = $assoc_args['version']; - - //check if the requested version exists - $version_check_response = wp_remote_head($api->download_link); - if (!$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream') { - WP_CLI::error( 'Can\'t find the requested plugin\'s version ' . $assoc_args['version'] . ' in the WordPress.org plugins repository.'); - exit(); + + // check if the requested version exists + $version_check_response = wp_remote_head( $api->download_link ); + if ( !$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream' ) { + WP_CLI::error( "Can't find the requested plugin's version " . $assoc_args['version'] . "in the WordPress.org plugins repository." ); } } @@ -346,7 +345,7 @@ public static function help() { WP_CLI::line( << [] or: wp plugin path [] [--dir] - or: wp plugin install [--activate] [--dev] + or: wp plugin install [--activate] [--dev] [--version=1.2.3] Available sub-commands: status display status of all installed plugins or of a particular plugin @@ -363,6 +362,7 @@ public static function help() { install install a plugin from wordpress.org --activate activate the plugin after installing it --dev install the development version + --version install a specific version update update a plugin from wordpress.org --all update all plugins from wordpress.org From 5a5c8baeb2d15f9f55b1bf382bc731d45808b3f2 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 20:26:03 +0300 Subject: [PATCH 0300/4858] Show wp-cli version only if there's no command passed. see #92 --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 60400ab3da..69e22d0417 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -30,7 +30,7 @@ define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); // Handle --version parameter -if ( isset( $assoc_args['version'] ) ) { +if ( isset( $assoc_args['version'] ) && empty( $arguments ) ) { WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); exit; } From 5dc3069a75c791e6fc18ce5438bf129e39e5a511 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 20:26:49 +0300 Subject: [PATCH 0301/4858] don't validate WP core version. Just let curl handle it. closes #92 --- src/php/wp-cli/commands/internals/core.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 39e8d829c3..38bdff797b 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -28,12 +28,6 @@ public function download( $args, $assoc_args ) { $download_url = 'http://wordpress.org/latest.zip'; } - $version_check_response = wp_remote_head( $download_url ); - if ( !$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream' ) { - WP_CLI::error( 'Unable to download remote file ' . $download_url ); - exit(); - } - $silent = ''; if( !empty( $assoc_args['silent'] ) ) $silent = '--silent '; From 0cf4117771ea9d91ba2f1dd604004d18b879283b Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 10 Apr 2012 20:28:37 +0300 Subject: [PATCH 0302/4858] fix some plugin command messages --- src/php/wp-cli/commands/internals/plugin.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index aa616164a9..e8f3a0e697 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -204,7 +204,7 @@ function install( $args, $assoc_args ) { $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( !$api ) { - WP_CLI::error( 'Can\'t find the plugin in the WordPress.org plugins repository.' ); + WP_CLI::error( "Can't find the plugin in the WordPress.org plugins repository." ); exit(); } @@ -222,7 +222,7 @@ function install( $args, $assoc_args ) { // check if the requested version exists $version_check_response = wp_remote_head( $api->download_link ); if ( !$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream' ) { - WP_CLI::error( "Can't find the requested plugin's version " . $assoc_args['version'] . "in the WordPress.org plugins repository." ); + WP_CLI::error( "Can't find the requested plugin's version " . $assoc_args['version'] . " in the WordPress.org plugins repository." ); } } @@ -244,10 +244,10 @@ function install( $args, $assoc_args ) { break; case 'newer_installed': - WP_CLI::error( sprintf( 'Newer version (%s) installed', $status['version'] ) ); + WP_CLI::error( sprintf( 'Newer version (%s) installed.', $status['version'] ) ); break; case 'latest_installed': - WP_CLI::error( 'Latest version already installed' ); + WP_CLI::error( 'Latest version already installed.' ); break; } } From 50beb9387e02342b2785d821c08cb3635f8f48df Mon Sep 17 00:00:00 2001 From: Zack Tollman Date: Fri, 13 Apr 2012 01:43:22 -0700 Subject: [PATCH 0303/4858] Added transient commands Added a new class that adds a wp transient command. The command takes "get", "set" and "delete", which correspond with "get_transient", "set_transient" and "delete_transient", respectively. Additionally, a fourth command, "type", indicates whether the transients API is using the database or object cache for storage. --- .../wp-cli/commands/internals/transient.php | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/transient.php diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/internals/transient.php new file mode 100644 index 0000000000..5bbe6e2e86 --- /dev/null +++ b/src/php/wp-cli/commands/internals/transient.php @@ -0,0 +1,109 @@ +' ); + exit; + } + + list( $key ) = $args; + + $value = get_transient( $key ); + + if ( false === $value ) { + WP_CLI::warning( 'Transient with key "' . $key . '" is not set.' ); + exit; + } + + if ( is_array( $value ) || is_object( $value ) ) + WP_CLI::line( var_export( $value ) ); + else + WP_CLI::success( $value ); + } + + /** + * Sets a value using the "set_transient" function. + * + * @param array $args + */ + public function set( $args ) { + if ( count( $args ) < 2 ) { + WP_CLI::error( 'usage: wp transient set [expiration]' ); + exit; + } + + list( $key, $value, $expiration ) = $args; + + $expiration = isset( $expiration ) ? $expiration : 0; + + if ( set_transient( $key, $value, $expiration ) ) + WP_CLI::success( 'Transient added.' ); + else + WP_CLI::error( 'Transient could not be set.' ); + } + + /** + * Deletes a value using the "delete_transient" function. + * + * @param array $args + */ + public function delete( $args ) { + if ( empty( $args ) ) { + WP_CLI::warning( 'Usage: wp transient delete ' ); + exit; + } + + list( $key ) = $args; + + if ( delete_transient( $key ) ) { + WP_CLI::success( 'Transient deleted.' ); + } else { + if ( get_transient( $key ) ) + WP_CLI::error( 'Transient was not deleted even though the transient appears to exist.' ); + else + WP_CLI::warning( 'Transient was not deleted; however, the transient does not appear to exist.' ); + } + } + + /** + * Indicates whether the transients API is using the object cache or options table in the current environment. + */ + public function type() { + global $_wp_using_ext_object_cache, $wpdb; + + if ( $_wp_using_ext_object_cache ) + $message = 'Transients are saved to the object cache.'; + else + $message = 'Transients are saved to the ' . $wpdb->prefix . 'options table.'; + + WP_CLI::line( $message ); + } + + /** + * Displays the help message. + */ + static function help() { + WP_CLI::line( << + or: wp transient set [expiration] + or: wp transient delete + or: wp transient type +EOB + ); + } +} \ No newline at end of file From c026106fb619abcab4e9d1d454c36074bcebc167 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 13 Apr 2012 19:00:59 +0300 Subject: [PATCH 0304/4858] remove --user param after handling it --- src/php/wp-cli/wp-cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 69e22d0417..42d217d6ee 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -78,7 +78,10 @@ } } -// Set the user +// Set filesystem method +add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); + +// Handle --user parameter if ( isset( $assoc_args['user'] ) ) { $user = $assoc_args['user']; if ( is_numeric( $user ) ) { @@ -89,12 +92,9 @@ if ( !$user_id || !wp_set_current_user( $user_id ) ) { WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); } - unset( $user ); + unset( $assoc_args['user'], $user ); } -// Set filesystem method -add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - // Handle --completions parameter if ( isset( $assoc_args['completions'] ) ) { WP_CLI::load_all_commands(); From db00e40d4911b0dd36762787ac81429204a731a1 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 13 Apr 2012 19:01:32 +0300 Subject: [PATCH 0305/4858] implement --require global parameter. fixes #94 --- src/php/wp-cli/commands/internals/help.php | 1 + src/php/wp-cli/wp-cli.php | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 4d6e28f137..21d4388dfe 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -54,6 +54,7 @@ private function general_help() { WP_CLI::line( ' --user= set the current user' ); WP_CLI::line( ' --url= set the current URL' ); WP_CLI::line( ' --path= set the current path to the WP install' ); + WP_CLI::line( ' --require= load a certain file before running the command' ); WP_CLI::line( ' --version print wp-cli version' ); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 42d217d6ee..c993122e09 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -95,6 +95,12 @@ unset( $assoc_args['user'], $user ); } +// Handle --require parameter +if ( isset( $assoc_args['require'] ) ) { + require $assoc_args['require']; + unset( $assoc_args['require'] ); +} + // Handle --completions parameter if ( isset( $assoc_args['completions'] ) ) { WP_CLI::load_all_commands(); From 96fabe98ee811940e4b57814cee0a59cb6d7ff5a Mon Sep 17 00:00:00 2001 From: Zack Tollman Date: Fri, 13 Apr 2012 15:02:55 -0700 Subject: [PATCH 0306/4858] Remove use of WP_CLI::line when outputting transient value In the main project, issue #71 outlines a problem with using this method to output option values when "%" is used. The transient get command is also susceptible to this issue. The same fix has been applied here. --- src/php/wp-cli/commands/internals/transient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/internals/transient.php index 5bbe6e2e86..4e7c8b1c84 100644 --- a/src/php/wp-cli/commands/internals/transient.php +++ b/src/php/wp-cli/commands/internals/transient.php @@ -31,9 +31,9 @@ public function get( $args ) { } if ( is_array( $value ) || is_object( $value ) ) - WP_CLI::line( var_export( $value ) ); + echo var_export( $value ) . "\n"; else - WP_CLI::success( $value ); + echo $value . "\n"; } /** From 9bd5ade184b4f07f7036e738698519588565dbe9 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 16 Apr 2012 18:59:30 +0300 Subject: [PATCH 0307/4858] make file names match command names. fixes #99 --- .../{google-sitemap-generator.php => google-sitemap.php} | 0 .../commands/community/{wp-super-cache.php => super-cache.php} | 0 .../commands/community/{w3-total-cache.php => total-cache.php} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/php/wp-cli/commands/community/{google-sitemap-generator.php => google-sitemap.php} (100%) rename src/php/wp-cli/commands/community/{wp-super-cache.php => super-cache.php} (100%) rename src/php/wp-cli/commands/community/{w3-total-cache.php => total-cache.php} (100%) diff --git a/src/php/wp-cli/commands/community/google-sitemap-generator.php b/src/php/wp-cli/commands/community/google-sitemap.php similarity index 100% rename from src/php/wp-cli/commands/community/google-sitemap-generator.php rename to src/php/wp-cli/commands/community/google-sitemap.php diff --git a/src/php/wp-cli/commands/community/wp-super-cache.php b/src/php/wp-cli/commands/community/super-cache.php similarity index 100% rename from src/php/wp-cli/commands/community/wp-super-cache.php rename to src/php/wp-cli/commands/community/super-cache.php diff --git a/src/php/wp-cli/commands/community/w3-total-cache.php b/src/php/wp-cli/commands/community/total-cache.php similarity index 100% rename from src/php/wp-cli/commands/community/w3-total-cache.php rename to src/php/wp-cli/commands/community/total-cache.php From bbbde0747e9fc33e45dbd4257cec7c1ced69ef87 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 11:12:01 -0700 Subject: [PATCH 0308/4858] Correct spelling in comment --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 03c1aef42d..ee287cd2e7 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -72,7 +72,7 @@ private function update_multiple( $args, $assoc_args ) { } /** - * Check wether an item has an update available or not. + * Check whether an item has an update available or not. * * @param string $item The plugin/theme theme path * From d00b8494075d2699759bdb6d0f0a5c3e4731ff9e Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 11:12:32 -0700 Subject: [PATCH 0309/4858] Initial commit for 'wp theme install' command. Ported from 'wp plugin install'. --- src/php/wp-cli/commands/internals/theme.php | 63 +++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index e8856ada3a..94c41d54e2 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -124,6 +124,65 @@ function path( $args, $assoc_args ) { WP_CLI::line( $path ); } + /** + * Install a new theme + * + * @param array $args + * @param array $assoc_args + */ + function install( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp theme install " ); + exit(); + } + + $slug = stripslashes( $args[0] ); + + // Force WordPress to update the theme list + wp_update_themes(); + + // If --file is set, install from file. + if ( isset( $assoc_args['file'] ) ) { + $result = WP_CLI::get_upgrader( $this->upgrader )->install( $args[0] ); + + // Else, install from .org theme repo. + } else { + $result = 0; + + $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); + if ( is_wp_error( $api ) ) { + WP_CLI::error( "Can't find the theme in the WordPress.org theme repository." ); + exit(); + } + + // Check to see if we should update, rather than install. + if ( $this->get_update_status( $api->slug ) ) { + WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); + $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $api->slug ); + + /** + * Else, if there's no update, it's either not installed, + * or it's newer than what we've got. + */ + } else if ( !is_readable( $this->get_stylesheet_path( $api->slug ) ) ) { + WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + $result = WP_CLI::get_upgrader( $this->upgrader )->install( $api->download_link ); + } else { + $result = 1; + WP_CLI::warning( 'Theme already installed and up to date.' ); + } + + /** + * Finally, activate theme if requested. + * At the moment, this only works with themes installed from repo. + */ + if ( $result && isset( $assoc_args['activate'] ) ) { + WP_CLI::line( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); + } + } + } + protected function get_item_list() { return wp_list_pluck( get_themes(), 'Stylesheet' ); } @@ -181,6 +240,10 @@ public static function help() { path print path to the theme's stylesheet --dir get the path to the closest parent directory + install install a theme from wordpress.org + --activate activate the theme after installing it + --file install from ZIP file + update update a theme from wordpress.org --all update all themes from wordpress.org From d209b44602be3f9caeafbaafaf05ed9050abccc0 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 16:31:00 -0700 Subject: [PATCH 0310/4858] Move to --file=file.zip and fix --activate with --file --- src/php/wp-cli/commands/internals/theme.php | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 94c41d54e2..76272468ae 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -131,22 +131,26 @@ function path( $args, $assoc_args ) { * @param array $assoc_args */ function install( $args, $assoc_args ) { - if ( empty( $args ) ) { + if ( empty( $args ) && empty( $assoc_args ) ) { WP_CLI::line( "usage: wp theme install " ); exit(); } - $slug = stripslashes( $args[0] ); + $slug = ''; // Force WordPress to update the theme list wp_update_themes(); // If --file is set, install from file. if ( isset( $assoc_args['file'] ) ) { - $result = WP_CLI::get_upgrader( $this->upgrader )->install( $args[0] ); + $upgrader = WP_CLI::get_upgrader( $this->upgrader ); + $result = $upgrader->install( $assoc_args['file'] ); + + $slug = $upgrader->result['destination_name']; // Else, install from .org theme repo. } else { + $slug = stripslashes( $args[0] ); $result = 0; $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); @@ -168,18 +172,14 @@ function install( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = WP_CLI::get_upgrader( $this->upgrader )->install( $api->download_link ); } else { - $result = 1; - WP_CLI::warning( 'Theme already installed and up to date.' ); + WP_CLI::error( 'Theme already installed and up to date.' ); } + } - /** - * Finally, activate theme if requested. - * At the moment, this only works with themes installed from repo. - */ - if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::line( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } + // Finally, activate theme if requested. + if ( $result && isset( $assoc_args['activate'] ) ) { + WP_CLI::line( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); } } From 415808baefb2d80e2e869bf93ade9c734740e702 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 16:46:48 -0700 Subject: [PATCH 0311/4858] Use .zip to decide if theme is a file Actually, just kidding. Let's use .zip to decide if we should install as a file, and avoid --file altogether. --- src/php/wp-cli/commands/internals/theme.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 76272468ae..4c09c8ad80 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -131,7 +131,7 @@ function path( $args, $assoc_args ) { * @param array $assoc_args */ function install( $args, $assoc_args ) { - if ( empty( $args ) && empty( $assoc_args ) ) { + if ( empty( $args ) ) { WP_CLI::line( "usage: wp theme install " ); exit(); } @@ -141,10 +141,10 @@ function install( $args, $assoc_args ) { // Force WordPress to update the theme list wp_update_themes(); - // If --file is set, install from file. - if ( isset( $assoc_args['file'] ) ) { + // If argument ends in .zip, install from file. + if ( preg_match( '/\.zip$/', $args[0] ) ) { $upgrader = WP_CLI::get_upgrader( $this->upgrader ); - $result = $upgrader->install( $assoc_args['file'] ); + $result = $upgrader->install( $args[0] ); $slug = $upgrader->result['destination_name']; @@ -242,7 +242,6 @@ public static function help() { install install a theme from wordpress.org --activate activate the theme after installing it - --file install from ZIP file update update a theme from wordpress.org --all update all themes from wordpress.org From 4dec8b4368c9d218aab2c149cc2a1469be3d76d7 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 17:00:39 -0700 Subject: [PATCH 0312/4858] Rename $upgrader to $file_upgrader like a good boy. --- src/php/wp-cli/commands/internals/theme.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 4c09c8ad80..2112093940 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -143,10 +143,10 @@ function install( $args, $assoc_args ) { // If argument ends in .zip, install from file. if ( preg_match( '/\.zip$/', $args[0] ) ) { - $upgrader = WP_CLI::get_upgrader( $this->upgrader ); - $result = $upgrader->install( $args[0] ); + $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); + $result = $file_upgrader->install( $args[0] ); - $slug = $upgrader->result['destination_name']; + $slug = $file_upgrader->result['destination_name']; // Else, install from .org theme repo. } else { From 05b55779ccceb539baff6d92e34776a0ac6d19a3 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 17:52:35 -0700 Subject: [PATCH 0313/4858] Add install_from_file and add .zip support to plugins Add install_from_file to WP_CLI_Command_With_Upgrade Add support to plugins for .zip through install_from_file Fix $result scope, and NULL by default. Use $slug instead of $api->slug when possible --- .../class-wp-cli-command-with-upgrade.php | 18 +++++++++++++++++- src/php/wp-cli/commands/internals/plugin.php | 12 ++++++++++++ src/php/wp-cli/commands/internals/theme.php | 14 +++++--------- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index ee287cd2e7..3b8f152310 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -83,5 +83,21 @@ protected function get_update_status( $file ) { return isset( $update_list->response[ $file ] ); } -} + /** + * Install a plugin/theme from a ZIP file + * + * @param string $file + * + * @return string The plugin/theme's slug, or NULL on failed install. + */ + protected function install_from_file( $file ) { + $slug = NULL; + $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); + + if ( $file_upgrader->install( $file ) ) + $slug = $file_upgrader->result['destination_name']; + + return $slug; + } +} diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index e8f3a0e697..23a3e87940 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -202,6 +202,18 @@ function install( $args, $assoc_args ) { // Force WordPress to update the plugin list wp_update_plugins(); + // If argument ends in .zip, install from file. + if ( preg_match( '/\.zip$/', $args[0] ) ) { + $slug = $this->install_from_file( $args[0] ); + + if ( $slug && isset( $assoc_args['activate'] ) ) { + WP_CLI::line( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); + } + + exit(); + } + $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( !$api ) { WP_CLI::error( "Can't find the plugin in the WordPress.org plugins repository." ); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 2112093940..d0e36026a0 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -136,22 +136,18 @@ function install( $args, $assoc_args ) { exit(); } - $slug = ''; + $slug = $result = NULL; // Force WordPress to update the theme list wp_update_themes(); // If argument ends in .zip, install from file. if ( preg_match( '/\.zip$/', $args[0] ) ) { - $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); - $result = $file_upgrader->install( $args[0] ); - - $slug = $file_upgrader->result['destination_name']; + $slug = $result = $this->install_from_file( $args[0] ); // Else, install from .org theme repo. } else { $slug = stripslashes( $args[0] ); - $result = 0; $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { @@ -160,15 +156,15 @@ function install( $args, $assoc_args ) { } // Check to see if we should update, rather than install. - if ( $this->get_update_status( $api->slug ) ) { + if ( $this->get_update_status( $slug ) ) { WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $api->slug ); + $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $slug ); /** * Else, if there's no update, it's either not installed, * or it's newer than what we've got. */ - } else if ( !is_readable( $this->get_stylesheet_path( $api->slug ) ) ) { + } else if ( !is_readable( $this->get_stylesheet_path( $slug ) ) ) { WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = WP_CLI::get_upgrader( $this->upgrader )->install( $api->download_link ); } else { From fba595644b0b32a472309e5b228ff51c39e1a49b Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 18:41:22 -0700 Subject: [PATCH 0314/4858] Make $result slightly more poetic. --- src/php/wp-cli/commands/internals/theme.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index d0e36026a0..6353116aa0 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -143,7 +143,12 @@ function install( $args, $assoc_args ) { // If argument ends in .zip, install from file. if ( preg_match( '/\.zip$/', $args[0] ) ) { - $slug = $result = $this->install_from_file( $args[0] ); + $slug = $this->install_from_file( $args[0] ); + + // If install_from_file() returns non-NULL, install succeeded. + if ( !is_null( $slug ) ) { + $result = 1; + } // Else, install from .org theme repo. } else { From 3611d07e8c1935f8c91a35cc1e3ed46e92637f95 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 18 Apr 2012 18:54:48 -0700 Subject: [PATCH 0315/4858] Avoid extra run of wp-cli on plugin install --activate --- src/php/wp-cli/commands/internals/plugin.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 23a3e87940..a8827b68d2 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -248,10 +248,9 @@ function install( $args, $assoc_args ) { $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); $result = $upgrader->install( $api->download_link ); - if ( $result ) { - if ( isset( $assoc_args['activate'] ) ) { - system( "wp plugin activate " . WP_CLI::compose_args( $args, $assoc_args ) ); - } + if ( $result && isset( $assoc_args['activate'] ) ) { + WP_CLI::line( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); } break; From 6da4a618e744355cac4c10a771055c4781621367 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 19 Apr 2012 17:13:09 +0300 Subject: [PATCH 0316/4858] replace install_from_file() with maybe_install_from_zip(). see #100 --- .../class-wp-cli-command-with-upgrade.php | 17 +++--- src/php/wp-cli/commands/internals/plugin.php | 17 ++---- src/php/wp-cli/commands/internals/theme.php | 52 ++++++++----------- 3 files changed, 37 insertions(+), 49 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 3b8f152310..7988dd3d9a 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -88,16 +88,21 @@ protected function get_update_status( $file ) { * Install a plugin/theme from a ZIP file * * @param string $file - * - * @return string The plugin/theme's slug, or NULL on failed install. + * @param bool $activate */ - protected function install_from_file( $file ) { - $slug = NULL; + protected function maybe_install_from_zip( $file, $activate ) { + if ( '.zip' != substr( $file, -4 ) ) + return; + $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); - if ( $file_upgrader->install( $file ) ) + if ( $file_upgrader->install( $file ) ) { $slug = $file_upgrader->result['destination_name']; - return $slug; + if ( $activate ) + $this->activate( array( $slug ) ); + } + + exit; } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index a8827b68d2..04c43da120 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -197,23 +197,14 @@ function install( $args, $assoc_args ) { exit; } - $slug = stripslashes( $args[0] ); - // Force WordPress to update the plugin list wp_update_plugins(); - // If argument ends in .zip, install from file. - if ( preg_match( '/\.zip$/', $args[0] ) ) { - $slug = $this->install_from_file( $args[0] ); - - if ( $slug && isset( $assoc_args['activate'] ) ) { - WP_CLI::line( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } + $slug = stripslashes( $args[0] ); - exit(); - } + $this->maybe_install_from_zip( $slug, isset( $assoc_args['activate'] ) ); + // Not a zip, so try to install from wp.org $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( !$api ) { WP_CLI::error( "Can't find the plugin in the WordPress.org plugins repository." ); @@ -370,7 +361,7 @@ public static function help() { path print path to the plugin's file --dir get the path to the closest parent directory - install install a plugin from wordpress.org + install install a plugin from wordpress.org or from a zip file --activate activate the plugin after installing it --dev install the development version --version install a specific version diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 6353116aa0..1f6ba5eee9 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -97,11 +97,12 @@ public function activate( $args = array() ) { if ( empty( $parent ) ) { $parent = $child; } elseif ( !is_readable( $this->get_stylesheet_path( $parent ) ) ) { - WP_CLI::warning( 'parent theme not found' ); - exit; + WP_CLI::error( 'Parent theme not found.' ); } switch_theme( $parent, $child ); + + WP_CLI::success( "Switched to '{$details['Title']}' theme." ); } /** @@ -136,45 +137,36 @@ function install( $args, $assoc_args ) { exit(); } - $slug = $result = NULL; - // Force WordPress to update the theme list wp_update_themes(); - // If argument ends in .zip, install from file. - if ( preg_match( '/\.zip$/', $args[0] ) ) { - $slug = $this->install_from_file( $args[0] ); + $slug = stripslashes( $args[0] ); - // If install_from_file() returns non-NULL, install succeeded. - if ( !is_null( $slug ) ) { - $result = 1; - } + $this->maybe_install_from_zip( $slug, isset( $assoc_args['activate'] ) ); - // Else, install from .org theme repo. - } else { - $slug = stripslashes( $args[0] ); + // Not a zip, so try to install from wp.org + $result = NULL; - $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); - if ( is_wp_error( $api ) ) { - WP_CLI::error( "Can't find the theme in the WordPress.org theme repository." ); - exit(); - } + $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); + if ( is_wp_error( $api ) ) { + WP_CLI::error( "Can't find the theme in the WordPress.org theme repository." ); + exit(); + } - // Check to see if we should update, rather than install. - if ( $this->get_update_status( $slug ) ) { - WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $slug ); + // Check to see if we should update, rather than install. + if ( $this->get_update_status( $slug ) ) { + WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); + $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $slug ); /** * Else, if there's no update, it's either not installed, * or it's newer than what we've got. */ - } else if ( !is_readable( $this->get_stylesheet_path( $slug ) ) ) { - WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI::get_upgrader( $this->upgrader )->install( $api->download_link ); - } else { - WP_CLI::error( 'Theme already installed and up to date.' ); - } + } else if ( !is_readable( $this->get_stylesheet_path( $slug ) ) ) { + WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + $result = WP_CLI::get_upgrader( $this->upgrader )->install( $api->download_link ); + } else { + WP_CLI::error( 'Theme already installed and up to date.' ); } // Finally, activate theme if requested. @@ -241,7 +233,7 @@ public static function help() { path print path to the theme's stylesheet --dir get the path to the closest parent directory - install install a theme from wordpress.org + install install a theme from wordpress.org or from a zip file --activate activate the theme after installing it update update a theme from wordpress.org From 812abfacbe8c12208d9b13ab3d416e32a3c407eb Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 22 Apr 2012 02:48:35 +0300 Subject: [PATCH 0317/4858] update copyright notice --- LICENSE.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 8a2f6b51ef..745e84216b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,8 @@ -Copyright (c) 2011 Andreas Creten +======================================== +wp-cli is licensed under the MIT License +======================================== + +Copyright (C) 2011-2012 WP-CLI Development Group (https://github.com/wp-cli/wp-cli/contributors) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From e152cf481ce2ca7519fee326e6517f04b69cbc2a Mon Sep 17 00:00:00 2001 From: "John P. Bloch" Date: Tue, 24 Apr 2012 10:54:59 -0400 Subject: [PATCH 0318/4858] Put the total cache flush function in a do .. while loop so we can send in multiple arguments at a time, such as: wp total-cache flush object post to flush both the object cache and the page cache at the same time. Uses array_unique on $args to make sure the explicitly defined switch cases are only hit once. Use a variable and check if it's set and true to keep the whole page cache from being flushed multiple times. --- .../wp-cli/commands/community/total-cache.php | 97 ++++++++++--------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index bac1dd8b82..5d24bd808c 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -21,57 +21,64 @@ class W3TotalCacheCommand extends WP_CLI_Command { */ function flush( $args = array(), $vars = array() ) { if ( function_exists( 'w3tc_pgcache_flush' ) ) { - $cache_type = array_shift($args); + $args = array_unique( $args ); + do { + $cache_type = array_shift($args); - switch($cache_type) { - case 'db': - case 'database': - if ( w3tc_dbcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + switch($cache_type) { + case 'db': + case 'database': + if ( w3tc_dbcache_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'minify': - if ( w3tc_minify_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + case 'minify': + if ( w3tc_minify_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'object': - if ( w3tc_objectcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + case 'object': + if ( w3tc_objectcache_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'post': - default: - if ( isset($vars['post_id']) ) { - if ( is_numeric( $vars['post_id'] ) ) { - w3tc_pgcache_flush_post( $vars['post_id'] ); - } else { - WP_CLI::error('This is not a valid post id.'); - } + case 'post': + default: + if ( isset($vars['post_id']) ) { + if ( is_numeric( $vars['post_id'] ) ) { + w3tc_pgcache_flush_post( $vars['post_id'] ); + } else { + WP_CLI::error('This is not a valid post id.'); + } - w3tc_pgcache_flush_post( $vars['post_id'] ); - } - elseif ( isset( $vars['permalink'] ) ) { - $id = url_to_postid( $vars['permalink'] ); + w3tc_pgcache_flush_post( $vars['post_id'] ); + } + elseif ( isset( $vars['permalink'] ) ) { + $id = url_to_postid( $vars['permalink'] ); - if ( is_numeric( $id ) ) { - w3tc_pgcache_flush_post( $id ); - } else { - WP_CLI::error('There is no post with this permalink.'); - } - } else { - w3tc_pgcache_flush(); - } - } + if ( is_numeric( $id ) ) { + w3tc_pgcache_flush_post( $id ); + } else { + WP_CLI::error('There is no post with this permalink.'); + } + } else { + if ( isset( $flushed_page_cache ) && $flushed_page_cache ) + break; + + $flushed_page_cache = true; + w3tc_pgcache_flush(); + } + } + } while ( !empty( $args ) ); } else { WP_CLI::error('The W3 Total Cache could not be found, is it installed?'); } From 6aa5f9b1a2bdb86a98ddedc8e6dd859bc3520198 Mon Sep 17 00:00:00 2001 From: "John P. Bloch" Date: Tue, 24 Apr 2012 11:37:26 -0400 Subject: [PATCH 0319/4858] Formatting issues... --- .../wp-cli/commands/community/total-cache.php | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index 5d24bd808c..365f8c9735 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -21,64 +21,64 @@ class W3TotalCacheCommand extends WP_CLI_Command { */ function flush( $args = array(), $vars = array() ) { if ( function_exists( 'w3tc_pgcache_flush' ) ) { - $args = array_unique( $args ); - do { - $cache_type = array_shift($args); + $args = array_unique( $args ); + do { + $cache_type = array_shift($args); - switch($cache_type) { - case 'db': - case 'database': - if ( w3tc_dbcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + switch($cache_type) { + case 'db': + case 'database': + if ( w3tc_dbcache_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'minify': - if ( w3tc_minify_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + case 'minify': + if ( w3tc_minify_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'object': - if ( w3tc_objectcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + case 'object': + if ( w3tc_objectcache_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'post': - default: - if ( isset($vars['post_id']) ) { - if ( is_numeric( $vars['post_id'] ) ) { - w3tc_pgcache_flush_post( $vars['post_id'] ); - } else { - WP_CLI::error('This is not a valid post id.'); - } + case 'post': + default: + if ( isset($vars['post_id']) ) { + if ( is_numeric( $vars['post_id'] ) ) { + w3tc_pgcache_flush_post( $vars['post_id'] ); + } else { + WP_CLI::error('This is not a valid post id.'); + } - w3tc_pgcache_flush_post( $vars['post_id'] ); - } - elseif ( isset( $vars['permalink'] ) ) { - $id = url_to_postid( $vars['permalink'] ); + w3tc_pgcache_flush_post( $vars['post_id'] ); + } + elseif ( isset( $vars['permalink'] ) ) { + $id = url_to_postid( $vars['permalink'] ); - if ( is_numeric( $id ) ) { - w3tc_pgcache_flush_post( $id ); - } else { - WP_CLI::error('There is no post with this permalink.'); - } - } else { - if ( isset( $flushed_page_cache ) && $flushed_page_cache ) - break; + if ( is_numeric( $id ) ) { + w3tc_pgcache_flush_post( $id ); + } else { + WP_CLI::error('There is no post with this permalink.'); + } + } else { + if ( isset( $flushed_page_cache ) && $flushed_page_cache ) + break; - $flushed_page_cache = true; - w3tc_pgcache_flush(); - } - } - } while ( !empty( $args ) ); + $flushed_page_cache = true; + w3tc_pgcache_flush(); + } + } + } while ( !empty( $args ) ); } else { WP_CLI::error('The W3 Total Cache could not be found, is it installed?'); } From e773d611635f8c4838995b07380b185c05330b74 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 25 Apr 2012 23:37:39 +0300 Subject: [PATCH 0320/4858] replace contributor impact link with contributor guide link (since the contributors page shows activity too now) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e6a32ad38..f715fdfae9 100644 --- a/README.md +++ b/README.md @@ -153,4 +153,4 @@ Contributors ------------ - [Contributor list](https://github.com/wp-cli/wp-cli/contributors) -- [Contributor impact](https://github.com/wp-cli/wp-cli/graphs/impact) +- [Contributor guide](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook) From 95aad0bc962c398508ffb88ca9a7f6dd61306b52 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 00:11:25 +0300 Subject: [PATCH 0321/4858] more readable check for core install --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c993122e09..a1b975b792 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -62,7 +62,7 @@ WP_CLI::_set_url( $assoc_args ); // Set installer flag before loading any WP files -if ( count( $arguments ) >= 2 && $arguments[0] == 'core' && $arguments[1] == 'install' ) { +if ( array( 'core', 'install' ) == $arguments ) { define( 'WP_INSTALLING', true ); } From e7c34cbfcda486eb903925607c83b769684e3b61 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 00:33:49 +0300 Subject: [PATCH 0322/4858] introduce `wp db create` command. fixes #103 --- src/php/wp-cli/class-wp-cli.php | 13 +++++++++++++ src/php/wp-cli/commands/internals/db.php | 18 ++++++++++++++---- src/php/wp-cli/wp-cli.php | 5 +++++ src/php/wp-cli/wp-settings.php | 4 ++++ 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 src/php/wp-cli/wp-settings.php diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 4613ae3b86..5247099a30 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -212,6 +212,19 @@ static function _set_url( &$assoc_args ) { } } + // Loads wp-config.php without loading the rest of WP + static function load_wp_config() { + define( 'ABSPATH', dirname(__FILE__) . '/' ); + + if ( file_exists( WP_ROOT . 'wp-config.php' ) ) { + require_once( WP_ROOT . 'wp-config.php' ); + } elseif ( file_exists( dirname(WP_ROOT) . '/wp-config.php' ) && ! file_exists( dirname(WP_ROOT) . '/wp-settings.php' ) ) { + require_once( dirname(WP_ROOT) . '/wp-config.php' ); + } else { + WP_CLI::error( 'No wp-config.php file.' ); + } + } + static function load_all_commands() { foreach ( array( 'internals', 'community' ) as $dir ) { foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 034b72c573..942f15cc7e 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -15,11 +15,11 @@ class DBCommand extends WP_CLI_Command { protected $aliases = array( 'dump' => 'export' ); /** - * Return a string for connecting to the DB. + * Creates the database according to the wp-config.php file */ - protected function connect_string() { - return sprintf( 'mysql --host="%s" --database="%s" --user="%s" --password="%s"', - DB_HOST, DB_NAME, DB_USER, DB_PASSWORD ); + function create() { + exec( sprintf( 'mysql --host="%s" --user="%s" --password="%s" --execute="CREATE DATABASE %s"', + DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); } /** @@ -82,6 +82,14 @@ function import( $args, $assoc_args ) { WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } + /** + * Return a string for connecting to the DB. + */ + private function connect_string() { + return sprintf( 'mysql --host="%s" --user="%s" --password="%s" --database="%s"', + DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); + } + private function get_file_name( $args ) { if ( empty( $args ) ) return sprintf( '%s.sql', DB_NAME ); @@ -106,6 +114,8 @@ public static function help() { import Import a database exported via mysqldump. query Execute a query against the WordPress database. + + create Create a database using the info from wp-config.php. EOB ); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index a1b975b792..9049ffa547 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -58,6 +58,11 @@ WP_CLI::run_command( $arguments, $assoc_args ); } +if ( array( 'db', 'create' ) == $arguments ) { + WP_CLI::load_wp_config(); + WP_CLI::run_command( $arguments, $assoc_args ); +} + // Handle --url and --blog parameters WP_CLI::_set_url( $assoc_args ); diff --git a/src/php/wp-cli/wp-settings.php b/src/php/wp-cli/wp-settings.php new file mode 100644 index 0000000000..648622d87c --- /dev/null +++ b/src/php/wp-cli/wp-settings.php @@ -0,0 +1,4 @@ + Date: Fri, 27 Apr 2012 00:50:08 +0300 Subject: [PATCH 0323/4858] load all commands only when generic help is needed --- src/php/wp-cli/class-wp-cli.php | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 5247099a30..33fc2e2ee9 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -248,17 +248,14 @@ static function run_command( $arguments, $assoc_args ) { } if ( 'help' == $command ) { - self::load_all_commands(); - } - else { - foreach ( array( 'internals', 'community' ) as $dir ) { - $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; - - if ( is_readable( $path ) ) { - include $path; - break; - } + if ( empty( $arguments ) ) { + self::load_all_commands(); + } else { + self::load_command( 'help' ); + self::load_command( $arguments[0] ); } + } else { + self::load_command( $command ); } if ( !isset( WP_CLI::$commands[$command] ) ) { @@ -269,5 +266,16 @@ static function run_command( $arguments, $assoc_args ) { new WP_CLI::$commands[$command]( $arguments, $assoc_args ); exit; } + + private function load_command( $command ) { + foreach ( array( 'internals', 'community' ) as $dir ) { + $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + + if ( is_readable( $path ) ) { + include $path; + break; + } + } + } } From 926edfc92745c92a0a5b2890998d9358926fea4b Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 02:15:49 +0300 Subject: [PATCH 0324/4858] don't call get_plugins() a second time if we already found a match --- src/php/wp-cli/commands/internals/plugin.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 04c43da120..401323d63d 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -324,17 +324,17 @@ protected function parse_name( $args, $subcommand ) { $plugins = get_plugins( '/' . $name ); if ( !empty( $plugins ) ) { - $file = $name . '/' . key( $plugins ); + $file = key( $plugins ); } else { $file = $name . '.php'; - } - $plugins = get_plugins(); + $plugins = get_plugins(); - if ( !isset( $plugins[$file] ) ) { - WP_CLI::error( "The plugin '$name' could not be found." ); - exit(); + if ( !isset( $plugins[$file] ) ) { + WP_CLI::error( "The plugin '$name' could not be found." ); + exit(); + } } return array( $file, $name ); From 223b524cead1a02455b209042d795ccbad00e941 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 02:45:41 +0300 Subject: [PATCH 0325/4858] add db prefix to parameter names. see #65 --- src/php/wp-cli/commands/internals/core.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 38bdff797b..e3e8d65a13 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -44,11 +44,11 @@ public function download( $args, $assoc_args ) { * Set up a wp-config.php file. */ public function config( $args, $assoc_args ) { - $_POST['dbname'] = $assoc_args['name']; - $_POST['uname'] = $assoc_args['user']; - $_POST['pwd'] = $assoc_args['pass']; - $_POST['dbhost'] = isset( $assoc_args['host'] ) ? $assoc_args['host'] : 'localhost'; - $_POST['prefix'] = isset( $assoc_args['prefix'] ) ? $assoc_args['prefix'] : 'wp_'; + $_POST['dbname'] = $assoc_args['dbname']; + $_POST['uname'] = $assoc_args['dbuser']; + $_POST['pwd'] = $assoc_args['dbpass']; + $_POST['dbhost'] = isset( $assoc_args['dbhost'] ) ? $assoc_args['dbhost'] : 'localhost'; + $_POST['prefix'] = isset( $assoc_args['dbprefix'] ) ? $assoc_args['dbprefix'] : 'wp_'; $_GET['step'] = 2; require WP_ROOT . '/wp-admin/setup-config.php'; From ae947a2f3903c3579d1ec79a8c087fd6b0973942 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 03:16:52 +0300 Subject: [PATCH 0326/4858] add wp core config example. see #65 --- src/php/wp-cli/commands/internals/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index e3e8d65a13..cbfe6a6bd9 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -171,6 +171,7 @@ public static function help() { usage: wp core update or: wp core version [--extra] or: wp core download [--version=1.2.3] + or: wp core config --dbname= --dbuser= --dbpass= [--dbhost=localhost] [--dbprefix=wp_] or: wp core install --site_url=example.com --site_title= [--admin_name=] --admin_password= --admin_email= EOB ); From 400201eb28d7bb1e42adc58b8eb9675b1cab8a79 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 18:29:44 +0300 Subject: [PATCH 0327/4858] call errorToString internally in WP_CLI::warning() --- src/php/wp-cli/class-cli-upgrader-skin.php | 2 +- src/php/wp-cli/class-wp-cli.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index a6d748490a..93488b8ca2 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -17,7 +17,7 @@ function error( $error ) { return; // TODO: show all errors, not just the first one - WP_CLI::warning( WP_CLI::errorToString( $error ) ); + WP_CLI::warning( $error ); } function feedback( $string ) { diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 33fc2e2ee9..d39cadbe03 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -69,7 +69,7 @@ static function success( $message, $label = 'Success' ) { */ static function warning( $message, $label = 'Warning' ) { if ( WP_CLI_SILENT ) return; - \cli\line( '%C' . $label . ': %n' . $message ); + \cli\line( '%C' . $label . ': %n' . self::errorToString( $message ) ); } /** From 88b1eeb9bc6598942779c62305f25411cd98dc0e Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 18:30:34 +0300 Subject: [PATCH 0328/4858] add underscores to command class names --- src/php/wp-cli/commands/community/google-sitemap.php | 4 ++-- src/php/wp-cli/commands/community/super-cache.php | 4 ++-- src/php/wp-cli/commands/community/total-cache.php | 4 ++-- src/php/wp-cli/commands/internals/core.php | 4 ++-- src/php/wp-cli/commands/internals/db.php | 4 ++-- src/php/wp-cli/commands/internals/eval-file.php | 4 ++-- src/php/wp-cli/commands/internals/eval.php | 4 ++-- src/php/wp-cli/commands/internals/export.php | 4 ++-- src/php/wp-cli/commands/internals/generate.php | 4 ++-- src/php/wp-cli/commands/internals/help.php | 4 ++-- src/php/wp-cli/commands/internals/home.php | 4 ++-- src/php/wp-cli/commands/internals/option.php | 4 ++-- src/php/wp-cli/commands/internals/plugin.php | 4 ++-- src/php/wp-cli/commands/internals/theme.php | 4 ++-- src/php/wp-cli/commands/internals/transient.php | 4 ++-- src/php/wp-cli/commands/internals/user.php | 4 ++-- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/php/wp-cli/commands/community/google-sitemap.php b/src/php/wp-cli/commands/community/google-sitemap.php index 268518701d..6a0a94a9c9 100644 --- a/src/php/wp-cli/commands/community/google-sitemap.php +++ b/src/php/wp-cli/commands/community/google-sitemap.php @@ -1,7 +1,7 @@ Date: Fri, 27 Apr 2012 18:31:25 +0300 Subject: [PATCH 0329/4858] rename errorToString() to error_to_string() --- src/php/wp-cli/class-wp-cli.php | 8 ++++---- src/php/wp-cli/commands/internals/core.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index d39cadbe03..b142edd6ee 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -46,7 +46,7 @@ static function line( $message = '' ) { * @param string $label */ static function error( $message, $label = 'Error' ) { - \cli\err( '%R' . $label . ': %n' . self::errorToString( $message ) ); + \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); exit(1); } @@ -69,16 +69,16 @@ static function success( $message, $label = 'Success' ) { */ static function warning( $message, $label = 'Warning' ) { if ( WP_CLI_SILENT ) return; - \cli\line( '%C' . $label . ': %n' . self::errorToString( $message ) ); + \cli\line( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } /** - * Convert a wp_error into a String + * Convert a wp_error into a string * * @param mixed $errors * @return string */ - static function errorToString( $errors ) { + static function error_to_string( $errors ) { if( is_string( $errors ) ) { return $errors; } elseif( is_wp_error( $errors ) && $errors->get_error_code() ) { diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 4159f96c44..a55efb3c0e 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -91,7 +91,7 @@ public function install( $args, $assoc_args ) { $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { - WP_CLI::error( 'Installation failed (' . WP_CLI::errorToString($result) . ').' ); + WP_CLI::error( 'Installation failed (' . WP_CLI::error_to_string($result) . ').' ); } else { WP_CLI::success( 'WordPress installed successfully.' ); } @@ -152,7 +152,7 @@ function update( $args ) { $result = WP_CLI::get_upgrader( 'Core_Upgrader' )->upgrade( $update ); if ( is_wp_error($result) ) { - $msg = WP_CLI::errorToString( $result ); + $msg = WP_CLI::error_to_string( $result ); if ( 'up_to_date' != $result->get_error_code() ) { WP_CLI::error( $msg ); } else { From d40828dc48e43b6c417dabfb6497a4da13711617 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 27 Apr 2012 19:55:32 +0300 Subject: [PATCH 0330/4858] rename addCommand() to add_command() --- src/php/wp-cli/class-wp-cli.php | 7 ++++++- src/php/wp-cli/commands/community/google-sitemap.php | 2 +- src/php/wp-cli/commands/community/super-cache.php | 2 +- src/php/wp-cli/commands/community/total-cache.php | 2 +- src/php/wp-cli/commands/internals/core.php | 2 +- src/php/wp-cli/commands/internals/db.php | 2 +- src/php/wp-cli/commands/internals/eval-file.php | 2 +- src/php/wp-cli/commands/internals/eval.php | 2 +- src/php/wp-cli/commands/internals/export.php | 2 +- src/php/wp-cli/commands/internals/generate.php | 2 +- src/php/wp-cli/commands/internals/help.php | 2 +- src/php/wp-cli/commands/internals/home.php | 2 +- src/php/wp-cli/commands/internals/option.php | 2 +- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 2 +- src/php/wp-cli/commands/internals/transient.php | 2 +- src/php/wp-cli/commands/internals/user.php | 2 +- 17 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index b142edd6ee..656e94ce9c 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -15,7 +15,7 @@ class WP_CLI { * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command */ - public function addCommand( $name, $class ) { + public function add_command( $name, $class ) { self::$commands[$name] = $class; } @@ -277,5 +277,10 @@ private function load_command( $command ) { } } } + + // back-compat + public function addCommand( $name, $class ) { + self::add_command( $name, $class ); + } } diff --git a/src/php/wp-cli/commands/community/google-sitemap.php b/src/php/wp-cli/commands/community/google-sitemap.php index 6a0a94a9c9..4248373233 100644 --- a/src/php/wp-cli/commands/community/google-sitemap.php +++ b/src/php/wp-cli/commands/community/google-sitemap.php @@ -1,7 +1,7 @@ Date: Sun, 29 Apr 2012 14:23:06 +0300 Subject: [PATCH 0331/4858] plugins_api() returns WP_Error --- src/php/wp-cli/commands/internals/plugin.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index c957cab6e1..74fec8b892 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -206,9 +206,9 @@ function install( $args, $assoc_args ) { // Not a zip, so try to install from wp.org $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); - if ( !$api ) { - WP_CLI::error( "Can't find the plugin in the WordPress.org plugins repository." ); - exit(); + + if ( is_wp_error( $api ) ) { + WP_CLI::error( $api ); } if ( isset( $assoc_args['dev'] ) ) { From 5e80652e000498ab14caac7845f0fb6785ac42d0 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 14:41:55 +0300 Subject: [PATCH 0332/4858] fix Plugin_Command::parse_name() --- src/php/wp-cli/commands/internals/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 74fec8b892..e32d2b5dc8 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -324,7 +324,7 @@ protected function parse_name( $args, $subcommand ) { $plugins = get_plugins( '/' . $name ); if ( !empty( $plugins ) ) { - $file = key( $plugins ); + $file = $name . '/' . key( $plugins ); } else { $file = $name . '.php'; From 96ca68dafa0628e8b60da622b22238d0bda1951e Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 15:17:49 +0300 Subject: [PATCH 0333/4858] update docs for get_update_status --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 7988dd3d9a..639573f83b 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -74,14 +74,14 @@ private function update_multiple( $args, $assoc_args ) { /** * Check whether an item has an update available or not. * - * @param string $item The plugin/theme theme path + * @param string $slug The plugin/theme slug * * @return bool */ - protected function get_update_status( $file ) { + protected function get_update_status( $slug ) { $update_list = get_site_transient( $this->upgrade_transient ); - return isset( $update_list->response[ $file ] ); + return isset( $update_list->response[ $slug ] ); } /** From b0402c857df335c8d7874c619ae43ca169b385ba Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 15:25:24 +0300 Subject: [PATCH 0334/4858] introduce precise is_active_theme() method --- src/php/wp-cli/commands/internals/theme.php | 31 +++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 4eaec4ccdd..b897b224a7 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -26,15 +26,16 @@ public function status( $args = array() ) { return; } - $name = $args[0]; + $slug = stripslashes( $args[0] ); - $details = get_theme_data( $this->get_stylesheet_path( $name ) ); + $stylesheet = $this->get_stylesheet_path( $slug ); + $details = get_theme_data( $stylesheet ); - $status = $this->get_status( $details['Name'], true ); + $status = $this->get_status( $stylesheet, true ); $version = $details['Version']; - if ( $this->get_update_status( $details['Stylesheet'] ) ) + if ( $this->get_update_status( $slug ) ) $version .= ' (%gUpdate available%n)'; WP_CLI::line( 'Theme %9' . $name . '%n details:' ); @@ -48,14 +49,16 @@ private function list_themes() { // Print the header WP_CLI::line( 'Installed themes:' ); - foreach ( get_themes() as $theme ) { + foreach ( get_themes() as $key => $theme ) { if ( $this->get_update_status( $theme['Stylesheet'] ) ) { $line = ' %yU%n'; } else { $line = ' '; } - $line .= $this->get_status( $theme['Name'] ) . ' ' . $theme['Stylesheet'] . '%n'; + $stylesheet = $this->get_stylesheet_path( $theme['Stylesheet'] ); + + $line .= $this->get_status( $stylesheet ) . ' ' . $theme['Stylesheet'] . '%n'; WP_CLI::line( $line ); } @@ -71,8 +74,8 @@ private function list_themes() { WP_CLI::legend( $legend ); } - private function get_status( $theme_name, $long = false ) { - if ( get_current_theme() == $theme_name ) { + private function get_status( $stylesheet, $long = false ) { + if ( $this->is_active_theme( $stylesheet ) ) { $line = '%g'; $line .= $long ? 'Active' : 'A'; } else { @@ -102,7 +105,17 @@ public function activate( $args = array() ) { switch_theme( $parent, $child ); - WP_CLI::success( "Switched to '{$details['Title']}' theme." ); + $name = $details['Title']; + + if ( $this->is_active_theme( $stylesheet ) ) { + WP_CLI::success( "Switched to '$name' theme." ); + } else { + WP_CLI::error( "Could not switch to '$name' theme." ); + } + } + + private function is_active_theme( $stylesheet ) { + return dirname( $stylesheet ) == get_stylesheet_directory(); } /** From 27a6acffbb14ecda5232e195d72d6d4efde45e25 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 15:26:05 +0300 Subject: [PATCH 0335/4858] call wp_update_themes() at the top of list_themes() --- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index e32d2b5dc8..4f5f4d3a2c 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -57,7 +57,7 @@ function status( $args = array(), $vars = array() ) { } private function list_plugins() { - // Force WordPress to update the plugin list + // Force WordPress to check for plugin updates wp_update_plugins(); $plugins = get_plugins(); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index b897b224a7..2dfbe9ea3b 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -46,6 +46,9 @@ public function status( $args = array() ) { } private function list_themes() { + // Force WordPress to check for theme updates + wp_update_themes(); + // Print the header WP_CLI::line( 'Installed themes:' ); From da2b8769b27a7740241bf763d960f1a952b83f73 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 15:55:33 +0300 Subject: [PATCH 0336/4858] move status() method up to WP_CLI_Command_With_Upgrade --- .../class-wp-cli-command-with-upgrade.php | 18 ++++++++++++++ src/php/wp-cli/commands/internals/plugin.php | 23 ++++-------------- src/php/wp-cli/commands/internals/theme.php | 24 ++++--------------- 3 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 639573f83b..579e76ef3d 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -4,6 +4,24 @@ class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { protected $default_subcommand = 'status'; + /** + * Get the status of one or all items + * + * @param array $args + */ + function status( $args = array() ) { + // Force WordPress to check for updates + call_user_func( $this->upgrade_refresh ); + + if ( empty( $args ) ) { + $this->status_all(); + } else { + list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + + $this->status_single( $file, $name ); + } + } + /** * Update a plugin/theme * diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 4f5f4d3a2c..5776823b21 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -24,21 +24,8 @@ function __construct( $args, $assoc_args ) { parent::__construct( $args, $assoc_args ); } - /** - * Get the status of one or all plugins - * - * @param array $args - */ - function status( $args = array(), $vars = array() ) { - $this->mu_plugins = get_mu_plugins(); - - if ( empty( $args ) ) { - $this->list_plugins(); - return; - } - - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - + // Show details about a single plugin + protected function status_single( $file, $name ) { $details = $this->get_details( $file ); $status = $this->get_status( $file, true ); @@ -56,9 +43,9 @@ function status( $args = array(), $vars = array() ) { WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); } - private function list_plugins() { - // Force WordPress to check for plugin updates - wp_update_plugins(); + // Show details about all plugins + protected function status_all() { + $this->mu_plugins = get_mu_plugins(); $plugins = get_plugins(); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 2dfbe9ea3b..16c75ea923 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -15,27 +15,15 @@ class Theme_Command extends WP_CLI_Command_With_Upgrade { protected $upgrade_refresh = 'wp_update_themes'; protected $upgrade_transient = 'update_themes'; - /** - * Get the status of one or all themes - * - * @param array $args - **/ - public function status( $args = array() ) { - if ( empty( $args ) ) { - $this->list_themes(); - return; - } - - $slug = stripslashes( $args[0] ); - - $stylesheet = $this->get_stylesheet_path( $slug ); + // Show details about a single theme + protected function status_single( $stylesheet, $name ) { $details = get_theme_data( $stylesheet ); $status = $this->get_status( $stylesheet, true ); $version = $details['Version']; - if ( $this->get_update_status( $slug ) ) + if ( $this->get_update_status( $name ) ) $version .= ' (%gUpdate available%n)'; WP_CLI::line( 'Theme %9' . $name . '%n details:' ); @@ -45,10 +33,8 @@ public function status( $args = array() ) { WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } - private function list_themes() { - // Force WordPress to check for theme updates - wp_update_themes(); - + // Show details about all themes + protected function status_all() { // Print the header WP_CLI::line( 'Installed themes:' ); From 43e92314e6a72210ce271bad6e37056bc9732e70 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 16:15:25 +0300 Subject: [PATCH 0337/4858] move install() method up to WP_CLI_Command_With_Upgrade --- .../class-wp-cli-command-with-upgrade.php | 23 +++++++++++++++++++ src/php/wp-cli/commands/internals/plugin.php | 21 +---------------- src/php/wp-cli/commands/internals/theme.php | 21 +---------------- 3 files changed, 25 insertions(+), 40 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 579e76ef3d..f4c89dab4d 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -22,6 +22,29 @@ function status( $args = array() ) { } } + /** + * Install a new plugin/theme + * + * @param array $args + * @param array $assoc_args + */ + function install( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp $this->item_type install " ); + exit; + } + + // Force WordPress to check for updates + call_user_func( $this->upgrade_refresh ); + + $slug = stripslashes( $args[0] ); + + $this->maybe_install_from_zip( $slug, isset( $assoc_args['activate'] ) ); + + // Not a zip, so try to install from wp.org + $this->install_from_repo( $slug, $assoc_args ); + } + /** * Update a plugin/theme * diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 5776823b21..bd051ba55c 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -172,26 +172,7 @@ function path( $args, $assoc_args ) { WP_CLI::line( $path ); } - /** - * Install a new plugin - * - * @param array $args - * @param array $assoc_args - */ - function install( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp plugin install " ); - exit; - } - - // Force WordPress to update the plugin list - wp_update_plugins(); - - $slug = stripslashes( $args[0] ); - - $this->maybe_install_from_zip( $slug, isset( $assoc_args['activate'] ) ); - - // Not a zip, so try to install from wp.org + protected function install_from_repo( $slug, $assoc_args ) { $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 16c75ea923..fe9fb4d5dd 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -127,26 +127,7 @@ function path( $args, $assoc_args ) { WP_CLI::line( $path ); } - /** - * Install a new theme - * - * @param array $args - * @param array $assoc_args - */ - function install( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp theme install " ); - exit(); - } - - // Force WordPress to update the theme list - wp_update_themes(); - - $slug = stripslashes( $args[0] ); - - $this->maybe_install_from_zip( $slug, isset( $assoc_args['activate'] ) ); - - // Not a zip, so try to install from wp.org + protected function install_from_repo( $slug, $assoc_args ) { $result = NULL; $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); From 7c8ee9d902622621b57f979a70324c5a77bd936c Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 29 Apr 2012 16:23:23 +0300 Subject: [PATCH 0338/4858] merge maybe_install_from_zip() into install() --- .../class-wp-cli-command-with-upgrade.php | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index f4c89dab4d..cad2fd1d8b 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -39,10 +39,20 @@ function install( $args, $assoc_args ) { $slug = stripslashes( $args[0] ); - $this->maybe_install_from_zip( $slug, isset( $assoc_args['activate'] ) ); + if ( '.zip' == substr( $slug, -4 ) ) { + $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); - // Not a zip, so try to install from wp.org - $this->install_from_repo( $slug, $assoc_args ); + if ( $file_upgrader->install( $slug ) ) { + $slug = $file_upgrader->result['destination_name']; + + if ( isset( $assoc_args['activate'] ) ) { + WP_CLI::line( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); + } + } + } else { + $this->install_from_repo( $slug, $assoc_args ); + } } /** @@ -124,26 +134,4 @@ protected function get_update_status( $slug ) { return isset( $update_list->response[ $slug ] ); } - - /** - * Install a plugin/theme from a ZIP file - * - * @param string $file - * @param bool $activate - */ - protected function maybe_install_from_zip( $file, $activate ) { - if ( '.zip' != substr( $file, -4 ) ) - return; - - $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); - - if ( $file_upgrader->install( $file ) ) { - $slug = $file_upgrader->result['destination_name']; - - if ( $activate ) - $this->activate( array( $slug ) ); - } - - exit; - } } From 5218ea61093b52aa91dc3869bcc050c7cdaf64b9 Mon Sep 17 00:00:00 2001 From: Evan Anderson Date: Wed, 4 Apr 2012 16:12:01 -0600 Subject: [PATCH 0339/4858] Initial add of blog commands --- src/php/wp-cli/commands/internals/blog.php | 166 +++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/blog.php diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php new file mode 100644 index 0000000000..45cb7d2bc8 --- /dev/null +++ b/src/php/wp-cli/commands/internals/blog.php @@ -0,0 +1,166 @@ + [email] [site_id] [public=(1 or 0)] []" ); + } + + private function get_site($site_id) { + global $wpdb; + // Load site data + $sites = $wpdb->get_results("SELECT * FROM $wpdb->site WHERE `id` = ".$site_id); + if (count($sites) > 0) { + // Only care about domain and path which are set here + return $sites[0]; + } + + return false; + } + + public function create($args) { + if (!is_multisite()) { + WP_CLI::line("ERROR: not a multisite instance"); + exit; + } + global $wpdb; + + // domain required + // title required + // email optional + // site optional + // public optional + if (empty($args[0]) || empty($args[1])) { + $this->_create_usage(); + exit; + } + + $base = $args[0]; + $title = $args[1]; + $email = empty($args[2]) ? '' : $args[2]; + // Site + if (!empty($args[3])) { + $site = $this->get_site($args[3]); + if ($site === false) { + WP_CLI::line('ERROR: Site with id '.$args[3].'does not exist'); + exit; + } + } + else { + $site = wpmu_current_site(); + } + // Public + if (!empty($args[4])) { + $public = $args[4]; + // Check for 1 or 0 + if ($public != '1' && $public != '0') { + $this->_create_usage(); + } + } + else { + $public = 1; + } + + $domain = ''; + if (preg_match( '|^([a-zA-Z0-9-])+$|', $blog['domain'])) { + $domain = strtolower( $blog['domain'] ); + } + + // If not a subdomain install, make sure the domain isn't a reserved word + if (!is_subdomain_install()) { + $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' )); + if (in_array($domain, $subdirectory_reserved_names)) { + WP_CLI::line(sprintf(__('ERROR: The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); + exit; + } + } + + + // Check for valid email, if not, use the first Super Admin found + // Probably a more efficient way to do this so we dont query for the + // User twice if super admin + $email = sanitize_email($email); + if (empty($email) || !is_email($email)) { + //@TODO just use super admin email if not specified + $super_admins = get_super_admins(); + + $email = ''; + if (!empty($super_admins) && is_array($super_admins)) { + // Just get the first one + $super_login = $super_admins[0]; + $super_user = get_user_by('login', $super_login); + if ($super_user) { + $email = $super_user->user_email; + } + } + } + + if ( is_subdomain_install() ) { + $newdomain = $base . '.' . preg_replace( '|^www\.|', '', $site->domain ); + $path = $site->path; + $url = $newdomain; + } else { + $newdomain = $site->domain; + $path = $site->domain.$site->path.$base.'/'; + $url = $path; + } + + $password = 'N/A'; + $user_id = email_exists($email); + if (!$user_id) { // Create a new user with a random password + $password = wp_generate_password(12, false); + $user_id = wpmu_create_user($base, $password, $email); + if (false == $user_id ) { + WP_CLI::line('ERROR: There was an issue creating the user.'); + exit; + } + else { + wp_new_user_notification($user_id, $password); + } + } + + $wpdb->hide_errors(); + $id = wpmu_create_blog($newdomain, $path, $title, $user_id, array( 'public' => $public ), $site->id); + $wpdb->show_errors(); + if (!is_wp_error($id)) { + if ( !is_super_admin($user_id) && !get_user_option('primary_blog', $user_id)) { + update_user_option($user_id, 'primary_blog', $id, true); + } +// $content_mail = sprintf(__( "New site created by WP Command Line Interface\n\nAddress: %2s\nName: %3s"), get_site_url($id), stripslashes($title)); + //@TODO Current site +// wp_mail(get_site_option('admin_email'), sprintf(__('[%s] New Site Created'), $current_site->site_name), $content_mail, 'From: "Site Admin" <'.get_site_option( 'admin_email').'>'); + } + else { + WP_CLI::line($id->get_error_message()); + exit; + } + WP_CLI::line('Blog created with URL: '.$url); + } + + public function update($args) {} + + public function delete($args) {} + + public function help() { + WP_CLI::line( <<<EOB +usage: wp blog <sub-command> [<theme-name>] + +Available sub-commands: + create display status of all installed themes or of a particular theme + + update activate a particular theme + + delete print path to the theme's stylesheet + --dir get the path to the closest parent directory +EOB + ); + } +} \ No newline at end of file From 8d15c5f3d119e6d11eec8c8853edf4ab7912dcb9 Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Wed, 4 Apr 2012 16:14:11 -0600 Subject: [PATCH 0340/4858] strtolower on base, not some unknown $blog var --- src/php/wp-cli/commands/internals/blog.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 45cb7d2bc8..05705b212b 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -69,9 +69,8 @@ public function create($args) { $public = 1; } - $domain = ''; - if (preg_match( '|^([a-zA-Z0-9-])+$|', $blog['domain'])) { - $domain = strtolower( $blog['domain'] ); + if (preg_match( '|^([a-zA-Z0-9-])+$|', $base)) { + $base = strtolower($base); } // If not a subdomain install, make sure the domain isn't a reserved word From d82a9e0d65065bd1e858118560f1765b1dab0c10 Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Wed, 4 Apr 2012 16:32:48 -0600 Subject: [PATCH 0341/4858] Code format tweaks, help dialog actually helpful --- src/php/wp-cli/commands/internals/blog.php | 32 ++++++++++------------ 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 05705b212b..e1a2402d87 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -10,8 +10,8 @@ */ class BlogCommand extends WP_CLI_Command { - private function _create_usage() { - WP_CLI::line( "usage: wp blog create <base> <title> [email] [site_id] [public=(1 or 0)] []" ); + private function _create_usage_string() { + return "usage: wp blog create <domain-base> <title> [email] [site_id] [public=(1 or 0)]"; } private function get_site($site_id) { @@ -39,7 +39,7 @@ public function create($args) { // site optional // public optional if (empty($args[0]) || empty($args[1])) { - $this->_create_usage(); + WP_CLI::line($this->_create_usage_string()); exit; } @@ -88,9 +88,7 @@ public function create($args) { // User twice if super admin $email = sanitize_email($email); if (empty($email) || !is_email($email)) { - //@TODO just use super admin email if not specified $super_admins = get_super_admins(); - $email = ''; if (!empty($super_admins) && is_array($super_admins)) { // Just get the first one @@ -102,11 +100,12 @@ public function create($args) { } } - if ( is_subdomain_install() ) { - $newdomain = $base . '.' . preg_replace( '|^www\.|', '', $site->domain ); + if (is_subdomain_install()) { + $newdomain = $base.'.'.preg_replace('|^www\.|', '', $site->domain); $path = $site->path; $url = $newdomain; - } else { + } + else { $newdomain = $site->domain; $path = $site->domain.$site->path.$base.'/'; $url = $path; @@ -117,7 +116,7 @@ public function create($args) { if (!$user_id) { // Create a new user with a random password $password = wp_generate_password(12, false); $user_id = wpmu_create_user($base, $password, $email); - if (false == $user_id ) { + if (false == $user_id) { WP_CLI::line('ERROR: There was an issue creating the user.'); exit; } @@ -149,17 +148,16 @@ public function update($args) {} public function delete($args) {} public function help() { - WP_CLI::line( <<<EOB -usage: wp blog <sub-command> [<theme-name>] + WP_CLI::line(" +usage: wp blog <sub-command> [options] Available sub-commands: - create display status of all installed themes or of a particular theme + create create a new blog + ".$this->_create_usage_string()." - update activate a particular theme + update //TODO - delete print path to the theme's stylesheet - --dir get the path to the closest parent directory -EOB - ); + delete //TODO +"); } } \ No newline at end of file From 42ce8f2df47779bf6cac41128e6ffdd97620cc93 Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Wed, 4 Apr 2012 16:46:52 -0600 Subject: [PATCH 0342/4858] Make wp blog arugments associative due to the number of optional params --- src/php/wp-cli/commands/internals/blog.php | 37 +++++++++++++--------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index e1a2402d87..2c40dd3525 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -10,11 +10,12 @@ */ class BlogCommand extends WP_CLI_Command { + //@TODO make associative due to optional params private function _create_usage_string() { - return "usage: wp blog create <domain-base> <title> [email] [site_id] [public=(1 or 0)]"; + return "usage: wp blog create --domain_base=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--public]"; } - private function get_site($site_id) { + private function _get_site($site_id) { global $wpdb; // Load site data $sites = $wpdb->get_results("SELECT * FROM $wpdb->site WHERE `id` = ".$site_id); @@ -26,7 +27,7 @@ private function get_site($site_id) { return false; } - public function create($args) { + public function create($args, $assoc_args) { if (!is_multisite()) { WP_CLI::line("ERROR: not a multisite instance"); exit; @@ -38,19 +39,20 @@ public function create($args) { // email optional // site optional // public optional - if (empty($args[0]) || empty($args[1])) { + error_log(print_r($assoc_args,1)); + if (empty($assoc_args['domain_base']) || empty($assoc_args['title'])) { WP_CLI::line($this->_create_usage_string()); exit; } - $base = $args[0]; - $title = $args[1]; - $email = empty($args[2]) ? '' : $args[2]; + $base = $assoc_args['domain_base']; + $title = $assoc_args['title']; + $email = empty($assoc_args['email']) ? '' : $assoc_args['email']; // Site - if (!empty($args[3])) { - $site = $this->get_site($args[3]); + if (!empty($assoc_args['site_id'])) { + $site = $this->_get_site($assoc_args['site_id']); if ($site === false) { - WP_CLI::line('ERROR: Site with id '.$args[3].'does not exist'); + WP_CLI::line('ERROR: Site with id '.$assoc_args['site_id'].'does not exist'); exit; } } @@ -58,8 +60,8 @@ public function create($args) { $site = wpmu_current_site(); } // Public - if (!empty($args[4])) { - $public = $args[4]; + if (!empty($assoc_args['public'])) { + $public = $args['public']; // Check for 1 or 0 if ($public != '1' && $public != '0') { $this->_create_usage(); @@ -148,16 +150,21 @@ public function update($args) {} public function delete($args) {} public function help() { - WP_CLI::line(" + WP_CLI::line(<<<EOB usage: wp blog <sub-command> [options] Available sub-commands: create create a new blog - ".$this->_create_usage_string()." + --domain_base Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs + --title Title of the new blog + [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included + [--site-id] Site to associate new blog with. Defaults to current site (typically 1) + [--public] Whether or not the new site is public (indexed) update //TODO delete //TODO -"); +EOB + ); } } \ No newline at end of file From be2f501026acad7fab791b08cc40168e978054ae Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Fri, 6 Apr 2012 15:22:43 -0600 Subject: [PATCH 0343/4858] Correct usage for site_id --- src/php/wp-cli/commands/internals/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 2c40dd3525..40e3b34356 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -158,7 +158,7 @@ public function help() { --domain_base Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs --title Title of the new blog [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included - [--site-id] Site to associate new blog with. Defaults to current site (typically 1) + [--site_id] Site to associate new blog with. Defaults to current site (typically 1) [--public] Whether or not the new site is public (indexed) update //TODO From 2d6c4eea8fa0ebd9d20040f5e96f755dc6d97a64 Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Tue, 17 Apr 2012 15:05:31 -0600 Subject: [PATCH 0344/4858] Tweaks for sub directory install --- src/php/wp-cli/commands/internals/blog.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 40e3b34356..ac63abaee0 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -39,7 +39,6 @@ public function create($args, $assoc_args) { // email optional // site optional // public optional - error_log(print_r($assoc_args,1)); if (empty($assoc_args['domain_base']) || empty($assoc_args['title'])) { WP_CLI::line($this->_create_usage_string()); exit; @@ -102,15 +101,18 @@ public function create($args, $assoc_args) { } } - if (is_subdomain_install()) { - $newdomain = $base.'.'.preg_replace('|^www\.|', '', $site->domain); - $path = $site->path; - $url = $newdomain; + if (is_subdomain_install()) { + $path = '/'; + $url = $newdomain = $base.'.'.preg_replace('|^www\.|', '', $site->domain); + } else { $newdomain = $site->domain; - $path = $site->domain.$site->path.$base.'/'; - $url = $path; + $path = $base; + if (strpos($path, '/') !== 0) { + $path = '/'.$path; + } + $url = $site->domain; } $password = 'N/A'; @@ -139,10 +141,10 @@ public function create($args, $assoc_args) { // wp_mail(get_site_option('admin_email'), sprintf(__('[%s] New Site Created'), $current_site->site_name), $content_mail, 'From: "Site Admin" <'.get_site_option( 'admin_email').'>'); } else { - WP_CLI::line($id->get_error_message()); + WP_CLI::line('ERROR: '.$id->get_error_message()); exit; } - WP_CLI::line('Blog created with URL: '.$url); + WP_CLI::line('Blog created with URL: '.$url.' ID: '.$id); } public function update($args) {} From 4b52401f689d92c4edff4202ee932e8d8277fe6b Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Fri, 20 Apr 2012 15:18:37 -0600 Subject: [PATCH 0345/4858] Adjustments to output domain, url and Id --- src/php/wp-cli/commands/internals/blog.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index ac63abaee0..7a374b05b5 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -96,6 +96,8 @@ public function create($args, $assoc_args) { $super_login = $super_admins[0]; $super_user = get_user_by('login', $super_login); if ($super_user) { + error_log($super_user->user_email); + error_log($super_user->email); $email = $super_user->user_email; } } @@ -112,7 +114,7 @@ public function create($args, $assoc_args) { if (strpos($path, '/') !== 0) { $path = '/'.$path; } - $url = $site->domain; + $url = $site->domain.$path; } $password = 'N/A'; @@ -144,7 +146,7 @@ public function create($args, $assoc_args) { WP_CLI::line('ERROR: '.$id->get_error_message()); exit; } - WP_CLI::line('Blog created with URL: '.$url.' ID: '.$id); + WP_CLI::line('Blog created with DOMAIN: '.$site->domain.' URL: '.$url.' ID: '.$id); } public function update($args) {} From 54e8bfb9d56f3de15cd3923d92dc1288f8b9e2c0 Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Mon, 30 Apr 2012 16:41:38 -0600 Subject: [PATCH 0346/4858] Cleanup of testing code, using built in error method to provide errors --- src/php/wp-cli/commands/internals/blog.php | 47 +++++++++++++--------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 7a374b05b5..63a837f397 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -10,15 +10,20 @@ */ class BlogCommand extends WP_CLI_Command { - //@TODO make associative due to optional params private function _create_usage_string() { return "usage: wp blog create --domain_base=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--public]"; } + /** + * Get site (network) data for a given id + * + * @param int $site_id + * @return bool|array False if no network found with given id, array otherwise + */ private function _get_site($site_id) { global $wpdb; // Load site data - $sites = $wpdb->get_results("SELECT * FROM $wpdb->site WHERE `id` = ".$site_id); + $sites = $wpdb->get_results("SELECT * FROM $wpdb->site WHERE `id` = ".$wpdb->escape($site_id)); if (count($sites) > 0) { // Only care about domain and path which are set here return $sites[0]; @@ -27,9 +32,16 @@ private function _get_site($site_id) { return false; } + /** + * Create a blog via passed in arguments + * + * @see BlogCommand::help() + * @param array $args + * @param array $assoc_args + */ public function create($args, $assoc_args) { if (!is_multisite()) { - WP_CLI::line("ERROR: not a multisite instance"); + WP_CLI::error("Not a multisite instance"); exit; } global $wpdb; @@ -51,25 +63,27 @@ public function create($args, $assoc_args) { if (!empty($assoc_args['site_id'])) { $site = $this->_get_site($assoc_args['site_id']); if ($site === false) { - WP_CLI::line('ERROR: Site with id '.$assoc_args['site_id'].'does not exist'); + WP_CLI::error('Site with id '.$assoc_args['site_id'].' does not exist'); exit; } } else { $site = wpmu_current_site(); } - // Public + // Public, default is true (1) if (!empty($assoc_args['public'])) { $public = $args['public']; // Check for 1 or 0 if ($public != '1' && $public != '0') { $this->_create_usage(); + exit; } } else { $public = 1; } - + + // Sanitize if (preg_match( '|^([a-zA-Z0-9-])+$|', $base)) { $base = strtolower($base); } @@ -78,12 +92,11 @@ public function create($args, $assoc_args) { if (!is_subdomain_install()) { $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' )); if (in_array($domain, $subdirectory_reserved_names)) { - WP_CLI::line(sprintf(__('ERROR: The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); + WP_CLI::error(sprintf(__('The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); exit; } } - // Check for valid email, if not, use the first Super Admin found // Probably a more efficient way to do this so we dont query for the // User twice if super admin @@ -96,8 +109,6 @@ public function create($args, $assoc_args) { $super_login = $super_admins[0]; $super_user = get_user_by('login', $super_login); if ($super_user) { - error_log($super_user->user_email); - error_log($super_user->email); $email = $super_user->user_email; } } @@ -106,7 +117,6 @@ public function create($args, $assoc_args) { if (is_subdomain_install()) { $path = '/'; $url = $newdomain = $base.'.'.preg_replace('|^www\.|', '', $site->domain); - } else { $newdomain = $site->domain; @@ -123,7 +133,7 @@ public function create($args, $assoc_args) { $password = wp_generate_password(12, false); $user_id = wpmu_create_user($base, $password, $email); if (false == $user_id) { - WP_CLI::line('ERROR: There was an issue creating the user.'); + WP_CLI::error('There was an issue creating the user.'); exit; } else { @@ -138,15 +148,16 @@ public function create($args, $assoc_args) { if ( !is_super_admin($user_id) && !get_user_option('primary_blog', $user_id)) { update_user_option($user_id, 'primary_blog', $id, true); } -// $content_mail = sprintf(__( "New site created by WP Command Line Interface\n\nAddress: %2s\nName: %3s"), get_site_url($id), stripslashes($title)); - //@TODO Current site -// wp_mail(get_site_option('admin_email'), sprintf(__('[%s] New Site Created'), $current_site->site_name), $content_mail, 'From: "Site Admin" <'.get_site_option( 'admin_email').'>'); + // Prevent mailing admins of new sites + // @TODO argument to pass in? + // $content_mail = sprintf(__( "New site created by WP Command Line Interface\n\nAddress: %2s\nName: %3s"), get_site_url($id), stripslashes($title)); + // wp_mail(get_site_option('admin_email'), sprintf(__('[%s] New Site Created'), $current_site->site_name), $content_mail, 'From: "Site Admin" <'.get_site_option( 'admin_email').'>'); } else { - WP_CLI::line('ERROR: '.$id->get_error_message()); + WP_CLI::error($id->get_error_message()); exit; } - WP_CLI::line('Blog created with DOMAIN: '.$site->domain.' URL: '.$url.' ID: '.$id); + WP_CLI::line('Blog created with domain: '.$site->domain.' url: '.$url.' id: '.$id); } public function update($args) {} @@ -162,7 +173,7 @@ public function help() { --domain_base Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs --title Title of the new blog [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included - [--site_id] Site to associate new blog with. Defaults to current site (typically 1) + [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) [--public] Whether or not the new site is public (indexed) update //TODO From 5cbd7fcc759c85675729ceeb605063afd04c88a2 Mon Sep 17 00:00:00 2001 From: Evan Anderson <ejdanderson@gmail.com> Date: Mon, 30 Apr 2012 17:12:44 -0600 Subject: [PATCH 0347/4858] no need to exit when using error --- src/php/wp-cli/commands/internals/blog.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 63a837f397..100b34a6b3 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -42,7 +42,6 @@ private function _get_site($site_id) { public function create($args, $assoc_args) { if (!is_multisite()) { WP_CLI::error("Not a multisite instance"); - exit; } global $wpdb; @@ -53,7 +52,7 @@ public function create($args, $assoc_args) { // public optional if (empty($assoc_args['domain_base']) || empty($assoc_args['title'])) { WP_CLI::line($this->_create_usage_string()); - exit; + exit(1); } $base = $assoc_args['domain_base']; @@ -64,7 +63,6 @@ public function create($args, $assoc_args) { $site = $this->_get_site($assoc_args['site_id']); if ($site === false) { WP_CLI::error('Site with id '.$assoc_args['site_id'].' does not exist'); - exit; } } else { @@ -93,7 +91,6 @@ public function create($args, $assoc_args) { $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' )); if (in_array($domain, $subdirectory_reserved_names)) { WP_CLI::error(sprintf(__('The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); - exit; } } @@ -134,7 +131,6 @@ public function create($args, $assoc_args) { $user_id = wpmu_create_user($base, $password, $email); if (false == $user_id) { WP_CLI::error('There was an issue creating the user.'); - exit; } else { wp_new_user_notification($user_id, $password); @@ -155,7 +151,6 @@ public function create($args, $assoc_args) { } else { WP_CLI::error($id->get_error_message()); - exit; } WP_CLI::line('Blog created with domain: '.$site->domain.' url: '.$url.' id: '.$id); } From d776f58e60409c6cda1f90c92e0c8a87c6f632cb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 02:53:29 +0300 Subject: [PATCH 0348/4858] s/BlogCommand/Blog_Command/g --- src/php/wp-cli/commands/internals/blog.php | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 100b34a6b3..f86e38ab70 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -1,6 +1,6 @@ <?php -WP_CLI::addCommand('blog', 'BlogCommand'); +WP_CLI::addCommand('blog', 'Blog_Command'); /** * Implement core command @@ -8,16 +8,16 @@ * @package wp-cli * @subpackage commands/internals */ -class BlogCommand extends WP_CLI_Command { - +class Blog_Command extends WP_CLI_Command { + private function _create_usage_string() { return "usage: wp blog create --domain_base=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--public]"; } - + /** * Get site (network) data for a given id * - * @param int $site_id + * @param int $site_id * @return bool|array False if no network found with given id, array otherwise */ private function _get_site($site_id) { @@ -28,23 +28,23 @@ private function _get_site($site_id) { // Only care about domain and path which are set here return $sites[0]; } - + return false; } - + /** * Create a blog via passed in arguments * * @see BlogCommand::help() - * @param array $args - * @param array $assoc_args + * @param array $args + * @param array $assoc_args */ public function create($args, $assoc_args) { if (!is_multisite()) { WP_CLI::error("Not a multisite instance"); } global $wpdb; - + // domain required // title required // email optional @@ -54,7 +54,7 @@ public function create($args, $assoc_args) { WP_CLI::line($this->_create_usage_string()); exit(1); } - + $base = $assoc_args['domain_base']; $title = $assoc_args['title']; $email = empty($assoc_args['email']) ? '' : $assoc_args['email']; @@ -80,12 +80,12 @@ public function create($args, $assoc_args) { else { $public = 1; } - + // Sanitize if (preg_match( '|^([a-zA-Z0-9-])+$|', $base)) { $base = strtolower($base); } - + // If not a subdomain install, make sure the domain isn't a reserved word if (!is_subdomain_install()) { $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' )); @@ -93,7 +93,7 @@ public function create($args, $assoc_args) { WP_CLI::error(sprintf(__('The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); } } - + // Check for valid email, if not, use the first Super Admin found // Probably a more efficient way to do this so we dont query for the // User twice if super admin @@ -111,10 +111,10 @@ public function create($args, $assoc_args) { } } - if (is_subdomain_install()) { + if (is_subdomain_install()) { $path = '/'; $url = $newdomain = $base.'.'.preg_replace('|^www\.|', '', $site->domain); - } + } else { $newdomain = $site->domain; $path = $base; @@ -123,7 +123,7 @@ public function create($args, $assoc_args) { } $url = $site->domain.$path; } - + $password = 'N/A'; $user_id = email_exists($email); if (!$user_id) { // Create a new user with a random password @@ -136,7 +136,7 @@ public function create($args, $assoc_args) { wp_new_user_notification($user_id, $password); } } - + $wpdb->hide_errors(); $id = wpmu_create_blog($newdomain, $path, $title, $user_id, array( 'public' => $public ), $site->id); $wpdb->show_errors(); @@ -148,17 +148,17 @@ public function create($args, $assoc_args) { // @TODO argument to pass in? // $content_mail = sprintf(__( "New site created by WP Command Line Interface\n\nAddress: %2s\nName: %3s"), get_site_url($id), stripslashes($title)); // wp_mail(get_site_option('admin_email'), sprintf(__('[%s] New Site Created'), $current_site->site_name), $content_mail, 'From: "Site Admin" <'.get_site_option( 'admin_email').'>'); - } + } else { WP_CLI::error($id->get_error_message()); - } + } WP_CLI::line('Blog created with domain: '.$site->domain.' url: '.$url.' id: '.$id); } - + public function update($args) {} - + public function delete($args) {} - + public function help() { WP_CLI::line(<<<EOB usage: wp blog <sub-command> [options] @@ -177,4 +177,4 @@ public function help() { EOB ); } -} \ No newline at end of file +} From 8ec98c720c06e160b6b87319a9355b84b04e6c33 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 02:58:07 +0300 Subject: [PATCH 0349/4858] rename domain_base parameter to slug. see #104 --- src/php/wp-cli/commands/internals/blog.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index f86e38ab70..246ed88c0f 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -11,7 +11,7 @@ class Blog_Command extends WP_CLI_Command { private function _create_usage_string() { - return "usage: wp blog create --domain_base=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--public]"; + return "usage: wp blog create --slug=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--public]"; } /** @@ -50,12 +50,12 @@ public function create($args, $assoc_args) { // email optional // site optional // public optional - if (empty($assoc_args['domain_base']) || empty($assoc_args['title'])) { + if (empty($assoc_args['slug']) || empty($assoc_args['title'])) { WP_CLI::line($this->_create_usage_string()); exit(1); } - $base = $assoc_args['domain_base']; + $base = $assoc_args['slug']; $title = $assoc_args['title']; $email = empty($assoc_args['email']) ? '' : $assoc_args['email']; // Site @@ -165,7 +165,7 @@ public function help() { Available sub-commands: create create a new blog - --domain_base Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs + --slug Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs --title Title of the new blog [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) From 67a987a1d4838581e6f957b929822080e0af110e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 03:03:14 +0300 Subject: [PATCH 0350/4858] use correct variable --- src/php/wp-cli/commands/internals/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 246ed88c0f..136d37bd84 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -89,7 +89,7 @@ public function create($args, $assoc_args) { // If not a subdomain install, make sure the domain isn't a reserved word if (!is_subdomain_install()) { $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' )); - if (in_array($domain, $subdirectory_reserved_names)) { + if (in_array($base, $subdirectory_reserved_names)) { WP_CLI::error(sprintf(__('The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); } } From 4dc51211ca8e057d0767007d819c55c78a0f7ba8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 03:25:05 +0300 Subject: [PATCH 0351/4858] use WP_CLI::success() and make message more compact. see #104 --- src/php/wp-cli/commands/internals/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 136d37bd84..6ff19c4fcb 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -152,7 +152,7 @@ public function create($args, $assoc_args) { else { WP_CLI::error($id->get_error_message()); } - WP_CLI::line('Blog created with domain: '.$site->domain.' url: '.$url.' id: '.$id); + WP_CLI::success("Blog $id created: $url"); } public function update($args) {} From 7753240e2c210b1a7a97ff1e17f59627d5f3442d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 03:30:09 +0300 Subject: [PATCH 0352/4858] terser error message --- src/php/wp-cli/commands/internals/blog.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 6ff19c4fcb..a666cb95a3 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -124,13 +124,12 @@ public function create($args, $assoc_args) { $url = $site->domain.$path; } - $password = 'N/A'; $user_id = email_exists($email); if (!$user_id) { // Create a new user with a random password $password = wp_generate_password(12, false); $user_id = wpmu_create_user($base, $password, $email); if (false == $user_id) { - WP_CLI::error('There was an issue creating the user.'); + WP_CLI::error("Can't create user."); } else { wp_new_user_notification($user_id, $password); From 5d5e8ece9ec3a811773a72fdc47da712ce872859 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 03:38:30 +0300 Subject: [PATCH 0353/4858] always add trailing slash to path. see #104 --- src/php/wp-cli/commands/internals/blog.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index a666cb95a3..6859dd5790 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -117,11 +117,8 @@ public function create($args, $assoc_args) { } else { $newdomain = $site->domain; - $path = $base; - if (strpos($path, '/') !== 0) { - $path = '/'.$path; - } - $url = $site->domain.$path; + $path = '/' . trim( $base, '/' ) . '/'; + $url = $site->domain . $path; } $user_id = email_exists($email); From 6dcfd1580dcbd74842539c959593df7314b8fb92 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 17:55:10 +0300 Subject: [PATCH 0354/4858] disable placeholder commands so that they don't show up in the general help --- src/php/wp-cli/commands/internals/blog.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 6859dd5790..b6f1b0a2a1 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -151,9 +151,9 @@ public function create($args, $assoc_args) { WP_CLI::success("Blog $id created: $url"); } - public function update($args) {} + /* public function update($args) {} */ - public function delete($args) {} + /* public function delete($args) {} */ public function help() { WP_CLI::line(<<<EOB @@ -166,10 +166,6 @@ public function help() { [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) [--public] Whether or not the new site is public (indexed) - - update //TODO - - delete //TODO EOB ); } From c4e3999f3a0d55e863cbf0e5168f07366c5b8383 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 17:56:17 +0300 Subject: [PATCH 0355/4858] don't enable the blog command on non-multisite installs. see #104 --- src/php/wp-cli/commands/internals/blog.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index b6f1b0a2a1..f9cf7ed6f0 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -1,6 +1,8 @@ <?php -WP_CLI::addCommand('blog', 'Blog_Command'); +if ( is_multisite() ) { + WP_CLI::addCommand( 'blog', 'Blog_Command' ); +} /** * Implement core command @@ -40,9 +42,6 @@ private function _get_site($site_id) { * @param array $assoc_args */ public function create($args, $assoc_args) { - if (!is_multisite()) { - WP_CLI::error("Not a multisite instance"); - } global $wpdb; // domain required From ede7ca89a5d8af0825750c2fce99bd9fc4741190 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 17:58:27 +0300 Subject: [PATCH 0356/4858] use add_command() --- src/php/wp-cli/commands/internals/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index f9cf7ed6f0..7449e1b912 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -1,7 +1,7 @@ <?php if ( is_multisite() ) { - WP_CLI::addCommand( 'blog', 'Blog_Command' ); + WP_CLI::add_command( 'blog', 'Blog_Command' ); } /** From 87b2f215120832b56717548aa43ad1b1fadb3719 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 18:00:39 +0300 Subject: [PATCH 0357/4858] coding standards --- src/php/wp-cli/commands/internals/blog.php | 90 +++++++++++----------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 7449e1b912..8c88b31fcd 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -19,14 +19,14 @@ private function _create_usage_string() { /** * Get site (network) data for a given id * - * @param int $site_id + * @param int $site_id * @return bool|array False if no network found with given id, array otherwise */ - private function _get_site($site_id) { + private function _get_site( $site_id ) { global $wpdb; // Load site data - $sites = $wpdb->get_results("SELECT * FROM $wpdb->site WHERE `id` = ".$wpdb->escape($site_id)); - if (count($sites) > 0) { + $sites = $wpdb->get_results( "SELECT * FROM $wpdb->site WHERE `id` = ".$wpdb->escape( $site_id ) ); + if ( count( $sites ) > 0 ) { // Only care about domain and path which are set here return $sites[0]; } @@ -38,10 +38,10 @@ private function _get_site($site_id) { * Create a blog via passed in arguments * * @see BlogCommand::help() - * @param array $args - * @param array $assoc_args + * @param array $args + * @param array $assoc_args */ - public function create($args, $assoc_args) { + public function create( $args, $assoc_args ) { global $wpdb; // domain required @@ -49,29 +49,29 @@ public function create($args, $assoc_args) { // email optional // site optional // public optional - if (empty($assoc_args['slug']) || empty($assoc_args['title'])) { - WP_CLI::line($this->_create_usage_string()); - exit(1); + if ( empty( $assoc_args['slug'] ) || empty( $assoc_args['title'] ) ) { + WP_CLI::line( $this->_create_usage_string() ); + exit( 1 ); } $base = $assoc_args['slug']; $title = $assoc_args['title']; - $email = empty($assoc_args['email']) ? '' : $assoc_args['email']; + $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; // Site - if (!empty($assoc_args['site_id'])) { - $site = $this->_get_site($assoc_args['site_id']); - if ($site === false) { - WP_CLI::error('Site with id '.$assoc_args['site_id'].' does not exist'); + if ( !empty( $assoc_args['site_id'] ) ) { + $site = $this->_get_site( $assoc_args['site_id'] ); + if ( $site === false ) { + WP_CLI::error( 'Site with id '.$assoc_args['site_id'].' does not exist' ); } } else { $site = wpmu_current_site(); } // Public, default is true (1) - if (!empty($assoc_args['public'])) { + if ( !empty( $assoc_args['public'] ) ) { $public = $args['public']; // Check for 1 or 0 - if ($public != '1' && $public != '0') { + if ( $public != '1' && $public != '0' ) { $this->_create_usage(); exit; } @@ -81,38 +81,38 @@ public function create($args, $assoc_args) { } // Sanitize - if (preg_match( '|^([a-zA-Z0-9-])+$|', $base)) { - $base = strtolower($base); + if ( preg_match( '|^([a-zA-Z0-9-])+$|', $base ) ) { + $base = strtolower( $base ); } // If not a subdomain install, make sure the domain isn't a reserved word - if (!is_subdomain_install()) { - $subdirectory_reserved_names = apply_filters('subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' )); - if (in_array($base, $subdirectory_reserved_names)) { - WP_CLI::error(sprintf(__('The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>'), implode('</code>, <code>', $subdirectory_reserved_names))); + if ( !is_subdomain_install() ) { + $subdirectory_reserved_names = apply_filters( 'subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' ) ); + if ( in_array( $base, $subdirectory_reserved_names ) ) { + WP_CLI::error( sprintf( __( 'The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>' ), implode( '</code>, <code>', $subdirectory_reserved_names ) ) ); } } // Check for valid email, if not, use the first Super Admin found // Probably a more efficient way to do this so we dont query for the // User twice if super admin - $email = sanitize_email($email); - if (empty($email) || !is_email($email)) { + $email = sanitize_email( $email ); + if ( empty( $email ) || !is_email( $email ) ) { $super_admins = get_super_admins(); $email = ''; - if (!empty($super_admins) && is_array($super_admins)) { + if ( !empty( $super_admins ) && is_array( $super_admins ) ) { // Just get the first one $super_login = $super_admins[0]; - $super_user = get_user_by('login', $super_login); - if ($super_user) { + $super_user = get_user_by( 'login', $super_login ); + if ( $super_user ) { $email = $super_user->user_email; } } } - if (is_subdomain_install()) { + if ( is_subdomain_install() ) { $path = '/'; - $url = $newdomain = $base.'.'.preg_replace('|^www\.|', '', $site->domain); + $url = $newdomain = $base.'.'.preg_replace( '|^www\.|', '', $site->domain ); } else { $newdomain = $site->domain; @@ -120,24 +120,24 @@ public function create($args, $assoc_args) { $url = $site->domain . $path; } - $user_id = email_exists($email); - if (!$user_id) { // Create a new user with a random password - $password = wp_generate_password(12, false); - $user_id = wpmu_create_user($base, $password, $email); - if (false == $user_id) { - WP_CLI::error("Can't create user."); + $user_id = email_exists( $email ); + if ( !$user_id ) { // Create a new user with a random password + $password = wp_generate_password( 12, false ); + $user_id = wpmu_create_user( $base, $password, $email ); + if ( false == $user_id ) { + WP_CLI::error( "Can't create user." ); } else { - wp_new_user_notification($user_id, $password); + wp_new_user_notification( $user_id, $password ); } } $wpdb->hide_errors(); - $id = wpmu_create_blog($newdomain, $path, $title, $user_id, array( 'public' => $public ), $site->id); + $id = wpmu_create_blog( $newdomain, $path, $title, $user_id, array( 'public' => $public ), $site->id ); $wpdb->show_errors(); - if (!is_wp_error($id)) { - if ( !is_super_admin($user_id) && !get_user_option('primary_blog', $user_id)) { - update_user_option($user_id, 'primary_blog', $id, true); + if ( !is_wp_error( $id ) ) { + if ( !is_super_admin( $user_id ) && !get_user_option( 'primary_blog', $user_id ) ) { + update_user_option( $user_id, 'primary_blog', $id, true ); } // Prevent mailing admins of new sites // @TODO argument to pass in? @@ -145,9 +145,9 @@ public function create($args, $assoc_args) { // wp_mail(get_site_option('admin_email'), sprintf(__('[%s] New Site Created'), $current_site->site_name), $content_mail, 'From: "Site Admin" <'.get_site_option( 'admin_email').'>'); } else { - WP_CLI::error($id->get_error_message()); + WP_CLI::error( $id->get_error_message() ); } - WP_CLI::success("Blog $id created: $url"); + WP_CLI::success( "Blog $id created: $url" ); } /* public function update($args) {} */ @@ -155,7 +155,7 @@ public function create($args, $assoc_args) { /* public function delete($args) {} */ public function help() { - WP_CLI::line(<<<EOB + WP_CLI::line( <<<EOB usage: wp blog <sub-command> [options] Available sub-commands: @@ -166,6 +166,6 @@ public function help() { [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) [--public] Whether or not the new site is public (indexed) EOB - ); + ); } } From c6b8ca54a3f40913140f8723062079fb0203323d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 18:05:32 +0300 Subject: [PATCH 0358/4858] more appropriate error message for reserved blog names --- src/php/wp-cli/commands/internals/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 8c88b31fcd..627e87a396 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -89,7 +89,7 @@ public function create( $args, $assoc_args ) { if ( !is_subdomain_install() ) { $subdirectory_reserved_names = apply_filters( 'subdirectory_reserved_names', array( 'page', 'comments', 'blog', 'files', 'feed' ) ); if ( in_array( $base, $subdirectory_reserved_names ) ) { - WP_CLI::error( sprintf( __( 'The following words are reserved for use by WordPress functions and cannot be used as blog names: <code>%s</code>' ), implode( '</code>, <code>', $subdirectory_reserved_names ) ) ); + WP_CLI::error( 'The following words are reserved and cannot be used as blog names: ' . implode( ', ', $subdirectory_reserved_names ) ); } } From 7e504c4335f46f2444448d81d36df562a7eb9f8a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 18:14:14 +0300 Subject: [PATCH 0359/4858] export: exit with an error status when not all required parameters are set --- src/php/wp-cli/commands/internals/export.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 6c6e15cdda..d24b13da54 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -60,8 +60,8 @@ public function validate_arguments( $args, $assoc_args ) { } } - if ( true === $has_errors ) { - exit; + if ( $has_errors ) { + exit(1); } $this->wxr_path = $assoc_args['path']; @@ -79,7 +79,6 @@ private function check_path( $path ) { if ( !is_dir( $path ) ) { WP_CLI::error( sprintf( "The path %s does not exist", $path ) ); - exit; } return true; From 3d50bbf12227d886d41da5c5f39c1ee4e8264309 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 18:14:49 +0300 Subject: [PATCH 0360/4858] show missing parameters instead of just usage string --- src/php/wp-cli/commands/internals/blog.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 627e87a396..3d50ee1d11 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -44,16 +44,18 @@ private function _get_site( $site_id ) { public function create( $args, $assoc_args ) { global $wpdb; - // domain required - // title required - // email optional - // site optional - // public optional - if ( empty( $assoc_args['slug'] ) || empty( $assoc_args['title'] ) ) { - WP_CLI::line( $this->_create_usage_string() ); - exit( 1 ); + $has_errors = false; + + foreach ( array( 'slug', 'title' ) as $required ) { + if ( empty( $assoc_args[$required] ) ) { + WP_CLI::warning( "missing --$required parameter" ); + $has_errors = true; + } } + if ( $has_errors ) + exit(1); + $base = $assoc_args['slug']; $title = $assoc_args['title']; $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; From 4936d5ce36f0fdf6ea0f74497bccc79c35b8c822 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 21:44:35 +0300 Subject: [PATCH 0361/4858] look for {command}.md files for help info --- src/doc/general.md | 9 ++++ src/php/wp-cli/class-wp-cli.php | 10 +++- src/php/wp-cli/commands/internals/help.php | 53 ++++++++++++---------- 3 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 src/doc/general.md diff --git a/src/doc/general.md b/src/doc/general.md new file mode 100644 index 0000000000..7a7fbfbd7f --- /dev/null +++ b/src/doc/general.md @@ -0,0 +1,9 @@ + +See 'wp help <command>' for more information on a specific command. + +Global parameters: + --user=<id|login> set the current user + --url=<url> set the current URL + --path=<path> set the current path to the WP install + --require=<path> load a certain file before running the command + --version print wp-cli version diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 656e94ce9c..79bbecb49f 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -278,8 +278,16 @@ private function load_command( $command ) { } } + static function get_path( $which ) { + switch ( $which ) { + case 'doc': + // TODO: pear config-get doc_dir + return WP_CLI_ROOT . "../../doc/"; + } + } + // back-compat - public function addCommand( $name, $class ) { + static function addCommand( $name, $class ) { self::add_command( $name, $class ); } } diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 98b6d1580f..2453240c30 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -18,27 +18,37 @@ class Help_Command extends WP_CLI_Command { public function __construct( $args ) { if ( empty( $args ) ) { $this->general_help(); - } else { - $command = $args[0]; - - if ( !isset( WP_CLI::$commands[$command] ) ) { - WP_CLI::error( "'$command' is not a registered wp command." ); - } elseif ( 'help' == $command ) { - // prevent endless loop - $this->general_help(); + return; + } + + $command = $args[0]; + + if ( !isset( WP_CLI::$commands[$command] ) ) + WP_CLI::error( "'$command' is not a registered wp command." ); + + if ( !$this->show_help( $command ) ) { + $class = WP_CLI::$commands[$command]; + + if ( method_exists( $class, 'help' ) ) { + $class::help(); } else { - $class = WP_CLI::$commands[$command]; - - if ( method_exists( $class, 'help' ) ) { - $class::help(); - } else { - WP_CLI::line( 'Example usage:' ); - $this->single_command_help( $command, $class ); - } + WP_CLI::line( 'Example usage:' ); + $this->single_command_help( $command, $class ); } } } + private function show_help( $command ) { + $doc_file = WP_CLI::get_path( 'doc' ) . "$command.md"; + + if ( !is_readable( $doc_file ) ) + return false; + + echo file_get_contents( $doc_file ); + + return true; + } + private function general_help() { WP_CLI::line( 'Available commands:' ); foreach ( WP_CLI::$commands as $name => $command ) { @@ -47,15 +57,8 @@ private function general_help() { $this->single_command_help( $name, $command ); } - WP_CLI::line(); - WP_CLI::line( "See 'wp help <command>' for more information on a specific command." ); - WP_CLI::line(); - WP_CLI::line( 'Global parameters:' ); - WP_CLI::line( ' --user=<id|login> set the current user' ); - WP_CLI::line( ' --url=<url> set the current URL' ); - WP_CLI::line( ' --path=<path> set the current path to the WP install' ); - WP_CLI::line( ' --require=<path> load a certain file before running the command' ); - WP_CLI::line( ' --version print wp-cli version' ); + + $this->show_help( 'general' ); } private function single_command_help( $name, $command ) { From 15c2ac739a175040df9377d877383a1c0cafee11 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 19:43:42 +0300 Subject: [PATCH 0362/4858] move help text to doc dir for internal commands --- src/doc/blog.md | 9 +++++ src/doc/core.md | 5 +++ src/doc/db.md | 14 ++++++++ src/doc/eval-file.md | 3 ++ src/doc/eval.md | 3 ++ src/doc/export.md | 14 ++++++++ src/doc/generate.md | 2 ++ src/doc/home.md | 3 ++ src/doc/option.md | 4 +++ src/doc/plugin.md | 27 ++++++++++++++ src/doc/theme.md | 18 ++++++++++ src/doc/transient.md | 4 +++ src/doc/user.md | 4 +++ src/php/wp-cli/commands/internals/blog.php | 19 ---------- src/php/wp-cli/commands/internals/core.php | 14 -------- src/php/wp-cli/commands/internals/db.php | 23 ------------ .../wp-cli/commands/internals/eval-file.php | 12 ------- src/php/wp-cli/commands/internals/eval.php | 12 ------- src/php/wp-cli/commands/internals/export.php | 23 ------------ .../wp-cli/commands/internals/generate.php | 11 ------ src/php/wp-cli/commands/internals/home.php | 12 ------- src/php/wp-cli/commands/internals/option.php | 15 +------- src/php/wp-cli/commands/internals/plugin.php | 36 ------------------- src/php/wp-cli/commands/internals/theme.php | 27 -------------- .../wp-cli/commands/internals/transient.php | 19 ++-------- src/php/wp-cli/commands/internals/user.php | 13 ------- 26 files changed, 114 insertions(+), 232 deletions(-) create mode 100644 src/doc/blog.md create mode 100644 src/doc/core.md create mode 100644 src/doc/db.md create mode 100644 src/doc/eval-file.md create mode 100644 src/doc/eval.md create mode 100644 src/doc/export.md create mode 100644 src/doc/generate.md create mode 100644 src/doc/home.md create mode 100644 src/doc/option.md create mode 100644 src/doc/plugin.md create mode 100644 src/doc/theme.md create mode 100644 src/doc/transient.md create mode 100644 src/doc/user.md diff --git a/src/doc/blog.md b/src/doc/blog.md new file mode 100644 index 0000000000..15ceea00f3 --- /dev/null +++ b/src/doc/blog.md @@ -0,0 +1,9 @@ +usage: wp blog <sub-command> [options] + +Available sub-commands: + create create a new blog + --slug Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs + --title Title of the new blog + [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included + [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) + [--public] Whether or not the new site is public (indexed) diff --git a/src/doc/core.md b/src/doc/core.md new file mode 100644 index 0000000000..eddc818afb --- /dev/null +++ b/src/doc/core.md @@ -0,0 +1,5 @@ +usage: wp core update + or: wp core version [--extra] + or: wp core download [--version=1.2.3] + or: wp core config --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=localhost] [--dbprefix=wp_] + or: wp core install --site_url=example.com --site_title=<site-title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email-address> diff --git a/src/doc/db.md b/src/doc/db.md new file mode 100644 index 0000000000..e318225e4f --- /dev/null +++ b/src/doc/db.md @@ -0,0 +1,14 @@ +usage: wp db <sub-command> [<file>] + +Available sub-commands: + cli Open a SQL command-line interface using the WordPress credentials. + + connect Print a string for connecting to the database. + + export Export the WordPress database using mysqldump. + + import Import a database exported via mysqldump. + + query Execute a query against the WordPress database. + + create Create a database using the info from wp-config.php. diff --git a/src/doc/eval-file.md b/src/doc/eval-file.md new file mode 100644 index 0000000000..c626a93530 --- /dev/null +++ b/src/doc/eval-file.md @@ -0,0 +1,3 @@ +example: wp eval-file some-file.php + +Loads and executes a PHP file after bootstrapping WordPress. diff --git a/src/doc/eval.md b/src/doc/eval.md new file mode 100644 index 0000000000..1005333a6c --- /dev/null +++ b/src/doc/eval.md @@ -0,0 +1,3 @@ +example: wp eval 'echo WP_CONTENT_DIR;' + +Executes arbitrary PHP code after bootstrapping WordPress. diff --git a/src/doc/export.md b/src/doc/export.md new file mode 100644 index 0000000000..ea644d8628 --- /dev/null +++ b/src/doc/export.md @@ -0,0 +1,14 @@ +usage: wp export --path=<export-path> --user=<username/id> + or: wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + +Required parameters: + --path Full Path to directory where WXR export files should be stored + +Optional filters: + --start_date Export only posts new than this date in format YYYY-MM-DD + --end_date Export only posts older than this date in format YYYY-MM-DD + --post_type Export only posts with this post_type + --author Export only posts by this author + --category Export only posts in this category + --post_status Export only posts with this post_status + --skip_comments Don't export comments diff --git a/src/doc/generate.md b/src/doc/generate.md new file mode 100644 index 0000000000..8b2364fb21 --- /dev/null +++ b/src/doc/generate.md @@ -0,0 +1,2 @@ +usage: wp generate posts [--count=100] [--type=post] [--status=publish] [--author=<login>] + or: wp generate users [--count=100] [--role=<role>] diff --git a/src/doc/home.md b/src/doc/home.md new file mode 100644 index 0000000000..5abbdf9954 --- /dev/null +++ b/src/doc/home.md @@ -0,0 +1,3 @@ +usage: wp home + +Opens the wp-cli homepage in your browser. diff --git a/src/doc/option.md b/src/doc/option.md new file mode 100644 index 0000000000..2985f7b7ff --- /dev/null +++ b/src/doc/option.md @@ -0,0 +1,4 @@ +usage: wp option get <option-name> + or: wp option add <option-name> <option-value> + or: wp option update <option-name> <option-value> + or: wp option delete <option-name> diff --git a/src/doc/plugin.md b/src/doc/plugin.md new file mode 100644 index 0000000000..6903e12900 --- /dev/null +++ b/src/doc/plugin.md @@ -0,0 +1,27 @@ +usage: wp plugin <sub-command> [<plugin-name>] + or: wp plugin path [<plugin-name>] [--dir] + or: wp plugin install <plugin-name> [--activate] [--dev] [--version=1.2.3] + +Available sub-commands: + status display status of all installed plugins or of a particular plugin + + activate activate a particular plugin + + deactivate deactivate a particular plugin + + toggle toggle activation state of a particular plugin + + path print path to the plugin's file + --dir get the path to the closest parent directory + + install install a plugin from wordpress.org or from a zip file + --activate activate the plugin after installing it + --dev install the development version + --version install a specific version + + update update a plugin from wordpress.org + --all update all plugins from wordpress.org + + uninstall run the uninstallation procedure for a plugin + + delete delete a plugin diff --git a/src/doc/theme.md b/src/doc/theme.md new file mode 100644 index 0000000000..094d7be4a1 --- /dev/null +++ b/src/doc/theme.md @@ -0,0 +1,18 @@ +usage: wp theme <sub-command> [<theme-name>] + or: wp theme path [<theme-name>] [--dir] + +Available sub-commands: + status display status of all installed themes or of a particular theme + + activate activate a particular theme + + path print path to the theme's stylesheet + --dir get the path to the closest parent directory + + install install a theme from wordpress.org or from a zip file + --activate activate the theme after installing it + + update update a theme from wordpress.org + --all update all themes from wordpress.org + + delete delete a theme diff --git a/src/doc/transient.md b/src/doc/transient.md new file mode 100644 index 0000000000..440f67f498 --- /dev/null +++ b/src/doc/transient.md @@ -0,0 +1,4 @@ +usage: wp transient get <key> + or: wp transient set <key> <value> [expiration] + or: wp transient delete <key> + or: wp transient type diff --git a/src/doc/user.md b/src/doc/user.md new file mode 100644 index 0000000000..ce3f19c5f0 --- /dev/null +++ b/src/doc/user.md @@ -0,0 +1,4 @@ +usage: wp user list [--role=<role>] + or: wp user create <user_login> <user_email> [--role=<default_role>] + or: wp user update <ID> [--field_name=<field_value>] + or: wp user delete <ID> [--reassign=<reassign_id>] diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 3d50ee1d11..ed94c78410 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -151,23 +151,4 @@ public function create( $args, $assoc_args ) { } WP_CLI::success( "Blog $id created: $url" ); } - - /* public function update($args) {} */ - - /* public function delete($args) {} */ - - public function help() { - WP_CLI::line( <<<EOB -usage: wp blog <sub-command> [options] - -Available sub-commands: - create create a new blog - --slug Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs - --title Title of the new blog - [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included - [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) - [--public] Whether or not the new site is public (indexed) -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 5fa81ed093..e1764c0503 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -162,19 +162,5 @@ function update( $args ) { WP_CLI::success('WordPress updated successfully.'); } } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp core update - or: wp core version [--extra] - or: wp core download [--version=1.2.3] - or: wp core config --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=localhost] [--dbprefix=wp_] - or: wp core install --site_url=example.com --site_title=<site-title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email-address> -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 448a933f7e..3687a1d77b 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -96,27 +96,4 @@ private function get_file_name( $args ) { return $args[0]; } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp db <sub-command> [<file>] - -Available sub-commands: - cli Open a SQL command-line interface using the WordPress credentials. - - connect Print a string for connecting to the database. - - export Export the WordPress database using mysqldump. - - import Import a database exported via mysqldump. - - query Execute a query against the WordPress database. - - create Create a database using the info from wp-config.php. -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/eval-file.php b/src/php/wp-cli/commands/internals/eval-file.php index 9626ab1b57..006f5dc00b 100644 --- a/src/php/wp-cli/commands/internals/eval-file.php +++ b/src/php/wp-cli/commands/internals/eval-file.php @@ -30,16 +30,4 @@ public function __construct( $args, $assoc_args ) { } } } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -example: wp eval-file some-file.php - -Loads and executes a PHP file after bootstrapping WordPress. -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/eval.php b/src/php/wp-cli/commands/internals/eval.php index fd0e737fef..0915224bcb 100644 --- a/src/php/wp-cli/commands/internals/eval.php +++ b/src/php/wp-cli/commands/internals/eval.php @@ -24,16 +24,4 @@ public function __construct( $args, $assoc_args ) { eval( $args[0] ); } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -example: wp eval 'echo WP_CONTENT_DIR;' - -Executes arbitrary PHP code after bootstrapping WordPress. -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index d24b13da54..555a29d389 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -9,29 +9,6 @@ * @subpackage commands/internals */ class Export_Command extends WP_CLI_Command { - protected $default_subcommand = 'validate_arguments'; - - public $export_args = array(); - - public static function help() { - WP_CLI::line( <<<EOB -usage: wp export --path=<export-path> --user=<username/id> - or: wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 - -Required parameters: - --path Full Path to directory where WXR export files should be stored - -Optional filters: - --start_date Export only posts new than this date in format YYYY-MM-DD - --end_date Export only posts older than this date in format YYYY-MM-DD - --post_type Export only posts with this post_type - --author Export only posts by this author - --category Export only posts in this category - --post_status Export only posts with this post_status - --skip_comments Don't export comments -EOB - ); - } /** * Argument validation functions below diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 2d40fbdbec..c4bddf2221 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -116,15 +116,4 @@ public function users( $args, $assoc_args ) { $notify->finish(); } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp generate posts [--count=100] [--type=post] [--status=publish] [--author=<login>] - or: wp generate users [--count=100] [--role=<role>] -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index c16bf6f42d..ce8efce9fa 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -34,16 +34,4 @@ public function __construct( $args, $assoc_args ) { WP_CLI::success('The wp-cli homepage should be opening in your browser.'); } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp home - -Opens the wp-cli homepage in your browser. -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 5e4b20f04a..79825b4b2e 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -91,17 +91,4 @@ public function get( $args ) { echo $value . "\n"; } } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp option get <option-name> - or: wp option add <option-name> <option-value> - or: wp option update <option-name> <option-value> - or: wp option delete <option-name> -EOB - ); - } -} \ No newline at end of file +} diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index bd051ba55c..5877e9b98e 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -307,40 +307,4 @@ protected function parse_name( $args, $subcommand ) { return array( $file, $name ); } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp plugin <sub-command> [<plugin-name>] - or: wp plugin path [<plugin-name>] [--dir] - or: wp plugin install <plugin-name> [--activate] [--dev] [--version=1.2.3] - -Available sub-commands: - status display status of all installed plugins or of a particular plugin - - activate activate a particular plugin - - deactivate deactivate a particular plugin - - toggle toggle activation state of a particular plugin - - path print path to the plugin's file - --dir get the path to the closest parent directory - - install install a plugin from wordpress.org or from a zip file - --activate activate the plugin after installing it - --dev install the development version - --version install a specific version - - update update a plugin from wordpress.org - --all update all plugins from wordpress.org - - uninstall run the uninstallation procedure for a plugin - - delete delete a plugin -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index fe9fb4d5dd..8313d8d445 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -199,31 +199,4 @@ protected function parse_name( $args, $subcommand ) { protected function get_stylesheet_path( $theme ) { return WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'; } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp theme <sub-command> [<theme-name>] - or: wp theme path [<theme-name>] [--dir] - -Available sub-commands: - status display status of all installed themes or of a particular theme - - activate activate a particular theme - - path print path to the theme's stylesheet - --dir get the path to the closest parent directory - - install install a theme from wordpress.org or from a zip file - --activate activate the theme after installing it - - update update a theme from wordpress.org - --all update all themes from wordpress.org - - delete delete a theme -EOB - ); - } } diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/internals/transient.php index 86a373e379..9d82368942 100644 --- a/src/php/wp-cli/commands/internals/transient.php +++ b/src/php/wp-cli/commands/internals/transient.php @@ -29,7 +29,7 @@ public function get( $args ) { WP_CLI::warning( 'Transient with key "' . $key . '" is not set.' ); exit; } - + if ( is_array( $value ) || is_object( $value ) ) echo var_export( $value ) . "\n"; else @@ -86,24 +86,11 @@ public function delete( $args ) { public function type() { global $_wp_using_ext_object_cache, $wpdb; - if ( $_wp_using_ext_object_cache ) + if ( $_wp_using_ext_object_cache ) $message = 'Transients are saved to the object cache.'; else $message = 'Transients are saved to the ' . $wpdb->prefix . 'options table.'; WP_CLI::line( $message ); } - - /** - * Displays the help message. - */ - static function help() { - WP_CLI::line( <<<EOB -usage: wp transient get <key> - or: wp transient set <key> <value> [expiration] - or: wp transient delete <key> - or: wp transient type -EOB - ); - } -} \ No newline at end of file +} diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index f9fd30a003..7515979d4e 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -156,17 +156,4 @@ public function update( $args, $assoc_args ) { WP_CLI::success( "Updated user $updated_id." ); } } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp user list [--role=<role>] - or: wp user create <user_login> <user_email> [--role=<default_role>] - or: wp user update <ID> [--field_name=<field_value>] - or: wp user delete <ID> [--reassign=<reassign_id>] -EOB - ); - } } From 19e195f4bc9890e34d81c13ffb191828522e5552 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 22:40:08 +0300 Subject: [PATCH 0363/4858] convert blog.md to ronn format --- src/doc/blog.md | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/doc/blog.md b/src/doc/blog.md index 15ceea00f3..5fc9e3ccf9 100644 --- a/src/doc/blog.md +++ b/src/doc/blog.md @@ -1,9 +1,28 @@ -usage: wp blog <sub-command> [options] - -Available sub-commands: - create create a new blog - --slug Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs - --title Title of the new blog - [--email] Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included - [--site_id] Site (network) to associate new blog with. Defaults to current site (typically 1) - [--public] Whether or not the new site is public (indexed) +wp-blog-create(1) -- Create a new blog in a multisite install. +==== + +## SYNOPSIS + +`wp blog create` --slug=<slug> --title=<Title> + +## OPTIONS + +* `--slug`=<slug>: + + Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs. + +* `--title`=<title>: + + Title of the new blog. + +* `--email`=<email>: + + Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included. + +* `--site_id`=<site-id>: + + Site (network) to associate new blog with. Defaults to current site (typically 1). + +* `--public`: + + Whether or not the new site is public (indexed). From 511085317e86bd1c373755db9d3e8ebcdbae6b8c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 22:58:49 +0300 Subject: [PATCH 0364/4858] move blog.md to blog-create.md --- src/doc/{blog.md => blog-create.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/doc/{blog.md => blog-create.md} (100%) diff --git a/src/doc/blog.md b/src/doc/blog-create.md similarity index 100% rename from src/doc/blog.md rename to src/doc/blog-create.md From f4da7c6ad8cae1627ec7e8ccd841323cebf68232 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 23:01:28 +0300 Subject: [PATCH 0365/4858] fix encoding issue in blog-create.md --- src/doc/blog-create.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/blog-create.md b/src/doc/blog-create.md index 5fc9e3ccf9..c19c966398 100644 --- a/src/doc/blog-create.md +++ b/src/doc/blog-create.md @@ -11,7 +11,7 @@ wp-blog-create(1) -- Create a new blog in a multisite install. Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs. -* `--title`=<title>: +* `--title`=<title>: Title of the new blog. From dc9877fc57c9b57900a7133dda83bfe85ac8d2c5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 23:03:30 +0300 Subject: [PATCH 0366/4858] add optional parameters to synopsis in blog-create.md --- src/doc/blog-create.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/blog-create.md b/src/doc/blog-create.md index c19c966398..fc4710e18f 100644 --- a/src/doc/blog-create.md +++ b/src/doc/blog-create.md @@ -3,7 +3,7 @@ wp-blog-create(1) -- Create a new blog in a multisite install. ## SYNOPSIS -`wp blog create` --slug=<slug> --title=<Title> +`wp blog create` --slug=<slug> --title=<Title> [--email=<email>] [--site_id=<site-id>] [--public=true] ## OPTIONS From 0e9fe2ca3dbd86fee8ecf6fc16eff7ebb45bf20a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 23:16:48 +0300 Subject: [PATCH 0367/4858] look for nested doc files --- src/php/wp-cli/commands/internals/help.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 2453240c30..5d94cf7f57 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -26,11 +26,11 @@ public function __construct( $args ) { if ( !isset( WP_CLI::$commands[$command] ) ) WP_CLI::error( "'$command' is not a registered wp command." ); - if ( !$this->show_help( $command ) ) { + if ( !$this->show_help( $args ) ) { $class = WP_CLI::$commands[$command]; if ( method_exists( $class, 'help' ) ) { - $class::help(); + $class::help( $subcommand ); } else { WP_CLI::line( 'Example usage:' ); $this->single_command_help( $command, $class ); @@ -38,8 +38,8 @@ public function __construct( $args ) { } } - private function show_help( $command ) { - $doc_file = WP_CLI::get_path( 'doc' ) . "$command.md"; + private function show_help( $args ) { + $doc_file = WP_CLI::get_path( 'doc' ) . implode( '-', $args ) . '.md'; if ( !is_readable( $doc_file ) ) return false; From b4cd34da3272af54e293507cac28f21046a93838 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 23:47:15 +0300 Subject: [PATCH 0368/4858] change doc extension from .md to .txt --- src/doc/{blog-create.md => blog-create.txt} | 0 src/doc/{core.md => core.txt} | 0 src/doc/{db.md => db.txt} | 0 src/doc/{eval-file.md => eval-file.txt} | 0 src/doc/{eval.md => eval.txt} | 0 src/doc/{export.md => export.txt} | 0 src/doc/{general.md => general.txt} | 0 src/doc/{generate.md => generate.txt} | 0 src/doc/{home.md => home.txt} | 0 src/doc/{option.md => option.txt} | 0 src/doc/{plugin.md => plugin.txt} | 0 src/doc/{theme.md => theme.txt} | 0 src/doc/{transient.md => transient.txt} | 0 src/doc/{user.md => user.txt} | 0 src/php/wp-cli/commands/internals/help.php | 2 +- 15 files changed, 1 insertion(+), 1 deletion(-) rename src/doc/{blog-create.md => blog-create.txt} (100%) rename src/doc/{core.md => core.txt} (100%) rename src/doc/{db.md => db.txt} (100%) rename src/doc/{eval-file.md => eval-file.txt} (100%) rename src/doc/{eval.md => eval.txt} (100%) rename src/doc/{export.md => export.txt} (100%) rename src/doc/{general.md => general.txt} (100%) rename src/doc/{generate.md => generate.txt} (100%) rename src/doc/{home.md => home.txt} (100%) rename src/doc/{option.md => option.txt} (100%) rename src/doc/{plugin.md => plugin.txt} (100%) rename src/doc/{theme.md => theme.txt} (100%) rename src/doc/{transient.md => transient.txt} (100%) rename src/doc/{user.md => user.txt} (100%) diff --git a/src/doc/blog-create.md b/src/doc/blog-create.txt similarity index 100% rename from src/doc/blog-create.md rename to src/doc/blog-create.txt diff --git a/src/doc/core.md b/src/doc/core.txt similarity index 100% rename from src/doc/core.md rename to src/doc/core.txt diff --git a/src/doc/db.md b/src/doc/db.txt similarity index 100% rename from src/doc/db.md rename to src/doc/db.txt diff --git a/src/doc/eval-file.md b/src/doc/eval-file.txt similarity index 100% rename from src/doc/eval-file.md rename to src/doc/eval-file.txt diff --git a/src/doc/eval.md b/src/doc/eval.txt similarity index 100% rename from src/doc/eval.md rename to src/doc/eval.txt diff --git a/src/doc/export.md b/src/doc/export.txt similarity index 100% rename from src/doc/export.md rename to src/doc/export.txt diff --git a/src/doc/general.md b/src/doc/general.txt similarity index 100% rename from src/doc/general.md rename to src/doc/general.txt diff --git a/src/doc/generate.md b/src/doc/generate.txt similarity index 100% rename from src/doc/generate.md rename to src/doc/generate.txt diff --git a/src/doc/home.md b/src/doc/home.txt similarity index 100% rename from src/doc/home.md rename to src/doc/home.txt diff --git a/src/doc/option.md b/src/doc/option.txt similarity index 100% rename from src/doc/option.md rename to src/doc/option.txt diff --git a/src/doc/plugin.md b/src/doc/plugin.txt similarity index 100% rename from src/doc/plugin.md rename to src/doc/plugin.txt diff --git a/src/doc/theme.md b/src/doc/theme.txt similarity index 100% rename from src/doc/theme.md rename to src/doc/theme.txt diff --git a/src/doc/transient.md b/src/doc/transient.txt similarity index 100% rename from src/doc/transient.md rename to src/doc/transient.txt diff --git a/src/doc/user.md b/src/doc/user.txt similarity index 100% rename from src/doc/user.md rename to src/doc/user.txt diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 5d94cf7f57..52df87369b 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -39,7 +39,7 @@ public function __construct( $args ) { } private function show_help( $args ) { - $doc_file = WP_CLI::get_path( 'doc' ) . implode( '-', $args ) . '.md'; + $doc_file = WP_CLI::get_path( 'doc' ) . implode( '-', $args ) . '.txt'; if ( !is_readable( $doc_file ) ) return false; From be1c437bce7d78552d3ff4ffaeb31f8c132dba48 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 23:49:46 +0300 Subject: [PATCH 0369/4858] replace --public with --private. see #104 --- src/php/wp-cli/commands/internals/blog.php | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index ed94c78410..b1efc2ce3d 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -13,7 +13,7 @@ class Blog_Command extends WP_CLI_Command { private function _create_usage_string() { - return "usage: wp blog create --slug=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--public]"; + return "usage: wp blog create --slug=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--private]"; } /** @@ -69,18 +69,8 @@ public function create( $args, $assoc_args ) { else { $site = wpmu_current_site(); } - // Public, default is true (1) - if ( !empty( $assoc_args['public'] ) ) { - $public = $args['public']; - // Check for 1 or 0 - if ( $public != '1' && $public != '0' ) { - $this->_create_usage(); - exit; - } - } - else { - $public = 1; - } + + $public = isset( $assoc_args['private'] ) ? 0 : 1; // Sanitize if ( preg_match( '|^([a-zA-Z0-9-])+$|', $base ) ) { From 3398b956a239a745b47722e1a6c2caabaa801bab Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 May 2012 23:53:39 +0300 Subject: [PATCH 0370/4858] update blog-create.txt --- src/doc/blog-create.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/blog-create.txt b/src/doc/blog-create.txt index fc4710e18f..991e19caf9 100644 --- a/src/doc/blog-create.txt +++ b/src/doc/blog-create.txt @@ -23,6 +23,6 @@ wp-blog-create(1) -- Create a new blog in a multisite install. Site (network) to associate new blog with. Defaults to current site (typically 1). -* `--public`: +* `--private`: - Whether or not the new site is public (indexed). + If set, the new blog will be non-public (not indexed) From e751d0ce423d85cbaebff072d554cf33022df116 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 00:07:38 +0300 Subject: [PATCH 0371/4858] add build-doc script --- .gitignore | 1 + utils/build-doc | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100755 utils/build-doc diff --git a/.gitignore b/.gitignore index d9cdde38e6..472657eea6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /.build /dist +/man diff --git a/utils/build-doc b/utils/build-doc new file mode 100755 index 0000000000..9b8866e41e --- /dev/null +++ b/utils/build-doc @@ -0,0 +1,9 @@ +#!/bin/bash + +# generate man pages + +mkdir -p man + +for file in $(ls src/doc/*.txt); do + cat $file | ronn --roff --manual="WP-CLI" > man/$(basename $file .txt).1 +done From b3494ae07cd97c11798562fe586288a451ab391e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 00:30:34 +0300 Subject: [PATCH 0372/4858] use generated man file --- src/php/wp-cli/class-wp-cli.php | 17 +++++++++-------- src/php/wp-cli/commands/internals/db.php | 2 +- src/php/wp-cli/commands/internals/help.php | 10 +++++++++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 79bbecb49f..1185314f80 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -148,6 +148,15 @@ static function legend( $legend ) { WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } + /** + * Launch an external process, closing the current one + * + * @param string Command to call + */ + static function launch( $command ) { + proc_close( proc_open( $command, array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); + } + /** * Sets the appropriate $_SERVER keys based on a given string * @@ -278,14 +287,6 @@ private function load_command( $command ) { } } - static function get_path( $which ) { - switch ( $which ) { - case 'doc': - // TODO: pear config-get doc_dir - return WP_CLI_ROOT . "../../doc/"; - } - } - // back-compat static function addCommand( $name, $class ) { self::add_command( $name, $class ); diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 3687a1d77b..77e631ee1c 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -33,7 +33,7 @@ function connect() { * Open a SQL command-line interface using WordPress's credentials. */ function cli() { - proc_close( proc_open( $this->connect_string() , array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); + WP_CLI::launch( $this->connect_string() ); } /** diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 52df87369b..3673429ee3 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -39,7 +39,15 @@ public function __construct( $args ) { } private function show_help( $args ) { - $doc_file = WP_CLI::get_path( 'doc' ) . implode( '-', $args ) . '.txt'; + $fname = implode( '-', $args ); + + $man_file = WP_CLI_ROOT . "../../../man/$fname.1"; + + if ( is_readable( $man_file ) ) { + WP_CLI::launch( "man $man_file" ); + } + + $doc_file = WP_CLI_ROOT . "../../doc/$fname.txt"; if ( !is_readable( $doc_file ) ) return false; From a14bcce96e6e6baf746f369e6a1e538386d28e84 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 00:35:05 +0300 Subject: [PATCH 0373/4858] move general help text back to the help command --- src/doc/general.txt | 9 --------- src/php/wp-cli/commands/internals/help.php | 13 ++++++++++++- 2 files changed, 12 insertions(+), 10 deletions(-) delete mode 100644 src/doc/general.txt diff --git a/src/doc/general.txt b/src/doc/general.txt deleted file mode 100644 index 7a7fbfbd7f..0000000000 --- a/src/doc/general.txt +++ /dev/null @@ -1,9 +0,0 @@ - -See 'wp help <command>' for more information on a specific command. - -Global parameters: - --user=<id|login> set the current user - --url=<url> set the current URL - --path=<path> set the current path to the WP install - --require=<path> load a certain file before running the command - --version print wp-cli version diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 3673429ee3..39c96c7a4d 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -66,7 +66,18 @@ private function general_help() { $this->single_command_help( $name, $command ); } - $this->show_help( 'general' ); + WP_CLI::line(<<<EOB + +See 'wp help <command>' for more information on a specific command. + +Global parameters: + --user=<id|login> set the current user + --url=<url> set the current URL + --path=<path> set the current path to the WP install + --require=<path> load a certain file before running the command + --version print wp-cli version +EOB + ); } private function single_command_help( $name, $command ) { From b69526dc8662311c9ed4208a986073706dea967b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 01:18:07 +0300 Subject: [PATCH 0374/4858] remove help related code from WP_CLI and make WP_CLI::$private private --- src/php/wp-cli/class-wp-cli.php | 37 +++++++------ src/php/wp-cli/commands/internals/help.php | 61 ++++++++++------------ src/php/wp-cli/wp-cli.php | 4 +- 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 1185314f80..8a6982e5c4 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -7,7 +7,7 @@ */ class WP_CLI { - static $commands = array(); + private static $commands = array(); /** * Add a command to the wp-cli list of commands @@ -237,9 +237,16 @@ static function load_wp_config() { static function load_all_commands() { foreach ( array( 'internals', 'community' ) as $dir ) { foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { + $command = substr( basename( $filename ), 0, -4 ); + + if ( isset( self::$commands[ $command ] ) ) + continue; + include $filename; } } + + return self::$commands; } static function run_command( $arguments, $assoc_args ) { @@ -256,27 +263,12 @@ static function run_command( $arguments, $assoc_args ) { $command = $aliases[ $command ]; } - if ( 'help' == $command ) { - if ( empty( $arguments ) ) { - self::load_all_commands(); - } else { - self::load_command( 'help' ); - self::load_command( $arguments[0] ); - } - } else { - self::load_command( $command ); - } - - if ( !isset( WP_CLI::$commands[$command] ) ) { - WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); - exit; - } + $class = self::load_command( $command ); - new WP_CLI::$commands[$command]( $arguments, $assoc_args ); - exit; + new $class( $arguments, $assoc_args ); } - private function load_command( $command ) { + static function load_command( $command ) { foreach ( array( 'internals', 'community' ) as $dir ) { $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; @@ -285,6 +277,13 @@ private function load_command( $command ) { break; } } + + if ( !isset( WP_CLI::$commands[$command] ) ) { + WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); + exit; + } + + return WP_CLI::$commands[$command]; } // back-compat diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 39c96c7a4d..04e7c22a35 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -21,49 +21,45 @@ public function __construct( $args ) { return; } - $command = $args[0]; + $this->maybe_load_man_page( $args ); - if ( !isset( WP_CLI::$commands[$command] ) ) - WP_CLI::error( "'$command' is not a registered wp command." ); + $this->show_available_subcommands( $args[0] ); + } + + private function maybe_load_man_page( $args ) { + $man_dir = WP_CLI_ROOT . "../../../man/"; - if ( !$this->show_help( $args ) ) { - $class = WP_CLI::$commands[$command]; + if ( !is_dir( $man_dir ) ) { + WP_CLI::warning( "man pages do not seem to be installed." ); + } else { + $man_file = $man_dir . implode( '-', $args ) . '.1'; - if ( method_exists( $class, 'help' ) ) { - $class::help( $subcommand ); - } else { - WP_CLI::line( 'Example usage:' ); - $this->single_command_help( $command, $class ); + if ( is_readable( $man_file ) ) { + WP_CLI::launch( "man $man_file" ); } } } - private function show_help( $args ) { - $fname = implode( '-', $args ); + private function show_available_subcommands( $command ) { + $class = WP_CLI::load_command( $command ); - $man_file = WP_CLI_ROOT . "../../../man/$fname.1"; - - if ( is_readable( $man_file ) ) { - WP_CLI::launch( "man $man_file" ); + if ( method_exists( $class, 'help' ) ) { + $class::help(); + } else { + WP_CLI::line( 'Example usage:' ); + $this->single_command_help( $command, $class ); + WP_CLI::line(); + WP_CLI::line( "See 'wp help blog <subcommand>' for more information on a specific subcommand." ); } - - $doc_file = WP_CLI_ROOT . "../../doc/$fname.txt"; - - if ( !is_readable( $doc_file ) ) - return false; - - echo file_get_contents( $doc_file ); - - return true; } private function general_help() { WP_CLI::line( 'Available commands:' ); - foreach ( WP_CLI::$commands as $name => $command ) { + foreach ( WP_CLI::load_all_commands() as $name => $class ) { if ( 'help' == $name ) continue; - $this->single_command_help( $name, $command ); + $this->single_command_help( $name, $class ); } WP_CLI::line(<<<EOB @@ -80,14 +76,15 @@ private function general_help() { ); } - private function single_command_help( $name, $command ) { - WP_CLI::out( ' wp ' . $name ); + private function single_command_help( $name, $class ) { + $out = " wp $name"; - $methods = WP_CLI_Command::get_subcommands( $command ); + $methods = WP_CLI_Command::get_subcommands( $class ); if ( !empty( $methods ) ) { - WP_CLI::out( ' [' . implode( '|', $methods ) . ']' ); + $out .= ' [' . implode( '|', $methods ) . ']'; } - WP_CLI::line(' ...'); + + WP_CLI::line( $out ); } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 9049ffa547..80681c8a71 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -108,9 +108,7 @@ // Handle --completions parameter if ( isset( $assoc_args['completions'] ) ) { - WP_CLI::load_all_commands(); - - foreach ( WP_CLI::$commands as $name => $command ) { + foreach ( WP_CLI::load_all_commands() as $name => $command ) { WP_CLI::line( $name . ' ' . implode( ' ', WP_CLI_Command::get_subcommands($command) ) ); } exit; From a87410d8725c65db7ab0f6bfb187468dbb3c636e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 03:29:32 +0300 Subject: [PATCH 0375/4858] Built-in help improvements - introduce WP_CLI_Command::describe_command() - short-circuit `wp [command] __construct` --- src/php/wp-cli/class-wp-cli-command.php | 44 +++++++++++++++++----- src/php/wp-cli/class-wp-cli.php | 16 +++++--- src/php/wp-cli/commands/internals/help.php | 41 ++++++-------------- src/php/wp-cli/wp-cli.php | 3 +- 4 files changed, 58 insertions(+), 46 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index c21846b728..aabf1c8db6 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -7,7 +7,7 @@ */ abstract class WP_CLI_Command { - protected $default_subcommand = 'help'; + protected $default_subcommand; protected $aliases = array(); @@ -31,11 +31,33 @@ public function __construct( $args, $assoc_args ) { $subcommand = '_' . $subcommand; } - if ( !method_exists( $this, $subcommand ) || isset( $assoc_args[ 'help' ] ) ) { - $subcommand = 'help'; + if ( __FUNCTION__ == $subcommand || !method_exists( $this, $subcommand ) || isset( $assoc_args[ 'help' ] ) ) { + self::describe_command( get_class( $this ), WP_CLI_COMMAND ); + } else { + $this->$subcommand( $args, $assoc_args ); } + } + + static function describe_command( $class, $command ) { + if ( method_exists( $class, 'help' ) ) { + $class::help(); + return; + } + + $methods = self::get_subcommands( $class ); + + $out = "usage: wp $command"; - $this->$subcommand( $args, $assoc_args ); + if ( empty( $methods ) ) { + WP_CLI::line( $out ); + } else { + $out .= ' [' . implode( '|', $methods ) . ']'; + + WP_CLI::line( $out ); + + WP_CLI::line(); + WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); + } } /** @@ -50,17 +72,19 @@ static function get_subcommands( $class ) { $methods = array(); foreach ( $reflection->getMethods() as $method ) { - if ( $method->isPublic() && !$method->isStatic() && !$method->isConstructor() ) { - $name = $method->name; + if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) + continue; - if ( strpos( $name, '_' ) === 0 ) { - $name = substr( $name, 1 ); - } + $name = $method->name; - $methods[] = $name; + if ( strpos( $name, '_' ) === 0 ) { + $name = substr( $name, 1 ); } + + $methods[] = $name; } return $methods; } } + diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8a6982e5c4..5387b49149 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -265,16 +265,20 @@ static function run_command( $arguments, $assoc_args ) { $class = self::load_command( $command ); - new $class( $arguments, $assoc_args ); + define( 'WP_CLI_COMMAND', $command ); + + $instance = new $class( $arguments, $assoc_args ); } static function load_command( $command ) { - foreach ( array( 'internals', 'community' ) as $dir ) { - $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + if ( !isset( WP_CLI::$commands[$command] ) ) { + foreach ( array( 'internals', 'community' ) as $dir ) { + $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; - if ( is_readable( $path ) ) { - include $path; - break; + if ( is_readable( $path ) ) { + include $path; + break; + } } } diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 04e7c22a35..1853484099 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -10,11 +10,6 @@ */ class Help_Command extends WP_CLI_Command { - /** - * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args - */ public function __construct( $args ) { if ( empty( $args ) ) { $this->general_help(); @@ -42,24 +37,24 @@ private function maybe_load_man_page( $args ) { private function show_available_subcommands( $command ) { $class = WP_CLI::load_command( $command ); - - if ( method_exists( $class, 'help' ) ) { - $class::help(); - } else { - WP_CLI::line( 'Example usage:' ); - $this->single_command_help( $command, $class ); - WP_CLI::line(); - WP_CLI::line( "See 'wp help blog <subcommand>' for more information on a specific subcommand." ); - } + WP_CLI_Command::describe_command( $class, $command ); } private function general_help() { WP_CLI::line( 'Available commands:' ); - foreach ( WP_CLI::load_all_commands() as $name => $class ) { - if ( 'help' == $name ) + foreach ( WP_CLI::load_all_commands() as $command => $class ) { + if ( 'help' == $command ) continue; - $this->single_command_help( $name, $class ); + $out = " wp $command"; + + $methods = WP_CLI_Command::get_subcommands( $class ); + + if ( !empty( $methods ) ) { + $out .= ' [' . implode( '|', $methods ) . ']'; + } + + WP_CLI::line( $out ); } WP_CLI::line(<<<EOB @@ -75,16 +70,4 @@ private function general_help() { EOB ); } - - private function single_command_help( $name, $class ) { - $out = " wp $name"; - - $methods = WP_CLI_Command::get_subcommands( $class ); - - if ( !empty( $methods ) ) { - $out .= ' [' . implode( '|', $methods ) . ']'; - } - - WP_CLI::line( $out ); - } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 80681c8a71..8a7c030f06 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -109,7 +109,8 @@ // Handle --completions parameter if ( isset( $assoc_args['completions'] ) ) { foreach ( WP_CLI::load_all_commands() as $name => $command ) { - WP_CLI::line( $name . ' ' . implode( ' ', WP_CLI_Command::get_subcommands($command) ) ); + $subcommands = implode( ' ', WP_CLI_Command::get_subcommands( $command ) ); + WP_CLI::line( $name . ' ' . $subcommands ); } exit; } From bbac551c39538544514a02f2e31acb456e3e5a09 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 04:52:05 +0300 Subject: [PATCH 0376/4858] add required WP version to readme. see #58 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f715fdfae9..7474ba4a96 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Requirements ------------ PHP >= 5.3 +WP >= 3.3 Installing ---------- From 470dd65341f66d27075b0b152df61aed0271f660 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 04:52:41 +0300 Subject: [PATCH 0377/4858] put requirements in a list --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7474ba4a96..e2578d61b4 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ A set of tools for controlling WordPress installations from the command line. Requirements ------------ -PHP >= 5.3 -WP >= 3.3 +* PHP >= 5.3 +* WP >= 3.3 Installing ---------- From 865b926907c4017ecd0bb994a71b9ca7c578172c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:01:43 +0300 Subject: [PATCH 0378/4858] core: create doc files for each subcommand --- src/doc/core-config.txt | 28 ++++++++++++++++++++++++++++ src/doc/core-download.txt | 16 ++++++++++++++++ src/doc/core-install.txt | 28 ++++++++++++++++++++++++++++ src/doc/core-update.txt | 6 ++++++ src/doc/core-version.txt | 12 ++++++++++++ src/doc/core.txt | 5 ----- 6 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/doc/core-config.txt create mode 100644 src/doc/core-download.txt create mode 100644 src/doc/core-install.txt create mode 100644 src/doc/core-update.txt create mode 100644 src/doc/core-version.txt delete mode 100644 src/doc/core.txt diff --git a/src/doc/core-config.txt b/src/doc/core-config.txt new file mode 100644 index 0000000000..01f71b1a0e --- /dev/null +++ b/src/doc/core-config.txt @@ -0,0 +1,28 @@ +wp-core-config(1) -- Create a wp-config.php file. +==== + +## SYNOPSIS + +`wp core config` --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=localhost] [--dbprefix=wp_] + +## OPTIONS + +* `--dbname`=<dbname>: + + Set the database name. + +* `--dbuser`=<dbuser>: + + Set the database user. + +* `--dbpass`=<dbpass>: + + Set the database user password. + +* `--dbhost`=<dbhost>: + + Set the database host. Default: 'localhost' + +* `--dbprefix`=<dbprefix>: + + Set the database table prefix. Default: 'wp_' diff --git a/src/doc/core-download.txt b/src/doc/core-download.txt new file mode 100644 index 0000000000..fe858f1526 --- /dev/null +++ b/src/doc/core-download.txt @@ -0,0 +1,16 @@ +wp-core-download(1) -- Download core WordPress files. +==== + +## SYNOPSIS + +`wp core download` [--version=<version>] + +## OPTIONS + +* `--version`=<version>: + + Select which version you want to download. + +## EXAMPLES + + Download version 3.3: wp core download --version=3.3 diff --git a/src/doc/core-install.txt b/src/doc/core-install.txt new file mode 100644 index 0000000000..20c14827d1 --- /dev/null +++ b/src/doc/core-install.txt @@ -0,0 +1,28 @@ +wp-core-install(1) -- Install the WordPress tables in the database. +==== + +## SYNOPSIS + +`wp core install` --site_url=<url> --site_title=<title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email> + +## OPTIONS + +* `--site_url`=<url>: + + The address of the new site. + +* `--site_title`=<title>: + + The title of the new site. + +* `--admin_name`=<username>: + + The name of the admin user. Default: 'admin' + +* `--admin_password`=<password>: + + The password for the admin user. + +* `--admin_email`=<email>: + + The email address for the admin user. diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt new file mode 100644 index 0000000000..8a6d15bd87 --- /dev/null +++ b/src/doc/core-update.txt @@ -0,0 +1,6 @@ +wp-core-update(1) -- Update WordPress to the latest version. +==== + +## SYNOPSIS + +`wp core update` diff --git a/src/doc/core-version.txt b/src/doc/core-version.txt new file mode 100644 index 0000000000..ecbdc4d48e --- /dev/null +++ b/src/doc/core-version.txt @@ -0,0 +1,12 @@ +wp-core-version(1) -- Show the WordPress version. +==== + +## SYNOPSIS + +`wp core version` [--extra] + +## OPTIONS + +* `--extra`: + + Show extended version information. diff --git a/src/doc/core.txt b/src/doc/core.txt deleted file mode 100644 index eddc818afb..0000000000 --- a/src/doc/core.txt +++ /dev/null @@ -1,5 +0,0 @@ -usage: wp core update - or: wp core version [--extra] - or: wp core download [--version=1.2.3] - or: wp core config --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=localhost] [--dbprefix=wp_] - or: wp core install --site_url=example.com --site_title=<site-title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email-address> From ebbabe5982110685cd64327f65b6659e72624c80 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:09:18 +0300 Subject: [PATCH 0379/4858] treat --help as an alias for wp help --- src/php/wp-cli/class-wp-cli-command.php | 2 +- src/php/wp-cli/wp-cli.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index aabf1c8db6..79eee88ac2 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -31,7 +31,7 @@ public function __construct( $args, $assoc_args ) { $subcommand = '_' . $subcommand; } - if ( __FUNCTION__ == $subcommand || !method_exists( $this, $subcommand ) || isset( $assoc_args[ 'help' ] ) ) { + if ( __FUNCTION__ == $subcommand || !method_exists( $this, $subcommand ) ) { self::describe_command( get_class( $this ), WP_CLI_COMMAND ); } else { $this->$subcommand( $args, $assoc_args ); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 8a7c030f06..a2c7e2ffdb 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -115,5 +115,11 @@ exit; } +// Handle --help parameter +if ( isset( $assoc_args['help'] ) ) { + array_unshift( $arguments, 'help' ); + unset( $assoc_args['help'] ); +} + WP_CLI::run_command( $arguments, $assoc_args ); From 40a0c98b1c46c55f9455b6862846e3532d65157f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:11:24 +0300 Subject: [PATCH 0380/4858] don't show command description after loading man page --- src/php/wp-cli/commands/internals/help.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 1853484099..ae8dc1024c 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -31,6 +31,7 @@ private function maybe_load_man_page( $args ) { if ( is_readable( $man_file ) ) { WP_CLI::launch( "man $man_file" ); + exit; } } } From f110d80c863a11750d0bc13b11f7f0661dfbbfe3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:31:00 +0300 Subject: [PATCH 0381/4858] db: create doc files for each subcommand --- src/doc/db-cli.txt | 6 ++++++ src/doc/db-connect.txt | 6 ++++++ src/doc/db-create.txt | 6 ++++++ src/doc/db-export.txt | 12 ++++++++++++ src/doc/db-import.txt | 12 ++++++++++++ src/doc/db-query.txt | 12 ++++++++++++ src/doc/db.txt | 14 -------------- src/php/wp-cli/commands/internals/db.php | 2 +- 8 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 src/doc/db-cli.txt create mode 100644 src/doc/db-connect.txt create mode 100644 src/doc/db-create.txt create mode 100644 src/doc/db-export.txt create mode 100644 src/doc/db-import.txt create mode 100644 src/doc/db-query.txt delete mode 100644 src/doc/db.txt diff --git a/src/doc/db-cli.txt b/src/doc/db-cli.txt new file mode 100644 index 0000000000..10753c08be --- /dev/null +++ b/src/doc/db-cli.txt @@ -0,0 +1,6 @@ +wp-db-cli(1) -- Open a SQL command-line interface to the WordPress database. +==== + +## SYNOPSIS + +`wp db cli` diff --git a/src/doc/db-connect.txt b/src/doc/db-connect.txt new file mode 100644 index 0000000000..b724452e1a --- /dev/null +++ b/src/doc/db-connect.txt @@ -0,0 +1,6 @@ +wp-db-connect(1) -- Print a string for connecting to the database. +==== + +## SYNOPSIS + +`wp db connect` diff --git a/src/doc/db-create.txt b/src/doc/db-create.txt new file mode 100644 index 0000000000..27a6b7c745 --- /dev/null +++ b/src/doc/db-create.txt @@ -0,0 +1,6 @@ +wp-db-create(1) -- Create a database using the credentials from wp-config.php. +==== + +## SYNOPSIS + +`wp db create` diff --git a/src/doc/db-export.txt b/src/doc/db-export.txt new file mode 100644 index 0000000000..c5019c2af7 --- /dev/null +++ b/src/doc/db-export.txt @@ -0,0 +1,12 @@ +wp-db-export(1) -- Export the WordPress database using mysqldump. +==== + +## SYNOPSIS + +`wp db export` [<file>] + +## OPTIONS + +* `<file>`: + + The name of the export file. If omitted, it will be '{dbname}.sql' diff --git a/src/doc/db-import.txt b/src/doc/db-import.txt new file mode 100644 index 0000000000..a0e65c2b9b --- /dev/null +++ b/src/doc/db-import.txt @@ -0,0 +1,12 @@ +wp-db-import(1) -- Import a database from a text file. +==== + +## SYNOPSIS + +`wp db import` [<file>] + +## OPTIONS + +* `<file>`: + + The name of the import file. If omitted, it will be '{dbname}.sql' diff --git a/src/doc/db-query.txt b/src/doc/db-query.txt new file mode 100644 index 0000000000..b4e986ba22 --- /dev/null +++ b/src/doc/db-query.txt @@ -0,0 +1,12 @@ +wp-db-query(1) -- Execute a query against the WordPress database. +==== + +## SYNOPSIS + +`wp db query` <SQL> + +## OPTIONS + +* `<SQL>`: + + A SQL query. diff --git a/src/doc/db.txt b/src/doc/db.txt deleted file mode 100644 index e318225e4f..0000000000 --- a/src/doc/db.txt +++ /dev/null @@ -1,14 +0,0 @@ -usage: wp db <sub-command> [<file>] - -Available sub-commands: - cli Open a SQL command-line interface using the WordPress credentials. - - connect Print a string for connecting to the database. - - export Export the WordPress database using mysqldump. - - import Import a database exported via mysqldump. - - query Execute a query against the WordPress database. - - create Create a database using the info from wp-config.php. diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 77e631ee1c..9239e1811f 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -41,7 +41,7 @@ function cli() { */ function query( $args, $assoc_args ) { if ( empty( $args ) ) { - WP_CLI::line( "usage: wp sql query <SQL>" ); + WP_CLI::line( "usage: wp db query <SQL>" ); exit; } From eb62635235afbc782f79cff2977b3e2beaadac70 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:31:43 +0300 Subject: [PATCH 0382/4858] handle --help parameter sooner, so that it works for special commands, such as `wp db create` --- src/php/wp-cli/wp-cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index a2c7e2ffdb..b932b719f9 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -35,6 +35,12 @@ exit; } +// Handle --help parameter +if ( isset( $assoc_args['help'] ) ) { + array_unshift( $arguments, 'help' ); + unset( $assoc_args['help'] ); +} + // Define the WordPress location if ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { define( 'WP_ROOT', $_SERVER['PWD'] . '/../' ); @@ -115,11 +121,5 @@ exit; } -// Handle --help parameter -if ( isset( $assoc_args['help'] ) ) { - array_unshift( $arguments, 'help' ); - unset( $assoc_args['help'] ); -} - WP_CLI::run_command( $arguments, $assoc_args ); From 4b520808d822a29c223b0e4bd7b16bf10abea2c0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:43:16 +0300 Subject: [PATCH 0383/4858] update eval.txt and eval-file.txt --- src/doc/eval-file.txt | 11 +++++++++-- src/doc/eval.txt | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/doc/eval-file.txt b/src/doc/eval-file.txt index c626a93530..47e6764bc6 100644 --- a/src/doc/eval-file.txt +++ b/src/doc/eval-file.txt @@ -1,3 +1,10 @@ -example: wp eval-file some-file.php +wp-eval-file(1) -- Loads and executes a PHP file after loading WordPress. +==== -Loads and executes a PHP file after bootstrapping WordPress. +## SYNOPSIS + +`wp eval-file` <file> + +## EXAMPLES + + wp eval-file my-code.php diff --git a/src/doc/eval.txt b/src/doc/eval.txt index 1005333a6c..97db070a9a 100644 --- a/src/doc/eval.txt +++ b/src/doc/eval.txt @@ -1,3 +1,10 @@ -example: wp eval 'echo WP_CONTENT_DIR;' +wp-eval(1) -- Executes arbitrary PHP code after loading WordPress. +==== -Executes arbitrary PHP code after bootstrapping WordPress. +## SYNOPSIS + +`wp eval` <PHP> + +## EXAMPLES + + wp eval 'echo WP_CONTENT_DIR;' From e0443a5d68190c3aee51d7f68b6515a6d76e9c27 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 18:53:18 +0300 Subject: [PATCH 0384/4858] update export.txt --- src/doc/export.txt | 60 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/doc/export.txt b/src/doc/export.txt index ea644d8628..9a27e63ab8 100644 --- a/src/doc/export.txt +++ b/src/doc/export.txt @@ -1,14 +1,46 @@ -usage: wp export --path=<export-path> --user=<username/id> - or: wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 - -Required parameters: - --path Full Path to directory where WXR export files should be stored - -Optional filters: - --start_date Export only posts new than this date in format YYYY-MM-DD - --end_date Export only posts older than this date in format YYYY-MM-DD - --post_type Export only posts with this post_type - --author Export only posts by this author - --category Export only posts in this category - --post_status Export only posts with this post_status - --skip_comments Don't export comments +wp-export(1) -- Create a WXR file. +==== + +## SYNOPSIS + +`wp export` --path=<dirname> [filters] [--skip_comments] + +## OPTIONS + +* `--path`=<dirname>: + + Full Path to directory where WXR export files should be stored. + +* `--skip_comments`: + + Don't export comments. + +## FILTERS + +* `--start_date`=<date>: + + Export only posts newer than this date in format YYYY-MM-DD. + +* `--end_date`=<date>: + + Export only posts older than this date in format YYYY-MM-DD. + +* `--post_type`=<post_type>: + + Export only posts with this post_type. + +* `--author`=<login/id>: + + Export only posts by this author. + +* `--category`=<category-id>: + + Export only posts in this category. + +* `--post_status`=<status>: + + Export only posts with this status. + +## EXAMPLES + + wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 From 854a872b0da41effc3d615d256835e24dac19598 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 19:02:23 +0300 Subject: [PATCH 0385/4858] generate: create doc files for each subcommand --- src/doc/generate-posts.txt | 24 ++++++++++++++++++++++++ src/doc/generate-users.txt | 16 ++++++++++++++++ src/doc/generate.txt | 2 -- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/doc/generate-posts.txt create mode 100644 src/doc/generate-users.txt delete mode 100644 src/doc/generate.txt diff --git a/src/doc/generate-posts.txt b/src/doc/generate-posts.txt new file mode 100644 index 0000000000..2f9b156062 --- /dev/null +++ b/src/doc/generate-posts.txt @@ -0,0 +1,24 @@ +wp-generate-posts(1) -- Generate a bunch of posts. +==== + +## SYNOPSIS + +`wp generate posts` [--count=100] [--type=post] [--status=publish] [--author=<login>] + +## OPTIONS + +* `--count`=<number>: + + How many posts to generate. Default: 100 + +* `--type`=<post_type>: + + The type of the generated posts. Default: 'post' + +* `--status`=<post_status>: + + The status of the generated posts. Default: 'publish' + +* `--author`=<login>: + + The author of the generated posts. Default: none diff --git a/src/doc/generate-users.txt b/src/doc/generate-users.txt new file mode 100644 index 0000000000..3b2da84a17 --- /dev/null +++ b/src/doc/generate-users.txt @@ -0,0 +1,16 @@ +wp-generate-users(1) -- Generate a bunch of users. +==== + +## SYNOPSIS + +`wp generate users` [--count=100] [--role=<role>] + +## OPTIONS + +* `--count`=<number>: + + How many users to generate. Default: 100 + +* `--role`=<role>: + + The role of the generated users. Default: default role from WP diff --git a/src/doc/generate.txt b/src/doc/generate.txt deleted file mode 100644 index 8b2364fb21..0000000000 --- a/src/doc/generate.txt +++ /dev/null @@ -1,2 +0,0 @@ -usage: wp generate posts [--count=100] [--type=post] [--status=publish] [--author=<login>] - or: wp generate users [--count=100] [--role=<role>] From ec04fd163b744a7bb9f207ae89cbbebf1251eb3e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 20:09:08 +0300 Subject: [PATCH 0386/4858] update home.txt --- src/doc/home.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/doc/home.txt b/src/doc/home.txt index 5abbdf9954..32d55a2792 100644 --- a/src/doc/home.txt +++ b/src/doc/home.txt @@ -1,3 +1,6 @@ -usage: wp home +wp-home(1) -- Opens the wp-cli homepage in your browser. +==== -Opens the wp-cli homepage in your browser. +## SYNOPSIS + +`wp home` From 85b13921f3b9c608d2659d0cdc49aca9f438e8b0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 20:14:54 +0300 Subject: [PATCH 0387/4858] update option.txt --- src/doc/option.txt | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/doc/option.txt b/src/doc/option.txt index 2985f7b7ff..05f5e7da3c 100644 --- a/src/doc/option.txt +++ b/src/doc/option.txt @@ -1,4 +1,40 @@ -usage: wp option get <option-name> - or: wp option add <option-name> <option-value> - or: wp option update <option-name> <option-value> - or: wp option delete <option-name> +wp-option(1) -- Manage WordPress options. +==== + +## SYNOPSIS + +wp option get <key> + +wp option add <key> <value> + +wp option update <key> <value> + +wp option delete <key> + +## SUBCOMMANDS + +* `get`: + + Get an option value. + +* `add`: + + Add a new option. + +* `update`: + + Update an existing option. + +* `delete`: + + Delete an option. + +## EXAMPLES + + wp option get siteurl + + wp option add my_option foobar + + wp option update my_option barfoo + + wp option delete my_option From 77811b51a746fb06228a39fe8a43cae88bbcccd9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 May 2012 20:23:17 +0300 Subject: [PATCH 0388/4858] update transient.txt --- src/doc/transient.txt | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/doc/transient.txt b/src/doc/transient.txt index 440f67f498..33a167aaad 100644 --- a/src/doc/transient.txt +++ b/src/doc/transient.txt @@ -1,4 +1,35 @@ -usage: wp transient get <key> - or: wp transient set <key> <value> [expiration] - or: wp transient delete <key> - or: wp transient type +wp-transient(1) -- Manage WordPress transients. +==== + +## SYNOPSIS + +wp transient get <key> + +wp transient set <key> <value> [<expiration>] + +wp transient delete <key> + +wp transient type + +## SUBCOMMANDS + +* `get`: + + Get a transient value. + +* `set`: + + Set a transient value. <expiration> is the time until expiration, in +seconds. + +* `delete`: + + Delete a transient value. + +* `type`: + + Delete an option. + +## EXAMPLES + +wp transient set my_key my_value 300 From 7a8eb1efab1208b0a69a907ab6990061ca3bc8f5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 00:44:28 +0300 Subject: [PATCH 0389/4858] user: create doc files for each subcommand --- src/doc/user-create.txt | 24 ++++++++++++++++++++++++ src/doc/user-delete.txt | 20 ++++++++++++++++++++ src/doc/user-list.txt | 12 ++++++++++++ src/doc/user-update.txt | 20 ++++++++++++++++++++ src/doc/user.txt | 4 ---- 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/doc/user-create.txt create mode 100644 src/doc/user-delete.txt create mode 100644 src/doc/user-list.txt create mode 100644 src/doc/user-update.txt delete mode 100644 src/doc/user.txt diff --git a/src/doc/user-create.txt b/src/doc/user-create.txt new file mode 100644 index 0000000000..1173efcf43 --- /dev/null +++ b/src/doc/user-create.txt @@ -0,0 +1,24 @@ +wp-user-create(1) -- Create a new WordPress user. +==== + +## SYNOPSIS + +`wp user create` <user-login> <user-email> [--role=<role>] + +## OPTIONS + +* `<user-login>`: + + The login of the user to create. + +* `<user-email>`: + + The email address of the user to create. + +* `--role`=<role>: + + The role of the user to create. + +## EXAMPLES + + wp user create bob bob@example.com --role=author diff --git a/src/doc/user-delete.txt b/src/doc/user-delete.txt new file mode 100644 index 0000000000..6d8832c6cc --- /dev/null +++ b/src/doc/user-delete.txt @@ -0,0 +1,20 @@ +wp-user-delete(1) -- Delete a WordPress user. +==== + +## SYNOPSIS + +`wp user delete` <ID> [--reassign=<ID>] + +## OPTIONS + +* `<ID>`: + + The ID of the user to delete. + +* `--reassign`=<ID>: + + User to reassign the posts to. + +## EXAMPLES + + wp user delete 123 --reassign=567 diff --git a/src/doc/user-list.txt b/src/doc/user-list.txt new file mode 100644 index 0000000000..32b88daade --- /dev/null +++ b/src/doc/user-list.txt @@ -0,0 +1,12 @@ +wp-user-list(1) -- List WordPress users. +==== + +## SYNOPSIS + +`wp user list` [--role=<role>] + +## OPTIONS + +* `--role`=<role>: + + Only display users with a certain role. diff --git a/src/doc/user-update.txt b/src/doc/user-update.txt new file mode 100644 index 0000000000..ca46b7e4e2 --- /dev/null +++ b/src/doc/user-update.txt @@ -0,0 +1,20 @@ +wp-user-update(1) -- Update a WordPress user. +==== + +## SYNOPSIS + +`wp user update` <ID> --<field>=<value> [--<field>=<value>...] + +## OPTIONS + +* `<ID>`: + + The ID of the user to update. + +* `--<field>`=<value>: + + One or more fields to update. For accepted fields, see wp_update_user(). + +## EXAMPLES + + wp user update 123 --user_login=mary --display_name=Mary diff --git a/src/doc/user.txt b/src/doc/user.txt deleted file mode 100644 index ce3f19c5f0..0000000000 --- a/src/doc/user.txt +++ /dev/null @@ -1,4 +0,0 @@ -usage: wp user list [--role=<role>] - or: wp user create <user_login> <user_email> [--role=<default_role>] - or: wp user update <ID> [--field_name=<field_value>] - or: wp user delete <ID> [--reassign=<reassign_id>] From 0b411030b69a9a1c66f86450387bc84b9902d6e5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 00:56:00 +0300 Subject: [PATCH 0390/4858] fix doc for wp transient type --- src/doc/transient.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/transient.txt b/src/doc/transient.txt index 33a167aaad..50dece19da 100644 --- a/src/doc/transient.txt +++ b/src/doc/transient.txt @@ -28,7 +28,8 @@ seconds. * `type`: - Delete an option. + See wether the transients API is using an object cache or the options +table. ## EXAMPLES From b63d11264727969b3c4c0cdae90536c40fe1e0a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 01:20:24 +0300 Subject: [PATCH 0391/4858] plugin install: merge --dev into --version=dev. fixes #107 --- src/php/wp-cli/commands/internals/plugin.php | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 5877e9b98e..13963a78e5 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -179,21 +179,21 @@ protected function install_from_repo( $slug, $assoc_args ) { WP_CLI::error( $api ); } - if ( isset( $assoc_args['dev'] ) ) { + if ( isset( $assoc_args['version'] ) ) { list( $link ) = explode( $slug, $api->download_link ); - $api->download_link = $link . $slug . '.zip'; - $api->version = 'Development Version'; - } else if ( isset( $assoc_args['version'] ) ) { - list( $link ) = explode( $slug, $api->download_link ); - - $api->download_link = $link . $slug . '.' . $assoc_args['version'] .'.zip'; - $api->version = $assoc_args['version']; - - // check if the requested version exists - $version_check_response = wp_remote_head( $api->download_link ); - if ( !$version_check_response || $version_check_response['headers']['content-type'] != 'application/octet-stream' ) { - WP_CLI::error( "Can't find the requested plugin's version " . $assoc_args['version'] . " in the WordPress.org plugins repository." ); + if ( 'dev' == $assoc_args['version'] ) { + $api->download_link = $link . $slug . '.zip'; + $api->version = 'Development Version'; + } else { + $api->download_link = $link . $slug . '.' . $assoc_args['version'] .'.zip'; + $api->version = $assoc_args['version']; + + // check if the requested version exists + $response = wp_remote_head( $api->download_link ); + if ( !$response || $response['headers']['content-type'] != 'application/octet-stream' ) { + WP_CLI::error( "Can't find the requested plugin's version " . $assoc_args['version'] . " in the WordPress.org plugins repository." ); + } } } From c76a068c642c896223cdf0959a3d2d9935e1d153 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 01:34:21 +0300 Subject: [PATCH 0392/4858] plugin: create doc files for each subcommand --- src/doc/plugin-activate.txt | 12 ++++++++++++ src/doc/plugin-deactivate.txt | 12 ++++++++++++ src/doc/plugin-delete.txt | 16 ++++++++++++++++ src/doc/plugin-install.txt | 25 +++++++++++++++++++++++++ src/doc/plugin-path.txt | 18 ++++++++++++++++++ src/doc/plugin-status.txt | 12 ++++++++++++ src/doc/plugin-toggle.txt | 12 ++++++++++++ src/doc/plugin-uninstall.txt | 16 ++++++++++++++++ src/doc/plugin-update.txt | 23 +++++++++++++++++++++++ src/doc/plugin.txt | 27 --------------------------- 10 files changed, 146 insertions(+), 27 deletions(-) create mode 100644 src/doc/plugin-activate.txt create mode 100644 src/doc/plugin-deactivate.txt create mode 100644 src/doc/plugin-delete.txt create mode 100644 src/doc/plugin-install.txt create mode 100644 src/doc/plugin-path.txt create mode 100644 src/doc/plugin-status.txt create mode 100644 src/doc/plugin-toggle.txt create mode 100644 src/doc/plugin-uninstall.txt create mode 100644 src/doc/plugin-update.txt delete mode 100644 src/doc/plugin.txt diff --git a/src/doc/plugin-activate.txt b/src/doc/plugin-activate.txt new file mode 100644 index 0000000000..58760b7099 --- /dev/null +++ b/src/doc/plugin-activate.txt @@ -0,0 +1,12 @@ +wp-plugin-activate(1) -- Activate an installed plugin. +==== + +## SYNOPSIS + +`wp plugin activate` <plugin> + +## OPTIONS + +* `<plugin>`: + + The plugin to activate. diff --git a/src/doc/plugin-deactivate.txt b/src/doc/plugin-deactivate.txt new file mode 100644 index 0000000000..e6093a8387 --- /dev/null +++ b/src/doc/plugin-deactivate.txt @@ -0,0 +1,12 @@ +wp-plugin-deactivate(1) -- Deactivate an active plugin. +==== + +## SYNOPSIS + +`wp plugin deactivate` <plugin> + +## OPTIONS + +* `<plugin>`: + + The plugin to deactivate. diff --git a/src/doc/plugin-delete.txt b/src/doc/plugin-delete.txt new file mode 100644 index 0000000000..e36d303fe8 --- /dev/null +++ b/src/doc/plugin-delete.txt @@ -0,0 +1,16 @@ +wp-plugin-delete(1) -- Delete a plugin's files, without removing it's data. +==== + +## SYNOPSIS + +`wp plugin delete` <plugin> + +## OPTIONS + +* <plugin>: + + The plugin to delete. + +## EXAMPLES + + wp plugin delete hello diff --git a/src/doc/plugin-install.txt b/src/doc/plugin-install.txt new file mode 100644 index 0000000000..b1b794009d --- /dev/null +++ b/src/doc/plugin-install.txt @@ -0,0 +1,25 @@ +wp-plugin-install(1) -- Install a plugin from wordpress.org or from a zip file. +==== + +## SYNOPSIS + +`wp plugin install` <plugin/zip> [--version=<version>] [--activate] + +## OPTIONS + +* <plugin>: + + A plugin slug or the path to a zip file. + +* `--version`=<version>: + + If set, get that particular version from wordpress.org, instead of the +stable version. + +## EXAMPLES + + wp plugin install bbpress --version=2.1 + + wp plugin install bbpress --version=dev + + wp plugin install ../my-plugin.zip diff --git a/src/doc/plugin-path.txt b/src/doc/plugin-path.txt new file mode 100644 index 0000000000..805b88212d --- /dev/null +++ b/src/doc/plugin-path.txt @@ -0,0 +1,18 @@ +wp-plugin-path(1) -- Activate/Deactivate an installed plugin. +==== + +## SYNOPSIS + +`wp plugin path` [<plugin>] [--dir] + +## OPTIONS + +* `<plugin>`: + + The plugin to get the path to. If not set, will return the path to the +plugins directory. + +* `--dir`: + + If set, get the path to the closest parent directory, instead of the +plugin file. diff --git a/src/doc/plugin-status.txt b/src/doc/plugin-status.txt new file mode 100644 index 0000000000..5ee1022dc0 --- /dev/null +++ b/src/doc/plugin-status.txt @@ -0,0 +1,12 @@ +wp-plugin-status(1) -- See the status of one or all plugins. +==== + +## SYNOPSIS + +`wp plugin status` [<plugin>] + +## OPTIONS + +* `<plugin>`: + + A particular plugin to show the status for. diff --git a/src/doc/plugin-toggle.txt b/src/doc/plugin-toggle.txt new file mode 100644 index 0000000000..5f90c0543e --- /dev/null +++ b/src/doc/plugin-toggle.txt @@ -0,0 +1,12 @@ +wp-plugin-deactivate(1) -- Activate/Deactivate an installed plugin. +==== + +## SYNOPSIS + +`wp plugin toggle` <plugin> + +## OPTIONS + +* `<plugin>`: + + The plugin to toggle. diff --git a/src/doc/plugin-uninstall.txt b/src/doc/plugin-uninstall.txt new file mode 100644 index 0000000000..cc2fb5327a --- /dev/null +++ b/src/doc/plugin-uninstall.txt @@ -0,0 +1,16 @@ +wp-plugin-uninstall(1) -- Run the uninstallation procedure for a plugin. +==== + +## SYNOPSIS + +`wp plugin uninstall` <plugin> + +## OPTIONS + +* <plugin>: + + The plugin to uninstall. + +## EXAMPLES + + wp plugin uninstall hello diff --git a/src/doc/plugin-update.txt b/src/doc/plugin-update.txt new file mode 100644 index 0000000000..f909d53bfa --- /dev/null +++ b/src/doc/plugin-update.txt @@ -0,0 +1,23 @@ +wp-plugin-update(1) -- Update an installed plugin. +==== + +## SYNOPSIS + +`wp plugin update` [<plugin>] [--all] + +## OPTIONS + +* <plugin>: + + The plugin to update. Can be omitted when --all is passed. + +* `--all`: + + If set, updates for all plugins will be performed. Use `wp plugin status` +to see which plugins have updates available. + +## EXAMPLES + + wp plugin update bbpress + + wp plugin update --all diff --git a/src/doc/plugin.txt b/src/doc/plugin.txt deleted file mode 100644 index 6903e12900..0000000000 --- a/src/doc/plugin.txt +++ /dev/null @@ -1,27 +0,0 @@ -usage: wp plugin <sub-command> [<plugin-name>] - or: wp plugin path [<plugin-name>] [--dir] - or: wp plugin install <plugin-name> [--activate] [--dev] [--version=1.2.3] - -Available sub-commands: - status display status of all installed plugins or of a particular plugin - - activate activate a particular plugin - - deactivate deactivate a particular plugin - - toggle toggle activation state of a particular plugin - - path print path to the plugin's file - --dir get the path to the closest parent directory - - install install a plugin from wordpress.org or from a zip file - --activate activate the plugin after installing it - --dev install the development version - --version install a specific version - - update update a plugin from wordpress.org - --all update all plugins from wordpress.org - - uninstall run the uninstallation procedure for a plugin - - delete delete a plugin From 041b70ae2d71f1b7ec3fcd2f3417f2f1fe592781 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 01:39:55 +0300 Subject: [PATCH 0393/4858] document --activate flag --- src/doc/plugin-install.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/doc/plugin-install.txt b/src/doc/plugin-install.txt index b1b794009d..e39aadedb2 100644 --- a/src/doc/plugin-install.txt +++ b/src/doc/plugin-install.txt @@ -16,9 +16,13 @@ wp-plugin-install(1) -- Install a plugin from wordpress.org or from a zip file. If set, get that particular version from wordpress.org, instead of the stable version. +* `--activate`: + + If set, the plugin will be activated immediately after install. + ## EXAMPLES - wp plugin install bbpress --version=2.1 + wp plugin install bbpress --version=2.1 --activate wp plugin install bbpress --version=dev From e4da376edee681de577812283d396a79caa12cf3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 01:50:49 +0300 Subject: [PATCH 0394/4858] fix plugin path description --- src/doc/plugin-path.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/plugin-path.txt b/src/doc/plugin-path.txt index 805b88212d..08e804aa13 100644 --- a/src/doc/plugin-path.txt +++ b/src/doc/plugin-path.txt @@ -1,4 +1,4 @@ -wp-plugin-path(1) -- Activate/Deactivate an installed plugin. +wp-plugin-path(1) -- Get the path to a plugin or to the plugin directory. ==== ## SYNOPSIS From ea746df1873c8ba3c075f20fb4b683896bf49cc0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 01:55:04 +0300 Subject: [PATCH 0395/4858] theme: create doc files for each subcommand --- src/doc/theme-activate.txt | 12 ++++++++++++ src/doc/theme-delete.txt | 16 ++++++++++++++++ src/doc/theme-install.txt | 18 ++++++++++++++++++ src/doc/theme-path.txt | 18 ++++++++++++++++++ src/doc/theme-status.txt | 12 ++++++++++++ src/doc/theme-update.txt | 23 +++++++++++++++++++++++ src/doc/theme.txt | 18 ------------------ 7 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 src/doc/theme-activate.txt create mode 100644 src/doc/theme-delete.txt create mode 100644 src/doc/theme-install.txt create mode 100644 src/doc/theme-path.txt create mode 100644 src/doc/theme-status.txt create mode 100644 src/doc/theme-update.txt delete mode 100644 src/doc/theme.txt diff --git a/src/doc/theme-activate.txt b/src/doc/theme-activate.txt new file mode 100644 index 0000000000..24a492d716 --- /dev/null +++ b/src/doc/theme-activate.txt @@ -0,0 +1,12 @@ +wp-theme-activate(1) -- Activate an installed theme. +==== + +## SYNOPSIS + +`wp theme activate` <theme> + +## OPTIONS + +* `<theme>`: + + The theme to activate. diff --git a/src/doc/theme-delete.txt b/src/doc/theme-delete.txt new file mode 100644 index 0000000000..94fa90cca2 --- /dev/null +++ b/src/doc/theme-delete.txt @@ -0,0 +1,16 @@ +wp-theme-delete(1) -- Delete a theme. +==== + +## SYNOPSIS + +`wp theme delete` <theme> + +## OPTIONS + +* <theme>: + + The theme to delete. + +## EXAMPLES + + wp theme delete twentyeleven diff --git a/src/doc/theme-install.txt b/src/doc/theme-install.txt new file mode 100644 index 0000000000..4f06c251b0 --- /dev/null +++ b/src/doc/theme-install.txt @@ -0,0 +1,18 @@ +wp-theme-install(1) -- Install a theme from wordpress.org or from a zip file. +==== + +## SYNOPSIS + +`wp theme install` <theme/zip> + +## OPTIONS + +* <theme>: + + A theme slug or the path to a zip file. + +## EXAMPLES + + wp theme install twentytwelve + + wp theme install ../my-theme.zip diff --git a/src/doc/theme-path.txt b/src/doc/theme-path.txt new file mode 100644 index 0000000000..32bb5c876d --- /dev/null +++ b/src/doc/theme-path.txt @@ -0,0 +1,18 @@ +wp-theme-path(1) -- Get the path to a theme or to the theme directory. +==== + +## SYNOPSIS + +`wp theme path` [<theme>] [--dir] + +## OPTIONS + +* `<theme>`: + + The theme to get the path to. If not set, will return the path to the +themes directory. + +* `--dir`: + + If set, get the path to the closest parent directory, instead of the +theme file. diff --git a/src/doc/theme-status.txt b/src/doc/theme-status.txt new file mode 100644 index 0000000000..48b5dfe149 --- /dev/null +++ b/src/doc/theme-status.txt @@ -0,0 +1,12 @@ +wp-theme-status(1) -- See the status of one or all themes. +==== + +## SYNOPSIS + +`wp theme status` [<theme>] + +## OPTIONS + +* `<theme>`: + + A particular theme to show the status for. diff --git a/src/doc/theme-update.txt b/src/doc/theme-update.txt new file mode 100644 index 0000000000..e6f5c5e012 --- /dev/null +++ b/src/doc/theme-update.txt @@ -0,0 +1,23 @@ +wp-theme-update(1) -- Update an installed theme. +==== + +## SYNOPSIS + +`wp theme update` [<theme>] [--all] + +## OPTIONS + +* <theme>: + + The theme to update. Can be omitted when --all is passed. + +* `--all`: + + If set, updates for all themes will be performed. Use `wp theme status` +to see which themes have updates available. + +## EXAMPLES + + wp theme update twentytwelve + + wp theme update --all diff --git a/src/doc/theme.txt b/src/doc/theme.txt deleted file mode 100644 index 094d7be4a1..0000000000 --- a/src/doc/theme.txt +++ /dev/null @@ -1,18 +0,0 @@ -usage: wp theme <sub-command> [<theme-name>] - or: wp theme path [<theme-name>] [--dir] - -Available sub-commands: - status display status of all installed themes or of a particular theme - - activate activate a particular theme - - path print path to the theme's stylesheet - --dir get the path to the closest parent directory - - install install a theme from wordpress.org or from a zip file - --activate activate the theme after installing it - - update update a theme from wordpress.org - --all update all themes from wordpress.org - - delete delete a theme From 88dbebf0872e366786c64e5711ac3cfc2f5c93ab Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 May 2012 02:03:03 +0300 Subject: [PATCH 0396/4858] add generated ROFF files to git, for convenience --- .gitignore | 1 - man/blog-create.1 | 43 +++++++++++++++++++++++++ man/core-config.1 | 43 +++++++++++++++++++++++++ man/core-download.1 | 27 ++++++++++++++++ man/core-install.1 | 43 +++++++++++++++++++++++++ man/core-update.1 | 10 ++++++ man/core-version.1 | 19 +++++++++++ man/db-cli.1 | 10 ++++++ man/db-connect.1 | 10 ++++++ man/db-create.1 | 10 ++++++ man/db-export.1 | 19 +++++++++++ man/db-import.1 | 19 +++++++++++ man/db-query.1 | 19 +++++++++++ man/eval-file.1 | 19 +++++++++++ man/eval.1 | 19 +++++++++++ man/export.1 | 71 +++++++++++++++++++++++++++++++++++++++++ man/generate-posts.1 | 37 +++++++++++++++++++++ man/generate-users.1 | 25 +++++++++++++++ man/home.1 | 10 ++++++ man/option.1 | 60 ++++++++++++++++++++++++++++++++++ man/plugin-activate.1 | 19 +++++++++++ man/plugin-deactivate.1 | 19 +++++++++++ man/plugin-delete.1 | 27 ++++++++++++++++ man/plugin-install.1 | 43 +++++++++++++++++++++++++ man/plugin-path.1 | 25 +++++++++++++++ man/plugin-status.1 | 19 +++++++++++ man/plugin-toggle.1 | 19 +++++++++++ man/plugin-uninstall.1 | 27 ++++++++++++++++ man/plugin-update.1 | 35 ++++++++++++++++++++ man/theme-activate.1 | 19 +++++++++++ man/theme-delete.1 | 27 ++++++++++++++++ man/theme-install.1 | 29 +++++++++++++++++ man/theme-path.1 | 25 +++++++++++++++ man/theme-status.1 | 19 +++++++++++ man/theme-update.1 | 35 ++++++++++++++++++++ man/transient.1 | 48 ++++++++++++++++++++++++++++ man/user-create.1 | 39 ++++++++++++++++++++++ man/user-delete.1 | 33 +++++++++++++++++++ man/user-list.1 | 19 +++++++++++ man/user-update.1 | 33 +++++++++++++++++++ utils/build-doc | 1 + 41 files changed, 1073 insertions(+), 1 deletion(-) create mode 100644 man/blog-create.1 create mode 100644 man/core-config.1 create mode 100644 man/core-download.1 create mode 100644 man/core-install.1 create mode 100644 man/core-update.1 create mode 100644 man/core-version.1 create mode 100644 man/db-cli.1 create mode 100644 man/db-connect.1 create mode 100644 man/db-create.1 create mode 100644 man/db-export.1 create mode 100644 man/db-import.1 create mode 100644 man/db-query.1 create mode 100644 man/eval-file.1 create mode 100644 man/eval.1 create mode 100644 man/export.1 create mode 100644 man/generate-posts.1 create mode 100644 man/generate-users.1 create mode 100644 man/home.1 create mode 100644 man/option.1 create mode 100644 man/plugin-activate.1 create mode 100644 man/plugin-deactivate.1 create mode 100644 man/plugin-delete.1 create mode 100644 man/plugin-install.1 create mode 100644 man/plugin-path.1 create mode 100644 man/plugin-status.1 create mode 100644 man/plugin-toggle.1 create mode 100644 man/plugin-uninstall.1 create mode 100644 man/plugin-update.1 create mode 100644 man/theme-activate.1 create mode 100644 man/theme-delete.1 create mode 100644 man/theme-install.1 create mode 100644 man/theme-path.1 create mode 100644 man/theme-status.1 create mode 100644 man/theme-update.1 create mode 100644 man/transient.1 create mode 100644 man/user-create.1 create mode 100644 man/user-delete.1 create mode 100644 man/user-list.1 create mode 100644 man/user-update.1 diff --git a/.gitignore b/.gitignore index 472657eea6..d9cdde38e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /.build /dist -/man diff --git a/man/blog-create.1 b/man/blog-create.1 new file mode 100644 index 0000000000..e75b5ee6c8 --- /dev/null +++ b/man/blog-create.1 @@ -0,0 +1,43 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-BLOG\-CREATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-blog\-create\fR \- Create a new blog in a multisite install\. +. +.SH "SYNOPSIS" +\fBwp blog create\fR \-\-slug=\fIslug\fR \-\-title=\fITitle\fR [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-public=true] +. +.SH "OPTIONS" +. +.TP +\fB\-\-slug\fR=\fIslug\fR: +. +.IP +Base for the new domain\. Subdomain on subdomain installs, directory on subdirectory installs\. +. +.TP +\fB\-\-title\fR=<title>: +. +.IP +Title of the new blog\. +. +.TP +\fB\-\-email\fR=\fIemail\fR: +. +.IP +Email for Admin user\. User will be created if none exists\. Assignement to Super Admin if not included\. +. +.TP +\fB\-\-site_id\fR=\fIsite\-id\fR: +. +.IP +Site (network) to associate new blog with\. Defaults to current site (typically 1)\. +. +.TP +\fB\-\-private\fR: +. +.IP +If set, the new blog will be non\-public (not indexed) + diff --git a/man/core-config.1 b/man/core-config.1 new file mode 100644 index 0000000000..0235a39bc9 --- /dev/null +++ b/man/core-config.1 @@ -0,0 +1,43 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-CONFIG" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-config\fR \- Create a wp\-config\.php file\. +. +.SH "SYNOPSIS" +\fBwp core config\fR \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=localhost] [\-\-dbprefix=wp_] +. +.SH "OPTIONS" +. +.TP +\fB\-\-dbname\fR=\fIdbname\fR: +. +.IP +Set the database name\. +. +.TP +\fB\-\-dbuser\fR=\fIdbuser\fR: +. +.IP +Set the database user\. +. +.TP +\fB\-\-dbpass\fR=\fIdbpass\fR: +. +.IP +Set the database user password\. +. +.TP +\fB\-\-dbhost\fR=\fIdbhost\fR: +. +.IP +Set the database host\. Default: \'localhost\' +. +.TP +\fB\-\-dbprefix\fR=\fIdbprefix\fR: +. +.IP +Set the database table prefix\. Default: \'wp_\' + diff --git a/man/core-download.1 b/man/core-download.1 new file mode 100644 index 0000000000..95d38d7819 --- /dev/null +++ b/man/core-download.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-DOWNLOAD" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-download\fR \- Download core WordPress files\. +. +.SH "SYNOPSIS" +\fBwp core download\fR [\-\-version=\fIversion\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-version\fR=\fIversion\fR: +. +.IP +Select which version you want to download\. +. +.SH "EXAMPLES" +. +.nf + +Download version 3\.3: wp core download \-\-version=3\.3 +. +.fi + diff --git a/man/core-install.1 b/man/core-install.1 new file mode 100644 index 0000000000..e8ab094784 --- /dev/null +++ b/man/core-install.1 @@ -0,0 +1,43 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-INSTALL" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-install\fR \- Install the WordPress tables in the database\. +. +.SH "SYNOPSIS" +\fBwp core install\fR \-\-site_url=\fIurl\fR \-\-site_title=\fItitle> [\-\-admin_name=<username\fR] \-\-admin_password=\fIpassword\fR \-\-admin_email=\fIemail\fR +. +.SH "OPTIONS" +. +.TP +\fB\-\-site_url\fR=\fIurl\fR: +. +.IP +The address of the new site\. +. +.TP +\fB\-\-site_title\fR=<title>: +. +.IP +The title of the new site\. +. +.TP +\fB\-\-admin_name\fR=\fIusername\fR: +. +.IP +The name of the admin user\. Default: \'admin\' +. +.TP +\fB\-\-admin_password\fR=\fIpassword\fR: +. +.IP +The password for the admin user\. +. +.TP +\fB\-\-admin_email\fR=\fIemail\fR: +. +.IP +The email address for the admin user\. + diff --git a/man/core-update.1 b/man/core-update.1 new file mode 100644 index 0000000000..24a01f15e9 --- /dev/null +++ b/man/core-update.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-UPDATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-update\fR \- Update WordPress to the latest version\. +. +.SH "SYNOPSIS" +\fBwp core update\fR diff --git a/man/core-version.1 b/man/core-version.1 new file mode 100644 index 0000000000..160ccb3765 --- /dev/null +++ b/man/core-version.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-VERSION" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-version\fR \- Show the WordPress version\. +. +.SH "SYNOPSIS" +\fBwp core version\fR [\-\-extra] +. +.SH "OPTIONS" +. +.TP +\fB\-\-extra\fR: +. +.IP +Show extended version information\. + diff --git a/man/db-cli.1 b/man/db-cli.1 new file mode 100644 index 0000000000..22f397c05b --- /dev/null +++ b/man/db-cli.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-CLI" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-cli\fR \- Open a SQL command\-line interface to the WordPress database\. +. +.SH "SYNOPSIS" +\fBwp db cli\fR diff --git a/man/db-connect.1 b/man/db-connect.1 new file mode 100644 index 0000000000..ea799644f8 --- /dev/null +++ b/man/db-connect.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-CONNECT" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-connect\fR \- Print a string for connecting to the database\. +. +.SH "SYNOPSIS" +\fBwp db connect\fR diff --git a/man/db-create.1 b/man/db-create.1 new file mode 100644 index 0000000000..93f9295825 --- /dev/null +++ b/man/db-create.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-CREATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-create\fR \- Create a database using the credentials from wp\-config\.php\. +. +.SH "SYNOPSIS" +\fBwp db create\fR diff --git a/man/db-export.1 b/man/db-export.1 new file mode 100644 index 0000000000..33648242f0 --- /dev/null +++ b/man/db-export.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-EXPORT" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-export\fR \- Export the WordPress database using mysqldump\. +. +.SH "SYNOPSIS" +\fBwp db export\fR [\fIfile\fR] +. +.SH "OPTIONS" +. +.TP +\fB<file>\fR: +. +.IP +The name of the export file\. If omitted, it will be \'{dbname}\.sql\' + diff --git a/man/db-import.1 b/man/db-import.1 new file mode 100644 index 0000000000..987cade497 --- /dev/null +++ b/man/db-import.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-IMPORT" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-import\fR \- Import a database from a text file\. +. +.SH "SYNOPSIS" +\fBwp db import\fR [\fIfile\fR] +. +.SH "OPTIONS" +. +.TP +\fB<file>\fR: +. +.IP +The name of the import file\. If omitted, it will be \'{dbname}\.sql\' + diff --git a/man/db-query.1 b/man/db-query.1 new file mode 100644 index 0000000000..0326bd394b --- /dev/null +++ b/man/db-query.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-QUERY" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-query\fR \- Execute a query against the WordPress database\. +. +.SH "SYNOPSIS" +\fBwp db query\fR \fISQL\fR +. +.SH "OPTIONS" +. +.TP +\fB<SQL>\fR: +. +.IP +A SQL query\. + diff --git a/man/eval-file.1 b/man/eval-file.1 new file mode 100644 index 0000000000..5060788e1f --- /dev/null +++ b/man/eval-file.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-EVAL\-FILE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-eval\-file\fR \- Loads and executes a PHP file after loading WordPress\. +. +.SH "SYNOPSIS" +\fBwp eval\-file\fR \fIfile\fR +. +.SH "EXAMPLES" +. +.nf + +wp eval\-file my\-code\.php +. +.fi + diff --git a/man/eval.1 b/man/eval.1 new file mode 100644 index 0000000000..473ec61df4 --- /dev/null +++ b/man/eval.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-EVAL" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-eval\fR \- Executes arbitrary PHP code after loading WordPress\. +. +.SH "SYNOPSIS" +\fBwp eval\fR \fIPHP\fR +. +.SH "EXAMPLES" +. +.nf + +wp eval \'echo WP_CONTENT_DIR;\' +. +.fi + diff --git a/man/export.1 b/man/export.1 new file mode 100644 index 0000000000..d064d5db0b --- /dev/null +++ b/man/export.1 @@ -0,0 +1,71 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-EXPORT" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-export\fR \- Create a WXR file\. +. +.SH "SYNOPSIS" +\fBwp export\fR \-\-path=\fIdirname\fR [filters] [\-\-skip_comments] +. +.SH "OPTIONS" +. +.TP +\fB\-\-path\fR=\fIdirname\fR: +. +.IP +Full Path to directory where WXR export files should be stored\. +. +.TP +\fB\-\-skip_comments\fR: +. +.IP +Don\'t export comments\. +. +.SH "FILTERS" +. +.TP +\fB\-\-start_date\fR=\fIdate\fR: +. +.IP +Export only posts newer than this date in format YYYY\-MM\-DD\. +. +.TP +\fB\-\-end_date\fR=\fIdate\fR: +. +.IP +Export only posts older than this date in format YYYY\-MM\-DD\. +. +.TP +\fB\-\-post_type\fR=\fIpost_type\fR: +. +.IP +Export only posts with this post_type\. +. +.TP +\fB\-\-author\fR=<login/id>: +. +.IP +Export only posts by this author\. +. +.TP +\fB\-\-category\fR=\fIcategory\-id\fR: +. +.IP +Export only posts in this category\. +. +.TP +\fB\-\-post_status\fR=\fIstatus\fR: +. +.IP +Export only posts with this status\. +. +.SH "EXAMPLES" +. +.nf + +wp export \-\-path=/tmp/ \-\-user=admin \-\-post_type=post \-\-start_date=2011\-01\-01 \-\-end_date=2011\-12\-31 +. +.fi + diff --git a/man/generate-posts.1 b/man/generate-posts.1 new file mode 100644 index 0000000000..c014d4ff63 --- /dev/null +++ b/man/generate-posts.1 @@ -0,0 +1,37 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-GENERATE\-POSTS" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-generate\-posts\fR \- Generate a bunch of posts\. +. +.SH "SYNOPSIS" +\fBwp generate posts\fR [\-\-count=100] [\-\-type=post] [\-\-status=publish] [\-\-author=\fIlogin\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-count\fR=\fInumber\fR: +. +.IP +How many posts to generate\. Default: 100 +. +.TP +\fB\-\-type\fR=\fIpost_type\fR: +. +.IP +The type of the generated posts\. Default: \'post\' +. +.TP +\fB\-\-status\fR=\fIpost_status\fR: +. +.IP +The status of the generated posts\. Default: \'publish\' +. +.TP +\fB\-\-author\fR=\fIlogin\fR: +. +.IP +The author of the generated posts\. Default: none + diff --git a/man/generate-users.1 b/man/generate-users.1 new file mode 100644 index 0000000000..9fadb9950d --- /dev/null +++ b/man/generate-users.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-GENERATE\-USERS" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-generate\-users\fR \- Generate a bunch of users\. +. +.SH "SYNOPSIS" +\fBwp generate users\fR [\-\-count=100] [\-\-role=\fIrole\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-count\fR=\fInumber\fR: +. +.IP +How many users to generate\. Default: 100 +. +.TP +\fB\-\-role\fR=\fIrole\fR: +. +.IP +The role of the generated users\. Default: default role from WP + diff --git a/man/home.1 b/man/home.1 new file mode 100644 index 0000000000..0695908844 --- /dev/null +++ b/man/home.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-HOME" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-home\fR \- Opens the wp\-cli homepage in your browser\. +. +.SH "SYNOPSIS" +\fBwp home\fR diff --git a/man/option.1 b/man/option.1 new file mode 100644 index 0000000000..30580ae815 --- /dev/null +++ b/man/option.1 @@ -0,0 +1,60 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-OPTION" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-option\fR \- Manage WordPress options\. +. +.SH "SYNOPSIS" +wp option get \fIkey\fR +. +.P +wp option add \fIkey\fR \fIvalue\fR +. +.P +wp option update \fIkey\fR \fIvalue\fR +. +.P +wp option delete \fIkey\fR +. +.SH "SUBCOMMANDS" +. +.TP +\fBget\fR: +. +.IP +Get an option value\. +. +.TP +\fBadd\fR: +. +.IP +Add a new option\. +. +.TP +\fBupdate\fR: +. +.IP +Update an existing option\. +. +.TP +\fBdelete\fR: +. +.IP +Delete an option\. +. +.SH "EXAMPLES" +. +.nf + +wp option get siteurl + +wp option add my_option foobar + +wp option update my_option barfoo + +wp option delete my_option +. +.fi + diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 new file mode 100644 index 0000000000..f78e014367 --- /dev/null +++ b/man/plugin-activate.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-ACTIVATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-activate\fR \- Activate an installed plugin\. +. +.SH "SYNOPSIS" +\fBwp plugin activate\fR \fIplugin\fR +. +.SH "OPTIONS" +. +.TP +\fB<plugin>\fR: +. +.IP +The plugin to activate\. + diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 new file mode 100644 index 0000000000..25bd7b38f3 --- /dev/null +++ b/man/plugin-deactivate.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-deactivate\fR \- Deactivate an active plugin\. +. +.SH "SYNOPSIS" +\fBwp plugin deactivate\fR \fIplugin\fR +. +.SH "OPTIONS" +. +.TP +\fB<plugin>\fR: +. +.IP +The plugin to deactivate\. + diff --git a/man/plugin-delete.1 b/man/plugin-delete.1 new file mode 100644 index 0000000000..b6c3b20340 --- /dev/null +++ b/man/plugin-delete.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-DELETE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-delete\fR \- Delete a plugin\'s files, without removing it\'s data\. +. +.SH "SYNOPSIS" +\fBwp plugin delete\fR \fIplugin\fR +. +.SH "OPTIONS" +. +.TP +\fIplugin\fR: +. +.IP +The plugin to delete\. +. +.SH "EXAMPLES" +. +.nf + +wp plugin delete hello +. +.fi + diff --git a/man/plugin-install.1 b/man/plugin-install.1 new file mode 100644 index 0000000000..a90117f766 --- /dev/null +++ b/man/plugin-install.1 @@ -0,0 +1,43 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-INSTALL" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-install\fR \- Install a plugin from wordpress\.org or from a zip file\. +. +.SH "SYNOPSIS" +\fBwp plugin install\fR <plugin/zip> [\-\-version=\fIversion\fR] [\-\-activate] +. +.SH "OPTIONS" +. +.TP +\fIplugin\fR: +. +.IP +A plugin slug or the path to a zip file\. +. +.TP +\fB\-\-version\fR=\fIversion\fR: +. +.IP +If set, get that particular version from wordpress\.org, instead of the stable version\. +. +.TP +\fB\-\-activate\fR: +. +.IP +If set, the plugin will be activated immediately after install\. +. +.SH "EXAMPLES" +. +.nf + +wp plugin install bbpress \-\-version=2\.1 \-\-activate + +wp plugin install bbpress \-\-version=dev + +wp plugin install \.\./my\-plugin\.zip +. +.fi + diff --git a/man/plugin-path.1 b/man/plugin-path.1 new file mode 100644 index 0000000000..cbf20513b6 --- /dev/null +++ b/man/plugin-path.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-PATH" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-path\fR \- Get the path to a plugin or to the plugin directory\. +. +.SH "SYNOPSIS" +\fBwp plugin path\fR [\fIplugin\fR] [\-\-dir] +. +.SH "OPTIONS" +. +.TP +\fB<plugin>\fR: +. +.IP +The plugin to get the path to\. If not set, will return the path to the plugins directory\. +. +.TP +\fB\-\-dir\fR: +. +.IP +If set, get the path to the closest parent directory, instead of the plugin file\. + diff --git a/man/plugin-status.1 b/man/plugin-status.1 new file mode 100644 index 0000000000..cbf0900fd9 --- /dev/null +++ b/man/plugin-status.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-STATUS" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-status\fR \- See the status of one or all plugins\. +. +.SH "SYNOPSIS" +\fBwp plugin status\fR [\fIplugin\fR] +. +.SH "OPTIONS" +. +.TP +\fB<plugin>\fR: +. +.IP +A particular plugin to show the status for\. + diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 new file mode 100644 index 0000000000..36a4a599d6 --- /dev/null +++ b/man/plugin-toggle.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-deactivate\fR \- Activate/Deactivate an installed plugin\. +. +.SH "SYNOPSIS" +\fBwp plugin toggle\fR \fIplugin\fR +. +.SH "OPTIONS" +. +.TP +\fB<plugin>\fR: +. +.IP +The plugin to toggle\. + diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 new file mode 100644 index 0000000000..de306138d3 --- /dev/null +++ b/man/plugin-uninstall.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-UNINSTALL" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-uninstall\fR \- Run the uninstallation procedure for a plugin\. +. +.SH "SYNOPSIS" +\fBwp plugin uninstall\fR \fIplugin\fR +. +.SH "OPTIONS" +. +.TP +\fIplugin\fR: +. +.IP +The plugin to uninstall\. +. +.SH "EXAMPLES" +. +.nf + +wp plugin uninstall hello +. +.fi + diff --git a/man/plugin-update.1 b/man/plugin-update.1 new file mode 100644 index 0000000000..63d2c81612 --- /dev/null +++ b/man/plugin-update.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-UPDATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-update\fR \- Update an installed plugin\. +. +.SH "SYNOPSIS" +\fBwp plugin update\fR [\fIplugin\fR] [\-\-all] +. +.SH "OPTIONS" +. +.TP +\fIplugin\fR: +. +.IP +The plugin to update\. Can be omitted when \-\-all is passed\. +. +.TP +\fB\-\-all\fR: +. +.IP +If set, updates for all plugins will be performed\. Use \fBwp plugin status\fR to see which plugins have updates available\. +. +.SH "EXAMPLES" +. +.nf + +wp plugin update bbpress + +wp plugin update \-\-all +. +.fi + diff --git a/man/theme-activate.1 b/man/theme-activate.1 new file mode 100644 index 0000000000..0d8c95f482 --- /dev/null +++ b/man/theme-activate.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-ACTIVATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-activate\fR \- Activate an installed theme\. +. +.SH "SYNOPSIS" +\fBwp theme activate\fR \fItheme\fR +. +.SH "OPTIONS" +. +.TP +\fB<theme>\fR: +. +.IP +The theme to activate\. + diff --git a/man/theme-delete.1 b/man/theme-delete.1 new file mode 100644 index 0000000000..48f0c83571 --- /dev/null +++ b/man/theme-delete.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-DELETE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-delete\fR \- Delete a theme\. +. +.SH "SYNOPSIS" +\fBwp theme delete\fR \fItheme\fR +. +.SH "OPTIONS" +. +.TP +\fItheme\fR: +. +.IP +The theme to delete\. +. +.SH "EXAMPLES" +. +.nf + +wp theme delete twentyeleven +. +.fi + diff --git a/man/theme-install.1 b/man/theme-install.1 new file mode 100644 index 0000000000..6b15db128d --- /dev/null +++ b/man/theme-install.1 @@ -0,0 +1,29 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-INSTALL" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-install\fR \- Install a theme from wordpress\.org or from a zip file\. +. +.SH "SYNOPSIS" +\fBwp theme install\fR <theme/zip> +. +.SH "OPTIONS" +. +.TP +\fItheme\fR: +. +.IP +A theme slug or the path to a zip file\. +. +.SH "EXAMPLES" +. +.nf + +wp theme install twentytwelve + +wp theme install \.\./my\-theme\.zip +. +.fi + diff --git a/man/theme-path.1 b/man/theme-path.1 new file mode 100644 index 0000000000..3d806d0579 --- /dev/null +++ b/man/theme-path.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-PATH" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-path\fR \- Get the path to a theme or to the theme directory\. +. +.SH "SYNOPSIS" +\fBwp theme path\fR [\fItheme\fR] [\-\-dir] +. +.SH "OPTIONS" +. +.TP +\fB<theme>\fR: +. +.IP +The theme to get the path to\. If not set, will return the path to the themes directory\. +. +.TP +\fB\-\-dir\fR: +. +.IP +If set, get the path to the closest parent directory, instead of the theme file\. + diff --git a/man/theme-status.1 b/man/theme-status.1 new file mode 100644 index 0000000000..2d68b088df --- /dev/null +++ b/man/theme-status.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-STATUS" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-status\fR \- See the status of one or all themes\. +. +.SH "SYNOPSIS" +\fBwp theme status\fR [\fItheme\fR] +. +.SH "OPTIONS" +. +.TP +\fB<theme>\fR: +. +.IP +A particular theme to show the status for\. + diff --git a/man/theme-update.1 b/man/theme-update.1 new file mode 100644 index 0000000000..686ccb02af --- /dev/null +++ b/man/theme-update.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-UPDATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-update\fR \- Update an installed theme\. +. +.SH "SYNOPSIS" +\fBwp theme update\fR [\fItheme\fR] [\-\-all] +. +.SH "OPTIONS" +. +.TP +\fItheme\fR: +. +.IP +The theme to update\. Can be omitted when \-\-all is passed\. +. +.TP +\fB\-\-all\fR: +. +.IP +If set, updates for all themes will be performed\. Use \fBwp theme status\fR to see which themes have updates available\. +. +.SH "EXAMPLES" +. +.nf + +wp theme update twentytwelve + +wp theme update \-\-all +. +.fi + diff --git a/man/transient.1 b/man/transient.1 new file mode 100644 index 0000000000..d2307b45b0 --- /dev/null +++ b/man/transient.1 @@ -0,0 +1,48 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TRANSIENT" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-transient\fR \- Manage WordPress transients\. +. +.SH "SYNOPSIS" +wp transient get \fIkey\fR +. +.P +wp transient set \fIkey\fR \fIvalue\fR [\fIexpiration\fR] +. +.P +wp transient delete \fIkey\fR +. +.P +wp transient type +. +.SH "SUBCOMMANDS" +. +.TP +\fBget\fR: +. +.IP +Get a transient value\. +. +.TP +\fBset\fR: +. +.IP +Set a transient value\. \fIexpiration\fR is the time until expiration, in seconds\. +. +.TP +\fBdelete\fR: +. +.IP +Delete a transient value\. +. +.TP +\fBtype\fR: +. +.IP +See wether the transients API is using an object cache or the options table\. +. +.SH "EXAMPLES" +wp transient set my_key my_value 300 diff --git a/man/user-create.1 b/man/user-create.1 new file mode 100644 index 0000000000..9f71326f32 --- /dev/null +++ b/man/user-create.1 @@ -0,0 +1,39 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-CREATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-create\fR \- Create a new WordPress user\. +. +.SH "SYNOPSIS" +\fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] +. +.SH "OPTIONS" +. +.TP +\fB<user\-login>\fR: +. +.IP +The login of the user to create\. +. +.TP +\fB<user\-email>\fR: +. +.IP +The email address of the user to create\. +. +.TP +\fB\-\-role\fR=\fIrole\fR: +. +.IP +The role of the user to create\. +. +.SH "EXAMPLES" +. +.nf + +wp user create bob bob@example\.com \-\-role=author +. +.fi + diff --git a/man/user-delete.1 b/man/user-delete.1 new file mode 100644 index 0000000000..dfab940b6d --- /dev/null +++ b/man/user-delete.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-DELETE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-delete\fR \- Delete a WordPress user\. +. +.SH "SYNOPSIS" +\fBwp user delete\fR \fIID\fR [\-\-reassign=\fIID\fR] +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the user to delete\. +. +.TP +\fB\-\-reassign\fR=\fIID\fR: +. +.IP +User to reassign the posts to\. +. +.SH "EXAMPLES" +. +.nf + +wp user delete 123 \-\-reassign=567 +. +.fi + diff --git a/man/user-list.1 b/man/user-list.1 new file mode 100644 index 0000000000..1ae1b93b54 --- /dev/null +++ b/man/user-list.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-LIST" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-list\fR \- List WordPress users\. +. +.SH "SYNOPSIS" +\fBwp user list\fR [\-\-role=\fIrole\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-role\fR=\fIrole\fR: +. +.IP +Only display users with a certain role\. + diff --git a/man/user-update.1 b/man/user-update.1 new file mode 100644 index 0000000000..c5b8af7f21 --- /dev/null +++ b/man/user-update.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-UPDATE" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-update\fR \- Update a WordPress user\. +. +.SH "SYNOPSIS" +\fBwp user update\fR \fIID\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the user to update\. +. +.TP +\fB\-\-<field>\fR=\fIvalue\fR: +. +.IP +One or more fields to update\. For accepted fields, see wp_update_user()\. +. +.SH "EXAMPLES" +. +.nf + +wp user update 123 \-\-user_login=mary \-\-display_name=Mary +. +.fi + diff --git a/utils/build-doc b/utils/build-doc index 9b8866e41e..eaa0b40e1c 100755 --- a/utils/build-doc +++ b/utils/build-doc @@ -2,6 +2,7 @@ # generate man pages +rm -rf man mkdir -p man for file in $(ls src/doc/*.txt); do From a66fc1e6c5d561436d2b8421820e024936d4635e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 May 2012 17:20:44 +0300 Subject: [PATCH 0397/4858] use $this->upgrader in plugin install --- src/php/wp-cli/commands/internals/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 13963a78e5..c9f1191396 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -204,7 +204,7 @@ protected function install_from_repo( $slug, $assoc_args ) { switch ( $status['status'] ) { case 'update_available': case 'install': - $upgrader = WP_CLI::get_upgrader( 'Plugin_Upgrader' ); + $upgrader = WP_CLI::get_upgrader( $this->upgrader ); $result = $upgrader->install( $api->download_link ); if ( $result && isset( $assoc_args['activate'] ) ) { From 015d696b03029778069c69209ada5ad75a9144e2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 16:26:17 +0300 Subject: [PATCH 0398/4858] bump version to 0.6.0-dev --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index b932b719f9..d4d878ba0b 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,7 +4,7 @@ die( 'Only cli access' ); } -define( 'WP_CLI_VERSION', '0.5.0' ); +define( 'WP_CLI_VERSION', '0.6.0-dev' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 9f15ead2d0e873106f3e7029a8ab4c5856019a19 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 17:49:59 +0300 Subject: [PATCH 0399/4858] make WP_CLI::launch() return the exit status --- src/php/wp-cli/class-wp-cli.php | 4 +++- src/php/wp-cli/commands/internals/db.php | 2 +- src/php/wp-cli/commands/internals/help.php | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 5387b49149..c078cbe694 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -152,9 +152,11 @@ static function legend( $legend ) { * Launch an external process, closing the current one * * @param string Command to call + * + * @return int The command exit status */ static function launch( $command ) { - proc_close( proc_open( $command, array( 0 => STDIN, 1 => STDOUT, 2 => STDERR ), $pipes ) ); + return proc_close( proc_open( $command, array( STDIN, STDOUT, STDERR ), $pipes ) ); } /** diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 9239e1811f..8934075017 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -33,7 +33,7 @@ function connect() { * Open a SQL command-line interface using WordPress's credentials. */ function cli() { - WP_CLI::launch( $this->connect_string() ); + exit( WP_CLI::launch( $this->connect_string() ) ); } /** diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index ae8dc1024c..8ca0538e26 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -30,8 +30,7 @@ private function maybe_load_man_page( $args ) { $man_file = $man_dir . implode( '-', $args ) . '.1'; if ( is_readable( $man_file ) ) { - WP_CLI::launch( "man $man_file" ); - exit; + exit( WP_CLI::launch( "man $man_file" ) ); } } } From 86416ae9521689dea98f4a20bc7eb2d5176a5168 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 17:52:13 +0300 Subject: [PATCH 0400/4858] don't run uninstall procedure in wp plugin delete. fixes #109 --- src/php/wp-cli/commands/internals/plugin.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index c9f1191396..84d8cd0f9a 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -242,20 +242,18 @@ function uninstall( $args ) { } /** - * Delete a plugin + * Delete plugin files * * @param array $args */ function delete( $args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - if ( is_plugin_active( $file ) ) { - WP_CLI::error( 'The plugin is active.' ); - } + $plugin_dir = dirname( $file ); + if ( '.' == $plugin_dir ) + $plugin_dir = $file; - if ( !delete_plugins( array( $file ) ) ) { - WP_CLI::error( 'There was an error while deleting the plugin.' ); - } + exit( WP_CLI::launch( 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ) ) ); } /* PRIVATES */ From a5969570ae2e365d6bd82165f6eb33229bc8e973 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 18:27:08 +0300 Subject: [PATCH 0401/4858] make --admin_password optional. fixes #106 --- src/php/wp-cli/commands/internals/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index e1764c0503..add41e0596 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -69,11 +69,11 @@ public function install( $args, $assoc_args ) { 'site_title' => '', 'admin_name' => 'admin', 'admin_email' => '', - 'admin_password' => '' + 'admin_password' => wp_generate_password( 12, false ) ) ), EXTR_SKIP ); $missing = false; - foreach ( array( 'site_url', 'site_title', 'admin_email', 'admin_password' ) as $required_arg ) { + foreach ( array( 'site_url', 'site_title', 'admin_email' ) as $required_arg ) { if ( empty( $$required_arg ) ) { WP_CLI::warning( "missing --$required_arg parameter" ); $missing = true; From 7d32c526708ee7774b28c54b0603f8b3104f145a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 19:32:16 +0300 Subject: [PATCH 0402/4858] make WP_CLI_Command_With_Upgrade abstract --- .../wp-cli/class-wp-cli-command-with-upgrade.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index cad2fd1d8b..5f43900778 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -1,9 +1,23 @@ <?php -class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { +abstract class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { + + protected $item_type; + protected $upgrader; + protected $upgrade_refresh; + protected $upgrade_transient; protected $default_subcommand = 'status'; + abstract protected function parse_name( $args, $subcommand ); + + abstract protected function get_item_list(); + + abstract protected function status_all(); + abstract protected function status_single( $file, $name ); + + abstract protected function install_from_repo( $slug, $assoc_args ); + /** * Get the status of one or all items * From d4fa0c697849bbf46f2f095f968f400e3514cf9c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 19:51:44 +0300 Subject: [PATCH 0403/4858] add wp plugin update --version=dev. fixes #83 --- src/php/wp-cli/commands/internals/plugin.php | 22 ++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 84d8cd0f9a..3d3e30ee49 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -222,6 +222,21 @@ protected function install_from_repo( $slug, $assoc_args ) { } } + /** + * Update a plugin (to the latest dev version) + * + * @param array $args + * @param array $assoc_args + */ + function update( $args, $assoc_args ) { + if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { + $this->delete( $args, array(), false ); + $this->install( $args, $assoc_args ); + } else { + parent::update( $args, $assoc_args ); + } + } + protected function get_item_list() { return array_keys( get_plugins() ); } @@ -246,14 +261,17 @@ function uninstall( $args ) { * * @param array $args */ - function delete( $args ) { + function delete( $args, $assoc_args = array(), $exit_on_success = true ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $plugin_dir = dirname( $file ); if ( '.' == $plugin_dir ) $plugin_dir = $file; - exit( WP_CLI::launch( 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ) ) ); + $status = WP_CLI::launch( 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ) ); + + if ( $status || $exit_on_success ) + exit( $status ); } /* PRIVATES */ From 132830f305aa77ffa9b04343b7b299b12ae43111 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 20:04:15 +0300 Subject: [PATCH 0404/4858] update docs for wp plugin update. see #83 --- man/plugin-update.1 | 10 ++++++++-- src/doc/plugin-update.txt | 9 +++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/man/plugin-update.1 b/man/plugin-update.1 index 63d2c81612..a5f21a8ebd 100644 --- a/man/plugin-update.1 +++ b/man/plugin-update.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-update\fR \- Update an installed plugin\. . .SH "SYNOPSIS" -\fBwp plugin update\fR [\fIplugin\fR] [\-\-all] +\fBwp plugin update\fR [\fIplugin\fR] [\-\-all] [\-\-version=dev] . .SH "OPTIONS" . @@ -18,6 +18,12 @@ The plugin to update\. Can be omitted when \-\-all is passed\. . .TP +\fB\-\-version=dev\fR: +. +.IP +If set, the plugin will be updated to the latest development version, regardless of what version is currently installed\. Not compatible with \-\-all\. +. +.TP \fB\-\-all\fR: . .IP @@ -27,7 +33,7 @@ If set, updates for all plugins will be performed\. Use \fBwp plugin status\fR t . .nf -wp plugin update bbpress +wp plugin update bbpress \-\-version=dev wp plugin update \-\-all . diff --git a/src/doc/plugin-update.txt b/src/doc/plugin-update.txt index f909d53bfa..4be28128b2 100644 --- a/src/doc/plugin-update.txt +++ b/src/doc/plugin-update.txt @@ -3,7 +3,7 @@ wp-plugin-update(1) -- Update an installed plugin. ## SYNOPSIS -`wp plugin update` [<plugin>] [--all] +`wp plugin update` [<plugin>] [--all] [--version=dev] ## OPTIONS @@ -11,6 +11,11 @@ wp-plugin-update(1) -- Update an installed plugin. The plugin to update. Can be omitted when --all is passed. +* `--version=dev`: + + If set, the plugin will be updated to the latest development version, +regardless of what version is currently installed. Not compatible with --all. + * `--all`: If set, updates for all plugins will be performed. Use `wp plugin status` @@ -18,6 +23,6 @@ to see which plugins have updates available. ## EXAMPLES - wp plugin update bbpress + wp plugin update bbpress --version=dev wp plugin update --all From 474c2ff7ec35111b329b9f45bf3c02c30d62079e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 5 May 2012 20:05:50 +0300 Subject: [PATCH 0405/4858] rename build-* to *-build --- README.md | 2 +- utils/{build-dev => dev-build} | 0 utils/{build-doc => doc-build} | 0 utils/{build-local => local-build} | 0 utils/{build-pear => pear-build} | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename utils/{build-dev => dev-build} (100%) rename utils/{build-doc => doc-build} (100%) rename utils/{build-local => local-build} (100%) rename utils/{build-pear => pear-build} (100%) diff --git a/README.md b/README.md index e2578d61b4..936fd76920 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ sudo pear install wp-cli.github.com/pear/wpcli ```sh git clone --recurse-submodules git://github.com/wp-cli/wp-cli.git ~/git/wp-cli cd ~/git/wp-cli -sudo utils/build-dev +sudo utils/dev-build ``` You can replace `~/git/wp-cli` with whatever you want. diff --git a/utils/build-dev b/utils/dev-build similarity index 100% rename from utils/build-dev rename to utils/dev-build diff --git a/utils/build-doc b/utils/doc-build similarity index 100% rename from utils/build-doc rename to utils/doc-build diff --git a/utils/build-local b/utils/local-build similarity index 100% rename from utils/build-local rename to utils/local-build diff --git a/utils/build-pear b/utils/pear-build similarity index 100% rename from utils/build-pear rename to utils/pear-build From 30ae0109b51c632e49c98e033cfc6a7260d3cab5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 00:38:10 +0300 Subject: [PATCH 0406/4858] let `wp core download` handle case when a WP instance already exists --- src/php/wp-cli/wp-cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index d4d878ba0b..0ea4d4ec0b 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -51,13 +51,13 @@ define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); } +if ( array( 'core', 'download' ) == $arguments ) { + WP_CLI::run_command( $arguments, $assoc_args ); + exit; +} + if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { - if ( array( 'core', 'download' ) == $arguments ) { - WP_CLI::run_command( $arguments, $assoc_args ); - } else { - WP_CLI::error('This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.'); - exit; - } + WP_CLI::error( 'This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.' ); } if ( array( 'core', 'config' ) == $arguments ) { From 6089793c96fdae4c4556b2b0ecf322ff0df6280b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 00:45:46 +0300 Subject: [PATCH 0407/4858] suppress error message when generating autocomplete strings --- src/php/wp-cli/class-wp-cli.php | 5 ++++- src/php/wp-cli/wp-cli.php | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index c078cbe694..66bf874f29 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -46,7 +46,10 @@ static function line( $message = '' ) { * @param string $label */ static function error( $message, $label = 'Error' ) { - \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); + if ( !WP_CLI_AUTOCOMPLETE ) { + \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); + } + exit(1); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 0ea4d4ec0b..43e87e472f 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -26,7 +26,8 @@ // Get the cli arguments list( $arguments, $assoc_args ) = WP_CLI::parse_args( array_slice( $GLOBALS['argv'], 1 ) ); -// Check --silent flag +// Set output levels +define( 'WP_CLI_AUTOCOMPLETE', isset( $assoc_args['completions'] ) ); define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); // Handle --version parameter @@ -112,8 +113,8 @@ unset( $assoc_args['require'] ); } -// Handle --completions parameter -if ( isset( $assoc_args['completions'] ) ) { +// Generate strings for autocomplete +if ( WP_CLI_AUTOCOMPLETE ) { foreach ( WP_CLI::load_all_commands() as $name => $command ) { $subcommands = implode( ' ', WP_CLI_Command::get_subcommands( $command ) ); WP_CLI::line( $name . ' ' . $subcommands ); From ae6b539265360303f06fee0be986836561ee56ef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 01:11:15 +0300 Subject: [PATCH 0408/4858] add check_required_args() method and use it for wp core config. see #65 --- src/php/wp-cli/class-wp-cli.php | 24 ++++++++++++++++++++++ src/php/wp-cli/commands/internals/core.php | 15 ++++---------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 66bf874f29..7853c2c88e 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -136,6 +136,30 @@ static function compose_args( $args, $assoc_args = array() ) { return $str; } + /** + * Issue warnings for each missing associative argument. + * + * @param array List of required arg names + * @param array Passed args + */ + static function check_required_args( $required, $assoc_args ) { + $missing = false; + + foreach ( $required as $arg ) { + if ( !isset( $assoc_args[ $arg ] ) ) { + WP_CLI::warning( "--$arg parameter is missing" ); + $missing = true; + } elseif ( true === $assoc_args[ $arg ] ) { + // passed as a flag + WP_CLI::warning( "--$arg needs to have a value" ); + $missing = true; + } + } + + if ( $missing ) + exit(1); + } + /** * Display a legend * diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index add41e0596..04c87d2419 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -44,6 +44,8 @@ public function download( $args, $assoc_args ) { * Set up a wp-config.php file. */ public function config( $args, $assoc_args ) { + WP_CLI::check_required_args( array( 'dbname', 'dbuser', 'dbpass' ), $assoc_args ); + $_POST['dbname'] = $assoc_args['dbname']; $_POST['uname'] = $assoc_args['dbuser']; $_POST['pwd'] = $assoc_args['dbpass']; @@ -64,6 +66,8 @@ public function install( $args, $assoc_args ) { WP_CLI::error( 'WordPress is already installed.' ); } + WP_CLI::check_required_args( array( 'site_url', 'site_title', 'admin_email' ), $assoc_args ); + extract( wp_parse_args( $assoc_args, array( 'site_url' => defined( 'WP_SITEURL' ) ? WP_SITEURL : '', 'site_title' => '', @@ -72,20 +76,9 @@ public function install( $args, $assoc_args ) { 'admin_password' => wp_generate_password( 12, false ) ) ), EXTR_SKIP ); - $missing = false; - foreach ( array( 'site_url', 'site_title', 'admin_email' ) as $required_arg ) { - if ( empty( $$required_arg ) ) { - WP_CLI::warning( "missing --$required_arg parameter" ); - $missing = true; - } - } - if ( $site_url ) WP_CLI::set_url_params( $site_url ); - if ( $missing ) - exit(1); - $public = true; $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); From f07b87cf4cd1633aa0a8ab74345ac2a620a66965 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 02:38:01 +0300 Subject: [PATCH 0409/4858] make wp core config obey the silent flag. see #65 --- src/php/wp-cli/commands/internals/core.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 04c87d2419..32a59542a4 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -53,7 +53,10 @@ public function config( $args, $assoc_args ) { $_POST['prefix'] = isset( $assoc_args['dbprefix'] ) ? $assoc_args['dbprefix'] : 'wp_'; $_GET['step'] = 2; + + if ( WP_CLI_SILENT ) ob_start(); require WP_ROOT . '/wp-admin/setup-config.php'; + if ( WP_CLI_SILENT ) ob_end_clean(); } /** From 5f58f994489bc56feb3ebbedb8bb7154f06a9734 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 02:38:31 +0300 Subject: [PATCH 0410/4858] exit after executing 'core config' or 'db create' --- src/php/wp-cli/wp-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 43e87e472f..96b457cfd2 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -63,11 +63,13 @@ if ( array( 'core', 'config' ) == $arguments ) { WP_CLI::run_command( $arguments, $assoc_args ); + exit; } if ( array( 'db', 'create' ) == $arguments ) { WP_CLI::load_wp_config(); WP_CLI::run_command( $arguments, $assoc_args ); + exit; } // Handle --url and --blog parameters From acccc4336dcfd04eff964186c34b4036bd04174e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 02:59:54 +0300 Subject: [PATCH 0411/4858] `wp core install` improvements: * rename --site_url to --url and check for it before loading WP * rename --site_title to --title for consistency --- man/core-install.1 | 6 +++--- src/doc/core-install.txt | 6 +++--- src/php/wp-cli/commands/internals/core.php | 8 +------- src/php/wp-cli/wp-cli.php | 8 +++++--- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/man/core-install.1 b/man/core-install.1 index e8ab094784..b7376703ee 100644 --- a/man/core-install.1 +++ b/man/core-install.1 @@ -7,18 +7,18 @@ \fBwp\-core\-install\fR \- Install the WordPress tables in the database\. . .SH "SYNOPSIS" -\fBwp core install\fR \-\-site_url=\fIurl\fR \-\-site_title=\fItitle> [\-\-admin_name=<username\fR] \-\-admin_password=\fIpassword\fR \-\-admin_email=\fIemail\fR +\fBwp core install\fR \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_password=\fIpassword\fR \-\-admin_email=\fIemail\fR . .SH "OPTIONS" . .TP -\fB\-\-site_url\fR=\fIurl\fR: +\fB\-\-url\fR=\fIurl\fR: . .IP The address of the new site\. . .TP -\fB\-\-site_title\fR=<title>: +\fB\-\-title\fR=\fIsite\-title\fR: . .IP The title of the new site\. diff --git a/src/doc/core-install.txt b/src/doc/core-install.txt index 20c14827d1..19231e671f 100644 --- a/src/doc/core-install.txt +++ b/src/doc/core-install.txt @@ -3,15 +3,15 @@ wp-core-install(1) -- Install the WordPress tables in the database. ## SYNOPSIS -`wp core install` --site_url=<url> --site_title=<title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email> +`wp core install` --url=<url> --title=<site-title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email> ## OPTIONS -* `--site_url`=<url>: +* `--url`=<url>: The address of the new site. -* `--site_title`=<title>: +* `--title`=<site-title>: The title of the new site. diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 32a59542a4..fe2b021844 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -69,19 +69,13 @@ public function install( $args, $assoc_args ) { WP_CLI::error( 'WordPress is already installed.' ); } - WP_CLI::check_required_args( array( 'site_url', 'site_title', 'admin_email' ), $assoc_args ); - extract( wp_parse_args( $assoc_args, array( - 'site_url' => defined( 'WP_SITEURL' ) ? WP_SITEURL : '', - 'site_title' => '', + 'title' => '', 'admin_name' => 'admin', 'admin_email' => '', 'admin_password' => wp_generate_password( 12, false ) ) ), EXTR_SKIP ); - if ( $site_url ) - WP_CLI::set_url_params( $site_url ); - $public = true; $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 96b457cfd2..fb7700c951 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -72,14 +72,16 @@ exit; } -// Handle --url and --blog parameters -WP_CLI::_set_url( $assoc_args ); - // Set installer flag before loading any WP files if ( array( 'core', 'install' ) == $arguments ) { + WP_CLI::check_required_args( array( 'url', 'title', 'admin_email' ), $assoc_args ); + define( 'WP_INSTALLING', true ); } +// Handle --url and --blog parameters +WP_CLI::_set_url( $assoc_args ); + // Load WordPress require WP_ROOT . 'wp-load.php'; require ABSPATH . 'wp-admin/includes/admin.php'; From 889a5c83a1336493382af75e4e2e1f3fbc680f85 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 03:11:56 +0300 Subject: [PATCH 0412/4858] make wp db create pass along the return status from mysql. see #103 --- src/php/wp-cli/commands/internals/db.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 8934075017..b36ad60e19 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -18,8 +18,10 @@ class DB_Command extends WP_CLI_Command { * Creates the database according to the wp-config.php file */ function create() { - exec( sprintf( 'mysql --host="%s" --user="%s" --password="%s" --execute="CREATE DATABASE %s"', - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); + exit( WP_CLI::launch( sprintf( + 'mysql --host="%s" --user="%s" --password="%s" --execute="CREATE DATABASE %s"', + DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + ) ) ); } /** From 16d623a24afda60b09f4d41911866040a7c89957 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 03:15:54 +0300 Subject: [PATCH 0413/4858] use WP_CLI::launch in wp db query --- src/php/wp-cli/commands/internals/db.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index b36ad60e19..2a1f19ca10 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -49,11 +49,9 @@ function query( $args, $assoc_args ) { $query = $args[0]; - $exec = $this->connect_string(); - $exec .= sprintf(' --execute="%s"', $query); + $command = $this->connect_string() . sprintf( ' --execute="%s"', $query ); - $result = exec( $exec ); - WP_CLI::line( $result ); + exit( WP_CLI::launch( $command ) ); } /** From 1bfff0129fac87f6eb576cf8248dcdc022382ada Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 03:23:30 +0300 Subject: [PATCH 0414/4858] use WP_CLI::launch in db export/import --- src/php/wp-cli/commands/internals/db.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 2a1f19ca10..39342fe190 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -60,10 +60,11 @@ function query( $args, $assoc_args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $exec = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', + $command = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - exec( $exec ); + $r = WP_CLI::launch( $command ); + if ( $r ) exit($r); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } @@ -74,10 +75,11 @@ function export( $args, $assoc_args ) { function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $exec = sprintf( 'mysql "%s" --user="%s" --password="%s" --host="%s" < "%s"', + $command = sprintf( 'mysql "%s" --user="%s" --password="%s" --host="%s" < "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - exec( $exec ); + $r = WP_CLI::launch( $command ); + if ( $r ) exit($r); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } From 6434b1b7a585327902c250366204c138e94c94b5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 May 2012 03:30:45 +0300 Subject: [PATCH 0415/4858] add exit_on_error parameter to WP_CLI::launch() --- src/php/wp-cli/class-wp-cli.php | 10 ++++++++-- src/php/wp-cli/commands/internals/db.php | 14 ++++++-------- src/php/wp-cli/commands/internals/plugin.php | 7 +++---- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 7853c2c88e..ace1ed4aba 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -179,11 +179,17 @@ static function legend( $legend ) { * Launch an external process, closing the current one * * @param string Command to call + * @param bool Whether to exit if the command returns an error status * * @return int The command exit status */ - static function launch( $command ) { - return proc_close( proc_open( $command, array( STDIN, STDOUT, STDERR ), $pipes ) ); + static function launch( $command, $exit_on_error = true ) { + $r = proc_close( proc_open( $command, array( STDIN, STDOUT, STDERR ), $pipes ) ); + + if ( $r && $exit_on_error ) + exit($r); + + return $r; } /** diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 39342fe190..f27583370a 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -18,10 +18,10 @@ class DB_Command extends WP_CLI_Command { * Creates the database according to the wp-config.php file */ function create() { - exit( WP_CLI::launch( sprintf( + WP_CLI::launch( sprintf( 'mysql --host="%s" --user="%s" --password="%s" --execute="CREATE DATABASE %s"', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME - ) ) ); + ) ); } /** @@ -35,7 +35,7 @@ function connect() { * Open a SQL command-line interface using WordPress's credentials. */ function cli() { - exit( WP_CLI::launch( $this->connect_string() ) ); + WP_CLI::launch( $this->connect_string() ); } /** @@ -51,7 +51,7 @@ function query( $args, $assoc_args ) { $command = $this->connect_string() . sprintf( ' --execute="%s"', $query ); - exit( WP_CLI::launch( $command ) ); + WP_CLI::launch( $command ); } /** @@ -63,8 +63,7 @@ function export( $args, $assoc_args ) { $command = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - $r = WP_CLI::launch( $command ); - if ( $r ) exit($r); + WP_CLI::launch( $command ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } @@ -78,8 +77,7 @@ function import( $args, $assoc_args ) { $command = sprintf( 'mysql "%s" --user="%s" --password="%s" --host="%s" < "%s"', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - $r = WP_CLI::launch( $command ); - if ( $r ) exit($r); + WP_CLI::launch( $command ); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 3d3e30ee49..5c8b4e36e4 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -261,17 +261,16 @@ function uninstall( $args ) { * * @param array $args */ - function delete( $args, $assoc_args = array(), $exit_on_success = true ) { + function delete( $args, $assoc_args = array(), $exit_on_error = true ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $plugin_dir = dirname( $file ); if ( '.' == $plugin_dir ) $plugin_dir = $file; - $status = WP_CLI::launch( 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ) ); + $command = 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ); - if ( $status || $exit_on_success ) - exit( $status ); + return WP_CLI::launch( $command, $exit_on_error ); } /* PRIVATES */ From 493437818224e89f39bbc80156169ec05683663b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 01:35:19 +0300 Subject: [PATCH 0416/4858] check --path before $_SERVER['PWD']. fixes #111 --- src/php/wp-cli/wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index fb7700c951..2dfc0620ad 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -43,11 +43,11 @@ } // Define the WordPress location -if ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { - define( 'WP_ROOT', $_SERVER['PWD'] . '/../' ); -} elseif ( !empty( $assoc_args['path'] ) ) { +if ( !empty( $assoc_args['path'] ) ) { // trailingslashit() isn't available yet define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); +} elseif ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { + define( 'WP_ROOT', $_SERVER['PWD'] . '/../' ); } else { define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); } From cb769a1034944cc0e980cb38c74fb5182e0369af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 02:12:41 +0300 Subject: [PATCH 0417/4858] use escapeshellarg() in WP_CLI::compose_args() --- src/php/wp-cli/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index ace1ed4aba..d9e163ed0d 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -124,13 +124,13 @@ static function parse_args( $arguments ) { * @return string */ static function compose_args( $args, $assoc_args = array() ) { - $str = implode( ' ', $args ); + $str = implode( ' ', array_map( 'escapeshellarg', $args ) ); foreach ( $assoc_args as $key => $value ) { if ( true == $value ) $str .= " --$key"; else - $str .= " --$key=$value"; + $str .= " --$key=" . escapeshellarg( $value ); } return $str; From 0bb8d05decf2c50d69a6a4ac2046cdf267d616f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 02:31:07 +0300 Subject: [PATCH 0418/4858] strict bool check in compose_args() --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index d9e163ed0d..255f1e8a45 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -127,7 +127,7 @@ static function compose_args( $args, $assoc_args = array() ) { $str = implode( ' ', array_map( 'escapeshellarg', $args ) ); foreach ( $assoc_args as $key => $value ) { - if ( true == $value ) + if ( true === $value ) $str .= " --$key"; else $str .= " --$key=" . escapeshellarg( $value ); From c5c132ad37e7603d4ffe3a3b8a59917783a8c127 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 02:34:47 +0300 Subject: [PATCH 0419/4858] add leading space to output of compose_args() --- src/php/wp-cli/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 255f1e8a45..f5d0f6f4ee 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -118,13 +118,13 @@ static function parse_args( $arguments ) { } /** - * Composes positional and associative arguments into a string + * Composes positional and associative arguments into a string. * * @param array * @return string */ static function compose_args( $args, $assoc_args = array() ) { - $str = implode( ' ', array_map( 'escapeshellarg', $args ) ); + $str = ' ' . implode( ' ', array_map( 'escapeshellarg', $args ) ); foreach ( $assoc_args as $key => $value ) { if ( true === $value ) From b002243dfca2da691ab4a3a9086d98344145a66e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 02:52:44 +0300 Subject: [PATCH 0420/4858] make wp plugin install return error status when it fails --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 5f43900778..fcd3346588 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -63,6 +63,8 @@ function install( $args, $assoc_args ) { WP_CLI::line( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } + } else { + exit(1); } } else { $this->install_from_repo( $slug, $assoc_args ); From e59998d0c60b90c6c5779d290ce491b7103f577c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 03:31:24 +0300 Subject: [PATCH 0421/4858] pass correct title variable to wp_install() --- src/php/wp-cli/commands/internals/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index fe2b021844..6a61606e2e 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -78,7 +78,7 @@ public function install( $args, $assoc_args ) { $public = true; - $result = wp_install( $site_title, $admin_name, $admin_email, $public, '', $admin_password ); + $result = wp_install( $title, $admin_name, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::error_to_string($result) . ').' ); From f1cce451689b3de19806b8b266c705499b3fad70 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 May 2012 03:34:33 +0300 Subject: [PATCH 0422/4858] introduce wp db drop --- src/php/wp-cli/commands/internals/db.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index f27583370a..6cb1764b64 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -15,7 +15,7 @@ class DB_Command extends WP_CLI_Command { protected $aliases = array( 'dump' => 'export' ); /** - * Creates the database according to the wp-config.php file + * Creates the database specified in the wp-config.php file. */ function create() { WP_CLI::launch( sprintf( @@ -24,6 +24,16 @@ function create() { ) ); } + /** + * Deletes the database specified in the wp-config.php file. + */ + function drop() { + WP_CLI::launch( sprintf( + 'mysql --host="%s" --user="%s" --password="%s" --execute="DROP DATABASE %s"', + DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + ) ); + } + /** * Print a string for connecting to the DB. */ From 34f37ce18f403fc6efeea9adb96f466a71bfab64 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 14 May 2012 04:14:17 +0300 Subject: [PATCH 0423/4858] ask for confirmation before dropping the database --- src/php/wp-cli/commands/internals/db.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 6cb1764b64..30f9e9e522 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -27,11 +27,22 @@ function create() { /** * Deletes the database specified in the wp-config.php file. */ - function drop() { + function drop( $args, $assoc_args ) { + if ( !isset( $assoc_args['really'] ) ) { + WP_CLI::out( "Are you sure you want to drop the database? [y/n] " ); + + $answer = trim( fgets( STDIN ) ); + + if ( 'y' != $answer ) + return; + } + WP_CLI::launch( sprintf( 'mysql --host="%s" --user="%s" --password="%s" --execute="DROP DATABASE %s"', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); + + WP_CLI::success( "Database dropped." ); } /** From 25fb157943f966153c41399d353592066d2405c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 14 May 2012 04:17:18 +0300 Subject: [PATCH 0424/4858] add man page for db drop --- man/db-drop.1 | 19 +++++++++++++++++++ src/doc/db-drop.txt | 12 ++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 man/db-drop.1 create mode 100644 src/doc/db-drop.txt diff --git a/man/db-drop.1 b/man/db-drop.1 new file mode 100644 index 0000000000..3a370feb82 --- /dev/null +++ b/man/db-drop.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-DROP" "1" "May 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-drop\fR \- Drop the database specified in wp\-config\.php +. +.SH "SYNOPSIS" +\fBwp db drop\fR [\-\-really] +. +.SH "OPTIONS" +. +.TP +\fB\-\-really\fR: +. +.IP +Skip the confirmation messaje\. + diff --git a/src/doc/db-drop.txt b/src/doc/db-drop.txt new file mode 100644 index 0000000000..074b141235 --- /dev/null +++ b/src/doc/db-drop.txt @@ -0,0 +1,12 @@ +wp-db-drop(1) -- Drop the database specified in wp-config.php +==== + +## SYNOPSIS + +`wp db drop` [--really] + +## OPTIONS + +* `--really`: + + Skip the confirmation messaje. From fc56284718a1a309cacf20b0cf5f4188c2ffc940 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 15 May 2012 21:09:55 +0300 Subject: [PATCH 0425/4858] warning() should write to STDERR, not STDOUT --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index f5d0f6f4ee..e990f29a99 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -72,7 +72,7 @@ static function success( $message, $label = 'Success' ) { */ static function warning( $message, $label = 'Warning' ) { if ( WP_CLI_SILENT ) return; - \cli\line( '%C' . $label . ': %n' . self::error_to_string( $message ) ); + \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } /** From 859c7850ee7b5bae8c0794384a8bf8bbee35354f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 17 May 2012 03:39:04 +0300 Subject: [PATCH 0426/4858] make git clone command compatible with older versions of git. props jasonblewis --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 936fd76920..92835f7e7a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ sudo pear install wp-cli.github.com/pear/wpcli **Via GIT:** ```sh -git clone --recurse-submodules git://github.com/wp-cli/wp-cli.git ~/git/wp-cli +git clone --recursive git://github.com/wp-cli/wp-cli.git ~/git/wp-cli cd ~/git/wp-cli sudo utils/dev-build ``` From 7dcf532b802588fc0b015c66fd223a9579517593 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 18 May 2012 19:43:54 +0300 Subject: [PATCH 0427/4858] add locale parameter to wp core download. fixes #112 --- src/php/wp-cli/commands/internals/core.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 6a61606e2e..5805fced29 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -22,10 +22,17 @@ public function download( $args, $assoc_args ) { else $docroot = './'; - if ( isset( $assoc_args['version'] ) ) { + if ( isset( $assoc_args['locale'] ) ) { + exec( 'curl -s ' . escapeshellarg( 'http://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); + if ($r) exit($r); + $download_url = $lines[2]; + WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $lines[3], $lines[4] ) ); + } elseif ( isset( $assoc_args['version'] ) ) { $download_url = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; + WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { $download_url = 'http://wordpress.org/latest.zip'; + WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } $silent = ''; From e0654744f0e08aff8620c511a32d005f33ab8c16 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 18 May 2012 19:44:05 +0300 Subject: [PATCH 0428/4858] update docs. see #112 --- man/core-download.1 | 8 +++++++- src/doc/core-download.txt | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/man/core-download.1 b/man/core-download.1 index 95d38d7819..8d4e9f8e60 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -7,11 +7,17 @@ \fBwp\-core\-download\fR \- Download core WordPress files\. . .SH "SYNOPSIS" -\fBwp core download\fR [\-\-version=\fIversion\fR] +\fBwp core download\fR [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] . .SH "OPTIONS" . .TP +\fB\-\-locale\fR=\fIlocale\fR: +. +.IP +Select which language you want to download\. The \-\-version parameter is ignored in this case\. +. +.TP \fB\-\-version\fR=\fIversion\fR: . .IP diff --git a/src/doc/core-download.txt b/src/doc/core-download.txt index fe858f1526..7fbaee097d 100644 --- a/src/doc/core-download.txt +++ b/src/doc/core-download.txt @@ -3,10 +3,15 @@ wp-core-download(1) -- Download core WordPress files. ## SYNOPSIS -`wp core download` [--version=<version>] +`wp core download` [--locale=<locale>] [--version=<version>] ## OPTIONS +* `--locale`=<locale>: + + Select which language you want to download. The --version parameter is +ignored in this case. + * `--version`=<version>: Select which version you want to download. From 2526aa89343cf30abf65c241898f38623d4c930a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 18 May 2012 19:48:04 +0300 Subject: [PATCH 0429/4858] use WP_CLI_SILENT constant instead of arg --- src/php/wp-cli/commands/internals/core.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 5805fced29..e24ac1745f 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -35,9 +35,7 @@ public function download( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - $silent = ''; - if( !empty( $assoc_args['silent'] ) ) - $silent = '--silent '; + $silent = WP_CLI_SILENT ? '--silent ' : ''; WP_CLI::line('Downloading WordPress...'); exec("curl {$silent}http://wordpress.org/latest.zip > /tmp/wordpress.zip"); From 148bf8008047d8cffd1ba7ae5b7684311f425808 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 18 May 2012 20:04:25 +0300 Subject: [PATCH 0430/4858] wp core download fixes: * actually use $download_url instead of always downloading the latest * use WP_CLI::launch() to prevent an error from cascading * pass -f to curl so that it returns an error message on 404 see #112 --- src/php/wp-cli/commands/internals/core.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index e24ac1745f..27deec66e4 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -17,7 +17,7 @@ public function download( $args, $assoc_args ) { if ( is_readable( WP_ROOT . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); - if (isset($assoc_args['path'])) + if ( isset( $assoc_args['path'] ) ) $docroot = $assoc_args['path']; else $docroot = './'; @@ -35,14 +35,12 @@ public function download( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - $silent = WP_CLI_SILENT ? '--silent ' : ''; + WP_CLI::launch( 'curl -f' . (WP_CLI_SILENT ? ' --silent ' : ' ') . escapeshellarg( $download_url ) . ' > /tmp/wordpress.zip' ); + WP_CLI::launch( 'unzip ' . (WP_CLI_SILENT ? '-qq ' : '-q ') . '/tmp/wordpress.zip' ); + WP_CLI::launch( 'mv wordpress/* ' . escapeshellarg( $docroot ) ); + WP_CLI::launch( 'rm -r wordpress' ); - WP_CLI::line('Downloading WordPress...'); - exec("curl {$silent}http://wordpress.org/latest.zip > /tmp/wordpress.zip"); - exec("unzip /tmp/wordpress.zip"); - exec("mv wordpress/* $docroot"); - exec("rm -r wordpress"); - WP_CLI::success('WordPress downloaded.'); + WP_CLI::success( 'WordPress downloaded.' ); } /** From e0bcd0fc70763db5ddea8fd2972819fe16aa3007 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 May 2012 21:30:21 +0300 Subject: [PATCH 0431/4858] don't ignore --url param when calling wp db create. see #103 --- src/php/wp-cli/wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 2dfc0620ad..6fc69e506f 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -52,6 +52,9 @@ define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); } +// Handle --url and --blog parameters +WP_CLI::_set_url( $assoc_args ); + if ( array( 'core', 'download' ) == $arguments ) { WP_CLI::run_command( $arguments, $assoc_args ); exit; @@ -79,9 +82,6 @@ define( 'WP_INSTALLING', true ); } -// Handle --url and --blog parameters -WP_CLI::_set_url( $assoc_args ); - // Load WordPress require WP_ROOT . 'wp-load.php'; require ABSPATH . 'wp-admin/includes/admin.php'; From 8b81cb29634daaff82dbd949018e6a0f1f9a7980 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 May 2012 21:43:05 +0300 Subject: [PATCH 0432/4858] make wp db import work without loading WP. fixes #116 --- src/php/wp-cli/wp-cli.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 6fc69e506f..ed2a2da563 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -75,6 +75,12 @@ exit; } +if ( array( 'db', 'import' ) == array_slice( $arguments, 0, 2 ) ) { + WP_CLI::load_wp_config(); + WP_CLI::run_command( $arguments, $assoc_args ); + exit; +} + // Set installer flag before loading any WP files if ( array( 'core', 'install' ) == $arguments ) { WP_CLI::check_required_args( array( 'url', 'title', 'admin_email' ), $assoc_args ); From e989c8cf733d5bbea88ea429c2522c141280297c Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 10:29:58 +0100 Subject: [PATCH 0433/4858] Add command to update a meta field for a user --- src/php/wp-cli/commands/internals/user.php | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 7515979d4e..34df9cc24b 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -156,4 +156,32 @@ public function update( $args, $assoc_args ) { WP_CLI::success( "Updated user $updated_id." ); } } + + /** + * Update meta field for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function update_meta( $args, $assoc_args ) { + $user_id = $args[0]; + $meta_key = $args[1]; + $meta_value = $args[2]; + + if ( ! is_numeric($user_id) ) { + WP_CLI::error( "User ID required (see 'wp user help')." ); + } + + if ( ! $meta_key || ! $meta_value ) { + WP_CLI:error( "meta_key and meta_value required (see 'wp user help')."); + } + + $success = update_user_meta( $user_id, $meta_key, $meta_value ); + + if ( $success ) { + WP_CLI::success( "Updated user $user_id." ); + } else { + WP_CLI::error( "Failed to update meta field" ); + } + } } From c3a8bbd5d7cdf95de9a3ae69c9ef7c02258d631c Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 10:33:48 +0100 Subject: [PATCH 0434/4858] Factor out duplicated error message string --- src/php/wp-cli/commands/internals/user.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 34df9cc24b..2c70241dd9 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -63,7 +63,7 @@ public function delete( $args, $assoc_args ) { $user_id = $args[0]; if ( ! is_numeric($user_id) ) { - WP_CLI::error("User ID required (see 'wp user help')"); + self::error_see_help( "User ID required" ); } $defaults = array( 'reassign' => NULL ); @@ -90,7 +90,7 @@ public function create( $args, $assoc_args ) { $user_email = $args[1]; if ( ! $user_login || ! $user_email ) { - WP_CLI::error("Login and email required (see 'wp user help')."); + self::error_see_help( "Login and email required" ); } $defaults = array( @@ -139,7 +139,7 @@ public function update( $args, $assoc_args ) { $user_id = $args[0]; if ( ! is_numeric($user_id) ) { - WP_CLI::error( "User ID required (see 'wp user help')." ); + self::error_see_help( "User ID required" ); } if ( empty( $assoc_args ) ) { @@ -169,11 +169,11 @@ public function update_meta( $args, $assoc_args ) { $meta_value = $args[2]; if ( ! is_numeric($user_id) ) { - WP_CLI::error( "User ID required (see 'wp user help')." ); + self::error_see_help( "User ID required" ); } if ( ! $meta_key || ! $meta_value ) { - WP_CLI:error( "meta_key and meta_value required (see 'wp user help')."); + self::error_see_help( "meta_key and meta_value required"); } $success = update_user_meta( $user_id, $meta_key, $meta_value ); @@ -184,4 +184,8 @@ public function update_meta( $args, $assoc_args ) { WP_CLI::error( "Failed to update meta field" ); } } + + private function error_see_help( $message ) { + WP_CLI::error( "$message (see 'wp user help')."); + } } From 534d7b922d6ec93aa5f442d1e3d2160ffd27b4d5 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 10:39:49 +0100 Subject: [PATCH 0435/4858] Factor out code to retrieve args in update_meta --- src/php/wp-cli/commands/internals/user.php | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 2c70241dd9..2c124b0e61 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -164,17 +164,9 @@ public function update( $args, $assoc_args ) { * @param array $assoc_args **/ public function update_meta( $args, $assoc_args ) { - $user_id = $args[0]; - $meta_key = $args[1]; - $meta_value = $args[2]; - - if ( ! is_numeric($user_id) ) { - self::error_see_help( "User ID required" ); - } - - if ( ! $meta_key || ! $meta_value ) { - self::error_see_help( "meta_key and meta_value required"); - } + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $meta_key = self::get_arg_or_error($args, 1, "meta_key");; + $meta_value = self::get_arg_or_error($args, 2, "meta_value");; $success = update_user_meta( $user_id, $meta_key, $meta_value ); @@ -185,6 +177,22 @@ public function update_meta( $args, $assoc_args ) { } } + private function get_numeric_arg_or_error( $args, $index, $name ) { + $value = self::get_arg_or_error( $args, $index, $name ); + if ( ! is_numeric( $value ) ) { + self::error_see_help( "$name must be numeric" ); + } + return $value; + } + + private function get_arg_or_error( $args, $index, $name ) { + $value = $args[$index]; + if ( ! $value ) { + self::error_see_help( "$name required" ); + } + return $value; + } + private function error_see_help( $message ) { WP_CLI::error( "$message (see 'wp user help')."); } From 487f5c7ffcfb4d5313e42b1b63a4b29ff59e7bd4 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 10:41:20 +0100 Subject: [PATCH 0436/4858] Factor out fetching user ID from $args --- src/php/wp-cli/commands/internals/user.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 2c124b0e61..1b408dc36e 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -59,12 +59,8 @@ public function _list( $args, $assoc_args ) { **/ public function delete( $args, $assoc_args ) { global $blog_id; - - $user_id = $args[0]; - - if ( ! is_numeric($user_id) ) { - self::error_see_help( "User ID required" ); - } + + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); $defaults = array( 'reassign' => NULL ); @@ -136,11 +132,7 @@ public function create( $args, $assoc_args ) { * @param array $assoc_args **/ public function update( $args, $assoc_args ) { - $user_id = $args[0]; - - if ( ! is_numeric($user_id) ) { - self::error_see_help( "User ID required" ); - } + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); if ( empty( $assoc_args ) ) { WP_CLI::error( "Need some fields to update." ); From 900f62515fc772a92f640b4bb64885d7af24db43 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 10:53:56 +0100 Subject: [PATCH 0437/4858] Add man page for user update_meta --- src/doc/user-update_meta.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/doc/user-update_meta.txt diff --git a/src/doc/user-update_meta.txt b/src/doc/user-update_meta.txt new file mode 100644 index 0000000000..74616807d8 --- /dev/null +++ b/src/doc/user-update_meta.txt @@ -0,0 +1,24 @@ +wp-user-update_meta(1) -- Update a meta field for a WordPress user. +==== + +## SYNOPSIS + +`wp user update_meta` <ID> <meta_key> <meta_value> + +## OPTIONS + +* `<ID>`: + + The ID of the user to update. + +* meta_key: + + The meta_key to be updated + +* meta_value: + + The new desired value of the meta_key + +## EXAMPLES + + wp user update_meta 123 description "Mary is a WordPress developer" From cd96aabb2882d02bc6ddb9e876f0829aae96017b Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 11:37:28 +0100 Subject: [PATCH 0438/4858] Use isset to check if an argument exists --- src/php/wp-cli/commands/internals/user.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 1b408dc36e..2b67398211 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -178,11 +178,10 @@ private function get_numeric_arg_or_error( $args, $index, $name ) { } private function get_arg_or_error( $args, $index, $name ) { - $value = $args[$index]; - if ( ! $value ) { + if ( ! isset( $args[$index] ) ) { self::error_see_help( "$name required" ); } - return $value; + return $args[$index]; } private function error_see_help( $message ) { From a06cb5dcb872d5bc3888bce47b09b533139a1167 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 31 May 2012 13:11:47 +0100 Subject: [PATCH 0439/4858] Change "wp user update_meta" to "wp user-meta set" --- src/doc/user-meta-set.txt | 24 +++++++++ src/doc/user-update_meta.txt | 24 --------- .../wp-cli/commands/internals/user-meta.php | 51 +++++++++++++++++++ src/php/wp-cli/commands/internals/user.php | 20 -------- 4 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 src/doc/user-meta-set.txt delete mode 100644 src/doc/user-update_meta.txt create mode 100644 src/php/wp-cli/commands/internals/user-meta.php diff --git a/src/doc/user-meta-set.txt b/src/doc/user-meta-set.txt new file mode 100644 index 0000000000..b40cc0cc4b --- /dev/null +++ b/src/doc/user-meta-set.txt @@ -0,0 +1,24 @@ +wp-user-meta-set(1) -- Update a meta field for a WordPress user. +==== + +## SYNOPSIS + +`wp user-meta set` <ID> <meta_key> <meta_value> + +## OPTIONS + +* `<ID>`: + + The ID of the user to update. + +* meta_key: + + The meta_key to be updated + +* meta_value: + + The new desired value of the meta_key + +## EXAMPLES + + wp user-meta set 123 description "Mary is a WordPress developer" diff --git a/src/doc/user-update_meta.txt b/src/doc/user-update_meta.txt deleted file mode 100644 index 74616807d8..0000000000 --- a/src/doc/user-update_meta.txt +++ /dev/null @@ -1,24 +0,0 @@ -wp-user-update_meta(1) -- Update a meta field for a WordPress user. -==== - -## SYNOPSIS - -`wp user update_meta` <ID> <meta_key> <meta_value> - -## OPTIONS - -* `<ID>`: - - The ID of the user to update. - -* meta_key: - - The meta_key to be updated - -* meta_value: - - The new desired value of the meta_key - -## EXAMPLES - - wp user update_meta 123 description "Mary is a WordPress developer" diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php new file mode 100644 index 0000000000..7636eff275 --- /dev/null +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -0,0 +1,51 @@ +<?php + +WP_CLI::add_command('user-meta', 'User_Meta_Command'); + +/** + * Implement user command + * + * @package wp-cli + * @subpackage commands/internals + */ +class User_Meta_Command extends WP_CLI_Command { + /** + * Update meta field for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function set( $args, $assoc_args ) { + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $meta_key = self::get_arg_or_error($args, 1, "meta_key");; + $meta_value = self::get_arg_or_error($args, 2, "meta_value");; + + $success = update_user_meta( $user_id, $meta_key, $meta_value ); + + if ( $success ) { + WP_CLI::success( "Updated user $user_id." ); + } else { + WP_CLI::error( "Failed to set meta field" ); + } + } + + private function get_numeric_arg_or_error( $args, $index, $name ) { + $value = self::get_arg_or_error( $args, $index, $name ); + if ( ! is_numeric( $value ) ) { + self::error_see_help( "$name must be numeric" ); + } + return $value; + } + + private function get_arg_or_error( $args, $index, $name ) { + if ( ! isset( $args[$index] ) ) { + self::error_see_help( "$name required" ); + } + return $args[$index]; + } + + private function error_see_help( $message ) { + WP_CLI::error( "$message (see 'wp user-meta help')."); + } +} + diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 2b67398211..2c9a6238b8 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -148,26 +148,6 @@ public function update( $args, $assoc_args ) { WP_CLI::success( "Updated user $updated_id." ); } } - - /** - * Update meta field for a user - * - * @param array $args - * @param array $assoc_args - **/ - public function update_meta( $args, $assoc_args ) { - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); - $meta_key = self::get_arg_or_error($args, 1, "meta_key");; - $meta_value = self::get_arg_or_error($args, 2, "meta_value");; - - $success = update_user_meta( $user_id, $meta_key, $meta_value ); - - if ( $success ) { - WP_CLI::success( "Updated user $user_id." ); - } else { - WP_CLI::error( "Failed to update meta field" ); - } - } private function get_numeric_arg_or_error( $args, $index, $name ) { $value = self::get_arg_or_error( $args, $index, $name ); From 5a69b91b5458365858a8b716496c3734f9604414 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Jun 2012 11:59:22 +0300 Subject: [PATCH 0440/4858] generate man page. see #117 --- man/user-meta-set.1 | 33 +++++++++++++++++++ src/doc/user-meta-set.txt | 14 ++++---- .../wp-cli/commands/internals/user-meta.php | 6 ++-- 3 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 man/user-meta-set.1 diff --git a/man/user-meta-set.1 b/man/user-meta-set.1 new file mode 100644 index 0000000000..8786c90b86 --- /dev/null +++ b/man/user-meta-set.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-META\-SET" "1" "June 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-meta\-set\fR \- Update a meta field for a WordPress user\. +. +.SH "SYNOPSIS" +\fBwp user\-meta set\fR \fIID\fR \fImeta_key\fR \fImeta_value\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the user to update\. +. +.TP +\fB<meta_key>\fR: +. +.IP +The meta_key to be updated\. +. +.TP +\fB<meta_value>\fR: +. +.IP +The new desired value of the meta_key\. +. +.SH "EXAMPLES" +wp user\-meta set 123 description "Mary is a WordPress developer\." diff --git a/src/doc/user-meta-set.txt b/src/doc/user-meta-set.txt index b40cc0cc4b..3140f4a1b6 100644 --- a/src/doc/user-meta-set.txt +++ b/src/doc/user-meta-set.txt @@ -11,14 +11,14 @@ wp-user-meta-set(1) -- Update a meta field for a WordPress user. The ID of the user to update. -* meta_key: +* `<meta_key>`: - The meta_key to be updated - -* meta_value: - - The new desired value of the meta_key + The meta_key to be updated. + +* `<meta_value>`: + + The new desired value of the meta_key. ## EXAMPLES - wp user-meta set 123 description "Mary is a WordPress developer" +wp user-meta set 123 description "Mary is a WordPress developer." diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index 7636eff275..ce602b5374 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -28,7 +28,7 @@ public function set( $args, $assoc_args ) { WP_CLI::error( "Failed to set meta field" ); } } - + private function get_numeric_arg_or_error( $args, $index, $name ) { $value = self::get_arg_or_error( $args, $index, $name ); if ( ! is_numeric( $value ) ) { @@ -36,14 +36,14 @@ private function get_numeric_arg_or_error( $args, $index, $name ) { } return $value; } - + private function get_arg_or_error( $args, $index, $name ) { if ( ! isset( $args[$index] ) ) { self::error_see_help( "$name required" ); } return $args[$index]; } - + private function error_see_help( $message ) { WP_CLI::error( "$message (see 'wp user-meta help')."); } From 73a86f059842d2b2ed40637abab38ea4670f2455 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Jun 2012 12:05:49 +0300 Subject: [PATCH 0441/4858] introduce WP_CLI::print_value() --- src/php/wp-cli/class-wp-cli.php | 13 +++++++++++++ src/php/wp-cli/commands/internals/option.php | 6 +----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index e990f29a99..d16470d80a 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -75,6 +75,19 @@ static function warning( $message, $label = 'Warning' ) { \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } + /** + * Display an easy to paste PHP value. + * + * @param string $message + */ + static function print_value( $value ) { + if ( is_array( $value ) || is_object( $value ) ) { + echo var_export( $value ) . "\n"; + } else { + echo $value . "\n"; + } + } + /** * Convert a wp_error into a string * diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 79825b4b2e..53a3a3372a 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -85,10 +85,6 @@ public function get( $args ) { if ( false === $value ) return; - if ( is_array( $value ) || is_object( $value ) ) { - echo var_export( $value ) . "\n"; - } else { - echo $value . "\n"; - } + WP_CLI::print_value( $value ); } } From 33fb1c6d9d39540e1a804201c6f2d7f58b9f5f0d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Jun 2012 12:10:04 +0300 Subject: [PATCH 0442/4858] add user-meta get. see #117 --- src/php/wp-cli/commands/internals/option.php | 2 +- .../wp-cli/commands/internals/user-meta.php | 23 +++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 53a3a3372a..955efb5f01 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -83,7 +83,7 @@ public function get( $args ) { $value = get_option( $key ); if ( false === $value ) - return; + die(1); WP_CLI::print_value( $value ); } diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index ce602b5374..bf263bcce3 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -9,6 +9,25 @@ * @subpackage commands/internals */ class User_Meta_Command extends WP_CLI_Command { + + /** + * Get meta field value for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function get( $args, $assoc_args ) { + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $meta_key = self::get_arg_or_error($args, 1, "meta_key"); + + $value = get_user_meta( $user_id, $meta_key, true ); + + if ( '' === $value ) + die(1); + + WP_CLI::print_value( $value ); + } + /** * Update meta field for a user * @@ -17,8 +36,8 @@ class User_Meta_Command extends WP_CLI_Command { **/ public function set( $args, $assoc_args ) { $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); - $meta_key = self::get_arg_or_error($args, 1, "meta_key");; - $meta_value = self::get_arg_or_error($args, 2, "meta_value");; + $meta_key = self::get_arg_or_error($args, 1, "meta_key"); + $meta_value = self::get_arg_or_error($args, 2, "meta_value"); $success = update_user_meta( $user_id, $meta_key, $meta_value ); From 94c2cdecac36a553c9573deecf28028cf8e67d97 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Jun 2012 12:19:27 +0300 Subject: [PATCH 0443/4858] Complete user-meta command: * rename 'user-meta set' to 'user-meta update' * add 'user-meta add' and 'user-meta delete' See #117 --- man/user-meta-set.1 | 33 ------------ man/user-meta.1 | 54 +++++++++++++++++++ src/doc/user-meta-set.txt | 24 --------- src/doc/user-meta.txt | 34 ++++++++++++ .../wp-cli/commands/internals/user-meta.php | 45 ++++++++++++++-- 5 files changed, 130 insertions(+), 60 deletions(-) delete mode 100644 man/user-meta-set.1 create mode 100644 man/user-meta.1 delete mode 100644 src/doc/user-meta-set.txt create mode 100644 src/doc/user-meta.txt diff --git a/man/user-meta-set.1 b/man/user-meta-set.1 deleted file mode 100644 index 8786c90b86..0000000000 --- a/man/user-meta-set.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-META\-SET" "1" "June 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-meta\-set\fR \- Update a meta field for a WordPress user\. -. -.SH "SYNOPSIS" -\fBwp user\-meta set\fR \fIID\fR \fImeta_key\fR \fImeta_value\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the user to update\. -. -.TP -\fB<meta_key>\fR: -. -.IP -The meta_key to be updated\. -. -.TP -\fB<meta_value>\fR: -. -.IP -The new desired value of the meta_key\. -. -.SH "EXAMPLES" -wp user\-meta set 123 description "Mary is a WordPress developer\." diff --git a/man/user-meta.1 b/man/user-meta.1 new file mode 100644 index 0000000000..a3429e9874 --- /dev/null +++ b/man/user-meta.1 @@ -0,0 +1,54 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-META" "1" "June 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-meta\fR \- Manage user custom fields\. +. +.SH "SYNOPSIS" +wp user\-meta get \fIID\fR \fIkey\fR +. +.P +wp user\-meta add \fIID\fR \fIkey\fR \fIvalue\fR +. +.P +wp user\-meta update \fIID\fR \fIkey\fR \fIvalue\fR +. +.P +wp user\-meta delete \fIID\fR \fIkey\fR +. +.SH "SUBCOMMANDS" +. +.TP +\fBget\fR: +. +.IP +Get a custom field value\. +. +.TP +\fBadd\fR: +. +.IP +Add a new custom field\. +. +.TP +\fBupdate\fR: +. +.IP +Update an existing custom field\. +. +.TP +\fBdelete\fR: +. +.IP +Delete a custom field\. +. +.SH "EXAMPLES" +. +.nf + +wp user\-meta set 123 description "Mary is a WordPress developer\." +. +.fi + diff --git a/src/doc/user-meta-set.txt b/src/doc/user-meta-set.txt deleted file mode 100644 index 3140f4a1b6..0000000000 --- a/src/doc/user-meta-set.txt +++ /dev/null @@ -1,24 +0,0 @@ -wp-user-meta-set(1) -- Update a meta field for a WordPress user. -==== - -## SYNOPSIS - -`wp user-meta set` <ID> <meta_key> <meta_value> - -## OPTIONS - -* `<ID>`: - - The ID of the user to update. - -* `<meta_key>`: - - The meta_key to be updated. - -* `<meta_value>`: - - The new desired value of the meta_key. - -## EXAMPLES - -wp user-meta set 123 description "Mary is a WordPress developer." diff --git a/src/doc/user-meta.txt b/src/doc/user-meta.txt new file mode 100644 index 0000000000..1825c508c2 --- /dev/null +++ b/src/doc/user-meta.txt @@ -0,0 +1,34 @@ +wp-user-meta(1) -- Manage user custom fields. +==== + +## SYNOPSIS + +wp user-meta get <ID> <key> + +wp user-meta add <ID> <key> <value> + +wp user-meta update <ID> <key> <value> + +wp user-meta delete <ID> <key> + +## SUBCOMMANDS + +* `get`: + + Get a custom field value. + +* `add`: + + Add a new custom field. + +* `update`: + + Update an existing custom field. + +* `delete`: + + Delete a custom field. + +## EXAMPLES + + wp user-meta set 123 description "Mary is a WordPress developer." diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index bf263bcce3..ebb32ce7ce 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -28,13 +28,52 @@ public function get( $args, $assoc_args ) { WP_CLI::print_value( $value ); } + /** + * Get meta field value for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function delete( $args, $assoc_args ) { + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $meta_key = self::get_arg_or_error($args, 1, "meta_key"); + + $success = delete_user_meta( $user_id, $meta_key ); + + if ( $success ) { + WP_CLI::success( "Deleted custom field." ); + } else { + WP_CLI::error( "Failed to delete custom field." ); + } + } + + /** + * Update meta field for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function add( $args, $assoc_args ) { + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $meta_key = self::get_arg_or_error($args, 1, "meta_key"); + $meta_value = self::get_arg_or_error($args, 2, "meta_value"); + + $success = add_user_meta( $user_id, $meta_key, $meta_value ); + + if ( $success ) { + WP_CLI::success( "Added custom field." ); + } else { + WP_CLI::error( "Failed to add custom field." ); + } + } + /** * Update meta field for a user * * @param array $args * @param array $assoc_args **/ - public function set( $args, $assoc_args ) { + public function update( $args, $assoc_args ) { $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); $meta_key = self::get_arg_or_error($args, 1, "meta_key"); $meta_value = self::get_arg_or_error($args, 2, "meta_value"); @@ -42,9 +81,9 @@ public function set( $args, $assoc_args ) { $success = update_user_meta( $user_id, $meta_key, $meta_value ); if ( $success ) { - WP_CLI::success( "Updated user $user_id." ); + WP_CLI::success( "Updated custom field." ); } else { - WP_CLI::error( "Failed to set meta field" ); + WP_CLI::error( "Failed to update custom field." ); } } From a02a3f9633198141933d16175a59be6b457451e5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Jun 2012 15:08:24 +0300 Subject: [PATCH 0444/4858] don't unset the --url parameter; needed for other things. see #103 --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index d16470d80a..16f6fa4fb7 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -235,7 +235,7 @@ static function get_upgrader( $class ) { static function _set_url( &$assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $blog = $assoc_args['url']; - unset( $assoc_args['url'] ); + /* unset( $assoc_args['url'] ); */ } elseif ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; unset( $assoc_args['blog'] ); From 47c9559938a09302276362b97d817f88d541b5f2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 6 Jun 2012 23:12:48 +0300 Subject: [PATCH 0445/4858] move version check into PHP. fixes #119 --- src/bin/wp | 24 +++++------------------- src/php/wp-cli/wp-cli-boot.php | 9 +++++++++ src/php/wp-cli/wp-cli.php | 3 ++- 3 files changed, 16 insertions(+), 20 deletions(-) create mode 100644 src/php/wp-cli/wp-cli-boot.php diff --git a/src/bin/wp b/src/bin/wp index 20e984096d..45da90e16c 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -10,9 +10,6 @@ # php executable it can find on your system. # -# Set the required PHP version -CHECK_VERSION='5.3.0' - # Get the absolute path of this executable ORIGDIR=$(pwd) SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0") @@ -29,12 +26,14 @@ while [ -h "$SELF_PATH" ]; do done cd "$ORIGDIR" -# Build the path to wp-cli.php. -SCRIPT_PATH='@@PHP_DIR@@/wp-cli/wp-cli.php' +# Build the path to the root PHP file +SCRIPT_PATH='@@PHP_DIR@@' if [ ! -f $SCRIPT_PATH ]; then - SCRIPT_PATH=$(dirname "$SELF_PATH")/../php/wp-cli/wp-cli.php + SCRIPT_PATH=$(dirname "$SELF_PATH")/../php fi +SCRIPT_PATH=$SCRIPT_PATH/wp-cli/wp-cli-boot.php + case $(uname -a) in CYGWIN*) SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; @@ -95,19 +94,6 @@ if [ "x$wp_cli_php_override" != "x" ] ; then php="$php $wp_cli_override_vars" fi -# Get the php version -PHP_VERSION=$(php -v | awk '/^PHP / {print $2}' | cut -d '-' -f 1) - -# Format version numbers -CURRENT_NUMBER=$(echo "$PHP_VERSION" | tr -d '.') -NEW_NUMBER=$(echo "$CHECK_VERSION" | tr -d '.') - -# Compare version numbers and exit if needed -if [ "$CURRENT_NUMBER" -lt "$NEW_NUMBER" ] ; then - echo "Error: PHP version $CHECK_VERSION is required to run wp-cli. You are running version $PHP_VERSION."; - exit -fi - # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands exec $php "$SCRIPT_PATH" "$@" diff --git a/src/php/wp-cli/wp-cli-boot.php b/src/php/wp-cli/wp-cli-boot.php new file mode 100644 index 0000000000..870cc61349 --- /dev/null +++ b/src/php/wp-cli/wp-cli-boot.php @@ -0,0 +1,9 @@ +<?php + +if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) { + printf( "Error: PHP version %s is required to run wp-cli. You are running version %s.\n", '5.3.0', PHP_VERSION ); + die(-1); +} + +include dirname(__FILE__) . '/wp-cli.php'; + diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index ed2a2da563..906eb25273 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -1,7 +1,8 @@ <?php if ( PHP_SAPI !== 'cli' ) { - die( 'Only cli access' ); + echo "Only CLI access.\n"; + die(-1); } define( 'WP_CLI_VERSION', '0.6.0-dev' ); From 4983355d6321c435f57e4816c62e4709dc55008c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 6 Jun 2012 23:33:52 +0300 Subject: [PATCH 0446/4858] make error message clearer --- src/php/wp-cli/wp-cli-boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli-boot.php b/src/php/wp-cli/wp-cli-boot.php index 870cc61349..972e60fd8d 100644 --- a/src/php/wp-cli/wp-cli-boot.php +++ b/src/php/wp-cli/wp-cli-boot.php @@ -1,7 +1,7 @@ <?php if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) { - printf( "Error: PHP version %s is required to run wp-cli. You are running version %s.\n", '5.3.0', PHP_VERSION ); + printf( "Error: wp-cli requires PHP %s or newer. You are running version %s.\n", '5.3.0', PHP_VERSION ); die(-1); } From fda56659b382fca4ecd12ed36cd9b872ffba0938 Mon Sep 17 00:00:00 2001 From: Mike Burns <mgburns@bu.edu> Date: Tue, 22 May 2012 12:58:18 -0400 Subject: [PATCH 0447/4858] updated wp core generate posts command to allow for random hierarchical post generation --- .../wp-cli/commands/internals/generate.php | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index c4bddf2221..8ef3bd9a79 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -21,6 +21,7 @@ public function posts( $args, $assoc_args ) { $defaults = array( 'count' => 100, + 'max_depth' => 1, 'type' => 'post', 'status' => 'publish', 'author' => false @@ -49,12 +50,30 @@ public function posts( $args, $assoc_args ) { $notify = new \cli\progress\Bar( 'Generating posts', $count ); + $post_ids = array(); + $current_depth = 1; + $current_parent = 0; + for ( $i = $total; $i < $limit; $i++ ) { - wp_insert_post( array( + + if( $this->maybe_make_child() && $current_depth < $max_depth ) { + + $current_parent = $post_ids[$i-1]; + $current_depth++; + + } else if( $this->maybe_reset_depth() ) { + + $current_depth = 1; + $current_parent = 0; + + } + + $post_ids[$i] = wp_insert_post( array( 'post_type' => $type, 'post_title' => "$label $i", 'post_status' => $status, - 'post_author' => $author + 'post_author' => $author, + 'post_parent' => $current_parent ) ); $notify->tick(); @@ -63,6 +82,16 @@ public function posts( $args, $assoc_args ) { $notify->finish(); } + private function maybe_make_child() { + // 50% chance of making child post + return ( mt_rand(1,2) == 1 ) ? true: false; + } + + private function maybe_reset_depth() { + // 10% chance of reseting to root depth + return ( mt_rand(1,10) == 7 ) ? true : false; + } + /** * Generate users * From f10f83ba1f902d23f7b5209a10afb7c9b9c234ac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 9 Jun 2012 02:07:23 +0300 Subject: [PATCH 0448/4858] add --max_depth parameter to docs --- man/generate-posts.1 | 10 ++++++++-- src/doc/generate-posts.txt | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/man/generate-posts.1 b/man/generate-posts.1 index c014d4ff63..fcd00ede49 100644 --- a/man/generate-posts.1 +++ b/man/generate-posts.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-GENERATE\-POSTS" "1" "May 2012" "" "WP-CLI" +.TH "WP\-GENERATE\-POSTS" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-generate\-posts\fR \- Generate a bunch of posts\. . .SH "SYNOPSIS" -\fBwp generate posts\fR [\-\-count=100] [\-\-type=post] [\-\-status=publish] [\-\-author=\fIlogin\fR] +\fBwp generate posts\fR [\-\-count=100] [\-\-type=post] [\-\-status=publish] [\-\-author=\fIlogin\fR] [\-\-max_depth=1] . .SH "OPTIONS" . @@ -34,4 +34,10 @@ The status of the generated posts\. Default: \'publish\' . .IP The author of the generated posts\. Default: none +. +.TP +\fB\-\-max_depth\fR=\fInumber\fR: +. +.IP +For hierarchical post types, generate child posts down to a certain depth\. Default: 1 diff --git a/src/doc/generate-posts.txt b/src/doc/generate-posts.txt index 2f9b156062..129e4a1d05 100644 --- a/src/doc/generate-posts.txt +++ b/src/doc/generate-posts.txt @@ -3,7 +3,8 @@ wp-generate-posts(1) -- Generate a bunch of posts. ## SYNOPSIS -`wp generate posts` [--count=100] [--type=post] [--status=publish] [--author=<login>] +`wp generate posts` [--count=100] [--type=post] [--status=publish] +[--author=<login>] [--max_depth=1] ## OPTIONS @@ -22,3 +23,7 @@ wp-generate-posts(1) -- Generate a bunch of posts. * `--author`=<login>: The author of the generated posts. Default: none + +* `--max_depth`=<number>: + + For hierarchical post types, generate child posts down to a certain depth. Default: 1 From 9f91349a25c5f93b68610c96391951498a242fe9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 9 Jun 2012 02:22:01 +0300 Subject: [PATCH 0449/4858] make doc-build accept file names as parameters --- utils/doc-build | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/utils/doc-build b/utils/doc-build index eaa0b40e1c..82ff06ae9c 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -1,10 +1,20 @@ #!/bin/bash -# generate man pages +# regenerate everything: +# ./utils/doc-build -rm -rf man -mkdir -p man +# regenerate certain files: +# ./utils/doc-build src/doc/core-update.txt -for file in $(ls src/doc/*.txt); do +files="$@" + +if [ "$files" == "" ]; then + files=$(ls src/doc/*.txt) + + rm -rf man + mkdir -p man +fi + +for file in $files; do cat $file | ronn --roff --manual="WP-CLI" > man/$(basename $file .txt).1 done From 672e204b049362f55a2d58fa23cce7547e3e25e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 9 Jun 2012 02:32:10 +0300 Subject: [PATCH 0450/4858] allow easy wildcards --- utils/doc-build | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/doc-build b/utils/doc-build index 82ff06ae9c..588836d8af 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -4,9 +4,10 @@ # ./utils/doc-build # regenerate certain files: -# ./utils/doc-build src/doc/core-update.txt +# ./utils/doc-build src/doc/core-* -files="$@" +# eliminate *~ files +files=$(echo "$@" | tr ' ' "\n" | grep -v '~$') if [ "$files" == "" ]; then files=$(ls src/doc/*.txt) From 8263eea841dbb493335936a90fd55482a4212eff Mon Sep 17 00:00:00 2001 From: Mike Burns <mike@grady-etc.com> Date: Sat, 9 Jun 2012 21:42:46 -0400 Subject: [PATCH 0451/4858] Added check for hierarchical post type before respecting max_depth argument --- src/php/wp-cli/commands/internals/generate.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 8ef3bd9a79..c72f820dfb 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -46,6 +46,8 @@ public function posts( $args, $assoc_args ) { $label = get_post_type_object( $type )->labels->singular_name; + $hierarchical = get_post_type_object( $type )->hierarchical; + $limit = $count + $total; $notify = new \cli\progress\Bar( 'Generating posts', $count ); @@ -56,16 +58,19 @@ public function posts( $args, $assoc_args ) { for ( $i = $total; $i < $limit; $i++ ) { - if( $this->maybe_make_child() && $current_depth < $max_depth ) { + if( $hierarchical ) { + + if( $this->maybe_make_child() && $current_depth < $max_depth ) { - $current_parent = $post_ids[$i-1]; - $current_depth++; + $current_parent = $post_ids[$i-1]; + $current_depth++; - } else if( $this->maybe_reset_depth() ) { + } else if( $this->maybe_reset_depth() ) { - $current_depth = 1; - $current_parent = 0; + $current_depth = 1; + $current_parent = 0; + } } $post_ids[$i] = wp_insert_post( array( From 49ebf0660b58d307b5321aaad5d1e496ef21d12c Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Tue, 12 Jun 2012 10:12:01 +0100 Subject: [PATCH 0452/4858] Add wp core upgrade_database --- src/doc/core-upgrade_database.txt | 6 ++++++ src/php/wp-cli/commands/internals/core.php | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 src/doc/core-upgrade_database.txt diff --git a/src/doc/core-upgrade_database.txt b/src/doc/core-upgrade_database.txt new file mode 100644 index 0000000000..b2d1d91e5e --- /dev/null +++ b/src/doc/core-upgrade_database.txt @@ -0,0 +1,6 @@ +wp-core-upgrade_database(1) -- Apply any outstanding database upgrades. +==== + +## SYNOPSIS + +`wp core database_upgrade` diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 27deec66e4..74cd228629 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -155,5 +155,11 @@ function update( $args ) { WP_CLI::success('WordPress updated successfully.'); } } + + function database_upgrade( $args ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + wp_upgrade(); + WP_CLI::success('WordPress database upgraded successfully.'); + } } From ffc6f72eb8a566212215b669877030327f52bc96 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Tue, 12 Jun 2012 10:15:19 +0100 Subject: [PATCH 0453/4858] Rename wp core database_upgrade to upgrade_database (to match docs) --- src/php/wp-cli/commands/internals/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 74cd228629..cde2e25a1a 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -156,7 +156,7 @@ function update( $args ) { } } - function database_upgrade( $args ) { + function upgrade_database( $args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); wp_upgrade(); WP_CLI::success('WordPress database upgraded successfully.'); From 1ed0717156ac47076de524c350a04784c2e77627 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Jun 2012 22:12:33 +0300 Subject: [PATCH 0454/4858] merge `wp core upgrade_database` into wp core update. see #121 --- man/core-update.1 | 13 +++++++++++-- src/doc/core-update.txt | 9 ++++++++- src/doc/core-upgrade_database.txt | 6 ------ src/php/wp-cli/commands/internals/core.php | 20 ++++++++++---------- 4 files changed, 29 insertions(+), 19 deletions(-) delete mode 100644 src/doc/core-upgrade_database.txt diff --git a/man/core-update.1 b/man/core-update.1 index 24a01f15e9..ee1aaebee5 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -1,10 +1,19 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-update\fR \- Update WordPress to the latest version\. . .SH "SYNOPSIS" -\fBwp core update\fR +\fBwp core update\fR [\-\-db] +. +.SH "OPTIONS" +. +.TP +\fB\-\-db\fR: +. +.IP +When passed, it applies any outstanding database upgrades, without touching the files\. + diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index 8a6d15bd87..64f3386ca7 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -3,4 +3,11 @@ wp-core-update(1) -- Update WordPress to the latest version. ## SYNOPSIS -`wp core update` +`wp core update` [--db] + +## OPTIONS + +* `--db`: + + When passed, it applies any outstanding database upgrades, without +touching the files. diff --git a/src/doc/core-upgrade_database.txt b/src/doc/core-upgrade_database.txt deleted file mode 100644 index b2d1d91e5e..0000000000 --- a/src/doc/core-upgrade_database.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-core-upgrade_database(1) -- Apply any outstanding database upgrades. -==== - -## SYNOPSIS - -`wp core database_upgrade` diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index cde2e25a1a..822253a513 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -130,7 +130,15 @@ public function version( $args = array(), $assoc_args = array() ) { * * @param array $args */ - function update( $args ) { + function update( $args, $assoc_args ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + if ( isset( $assoc_args['db'] ) ) { + wp_upgrade(); + WP_CLI::success( 'WordPress database upgraded successfully.' ); + return; + } + wp_version_check(); $from_api = get_site_transient( 'update_core' ); @@ -140,8 +148,6 @@ function update( $args ) { else list( $update ) = $from_api->updates; - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - $result = WP_CLI::get_upgrader( 'Core_Upgrader' )->upgrade( $update ); if ( is_wp_error($result) ) { @@ -152,14 +158,8 @@ function update( $args ) { WP_CLI::success( $msg ); } } else { - WP_CLI::success('WordPress updated successfully.'); + WP_CLI::success( 'WordPress updated successfully.' ); } } - - function upgrade_database( $args ) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - wp_upgrade(); - WP_CLI::success('WordPress database upgraded successfully.'); - } } From 451f13d06bfb3ed3ab2df809f19379d94320f9f2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 20 Jun 2012 19:52:31 +0300 Subject: [PATCH 0455/4858] handle MAMP paths generically. see #66 --- src/bin/wp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bin/wp b/src/bin/wp index 45da90e16c..20e3cb559a 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -67,9 +67,10 @@ else fi # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php5/bin/php /Applications/MAMP/bin/php5.2/bin/php /Applications/MAMP/bin/php5.3/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + for amp_php in /Applications/MAMP/bin/php5*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do if [ -x $amp_php ]; then php=$amp_php + break fi done fi From 361d41d2f9188de7ca403d9f34734f6b1af78bb0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 20 Jun 2012 19:56:04 +0300 Subject: [PATCH 0456/4858] fix indenting in src/bin/wp --- src/bin/wp | 78 +++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/bin/wp b/src/bin/wp index 20e3cb559a..f4e9ec769f 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -16,13 +16,13 @@ SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(b # Resolve symlinks - this is the equivalent of "readlink -f", but also works with non-standard OS X readlink. while [ -h "$SELF_PATH" ]; do - # 1) cd to directory of the symlink - # 2) cd to the directory of where the symlink points - # 3) Get the pwd - # 4) Append the basename - DIR=$(dirname -- "$SELF_PATH") - SYM=$(readlink $SELF_PATH) - SELF_PATH=$(cd $DIR && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") + # 1) cd to directory of the symlink + # 2) cd to the directory of where the symlink points + # 3) Get the pwd + # 4) Append the basename + DIR=$(dirname -- "$SELF_PATH") + SYM=$(readlink $SELF_PATH) + SELF_PATH=$(cd $DIR && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") done cd "$ORIGDIR" @@ -35,8 +35,8 @@ fi SCRIPT_PATH=$SCRIPT_PATH/wp-cli/wp-cli-boot.php case $(uname -a) in - CYGWIN*) - SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; + CYGWIN*) + SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; esac # If not exported, try to determine and export the number of columns. @@ -46,53 +46,53 @@ esac # error message is suppressed, but tput cols becomes confused about the # terminal and prints out the default value (80). if [ -z $COLUMNS ] && [ -n "$TERM" ] && [ "$TERM" != dumb ] ; then - # Note to cygwin users: install the ncurses package to get tput command. - if COLUMNS=$(tput cols); then - export COLUMNS - fi + # Note to cygwin users: install the ncurses package to get tput command. + if COLUMNS=$(tput cols); then + export COLUMNS + fi fi if [ ! -z "$WP_CLI_PHP" ] ; then - # Use the WP_CLI_PHP environment variable if it is available. - php="$WP_CLI_PHP" + # Use the WP_CLI_PHP environment variable if it is available. + php="$WP_CLI_PHP" else - # Default to using the php that we find on the PATH. - # Note that we need the full path to php here for Dreamhost, which behaves oddly. See http://drupal.org/node/662926 - php=`which php` + # Default to using the php that we find on the PATH. + # Note that we need the full path to php here for Dreamhost, which behaves oddly. See http://drupal.org/node/662926 + php=`which php` - # We check for a command line (cli) version of php, and if found use that. - which php-cli >/dev/null 2>&1 - if [ "$?" = 0 ] ; then - php=`which php-cli` - fi + # We check for a command line (cli) version of php, and if found use that. + which php-cli >/dev/null 2>&1 + if [ "$?" = 0 ] ; then + php=`which php-cli` + fi - # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php5*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do - if [ -x $amp_php ]; then - php=$amp_php - break - fi - done + # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. + for amp_php in /Applications/MAMP/bin/php5*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + if [ -x $amp_php ]; then + php=$amp_php + break + fi + done fi # Check to see if the user has provided a php.ini file or wp-cli.ini file in any conf dir # Last found wins, so search in reverse priority order for conf_dir in $(dirname "$SELF_PATH") /etc/wp-cli $HOME/.wp-cli ; do - if [ -f $conf_dir/php.ini ] ; then - wp_cli_php_ini=$conf_dir/php.ini - fi - if [ -f $conf_dir/wp-cli.ini ] ; then - wp_cli_php_override=$conf_dir/wp-cli.ini - fi + if [ -f $conf_dir/php.ini ] ; then + wp_cli_php_ini=$conf_dir/php.ini + fi + if [ -f $conf_dir/wp-cli.ini ] ; then + wp_cli_php_override=$conf_dir/wp-cli.ini + fi done # Add in the php file location and/or the php override variables as appropriate if [ "x$wp_cli_php_ini" != "x" ] ; then - php="$php --php-ini $wp_cli_php_ini" + php="$php --php-ini $wp_cli_php_ini" fi if [ "x$wp_cli_php_override" != "x" ] ; then - wp_cli_override_vars=`grep '^[a-z_A-Z0-9]\+ *=' $wp_cli_php_override | sed -e 's|\([^ =]*\) *= *\(.*\)|\1="\2"|' -e 's| ||g' -e 's|^|-d |' | tr '\n\r' ' '` - php="$php $wp_cli_override_vars" + wp_cli_override_vars=`grep '^[a-z_A-Z0-9]\+ *=' $wp_cli_php_override | sed -e 's|\([^ =]*\) *= *\(.*\)|\1="\2"|' -e 's| ||g' -e 's|^|-d |' | tr '\n\r' ' '` + php="$php $wp_cli_override_vars" fi # Pass in the path to php so that wp-cli knows which one From d759983324a30f54716c9c4dc65520eb81b2aa31 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Jun 2012 06:16:19 +0300 Subject: [PATCH 0457/4858] add --network flag to wp plugin activate|deactivate|toggle. fixes #127 --- src/php/wp-cli/commands/internals/plugin.php | 44 +++++++++++++------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 5c8b4e36e4..57b2719f66 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -108,15 +108,17 @@ private function get_status( $file, $long = false ) { * * @param array $args */ - function activate( $args ) { + function activate( $args, $assoc_args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - activate_plugin( $file ); + $network_wide = isset( $assoc_args['network'] ); - if ( !is_plugin_active( $file ) ) { - WP_CLI::error( 'Could not activate this plugin: ' . $name ); - } else { + activate_plugin( $file, '', $network_wide ); + + if ( $this->check_active( $file, $network_wide ) ) { WP_CLI::success( "Plugin '$name' activated." ); + } else { + WP_CLI::error( 'Could not activate plugin: ' . $name ); } } @@ -125,30 +127,44 @@ function activate( $args ) { * * @param array $args */ - function deactivate( $args ) { + function deactivate( $args, $assoc_args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - deactivate_plugins( $file ); + $network_wide = isset( $assoc_args['network'] ); - if ( !is_plugin_inactive( $file ) ) { - WP_CLI::error( 'Could not deactivate this plugin: '.$name ); - } else { + deactivate_plugins( $file, false, $network_wide ); + + if ( ! $this->check_active( $file, $network_wide ) ) { WP_CLI::success( "Plugin '$name' deactivated." ); + } else { + WP_CLI::error( 'Could not deactivate plugin: ' . $name ); } } + private function check_active( $file, $network_wide ) { + if ( $network_wide ) { + $check = is_plugin_active_for_network( $file ); + } else { + $check = is_plugin_active( $file ); + } + + return $check; + } + /** * Toggle a plugin's activation state * * @param array $args */ - function toggle( $args ) { + function toggle( $args, $assoc_args ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - if ( is_plugin_active( $file ) ) { - $this->deactivate( $args ); + $network_wide = isset( $assoc_args['network'] ); + + if ( $this->check_active( $file, $network_wide ) ) { + $this->deactivate( $args, $assoc_args ); } else { - $this->activate( $args ); + $this->activate( $args, $assoc_args ); } } From 22ab2343c930759075f7185b13eb5e8fa757d15b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Jun 2012 06:21:44 +0300 Subject: [PATCH 0458/4858] update docs. see #127 --- man/plugin-activate.1 | 10 ++++++++-- man/plugin-deactivate.1 | 10 ++++++++-- man/plugin-toggle.1 | 10 ++++++++-- src/doc/plugin-activate.txt | 6 +++++- src/doc/plugin-deactivate.txt | 6 +++++- src/doc/plugin-toggle.txt | 6 +++++- 6 files changed, 39 insertions(+), 9 deletions(-) diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 index f78e014367..4dfd3c7802 100644 --- a/man/plugin-activate.1 +++ b/man/plugin-activate.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-ACTIVATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-ACTIVATE" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-activate\fR \- Activate an installed plugin\. . .SH "SYNOPSIS" -\fBwp plugin activate\fR \fIplugin\fR +\fBwp plugin activate\fR \fIplugin\fR [\-\-network] . .SH "OPTIONS" . @@ -16,4 +16,10 @@ . .IP The plugin to activate\. +. +.TP +\fB\-\-network\fR: +. +.IP +If set, the plugin will be deactivated for the entire multisite network\. diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 index 25bd7b38f3..a9823535ca 100644 --- a/man/plugin-deactivate.1 +++ b/man/plugin-deactivate.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-deactivate\fR \- Deactivate an active plugin\. . .SH "SYNOPSIS" -\fBwp plugin deactivate\fR \fIplugin\fR +\fBwp plugin deactivate\fR \fIplugin\fR [\-\-network] . .SH "OPTIONS" . @@ -16,4 +16,10 @@ . .IP The plugin to deactivate\. +. +.TP +\fB\-\-network\fR: +. +.IP +If set, the plugin will be deactivated for the entire multisite network\. diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 index 36a4a599d6..52dba0c003 100644 --- a/man/plugin-toggle.1 +++ b/man/plugin-toggle.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-deactivate\fR \- Activate/Deactivate an installed plugin\. . .SH "SYNOPSIS" -\fBwp plugin toggle\fR \fIplugin\fR +\fBwp plugin toggle\fR \fIplugin\fR [\-\-network] . .SH "OPTIONS" . @@ -16,4 +16,10 @@ . .IP The plugin to toggle\. +. +.TP +\fB\-\-network\fR: +. +.IP +If set, the plugin will be deactivated for the entire multisite network\. diff --git a/src/doc/plugin-activate.txt b/src/doc/plugin-activate.txt index 58760b7099..9060625412 100644 --- a/src/doc/plugin-activate.txt +++ b/src/doc/plugin-activate.txt @@ -3,10 +3,14 @@ wp-plugin-activate(1) -- Activate an installed plugin. ## SYNOPSIS -`wp plugin activate` <plugin> +`wp plugin activate` <plugin> [--network] ## OPTIONS * `<plugin>`: The plugin to activate. + +* `--network`: + + If set, the plugin will be deactivated for the entire multisite network. diff --git a/src/doc/plugin-deactivate.txt b/src/doc/plugin-deactivate.txt index e6093a8387..d114fafed8 100644 --- a/src/doc/plugin-deactivate.txt +++ b/src/doc/plugin-deactivate.txt @@ -3,10 +3,14 @@ wp-plugin-deactivate(1) -- Deactivate an active plugin. ## SYNOPSIS -`wp plugin deactivate` <plugin> +`wp plugin deactivate` <plugin> [--network] ## OPTIONS * `<plugin>`: The plugin to deactivate. + +* `--network`: + + If set, the plugin will be deactivated for the entire multisite network. diff --git a/src/doc/plugin-toggle.txt b/src/doc/plugin-toggle.txt index 5f90c0543e..5dee2ee944 100644 --- a/src/doc/plugin-toggle.txt +++ b/src/doc/plugin-toggle.txt @@ -3,10 +3,14 @@ wp-plugin-deactivate(1) -- Activate/Deactivate an installed plugin. ## SYNOPSIS -`wp plugin toggle` <plugin> +`wp plugin toggle` <plugin> [--network] ## OPTIONS * `<plugin>`: The plugin to toggle. + +* `--network`: + + If set, the plugin will be deactivated for the entire multisite network. From 377793003548f9b3935bc1c9805beb5cfb9c5e42 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Jun 2012 06:28:03 +0300 Subject: [PATCH 0459/4858] make doc-build regenerate only the files that git says have changed --- utils/doc-build | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/utils/doc-build b/utils/doc-build index 588836d8af..048af6a362 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -1,21 +1,8 @@ #!/bin/bash -# regenerate everything: +# regenerate modified files: # ./utils/doc-build -# regenerate certain files: -# ./utils/doc-build src/doc/core-* - -# eliminate *~ files -files=$(echo "$@" | tr ' ' "\n" | grep -v '~$') - -if [ "$files" == "" ]; then - files=$(ls src/doc/*.txt) - - rm -rf man - mkdir -p man -fi - -for file in $files; do +for file in $(git st src/doc/ --porcelain | cut -d ' ' -f 3); do cat $file | ronn --roff --manual="WP-CLI" > man/$(basename $file .txt).1 done From c828c8f474187a393169c6589d3c626f01380fbf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Jun 2012 06:28:17 +0300 Subject: [PATCH 0460/4858] fix docs. see #127 --- man/plugin-activate.1 | 2 +- man/plugin-toggle.1 | 2 +- src/doc/plugin-activate.txt | 2 +- src/doc/plugin-toggle.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 index 4dfd3c7802..bcecd12c9f 100644 --- a/man/plugin-activate.1 +++ b/man/plugin-activate.1 @@ -21,5 +21,5 @@ The plugin to activate\. \fB\-\-network\fR: . .IP -If set, the plugin will be deactivated for the entire multisite network\. +If set, the plugin will be activated for the entire multisite network\. diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 index 52dba0c003..f86b819e5c 100644 --- a/man/plugin-toggle.1 +++ b/man/plugin-toggle.1 @@ -21,5 +21,5 @@ The plugin to toggle\. \fB\-\-network\fR: . .IP -If set, the plugin will be deactivated for the entire multisite network\. +If set, the plugin will be toggled for the entire multisite network\. diff --git a/src/doc/plugin-activate.txt b/src/doc/plugin-activate.txt index 9060625412..b7207bf814 100644 --- a/src/doc/plugin-activate.txt +++ b/src/doc/plugin-activate.txt @@ -13,4 +13,4 @@ wp-plugin-activate(1) -- Activate an installed plugin. * `--network`: - If set, the plugin will be deactivated for the entire multisite network. + If set, the plugin will be activated for the entire multisite network. diff --git a/src/doc/plugin-toggle.txt b/src/doc/plugin-toggle.txt index 5dee2ee944..07c243ea27 100644 --- a/src/doc/plugin-toggle.txt +++ b/src/doc/plugin-toggle.txt @@ -13,4 +13,4 @@ wp-plugin-deactivate(1) -- Activate/Deactivate an installed plugin. * `--network`: - If set, the plugin will be deactivated for the entire multisite network. + If set, the plugin will be toggled for the entire multisite network. From 5b7106a830851e313fce61c8eb1e8956f09a6a8c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Jun 2012 09:39:01 +0300 Subject: [PATCH 0461/4858] make --admin_password mandatory. fixes #128 --- man/core-install.1 | 4 ++-- src/doc/core-install.txt | 2 +- src/php/wp-cli/commands/internals/core.php | 2 +- src/php/wp-cli/wp-cli.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/man/core-install.1 b/man/core-install.1 index b7376703ee..1c42139657 100644 --- a/man/core-install.1 +++ b/man/core-install.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-INSTALL" "1" "May 2012" "" "WP-CLI" +.TH "WP\-CORE\-INSTALL" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-install\fR \- Install the WordPress tables in the database\. . .SH "SYNOPSIS" -\fBwp core install\fR \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_password=\fIpassword\fR \-\-admin_email=\fIemail\fR +\fBwp core install\fR \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_email=\fIemail\fR \-\-admin_password=\fIpassword\fR . .SH "OPTIONS" . diff --git a/src/doc/core-install.txt b/src/doc/core-install.txt index 19231e671f..8f65a9a00d 100644 --- a/src/doc/core-install.txt +++ b/src/doc/core-install.txt @@ -3,7 +3,7 @@ wp-core-install(1) -- Install the WordPress tables in the database. ## SYNOPSIS -`wp core install` --url=<url> --title=<site-title> [--admin_name=<username>] --admin_password=<password> --admin_email=<email> +`wp core install` --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> ## OPTIONS diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 822253a513..4d45d4371e 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -76,7 +76,7 @@ public function install( $args, $assoc_args ) { 'title' => '', 'admin_name' => 'admin', 'admin_email' => '', - 'admin_password' => wp_generate_password( 12, false ) + 'admin_password' => '' ) ), EXTR_SKIP ); $public = true; diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 906eb25273..c1be3a9976 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -84,7 +84,7 @@ // Set installer flag before loading any WP files if ( array( 'core', 'install' ) == $arguments ) { - WP_CLI::check_required_args( array( 'url', 'title', 'admin_email' ), $assoc_args ); + WP_CLI::check_required_args( array( 'url', 'title', 'admin_email', 'admin_password' ), $assoc_args ); define( 'WP_INSTALLING', true ); } From 919c1414345ce4598964e2824e1967a32d658954 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Jun 2012 22:24:09 +0300 Subject: [PATCH 0462/4858] always define WP_MEMORY_LIMIT. props larsemil. fixes #122 --- src/php/wp-cli/wp-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c1be3a9976..c3ab62a5dc 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -89,6 +89,10 @@ define( 'WP_INSTALLING', true ); } +// Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 +if ( !defined('WP_MEMORY_LIMIT') ) + define('WP_MEMORY_LIMIT', '1024M'); + // Load WordPress require WP_ROOT . 'wp-load.php'; require ABSPATH . 'wp-admin/includes/admin.php'; From ada7f0fc5ab9a5e655f8b4ab1d4562f11b590f1a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Jun 2012 23:10:45 +0300 Subject: [PATCH 0463/4858] reset memory limit right before loading admin files. see #122 --- src/php/wp-cli/wp-cli.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c3ab62a5dc..3db7c17c86 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -89,12 +89,12 @@ define( 'WP_INSTALLING', true ); } -// Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 -if ( !defined('WP_MEMORY_LIMIT') ) - define('WP_MEMORY_LIMIT', '1024M'); - // Load WordPress require WP_ROOT . 'wp-load.php'; + +// Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 +@ini_set( 'memory_limit', -1 ); + require ABSPATH . 'wp-admin/includes/admin.php'; // Load the right info into the global wp_query From 2af9287f99aa441cf3f450bcf6e73670548e3a17 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Jun 2012 14:50:31 +0300 Subject: [PATCH 0464/4858] fix notice from install --activate --- src/php/wp-cli/commands/internals/plugin.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 57b2719f66..dfe6da512a 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -108,7 +108,7 @@ private function get_status( $file, $long = false ) { * * @param array $args */ - function activate( $args, $assoc_args ) { + function activate( $args, $assoc_args = array() ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $network_wide = isset( $assoc_args['network'] ); @@ -127,7 +127,7 @@ function activate( $args, $assoc_args ) { * * @param array $args */ - function deactivate( $args, $assoc_args ) { + function deactivate( $args, $assoc_args = array() ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $network_wide = isset( $assoc_args['network'] ); @@ -156,7 +156,7 @@ private function check_active( $file, $network_wide ) { * * @param array $args */ - function toggle( $args, $assoc_args ) { + function toggle( $args, $assoc_args = array() ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); $network_wide = isset( $assoc_args['network'] ); From f197ff82a04af786c7356c2c82dc0169d6dbaf5c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Jun 2012 15:06:42 +0300 Subject: [PATCH 0465/4858] make `wp plugin uninstall` delete the plugin files; add -no-delete flag --- man/plugin-uninstall.1 | 10 ++++++++-- src/doc/plugin-uninstall.txt | 7 ++++++- src/php/wp-cli/commands/internals/plugin.php | 5 ++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 index de306138d3..0d54300322 100644 --- a/man/plugin-uninstall.1 +++ b/man/plugin-uninstall.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UNINSTALL" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UNINSTALL" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-uninstall\fR \- Run the uninstallation procedure for a plugin\. . .SH "SYNOPSIS" -\fBwp plugin uninstall\fR \fIplugin\fR +\fBwp plugin uninstall\fR \fIplugin\fR [\-\-no\-delete] . .SH "OPTIONS" . @@ -17,6 +17,12 @@ .IP The plugin to uninstall\. . +.TP +\fB\-\-no\-delete\fR: +. +.IP +If set, the plugin files will not be deleted\. Only the uninstall procedure will be run\. +. .SH "EXAMPLES" . .nf diff --git a/src/doc/plugin-uninstall.txt b/src/doc/plugin-uninstall.txt index cc2fb5327a..d0783f3ddf 100644 --- a/src/doc/plugin-uninstall.txt +++ b/src/doc/plugin-uninstall.txt @@ -3,7 +3,7 @@ wp-plugin-uninstall(1) -- Run the uninstallation procedure for a plugin. ## SYNOPSIS -`wp plugin uninstall` <plugin> +`wp plugin uninstall` <plugin> [--no-delete] ## OPTIONS @@ -11,6 +11,11 @@ wp-plugin-uninstall(1) -- Run the uninstallation procedure for a plugin. The plugin to uninstall. +* `--no-delete`: + + If set, the plugin files will not be deleted. Only the uninstall procedure +will be run. + ## EXAMPLES wp plugin uninstall hello diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index dfe6da512a..acf7ca5cff 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -262,7 +262,7 @@ protected function get_item_list() { * * @param array $args */ - function uninstall( $args ) { + function uninstall( $args, $assoc_args = array() ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); if ( is_plugin_active( $file ) ) { @@ -270,6 +270,9 @@ function uninstall( $args ) { } uninstall_plugin( $file ); + + if ( !isset( $assoc_args['no-delete'] ) ) + $this->delete( $args ); } /** From 0d8487b771afbaf1acd8c086e088f9d3601c3395 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Jun 2012 15:07:34 +0300 Subject: [PATCH 0466/4858] transform doc-build into a pre-commit hook --- utils/doc-build | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/utils/doc-build b/utils/doc-build index 048af6a362..8a42244494 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -1,8 +1,12 @@ #!/bin/bash -# regenerate modified files: -# ./utils/doc-build +# regenerates modified man pages +# +# run automatically before each commit: +# ln -s ../../utils/doc-build .git/hooks/pre-commit -for file in $(git st src/doc/ --porcelain | cut -d ' ' -f 3); do - cat $file | ronn --roff --manual="WP-CLI" > man/$(basename $file .txt).1 +for file in $(git diff --cached --name-only src/doc/); do + man_file=man/$(basename $file .txt).1 + cat $file | ronn --roff --manual="WP-CLI" > $man_file + git add $man_file done From 80bab547cac1ee34c406876f6f9c3477db6f5fdd Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 28 Jun 2012 09:14:15 +0100 Subject: [PATCH 0467/4858] Add --json argument to "wp option get" --- src/php/wp-cli/commands/internals/option.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 955efb5f01..388b98aec8 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -72,7 +72,7 @@ public function delete( $args ) { * * @param array $args **/ - public function get( $args ) { + public function get( $args, $assoc_args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp option get <option-name>" ); exit; @@ -85,6 +85,10 @@ public function get( $args ) { if ( false === $value ) die(1); + if ( isset( $assoc_args['json'] ) ) { + $value = json_encode( $value ); + } + WP_CLI::print_value( $value ); } } From d34ceb0157aef7f35316dbda4dcd547808398216 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 28 Jun 2012 09:17:10 +0100 Subject: [PATCH 0468/4858] Add --json option to docs --- src/doc/option.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/option.txt b/src/doc/option.txt index 05f5e7da3c..e1d75245cc 100644 --- a/src/doc/option.txt +++ b/src/doc/option.txt @@ -3,7 +3,7 @@ wp-option(1) -- Manage WordPress options. ## SYNOPSIS -wp option get <key> +wp option get <key> [--json] wp option add <key> <value> @@ -15,7 +15,8 @@ wp option delete <key> * `get`: - Get an option value. + Get an option value. Passing --json causes the output to be formatted + as JSON. * `add`: From 5d7537a4213af49b34aec695f338cb1e248462c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 11:47:49 +0300 Subject: [PATCH 0469/4858] update man page --- man/option.1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/option.1 b/man/option.1 index 30580ae815..6fd2f524c8 100644 --- a/man/option.1 +++ b/man/option.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-OPTION" "1" "May 2012" "" "WP-CLI" +.TH "WP\-OPTION" "1" "June 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-option\fR \- Manage WordPress options\. . .SH "SYNOPSIS" -wp option get \fIkey\fR +wp option get \fIkey\fR [\-\-json] . .P wp option add \fIkey\fR \fIvalue\fR @@ -24,7 +24,7 @@ wp option delete \fIkey\fR \fBget\fR: . .IP -Get an option value\. +Get an option value\. Passing \-\-json causes the output to be formatted as JSON\. . .TP \fBadd\fR: From be136373aa241ba21f8463529046a5bdbbc27c79 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 11:49:14 +0300 Subject: [PATCH 0470/4858] allow passing man pages to doc-build again --- utils/doc-build | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/utils/doc-build b/utils/doc-build index 8a42244494..f19a97f5a7 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -5,7 +5,13 @@ # run automatically before each commit: # ln -s ../../utils/doc-build .git/hooks/pre-commit -for file in $(git diff --cached --name-only src/doc/); do +if [ -n "$@" ]; then + files=$(git diff --cached --name-only src/doc/) +else + files=$@ +fi + +for file in $files; do man_file=man/$(basename $file .txt).1 cat $file | ronn --roff --manual="WP-CLI" > $man_file git add $man_file From 819c71df2d29ce51621569ed5c4cf254aeeb5a98 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 28 Jun 2012 09:54:52 +0100 Subject: [PATCH 0471/4858] Add --json option to "wp option update" --- src/php/wp-cli/commands/internals/option.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 388b98aec8..30bb544fab 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -33,7 +33,7 @@ public function add( $args ) { * * @param array $args **/ - public function update( $args ) { + public function update( $args, $assoc_args ) { if ( count( $args ) < 2 ) { WP_CLI::line( "usage: wp option update <option-name> <option-value>" ); exit; @@ -41,6 +41,10 @@ public function update( $args ) { list( $key, $value ) = $args; + if ( isset( $assoc_args['json'] ) ) { + $value = json_decode( $value, true ); + } + if ( $value === get_option( $key ) ) return; From 45db34fff2885c419e5f043346cc36f844d59143 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 11:58:03 +0300 Subject: [PATCH 0472/4858] move --json handling to WP_CLI::print_value(). see #120 --- src/php/wp-cli/class-wp-cli.php | 10 ++++++---- src/php/wp-cli/commands/internals/option.php | 6 +----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 16f6fa4fb7..b727dfe8ff 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -80,12 +80,14 @@ static function warning( $message, $label = 'Warning' ) { * * @param string $message */ - static function print_value( $value ) { + static function print_value( $value, $assoc_args = array() ) { if ( is_array( $value ) || is_object( $value ) ) { - echo var_export( $value ) . "\n"; - } else { - echo $value . "\n"; + $formatter = isset( $assoc_args['json'] ) ? 'json_encode' : 'var_export'; + + $value = $formatter( $value ); } + + echo $value . "\n"; } /** diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 388b98aec8..670fe72efd 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -85,10 +85,6 @@ public function get( $args, $assoc_args ) { if ( false === $value ) die(1); - if ( isset( $assoc_args['json'] ) ) { - $value = json_encode( $value ); - } - - WP_CLI::print_value( $value ); + WP_CLI::print_value( $value, $assoc_args ); } } From c10c9f375e2230e1f68e8866ddd85810f48d0604 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 12:01:36 +0300 Subject: [PATCH 0473/4858] add --json to wp user-meta get. see #120 --- man/user-meta.1 | 4 ++-- src/doc/user-meta.txt | 5 +++-- src/php/wp-cli/commands/internals/user-meta.php | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/man/user-meta.1 b/man/user-meta.1 index a3429e9874..fa9b646d57 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -7,7 +7,7 @@ \fBwp\-user\-meta\fR \- Manage user custom fields\. . .SH "SYNOPSIS" -wp user\-meta get \fIID\fR \fIkey\fR +wp user\-meta get \fIID\fR \fIkey\fR [\-\-json] . .P wp user\-meta add \fIID\fR \fIkey\fR \fIvalue\fR @@ -24,7 +24,7 @@ wp user\-meta delete \fIID\fR \fIkey\fR \fBget\fR: . .IP -Get a custom field value\. +Get a custom field value\. Passing \-\-json causes the output to be formatted as JSON\. . .TP \fBadd\fR: diff --git a/src/doc/user-meta.txt b/src/doc/user-meta.txt index 1825c508c2..8a7562f0fc 100644 --- a/src/doc/user-meta.txt +++ b/src/doc/user-meta.txt @@ -3,7 +3,7 @@ wp-user-meta(1) -- Manage user custom fields. ## SYNOPSIS -wp user-meta get <ID> <key> +wp user-meta get <ID> <key> [--json] wp user-meta add <ID> <key> <value> @@ -15,7 +15,8 @@ wp user-meta delete <ID> <key> * `get`: - Get a custom field value. + Get a custom field value. Passing --json causes the output to be formatted + as JSON. * `add`: diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index ebb32ce7ce..95450218d2 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -25,7 +25,7 @@ public function get( $args, $assoc_args ) { if ( '' === $value ) die(1); - WP_CLI::print_value( $value ); + WP_CLI::print_value( $value, $assoc_args ); } /** From 243364d9a4a935cd6b2c3d2ba07b2d6ef25579b3 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 28 Jun 2012 10:02:58 +0100 Subject: [PATCH 0474/4858] Add --json option to "wp option add" --- src/php/wp-cli/commands/internals/option.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 30bb544fab..d20bc93aa0 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -15,13 +15,13 @@ class Option_Command extends WP_CLI_Command { * * @param array $args **/ - public function add( $args ) { + public function add( $args, $assoc_args ) { if ( count( $args ) < 2 ) { WP_CLI::line( "usage: wp option add <option-name> <option-value>" ); exit; } - list( $key, $value ) = $args; + list( $key, $value ) = self::read_name_and_value( $args, $assoc_args ); if ( !add_option( $key, $value ) ) { WP_CLI::error( "Could not add option '$key'. Does it already exist?" ); @@ -39,11 +39,7 @@ public function update( $args, $assoc_args ) { exit; } - list( $key, $value ) = $args; - - if ( isset( $assoc_args['json'] ) ) { - $value = json_decode( $value, true ); - } + list( $key, $value ) = self::read_name_and_value( $args, $assoc_args ); if ( $value === get_option( $key ) ) return; @@ -52,6 +48,16 @@ public function update( $args, $assoc_args ) { WP_CLI::error( "Could not update option '$key'." ); } } + + private function read_name_and_value( $args, $assoc_args) { + list( $key, $value ) = $args; + + if ( isset( $assoc_args['json'] ) ) { + $value = json_decode( $value, true ); + } + + return array( $key, $value ); + } /** * Delete an option From 7dd05600a779be6d00409a83f750bbabdb060a13 Mon Sep 17 00:00:00 2001 From: Michael Williamson <michael.williamson@red-gate.com> Date: Thu, 28 Jun 2012 10:04:28 +0100 Subject: [PATCH 0475/4858] Update documentation for --json option in "wp option {add|update}" --- src/doc/option.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/doc/option.txt b/src/doc/option.txt index e1d75245cc..cbb7b79c69 100644 --- a/src/doc/option.txt +++ b/src/doc/option.txt @@ -5,9 +5,9 @@ wp-option(1) -- Manage WordPress options. wp option get <key> [--json] -wp option add <key> <value> +wp option add <key> <value> [--json] -wp option update <key> <value> +wp option update <key> <value> [--json] wp option delete <key> @@ -20,11 +20,13 @@ wp option delete <key> * `add`: - Add a new option. + Add a new option. Pass --json to decode JSON values before adding + the option. * `update`: - Update an existing option. + Update an existing option. Pass --json to decode JSON values before + updating the option. * `delete`: From 8119f8eb22b92fb0117897b659ab8b1dd2a6ec1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 12:46:36 +0300 Subject: [PATCH 0476/4858] return JSON even for simple values --- src/php/wp-cli/class-wp-cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index b727dfe8ff..664d939a14 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -81,13 +81,13 @@ static function warning( $message, $label = 'Warning' ) { * @param string $message */ static function print_value( $value, $assoc_args = array() ) { - if ( is_array( $value ) || is_object( $value ) ) { - $formatter = isset( $assoc_args['json'] ) ? 'json_encode' : 'var_export'; - - $value = $formatter( $value ); + if ( isset( $assoc_args['json'] ) ) { + $value = json_encode( $value ); + } elseif ( is_array( $value ) || is_object( $value ) ) { + $value = var_export( $value ); } - echo $value . "\n"; + echo var_export( $value ) . "\n"; } /** From 57606f51aed69b634efcaf7cffc8521243b8016e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 14:04:57 +0300 Subject: [PATCH 0477/4858] remove double var_export() call --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 664d939a14..794af4fa4f 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -87,7 +87,7 @@ static function print_value( $value, $assoc_args = array() ) { $value = var_export( $value ); } - echo var_export( $value ) . "\n"; + echo $value . "\n"; } /** From 1934a06f0d3e80ed6488f68ee66d215312ce6500 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 14:05:25 +0300 Subject: [PATCH 0478/4858] replace read_name_and_value() with WP_CLI::read_value() --- src/php/wp-cli/class-wp-cli.php | 19 +++++++++++++++++-- src/php/wp-cli/commands/internals/option.php | 18 ++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 794af4fa4f..6eaaac3f4b 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -76,9 +76,24 @@ static function warning( $message, $label = 'Warning' ) { } /** - * Display an easy to paste PHP value. + * Read a value, from various formats * - * @param string $message + * @param mixed $value + * @param array $assoc_args + */ + static function read_value( $value, $assoc_args = array() ) { + if ( isset( $assoc_args['json'] ) ) { + $value = json_decode( $value, true ); + } + + return $value; + } + + /** + * Display a value, in various formats + * + * @param mixed $value + * @param array $assoc_args */ static function print_value( $value, $assoc_args = array() ) { if ( isset( $assoc_args['json'] ) ) { diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 954bae6924..fcea4789d8 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -21,7 +21,9 @@ public function add( $args, $assoc_args ) { exit; } - list( $key, $value ) = self::read_name_and_value( $args, $assoc_args ); + $key = $args[0]; + + $value = WP_CLI::read_value( $args[1], $assoc_args ); if ( !add_option( $key, $value ) ) { WP_CLI::error( "Could not add option '$key'. Does it already exist?" ); @@ -39,7 +41,9 @@ public function update( $args, $assoc_args ) { exit; } - list( $key, $value ) = self::read_name_and_value( $args, $assoc_args ); + $key = $args[0]; + + $value = WP_CLI::read_value( $args[1], $assoc_args ); if ( $value === get_option( $key ) ) return; @@ -48,16 +52,6 @@ public function update( $args, $assoc_args ) { WP_CLI::error( "Could not update option '$key'." ); } } - - private function read_name_and_value( $args, $assoc_args) { - list( $key, $value ) = $args; - - if ( isset( $assoc_args['json'] ) ) { - $value = json_decode( $value, true ); - } - - return array( $key, $value ); - } /** * Delete an option From ffa76a177cec60f063c4956e3e5b5f95fe21e953 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 14:07:45 +0300 Subject: [PATCH 0479/4858] update man page --- man/option.1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/man/option.1 b/man/option.1 index 6fd2f524c8..660dc4d263 100644 --- a/man/option.1 +++ b/man/option.1 @@ -10,10 +10,10 @@ wp option get \fIkey\fR [\-\-json] . .P -wp option add \fIkey\fR \fIvalue\fR +wp option add \fIkey\fR \fIvalue\fR [\-\-json] . .P -wp option update \fIkey\fR \fIvalue\fR +wp option update \fIkey\fR \fIvalue\fR [\-\-json] . .P wp option delete \fIkey\fR @@ -30,13 +30,13 @@ Get an option value\. Passing \-\-json causes the output to be formatted as JSON \fBadd\fR: . .IP -Add a new option\. +Add a new option\. Pass \-\-json to decode JSON values before adding the option\. . .TP \fBupdate\fR: . .IP -Update an existing option\. +Update an existing option\. Pass \-\-json to decode JSON values before updating the option\. . .TP \fBdelete\fR: From ed2ac85c6aede26ae1ab8c6abb761191625280a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Jun 2012 14:08:06 +0300 Subject: [PATCH 0480/4858] use $# to check if there are no parameters passed --- utils/doc-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/doc-build b/utils/doc-build index f19a97f5a7..9a71c69f97 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -5,7 +5,7 @@ # run automatically before each commit: # ln -s ../../utils/doc-build .git/hooks/pre-commit -if [ -n "$@" ]; then +if [ $# -eq 0 ]; then files=$(git diff --cached --name-only src/doc/) else files=$@ From dceaa271b0f3965b0aa0d60b6d1f9bebb8f9b96a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Jun 2012 20:49:13 +0300 Subject: [PATCH 0481/4858] don't look in parent dir for wp-load.php. fixes #134 --- src/php/wp-cli/wp-cli.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3db7c17c86..ca99bb7034 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -47,8 +47,6 @@ if ( !empty( $assoc_args['path'] ) ) { // trailingslashit() isn't available yet define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); -} elseif ( is_readable( $_SERVER['PWD'] . '/../wp-load.php' ) ) { - define( 'WP_ROOT', $_SERVER['PWD'] . '/../' ); } else { define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); } From 0e5e473f3ad3b76e37840090d56a3fce2315c7c8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 1 Jul 2012 15:31:57 +0300 Subject: [PATCH 0482/4858] add `wp option set` and `wp user-meta set` aliases --- src/php/wp-cli/commands/internals/option.php | 4 ++++ src/php/wp-cli/commands/internals/user-meta.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index fcea4789d8..861e05eaec 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -10,6 +10,10 @@ */ class Option_Command extends WP_CLI_Command { + protected $aliases = array( + 'set' => 'update' + ); + /** * Add an option * diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index 95450218d2..b12a8addec 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -10,6 +10,10 @@ */ class User_Meta_Command extends WP_CLI_Command { + protected $aliases = array( + 'set' => 'update' + ); + /** * Get meta field value for a user * From 8b01c257570bd9faec0cddda1bd92029f13970a8 Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Sun, 1 Jul 2012 23:24:30 -0700 Subject: [PATCH 0483/4858] Initial commit for core updates from local source --- man/core-update.1 | 20 +++++++++- src/doc/core-update.txt | 13 ++++++- src/php/wp-cli/commands/internals/core.php | 44 ++++++++++++++++++---- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/man/core-update.1 b/man/core-update.1 index ee1aaebee5..bee1b2a11b 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE" "1" "June 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE" "1" "July 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-update\fR \- Update WordPress to the latest version\. . .SH "SYNOPSIS" -\fBwp core update\fR [\-\-db] +\fBwp core update\fR [\-\-db] [\-\-version=\fInew_version\fR <package/zip>] . .SH "OPTIONS" . @@ -16,4 +16,20 @@ . .IP When passed, it applies any outstanding database upgrades, without touching the files\. +. +.TP +\fB\-\-version=\fR\fInew_version\fR <package/zip>: +. +.IP +When passed, updates to new_version using package/zip as input\. NOTE: package removed by WordPress automatically upon completion\. +. +.SH "EXAMPLES" +. +.nf + +wp core update + +wp core update \-\-version=3\.4 \.\./latest\.zip +. +.fi diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index 64f3386ca7..c8cb05917e 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -3,7 +3,7 @@ wp-core-update(1) -- Update WordPress to the latest version. ## SYNOPSIS -`wp core update` [--db] +`wp core update` [--db] [--version=<new_version> <package/zip>] ## OPTIONS @@ -11,3 +11,14 @@ wp-core-update(1) -- Update WordPress to the latest version. When passed, it applies any outstanding database upgrades, without touching the files. + +* `--version=`<new_version> <package/zip>: + + When passed, updates to new_version using package/zip as input. + NOTE: package removed by WordPress automatically upon completion. + +## EXAMPLES + + wp core update + + wp core update --version=3.4 ../latest.zip diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 4d45d4371e..62f552555c 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -129,9 +129,11 @@ public function version( $args = array(), $assoc_args = array() ) { * Update the WordPress core * * @param array $args + * @param array $assoc_args */ function update( $args, $assoc_args ) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + global $wp_version; + $update = $from_api = null; if ( isset( $assoc_args['db'] ) ) { wp_upgrade(); @@ -139,14 +141,42 @@ function update( $args, $assoc_args ) { return; } - wp_version_check(); + if ( empty( $assoc_args['version'] ) ) { + wp_version_check(); + $from_api = get_site_transient( 'update_core' ); - $from_api = get_site_transient( 'update_core' ); + if ( empty( $from_api->updates ) ) + $update = false; + else + list( $update ) = $from_api->updates; - if ( empty( $from_api->updates ) ) - $update = false; - else - list( $update ) = $from_api->updates; + } else { + if ( empty( $args[0] ) ) + WP_CLI::error( "Package not specified." ); + + $new_package = $args[0]; + $new_version = $assoc_args['version']; + + if ( version_compare( $wp_version, $new_version, '<' ) ) { + $update = (object) array( + 'response' => 'upgrade', + 'current' => $new_version, + 'download' => $new_package, + 'packages' => (object) array ( + 'partial' => null, + 'new_bundled' => null, + 'no_content' => null, + 'full' => $new_package, + ), + ); + + } else { + WP_CLI::success( 'WordPress is up to date.' ); + return; + } + } + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); $result = WP_CLI::get_upgrader( 'Core_Upgrader' )->upgrade( $update ); From d034d193152dc2b8fdb55dc6795f6a2b0b45572a Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Tue, 3 Jul 2012 12:41:40 -0700 Subject: [PATCH 0484/4858] Avoid deleting specified package after Core Update. See #135 Introduces Non_Destructive_Core_Upgrader --- man/core-update.1 | 2 +- src/doc/core-update.txt | 1 - src/php/wp-cli/class-cli-upgrader-skin.php | 10 ++++++++++ src/php/wp-cli/commands/internals/core.php | 8 ++++++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/man/core-update.1 b/man/core-update.1 index bee1b2a11b..4e8c61215d 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -21,7 +21,7 @@ When passed, it applies any outstanding database upgrades, without touching the \fB\-\-version=\fR\fInew_version\fR <package/zip>: . .IP -When passed, updates to new_version using package/zip as input\. NOTE: package removed by WordPress automatically upon completion\. +When passed, updates to new_version using package/zip as input\. . .SH "EXAMPLES" . diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index c8cb05917e..411ea0082c 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -15,7 +15,6 @@ touching the files. * `--version=`<new_version> <package/zip>: When passed, updates to new_version using package/zip as input. - NOTE: package removed by WordPress automatically upon completion. ## EXAMPLES diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index 93488b8ca2..45266bfd95 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -40,3 +40,13 @@ function feedback( $string ) { } } +/** + * A Core Upgrader class that leaves packages intact by default. + * + * @package wp-cli + */ +class Non_Destructive_Core_Upgrader extends Core_Upgrader { + function unpack_package($package, $delete_package = false) { + return parent::unpack_package( $package, $delete_package ); + } +} diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 62f552555c..ee96d11cc5 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -133,7 +133,7 @@ public function version( $args = array(), $assoc_args = array() ) { */ function update( $args, $assoc_args ) { global $wp_version; - $update = $from_api = null; + $update = $from_api = $upgrader = null; if ( isset( $assoc_args['db'] ) ) { wp_upgrade(); @@ -150,6 +150,8 @@ function update( $args, $assoc_args ) { else list( $update ) = $from_api->updates; + $upgrader = 'Core_Upgrader'; + } else { if ( empty( $args[0] ) ) WP_CLI::error( "Package not specified." ); @@ -170,6 +172,8 @@ function update( $args, $assoc_args ) { ), ); + $upgrader = 'Non_Destructive_Core_Upgrader'; + } else { WP_CLI::success( 'WordPress is up to date.' ); return; @@ -178,7 +182,7 @@ function update( $args, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - $result = WP_CLI::get_upgrader( 'Core_Upgrader' )->upgrade( $update ); + $result = WP_CLI::get_upgrader( $upgrader )->upgrade( $update ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); From 390e7dbbabee7398527c3a1552e849f5c87053aa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 14:07:13 +0300 Subject: [PATCH 0485/4858] set DOCUMENT_ROOT to the current working dir. fixes #137 --- src/php/wp-cli/wp-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index ca99bb7034..7d42d32d9c 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -43,6 +43,8 @@ unset( $assoc_args['help'] ); } +$_SERVER['DOCUMENT_ROOT'] = getcwd(); + // Define the WordPress location if ( !empty( $assoc_args['path'] ) ) { // trailingslashit() isn't available yet From 2e08bbd94949b5c845556d5432da5fe9760f5f44 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 20:38:49 +0300 Subject: [PATCH 0486/4858] don't attempt to populate wp_query when the blog is being installed --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 7d42d32d9c..22485f1b53 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -98,7 +98,7 @@ require ABSPATH . 'wp-admin/includes/admin.php'; // Load the right info into the global wp_query -if ( isset( $assoc_args['url'] ) ) { +if ( !defined( 'WP_INSTALLING' ) && isset( $assoc_args['url'] ) ) { if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { $GLOBALS['wp']->parse_request(); $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); From 8d7504f8f51913779f3623acd07590ac0ea2cd03 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 22:55:55 +0300 Subject: [PATCH 0487/4858] introduce WP_CLI::locate_wp_config() --- src/php/wp-cli/class-wp-cli.php | 44 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 6eaaac3f4b..f056846338 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -261,24 +261,23 @@ static function _set_url( &$assoc_args ) { } } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); - } else { + } elseif ( $wp_config_path = self::locate_wp_config() ) { // Try to find the blog parameter in the wp-config file - if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { - $wp_config_file = file_get_contents( WP_ROOT . '/wp-config.php' ); - $hit = array(); - if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { - foreach( $matches[2] as $def_key => $def_name ) { - if ( 'DOMAIN_CURRENT_SITE' == $def_name ) - $hit['domain'] = $matches[5][$def_key]; - if ( 'PATH_CURRENT_SITE' == $def_name ) - $hit['path'] = $matches[5][$def_key]; - } + $wp_config_file = file_get_contents( $wp_config_path ); + $hit = array(); + if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { + foreach ( $matches[2] as $def_key => $def_name ) { + if ( 'DOMAIN_CURRENT_SITE' == $def_name ) + $hit['domain'] = $matches[5][$def_key]; + if ( 'PATH_CURRENT_SITE' == $def_name ) + $hit['path'] = $matches[5][$def_key]; } - if ( !empty( $hit ) && isset( $hit['domain'] ) ) - $blog = $hit['domain']; - if ( !empty( $hit ) && isset( $hit['path'] ) ) - $blog .= $hit['path']; } + + if ( !empty( $hit ) && isset( $hit['domain'] ) ) + $blog = $hit['domain']; + if ( !empty( $hit ) && isset( $hit['path'] ) ) + $blog .= $hit['path']; } if ( isset( $blog ) ) { @@ -290,12 +289,19 @@ static function _set_url( &$assoc_args ) { static function load_wp_config() { define( 'ABSPATH', dirname(__FILE__) . '/' ); + if ( $wp_config_path = self::locate_wp_config() ) + require self::locate_wp_config(); + else + WP_CLI::error( 'No wp-config.php file.' ); + } + + static function locate_wp_config() { if ( file_exists( WP_ROOT . 'wp-config.php' ) ) { - require_once( WP_ROOT . 'wp-config.php' ); - } elseif ( file_exists( dirname(WP_ROOT) . '/wp-config.php' ) && ! file_exists( dirname(WP_ROOT) . '/wp-settings.php' ) ) { - require_once( dirname(WP_ROOT) . '/wp-config.php' ); + return WP_ROOT . 'wp-config.php'; + } elseif ( file_exists( WP_ROOT . '/../wp-config.php' ) && ! file_exists( WP_ROOT . '/../wp-settings.php' ) ) { + return WP_ROOT . '/../wp-config.php'; } else { - WP_CLI::error( 'No wp-config.php file.' ); + return false; } } From 68541632a0e1f777187b81a15a7f03a4cc60f99e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 23:18:35 +0300 Subject: [PATCH 0488/4858] replace --really with --yes --- man/db-drop.1 | 19 ------------------- src/doc/db-drop.txt | 4 ++-- src/php/wp-cli/commands/internals/db.php | 2 +- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/man/db-drop.1 b/man/db-drop.1 index 3a370feb82..e69de29bb2 100644 --- a/man/db-drop.1 +++ b/man/db-drop.1 @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-DROP" "1" "May 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-drop\fR \- Drop the database specified in wp\-config\.php -. -.SH "SYNOPSIS" -\fBwp db drop\fR [\-\-really] -. -.SH "OPTIONS" -. -.TP -\fB\-\-really\fR: -. -.IP -Skip the confirmation messaje\. - diff --git a/src/doc/db-drop.txt b/src/doc/db-drop.txt index 074b141235..15a1bbd8f7 100644 --- a/src/doc/db-drop.txt +++ b/src/doc/db-drop.txt @@ -7,6 +7,6 @@ wp-db-drop(1) -- Drop the database specified in wp-config.php ## OPTIONS -* `--really`: +* `--yes`: - Skip the confirmation messaje. + Answer yes to the confirmation message. diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 30f9e9e522..ec5780fad5 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -28,7 +28,7 @@ function create() { * Deletes the database specified in the wp-config.php file. */ function drop( $args, $assoc_args ) { - if ( !isset( $assoc_args['really'] ) ) { + if ( !isset( $assoc_args['yes'] ) ) { WP_CLI::out( "Are you sure you want to drop the database? [y/n] " ); $answer = trim( fgets( STDIN ) ); From bc6a036f662c166a36e8eca83aebb52c8ba391f2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 23:34:29 +0300 Subject: [PATCH 0489/4858] add install_network subcommand. fixes #139 --- man/core-install_network.1 | 0 src/doc/core-install_network.txt | 17 +++++++ src/php/wp-cli/commands/internals/core.php | 59 ++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 man/core-install_network.1 create mode 100644 src/doc/core-install_network.txt diff --git a/man/core-install_network.1 b/man/core-install_network.1 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/doc/core-install_network.txt b/src/doc/core-install_network.txt new file mode 100644 index 0000000000..d40d946483 --- /dev/null +++ b/src/doc/core-install_network.txt @@ -0,0 +1,17 @@ +wp-core-install_network(1) -- Transform a single-site install into a +multi-site install. +==== + +## SYNOPSIS + +`wp core install_network` --title=<network-title> [--base_path=/] + +## OPTIONS + +* `--title`=<site-title>: + + The title of the new network. + +* `--base_path`=<path>: + + Base path after the domain name that each site url will start with. diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 4d45d4371e..38d7fc88a7 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -90,6 +90,65 @@ public function install( $args, $assoc_args ) { } } + public function install_network( $args, $assoc_args ) { + if ( is_multisite() ) + WP_CLI::error( 'This already is a multisite install.' ); + + global $wpdb; + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + // need to register the multisite tables manually for some reason + foreach ( $wpdb->tables( 'ms_global' ) as $table => $prefixed_table ) + $wpdb->$table = $prefixed_table; + + WP_CLI::check_required_args( array( 'title' ), $assoc_args ); + + extract( wp_parse_args( $assoc_args, array( + 'base' => '/', + ) ) ); + + $hostname = self::get_clean_basedomain(); + $subdomain_install = isset( $assoc_args['subdomains'] ); + + install_network(); + + $result = populate_network( 1, $hostname, get_option( 'admin_email' ), $assoc_args['title'], $base, $subdomain_install ); + + if ( is_wp_error( $result ) ) + WP_CLI::error( $result ); + + ob_start(); +?> +define('MULTISITE', true); +define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>); +$base = '<?php echo $base; ?>'; +define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>'); +define('PATH_CURRENT_SITE', '<?php echo $base; ?>'); +define('SITE_ID_CURRENT_SITE', 1); +define('BLOG_ID_CURRENT_SITE', 1); + +<?php + $ms_config = ob_get_clean(); + + $wp_config_path = WP_CLI::locate_wp_config(); + + $token = "/* That's all, stop editing!"; + + list( $before, $after ) = explode( $token, file_get_contents( $wp_config_path ) ); + + file_put_contents( $wp_config_path, $before . $ms_config . $token . $after ); + + WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); + } + + private static function get_clean_basedomain() { + $domain = preg_replace( '|https?://|', '', get_option( 'siteurl' ) ); + if ( $slash = strpos( $domain, '/' ) ) + $domain = substr( $domain, 0, $slash ); + return $domain; + } + /** * Display the WordPress version. */ From e03b3ba8b8baf2389428296a40807ba5e96a5624 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 23:48:14 +0300 Subject: [PATCH 0490/4858] fix man page. see #139 --- man/core-install_network.1 | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/man/core-install_network.1 b/man/core-install_network.1 index e69de29bb2..09fcc2890d 100644 --- a/man/core-install_network.1 +++ b/man/core-install_network.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-INSTALL_NETWORK" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-install_network\fR \- Transform a single\-site install into a +. +.SH "SYNOPSIS" +\fBwp core install_network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=/] +. +.SH "OPTIONS" +. +.TP +\fB\-\-title\fR=\fIsite\-title\fR: +. +.IP +The title of the new network\. +. +.TP +\fB\-\-base_path\fR=\fIpath\fR: +. +.IP +Base path after the domain name that each site url will start with\. + From e92ea5210b9a05cf70616511e03748a3d9dc9e9d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Jul 2012 23:49:09 +0300 Subject: [PATCH 0491/4858] check if ronn is installed --- utils/doc-build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utils/doc-build b/utils/doc-build index 9a71c69f97..87ca6f64f5 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -11,6 +11,11 @@ else files=$@ fi +if ! which ronn; then + echo "doc-build: ronn is not installed" + exit 1 +fi + for file in $files; do man_file=man/$(basename $file .txt).1 cat $file | ronn --roff --manual="WP-CLI" > $man_file From 0e85d0514993c83f9ccea0c8aa2f8e4d6818be7b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 00:15:43 +0300 Subject: [PATCH 0492/4858] create blogs.dir. see #139 --- src/php/wp-cli/commands/internals/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 38d7fc88a7..8c8b1ceca8 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -139,6 +139,8 @@ public function install_network( $args, $assoc_args ) { file_put_contents( $wp_config_path, $before . $ms_config . $token . $after ); + wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); + WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); } From db13ea5aeafcd9c736f8bae10f0a0e040d8522b2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 19:32:45 +0300 Subject: [PATCH 0493/4858] add --porcelain flag to `wp user create` --- man/user-create.1 | 10 ++++++++-- src/doc/user-create.txt | 6 +++++- src/php/wp-cli/commands/internals/user.php | 13 ++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/man/user-create.1 b/man/user-create.1 index 9f71326f32..c96e198274 100644 --- a/man/user-create.1 +++ b/man/user-create.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-CREATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-USER\-CREATE" "1" "July 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-create\fR \- Create a new WordPress user\. . .SH "SYNOPSIS" -\fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] +\fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-porcelain] . .SH "OPTIONS" . @@ -29,6 +29,12 @@ The email address of the user to create\. .IP The role of the user to create\. . +.TP +\fB\-\-porcelain\fR: +. +.IP +Output just the new user id\. +. .SH "EXAMPLES" . .nf diff --git a/src/doc/user-create.txt b/src/doc/user-create.txt index 1173efcf43..0ed2e2214c 100644 --- a/src/doc/user-create.txt +++ b/src/doc/user-create.txt @@ -3,7 +3,7 @@ wp-user-create(1) -- Create a new WordPress user. ## SYNOPSIS -`wp user create` <user-login> <user-email> [--role=<role>] +`wp user create` <user-login> <user-email> [--role=<role>] [--porcelain] ## OPTIONS @@ -19,6 +19,10 @@ wp-user-create(1) -- Create a new WordPress user. The role of the user to create. +* `--porcelain`: + + Output just the new user id. + ## EXAMPLES wp user create bob bob@example.com --role=author diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 2c9a6238b8..2f601958e4 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -59,7 +59,7 @@ public function _list( $args, $assoc_args ) { **/ public function delete( $args, $assoc_args ) { global $blog_id; - + $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); $defaults = array( 'reassign' => NULL ); @@ -122,7 +122,10 @@ public function create( $args, $assoc_args ) { } } - WP_CLI::success( "Created user $user_id." ); + if ( isset( $assoc_args['porcelain'] ) ) + WP_CLI::line( $user_id ); + else + WP_CLI::success( "Created user $user_id." ); } /** @@ -148,7 +151,7 @@ public function update( $args, $assoc_args ) { WP_CLI::success( "Updated user $updated_id." ); } } - + private function get_numeric_arg_or_error( $args, $index, $name ) { $value = self::get_arg_or_error( $args, $index, $name ); if ( ! is_numeric( $value ) ) { @@ -156,14 +159,14 @@ private function get_numeric_arg_or_error( $args, $index, $name ) { } return $value; } - + private function get_arg_or_error( $args, $index, $name ) { if ( ! isset( $args[$index] ) ) { self::error_see_help( "$name required" ); } return $args[$index]; } - + private function error_see_help( $message ) { WP_CLI::error( "$message (see 'wp user help')."); } From b036a5fb197ae108129ffce1dd6fe19f7abe45df Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 19:32:57 +0300 Subject: [PATCH 0494/4858] silence output from which --- utils/doc-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/doc-build b/utils/doc-build index 87ca6f64f5..a4bf43d081 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -11,7 +11,7 @@ else files=$@ fi -if ! which ronn; then +if ! which ronn > /dev/null; then echo "doc-build: ronn is not installed" exit 1 fi From 5258812e3019250d9e08fbbe6e423a815a3a0721 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 19:52:15 +0300 Subject: [PATCH 0495/4858] move User_Command::get_numeric_arg_or_error() to WP_CLI::get_numeric_arg() --- src/php/wp-cli/class-wp-cli.php | 12 ++++++++++ src/php/wp-cli/commands/internals/user.php | 28 ++++------------------ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index f056846338..8b5864e3db 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -190,6 +190,18 @@ static function check_required_args( $required, $assoc_args ) { exit(1); } + static function get_numeric_arg( $args, $index, $name ) { + if ( ! isset( $args[$index] ) ) { + WP_CLI::error( "$name required" ); + } + + if ( ! is_numeric( $args[$index] ) ) { + WP_CLI::error( "$name must be numeric" ); + } + + return $args[$index]; + } + /** * Display a legend * diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 2f601958e4..e5539639ba 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -60,7 +60,7 @@ public function _list( $args, $assoc_args ) { public function delete( $args, $assoc_args ) { global $blog_id; - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $user_id = WP_CLI::get_numeric_arg( $args, 0, "User ID" ); $defaults = array( 'reassign' => NULL ); @@ -82,11 +82,10 @@ public function delete( $args, $assoc_args ) { public function create( $args, $assoc_args ) { global $blog_id; - $user_login = $args[0]; - $user_email = $args[1]; + list( $user_login, $user_email ) = $args[0]; if ( ! $user_login || ! $user_email ) { - self::error_see_help( "Login and email required" ); + WP_CLI::error( "Login and email required." ); } $defaults = array( @@ -135,7 +134,7 @@ public function create( $args, $assoc_args ) { * @param array $assoc_args **/ public function update( $args, $assoc_args ) { - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); + $user_id = WP_CLI::get_numeric_arg( $args, 0, "User ID" ); if ( empty( $assoc_args ) ) { WP_CLI::error( "Need some fields to update." ); @@ -151,23 +150,4 @@ public function update( $args, $assoc_args ) { WP_CLI::success( "Updated user $updated_id." ); } } - - private function get_numeric_arg_or_error( $args, $index, $name ) { - $value = self::get_arg_or_error( $args, $index, $name ); - if ( ! is_numeric( $value ) ) { - self::error_see_help( "$name must be numeric" ); - } - return $value; - } - - private function get_arg_or_error( $args, $index, $name ) { - if ( ! isset( $args[$index] ) ) { - self::error_see_help( "$name required" ); - } - return $args[$index]; - } - - private function error_see_help( $message ) { - WP_CLI::error( "$message (see 'wp user help')."); - } } From 5a538c7b983f8225b87744f100ccd754ac31abed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 20:26:48 +0300 Subject: [PATCH 0496/4858] add basic post commands. fixes #141 --- src/php/wp-cli/commands/internals/post.php | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/post.php diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php new file mode 100644 index 0000000000..97687b56c8 --- /dev/null +++ b/src/php/wp-cli/commands/internals/post.php @@ -0,0 +1,69 @@ +<?php + +WP_CLI::add_command( 'post', 'Post_Command' ); + +/** + * Implement post command + * + * @package wp-cli + * @subpackage commands/internals + */ +class Post_Command extends WP_CLI_Command { + + /** + * Create a post + * + * @param array $args + * @param array $assoc_args + */ + public function create( $args, $assoc_args ) { + $post_id = wp_insert_post( $assoc_args, true ); + + if ( is_wp_error( $post_id ) ) { + WP_CLI::error( $post_id ); + } + + if ( isset( $assoc_args['porcelain'] ) ) + WP_CLI::line( $post_id ); + else + WP_CLI::success( "Created post $post_id." ); + } + + /** + * Update a user + * + * @param array $args + * @param array $assoc_args + */ + public function update( $args, $assoc_args ) { + $post_id = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); + + if ( empty( $assoc_args ) ) { + WP_CLI::error( "Need some fields to update." ); + } + + $params = array_merge( $assoc_args, array( 'ID' => $post_id ) ); + + if ( wp_update_post( $params ) ) { + WP_CLI::success( "Updated post $post_id." ); + } else { + WP_CLI::error( "Failed updating post $post_id" ); + } + } + + /** + * Delete a post + * + * @param array $args + * @param array $assoc_args + */ + public function delete( $args, $assoc_args ) { + $post_id = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); + + if ( wp_delete_post( $post_id, isset( $assoc_args['force'] ) ) ) { + WP_CLI::success( "Deleted post $post_id." ); + } else { + WP_CLI::error( "Failed deleting post $post_id." ); + } + } +} From 7101df24f14887e32534bb31cd742327d083677c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 20:35:21 +0300 Subject: [PATCH 0497/4858] add docs for post commands. see #141 --- man/post-create.1 | 35 +++++++++++++++++++++++++++++++++++ man/post-delete.1 | 33 +++++++++++++++++++++++++++++++++ man/post-update.1 | 33 +++++++++++++++++++++++++++++++++ src/doc/post-create.txt | 21 +++++++++++++++++++++ src/doc/post-delete.txt | 20 ++++++++++++++++++++ src/doc/post-update.txt | 20 ++++++++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 man/post-create.1 create mode 100644 man/post-delete.1 create mode 100644 man/post-update.1 create mode 100644 src/doc/post-create.txt create mode 100644 src/doc/post-delete.txt create mode 100644 src/doc/post-update.txt diff --git a/man/post-create.1 b/man/post-create.1 new file mode 100644 index 0000000000..3ed689f819 --- /dev/null +++ b/man/post-create.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-CREATE" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-create\fR \- Create a new WordPress post\. +. +.SH "SYNOPSIS" +\fBwp post create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] [\-\-porcelain] +. +.SH "OPTIONS" +. +.TP +\fB\-\-<field>\fR=\fIvalue\fR: +. +.IP +Field values for the new post\. See wp_insert_post()\. +. +.TP +\fB\-\-porcelain\fR: +. +.IP +Output just the new post id\. +. +.SH "EXAMPLES" +. +.nf + +wp post create \-\-post_type=page \-\-post_status=publish \-\-post_title=\'A new +. +.fi +. +.P +page\' diff --git a/man/post-delete.1 b/man/post-delete.1 new file mode 100644 index 0000000000..3bfd901a93 --- /dev/null +++ b/man/post-delete.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-DELETE" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-delete\fR \- Delete a WordPress post\. +. +.SH "SYNOPSIS" +\fBwp post delete\fR \fIID\fR [\-\-force] +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the post to delete\. +. +.TP +\fB\-\-force\fR: +. +.IP +Skip the trash bin\. +. +.SH "EXAMPLES" +. +.nf + +wp post delete 123 \-\-force +. +.fi + diff --git a/man/post-update.1 b/man/post-update.1 new file mode 100644 index 0000000000..7ef6418ed2 --- /dev/null +++ b/man/post-update.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-UPDATE" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-update\fR \- Update a WordPress post\. +. +.SH "SYNOPSIS" +\fBwp post update\fR \fIID\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the post to update\. +. +.TP +\fB\-\-<field>\fR=\fIvalue\fR: +. +.IP +One or more fields to update\. See wp_update_post()\. +. +.SH "EXAMPLES" +. +.nf + +wp post update 123 \-\-post_name=something \-\-post_status=draft +. +.fi + diff --git a/src/doc/post-create.txt b/src/doc/post-create.txt new file mode 100644 index 0000000000..467f30501e --- /dev/null +++ b/src/doc/post-create.txt @@ -0,0 +1,21 @@ +wp-post-create(1) -- Create a new WordPress post. +==== + +## SYNOPSIS + +`wp post create` --<field>=<value> [--<field>=<value>...] [--porcelain] + +## OPTIONS + +* `--<field>`=<value>: + + Field values for the new post. See wp_insert_post(). + +* `--porcelain`: + + Output just the new post id. + +## EXAMPLES + + wp post create --post_type=page --post_status=publish --post_title='A new +page' diff --git a/src/doc/post-delete.txt b/src/doc/post-delete.txt new file mode 100644 index 0000000000..97c07cc74a --- /dev/null +++ b/src/doc/post-delete.txt @@ -0,0 +1,20 @@ +wp-post-delete(1) -- Delete a WordPress post. +==== + +## SYNOPSIS + +`wp post delete` <ID> [--force] + +## OPTIONS + +* `<ID>`: + + The ID of the post to delete. + +* `--force`: + + Skip the trash bin. + +## EXAMPLES + + wp post delete 123 --force diff --git a/src/doc/post-update.txt b/src/doc/post-update.txt new file mode 100644 index 0000000000..53a454859f --- /dev/null +++ b/src/doc/post-update.txt @@ -0,0 +1,20 @@ +wp-post-update(1) -- Update a WordPress post. +==== + +## SYNOPSIS + +`wp post update` <ID> --<field>=<value> [--<field>=<value>...] + +## OPTIONS + +* `<ID>`: + + The ID of the post to update. + +* `--<field>`=<value>: + + One or more fields to update. See wp_update_post(). + +## EXAMPLES + + wp post update 123 --post_name=something --post_status=draft From 35ec772f8b6c5432b77ef8f56d302f54c4be2a75 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 21:49:24 +0300 Subject: [PATCH 0498/4858] introduce WP_CLI_Command_With_Meta and implement wp post-meta with it. see #141 --- man/post-meta.1 | 54 +++++++++ src/doc/post-meta.txt | 35 ++++++ .../wp-cli/class-wp-cli-command-with-meta.php | 101 +++++++++++++++++ .../wp-cli/commands/internals/post-meta.php | 14 +++ .../wp-cli/commands/internals/user-meta.php | 107 +----------------- src/php/wp-cli/wp-cli.php | 1 + 6 files changed, 209 insertions(+), 103 deletions(-) create mode 100644 man/post-meta.1 create mode 100644 src/doc/post-meta.txt create mode 100644 src/php/wp-cli/class-wp-cli-command-with-meta.php create mode 100644 src/php/wp-cli/commands/internals/post-meta.php diff --git a/man/post-meta.1 b/man/post-meta.1 new file mode 100644 index 0000000000..65bce7c9bf --- /dev/null +++ b/man/post-meta.1 @@ -0,0 +1,54 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-META" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-meta\fR \- Manage post custom fields\. +. +.SH "SYNOPSIS" +wp post\-meta get \fIID\fR \fIkey\fR [\-\-json] +. +.P +wp post\-meta add \fIID\fR \fIkey\fR \fIvalue\fR +. +.P +wp post\-meta update \fIID\fR \fIkey\fR \fIvalue\fR +. +.P +wp post\-meta delete \fIID\fR \fIkey\fR +. +.SH "SUBCOMMANDS" +. +.TP +\fBget\fR: +. +.IP +Get a custom field value\. Passing \-\-json causes the output to be formatted as JSON\. +. +.TP +\fBadd\fR: +. +.IP +Add a new custom field\. +. +.TP +\fBupdate\fR: +. +.IP +Update an existing custom field\. +. +.TP +\fBdelete\fR: +. +.IP +Delete a custom field\. +. +.SH "EXAMPLES" +. +.nf + +wp post\-meta set 123 _wp_page_template about\.php +. +.fi + diff --git a/src/doc/post-meta.txt b/src/doc/post-meta.txt new file mode 100644 index 0000000000..55a0af3289 --- /dev/null +++ b/src/doc/post-meta.txt @@ -0,0 +1,35 @@ +wp-post-meta(1) -- Manage post custom fields. +==== + +## SYNOPSIS + +wp post-meta get <ID> <key> [--json] + +wp post-meta add <ID> <key> <value> + +wp post-meta update <ID> <key> <value> + +wp post-meta delete <ID> <key> + +## SUBCOMMANDS + +* `get`: + + Get a custom field value. Passing --json causes the output to be formatted + as JSON. + +* `add`: + + Add a new custom field. + +* `update`: + + Update an existing custom field. + +* `delete`: + + Delete a custom field. + +## EXAMPLES + + wp post-meta set 123 _wp_page_template about.php diff --git a/src/php/wp-cli/class-wp-cli-command-with-meta.php b/src/php/wp-cli/class-wp-cli-command-with-meta.php new file mode 100644 index 0000000000..62934e48b2 --- /dev/null +++ b/src/php/wp-cli/class-wp-cli-command-with-meta.php @@ -0,0 +1,101 @@ +<?php + +/** + * Base class for WP-CLI commands that deal with metadata + * + * @package wp-cli + */ +abstract class WP_CLI_Command_With_Meta extends WP_CLI_Command { + + protected $meta_type; + + protected $aliases = array( + 'set' => 'update' + ); + + /** + * Get meta field value + * + * @param array $args + * @param array $assoc_args + **/ + public function get( $args, $assoc_args ) { + $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); + $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); + + $value = get_metadata( $this->meta_type, $object_id, $meta_key, true ); + + if ( '' === $value ) + die(1); + + WP_CLI::print_value( $value, $assoc_args ); + } + + /** + * Get meta field value for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function delete( $args, $assoc_args ) { + $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); + $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); + + $success = delete_metadata( $this->meta_type, $object_id, $meta_key ); + + if ( $success ) { + WP_CLI::success( "Deleted custom field." ); + } else { + WP_CLI::error( "Failed to delete custom field." ); + } + } + + /** + * Update meta field for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function add( $args, $assoc_args ) { + $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); + $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); + $meta_value = self::get_arg_or_error( $args, 2, "meta_value" ); + + $success = add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + + if ( $success ) { + WP_CLI::success( "Added custom field." ); + } else { + WP_CLI::error( "Failed to add custom field." ); + } + } + + /** + * Update meta field for a user + * + * @param array $args + * @param array $assoc_args + **/ + public function update( $args, $assoc_args ) { + $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); + $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); + $meta_value = self::get_arg_or_error( $args, 2, "meta_value" ); + + $success = update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + + if ( $success ) { + WP_CLI::success( "Updated custom field." ); + } else { + WP_CLI::error( "Failed to update custom field." ); + } + } + + protected function get_arg_or_error( $args, $index, $name ) { + if ( ! isset( $args[$index] ) ) { + WP_CLI::error( "$name required" ); + } + + return $args[$index]; + } +} + diff --git a/src/php/wp-cli/commands/internals/post-meta.php b/src/php/wp-cli/commands/internals/post-meta.php new file mode 100644 index 0000000000..6e3b710f84 --- /dev/null +++ b/src/php/wp-cli/commands/internals/post-meta.php @@ -0,0 +1,14 @@ +<?php + +WP_CLI::add_command( 'post-meta', 'Post_Meta_Command' ); + +/** + * Implement post-meta command + * + * @package wp-cli + * @subpackage commands/internals + */ +class Post_Meta_Command extends WP_CLI_Command_With_Meta { + protected $meta_type = 'post'; +} + diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index b12a8addec..317420652a 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -1,113 +1,14 @@ <?php -WP_CLI::add_command('user-meta', 'User_Meta_Command'); +WP_CLI::add_command( 'user-meta', 'User_Meta_Command' ); /** - * Implement user command + * Implement user-meta command * * @package wp-cli * @subpackage commands/internals */ -class User_Meta_Command extends WP_CLI_Command { - - protected $aliases = array( - 'set' => 'update' - ); - - /** - * Get meta field value for a user - * - * @param array $args - * @param array $assoc_args - **/ - public function get( $args, $assoc_args ) { - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); - $meta_key = self::get_arg_or_error($args, 1, "meta_key"); - - $value = get_user_meta( $user_id, $meta_key, true ); - - if ( '' === $value ) - die(1); - - WP_CLI::print_value( $value, $assoc_args ); - } - - /** - * Get meta field value for a user - * - * @param array $args - * @param array $assoc_args - **/ - public function delete( $args, $assoc_args ) { - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); - $meta_key = self::get_arg_or_error($args, 1, "meta_key"); - - $success = delete_user_meta( $user_id, $meta_key ); - - if ( $success ) { - WP_CLI::success( "Deleted custom field." ); - } else { - WP_CLI::error( "Failed to delete custom field." ); - } - } - - /** - * Update meta field for a user - * - * @param array $args - * @param array $assoc_args - **/ - public function add( $args, $assoc_args ) { - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); - $meta_key = self::get_arg_or_error($args, 1, "meta_key"); - $meta_value = self::get_arg_or_error($args, 2, "meta_value"); - - $success = add_user_meta( $user_id, $meta_key, $meta_value ); - - if ( $success ) { - WP_CLI::success( "Added custom field." ); - } else { - WP_CLI::error( "Failed to add custom field." ); - } - } - - /** - * Update meta field for a user - * - * @param array $args - * @param array $assoc_args - **/ - public function update( $args, $assoc_args ) { - $user_id = self::get_numeric_arg_or_error($args, 0, "User ID"); - $meta_key = self::get_arg_or_error($args, 1, "meta_key"); - $meta_value = self::get_arg_or_error($args, 2, "meta_value"); - - $success = update_user_meta( $user_id, $meta_key, $meta_value ); - - if ( $success ) { - WP_CLI::success( "Updated custom field." ); - } else { - WP_CLI::error( "Failed to update custom field." ); - } - } - - private function get_numeric_arg_or_error( $args, $index, $name ) { - $value = self::get_arg_or_error( $args, $index, $name ); - if ( ! is_numeric( $value ) ) { - self::error_see_help( "$name must be numeric" ); - } - return $value; - } - - private function get_arg_or_error( $args, $index, $name ) { - if ( ! isset( $args[$index] ) ) { - self::error_see_help( "$name required" ); - } - return $args[$index]; - } - - private function error_see_help( $message ) { - WP_CLI::error( "$message (see 'wp user-meta help')."); - } +class User_Meta_Command extends WP_CLI_Command_With_Meta { + protected $meta_type = 'user'; } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 22485f1b53..5da128c23d 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -16,6 +16,7 @@ // Include the wp-cli classes include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; +include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-upgrade.php'; // Include the command line tools From 170def0ccd3167d8eb33823582e76033ff45ae5d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 23:30:36 +0300 Subject: [PATCH 0499/4858] convert error message into string. see #140 --- src/php/wp-cli/class-cli-upgrader-skin.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index 93488b8ca2..029811e88a 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -16,8 +16,13 @@ function error( $error ) { if ( !$error ) return; + if ( isset( $this->upgrader->strings[$error] ) ) + $string = $this->upgrader->strings[$error]; + else + $string = $error; + // TODO: show all errors, not just the first one - WP_CLI::warning( $error ); + WP_CLI::warning( $string ); } function feedback( $string ) { From 9c6bf7d7207a9b5cd7b0236999e64eeee1a845b7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 5 Jul 2012 23:44:51 +0300 Subject: [PATCH 0500/4858] pass plugin file not plugin name to the upgrader. fixes #140 --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index fcd3346588..ab13718dce 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -83,7 +83,7 @@ function update( $args, $assoc_args ) { if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); - WP_CLI::get_upgrader( $this->upgrader )->upgrade( $name ); + WP_CLI::get_upgrader( $this->upgrader )->upgrade( $file ); } else { $this->update_multiple( $args, $assoc_args ); } From c30a4bc5dfcf8f971f16d37b283557546e89e9b6 Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Thu, 5 Jul 2012 14:11:18 -0700 Subject: [PATCH 0501/4858] Core Update with specified `--version` from WP.org Can now update core with --version without specifying a local package. Also, `--force` added to allow downgrades. _Use With Caution_ --- man/core-update.1 | 6 ++- src/doc/core-update.txt | 7 ++- src/php/wp-cli/commands/internals/core.php | 51 +++++++++++----------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/man/core-update.1 b/man/core-update.1 index 4e8c61215d..665925fe37 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -18,10 +18,10 @@ When passed, it applies any outstanding database upgrades, without touching the files\. . .TP -\fB\-\-version=\fR\fInew_version\fR <package/zip>: +\fB\-\-version=\fR\fInew_version\fR [\-\-force] [package/zip]: . .IP -When passed, updates to new_version using package/zip as input\. +When passed, updates to new_version, optionally using package/zip as input\. Will update even when current WP version < new_version if \-\-force is specified\. Use with caution, since if you update to < 3\.0, you won\'t be able to revert using wp\-cli\. . .SH "EXAMPLES" . @@ -30,6 +30,8 @@ When passed, updates to new_version using package/zip as input\. wp core update wp core update \-\-version=3\.4 \.\./latest\.zip + +wp core update \-\-version=3\.1 \-\-force . .fi diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index 411ea0082c..23da940ee5 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -12,12 +12,15 @@ wp-core-update(1) -- Update WordPress to the latest version. When passed, it applies any outstanding database upgrades, without touching the files. -* `--version=`<new_version> <package/zip>: +* `--version=`<new_version> [--force] [package/zip]: - When passed, updates to new_version using package/zip as input. + When passed, updates to new_version, optionally using package/zip as input. + Will update even when current WP version < new_version if --force is specified. Use with caution, since if you update to < 3.0, you won't be able to revert using wp-cli. ## EXAMPLES wp core update wp core update --version=3.4 ../latest.zip + + wp core update --version=3.1 --force diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index ee96d11cc5..73ec3028d8 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -133,7 +133,8 @@ public function version( $args = array(), $assoc_args = array() ) { */ function update( $args, $assoc_args ) { global $wp_version; - $update = $from_api = $upgrader = null; + $update = $from_api = null; + $upgrader = 'Core_Upgrader'; if ( isset( $assoc_args['db'] ) ) { wp_upgrade(); @@ -150,34 +151,34 @@ function update( $args, $assoc_args ) { else list( $update ) = $from_api->updates; - $upgrader = 'Core_Upgrader'; + } else if ( version_compare( $wp_version, $assoc_args['version'], '<' ) + || isset( $assoc_args['force'] ) ) { - } else { - if ( empty( $args[0] ) ) - WP_CLI::error( "Package not specified." ); - - $new_package = $args[0]; - $new_version = $assoc_args['version']; - - if ( version_compare( $wp_version, $new_version, '<' ) ) { - $update = (object) array( - 'response' => 'upgrade', - 'current' => $new_version, - 'download' => $new_package, - 'packages' => (object) array ( - 'partial' => null, - 'new_bundled' => null, - 'no_content' => null, - 'full' => $new_package, - ), - ); - - $upgrader = 'Non_Destructive_Core_Upgrader'; + $new_package = null; + if ( empty( $args[0] ) ) { + $new_package = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; + WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { - WP_CLI::success( 'WordPress is up to date.' ); - return; + $new_package = $args[0]; + $upgrader = 'Non_Destructive_Core_Upgrader'; } + + $update = (object) array( + 'response' => 'upgrade', + 'current' => $assoc_args['version'], + 'download' => $new_package, + 'packages' => (object) array ( + 'partial' => null, + 'new_bundled' => null, + 'no_content' => null, + 'full' => $new_package, + ), + ); + + } else { + WP_CLI::success( 'WordPress is up to date.' ); + return; } require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); From 29e0407dc7f677a4d8dfc58ffea7082051428aaf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Jul 2012 01:22:53 +0300 Subject: [PATCH 0502/4858] update docs. see #136 --- man/core-update.1 | 2 +- src/doc/core-update.txt | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/man/core-update.1 b/man/core-update.1 index 665925fe37..9a667d392b 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -7,7 +7,7 @@ \fBwp\-core\-update\fR \- Update WordPress to the latest version\. . .SH "SYNOPSIS" -\fBwp core update\fR [\-\-db] [\-\-version=\fInew_version\fR <package/zip>] +\fBwp core update\fR [\-\-db] [\-\-version=\fInew_version\fR] [\-\-force] [<package/zip>] . .SH "OPTIONS" . diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index 23da940ee5..e3fb990eb1 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -3,7 +3,7 @@ wp-core-update(1) -- Update WordPress to the latest version. ## SYNOPSIS -`wp core update` [--db] [--version=<new_version> <package/zip>] +`wp core update` [--db] [--version=<new_version>] [--force] [<package/zip>] ## OPTIONS @@ -14,8 +14,11 @@ touching the files. * `--version=`<new_version> [--force] [package/zip]: - When passed, updates to new_version, optionally using package/zip as input. - Will update even when current WP version < new_version if --force is specified. Use with caution, since if you update to < 3.0, you won't be able to revert using wp-cli. + When passed, updates to new_version, optionally using package/zip as +input. + Will update even when current WP version < new_version if --force is +specified. Use with caution, since if you update to < 3.0, you won't be able +to revert using wp-cli. ## EXAMPLES From 0e551345a568c61085be6e4f298c5ecf3232f4ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Jul 2012 01:26:48 +0300 Subject: [PATCH 0503/4858] move --force to it's own section. see #136 --- man/core-update.1 | 10 ++++++++-- src/doc/core-update.txt | 10 ++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/man/core-update.1 b/man/core-update.1 index 9a667d392b..687a18154e 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -18,10 +18,16 @@ When passed, it applies any outstanding database upgrades, without touching the files\. . .TP -\fB\-\-version=\fR\fInew_version\fR [\-\-force] [package/zip]: +\fB\-\-version=\fR\fInew_version\fR [package/zip]: . .IP -When passed, updates to new_version, optionally using package/zip as input\. Will update even when current WP version < new_version if \-\-force is specified\. Use with caution, since if you update to < 3\.0, you won\'t be able to revert using wp\-cli\. +When passed, updates to new_version, optionally using package/zip as input\. +. +.TP +\fB\-\-force\fR: +. +.IP +Will update even when current WP version < passed version\. Use with caution\. . .SH "EXAMPLES" . diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index e3fb990eb1..3bccb6ce77 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -12,13 +12,15 @@ wp-core-update(1) -- Update WordPress to the latest version. When passed, it applies any outstanding database upgrades, without touching the files. -* `--version=`<new_version> [--force] [package/zip]: +* `--version=`<new_version> [package/zip]: When passed, updates to new_version, optionally using package/zip as input. - Will update even when current WP version < new_version if --force is -specified. Use with caution, since if you update to < 3.0, you won't be able -to revert using wp-cli. + +* `--force`: + + Will update even when current WP version < passed version. Use with +caution. ## EXAMPLES From f06fbae9c33661bc82a04a6ea676468c461d1463 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Jul 2012 01:32:18 +0300 Subject: [PATCH 0504/4858] move database upgrade out of wp core update again. see #121 --- man/core-update.1 | 8 +------- man/core-update_db.1 | 10 ++++++++++ src/doc/core-update.txt | 7 +------ src/doc/core-update_db.txt | 6 ++++++ src/php/wp-cli/commands/internals/core.php | 18 +++++++++++------- 5 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 man/core-update_db.1 create mode 100644 src/doc/core-update_db.txt diff --git a/man/core-update.1 b/man/core-update.1 index 687a18154e..af27373d7a 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -7,17 +7,11 @@ \fBwp\-core\-update\fR \- Update WordPress to the latest version\. . .SH "SYNOPSIS" -\fBwp core update\fR [\-\-db] [\-\-version=\fInew_version\fR] [\-\-force] [<package/zip>] +\fBwp core update\fR [\-\-version=\fInew_version\fR] [\-\-force] [<package/zip>] . .SH "OPTIONS" . .TP -\fB\-\-db\fR: -. -.IP -When passed, it applies any outstanding database upgrades, without touching the files\. -. -.TP \fB\-\-version=\fR\fInew_version\fR [package/zip]: . .IP diff --git a/man/core-update_db.1 b/man/core-update_db.1 new file mode 100644 index 0000000000..e9a570d92f --- /dev/null +++ b/man/core-update_db.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-UPDATE_DB" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-update_db\fR \- Update the WordPress database\. +. +.SH "SYNOPSIS" +\fBwp core update_db\fR diff --git a/src/doc/core-update.txt b/src/doc/core-update.txt index 3bccb6ce77..abdc56e07e 100644 --- a/src/doc/core-update.txt +++ b/src/doc/core-update.txt @@ -3,15 +3,10 @@ wp-core-update(1) -- Update WordPress to the latest version. ## SYNOPSIS -`wp core update` [--db] [--version=<new_version>] [--force] [<package/zip>] +`wp core update` [--version=<new_version>] [--force] [<package/zip>] ## OPTIONS -* `--db`: - - When passed, it applies any outstanding database upgrades, without -touching the files. - * `--version=`<new_version> [package/zip]: When passed, updates to new_version, optionally using package/zip as diff --git a/src/doc/core-update_db.txt b/src/doc/core-update_db.txt new file mode 100644 index 0000000000..7464475134 --- /dev/null +++ b/src/doc/core-update_db.txt @@ -0,0 +1,6 @@ +wp-core-update_db(1) -- Update the WordPress database. +==== + +## SYNOPSIS + +`wp core update_db` diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 5962c29e82..f7419a979e 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -197,12 +197,6 @@ function update( $args, $assoc_args ) { $update = $from_api = null; $upgrader = 'Core_Upgrader'; - if ( isset( $assoc_args['db'] ) ) { - wp_upgrade(); - WP_CLI::success( 'WordPress database upgraded successfully.' ); - return; - } - if ( empty( $assoc_args['version'] ) ) { wp_version_check(); $from_api = get_site_transient( 'update_core' ); @@ -257,5 +251,15 @@ function update( $args, $assoc_args ) { WP_CLI::success( 'WordPress updated successfully.' ); } } -} + /** + * Update the WordPress database + * + * @param array $args + * @param array $assoc_args + */ + function update_db() { + wp_upgrade(); + WP_CLI::success( 'WordPress database upgraded successfully.' ); + } +} From 49ddfb4f913a860ca7aad81271341e07388b9926 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Jul 2012 18:35:32 +0300 Subject: [PATCH 0505/4858] allow --no-delete flag to work --- src/php/wp-cli/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8b5864e3db..8dca01e32a 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -135,9 +135,9 @@ static function parse_args( $arguments ) { $assoc_args = array(); foreach ( $arguments as $arg ) { - if ( preg_match( '|^--(\w+)$|', $arg, $matches ) ) { + if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { $assoc_args[ $matches[1] ] = true; - } elseif ( preg_match( '|^--(\w+)=(.+)|', $arg, $matches ) ) { + } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { $assoc_args[ $matches[1] ] = $matches[2]; } else { $regular_args[] = $arg; From 3e4a9e39ea102112ff8440d13b8c8f5f611bb145 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 10 Jul 2012 03:20:17 +0300 Subject: [PATCH 0506/4858] handle case where plugin is not found better --- src/php/wp-cli/commands/internals/plugin.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index acf7ca5cff..1da0d2e3ac 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -192,7 +192,10 @@ protected function install_from_repo( $slug, $assoc_args ) { $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { - WP_CLI::error( $api ); + if ( null === maybe_unserialize( $api->get_error_data() ) ) + WP_CLI::error( 'Plugin not found.' ); + else + WP_CLI::error( $api ); } if ( isset( $assoc_args['version'] ) ) { From 8f24e29a9ac357cc38147307dbecf3ebda07a5ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 10 Jul 2012 16:19:24 +0300 Subject: [PATCH 0507/4858] harmonize error messages between themes and plugins --- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 1da0d2e3ac..1fa3433876 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -193,7 +193,7 @@ protected function install_from_repo( $slug, $assoc_args ) { if ( is_wp_error( $api ) ) { if ( null === maybe_unserialize( $api->get_error_data() ) ) - WP_CLI::error( 'Plugin not found.' ); + WP_CLI::error( "Can't find the plugin in the WordPress.org repository." ); else WP_CLI::error( $api ); } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 8313d8d445..be09b205f2 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -131,9 +131,12 @@ protected function install_from_repo( $slug, $assoc_args ) { $result = NULL; $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); + if ( is_wp_error( $api ) ) { - WP_CLI::error( "Can't find the theme in the WordPress.org theme repository." ); - exit(); + if ( null === maybe_unserialize( $api->get_error_data() ) ) + WP_CLI::error( "Can't find the theme in the WordPress.org repository." ); + else + WP_CLI::error( $api ); } // Check to see if we should update, rather than install. From 53f519d75bbca3e0172dffb01cdc90712cec550a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 10 Jul 2012 16:23:35 +0300 Subject: [PATCH 0508/4858] document the --activate flag for wp theme install --- man/theme-install.1 | 12 +++++++++--- src/doc/theme-install.txt | 8 ++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/man/theme-install.1 b/man/theme-install.1 index 6b15db128d..71f60fb0e5 100644 --- a/man/theme-install.1 +++ b/man/theme-install.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-INSTALL" "1" "May 2012" "" "WP-CLI" +.TH "WP\-THEME\-INSTALL" "1" "July 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-install\fR \- Install a theme from wordpress\.org or from a zip file\. . .SH "SYNOPSIS" -\fBwp theme install\fR <theme/zip> +\fBwp theme install\fR <theme/zip> [\-\-activate] . .SH "OPTIONS" . @@ -17,11 +17,17 @@ .IP A theme slug or the path to a zip file\. . +.TP +\fB\-\-activate\fR: +. +.IP +If set, the theme will be activated immediately after install\. +. .SH "EXAMPLES" . .nf -wp theme install twentytwelve +wp theme install twentytwelve \-\-activate wp theme install \.\./my\-theme\.zip . diff --git a/src/doc/theme-install.txt b/src/doc/theme-install.txt index 4f06c251b0..df18a80e1d 100644 --- a/src/doc/theme-install.txt +++ b/src/doc/theme-install.txt @@ -3,7 +3,7 @@ wp-theme-install(1) -- Install a theme from wordpress.org or from a zip file. ## SYNOPSIS -`wp theme install` <theme/zip> +`wp theme install` <theme/zip> [--activate] ## OPTIONS @@ -11,8 +11,12 @@ wp-theme-install(1) -- Install a theme from wordpress.org or from a zip file. A theme slug or the path to a zip file. +* `--activate`: + + If set, the theme will be activated immediately after install. + ## EXAMPLES - wp theme install twentytwelve + wp theme install twentytwelve --activate wp theme install ../my-theme.zip From a1475c791543fb91552a95caea3af0d77c35e357 Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Thu, 12 Jul 2012 14:18:14 -0700 Subject: [PATCH 0509/4858] Introduce `db optimize` and `db repair` --- man/db-optimize.1 | 10 ++++++++++ man/db-repair.1 | 10 ++++++++++ src/doc/db-optimize.txt | 6 ++++++ src/doc/db-repair.txt | 6 ++++++ src/php/wp-cli/commands/internals/db.php | 24 ++++++++++++++++++++++++ 5 files changed, 56 insertions(+) create mode 100644 man/db-optimize.1 create mode 100644 man/db-repair.1 create mode 100644 src/doc/db-optimize.txt create mode 100644 src/doc/db-repair.txt diff --git a/man/db-optimize.1 b/man/db-optimize.1 new file mode 100644 index 0000000000..56b099bad7 --- /dev/null +++ b/man/db-optimize.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-OPTIMIZE" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-optimize\fR \- Optimize the database specified in the wp\-config\.php file\. +. +.SH "SYNOPSIS" +\fBwp db optimize\fR diff --git a/man/db-repair.1 b/man/db-repair.1 new file mode 100644 index 0000000000..2f9089eb69 --- /dev/null +++ b/man/db-repair.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-REPAIR" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-repair\fR \- Optimize the database specified in the wp\-config\.php file\. +. +.SH "SYNOPSIS" +\fBwp db repair\fR diff --git a/src/doc/db-optimize.txt b/src/doc/db-optimize.txt new file mode 100644 index 0000000000..bd640f7f60 --- /dev/null +++ b/src/doc/db-optimize.txt @@ -0,0 +1,6 @@ +wp-db-optimize(1) -- Optimize the database specified in the wp-config.php file. +==== + +## SYNOPSIS + +`wp db optimize` diff --git a/src/doc/db-repair.txt b/src/doc/db-repair.txt new file mode 100644 index 0000000000..e882046c4f --- /dev/null +++ b/src/doc/db-repair.txt @@ -0,0 +1,6 @@ +wp-db-repair(1) -- Optimize the database specified in the wp-config.php file. +==== + +## SYNOPSIS + +`wp db repair` diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index ec5780fad5..e27a93e365 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -45,6 +45,30 @@ function drop( $args, $assoc_args ) { WP_CLI::success( "Database dropped." ); } + /** + * Optimizes the database specified in the wp-config.php file. + */ + function optimize() { + WP_CLI::launch( sprintf( + 'mysqlcheck --optimize --host=%s --user=%s --password=%s %s', + DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + ) ); + + WP_CLI::success( "Database optimized." ); + } + + /** + * Repairs the database specified in the wp-config.php file. + */ + function repair() { + WP_CLI::launch( sprintf( + 'mysqlcheck --repair --host=%s --user=%s --password=%s %s', + DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + ) ); + + WP_CLI::success( "Database repaired." ); + } + /** * Print a string for connecting to the DB. */ From c0e3a240202373064944d905350a89f71ba285cd Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Thu, 12 Jul 2012 14:43:01 -0700 Subject: [PATCH 0510/4858] Correct `wp db drop` docs to properly reference `--yes` --- man/db-drop.1 | 19 +++++++++++++++++++ src/doc/db-drop.txt | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/man/db-drop.1 b/man/db-drop.1 index e69de29bb2..f5c8f3b768 100644 --- a/man/db-drop.1 +++ b/man/db-drop.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-DROP" "1" "July 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-drop\fR \- Drop the database specified in wp\-config\.php +. +.SH "SYNOPSIS" +\fBwp db drop\fR [\-\-yes] +. +.SH "OPTIONS" +. +.TP +\fB\-\-yes\fR: +. +.IP +Answer yes to the confirmation message\. + diff --git a/src/doc/db-drop.txt b/src/doc/db-drop.txt index 15a1bbd8f7..76f4266ca7 100644 --- a/src/doc/db-drop.txt +++ b/src/doc/db-drop.txt @@ -3,7 +3,7 @@ wp-db-drop(1) -- Drop the database specified in wp-config.php ## SYNOPSIS -`wp db drop` [--really] +`wp db drop` [--yes] ## OPTIONS From fe2be3169b315fd0ffd5e65949aa29713f7329d9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 18 Jul 2012 14:17:47 +0300 Subject: [PATCH 0511/4858] make wp generate posts faster --- src/php/wp-cli/commands/internals/generate.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index c72f820dfb..a1cea714fe 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -52,14 +52,13 @@ public function posts( $args, $assoc_args ) { $notify = new \cli\progress\Bar( 'Generating posts', $count ); - $post_ids = array(); $current_depth = 1; $current_parent = 0; for ( $i = $total; $i < $limit; $i++ ) { - if( $hierarchical ) { - + if ( $hierarchical ) { + if( $this->maybe_make_child() && $current_depth < $max_depth ) { $current_parent = $post_ids[$i-1]; @@ -73,13 +72,17 @@ public function posts( $args, $assoc_args ) { } } - $post_ids[$i] = wp_insert_post( array( + $args = array( 'post_type' => $type, 'post_title' => "$label $i", 'post_status' => $status, 'post_author' => $author, - 'post_parent' => $current_parent - ) ); + 'post_parent' => $current_parent, + 'post_name' => "post-$i" + ); + + // Not using wp_insert_post() because it's slow + $wpdb->insert( $wpdb->posts, $args ); $notify->tick(); } From 0723df10f0cdb9984cb455dd464b1e6b5d03d8ac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 21 Jul 2012 14:35:15 +0300 Subject: [PATCH 0512/4858] pipe curl directly to tar, avoiding temporary files. fixes #144 --- src/php/wp-cli/commands/internals/core.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index f7419a979e..5ba7ff1b79 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -25,20 +25,18 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['locale'] ) ) { exec( 'curl -s ' . escapeshellarg( 'http://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); if ($r) exit($r); - $download_url = $lines[2]; + $download_url = str_replace( '.zip', '.tar.gz', $lines[2] ); WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $lines[3], $lines[4] ) ); } elseif ( isset( $assoc_args['version'] ) ) { - $download_url = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; + $download_url = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { - $download_url = 'http://wordpress.org/latest.zip'; + $download_url = 'http://wordpress.org/latest.tar.gz'; WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - WP_CLI::launch( 'curl -f' . (WP_CLI_SILENT ? ' --silent ' : ' ') . escapeshellarg( $download_url ) . ' > /tmp/wordpress.zip' ); - WP_CLI::launch( 'unzip ' . (WP_CLI_SILENT ? '-qq ' : '-q ') . '/tmp/wordpress.zip' ); - WP_CLI::launch( 'mv wordpress/* ' . escapeshellarg( $docroot ) ); - WP_CLI::launch( 'rm -r wordpress' ); + WP_CLI::launch( 'curl -f' . (WP_CLI_SILENT ? ' --silent ' : ' ') . escapeshellarg( $download_url ) . ' | tar xz' ); + WP_CLI::launch( 'mv wordpress/* . && rm -rf wordpress' ); WP_CLI::success( 'WordPress downloaded.' ); } From b4b73bcb14bd457a79590f2ef916ed2a7fd61cb2 Mon Sep 17 00:00:00 2001 From: joshstoik1 <joshstoik@gmail.com> Date: Sun, 22 Jul 2012 09:57:09 -0700 Subject: [PATCH 0513/4858] fixed missing requirement (wp-admin/includes/upgrade.php contains wp_upgrade() function), Core_Command->update_db() --- src/php/wp-cli/commands/internals/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 5ba7ff1b79..29843bb56a 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -257,6 +257,7 @@ function update( $args, $assoc_args ) { * @param array $assoc_args */ function update_db() { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); wp_upgrade(); WP_CLI::success( 'WordPress database upgraded successfully.' ); } From 1d356a81fce98db53186235f45e72c608197d6d9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 23 Jul 2012 02:33:25 +0300 Subject: [PATCH 0514/4858] accept closures as command implementations. fixes #146 --- src/php/wp-cli/class-wp-cli.php | 9 ++-- .../wp-cli/commands/internals/eval-file.php | 40 +++++----------- src/php/wp-cli/commands/internals/eval.php | 30 +++--------- src/php/wp-cli/commands/internals/home.php | 48 +++++++------------ 4 files changed, 41 insertions(+), 86 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8dca01e32a..db84240634 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -346,11 +346,14 @@ static function run_command( $arguments, $assoc_args ) { $command = $aliases[ $command ]; } - $class = self::load_command( $command ); - define( 'WP_CLI_COMMAND', $command ); - $instance = new $class( $arguments, $assoc_args ); + $implementation = self::load_command( $command ); + + if ( is_string( $implementation ) && class_exists( $implementation ) ) + $instance = new $implementation( $arguments, $assoc_args ); + else + call_user_func( $implementation, $arguments, $assoc_args ); } static function load_command( $command ) { diff --git a/src/php/wp-cli/commands/internals/eval-file.php b/src/php/wp-cli/commands/internals/eval-file.php index 006f5dc00b..044ff7fac2 100644 --- a/src/php/wp-cli/commands/internals/eval-file.php +++ b/src/php/wp-cli/commands/internals/eval-file.php @@ -1,33 +1,17 @@ <?php -WP_CLI::add_command('eval-file', 'Eval_File_Command'); - -/** - * Implement eval-file command - * - * @package wp-cli - * @subpackage commands/internals - */ -class Eval_File_Command extends WP_CLI_Command { - - /** - * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args - * @param array $assoc_args - */ - public function __construct( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp eval-file <path>" ); - exit; - } +WP_CLI::add_command( 'eval-file', function( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp eval-file <path>" ); + exit; + } - foreach ( $args as $file ) { - if ( !file_exists( $file ) ) { - WP_CLI::error( "'$file' does not exist." ); - } else { - include( $file ); - } + foreach ( $args as $file ) { + if ( !file_exists( $file ) ) { + WP_CLI::error( "'$file' does not exist." ); + } else { + include( $file ); } } -} +} ); + diff --git a/src/php/wp-cli/commands/internals/eval.php b/src/php/wp-cli/commands/internals/eval.php index 0915224bcb..373cedfe28 100644 --- a/src/php/wp-cli/commands/internals/eval.php +++ b/src/php/wp-cli/commands/internals/eval.php @@ -1,27 +1,11 @@ <?php -WP_CLI::add_command('eval', 'Eval_Command'); - -/** - * Implement eval command - * - * @package wp-cli - * @subpackage commands/internals - */ -class Eval_Command extends WP_CLI_Command { +WP_CLI::add_command( 'eval', function( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( "usage: wp eval '<php-code>'" ); + exit; + } - /** - * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args - * @param array $assoc_args - */ - public function __construct( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp eval <php-code>" ); - exit; - } + eval( $args[0] ); +} ); - eval( $args[0] ); - } -} diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index ce8efce9fa..75b006fa8f 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -1,37 +1,21 @@ <?php -WP_CLI::add_command('home', 'Home_Command'); +WP_CLI::add_command( 'home', function() { + // The url for the wp-cli repository + $repository_url = 'http://github.com/wp-cli/wp-cli'; -/** - * Implement home command - * - * @package wp-cli - * @subpackage commands/internals - */ -class Home_Command extends WP_CLI_Command { - - /** - * Overwrite the constructor to have a command without sub-commands. - * - * @param array $args - * @param array $assoc_args - */ - public function __construct( $args, $assoc_args ) { - // The url for the wp-cli repository - $repository_url = 'http://github.com/wp-cli/wp-cli'; + // Open the wp-cli page in the browser + if ( exec( 'which x-www-browser' ) ) { + system( 'x-www-browser '.$repository_url ); + } + elseif ( exec( 'which open' ) ) { + system( 'open '.$repository_url ); + } + else { + WP_CLI::error( 'No command found to open the homepage in the browser. Please open it manually: '.$repository_url ); + return; + } - // Open the wp-cli page in the browser - if(exec('which x-www-browser')) { - system('x-www-browser '.$repository_url); - } - elseif(exec('which open')) { - system('open '.$repository_url); - } - else { - WP_CLI::error('No command found to open the homepage in the browser. Please open it manually: '.$repository_url); - return; - } + WP_CLI::success( 'The wp-cli homepage should be opening in your browser.' ); +} ); - WP_CLI::success('The wp-cli homepage should be opening in your browser.'); - } -} From cb300c73addfa2452b33469cc320b89f6b6954c4 Mon Sep 17 00:00:00 2001 From: Andreas Creten <andreas@madewithlove.be> Date: Fri, 3 Aug 2012 08:43:31 +0200 Subject: [PATCH 0515/4858] Support for new MAMP version --- src/bin/wp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wp b/src/bin/wp index f4e9ec769f..aaf8d1d6e4 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -67,7 +67,7 @@ else fi # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php5*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + for amp_php in /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do if [ -x $amp_php ]; then php=$amp_php break From 3e44f9221bf23f3728a8ee2b672a2b2104c36a55 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 Aug 2012 16:53:59 +0300 Subject: [PATCH 0516/4858] properly escape db parameters. fixes #151 --- src/php/wp-cli/commands/internals/db.php | 33 +++++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index e27a93e365..0707f1fd3f 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -18,8 +18,8 @@ class DB_Command extends WP_CLI_Command { * Creates the database specified in the wp-config.php file. */ function create() { - WP_CLI::launch( sprintf( - 'mysql --host="%s" --user="%s" --password="%s" --execute="CREATE DATABASE %s"', + WP_CLI::launch( self::create_cmd( + 'mysql --host=%s --user=%s --password=%s --execute=CREATE DATABASE %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); } @@ -37,8 +37,8 @@ function drop( $args, $assoc_args ) { return; } - WP_CLI::launch( sprintf( - 'mysql --host="%s" --user="%s" --password="%s" --execute="DROP DATABASE %s"', + WP_CLI::launch( self::create_cmd( + 'mysql --host=%s --user=%s --password=%s --execute=DROP DATABASE %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -49,7 +49,7 @@ function drop( $args, $assoc_args ) { * Optimizes the database specified in the wp-config.php file. */ function optimize() { - WP_CLI::launch( sprintf( + WP_CLI::launch( self::create_cmd( 'mysqlcheck --optimize --host=%s --user=%s --password=%s %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -61,7 +61,7 @@ function optimize() { * Repairs the database specified in the wp-config.php file. */ function repair() { - WP_CLI::launch( sprintf( + WP_CLI::launch( self::create_cmd( 'mysqlcheck --repair --host=%s --user=%s --password=%s %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -94,7 +94,7 @@ function query( $args, $assoc_args ) { $query = $args[0]; - $command = $this->connect_string() . sprintf( ' --execute="%s"', $query ); + $command = $this->connect_string() . self::create_cmd( ' --execute=%s', $query ); WP_CLI::launch( $command ); } @@ -105,7 +105,7 @@ function query( $args, $assoc_args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $command = sprintf( 'mysqldump "%s" --user="%s" --password="%s" --host="%s" --result-file "%s"', + $command = self::create_cmd( 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); WP_CLI::launch( $command ); @@ -119,7 +119,8 @@ function export( $args, $assoc_args ) { function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $command = sprintf( 'mysql "%s" --user="%s" --password="%s" --host="%s" < "%s"', + $command = self::create_cmd( + 'mysql %s --user=%s --password=%s --host=%s < %s', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); WP_CLI::launch( $command ); @@ -131,7 +132,7 @@ function import( $args, $assoc_args ) { * Return a string for connecting to the DB. */ private function connect_string() { - return sprintf( 'mysql --host="%s" --user="%s" --password="%s" --database="%s"', + return self::create_cmd( 'mysql --host=%s --user=%s --password=%s --database=%s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); } @@ -141,4 +142,16 @@ private function get_file_name( $args ) { return $args[0]; } + + /** + * Given a formatted string and an arbitrary number of arguments, + * returns the final command, with the parameters escaped + */ + private static function create_cmd( $cmd ) { + $args = func_get_args(); + + $cmd = array_shift( $args ); + + return vsprintf( $cmd, array_map( 'escapeshellarg', $args ) ); + } } From 0de3fc551d784e4b75ed5c1f2820f642514f11a8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 21 Aug 2012 12:00:58 +0300 Subject: [PATCH 0517/4858] fix db create and db drop. see #151 --- src/php/wp-cli/commands/internals/db.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 0707f1fd3f..939e86265d 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -19,8 +19,8 @@ class DB_Command extends WP_CLI_Command { */ function create() { WP_CLI::launch( self::create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=CREATE DATABASE %s', - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + 'mysql --host=%s --user=%s --password=%s --execute=%s', + DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME ) ); } @@ -38,8 +38,8 @@ function drop( $args, $assoc_args ) { } WP_CLI::launch( self::create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=DROP DATABASE %s', - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + 'mysql --host=%s --user=%s --password=%s --execute=%s', + DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE ' . DB_NAME ) ); WP_CLI::success( "Database dropped." ); From 1fb105d1c03b540e03682209e2614d8ef8fccf4e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 21 Aug 2012 12:03:54 +0300 Subject: [PATCH 0518/4858] add success message to db create --- src/php/wp-cli/commands/internals/db.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 939e86265d..23ab4e0d37 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -22,6 +22,8 @@ function create() { 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME ) ); + + WP_CLI::success( "Database created." ); } /** From 88817176740c8536ec6be3077a7f4e6be8b45e46 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 22 Aug 2012 00:34:11 +0300 Subject: [PATCH 0519/4858] fix user create --- src/php/wp-cli/commands/internals/user.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index e5539639ba..c6fd1350f1 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -82,12 +82,12 @@ public function delete( $args, $assoc_args ) { public function create( $args, $assoc_args ) { global $blog_id; - list( $user_login, $user_email ) = $args[0]; - - if ( ! $user_login || ! $user_email ) { + if ( count( $args ) < 2 ) { WP_CLI::error( "Login and email required." ); } + list( $user_login, $user_email ) = $args; + $defaults = array( 'role' => get_option('default_role'), 'user_pass' => wp_generate_password(), From 0fde04b43ac18ed6ce75164ec2eb8f6ea28bb155 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 22 Aug 2012 15:58:56 +0300 Subject: [PATCH 0520/4858] make db drop work without having wp installed --- src/php/wp-cli/wp-cli.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 5da128c23d..3926bfae82 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -77,6 +77,12 @@ exit; } +if ( array( 'db', 'drop' ) == $arguments ) { + WP_CLI::load_wp_config(); + WP_CLI::run_command( $arguments, $assoc_args ); + exit; +} + if ( array( 'db', 'import' ) == array_slice( $arguments, 0, 2 ) ) { WP_CLI::load_wp_config(); WP_CLI::run_command( $arguments, $assoc_args ); From 9b1b39a977da8eb4d8e90a4eba856ab1fea19f0e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 23 Aug 2012 14:30:50 +0300 Subject: [PATCH 0521/4858] add --quiet to the help text --- src/php/wp-cli/class-wp-cli.php | 8 ++++---- src/php/wp-cli/commands/internals/core.php | 6 +++--- src/php/wp-cli/commands/internals/help.php | 1 + src/php/wp-cli/wp-cli.php | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index db84240634..7a1b2d4e48 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -25,7 +25,7 @@ public function add_command( $name, $class ) { * @param string $message */ static function out( $message ) { - if ( WP_CLI_SILENT ) return; + if ( WP_CLI_QUIET ) return; \cli\out($message); } @@ -35,7 +35,7 @@ static function out( $message ) { * @param string $message */ static function line( $message = '' ) { - if ( WP_CLI_SILENT ) return; + if ( WP_CLI_QUIET ) return; \cli\line($message); } @@ -60,7 +60,7 @@ static function error( $message, $label = 'Error' ) { * @param string $label */ static function success( $message, $label = 'Success' ) { - if ( WP_CLI_SILENT ) return; + if ( WP_CLI_QUIET ) return; \cli\line( '%G' . $label . ': %n' . $message ); } @@ -71,7 +71,7 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { - if ( WP_CLI_SILENT ) return; + if ( WP_CLI_QUIET ) return; \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 29843bb56a..41ad7a18ac 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -35,7 +35,7 @@ public function download( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - WP_CLI::launch( 'curl -f' . (WP_CLI_SILENT ? ' --silent ' : ' ') . escapeshellarg( $download_url ) . ' | tar xz' ); + WP_CLI::launch( 'curl -f' . (WP_CLI_QUIET ? ' --silent ' : ' ') . escapeshellarg( $download_url ) . ' | tar xz' ); WP_CLI::launch( 'mv wordpress/* . && rm -rf wordpress' ); WP_CLI::success( 'WordPress downloaded.' ); @@ -55,9 +55,9 @@ public function config( $args, $assoc_args ) { $_GET['step'] = 2; - if ( WP_CLI_SILENT ) ob_start(); + if ( WP_CLI_QUIET ) ob_start(); require WP_ROOT . '/wp-admin/setup-config.php'; - if ( WP_CLI_SILENT ) ob_end_clean(); + if ( WP_CLI_QUIET ) ob_end_clean(); } /** diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 8ca0538e26..8ff24eb3eb 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -66,6 +66,7 @@ private function general_help() { --url=<url> set the current URL --path=<path> set the current path to the WP install --require=<path> load a certain file before running the command + --quiet suppress informational messages --version print wp-cli version EOB ); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3926bfae82..3002a44353 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -30,7 +30,7 @@ // Set output levels define( 'WP_CLI_AUTOCOMPLETE', isset( $assoc_args['completions'] ) ); -define( 'WP_CLI_SILENT', isset( $assoc_args['silent'] ) ); +define( 'WP_CLI_QUIET', isset( $assoc_args['quiet'] ) || isset( $assoc_args['silent'] ) ); // Handle --version parameter if ( isset( $assoc_args['version'] ) && empty( $arguments ) ) { From 6775cd7d12de4a7c213a183ed6264e6f24996fb5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 23 Aug 2012 23:26:52 +0300 Subject: [PATCH 0522/4858] introduce db reset --- man/db-reset.1 | 19 +++++++++++++++++ src/doc/db-reset.txt | 12 +++++++++++ src/php/wp-cli/commands/internals/db.php | 26 ++++++++++++++++++++++++ src/php/wp-cli/wp-cli.php | 15 ++------------ 4 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 man/db-reset.1 create mode 100644 src/doc/db-reset.txt diff --git a/man/db-reset.1 b/man/db-reset.1 new file mode 100644 index 0000000000..4f40b8300c --- /dev/null +++ b/man/db-reset.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB\-RESET" "1" "August 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\-reset\fR \- Remove all data from the database specified in wp\-config\.php +. +.SH "SYNOPSIS" +\fBwp db reset\fR [\-\-yes] +. +.SH "OPTIONS" +. +.TP +\fB\-\-yes\fR: +. +.IP +Answer yes to the confirmation message\. + diff --git a/src/doc/db-reset.txt b/src/doc/db-reset.txt new file mode 100644 index 0000000000..8ba5a5ed50 --- /dev/null +++ b/src/doc/db-reset.txt @@ -0,0 +1,12 @@ +wp-db-reset(1) -- Remove all data from the database specified in wp-config.php +==== + +## SYNOPSIS + +`wp db reset` [--yes] + +## OPTIONS + +* `--yes`: + + Answer yes to the confirmation message. diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 23ab4e0d37..f382651d33 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -47,6 +47,32 @@ function drop( $args, $assoc_args ) { WP_CLI::success( "Database dropped." ); } + /** + * Removes all tables from the database. + */ + function reset( $args, $assoc_args ) { + if ( !isset( $assoc_args['yes'] ) ) { + WP_CLI::out( "Are you sure you want to reset the database? [y/n] " ); + + $answer = trim( fgets( STDIN ) ); + + if ( 'y' != $answer ) + return; + } + + WP_CLI::launch( self::create_cmd( + 'mysql --host=%s --user=%s --password=%s --execute=%s', + DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE IF EXISTS ' . DB_NAME + ) ); + + WP_CLI::launch( self::create_cmd( + 'mysql --host=%s --user=%s --password=%s --execute=%s', + DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME + ) ); + + WP_CLI::success( "Database reset." ); + } + /** * Optimizes the database specified in the wp-config.php file. */ diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3002a44353..834e3b698f 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -71,19 +71,8 @@ exit; } -if ( array( 'db', 'create' ) == $arguments ) { - WP_CLI::load_wp_config(); - WP_CLI::run_command( $arguments, $assoc_args ); - exit; -} - -if ( array( 'db', 'drop' ) == $arguments ) { - WP_CLI::load_wp_config(); - WP_CLI::run_command( $arguments, $assoc_args ); - exit; -} - -if ( array( 'db', 'import' ) == array_slice( $arguments, 0, 2 ) ) { +// The db commands don't need any WP files +if ( array( 'db' ) == array_slice( $arguments, 0, 1 ) ) { WP_CLI::load_wp_config(); WP_CLI::run_command( $arguments, $assoc_args ); exit; From a3fc9ea98c47f05d32471e034180eb72eb024bd2 Mon Sep 17 00:00:00 2001 From: Roel van der Ven <roel@soundcloud.com> Date: Sat, 25 Aug 2012 13:52:14 +0200 Subject: [PATCH 0523/4858] fix notice wording for total-cache flush --- src/php/wp-cli/commands/community/total-cache.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index bc623bc4ec..df18a647ab 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -29,17 +29,17 @@ function flush( $args = array(), $vars = array() ) { case 'db': case 'database': if ( w3tc_dbcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); + WP_CLI::success( 'The database cache is flushed successfully.' ); } else { - WP_CLI::error( 'Flushing the object cache failed.' ); + WP_CLI::error( 'Flushing the database cache failed.' ); } break; case 'minify': if ( w3tc_minify_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); + WP_CLI::success( 'The minify cache is flushed successfully.' ); } else { - WP_CLI::error( 'Flushing the object cache failed.' ); + WP_CLI::error( 'Flushing the minify cache failed.' ); } break; From 9e9a81eee2dff3df20f6d962868857115936822b Mon Sep 17 00:00:00 2001 From: Roel van der Ven <roel@soundcloud.com> Date: Sat, 25 Aug 2012 13:54:24 +0200 Subject: [PATCH 0524/4858] add seperate handle for flushing whole page cache --- src/php/wp-cli/commands/community/total-cache.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index df18a647ab..ed3d1af0e3 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -51,6 +51,14 @@ function flush( $args = array(), $vars = array() ) { } break; + case 'page': + if ( w3tc_pgcache_flush() ) { + WP_CLI::success( 'The page cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the page cache failed.' ); + } + break; + case 'post': default: if ( isset($vars['post_id']) ) { @@ -70,12 +78,6 @@ function flush( $args = array(), $vars = array() ) { } else { WP_CLI::error('There is no post with this permalink.'); } - } else { - if ( isset( $flushed_page_cache ) && $flushed_page_cache ) - break; - - $flushed_page_cache = true; - w3tc_pgcache_flush(); } } } while ( !empty( $args ) ); From f8fe0813be807a934adbc4a1cf2f58c391f60c8f Mon Sep 17 00:00:00 2001 From: Roel van der Ven <roel@soundcloud.com> Date: Sat, 25 Aug 2012 14:06:07 +0200 Subject: [PATCH 0525/4858] add notices for post / permalink flushes --- src/php/wp-cli/commands/community/total-cache.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index ed3d1af0e3..982bd80c24 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -63,18 +63,24 @@ function flush( $args = array(), $vars = array() ) { default: if ( isset($vars['post_id']) ) { if ( is_numeric( $vars['post_id'] ) ) { - w3tc_pgcache_flush_post( $vars['post_id'] ); + if ( w3tc_pgcache_flush_post( $vars['post_id'] ) ) { + WP_CLI::success( 'Post '.$vars['post_id'].' is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing '.$vars['post_id'].' from cache failed.' ); + } } else { WP_CLI::error('This is not a valid post id.'); } - - w3tc_pgcache_flush_post( $vars['post_id'] ); } elseif ( isset( $vars['permalink'] ) ) { $id = url_to_postid( $vars['permalink'] ); if ( is_numeric( $id ) ) { - w3tc_pgcache_flush_post( $id ); + if ( w3tc_pgcache_flush_post( $id ) ) { + WP_CLI::success( $id.' is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing '.$id.' from cache failed.' ); + } } else { WP_CLI::error('There is no post with this permalink.'); } From c1fbd93add53cbacd5af1e61f0f487476c0a849f Mon Sep 17 00:00:00 2001 From: Roel van der Ven <roel@soundcloud.com> Date: Sat, 25 Aug 2012 14:12:43 +0200 Subject: [PATCH 0526/4858] fail better on trying to flush a non-existent permalink --- src/php/wp-cli/commands/community/total-cache.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index 982bd80c24..ca0259ee0d 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -75,9 +75,9 @@ function flush( $args = array(), $vars = array() ) { elseif ( isset( $vars['permalink'] ) ) { $id = url_to_postid( $vars['permalink'] ); - if ( is_numeric( $id ) ) { + if ( is_numeric( $id ) && $id > 0 ) { if ( w3tc_pgcache_flush_post( $id ) ) { - WP_CLI::success( $id.' is flushed successfully.' ); + WP_CLI::success( $id.' is flushed successfully.' ); } else { WP_CLI::error( 'Flushing '.$id.' from cache failed.' ); } From afdfb50bc97e0c4d39f189fd2b2cc8ea15b041b6 Mon Sep 17 00:00:00 2001 From: Roel van der Ven <roel@soundcloud.com> Date: Sat, 25 Aug 2012 14:15:35 +0200 Subject: [PATCH 0527/4858] check if post id actually exists before flushing it from cache --- src/php/wp-cli/commands/community/total-cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index ca0259ee0d..d63ae75b53 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -62,7 +62,7 @@ function flush( $args = array(), $vars = array() ) { case 'post': default: if ( isset($vars['post_id']) ) { - if ( is_numeric( $vars['post_id'] ) ) { + if ( is_numeric( $vars['post_id'] ) && get_post( $vars['post_id'] ) ) { if ( w3tc_pgcache_flush_post( $vars['post_id'] ) ) { WP_CLI::success( 'Post '.$vars['post_id'].' is flushed successfully.' ); } else { From 1e8c2c102c5529b7dad98145cbbb1d214b0b194b Mon Sep 17 00:00:00 2001 From: Roel van der Ven <roel@soundcloud.com> Date: Sat, 25 Aug 2012 14:54:36 +0200 Subject: [PATCH 0528/4858] add page handle to command explanation --- src/php/wp-cli/commands/community/total-cache.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index d63ae75b53..8e1a35a4c7 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -97,15 +97,16 @@ function flush( $args = array(), $vars = array() ) { */ public static function help() { WP_CLI::line( <<<EOB -usage: wp total-cache flush [post|database|minify|object] [--post_id=<post-id>] [--permalink=<post-permalink>] +usage: wp total-cache flush [post|database|minify|object|page] [--post_id=<post-id>] [--permalink=<post-permalink>] Available sub-commands: - flush flushes whole cache + flush --post_id=<id> flush specific ID --permalink=<post-permalink> flush specific permalink database flushes database cache object flush object cache minify flush minify cache + page flush page cache EOB ); } From 124f233436633058bb657fc9486e7dd4f0f44b0a Mon Sep 17 00:00:00 2001 From: Marco Ceppi <marco@ceppi.net> Date: Mon, 27 Aug 2012 16:06:08 -0400 Subject: [PATCH 0529/4858] Added HTTPS to all URLS which access WP for information. --- src/php/wp-cli/commands/internals/core.php | 8 ++++---- src/php/wp-cli/commands/internals/home.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 41ad7a18ac..2da3efe8a1 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -23,15 +23,15 @@ public function download( $args, $assoc_args ) { $docroot = './'; if ( isset( $assoc_args['locale'] ) ) { - exec( 'curl -s ' . escapeshellarg( 'http://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); + exec( 'curl -s ' . escapeshellarg( 'https://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); if ($r) exit($r); $download_url = str_replace( '.zip', '.tar.gz', $lines[2] ); WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $lines[3], $lines[4] ) ); } elseif ( isset( $assoc_args['version'] ) ) { - $download_url = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; + $download_url = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { - $download_url = 'http://wordpress.org/latest.tar.gz'; + $download_url = 'https://wordpress.org/latest.tar.gz'; WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } @@ -210,7 +210,7 @@ function update( $args, $assoc_args ) { $new_package = null; if ( empty( $args[0] ) ) { - $new_package = 'http://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; + $new_package = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { $new_package = $args[0]; diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index 75b006fa8f..c2efd8623b 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -2,7 +2,7 @@ WP_CLI::add_command( 'home', function() { // The url for the wp-cli repository - $repository_url = 'http://github.com/wp-cli/wp-cli'; + $repository_url = 'https://github.com/wp-cli/wp-cli'; // Open the wp-cli page in the browser if ( exec( 'which x-www-browser' ) ) { From 445c4360a19fc8401d238f5f738557dcb42563cb Mon Sep 17 00:00:00 2001 From: tollmanz <tollmanz@gmail.com> Date: Mon, 3 Sep 2012 22:11:04 -0700 Subject: [PATCH 0530/4858] Added commands for the WordPress object cache. This commit adds commands for interacting with the WordPress object cache. For each public function in for the WordPress object cache, a corresponding command has been created. Additionally, a "which" command has been written that attempts to determine which 3rd party object cache the current installation is implementing. --- src/php/wp-cli/commands/internals/cache.php | 361 ++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/cache.php diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php new file mode 100644 index 0000000000..8a7141b13f --- /dev/null +++ b/src/php/wp-cli/commands/internals/cache.php @@ -0,0 +1,361 @@ +<?php + +WP_CLI::add_command( 'cache', 'Cache_Command' ); + +/** + * Implement cache command + * + * @package wp-cli + * @subpackage commands/internals + */ +class Cache_Command extends WP_CLI_Command { + + /** + * Add a value to the object cache. + * + * @uses wp_cache_add + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function add( $args, $assoc_args ) { + if ( count( $assoc_args ) + count( $args ) < 2 ) { + WP_CLI::line( 'usage: wp cache add <key> <value> [group] [expiration]' ); + exit; + } + + list( $key, $value ) = $args; + + $group = ( isset( $args[2] ) ) ? $args[2] : ''; + + $expiration = ( isset( $args[3] ) ) ? $args[3] : 0; + + if ( ! wp_cache_add( $key, $value, $group, $expiration ) ) { + WP_CLI::error( "Could not add object '$key' in group '$group'. Does it already exist?" ); + exit; + } + + WP_CLI::success( "Added object '$key' in group '$group'." ); + } + + /** + * Add global cache groups. + * + * @uses wp_cache_add_global_groups + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function add_global_groups( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache add_global_groups <group>' ); + exit; + } + + $group = $args[0]; + + wp_cache_add_global_groups( $group ); + } + + /** + * Adds a non-persistent group to the list. + * + * @uses wp_cache_add_non_persistent_groups + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function add_non_persistent_groups( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache add_non_persistent_groups <group>' ); + exit; + } + + $group = $args[0]; + + wp_cache_add_non_persistent_groups( $group ); + } + + /** + * Decrement a value in the object cache. + * + * @uses wp_cache_decr + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function decr( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache decr <key> [offset] [group]' ); + exit; + } + + $key = $args[0]; + + $offset = ( isset( $args[1] ) ) ? $args[1] : 1; + + $group = ( isset( $args[2] ) ) ? $args[2] : ''; + + $value = wp_cache_decr( $key, $offset, $group ); + + if ( false === $value ) { + WP_CLI::error( 'The value was not decremented.' ); + exit; + } + + WP_CLI::print_value( $value, $assoc_args ); + } + + /** + * Remove a value from the object cache. + * + * @uses wp_cache_delete + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function delete( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache delete <key> [group]' ); + exit; + } + + $key = $args[0]; + + $group = ( isset( $args[1] ) ) ? $args[1] : ''; + + $result = wp_cache_delete( $key, $group ); + + if ( false === $result ) { + WP_CLI::error( 'The object was not deleted.' ); + exit; + } + + WP_CLI::success( 'Object deleted.' ); + } + + /** + * Flush the object cache. + * + * @uses wp_cache_flush + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function flush( $args, $assoc_args ) { + $value = wp_cache_flush(); + + if ( false === $value ) { + WP_CLI::error( 'The object cache could not be flushed.' ); + exit; + } + + WP_CLI::success( 'The cache was flushed.' ); + } + + /** + * Get a value from the object cache. + * + * @uses wp_cache_get + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function get( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache get <key> [group]' ); + exit; + } + + $key = $args[0]; + + $group = ( isset( $args[1] ) ) ? $args[1] : ''; + + $value = wp_cache_get( $key, $group ); + + if ( false === $value ) { + WP_CLI::error( "Object with key '$key' and group '$group' not found." ); + exit; + } + + WP_CLI::print_value( $value, $assoc_args ); + } + + /** + * Increment a value in the object cache. + * + * @uses wp_cache_incr + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function incr( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache incr <key> [offset] [group]' ); + exit; + } + + $key = $args[0]; + + $offset = ( isset( $args[1] ) ) ? $args[1] : 1; + + $group = ( isset( $args[2] ) ) ? $args[2] : ''; + + $value = wp_cache_incr( $key, $offset, $group ); + + if ( false === $value ) { + WP_CLI::error( 'The value was not incremented.' ); + exit; + } + + WP_CLI::print_value( $value, $assoc_args ); + } + + /** + * Replace an existing value in the object cache. + * + * @uses wp_cache_replace + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function replace( $args, $assoc_args ) { + if ( count( $assoc_args ) + count( $args ) < 2 ) { + WP_CLI::line( 'usage: wp cache replace <key> <value> [group] [expiration]' ); + exit; + } + + list( $key, $value ) = $args; + + $group = ( isset( $args[2] ) ) ? $args[2] : ''; + + $expiration = ( isset( $args[3] ) ) ? $args[3] : 0; + + $result = wp_cache_replace( $key, $value, $group, $expiration ); + + if ( false === $result ) { + WP_CLI::error( "Could not replace object '$key' in group '$group'. Does it already exist?" ); + exit; + } + + WP_CLI::success( "Replaced object '$key' in group '$group'." ); + } + + /** + * Set a value to the object cache. + * + * @uses wp_cache_set + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function set( $args, $assoc_args ) { + if ( count( $assoc_args ) + count( $args ) < 2 ) { + WP_CLI::line( 'usage: wp cache set <key> <value> [group] [expiration]' ); + exit; + } + + list( $key, $value ) = $args; + + $group = ( isset( $args[2] ) ) ? $args[2] : ''; + + $expiration = ( isset( $args[3] ) ) ? $args[3] : 0; + + $result = wp_cache_set( $key, $value, $group, $expiration ); + + if ( false === $result ) { + WP_CLI::error( "Could not add object '$key' in group '$group'." ); + exit; + } + + WP_CLI::success( "Set object '$key' in group '$group'." ); + } + + /** + * Switch the blog id, which switches the cache keys for all values. + * + * @uses wp_cache_switch_to_blog + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function switch_to_blog( $args, $assoc_args ) { + if ( empty( $args ) ) { + WP_CLI::line( 'usage: wp cache switch_to_blog <blog_id>' ); + exit; + } + + if ( ! function_exists( 'wp_cache_switch_to_blog' ) ) { + WP_CLI::warning( "Command cannot be executed because the 'wp_cache_switch_to_blog' function does not exist." ); + } + + $blog_id = $args[0]; + + wp_cache_switch_to_blog( $blog_id ); + } + + /** + * Attempts to determine which object cache is being used. + * + * Note that the guesses made by this function are based on the WP_Object_Cache classes + * that define the 3rd party object cache extension. Changes to those classes could render + * problems with this function's ability to determine which object cache is being used. + * + * @uses $_wp_using_ext_object_cache + * @uses $wp_object_cache + * + * @param array $args Function arguments. + * @param array $assoc_args Function arguments with parameter key. + * @return void + */ + public function which( $args, $assoc_args ) { + global $_wp_using_ext_object_cache, $wp_object_cache; + + $message = 'Using an unknown object cache'; + + if ( false !== $_wp_using_ext_object_cache ) { + // Test for Memcached PECL extension memcached object cache (https://github.com/tollmanz/wordpress-memcached-backend) + if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) + $message = 'Using memcached with the memcached PECL extension'; + + // Test for Memcache PECL extension memcached object cache (http://wordpress.org/extend/plugins/memcached/) + if ( isset( $wp_object_cache->mc ) ) { + $is_memcache = true; + foreach ( $wp_object_cache->mc as $bucket ) { + if ( ! is_a( $bucket, 'Memcache' ) ) + $is_memcache = false; + } + + if ( $is_memcache ) + $message = 'Using memcached with the memcache PECL extension'; + } + + // Test for Xcache object cache (http://plugins.svn.wordpress.org/xcache/trunk/object-cache.php) + if ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) + $message = 'Using the xcache object cache'; + + // Test for WinCache object cache (http://wordpress.org/extend/plugins/wincache-object-cache-backend/) + if ( class_exists( 'WinCache_Object_Cache' ) ) + $message = 'Using the wincache object cache'; + + // Test for APC object cache (http://wordpress.org/extend/plugins/apc/) + if ( class_exists( 'APC_Object_Cache' ) ) + $message = 'Using the APC object cache'; + } else { + $message = 'Using the default object cache'; + } + + WP_CLI::print_value( $message ); + } +} \ No newline at end of file From aa4d749da1508690731db1a178f6d313d1170895 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Sep 2012 23:19:07 +0300 Subject: [PATCH 0531/4858] abort at first error --- utils/pear-build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/pear-build b/utils/pear-build index 2172050ecd..1a25b8df17 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -1,5 +1,7 @@ #!/bin/bash +set -ex + # generate package find -name '*~' -delete phing pear-package From f0d60294338a5a49cbccb05c9a310f8d5f05a626 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Sep 2012 01:48:12 +0300 Subject: [PATCH 0532/4858] add version 0.6.0 changelog --- README.md | 20 ++++++++++++++++++++ src/php/wp-cli/wp-cli.php | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 92835f7e7a..4806bac2ea 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,26 @@ You can find more information about adding commands in the [Commands Cookbook](h Changelog --------------- +**0.6** + +- added `wp post` and `wp post-meta` +- added `wp user-meta` +- added `wp blog create` +- added `wp export` +- added `wp transient` +- added `wp db optimize` and `wp db repair` +- added `wp db create`, `wp db drop` and `wp db reset` +- added `wp db import` +- added `wp theme install` and `wp theme update` +- added `wp core install_network` +- added `--json` option to several subcommands +- added `--network` option to `wp plugin activate` +- added `--require` global parameter +- fixed `wp plugin update` +- fixed "out of memory" error +- misc bugfixes and optimizations +- man pages (not in PEAR package) + **0.5** - added `wp user` diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 834e3b698f..7ad523325d 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -5,7 +5,7 @@ die(-1); } -define( 'WP_CLI_VERSION', '0.6.0-dev' ); +define( 'WP_CLI_VERSION', '0.6.0' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 8578919ed7dc534109fd5cf02c22f3e369b9b523 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Sep 2012 01:50:28 +0300 Subject: [PATCH 0533/4858] mention wp core update_db --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4806bac2ea..2e0590d15c 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ Changelog - added `wp db import` - added `wp theme install` and `wp theme update` - added `wp core install_network` +- added `wp core update_db` - added `--json` option to several subcommands - added `--network` option to `wp plugin activate` - added `--require` global parameter From c84163073322e442fb7d2da2b7b71fd7b43fd57d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Sep 2012 02:30:11 +0300 Subject: [PATCH 0534/4858] pear-build: create missing directories --- utils/pear-build | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/utils/pear-build b/utils/pear-build index 1a25b8df17..1d9fadeda9 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -2,6 +2,12 @@ set -ex +# create bunch of directories that phing complains about +mkdir -p src/data +mkdir -p src/tests/unit-tests/php +mkdir -p src/www +mkdir -p src/docs + # generate package find -name '*~' -delete phing pear-package From bbb4c81be2e19718948ee93a7f2db453993f31c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Sep 2012 02:30:25 +0300 Subject: [PATCH 0535/4858] update stable version and license --- build.properties | 2 +- package.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.properties b/build.properties index 2a40f3cd4e..2bc7131b07 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.name=wpcli project.channel=wp-cli.github.com/pear project.majorVersion=0 -project.minorVersion=5 +project.minorVersion=6 project.patchLevel=0 project.snapshot=false diff --git a/package.xml b/package.xml index aa11e65f2c..852e8c4b14 100644 --- a/package.xml +++ b/package.xml @@ -31,7 +31,7 @@ <release>${project.stability}</release> <api>stable</api> </stability> - <license>GPL 2+</license> + <license>MIT</license> <notes> No notes. </notes> From c85b1b64f18953459147770b5281496fd9b7ca0d Mon Sep 17 00:00:00 2001 From: tollmanz <tollmanz@gmail.com> Date: Tue, 4 Sep 2012 20:57:10 -0700 Subject: [PATCH 0536/4858] Changed "which" command to "type" and simplified output --- src/php/wp-cli/commands/internals/cache.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index 8a7141b13f..57a225b0bd 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -319,15 +319,15 @@ public function switch_to_blog( $args, $assoc_args ) { * @param array $assoc_args Function arguments with parameter key. * @return void */ - public function which( $args, $assoc_args ) { + public function type( $args, $assoc_args ) { global $_wp_using_ext_object_cache, $wp_object_cache; - $message = 'Using an unknown object cache'; + $message = 'Unknown'; if ( false !== $_wp_using_ext_object_cache ) { // Test for Memcached PECL extension memcached object cache (https://github.com/tollmanz/wordpress-memcached-backend) if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) - $message = 'Using memcached with the memcached PECL extension'; + $message = 'Memcached (Memcached PECL extension)'; // Test for Memcache PECL extension memcached object cache (http://wordpress.org/extend/plugins/memcached/) if ( isset( $wp_object_cache->mc ) ) { @@ -338,22 +338,22 @@ public function which( $args, $assoc_args ) { } if ( $is_memcache ) - $message = 'Using memcached with the memcache PECL extension'; + $message = 'Memcached (Memcache PECL extension)'; } // Test for Xcache object cache (http://plugins.svn.wordpress.org/xcache/trunk/object-cache.php) if ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) - $message = 'Using the xcache object cache'; + $message = 'Xcache'; // Test for WinCache object cache (http://wordpress.org/extend/plugins/wincache-object-cache-backend/) if ( class_exists( 'WinCache_Object_Cache' ) ) - $message = 'Using the wincache object cache'; + $message = 'WinCache'; // Test for APC object cache (http://wordpress.org/extend/plugins/apc/) if ( class_exists( 'APC_Object_Cache' ) ) - $message = 'Using the APC object cache'; + $message = 'APC'; } else { - $message = 'Using the default object cache'; + $message = 'Default object cache'; } WP_CLI::print_value( $message ); From a5d88bcb98a28537c3c3a952d372759aaa32eac1 Mon Sep 17 00:00:00 2001 From: tollmanz <tollmanz@gmail.com> Date: Tue, 4 Sep 2012 21:50:49 -0700 Subject: [PATCH 0537/4858] Added man page for cache command --- man/cache.1 | 123 ++++++++++++++++++++++++++++++++++++++++++++++ src/doc/cache.txt | 84 +++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 man/cache.1 create mode 100644 src/doc/cache.txt diff --git a/man/cache.1 b/man/cache.1 new file mode 100644 index 0000000000..6024971c06 --- /dev/null +++ b/man/cache.1 @@ -0,0 +1,123 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\fR \- Manage WordPress the object cache\. +. +.SH "SYNOPSIS" +wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] +. +.P +wp cache add_global_groups \fIgroup\fR +. +.P +wp cache add_non_persistent_groups \fIgroup\fR +. +.P +wp cache decr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] +. +.P +wp cache delete \fIkey\fR \fIgroup\fR +. +.P +wp cache flush +. +.P +wp cache get \fIkey\fR [\fIgroup\fR] +. +.P +wp cache incr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] +. +.P +wp cache replace \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] +. +.P +wp cache set \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] +. +.P +wp cache switch_to_blog \fIblog_id\fR +. +.P +wp cache type +. +.SH "SUBCOMMANDS" +. +.TP +\fBadd\fR: +. +.IP +Add a value to cache where \fIkey\fR in \fIgroup\fR does not already exist\. +. +.TP +\fBadd_global_groups\fR: +. +.IP +Add a value to the global groups array\. +. +.TP +\fBadd_non_persistent_groups\fR: +. +.IP +Add a value to the non persistent groups array\. +. +.TP +\fBdecr\fR: +. +.IP +Decrement the value of a cached object by 1 or the value of the \fIoffset\fR parameter\. +. +.TP +\fBdelete\fR: +. +.IP +Remove an object from cache\. +. +.TP +\fBflush\fR: +. +.IP +Flush the cache\. +. +.TP +\fBget\fR: +. +.IP +Get a value from cache\. +. +.TP +\fBincr\fR: +. +.IP +Increment the value of a cached object by 1 or the value of the \fIoffset\fR parameter\. +. +.TP +\fBreplace\fR: +. +.IP +Replace a value in cache with a new value\. +. +.TP +\fBset\fR: +. +.IP +Set a value in cache\. +. +.TP +\fBswitch_to_blog\fR: +. +.IP +Interact with the cache for the specified \fIblog_id\fR\. +. +.TP +\fBtype\fR: +. +.IP +Report the type of object being used\. +. +.SH "EXAMPLES" +wp cache set my_key my_value my_group 300 +. +.P +wp cache get my_key my_group diff --git a/src/doc/cache.txt b/src/doc/cache.txt new file mode 100644 index 0000000000..e28de79f66 --- /dev/null +++ b/src/doc/cache.txt @@ -0,0 +1,84 @@ +wp-cache(1) -- Manage WordPress the object cache. +==== + +## SYNOPSIS + +wp cache add <key> <value> [<group>] [<expiration>] + +wp cache add_global_groups <group> + +wp cache add_non_persistent_groups <group> + +wp cache decr <key> [<offset>] [<group>] + +wp cache delete <key> <group> + +wp cache flush + +wp cache get <key> [<group>] + +wp cache incr <key> [<offset>] [<group>] + +wp cache replace <key> <value> [<group>] [<expiration>] + +wp cache set <key> <value> [<group>] [<expiration>] + +wp cache switch_to_blog <blog_id> + +wp cache type + +## SUBCOMMANDS + +* `add`: + + Add a value to cache where <key> in <group> does not already exist. + +* `add_global_groups`: + + Add a value to the global groups array. + +* `add_non_persistent_groups`: + + Add a value to the non persistent groups array. + +* `decr`: + + Decrement the value of a cached object by 1 or the value of the <offset> parameter. + +* `delete`: + + Remove an object from cache. + +* `flush`: + + Flush the cache. + +* `get`: + + Get a value from cache. + +* `incr`: + + Increment the value of a cached object by 1 or the value of the <offset> parameter. + +* `replace`: + + Replace a value in cache with a new value. + +* `set`: + + Set a value in cache. + +* `switch_to_blog`: + + Interact with the cache for the specified <blog_id>. + +* `type`: + + Report the type of object being used. + +## EXAMPLES + +wp cache set my_key my_value my_group 300 + +wp cache get my_key my_group From 346213612013e618a5a54ee3c01511654ed71529 Mon Sep 17 00:00:00 2001 From: tollmanz <tollmanz@gmail.com> Date: Wed, 5 Sep 2012 20:31:48 -0700 Subject: [PATCH 0538/4858] Updated output and if/else struture in the type subcommand --- src/php/wp-cli/commands/internals/cache.php | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index 57a225b0bd..546439036d 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -322,15 +322,13 @@ public function switch_to_blog( $args, $assoc_args ) { public function type( $args, $assoc_args ) { global $_wp_using_ext_object_cache, $wp_object_cache; - $message = 'Unknown'; - if ( false !== $_wp_using_ext_object_cache ) { // Test for Memcached PECL extension memcached object cache (https://github.com/tollmanz/wordpress-memcached-backend) - if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) - $message = 'Memcached (Memcached PECL extension)'; + if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) { + $message = 'Memcached'; // Test for Memcache PECL extension memcached object cache (http://wordpress.org/extend/plugins/memcached/) - if ( isset( $wp_object_cache->mc ) ) { + } elseif ( isset( $wp_object_cache->mc ) ) { $is_memcache = true; foreach ( $wp_object_cache->mc as $bucket ) { if ( ! is_a( $bucket, 'Memcache' ) ) @@ -338,22 +336,24 @@ public function type( $args, $assoc_args ) { } if ( $is_memcache ) - $message = 'Memcached (Memcache PECL extension)'; - } + $message = 'Memcache'; // Test for Xcache object cache (http://plugins.svn.wordpress.org/xcache/trunk/object-cache.php) - if ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) + } elseif ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) { $message = 'Xcache'; // Test for WinCache object cache (http://wordpress.org/extend/plugins/wincache-object-cache-backend/) - if ( class_exists( 'WinCache_Object_Cache' ) ) + } elseif ( class_exists( 'WinCache_Object_Cache' ) ) { $message = 'WinCache'; // Test for APC object cache (http://wordpress.org/extend/plugins/apc/) - if ( class_exists( 'APC_Object_Cache' ) ) + } elseif ( class_exists( 'APC_Object_Cache' ) ) { $message = 'APC'; + } else { + $message = 'Unknown'; + } } else { - $message = 'Default object cache'; + $message = 'Default'; } WP_CLI::print_value( $message ); From c916695ee9c8c94ea31ee9ef1381837630778b31 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Sep 2012 02:33:44 +0300 Subject: [PATCH 0539/4858] need sudo for pear config-set too --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e0590d15c..4b99c1d1c9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Installing **Via PEAR:** ```sh -pear config-set auto_discover 1 +sudo pear config-set auto_discover 1 sudo pear install wp-cli.github.com/pear/wpcli ``` From 793b470327543481e4e230f6aaa6fc64bba597b0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Sep 2012 02:49:45 +0300 Subject: [PATCH 0540/4858] make pear package work --- src/bin/wp | 2 +- utils/pear-build | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/bin/wp b/src/bin/wp index aaf8d1d6e4..1856f53e0e 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -28,7 +28,7 @@ cd "$ORIGDIR" # Build the path to the root PHP file SCRIPT_PATH='@@PHP_DIR@@' -if [ ! -f $SCRIPT_PATH ]; then +if [ ! -d $SCRIPT_PATH ]; then SCRIPT_PATH=$(dirname "$SELF_PATH")/../php fi diff --git a/utils/pear-build b/utils/pear-build index 1d9fadeda9..07530db9a0 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -8,10 +8,20 @@ mkdir -p src/tests/unit-tests/php mkdir -p src/www mkdir -p src/docs +# temporarily move the .git dir, because phing is stupid +git_dir=src/php/php-cli-tools/.git +if [ -d $git_dir ]; then + mv $git_dir /tmp/php-cli-tools-git +fi + # generate package find -name '*~' -delete phing pear-package +if [ ! -d $git_dir ]; then + mv /tmp/php-cli-tools-git $git_dir +fi + version=$(cat dist/lastBuilt) version="${version/*wpcli-/}" version="${version/.tgz/}" From 7d4ff9198bf1935d83551c8896c84596d7823c98 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Sep 2012 14:28:51 +0300 Subject: [PATCH 0541/4858] mv src/doc src/docs --- man/blog-create.1 | 2 +- man/core-config.1 | 2 +- man/core-download.1 | 2 +- man/core-install.1 | 2 +- man/core-install_network.1 | 2 +- man/core-update.1 | 2 +- man/core-update_db.1 | 2 +- man/core-version.1 | 2 +- man/db-cli.1 | 2 +- man/db-connect.1 | 2 +- man/db-create.1 | 2 +- man/db-drop.1 | 2 +- man/db-export.1 | 2 +- man/db-import.1 | 2 +- man/db-optimize.1 | 2 +- man/db-query.1 | 2 +- man/db-repair.1 | 2 +- man/db-reset.1 | 2 +- man/eval-file.1 | 2 +- man/eval.1 | 2 +- man/export.1 | 2 +- man/generate-posts.1 | 2 +- man/generate-users.1 | 2 +- man/home.1 | 2 +- man/option.1 | 2 +- man/plugin-activate.1 | 2 +- man/plugin-deactivate.1 | 2 +- man/plugin-delete.1 | 2 +- man/plugin-install.1 | 2 +- man/plugin-path.1 | 2 +- man/plugin-status.1 | 2 +- man/plugin-toggle.1 | 2 +- man/plugin-uninstall.1 | 2 +- man/plugin-update.1 | 2 +- man/post-create.1 | 2 +- man/post-delete.1 | 2 +- man/post-meta.1 | 2 +- man/post-update.1 | 2 +- man/theme-activate.1 | 2 +- man/theme-delete.1 | 2 +- man/theme-install.1 | 2 +- man/theme-path.1 | 2 +- man/theme-status.1 | 2 +- man/theme-update.1 | 2 +- man/transient.1 | 2 +- man/user-create.1 | 2 +- man/user-delete.1 | 2 +- man/user-list.1 | 2 +- man/user-meta.1 | 2 +- man/user-update.1 | 2 +- src/{doc => docs}/blog-create.txt | 0 src/{doc => docs}/cache.txt | 0 src/{doc => docs}/core-config.txt | 0 src/{doc => docs}/core-download.txt | 0 src/{doc => docs}/core-install.txt | 0 src/{doc => docs}/core-install_network.txt | 0 src/{doc => docs}/core-update.txt | 0 src/{doc => docs}/core-update_db.txt | 0 src/{doc => docs}/core-version.txt | 0 src/{doc => docs}/db-cli.txt | 0 src/{doc => docs}/db-connect.txt | 0 src/{doc => docs}/db-create.txt | 0 src/{doc => docs}/db-drop.txt | 0 src/{doc => docs}/db-export.txt | 0 src/{doc => docs}/db-import.txt | 0 src/{doc => docs}/db-optimize.txt | 0 src/{doc => docs}/db-query.txt | 0 src/{doc => docs}/db-repair.txt | 0 src/{doc => docs}/db-reset.txt | 0 src/{doc => docs}/eval-file.txt | 0 src/{doc => docs}/eval.txt | 0 src/{doc => docs}/export.txt | 0 src/{doc => docs}/generate-posts.txt | 0 src/{doc => docs}/generate-users.txt | 0 src/{doc => docs}/home.txt | 0 src/{doc => docs}/option.txt | 0 src/{doc => docs}/plugin-activate.txt | 0 src/{doc => docs}/plugin-deactivate.txt | 0 src/{doc => docs}/plugin-delete.txt | 0 src/{doc => docs}/plugin-install.txt | 0 src/{doc => docs}/plugin-path.txt | 0 src/{doc => docs}/plugin-status.txt | 0 src/{doc => docs}/plugin-toggle.txt | 0 src/{doc => docs}/plugin-uninstall.txt | 0 src/{doc => docs}/plugin-update.txt | 0 src/{doc => docs}/post-create.txt | 0 src/{doc => docs}/post-delete.txt | 0 src/{doc => docs}/post-meta.txt | 0 src/{doc => docs}/post-update.txt | 0 src/{doc => docs}/theme-activate.txt | 0 src/{doc => docs}/theme-delete.txt | 0 src/{doc => docs}/theme-install.txt | 0 src/{doc => docs}/theme-path.txt | 0 src/{doc => docs}/theme-status.txt | 0 src/{doc => docs}/theme-update.txt | 0 src/{doc => docs}/transient.txt | 0 src/{doc => docs}/user-create.txt | 0 src/{doc => docs}/user-delete.txt | 0 src/{doc => docs}/user-list.txt | 0 src/{doc => docs}/user-meta.txt | 0 src/{doc => docs}/user-update.txt | 0 utils/doc-build | 2 +- utils/pear-build | 1 - 103 files changed, 51 insertions(+), 52 deletions(-) rename src/{doc => docs}/blog-create.txt (100%) rename src/{doc => docs}/cache.txt (100%) rename src/{doc => docs}/core-config.txt (100%) rename src/{doc => docs}/core-download.txt (100%) rename src/{doc => docs}/core-install.txt (100%) rename src/{doc => docs}/core-install_network.txt (100%) rename src/{doc => docs}/core-update.txt (100%) rename src/{doc => docs}/core-update_db.txt (100%) rename src/{doc => docs}/core-version.txt (100%) rename src/{doc => docs}/db-cli.txt (100%) rename src/{doc => docs}/db-connect.txt (100%) rename src/{doc => docs}/db-create.txt (100%) rename src/{doc => docs}/db-drop.txt (100%) rename src/{doc => docs}/db-export.txt (100%) rename src/{doc => docs}/db-import.txt (100%) rename src/{doc => docs}/db-optimize.txt (100%) rename src/{doc => docs}/db-query.txt (100%) rename src/{doc => docs}/db-repair.txt (100%) rename src/{doc => docs}/db-reset.txt (100%) rename src/{doc => docs}/eval-file.txt (100%) rename src/{doc => docs}/eval.txt (100%) rename src/{doc => docs}/export.txt (100%) rename src/{doc => docs}/generate-posts.txt (100%) rename src/{doc => docs}/generate-users.txt (100%) rename src/{doc => docs}/home.txt (100%) rename src/{doc => docs}/option.txt (100%) rename src/{doc => docs}/plugin-activate.txt (100%) rename src/{doc => docs}/plugin-deactivate.txt (100%) rename src/{doc => docs}/plugin-delete.txt (100%) rename src/{doc => docs}/plugin-install.txt (100%) rename src/{doc => docs}/plugin-path.txt (100%) rename src/{doc => docs}/plugin-status.txt (100%) rename src/{doc => docs}/plugin-toggle.txt (100%) rename src/{doc => docs}/plugin-uninstall.txt (100%) rename src/{doc => docs}/plugin-update.txt (100%) rename src/{doc => docs}/post-create.txt (100%) rename src/{doc => docs}/post-delete.txt (100%) rename src/{doc => docs}/post-meta.txt (100%) rename src/{doc => docs}/post-update.txt (100%) rename src/{doc => docs}/theme-activate.txt (100%) rename src/{doc => docs}/theme-delete.txt (100%) rename src/{doc => docs}/theme-install.txt (100%) rename src/{doc => docs}/theme-path.txt (100%) rename src/{doc => docs}/theme-status.txt (100%) rename src/{doc => docs}/theme-update.txt (100%) rename src/{doc => docs}/transient.txt (100%) rename src/{doc => docs}/user-create.txt (100%) rename src/{doc => docs}/user-delete.txt (100%) rename src/{doc => docs}/user-list.txt (100%) rename src/{doc => docs}/user-meta.txt (100%) rename src/{doc => docs}/user-update.txt (100%) diff --git a/man/blog-create.1 b/man/blog-create.1 index e75b5ee6c8..338aff284d 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-CREATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-BLOG\-CREATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-blog\-create\fR \- Create a new blog in a multisite install\. diff --git a/man/core-config.1 b/man/core-config.1 index 0235a39bc9..cc545a6659 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-CONFIG" "1" "May 2012" "" "WP-CLI" +.TH "WP\-CORE\-CONFIG" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-config\fR \- Create a wp\-config\.php file\. diff --git a/man/core-download.1 b/man/core-download.1 index 8d4e9f8e60..9dc988e6d6 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-DOWNLOAD" "1" "May 2012" "" "WP-CLI" +.TH "WP\-CORE\-DOWNLOAD" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-download\fR \- Download core WordPress files\. diff --git a/man/core-install.1 b/man/core-install.1 index 1c42139657..9ba7e9e4a1 100644 --- a/man/core-install.1 +++ b/man/core-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-INSTALL" "1" "June 2012" "" "WP-CLI" +.TH "WP\-CORE\-INSTALL" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-install\fR \- Install the WordPress tables in the database\. diff --git a/man/core-install_network.1 b/man/core-install_network.1 index 09fcc2890d..6aad5aa0f3 100644 --- a/man/core-install_network.1 +++ b/man/core-install_network.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-INSTALL_NETWORK" "1" "July 2012" "" "WP-CLI" +.TH "WP\-CORE\-INSTALL_NETWORK" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-install_network\fR \- Transform a single\-site install into a diff --git a/man/core-update.1 b/man/core-update.1 index af27373d7a..c0b4f8c61c 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE" "1" "July 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-update\fR \- Update WordPress to the latest version\. diff --git a/man/core-update_db.1 b/man/core-update_db.1 index e9a570d92f..dc5a11563b 100644 --- a/man/core-update_db.1 +++ b/man/core-update_db.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE_DB" "1" "July 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE_DB" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-update_db\fR \- Update the WordPress database\. diff --git a/man/core-version.1 b/man/core-version.1 index 160ccb3765..8e910bab17 100644 --- a/man/core-version.1 +++ b/man/core-version.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-VERSION" "1" "May 2012" "" "WP-CLI" +.TH "WP\-CORE\-VERSION" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-version\fR \- Show the WordPress version\. diff --git a/man/db-cli.1 b/man/db-cli.1 index 22f397c05b..c8ae69ee69 100644 --- a/man/db-cli.1 +++ b/man/db-cli.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-CLI" "1" "May 2012" "" "WP-CLI" +.TH "WP\-DB\-CLI" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-cli\fR \- Open a SQL command\-line interface to the WordPress database\. diff --git a/man/db-connect.1 b/man/db-connect.1 index ea799644f8..bb73c49b1e 100644 --- a/man/db-connect.1 +++ b/man/db-connect.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-CONNECT" "1" "May 2012" "" "WP-CLI" +.TH "WP\-DB\-CONNECT" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-connect\fR \- Print a string for connecting to the database\. diff --git a/man/db-create.1 b/man/db-create.1 index 93f9295825..06d9543539 100644 --- a/man/db-create.1 +++ b/man/db-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-CREATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-DB\-CREATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-create\fR \- Create a database using the credentials from wp\-config\.php\. diff --git a/man/db-drop.1 b/man/db-drop.1 index f5c8f3b768..b3cf01108a 100644 --- a/man/db-drop.1 +++ b/man/db-drop.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-DROP" "1" "July 2012" "" "WP-CLI" +.TH "WP\-DB\-DROP" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-drop\fR \- Drop the database specified in wp\-config\.php diff --git a/man/db-export.1 b/man/db-export.1 index 33648242f0..06b28380c7 100644 --- a/man/db-export.1 +++ b/man/db-export.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-EXPORT" "1" "May 2012" "" "WP-CLI" +.TH "WP\-DB\-EXPORT" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-export\fR \- Export the WordPress database using mysqldump\. diff --git a/man/db-import.1 b/man/db-import.1 index 987cade497..8941bbe14f 100644 --- a/man/db-import.1 +++ b/man/db-import.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-IMPORT" "1" "May 2012" "" "WP-CLI" +.TH "WP\-DB\-IMPORT" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-import\fR \- Import a database from a text file\. diff --git a/man/db-optimize.1 b/man/db-optimize.1 index 56b099bad7..3381c63eed 100644 --- a/man/db-optimize.1 +++ b/man/db-optimize.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-OPTIMIZE" "1" "July 2012" "" "WP-CLI" +.TH "WP\-DB\-OPTIMIZE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-optimize\fR \- Optimize the database specified in the wp\-config\.php file\. diff --git a/man/db-query.1 b/man/db-query.1 index 0326bd394b..9ba0d685b6 100644 --- a/man/db-query.1 +++ b/man/db-query.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-QUERY" "1" "May 2012" "" "WP-CLI" +.TH "WP\-DB\-QUERY" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-query\fR \- Execute a query against the WordPress database\. diff --git a/man/db-repair.1 b/man/db-repair.1 index 2f9089eb69..9c96284d3d 100644 --- a/man/db-repair.1 +++ b/man/db-repair.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-REPAIR" "1" "July 2012" "" "WP-CLI" +.TH "WP\-DB\-REPAIR" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-repair\fR \- Optimize the database specified in the wp\-config\.php file\. diff --git a/man/db-reset.1 b/man/db-reset.1 index 4f40b8300c..de44c95390 100644 --- a/man/db-reset.1 +++ b/man/db-reset.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-RESET" "1" "August 2012" "" "WP-CLI" +.TH "WP\-DB\-RESET" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-reset\fR \- Remove all data from the database specified in wp\-config\.php diff --git a/man/eval-file.1 b/man/eval-file.1 index 5060788e1f..b0a1694d44 100644 --- a/man/eval-file.1 +++ b/man/eval-file.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EVAL\-FILE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-EVAL\-FILE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-eval\-file\fR \- Loads and executes a PHP file after loading WordPress\. diff --git a/man/eval.1 b/man/eval.1 index 473ec61df4..2a8dbdb239 100644 --- a/man/eval.1 +++ b/man/eval.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EVAL" "1" "May 2012" "" "WP-CLI" +.TH "WP\-EVAL" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-eval\fR \- Executes arbitrary PHP code after loading WordPress\. diff --git a/man/export.1 b/man/export.1 index d064d5db0b..27afcfb5a0 100644 --- a/man/export.1 +++ b/man/export.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EXPORT" "1" "May 2012" "" "WP-CLI" +.TH "WP\-EXPORT" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-export\fR \- Create a WXR file\. diff --git a/man/generate-posts.1 b/man/generate-posts.1 index fcd00ede49..9f0ef3a2e3 100644 --- a/man/generate-posts.1 +++ b/man/generate-posts.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-GENERATE\-POSTS" "1" "June 2012" "" "WP-CLI" +.TH "WP\-GENERATE\-POSTS" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-generate\-posts\fR \- Generate a bunch of posts\. diff --git a/man/generate-users.1 b/man/generate-users.1 index 9fadb9950d..347a6a5f0f 100644 --- a/man/generate-users.1 +++ b/man/generate-users.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-GENERATE\-USERS" "1" "May 2012" "" "WP-CLI" +.TH "WP\-GENERATE\-USERS" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-generate\-users\fR \- Generate a bunch of users\. diff --git a/man/home.1 b/man/home.1 index 0695908844..2dc74647ea 100644 --- a/man/home.1 +++ b/man/home.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-HOME" "1" "May 2012" "" "WP-CLI" +.TH "WP\-HOME" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-home\fR \- Opens the wp\-cli homepage in your browser\. diff --git a/man/option.1 b/man/option.1 index 660dc4d263..678c77b487 100644 --- a/man/option.1 +++ b/man/option.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-OPTION" "1" "June 2012" "" "WP-CLI" +.TH "WP\-OPTION" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-option\fR \- Manage WordPress options\. diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 index bcecd12c9f..bff5b9bbe6 100644 --- a/man/plugin-activate.1 +++ b/man/plugin-activate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-ACTIVATE" "1" "June 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-ACTIVATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-activate\fR \- Activate an installed plugin\. diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 index a9823535ca..3de02d9696 100644 --- a/man/plugin-deactivate.1 +++ b/man/plugin-deactivate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "June 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-deactivate\fR \- Deactivate an active plugin\. diff --git a/man/plugin-delete.1 b/man/plugin-delete.1 index b6c3b20340..8a8834c486 100644 --- a/man/plugin-delete.1 +++ b/man/plugin-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DELETE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DELETE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-delete\fR \- Delete a plugin\'s files, without removing it\'s data\. diff --git a/man/plugin-install.1 b/man/plugin-install.1 index a90117f766..af740f73b9 100644 --- a/man/plugin-install.1 +++ b/man/plugin-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-INSTALL" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-INSTALL" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-install\fR \- Install a plugin from wordpress\.org or from a zip file\. diff --git a/man/plugin-path.1 b/man/plugin-path.1 index cbf20513b6..87c1c8eb0d 100644 --- a/man/plugin-path.1 +++ b/man/plugin-path.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-PATH" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-PATH" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-path\fR \- Get the path to a plugin or to the plugin directory\. diff --git a/man/plugin-status.1 b/man/plugin-status.1 index cbf0900fd9..98c1ea1776 100644 --- a/man/plugin-status.1 +++ b/man/plugin-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-STATUS" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-STATUS" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-status\fR \- See the status of one or all plugins\. diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 index f86b819e5c..9764eca030 100644 --- a/man/plugin-toggle.1 +++ b/man/plugin-toggle.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "June 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-deactivate\fR \- Activate/Deactivate an installed plugin\. diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 index 0d54300322..7e6bd90437 100644 --- a/man/plugin-uninstall.1 +++ b/man/plugin-uninstall.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UNINSTALL" "1" "June 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UNINSTALL" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-uninstall\fR \- Run the uninstallation procedure for a plugin\. diff --git a/man/plugin-update.1 b/man/plugin-update.1 index a5f21a8ebd..3fcac90c5b 100644 --- a/man/plugin-update.1 +++ b/man/plugin-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UPDATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UPDATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-update\fR \- Update an installed plugin\. diff --git a/man/post-create.1 b/man/post-create.1 index 3ed689f819..072011b4cd 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-CREATE" "1" "July 2012" "" "WP-CLI" +.TH "WP\-POST\-CREATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-create\fR \- Create a new WordPress post\. diff --git a/man/post-delete.1 b/man/post-delete.1 index 3bfd901a93..a46fb79bbd 100644 --- a/man/post-delete.1 +++ b/man/post-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-DELETE" "1" "July 2012" "" "WP-CLI" +.TH "WP\-POST\-DELETE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-delete\fR \- Delete a WordPress post\. diff --git a/man/post-meta.1 b/man/post-meta.1 index 65bce7c9bf..6107d180ab 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-META" "1" "July 2012" "" "WP-CLI" +.TH "WP\-POST\-META" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-meta\fR \- Manage post custom fields\. diff --git a/man/post-update.1 b/man/post-update.1 index 7ef6418ed2..60d85f15b8 100644 --- a/man/post-update.1 +++ b/man/post-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-UPDATE" "1" "July 2012" "" "WP-CLI" +.TH "WP\-POST\-UPDATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-update\fR \- Update a WordPress post\. diff --git a/man/theme-activate.1 b/man/theme-activate.1 index 0d8c95f482..55861bc3dd 100644 --- a/man/theme-activate.1 +++ b/man/theme-activate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-ACTIVATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-THEME\-ACTIVATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-activate\fR \- Activate an installed theme\. diff --git a/man/theme-delete.1 b/man/theme-delete.1 index 48f0c83571..0514d865d2 100644 --- a/man/theme-delete.1 +++ b/man/theme-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-DELETE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-THEME\-DELETE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-delete\fR \- Delete a theme\. diff --git a/man/theme-install.1 b/man/theme-install.1 index 71f60fb0e5..3042b5bee8 100644 --- a/man/theme-install.1 +++ b/man/theme-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-INSTALL" "1" "July 2012" "" "WP-CLI" +.TH "WP\-THEME\-INSTALL" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-install\fR \- Install a theme from wordpress\.org or from a zip file\. diff --git a/man/theme-path.1 b/man/theme-path.1 index 3d806d0579..90bf49d82e 100644 --- a/man/theme-path.1 +++ b/man/theme-path.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-PATH" "1" "May 2012" "" "WP-CLI" +.TH "WP\-THEME\-PATH" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-path\fR \- Get the path to a theme or to the theme directory\. diff --git a/man/theme-status.1 b/man/theme-status.1 index 2d68b088df..53b68274a1 100644 --- a/man/theme-status.1 +++ b/man/theme-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-STATUS" "1" "May 2012" "" "WP-CLI" +.TH "WP\-THEME\-STATUS" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-status\fR \- See the status of one or all themes\. diff --git a/man/theme-update.1 b/man/theme-update.1 index 686ccb02af..5ae00b078d 100644 --- a/man/theme-update.1 +++ b/man/theme-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-UPDATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-THEME\-UPDATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-update\fR \- Update an installed theme\. diff --git a/man/transient.1 b/man/transient.1 index d2307b45b0..0d10b8a23f 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-TRANSIENT" "1" "May 2012" "" "WP-CLI" +.TH "WP\-TRANSIENT" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-transient\fR \- Manage WordPress transients\. diff --git a/man/user-create.1 b/man/user-create.1 index c96e198274..67537e0c70 100644 --- a/man/user-create.1 +++ b/man/user-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-CREATE" "1" "July 2012" "" "WP-CLI" +.TH "WP\-USER\-CREATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-create\fR \- Create a new WordPress user\. diff --git a/man/user-delete.1 b/man/user-delete.1 index dfab940b6d..a33d6fdd39 100644 --- a/man/user-delete.1 +++ b/man/user-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-DELETE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-USER\-DELETE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-delete\fR \- Delete a WordPress user\. diff --git a/man/user-list.1 b/man/user-list.1 index 1ae1b93b54..0535f8674b 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-LIST" "1" "May 2012" "" "WP-CLI" +.TH "WP\-USER\-LIST" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-list\fR \- List WordPress users\. diff --git a/man/user-meta.1 b/man/user-meta.1 index fa9b646d57..73130d87e1 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-META" "1" "June 2012" "" "WP-CLI" +.TH "WP\-USER\-META" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-meta\fR \- Manage user custom fields\. diff --git a/man/user-update.1 b/man/user-update.1 index c5b8af7f21..cebdfef6b3 100644 --- a/man/user-update.1 +++ b/man/user-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-UPDATE" "1" "May 2012" "" "WP-CLI" +.TH "WP\-USER\-UPDATE" "1" "September 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-update\fR \- Update a WordPress user\. diff --git a/src/doc/blog-create.txt b/src/docs/blog-create.txt similarity index 100% rename from src/doc/blog-create.txt rename to src/docs/blog-create.txt diff --git a/src/doc/cache.txt b/src/docs/cache.txt similarity index 100% rename from src/doc/cache.txt rename to src/docs/cache.txt diff --git a/src/doc/core-config.txt b/src/docs/core-config.txt similarity index 100% rename from src/doc/core-config.txt rename to src/docs/core-config.txt diff --git a/src/doc/core-download.txt b/src/docs/core-download.txt similarity index 100% rename from src/doc/core-download.txt rename to src/docs/core-download.txt diff --git a/src/doc/core-install.txt b/src/docs/core-install.txt similarity index 100% rename from src/doc/core-install.txt rename to src/docs/core-install.txt diff --git a/src/doc/core-install_network.txt b/src/docs/core-install_network.txt similarity index 100% rename from src/doc/core-install_network.txt rename to src/docs/core-install_network.txt diff --git a/src/doc/core-update.txt b/src/docs/core-update.txt similarity index 100% rename from src/doc/core-update.txt rename to src/docs/core-update.txt diff --git a/src/doc/core-update_db.txt b/src/docs/core-update_db.txt similarity index 100% rename from src/doc/core-update_db.txt rename to src/docs/core-update_db.txt diff --git a/src/doc/core-version.txt b/src/docs/core-version.txt similarity index 100% rename from src/doc/core-version.txt rename to src/docs/core-version.txt diff --git a/src/doc/db-cli.txt b/src/docs/db-cli.txt similarity index 100% rename from src/doc/db-cli.txt rename to src/docs/db-cli.txt diff --git a/src/doc/db-connect.txt b/src/docs/db-connect.txt similarity index 100% rename from src/doc/db-connect.txt rename to src/docs/db-connect.txt diff --git a/src/doc/db-create.txt b/src/docs/db-create.txt similarity index 100% rename from src/doc/db-create.txt rename to src/docs/db-create.txt diff --git a/src/doc/db-drop.txt b/src/docs/db-drop.txt similarity index 100% rename from src/doc/db-drop.txt rename to src/docs/db-drop.txt diff --git a/src/doc/db-export.txt b/src/docs/db-export.txt similarity index 100% rename from src/doc/db-export.txt rename to src/docs/db-export.txt diff --git a/src/doc/db-import.txt b/src/docs/db-import.txt similarity index 100% rename from src/doc/db-import.txt rename to src/docs/db-import.txt diff --git a/src/doc/db-optimize.txt b/src/docs/db-optimize.txt similarity index 100% rename from src/doc/db-optimize.txt rename to src/docs/db-optimize.txt diff --git a/src/doc/db-query.txt b/src/docs/db-query.txt similarity index 100% rename from src/doc/db-query.txt rename to src/docs/db-query.txt diff --git a/src/doc/db-repair.txt b/src/docs/db-repair.txt similarity index 100% rename from src/doc/db-repair.txt rename to src/docs/db-repair.txt diff --git a/src/doc/db-reset.txt b/src/docs/db-reset.txt similarity index 100% rename from src/doc/db-reset.txt rename to src/docs/db-reset.txt diff --git a/src/doc/eval-file.txt b/src/docs/eval-file.txt similarity index 100% rename from src/doc/eval-file.txt rename to src/docs/eval-file.txt diff --git a/src/doc/eval.txt b/src/docs/eval.txt similarity index 100% rename from src/doc/eval.txt rename to src/docs/eval.txt diff --git a/src/doc/export.txt b/src/docs/export.txt similarity index 100% rename from src/doc/export.txt rename to src/docs/export.txt diff --git a/src/doc/generate-posts.txt b/src/docs/generate-posts.txt similarity index 100% rename from src/doc/generate-posts.txt rename to src/docs/generate-posts.txt diff --git a/src/doc/generate-users.txt b/src/docs/generate-users.txt similarity index 100% rename from src/doc/generate-users.txt rename to src/docs/generate-users.txt diff --git a/src/doc/home.txt b/src/docs/home.txt similarity index 100% rename from src/doc/home.txt rename to src/docs/home.txt diff --git a/src/doc/option.txt b/src/docs/option.txt similarity index 100% rename from src/doc/option.txt rename to src/docs/option.txt diff --git a/src/doc/plugin-activate.txt b/src/docs/plugin-activate.txt similarity index 100% rename from src/doc/plugin-activate.txt rename to src/docs/plugin-activate.txt diff --git a/src/doc/plugin-deactivate.txt b/src/docs/plugin-deactivate.txt similarity index 100% rename from src/doc/plugin-deactivate.txt rename to src/docs/plugin-deactivate.txt diff --git a/src/doc/plugin-delete.txt b/src/docs/plugin-delete.txt similarity index 100% rename from src/doc/plugin-delete.txt rename to src/docs/plugin-delete.txt diff --git a/src/doc/plugin-install.txt b/src/docs/plugin-install.txt similarity index 100% rename from src/doc/plugin-install.txt rename to src/docs/plugin-install.txt diff --git a/src/doc/plugin-path.txt b/src/docs/plugin-path.txt similarity index 100% rename from src/doc/plugin-path.txt rename to src/docs/plugin-path.txt diff --git a/src/doc/plugin-status.txt b/src/docs/plugin-status.txt similarity index 100% rename from src/doc/plugin-status.txt rename to src/docs/plugin-status.txt diff --git a/src/doc/plugin-toggle.txt b/src/docs/plugin-toggle.txt similarity index 100% rename from src/doc/plugin-toggle.txt rename to src/docs/plugin-toggle.txt diff --git a/src/doc/plugin-uninstall.txt b/src/docs/plugin-uninstall.txt similarity index 100% rename from src/doc/plugin-uninstall.txt rename to src/docs/plugin-uninstall.txt diff --git a/src/doc/plugin-update.txt b/src/docs/plugin-update.txt similarity index 100% rename from src/doc/plugin-update.txt rename to src/docs/plugin-update.txt diff --git a/src/doc/post-create.txt b/src/docs/post-create.txt similarity index 100% rename from src/doc/post-create.txt rename to src/docs/post-create.txt diff --git a/src/doc/post-delete.txt b/src/docs/post-delete.txt similarity index 100% rename from src/doc/post-delete.txt rename to src/docs/post-delete.txt diff --git a/src/doc/post-meta.txt b/src/docs/post-meta.txt similarity index 100% rename from src/doc/post-meta.txt rename to src/docs/post-meta.txt diff --git a/src/doc/post-update.txt b/src/docs/post-update.txt similarity index 100% rename from src/doc/post-update.txt rename to src/docs/post-update.txt diff --git a/src/doc/theme-activate.txt b/src/docs/theme-activate.txt similarity index 100% rename from src/doc/theme-activate.txt rename to src/docs/theme-activate.txt diff --git a/src/doc/theme-delete.txt b/src/docs/theme-delete.txt similarity index 100% rename from src/doc/theme-delete.txt rename to src/docs/theme-delete.txt diff --git a/src/doc/theme-install.txt b/src/docs/theme-install.txt similarity index 100% rename from src/doc/theme-install.txt rename to src/docs/theme-install.txt diff --git a/src/doc/theme-path.txt b/src/docs/theme-path.txt similarity index 100% rename from src/doc/theme-path.txt rename to src/docs/theme-path.txt diff --git a/src/doc/theme-status.txt b/src/docs/theme-status.txt similarity index 100% rename from src/doc/theme-status.txt rename to src/docs/theme-status.txt diff --git a/src/doc/theme-update.txt b/src/docs/theme-update.txt similarity index 100% rename from src/doc/theme-update.txt rename to src/docs/theme-update.txt diff --git a/src/doc/transient.txt b/src/docs/transient.txt similarity index 100% rename from src/doc/transient.txt rename to src/docs/transient.txt diff --git a/src/doc/user-create.txt b/src/docs/user-create.txt similarity index 100% rename from src/doc/user-create.txt rename to src/docs/user-create.txt diff --git a/src/doc/user-delete.txt b/src/docs/user-delete.txt similarity index 100% rename from src/doc/user-delete.txt rename to src/docs/user-delete.txt diff --git a/src/doc/user-list.txt b/src/docs/user-list.txt similarity index 100% rename from src/doc/user-list.txt rename to src/docs/user-list.txt diff --git a/src/doc/user-meta.txt b/src/docs/user-meta.txt similarity index 100% rename from src/doc/user-meta.txt rename to src/docs/user-meta.txt diff --git a/src/doc/user-update.txt b/src/docs/user-update.txt similarity index 100% rename from src/doc/user-update.txt rename to src/docs/user-update.txt diff --git a/utils/doc-build b/utils/doc-build index a4bf43d081..8cb5c7c28c 100755 --- a/utils/doc-build +++ b/utils/doc-build @@ -6,7 +6,7 @@ # ln -s ../../utils/doc-build .git/hooks/pre-commit if [ $# -eq 0 ]; then - files=$(git diff --cached --name-only src/doc/) + files=$(git diff --cached --name-only src/docs/) else files=$@ fi diff --git a/utils/pear-build b/utils/pear-build index 07530db9a0..e044a8c4d0 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -6,7 +6,6 @@ set -ex mkdir -p src/data mkdir -p src/tests/unit-tests/php mkdir -p src/www -mkdir -p src/docs # temporarily move the .git dir, because phing is stupid git_dir=src/php/php-cli-tools/.git From 15009ab451eefdf97ec345ae221904e40dad928f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Sep 2012 14:31:00 +0300 Subject: [PATCH 0542/4858] wp cache switch_to_blog does not make sense as a standalone subcommands. see #155 --- man/cache.1 | 6 ----- src/docs/cache.txt | 4 ---- src/php/wp-cli/commands/internals/cache.php | 26 +-------------------- 3 files changed, 1 insertion(+), 35 deletions(-) diff --git a/man/cache.1 b/man/cache.1 index 6024971c06..553960fad2 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -105,12 +105,6 @@ Replace a value in cache with a new value\. Set a value in cache\. . .TP -\fBswitch_to_blog\fR: -. -.IP -Interact with the cache for the specified \fIblog_id\fR\. -. -.TP \fBtype\fR: . .IP diff --git a/src/docs/cache.txt b/src/docs/cache.txt index e28de79f66..069a875d30 100644 --- a/src/docs/cache.txt +++ b/src/docs/cache.txt @@ -69,10 +69,6 @@ wp cache type Set a value in cache. -* `switch_to_blog`: - - Interact with the cache for the specified <blog_id>. - * `type`: Report the type of object being used. diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index 546439036d..5c1233994c 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -281,30 +281,6 @@ public function set( $args, $assoc_args ) { WP_CLI::success( "Set object '$key' in group '$group'." ); } - /** - * Switch the blog id, which switches the cache keys for all values. - * - * @uses wp_cache_switch_to_blog - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void - */ - public function switch_to_blog( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache switch_to_blog <blog_id>' ); - exit; - } - - if ( ! function_exists( 'wp_cache_switch_to_blog' ) ) { - WP_CLI::warning( "Command cannot be executed because the 'wp_cache_switch_to_blog' function does not exist." ); - } - - $blog_id = $args[0]; - - wp_cache_switch_to_blog( $blog_id ); - } - /** * Attempts to determine which object cache is being used. * @@ -358,4 +334,4 @@ public function type( $args, $assoc_args ) { WP_CLI::print_value( $message ); } -} \ No newline at end of file +} From 9c30fe19f889da6f83c67f4af505c718d7a9efa0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Sep 2012 15:39:01 +0300 Subject: [PATCH 0543/4858] bump version to 0.7.0-alpha --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 7ad523325d..1fbd96dd96 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -5,7 +5,7 @@ die(-1); } -define( 'WP_CLI_VERSION', '0.6.0' ); +define( 'WP_CLI_VERSION', '0.7.0-alpha' ); // Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 9509bf4148c1840aaedee70ffc6a37f7dad3323c Mon Sep 17 00:00:00 2001 From: ozh <ozh@ozh.org> Date: Fri, 7 Sep 2012 14:52:32 +0200 Subject: [PATCH 0544/4858] Implementation of the "comment" command Subcommands: create, delete, trash, untrash, spam, unspam, approve, unapprove, status, count, last --- src/php/wp-cli/commands/internals/comment.php | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/comment.php diff --git a/src/php/wp-cli/commands/internals/comment.php b/src/php/wp-cli/commands/internals/comment.php new file mode 100644 index 0000000000..e641212953 --- /dev/null +++ b/src/php/wp-cli/commands/internals/comment.php @@ -0,0 +1,266 @@ +<?php +/** + * Implement 'comment' command + * + * @package wp-cli + * @subpackage commands/internals + */ + +// Register the 'comment' command handler +WP_CLI::add_command( 'comment', 'Comment_Command' ); + +class Comment_Command extends WP_CLI_Command { + + /** + * Basic help message + */ + static function help() { + WP_CLI::line( 'usage: wp comment [last|create|delete|trash|untrash|spam|unspam|approve|unapprove|count|status]' ); + } + + + /** + * Insert a comment. + * + * Example: wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" + * + * @param array $args} + * @param array $assoc_args + */ + public function create( $args, $assoc_args ) { + // Just one check: make sure the post actually exists + $comment_post_ID = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); + $post = get_post( $comment_post_ID ); + if ( empty( $post->comment_status ) ) { + WP_CLI::error( "Cannot find post $comment_post_ID" ); + } + + // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and avoid wp_die() formatted messages or notifications + $comment_id = wp_insert_comment( $assoc_args ); + + if ( 0 == $comment_id ) { + WP_CLI::error( "Could not create comment" ); + } + + if ( isset( $assoc_args['porcelain'] ) ) + WP_CLI::line( $comment_id ); + else + WP_CLI::success( "Inserted comment $comment_id." ); + } + + + /** + * Delete a comment + * + * Example: wp comment delete 15 --force + * + * @param array $args} + * @param array $assoc_args + */ + public function delete( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + // Boolean $force parameter to bypass trash and really delete + $force = ( isset( $assoc_args['force'] ) ? true : false ); + + if ( wp_delete_comment( $comment_id, $force ) ) { + WP_CLI::success( "Deleted comment $comment_id." ); + } else { + WP_CLI::error( "Failed deleting comment $comment_id" ); + } + } + + + /** + * Trash a comment + * + * Example: wp comment trash 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function trash( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + if ( wp_trash_comment( $comment_id ) ) { + WP_CLI::success( "Trashed comment $comment_id." ); + } else { + WP_CLI::error( "Failed trashing comment $comment_id" ); + } + } + + + /** + * Untrash a comment + * + * Example: wp comment untrash 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function untrash( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + if ( wp_untrash_comment( $comment_id ) ) { + WP_CLI::success( "Untrashed comment $comment_id." ); + } else { + WP_CLI::error( "Failed untrashing comment $comment_id" ); + } + } + + + /** + * Spam a comment + * + * Example: wp comment spam 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function spam( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + if ( wp_spam_comment( $comment_id ) ) { + WP_CLI::success( "Spammed comment $comment_id." ); + } else { + WP_CLI::error( "Failed spamming comment $comment_id" ); + } + } + + + /** + * Unspam a comment + * + * Example: wp comment unspam 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function unspam( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + if ( wp_unspam_comment( $comment_id ) ) { + WP_CLI::success( "Unspammed comment $comment_id." ); + } else { + WP_CLI::error( "Failed unspamming comment $comment_id" ); + } + } + + + /** + * Approve a comment + * + * Example: wp comment approve 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function approve( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + $comment = wp_set_comment_status( $comment_id, 'approve', true ); // last parameter 'true' to return a WP_Error object if there is a failure + + if ( is_wp_error( $comment ) ) { + WP_CLI::error( $comment ); + } else { + WP_CLI::success( "Approved comment $comment_id" ); + } + } + + + /** + * Unapprove a comment + * + * Example: wp comment unapprove 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function unapprove( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + $comment = wp_set_comment_status( $comment_id, 'hold', true ); + + if ( is_wp_error( $comment ) ) { + WP_CLI::error( $comment ); + } else { + WP_CLI::success( "Unapproved comment $comment_id" ); + } + } + + + /** + * Count comments, in whole blog or in a given post + * + * Example: "wp comment count 43" to count comments on post 43 + * Example: "wp comment count" to count comments on blog + * + * @param array $args} + * @param array $assoc_args + */ + public function count( $args, $assoc_args ) { + $post_id = ( isset( $args[0] ) && is_numeric( $args[0] ) ? $args[0] : 0 ); + + $comments = wp_count_comments( $post_id ); + // Move total_comments to the end of the object + $total = $comments->total_comments; + unset( $comments->total_comments ); + $comments->total_comments = $total; + + foreach( $comments as $status => $count ) { + WP_CLI::line( str_pad( "$status:", 17 ) . $count ); + } + } + + + /** + * Get status of a comment + * + * Example: wp comment status 15 + * + * @param array $args} + * @param array $assoc_args + */ + public function status( $args, $assoc_args ) { + $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + + $status = wp_get_comment_status( $comment_id ); + + if( false === $status ) { + WP_CLI::error( "Could not check status of comment $comment" ); + } else { + WP_CLI::line( $status ); + } + } + + + /** + * Get last approved comment. Options: --porcelain, --full|verbose + * + * @param array $args} + * @param array $assoc_args + */ + function last( $args = array(), $assoc_args = array() ) { + $last = get_comments( array( 'number' => 1, 'status' => 'approve' ) ); + extract( get_object_vars( $last[0] ) ); + // populates: comment_ID, comment_post_ID, comment_author, ... See http://codex.wordpress.org/Function_Reference/get_comments#Returns + + if ( isset( $assoc_args['porcelain'] ) ) { + WP_CLI::line( $comment_ID ); + exit( 1 ); + } + + WP_CLI::line( "%yLast approved comment :%n" ); + + if( isset( $assoc_args['verbose'] ) OR isset( $assoc_args['full'] ) ) { + $keys = array_keys( get_object_vars( $last[0] ) ); + } else { + $keys = array( 'comment_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); + } + foreach( $keys as $key ) { + WP_CLI::line( str_pad( "$key:", 23 ) . ${$key} ); + } + } + + +} From 384a2e435dae0769aef3fa01d201ec24996447b6 Mon Sep 17 00:00:00 2001 From: ozh <ozh@ozh.org> Date: Fri, 7 Sep 2012 15:39:51 +0200 Subject: [PATCH 0545/4858] Help files for the comment subcommands --- src/docs/comment-approve.txt | 16 ++++++++++++++ src/docs/comment-count.txt | 17 +++++++++++++++ src/docs/comment-create.txt | 21 +++++++++++++++++++ src/docs/comment-delete.txt | 20 ++++++++++++++++++ src/docs/comment-last.txt | 20 ++++++++++++++++++ src/docs/comment-spam.txt | 16 ++++++++++++++ src/docs/comment-status.txt | 16 ++++++++++++++ src/docs/comment-trash.txt | 16 ++++++++++++++ src/docs/comment-unapprove.txt | 16 ++++++++++++++ src/docs/comment-unspam.txt | 16 ++++++++++++++ src/docs/comment-untrash.txt | 16 ++++++++++++++ src/php/wp-cli/commands/internals/comment.php | 8 ------- 12 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 src/docs/comment-approve.txt create mode 100644 src/docs/comment-count.txt create mode 100644 src/docs/comment-create.txt create mode 100644 src/docs/comment-delete.txt create mode 100644 src/docs/comment-last.txt create mode 100644 src/docs/comment-spam.txt create mode 100644 src/docs/comment-status.txt create mode 100644 src/docs/comment-trash.txt create mode 100644 src/docs/comment-unapprove.txt create mode 100644 src/docs/comment-unspam.txt create mode 100644 src/docs/comment-untrash.txt diff --git a/src/docs/comment-approve.txt b/src/docs/comment-approve.txt new file mode 100644 index 0000000000..7ed0ac4a11 --- /dev/null +++ b/src/docs/comment-approve.txt @@ -0,0 +1,16 @@ +wp-comment-approve(1) -- Approve a comment. +==== + +## SYNOPSIS + +`wp comment approve` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to approve. + +## EXAMPLES + + wp comment approve 1337 diff --git a/src/docs/comment-count.txt b/src/docs/comment-count.txt new file mode 100644 index 0000000000..1c2abcf86e --- /dev/null +++ b/src/docs/comment-count.txt @@ -0,0 +1,17 @@ +wp-comment-count(1) -- Get total comments for blog or single post +==== + +## SYNOPSIS + +`wp comment count` [<ID>] + +## OPTIONS + +* `<ID>`: + + The ID of the post to count comments in + +## EXAMPLES + + wp comment count + wp comment count 42 diff --git a/src/docs/comment-create.txt b/src/docs/comment-create.txt new file mode 100644 index 0000000000..b64ecb4e0d --- /dev/null +++ b/src/docs/comment-create.txt @@ -0,0 +1,21 @@ +wp-comment-create(1) -- Create a new comment. +==== + +## SYNOPSIS + +`wp comment create` --<field>=<value> [--<field>=<value>...] [--porcelain] + +## OPTIONS + +* `--<field>`=<value>: + + Field values for the new comment. See wp_insert_comment(). + +* `--porcelain`: + + Output just the new comment id. + +## EXAMPLES + + wp comment create --comment_post_ID=15 --comment_content="hello blog" +--comment_author="wp-cli" diff --git a/src/docs/comment-delete.txt b/src/docs/comment-delete.txt new file mode 100644 index 0000000000..2cb016dcb7 --- /dev/null +++ b/src/docs/comment-delete.txt @@ -0,0 +1,20 @@ +wp-comment-delete(1) -- Delete a comment. +==== + +## SYNOPSIS + +`wp comment delete` <ID> [--force] + +## OPTIONS + +* `<ID>`: + + The ID of the comment to delete. + +* `--force`: + + Skip the trash bin. + +## EXAMPLES + + wp comment delete 1337 --force diff --git a/src/docs/comment-last.txt b/src/docs/comment-last.txt new file mode 100644 index 0000000000..dec1e1308b --- /dev/null +++ b/src/docs/comment-last.txt @@ -0,0 +1,20 @@ +wp-comment-last(1) -- Retrieve last approved comment +==== + +## SYNOPSIS + +`wp comment last` [--porcelain] [--full|verbose] + +## OPTIONS + +* `--porcelain`: + + Output just the last comment id. + +* `--full` or `--verbose`: + + Output complete comment information + +## EXAMPLES + + wp comment last diff --git a/src/docs/comment-spam.txt b/src/docs/comment-spam.txt new file mode 100644 index 0000000000..0fcdaf9a6d --- /dev/null +++ b/src/docs/comment-spam.txt @@ -0,0 +1,16 @@ +wp-comment-spam(1) -- Mark a comment as spam. +==== + +## SYNOPSIS + +`wp comment spam` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to mark as spam. + +## EXAMPLES + + wp comment spam 1337 diff --git a/src/docs/comment-status.txt b/src/docs/comment-status.txt new file mode 100644 index 0000000000..ee51ec4fd5 --- /dev/null +++ b/src/docs/comment-status.txt @@ -0,0 +1,16 @@ +wp-comment-status(1) -- Get status of a comment +==== + +## SYNOPSIS + +`wp comment status` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to check + +## EXAMPLES + + wp comment status 1337 diff --git a/src/docs/comment-trash.txt b/src/docs/comment-trash.txt new file mode 100644 index 0000000000..791968f524 --- /dev/null +++ b/src/docs/comment-trash.txt @@ -0,0 +1,16 @@ +wp-comment-trash(1) -- Trash a comment. +==== + +## SYNOPSIS + +`wp comment trash` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to trash. + +## EXAMPLES + + wp comment trash 1337 diff --git a/src/docs/comment-unapprove.txt b/src/docs/comment-unapprove.txt new file mode 100644 index 0000000000..1fee7ac486 --- /dev/null +++ b/src/docs/comment-unapprove.txt @@ -0,0 +1,16 @@ +wp-comment-unapprove(1) -- Unapprove a comment. +==== + +## SYNOPSIS + +`wp comment unapprove` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to unapprove. + +## EXAMPLES + + wp comment unapprove 1337 diff --git a/src/docs/comment-unspam.txt b/src/docs/comment-unspam.txt new file mode 100644 index 0000000000..59e9ff4944 --- /dev/null +++ b/src/docs/comment-unspam.txt @@ -0,0 +1,16 @@ +wp-comment-unspam(1) -- Unmark a comment as spam. +==== + +## SYNOPSIS + +`wp comment unspam` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to unmark as spam. + +## EXAMPLES + + wp comment unspam 1337 diff --git a/src/docs/comment-untrash.txt b/src/docs/comment-untrash.txt new file mode 100644 index 0000000000..d35967a3fd --- /dev/null +++ b/src/docs/comment-untrash.txt @@ -0,0 +1,16 @@ +wp-comment-untrash(1) -- Untrash a comment. +==== + +## SYNOPSIS + +`wp comment untrash` <ID> + +## OPTIONS + +* `<ID>`: + + The ID of the comment to untrash. + +## EXAMPLES + + wp comment untrash 1337 diff --git a/src/php/wp-cli/commands/internals/comment.php b/src/php/wp-cli/commands/internals/comment.php index e641212953..b6b4abc93c 100644 --- a/src/php/wp-cli/commands/internals/comment.php +++ b/src/php/wp-cli/commands/internals/comment.php @@ -11,14 +11,6 @@ class Comment_Command extends WP_CLI_Command { - /** - * Basic help message - */ - static function help() { - WP_CLI::line( 'usage: wp comment [last|create|delete|trash|untrash|spam|unspam|approve|unapprove|count|status]' ); - } - - /** * Insert a comment. * From 6ade0b17cb51c0fabc49332f335778b1655569fa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Sep 2012 17:03:46 +0300 Subject: [PATCH 0546/4858] add man pages. see #158 --- man/comment-approve.1 | 27 +++++++++++++++++++++++++++ man/comment-count.1 | 28 ++++++++++++++++++++++++++++ man/comment-create.1 | 35 +++++++++++++++++++++++++++++++++++ man/comment-delete.1 | 33 +++++++++++++++++++++++++++++++++ man/comment-last.1 | 33 +++++++++++++++++++++++++++++++++ man/comment-spam.1 | 27 +++++++++++++++++++++++++++ man/comment-status.1 | 27 +++++++++++++++++++++++++++ man/comment-trash.1 | 27 +++++++++++++++++++++++++++ man/comment-unapprove.1 | 27 +++++++++++++++++++++++++++ man/comment-unspam.1 | 27 +++++++++++++++++++++++++++ man/comment-untrash.1 | 27 +++++++++++++++++++++++++++ 11 files changed, 318 insertions(+) create mode 100644 man/comment-approve.1 create mode 100644 man/comment-count.1 create mode 100644 man/comment-create.1 create mode 100644 man/comment-delete.1 create mode 100644 man/comment-last.1 create mode 100644 man/comment-spam.1 create mode 100644 man/comment-status.1 create mode 100644 man/comment-trash.1 create mode 100644 man/comment-unapprove.1 create mode 100644 man/comment-unspam.1 create mode 100644 man/comment-untrash.1 diff --git a/man/comment-approve.1 b/man/comment-approve.1 new file mode 100644 index 0000000000..5fbb4caa7c --- /dev/null +++ b/man/comment-approve.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-APPROVE" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-approve\fR \- Approve a comment\. +. +.SH "SYNOPSIS" +\fBwp comment approve\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to approve\. +. +.SH "EXAMPLES" +. +.nf + +wp comment approve 1337 +. +.fi + diff --git a/man/comment-count.1 b/man/comment-count.1 new file mode 100644 index 0000000000..733606c17b --- /dev/null +++ b/man/comment-count.1 @@ -0,0 +1,28 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-COUNT" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-count\fR \- Get total comments for blog or single post +. +.SH "SYNOPSIS" +\fBwp comment count\fR [\fIID\fR] +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the post to count comments in +. +.SH "EXAMPLES" +. +.nf + +wp comment count +wp comment count 42 +. +.fi + diff --git a/man/comment-create.1 b/man/comment-create.1 new file mode 100644 index 0000000000..b164b96e7a --- /dev/null +++ b/man/comment-create.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-CREATE" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-create\fR \- Create a new comment\. +. +.SH "SYNOPSIS" +\fBwp comment create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] [\-\-porcelain] +. +.SH "OPTIONS" +. +.TP +\fB\-\-<field>\fR=\fIvalue\fR: +. +.IP +Field values for the new comment\. See wp_insert_comment()\. +. +.TP +\fB\-\-porcelain\fR: +. +.IP +Output just the new comment id\. +. +.SH "EXAMPLES" +. +.nf + +wp comment create \-\-comment_post_ID=15 \-\-comment_content="hello blog" +. +.fi +. +.P +\-\-comment_author="wp\-cli" diff --git a/man/comment-delete.1 b/man/comment-delete.1 new file mode 100644 index 0000000000..e7daaf6d6f --- /dev/null +++ b/man/comment-delete.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-DELETE" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-delete\fR \- Delete a comment\. +. +.SH "SYNOPSIS" +\fBwp comment delete\fR \fIID\fR [\-\-force] +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to delete\. +. +.TP +\fB\-\-force\fR: +. +.IP +Skip the trash bin\. +. +.SH "EXAMPLES" +. +.nf + +wp comment delete 1337 \-\-force +. +.fi + diff --git a/man/comment-last.1 b/man/comment-last.1 new file mode 100644 index 0000000000..ee29cdc9ff --- /dev/null +++ b/man/comment-last.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-LAST" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-last\fR \- Retrieve last approved comment +. +.SH "SYNOPSIS" +\fBwp comment last\fR [\-\-porcelain] [\-\-full|verbose] +. +.SH "OPTIONS" +. +.TP +\fB\-\-porcelain\fR: +. +.IP +Output just the last comment id\. +. +.TP +\fB\-\-full\fR or \fB\-\-verbose\fR: +. +.IP +Output complete comment information +. +.SH "EXAMPLES" +. +.nf + +wp comment last +. +.fi + diff --git a/man/comment-spam.1 b/man/comment-spam.1 new file mode 100644 index 0000000000..303d179e78 --- /dev/null +++ b/man/comment-spam.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-SPAM" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-spam\fR \- Mark a comment as spam\. +. +.SH "SYNOPSIS" +\fBwp comment spam\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to mark as spam\. +. +.SH "EXAMPLES" +. +.nf + +wp comment spam 1337 +. +.fi + diff --git a/man/comment-status.1 b/man/comment-status.1 new file mode 100644 index 0000000000..6ca168f9d0 --- /dev/null +++ b/man/comment-status.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-STATUS" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-status\fR \- Get status of a comment +. +.SH "SYNOPSIS" +\fBwp comment status\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to check +. +.SH "EXAMPLES" +. +.nf + +wp comment status 1337 +. +.fi + diff --git a/man/comment-trash.1 b/man/comment-trash.1 new file mode 100644 index 0000000000..cf451e98f4 --- /dev/null +++ b/man/comment-trash.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-TRASH" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-trash\fR \- Trash a comment\. +. +.SH "SYNOPSIS" +\fBwp comment trash\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to trash\. +. +.SH "EXAMPLES" +. +.nf + +wp comment trash 1337 +. +.fi + diff --git a/man/comment-unapprove.1 b/man/comment-unapprove.1 new file mode 100644 index 0000000000..7df1204dac --- /dev/null +++ b/man/comment-unapprove.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-UNAPPROVE" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-unapprove\fR \- Unapprove a comment\. +. +.SH "SYNOPSIS" +\fBwp comment unapprove\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to unapprove\. +. +.SH "EXAMPLES" +. +.nf + +wp comment unapprove 1337 +. +.fi + diff --git a/man/comment-unspam.1 b/man/comment-unspam.1 new file mode 100644 index 0000000000..4eb765e917 --- /dev/null +++ b/man/comment-unspam.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-UNSPAM" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-unspam\fR \- Unmark a comment as spam\. +. +.SH "SYNOPSIS" +\fBwp comment unspam\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to unmark as spam\. +. +.SH "EXAMPLES" +. +.nf + +wp comment unspam 1337 +. +.fi + diff --git a/man/comment-untrash.1 b/man/comment-untrash.1 new file mode 100644 index 0000000000..223fd5cfc5 --- /dev/null +++ b/man/comment-untrash.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-COMMENT\-UNTRASH" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-comment\-untrash\fR \- Untrash a comment\. +. +.SH "SYNOPSIS" +\fBwp comment untrash\fR \fIID\fR +. +.SH "OPTIONS" +. +.TP +\fB<ID>\fR: +. +.IP +The ID of the comment to untrash\. +. +.SH "EXAMPLES" +. +.nf + +wp comment untrash 1337 +. +.fi + From 725a4b1a4172a2513fa9c3330cc5d3ecc08e19a3 Mon Sep 17 00:00:00 2001 From: Nathaniel Taintor <ntaintor@janrain.com> Date: Fri, 7 Sep 2012 16:20:46 -0700 Subject: [PATCH 0547/4858] Implement rewrite command Adds a command for wp rewrite, with three methods: - wp rewrite flush (--verbose) (--soft) - wp rewrite structure (structure) (--category-base=catstruct) (--tag-base=tagstruct) (--verbose) - wp rewrite dump --- src/php/wp-cli/commands/internals/rewrite.php | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/rewrite.php diff --git a/src/php/wp-cli/commands/internals/rewrite.php b/src/php/wp-cli/commands/internals/rewrite.php new file mode 100644 index 0000000000..839b595917 --- /dev/null +++ b/src/php/wp-cli/commands/internals/rewrite.php @@ -0,0 +1,119 @@ +<?php + +WP_CLI:: add_command('rewrite', 'Rewrite_Command'); + +/** + * Implement rewrite command + * + * @package wp-cli + * @subpackage commands/internal + */ +class Rewrite_Command extends WP_CLI_Command { + + protected $aliases = array( + ); + + /** + * Flush rules + * + * @param array $args + * @param array $assoc_args + */ + public function flush( $args, $assoc_args ) { + + $verbose = ( isset( $assoc_args['verbose'] ) ); + $hard = ( isset( $assoc_args['soft'] ) ) ? false : true; + + if ( $verbose ) + WP_CLI::line( "Triggering ".( ( $hard ) ? 'hard' : 'soft' ). " permalink flush." ); + + flush_rewrite_rules( $hard ); + } + + /** + * Set permalink structure + * + * @param array $args + * @param array $assoc_args + */ + public function structure( $args, $assoc_args ) { + if ( !count( $args ) && !count( $assoc_args ) ) { + WP_CLI::line( "usage: wp rewrite structure <new-permalink-structure>" ); + exit; + } + global $wp_rewrite; + + // copypasta from /wp-admin/options-permalink.php + $home_path = get_home_path(); + $iis7_permalinks = iis7_supports_permalinks(); + + $prefix = $blog_prefix = ''; + if ( ! got_mod_rewrite() && ! $iis7_permalinks ) + $prefix = '/index.php'; + if ( is_multisite() && !is_subdomain_install() && is_main_site() ) + $blog_prefix = '/blog'; + + $verbose = ( isset( $assoc_args['verbose'] ) ); + + + // Update base permastruct if argument is provided + if ( isset( $args[0] ) ) { + + if ( $verbose ) + WP_CLI::line( "Setting permalink structure to ". $args[0] ); + + $permalink_structure = ( $args[0] == 'default' ) ? '' : $args[0]; + + if ( ! empty( $permalink_structure ) ) { + $permalink_structure = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', $permalink_structure ) ); + if ( $prefix && $blog_prefix ) + $permalink_structure = $prefix . preg_replace( '#^/?index\.php#', '', $permalink_structure ); + else + $permalink_structure = $blog_prefix . $permalink_structure; + } + $wp_rewrite->set_permalink_structure( $permalink_structure ); + } + + // Update category or tag bases + if ( isset( $assoc_args['category-base'] ) ) { + + if ( $verbose ) + WP_CLI::line( "Setting category base to ". $assoc_args['category-base'] ); + + $category_base = $assoc_args['category-base']; + if ( ! empty( $category_base ) ) + $category_base = $blog_prefix . preg_replace('#/+#', '/', '/' . str_replace( '#', '', $category_base ) ); + $wp_rewrite->set_category_base( $category_base ); + } + + if ( isset( $assoc_args['tag-base'] ) ) { + + if ( $verbose ) + WP_CLI::line( "Setting tag base to ". $assoc_args['tag-base'] ); + + $tag_base = $assoc_args['tag-base']; + if ( ! empty( $tag_base ) ) + $tag_base = $blog_prefix . preg_replace('#/+#', '/', '/' . str_replace( '#', '', $tag_base ) ); + $wp_rewrite->set_tag_base( $tag_base ); + } + + + flush_rewrite_rules( $hard ); + } + + /** + * Dump rewrite rules + * + * @param none + */ + public function dump() { + + $rules = get_option( 'rewrite_rules' ); + + foreach ( $rules as $route => $rule ) + WP_CLI::line( $route . "\t" . $rule ); + + } +} + +?> From cf595d5f987d946b6245134c3aa00e53d5763e5e Mon Sep 17 00:00:00 2001 From: Nathaniel Taintor <ntaintor@janrain.com> Date: Sun, 9 Sep 2012 13:27:26 -0700 Subject: [PATCH 0548/4858] Remove useless '--verbose' arg option There's no useful information to provide here, so allowing people to choose verbose output is useless. --- src/php/wp-cli/commands/internals/rewrite.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/php/wp-cli/commands/internals/rewrite.php b/src/php/wp-cli/commands/internals/rewrite.php index 839b595917..f57282aa09 100644 --- a/src/php/wp-cli/commands/internals/rewrite.php +++ b/src/php/wp-cli/commands/internals/rewrite.php @@ -20,13 +20,7 @@ class Rewrite_Command extends WP_CLI_Command { * @param array $assoc_args */ public function flush( $args, $assoc_args ) { - - $verbose = ( isset( $assoc_args['verbose'] ) ); $hard = ( isset( $assoc_args['soft'] ) ) ? false : true; - - if ( $verbose ) - WP_CLI::line( "Triggering ".( ( $hard ) ? 'hard' : 'soft' ). " permalink flush." ); - flush_rewrite_rules( $hard ); } @@ -53,15 +47,9 @@ public function structure( $args, $assoc_args ) { if ( is_multisite() && !is_subdomain_install() && is_main_site() ) $blog_prefix = '/blog'; - $verbose = ( isset( $assoc_args['verbose'] ) ); - - // Update base permastruct if argument is provided if ( isset( $args[0] ) ) { - if ( $verbose ) - WP_CLI::line( "Setting permalink structure to ". $args[0] ); - $permalink_structure = ( $args[0] == 'default' ) ? '' : $args[0]; if ( ! empty( $permalink_structure ) ) { @@ -77,9 +65,6 @@ public function structure( $args, $assoc_args ) { // Update category or tag bases if ( isset( $assoc_args['category-base'] ) ) { - if ( $verbose ) - WP_CLI::line( "Setting category base to ". $assoc_args['category-base'] ); - $category_base = $assoc_args['category-base']; if ( ! empty( $category_base ) ) $category_base = $blog_prefix . preg_replace('#/+#', '/', '/' . str_replace( '#', '', $category_base ) ); @@ -88,9 +73,6 @@ public function structure( $args, $assoc_args ) { if ( isset( $assoc_args['tag-base'] ) ) { - if ( $verbose ) - WP_CLI::line( "Setting tag base to ". $assoc_args['tag-base'] ); - $tag_base = $assoc_args['tag-base']; if ( ! empty( $tag_base ) ) $tag_base = $blog_prefix . preg_replace('#/+#', '/', '/' . str_replace( '#', '', $tag_base ) ); From 33638443602cec68d5d3f54802d9802b5b26ea7a Mon Sep 17 00:00:00 2001 From: Nathaniel Taintor <ntaintor@janrain.com> Date: Sun, 9 Sep 2012 13:37:11 -0700 Subject: [PATCH 0549/4858] Add --json option to wp rewrite dump I'm not imagining any situations where you would actually want this data in json format, but it seems as though the option should be available to parallel the other subcommands where --json is available as a possible output format. --- src/php/wp-cli/commands/internals/rewrite.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/rewrite.php b/src/php/wp-cli/commands/internals/rewrite.php index f57282aa09..feb28d45f3 100644 --- a/src/php/wp-cli/commands/internals/rewrite.php +++ b/src/php/wp-cli/commands/internals/rewrite.php @@ -16,8 +16,8 @@ class Rewrite_Command extends WP_CLI_Command { /** * Flush rules * - * @param array $args - * @param array $assoc_args + * @param array $args not used + * @param array $assoc_args --soft or --hard (default) */ public function flush( $args, $assoc_args ) { $hard = ( isset( $assoc_args['soft'] ) ) ? false : true; @@ -86,16 +86,18 @@ public function structure( $args, $assoc_args ) { /** * Dump rewrite rules * - * @param none + * @param array $args + * @param array $assoc_args */ - public function dump() { + public function dump( $args, $assoc_args ) { $rules = get_option( 'rewrite_rules' ); - foreach ( $rules as $route => $rule ) - WP_CLI::line( $route . "\t" . $rule ); + if ( isset( $assoc_args['json'] ) ) + echo json_encode( $rules ); + else + foreach ( $rules as $route => $rule ) + WP_CLI::line( $route . "\t" . $rule ); } } - -?> From df849aa984f1667cd38b0934657bffe2e57343ba Mon Sep 17 00:00:00 2001 From: Nathaniel Taintor <ntaintor@janrain.com> Date: Mon, 10 Sep 2012 09:19:14 -0700 Subject: [PATCH 0550/4858] Add man pages --- man/rewrite-dump.1 | 19 +++++++++++++++++++ man/rewrite-flush.1 | 19 +++++++++++++++++++ man/rewrite-structure.1 | 31 +++++++++++++++++++++++++++++++ src/docs/rewrite-dump.txt | 12 ++++++++++++ src/docs/rewrite-flush.txt | 14 ++++++++++++++ src/docs/rewrite-structure.txt | 21 +++++++++++++++++++++ 6 files changed, 116 insertions(+) create mode 100644 man/rewrite-dump.1 create mode 100644 man/rewrite-flush.1 create mode 100644 man/rewrite-structure.1 create mode 100644 src/docs/rewrite-dump.txt create mode 100644 src/docs/rewrite-flush.txt create mode 100644 src/docs/rewrite-structure.txt diff --git a/man/rewrite-dump.1 b/man/rewrite-dump.1 new file mode 100644 index 0000000000..fffedb924c --- /dev/null +++ b/man/rewrite-dump.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "REWRITE\-DUMP" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBrewrite\-dump\fR \- Print current rewrite rules to STDOUT\. +. +.SH "SYNOPSIS" +\fBwp rewrite dump\fR [\-\-json] +. +.SH "OPTIONS" +. +.TP +\fB\-\-json\fR: +. +.IP +Output rules in JSON format\. + diff --git a/man/rewrite-flush.1 b/man/rewrite-flush.1 new file mode 100644 index 0000000000..02a631a4ad --- /dev/null +++ b/man/rewrite-flush.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "REWRITE\-FLUSH" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBrewrite\-flush\fR \- Flush rewrite rules\. +. +.SH "SYNOPSIS" +\fBwp rewrite flush\fR [\-\-soft] +. +.SH "OPTIONS" +. +.TP +\fB\-\-soft\fR: +. +.IP +Perform a soft flush \- do not overwrite \fB\.htaccess\fR\. The default is to update \fB\.htaccess\fR rules as well as rewrite rules in database\. + diff --git a/man/rewrite-structure.1 b/man/rewrite-structure.1 new file mode 100644 index 0000000000..833cd3e3a1 --- /dev/null +++ b/man/rewrite-structure.1 @@ -0,0 +1,31 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "REWRITE\-STRUCTURE" "1" "September 2012" "" "WP-CLI" +. +.SH "NAME" +\fBrewrite\-structure\fR \- Update the permalink structure +. +.SH "SYNOPSIS" +\fBwp rewrite structure\fR \fIpermastruct\fR [\-\-category\-base=\fIcategorybase\fR] [\-\-tag\-base=\fItagbase\fR] +. +.SH "OPTIONS" +. +.TP +\fIpermastruct\fR: +. +.IP +The new permalink structure to apply; like "/%year%/%monthnum%/%postname%"\. +. +.TP +\fB\-\-category\-base\fR=\fIcategorybase\fR: +. +.IP +Set the base for category permalinks, ie \'/category/\'\. +. +.TP +\fB\-\-tag\-base\fR=\fItagbase\fR: +. +.IP +Set the base for tag permalinks, ie \'/tag/\'\. + diff --git a/src/docs/rewrite-dump.txt b/src/docs/rewrite-dump.txt new file mode 100644 index 0000000000..2a39b8527d --- /dev/null +++ b/src/docs/rewrite-dump.txt @@ -0,0 +1,12 @@ +rewrite-dump(1) -- Print current rewrite rules to STDOUT. +==== + +## SYNOPSIS + +`wp rewrite dump` [--json] + +## OPTIONS + +* `--json`: + + Output rules in JSON format. diff --git a/src/docs/rewrite-flush.txt b/src/docs/rewrite-flush.txt new file mode 100644 index 0000000000..e7d11dd391 --- /dev/null +++ b/src/docs/rewrite-flush.txt @@ -0,0 +1,14 @@ +rewrite-flush(1) -- Flush rewrite rules. +==== + +## SYNOPSIS + +`wp rewrite flush` [--soft] + +## OPTIONS + +* `--soft`: + + Perform a soft flush - do not overwrite `.htaccess`. The default is to update + `.htaccess` rules as well as rewrite rules in database. + diff --git a/src/docs/rewrite-structure.txt b/src/docs/rewrite-structure.txt new file mode 100644 index 0000000000..8e77ea39db --- /dev/null +++ b/src/docs/rewrite-structure.txt @@ -0,0 +1,21 @@ +rewrite-structure(1) -- Update the permalink structure +==== + +## SYNOPSIS + +`wp rewrite structure` <permastruct> [--category-base=<categorybase>] [--tag-base=<tagbase>] + +## OPTIONS + +* <permastruct>: + + The new permalink structure to apply; like "/%year%/%monthnum%/%postname%". + +* `--category-base`=<categorybase>: + + Set the base for category permalinks, ie '/category/'. + +* `--tag-base`=<tagbase>: + + Set the base for tag permalinks, ie '/tag/'. + From bafab795ffcbcc4799029b65cb09e41b09c87d63 Mon Sep 17 00:00:00 2001 From: Ben <benjamin.j.brooks@gmail.com> Date: Mon, 10 Sep 2012 12:03:13 -0700 Subject: [PATCH 0551/4858] Updated PHP path for MAMP 2.0.5 Updating the 'Special case for *AMP installers' to reflect that the current version of MAMP PRO stores the PHP executable in /Applications/MAMP/bin/php/php5.3*/bin/php --- src/bin/wp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wp b/src/bin/wp index 1856f53e0e..fa1037e4e7 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -67,7 +67,7 @@ else fi # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + for amp_php in /Applications/MAMP/bin/php/php5.3*/bin/php /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do if [ -x $amp_php ]; then php=$amp_php break From 17f6c144c5507af3c70f4969e614f932b8ec835e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 15 Sep 2012 13:44:45 -0700 Subject: [PATCH 0552/4858] First pass at extending the 'delete' command to support deleting arbitrary sets of posts based on standard WP_Query arguments --- src/php/wp-cli/commands/internals/post.php | 50 +++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 97687b56c8..490c07874c 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -52,18 +52,58 @@ public function update( $args, $assoc_args ) { } /** - * Delete a post + * Delete a single post, or series of posts based on arguments * * @param array $args * @param array $assoc_args */ public function delete( $args, $assoc_args ) { - $post_id = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); - if ( wp_delete_post( $post_id, isset( $assoc_args['force'] ) ) ) { - WP_CLI::success( "Deleted post $post_id." ); + $defaults = array( + 'post_id' => null, + 'post_type' => null, + 'author' => null, + 'post_status' => 'any', + 'force' => false, + ); + $assoc_args = wp_parse_args( $assoc_args, $defaults ); + + // Support for simply passing the post ID as the first argument + if ( isset( $args[0] ) && is_numeric( $args[0] ) ) + $post_id = $args[0]; + else if ( is_numeric( $assoc_args['post_id'] ) ) + $post_id = $assoc_args['post_id']; + else + $post_id = false; + + if ( $post_id ) { + $posts_to_delete = array( $post_id ); } else { - WP_CLI::error( "Failed deleting post $post_id." ); + $query_args = array( + 'fields' => 'ids', + 'posts_per_page' => -1, + 'post_type' => $assoc_args['post_type'], + 'author' => $assoc_args['author'], + 'post_status' => $assoc_args['post_status'], + ); + $maybe_posts = new WP_Query( $query_args ); + if ( ! is_wp_error( $maybe_posts ) ) + $posts_to_delete = $maybe_posts->posts; + else + $posts_to_delete = array(); + } + + if ( empty( $posts_to_delete ) ) { + WP_CLI::error( "No posts to delete." ); + } + + foreach( $posts_to_delete as $post_id ) { + if ( wp_delete_post( $post_id, (bool)$assoc_args['force'] ) ) { + $action = ( (bool) $assoc_args['force'] ) ? 'Deleted' : 'Trashed'; + WP_CLI::success( "{$action} post $post_id." ); + } else { + WP_CLI::error( "Failed deleting post $post_id." ); + } } } } From 7865cc0e98104932f5e0c85c8e882605a733b4e7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 15 Sep 2012 14:01:30 -0700 Subject: [PATCH 0553/4858] Use WP_Query's native 'p' parameter, instead of inventing our own. Props @scribu --- src/php/wp-cli/commands/internals/post.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 490c07874c..ececdb6e8e 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -60,7 +60,7 @@ public function update( $args, $assoc_args ) { public function delete( $args, $assoc_args ) { $defaults = array( - 'post_id' => null, + 'p' => null, 'post_type' => null, 'author' => null, 'post_status' => 'any', @@ -71,8 +71,8 @@ public function delete( $args, $assoc_args ) { // Support for simply passing the post ID as the first argument if ( isset( $args[0] ) && is_numeric( $args[0] ) ) $post_id = $args[0]; - else if ( is_numeric( $assoc_args['post_id'] ) ) - $post_id = $assoc_args['post_id']; + else if ( is_numeric( $assoc_args['p'] ) ) + $post_id = $assoc_args['p']; else $post_id = false; From ad025219f49b22cc9c7c96609b82193670e414f9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 15 Sep 2012 14:04:29 -0700 Subject: [PATCH 0554/4858] WP_Query shouldn't ever be a WP_Error object, so we don't need to check as such. Props @scribu --- src/php/wp-cli/commands/internals/post.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index ececdb6e8e..7e0e1c9a5a 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -87,10 +87,7 @@ public function delete( $args, $assoc_args ) { 'post_status' => $assoc_args['post_status'], ); $maybe_posts = new WP_Query( $query_args ); - if ( ! is_wp_error( $maybe_posts ) ) - $posts_to_delete = $maybe_posts->posts; - else - $posts_to_delete = array(); + $posts_to_delete = $maybe_posts->posts; } if ( empty( $posts_to_delete ) ) { From 682736c829ad0d87a8214931bd46cf5b8f625b5c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 15 Sep 2012 14:10:19 -0700 Subject: [PATCH 0555/4858] s/author/post_author/ --- src/php/wp-cli/commands/internals/post.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 7e0e1c9a5a..06b80ded54 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -62,7 +62,7 @@ public function delete( $args, $assoc_args ) { $defaults = array( 'p' => null, 'post_type' => null, - 'author' => null, + 'post_author' => null, 'post_status' => 'any', 'force' => false, ); @@ -83,7 +83,7 @@ public function delete( $args, $assoc_args ) { 'fields' => 'ids', 'posts_per_page' => -1, 'post_type' => $assoc_args['post_type'], - 'author' => $assoc_args['author'], + 'post_author' => $assoc_args['post_author'], 'post_status' => $assoc_args['post_status'], ); $maybe_posts = new WP_Query( $query_args ); From 7640b7e47b72cebb332d495c392f5048273983d1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 15 Sep 2012 14:14:12 -0700 Subject: [PATCH 0556/4858] Update 'wp post delete' docs with information about new arguments --- src/doc/post-delete.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/doc/post-delete.txt b/src/doc/post-delete.txt index 97c07cc74a..f2a017101a 100644 --- a/src/doc/post-delete.txt +++ b/src/doc/post-delete.txt @@ -3,7 +3,7 @@ wp-post-delete(1) -- Delete a WordPress post. ## SYNOPSIS -`wp post delete` <ID> [--force] +`wp post delete` [<ID>] [--post_type=<value>] [--post_author=<value>] [--post_status=<value>] [--force] ## OPTIONS @@ -11,6 +11,18 @@ wp-post-delete(1) -- Delete a WordPress post. The ID of the post to delete. +* `--post_type`: + + Trash or delete all posts of a given post type + +* `--post_author`: + + Trash or delete all posts written by a specific user + +* `--post_status`: + + Trash or delete all posts of a given post status + * `--force`: Skip the trash bin. @@ -18,3 +30,5 @@ wp-post-delete(1) -- Delete a WordPress post. ## EXAMPLES wp post delete 123 --force + + wp post delete --post_type=page --post_status=draft From 743e2616c7d3417564fe6e93b1276d3f49a2c8a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 15:58:47 +0300 Subject: [PATCH 0557/4858] split logic from presentation in plugin/theme get_status() --- src/php/wp-cli/commands/internals/plugin.php | 51 +++++++++++++++----- src/php/wp-cli/commands/internals/theme.php | 33 ++++++++++--- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 1fa3433876..301ada39b8 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -86,21 +86,46 @@ protected function status_all() { WP_CLI::legend( $legend ); } + private function _get_status( $file ) { + if ( isset( $this->mu_plugins[ $file ] ) ) + return 'must-use'; + + if ( is_plugin_active_for_network( $file ) ) + return 'active-network'; + + if ( is_plugin_active( $file ) ) + return 'active'; + + return 'inactive'; + } + private function get_status( $file, $long = false ) { - if ( isset( $this->mu_plugins[ $file ] ) ) { - $line = '%c'; - $line .= $long ? 'Must Use' : 'M'; - } elseif ( is_plugin_active_for_network( $file ) ) { - $line = '%b'; - $line .= $long ? 'Network Active' : 'N'; - } elseif ( is_plugin_active( $file ) ) { - $line = '%g'; - $line .= $long ? 'Active' : 'A'; - } else { - $line = $long ? 'Inactive' : 'I'; - } + $status = $this->_get_status( $file ); + + $colors = array( + 'inactive' => '', + 'active' => '%g', + 'active-network' => '%g', + 'must-use' => '%c', + ); + + $map_short = array( + 'inactive' => 'I', + 'active' => 'A', + 'active-network' => 'N', + 'must-use' => 'M', + ); + + $map_long = array( + 'inactive' => 'Inactive', + 'active' => 'Active', + 'active-network' => 'Must Use', + 'must-use' => 'Network Active', + ); + + $active_map = $long ? $map_long : $map_short; - return $line; + return $colors[ $status ] . $active_map[ $status ]; } /** diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index be09b205f2..b57e007566 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -63,15 +63,34 @@ protected function status_all() { WP_CLI::legend( $legend ); } + private function _get_status( $stylesheet ) { + if ( $this->is_active_theme( $stylesheet ) ) + return 'active'; + + return 'inactive'; + } + private function get_status( $stylesheet, $long = false ) { - if ( $this->is_active_theme( $stylesheet ) ) { - $line = '%g'; - $line .= $long ? 'Active' : 'A'; - } else { - $line = $long ? 'Inactive' : 'I'; - } + $status = $this->_get_status( $stylesheet ); + + $colors = array( + 'inactive' => '', + 'active' => '%g', + ); + + $map_short = array( + 'inactive' => 'I', + 'active' => 'A', + ); + + $map_long = array( + 'inactive' => 'Inactive', + 'active' => 'Active', + ); + + $active_map = $long ? $map_long : $map_short; - return $line; + return $colors[ $status ] . $active_map[ $status ]; } /** From 419b587e2a035ef0686a0067820de9f6c0d99156 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 16:08:11 +0300 Subject: [PATCH 0558/4858] renamings: _get_status() -> get_status() -> format_status() --- src/php/wp-cli/commands/internals/plugin.php | 10 +++++----- src/php/wp-cli/commands/internals/theme.php | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 301ada39b8..e2151a83c0 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -28,7 +28,7 @@ function __construct( $args, $assoc_args ) { protected function status_single( $file, $name ) { $details = $this->get_details( $file ); - $status = $this->get_status( $file, true ); + $status = $this->format_status( $file, true ); $version = $details[ 'Version' ]; @@ -66,7 +66,7 @@ protected function status_all() { $line = ' '; } - $line .= $this->get_status( $file ) . " $name%n"; + $line .= $this->format_status( $file ) . " $name%n"; WP_CLI::line( $line ); } @@ -86,7 +86,7 @@ protected function status_all() { WP_CLI::legend( $legend ); } - private function _get_status( $file ) { + private function get_status( $file ) { if ( isset( $this->mu_plugins[ $file ] ) ) return 'must-use'; @@ -99,8 +99,8 @@ private function _get_status( $file ) { return 'inactive'; } - private function get_status( $file, $long = false ) { - $status = $this->_get_status( $file ); + private function format_status( $file, $long = false ) { + $status = $this->get_status( $file ); $colors = array( 'inactive' => '', diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index b57e007566..82564c9eea 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -19,7 +19,7 @@ class Theme_Command extends WP_CLI_Command_With_Upgrade { protected function status_single( $stylesheet, $name ) { $details = get_theme_data( $stylesheet ); - $status = $this->get_status( $stylesheet, true ); + $status = $this->format_status( $stylesheet, true ); $version = $details['Version']; @@ -47,7 +47,7 @@ protected function status_all() { $stylesheet = $this->get_stylesheet_path( $theme['Stylesheet'] ); - $line .= $this->get_status( $stylesheet ) . ' ' . $theme['Stylesheet'] . '%n'; + $line .= $this->format_status( $stylesheet ) . ' ' . $theme['Stylesheet'] . '%n'; WP_CLI::line( $line ); } @@ -63,15 +63,15 @@ protected function status_all() { WP_CLI::legend( $legend ); } - private function _get_status( $stylesheet ) { + private function get_status( $stylesheet ) { if ( $this->is_active_theme( $stylesheet ) ) return 'active'; return 'inactive'; } - private function get_status( $stylesheet, $long = false ) { - $status = $this->_get_status( $stylesheet ); + private function format_status( $stylesheet, $long = false ) { + $status = $this->get_status( $stylesheet ); $colors = array( 'inactive' => '', From 36fd51c70e62ab1cac6b8300a2e968dd7a0fdd90 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 16:11:27 +0300 Subject: [PATCH 0559/4858] move format_status() to parent class --- .../class-wp-cli-command-with-upgrade.php | 30 ++++++++++++++++++ src/php/wp-cli/commands/internals/plugin.php | 31 +------------------ src/php/wp-cli/commands/internals/theme.php | 25 +-------------- 3 files changed, 32 insertions(+), 54 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index ab13718dce..37ef1ed011 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -15,6 +15,7 @@ abstract protected function get_item_list(); abstract protected function status_all(); abstract protected function status_single( $file, $name ); + abstract protected function get_status( $file ); abstract protected function install_from_repo( $slug, $assoc_args ); @@ -150,4 +151,33 @@ protected function get_update_status( $slug ) { return isset( $update_list->response[ $slug ] ); } + + protected function format_status( $file, $long = false ) { + $status = $this->get_status( $file ); + + $colors = array( + 'inactive' => '', + 'active' => '%g', + 'active-network' => '%g', + 'must-use' => '%c', + ); + + $map_short = array( + 'inactive' => 'I', + 'active' => 'A', + 'active-network' => 'N', + 'must-use' => 'M', + ); + + $map_long = array( + 'inactive' => 'Inactive', + 'active' => 'Active', + 'active-network' => 'Must Use', + 'must-use' => 'Network Active', + ); + + $active_map = $long ? $map_long : $map_short; + + return $colors[ $status ] . $active_map[ $status ]; + } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index e2151a83c0..ac7a400185 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -86,7 +86,7 @@ protected function status_all() { WP_CLI::legend( $legend ); } - private function get_status( $file ) { + protected function get_status( $file ) { if ( isset( $this->mu_plugins[ $file ] ) ) return 'must-use'; @@ -99,35 +99,6 @@ private function get_status( $file ) { return 'inactive'; } - private function format_status( $file, $long = false ) { - $status = $this->get_status( $file ); - - $colors = array( - 'inactive' => '', - 'active' => '%g', - 'active-network' => '%g', - 'must-use' => '%c', - ); - - $map_short = array( - 'inactive' => 'I', - 'active' => 'A', - 'active-network' => 'N', - 'must-use' => 'M', - ); - - $map_long = array( - 'inactive' => 'Inactive', - 'active' => 'Active', - 'active-network' => 'Must Use', - 'must-use' => 'Network Active', - ); - - $active_map = $long ? $map_long : $map_short; - - return $colors[ $status ] . $active_map[ $status ]; - } - /** * Activate a plugin * diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 82564c9eea..4565ee894c 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -63,36 +63,13 @@ protected function status_all() { WP_CLI::legend( $legend ); } - private function get_status( $stylesheet ) { + protected function get_status( $stylesheet ) { if ( $this->is_active_theme( $stylesheet ) ) return 'active'; return 'inactive'; } - private function format_status( $stylesheet, $long = false ) { - $status = $this->get_status( $stylesheet ); - - $colors = array( - 'inactive' => '', - 'active' => '%g', - ); - - $map_short = array( - 'inactive' => 'I', - 'active' => 'A', - ); - - $map_long = array( - 'inactive' => 'Inactive', - 'active' => 'Active', - ); - - $active_map = $long ? $map_long : $map_short; - - return $colors[ $status ] . $active_map[ $status ]; - } - /** * Activate a theme * From 511489dc2d75bf0c1358f43f9eb6694cc862b4ce Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 16:14:00 +0300 Subject: [PATCH 0560/4858] convert boolean $long parameter to $format --- .../class-wp-cli-command-with-upgrade.php | 35 +++++++++---------- src/php/wp-cli/commands/internals/plugin.php | 4 +-- src/php/wp-cli/commands/internals/theme.php | 4 +-- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 37ef1ed011..1b5a6ce8d3 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -152,7 +152,22 @@ protected function get_update_status( $slug ) { return isset( $update_list->response[ $slug ] ); } - protected function format_status( $file, $long = false ) { + protected function format_status( $file, $format ) { + static $map = array( + 'short' => array( + 'inactive' => 'I', + 'active' => 'A', + 'active-network' => 'N', + 'must-use' => 'M', + ), + 'long' => array( + 'inactive' => 'Inactive', + 'active' => 'Active', + 'active-network' => 'Must Use', + 'must-use' => 'Network Active', + ) + ); + $status = $this->get_status( $file ); $colors = array( @@ -162,22 +177,6 @@ protected function format_status( $file, $long = false ) { 'must-use' => '%c', ); - $map_short = array( - 'inactive' => 'I', - 'active' => 'A', - 'active-network' => 'N', - 'must-use' => 'M', - ); - - $map_long = array( - 'inactive' => 'Inactive', - 'active' => 'Active', - 'active-network' => 'Must Use', - 'must-use' => 'Network Active', - ); - - $active_map = $long ? $map_long : $map_short; - - return $colors[ $status ] . $active_map[ $status ]; + return $colors[ $status ] . $map[ $format ][ $status ]; } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index ac7a400185..acb9d0cce7 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -28,7 +28,7 @@ function __construct( $args, $assoc_args ) { protected function status_single( $file, $name ) { $details = $this->get_details( $file ); - $status = $this->format_status( $file, true ); + $status = $this->format_status( $file, 'long' ); $version = $details[ 'Version' ]; @@ -66,7 +66,7 @@ protected function status_all() { $line = ' '; } - $line .= $this->format_status( $file ) . " $name%n"; + $line .= $this->format_status( $file, 'short' ) . " $name%n"; WP_CLI::line( $line ); } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 4565ee894c..ab2cc6592e 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -19,7 +19,7 @@ class Theme_Command extends WP_CLI_Command_With_Upgrade { protected function status_single( $stylesheet, $name ) { $details = get_theme_data( $stylesheet ); - $status = $this->format_status( $stylesheet, true ); + $status = $this->format_status( $stylesheet, 'long' ); $version = $details['Version']; @@ -47,7 +47,7 @@ protected function status_all() { $stylesheet = $this->get_stylesheet_path( $theme['Stylesheet'] ); - $line .= $this->format_status( $stylesheet ) . ' ' . $theme['Stylesheet'] . '%n'; + $line .= $this->format_status( $stylesheet, 'short' ) . ' ' . $theme['Stylesheet'] . '%n'; WP_CLI::line( $line ); } From 3d1ee2a818df9e6c71593cf11c7e22d5478ee961 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 16:17:45 +0300 Subject: [PATCH 0561/4858] make get_details() method required --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 3 ++- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 1b5a6ce8d3..6360f3660a 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -12,10 +12,11 @@ abstract class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { abstract protected function parse_name( $args, $subcommand ); abstract protected function get_item_list(); + abstract protected function get_status( $file ); + abstract protected function get_details( $file ); abstract protected function status_all(); abstract protected function status_single( $file, $name ); - abstract protected function get_status( $file ); abstract protected function install_from_repo( $slug, $assoc_args ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index acb9d0cce7..6727ea8ea9 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -299,7 +299,7 @@ function delete( $args, $assoc_args = array(), $exit_on_error = true ) { * @param string $file * @return array */ - private function get_details( $file ) { + protected function get_details( $file ) { $plugin_folder = get_plugins( '/' . plugin_basename( dirname( $file ) ) ); $plugin_file = basename( ( $file ) ); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index ab2cc6592e..0b0d7e2be9 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -17,7 +17,7 @@ class Theme_Command extends WP_CLI_Command_With_Upgrade { // Show details about a single theme protected function status_single( $stylesheet, $name ) { - $details = get_theme_data( $stylesheet ); + $details = $this->get_details( $stylesheet ); $status = $this->format_status( $stylesheet, 'long' ); @@ -33,6 +33,10 @@ protected function status_single( $stylesheet, $name ) { WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } + protected function get_details( $stylesheet ) { + return get_theme_data( $stylesheet ); + } + // Show details about all themes protected function status_all() { // Print the header From 1ec922f71fbe650703e398cb404ff89732078b8d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 17:42:58 +0300 Subject: [PATCH 0562/4858] move common code from status_single() into parent class --- .../wp-cli/class-wp-cli-command-with-upgrade.php | 15 ++++++++++++++- src/php/wp-cli/commands/internals/plugin.php | 12 +----------- src/php/wp-cli/commands/internals/theme.php | 12 +----------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 6360f3660a..1337315486 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -16,7 +16,7 @@ abstract protected function get_status( $file ); abstract protected function get_details( $file ); abstract protected function status_all(); - abstract protected function status_single( $file, $name ); + abstract protected function _status_single( $details, $name, $version, $status ); abstract protected function install_from_repo( $slug, $assoc_args ); @@ -38,6 +38,19 @@ function status( $args = array() ) { } } + protected function status_single( $file, $name ) { + $details = $this->get_details( $file ); + + $status = $this->format_status( $file, 'long' ); + + $version = $details[ 'Version' ]; + + if ( $this->get_update_status( $file ) ) + $version .= ' (%gUpdate available%n)'; + + $this->_status_single( $details, $name, $version, $status ); + } + /** * Install a new plugin/theme * diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 6727ea8ea9..98e59feb41 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -24,17 +24,7 @@ function __construct( $args, $assoc_args ) { parent::__construct( $args, $assoc_args ); } - // Show details about a single plugin - protected function status_single( $file, $name ) { - $details = $this->get_details( $file ); - - $status = $this->format_status( $file, 'long' ); - - $version = $details[ 'Version' ]; - - if ( $this->get_update_status( $file ) ) - $version .= ' (%gUpdate available%n)'; - + protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); WP_CLI::line( ' Status: ' . $status .'%n' ); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 0b0d7e2be9..5612177517 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -15,17 +15,7 @@ class Theme_Command extends WP_CLI_Command_With_Upgrade { protected $upgrade_refresh = 'wp_update_themes'; protected $upgrade_transient = 'update_themes'; - // Show details about a single theme - protected function status_single( $stylesheet, $name ) { - $details = $this->get_details( $stylesheet ); - - $status = $this->format_status( $stylesheet, 'long' ); - - $version = $details['Version']; - - if ( $this->get_update_status( $name ) ) - $version .= ' (%gUpdate available%n)'; - + protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( 'Theme %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); WP_CLI::line( ' Status: ' . $status .'%n' ); From b7ae1397d56b5a8fb57e335740e2ee77789d9e58 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 17:46:52 +0300 Subject: [PATCH 0563/4858] move legend() to WP_CLI_Command_With_Upgrade --- .../wp-cli/class-wp-cli-command-with-upgrade.php | 15 +++++++++++++++ src/php/wp-cli/class-wp-cli.php | 15 --------------- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 1337315486..71e49d91c7 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -51,6 +51,21 @@ protected function status_single( $file, $name ) { $this->_status_single( $details, $name, $version, $status ); } + /** + * Display a legend + * + * @param array( code => title ) $legend + */ + protected static function legend( $legend ) { + $legend[ '%yU' ] = 'Update Available'; + + $legend_line = array(); + foreach ( $legend as $key => $title ) + $legend_line[] = "$key = $title%n"; + + WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); + } + /** * Install a new plugin/theme * diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 7a1b2d4e48..967e3a143b 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -202,21 +202,6 @@ static function get_numeric_arg( $args, $index, $name ) { return $args[$index]; } - /** - * Display a legend - * - * @param array( code => title ) $legend - */ - static function legend( $legend ) { - $legend[ '%yU' ] = 'Update Available'; - - $legend_line = array(); - foreach ( $legend as $key => $title ) - $legend_line[] = "$key = $title%n"; - - WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); - } - /** * Launch an external process, closing the current one * diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 98e59feb41..083a6200d7 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -73,7 +73,7 @@ protected function status_all() { if ( is_multisite() ) $legend['%bN'] = 'Network Active'; - WP_CLI::legend( $legend ); + self::legend( $legend ); } protected function get_status( $file ) { diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 5612177517..b456ad86a7 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -54,7 +54,7 @@ protected function status_all() { '%gA' => 'Active', ); - WP_CLI::legend( $legend ); + self::legend( $legend ); } protected function get_status( $stylesheet ) { From 63e6d0fc84ee3448ffb4f41a0f69f16563984b48 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 17:50:52 +0300 Subject: [PATCH 0564/4858] move colors array to function --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 71e49d91c7..8d12056fb1 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -199,13 +199,17 @@ protected function format_status( $file, $format ) { $status = $this->get_status( $file ); - $colors = array( + return $this->get_color( $status ) . $map[ $format ][ $status ]; + } + + protected function get_color( $status ) { + static $colors = array( 'inactive' => '', 'active' => '%g', 'active-network' => '%g', 'must-use' => '%c', ); - return $colors[ $status ] . $map[ $format ][ $status ]; + return $colors[ $status ]; } } From 2341d80366ec8b172de26442c3d9fe33df450483 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 18:36:19 +0300 Subject: [PATCH 0565/4858] move get_status() call out of format_status() --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 6 ++---- src/php/wp-cli/commands/internals/plugin.php | 4 +++- src/php/wp-cli/commands/internals/theme.php | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 8d12056fb1..c0f281d785 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -41,7 +41,7 @@ function status( $args = array() ) { protected function status_single( $file, $name ) { $details = $this->get_details( $file ); - $status = $this->format_status( $file, 'long' ); + $status = $this->format_status( $this->get_status( $file ), 'long' ); $version = $details[ 'Version' ]; @@ -181,7 +181,7 @@ protected function get_update_status( $slug ) { return isset( $update_list->response[ $slug ] ); } - protected function format_status( $file, $format ) { + protected function format_status( $status, $format ) { static $map = array( 'short' => array( 'inactive' => 'I', @@ -197,8 +197,6 @@ protected function format_status( $file, $format ) { ) ); - $status = $this->get_status( $file ); - return $this->get_color( $status ) . $map[ $format ][ $status ]; } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 083a6200d7..59a69ab718 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -56,7 +56,9 @@ protected function status_all() { $line = ' '; } - $line .= $this->format_status( $file, 'short' ) . " $name%n"; + $status = $this->get_status( $file ); + + $line .= $this->format_status( $status, 'short' ) . " $name%n"; WP_CLI::line( $line ); } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index b456ad86a7..35177be961 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -41,7 +41,9 @@ protected function status_all() { $stylesheet = $this->get_stylesheet_path( $theme['Stylesheet'] ); - $line .= $this->format_status( $stylesheet, 'short' ) . ' ' . $theme['Stylesheet'] . '%n'; + $status = $this->get_status( $stylesheet ); + + $line .= $this->format_status( $status, 'short' ) . ' ' . $theme['Stylesheet'] . '%n'; WP_CLI::line( $line ); } From 1fa143b9bc0a33c72b87ae3230ca7e68b6829ca7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 18:39:26 +0300 Subject: [PATCH 0566/4858] move some methods around --- src/php/wp-cli/commands/internals/plugin.php | 26 ++++++++++---------- src/php/wp-cli/commands/internals/theme.php | 8 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 59a69ab718..b043da0558 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -78,19 +78,6 @@ protected function status_all() { self::legend( $legend ); } - protected function get_status( $file ) { - if ( isset( $this->mu_plugins[ $file ] ) ) - return 'must-use'; - - if ( is_plugin_active_for_network( $file ) ) - return 'active-network'; - - if ( is_plugin_active( $file ) ) - return 'active'; - - return 'inactive'; - } - /** * Activate a plugin * @@ -285,6 +272,19 @@ function delete( $args, $assoc_args = array(), $exit_on_error = true ) { /* PRIVATES */ + protected function get_status( $file ) { + if ( isset( $this->mu_plugins[ $file ] ) ) + return 'must-use'; + + if ( is_plugin_active_for_network( $file ) ) + return 'active-network'; + + if ( is_plugin_active( $file ) ) + return 'active'; + + return 'inactive'; + } + /** * Get the details of a plugin * diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 35177be961..03c8c2410c 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -23,10 +23,6 @@ protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } - protected function get_details( $stylesheet ) { - return get_theme_data( $stylesheet ); - } - // Show details about all themes protected function status_all() { // Print the header @@ -66,6 +62,10 @@ protected function get_status( $stylesheet ) { return 'inactive'; } + protected function get_details( $stylesheet ) { + return get_theme_data( $stylesheet ); + } + /** * Activate a theme * From 218d104473de27003ab09f6105dbc8ee0e30db21 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 18:42:09 +0300 Subject: [PATCH 0567/4858] use get_status() in check_active() --- src/php/wp-cli/commands/internals/plugin.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index b043da0558..4e9646d92b 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -117,13 +117,9 @@ function deactivate( $args, $assoc_args = array() ) { } private function check_active( $file, $network_wide ) { - if ( $network_wide ) { - $check = is_plugin_active_for_network( $file ); - } else { - $check = is_plugin_active( $file ); - } + $required = $network_wide ? 'active-network' : 'active'; - return $check; + return $required == $this->get_status( $file ); } /** From ab70c913ab1583499dd184f7ceb3d43bdf11d1dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 18:44:02 +0300 Subject: [PATCH 0568/4858] move check_active lower --- src/php/wp-cli/commands/internals/plugin.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 4e9646d92b..34723c0e5e 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -116,12 +116,6 @@ function deactivate( $args, $assoc_args = array() ) { } } - private function check_active( $file, $network_wide ) { - $required = $network_wide ? 'active-network' : 'active'; - - return $required == $this->get_status( $file ); - } - /** * Toggle a plugin's activation state * @@ -268,6 +262,12 @@ function delete( $args, $assoc_args = array(), $exit_on_error = true ) { /* PRIVATES */ + private function check_active( $file, $network_wide ) { + $required = $network_wide ? 'active-network' : 'active'; + + return $required == $this->get_status( $file ); + } + protected function get_status( $file ) { if ( isset( $this->mu_plugins[ $file ] ) ) return 'must-use'; From 6f0526047c9a15a3ae041a4bea646b73c4a7c0dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 18:48:31 +0300 Subject: [PATCH 0569/4858] introduce get_name() helper for plugin status_all() --- src/php/wp-cli/commands/internals/plugin.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 34723c0e5e..225ec55ce8 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -44,12 +44,7 @@ protected function status_all() { // Print the header WP_CLI::line('Installed plugins:'); - foreach ($plugins as $file => $plugin) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace('.php', '', basename($file)); - else - $name = dirname($file); - + foreach ( $plugins as $file => $plugin ) { if ( $this->get_update_status( $file ) ) { $line = ' %yU%n'; } else { @@ -58,7 +53,8 @@ protected function status_all() { $status = $this->get_status( $file ); - $line .= $this->format_status( $status, 'short' ) . " $name%n"; + $line .= $this->format_status( $status, 'short' ); + $line .= " " . $this->get_name( $file ) . "%n"; WP_CLI::line( $line ); } @@ -78,6 +74,15 @@ protected function status_all() { self::legend( $legend ); } + private function get_name( $file ) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace( '.php', '', basename( $file ) ); + else + $name = dirname( $file ); + + return $name; + } + /** * Activate a plugin * From 23d89cd1109e607c83577b7ab26b18508f1d9e55 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 18:50:24 +0300 Subject: [PATCH 0570/4858] rename get_update_status() to has_update() --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 6 +++--- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index c0f281d785..b18c7af1f2 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -45,7 +45,7 @@ protected function status_single( $file, $name ) { $version = $details[ 'Version' ]; - if ( $this->get_update_status( $file ) ) + if ( $this->has_update( $file ) ) $version .= ' (%gUpdate available%n)'; $this->_status_single( $details, $name, $version, $status ); @@ -125,7 +125,7 @@ private function update_multiple( $args, $assoc_args ) { $item_list = "Available {$this->item_type} updates:"; $items_to_update = array(); foreach ( $this->get_item_list() as $file ) { - if ( $this->get_update_status( $file ) ) { + if ( $this->has_update( $file ) ) { $items_to_update[] = $file; if ( empty( $assoc_args ) ) { @@ -175,7 +175,7 @@ private function update_multiple( $args, $assoc_args ) { * * @return bool */ - protected function get_update_status( $slug ) { + protected function has_update( $slug ) { $update_list = get_site_transient( $this->upgrade_transient ); return isset( $update_list->response[ $slug ] ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 225ec55ce8..7002786128 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -45,7 +45,7 @@ protected function status_all() { WP_CLI::line('Installed plugins:'); foreach ( $plugins as $file => $plugin ) { - if ( $this->get_update_status( $file ) ) { + if ( $this->has_update( $file ) ) { $line = ' %yU%n'; } else { $line = ' '; diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 03c8c2410c..5455ead13b 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -29,7 +29,7 @@ protected function status_all() { WP_CLI::line( 'Installed themes:' ); foreach ( get_themes() as $key => $theme ) { - if ( $this->get_update_status( $theme['Stylesheet'] ) ) { + if ( $this->has_update( $theme['Stylesheet'] ) ) { $line = ' %yU%n'; } else { $line = ' '; @@ -132,7 +132,7 @@ protected function install_from_repo( $slug, $assoc_args ) { } // Check to see if we should update, rather than install. - if ( $this->get_update_status( $slug ) ) { + if ( $this->has_update( $slug ) ) { WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $slug ); From 6701c6eb407155de71eefcc9f54ee744153361c5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 22:18:18 +0300 Subject: [PATCH 0571/4858] generate legend array from existing data --- .../class-wp-cli-command-with-upgrade.php | 63 ++++++++++--------- src/php/wp-cli/commands/internals/plugin.php | 11 +--- src/php/wp-cli/commands/internals/theme.php | 7 +-- 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index b18c7af1f2..02998a5f45 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -51,21 +51,6 @@ protected function status_single( $file, $name ) { $this->_status_single( $details, $name, $version, $status ); } - /** - * Display a legend - * - * @param array( code => title ) $legend - */ - protected static function legend( $legend ) { - $legend[ '%yU' ] = 'Update Available'; - - $legend_line = array(); - foreach ( $legend as $key => $title ) - $legend_line[] = "$key = $title%n"; - - WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); - } - /** * Install a new plugin/theme * @@ -181,23 +166,41 @@ protected function has_update( $slug ) { return isset( $update_list->response[ $slug ] ); } + protected $map = array( + 'short' => array( + 'inactive' => 'I', + 'active' => 'A', + 'active-network' => 'N', + 'must-use' => 'M', + ), + 'long' => array( + 'inactive' => 'Inactive', + 'active' => 'Active', + 'active-network' => 'Must Use', + 'must-use' => 'Network Active', + ) + ); + protected function format_status( $status, $format ) { - static $map = array( - 'short' => array( - 'inactive' => 'I', - 'active' => 'A', - 'active-network' => 'N', - 'must-use' => 'M', - ), - 'long' => array( - 'inactive' => 'Inactive', - 'active' => 'Active', - 'active-network' => 'Must Use', - 'must-use' => 'Network Active', - ) - ); + return $this->get_color( $status ) . $this->map[ $format ][ $status ]; + } + + protected function show_legend() { + $legend = array(); + + // TODO: show only the values that were used + foreach ( $this->map['short'] as $status => $short ) { + $key = $this->format_status( $status, 'short' ); + $legend[ $key ] = $this->map['long'][ $status ]; + } + + $legend[ '%yU' ] = 'Update Available'; + + $legend_line = array(); + foreach ( $legend as $key => $title ) + $legend_line[] = "$key = $title%n"; - return $this->get_color( $status ) . $map[ $format ][ $status ]; + WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } protected function get_color( $status ) { diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 7002786128..d07e0cb198 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -62,16 +62,7 @@ protected function status_all() { // Print the footer WP_CLI::line(); - $legend = array( - 'I' => 'Inactive', - '%gA' => 'Active', - '%cM' => 'Must Use', - ); - - if ( is_multisite() ) - $legend['%bN'] = 'Network Active'; - - self::legend( $legend ); + $this->show_legend(); } private function get_name( $file ) { diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 5455ead13b..5a07908af0 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -47,12 +47,7 @@ protected function status_all() { // Print the footer WP_CLI::line(); - $legend = array( - 'I' => 'Inactive', - '%gA' => 'Active', - ); - - self::legend( $legend ); + $this->show_legend(); } protected function get_status( $stylesheet ) { From 77d56fce308fa7bf19db7dfda980bb5de6a55bb6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 22:25:31 +0300 Subject: [PATCH 0572/4858] move get_name() to parent class --- .../wp-cli/class-wp-cli-command-with-upgrade.php | 16 ++++++++++------ src/php/wp-cli/commands/internals/plugin.php | 9 --------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 02998a5f45..a55d3a12d3 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -114,12 +114,7 @@ private function update_multiple( $args, $assoc_args ) { $items_to_update[] = $file; if ( empty( $assoc_args ) ) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace('.php', '', basename($file)); - else - $name = dirname($file); - - $item_list .= "\n\t%y$name%n"; + $item_list .= "\n\t%y" . $this->get_name( $file ) . "%n"; } } } @@ -153,6 +148,15 @@ private function update_multiple( $args, $assoc_args ) { } } + protected function get_name( $file ) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace( '.php', '', basename( $file ) ); + else + $name = dirname( $file ); + + return $name; + } + /** * Check whether an item has an update available or not. * diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index d07e0cb198..8e09d99898 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -65,15 +65,6 @@ protected function status_all() { $this->show_legend(); } - private function get_name( $file ) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace( '.php', '', basename( $file ) ); - else - $name = dirname( $file ); - - return $name; - } - /** * Activate a plugin * From 9aa9fffbc4d4ed008a245c10f923051d9994098c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 22:38:12 +0300 Subject: [PATCH 0573/4858] beef up get_item_list() and refactor update_multiple() --- .../class-wp-cli-command-with-upgrade.php | 22 ++++++++----------- src/php/wp-cli/commands/internals/plugin.php | 11 +++++++++- src/php/wp-cli/commands/internals/theme.php | 13 ++++++++++- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index a55d3a12d3..9d66cf491e 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -105,19 +105,9 @@ function update( $args, $assoc_args ) { } private function update_multiple( $args, $assoc_args ) { - // Grab all items that need updates - // If we have no sub-arguments, add them to the output list. - $item_list = "Available {$this->item_type} updates:"; - $items_to_update = array(); - foreach ( $this->get_item_list() as $file ) { - if ( $this->has_update( $file ) ) { - $items_to_update[] = $file; - - if ( empty( $assoc_args ) ) { - $item_list .= "\n\t%y" . $this->get_name( $file ) . "%n"; - } - } - } + $items_to_update = wp_list_filter( $this->get_item_list(), array( + 'update' => true + ) ); if ( empty( $items_to_update ) ) { WP_CLI::line( "No {$this->item_type} updates available." ); @@ -144,6 +134,12 @@ private function update_multiple( $args, $assoc_args ) { // Else list items that require updates } else { + $item_list = "Available {$this->item_type} updates:"; + + foreach ( $items_to_update as $file => $details ) { + $item_list .= "\n\t%y" . $this->get_name( $file ) . "%n"; + } + WP_CLI::line( $item_list ); } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 8e09d99898..0b84526e20 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -209,7 +209,16 @@ function update( $args, $assoc_args ) { } protected function get_item_list() { - return array_keys( get_plugins() ); + $items = array(); + + foreach ( get_plugins() as $file => $details ) { + $items[ $file ] = array( + 'status' => $this->get_status( $file ), + 'update' => $this->has_update( $file ), + ); + } + + return $items; } /** diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 5a07908af0..ab17467a9a 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -150,7 +150,18 @@ protected function install_from_repo( $slug, $assoc_args ) { } protected function get_item_list() { - return wp_list_pluck( get_themes(), 'Stylesheet' ); + $items = array(); + + foreach ( get_themes() as $title => $details ) { + $file = $details['Stylesheet']; + + $items[ $file ] = array( + 'status' => $this->get_status( $file ), + 'update' => $this->has_update( $file ), + ); + } + + return $items; } /** From 3f05a88a6382fed0b15fb270841c3e90b57f4359 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 22:49:18 +0300 Subject: [PATCH 0574/4858] use get_item_list() in status_all() --- src/php/wp-cli/commands/internals/plugin.php | 24 ++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 0b84526e20..0430ad2ea5 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -15,8 +15,6 @@ class Plugin_Command extends WP_CLI_Command_With_Upgrade { protected $upgrade_refresh = 'wp_update_plugins'; protected $upgrade_transient = 'update_plugins'; - private $mu_plugins; - function __construct( $args, $assoc_args ) { require_once ABSPATH.'wp-admin/includes/plugin.php'; require_once ABSPATH.'wp-admin/includes/plugin-install.php'; @@ -35,25 +33,26 @@ protected function _status_single( $details, $name, $version, $status ) { // Show details about all plugins protected function status_all() { - $this->mu_plugins = get_mu_plugins(); - - $plugins = get_plugins(); + $items = $this->get_item_list(); - $plugins = array_merge( $plugins, $this->mu_plugins ); + foreach ( get_mu_plugins() as $mu_plugin ) { + $items[ $mu_plugin ] = array( + 'status' => 'must-use', + 'update' => false + ); + } // Print the header WP_CLI::line('Installed plugins:'); - foreach ( $plugins as $file => $plugin ) { - if ( $this->has_update( $file ) ) { + foreach ( $items as $file => $details ) { + if ( $details['update'] ) { $line = ' %yU%n'; } else { $line = ' '; } - $status = $this->get_status( $file ); - - $line .= $this->format_status( $status, 'short' ); + $line .= $this->format_status( $details['status'], 'short' ); $line .= " " . $this->get_name( $file ) . "%n"; WP_CLI::line( $line ); @@ -265,9 +264,6 @@ private function check_active( $file, $network_wide ) { } protected function get_status( $file ) { - if ( isset( $this->mu_plugins[ $file ] ) ) - return 'must-use'; - if ( is_plugin_active_for_network( $file ) ) return 'active-network'; From c09b68070c367e6d0d62f1ba538e25eb9cb9c89d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 22:55:05 +0300 Subject: [PATCH 0575/4858] move get_name() back to plugin.php, where it belongs --- .../class-wp-cli-command-with-upgrade.php | 11 +---------- src/php/wp-cli/commands/internals/plugin.php | 17 ++++++++++++++--- src/php/wp-cli/commands/internals/theme.php | 1 + 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 9d66cf491e..d3bd22ea7b 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -137,22 +137,13 @@ private function update_multiple( $args, $assoc_args ) { $item_list = "Available {$this->item_type} updates:"; foreach ( $items_to_update as $file => $details ) { - $item_list .= "\n\t%y" . $this->get_name( $file ) . "%n"; + $item_list .= "\n\t%y" . $details['name'] . "%n"; } WP_CLI::line( $item_list ); } } - protected function get_name( $file ) { - if ( false === strpos( $file, '/' ) ) - $name = str_replace( '.php', '', basename( $file ) ); - else - $name = dirname( $file ); - - return $name; - } - /** * Check whether an item has an update available or not. * diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 0430ad2ea5..a5c7135d3f 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -35,8 +35,9 @@ protected function _status_single( $details, $name, $version, $status ) { protected function status_all() { $items = $this->get_item_list(); - foreach ( get_mu_plugins() as $mu_plugin ) { - $items[ $mu_plugin ] = array( + foreach ( get_mu_plugins() as $file => $mu_plugin ) { + $items[ $file ] = array( + 'name' => $this->get_name( $file ), 'status' => 'must-use', 'update' => false ); @@ -53,7 +54,7 @@ protected function status_all() { } $line .= $this->format_status( $details['status'], 'short' ); - $line .= " " . $this->get_name( $file ) . "%n"; + $line .= " " . $details['name'] . "%n"; WP_CLI::line( $line ); } @@ -212,6 +213,7 @@ protected function get_item_list() { foreach ( get_plugins() as $file => $details ) { $items[ $file ] = array( + 'name' => $this->get_name( $file ), 'status' => $this->get_status( $file ), 'update' => $this->has_update( $file ), ); @@ -320,4 +322,13 @@ protected function parse_name( $args, $subcommand ) { return array( $file, $name ); } + + private function get_name( $file ) { + if ( false === strpos( $file, '/' ) ) + $name = str_replace( '.php', '', basename( $file ) ); + else + $name = dirname( $file ); + + return $name; + } } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index ab17467a9a..661d043c69 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -156,6 +156,7 @@ protected function get_item_list() { $file = $details['Stylesheet']; $items[ $file ] = array( + 'name' => $details['Stylesheet'], 'status' => $this->get_status( $file ), 'update' => $this->has_update( $file ), ); From d3d49c8cd407a4c748d7a94860d464c82bc878b1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 23:01:53 +0300 Subject: [PATCH 0576/4858] extract common print_status_all() method --- .../class-wp-cli-command-with-upgrade.php | 19 +++++++++++++ src/php/wp-cli/commands/internals/plugin.php | 22 ++------------- src/php/wp-cli/commands/internals/theme.php | 27 +++---------------- 3 files changed, 24 insertions(+), 44 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index d3bd22ea7b..fa911d9275 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -38,6 +38,25 @@ function status( $args = array() ) { } } + protected function print_status_all( $items ) { + foreach ( $items as $file => $details ) { + if ( $details['update'] ) { + $line = ' %yU%n'; + } else { + $line = ' '; + } + + $line .= $this->format_status( $details['status'], 'short' ); + $line .= " " . $details['name'] . "%n"; + + WP_CLI::line( $line ); + } + + WP_CLI::line(); + + $this->show_legend(); + } + protected function status_single( $file, $name ) { $details = $this->get_details( $file ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index a5c7135d3f..8678312ad7 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -31,7 +31,6 @@ protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); } - // Show details about all plugins protected function status_all() { $items = $this->get_item_list(); @@ -43,26 +42,9 @@ protected function status_all() { ); } - // Print the header - WP_CLI::line('Installed plugins:'); + WP_CLI::line( 'Installed plugins:' ); - foreach ( $items as $file => $details ) { - if ( $details['update'] ) { - $line = ' %yU%n'; - } else { - $line = ' '; - } - - $line .= $this->format_status( $details['status'], 'short' ); - $line .= " " . $details['name'] . "%n"; - - WP_CLI::line( $line ); - } - - // Print the footer - WP_CLI::line(); - - $this->show_legend(); + $this->print_status_all( $items ); } /** diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 661d043c69..faa7246793 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -23,31 +23,10 @@ protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } - // Show details about all themes protected function status_all() { - // Print the header WP_CLI::line( 'Installed themes:' ); - foreach ( get_themes() as $key => $theme ) { - if ( $this->has_update( $theme['Stylesheet'] ) ) { - $line = ' %yU%n'; - } else { - $line = ' '; - } - - $stylesheet = $this->get_stylesheet_path( $theme['Stylesheet'] ); - - $status = $this->get_status( $stylesheet ); - - $line .= $this->format_status( $status, 'short' ) . ' ' . $theme['Stylesheet'] . '%n'; - - WP_CLI::line( $line ); - } - - // Print the footer - WP_CLI::line(); - - $this->show_legend(); + $this->print_status_all( $this->get_item_list() ); } protected function get_status( $stylesheet ) { @@ -153,12 +132,12 @@ protected function get_item_list() { $items = array(); foreach ( get_themes() as $title => $details ) { - $file = $details['Stylesheet']; + $file = $this->get_stylesheet_path( $details['Stylesheet'] ); $items[ $file ] = array( 'name' => $details['Stylesheet'], 'status' => $this->get_status( $file ), - 'update' => $this->has_update( $file ), + 'update' => $this->has_update( $details['Stylesheet'] ), ); } From e9b318df6baf7393b50038e44b3b2c4ae095af25 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 23:12:25 +0300 Subject: [PATCH 0577/4858] fix inverted descriptions --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index fa911d9275..8845735698 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -186,8 +186,8 @@ protected function has_update( $slug ) { 'long' => array( 'inactive' => 'Inactive', 'active' => 'Active', - 'active-network' => 'Must Use', - 'must-use' => 'Network Active', + 'active-network' => 'Network Active', + 'must-use' => 'Must Use', ) ); From 64dddc8cadebbbc10d41ad7aa4e59318eb4326e7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 23:15:39 +0300 Subject: [PATCH 0578/4858] show only relevant legend items --- .../class-wp-cli-command-with-upgrade.php | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 8845735698..4158907b6c 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -54,7 +54,26 @@ protected function print_status_all( $items ) { WP_CLI::line(); - $this->show_legend(); + $this->show_legend( $items ); + } + + protected function show_legend( $items ) { + $statuses = array_unique( wp_list_pluck( $items, 'status' ) ); + + $legend_line = array(); + + foreach ( $statuses as $status ) { + $legend_line[] = sprintf( '%s%s = %s%%n', + $this->get_color( $status ), + $this->map['short'][ $status ], + $this->map['long'][ $status ] + ); + } + + if ( in_array( true, wp_list_pluck( $items, 'update' ) ) ) + $legend_line[] = '%yU = Update Available%n'; + + WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } protected function status_single( $file, $name ) { @@ -195,24 +214,6 @@ protected function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } - protected function show_legend() { - $legend = array(); - - // TODO: show only the values that were used - foreach ( $this->map['short'] as $status => $short ) { - $key = $this->format_status( $status, 'short' ); - $legend[ $key ] = $this->map['long'][ $status ]; - } - - $legend[ '%yU' ] = 'Update Available'; - - $legend_line = array(); - foreach ( $legend as $key => $title ) - $legend_line[] = "$key = $title%n"; - - WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); - } - protected function get_color( $status ) { static $colors = array( 'inactive' => '', From 073ffdd848bdf9b7fb8337efd55562789c3cb9a6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 23:25:34 +0300 Subject: [PATCH 0579/4858] fix bulk upgrade --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 2 +- src/php/wp-cli/commands/internals/plugin.php | 1 + src/php/wp-cli/commands/internals/theme.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 4158907b6c..6193a75771 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -155,7 +155,7 @@ private function update_multiple( $args, $assoc_args ) { // If --all, UPDATE ALL THE THINGS if ( isset( $assoc_args['all'] ) ) { $upgrader = WP_CLI::get_upgrader( $this->upgrader ); - $result = $upgrader->bulk_upgrade( $items_to_update ); + $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); // Let the user know the results. $num_to_update = count( $items_to_update ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 8678312ad7..7c663bbd5c 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -198,6 +198,7 @@ protected function get_item_list() { 'name' => $this->get_name( $file ), 'status' => $this->get_status( $file ), 'update' => $this->has_update( $file ), + 'update_id' => $file, ); } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index faa7246793..4c90915e32 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -138,6 +138,7 @@ protected function get_item_list() { 'name' => $details['Stylesheet'], 'status' => $this->get_status( $file ), 'update' => $this->has_update( $details['Stylesheet'] ), + 'update_id' => $details['Stylesheet'], ); } From 5912c918d5f6d515e8b3e0a5b6d9bcf709b94c0f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Sep 2012 23:30:57 +0300 Subject: [PATCH 0580/4858] mark some things as private --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 6193a75771..d6fa809c90 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -57,7 +57,7 @@ protected function print_status_all( $items ) { $this->show_legend( $items ); } - protected function show_legend( $items ) { + private function show_legend( $items ) { $statuses = array_unique( wp_list_pluck( $items, 'status' ) ); $legend_line = array(); @@ -76,7 +76,7 @@ protected function show_legend( $items ) { WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } - protected function status_single( $file, $name ) { + private function status_single( $file, $name ) { $details = $this->get_details( $file ); $status = $this->format_status( $this->get_status( $file ), 'long' ); @@ -195,7 +195,7 @@ protected function has_update( $slug ) { return isset( $update_list->response[ $slug ] ); } - protected $map = array( + private $map = array( 'short' => array( 'inactive' => 'I', 'active' => 'A', @@ -210,11 +210,11 @@ protected function has_update( $slug ) { ) ); - protected function format_status( $status, $format ) { + private function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } - protected function get_color( $status ) { + private function get_color( $status ) { static $colors = array( 'inactive' => '', 'active' => '%g', From df0f50c3a012107bffd9a6f23c1c7b48d0c25de4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Sep 2012 00:00:44 +0300 Subject: [PATCH 0581/4858] separate item fetching logic from output --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 9 +++++++-- src/php/wp-cli/commands/internals/plugin.php | 6 ++---- src/php/wp-cli/commands/internals/theme.php | 6 ++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index d6fa809c90..550c148d99 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -12,10 +12,11 @@ abstract class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { abstract protected function parse_name( $args, $subcommand ); abstract protected function get_item_list(); + abstract protected function get_all_items(); + abstract protected function get_status( $file ); abstract protected function get_details( $file ); - abstract protected function status_all(); abstract protected function _status_single( $details, $name, $version, $status ); abstract protected function install_from_repo( $slug, $assoc_args ); @@ -38,7 +39,11 @@ function status( $args = array() ) { } } - protected function print_status_all( $items ) { + private function status_all() { + $items = $this->get_all_items(); + + WP_CLI::line( "Installed {$this->item_type}s:" ); + foreach ( $items as $file => $details ) { if ( $details['update'] ) { $line = ' %yU%n'; diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 7c663bbd5c..1082eb1178 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -31,7 +31,7 @@ protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); } - protected function status_all() { + protected function get_all_items() { $items = $this->get_item_list(); foreach ( get_mu_plugins() as $file => $mu_plugin ) { @@ -42,9 +42,7 @@ protected function status_all() { ); } - WP_CLI::line( 'Installed plugins:' ); - - $this->print_status_all( $items ); + return $items; } /** diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 4c90915e32..bf0b349107 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -23,10 +23,8 @@ protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); } - protected function status_all() { - WP_CLI::line( 'Installed themes:' ); - - $this->print_status_all( $this->get_item_list() ); + protected function get_all_items() { + return $this->get_item_list(); } protected function get_status( $stylesheet ) { From cebef2c1f4516bd7ad38edb0ce8f4c491d5bfc1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Sep 2012 00:25:05 +0300 Subject: [PATCH 0582/4858] use suffix parameter from basename() instead of using str_replace() --- src/php/wp-cli/commands/internals/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 1082eb1178..8154e15ebf 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -306,7 +306,7 @@ protected function parse_name( $args, $subcommand ) { private function get_name( $file ) { if ( false === strpos( $file, '/' ) ) - $name = str_replace( '.php', '', basename( $file ) ); + $name = basename( $file, '.php' ); else $name = dirname( $file ); From 9dc12d53acd92af3f325d41645252951533b17ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Sep 2012 03:22:20 +0300 Subject: [PATCH 0583/4858] generate: issue error when passed an invalid post type --- src/php/wp-cli/commands/internals/generate.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index a1cea714fe..965cdc16f8 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -30,8 +30,7 @@ public function posts( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); if ( !post_type_exists( $type ) ) { - WP_CLI::warning( 'invalid post type.' ); - exit; + WP_CLI::error( sprintf( "'%s' is not a registered post type.", $type ) ); } if ( $author ) { From 022734127f81c9a0fc3e3ba4991274b0618b01d7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Sep 2012 13:41:55 +0300 Subject: [PATCH 0584/4858] update php-cli-tools revision; makes cli\Table output cleaner when piping to another command --- src/php/php-cli-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/php-cli-tools b/src/php/php-cli-tools index 1fd565ce6c..7924a9dccc 160000 --- a/src/php/php-cli-tools +++ b/src/php/php-cli-tools @@ -1 +1 @@ -Subproject commit 1fd565ce6c989c1e1faf8571e2af6da7d88b8b32 +Subproject commit 7924a9dccc8dcd84bfeb7f9767104958caac3242 From 5f9982f6de454695bb52a119dccc910db93b62cd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Sep 2012 15:26:45 +0300 Subject: [PATCH 0585/4858] move $action out of loop. see #160 --- src/php/wp-cli/commands/internals/post.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 06b80ded54..97d7885692 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -94,9 +94,12 @@ public function delete( $args, $assoc_args ) { WP_CLI::error( "No posts to delete." ); } - foreach( $posts_to_delete as $post_id ) { - if ( wp_delete_post( $post_id, (bool)$assoc_args['force'] ) ) { - $action = ( (bool) $assoc_args['force'] ) ? 'Deleted' : 'Trashed'; + $force = (bool) $assoc_args['force']; + + $action = $force ? 'Deleted' : 'Trashed'; + + foreach ( $posts_to_delete as $post_id ) { + if ( wp_delete_post( $post_id, $force ) ) { WP_CLI::success( "{$action} post $post_id." ); } else { WP_CLI::error( "Failed deleting post $post_id." ); From 003232a4f36f73847fec62c2adb99213367f7910 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Sep 2012 16:30:36 +0300 Subject: [PATCH 0586/4858] export: validate_arguments() is not a subcommand, so make it private --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 555a29d389..f884738eea 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -13,7 +13,7 @@ class Export_Command extends WP_CLI_Command { /** * Argument validation functions below */ - public function validate_arguments( $args, $assoc_args ) { + private function validate_arguments( $args, $assoc_args ) { $defaults = array( 'path' => NULL, 'start_date' => NULL, From 4da5c54ecea01094cf4488784a06ad508bce7e3d Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jeff@bigfish.co.uk> Date: Thu, 27 Sep 2012 22:30:48 +0100 Subject: [PATCH 0587/4858] Use consistent names relating to post columns - Rename type to post_type - Rename status to post_status --- src/php/wp-cli/commands/internals/generate.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 965cdc16f8..ab67433c72 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -23,14 +23,14 @@ public function posts( $args, $assoc_args ) { 'count' => 100, 'max_depth' => 1, 'type' => 'post', - 'status' => 'publish', - 'author' => false + 'post_status' => 'publish', + 'post_author' => false, ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - if ( !post_type_exists( $type ) ) { - WP_CLI::error( sprintf( "'%s' is not a registered post type.", $type ) ); + if ( !post_type_exists( $post_type ) ) { + WP_CLI::error( sprintf( "'%s' is not a registered post type.", $post_type ) ); } if ( $author ) { @@ -41,11 +41,11 @@ public function posts( $args, $assoc_args ) { } // Get the total number of posts - $total = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = %s", $type ) ); + $total = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = %s", $post_type ) ); - $label = get_post_type_object( $type )->labels->singular_name; + $label = get_post_type_object( $post_type )->labels->singular_name; - $hierarchical = get_post_type_object( $type )->hierarchical; + $hierarchical = get_post_type_object( $post_type )->hierarchical; $limit = $count + $total; @@ -72,9 +72,9 @@ public function posts( $args, $assoc_args ) { } $args = array( - 'post_type' => $type, + 'post_type' => $post_type, 'post_title' => "$label $i", - 'post_status' => $status, + 'post_status' => $post_status, 'post_author' => $author, 'post_parent' => $current_parent, 'post_name' => "post-$i" From 8dc741d55ba03820628ce5799a9f84fa1d44b66b Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jeff@bigfish.co.uk> Date: Thu, 27 Sep 2012 22:33:42 +0100 Subject: [PATCH 0588/4858] Posts without a date cause 404s - Provide post_date argument - Set the default date to now --- src/php/wp-cli/commands/internals/generate.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index ab67433c72..0eb9a84ca3 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -25,6 +25,7 @@ public function posts( $args, $assoc_args ) { 'type' => 'post', 'post_status' => 'publish', 'post_author' => false, + 'post_date' => date('Y-m-d H:i:s'), ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); @@ -77,7 +78,8 @@ public function posts( $args, $assoc_args ) { 'post_status' => $post_status, 'post_author' => $author, 'post_parent' => $current_parent, - 'post_name' => "post-$i" + 'post_name' => "post-$i", + 'post_date' => $post_date, ); // Not using wp_insert_post() because it's slow From cd740e92023472d6b6b4445a66d17f2a438ffdc2 Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jeff@bigfish.co.uk> Date: Thu, 27 Sep 2012 22:46:16 +0100 Subject: [PATCH 0589/4858] Make Authors consisten with column names : post_author Fix error in previous commit regarding post_type --- src/php/wp-cli/commands/internals/generate.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 0eb9a84ca3..6b39d66174 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -22,7 +22,7 @@ public function posts( $args, $assoc_args ) { $defaults = array( 'count' => 100, 'max_depth' => 1, - 'type' => 'post', + 'post_type' => 'post', 'post_status' => 'publish', 'post_author' => false, 'post_date' => date('Y-m-d H:i:s'), @@ -34,11 +34,11 @@ public function posts( $args, $assoc_args ) { WP_CLI::error( sprintf( "'%s' is not a registered post type.", $post_type ) ); } - if ( $author ) { - $author = get_user_by( 'login', $author ); + if ( $post_author ) { + $post_author = get_user_by( 'login', $post_author ); - if ( $author ) - $author = $author->ID; + if ( $post_author ) + $post_author = $post_author->ID; } // Get the total number of posts @@ -76,7 +76,7 @@ public function posts( $args, $assoc_args ) { 'post_type' => $post_type, 'post_title' => "$label $i", 'post_status' => $post_status, - 'post_author' => $author, + 'post_author' => $post_author, 'post_parent' => $current_parent, 'post_name' => "post-$i", 'post_date' => $post_date, From 653ce4665dd5ab7ebe59ddcb746e994e34fc3bc2 Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jeff@bigfish.co.uk> Date: Thu, 27 Sep 2012 22:58:44 +0100 Subject: [PATCH 0590/4858] Make the command post generate, not generate post --- src/php/wp-cli/commands/internals/generate.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php index 6b39d66174..ce0f0072df 100644 --- a/src/php/wp-cli/commands/internals/generate.php +++ b/src/php/wp-cli/commands/internals/generate.php @@ -1,6 +1,6 @@ <?php -WP_CLI::add_command('generate', 'Generate_Command'); +WP_CLI::add_command('post', 'Post_Command'); /** * Implement generate command @@ -8,7 +8,7 @@ * @package wp-cli * @subpackage commands/internals */ -class Generate_Command extends WP_CLI_Command { +class Post_Command extends WP_CLI_Command { /** * Generate posts @@ -16,7 +16,7 @@ class Generate_Command extends WP_CLI_Command { * @param array $args * @param array $assoc_args **/ - public function posts( $args, $assoc_args ) { + public function generate( $args, $assoc_args ) { global $wpdb; $defaults = array( From 9997e41cc1bb133d38633b953e2febb4b6e0daf5 Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jeff@bigfish.co.uk> Date: Fri, 28 Sep 2012 09:05:31 +0100 Subject: [PATCH 0591/4858] Move generate post and user into respective locations --- .../wp-cli/commands/internals/generate.php | 157 ------------------ src/php/wp-cli/commands/internals/post.php | 91 ++++++++++ src/php/wp-cli/commands/internals/user.php | 55 ++++++ 3 files changed, 146 insertions(+), 157 deletions(-) delete mode 100644 src/php/wp-cli/commands/internals/generate.php diff --git a/src/php/wp-cli/commands/internals/generate.php b/src/php/wp-cli/commands/internals/generate.php deleted file mode 100644 index ce0f0072df..0000000000 --- a/src/php/wp-cli/commands/internals/generate.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php - -WP_CLI::add_command('post', 'Post_Command'); - -/** - * Implement generate command - * - * @package wp-cli - * @subpackage commands/internals - */ -class Post_Command extends WP_CLI_Command { - - /** - * Generate posts - * - * @param array $args - * @param array $assoc_args - **/ - 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' => date('Y-m-d H:i:s'), - ); - - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - if ( !post_type_exists( $post_type ) ) { - WP_CLI::error( sprintf( "'%s' is not a registered post type.", $post_type ) ); - } - - if ( $post_author ) { - $post_author = get_user_by( 'login', $post_author ); - - if ( $post_author ) - $post_author = $post_author->ID; - } - - // 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 = new \cli\progress\Bar( 'Generating posts', $count ); - - $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 = $post_ids[$i-1]; - $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, - ); - - // Not using wp_insert_post() because it's slow - $wpdb->insert( $wpdb->posts, $args ); - - $notify->tick(); - } - - $notify->finish(); - } - - private function maybe_make_child() { - // 50% chance of making child post - return ( mt_rand(1,2) == 1 ) ? true: false; - } - - private function maybe_reset_depth() { - // 10% chance of reseting to root depth - return ( mt_rand(1,10) == 7 ) ? true : false; - } - - /** - * Generate users - * - * @param array $args - * @param array $assoc_args - **/ - public function users( $args, $assoc_args ) { - global $blog_id; - - $defaults = array( - 'count' => 100, - 'role' => get_option('default_role'), - ); - - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - if ( 'none' == $role ) { - $role = false; - } elseif ( is_null( get_role( $role ) ) ) { - WP_CLI::warning( "invalid role." ); - exit; - } - - $user_count = count_users(); - - $total = $user_count['total_users']; - - $limit = $count + $total; - - $notify = new \cli\progress\Bar( 'Generating users', $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(); - } -} diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 97d7885692..d6a614d6fd 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -106,4 +106,95 @@ public function delete( $args, $assoc_args ) { } } } + + /** + * Generate posts + * + * @param array $args + * @param array $assoc_args + **/ + 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' => date('Y-m-d H:i:s'), + ); + + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + if ( !post_type_exists( $post_type ) ) { + WP_CLI::error( sprintf( "'%s' is not a registered post type.", $post_type ) ); + } + + if ( $post_author ) { + $post_author = get_user_by( 'login', $post_author ); + + if ( $post_author ) + $post_author = $post_author->ID; + } + + // 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 = new \cli\progress\Bar( 'Generating posts', $count ); + + $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 = $post_ids[$i-1]; + $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, + ); + + // Not using wp_insert_post() because it's slow + $wpdb->insert( $wpdb->posts, $args ); + + $notify->tick(); + } + + $notify->finish(); + } + + private function maybe_make_child() { + // 50% chance of making child post + return ( mt_rand(1,2) == 1 ) ? true: false; + } + + private function maybe_reset_depth() { + // 10% chance of reseting to root depth + return ( mt_rand(1,10) == 7 ) ? true : false; + } } diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index c6fd1350f1..4fbceb0976 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -150,4 +150,59 @@ public function update( $args, $assoc_args ) { WP_CLI::success( "Updated user $updated_id." ); } } + + + /** + * Generate users + * + * @param array $args + * @param array $assoc_args + **/ + public function generate( $args, $assoc_args ) { + global $blog_id; + + $defaults = array( + 'count' => 100, + 'role' => get_option('default_role'), + ); + + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + if ( 'none' == $role ) { + $role = false; + } elseif ( is_null( get_role( $role ) ) ) { + WP_CLI::warning( "invalid role." ); + exit; + } + + $user_count = count_users(); + + $total = $user_count['total_users']; + + $limit = $count + $total; + + $notify = new \cli\progress\Bar( 'Generating users', $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(); + } } From f6a939babe6308280912af8125acec3223bdc2fa Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jeff@bigfish.co.uk> Date: Fri, 28 Sep 2012 08:15:15 +0000 Subject: [PATCH 0592/4858] Fix typo in update post comment --- src/php/wp-cli/commands/internals/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index d6a614d6fd..0d21244658 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -30,7 +30,7 @@ public function create( $args, $assoc_args ) { } /** - * Update a user + * Update a post * * @param array $args * @param array $assoc_args From 157bd7480a0dc9b426522f7a85fa5bb415429f81 Mon Sep 17 00:00:00 2001 From: Jeffry Ghazally <jghazally@gmail.com> Date: Sun, 30 Sep 2012 10:38:48 +0000 Subject: [PATCH 0593/4858] change post_date default to use current_time --- src/php/wp-cli/commands/internals/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 0d21244658..13d33c47a6 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -122,7 +122,7 @@ public function generate( $args, $assoc_args ) { 'post_type' => 'post', 'post_status' => 'publish', 'post_author' => false, - 'post_date' => date('Y-m-d H:i:s'), + 'post_date' => current_time( 'mysql' ), ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); From 6bdc27fb36b603b76c9a645916b14b93ed6adc9d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 1 Oct 2012 18:02:20 +0000 Subject: [PATCH 0594/4858] Basic commands for adding and removing users from blogs --- src/php/wp-cli/commands/internals/user.php | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 4fbceb0976..e9fed335a7 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -205,4 +205,60 @@ public function generate( $args, $assoc_args ) { $notify->finish(); } + + /** + * Add a user to a blog + * + * @param array $args + * @param array $assoc_args + **/ + public function add_to_blog( $args, $assoc_args ) { + + $defaults = array( + 'id_or_login' => $args[0], + 'role' => $args[1], + ); + $args = array_merge( $assoc_args, $defaults ); + + if ( is_numeric( $args['id_or_login'] ) ) + $user = get_user_by( 'id', $args['id_or_login'] ); + else + $user = get_user_by( 'login', $args['id_or_login'] ); + + if ( empty( $args['id_or_login'] ) || empty( $user ) ) + WP_CLI::error( "Please specify a valid user ID or user login to add to this blog" ); + + global $wp_roles; + if ( empty( $args['role'] ) || ! array_key_exists( $args['role'], $wp_roles->roles ) ) + $args['role'] = get_option( 'default_role' ); + + add_user_to_blog( get_current_blog_id(), $user->ID, $args['role'] ); + WP_CLI::success( "Added {$user->user_login} ({$user->ID}) to " . site_url() . " as {$args['role']}" ); + } + + /** + * Remove a user from a blog + * + * @param array $args + * @param array $assoc_args + **/ + public function remove_from_blog( $args, $assoc_args ) { + + $defaults = array( + 'id_or_login' => $args[0], + ); + $args = array_merge( $assoc_args, $defaults ); + + if ( is_numeric( $args['id_or_login'] ) ) + $user = get_user_by( 'id', $args['id_or_login'] ); + else + $user = get_user_by( 'login', $args['id_or_login'] ); + + if ( empty( $args['id_or_login'] ) || empty( $user ) ) + WP_CLI::error( "Please specify a valid user ID or user login to remove from this blog" ); + + remove_user_from_blog( $user->ID, get_current_blog_id() ); + WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); + } + } From cb0d619586eef3dc2fcd216517a92aea2cc85e65 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 1 Oct 2012 18:07:23 +0000 Subject: [PATCH 0595/4858] Basic documentation for the add_to_blog and remove_from_blog subcommands --- src/docs/user-add_to_blog.txt | 20 ++++++++++++++++++++ src/docs/user-remove_from_blog.txt | 16 ++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/docs/user-add_to_blog.txt create mode 100644 src/docs/user-remove_from_blog.txt diff --git a/src/docs/user-add_to_blog.txt b/src/docs/user-add_to_blog.txt new file mode 100644 index 0000000000..76a3056c48 --- /dev/null +++ b/src/docs/user-add_to_blog.txt @@ -0,0 +1,20 @@ +wp-user-add_to_blog(1) -- Add an existing WordPress user to an existing blog +==== + +## SYNOPSIS + +`wp user add_to_blog` <user-login> [--role=<role>] + +## OPTIONS + +* `<user-login>`: + + The login of the user to add to the blog. + +* `--role`=<role>: + + Add the user with the specified role. Defaults to blog default. + +## EXAMPLES + + wp user add_to_blog bob --role=author diff --git a/src/docs/user-remove_from_blog.txt b/src/docs/user-remove_from_blog.txt new file mode 100644 index 0000000000..619ab98404 --- /dev/null +++ b/src/docs/user-remove_from_blog.txt @@ -0,0 +1,16 @@ +wp-user-remove_from_blog(1) -- Remove a WordPress user from a blog +==== + +## SYNOPSIS + +`wp user remove_from_blog` <user-login> + +## OPTIONS + +* `<user-login>`: + + The login of the user to remove from the blog. + +## EXAMPLES + + wp user remove_from_blog bob From ff5772f650fe24a01df1cd61422dd2ac2f27c741 Mon Sep 17 00:00:00 2001 From: Andreas Creten <andreas@madewithlove.be> Date: Thu, 4 Oct 2012 14:26:32 +0200 Subject: [PATCH 0596/4858] Fixed broken wp export command. Fixes #175. --- man/export.1 | 6 +++--- src/docs/export.txt | 4 ++-- src/php/wp-cli/class-wp-cli-command.php | 2 +- src/php/wp-cli/commands/internals/export.php | 17 +++++++++-------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/man/export.1 b/man/export.1 index 27afcfb5a0..a2e45d461d 100644 --- a/man/export.1 +++ b/man/export.1 @@ -7,12 +7,12 @@ \fBwp\-export\fR \- Create a WXR file\. . .SH "SYNOPSIS" -\fBwp export\fR \-\-path=\fIdirname\fR [filters] [\-\-skip_comments] +\fBwp export\fR \-\-dir=\fIdirname\fR [filters] [\-\-skip_comments] . .SH "OPTIONS" . .TP -\fB\-\-path\fR=\fIdirname\fR: +\fB\-\-dir\fR=\fIdirname\fR: . .IP Full Path to directory where WXR export files should be stored\. @@ -65,7 +65,7 @@ Export only posts with this status\. . .nf -wp export \-\-path=/tmp/ \-\-user=admin \-\-post_type=post \-\-start_date=2011\-01\-01 \-\-end_date=2011\-12\-31 +wp export \-\-dir=/tmp/ \-\-user=admin \-\-post_type=post \-\-start_date=2011\-01\-01 \-\-end_date=2011\-12\-31 . .fi diff --git a/src/docs/export.txt b/src/docs/export.txt index 9a27e63ab8..5e7d32e54b 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -7,7 +7,7 @@ wp-export(1) -- Create a WXR file. ## OPTIONS -* `--path`=<dirname>: +* `--dir`=<dirname>: Full Path to directory where WXR export files should be stored. @@ -43,4 +43,4 @@ wp-export(1) -- Create a WXR file. ## EXAMPLES - wp export --path=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index 79eee88ac2..e9701c26a7 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -30,7 +30,7 @@ public function __construct( $args, $assoc_args ) { // This if for reserved keywords in php (like list, isset) $subcommand = '_' . $subcommand; } - + if ( __FUNCTION__ == $subcommand || !method_exists( $this, $subcommand ) ) { self::describe_command( get_class( $this ), WP_CLI_COMMAND ); } else { diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index f884738eea..275d93f73e 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -9,13 +9,15 @@ * @subpackage commands/internals */ class Export_Command extends WP_CLI_Command { + + protected $default_subcommand = 'export'; /** * Argument validation functions below */ - private function validate_arguments( $args, $assoc_args ) { + protected function export( $args, $assoc_args ) { $defaults = array( - 'path' => NULL, + 'dir' => NULL, 'start_date' => NULL, 'end_date' => NULL, 'post_type' => NULL, @@ -41,21 +43,21 @@ private function validate_arguments( $args, $assoc_args ) { exit(1); } - $this->wxr_path = $assoc_args['path']; + $this->wxr_path = $assoc_args['dir']; WP_CLI::line( 'Starting export process...' ); WP_CLI::line(); $this->export_wp( $this->export_args ); } - private function check_path( $path ) { + private function check_dir( $path ) { if ( empty( $path ) ) { - WP_CLI::warning( 'missing --path parameter' ); + WP_CLI::warning( 'missing --dir parameter' ); return false; } if ( !is_dir( $path ) ) { - WP_CLI::error( sprintf( "The path %s does not exist", $path ) ); + WP_CLI::error( sprintf( "The directory %s does not exist", $path ) ); } return true; @@ -455,5 +457,4 @@ private function export_wp( $args = array() ) { file_put_contents( $full_path, $result ); } } -} - +} \ No newline at end of file From a4374f8608ab5bbfa6aac3bd3d4c16808b6fd50b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 19:27:18 +0300 Subject: [PATCH 0597/4858] move get_subcommands() and describe_command() to WP_CLI class --- src/php/wp-cli/class-wp-cli-command.php | 53 +--------------------- src/php/wp-cli/class-wp-cli.php | 49 ++++++++++++++++++++ src/php/wp-cli/commands/internals/help.php | 4 +- src/php/wp-cli/wp-cli.php | 2 +- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index e9701c26a7..338f26c7ca 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -30,61 +30,12 @@ public function __construct( $args, $assoc_args ) { // This if for reserved keywords in php (like list, isset) $subcommand = '_' . $subcommand; } - + if ( __FUNCTION__ == $subcommand || !method_exists( $this, $subcommand ) ) { - self::describe_command( get_class( $this ), WP_CLI_COMMAND ); + WP_CLI::describe_command( get_class( $this ), WP_CLI_COMMAND ); } else { $this->$subcommand( $args, $assoc_args ); } } - - static function describe_command( $class, $command ) { - if ( method_exists( $class, 'help' ) ) { - $class::help(); - return; - } - - $methods = self::get_subcommands( $class ); - - $out = "usage: wp $command"; - - if ( empty( $methods ) ) { - WP_CLI::line( $out ); - } else { - $out .= ' [' . implode( '|', $methods ) . ']'; - - WP_CLI::line( $out ); - - WP_CLI::line(); - WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); - } - } - - /** - * Get the list of subcommands for a class. - * - * @param string $class - * @return array The list of methods - */ - static function get_subcommands( $class ) { - $reflection = new ReflectionClass( $class ); - - $methods = array(); - - foreach ( $reflection->getMethods() as $method ) { - if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) - continue; - - $name = $method->name; - - if ( strpos( $name, '_' ) === 0 ) { - $name = substr( $name, 1 ); - } - - $methods[] = $name; - } - - return $methods; - } } diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 967e3a143b..e005001296 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -361,6 +361,55 @@ static function load_command( $command ) { return WP_CLI::$commands[$command]; } + /** + * Get the list of subcommands for a class. + * + * @param string $class + * @return array The list of methods + */ + static function get_subcommands( $class ) { + $reflection = new ReflectionClass( $class ); + + $methods = array(); + + foreach ( $reflection->getMethods() as $method ) { + if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) + continue; + + $name = $method->name; + + if ( strpos( $name, '_' ) === 0 ) { + $name = substr( $name, 1 ); + } + + $methods[] = $name; + } + + return $methods; + } + + static function describe_command( $class, $command ) { + if ( method_exists( $class, 'help' ) ) { + $class::help(); + return; + } + + $methods = WP_CLI::get_subcommands( $class ); + + $out = "usage: wp $command"; + + if ( empty( $methods ) ) { + WP_CLI::line( $out ); + } else { + $out .= ' [' . implode( '|', $methods ) . ']'; + + WP_CLI::line( $out ); + + WP_CLI::line(); + WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); + } + } + // back-compat static function addCommand( $name, $class ) { self::add_command( $name, $class ); diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 8ff24eb3eb..f5be9c2227 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -37,7 +37,7 @@ private function maybe_load_man_page( $args ) { private function show_available_subcommands( $command ) { $class = WP_CLI::load_command( $command ); - WP_CLI_Command::describe_command( $class, $command ); + WP_CLI::describe_command( $class, $command ); } private function general_help() { @@ -48,7 +48,7 @@ private function general_help() { $out = " wp $command"; - $methods = WP_CLI_Command::get_subcommands( $class ); + $methods = WP_CLI::get_subcommands( $class ); if ( !empty( $methods ) ) { $out .= ' [' . implode( '|', $methods ) . ']'; diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 1fbd96dd96..c989911707 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -127,7 +127,7 @@ // Generate strings for autocomplete if ( WP_CLI_AUTOCOMPLETE ) { foreach ( WP_CLI::load_all_commands() as $name => $command ) { - $subcommands = implode( ' ', WP_CLI_Command::get_subcommands( $command ) ); + $subcommands = implode( ' ', WP_CLI::get_subcommands( $command ) ); WP_CLI::line( $name . ' ' . $subcommands ); } exit; From 95cf164614f17167b2f575502d6f99d7d062d68c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 20:15:53 +0300 Subject: [PATCH 0598/4858] introduce filter_methods() --- src/php/wp-cli/class-wp-cli.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index e005001296..697ae2a767 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -370,19 +370,25 @@ static function load_command( $command ) { static function get_subcommands( $class ) { $reflection = new ReflectionClass( $class ); - $methods = array(); - - foreach ( $reflection->getMethods() as $method ) { - if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) - continue; - + return self::filter_methods( $reflection, function( $method ) { $name = $method->name; if ( strpos( $name, '_' ) === 0 ) { $name = substr( $name, 1 ); } - $methods[] = $name; + return $name; + } ); + } + + private static function filter_methods( $reflection, $cb ) { + $methods = array(); + + foreach ( $reflection->getMethods() as $method ) { + if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) + continue; + + $methods[] = $cb( $method ); } return $methods; From 0844ec07a9905f3efa6b9af0d6f14b536ee79142 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 21:42:21 +0300 Subject: [PATCH 0599/4858] implement 'help' command as a closure in a namespace --- src/php/wp-cli/commands/internals/help.php | 95 ++++++++++------------ 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index f5be9c2227..a8fe0f8e24 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -1,74 +1,65 @@ <?php +namespace WP_CLI\Help; -WP_CLI::add_command('help', 'Help_Command'); - -/** - * Implement help command - * - * @package wp-cli - * @subpackage commands/internals - */ -class Help_Command extends WP_CLI_Command { +\WP_CLI::add_command( 'help', function( $args ) { + if ( empty( $args ) ) { + general_help(); + return; + } - public function __construct( $args ) { - if ( empty( $args ) ) { - $this->general_help(); - return; - } + maybe_load_man_page( $args ); - $this->maybe_load_man_page( $args ); + show_available_subcommands( $args[0] ); +} ); - $this->show_available_subcommands( $args[0] ); - } +function maybe_load_man_page( $args ) { + $man_dir = WP_CLI_ROOT . "../../../man/"; - private function maybe_load_man_page( $args ) { - $man_dir = WP_CLI_ROOT . "../../../man/"; + if ( !is_dir( $man_dir ) ) { + \WP_CLI::warning( "man pages do not seem to be installed." ); + } else { + $man_file = $man_dir . implode( '-', $args ) . '.1'; - if ( !is_dir( $man_dir ) ) { - WP_CLI::warning( "man pages do not seem to be installed." ); - } else { - $man_file = $man_dir . implode( '-', $args ) . '.1'; - - if ( is_readable( $man_file ) ) { - exit( WP_CLI::launch( "man $man_file" ) ); - } + if ( is_readable( $man_file ) ) { + exit( \WP_CLI::launch( "man $man_file" ) ); } } +} - private function show_available_subcommands( $command ) { - $class = WP_CLI::load_command( $command ); - WP_CLI::describe_command( $class, $command ); - } - - private function general_help() { - WP_CLI::line( 'Available commands:' ); - foreach ( WP_CLI::load_all_commands() as $command => $class ) { - if ( 'help' == $command ) - continue; +function show_available_subcommands( $command ) { + $class = \WP_CLI::load_command( $command ); + \WP_CLI::describe_command( $class, $command ); +} - $out = " wp $command"; +function general_help() { + \WP_CLI::line( 'Available commands:' ); + foreach ( \WP_CLI::load_all_commands() as $command => $class ) { + if ( 'help' == $command ) + continue; - $methods = WP_CLI::get_subcommands( $class ); + $out = " wp $command"; - if ( !empty( $methods ) ) { - $out .= ' [' . implode( '|', $methods ) . ']'; - } + $methods = \WP_CLI::get_subcommands( $class ); - WP_CLI::line( $out ); + if ( !empty( $methods ) ) { + $out .= ' [' . implode( '|', $methods ) . ']'; } - WP_CLI::line(<<<EOB + \WP_CLI::line( $out ); + } + + \WP_CLI::line(<<<EOB See 'wp help <command>' for more information on a specific command. Global parameters: - --user=<id|login> set the current user - --url=<url> set the current URL - --path=<path> set the current path to the WP install - --require=<path> load a certain file before running the command - --quiet suppress informational messages - --version print wp-cli version +--user=<id|login> set the current user +--url=<url> set the current URL +--path=<path> set the current path to the WP install +--require=<path> load a certain file before running the command +--quiet suppress informational messages +--version print wp-cli version EOB - ); - } + ); } + From bdbeaacaad24554765be83444b62b29ed09de74b Mon Sep 17 00:00:00 2001 From: Lane Goldberg <lanegoldberg@gmail.com> Date: Mon, 8 Oct 2012 15:51:22 -0300 Subject: [PATCH 0600/4858] Added case for my fresh install of Mamp 2.1.1 ADDED: /Applications/MAMP/bin/php/php5.[34]*/bin/php --- src/bin/wp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wp b/src/bin/wp index fa1037e4e7..ec8e4a9526 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -67,7 +67,7 @@ else fi # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php/php5.3*/bin/php /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + for amp_php in /Applications/MAMP/bin/php/php5.3*/bin/php /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php5.[34]*/bin/php /Applications/MAMP/bin/php/php.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do if [ -x $amp_php ]; then php=$amp_php break From 506797bb0fa78002e9080369e23f572ad7afcfcd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 22:04:35 +0300 Subject: [PATCH 0601/4858] implement 'export' command without relying on default subcommand or custom constructor --- src/php/wp-cli/commands/internals/export.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 275d93f73e..02a42ddd48 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -1,6 +1,6 @@ <?php -WP_CLI::add_command('export', 'Export_Command'); +WP_CLI::add_command( 'export', array( new Export_Command, 'export' ) ); /** * Implement export command @@ -8,14 +8,12 @@ * @package wp-cli * @subpackage commands/internals */ -class Export_Command extends WP_CLI_Command { - - protected $default_subcommand = 'export'; +class Export_Command { /** * Argument validation functions below */ - protected function export( $args, $assoc_args ) { + public function export( $args, $assoc_args ) { $defaults = array( 'dir' => NULL, 'start_date' => NULL, @@ -457,4 +455,4 @@ private function export_wp( $args = array() ) { file_put_contents( $full_path, $result ); } } -} \ No newline at end of file +} From 53461fe532bd0fbec128003152f7822c56da024a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 22:12:56 +0300 Subject: [PATCH 0602/4858] move dispatch logic out of WP_CLI_Command constructor and into a separate namespace --- .../class-wp-cli-command-with-upgrade.php | 6 +- src/php/wp-cli/class-wp-cli-command.php | 35 ++---- src/php/wp-cli/class-wp-cli.php | 60 +--------- src/php/wp-cli/commands/internals/db.php | 4 +- src/php/wp-cli/commands/internals/help.php | 4 +- src/php/wp-cli/commands/internals/plugin.php | 4 +- src/php/wp-cli/dispatcher.php | 108 ++++++++++++++++++ src/php/wp-cli/wp-cli.php | 3 +- 8 files changed, 129 insertions(+), 95 deletions(-) create mode 100644 src/php/wp-cli/dispatcher.php diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 550c148d99..253724cb05 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -2,13 +2,15 @@ abstract class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { + public static function get_default_subcommand() { + return 'status'; + } + protected $item_type; protected $upgrader; protected $upgrade_refresh; protected $upgrade_transient; - protected $default_subcommand = 'status'; - abstract protected function parse_name( $args, $subcommand ); abstract protected function get_item_list(); diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index 338f26c7ca..9bd137b854 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -7,35 +7,14 @@ */ abstract class WP_CLI_Command { - protected $default_subcommand; - - protected $aliases = array(); - - /** - * Transfers the handling to the appropriate method - * - * @param array $args - * @param array $assoc_args - */ - public function __construct( $args, $assoc_args ) { - if ( empty( $args ) ) - $subcommand = $this->default_subcommand; - else - $subcommand = array_shift( $args ); - - if ( isset( $this->aliases[ $subcommand ] ) ) - $subcommand = $this->aliases[ $subcommand ]; - - if ( !method_exists( $this, $subcommand ) ) { - // This if for reserved keywords in php (like list, isset) - $subcommand = '_' . $subcommand; - } + public static function get_default_subcommand() { + return false; + } - if ( __FUNCTION__ == $subcommand || !method_exists( $this, $subcommand ) ) { - WP_CLI::describe_command( get_class( $this ), WP_CLI_COMMAND ); - } else { - $this->$subcommand( $args, $assoc_args ); - } + static function get_aliases() { + return array(); } + + public function __construct() {} } diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 697ae2a767..17507abd05 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -335,10 +335,7 @@ static function run_command( $arguments, $assoc_args ) { $implementation = self::load_command( $command ); - if ( is_string( $implementation ) && class_exists( $implementation ) ) - $instance = new $implementation( $arguments, $assoc_args ); - else - call_user_func( $implementation, $arguments, $assoc_args ); + \WP_CLI\Dispatcher\dispatch( $implementation, $arguments, $assoc_args ); } static function load_command( $command ) { @@ -361,61 +358,6 @@ static function load_command( $command ) { return WP_CLI::$commands[$command]; } - /** - * Get the list of subcommands for a class. - * - * @param string $class - * @return array The list of methods - */ - static function get_subcommands( $class ) { - $reflection = new ReflectionClass( $class ); - - return self::filter_methods( $reflection, function( $method ) { - $name = $method->name; - - if ( strpos( $name, '_' ) === 0 ) { - $name = substr( $name, 1 ); - } - - return $name; - } ); - } - - private static function filter_methods( $reflection, $cb ) { - $methods = array(); - - foreach ( $reflection->getMethods() as $method ) { - if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) - continue; - - $methods[] = $cb( $method ); - } - - return $methods; - } - - static function describe_command( $class, $command ) { - if ( method_exists( $class, 'help' ) ) { - $class::help(); - return; - } - - $methods = WP_CLI::get_subcommands( $class ); - - $out = "usage: wp $command"; - - if ( empty( $methods ) ) { - WP_CLI::line( $out ); - } else { - $out .= ' [' . implode( '|', $methods ) . ']'; - - WP_CLI::line( $out ); - - WP_CLI::line(); - WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); - } - } - // back-compat static function addCommand( $name, $class ) { self::add_command( $name, $class ); diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index f382651d33..b426d30a39 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -10,7 +10,9 @@ **/ class DB_Command extends WP_CLI_Command { - protected $default_subcommand = 'cli'; + public static function get_default_subcommand() { + return 'cli'; + } protected $aliases = array( 'dump' => 'export' ); diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index a8fe0f8e24..b4059ba1a9 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -28,7 +28,7 @@ function maybe_load_man_page( $args ) { function show_available_subcommands( $command ) { $class = \WP_CLI::load_command( $command ); - \WP_CLI::describe_command( $class, $command ); + \WP_CLI\Dispatcher\describe_command( $class, $command ); } function general_help() { @@ -39,7 +39,7 @@ function general_help() { $out = " wp $command"; - $methods = \WP_CLI::get_subcommands( $class ); + $methods = \WP_CLI\Dispatcher\get_subcommands( $class ); if ( !empty( $methods ) ) { $out .= ' [' . implode( '|', $methods ) . ']'; diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 8154e15ebf..dfc3a1272d 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -15,11 +15,11 @@ class Plugin_Command extends WP_CLI_Command_With_Upgrade { protected $upgrade_refresh = 'wp_update_plugins'; protected $upgrade_transient = 'update_plugins'; - function __construct( $args, $assoc_args ) { + function __construct() { require_once ABSPATH.'wp-admin/includes/plugin.php'; require_once ABSPATH.'wp-admin/includes/plugin-install.php'; - parent::__construct( $args, $assoc_args ); + parent::__construct(); } protected function _status_single( $details, $name, $version, $status ) { diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php new file mode 100644 index 0000000000..9a26071fb2 --- /dev/null +++ b/src/php/wp-cli/dispatcher.php @@ -0,0 +1,108 @@ +<?php + +namespace WP_CLI\Dispatcher; + +function dispatch( $implementation, $arguments, $assoc_args ) { + if ( is_string( $implementation ) && class_exists( $implementation ) ) + dispatch_subcommand( $implementation, $arguments, $assoc_args ); + else + call_user_func( $implementation, $arguments, $assoc_args ); +} + +/** + * Transfers the handling to the appropriate method + * + * @param array $args + * @param array $assoc_args + */ +function dispatch_subcommand( $class, $args, $assoc_args ) { + if ( empty( $args ) ) { + $subcommand = $class::get_default_subcommand(); + } else { + $subcommand = subcommand_to_method( $class, array_shift( $args ) ); + } + + if ( !$subcommand ) { + describe_command( $class, WP_CLI_COMMAND ); + return; + } + + $instance = new $class; + $instance->$subcommand( $args, $assoc_args ); +} + +function subcommand_to_method( $class, $command ) { + $aliases = $class::get_aliases(); + + if ( isset( $aliases[ $subcommand ] ) ) { + $method = $aliases[ $subcommand ]; + } + + if ( !method_exists( $class, $subcommand ) ) { + // This if for reserved keywords in php (like list, isset) + $subcommand = '_' . $subcommand; + } + + if ( !method_exists( $class, $method ) ) { + return false; + } +} + +function describe_command( $class, $command ) { + if ( method_exists( $class, 'help' ) ) { + $class::help(); + return; + } + + $methods = get_subcommands( $class ); + + $out = "usage: wp $command"; + + if ( empty( $methods ) ) { + \WP_CLI::line( $out ); + } else { + $out .= ' [' . implode( '|', $methods ) . ']'; + + \WP_CLI::line( $out ); + + \WP_CLI::line(); + \WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); + } +} + +/** + * Get the list of subcommands for a class (reverse-dispatch). + * + * @param string $class + * @return array The list of methods + */ +function get_subcommands( $class ) { + if ( !is_string( $class ) ) + return array(); + + $reflection = new \ReflectionClass( $class ); + + return _filter_methods( $reflection, function( $method ) { + $name = $method->name; + + if ( strpos( $name, '_' ) === 0 ) { + $name = substr( $name, 1 ); + } + + return $name; + } ); +} + +function _filter_methods( $reflection, $cb ) { + $methods = array(); + + foreach ( $reflection->getMethods() as $method ) { + if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) + continue; + + $methods[] = $cb( $method ); + } + + return $methods; +} + diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c989911707..25199d918e 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -14,6 +14,7 @@ define( 'WP_CLI', true ); // Include the wp-cli classes +include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; @@ -127,7 +128,7 @@ // Generate strings for autocomplete if ( WP_CLI_AUTOCOMPLETE ) { foreach ( WP_CLI::load_all_commands() as $name => $command ) { - $subcommands = implode( ' ', WP_CLI::get_subcommands( $command ) ); + $subcommands = implode( ' ', WP_CLI\Dispatcher\get_subcommands( $command ) ); WP_CLI::line( $name . ' ' . $subcommands ); } exit; From b56d1b7aac9dbb58b45336209ce8b801c1aa5b9c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 22:24:55 +0300 Subject: [PATCH 0603/4858] fix likely incorrect mamp path. see #179 --- src/bin/wp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wp b/src/bin/wp index ec8e4a9526..9a7755d4ad 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -67,7 +67,7 @@ else fi # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php/php5.3*/bin/php /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php5.[34]*/bin/php /Applications/MAMP/bin/php/php.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do + for amp_php in /Applications/MAMP/bin/php/php5.3*/bin/php /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php5.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do if [ -x $amp_php ]; then php=$amp_php break From 39dd428a4881660227ec56f60d709798d9eb3e4c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 8 Oct 2012 23:36:58 +0300 Subject: [PATCH 0604/4858] move php detection to separate utility --- src/bin/wp | 18 ------------------ utils/amp-paths.txt | 5 +++++ utils/find-php | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 utils/amp-paths.txt create mode 100755 utils/find-php diff --git a/src/bin/wp b/src/bin/wp index 9a7755d4ad..d0fbdb4ea7 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -5,10 +5,6 @@ # http://drupal.org/project/drush # And 0.09% to the author of this project: # https://github.com/88mph/wpadmin/blob/master/wpadmin.php -# -# This is a wrapper script that will run wp-cli.php with the most appropriate -# php executable it can find on your system. -# # Get the absolute path of this executable ORIGDIR=$(pwd) @@ -59,20 +55,6 @@ else # Default to using the php that we find on the PATH. # Note that we need the full path to php here for Dreamhost, which behaves oddly. See http://drupal.org/node/662926 php=`which php` - - # We check for a command line (cli) version of php, and if found use that. - which php-cli >/dev/null 2>&1 - if [ "$?" = 0 ] ; then - php=`which php-cli` - fi - - # Special case for *AMP installers, since they normally don't set themselves as the default cli php out of the box. - for amp_php in /Applications/MAMP/bin/php/php5.3*/bin/php /Applications/MAMP/bin/php5*/bin/php /Applications/MAMP/bin/php/php5.[34]*/bin/php /opt/lampp/bin/php /Applications/xampp/xamppfiles/bin/php; do - if [ -x $amp_php ]; then - php=$amp_php - break - fi - done fi # Check to see if the user has provided a php.ini file or wp-cli.ini file in any conf dir diff --git a/utils/amp-paths.txt b/utils/amp-paths.txt new file mode 100644 index 0000000000..a6c891d3b8 --- /dev/null +++ b/utils/amp-paths.txt @@ -0,0 +1,5 @@ +/Applications/MAMP/bin/php/php5.3*/bin/php +/Applications/MAMP/bin/php5*/bin/php +/Applications/MAMP/bin/php/php5.[34]*/bin/php +/Applications/xampp/xamppfiles/bin/php; +/opt/lampp/bin/php diff --git a/utils/find-php b/utils/find-php new file mode 100755 index 0000000000..6c4d115cf3 --- /dev/null +++ b/utils/find-php @@ -0,0 +1,19 @@ +#!/usr/bin/env sh + +which php || which php-cli + +if [ $? -eq 0 ]; then + exit +fi + +# Special case for *AMP installers, since they normally don't set themselves +# as the default cli php out of the box. +for amp_php in $(cat $(dirname $0)/amp-paths.txt); do + if [ -x $amp_php ]; then + echo $amp_php + exit + fi +done + +echo "no php binary found" +exit 1 From 17e22502bf7d95877e795952accfd205ab959c51 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 9 Oct 2012 00:30:43 +0300 Subject: [PATCH 0605/4858] mention find-php in readme --- README.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4b99c1d1c9..7ac88e5df6 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ What is wp-cli? A set of tools for controlling WordPress installations from the command line. Requirements ------------- +============ * PHP >= 5.3 * WP >= 3.3 Installing ----------- +========== **Via PEAR:** @@ -29,9 +29,25 @@ sudo utils/dev-build You can replace `~/git/wp-cli` with whatever you want. +MAMP, XAMP, etc. +----------- + +If the `php` command is not available, you can try finding an appropriate binary: + +```sh +./utils/find-php +``` + +Then, create an environment variable called `WP_CLI_PHP` with the path found by `find-php`. + +In a UNIX environment, you would do this by adding the following line to your `.bashrc` file: + +```sh +WP_CLI_PHP=/path/to/php-binary +``` Using ------ +===== Go into a WordPress root folder: @@ -100,7 +116,7 @@ wp theme status ``` Adding commands ---------------- +=============== Adding commands to wp-cli is very easy. You can even add them from within your own plugin. You can find more information about adding commands in the [Commands Cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook) on our Wiki. @@ -108,7 +124,7 @@ You can find more information about adding commands in the [Commands Cookbook](h **Please share the commands you make, issue a pull request to get them included in wp-cli by default.** Changelog ---------------- +========= **0.6** From 66bf7da8e5baeb42243122402eb78e05274dfb36 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 9 Oct 2012 00:36:24 +0300 Subject: [PATCH 0606/4858] link to wiki from readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ac88e5df6..7dc46db18a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ What is wp-cli? -------------- -A set of tools for controlling WordPress installations from the command line. +wp-cli is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs, update posts and much more. + +Visit the [wiki](https://github.com/wp-cli/wp-cli/wiki) for more information. Requirements ============ From 655b26e9fde757bd3bec08c21df69879dadee0ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 9 Oct 2012 00:52:50 +0300 Subject: [PATCH 0607/4858] update docs; see #166 --- man/generate-posts.1 | 40 --------------- man/generate-users.1 | 22 -------- man/post-generate.1 | 51 +++++++++++++++++++ man/user-generate.1 | 25 +++++++++ .../{generate-posts.txt => post-generate.txt} | 10 ++-- .../{generate-users.txt => user-generate.txt} | 4 +- 6 files changed, 85 insertions(+), 67 deletions(-) create mode 100644 man/post-generate.1 create mode 100644 man/user-generate.1 rename src/docs/{generate-posts.txt => post-generate.txt} (62%) rename src/docs/{generate-users.txt => user-generate.txt} (64%) diff --git a/man/generate-posts.1 b/man/generate-posts.1 index 9f0ef3a2e3..995c5436f1 100644 --- a/man/generate-posts.1 +++ b/man/generate-posts.1 @@ -1,43 +1,3 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-GENERATE\-POSTS" "1" "September 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-generate\-posts\fR \- Generate a bunch of posts\. -. -.SH "SYNOPSIS" -\fBwp generate posts\fR [\-\-count=100] [\-\-type=post] [\-\-status=publish] [\-\-author=\fIlogin\fR] [\-\-max_depth=1] -. -.SH "OPTIONS" -. -.TP -\fB\-\-count\fR=\fInumber\fR: -. -.IP -How many posts to generate\. Default: 100 -. -.TP -\fB\-\-type\fR=\fIpost_type\fR: -. -.IP -The type of the generated posts\. Default: \'post\' -. -.TP -\fB\-\-status\fR=\fIpost_status\fR: -. -.IP -The status of the generated posts\. Default: \'publish\' -. -.TP -\fB\-\-author\fR=\fIlogin\fR: -. -.IP -The author of the generated posts\. Default: none -. -.TP -\fB\-\-max_depth\fR=\fInumber\fR: -. -.IP -For hierarchical post types, generate child posts down to a certain depth\. Default: 1 diff --git a/man/generate-users.1 b/man/generate-users.1 index 347a6a5f0f..995c5436f1 100644 --- a/man/generate-users.1 +++ b/man/generate-users.1 @@ -1,25 +1,3 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-GENERATE\-USERS" "1" "September 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-generate\-users\fR \- Generate a bunch of users\. -. -.SH "SYNOPSIS" -\fBwp generate users\fR [\-\-count=100] [\-\-role=\fIrole\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-count\fR=\fInumber\fR: -. -.IP -How many users to generate\. Default: 100 -. -.TP -\fB\-\-role\fR=\fIrole\fR: -. -.IP -The role of the generated users\. Default: default role from WP diff --git a/man/post-generate.1 b/man/post-generate.1 new file mode 100644 index 0000000000..afb014a25c --- /dev/null +++ b/man/post-generate.1 @@ -0,0 +1,51 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-GENERATE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-generate\fR \- Generate a bunch of posts\. +. +.SH "SYNOPSIS" +\fBwp post generate\fR [\-\-count=100] [\-\-post_type=post] [\-\-post_status=publish] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIdate\fR] [\-\-max_depth=1] +. +.SH "OPTIONS" +. +.TP +\fB\-\-count\fR=\fInumber\fR: +. +.IP +How many posts to generate\. Default: 100 +. +.TP +\fB\-\-type\fR=\fIpost_type\fR: +. +.IP +The type of the generated posts\. Default: \'post\' +. +.TP +\fB\-\-status\fR=\fIpost_status\fR: +. +.IP +The status of the generated posts\. Default: \'publish\' +. +.TP +\fB\-\-author\fR=\fIlogin\fR: +. +.IP +The author of the generated posts\. Default: none +. +.TP +\fB\-\-max_depth\fR=\fInumber\fR: +. +.IP +For hierarchical post types, generate child posts down to a certain depth\. Default: 1 +. +.SH "EXAMPLES" +. +.nf + +wp post generate \-\-count=10 \-\-post_type=page \-\-post_date=1999\-01\-04 +. +.fi + diff --git a/man/user-generate.1 b/man/user-generate.1 new file mode 100644 index 0000000000..a2331a2168 --- /dev/null +++ b/man/user-generate.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-GENERATE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-generate\fR \- Generate a bunch of users\. +. +.SH "SYNOPSIS" +\fBwp user generate\fR [\-\-count=100] [\-\-role=\fIrole\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-count\fR=\fInumber\fR: +. +.IP +How many users to generate\. Default: 100 +. +.TP +\fB\-\-role\fR=\fIrole\fR: +. +.IP +The role of the generated users\. Default: default role from WP + diff --git a/src/docs/generate-posts.txt b/src/docs/post-generate.txt similarity index 62% rename from src/docs/generate-posts.txt rename to src/docs/post-generate.txt index 129e4a1d05..3b5e282b2f 100644 --- a/src/docs/generate-posts.txt +++ b/src/docs/post-generate.txt @@ -1,10 +1,10 @@ -wp-generate-posts(1) -- Generate a bunch of posts. +wp-post-generate(1) -- Generate a bunch of posts. ==== ## SYNOPSIS -`wp generate posts` [--count=100] [--type=post] [--status=publish] -[--author=<login>] [--max_depth=1] +`wp post generate` [--count=100] [--post_type=post] [--post_status=publish] +[--post_author=<login>] [--post_date=<date>] [--max_depth=1] ## OPTIONS @@ -27,3 +27,7 @@ wp-generate-posts(1) -- Generate a bunch of posts. * `--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 diff --git a/src/docs/generate-users.txt b/src/docs/user-generate.txt similarity index 64% rename from src/docs/generate-users.txt rename to src/docs/user-generate.txt index 3b2da84a17..52885be9f0 100644 --- a/src/docs/generate-users.txt +++ b/src/docs/user-generate.txt @@ -1,9 +1,9 @@ -wp-generate-users(1) -- Generate a bunch of users. +wp-user-generate(1) -- Generate a bunch of users. ==== ## SYNOPSIS -`wp generate users` [--count=100] [--role=<role>] +`wp user generate` [--count=100] [--role=<role>] ## OPTIONS From eb8dd1679f80a7c25fe2ccf24c4cb506dcb77075 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 9 Oct 2012 01:31:17 +0300 Subject: [PATCH 0608/4858] introduce @subcommand and use same logic for describing and dispatching a command --- man/cache.1 | 10 ++-- man/core-install-network.1 | 25 +++++++++ man/core-install_network.1 | 22 -------- man/core-update-db.1 | 10 ++++ man/core-update_db.1 | 9 +-- src/docs/cache.txt | 8 +-- ...l_network.txt => core-install-network.txt} | 4 +- src/docs/core-update-db.txt | 6 ++ src/docs/core-update_db.txt | 6 -- src/php/wp-cli/commands/internals/cache.php | 12 +--- src/php/wp-cli/commands/internals/core.php | 3 +- src/php/wp-cli/commands/internals/help.php | 2 +- src/php/wp-cli/commands/internals/user.php | 3 +- src/php/wp-cli/dispatcher.php | 56 ++++++++++--------- src/php/wp-cli/wp-cli.php | 4 +- 15 files changed, 89 insertions(+), 91 deletions(-) create mode 100644 man/core-install-network.1 create mode 100644 man/core-update-db.1 rename src/docs/{core-install_network.txt => core-install-network.txt} (62%) create mode 100644 src/docs/core-update-db.txt delete mode 100644 src/docs/core-update_db.txt diff --git a/man/cache.1 b/man/cache.1 index 553960fad2..8d4bfc487f 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CACHE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-CACHE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-cache\fR \- Manage WordPress the object cache\. @@ -10,10 +10,10 @@ wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] . .P -wp cache add_global_groups \fIgroup\fR +wp cache add\-global\-groups \fIgroup\fR . .P -wp cache add_non_persistent_groups \fIgroup\fR +wp cache add\-non\-persistent\-groups \fIgroup\fR . .P wp cache decr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] @@ -51,13 +51,13 @@ wp cache type Add a value to cache where \fIkey\fR in \fIgroup\fR does not already exist\. . .TP -\fBadd_global_groups\fR: +\fBadd\-global\-groups\fR: . .IP Add a value to the global groups array\. . .TP -\fBadd_non_persistent_groups\fR: +\fBadd\-non\-persistent\-groups\fR: . .IP Add a value to the non persistent groups array\. diff --git a/man/core-install-network.1 b/man/core-install-network.1 new file mode 100644 index 0000000000..d849532c33 --- /dev/null +++ b/man/core-install-network.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-INSTALL\-NETWORK" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-install\-network\fR \- Transform a single\-site install into a +. +.SH "SYNOPSIS" +\fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=/] +. +.SH "OPTIONS" +. +.TP +\fB\-\-title\fR=\fIsite\-title\fR: +. +.IP +The title of the new network\. +. +.TP +\fB\-\-base_path\fR=\fIpath\fR: +. +.IP +Base path after the domain name that each site url will start with\. + diff --git a/man/core-install_network.1 b/man/core-install_network.1 index 6aad5aa0f3..995c5436f1 100644 --- a/man/core-install_network.1 +++ b/man/core-install_network.1 @@ -1,25 +1,3 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-INSTALL_NETWORK" "1" "September 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-install_network\fR \- Transform a single\-site install into a -. -.SH "SYNOPSIS" -\fBwp core install_network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=/] -. -.SH "OPTIONS" -. -.TP -\fB\-\-title\fR=\fIsite\-title\fR: -. -.IP -The title of the new network\. -. -.TP -\fB\-\-base_path\fR=\fIpath\fR: -. -.IP -Base path after the domain name that each site url will start with\. diff --git a/man/core-update-db.1 b/man/core-update-db.1 new file mode 100644 index 0000000000..87d2dbdb9c --- /dev/null +++ b/man/core-update-db.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-UPDATE\-DB" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-update\-db\fR \- Update the WordPress database\. +. +.SH "SYNOPSIS" +\fBwp core update\-db\fR diff --git a/man/core-update_db.1 b/man/core-update_db.1 index dc5a11563b..995c5436f1 100644 --- a/man/core-update_db.1 +++ b/man/core-update_db.1 @@ -1,10 +1,3 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-UPDATE_DB" "1" "September 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-update_db\fR \- Update the WordPress database\. -. -.SH "SYNOPSIS" -\fBwp core update_db\fR + diff --git a/src/docs/cache.txt b/src/docs/cache.txt index 069a875d30..c459862941 100644 --- a/src/docs/cache.txt +++ b/src/docs/cache.txt @@ -5,9 +5,9 @@ wp-cache(1) -- Manage WordPress the object cache. wp cache add <key> <value> [<group>] [<expiration>] -wp cache add_global_groups <group> +wp cache add-global-groups <group> -wp cache add_non_persistent_groups <group> +wp cache add-non-persistent-groups <group> wp cache decr <key> [<offset>] [<group>] @@ -33,11 +33,11 @@ wp cache type Add a value to cache where <key> in <group> does not already exist. -* `add_global_groups`: +* `add-global-groups`: Add a value to the global groups array. -* `add_non_persistent_groups`: +* `add-non-persistent-groups`: Add a value to the non persistent groups array. diff --git a/src/docs/core-install_network.txt b/src/docs/core-install-network.txt similarity index 62% rename from src/docs/core-install_network.txt rename to src/docs/core-install-network.txt index d40d946483..30c37441d6 100644 --- a/src/docs/core-install_network.txt +++ b/src/docs/core-install-network.txt @@ -1,10 +1,10 @@ -wp-core-install_network(1) -- Transform a single-site install into a +wp-core-install-network(1) -- Transform a single-site install into a multi-site install. ==== ## SYNOPSIS -`wp core install_network` --title=<network-title> [--base_path=/] +`wp core install-network` --title=<network-title> [--base_path=/] ## OPTIONS diff --git a/src/docs/core-update-db.txt b/src/docs/core-update-db.txt new file mode 100644 index 0000000000..b199312fdd --- /dev/null +++ b/src/docs/core-update-db.txt @@ -0,0 +1,6 @@ +wp-core-update-db(1) -- Update the WordPress database. +==== + +## SYNOPSIS + +`wp core update-db` diff --git a/src/docs/core-update_db.txt b/src/docs/core-update_db.txt deleted file mode 100644 index 7464475134..0000000000 --- a/src/docs/core-update_db.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-core-update_db(1) -- Update the WordPress database. -==== - -## SYNOPSIS - -`wp core update_db` diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index 5c1233994c..adf3454037 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -42,11 +42,7 @@ public function add( $args, $assoc_args ) { /** * Add global cache groups. * - * @uses wp_cache_add_global_groups - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @subcommand add-global-groups */ public function add_global_groups( $args, $assoc_args ) { if ( empty( $args ) ) { @@ -62,11 +58,7 @@ public function add_global_groups( $args, $assoc_args ) { /** * Adds a non-persistent group to the list. * - * @uses wp_cache_add_non_persistent_groups - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @subcommand add-non-persistent-groups */ public function add_non_persistent_groups( $args, $assoc_args ) { if ( empty( $args ) ) { diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 2da3efe8a1..8f177ff35e 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -253,8 +253,7 @@ function update( $args, $assoc_args ) { /** * Update the WordPress database * - * @param array $args - * @param array $assoc_args + * @subcommand update-db */ function update_db() { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index b4059ba1a9..e46bf1dcdc 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -39,7 +39,7 @@ function general_help() { $out = " wp $command"; - $methods = \WP_CLI\Dispatcher\get_subcommands( $class ); + $methods = array_keys( \WP_CLI\Dispatcher\get_subcommands( $class ) ); if ( !empty( $methods ) ) { $out .= ' [' . implode( '|', $methods ) . ']'; diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 4fbceb0976..50fbbb8e99 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -13,8 +13,7 @@ class User_Command extends WP_CLI_Command { /** * List users * - * @param array $args - * @param array $assoc_args + * @subcommand list **/ public function _list( $args, $assoc_args ) { global $blog_id; diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 9a26071fb2..1b1cd48378 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -19,33 +19,34 @@ function dispatch_subcommand( $class, $args, $assoc_args ) { if ( empty( $args ) ) { $subcommand = $class::get_default_subcommand(); } else { - $subcommand = subcommand_to_method( $class, array_shift( $args ) ); + $subcommand = array_shift( $args ); } - if ( !$subcommand ) { + $method = subcommand_to_method( $class, $subcommand ); + + if ( !$method ) { describe_command( $class, WP_CLI_COMMAND ); return; } $instance = new $class; - $instance->$subcommand( $args, $assoc_args ); + + $method->invoke( $instance, $args, $assoc_args ); } -function subcommand_to_method( $class, $command ) { +function subcommand_to_method( $class, $subcommand ) { $aliases = $class::get_aliases(); if ( isset( $aliases[ $subcommand ] ) ) { - $method = $aliases[ $subcommand ]; + $subcommand = $aliases[ $subcommand ]; } - if ( !method_exists( $class, $subcommand ) ) { - // This if for reserved keywords in php (like list, isset) - $subcommand = '_' . $subcommand; - } + $subcommands = get_subcommands( $class ); - if ( !method_exists( $class, $method ) ) { + if ( !isset( $subcommands[ $subcommand ] ) ) return false; - } + + return $subcommands[ $subcommand ]; } function describe_command( $class, $command ) { @@ -54,7 +55,7 @@ function describe_command( $class, $command ) { return; } - $methods = get_subcommands( $class ); + $methods = array_keys( get_subcommands( $class ) ); $out = "usage: wp $command"; @@ -74,7 +75,7 @@ function describe_command( $class, $command ) { * Get the list of subcommands for a class (reverse-dispatch). * * @param string $class - * @return array The list of methods + * @return array('subcommand' => $method) The list of methods */ function get_subcommands( $class ) { if ( !is_string( $class ) ) @@ -82,27 +83,28 @@ function get_subcommands( $class ) { $reflection = new \ReflectionClass( $class ); - return _filter_methods( $reflection, function( $method ) { - $name = $method->name; - - if ( strpos( $name, '_' ) === 0 ) { - $name = substr( $name, 1 ); - } - - return $name; - } ); -} - -function _filter_methods( $reflection, $cb ) { $methods = array(); foreach ( $reflection->getMethods() as $method ) { - if ( !$method->isPublic() || $method->isStatic() || $method->isConstructor() ) + if ( !_is_good_method( $method ) ) continue; - $methods[] = $cb( $method ); + $methods[ _get_subcommand_name( $method ) ] = $method; } return $methods; } +function _is_good_method( $method ) { + return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); +} + +function _get_subcommand_name( $method ) { + $comment = $method->getDocComment(); + + if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) + return $matches[1]; + + return $method->name; +} + diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 25199d918e..3605093ec2 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -128,8 +128,8 @@ // Generate strings for autocomplete if ( WP_CLI_AUTOCOMPLETE ) { foreach ( WP_CLI::load_all_commands() as $name => $command ) { - $subcommands = implode( ' ', WP_CLI\Dispatcher\get_subcommands( $command ) ); - WP_CLI::line( $name . ' ' . $subcommands ); + $subcommands = array_keys( WP_CLI\Dispatcher\get_subcommands( $command ) ); + WP_CLI::line( $name . ' ' . implode( ' ', $subcommands ) ); } exit; } From f01c0bcd5052b4f1c22e8200681c5f494edfa813 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 9 Oct 2012 02:04:13 +0300 Subject: [PATCH 0609/4858] remove cache subcommands that have ephemeral side-effects --- man/cache.1 | 18 ------------ src/docs/cache.txt | 12 -------- src/php/wp-cli/commands/internals/cache.php | 32 --------------------- 3 files changed, 62 deletions(-) diff --git a/man/cache.1 b/man/cache.1 index 8d4bfc487f..291f65dd12 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -10,12 +10,6 @@ wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] . .P -wp cache add\-global\-groups \fIgroup\fR -. -.P -wp cache add\-non\-persistent\-groups \fIgroup\fR -. -.P wp cache decr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] . .P @@ -51,18 +45,6 @@ wp cache type Add a value to cache where \fIkey\fR in \fIgroup\fR does not already exist\. . .TP -\fBadd\-global\-groups\fR: -. -.IP -Add a value to the global groups array\. -. -.TP -\fBadd\-non\-persistent\-groups\fR: -. -.IP -Add a value to the non persistent groups array\. -. -.TP \fBdecr\fR: . .IP diff --git a/src/docs/cache.txt b/src/docs/cache.txt index c459862941..d395a4d5fb 100644 --- a/src/docs/cache.txt +++ b/src/docs/cache.txt @@ -5,10 +5,6 @@ wp-cache(1) -- Manage WordPress the object cache. wp cache add <key> <value> [<group>] [<expiration>] -wp cache add-global-groups <group> - -wp cache add-non-persistent-groups <group> - wp cache decr <key> [<offset>] [<group>] wp cache delete <key> <group> @@ -33,14 +29,6 @@ wp cache type Add a value to cache where <key> in <group> does not already exist. -* `add-global-groups`: - - Add a value to the global groups array. - -* `add-non-persistent-groups`: - - Add a value to the non persistent groups array. - * `decr`: Decrement the value of a cached object by 1 or the value of the <offset> parameter. diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index adf3454037..d595ce9867 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -39,38 +39,6 @@ public function add( $args, $assoc_args ) { WP_CLI::success( "Added object '$key' in group '$group'." ); } - /** - * Add global cache groups. - * - * @subcommand add-global-groups - */ - public function add_global_groups( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache add_global_groups <group>' ); - exit; - } - - $group = $args[0]; - - wp_cache_add_global_groups( $group ); - } - - /** - * Adds a non-persistent group to the list. - * - * @subcommand add-non-persistent-groups - */ - public function add_non_persistent_groups( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache add_non_persistent_groups <group>' ); - exit; - } - - $group = $args[0]; - - wp_cache_add_non_persistent_groups( $group ); - } - /** * Decrement a value in the object cache. * From 983b21e06ed04d6dd855b04b84b76c85e4fd37c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 15:26:46 +0300 Subject: [PATCH 0610/4858] remove nonexistant command from cache docs --- man/cache.1 | 3 --- man/core-install_network.1 | 3 --- man/core-update_db.1 | 3 --- src/docs/cache.txt | 2 -- 4 files changed, 11 deletions(-) delete mode 100644 man/core-install_network.1 delete mode 100644 man/core-update_db.1 diff --git a/man/cache.1 b/man/cache.1 index 291f65dd12..0788dfb513 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -31,9 +31,6 @@ wp cache replace \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] wp cache set \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] . .P -wp cache switch_to_blog \fIblog_id\fR -. -.P wp cache type . .SH "SUBCOMMANDS" diff --git a/man/core-install_network.1 b/man/core-install_network.1 deleted file mode 100644 index 995c5436f1..0000000000 --- a/man/core-install_network.1 +++ /dev/null @@ -1,3 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 - diff --git a/man/core-update_db.1 b/man/core-update_db.1 deleted file mode 100644 index 995c5436f1..0000000000 --- a/man/core-update_db.1 +++ /dev/null @@ -1,3 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 - diff --git a/src/docs/cache.txt b/src/docs/cache.txt index d395a4d5fb..bd2d0f2865 100644 --- a/src/docs/cache.txt +++ b/src/docs/cache.txt @@ -19,8 +19,6 @@ wp cache replace <key> <value> [<group>] [<expiration>] wp cache set <key> <value> [<group>] [<expiration>] -wp cache switch_to_blog <blog_id> - wp cache type ## SUBCOMMANDS From 82c89cdc3b49570855dfb550044b639552fd9f50 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 15:28:25 +0300 Subject: [PATCH 0611/4858] rename install_network to install-network --- src/php/wp-cli/commands/internals/core.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 8f177ff35e..e433658e57 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -88,6 +88,9 @@ public function install( $args, $assoc_args ) { } } + /** + * @subcommand install-network + */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) WP_CLI::error( 'This already is a multisite install.' ); From 1c788d8f92ef1839aec8e1b960c03a8a30ca5201 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 16:10:12 +0300 Subject: [PATCH 0612/4858] first pass at @synopsis tag --- src/php/wp-cli/commands/internals/blog.php | 10 ++----- src/php/wp-cli/dispatcher.php | 35 +++++++++++++++------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index b1efc2ce3d..070e118852 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -12,10 +12,6 @@ */ class Blog_Command extends WP_CLI_Command { - private function _create_usage_string() { - return "usage: wp blog create --slug=<subdomain or directory name> --title=<blog title> [--email] [--site_id] [--private]"; - } - /** * Get site (network) data for a given id * @@ -35,11 +31,9 @@ private function _get_site( $site_id ) { } /** - * Create a blog via passed in arguments + * Create a blog in a multisite install. * - * @see BlogCommand::help() - * @param array $args - * @param array $assoc_args + * @synopsis --slug=<slug> --title=<Title> [--email=<email>] [--site_id=<site-id>] [--public] */ public function create( $args, $assoc_args ) { global $wpdb; diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 1b1cd48378..3cb97d51da 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -55,24 +55,30 @@ function describe_command( $class, $command ) { return; } - $methods = array_keys( get_subcommands( $class ) ); - - $out = "usage: wp $command"; + $methods = get_subcommands( $class ); if ( empty( $methods ) ) { - \WP_CLI::line( $out ); - } else { - $out .= ' [' . implode( '|', $methods ) . ']'; + \WP_CLI::line( "usage: wp $command" ); + return; + } - \WP_CLI::line( $out ); + $i = 0; - \WP_CLI::line(); - \WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); + foreach ( $methods as $subcommand => $method ) { + $synopsis = _get_subcommand_synopsis( $method ); + + $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; + + $desc = "wp $command $subcommand $synopsis"; + \WP_CLI::line( $prefix . $desc ); } + + \WP_CLI::line(); + \WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); } /** - * Get the list of subcommands for a class (reverse-dispatch). + * Get the list of subcommands for a class. * * @param string $class * @return array('subcommand' => $method) The list of methods @@ -108,3 +114,12 @@ function _get_subcommand_name( $method ) { return $method->name; } +function _get_subcommand_synopsis( $method ) { + $comment = $method->getDocComment(); + + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) + return false; + + return $matches[1]; +} + From f467e3cbd977197c4bfdc64f62435ae90339f7fb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 16:17:18 +0300 Subject: [PATCH 0613/4858] use get_aliases() in remaining places --- src/php/wp-cli/class-wp-cli-command-with-meta.php | 10 ++++++---- src/php/wp-cli/class-wp-cli-command.php | 2 +- src/php/wp-cli/commands/internals/db.php | 6 +++++- src/php/wp-cli/commands/internals/option.php | 8 +++++--- src/php/wp-cli/commands/internals/rewrite.php | 3 --- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-meta.php b/src/php/wp-cli/class-wp-cli-command-with-meta.php index 62934e48b2..d636fd809f 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-meta.php +++ b/src/php/wp-cli/class-wp-cli-command-with-meta.php @@ -7,11 +7,13 @@ */ abstract class WP_CLI_Command_With_Meta extends WP_CLI_Command { - protected $meta_type; + public static function get_aliases() { + return array( + 'set' => 'update' + ); + } - protected $aliases = array( - 'set' => 'update' - ); + protected $meta_type; /** * Get meta field value diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index 9bd137b854..c8166549ce 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -11,7 +11,7 @@ public static function get_default_subcommand() { return false; } - static function get_aliases() { + public static function get_aliases() { return array(); } diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index b426d30a39..2a2eb1be3a 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -14,7 +14,11 @@ public static function get_default_subcommand() { return 'cli'; } - protected $aliases = array( 'dump' => 'export' ); + public static function get_aliases() { + return array( + 'dump' => 'export' + ); + } /** * Creates the database specified in the wp-config.php file. diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 861e05eaec..ee3071e4be 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -10,9 +10,11 @@ */ class Option_Command extends WP_CLI_Command { - protected $aliases = array( - 'set' => 'update' - ); + public static function get_aliases() { + return array( + 'set' => 'update' + ); + } /** * Add an option diff --git a/src/php/wp-cli/commands/internals/rewrite.php b/src/php/wp-cli/commands/internals/rewrite.php index feb28d45f3..87ea5da60a 100644 --- a/src/php/wp-cli/commands/internals/rewrite.php +++ b/src/php/wp-cli/commands/internals/rewrite.php @@ -10,9 +10,6 @@ */ class Rewrite_Command extends WP_CLI_Command { - protected $aliases = array( - ); - /** * Flush rules * From b2bfff5560925dc44cfc739c03c5d4ca7057049f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 16:26:06 +0300 Subject: [PATCH 0614/4858] add synopsis for option subcommands --- src/php/wp-cli/commands/internals/option.php | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index ee3071e4be..d843083db2 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -17,13 +17,13 @@ public static function get_aliases() { } /** - * Add an option + * Add an option. * - * @param array $args - **/ + * @synopsis <key> <value> [--json] + */ public function add( $args, $assoc_args ) { if ( count( $args ) < 2 ) { - WP_CLI::line( "usage: wp option add <option-name> <option-value>" ); + WP_CLI::line( "usage: wp option add <key> <value>" ); exit; } @@ -39,11 +39,11 @@ public function add( $args, $assoc_args ) { /** * Update an option * - * @param array $args + * @synopsis <key> <value> [--json] **/ public function update( $args, $assoc_args ) { if ( count( $args ) < 2 ) { - WP_CLI::line( "usage: wp option update <option-name> <option-value>" ); + WP_CLI::line( "usage: wp option update <key> <value>" ); exit; } @@ -62,11 +62,11 @@ public function update( $args, $assoc_args ) { /** * Delete an option * - * @param array $args - **/ + * @synopsis <key> + */ public function delete( $args ) { if ( empty( $args ) ) { - WP_CLI::line( "usage: wp option get <option-name>" ); + WP_CLI::line( "usage: wp option delete <key>" ); exit; } @@ -80,11 +80,11 @@ public function delete( $args ) { /** * Get an option * - * @param array $args - **/ + * @synopsis <key> [--json] + */ public function get( $args, $assoc_args ) { if ( empty( $args ) ) { - WP_CLI::line( "usage: wp option get <option-name>" ); + WP_CLI::line( "usage: wp option get <key>" ); exit; } From b26b755c59c9e059d5d436190fd4d6371d8ea718 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 16:41:44 +0300 Subject: [PATCH 0615/4858] introduce Subcommand class --- src/php/wp-cli/dispatcher.php | 81 ++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 3cb97d51da..a8c9221c77 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -16,37 +16,37 @@ function dispatch( $implementation, $arguments, $assoc_args ) { * @param array $assoc_args */ function dispatch_subcommand( $class, $args, $assoc_args ) { - if ( empty( $args ) ) { - $subcommand = $class::get_default_subcommand(); - } else { - $subcommand = array_shift( $args ); - } + $subcommand = find_subcommand( $class, $args ); - $method = subcommand_to_method( $class, $subcommand ); - - if ( !$method ) { + if ( !$subcommand ) { describe_command( $class, WP_CLI_COMMAND ); return; } $instance = new $class; - $method->invoke( $instance, $args, $assoc_args ); + $subcommand->invoke( $instance, $args, $assoc_args ); } -function subcommand_to_method( $class, $subcommand ) { +function find_subcommand( $class, $args ) { + if ( empty( $args ) ) { + $name = $class::get_default_subcommand(); + } else { + $name = array_shift( $args ); + } + $aliases = $class::get_aliases(); - if ( isset( $aliases[ $subcommand ] ) ) { - $subcommand = $aliases[ $subcommand ]; + if ( isset( $aliases[ $name ] ) ) { + $name = $aliases[ $name ]; } $subcommands = get_subcommands( $class ); - if ( !isset( $subcommands[ $subcommand ] ) ) + if ( !isset( $subcommands[ $name ] ) ) return false; - return $subcommands[ $subcommand ]; + return $subcommands[ $name ]; } function describe_command( $class, $command ) { @@ -64,13 +64,10 @@ function describe_command( $class, $command ) { $i = 0; - foreach ( $methods as $subcommand => $method ) { - $synopsis = _get_subcommand_synopsis( $method ); - - $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; + foreach ( $methods as $name => $subcommand ) { + $prefix = ( 0 == $i++ ) ? 'usage:' : ' or:'; - $desc = "wp $command $subcommand $synopsis"; - \WP_CLI::line( $prefix . $desc ); + \WP_CLI::line( "$prefix wp $command $name " . $subcommand->get_synopsis() ); } \WP_CLI::line(); @@ -81,7 +78,7 @@ function describe_command( $class, $command ) { * Get the list of subcommands for a class. * * @param string $class - * @return array('subcommand' => $method) The list of methods + * @return array('subcommand' => Subcommand) The list of subcommands */ function get_subcommands( $class ) { if ( !is_string( $class ) ) @@ -89,37 +86,51 @@ function get_subcommands( $class ) { $reflection = new \ReflectionClass( $class ); - $methods = array(); + $subcommands = array(); foreach ( $reflection->getMethods() as $method ) { if ( !_is_good_method( $method ) ) continue; - $methods[ _get_subcommand_name( $method ) ] = $method; + $subcommand = new Subcommand( $method ); + + $subcommands[ $subcommand->get_name() ] = $subcommand; } - return $methods; + return $subcommands; } function _is_good_method( $method ) { return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); } -function _get_subcommand_name( $method ) { - $comment = $method->getDocComment(); - if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) - return $matches[1]; +class Subcommand { - return $method->name; -} + function __construct( $method ) { + $this->method = $method; + } -function _get_subcommand_synopsis( $method ) { - $comment = $method->getDocComment(); + function get_name() { + $comment = $this->method->getDocComment(); - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) - return false; + if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) + return $matches[1]; + + return $this->method->name; + } + + function get_synopsis() { + $comment = $this->method->getDocComment(); - return $matches[1]; + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) + return false; + + return $matches[1]; + } + + function invoke() { + return call_user_func_array( array( $this->method, 'invoke' ), func_get_args() ); + } } From 89c3ab8b5d4ada6b340d76a5548d731e4b329f22 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 17:33:11 +0300 Subject: [PATCH 0616/4858] add validation for mandatory positional args --- src/php/wp-cli/dispatcher.php | 83 ++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index a8c9221c77..8e26eb296d 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -65,9 +65,9 @@ function describe_command( $class, $command ) { $i = 0; foreach ( $methods as $name => $subcommand ) { - $prefix = ( 0 == $i++ ) ? 'usage:' : ' or:'; + $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; - \WP_CLI::line( "$prefix wp $command $name " . $subcommand->get_synopsis() ); + $subcommand->show_usage( $prefix ); } \WP_CLI::line(); @@ -92,7 +92,7 @@ function get_subcommands( $class ) { if ( !_is_good_method( $method ) ) continue; - $subcommand = new Subcommand( $method ); + $subcommand = new Subcommand( $method, 'TODO' ); $subcommands[ $subcommand->get_name() ] = $subcommand; } @@ -107,8 +107,9 @@ function _is_good_method( $method ) { class Subcommand { - function __construct( $method ) { + function __construct( $method, $command ) { $this->method = $method; + $this->command = $command; } function get_name() { @@ -120,7 +121,19 @@ function get_name() { return $this->method->name; } - function get_synopsis() { + function show_usage( $prefix = 'usage: ' ) { + $name = $this->get_name(); + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $this->command $name $synopsis" ); + } + + function invoke( $instance, $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + return $this->method->invoke( $instance, $args, $assoc_args ); + } + + protected function get_synopsis() { $comment = $this->method->getDocComment(); if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) @@ -129,8 +142,64 @@ function get_synopsis() { return $matches[1]; } - function invoke() { - return call_user_func_array( array( $this->method, 'invoke' ), func_get_args() ); + protected function check_args( $args, $assoc_args ) { + $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); + + $mandatory_positinal = wp_list_filter( $accepted_params, array( + 'type' => 'positional', + 'optional' => false + ) ); + + if ( count( $args ) < count( $mandatory_positinal ) ) { + $this->show_usage(); + exit(1); + } + } + + protected function parse_synopsis( $synopsis ) { + $patterns = self::get_patterns(); + + $tokens = preg_split( '/[\s\t]+/', $synopsis ); + + $params = array(); + + foreach ( $tokens as $token ) { + foreach ( $patterns as $regex => $desc ) { + if ( preg_match( $regex, $token, $matches ) ) { + $params[] = array_merge( $matches, $desc ); + break; + } + } + } + + return $params; + } + + private static function get_patterns() { + $p_name = '(?P<name>[a-z-]+)'; + $p_value = '<(?P<value>[a-z-]+)>'; + + $param_types = array( + 'positional' => $p_value, + 'assoc' => "--$p_name=$p_value", + 'flag' => "--$p_name" + ); + + $patterns = array(); + + foreach ( $param_types as $type => $pattern ) { + $patterns[ "/^$pattern$/" ] = array( + 'type' => $type, + 'optional' => false + ); + + $patterns[ "/^\[$pattern\]$/" ] = array( + 'type' => $type, + 'optional' => true + ); + } + + return $patterns; } } From 95e77c66963696d5a7aecca73f8d94c6664969a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 18:06:50 +0300 Subject: [PATCH 0617/4858] introduce SimpleCommand and CompositeCommand --- src/php/wp-cli/class-wp-cli.php | 13 +- src/php/wp-cli/commands/internals/help.php | 18 +-- src/php/wp-cli/dispatcher.php | 158 ++++++++++++--------- src/php/wp-cli/wp-cli.php | 3 +- 4 files changed, 106 insertions(+), 86 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 17507abd05..8e2a7292f1 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -15,8 +15,13 @@ class WP_CLI { * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command */ - public function add_command( $name, $class ) { - self::$commands[$name] = $class; + public function add_command( $name, $implementation ) { + if ( is_string( $implementation ) && class_exists( $implementation ) ) + $class = '\WP_CLI\Dispatcher\CompositeCommand'; + else + $class = '\WP_CLI\Dispatcher\SimpleCommand'; + + self::$commands[ $name ] = new $class( $implementation, $name ); } /** @@ -333,9 +338,9 @@ static function run_command( $arguments, $assoc_args ) { define( 'WP_CLI_COMMAND', $command ); - $implementation = self::load_command( $command ); + $command = self::load_command( $command ); - \WP_CLI\Dispatcher\dispatch( $implementation, $arguments, $assoc_args ); + $command->invoke( $arguments, $assoc_args ); } static function load_command( $command ) { diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index e46bf1dcdc..0aced7af8b 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -27,25 +27,17 @@ function maybe_load_man_page( $args ) { } function show_available_subcommands( $command ) { - $class = \WP_CLI::load_command( $command ); - \WP_CLI\Dispatcher\describe_command( $class, $command ); + $command = \WP_CLI::load_command( $command ); + $command->show_usage(); } function general_help() { \WP_CLI::line( 'Available commands:' ); - foreach ( \WP_CLI::load_all_commands() as $command => $class ) { - if ( 'help' == $command ) + foreach ( \WP_CLI::load_all_commands() as $name => $command ) { + if ( 'help' == $name ) continue; - $out = " wp $command"; - - $methods = array_keys( \WP_CLI\Dispatcher\get_subcommands( $class ) ); - - if ( !empty( $methods ) ) { - $out .= ' [' . implode( '|', $methods ) . ']'; - } - - \WP_CLI::line( $out ); + \WP_CLI::line( " wp $name " . $command->shortdesc() ); } \WP_CLI::line(<<<EOB diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 8e26eb296d..1567a6cb1a 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -2,106 +2,130 @@ namespace WP_CLI\Dispatcher; -function dispatch( $implementation, $arguments, $assoc_args ) { - if ( is_string( $implementation ) && class_exists( $implementation ) ) - dispatch_subcommand( $implementation, $arguments, $assoc_args ); - else - call_user_func( $implementation, $arguments, $assoc_args ); +abstract class Command { + + function __construct( $implementation, $name ) { + $this->implementation = $implementation; + $this->name = $name; + } + + abstract function autocomplete(); + abstract function shortdesc(); + abstract function show_usage(); + abstract function invoke( $arguments, $assoc_args ); } -/** - * Transfers the handling to the appropriate method - * - * @param array $args - * @param array $assoc_args - */ -function dispatch_subcommand( $class, $args, $assoc_args ) { - $subcommand = find_subcommand( $class, $args ); - if ( !$subcommand ) { - describe_command( $class, WP_CLI_COMMAND ); - return; +class SimpleCommand extends Command { + + function autocomplete() { + return $this->name; } - $instance = new $class; + function shortdesc() { + return ''; + } + + function show_usage() { + \WP_CLI::line( "usage: wp $this->name" ); + } - $subcommand->invoke( $instance, $args, $assoc_args ); + function invoke( $arguments, $assoc_args ) { + call_user_func( $this->implementation, $arguments, $assoc_args ); + } } -function find_subcommand( $class, $args ) { - if ( empty( $args ) ) { - $name = $class::get_default_subcommand(); - } else { - $name = array_shift( $args ); + +class CompositeCommand extends Command { + + function autocomplete() { + $subcommands = array_keys( $this->get_subcommands() ); + return $this->name . ' ' . implode( ' ', $subcommands ); } - $aliases = $class::get_aliases(); + function shortdesc() { + $methods = array_keys( $this->get_subcommands() ); - if ( isset( $aliases[ $name ] ) ) { - $name = $aliases[ $name ]; + return implode( '|', $methods ); } - $subcommands = get_subcommands( $class ); + function show_usage() { + if ( method_exists( $this->implementation, 'help' ) ) { + $class::help(); + return; + } - if ( !isset( $subcommands[ $name ] ) ) - return false; + $methods = $this->get_subcommands(); - return $subcommands[ $name ]; -} + $i = 0; -function describe_command( $class, $command ) { - if ( method_exists( $class, 'help' ) ) { - $class::help(); - return; - } + foreach ( $methods as $name => $subcommand ) { + $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; - $methods = get_subcommands( $class ); + $subcommand->show_usage( $prefix ); + } - if ( empty( $methods ) ) { - \WP_CLI::line( "usage: wp $command" ); - return; + \WP_CLI::line(); + \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); } - $i = 0; + function invoke( $args, $assoc_args ) { + $subcommand = $this->find_subcommand( $args ); + + if ( !$subcommand ) { + $this->show_usage(); + return; + } - foreach ( $methods as $name => $subcommand ) { - $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; + $class = $this->implementation; + $instance = new $class; - $subcommand->show_usage( $prefix ); + $subcommand->invoke( $instance, $args, $assoc_args ); } - \WP_CLI::line(); - \WP_CLI::line( "See 'wp help $command <subcommand>' for more information on a specific subcommand." ); -} + protected function find_subcommand( $args ) { + $class = $this->implementation; -/** - * Get the list of subcommands for a class. - * - * @param string $class - * @return array('subcommand' => Subcommand) The list of subcommands - */ -function get_subcommands( $class ) { - if ( !is_string( $class ) ) - return array(); + if ( empty( $args ) ) { + $name = $class::get_default_subcommand(); + } else { + $name = array_shift( $args ); + } - $reflection = new \ReflectionClass( $class ); + $aliases = $class::get_aliases(); - $subcommands = array(); + if ( isset( $aliases[ $name ] ) ) { + $name = $aliases[ $name ]; + } - foreach ( $reflection->getMethods() as $method ) { - if ( !_is_good_method( $method ) ) - continue; + $subcommands = $this->get_subcommands(); - $subcommand = new Subcommand( $method, 'TODO' ); + if ( !isset( $subcommands[ $name ] ) ) + return false; - $subcommands[ $subcommand->get_name() ] = $subcommand; + return $subcommands[ $name ]; } - return $subcommands; -} + protected function get_subcommands() { + $reflection = new \ReflectionClass( $this->implementation ); + + $subcommands = array(); -function _is_good_method( $method ) { - return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); + foreach ( $reflection->getMethods() as $method ) { + if ( !self::_is_good_method( $method ) ) + continue; + + $subcommand = new Subcommand( $method, $this->name ); + + $subcommands[ $subcommand->get_name() ] = $subcommand; + } + + return $subcommands; + } + + private static function _is_good_method( $method ) { + return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); + } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 3605093ec2..016fd3a5af 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -128,8 +128,7 @@ // Generate strings for autocomplete if ( WP_CLI_AUTOCOMPLETE ) { foreach ( WP_CLI::load_all_commands() as $name => $command ) { - $subcommands = array_keys( WP_CLI\Dispatcher\get_subcommands( $command ) ); - WP_CLI::line( $name . ' ' . implode( ' ', $subcommands ) ); + WP_CLI::line( $command->autocomplete() ); } exit; } From 59d71ac8233e7a3c5f8322aa5efcf1f945593a6a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 18:52:57 +0300 Subject: [PATCH 0618/4858] remove first argument again, which represents the subcommand --- src/php/wp-cli/dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 1567a6cb1a..92adbfb835 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -83,7 +83,7 @@ function invoke( $args, $assoc_args ) { $subcommand->invoke( $instance, $args, $assoc_args ); } - protected function find_subcommand( $args ) { + protected function find_subcommand( &$args ) { $class = $this->implementation; if ( empty( $args ) ) { From 3b7b50e8a1836f2536a6cecd775109177475145d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 18:54:59 +0300 Subject: [PATCH 0619/4858] remove redundant arg checking inside option subcommands --- src/php/wp-cli/commands/internals/option.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index d843083db2..966055579a 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -22,11 +22,6 @@ public static function get_aliases() { * @synopsis <key> <value> [--json] */ public function add( $args, $assoc_args ) { - if ( count( $args ) < 2 ) { - WP_CLI::line( "usage: wp option add <key> <value>" ); - exit; - } - $key = $args[0]; $value = WP_CLI::read_value( $args[1], $assoc_args ); @@ -42,11 +37,6 @@ public function add( $args, $assoc_args ) { * @synopsis <key> <value> [--json] **/ public function update( $args, $assoc_args ) { - if ( count( $args ) < 2 ) { - WP_CLI::line( "usage: wp option update <key> <value>" ); - exit; - } - $key = $args[0]; $value = WP_CLI::read_value( $args[1], $assoc_args ); @@ -65,11 +55,6 @@ public function update( $args, $assoc_args ) { * @synopsis <key> */ public function delete( $args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp option delete <key>" ); - exit; - } - list( $key ) = $args; if ( !delete_option( $key ) ) { @@ -83,11 +68,6 @@ public function delete( $args ) { * @synopsis <key> [--json] */ public function get( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp option get <key>" ); - exit; - } - list( $key ) = $args; $value = get_option( $key ); From fb988cf49521e96ad84cbf71621a30250646fd2f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 18:56:54 +0300 Subject: [PATCH 0620/4858] some reordering --- src/php/wp-cli/commands/internals/option.php | 32 ++++++++++---------- src/php/wp-cli/dispatcher.php | 18 +++++------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 966055579a..0f3ddc0d31 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -16,6 +16,22 @@ public static function get_aliases() { ); } + /** + * Get an option + * + * @synopsis <key> [--json] + */ + public function get( $args, $assoc_args ) { + list( $key ) = $args; + + $value = get_option( $key ); + + if ( false === $value ) + die(1); + + WP_CLI::print_value( $value, $assoc_args ); + } + /** * Add an option. * @@ -61,20 +77,4 @@ public function delete( $args ) { WP_CLI::error( "Could not delete '$key' option. Does it exist?" ); } } - - /** - * Get an option - * - * @synopsis <key> [--json] - */ - public function get( $args, $assoc_args ) { - list( $key ) = $args; - - $value = get_option( $key ); - - if ( false === $value ) - die(1); - - WP_CLI::print_value( $value, $assoc_args ); - } } diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 92adbfb835..d6adacf206 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -157,15 +157,6 @@ function invoke( $instance, $args, $assoc_args ) { return $this->method->invoke( $instance, $args, $assoc_args ); } - protected function get_synopsis() { - $comment = $this->method->getDocComment(); - - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) - return false; - - return $matches[1]; - } - protected function check_args( $args, $assoc_args ) { $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); @@ -180,6 +171,15 @@ protected function check_args( $args, $assoc_args ) { } } + protected function get_synopsis() { + $comment = $this->method->getDocComment(); + + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) + return false; + + return $matches[1]; + } + protected function parse_synopsis( $synopsis ) { $patterns = self::get_patterns(); From 1ccdd2e6a34d5524f111cad1a1d2cd4eb47e5b63 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 19:07:02 +0300 Subject: [PATCH 0621/4858] check mandatory assoc args too --- src/php/wp-cli/commands/internals/blog.php | 14 +------------- src/php/wp-cli/dispatcher.php | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 070e118852..a9ebc6e626 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -33,23 +33,11 @@ private function _get_site( $site_id ) { /** * Create a blog in a multisite install. * - * @synopsis --slug=<slug> --title=<Title> [--email=<email>] [--site_id=<site-id>] [--public] + * @synopsis --slug=<slug> --title=<title> [--email=<email>] [--site_id=<site-id>] [--public] */ public function create( $args, $assoc_args ) { global $wpdb; - $has_errors = false; - - foreach ( array( 'slug', 'title' ) as $required ) { - if ( empty( $assoc_args[$required] ) ) { - WP_CLI::warning( "missing --$required parameter" ); - $has_errors = true; - } - } - - if ( $has_errors ) - exit(1); - $base = $assoc_args['slug']; $title = $assoc_args['title']; $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index d6adacf206..c368b7ce51 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -169,6 +169,28 @@ protected function check_args( $args, $assoc_args ) { $this->show_usage(); exit(1); } + + $mandatory_assoc = wp_list_pluck( wp_list_filter( $accepted_params, array( + 'type' => 'assoc', + 'optional' => false + ) ), 'name' ); + + $errors = array(); + + foreach ( $mandatory_assoc as $key ) { + if ( !isset( $assoc_args[ $key ] ) ) + $errors[] = "missing --$key parameter"; + elseif ( true === $assoc_args[ $key ] ) + $errors[] = "--$key parameter needs a value"; + } + + if ( empty( $errors ) ) + return; + + foreach ( $errors as $error ) + \WP_CLI::warning( $error ); + + exit(1); } protected function get_synopsis() { From 944ef1315ddff27f9f4905b63d63fbe32aee2c41 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 20:03:12 +0300 Subject: [PATCH 0622/4858] add @synopsis for plugin commands --- src/php/wp-cli/commands/internals/plugin.php | 51 ++++++++------------ 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index dfc3a1272d..053d7bab86 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -46,12 +46,12 @@ protected function get_all_items() { } /** - * Activate a plugin + * Activate a plugin. * - * @param array $args + * @synopsis <plugin> [--network] */ function activate( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $network_wide = isset( $assoc_args['network'] ); @@ -65,12 +65,12 @@ function activate( $args, $assoc_args = array() ) { } /** - * Deactivate a plugin + * Deactivate a plugin. * - * @param array $args + * @synopsis <plugin> [--network] */ function deactivate( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $network_wide = isset( $assoc_args['network'] ); @@ -84,12 +84,12 @@ function deactivate( $args, $assoc_args = array() ) { } /** - * Toggle a plugin's activation state + * Toggle a plugin's activation state. * - * @param array $args + * @synopsis <plugin> [--network] */ function toggle( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $network_wide = isset( $assoc_args['network'] ); @@ -101,16 +101,15 @@ function toggle( $args, $assoc_args = array() ) { } /** - * Get a plugin path + * Get a plugin path. * - * @param array $args - * @param array $assoc_args + * @synopsis [<plugin>] [--dir] */ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); if ( !empty( $args ) ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $path .= '/' . $file; if ( isset( $assoc_args['dir'] ) ) @@ -174,10 +173,9 @@ protected function install_from_repo( $slug, $assoc_args ) { } /** - * Update a plugin (to the latest dev version) + * Update a plugin. * - * @param array $args - * @param array $assoc_args + * @synopsis [<plugin>] [--all] [--version=<version>] */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { @@ -204,12 +202,12 @@ protected function get_item_list() { } /** - * Uninstall a plugin + * Uninstall a plugin. * - * @param array $args + * @synopsis <plugin> [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); if ( is_plugin_active( $file ) ) { WP_CLI::error( 'The plugin is active.' ); @@ -222,12 +220,12 @@ function uninstall( $args, $assoc_args = array() ) { } /** - * Delete plugin files + * Delete plugin files. * - * @param array $args + * @synopsis <plugin> */ function delete( $args, $assoc_args = array(), $exit_on_error = true ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $plugin_dir = dirname( $file ); if ( '.' == $plugin_dir ) @@ -273,16 +271,9 @@ protected function get_details( $file ) { * Parse the name of a plugin to a filename, check if it exists * * @param array $args - * @param string $subcommand - * @param bool $exit * @return array */ - protected function parse_name( $args, $subcommand ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp plugin $subcommand <plugin-name>" ); - exit; - } - + protected function parse_name( $args ) { $name = $args[0]; $plugins = get_plugins( '/' . $name ); From 29e34dc3e73a28d3e1b7425da75bfa8c35accdce Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 22:19:45 +0300 Subject: [PATCH 0623/4858] add synopsis for all theme subcommands --- .../class-wp-cli-command-with-upgrade.php | 25 ++-------- src/php/wp-cli/commands/internals/plugin.php | 18 +++++++ src/php/wp-cli/commands/internals/theme.php | 48 ++++++++++++++----- src/php/wp-cli/dispatcher.php | 2 +- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 253724cb05..d11741b237 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -11,7 +11,7 @@ public static function get_default_subcommand() { protected $upgrade_refresh; protected $upgrade_transient; - abstract protected function parse_name( $args, $subcommand ); + abstract protected function parse_name( $args ); abstract protected function get_item_list(); abstract protected function get_all_items(); @@ -23,19 +23,14 @@ abstract protected function _status_single( $details, $name, $version, $status ) abstract protected function install_from_repo( $slug, $assoc_args ); - /** - * Get the status of one or all items - * - * @param array $args - */ - function status( $args = array() ) { + function status( $args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); if ( empty( $args ) ) { $this->status_all(); } else { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $this->status_single( $file, $name ); } @@ -96,12 +91,6 @@ private function status_single( $file, $name ) { $this->_status_single( $details, $name, $version, $status ); } - /** - * Install a new plugin/theme - * - * @param array $args - * @param array $assoc_args - */ function install( $args, $assoc_args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp $this->item_type install <slug>" ); @@ -131,17 +120,11 @@ function install( $args, $assoc_args ) { } } - /** - * Update a plugin/theme - * - * @param array $args - * @param array $assoc_args - */ function update( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); WP_CLI::get_upgrader( $this->upgrader )->upgrade( $file ); } else { diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 053d7bab86..7d93c962c6 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -22,6 +22,15 @@ function __construct() { parent::__construct(); } + /** + * See the status of one or all plugins. + * + * @synopsis [<plugin>] + */ + function status( $args ) { + parent::status( $args ); + } + protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); @@ -201,6 +210,15 @@ protected function get_item_list() { return $items; } + /** + * Install a plugin from wordpress.org or from a zip file. + * + * @synopsis <plugin|zip> [--version=<version>] [--activate] + */ + function install( $args, $assoc_args ) { + parent::install( $args, $assoc_args ); + } + /** * Uninstall a plugin. * diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index bf0b349107..e86c5ede57 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -15,6 +15,15 @@ class Theme_Command extends WP_CLI_Command_With_Upgrade { protected $upgrade_refresh = 'wp_update_themes'; protected $upgrade_transient = 'update_themes'; + /** + * See the status of one or all themes. + * + * @synopsis [<theme>] + */ + function status( $args ) { + parent::status( $args ); + } + protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( 'Theme %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); @@ -39,12 +48,12 @@ protected function get_details( $stylesheet ) { } /** - * Activate a theme + * Activate a theme. * - * @param array $args + * @synopsis <theme> **/ public function activate( $args = array() ) { - list( $stylesheet, $child ) = $this->parse_name( $args, __FUNCTION__ ); + list( $stylesheet, $child ) = $this->parse_name( $args ); $details = get_theme_data( $stylesheet ); @@ -72,16 +81,15 @@ private function is_active_theme( $stylesheet ) { } /** - * Get a theme path + * Get a theme path. * - * @param array $args - * @param array $assoc_args + * @synopsis [<theme>] [--dir] */ function path( $args, $assoc_args ) { if ( empty( $args ) ) { $path = WP_CONTENT_DIR . '/themes'; } else { - list( $stylesheet, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $stylesheet, $name ) = $this->parse_name( $args ); $path = $stylesheet; if ( isset( $assoc_args['dir'] ) ) @@ -144,12 +152,30 @@ protected function get_item_list() { } /** - * Delete a theme + * Install a theme from wordpress.org or from a zip file. + * + * @synopsis <theme|zip> [--version=<version>] [--activate] + */ + function install( $args, $assoc_args ) { + parent::install( $args, $assoc_args ); + } + + /** + * Update a theme. + * + * @synopsis [<theme>] [--all] + */ + function update( $args, $assoc_args ) { + parent::update( $args, $assoc_args ); + } + + /** + * Delete a theme. * - * @param array $args + * @synopsis <theme> */ function delete( $args ) { - list( $file, $name ) = $this->parse_name( $args, __FUNCTION__ ); + list( $file, $name ) = $this->parse_name( $args ); $r = delete_theme( $name ); @@ -158,7 +184,7 @@ function delete( $args ) { } } - protected function parse_name( $args, $subcommand ) { + protected function parse_name( $args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp theme $subcommand <theme-name>" ); exit; diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index c368b7ce51..bbf2d8ba30 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -223,7 +223,7 @@ protected function parse_synopsis( $synopsis ) { private static function get_patterns() { $p_name = '(?P<name>[a-z-]+)'; - $p_value = '<(?P<value>[a-z-]+)>'; + $p_value = '<(?P<value>[a-z-|]+)>'; $param_types = array( 'positional' => $p_value, From 13493b223130f47324d8211f05c4527c918aa4e4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 22:27:39 +0300 Subject: [PATCH 0624/4858] replace closures with $method parameter in add_command() --- man/export.1 | 2 +- src/docs/export.txt | 2 +- src/php/wp-cli/class-wp-cli.php | 11 +-- src/php/wp-cli/commands/internals/export.php | 8 +- src/php/wp-cli/commands/internals/help.php | 72 ++++++++++-------- src/php/wp-cli/commands/internals/home.php | 43 +++++++---- src/php/wp-cli/dispatcher.php | 79 +++++++++++--------- 7 files changed, 126 insertions(+), 91 deletions(-) diff --git a/man/export.1 b/man/export.1 index a2e45d461d..20f47f672e 100644 --- a/man/export.1 +++ b/man/export.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EXPORT" "1" "September 2012" "" "WP-CLI" +.TH "WP\-EXPORT" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-export\fR \- Create a WXR file\. diff --git a/src/docs/export.txt b/src/docs/export.txt index 5e7d32e54b..1aafbc5b17 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -3,7 +3,7 @@ wp-export(1) -- Create a WXR file. ## SYNOPSIS -`wp export` --path=<dirname> [filters] [--skip_comments] +`wp export` --dir=<dirname> [filters] [--skip_comments] ## OPTIONS diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8e2a7292f1..553c077793 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -14,14 +14,15 @@ class WP_CLI { * * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command + * @param string $method The method to call, instead of subcommands */ - public function add_command( $name, $implementation ) { - if ( is_string( $implementation ) && class_exists( $implementation ) ) - $class = '\WP_CLI\Dispatcher\CompositeCommand'; + public function add_command( $name, $class, $method = false ) { + if ( !$method ) + $command = new \WP_CLI\Dispatcher\CompositeCommand( $name, $class ); else - $class = '\WP_CLI\Dispatcher\SimpleCommand'; + $command = new \WP_CLI\Dispatcher\SimpleCommand( $name, $class, $method ); - self::$commands[ $name ] = new $class( $implementation, $name ); + self::$commands[ $name ] = $command; } /** diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 02a42ddd48..350cbb5dd5 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -1,6 +1,6 @@ <?php -WP_CLI::add_command( 'export', array( new Export_Command, 'export' ) ); +WP_CLI::add_command( 'export', 'Export_Command', 'export' ); /** * Implement export command @@ -8,10 +8,12 @@ * @package wp-cli * @subpackage commands/internals */ -class Export_Command { +class Export_Command extends WP_CLI_Command { /** - * Argument validation functions below + * Export posts to a WXR file. + * + * @synopsis --dir=<dir> [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] */ public function export( $args, $assoc_args ) { $defaults = array( diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 0aced7af8b..7f852ba8bd 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -1,46 +1,55 @@ <?php -namespace WP_CLI\Help; -\WP_CLI::add_command( 'help', function( $args ) { - if ( empty( $args ) ) { - general_help(); - return; - } +WP_CLI::add_command( 'help', 'Help_Command', 'help' ); + +/** + * Implement help command + * + * @package wp-cli + * @subpackage commands/internals + */ +class Help_Command extends WP_CLI_Command { + + function help( $args ) { + if ( empty( $args ) ) { + self::general_help(); + return; + } - maybe_load_man_page( $args ); + self::maybe_load_man_page( $args ); - show_available_subcommands( $args[0] ); -} ); + self::show_available_subcommands( $args[0] ); + } -function maybe_load_man_page( $args ) { - $man_dir = WP_CLI_ROOT . "../../../man/"; + private static function maybe_load_man_page( $args ) { + $man_dir = WP_CLI_ROOT . "../../../man/"; - if ( !is_dir( $man_dir ) ) { - \WP_CLI::warning( "man pages do not seem to be installed." ); - } else { - $man_file = $man_dir . implode( '-', $args ) . '.1'; + if ( !is_dir( $man_dir ) ) { + WP_CLI::warning( "man pages do not seem to be installed." ); + } else { + $man_file = $man_dir . implode( '-', $args ) . '.1'; - if ( is_readable( $man_file ) ) { - exit( \WP_CLI::launch( "man $man_file" ) ); + if ( is_readable( $man_file ) ) { + exit( WP_CLI::launch( "man $man_file" ) ); + } } } -} -function show_available_subcommands( $command ) { - $command = \WP_CLI::load_command( $command ); - $command->show_usage(); -} + private static function show_available_subcommands( $command ) { + $command = WP_CLI::load_command( $command ); + $command->show_usage(); + } -function general_help() { - \WP_CLI::line( 'Available commands:' ); - foreach ( \WP_CLI::load_all_commands() as $name => $command ) { - if ( 'help' == $name ) - continue; + private static function general_help() { + WP_CLI::line( 'Available commands:' ); + foreach ( WP_CLI::load_all_commands() as $name => $command ) { + if ( 'help' == $name ) + continue; - \WP_CLI::line( " wp $name " . $command->shortdesc() ); - } + WP_CLI::line( " wp $name " . $command->shortdesc() ); + } - \WP_CLI::line(<<<EOB + WP_CLI::line(<<<EOB See 'wp help <command>' for more information on a specific command. @@ -52,6 +61,7 @@ function general_help() { --quiet suppress informational messages --version print wp-cli version EOB - ); + ); + } } diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index c2efd8623b..ca889c49d5 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -1,21 +1,32 @@ <?php -WP_CLI::add_command( 'home', function() { - // The url for the wp-cli repository - $repository_url = 'https://github.com/wp-cli/wp-cli'; +WP_CLI::add_command( 'home', 'Home_Command', 'home' ); - // Open the wp-cli page in the browser - if ( exec( 'which x-www-browser' ) ) { - system( 'x-www-browser '.$repository_url ); - } - elseif ( exec( 'which open' ) ) { - system( 'open '.$repository_url ); - } - else { - WP_CLI::error( 'No command found to open the homepage in the browser. Please open it manually: '.$repository_url ); - return; - } +/** + * Implement home command + * + * @package wp-cli + * @subpackage commands/internals + */ +class Home_Command extends WP_CLI_Command { - WP_CLI::success( 'The wp-cli homepage should be opening in your browser.' ); -} ); + function home() { + // The url for the wp-cli repository + $repository_url = 'https://github.com/wp-cli/wp-cli'; + + // Open the wp-cli page in the browser + if ( exec( 'which x-www-browser' ) ) { + system( 'x-www-browser '.$repository_url ); + } + elseif ( exec( 'which open' ) ) { + system( 'open '.$repository_url ); + } + else { + WP_CLI::error( 'No command found to open the homepage in the browser. Please open it manually: '.$repository_url ); + return; + } + + WP_CLI::success( 'The wp-cli homepage should be opening in your browser.' ); + } +} diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index bbf2d8ba30..1b8f02d8f2 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -2,41 +2,21 @@ namespace WP_CLI\Dispatcher; -abstract class Command { +interface Command { - function __construct( $implementation, $name ) { - $this->implementation = $implementation; - $this->name = $name; - } - - abstract function autocomplete(); - abstract function shortdesc(); - abstract function show_usage(); - abstract function invoke( $arguments, $assoc_args ); + function autocomplete(); + function shortdesc(); + function show_usage(); + function invoke( $arguments, $assoc_args ); } -class SimpleCommand extends Command { - - function autocomplete() { - return $this->name; - } - - function shortdesc() { - return ''; - } - - function show_usage() { - \WP_CLI::line( "usage: wp $this->name" ); - } +class CompositeCommand implements Command { - function invoke( $arguments, $assoc_args ) { - call_user_func( $this->implementation, $arguments, $assoc_args ); + function __construct( $name, $class ) { + $this->name = $name; + $this->class = $class; } -} - - -class CompositeCommand extends Command { function autocomplete() { $subcommands = array_keys( $this->get_subcommands() ); @@ -50,7 +30,7 @@ function shortdesc() { } function show_usage() { - if ( method_exists( $this->implementation, 'help' ) ) { + if ( method_exists( $this->class, 'help' ) ) { $class::help(); return; } @@ -77,14 +57,14 @@ function invoke( $args, $assoc_args ) { return; } - $class = $this->implementation; + $class = $this->class; $instance = new $class; $subcommand->invoke( $instance, $args, $assoc_args ); } protected function find_subcommand( &$args ) { - $class = $this->implementation; + $class = $this->class; if ( empty( $args ) ) { $name = $class::get_default_subcommand(); @@ -106,8 +86,8 @@ protected function find_subcommand( &$args ) { return $subcommands[ $name ]; } - protected function get_subcommands() { - $reflection = new \ReflectionClass( $this->implementation ); + private function get_subcommands() { + $reflection = new \ReflectionClass( $this->class ); $subcommands = array(); @@ -129,6 +109,36 @@ private static function _is_good_method( $method ) { } +class SimpleCommand extends CompositeCommand { + + function __construct( $name, $class, $method ) { + $this->name = $name; + $this->class = $class; + $this->method = $method; + } + + function autocomplete() { + return $this->name; + } + + function shortdesc() { + return ''; + } + + function show_usage() { + \WP_CLI::line( "usage: wp $this->name" ); + } + + protected function find_subcommand( &$args ) { + $class = $this->class; + + $method = new \ReflectionMethod( $this->class, $this->method ); + + return new Subcommand( $method, $this->name ); + } +} + + class Subcommand { function __construct( $method, $command ) { @@ -249,3 +259,4 @@ private static function get_patterns() { } } + From b297f1f918bae142b43df29fe11ce73af2da5321 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 23:11:35 +0300 Subject: [PATCH 0625/4858] introduce SimpleSubcommand class to avoid double name in show_usage() --- src/php/wp-cli/dispatcher.php | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 1b8f02d8f2..e8e1fa8212 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -134,7 +134,7 @@ protected function find_subcommand( &$args ) { $method = new \ReflectionMethod( $this->class, $this->method ); - return new Subcommand( $method, $this->name ); + return new SimpleSubcommand( $method, $this->name ); } } @@ -146,6 +146,13 @@ function __construct( $method, $command ) { $this->command = $command; } + function show_usage( $prefix = 'usage: ' ) { + $name = $this->get_name(); + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $this->command $name $synopsis" ); + } + function get_name() { $comment = $this->method->getDocComment(); @@ -155,13 +162,6 @@ function get_name() { return $this->method->name; } - function show_usage( $prefix = 'usage: ' ) { - $name = $this->get_name(); - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $this->command $name $synopsis" ); - } - function invoke( $instance, $args, $assoc_args ) { $this->check_args( $args, $assoc_args ); return $this->method->invoke( $instance, $args, $assoc_args ); @@ -197,9 +197,7 @@ protected function check_args( $args, $assoc_args ) { if ( empty( $errors ) ) return; - foreach ( $errors as $error ) - \WP_CLI::warning( $error ); - + $this->show_usage(); exit(1); } @@ -260,3 +258,12 @@ private static function get_patterns() { } +class SimpleSubcommand extends Subcommand { + + function show_usage( $prefix = 'usage: ' ) { + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $this->command $synopsis" ); + } +} + From f041df477cae392b96821a78279392bd2236c8d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 23:37:24 +0300 Subject: [PATCH 0626/4858] remove support for old static help() method --- src/php/wp-cli/dispatcher.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index e8e1fa8212..a58eb13a7f 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -30,11 +30,6 @@ function shortdesc() { } function show_usage() { - if ( method_exists( $this->class, 'help' ) ) { - $class::help(); - return; - } - $methods = $this->get_subcommands(); $i = 0; From 7de8cbc37848b10bde383d2690f61d0be251a20c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 23:42:33 +0300 Subject: [PATCH 0627/4858] replace $method parameter in add_command() with __invoke() magic method --- src/php/wp-cli/class-wp-cli.php | 7 +++---- src/php/wp-cli/commands/internals/export.php | 4 ++-- src/php/wp-cli/commands/internals/help.php | 4 ++-- src/php/wp-cli/commands/internals/home.php | 4 ++-- src/php/wp-cli/dispatcher.php | 15 +++++++++------ 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 553c077793..98faba63f3 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -14,13 +14,12 @@ class WP_CLI { * * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command - * @param string $method The method to call, instead of subcommands */ - public function add_command( $name, $class, $method = false ) { - if ( !$method ) + public function add_command( $name, $class ) { + if ( is_string( $class ) ) $command = new \WP_CLI\Dispatcher\CompositeCommand( $name, $class ); else - $command = new \WP_CLI\Dispatcher\SimpleCommand( $name, $class, $method ); + $command = new \WP_CLI\Dispatcher\SimpleCommand( $name, $class ); self::$commands[ $name ] = $command; } diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 350cbb5dd5..96527aface 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -1,6 +1,6 @@ <?php -WP_CLI::add_command( 'export', 'Export_Command', 'export' ); +WP_CLI::add_command( 'export', new Export_Command ); /** * Implement export command @@ -15,7 +15,7 @@ class Export_Command extends WP_CLI_Command { * * @synopsis --dir=<dir> [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] */ - public function export( $args, $assoc_args ) { + public function __invoke( $args, $assoc_args ) { $defaults = array( 'dir' => NULL, 'start_date' => NULL, diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 7f852ba8bd..2f640280ad 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -1,6 +1,6 @@ <?php -WP_CLI::add_command( 'help', 'Help_Command', 'help' ); +WP_CLI::add_command( 'help', new Help_Command ); /** * Implement help command @@ -10,7 +10,7 @@ */ class Help_Command extends WP_CLI_Command { - function help( $args ) { + function __invoke( $args ) { if ( empty( $args ) ) { self::general_help(); return; diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index ca889c49d5..f20bcf03eb 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -1,6 +1,6 @@ <?php -WP_CLI::add_command( 'home', 'Home_Command', 'home' ); +WP_CLI::add_command( 'home', new Home_Command ); /** * Implement home command @@ -10,7 +10,7 @@ */ class Home_Command extends WP_CLI_Command { - function home() { + function __invoke() { // The url for the wp-cli repository $repository_url = 'https://github.com/wp-cli/wp-cli'; diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index a58eb13a7f..4098cce024 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -106,10 +106,9 @@ private static function _is_good_method( $method ) { class SimpleCommand extends CompositeCommand { - function __construct( $name, $class, $method ) { + function __construct( $name, $callable ) { $this->name = $name; - $this->class = $class; - $this->method = $method; + $this->callable = $callable; } function autocomplete() { @@ -124,10 +123,14 @@ function show_usage() { \WP_CLI::line( "usage: wp $this->name" ); } - protected function find_subcommand( &$args ) { - $class = $this->class; + function invoke( $args, $assoc_args ) { + $subcommand = $this->find_subcommand( $args ); + + $subcommand->invoke( $this->callable, $args, $assoc_args ); + } - $method = new \ReflectionMethod( $this->class, $this->method ); + protected function find_subcommand( &$args ) { + $method = new \ReflectionMethod( $this->callable, '__invoke' ); return new SimpleSubcommand( $method, $this->name ); } From 3e53cec0779c432de6557d7dd8d442c10010ae5f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 23:49:36 +0300 Subject: [PATCH 0628/4858] rename Simple* to Single* --- src/php/wp-cli/class-wp-cli.php | 2 +- src/php/wp-cli/dispatcher.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 98faba63f3..8be897c549 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -19,7 +19,7 @@ public function add_command( $name, $class ) { if ( is_string( $class ) ) $command = new \WP_CLI\Dispatcher\CompositeCommand( $name, $class ); else - $command = new \WP_CLI\Dispatcher\SimpleCommand( $name, $class ); + $command = new \WP_CLI\Dispatcher\SingleCommand( $name, $class ); self::$commands[ $name ] = $command; } diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 4098cce024..5deb4674d3 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -104,7 +104,7 @@ private static function _is_good_method( $method ) { } -class SimpleCommand extends CompositeCommand { +class SingleCommand extends CompositeCommand { function __construct( $name, $callable ) { $this->name = $name; @@ -132,7 +132,7 @@ function invoke( $args, $assoc_args ) { protected function find_subcommand( &$args ) { $method = new \ReflectionMethod( $this->callable, '__invoke' ); - return new SimpleSubcommand( $method, $this->name ); + return new SingleSubcommand( $method, $this->name ); } } @@ -256,7 +256,7 @@ private static function get_patterns() { } -class SimpleSubcommand extends Subcommand { +class SingleSubcommand extends Subcommand { function show_usage( $prefix = 'usage: ' ) { $synopsis = $this->get_synopsis(); From ca66de0c70f3caeb3017826a306de5845d713b5c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Oct 2012 23:57:52 +0300 Subject: [PATCH 0629/4858] move Subcommand classes to separate file --- src/php/wp-cli/dispatcher-subcommand.php | 132 +++++++++++++++++++++++ src/php/wp-cli/dispatcher.php | 129 ---------------------- src/php/wp-cli/wp-cli.php | 1 + 3 files changed, 133 insertions(+), 129 deletions(-) create mode 100644 src/php/wp-cli/dispatcher-subcommand.php diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php new file mode 100644 index 0000000000..d798a8be83 --- /dev/null +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -0,0 +1,132 @@ +<?php + +namespace WP_CLI\Dispatcher; + +class Subcommand { + + function __construct( $method, $command ) { + $this->method = $method; + $this->command = $command; + } + + function show_usage( $prefix = 'usage: ' ) { + $name = $this->get_name(); + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $this->command $name $synopsis" ); + } + + function get_name() { + $comment = $this->method->getDocComment(); + + if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) + return $matches[1]; + + return $this->method->name; + } + + function invoke( $instance, $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + return $this->method->invoke( $instance, $args, $assoc_args ); + } + + protected function check_args( $args, $assoc_args ) { + $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); + + $mandatory_positinal = wp_list_filter( $accepted_params, array( + 'type' => 'positional', + 'optional' => false + ) ); + + if ( count( $args ) < count( $mandatory_positinal ) ) { + $this->show_usage(); + exit(1); + } + + $mandatory_assoc = wp_list_pluck( wp_list_filter( $accepted_params, array( + 'type' => 'assoc', + 'optional' => false + ) ), 'name' ); + + $errors = array(); + + foreach ( $mandatory_assoc as $key ) { + if ( !isset( $assoc_args[ $key ] ) ) + $errors[] = "missing --$key parameter"; + elseif ( true === $assoc_args[ $key ] ) + $errors[] = "--$key parameter needs a value"; + } + + if ( empty( $errors ) ) + return; + + $this->show_usage(); + exit(1); + } + + protected function get_synopsis() { + $comment = $this->method->getDocComment(); + + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) + return false; + + return $matches[1]; + } + + protected function parse_synopsis( $synopsis ) { + $patterns = self::get_patterns(); + + $tokens = preg_split( '/[\s\t]+/', $synopsis ); + + $params = array(); + + foreach ( $tokens as $token ) { + foreach ( $patterns as $regex => $desc ) { + if ( preg_match( $regex, $token, $matches ) ) { + $params[] = array_merge( $matches, $desc ); + break; + } + } + } + + return $params; + } + + private static function get_patterns() { + $p_name = '(?P<name>[a-z-]+)'; + $p_value = '<(?P<value>[a-z-|]+)>'; + + $param_types = array( + 'positional' => $p_value, + 'assoc' => "--$p_name=$p_value", + 'flag' => "--$p_name" + ); + + $patterns = array(); + + foreach ( $param_types as $type => $pattern ) { + $patterns[ "/^$pattern$/" ] = array( + 'type' => $type, + 'optional' => false + ); + + $patterns[ "/^\[$pattern\]$/" ] = array( + 'type' => $type, + 'optional' => true + ); + } + + return $patterns; + } +} + + +class SingleSubcommand extends Subcommand { + + function show_usage( $prefix = 'usage: ' ) { + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $this->command $synopsis" ); + } +} + diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 5deb4674d3..1d30c7b0dd 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -136,132 +136,3 @@ protected function find_subcommand( &$args ) { } } - -class Subcommand { - - function __construct( $method, $command ) { - $this->method = $method; - $this->command = $command; - } - - function show_usage( $prefix = 'usage: ' ) { - $name = $this->get_name(); - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $this->command $name $synopsis" ); - } - - function get_name() { - $comment = $this->method->getDocComment(); - - if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) - return $matches[1]; - - return $this->method->name; - } - - function invoke( $instance, $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - return $this->method->invoke( $instance, $args, $assoc_args ); - } - - protected function check_args( $args, $assoc_args ) { - $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); - - $mandatory_positinal = wp_list_filter( $accepted_params, array( - 'type' => 'positional', - 'optional' => false - ) ); - - if ( count( $args ) < count( $mandatory_positinal ) ) { - $this->show_usage(); - exit(1); - } - - $mandatory_assoc = wp_list_pluck( wp_list_filter( $accepted_params, array( - 'type' => 'assoc', - 'optional' => false - ) ), 'name' ); - - $errors = array(); - - foreach ( $mandatory_assoc as $key ) { - if ( !isset( $assoc_args[ $key ] ) ) - $errors[] = "missing --$key parameter"; - elseif ( true === $assoc_args[ $key ] ) - $errors[] = "--$key parameter needs a value"; - } - - if ( empty( $errors ) ) - return; - - $this->show_usage(); - exit(1); - } - - protected function get_synopsis() { - $comment = $this->method->getDocComment(); - - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) - return false; - - return $matches[1]; - } - - protected function parse_synopsis( $synopsis ) { - $patterns = self::get_patterns(); - - $tokens = preg_split( '/[\s\t]+/', $synopsis ); - - $params = array(); - - foreach ( $tokens as $token ) { - foreach ( $patterns as $regex => $desc ) { - if ( preg_match( $regex, $token, $matches ) ) { - $params[] = array_merge( $matches, $desc ); - break; - } - } - } - - return $params; - } - - private static function get_patterns() { - $p_name = '(?P<name>[a-z-]+)'; - $p_value = '<(?P<value>[a-z-|]+)>'; - - $param_types = array( - 'positional' => $p_value, - 'assoc' => "--$p_name=$p_value", - 'flag' => "--$p_name" - ); - - $patterns = array(); - - foreach ( $param_types as $type => $pattern ) { - $patterns[ "/^$pattern$/" ] = array( - 'type' => $type, - 'optional' => false - ); - - $patterns[ "/^\[$pattern\]$/" ] = array( - 'type' => $type, - 'optional' => true - ); - } - - return $patterns; - } -} - - -class SingleSubcommand extends Subcommand { - - function show_usage( $prefix = 'usage: ' ) { - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $this->command $synopsis" ); - } -} - diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 016fd3a5af..37d95ba926 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -15,6 +15,7 @@ // Include the wp-cli classes include WP_CLI_ROOT . 'dispatcher.php'; +include WP_CLI_ROOT . 'dispatcher-subcommand.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; From 223a75400a31bf7079b2dcc61a8de9904295af55 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 00:10:39 +0300 Subject: [PATCH 0630/4858] make subcommand invoke() signature match command invoke() signature --- src/php/wp-cli/dispatcher-subcommand.php | 67 +++++++++++++++--------- src/php/wp-cli/dispatcher.php | 15 ++---- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index d798a8be83..2e855cba52 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -2,33 +2,15 @@ namespace WP_CLI\Dispatcher; -class Subcommand { +abstract class Subcommand { - function __construct( $method, $command ) { + function __construct( $method, $parent ) { $this->method = $method; - $this->command = $command; + $this->parent = $parent; } - function show_usage( $prefix = 'usage: ' ) { - $name = $this->get_name(); - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $this->command $name $synopsis" ); - } - - function get_name() { - $comment = $this->method->getDocComment(); - - if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) - return $matches[1]; - - return $this->method->name; - } - - function invoke( $instance, $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - return $this->method->invoke( $instance, $args, $assoc_args ); - } + abstract function show_usage(); + abstract function invoke( $args, $assoc_args ); protected function check_args( $args, $assoc_args ) { $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); @@ -121,12 +103,49 @@ private static function get_patterns() { } +class MethodSubcommand extends Subcommand { + + function show_usage( $prefix = 'usage: ' ) { + $command = $this->parent->name; + $subcommand = $this->get_name(); + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $command $subcommand $synopsis" ); + } + + function get_name() { + $comment = $this->method->getDocComment(); + + if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) + return $matches[1]; + + return $this->method->name; + } + + function invoke( $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + + $class = $this->parent->class; + $instance = new $class; + + return $this->method->invoke( $instance, $args, $assoc_args ); + } +} + + class SingleSubcommand extends Subcommand { function show_usage( $prefix = 'usage: ' ) { + $command = $this->parent->name; $synopsis = $this->get_synopsis(); - \WP_CLI::line( $prefix . "wp $this->command $synopsis" ); + \WP_CLI::line( $prefix . "wp $command $synopsis" ); + } + + function invoke( $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + + return $this->method->invoke( $this->parent->callable, $args, $assoc_args ); } } diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 1d30c7b0dd..9673c61d83 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -52,10 +52,7 @@ function invoke( $args, $assoc_args ) { return; } - $class = $this->class; - $instance = new $class; - - $subcommand->invoke( $instance, $args, $assoc_args ); + $subcommand->invoke( $args, $assoc_args ); } protected function find_subcommand( &$args ) { @@ -90,7 +87,7 @@ private function get_subcommands() { if ( !self::_is_good_method( $method ) ) continue; - $subcommand = new Subcommand( $method, $this->name ); + $subcommand = new MethodSubcommand( $method, $this ); $subcommands[ $subcommand->get_name() ] = $subcommand; } @@ -123,16 +120,10 @@ function show_usage() { \WP_CLI::line( "usage: wp $this->name" ); } - function invoke( $args, $assoc_args ) { - $subcommand = $this->find_subcommand( $args ); - - $subcommand->invoke( $this->callable, $args, $assoc_args ); - } - protected function find_subcommand( &$args ) { $method = new \ReflectionMethod( $this->callable, '__invoke' ); - return new SingleSubcommand( $method, $this->name ); + return new SingleSubcommand( $method, $this ); } } From 2724e21b97cfd289bb960d0fc0dbe41b0792b14a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 00:50:44 +0300 Subject: [PATCH 0631/4858] SingleCommand doesn't need to inherit from CompositeCommand --- src/php/wp-cli/dispatcher.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 9673c61d83..81a4e395a7 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -101,7 +101,7 @@ private static function _is_good_method( $method ) { } -class SingleCommand extends CompositeCommand { +class SingleCommand implements Command { function __construct( $name, $callable ) { $this->name = $name; @@ -120,10 +120,12 @@ function show_usage() { \WP_CLI::line( "usage: wp $this->name" ); } - protected function find_subcommand( &$args ) { + function invoke( $args, $assoc_args ) { $method = new \ReflectionMethod( $this->callable, '__invoke' ); - return new SingleSubcommand( $method, $this ); + $subcommand = new SingleSubcommand( $method, $this ); + + $subcommand->invoke( $args, $assoc_args ); } } From 250a10fcb0b6ef10c395b3355e0eb174443a03dd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 00:56:55 +0300 Subject: [PATCH 0632/4858] merge SingleSubcommand into SingleCommand --- src/php/wp-cli/dispatcher-subcommand.php | 28 +++++++----------------- src/php/wp-cli/dispatcher.php | 19 ++++++++++------ src/php/wp-cli/wp-cli.php | 2 +- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index 2e855cba52..dda879f767 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -4,9 +4,8 @@ abstract class Subcommand { - function __construct( $method, $parent ) { + function __construct( $method ) { $this->method = $method; - $this->parent = $parent; } abstract function show_usage(); @@ -105,6 +104,12 @@ private static function get_patterns() { class MethodSubcommand extends Subcommand { + function __construct( $method, $parent ) { + $this->parent = $parent; + + parent::__construct( $method ); + } + function show_usage( $prefix = 'usage: ' ) { $command = $this->parent->name; $subcommand = $this->get_name(); @@ -128,24 +133,7 @@ function invoke( $args, $assoc_args ) { $class = $this->parent->class; $instance = new $class; - return $this->method->invoke( $instance, $args, $assoc_args ); - } -} - - -class SingleSubcommand extends Subcommand { - - function show_usage( $prefix = 'usage: ' ) { - $command = $this->parent->name; - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $command $synopsis" ); - } - - function invoke( $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - - return $this->method->invoke( $this->parent->callable, $args, $assoc_args ); + $this->method->invoke( $instance, $args, $assoc_args ); } } diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 81a4e395a7..b6d5e6398e 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -101,11 +101,15 @@ private static function _is_good_method( $method ) { } -class SingleCommand implements Command { +class SingleCommand extends Subcommand implements Command { function __construct( $name, $callable ) { $this->name = $name; $this->callable = $callable; + + $method = new \ReflectionMethod( $this->callable, '__invoke' ); + + parent::__construct( $method ); } function autocomplete() { @@ -116,16 +120,17 @@ function shortdesc() { return ''; } - function show_usage() { - \WP_CLI::line( "usage: wp $this->name" ); + function show_usage( $prefix = 'usage: ' ) { + $command = $this->name; + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $command $synopsis" ); } function invoke( $args, $assoc_args ) { - $method = new \ReflectionMethod( $this->callable, '__invoke' ); + $this->check_args( $args, $assoc_args ); - $subcommand = new SingleSubcommand( $method, $this ); - - $subcommand->invoke( $args, $assoc_args ); + $this->method->invoke( $this->callable, $args, $assoc_args ); } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 37d95ba926..178c83cca0 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -14,8 +14,8 @@ define( 'WP_CLI', true ); // Include the wp-cli classes -include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'dispatcher-subcommand.php'; +include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; From 8758fea612b985ead2da3ad78c88e07f5cef3f07 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 01:17:17 +0300 Subject: [PATCH 0633/4858] add @synopsis for eval and eval-file --- .../wp-cli/commands/internals/eval-file.php | 27 +++++++++++-------- src/php/wp-cli/commands/internals/eval.php | 19 ++++++++----- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/php/wp-cli/commands/internals/eval-file.php b/src/php/wp-cli/commands/internals/eval-file.php index 044ff7fac2..1887930d24 100644 --- a/src/php/wp-cli/commands/internals/eval-file.php +++ b/src/php/wp-cli/commands/internals/eval-file.php @@ -1,17 +1,22 @@ <?php -WP_CLI::add_command( 'eval-file', function( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp eval-file <path>" ); - exit; - } +WP_CLI::add_command( 'eval-file', new EvalFile_Command ); + +class EvalFile_Command extends WP_CLI_Command { - foreach ( $args as $file ) { - if ( !file_exists( $file ) ) { - WP_CLI::error( "'$file' does not exist." ); - } else { - include( $file ); + /** + * Loads and executes a PHP file after loading WordPress. + * + * @synopsis <path> + */ + public function __invoke( $args, $assoc_args ) { + foreach ( $args as $file ) { + if ( !file_exists( $file ) ) { + WP_CLI::error( "'$file' does not exist." ); + } else { + include( $file ); + } } } -} ); +} diff --git a/src/php/wp-cli/commands/internals/eval.php b/src/php/wp-cli/commands/internals/eval.php index 373cedfe28..fe8ae5f176 100644 --- a/src/php/wp-cli/commands/internals/eval.php +++ b/src/php/wp-cli/commands/internals/eval.php @@ -1,11 +1,16 @@ <?php -WP_CLI::add_command( 'eval', function( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp eval '<php-code>'" ); - exit; - } +WP_CLI::add_command( 'eval', new Eval_Command ); + +class Eval_Command extends WP_CLI_Command { - eval( $args[0] ); -} ); + /** + * Executes arbitrary PHP code after loading WordPress. + * + * @synopsis <php-code> + */ + public function __invoke( $args, $assoc_args ) { + eval( $args[0] ); + } +} From e6b5ac67fcc64695ac5699282ba91adc419f8ec4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 03:30:24 +0300 Subject: [PATCH 0634/4858] add warning when passing unknown assoc args --- src/php/wp-cli/dispatcher-subcommand.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index dda879f767..ad530cc33f 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -38,11 +38,20 @@ protected function check_args( $args, $assoc_args ) { $errors[] = "--$key parameter needs a value"; } - if ( empty( $errors ) ) - return; + if ( !empty( $errors ) ) { + $this->show_usage(); + exit(1); + } - $this->show_usage(); - exit(1); + $known_assoc = wp_list_pluck( wp_list_filter( $accepted_params, array( + 'type' => 'positional', + ), 'NOT' ), 'name' ); + + $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); + + foreach ( $unknown_assoc as $key ) { + \WP_CLI::warning( "unkown --$key parameter" ); + } } protected function get_synopsis() { From 9f5bf59d2c3385ec033a49b146c828dec13340a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 03:42:26 +0300 Subject: [PATCH 0635/4858] add @synopsis for rewrite subcommands --- src/php/wp-cli/commands/internals/rewrite.php | 53 ++++++------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/src/php/wp-cli/commands/internals/rewrite.php b/src/php/wp-cli/commands/internals/rewrite.php index 87ea5da60a..67ca9313d3 100644 --- a/src/php/wp-cli/commands/internals/rewrite.php +++ b/src/php/wp-cli/commands/internals/rewrite.php @@ -1,37 +1,24 @@ <?php -WP_CLI:: add_command('rewrite', 'Rewrite_Command'); - -/** - * Implement rewrite command - * - * @package wp-cli - * @subpackage commands/internal - */ +WP_CLI:: add_command( 'rewrite', 'Rewrite_Command' ); + class Rewrite_Command extends WP_CLI_Command { /** - * Flush rules + * Flush rewrite rules. * - * @param array $args not used - * @param array $assoc_args --soft or --hard (default) + * @synopsis [--soft] */ public function flush( $args, $assoc_args ) { - $hard = ( isset( $assoc_args['soft'] ) ) ? false : true; - flush_rewrite_rules( $hard ); + flush_rewrite_rules( isset( $assoc_args['soft'] ) ); } /** - * Set permalink structure + * Update the permalink structure. * - * @param array $args - * @param array $assoc_args + * @synopsis <permastruct> [--category-base=<base>] [--tag-base=<base>] */ public function structure( $args, $assoc_args ) { - if ( !count( $args ) && !count( $assoc_args ) ) { - WP_CLI::line( "usage: wp rewrite structure <new-permalink-structure>" ); - exit; - } global $wp_rewrite; // copypasta from /wp-admin/options-permalink.php @@ -44,20 +31,16 @@ public function structure( $args, $assoc_args ) { if ( is_multisite() && !is_subdomain_install() && is_main_site() ) $blog_prefix = '/blog'; - // Update base permastruct if argument is provided - if ( isset( $args[0] ) ) { + $permalink_structure = ( $args[0] == 'default' ) ? '' : $args[0]; - $permalink_structure = ( $args[0] == 'default' ) ? '' : $args[0]; - - if ( ! empty( $permalink_structure ) ) { - $permalink_structure = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', $permalink_structure ) ); - if ( $prefix && $blog_prefix ) - $permalink_structure = $prefix . preg_replace( '#^/?index\.php#', '', $permalink_structure ); - else - $permalink_structure = $blog_prefix . $permalink_structure; - } - $wp_rewrite->set_permalink_structure( $permalink_structure ); + if ( ! empty( $permalink_structure ) ) { + $permalink_structure = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', $permalink_structure ) ); + if ( $prefix && $blog_prefix ) + $permalink_structure = $prefix . preg_replace( '#^/?index\.php#', '', $permalink_structure ); + else + $permalink_structure = $blog_prefix . $permalink_structure; } + $wp_rewrite->set_permalink_structure( $permalink_structure ); // Update category or tag bases if ( isset( $assoc_args['category-base'] ) ) { @@ -76,15 +59,13 @@ public function structure( $args, $assoc_args ) { $wp_rewrite->set_tag_base( $tag_base ); } - flush_rewrite_rules( $hard ); } /** - * Dump rewrite rules + * Print current rewrite rules. * - * @param array $args - * @param array $assoc_args + * @synopsis [--json] */ public function dump( $args, $assoc_args ) { From 314e9569932c18878317dbd5be332a63527297d8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 04:02:04 +0300 Subject: [PATCH 0636/4858] add @synopsis for cache subcommands --- src/php/wp-cli/commands/internals/cache.php | 92 ++------------------- 1 file changed, 8 insertions(+), 84 deletions(-) diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index d595ce9867..32cf156a49 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -13,18 +13,9 @@ class Cache_Command extends WP_CLI_Command { /** * Add a value to the object cache. * - * @uses wp_cache_add - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> <value> [<group>] [<expiration>] */ public function add( $args, $assoc_args ) { - if ( count( $assoc_args ) + count( $args ) < 2 ) { - WP_CLI::line( 'usage: wp cache add <key> <value> [group] [expiration]' ); - exit; - } - list( $key, $value ) = $args; $group = ( isset( $args[2] ) ) ? $args[2] : ''; @@ -42,18 +33,9 @@ public function add( $args, $assoc_args ) { /** * Decrement a value in the object cache. * - * @uses wp_cache_decr - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> [<offset>] [<group>] */ public function decr( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache decr <key> [offset] [group]' ); - exit; - } - $key = $args[0]; $offset = ( isset( $args[1] ) ) ? $args[1] : 1; @@ -64,7 +46,6 @@ public function decr( $args, $assoc_args ) { if ( false === $value ) { WP_CLI::error( 'The value was not decremented.' ); - exit; } WP_CLI::print_value( $value, $assoc_args ); @@ -73,18 +54,9 @@ public function decr( $args, $assoc_args ) { /** * Remove a value from the object cache. * - * @uses wp_cache_delete - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> <group> */ public function delete( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache delete <key> [group]' ); - exit; - } - $key = $args[0]; $group = ( isset( $args[1] ) ) ? $args[1] : ''; @@ -101,12 +73,6 @@ public function delete( $args, $assoc_args ) { /** * Flush the object cache. - * - * @uses wp_cache_flush - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void */ public function flush( $args, $assoc_args ) { $value = wp_cache_flush(); @@ -122,18 +88,9 @@ public function flush( $args, $assoc_args ) { /** * Get a value from the object cache. * - * @uses wp_cache_get - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> [<group>] */ public function get( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache get <key> [group]' ); - exit; - } - $key = $args[0]; $group = ( isset( $args[1] ) ) ? $args[1] : ''; @@ -151,18 +108,9 @@ public function get( $args, $assoc_args ) { /** * Increment a value in the object cache. * - * @uses wp_cache_incr - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> [<offset>] [<group>] */ public function incr( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( 'usage: wp cache incr <key> [offset] [group]' ); - exit; - } - $key = $args[0]; $offset = ( isset( $args[1] ) ) ? $args[1] : 1; @@ -182,18 +130,9 @@ public function incr( $args, $assoc_args ) { /** * Replace an existing value in the object cache. * - * @uses wp_cache_replace - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> <value> [<group>] [<expiration>] */ public function replace( $args, $assoc_args ) { - if ( count( $assoc_args ) + count( $args ) < 2 ) { - WP_CLI::line( 'usage: wp cache replace <key> <value> [group] [expiration]' ); - exit; - } - list( $key, $value ) = $args; $group = ( isset( $args[2] ) ) ? $args[2] : ''; @@ -213,18 +152,9 @@ public function replace( $args, $assoc_args ) { /** * Set a value to the object cache. * - * @uses wp_cache_set - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void + * @synopsis <key> <value> [<group>] [<expiration>] */ public function set( $args, $assoc_args ) { - if ( count( $assoc_args ) + count( $args ) < 2 ) { - WP_CLI::line( 'usage: wp cache set <key> <value> [group] [expiration]' ); - exit; - } - list( $key, $value ) = $args; $group = ( isset( $args[2] ) ) ? $args[2] : ''; @@ -247,13 +177,6 @@ public function set( $args, $assoc_args ) { * Note that the guesses made by this function are based on the WP_Object_Cache classes * that define the 3rd party object cache extension. Changes to those classes could render * problems with this function's ability to determine which object cache is being used. - * - * @uses $_wp_using_ext_object_cache - * @uses $wp_object_cache - * - * @param array $args Function arguments. - * @param array $assoc_args Function arguments with parameter key. - * @return void */ public function type( $args, $assoc_args ) { global $_wp_using_ext_object_cache, $wp_object_cache; @@ -295,3 +218,4 @@ public function type( $args, $assoc_args ) { WP_CLI::print_value( $message ); } } + From 6dc7cc36a524e6c6ca84fac47c41ea010473a6f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 04:19:03 +0300 Subject: [PATCH 0637/4858] add @synopsis for core subcommands --- src/php/wp-cli/class-wp-cli.php | 24 --------------------- src/php/wp-cli/commands/internals/core.php | 25 +++++++++++++++------- src/php/wp-cli/wp-cli.php | 2 -- 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8be897c549..eb084f6a39 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -171,30 +171,6 @@ static function compose_args( $args, $assoc_args = array() ) { return $str; } - /** - * Issue warnings for each missing associative argument. - * - * @param array List of required arg names - * @param array Passed args - */ - static function check_required_args( $required, $assoc_args ) { - $missing = false; - - foreach ( $required as $arg ) { - if ( !isset( $assoc_args[ $arg ] ) ) { - WP_CLI::warning( "--$arg parameter is missing" ); - $missing = true; - } elseif ( true === $assoc_args[ $arg ] ) { - // passed as a flag - WP_CLI::warning( "--$arg needs to have a value" ); - $missing = true; - } - } - - if ( $missing ) - exit(1); - } - static function get_numeric_arg( $args, $index, $name ) { if ( ! isset( $args[$index] ) ) { WP_CLI::error( "$name required" ); diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index e433658e57..3264330728 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -12,6 +12,8 @@ class Core_Command extends WP_CLI_Command { /** * Download the core files from wordpress.org + * + * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] */ public function download( $args, $assoc_args ) { if ( is_readable( WP_ROOT . 'wp-load.php' ) ) @@ -43,10 +45,10 @@ public function download( $args, $assoc_args ) { /** * Set up a wp-config.php file. + * + * @synopsis --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=<host>] [--dbprefix=<prefix>] */ public function config( $args, $assoc_args ) { - WP_CLI::check_required_args( array( 'dbname', 'dbuser', 'dbpass' ), $assoc_args ); - $_POST['dbname'] = $assoc_args['dbname']; $_POST['uname'] = $assoc_args['dbuser']; $_POST['pwd'] = $assoc_args['dbpass']; @@ -62,6 +64,8 @@ public function config( $args, $assoc_args ) { /** * Run wp_install. Assumes that wp-config.php is already in place. + * + * @synopsis --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); @@ -89,7 +93,10 @@ public function install( $args, $assoc_args ) { } /** + * Transform a single-site install into a multi-site install. + * * @subcommand install-network + * @synopsis --title=<network-title> [--base_path=/] */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) @@ -103,8 +110,6 @@ public function install_network( $args, $assoc_args ) { foreach ( $wpdb->tables( 'ms_global' ) as $table => $prefixed_table ) $wpdb->$table = $prefixed_table; - WP_CLI::check_required_args( array( 'title' ), $assoc_args ); - extract( wp_parse_args( $assoc_args, array( 'base' => '/', ) ) ); @@ -154,6 +159,8 @@ private static function get_clean_basedomain() { /** * Display the WordPress version. + * + * @synopsis [--extra] */ public function version( $args = array(), $assoc_args = array() ) { global $wp_version, $wp_db_version, $tinymce_version, $manifest_version; @@ -165,6 +172,7 @@ public function version( $args = array(), $assoc_args = array() ) { '-beta' => array( 'beta', '%B' ), '-' => array( 'in development', '%R' ), ); + foreach( $version_types as $needle => $type ) { if ( stristr( $wp_version, $needle ) ) { list( $version_text, $color ) = $type; @@ -172,6 +180,7 @@ public function version( $args = array(), $assoc_args = array() ) { break; } } + if ( isset( $assoc_args['extra'] ) ) { WP_CLI::line( "WordPress version:\t$version_text" ); @@ -188,13 +197,13 @@ public function version( $args = array(), $assoc_args = array() ) { } /** - * Update the WordPress core + * Update WordPress. * - * @param array $args - * @param array $assoc_args + * @synopsis [<zip>] [--version=<version>] [--force] */ function update( $args, $assoc_args ) { global $wp_version; + $update = $from_api = null; $upgrader = 'Core_Upgrader'; @@ -254,7 +263,7 @@ function update( $args, $assoc_args ) { } /** - * Update the WordPress database + * Update the WordPress database. * * @subcommand update-db */ diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 178c83cca0..c161804593 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -82,8 +82,6 @@ // Set installer flag before loading any WP files if ( array( 'core', 'install' ) == $arguments ) { - WP_CLI::check_required_args( array( 'url', 'title', 'admin_email', 'admin_password' ), $assoc_args ); - define( 'WP_INSTALLING', true ); } From ec86462816e288d4b14bf0243a92fb46c6f379e6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 04:40:54 +0300 Subject: [PATCH 0638/4858] don't assume WP functions exist when checking args --- src/php/wp-cli/dispatcher-subcommand.php | 43 +++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index ad530cc33f..81d401509d 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -14,20 +14,34 @@ abstract function invoke( $args, $assoc_args ); protected function check_args( $args, $assoc_args ) { $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); - $mandatory_positinal = wp_list_filter( $accepted_params, array( - 'type' => 'positional', - 'optional' => false - ) ); + $this->check_positional( $args, $accepted_params ); - if ( count( $args ) < count( $mandatory_positinal ) ) { + $this->check_assoc( $assoc_args, $accepted_params ); + + $this->check_unknown_assoc( $assoc_args, $accepted_params ); + } + + private function check_positional( $args, $accepted_params ) { + $count = 0; + + foreach ( $accepted_params as $param ) { + if ( 'positional' == $param['type'] && !$param['optional'] ) + $count++; + } + + if ( count( $args ) < $count ) { $this->show_usage(); exit(1); } + } + + private function check_assoc( $assoc_args, $accepted_params ) { + $mandatory_assoc = array(); - $mandatory_assoc = wp_list_pluck( wp_list_filter( $accepted_params, array( - 'type' => 'assoc', - 'optional' => false - ) ), 'name' ); + foreach ( $accepted_params as $param ) { + if ( 'assoc' == $param['type'] && !$param['optional'] ) + $mandatory_assoc[] = $param['name']; + } $errors = array(); @@ -42,10 +56,15 @@ protected function check_args( $args, $assoc_args ) { $this->show_usage(); exit(1); } + } + + private function check_unknown_assoc( $assoc_args, $accepted_params ) { + $known_assoc = array(); - $known_assoc = wp_list_pluck( wp_list_filter( $accepted_params, array( - 'type' => 'positional', - ), 'NOT' ), 'name' ); + foreach ( $accepted_params as $param ) { + if ( 'positional' != $param['type'] ) + $known_assoc[] = $param['name']; + } $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); From 98e77e116920e3fd195904d7ade8a5902bd70cb7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 04:44:01 +0300 Subject: [PATCH 0639/4858] fix indentation in core.php --- src/php/wp-cli/commands/internals/core.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 3264330728..8ea46d4c23 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -92,12 +92,12 @@ public function install( $args, $assoc_args ) { } } - /** + /** * Transform a single-site install into a multi-site install. * - * @subcommand install-network + * @subcommand install-network * @synopsis --title=<network-title> [--base_path=/] - */ + */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) WP_CLI::error( 'This already is a multisite install.' ); From d74129c66b4cc3c101471fcbe05b6249add07b93 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 04:57:55 +0300 Subject: [PATCH 0640/4858] add @synopsis for db subcommands --- src/php/wp-cli/commands/internals/db.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 2a2eb1be3a..f84c9a40b1 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -34,6 +34,8 @@ function create() { /** * Deletes the database specified in the wp-config.php file. + * + * @synopsis [--yes] */ function drop( $args, $assoc_args ) { if ( !isset( $assoc_args['yes'] ) ) { @@ -55,6 +57,8 @@ function drop( $args, $assoc_args ) { /** * Removes all tables from the database. + * + * @synopsis [--yes] */ function reset( $args, $assoc_args ) { if ( !isset( $assoc_args['yes'] ) ) { @@ -119,13 +123,10 @@ function cli() { /** * Execute a query against the site database. + * + * @synopsis <sql> */ function query( $args, $assoc_args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp db query <SQL>" ); - exit; - } - $query = $args[0]; $command = $this->connect_string() . self::create_cmd( ' --execute=%s', $query ); @@ -135,6 +136,8 @@ function query( $args, $assoc_args ) { /** * Exports the WordPress DB as SQL using mysqldump. + * + * @synopsis [<file>] */ function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); @@ -149,6 +152,8 @@ function export( $args, $assoc_args ) { /** * Imports a database from a file. + * + * @synopsis [<file>] */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); From 1f95a84d1804a86ad4e315f79c26792d0442102f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 05:11:01 +0300 Subject: [PATCH 0641/4858] convert **/ to */ --- src/php/wp-cli/class-wp-cli-command-with-meta.php | 8 ++++---- src/php/wp-cli/commands/internals/db.php | 2 +- src/php/wp-cli/commands/internals/option.php | 2 +- src/php/wp-cli/commands/internals/post.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 2 +- src/php/wp-cli/commands/internals/user.php | 10 +++++----- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-meta.php b/src/php/wp-cli/class-wp-cli-command-with-meta.php index d636fd809f..18521d486e 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-meta.php +++ b/src/php/wp-cli/class-wp-cli-command-with-meta.php @@ -20,7 +20,7 @@ public static function get_aliases() { * * @param array $args * @param array $assoc_args - **/ + */ public function get( $args, $assoc_args ) { $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); @@ -38,7 +38,7 @@ public function get( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function delete( $args, $assoc_args ) { $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); @@ -57,7 +57,7 @@ public function delete( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function add( $args, $assoc_args ) { $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); @@ -77,7 +77,7 @@ public function add( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function update( $args, $assoc_args ) { $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index f84c9a40b1..e5448e92f7 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -7,7 +7,7 @@ * * @package wp-cli * @subpackage commands/internals - **/ + */ class DB_Command extends WP_CLI_Command { public static function get_default_subcommand() { diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 0f3ddc0d31..c7a1fb532c 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -51,7 +51,7 @@ public function add( $args, $assoc_args ) { * Update an option * * @synopsis <key> <value> [--json] - **/ + */ public function update( $args, $assoc_args ) { $key = $args[0]; diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 13d33c47a6..89ad3fccbd 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -112,7 +112,7 @@ public function delete( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function generate( $args, $assoc_args ) { global $wpdb; diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index e86c5ede57..9bbe1050bd 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -51,7 +51,7 @@ protected function get_details( $stylesheet ) { * Activate a theme. * * @synopsis <theme> - **/ + */ public function activate( $args = array() ) { list( $stylesheet, $child ) = $this->parse_name( $args ); diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 50fbbb8e99..a371ce35f8 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -14,7 +14,7 @@ class User_Command extends WP_CLI_Command { * List users * * @subcommand list - **/ + */ public function _list( $args, $assoc_args ) { global $blog_id; @@ -55,7 +55,7 @@ public function _list( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function delete( $args, $assoc_args ) { global $blog_id; @@ -77,7 +77,7 @@ public function delete( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function create( $args, $assoc_args ) { global $blog_id; @@ -131,7 +131,7 @@ public function create( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function update( $args, $assoc_args ) { $user_id = WP_CLI::get_numeric_arg( $args, 0, "User ID" ); @@ -156,7 +156,7 @@ public function update( $args, $assoc_args ) { * * @param array $args * @param array $assoc_args - **/ + */ public function generate( $args, $assoc_args ) { global $blog_id; From f989d598951cf65038887766a3eacfba7b05f5dd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 05:19:42 +0300 Subject: [PATCH 0642/4858] add @synopsis for user subcommands (except update) --- src/php/wp-cli/commands/internals/user.php | 25 +++++++--------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index a371ce35f8..d0a6959610 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -11,9 +11,10 @@ class User_Command extends WP_CLI_Command { /** - * List users + * List users. * * @subcommand list + * @synopsis [--role=<role>] */ public function _list( $args, $assoc_args ) { global $blog_id; @@ -51,10 +52,9 @@ public function _list( $args, $assoc_args ) { } /** - * Delete a user + * Delete a user. * - * @param array $args - * @param array $assoc_args + * @synopsis <id> [--reassign=<id>] */ public function delete( $args, $assoc_args ) { global $blog_id; @@ -73,18 +73,13 @@ public function delete( $args, $assoc_args ) { } /** - * Create a user + * Create a user. * - * @param array $args - * @param array $assoc_args + * @synopsis <user-login> <user-email> [--role=<role>] [--porcelain] */ public function create( $args, $assoc_args ) { global $blog_id; - if ( count( $args ) < 2 ) { - WP_CLI::error( "Login and email required." ); - } - list( $user_login, $user_email ) = $args; $defaults = array( @@ -127,10 +122,7 @@ public function create( $args, $assoc_args ) { } /** - * Update a user - * - * @param array $args - * @param array $assoc_args + * Update a user. */ public function update( $args, $assoc_args ) { $user_id = WP_CLI::get_numeric_arg( $args, 0, "User ID" ); @@ -154,8 +146,7 @@ public function update( $args, $assoc_args ) { /** * Generate users * - * @param array $args - * @param array $assoc_args + * @synopsis [--count=100] [--role=<role>] */ public function generate( $args, $assoc_args ) { global $blog_id; From f65823bdb0761a392b9da062b4680b52716f7a93 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 05:35:04 +0300 Subject: [PATCH 0643/4858] split --all flag into an update-all subcommand. fixes #180 --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 12 +++++------- src/php/wp-cli/commands/internals/plugin.php | 11 ++++++++++- src/php/wp-cli/commands/internals/theme.php | 9 +++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index d11741b237..d76eaf63dd 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -123,16 +123,14 @@ function install( $args, $assoc_args ) { function update( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); - if ( !empty( $args ) && !isset( $assoc_args['all'] ) ) { - list( $file, $name ) = $this->parse_name( $args ); + list( $file, $name ) = $this->parse_name( $args ); - WP_CLI::get_upgrader( $this->upgrader )->upgrade( $file ); - } else { - $this->update_multiple( $args, $assoc_args ); - } + WP_CLI::get_upgrader( $this->upgrader )->upgrade( $file ); } - private function update_multiple( $args, $assoc_args ) { + function update_all( $args, $assoc_args ) { + call_user_func( $this->upgrade_refresh ); + $items_to_update = wp_list_filter( $this->get_item_list(), array( 'update' => true ) ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 7d93c962c6..8a98361ea5 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -184,7 +184,7 @@ protected function install_from_repo( $slug, $assoc_args ) { /** * Update a plugin. * - * @synopsis [<plugin>] [--all] [--version=<version>] + * @synopsis <plugin> [--version=<version>] */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { @@ -195,6 +195,15 @@ function update( $args, $assoc_args ) { } } + /** + * Update all plugins. + * + * @subcommand update-all + */ + function update_all( $args, $assoc_args ) { + parent::update_all( $args, $assoc_args ); + } + protected function get_item_list() { $items = array(); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 9bbe1050bd..0316cf2855 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -169,6 +169,15 @@ function update( $args, $assoc_args ) { parent::update( $args, $assoc_args ); } + /** + * Update all themes. + * + * @subcommand update-all + */ + function update_all( $args, $assoc_args ) { + parent::update_all( $args, $assoc_args ); + } + /** * Delete a theme. * From 9a72ba16e26dd5437259fee251b9a9ab9a2818ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Oct 2012 05:36:42 +0300 Subject: [PATCH 0644/4858] update synopsis for theme update. see #180 --- src/php/wp-cli/commands/internals/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 0316cf2855..24559601d9 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -163,7 +163,7 @@ function install( $args, $assoc_args ) { /** * Update a theme. * - * @synopsis [<theme>] [--all] + * @synopsis <theme> */ function update( $args, $assoc_args ) { parent::update( $args, $assoc_args ); From 8709268bf4282d042de09e188e1cd9b3ad755661 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 16:59:05 +0300 Subject: [PATCH 0645/4858] allow underscores in key names --- src/php/wp-cli/dispatcher-subcommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index 81d401509d..afdb35b3ee 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -102,7 +102,7 @@ protected function parse_synopsis( $synopsis ) { } private static function get_patterns() { - $p_name = '(?P<name>[a-z-]+)'; + $p_name = '(?P<name>[a-z-_]+)'; $p_value = '<(?P<value>[a-z-|]+)>'; $param_types = array( From ecbba6020f44ed66400876291d1d734211eff55b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 16:59:28 +0300 Subject: [PATCH 0646/4858] show missing parameters before showing usage --- src/php/wp-cli/dispatcher-subcommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index afdb35b3ee..2bebf609d8 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -53,6 +53,9 @@ private function check_assoc( $assoc_args, $accepted_params ) { } if ( !empty( $errors ) ) { + foreach ( $errors as $error ) { + \WP_CLI::warning( $error ); + } $this->show_usage(); exit(1); } From 88bd92e967efc49df7ca85d55616048382624e3e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 17:12:56 +0300 Subject: [PATCH 0647/4858] add synopsis for WP_CLI_Command_With_Meta --- .../wp-cli/class-wp-cli-command-with-meta.php | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-meta.php b/src/php/wp-cli/class-wp-cli-command-with-meta.php index 18521d486e..968abf7216 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-meta.php +++ b/src/php/wp-cli/class-wp-cli-command-with-meta.php @@ -16,14 +16,12 @@ public static function get_aliases() { protected $meta_type; /** - * Get meta field value + * Get meta field value. * - * @param array $args - * @param array $assoc_args + * @synopsis <id> <key> [--json] */ public function get( $args, $assoc_args ) { - $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); - $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); + list( $object_id, $meta_key ) = $args; $value = get_metadata( $this->meta_type, $object_id, $meta_key, true ); @@ -34,14 +32,12 @@ public function get( $args, $assoc_args ) { } /** - * Get meta field value for a user + * Delete a meta field. * - * @param array $args - * @param array $assoc_args + * @synopsis <id> <key> */ public function delete( $args, $assoc_args ) { - $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); - $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); + list( $object_id, $meta_key ) = $args; $success = delete_metadata( $this->meta_type, $object_id, $meta_key ); @@ -53,15 +49,12 @@ public function delete( $args, $assoc_args ) { } /** - * Update meta field for a user + * Add a meta field. * - * @param array $args - * @param array $assoc_args + * @synopsis <id> <key> <value> */ public function add( $args, $assoc_args ) { - $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); - $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); - $meta_value = self::get_arg_or_error( $args, 2, "meta_value" ); + list( $object_id, $meta_key, $meta_value ) = $args; $success = add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); @@ -73,15 +66,12 @@ public function add( $args, $assoc_args ) { } /** - * Update meta field for a user + * Update a meta field. * - * @param array $args - * @param array $assoc_args + * @synopsis <id> <key> <value> */ public function update( $args, $assoc_args ) { - $object_id = WP_CLI::get_numeric_arg( $args, 0, "$this->meta_type ID" ); - $meta_key = self::get_arg_or_error( $args, 1, "meta_key" ); - $meta_value = self::get_arg_or_error( $args, 2, "meta_value" ); + list( $object_id, $meta_key, $meta_value ) = $args; $success = update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); @@ -91,13 +81,5 @@ public function update( $args, $assoc_args ) { WP_CLI::error( "Failed to update custom field." ); } } - - protected function get_arg_or_error( $args, $index, $name ) { - if ( ! isset( $args[$index] ) ) { - WP_CLI::error( "$name required" ); - } - - return $args[$index]; - } } From 70821fcc532f8e6deb4d39f5ed14af5aa150149f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 17:48:12 +0300 Subject: [PATCH 0648/4858] add @synopsis for transient subcommands --- .../wp-cli/commands/internals/transient.php | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/internals/transient.php index 9d82368942..6c8a998249 100644 --- a/src/php/wp-cli/commands/internals/transient.php +++ b/src/php/wp-cli/commands/internals/transient.php @@ -11,16 +11,11 @@ class Transient_Command extends WP_CLI_Command { /** - * Gets a value using the "get_transient" function. + * Get a transient value. * - * @param array $args + * @synopsis <key> */ public function get( $args ) { - if ( empty( $args ) ) { - WP_CLI::error( 'Usage: wp transient get <key>' ); - exit; - } - list( $key ) = $args; $value = get_transient( $key ); @@ -37,19 +32,14 @@ public function get( $args ) { } /** - * Sets a value using the "set_transient" function. + * Set a transient value. <expiration> is the time until expiration, in seconds. * - * @param array $args + * @synopsis <key> <value> [<expiration>] */ public function set( $args ) { - if ( count( $args ) < 2 ) { - WP_CLI::error( 'usage: wp transient set <key> <value> [expiration]' ); - exit; - } + list( $key, $value ) = $args; - list( $key, $value, $expiration ) = $args; - - $expiration = isset( $expiration ) ? $expiration : 0; + $expiration = isset( $args[2] ) ? $args[2] : 0; if ( set_transient( $key, $value, $expiration ) ) WP_CLI::success( 'Transient added.' ); @@ -58,16 +48,11 @@ public function set( $args ) { } /** - * Deletes a value using the "delete_transient" function. + * Delete a transient value. * - * @param array $args + * @synopsis <key> */ public function delete( $args ) { - if ( empty( $args ) ) { - WP_CLI::warning( 'Usage: wp transient delete <key>' ); - exit; - } - list( $key ) = $args; if ( delete_transient( $key ) ) { @@ -81,7 +66,7 @@ public function delete( $args ) { } /** - * Indicates whether the transients API is using the object cache or options table in the current environment. + * See wether the transients API is using an object cache or the options table. */ public function type() { global $_wp_using_ext_object_cache, $wpdb; From 8f7414fef3733be33c72186a48bb043bce6f37e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 17:49:27 +0300 Subject: [PATCH 0649/4858] add --json flag for wp transient get --- src/php/wp-cli/commands/internals/transient.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/internals/transient.php index 6c8a998249..4b6d246626 100644 --- a/src/php/wp-cli/commands/internals/transient.php +++ b/src/php/wp-cli/commands/internals/transient.php @@ -13,9 +13,9 @@ class Transient_Command extends WP_CLI_Command { /** * Get a transient value. * - * @synopsis <key> + * @synopsis <key> [--json] */ - public function get( $args ) { + public function get( $args, $assoc_args ) { list( $key ) = $args; $value = get_transient( $key ); @@ -25,10 +25,7 @@ public function get( $args ) { exit; } - if ( is_array( $value ) || is_object( $value ) ) - echo var_export( $value ) . "\n"; - else - echo $value . "\n"; + WP_CLI::print_value( $value, $assoc_args ); } /** From b55729eaeb6b46cf4d0b4357742f6eca7dc570e1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 17:54:56 +0300 Subject: [PATCH 0650/4858] add synopsis for wp post generate --- src/php/wp-cli/commands/internals/post.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 89ad3fccbd..0813e3dfbd 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -108,10 +108,9 @@ public function delete( $args, $assoc_args ) { } /** - * Generate posts + * Generate some posts. * - * @param array $args - * @param array $assoc_args + * @synopsis [--count=100] [--post_type=post] [--post_status=publish] [--post_author=<login>] [--post_date=<date>] [--max_depth=1] */ public function generate( $args, $assoc_args ) { global $wpdb; From 35e77ff4710e32111a169a0116384037cf2a9944 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 18:03:30 +0300 Subject: [PATCH 0651/4858] add synopsis for wp post delete --- src/php/wp-cli/commands/internals/post.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 0813e3dfbd..2708f718d9 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -52,13 +52,11 @@ public function update( $args, $assoc_args ) { } /** - * Delete a single post, or series of posts based on arguments + * Delete a single post, or series of posts based on arguments. * - * @param array $args - * @param array $assoc_args + * @synopsis [<ID>] [--post_type=<value>] [--post_author=<value>] [--post_status=<value>] [--force] */ public function delete( $args, $assoc_args ) { - $defaults = array( 'p' => null, 'post_type' => null, From fc588a3a4f15a3a41d93b5e379a9eb4f6ebda914 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 18:15:22 +0300 Subject: [PATCH 0652/4858] introduce wp post delete-many --- src/php/wp-cli/commands/internals/post.php | 58 ++++++++++------------ 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 2708f718d9..4403efe5d2 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -52,51 +52,45 @@ public function update( $args, $assoc_args ) { } /** - * Delete a single post, or series of posts based on arguments. + * Delete a post by ID. * - * @synopsis [<ID>] [--post_type=<value>] [--post_author=<value>] [--post_status=<value>] [--force] + * @synopsis <id> */ public function delete( $args, $assoc_args ) { - $defaults = array( - 'p' => null, - 'post_type' => null, - 'post_author' => null, - 'post_status' => 'any', - 'force' => false, - ); - $assoc_args = wp_parse_args( $assoc_args, $defaults ); + $post_id = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); - // Support for simply passing the post ID as the first argument - if ( isset( $args[0] ) && is_numeric( $args[0] ) ) - $post_id = $args[0]; - else if ( is_numeric( $assoc_args['p'] ) ) - $post_id = $assoc_args['p']; - else - $post_id = false; + $this->_delete_posts( array( $post_id ), isset( $assoc_args['force'] ) ); + } - if ( $post_id ) { - $posts_to_delete = array( $post_id ); - } else { - $query_args = array( - 'fields' => 'ids', - 'posts_per_page' => -1, - 'post_type' => $assoc_args['post_type'], - 'post_author' => $assoc_args['post_author'], - 'post_status' => $assoc_args['post_status'], - ); - $maybe_posts = new WP_Query( $query_args ); - $posts_to_delete = $maybe_posts->posts; - } + /** + * Delete a series of posts based on arguments. + * + * @subcommand delete-many + * @synopsis [--post_type=<value>] [--post_author=<value>] [--post_status=<value>] [--force] + */ + public function delete_many( $_, $assoc_args ) { + $query_args = array( + 'fields' => 'ids', + 'posts_per_page' => -1, + 'post_type' => $assoc_args['post_type'], + 'post_author' => $assoc_args['post_author'], + 'post_status' => $assoc_args['post_status'], + ); + + $query = new WP_Query( $query_args ); + $posts_to_delete = $query->posts; if ( empty( $posts_to_delete ) ) { WP_CLI::error( "No posts to delete." ); } - $force = (bool) $assoc_args['force']; + $this->_delete_posts( $posts_to_delete, isset( $assoc_args['force'] ) ); + } + protected function _delete_posts( $post_ids, $force ) { $action = $force ? 'Deleted' : 'Trashed'; - foreach ( $posts_to_delete as $post_id ) { + foreach ( $post_ids as $post_id ) { if ( wp_delete_post( $post_id, $force ) ) { WP_CLI::success( "{$action} post $post_id." ); } else { From d20d837428d35e9f8869b8d943a3bc737dcced74 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Oct 2012 18:26:27 +0300 Subject: [PATCH 0653/4858] allow wp post delete to accept more than one ID --- src/php/wp-cli/commands/internals/post.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 4403efe5d2..027f0a184f 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -54,12 +54,10 @@ public function update( $args, $assoc_args ) { /** * Delete a post by ID. * - * @synopsis <id> + * @synopsis <id>... [--force] */ public function delete( $args, $assoc_args ) { - $post_id = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); - - $this->_delete_posts( array( $post_id ), isset( $assoc_args['force'] ) ); + $this->_delete_posts( $args, isset( $assoc_args['force'] ) ); } /** From bdda3cb96c88523ed22b9e892d5aafd4469449b9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 00:54:36 +0300 Subject: [PATCH 0654/4858] index synopsis parameters by type --- src/php/wp-cli/class-defaultdict.php | 44 ++++++++++++++++++++++++ src/php/wp-cli/dispatcher-subcommand.php | 18 +++++----- src/php/wp-cli/wp-cli.php | 1 + 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 src/php/wp-cli/class-defaultdict.php diff --git a/src/php/wp-cli/class-defaultdict.php b/src/php/wp-cli/class-defaultdict.php new file mode 100644 index 0000000000..6dcbece2ae --- /dev/null +++ b/src/php/wp-cli/class-defaultdict.php @@ -0,0 +1,44 @@ +<?php + +namespace WP_CLI\Utils; + +class Defaultdict implements \ArrayAccess { + + private $container = array(); + private $default; + + public function __construct( $default ) { + $this->default = $default; + } + + public function offsetSet( $offset, $value ) { + if ( is_null($offset) ) { + trigger_error( sprintf( "Trying to use %s as a list.", __CLASS__ ), E_USER_WARNING ); + return; + } + + $this->container[$offset] = $value; + } + + public function offsetExists( $offset ) { + return true; + } + + public function offsetUnset( $offset ) { + unset( $this->container[$offset] ); + } + + public function &offsetGet( $offset ) { + if ( !isset( $this->container[$offset] ) ) { + if ( is_callable($this->default) ) + $value = call_user_func( $this->default, $offset ); + else + $value = $this->default; + + $this->container[$offset] = $value; + } + + return $this->container[$offset]; + } +} + diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index 2bebf609d8..1025a28b64 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -24,8 +24,8 @@ protected function check_args( $args, $assoc_args ) { private function check_positional( $args, $accepted_params ) { $count = 0; - foreach ( $accepted_params as $param ) { - if ( 'positional' == $param['type'] && !$param['optional'] ) + foreach ( $accepted_params['positional'] as $param ) { + if ( !$param['optional'] ) $count++; } @@ -38,8 +38,8 @@ private function check_positional( $args, $accepted_params ) { private function check_assoc( $assoc_args, $accepted_params ) { $mandatory_assoc = array(); - foreach ( $accepted_params as $param ) { - if ( 'assoc' == $param['type'] && !$param['optional'] ) + foreach ( $accepted_params['assoc'] as $param ) { + if ( !$param['optional'] ) $mandatory_assoc[] = $param['name']; } @@ -64,9 +64,10 @@ private function check_assoc( $assoc_args, $accepted_params ) { private function check_unknown_assoc( $assoc_args, $accepted_params ) { $known_assoc = array(); - foreach ( $accepted_params as $param ) { - if ( 'positional' != $param['type'] ) + foreach ( array( 'assoc', 'flag' ) as $type ) { + foreach ( $accepted_params[$type] as $param ) { $known_assoc[] = $param['name']; + } } $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); @@ -90,12 +91,13 @@ protected function parse_synopsis( $synopsis ) { $tokens = preg_split( '/[\s\t]+/', $synopsis ); - $params = array(); + $params = new \WP_CLI\Utils\Defaultdict( array() ); foreach ( $tokens as $token ) { foreach ( $patterns as $regex => $desc ) { if ( preg_match( $regex, $token, $matches ) ) { - $params[] = array_merge( $matches, $desc ); + $type = $desc['type']; + $params[$type][] = array_merge( $matches, $desc ); break; } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c161804593..42c006192b 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -14,6 +14,7 @@ define( 'WP_CLI', true ); // Include the wp-cli classes +include WP_CLI_ROOT . 'class-defaultdict.php'; include WP_CLI_ROOT . 'dispatcher-subcommand.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; From 49f196e1ae8d85c07ce65d600598953edf8447ae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 01:45:19 +0300 Subject: [PATCH 0655/4858] first pass at wp post list --- src/php/wp-cli/commands/internals/post.php | 64 ++++++++++++++-------- src/php/wp-cli/commands/internals/user.php | 3 +- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 027f0a184f..19068f196b 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -56,44 +56,60 @@ public function update( $args, $assoc_args ) { * * @synopsis <id>... [--force] */ - public function delete( $args, $assoc_args ) { - $this->_delete_posts( $args, isset( $assoc_args['force'] ) ); + public function delete( $post_ids, $assoc_args ) { + $action = isset( $assoc_args['force'] ) ? 'Deleted' : 'Trashed'; + + foreach ( $post_ids as $post_id ) { + if ( wp_delete_post( $post_id, $force ) ) { + WP_CLI::success( "{$action} post $post_id." ); + } else { + WP_CLI::error( "Failed deleting post $post_id." ); + } + } } /** - * Delete a series of posts based on arguments. + * Get a list of posts. * - * @subcommand delete-many - * @synopsis [--post_type=<value>] [--post_author=<value>] [--post_status=<value>] [--force] + * @subcommand list */ - public function delete_many( $_, $assoc_args ) { + public function _list( $_, $assoc_args ) { $query_args = array( - 'fields' => 'ids', - 'posts_per_page' => -1, - 'post_type' => $assoc_args['post_type'], - 'post_author' => $assoc_args['post_author'], - 'post_status' => $assoc_args['post_status'], + 'posts_per_page' => -1 ); - $query = new WP_Query( $query_args ); - $posts_to_delete = $query->posts; + foreach ( $assoc_args as $key => $value ) { + if ( true === $value ) + continue; - if ( empty( $posts_to_delete ) ) { - WP_CLI::error( "No posts to delete." ); + $query_args[ $key ] = $value; } - $this->_delete_posts( $posts_to_delete, isset( $assoc_args['force'] ) ); - } + if ( isset( $assoc_args['ids'] ) ) + $query_args['fields'] = 'ids'; - protected function _delete_posts( $post_ids, $force ) { - $action = $force ? 'Deleted' : 'Trashed'; + $query = new WP_Query( $query_args ); - foreach ( $post_ids as $post_id ) { - if ( wp_delete_post( $post_id, $force ) ) { - WP_CLI::success( "{$action} post $post_id." ); - } else { - WP_CLI::error( "Failed deleting post $post_id." ); + if ( isset( $assoc_args['ids'] ) ) { + WP_CLI::out( implode( ' ', $query->posts ) ); + } else { + $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); + + $table = new \cli\Table(); + + $table->setHeaders( $fields ); + + foreach ( $query->posts as $post ) { + $line = array(); + + foreach ( $fields as $field ) { + $line[] = $post->$field; + } + + $table->addRow( $line ); } + + $table->display(); } } diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index d0a6959610..7fe8ca529d 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -28,11 +28,12 @@ public function _list( $args, $assoc_args ) { $params['role'] = $assoc_args['role']; } - $table = new \cli\Table(); $users = get_users( $params ); $fields = array('ID', 'user_login', 'display_name', 'user_email', 'user_registered'); + $table = new \cli\Table(); + $table->setHeaders( array_merge($fields, array('roles')) ); foreach ( $users as $user ) { From 52c0d43fde6a0ebb0435ebf4b08e62b5f4824456 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 01:48:31 +0300 Subject: [PATCH 0656/4858] update docs for wp post delete --- man/post-delete.1 | 26 ++++---------------------- src/docs/post-delete.txt | 18 +++--------------- 2 files changed, 7 insertions(+), 37 deletions(-) diff --git a/man/post-delete.1 b/man/post-delete.1 index 9ca88b26d8..616087a1e0 100644 --- a/man/post-delete.1 +++ b/man/post-delete.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-DELETE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-POST\-DELETE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-post\-delete\fR \- Delete a WordPress post\. +\fBwp\-post\-delete\fR \- Delete one or several posts by ID\. . .SH "SYNOPSIS" -\fBwp post delete\fR [\fIID\fR] [\-\-post_type=\fIvalue\fR] [\-\-post_author=\fIvalue\fR] [\-\-post_status=\fIvalue\fR] [\-\-force] +\fBwp post delete\fR \fIID\fR\.\.\. [\-\-force] . .SH "OPTIONS" . @@ -18,24 +18,6 @@ The ID of the post to delete\. . .TP -\fB\-\-post_type\fR: -. -.IP -Trash or delete all posts of a given post type -. -.TP -\fB\-\-post_author\fR: -. -.IP -Trash or delete all posts written by a specific user -. -.TP -\fB\-\-post_status\fR: -. -.IP -Trash or delete all posts of a given post status -. -.TP \fB\-\-force\fR: . .IP @@ -47,7 +29,7 @@ Skip the trash bin\. wp post delete 123 \-\-force -wp post delete \-\-post_type=page \-\-post_status=draft +wp post delete $(wp post list \-\-post_type=\'page\' \-\-ids) . .fi diff --git a/src/docs/post-delete.txt b/src/docs/post-delete.txt index f2a017101a..21ce192f6a 100644 --- a/src/docs/post-delete.txt +++ b/src/docs/post-delete.txt @@ -1,9 +1,9 @@ -wp-post-delete(1) -- Delete a WordPress post. +wp-post-delete(1) -- Delete one or several posts by ID. ==== ## SYNOPSIS -`wp post delete` [<ID>] [--post_type=<value>] [--post_author=<value>] [--post_status=<value>] [--force] +`wp post delete` <ID>... [--force] ## OPTIONS @@ -11,18 +11,6 @@ wp-post-delete(1) -- Delete a WordPress post. The ID of the post to delete. -* `--post_type`: - - Trash or delete all posts of a given post type - -* `--post_author`: - - Trash or delete all posts written by a specific user - -* `--post_status`: - - Trash or delete all posts of a given post status - * `--force`: Skip the trash bin. @@ -31,4 +19,4 @@ wp-post-delete(1) -- Delete a WordPress post. wp post delete 123 --force - wp post delete --post_type=page --post_status=draft + wp post delete $(wp post list --post_type='page' --ids) From bf8f34df9ba90102251f4d5177d2da83b92b7fba Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 01:56:39 +0300 Subject: [PATCH 0657/4858] don't check args if synopsis isn't set --- src/php/wp-cli/dispatcher-subcommand.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index 1025a28b64..9b716b7fbd 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -12,7 +12,11 @@ abstract function show_usage(); abstract function invoke( $args, $assoc_args ); protected function check_args( $args, $assoc_args ) { - $accepted_params = $this->parse_synopsis( $this->get_synopsis() ); + $synopsis = $this->get_synopsis(); + if ( !$synopsis ) + return; + + $accepted_params = $this->parse_synopsis( $synopsis ); $this->check_positional( $args, $accepted_params ); From 472f680e74077cb229725b4a6da11410814c4379 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 02:05:30 +0300 Subject: [PATCH 0658/4858] add docs for wp post list --- man/post-list.1 | 29 +++++++++++++++++++++++++++++ src/docs/post-list.txt | 18 ++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 man/post-list.1 create mode 100644 src/docs/post-list.txt diff --git a/man/post-list.1 b/man/post-list.1 new file mode 100644 index 0000000000..cb8d82da81 --- /dev/null +++ b/man/post-list.1 @@ -0,0 +1,29 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-LIST" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-list\fR \- Get a list of posts\. +. +.SH "SYNOPSIS" +\fBwp post list\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] [\-\-ids] +. +.SH "OPTIONS" +. +.TP +\fB\-\-<field>\fR=\fIvalue\fR: +. +.IP +One or more args to pass to WP_Query\. +. +.SH "EXAMPLES" +. +.nf + +wp post list + +wp post list \-\-post_type=page \-\-post_status=draft \-\-ids +. +.fi + diff --git a/src/docs/post-list.txt b/src/docs/post-list.txt new file mode 100644 index 0000000000..e2d9bd2951 --- /dev/null +++ b/src/docs/post-list.txt @@ -0,0 +1,18 @@ +wp-post-list(1) -- Get a list of posts. +==== + +## SYNOPSIS + +`wp post list` --<field>=<value> [--<field>=<value>...] [--ids] + +## OPTIONS + +* `--<field>`=<value>: + + One or more args to pass to WP_Query. + +## EXAMPLES + + wp post list + + wp post list --post_type=page --post_status=draft --ids From c8ebd125c25f45b707b79b5b67cc437987e512b0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 04:12:29 +0300 Subject: [PATCH 0659/4858] document the --ids flag. see #182 --- man/post-list.1 | 6 ++++++ src/docs/post-list.txt | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/man/post-list.1 b/man/post-list.1 index cb8d82da81..b66c8137ab 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -17,6 +17,12 @@ .IP One or more args to pass to WP_Query\. . +.TP +\fB\-\-ids\fR: +. +.IP +Return only the IDs of the found posts, separated by spaces\. +. .SH "EXAMPLES" . .nf diff --git a/src/docs/post-list.txt b/src/docs/post-list.txt index e2d9bd2951..de04f98eae 100644 --- a/src/docs/post-list.txt +++ b/src/docs/post-list.txt @@ -11,6 +11,10 @@ wp-post-list(1) -- Get a list of posts. One or more args to pass to WP_Query. +* `--ids`: + + Return only the IDs of the found posts, separated by spaces. + ## EXAMPLES wp post list From f0650e5b01b99f582542d3ebde4cc3dd8fc2ae1d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 16:45:17 +0300 Subject: [PATCH 0660/4858] manually initialize empty arrays instead of using Defaultdict. see #184 --- src/php/wp-cli/class-defaultdict.php | 44 ------------------------ src/php/wp-cli/dispatcher-subcommand.php | 10 +++--- src/php/wp-cli/wp-cli.php | 1 - 3 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 src/php/wp-cli/class-defaultdict.php diff --git a/src/php/wp-cli/class-defaultdict.php b/src/php/wp-cli/class-defaultdict.php deleted file mode 100644 index 6dcbece2ae..0000000000 --- a/src/php/wp-cli/class-defaultdict.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace WP_CLI\Utils; - -class Defaultdict implements \ArrayAccess { - - private $container = array(); - private $default; - - public function __construct( $default ) { - $this->default = $default; - } - - public function offsetSet( $offset, $value ) { - if ( is_null($offset) ) { - trigger_error( sprintf( "Trying to use %s as a list.", __CLASS__ ), E_USER_WARNING ); - return; - } - - $this->container[$offset] = $value; - } - - public function offsetExists( $offset ) { - return true; - } - - public function offsetUnset( $offset ) { - unset( $this->container[$offset] ); - } - - public function &offsetGet( $offset ) { - if ( !isset( $this->container[$offset] ) ) { - if ( is_callable($this->default) ) - $value = call_user_func( $this->default, $offset ); - else - $value = $this->default; - - $this->container[$offset] = $value; - } - - return $this->container[$offset]; - } -} - diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index 9b716b7fbd..a60ca8dc72 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -91,12 +91,10 @@ protected function get_synopsis() { } protected function parse_synopsis( $synopsis ) { - $patterns = self::get_patterns(); + list( $patterns, $params ) = self::get_patterns(); $tokens = preg_split( '/[\s\t]+/', $synopsis ); - $params = new \WP_CLI\Utils\Defaultdict( array() ); - foreach ( $tokens as $token ) { foreach ( $patterns as $regex => $desc ) { if ( preg_match( $regex, $token, $matches ) ) { @@ -134,7 +132,11 @@ private static function get_patterns() { ); } - return $patterns; + $params = array(); + foreach ( array_keys( $param_types ) as $type ) + $params[$type] = array(); + + return array( $patterns, $params ); } } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 42c006192b..c161804593 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -14,7 +14,6 @@ define( 'WP_CLI', true ); // Include the wp-cli classes -include WP_CLI_ROOT . 'class-defaultdict.php'; include WP_CLI_ROOT . 'dispatcher-subcommand.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; From de3929e4222432a08044eda57ce651f04bfb39b8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 16:50:49 +0300 Subject: [PATCH 0661/4858] move concrete methods into a separate AbstractSubcommand class see #184 --- src/php/wp-cli/dispatcher-subcommand.php | 14 +++++++++----- src/php/wp-cli/dispatcher.php | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php index a60ca8dc72..a6e52c8a05 100644 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ b/src/php/wp-cli/dispatcher-subcommand.php @@ -2,15 +2,19 @@ namespace WP_CLI\Dispatcher; -abstract class Subcommand { +interface Subcommand { + + function show_usage(); + function invoke( $arguments, $assoc_args ); +} + + +abstract class AbstractSubcommand implements Subcommand { function __construct( $method ) { $this->method = $method; } - abstract function show_usage(); - abstract function invoke( $args, $assoc_args ); - protected function check_args( $args, $assoc_args ) { $synopsis = $this->get_synopsis(); if ( !$synopsis ) @@ -141,7 +145,7 @@ private static function get_patterns() { } -class MethodSubcommand extends Subcommand { +class MethodSubcommand extends AbstractSubcommand { function __construct( $method, $parent ) { $this->parent = $parent; diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index b6d5e6398e..2bbc3cffa4 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -101,7 +101,7 @@ private static function _is_good_method( $method ) { } -class SingleCommand extends Subcommand implements Command { +class SingleCommand extends AbstractSubcommand implements Command { function __construct( $name, $callable ) { $this->name = $name; From 95459766384e1339333f3938b77e0660024abb6c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 16:59:58 +0300 Subject: [PATCH 0662/4858] use Command interface for all dispatcher classes --- src/php/wp-cli/dispatcher-subcommand.php | 182 ----------------------- src/php/wp-cli/dispatcher.php | 182 ++++++++++++++++++++++- src/php/wp-cli/wp-cli.php | 1 - 3 files changed, 181 insertions(+), 184 deletions(-) delete mode 100644 src/php/wp-cli/dispatcher-subcommand.php diff --git a/src/php/wp-cli/dispatcher-subcommand.php b/src/php/wp-cli/dispatcher-subcommand.php deleted file mode 100644 index a6e52c8a05..0000000000 --- a/src/php/wp-cli/dispatcher-subcommand.php +++ /dev/null @@ -1,182 +0,0 @@ -<?php - -namespace WP_CLI\Dispatcher; - -interface Subcommand { - - function show_usage(); - function invoke( $arguments, $assoc_args ); -} - - -abstract class AbstractSubcommand implements Subcommand { - - function __construct( $method ) { - $this->method = $method; - } - - protected function check_args( $args, $assoc_args ) { - $synopsis = $this->get_synopsis(); - if ( !$synopsis ) - return; - - $accepted_params = $this->parse_synopsis( $synopsis ); - - $this->check_positional( $args, $accepted_params ); - - $this->check_assoc( $assoc_args, $accepted_params ); - - $this->check_unknown_assoc( $assoc_args, $accepted_params ); - } - - private function check_positional( $args, $accepted_params ) { - $count = 0; - - foreach ( $accepted_params['positional'] as $param ) { - if ( !$param['optional'] ) - $count++; - } - - if ( count( $args ) < $count ) { - $this->show_usage(); - exit(1); - } - } - - private function check_assoc( $assoc_args, $accepted_params ) { - $mandatory_assoc = array(); - - foreach ( $accepted_params['assoc'] as $param ) { - if ( !$param['optional'] ) - $mandatory_assoc[] = $param['name']; - } - - $errors = array(); - - foreach ( $mandatory_assoc as $key ) { - if ( !isset( $assoc_args[ $key ] ) ) - $errors[] = "missing --$key parameter"; - elseif ( true === $assoc_args[ $key ] ) - $errors[] = "--$key parameter needs a value"; - } - - if ( !empty( $errors ) ) { - foreach ( $errors as $error ) { - \WP_CLI::warning( $error ); - } - $this->show_usage(); - exit(1); - } - } - - private function check_unknown_assoc( $assoc_args, $accepted_params ) { - $known_assoc = array(); - - foreach ( array( 'assoc', 'flag' ) as $type ) { - foreach ( $accepted_params[$type] as $param ) { - $known_assoc[] = $param['name']; - } - } - - $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); - - foreach ( $unknown_assoc as $key ) { - \WP_CLI::warning( "unkown --$key parameter" ); - } - } - - protected function get_synopsis() { - $comment = $this->method->getDocComment(); - - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) - return false; - - return $matches[1]; - } - - protected function parse_synopsis( $synopsis ) { - list( $patterns, $params ) = self::get_patterns(); - - $tokens = preg_split( '/[\s\t]+/', $synopsis ); - - foreach ( $tokens as $token ) { - foreach ( $patterns as $regex => $desc ) { - if ( preg_match( $regex, $token, $matches ) ) { - $type = $desc['type']; - $params[$type][] = array_merge( $matches, $desc ); - break; - } - } - } - - return $params; - } - - private static function get_patterns() { - $p_name = '(?P<name>[a-z-_]+)'; - $p_value = '<(?P<value>[a-z-|]+)>'; - - $param_types = array( - 'positional' => $p_value, - 'assoc' => "--$p_name=$p_value", - 'flag' => "--$p_name" - ); - - $patterns = array(); - - foreach ( $param_types as $type => $pattern ) { - $patterns[ "/^$pattern$/" ] = array( - 'type' => $type, - 'optional' => false - ); - - $patterns[ "/^\[$pattern\]$/" ] = array( - 'type' => $type, - 'optional' => true - ); - } - - $params = array(); - foreach ( array_keys( $param_types ) as $type ) - $params[$type] = array(); - - return array( $patterns, $params ); - } -} - - -class MethodSubcommand extends AbstractSubcommand { - - function __construct( $method, $parent ) { - $this->parent = $parent; - - parent::__construct( $method ); - } - - function show_usage( $prefix = 'usage: ' ) { - $command = $this->parent->name; - $subcommand = $this->get_name(); - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $command $subcommand $synopsis" ); - } - - function get_name() { - $comment = $this->method->getDocComment(); - - if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) - return $matches[1]; - - return $this->method->name; - } - - function invoke( $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - - $class = $this->parent->class; - $instance = new $class; - - $this->method->invoke( $instance, $args, $assoc_args ); - } -} - diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 2bbc3cffa4..4c51456220 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -101,7 +101,187 @@ private static function _is_good_method( $method ) { } -class SingleCommand extends AbstractSubcommand implements Command { +abstract class Subcommand implements Command { + + function __construct( $method ) { + $this->method = $method; + } + + protected function check_args( $args, $assoc_args ) { + $synopsis = $this->get_synopsis(); + if ( !$synopsis ) + return; + + $accepted_params = $this->parse_synopsis( $synopsis ); + + $this->check_positional( $args, $accepted_params ); + + $this->check_assoc( $assoc_args, $accepted_params ); + + $this->check_unknown_assoc( $assoc_args, $accepted_params ); + } + + private function check_positional( $args, $accepted_params ) { + $count = 0; + + foreach ( $accepted_params['positional'] as $param ) { + if ( !$param['optional'] ) + $count++; + } + + if ( count( $args ) < $count ) { + $this->show_usage(); + exit(1); + } + } + + private function check_assoc( $assoc_args, $accepted_params ) { + $mandatory_assoc = array(); + + foreach ( $accepted_params['assoc'] as $param ) { + if ( !$param['optional'] ) + $mandatory_assoc[] = $param['name']; + } + + $errors = array(); + + foreach ( $mandatory_assoc as $key ) { + if ( !isset( $assoc_args[ $key ] ) ) + $errors[] = "missing --$key parameter"; + elseif ( true === $assoc_args[ $key ] ) + $errors[] = "--$key parameter needs a value"; + } + + if ( !empty( $errors ) ) { + foreach ( $errors as $error ) { + \WP_CLI::warning( $error ); + } + $this->show_usage(); + exit(1); + } + } + + private function check_unknown_assoc( $assoc_args, $accepted_params ) { + $known_assoc = array(); + + foreach ( array( 'assoc', 'flag' ) as $type ) { + foreach ( $accepted_params[$type] as $param ) { + $known_assoc[] = $param['name']; + } + } + + $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); + + foreach ( $unknown_assoc as $key ) { + \WP_CLI::warning( "unkown --$key parameter" ); + } + } + + protected function get_synopsis() { + $comment = $this->method->getDocComment(); + + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) + return false; + + return $matches[1]; + } + + protected function parse_synopsis( $synopsis ) { + list( $patterns, $params ) = self::get_patterns(); + + $tokens = preg_split( '/[\s\t]+/', $synopsis ); + + foreach ( $tokens as $token ) { + foreach ( $patterns as $regex => $desc ) { + if ( preg_match( $regex, $token, $matches ) ) { + $type = $desc['type']; + $params[$type][] = array_merge( $matches, $desc ); + break; + } + } + } + + return $params; + } + + private static function get_patterns() { + $p_name = '(?P<name>[a-z-_]+)'; + $p_value = '<(?P<value>[a-z-|]+)>'; + + $param_types = array( + 'positional' => $p_value, + 'assoc' => "--$p_name=$p_value", + 'flag' => "--$p_name" + ); + + $patterns = array(); + + foreach ( $param_types as $type => $pattern ) { + $patterns[ "/^$pattern$/" ] = array( + 'type' => $type, + 'optional' => false + ); + + $patterns[ "/^\[$pattern\]$/" ] = array( + 'type' => $type, + 'optional' => true + ); + } + + $params = array(); + foreach ( array_keys( $param_types ) as $type ) + $params[$type] = array(); + + return array( $patterns, $params ); + } +} + + +class MethodSubcommand extends Subcommand { + + function __construct( $method, $parent ) { + $this->parent = $parent; + + parent::__construct( $method ); + } + + function autocomplete() { + throw new Exception( "Not implemented." ); + } + + function shortdesc() { + throw new Exception( "Not implemented." ); + } + + function show_usage( $prefix = 'usage: ' ) { + $command = $this->parent->name; + $subcommand = $this->get_name(); + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $command $subcommand $synopsis" ); + } + + function get_name() { + $comment = $this->method->getDocComment(); + + if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) + return $matches[1]; + + return $this->method->name; + } + + function invoke( $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + + $class = $this->parent->class; + $instance = new $class; + + $this->method->invoke( $instance, $args, $assoc_args ); + } +} + + +class SingleCommand extends Subcommand { function __construct( $name, $callable ) { $this->name = $name; diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c161804593..0194beb6ac 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -14,7 +14,6 @@ define( 'WP_CLI', true ); // Include the wp-cli classes -include WP_CLI_ROOT . 'dispatcher-subcommand.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; From 7b50818bb586f6e8b92bac44ccd865d64d98f1c8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 18:22:19 +0300 Subject: [PATCH 0663/4858] introduce get_subcommand_names() helper --- src/php/wp-cli/dispatcher.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 4c51456220..86ee6e14ae 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -19,14 +19,11 @@ function __construct( $name, $class ) { } function autocomplete() { - $subcommands = array_keys( $this->get_subcommands() ); - return $this->name . ' ' . implode( ' ', $subcommands ); + return $this->name . ' ' . implode( ' ', $this->get_subcommand_names() ); } function shortdesc() { - $methods = array_keys( $this->get_subcommands() ); - - return implode( '|', $methods ); + return implode( '|', $this->get_subcommand_names() ); } function show_usage() { @@ -78,6 +75,10 @@ protected function find_subcommand( &$args ) { return $subcommands[ $name ]; } + private function get_subcommand_names() { + return array_keys( $this->get_subcommands() ); + } + private function get_subcommands() { $reflection = new \ReflectionClass( $this->class ); From 29f3357c42465996466dc1531b6fcf36a4e68a0f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 18:23:01 +0300 Subject: [PATCH 0664/4858] make find_subcommand() private --- src/php/wp-cli/dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 86ee6e14ae..7e353b9d1d 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -52,7 +52,7 @@ function invoke( $args, $assoc_args ) { $subcommand->invoke( $args, $assoc_args ); } - protected function find_subcommand( &$args ) { + private function find_subcommand( &$args ) { $class = $this->class; if ( empty( $args ) ) { From f26ff3383e13eccea23aa107f74be6108d81e5ef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 18:57:59 +0300 Subject: [PATCH 0665/4858] make get_name() mandatory for Subcommand classes --- src/php/wp-cli/dispatcher.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 7e353b9d1d..fcbf9f938e 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -108,6 +108,8 @@ function __construct( $method ) { $this->method = $method; } + abstract function get_name(); + protected function check_args( $args, $assoc_args ) { $synopsis = $this->get_synopsis(); if ( !$synopsis ) @@ -293,6 +295,10 @@ function __construct( $name, $callable ) { parent::__construct( $method ); } + function get_name() { + return $this->name; + } + function autocomplete() { return $this->name; } @@ -302,7 +308,7 @@ function shortdesc() { } function show_usage( $prefix = 'usage: ' ) { - $command = $this->name; + $command = $this->get_name(); $synopsis = $this->get_synopsis(); \WP_CLI::line( $prefix . "wp $command $synopsis" ); From 10f26ae37b88c664b5957f01ec55cb7a20c6b2ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 19:04:45 +0300 Subject: [PATCH 0666/4858] introduce TopLevelCommand. see #184 --- src/php/wp-cli/dispatcher.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index fcbf9f938e..a409c7035c 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -4,14 +4,18 @@ interface Command { - function autocomplete(); - function shortdesc(); function show_usage(); function invoke( $arguments, $assoc_args ); } +interface TopLevelCommand { + + function autocomplete(); + function shortdesc(); +} + -class CompositeCommand implements Command { +class CompositeCommand implements Command, TopLevelCommand { function __construct( $name, $class ) { $this->name = $name; @@ -248,14 +252,6 @@ function __construct( $method, $parent ) { parent::__construct( $method ); } - function autocomplete() { - throw new Exception( "Not implemented." ); - } - - function shortdesc() { - throw new Exception( "Not implemented." ); - } - function show_usage( $prefix = 'usage: ' ) { $command = $this->parent->name; $subcommand = $this->get_name(); @@ -284,7 +280,7 @@ function invoke( $args, $assoc_args ) { } -class SingleCommand extends Subcommand { +class SingleCommand extends Subcommand implements TopLevelCommand { function __construct( $name, $callable ) { $this->name = $name; From be9f305ca7815b4569daa8cf84904ac7c0b77571 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 19:38:33 +0300 Subject: [PATCH 0667/4858] move WP_CLI::parse_args() to WP_CLI\Utils\parse_args() --- src/php/wp-cli/class-wp-cli.php | 23 ----------------------- src/php/wp-cli/utils.php | 27 +++++++++++++++++++++++++++ src/php/wp-cli/wp-cli.php | 3 ++- 3 files changed, 29 insertions(+), 24 deletions(-) create mode 100644 src/php/wp-cli/utils.php diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index eb084f6a39..c961bb56fb 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -129,29 +129,6 @@ static function error_to_string( $errors ) { } } - /** - * Splits a string into positional and associative arguments. - * - * @param string - * @return array - */ - static function parse_args( $arguments ) { - $regular_args = array(); - $assoc_args = array(); - - foreach ( $arguments as $arg ) { - if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { - $assoc_args[ $matches[1] ] = true; - } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { - $assoc_args[ $matches[1] ] = $matches[2]; - } else { - $regular_args[] = $arg; - } - } - - return array( $regular_args, $assoc_args ); - } - /** * Composes positional and associative arguments into a string. * diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php new file mode 100644 index 0000000000..f9d667092c --- /dev/null +++ b/src/php/wp-cli/utils.php @@ -0,0 +1,27 @@ +<?php + +namespace WP_CLI\Utils; + +/** + * Splits $argv into positional and associative arguments. + * + * @param string + * @return array + */ +function parse_args() { + $regular_args = array(); + $assoc_args = array(); + + foreach ( array_slice( $GLOBALS['argv'], 1 ) as $arg ) { + if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = true; + } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = $matches[2]; + } else { + $regular_args[] = $arg; + } + } + + return array( $regular_args, $assoc_args ); +} + diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 0194beb6ac..6a0aa01cae 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -14,6 +14,7 @@ define( 'WP_CLI', true ); // Include the wp-cli classes +include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; @@ -27,7 +28,7 @@ \cli\register_autoload(); // Get the cli arguments -list( $arguments, $assoc_args ) = WP_CLI::parse_args( array_slice( $GLOBALS['argv'], 1 ) ); +list( $arguments, $assoc_args ) = WP_CLI\Utils\parse_args(); // Set output levels define( 'WP_CLI_AUTOCOMPLETE', isset( $assoc_args['completions'] ) ); From d0153c7ac20752ae57d333748bd78782fa285e5a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 19:53:26 +0300 Subject: [PATCH 0668/4858] move WP_CLI::_set_url() & co to WP_CLI\Utils\ --- src/php/wp-cli/class-wp-cli.php | 74 ---------------------- src/php/wp-cli/commands/internals/core.php | 2 +- src/php/wp-cli/utils.php | 74 ++++++++++++++++++++++ src/php/wp-cli/wp-cli.php | 4 +- 4 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index c961bb56fb..5a557ff1ca 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -177,24 +177,6 @@ static function launch( $command, $exit_on_error = true ) { return $r; } - /** - * Sets the appropriate $_SERVER keys based on a given string - * - * @param string $url The URL - */ - static function set_url_params( $url ) { - $url_parts = parse_url( $url ); - - if ( !isset( $url_parts['scheme'] ) ) { - $url_parts = parse_url( 'http://' . $url ); - } - - $_SERVER['HTTP_HOST'] = isset($url_parts['host']) ? $url_parts['host'] : ''; - $_SERVER['REQUEST_URI'] = (isset($url_parts['path']) ? $url_parts['path'] : '') . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); - $_SERVER['REQUEST_URL'] = isset($url_parts['path']) ? $url_parts['path'] : ''; - $_SERVER['QUERY_STRING'] = isset($url_parts['query']) ? $url_parts['query'] : ''; - } - static function get_upgrader( $class ) { if ( !class_exists( 'WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; @@ -204,62 +186,6 @@ static function get_upgrader( $class ) { return new $class( new CLI_Upgrader_Skin ); } - static function _set_url( &$assoc_args ) { - if ( isset( $assoc_args['url'] ) ) { - $blog = $assoc_args['url']; - /* unset( $assoc_args['url'] ); */ - } elseif ( isset( $assoc_args['blog'] ) ) { - $blog = $assoc_args['blog']; - unset( $assoc_args['blog'] ); - if ( true === $blog ) { - WP_CLI::line( 'usage: wp --blog=example.com' ); - } - } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { - $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); - } elseif ( $wp_config_path = self::locate_wp_config() ) { - // Try to find the blog parameter in the wp-config file - $wp_config_file = file_get_contents( $wp_config_path ); - $hit = array(); - if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { - foreach ( $matches[2] as $def_key => $def_name ) { - if ( 'DOMAIN_CURRENT_SITE' == $def_name ) - $hit['domain'] = $matches[5][$def_key]; - if ( 'PATH_CURRENT_SITE' == $def_name ) - $hit['path'] = $matches[5][$def_key]; - } - } - - if ( !empty( $hit ) && isset( $hit['domain'] ) ) - $blog = $hit['domain']; - if ( !empty( $hit ) && isset( $hit['path'] ) ) - $blog .= $hit['path']; - } - - if ( isset( $blog ) ) { - WP_CLI::set_url_params( $blog ); - } - } - - // Loads wp-config.php without loading the rest of WP - static function load_wp_config() { - define( 'ABSPATH', dirname(__FILE__) . '/' ); - - if ( $wp_config_path = self::locate_wp_config() ) - require self::locate_wp_config(); - else - WP_CLI::error( 'No wp-config.php file.' ); - } - - static function locate_wp_config() { - if ( file_exists( WP_ROOT . 'wp-config.php' ) ) { - return WP_ROOT . 'wp-config.php'; - } elseif ( file_exists( WP_ROOT . '/../wp-config.php' ) && ! file_exists( WP_ROOT . '/../wp-settings.php' ) ) { - return WP_ROOT . '/../wp-config.php'; - } else { - return false; - } - } - static function load_all_commands() { foreach ( array( 'internals', 'community' ) as $dir ) { foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 8ea46d4c23..cfef343903 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -137,7 +137,7 @@ public function install_network( $args, $assoc_args ) { <?php $ms_config = ob_get_clean(); - $wp_config_path = WP_CLI::locate_wp_config(); + $wp_config_path = WP_CLI\Utils\locate_wp_config(); $token = "/* That's all, stop editing!"; diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index f9d667092c..cecec9b36f 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -25,3 +25,77 @@ function parse_args() { return array( $regular_args, $assoc_args ); } +function set_url( &$assoc_args ) { + if ( isset( $assoc_args['url'] ) ) { + $blog = $assoc_args['url']; + /* unset( $assoc_args['url'] ); */ + } elseif ( isset( $assoc_args['blog'] ) ) { + $blog = $assoc_args['blog']; + unset( $assoc_args['blog'] ); + if ( true === $blog ) { + \WP_CLI::line( 'usage: wp --blog=example.com' ); + } + } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { + $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); + } elseif ( $wp_config_path = locate_wp_config() ) { + // Try to find the blog parameter in the wp-config file + $wp_config_file = file_get_contents( $wp_config_path ); + $hit = array(); + if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { + foreach ( $matches[2] as $def_key => $def_name ) { + if ( 'DOMAIN_CURRENT_SITE' == $def_name ) + $hit['domain'] = $matches[5][$def_key]; + if ( 'PATH_CURRENT_SITE' == $def_name ) + $hit['path'] = $matches[5][$def_key]; + } + } + + if ( !empty( $hit ) && isset( $hit['domain'] ) ) + $blog = $hit['domain']; + if ( !empty( $hit ) && isset( $hit['path'] ) ) + $blog .= $hit['path']; + } + + if ( isset( $blog ) ) { + set_url_params( $blog ); + } +} + +/** + * Sets the appropriate $_SERVER keys based on a given string + * + * @param string $url The URL + */ +function set_url_params( $url ) { + $url_parts = parse_url( $url ); + + if ( !isset( $url_parts['scheme'] ) ) { + $url_parts = parse_url( 'http://' . $url ); + } + + $_SERVER['HTTP_HOST'] = isset($url_parts['host']) ? $url_parts['host'] : ''; + $_SERVER['REQUEST_URI'] = (isset($url_parts['path']) ? $url_parts['path'] : '') . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); + $_SERVER['REQUEST_URL'] = isset($url_parts['path']) ? $url_parts['path'] : ''; + $_SERVER['QUERY_STRING'] = isset($url_parts['query']) ? $url_parts['query'] : ''; +} + +function locate_wp_config() { + if ( file_exists( WP_ROOT . 'wp-config.php' ) ) { + return WP_ROOT . 'wp-config.php'; + } elseif ( file_exists( WP_ROOT . '/../wp-config.php' ) && ! file_exists( WP_ROOT . '/../wp-settings.php' ) ) { + return WP_ROOT . '/../wp-config.php'; + } else { + return false; + } +} + +// Loads wp-config.php without loading the rest of WP +function load_wp_config() { + define( 'ABSPATH', dirname(__FILE__) . '/' ); + + if ( $wp_config_path = locate_wp_config() ) + require locate_wp_config(); + else + WP_CLI::error( 'No wp-config.php file.' ); +} + diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 6a0aa01cae..938c8c99d4 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -57,7 +57,7 @@ } // Handle --url and --blog parameters -WP_CLI::_set_url( $assoc_args ); +WP_CLI\Utils\set_url( $assoc_args ); if ( array( 'core', 'download' ) == $arguments ) { WP_CLI::run_command( $arguments, $assoc_args ); @@ -75,7 +75,7 @@ // The db commands don't need any WP files if ( array( 'db' ) == array_slice( $arguments, 0, 1 ) ) { - WP_CLI::load_wp_config(); + WP_CLI\Utils\load_wp_config(); WP_CLI::run_command( $arguments, $assoc_args ); exit; } From c8be260a0f4acb17674a375b81a3fdfe0a3b8c54 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 20:00:03 +0300 Subject: [PATCH 0669/4858] introduce set_user() utility --- src/php/wp-cli/utils.php | 28 +++++++++++++++++++++++++++- src/php/wp-cli/wp-cli.php | 14 +------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index cecec9b36f..bb6758f4d7 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -96,6 +96,32 @@ function load_wp_config() { if ( $wp_config_path = locate_wp_config() ) require locate_wp_config(); else - WP_CLI::error( 'No wp-config.php file.' ); + \WP_CLI::error( 'No wp-config.php file.' ); +} + + + +// ---- AFTER WORDPRESS IS LOADED ---- // + + + +// Handle --user parameter +function set_user( &$assoc_args ) { + if ( !isset( $assoc_args['user'] ) ) + return; + + $user = $assoc_args['user']; + + if ( is_numeric( $user ) ) { + $user_id = (int) $user; + } else { + $user_id = (int) username_exists( $user ); + } + + if ( !$user_id || !wp_set_current_user( $user_id ) ) { + \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); + } + + unset( $assoc_args['user'] ); } diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 938c8c99d4..e1bc29f1dd 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -104,19 +104,7 @@ // Set filesystem method add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); -// Handle --user parameter -if ( isset( $assoc_args['user'] ) ) { - $user = $assoc_args['user']; - if ( is_numeric( $user ) ) { - $user_id = (int) $user; - } else { - $user_id = (int) username_exists( $user ); - } - if ( !$user_id || !wp_set_current_user( $user_id ) ) { - WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); - } - unset( $assoc_args['user'], $user ); -} +WP_CLI\Utils\set_user( $assoc_args ); // Handle --require parameter if ( isset( $assoc_args['require'] ) ) { From 083d8b27bc7b6cbeb90de9dc68e62736846b16cd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 20:15:41 +0300 Subject: [PATCH 0670/4858] move get_upgrader() to WP_CLI\Utils\ --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 6 +++--- src/php/wp-cli/class-wp-cli.php | 9 --------- src/php/wp-cli/commands/internals/core.php | 2 +- src/php/wp-cli/commands/internals/plugin.php | 2 +- src/php/wp-cli/commands/internals/theme.php | 4 ++-- src/php/wp-cli/utils.php | 9 +++++++++ 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index d76eaf63dd..8357991a6c 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -103,7 +103,7 @@ function install( $args, $assoc_args ) { $slug = stripslashes( $args[0] ); if ( '.zip' == substr( $slug, -4 ) ) { - $file_upgrader = WP_CLI::get_upgrader( $this->upgrader ); + $file_upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); if ( $file_upgrader->install( $slug ) ) { $slug = $file_upgrader->result['destination_name']; @@ -125,7 +125,7 @@ function update( $args, $assoc_args ) { list( $file, $name ) = $this->parse_name( $args ); - WP_CLI::get_upgrader( $this->upgrader )->upgrade( $file ); + WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $file ); } function update_all( $args, $assoc_args ) { @@ -142,7 +142,7 @@ function update_all( $args, $assoc_args ) { // If --all, UPDATE ALL THE THINGS if ( isset( $assoc_args['all'] ) ) { - $upgrader = WP_CLI::get_upgrader( $this->upgrader ); + $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); // Let the user know the results. diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 5a557ff1ca..7bc6639d0b 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -177,15 +177,6 @@ static function launch( $command, $exit_on_error = true ) { return $r; } - static function get_upgrader( $class ) { - if ( !class_exists( 'WP_Upgrader' ) ) - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - - require WP_CLI_ROOT . '/class-cli-upgrader-skin.php'; - - return new $class( new CLI_Upgrader_Skin ); - } - static function load_all_commands() { foreach ( array( 'internals', 'community' ) as $dir ) { foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index cfef343903..a652f3219b 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -248,7 +248,7 @@ function update( $args, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - $result = WP_CLI::get_upgrader( $upgrader )->upgrade( $update ); + $result = WP_CLI\Utils\get_upgrader( $upgrader )->upgrade( $update ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 8a98361ea5..2a57a486ff 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -163,7 +163,7 @@ protected function install_from_repo( $slug, $assoc_args ) { switch ( $status['status'] ) { case 'update_available': case 'install': - $upgrader = WP_CLI::get_upgrader( $this->upgrader ); + $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); $result = $upgrader->install( $api->download_link ); if ( $result && isset( $assoc_args['activate'] ) ) { diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 24559601d9..cceefb8444 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -114,7 +114,7 @@ protected function install_from_repo( $slug, $assoc_args ) { // Check to see if we should update, rather than install. if ( $this->has_update( $slug ) ) { WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI::get_upgrader( $this->upgrader )->upgrade( $slug ); + $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $slug ); /** * Else, if there's no update, it's either not installed, @@ -122,7 +122,7 @@ protected function install_from_repo( $slug, $assoc_args ) { */ } else if ( !is_readable( $this->get_stylesheet_path( $slug ) ) ) { WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI::get_upgrader( $this->upgrader )->install( $api->download_link ); + $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); } else { WP_CLI::error( 'Theme already installed and up to date.' ); } diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index bb6758f4d7..f91362645f 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -125,3 +125,12 @@ function set_user( &$assoc_args ) { unset( $assoc_args['user'] ); } +function get_upgrader( $class ) { + if ( !class_exists( '\WP_Upgrader' ) ) + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + + require WP_CLI_ROOT . '/class-cli-upgrader-skin.php'; + + return new $class( new \CLI_Upgrader_Skin ); +} + From db2756351b388e8e1b73c213fb44b2a0471ae923 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 20:22:46 +0300 Subject: [PATCH 0671/4858] move SAPI check to wp-cli-boot.php --- src/php/wp-cli/wp-cli-boot.php | 5 +++++ src/php/wp-cli/wp-cli.php | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/wp-cli-boot.php b/src/php/wp-cli/wp-cli-boot.php index 972e60fd8d..3effc22d4e 100644 --- a/src/php/wp-cli/wp-cli-boot.php +++ b/src/php/wp-cli/wp-cli-boot.php @@ -1,5 +1,10 @@ <?php +if ( 'cli' !== PHP_SAPI ) { + echo "Only CLI access.\n"; + die(-1); +} + if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) { printf( "Error: wp-cli requires PHP %s or newer. You are running version %s.\n", '5.3.0', PHP_VERSION ); die(-1); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index e1bc29f1dd..6a432666c2 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -1,13 +1,7 @@ <?php -if ( PHP_SAPI !== 'cli' ) { - echo "Only CLI access.\n"; - die(-1); -} - define( 'WP_CLI_VERSION', '0.7.0-alpha' ); -// Define the wp-cli location define( 'WP_CLI_ROOT', __DIR__ . '/' ); // Set a constant that can be used to check if we are running wp-cli or not From e8b9231dea944bb723533e14a4eca7351cbf8b67 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 20:31:56 +0300 Subject: [PATCH 0672/4858] define WP_CLI_URL constant, instead of leaving 'url' in $assoc_args --- src/php/wp-cli/utils.php | 3 ++- src/php/wp-cli/wp-cli.php | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index f91362645f..f6ee850ee2 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -27,8 +27,9 @@ function parse_args() { function set_url( &$assoc_args ) { if ( isset( $assoc_args['url'] ) ) { + define( 'WP_CLI_URL', $assoc_args['url'] ); $blog = $assoc_args['url']; - /* unset( $assoc_args['url'] ); */ + unset( $assoc_args['url'] ); } elseif ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; unset( $assoc_args['blog'] ); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 6a432666c2..04e3b49011 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -76,7 +76,7 @@ // Set installer flag before loading any WP files if ( array( 'core', 'install' ) == $arguments ) { - define( 'WP_INSTALLING', true ); + define( 'WP_INSTALLING', true ); } // Load WordPress @@ -88,11 +88,11 @@ require ABSPATH . 'wp-admin/includes/admin.php'; // Load the right info into the global wp_query -if ( !defined( 'WP_INSTALLING' ) && isset( $assoc_args['url'] ) ) { - if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { - $GLOBALS['wp']->parse_request(); - $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); - } +if ( !defined( 'WP_INSTALLING' ) && defined( 'WP_CLI_URL' ) ) { + if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { + $GLOBALS['wp']->parse_request(); + $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); + } } // Set filesystem method From f1e358087ba9d16ac6ec7cbc5e0fb3ebe04d3867 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 21:34:37 +0300 Subject: [PATCH 0673/4858] Store arguments as properties on WP_CLI, instead of as global variables. This avoids having to define various constants. Also: - removes support for deprecated --help global parameter - removes support for deprecated --silent global parameter --- src/php/wp-cli/class-wp-cli.php | 111 ++++++++++++++++++++++++++++---- src/php/wp-cli/dispatcher.php | 2 + src/php/wp-cli/utils.php | 37 ++++++++--- src/php/wp-cli/wp-cli.php | 94 +-------------------------- 4 files changed, 132 insertions(+), 112 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 7bc6639d0b..45ad48ca51 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -51,7 +51,7 @@ static function line( $message = '' ) { * @param string $label */ static function error( $message, $label = 'Error' ) { - if ( !WP_CLI_AUTOCOMPLETE ) { + if ( !isset( self::$assoc_special['completions'] ) ) { \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); } @@ -192,6 +192,26 @@ static function load_all_commands() { return self::$commands; } + static function load_command( $command ) { + if ( !isset( WP_CLI::$commands[$command] ) ) { + foreach ( array( 'internals', 'community' ) as $dir ) { + $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + + if ( is_readable( $path ) ) { + include $path; + break; + } + } + } + + if ( !isset( WP_CLI::$commands[$command] ) ) { + WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); + exit; + } + + return WP_CLI::$commands[$command]; + } + static function run_command( $arguments, $assoc_args ) { if ( empty( $arguments ) ) { $command = 'help'; @@ -213,24 +233,89 @@ static function run_command( $arguments, $assoc_args ) { $command->invoke( $arguments, $assoc_args ); } - static function load_command( $command ) { - if ( !isset( WP_CLI::$commands[$command] ) ) { - foreach ( array( 'internals', 'community' ) as $dir ) { - $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + private static $arguments, $assoc_args, $assoc_special; - if ( is_readable( $path ) ) { - include $path; - break; - } - } + static function before_wp_load() { + $r = WP_CLI\Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); + + list( self::$arguments, self::$assoc_args ) = $r; + + self::$assoc_special = WP_CLI\Utils\split_assoc( self::$assoc_args, array( + 'path', 'url', 'blog', 'user', 'require', + 'quiet', 'completions' + ) ); + + define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); + + // Handle --version parameter + if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { + self::line( 'wp-cli ' . WP_CLI_VERSION ); + exit; } - if ( !isset( WP_CLI::$commands[$command] ) ) { - WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); + $_SERVER['DOCUMENT_ROOT'] = getcwd(); + + // Define the WordPress location + if ( !empty( self::$assoc_special['path'] ) ) { + // trailingslashit() isn't available yet + define( 'WP_ROOT', rtrim( self::$assoc_args['path'], '/' ) . '/' ); + } else { + define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); + } + + // Handle --url and --blog parameters + WP_CLI\Utils\set_url( self::$assoc_special ); + + if ( array( 'core', 'download' ) == self::$arguments ) { + WP_CLI::run_command( self::$arguments, self::$assoc_args ); exit; } - return WP_CLI::$commands[$command]; + if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { + WP_CLI::error( 'This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.' ); + } + + if ( array( 'core', 'config' ) == self::$arguments ) { + WP_CLI::run_command( self::$arguments, self::$assoc_args ); + exit; + } + + // The db commands don't need any WP files + if ( array( 'db' ) == array_slice( self::$arguments, 0, 1 ) ) { + WP_CLI\Utils\load_wp_config(); + WP_CLI::run_command( self::$arguments, self::$assoc_args ); + exit; + } + + // Set installer flag before loading any WP files + if ( array( 'core', 'install' ) == self::$arguments ) { + define( 'WP_INSTALLING', true ); + } + } + + static function get_assoc_special() { + return self::$assoc_special; + } + + static function after_wp_load() { + add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); + + WP_CLI\Utils\set_user( self::$assoc_special ); + + if ( !defined( 'WP_INSTALLING' ) && isset( self::$assoc_special['url'] ) ) + WP_CLI\Utils\set_wp_query(); + + if ( isset( self::$assoc_special['require'] ) ) + require self::$assoc_special['require']; + + if ( isset( self::$assoc_special['completions'] ) ) { + foreach ( self::load_all_commands() as $name => $command ) { + self::line( $command->autocomplete() ); + } + exit; + } + + self::run_command( self::$arguments, self::$assoc_args ); } // back-compat diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index a409c7035c..0b2d19ba5b 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -145,6 +145,8 @@ private function check_positional( $args, $accepted_params ) { private function check_assoc( $assoc_args, $accepted_params ) { $mandatory_assoc = array(); + $assoc_args += \WP_CLI::get_assoc_special(); + foreach ( $accepted_params['assoc'] as $param ) { if ( !$param['optional'] ) $mandatory_assoc[] = $param['name']; diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index f6ee850ee2..1e49fcb89e 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -8,11 +8,11 @@ * @param string * @return array */ -function parse_args() { +function parse_args( $arguments ) { $regular_args = array(); $assoc_args = array(); - foreach ( array_slice( $GLOBALS['argv'], 1 ) as $arg ) { + foreach ( $arguments as $arg ) { if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { $assoc_args[ $matches[1] ] = true; } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { @@ -25,14 +25,30 @@ function parse_args() { return array( $regular_args, $assoc_args ); } -function set_url( &$assoc_args ) { +/** + * Splits $argv into positional and associative arguments. + * + * @param string + * @return array + */ +function split_assoc( &$assoc_args, $special_keys ) { + $assoc_special = array(); + + foreach ( $special_keys as $key ) { + if ( isset( $assoc_args[ $key ] ) ) { + $assoc_special[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } + } + + return $assoc_special; +} + +function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { - define( 'WP_CLI_URL', $assoc_args['url'] ); $blog = $assoc_args['url']; - unset( $assoc_args['url'] ); } elseif ( isset( $assoc_args['blog'] ) ) { $blog = $assoc_args['blog']; - unset( $assoc_args['blog'] ); if ( true === $blog ) { \WP_CLI::line( 'usage: wp --blog=example.com' ); } @@ -107,7 +123,7 @@ function load_wp_config() { // Handle --user parameter -function set_user( &$assoc_args ) { +function set_user( $assoc_args ) { if ( !isset( $assoc_args['user'] ) ) return; @@ -122,8 +138,13 @@ function set_user( &$assoc_args ) { if ( !$user_id || !wp_set_current_user( $user_id ) ) { \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); } +} - unset( $assoc_args['user'] ); +function set_wp_query() { + if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { + $GLOBALS['wp']->parse_request(); + $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); + } } function get_upgrader( $class ) { diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 04e3b49011..94fe0e5fa5 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -4,10 +4,9 @@ define( 'WP_CLI_ROOT', __DIR__ . '/' ); -// Set a constant that can be used to check if we are running wp-cli or not +// Can be used to check if we are running wp-cli or not define( 'WP_CLI', true ); -// Include the wp-cli classes include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; @@ -15,71 +14,11 @@ include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-upgrade.php'; -// Include the command line tools include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; - -// Register the cli tools autoload \cli\register_autoload(); -// Get the cli arguments -list( $arguments, $assoc_args ) = WP_CLI\Utils\parse_args(); - -// Set output levels -define( 'WP_CLI_AUTOCOMPLETE', isset( $assoc_args['completions'] ) ); -define( 'WP_CLI_QUIET', isset( $assoc_args['quiet'] ) || isset( $assoc_args['silent'] ) ); - -// Handle --version parameter -if ( isset( $assoc_args['version'] ) && empty( $arguments ) ) { - WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); - exit; -} - -// Handle --help parameter -if ( isset( $assoc_args['help'] ) ) { - array_unshift( $arguments, 'help' ); - unset( $assoc_args['help'] ); -} - -$_SERVER['DOCUMENT_ROOT'] = getcwd(); - -// Define the WordPress location -if ( !empty( $assoc_args['path'] ) ) { - // trailingslashit() isn't available yet - define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); -} else { - define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); -} - -// Handle --url and --blog parameters -WP_CLI\Utils\set_url( $assoc_args ); - -if ( array( 'core', 'download' ) == $arguments ) { - WP_CLI::run_command( $arguments, $assoc_args ); - exit; -} - -if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { - WP_CLI::error( 'This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.' ); -} +WP_CLI::before_wp_load(); -if ( array( 'core', 'config' ) == $arguments ) { - WP_CLI::run_command( $arguments, $assoc_args ); - exit; -} - -// The db commands don't need any WP files -if ( array( 'db' ) == array_slice( $arguments, 0, 1 ) ) { - WP_CLI\Utils\load_wp_config(); - WP_CLI::run_command( $arguments, $assoc_args ); - exit; -} - -// Set installer flag before loading any WP files -if ( array( 'core', 'install' ) == $arguments ) { - define( 'WP_INSTALLING', true ); -} - -// Load WordPress require WP_ROOT . 'wp-load.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @@ -87,32 +26,5 @@ require ABSPATH . 'wp-admin/includes/admin.php'; -// Load the right info into the global wp_query -if ( !defined( 'WP_INSTALLING' ) && defined( 'WP_CLI_URL' ) ) { - if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { - $GLOBALS['wp']->parse_request(); - $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); - } -} - -// Set filesystem method -add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - -WP_CLI\Utils\set_user( $assoc_args ); - -// Handle --require parameter -if ( isset( $assoc_args['require'] ) ) { - require $assoc_args['require']; - unset( $assoc_args['require'] ); -} - -// Generate strings for autocomplete -if ( WP_CLI_AUTOCOMPLETE ) { - foreach ( WP_CLI::load_all_commands() as $name => $command ) { - WP_CLI::line( $command->autocomplete() ); - } - exit; -} - -WP_CLI::run_command( $arguments, $assoc_args ); +WP_CLI::after_wp_load(); From 724a565a7c87014e5d9b58a9c9ea764fab79a883 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Oct 2012 23:23:39 +0300 Subject: [PATCH 0674/4858] add some comments to the init process --- src/php/wp-cli/wp-cli-boot.php | 2 ++ src/php/wp-cli/wp-cli.php | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/wp-cli-boot.php b/src/php/wp-cli/wp-cli-boot.php index 3effc22d4e..b7c8de526a 100644 --- a/src/php/wp-cli/wp-cli-boot.php +++ b/src/php/wp-cli/wp-cli-boot.php @@ -1,5 +1,7 @@ <?php +// This file needs to parse without error in PHP < 5.3 + if ( 'cli' !== PHP_SAPI ) { echo "Only CLI access.\n"; die(-1); diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 94fe0e5fa5..61e7a1af9c 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -1,12 +1,12 @@ <?php +// Can be used by plugins/themes to check if wp-cli is running or not +define( 'WP_CLI', true ); + define( 'WP_CLI_VERSION', '0.7.0-alpha' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); -// Can be used to check if we are running wp-cli or not -define( 'WP_CLI', true ); - include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; @@ -19,11 +19,13 @@ WP_CLI::before_wp_load(); +// Load WordPress, in the global scope require WP_ROOT . 'wp-load.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); +// Load all admin utilities require ABSPATH . 'wp-admin/includes/admin.php'; WP_CLI::after_wp_load(); From db8ab9d85425a6ed7783907be115b1ac1e5510b7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 00:22:06 +0300 Subject: [PATCH 0675/4858] implement alias tag --- .../wp-cli/class-wp-cli-command-with-meta.php | 7 +--- src/php/wp-cli/class-wp-cli-command.php | 4 -- src/php/wp-cli/commands/internals/db.php | 7 +--- src/php/wp-cli/commands/internals/option.php | 7 +--- src/php/wp-cli/dispatcher.php | 39 +++++++++++++++---- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-meta.php b/src/php/wp-cli/class-wp-cli-command-with-meta.php index 968abf7216..7a18853b3c 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-meta.php +++ b/src/php/wp-cli/class-wp-cli-command-with-meta.php @@ -7,12 +7,6 @@ */ abstract class WP_CLI_Command_With_Meta extends WP_CLI_Command { - public static function get_aliases() { - return array( - 'set' => 'update' - ); - } - protected $meta_type; /** @@ -68,6 +62,7 @@ public function add( $args, $assoc_args ) { /** * Update a meta field. * + * @alias set * @synopsis <id> <key> <value> */ public function update( $args, $assoc_args ) { diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index c8166549ce..0bd4e12473 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -11,10 +11,6 @@ public static function get_default_subcommand() { return false; } - public static function get_aliases() { - return array(); - } - public function __construct() {} } diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index e5448e92f7..ddd9c16118 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -14,12 +14,6 @@ public static function get_default_subcommand() { return 'cli'; } - public static function get_aliases() { - return array( - 'dump' => 'export' - ); - } - /** * Creates the database specified in the wp-config.php file. */ @@ -137,6 +131,7 @@ function query( $args, $assoc_args ) { /** * Exports the WordPress DB as SQL using mysqldump. * + * @alias dump * @synopsis [<file>] */ function export( $args, $assoc_args ) { diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index c7a1fb532c..091677f0e4 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -10,12 +10,6 @@ */ class Option_Command extends WP_CLI_Command { - public static function get_aliases() { - return array( - 'set' => 'update' - ); - } - /** * Get an option * @@ -50,6 +44,7 @@ public function add( $args, $assoc_args ) { /** * Update an option * + * @alias set * @synopsis <key> <value> [--json] */ public function update( $args, $assoc_args ) { diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 0b2d19ba5b..5f038f8ff8 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -65,13 +65,15 @@ private function find_subcommand( &$args ) { $name = array_shift( $args ); } - $aliases = $class::get_aliases(); + $subcommands = $this->get_subcommands(); - if ( isset( $aliases[ $name ] ) ) { - $name = $aliases[ $name ]; - } + if ( !isset( $subcommands[ $name ] ) ) { + $aliases = self::get_aliases( $subcommands ); - $subcommands = $this->get_subcommands(); + if ( isset( $aliases[ $name ] ) ) { + $name = $aliases[ $name ]; + } + } if ( !isset( $subcommands[ $name ] ) ) return false; @@ -79,6 +81,18 @@ private function find_subcommand( &$args ) { return $subcommands[ $name ]; } + private static function get_aliases( $subcommands ) { + $aliases = array(); + + foreach ( $subcommands as $name => $subcommand ) { + $alias = $subcommand->get_alias(); + if ( $alias ) + $aliases[ $alias ] = $name; + } + + return $aliases; + } + private function get_subcommand_names() { return array_keys( $this->get_subcommands() ); } @@ -262,15 +276,26 @@ function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $prefix . "wp $command $subcommand $synopsis" ); } - function get_name() { + private function get_tag( $name ) { $comment = $this->method->getDocComment(); - if ( preg_match( '/@subcommand\s+([a-z-]+)/', $comment, $matches ) ) + if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $comment, $matches ) ) return $matches[1]; + return false; + } + + function get_name() { + if ( $name = $this->get_tag( 'subcommand' ) ) + return $name; + return $this->method->name; } + function get_alias() { + return $this->get_tag( 'alias' ); + } + function invoke( $args, $assoc_args ) { $this->check_args( $args, $assoc_args ); From ebcf50d60d38a87a1934cd5ffbba1447a2f315d4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 01:08:05 +0300 Subject: [PATCH 0676/4858] flags can't be mandatory --- src/php/wp-cli/dispatcher.php | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 0b2d19ba5b..9efbc85254 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -218,23 +218,29 @@ private static function get_patterns() { $p_value = '<(?P<value>[a-z-|]+)>'; $param_types = array( - 'positional' => $p_value, - 'assoc' => "--$p_name=$p_value", - 'flag' => "--$p_name" + array( 'positional', $p_value, 1, 1 ), + array( 'assoc', "--$p_name=$p_value", 1, 1 ), + array( 'flag', "--$p_name", 1, 0 ), ); $patterns = array(); - foreach ( $param_types as $type => $pattern ) { - $patterns[ "/^$pattern$/" ] = array( - 'type' => $type, - 'optional' => false - ); + foreach ( $param_types as $pt ) { + list( $type, $pattern, $optional, $mandatory ) = $pt; - $patterns[ "/^\[$pattern\]$/" ] = array( - 'type' => $type, - 'optional' => true - ); + if ( $mandatory ) { + $patterns[ "/^$pattern$/" ] = array( + 'type' => $type, + 'optional' => false + ); + } + + if ( $optional ) { + $patterns[ "/^\[$pattern\]$/" ] = array( + 'type' => $type, + 'optional' => true + ); + } } $params = array(); From cfab0bc5b81070cfbd6d22a69830711d8a26baab Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 01:43:29 +0300 Subject: [PATCH 0677/4858] support generic assoc args in synopsis --- src/php/wp-cli/commands/internals/post.php | 13 ++++++------- src/php/wp-cli/commands/internals/user.php | 7 ++++--- src/php/wp-cli/dispatcher.php | 19 ++++++++++--------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 19068f196b..1714b3ffdf 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -11,10 +11,9 @@ class Post_Command extends WP_CLI_Command { /** - * Create a post + * Create a post. * - * @param array $args - * @param array $assoc_args + * @synopsis --<field>=<value> [--porcelain] */ public function create( $args, $assoc_args ) { $post_id = wp_insert_post( $assoc_args, true ); @@ -30,13 +29,12 @@ public function create( $args, $assoc_args ) { } /** - * Update a post + * Update a post. * - * @param array $args - * @param array $assoc_args + * @synopsis <id> --<field>=<value> */ public function update( $args, $assoc_args ) { - $post_id = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); + list( $post_id ) = $args; if ( empty( $assoc_args ) ) { WP_CLI::error( "Need some fields to update." ); @@ -72,6 +70,7 @@ public function delete( $post_ids, $assoc_args ) { * Get a list of posts. * * @subcommand list + * @synopsis [--<field>=<value>] */ public function _list( $_, $assoc_args ) { $query_args = array( diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 7fe8ca529d..f9bd9c26cf 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -60,7 +60,7 @@ public function _list( $args, $assoc_args ) { public function delete( $args, $assoc_args ) { global $blog_id; - $user_id = WP_CLI::get_numeric_arg( $args, 0, "User ID" ); + list( $user_id ) = $args; $defaults = array( 'reassign' => NULL ); @@ -124,9 +124,11 @@ public function create( $args, $assoc_args ) { /** * Update a user. + * + * @synopsis <id> --<field>=<value> */ public function update( $args, $assoc_args ) { - $user_id = WP_CLI::get_numeric_arg( $args, 0, "User ID" ); + list( $user_id ) = $args; if ( empty( $assoc_args ) ) { WP_CLI::error( "Need some fields to update." ); @@ -143,7 +145,6 @@ public function update( $args, $assoc_args ) { } } - /** * Generate users * diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 9efbc85254..5fa2ec2223 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -125,7 +125,8 @@ protected function check_args( $args, $assoc_args ) { $this->check_assoc( $assoc_args, $accepted_params ); - $this->check_unknown_assoc( $assoc_args, $accepted_params ); + if ( empty( $accepted_params['generic'] ) ) + $this->check_unknown_assoc( $assoc_args, $accepted_params ); } private function check_positional( $args, $accepted_params ) { @@ -215,15 +216,17 @@ protected function parse_synopsis( $synopsis ) { private static function get_patterns() { $p_name = '(?P<name>[a-z-_]+)'; - $p_value = '<(?P<value>[a-z-|]+)>'; + $p_value = '(?P<value>[a-z-|]+)'; $param_types = array( - array( 'positional', $p_value, 1, 1 ), - array( 'assoc', "--$p_name=$p_value", 1, 1 ), - array( 'flag', "--$p_name", 1, 0 ), + array( 'positional', "<$p_value>", 1, 1 ), + array( 'generic', "--<field>=<value>", 1, 1 ), + array( 'assoc', "--$p_name=<$p_value>", 1, 1 ), + array( 'flag', "--$p_name", 1, 0 ), ); $patterns = array(); + $params = array(); foreach ( $param_types as $pt ) { list( $type, $pattern, $optional, $mandatory ) = $pt; @@ -241,11 +244,9 @@ private static function get_patterns() { 'optional' => true ); } - } - $params = array(); - foreach ( array_keys( $param_types ) as $type ) - $params[$type] = array(); + $params[ $type ] = array(); + } return array( $patterns, $params ); } From 0be8cb2be07b0e91bdaa71bc525382b6dbb802f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 02:02:55 +0300 Subject: [PATCH 0678/4858] make get_subcommands() a required method and get rid of the TopLevelSubcommand interface --- src/php/wp-cli/class-wp-cli.php | 13 ++++++--- src/php/wp-cli/commands/internals/help.php | 3 +- src/php/wp-cli/dispatcher.php | 34 +++++----------------- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 45ad48ca51..8bc2f32bdc 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -309,15 +309,20 @@ static function after_wp_load() { require self::$assoc_special['require']; if ( isset( self::$assoc_special['completions'] ) ) { - foreach ( self::load_all_commands() as $name => $command ) { - self::line( $command->autocomplete() ); - } - exit; + self::render_automcomplete(); } self::run_command( self::$arguments, self::$assoc_args ); } + private static function render_automcomplete() { + foreach ( self::load_all_commands() as $name => $command ) { + $subcommands = $command->get_subcommands(); + self::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); + } + exit; + } + // back-compat static function addCommand( $name, $class ) { self::add_command( $name, $class ); diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 2f640280ad..85e69ce79b 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -46,7 +46,8 @@ private static function general_help() { if ( 'help' == $name ) continue; - WP_CLI::line( " wp $name " . $command->shortdesc() ); + $subcommands = $command->get_subcommands(); + WP_CLI::line( " wp $name " . implode( '|', array_keys( $subcommands ) ) ); } WP_CLI::line(<<<EOB diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 5fa2ec2223..cf16967ca5 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -6,28 +6,18 @@ interface Command { function show_usage(); function invoke( $arguments, $assoc_args ); + function get_subcommands(); } -interface TopLevelCommand { - - function autocomplete(); - function shortdesc(); -} - -class CompositeCommand implements Command, TopLevelCommand { +class CompositeCommand implements Command { function __construct( $name, $class ) { $this->name = $name; $this->class = $class; } - function autocomplete() { - return $this->name . ' ' . implode( ' ', $this->get_subcommand_names() ); - } - function shortdesc() { - return implode( '|', $this->get_subcommand_names() ); } function show_usage() { @@ -79,11 +69,7 @@ private function find_subcommand( &$args ) { return $subcommands[ $name ]; } - private function get_subcommand_names() { - return array_keys( $this->get_subcommands() ); - } - - private function get_subcommands() { + public function get_subcommands() { $reflection = new \ReflectionClass( $this->class ); $subcommands = array(); @@ -112,6 +98,10 @@ function __construct( $method ) { $this->method = $method; } + function get_subcommands() { + return array(); + } + abstract function get_name(); protected function check_args( $args, $assoc_args ) { @@ -289,7 +279,7 @@ function invoke( $args, $assoc_args ) { } -class SingleCommand extends Subcommand implements TopLevelCommand { +class SingleCommand extends Subcommand { function __construct( $name, $callable ) { $this->name = $name; @@ -304,14 +294,6 @@ function get_name() { return $this->name; } - function autocomplete() { - return $this->name; - } - - function shortdesc() { - return ''; - } - function show_usage( $prefix = 'usage: ' ) { $command = $this->get_name(); $synopsis = $this->get_synopsis(); From 17acfed52b4c9ba1efc70d3d71af30bd01475092 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 03:34:00 +0300 Subject: [PATCH 0679/4858] Introduce RootCommand class. It implements the Command interface, so it's easier to reason about it. --- src/php/wp-cli/class-wp-cli.php | 43 ++++++------------ src/php/wp-cli/commands/internals/help.php | 30 ------------- src/php/wp-cli/dispatcher.php | 52 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8bc2f32bdc..a76093cf5d 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -193,7 +193,7 @@ static function load_all_commands() { } static function load_command( $command ) { - if ( !isset( WP_CLI::$commands[$command] ) ) { + if ( !isset( self::$commands[$command] ) ) { foreach ( array( 'internals', 'community' ) as $dir ) { $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; @@ -204,33 +204,12 @@ static function load_command( $command ) { } } - if ( !isset( WP_CLI::$commands[$command] ) ) { - WP_CLI::error( "'$command' is not a registered wp command. See 'wp help'." ); + if ( !isset( self::$commands[$command] ) ) { + self::error( "'$command' is not a registered wp command. See 'wp help'." ); exit; } - return WP_CLI::$commands[$command]; - } - - static function run_command( $arguments, $assoc_args ) { - if ( empty( $arguments ) ) { - $command = 'help'; - } else { - $command = array_shift( $arguments ); - - $aliases = array( - 'sql' => 'db' - ); - - if ( isset( $aliases[ $command ] ) ) - $command = $aliases[ $command ]; - } - - define( 'WP_CLI_COMMAND', $command ); - - $command = self::load_command( $command ); - - $command->invoke( $arguments, $assoc_args ); + return self::$commands[$command]; } private static $arguments, $assoc_args, $assoc_special; @@ -267,7 +246,7 @@ static function before_wp_load() { WP_CLI\Utils\set_url( self::$assoc_special ); if ( array( 'core', 'download' ) == self::$arguments ) { - WP_CLI::run_command( self::$arguments, self::$assoc_args ); + self::run_command(); exit; } @@ -276,14 +255,14 @@ static function before_wp_load() { } if ( array( 'core', 'config' ) == self::$arguments ) { - WP_CLI::run_command( self::$arguments, self::$assoc_args ); + self::run_command(); exit; } // The db commands don't need any WP files if ( array( 'db' ) == array_slice( self::$arguments, 0, 1 ) ) { WP_CLI\Utils\load_wp_config(); - WP_CLI::run_command( self::$arguments, self::$assoc_args ); + self::run_command(); exit; } @@ -312,7 +291,13 @@ static function after_wp_load() { self::render_automcomplete(); } - self::run_command( self::$arguments, self::$assoc_args ); + self::run_command(); + } + + private static function run_command() { + $root = new \WP_CLI\Dispatcher\RootCommand; + + $root->invoke( self::$arguments, self::$assoc_args ); } private static function render_automcomplete() { diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 85e69ce79b..5231a0dd22 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -11,11 +11,6 @@ class Help_Command extends WP_CLI_Command { function __invoke( $args ) { - if ( empty( $args ) ) { - self::general_help(); - return; - } - self::maybe_load_man_page( $args ); self::show_available_subcommands( $args[0] ); @@ -39,30 +34,5 @@ private static function show_available_subcommands( $command ) { $command = WP_CLI::load_command( $command ); $command->show_usage(); } - - private static function general_help() { - WP_CLI::line( 'Available commands:' ); - foreach ( WP_CLI::load_all_commands() as $name => $command ) { - if ( 'help' == $name ) - continue; - - $subcommands = $command->get_subcommands(); - WP_CLI::line( " wp $name " . implode( '|', array_keys( $subcommands ) ) ); - } - - WP_CLI::line(<<<EOB - -See 'wp help <command>' for more information on a specific command. - -Global parameters: ---user=<id|login> set the current user ---url=<url> set the current URL ---path=<path> set the current path to the WP install ---require=<path> load a certain file before running the command ---quiet suppress informational messages ---version print wp-cli version -EOB - ); - } } diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index b1e1a64cee..fe70e3a159 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -10,6 +10,58 @@ function get_subcommands(); } +class RootCommand implements Command { + + function show_usage() { + \WP_CLI::line( 'Available commands:' ); + foreach ( \WP_CLI::load_all_commands() as $name => $command ) { + $subcommands = $command->get_subcommands(); + \WP_CLI::line( " wp $name " . implode( '|', array_keys( $subcommands ) ) ); + } + + \WP_CLI::line(<<<EOB + +See 'wp help <command>' for more information on a specific command. + +Global parameters: +--user=<id|login> set the current user +--url=<url> set the current URL +--path=<path> set the current path to the WP install +--require=<path> load a certain file before running the command +--quiet suppress informational messages +--version print wp-cli version +EOB + ); + } + + function invoke( $arguments, $assoc_args ) { + if ( empty( $arguments ) ) { + $this->show_usage(); + exit; + } + + $command = array_shift( $arguments ); + + $aliases = array( + 'sql' => 'db' + ); + + if ( isset( $aliases[ $command ] ) ) + $command = $aliases[ $command ]; + + define( 'WP_CLI_COMMAND', $command ); + + $command = \WP_CLI::load_command( $command ); + + $command->invoke( $arguments, $assoc_args ); + } + + function get_subcommands() { + return \WP_CLI::load_all_commands(); + } +} + + class CompositeCommand implements Command { function __construct( $name, $class ) { From ca0a81d7dd83d966196e6dd03751c5aa79a8f45b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 05:04:02 +0300 Subject: [PATCH 0680/4858] show general help when calling wp help --- src/php/wp-cli/dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index fe70e3a159..951b311d82 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -35,7 +35,7 @@ function show_usage() { } function invoke( $arguments, $assoc_args ) { - if ( empty( $arguments ) ) { + if ( empty( $arguments ) || array( 'help' ) == $arguments ) { $this->show_usage(); exit; } From 62567491cd89bb5915c9b9189eb6aa01c5789f27 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 05:09:51 +0300 Subject: [PATCH 0681/4858] add --ids flag to wp post list synopsis --- src/php/wp-cli/commands/internals/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 1714b3ffdf..22335357c6 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -70,7 +70,7 @@ public function delete( $post_ids, $assoc_args ) { * Get a list of posts. * * @subcommand list - * @synopsis [--<field>=<value>] + * @synopsis [--<field>=<value>] [--ids] */ public function _list( $_, $assoc_args ) { $query_args = array( From ff5d4b537e51b3de32686b563c9f46ba0087c45f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 05:41:59 +0300 Subject: [PATCH 0682/4858] clean up comment.php and add synopsis tags. see #158 --- man/comment-last.1 | 12 +- src/docs/comment-last.txt | 10 +- src/php/wp-cli/commands/internals/comment.php | 231 +++++++----------- 3 files changed, 95 insertions(+), 158 deletions(-) diff --git a/man/comment-last.1 b/man/comment-last.1 index ee29cdc9ff..f1c4809d25 100644 --- a/man/comment-last.1 +++ b/man/comment-last.1 @@ -1,33 +1,33 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-LAST" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-LAST" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-last\fR \- Retrieve last approved comment . .SH "SYNOPSIS" -\fBwp comment last\fR [\-\-porcelain] [\-\-full|verbose] +\fBwp comment last\fR [\-\-id] [\-\-full] . .SH "OPTIONS" . .TP -\fB\-\-porcelain\fR: +\fB\-\-id\fR: . .IP Output just the last comment id\. . .TP -\fB\-\-full\fR or \fB\-\-verbose\fR: +\fB\-\-full\fR: . .IP -Output complete comment information +Output complete comment information\. . .SH "EXAMPLES" . .nf -wp comment last +wp comment last \-\-full . .fi diff --git a/src/docs/comment-last.txt b/src/docs/comment-last.txt index dec1e1308b..358fcd79a0 100644 --- a/src/docs/comment-last.txt +++ b/src/docs/comment-last.txt @@ -3,18 +3,18 @@ wp-comment-last(1) -- Retrieve last approved comment ## SYNOPSIS -`wp comment last` [--porcelain] [--full|verbose] +`wp comment last` [--id] [--full] ## OPTIONS -* `--porcelain`: +* `--id`: Output just the last comment id. -* `--full` or `--verbose`: +* `--full`: - Output complete comment information + Output complete comment information. ## EXAMPLES - wp comment last + wp comment last --full diff --git a/src/php/wp-cli/commands/internals/comment.php b/src/php/wp-cli/commands/internals/comment.php index b6b4abc93c..77d2fecb85 100644 --- a/src/php/wp-cli/commands/internals/comment.php +++ b/src/php/wp-cli/commands/internals/comment.php @@ -1,258 +1,195 @@ <?php + +WP_CLI::add_command( 'comment', 'Comment_Command' ); + /** * Implement 'comment' command * * @package wp-cli * @subpackage commands/internals */ - -// Register the 'comment' command handler -WP_CLI::add_command( 'comment', 'Comment_Command' ); - class Comment_Command extends WP_CLI_Command { /** * Insert a comment. * - * Example: wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" - * - * @param array $args} - * @param array $assoc_args + * @synopsis --<field>=<value> [--porcelain] */ public function create( $args, $assoc_args ) { - // Just one check: make sure the post actually exists - $comment_post_ID = WP_CLI::get_numeric_arg( $args, 0, "Post ID" ); - $post = get_post( $comment_post_ID ); - if ( empty( $post->comment_status ) ) { + $post = get_post( $assoc_args['comment_post_ID'] ); + if ( !$post ) { WP_CLI::error( "Cannot find post $comment_post_ID" ); } - + // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and avoid wp_die() formatted messages or notifications $comment_id = wp_insert_comment( $assoc_args ); - if ( 0 == $comment_id ) { + if ( !$comment_id ) { WP_CLI::error( "Could not create comment" ); } - + if ( isset( $assoc_args['porcelain'] ) ) WP_CLI::line( $comment_id ); else WP_CLI::success( "Inserted comment $comment_id." ); } - /** - * Delete a comment - * - * Example: wp comment delete 15 --force + * Delete a comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> [--force] */ public function delete( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); + list( $comment_id ) = $args; - // Boolean $force parameter to bypass trash and really delete - $force = ( isset( $assoc_args['force'] ) ? true : false ); - - if ( wp_delete_comment( $comment_id, $force ) ) { + if ( wp_delete_comment( $comment_id, isset( $assoc_args['force'] ) ) ) { WP_CLI::success( "Deleted comment $comment_id." ); } else { WP_CLI::error( "Failed deleting comment $comment_id" ); } } - + private function call( $args, $status, $success, $failure ) { + list( $comment_id ) = $args; + + $func = sprintf( 'wp_%s_comment', $status ); + + if ( $func( $comment_id ) ) { + WP_CLI::success( "$success comment $comment_id." ); + } else { + WP_CLI::error( "$failure comment $comment_id" ); + } + } + + private function set_status( $args, $status, $success ) { + list( $comment_id ) = $args; + + $r = wp_set_comment_status( $comment_id, 'approve', true ); + + if ( is_wp_error( $r ) ) { + WP_CLI::error( $r ); + } else { + WP_CLI::success( "$success comment $comment_id" ); + } + } + /** - * Trash a comment + * Trash a comment. * - * Example: wp comment trash 15 - * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function trash( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - - if ( wp_trash_comment( $comment_id ) ) { - WP_CLI::success( "Trashed comment $comment_id." ); - } else { - WP_CLI::error( "Failed trashing comment $comment_id" ); - } + $this->call( $args, __FUNCTION__, 'Trashed', 'Failed trashing' ); } - /** - * Untrash a comment - * - * Example: wp comment untrash 15 + * Untrash a comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function untrash( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - - if ( wp_untrash_comment( $comment_id ) ) { - WP_CLI::success( "Untrashed comment $comment_id." ); - } else { - WP_CLI::error( "Failed untrashing comment $comment_id" ); - } + $this->call( $args, __FUNCTION__, 'Untrashed', 'Failed untrashing' ); } - /** - * Spam a comment - * - * Example: wp comment spam 15 + * Spam a comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function spam( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - - if ( wp_spam_comment( $comment_id ) ) { - WP_CLI::success( "Spammed comment $comment_id." ); - } else { - WP_CLI::error( "Failed spamming comment $comment_id" ); - } + $this->call( $args, __FUNCTION__, 'Marked as spam', 'Failed marking as spam' ); } - /** - * Unspam a comment - * - * Example: wp comment unspam 15 + * Unspam a comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function unspam( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - - if ( wp_unspam_comment( $comment_id ) ) { - WP_CLI::success( "Unspammed comment $comment_id." ); - } else { - WP_CLI::error( "Failed unspamming comment $comment_id" ); - } + $this->call( $args, __FUNCTION__, 'Unspammed', 'Failed unspamming' ); } - /** - * Approve a comment - * - * Example: wp comment approve 15 + * Approve a comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function approve( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - - $comment = wp_set_comment_status( $comment_id, 'approve', true ); // last parameter 'true' to return a WP_Error object if there is a failure - - if ( is_wp_error( $comment ) ) { - WP_CLI::error( $comment ); - } else { - WP_CLI::success( "Approved comment $comment_id" ); - } + $this->set_status( $args, 'approve', "Approved" ); } - /** * Unapprove a comment * - * Example: wp comment unapprove 15 - * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function unapprove( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - - $comment = wp_set_comment_status( $comment_id, 'hold', true ); - - if ( is_wp_error( $comment ) ) { - WP_CLI::error( $comment ); - } else { - WP_CLI::success( "Unapproved comment $comment_id" ); - } + $this->set_status( $args, 'hold', "Unapproved" ); } - /** - * Count comments, in whole blog or in a given post + * Count comments, on whole blog or on a given post. * - * Example: "wp comment count 43" to count comments on post 43 - * Example: "wp comment count" to count comments on blog - * - * @param array $args} - * @param array $assoc_args + * @synopsis [<post-id>] */ public function count( $args, $assoc_args ) { - $post_id = ( isset( $args[0] ) && is_numeric( $args[0] ) ? $args[0] : 0 ); - - $comments = wp_count_comments( $post_id ); + $post_id = isset( $args[0] ) ? $args[0] : 0; + + $count = wp_count_comments( $post_id ); + // Move total_comments to the end of the object - $total = $comments->total_comments; - unset( $comments->total_comments ); - $comments->total_comments = $total; + $total = $count->total_comments; + unset( $count->total_comments ); + $count->total_comments = $total; - foreach( $comments as $status => $count ) { + foreach ( $count as $status => $count ) { WP_CLI::line( str_pad( "$status:", 17 ) . $count ); } } - /** - * Get status of a comment - * - * Example: wp comment status 15 + * Get status of a comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis <id> */ public function status( $args, $assoc_args ) { - $comment_id = WP_CLI::get_numeric_arg( $args, 0, "Comment ID" ); - + list( $comment_id ) = $args; + $status = wp_get_comment_status( $comment_id ); - - if( false === $status ) { - WP_CLI::error( "Could not check status of comment $comment" ); + + if ( false === $status ) { + WP_CLI::error( "Could not check status of comment $comment_id." ); } else { WP_CLI::line( $status ); } } - /** - * Get last approved comment. Options: --porcelain, --full|verbose + * Get last approved comment. * - * @param array $args} - * @param array $assoc_args + * @synopsis [--id] [--full] */ function last( $args = array(), $assoc_args = array() ) { $last = get_comments( array( 'number' => 1, 'status' => 'approve' ) ); - extract( get_object_vars( $last[0] ) ); - // populates: comment_ID, comment_post_ID, comment_author, ... See http://codex.wordpress.org/Function_Reference/get_comments#Returns - if ( isset( $assoc_args['porcelain'] ) ) { - WP_CLI::line( $comment_ID ); + list( $comment ) = $last; + + if ( isset( $assoc_args['id'] ) ) { + WP_CLI::line( $comment->comment_ID ); exit( 1 ); } - WP_CLI::line( "%yLast approved comment :%n" ); + WP_CLI::line( "%yLast approved comment:%n " ); - if( isset( $assoc_args['verbose'] ) OR isset( $assoc_args['full'] ) ) { - $keys = array_keys( get_object_vars( $last[0] ) ); + if ( isset( $assoc_args['full'] ) ) { + $keys = array_keys( get_object_vars( $comment ) ); } else { $keys = array( 'comment_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); } - foreach( $keys as $key ) { - WP_CLI::line( str_pad( "$key:", 23 ) . ${$key} ); + + foreach ( $keys as $key ) { + WP_CLI::line( str_pad( "$key:", 23 ) . $comment->$key ); } } - - } + From 16df306fe7d3b83495a43954548c709d3b4ff6fb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 05:50:22 +0300 Subject: [PATCH 0683/4858] fix synopsis for wp core install-network --- man/core-install-network.1 | 6 +++--- src/docs/core-install-network.txt | 5 +++-- src/php/wp-cli/commands/internals/core.php | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/man/core-install-network.1 b/man/core-install-network.1 index d849532c33..d2bfef7106 100644 --- a/man/core-install-network.1 +++ b/man/core-install-network.1 @@ -7,7 +7,7 @@ \fBwp\-core\-install\-network\fR \- Transform a single\-site install into a . .SH "SYNOPSIS" -\fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=/] +\fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=\fIurl\-path\fR] . .SH "OPTIONS" . @@ -18,8 +18,8 @@ The title of the new network\. . .TP -\fB\-\-base_path\fR=\fIpath\fR: +\fB\-\-base_path\fR=\fIurl\-path\fR: . .IP -Base path after the domain name that each site url will start with\. +Base path after the domain name that each site url will start with\. Default: \'/\' diff --git a/src/docs/core-install-network.txt b/src/docs/core-install-network.txt index 30c37441d6..74fe22d988 100644 --- a/src/docs/core-install-network.txt +++ b/src/docs/core-install-network.txt @@ -4,7 +4,7 @@ multi-site install. ## SYNOPSIS -`wp core install-network` --title=<network-title> [--base_path=/] +`wp core install-network` --title=<network-title> [--base_path=<url-path>] ## OPTIONS @@ -12,6 +12,7 @@ multi-site install. The title of the new network. -* `--base_path`=<path>: +* `--base_path`=<url-path>: Base path after the domain name that each site url will start with. +Default: '/' diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index a652f3219b..98a0db8fca 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -96,7 +96,7 @@ public function install( $args, $assoc_args ) { * Transform a single-site install into a multi-site install. * * @subcommand install-network - * @synopsis --title=<network-title> [--base_path=/] + * @synopsis --title=<network-title> [--base_path=<url-path>] */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) From e7486c77c7b0d6aabdb1573734bbfc93793273f5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 06:00:12 +0300 Subject: [PATCH 0684/4858] add confirm() helper method for db subcommands --- src/php/wp-cli/commands/internals/db.php | 29 +++++++++++------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index ddd9c16118..542c67ebaf 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -14,6 +14,17 @@ public static function get_default_subcommand() { return 'cli'; } + private static function confirm( $question, $assoc_args ) { + if ( !isset( $assoc_args['yes'] ) ) { + WP_CLI::out( $question . " [y/n] " ); + + $answer = trim( fgets( STDIN ) ); + + if ( 'y' != $answer ) + exit; + } + } + /** * Creates the database specified in the wp-config.php file. */ @@ -32,14 +43,7 @@ function create() { * @synopsis [--yes] */ function drop( $args, $assoc_args ) { - if ( !isset( $assoc_args['yes'] ) ) { - WP_CLI::out( "Are you sure you want to drop the database? [y/n] " ); - - $answer = trim( fgets( STDIN ) ); - - if ( 'y' != $answer ) - return; - } + self::confirm( "Are you sure you want to drop the database?", $assoc_args ); WP_CLI::launch( self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', @@ -55,14 +59,7 @@ function drop( $args, $assoc_args ) { * @synopsis [--yes] */ function reset( $args, $assoc_args ) { - if ( !isset( $assoc_args['yes'] ) ) { - WP_CLI::out( "Are you sure you want to reset the database? [y/n] " ); - - $answer = trim( fgets( STDIN ) ); - - if ( 'y' != $answer ) - return; - } + self::confirm( "Are you sure you want to reset the database?", $assoc_args ); WP_CLI::launch( self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', From e354c59b7cb2a322871b15d488e445c23715631d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 18:32:32 +0300 Subject: [PATCH 0685/4858] update php-cli-tools --- src/php/php-cli-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/php-cli-tools b/src/php/php-cli-tools index 7924a9dccc..c23ffe979c 160000 --- a/src/php/php-cli-tools +++ b/src/php/php-cli-tools @@ -1 +1 @@ -Subproject commit 7924a9dccc8dcd84bfeb7f9767104958caac3242 +Subproject commit c23ffe979c7956614fd8721c2e28e61a3cb6bad3 From 8bfdc91ddf2743f0e40d561e28a5c2241c1cd80e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 18:33:16 +0300 Subject: [PATCH 0686/4858] remove unused get_numeric_arg() --- src/php/wp-cli/class-wp-cli.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index a76093cf5d..f5e8c18dd3 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -148,18 +148,6 @@ static function compose_args( $args, $assoc_args = array() ) { return $str; } - static function get_numeric_arg( $args, $index, $name ) { - if ( ! isset( $args[$index] ) ) { - WP_CLI::error( "$name required" ); - } - - if ( ! is_numeric( $args[$index] ) ) { - WP_CLI::error( "$name must be numeric" ); - } - - return $args[$index]; - } - /** * Launch an external process, closing the current one * From 2d4c8b0f1f09f37158a9786022cd7739267cd21f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Oct 2012 19:02:37 +0300 Subject: [PATCH 0687/4858] introduce get_path() method to use in show_usage() --- src/php/wp-cli/dispatcher.php | 43 +++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 951b311d82..4700bdcc6f 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -4,19 +4,28 @@ interface Command { + function get_path(); + function get_subcommands(); + function show_usage(); function invoke( $arguments, $assoc_args ); - function get_subcommands(); } class RootCommand implements Command { + function get_path() { + return array(); + } + function show_usage() { \WP_CLI::line( 'Available commands:' ); - foreach ( \WP_CLI::load_all_commands() as $name => $command ) { - $subcommands = $command->get_subcommands(); - \WP_CLI::line( " wp $name " . implode( '|', array_keys( $subcommands ) ) ); + + foreach ( \WP_CLI::load_all_commands() as $command ) { + \WP_CLI::line( sprintf( " wp %s %s", + implode( ' ', $command->get_path() ), + implode( '|', array_keys( $command->get_subcommands() ) ) + ) ); } \WP_CLI::line(<<<EOB @@ -69,6 +78,10 @@ function __construct( $name, $class ) { $this->class = $class; } + function get_path() { + return array( $this->name ); + } + function show_usage() { $methods = $this->get_subcommands(); @@ -161,6 +174,13 @@ function __construct( $method ) { $this->method = $method; } + function show_usage( $prefix = 'usage: ' ) { + $full_name = implode( ' ', $this->get_path() ); + $synopsis = $this->get_synopsis(); + + \WP_CLI::line( $prefix . "wp $full_name $synopsis" ); + } + function get_subcommands() { return array(); } @@ -314,12 +334,8 @@ function __construct( $method, $parent ) { parent::__construct( $method ); } - function show_usage( $prefix = 'usage: ' ) { - $command = $this->parent->name; - $subcommand = $this->get_name(); - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $command $subcommand $synopsis" ); + function get_path() { + return array( $this->parent->name, $this->get_name() ); } private function get_tag( $name ) { @@ -368,11 +384,8 @@ function get_name() { return $this->name; } - function show_usage( $prefix = 'usage: ' ) { - $command = $this->get_name(); - $synopsis = $this->get_synopsis(); - - \WP_CLI::line( $prefix . "wp $command $synopsis" ); + function get_path() { + return array( $this->name ); } function invoke( $args, $assoc_args ) { From c8fd44b78f28c87196315b155083c7a0d969469d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Oct 2012 02:33:26 +0300 Subject: [PATCH 0688/4858] fix update-all and add --dry-run option closes #188. related #180. --- .../class-wp-cli-command-with-upgrade.php | 48 +++++++++---------- src/php/wp-cli/commands/internals/plugin.php | 1 + src/php/wp-cli/commands/internals/theme.php | 1 + 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 8357991a6c..a8a9d96453 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -135,38 +135,36 @@ function update_all( $args, $assoc_args ) { 'update' => true ) ); - if ( empty( $items_to_update ) ) { - WP_CLI::line( "No {$this->item_type} updates available." ); + if ( isset( $assoc_args['dry-run'] ) ) { + $item_list = "Available {$this->item_type} updates:"; + + if ( empty( $items_to_update ) ) { + $item_list .= " none"; + } else { + foreach ( $items_to_update as $file => $details ) { + $item_list .= "\n\t%y" . $details['name'] . "%n"; + } + } + + WP_CLI::line( $item_list ); return; } - // If --all, UPDATE ALL THE THINGS - if ( isset( $assoc_args['all'] ) ) { - $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); - $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); + $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); + $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); - // Let the user know the results. - $num_to_update = count( $items_to_update ); - $num_updated = count( array_filter( $result ) ); + // Let the user know the results. + $num_to_update = count( $items_to_update ); + $num_updated = count( array_filter( $result ) ); - $line = "Updated $num_updated/$num_to_update {$this->item_type}s."; - if ( $num_to_update == $num_updated ) { - WP_CLI::success( $line ); - } else if ( $num_updated > 0 ) { - WP_CLI::warning( $line ); - } else { - WP_CLI::error( $line ); - } + $line = "Updated $num_updated/$num_to_update {$this->item_type}s."; - // Else list items that require updates + if ( $num_to_update == $num_updated ) { + WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + WP_CLI::warning( $line ); } else { - $item_list = "Available {$this->item_type} updates:"; - - foreach ( $items_to_update as $file => $details ) { - $item_list .= "\n\t%y" . $details['name'] . "%n"; - } - - WP_CLI::line( $item_list ); + WP_CLI::error( $line ); } } diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 2a57a486ff..4fd4a1672d 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -199,6 +199,7 @@ function update( $args, $assoc_args ) { * Update all plugins. * * @subcommand update-all + * @synopsis [--dry-run] */ function update_all( $args, $assoc_args ) { parent::update_all( $args, $assoc_args ); diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index cceefb8444..278b0ad40e 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -173,6 +173,7 @@ function update( $args, $assoc_args ) { * Update all themes. * * @subcommand update-all + * @synopsis [--dry-run] */ function update_all( $args, $assoc_args ) { parent::update_all( $args, $assoc_args ); From 85fa00c75bad696f2926f8a1e8f23b376e92b4cf Mon Sep 17 00:00:00 2001 From: Ben Doherty <ben@thinkoomph.com> Date: Tue, 16 Oct 2012 20:05:24 -0400 Subject: [PATCH 0689/4858] Checks for existence of wp_get_themes to use instead of deprecated (as of 3.4) get_themes function --- src/php/wp-cli/commands/internals/theme.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 278b0ad40e..8b16e41436 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -137,7 +137,12 @@ protected function install_from_repo( $slug, $assoc_args ) { protected function get_item_list() { $items = array(); - foreach ( get_themes() as $title => $details ) { + if( function_exists( 'wp_get_themes' ) ) + $themes = wp_get_themes(); + else + $themes = get_themes(); + + foreach ( $themes as $title => $details ) { $file = $this->get_stylesheet_path( $details['Stylesheet'] ); $items[ $file ] = array( From 13d588405f493d5142103f1bd0532185b4b7ee7e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 18 Oct 2012 02:15:46 +0300 Subject: [PATCH 0690/4858] get_themes() indexes themes differently than wp_get_themes(). see #189 --- src/php/wp-cli/commands/internals/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 8b16e41436..a10dadb992 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -142,7 +142,7 @@ protected function get_item_list() { else $themes = get_themes(); - foreach ( $themes as $title => $details ) { + foreach ( $themes as $details ) { $file = $this->get_stylesheet_path( $details['Stylesheet'] ); $items[ $file ] = array( From 78981e2279f477a28d6dfb7112d9fbbd7586f1fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 21 Oct 2012 00:36:03 +0300 Subject: [PATCH 0691/4858] first pass at blog delete command --- src/php/wp-cli/commands/internals/blog.php | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index a9ebc6e626..53402cc0d6 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -123,4 +123,33 @@ public function create( $args, $assoc_args ) { } WP_CLI::success( "Blog $id created: $url" ); } + + /** + * Delete a blog in a multisite install. + * + * @synopsis --slug=<slug> + */ + function delete( $_, $assoc_args ) { + $slug = $assoc_args['slug']; + + $slug = '/' . trim( $slug, '/' ) . '/'; + + $blog_id = self::get_blog_id_by_slug( $slug ); + + if ( !$blog_id ) + WP_CLI::error( sprintf( "'%s' blog not found.", $slug ) ); + + wpmu_delete_blog( $blog_id, true ); + + WP_CLI::success( "Blog '%s' deleted." ); + } + + protected static function get_blog_id_by_slug( $slug ) { + global $wpdb, $current_site; + + return $wpdb->get_var( $wpdb->prepare( " + SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s" + , $current_site->domain, $slug ) ); + } } + From b7df777b597cb1ec5516ef0bb8743bd038376a24 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 21 Oct 2012 00:40:49 +0300 Subject: [PATCH 0692/4858] add confirmation --- src/php/wp-cli/class-wp-cli.php | 14 ++++++++++++++ src/php/wp-cli/commands/internals/blog.php | 8 ++++---- src/php/wp-cli/commands/internals/db.php | 15 ++------------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index f5e8c18dd3..d533ffbe8b 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -80,6 +80,20 @@ static function warning( $message, $label = 'Warning' ) { \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } + /** + * Ask for confirmation before running a destructive operation. + */ + static function confirm( $question, $assoc_args ) { + if ( !isset( $assoc_args['yes'] ) ) { + WP_CLI::out( $question . " [y/n] " ); + + $answer = trim( fgets( STDIN ) ); + + if ( 'y' != $answer ) + exit; + } + } + /** * Read a value, from various formats * diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 53402cc0d6..e593960cca 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -127,18 +127,18 @@ public function create( $args, $assoc_args ) { /** * Delete a blog in a multisite install. * - * @synopsis --slug=<slug> + * @synopsis --slug=<slug> [--yes] */ function delete( $_, $assoc_args ) { - $slug = $assoc_args['slug']; - - $slug = '/' . trim( $slug, '/' ) . '/'; + $slug = '/' . trim( $assoc_args['slug'], '/' ) . '/'; $blog_id = self::get_blog_id_by_slug( $slug ); if ( !$blog_id ) WP_CLI::error( sprintf( "'%s' blog not found.", $slug ) ); + WP_CLI::confirm( "Are you sure you want to delete the '$slug' blog?", $assoc_args ); + wpmu_delete_blog( $blog_id, true ); WP_CLI::success( "Blog '%s' deleted." ); diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 542c67ebaf..ed9c8b2c1f 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -14,17 +14,6 @@ public static function get_default_subcommand() { return 'cli'; } - private static function confirm( $question, $assoc_args ) { - if ( !isset( $assoc_args['yes'] ) ) { - WP_CLI::out( $question . " [y/n] " ); - - $answer = trim( fgets( STDIN ) ); - - if ( 'y' != $answer ) - exit; - } - } - /** * Creates the database specified in the wp-config.php file. */ @@ -43,7 +32,7 @@ function create() { * @synopsis [--yes] */ function drop( $args, $assoc_args ) { - self::confirm( "Are you sure you want to drop the database?", $assoc_args ); + WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); WP_CLI::launch( self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', @@ -59,7 +48,7 @@ function drop( $args, $assoc_args ) { * @synopsis [--yes] */ function reset( $args, $assoc_args ) { - self::confirm( "Are you sure you want to reset the database?", $assoc_args ); + WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); WP_CLI::launch( self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', From 7391296386645c0bebfc66278f21fe745e959d85 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 21 Oct 2012 00:42:50 +0300 Subject: [PATCH 0693/4858] add keep-tables flag --- src/php/wp-cli/commands/internals/blog.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index e593960cca..cc2649caa6 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -127,7 +127,7 @@ public function create( $args, $assoc_args ) { /** * Delete a blog in a multisite install. * - * @synopsis --slug=<slug> [--yes] + * @synopsis --slug=<slug> [--yes] [--keep-tables] */ function delete( $_, $assoc_args ) { $slug = '/' . trim( $assoc_args['slug'], '/' ) . '/'; @@ -139,7 +139,7 @@ function delete( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to delete the '$slug' blog?", $assoc_args ); - wpmu_delete_blog( $blog_id, true ); + wpmu_delete_blog( $blog_id, !isset( $assoc_args['keep-tables'] ) ); WP_CLI::success( "Blog '%s' deleted." ); } From d2f31888c0d3ad134c716d004e3a33c5dbad852c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 21 Oct 2012 00:53:05 +0300 Subject: [PATCH 0694/4858] add man page --- man/blog-create.1 | 4 ++-- man/blog-delete.1 | 30 ++++++++++++++++++++++++++++++ src/docs/blog-create.txt | 2 +- src/docs/blog-delete.txt | 21 +++++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 man/blog-delete.1 create mode 100644 src/docs/blog-delete.txt diff --git a/man/blog-create.1 b/man/blog-create.1 index 338aff284d..574670f93a 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-CREATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-BLOG\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-blog\-create\fR \- Create a new blog in a multisite install\. @@ -15,7 +15,7 @@ \fB\-\-slug\fR=\fIslug\fR: . .IP -Base for the new domain\. Subdomain on subdomain installs, directory on subdirectory installs\. +Path for the new blog\. Subdomain on subdomain installs, directory on subdirectory installs\. . .TP \fB\-\-title\fR=<title>: diff --git a/man/blog-delete.1 b/man/blog-delete.1 new file mode 100644 index 0000000000..b8f45e50be --- /dev/null +++ b/man/blog-delete.1 @@ -0,0 +1,30 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +wp\-blog\-delete(1) \-\- Delete a blog in a multisite install\. +. +.P +==== +. +.SH "SYNOPSIS" +\fBwp blog delete\fR \-\-slug=\fIslug\fR [\-\-yes] [\-\-keep\-tables] +. +.SH "OPTIONS" +. +.TP +\fB\-\-slug\fR=\fIslug\fR: +. +.IP +Path of the blog to be deleted\. Subdomain on subdomain installs, directory on subdirectory installs\. +. +.TP +\fB\-\-yes\fR: +. +.IP +Answer yes to the confirmation message\. +. +.TP +\fB\-\-keep\-tables\fR: +. +.IP +Delete the blog from the list, but don\'t drop it\'s tables\. + diff --git a/src/docs/blog-create.txt b/src/docs/blog-create.txt index 991e19caf9..cfe7b2b390 100644 --- a/src/docs/blog-create.txt +++ b/src/docs/blog-create.txt @@ -9,7 +9,7 @@ wp-blog-create(1) -- Create a new blog in a multisite install. * `--slug`=<slug>: - Base for the new domain. Subdomain on subdomain installs, directory on subdirectory installs. + Path for the new blog. Subdomain on subdomain installs, directory on subdirectory installs. * `--title`=<title>: diff --git a/src/docs/blog-delete.txt b/src/docs/blog-delete.txt new file mode 100644 index 0000000000..18b3ac87b7 --- /dev/null +++ b/src/docs/blog-delete.txt @@ -0,0 +1,21 @@ +wp-blog-delete(1) -- Delete a blog in a multisite install. + +==== + +## SYNOPSIS + +`wp blog delete` --slug=<slug> [--yes] [--keep-tables] + +## OPTIONS + +* `--slug`=<slug>: + + Path of the blog to be deleted. Subdomain on subdomain installs, directory on subdirectory installs. + +* `--yes`: + + Answer yes to the confirmation message. + +* `--keep-tables`: + + Delete the blog from the list, but don't drop it's tables. From 6ebb2ab378d86d5369bb2ea6857406922279d4e5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 21 Oct 2012 01:02:44 +0300 Subject: [PATCH 0695/4858] fix message. see #191 --- src/php/wp-cli/commands/internals/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index cc2649caa6..4c027ef2f5 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -141,7 +141,7 @@ function delete( $_, $assoc_args ) { wpmu_delete_blog( $blog_id, !isset( $assoc_args['keep-tables'] ) ); - WP_CLI::success( "Blog '%s' deleted." ); + WP_CLI::success( "Blog '$slug' deleted." ); } protected static function get_blog_id_by_slug( $slug ) { From 966e6036df645b4565172610ca082d1ddfcc899c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Oct 2012 22:55:01 +0300 Subject: [PATCH 0696/4858] remove unnecessary WP_CLI_COMMAND constant --- src/php/wp-cli/dispatcher.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 4700bdcc6f..dbbd4e654d 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -58,8 +58,6 @@ function invoke( $arguments, $assoc_args ) { if ( isset( $aliases[ $command ] ) ) $command = $aliases[ $command ]; - define( 'WP_CLI_COMMAND', $command ); - $command = \WP_CLI::load_command( $command ); $command->invoke( $arguments, $assoc_args ); From 71ee445126991177d0fc3b01067468512d425926 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Oct 2012 22:22:10 +0300 Subject: [PATCH 0697/4858] add get_synopsis() method to Command interface --- src/php/wp-cli/dispatcher.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index dbbd4e654d..80d8e947cd 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -6,6 +6,7 @@ interface Command { function get_path(); function get_subcommands(); + function get_synopsis(); function show_usage(); function invoke( $arguments, $assoc_args ); @@ -18,6 +19,10 @@ function get_path() { return array(); } + function get_synopsis() { + return ''; + } + function show_usage() { \WP_CLI::line( 'Available commands:' ); @@ -80,6 +85,10 @@ function get_path() { return array( $this->name ); } + function get_synopsis() { + return ''; + } + function show_usage() { $methods = $this->get_subcommands(); @@ -258,7 +267,7 @@ private function check_unknown_assoc( $assoc_args, $accepted_params ) { } } - protected function get_synopsis() { + public function get_synopsis() { $comment = $this->method->getDocComment(); if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) From 944f805969ff04e9063ce31905ca9be913948681 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Oct 2012 22:30:01 +0300 Subject: [PATCH 0698/4858] add get_shortdesc() method --- src/php/wp-cli/dispatcher.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 80d8e947cd..ad3bb56413 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -6,6 +6,8 @@ interface Command { function get_path(); function get_subcommands(); + + function get_shortdesc(); function get_synopsis(); function show_usage(); @@ -19,6 +21,10 @@ function get_path() { return array(); } + function get_shortdesc() { + return ''; + } + function get_synopsis() { return ''; } @@ -85,6 +91,10 @@ function get_path() { return array( $this->name ); } + function get_shortdesc() { + return ''; + } + function get_synopsis() { return ''; } @@ -267,6 +277,15 @@ private function check_unknown_assoc( $assoc_args, $accepted_params ) { } } + function get_shortdesc() { + $comment = $this->method->getDocComment(); + + if ( !preg_match( '/\* ([^@\.]+\.)\s*/', $comment, $matches ) ) + return false; + + return $matches[1]; + } + public function get_synopsis() { $comment = $this->method->getDocComment(); From 6b74860e2df23415092b9fb575713fbda600373a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Oct 2012 22:46:57 +0300 Subject: [PATCH 0699/4858] create separate Documentable interface --- src/php/wp-cli/dispatcher.php | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index ad3bb56413..f41c48a4b0 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -7,28 +7,24 @@ interface Command { function get_path(); function get_subcommands(); - function get_shortdesc(); - function get_synopsis(); - function show_usage(); function invoke( $arguments, $assoc_args ); } +interface Documentable { + + function get_shortdesc(); + function get_synopsis(); +} + + class RootCommand implements Command { function get_path() { return array(); } - function get_shortdesc() { - return ''; - } - - function get_synopsis() { - return ''; - } - function show_usage() { \WP_CLI::line( 'Available commands:' ); @@ -91,14 +87,6 @@ function get_path() { return array( $this->name ); } - function get_shortdesc() { - return ''; - } - - function get_synopsis() { - return ''; - } - function show_usage() { $methods = $this->get_subcommands(); @@ -185,7 +173,7 @@ private static function _is_good_method( $method ) { } -abstract class Subcommand implements Command { +abstract class Subcommand implements Command, Documentable { function __construct( $method ) { $this->method = $method; From 763a1c6b448ae0ac52d982e663232fff10045a47 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Oct 2012 23:43:39 +0300 Subject: [PATCH 0700/4858] introduce Composite interface and traverse() function --- src/php/wp-cli/class-wp-cli.php | 3 +- src/php/wp-cli/commands/internals/help.php | 13 +++---- src/php/wp-cli/dispatcher.php | 41 ++++++++++++++++++---- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index d533ffbe8b..74be4e9737 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -207,8 +207,7 @@ static function load_command( $command ) { } if ( !isset( self::$commands[$command] ) ) { - self::error( "'$command' is not a registered wp command. See 'wp help'." ); - exit; + return false; } return self::$commands[$command]; diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 5231a0dd22..410c1cf621 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -13,7 +13,13 @@ class Help_Command extends WP_CLI_Command { function __invoke( $args ) { self::maybe_load_man_page( $args ); - self::show_available_subcommands( $args[0] ); + $command = \WP_CLI\Dispatcher\traverse( $args ); + + if ( !$command ) { + \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); + } + + $command->show_usage(); } private static function maybe_load_man_page( $args ) { @@ -29,10 +35,5 @@ private static function maybe_load_man_page( $args ) { } } } - - private static function show_available_subcommands( $command ) { - $command = WP_CLI::load_command( $command ); - $command->show_usage(); - } } diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index f41c48a4b0..9a12b6807c 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -2,6 +2,22 @@ namespace WP_CLI\Dispatcher; +function traverse( &$args ) { + $args_copy = $args; + + $command = new RootCommand; + + while ( !empty( $args ) && $command && $command instanceof Composite ) { + $command = $command->find_subcommand( $args ); + } + + if ( !$command ) + $args = $args_copy; + + return $command; +} + + interface Command { function get_path(); @@ -12,6 +28,12 @@ function invoke( $arguments, $assoc_args ); } +interface Composite { + + function find_subcommand( &$arguments ); +} + + interface Documentable { function get_shortdesc(); @@ -19,7 +41,7 @@ function get_synopsis(); } -class RootCommand implements Command { +class RootCommand implements Command, Composite { function get_path() { return array(); @@ -56,6 +78,15 @@ function invoke( $arguments, $assoc_args ) { exit; } + $command = $this->find_subcommand( $arguments ); + + if ( !$command ) + \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $arguments[0] ) ); + + $command->invoke( $arguments, $assoc_args ); + } + + function find_subcommand( &$arguments ) { $command = array_shift( $arguments ); $aliases = array( @@ -65,9 +96,7 @@ function invoke( $arguments, $assoc_args ) { if ( isset( $aliases[ $command ] ) ) $command = $aliases[ $command ]; - $command = \WP_CLI::load_command( $command ); - - $command->invoke( $arguments, $assoc_args ); + return \WP_CLI::load_command( $command ); } function get_subcommands() { @@ -76,7 +105,7 @@ function get_subcommands() { } -class CompositeCommand implements Command { +class CompositeCommand implements Command, Composite { function __construct( $name, $class ) { $this->name = $name; @@ -113,7 +142,7 @@ function invoke( $args, $assoc_args ) { $subcommand->invoke( $args, $assoc_args ); } - private function find_subcommand( &$args ) { + function find_subcommand( &$args ) { $class = $this->class; if ( empty( $args ) ) { From c6e48a77017f566ee74213e9c489dbb69e4ed1ac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 00:44:13 +0300 Subject: [PATCH 0701/4858] add missing short descriptions --- src/php/wp-cli/commands/internals/comment.php | 2 +- src/php/wp-cli/commands/internals/help.php | 5 +++++ src/php/wp-cli/commands/internals/home.php | 3 +++ src/php/wp-cli/commands/internals/option.php | 6 +++--- src/php/wp-cli/commands/internals/user.php | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/comment.php b/src/php/wp-cli/commands/internals/comment.php index 77d2fecb85..0604b8e255 100644 --- a/src/php/wp-cli/commands/internals/comment.php +++ b/src/php/wp-cli/commands/internals/comment.php @@ -119,7 +119,7 @@ public function approve( $args, $assoc_args ) { } /** - * Unapprove a comment + * Unapprove a comment. * * @synopsis <id> */ diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 410c1cf621..3fc90c1d18 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -10,6 +10,11 @@ */ class Help_Command extends WP_CLI_Command { + /** + * Get help on a certain topic. + * + * @synopsis [<command>] + */ function __invoke( $args ) { self::maybe_load_man_page( $args ); diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/internals/home.php index f20bcf03eb..730ce8d2c2 100644 --- a/src/php/wp-cli/commands/internals/home.php +++ b/src/php/wp-cli/commands/internals/home.php @@ -10,6 +10,9 @@ */ class Home_Command extends WP_CLI_Command { + /** + * Opens the wp-cli homepage in your browser. + */ function __invoke() { // The url for the wp-cli repository $repository_url = 'https://github.com/wp-cli/wp-cli'; diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index 091677f0e4..cf0147f6f1 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -11,7 +11,7 @@ class Option_Command extends WP_CLI_Command { /** - * Get an option + * Get an option. * * @synopsis <key> [--json] */ @@ -42,7 +42,7 @@ public function add( $args, $assoc_args ) { } /** - * Update an option + * Update an option. * * @alias set * @synopsis <key> <value> [--json] @@ -61,7 +61,7 @@ public function update( $args, $assoc_args ) { } /** - * Delete an option + * Delete an option. * * @synopsis <key> */ diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index f9bd9c26cf..6864fd124f 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -146,7 +146,7 @@ public function update( $args, $assoc_args ) { } /** - * Generate users + * Generate users. * * @synopsis [--count=100] [--role=<role>] */ From 055b52384a5543b5b8ad372bc82eb8cc6e501b35 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 01:08:59 +0300 Subject: [PATCH 0702/4858] add special --doc flag --- src/php/wp-cli/class-wp-cli.php | 23 +++++++++++++++++++++-- src/php/wp-cli/utils.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 74be4e9737..99952ce839 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -222,7 +222,7 @@ static function before_wp_load() { self::$assoc_special = WP_CLI\Utils\split_assoc( self::$assoc_args, array( 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'completions' + 'quiet', 'completions', 'doc' ) ); define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); @@ -288,8 +288,14 @@ static function after_wp_load() { if ( isset( self::$assoc_special['require'] ) ) require self::$assoc_special['require']; + if ( isset( self::$assoc_special['doc'] ) ) { + self::render_doc(); + exit; + } + if ( isset( self::$assoc_special['completions'] ) ) { self::render_automcomplete(); + exit; } self::run_command(); @@ -301,12 +307,25 @@ private static function run_command() { $root->invoke( self::$arguments, self::$assoc_args ); } + private static function render_doc() { + foreach ( self::load_all_commands() as $command ) { + $subcommands = $command->get_subcommands(); + + if ( empty( $subcommands ) ) { + \WP_CLI\Utils\print_man_markdown( $command ); + } else { + foreach ( $subcommands as $subcommand ) { + \WP_CLI\Utils\print_man_markdown( $subcommand ); + } + } + } + } + private static function render_automcomplete() { foreach ( self::load_all_commands() as $name => $command ) { $subcommands = $command->get_subcommands(); self::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); } - exit; } // back-compat diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index 1e49fcb89e..b9a5d996b3 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -156,3 +156,31 @@ function get_upgrader( $class ) { return new $class( new \CLI_Upgrader_Skin ); } +function print_man_markdown( \WP_CLI\Dispatcher\Documentable $command ) { + $path = $command->get_path(); + $shortdesc = $command->get_shortdesc(); + $synopsis = $command->get_synopsis(); + + $name_m = implode( '-', $path ); + $name_s = implode( ' ', $path ); + + if ( !$shortdesc ) { + WP_CLI::warning( "No shortdesc for $name_s" ); + } + + echo <<<DOC +wp-$name_m(1) -- $shortdesc +==== + +## SYNOPSIS + +`wp $name_s` $synopsis + +DOC; + + $doc_path = WP_CLI_ROOT . "../../docs/$name_m.txt"; + + if ( file_exists( $doc_path ) ) + echo file_get_contents( $doc_path ); +} + From 838e35618aba02de7d1ca079e1dfb398bc3728b9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 02:48:03 +0300 Subject: [PATCH 0703/4858] pass doc markdown to ronn from PHP --- src/php/wp-cli/class-wp-cli.php | 27 ++++----- src/php/wp-cli/commands/internals/help.php | 12 +--- src/php/wp-cli/man.php | 69 ++++++++++++++++++++++ src/php/wp-cli/utils.php | 28 --------- src/php/wp-cli/wp-cli.php | 1 + utils/doc-build | 23 -------- 6 files changed, 85 insertions(+), 75 deletions(-) create mode 100644 src/php/wp-cli/man.php delete mode 100755 utils/doc-build diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 99952ce839..8b259bb449 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -1,5 +1,7 @@ <?php +use \WP_CLI\Dispatcher; + /** * Wrapper class for WP-CLI * @@ -222,7 +224,7 @@ static function before_wp_load() { self::$assoc_special = WP_CLI\Utils\split_assoc( self::$assoc_args, array( 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'completions', 'doc' + 'quiet', 'completions', 'man' ) ); define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); @@ -288,8 +290,8 @@ static function after_wp_load() { if ( isset( self::$assoc_special['require'] ) ) require self::$assoc_special['require']; - if ( isset( self::$assoc_special['doc'] ) ) { - self::render_doc(); + if ( isset( self::$assoc_special['man'] ) ) { + self::generate_man( self::$arguments ); exit; } @@ -302,28 +304,23 @@ static function after_wp_load() { } private static function run_command() { - $root = new \WP_CLI\Dispatcher\RootCommand; + $root = new Dispatcher\RootCommand; $root->invoke( self::$arguments, self::$assoc_args ); } - private static function render_doc() { - foreach ( self::load_all_commands() as $command ) { - $subcommands = $command->get_subcommands(); + private static function generate_man( $args ) { + $command = Dispatcher\traverse( $args ); + if ( !$command ) + WP_CLI::error( sprintf( "'%s' command not found." ) ); - if ( empty( $subcommands ) ) { - \WP_CLI\Utils\print_man_markdown( $command ); - } else { - foreach ( $subcommands as $subcommand ) { - \WP_CLI\Utils\print_man_markdown( $subcommand ); - } - } - } + \WP_CLI\Man\generate( $command ); } private static function render_automcomplete() { foreach ( self::load_all_commands() as $name => $command ) { $subcommands = $command->get_subcommands(); + self::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); } } diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 3fc90c1d18..16a3a2c4d7 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -28,16 +28,10 @@ function __invoke( $args ) { } private static function maybe_load_man_page( $args ) { - $man_dir = WP_CLI_ROOT . "../../../man/"; + $man_file = \WP_CLI\Man\get_path( $args ); - if ( !is_dir( $man_dir ) ) { - WP_CLI::warning( "man pages do not seem to be installed." ); - } else { - $man_file = $man_dir . implode( '-', $args ) . '.1'; - - if ( is_readable( $man_file ) ) { - exit( WP_CLI::launch( "man $man_file" ) ); - } + if ( is_readable( $man_file ) ) { + exit( WP_CLI::launch( "man $man_file" ) ); } } } diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php new file mode 100644 index 0000000000..546956bb1d --- /dev/null +++ b/src/php/wp-cli/man.php @@ -0,0 +1,69 @@ +<?php + +namespace WP_CLI\Man; + +use \WP_CLI\Dispatcher; + +function get_path( $args ) { + return WP_CLI_ROOT . "../../../man/" . implode( '-', $args ) . '.1'; +} + +function get_doc_path() { + return WP_CLI_ROOT . "../../docs/"; +} + +function generate( $command ) { + if ( $command instanceof Dispatcher\Composite ) { + foreach ( $command->get_subcommands() as $subcommand ) { + generate( $subcommand ); + } + return; + } + + $descriptorspec = array( + 0 => get_markdown( $command ), + 1 => array( 'file', get_path( $command->get_path() ), 'w' ), + 2 => STDERR + ); + + $r = proc_close( proc_open( "ronn --roff --manual='WP-CLI'", $descriptorspec, $pipes ) ); + + \WP_CLI::line( "generated man page for " . implode( '-', $command->get_path() ) ); +} + +// returns a file descriptor containing markdown that will be passed to ronn +function get_markdown( Dispatcher\Documentable $command ) { + $path = $command->get_path(); + $shortdesc = $command->get_shortdesc(); + $synopsis = $command->get_synopsis(); + + $name_m = implode( '-', $path ); + $name_s = implode( ' ', $path ); + + if ( !$shortdesc ) { + \WP_CLI::warning( "No shortdesc for $name_s" ); + } + + $temp = fopen( "php://temp", "rw" ); + + fwrite( $temp, <<<DOC +wp-$name_m(1) -- $shortdesc +==== + +## SYNOPSIS + +`wp $name_s` $synopsis + +DOC + ); + + $doc_path = get_doc_path() . "$name_m.txt"; + + if ( file_exists( $doc_path ) ) + fwrite( $temp, file_get_contents( $doc_path ) ); + + fseek( $temp, 0 ); + + return $temp; +} + diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index b9a5d996b3..1e49fcb89e 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -156,31 +156,3 @@ function get_upgrader( $class ) { return new $class( new \CLI_Upgrader_Skin ); } -function print_man_markdown( \WP_CLI\Dispatcher\Documentable $command ) { - $path = $command->get_path(); - $shortdesc = $command->get_shortdesc(); - $synopsis = $command->get_synopsis(); - - $name_m = implode( '-', $path ); - $name_s = implode( ' ', $path ); - - if ( !$shortdesc ) { - WP_CLI::warning( "No shortdesc for $name_s" ); - } - - echo <<<DOC -wp-$name_m(1) -- $shortdesc -==== - -## SYNOPSIS - -`wp $name_s` $synopsis - -DOC; - - $doc_path = WP_CLI_ROOT . "../../docs/$name_m.txt"; - - if ( file_exists( $doc_path ) ) - echo file_get_contents( $doc_path ); -} - diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 61e7a1af9c..295dadc4a8 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -13,6 +13,7 @@ include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; include WP_CLI_ROOT . 'class-wp-cli-command-with-upgrade.php'; +include WP_CLI_ROOT . 'man.php'; include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); diff --git a/utils/doc-build b/utils/doc-build deleted file mode 100755 index 8cb5c7c28c..0000000000 --- a/utils/doc-build +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# regenerates modified man pages -# -# run automatically before each commit: -# ln -s ../../utils/doc-build .git/hooks/pre-commit - -if [ $# -eq 0 ]; then - files=$(git diff --cached --name-only src/docs/) -else - files=$@ -fi - -if ! which ronn > /dev/null; then - echo "doc-build: ronn is not installed" - exit 1 -fi - -for file in $files; do - man_file=man/$(basename $file .txt).1 - cat $file | ronn --roff --manual="WP-CLI" > $man_file - git add $man_file -done From e17ad0f38c863948efc505807daeac342b0252ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 04:29:50 +0300 Subject: [PATCH 0704/4858] fix synopsis encoding bugs --- src/php/wp-cli/man.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index 546956bb1d..daee08c691 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -37,6 +37,8 @@ function get_markdown( Dispatcher\Documentable $command ) { $shortdesc = $command->get_shortdesc(); $synopsis = $command->get_synopsis(); + $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); + $name_m = implode( '-', $path ); $name_s = implode( ' ', $path ); From 1880307632f6c2fdb5cd3bb0a743a486ec55b2ec Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 04:54:37 +0300 Subject: [PATCH 0705/4858] fix some synopses --- src/php/wp-cli/commands/internals/core.php | 4 ++-- src/php/wp-cli/commands/internals/db.php | 21 +++++++++----------- src/php/wp-cli/commands/internals/plugin.php | 4 ++-- src/php/wp-cli/commands/internals/theme.php | 4 ++-- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 98a0db8fca..f16aa9f2f0 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -11,7 +11,7 @@ class Core_Command extends WP_CLI_Command { /** - * Download the core files from wordpress.org + * Download core WordPress files. * * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] */ @@ -63,7 +63,7 @@ public function config( $args, $assoc_args ) { } /** - * Run wp_install. Assumes that wp-config.php is already in place. + * Create the WordPress tables in the database. * * @synopsis --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index ed9c8b2c1f..12f6918a03 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -15,7 +15,7 @@ public static function get_default_subcommand() { } /** - * Creates the database specified in the wp-config.php file. + * Create the database. */ function create() { WP_CLI::launch( self::create_cmd( @@ -27,7 +27,7 @@ function create() { } /** - * Deletes the database specified in the wp-config.php file. + * Delete the database. * * @synopsis [--yes] */ @@ -43,7 +43,7 @@ function drop( $args, $assoc_args ) { } /** - * Removes all tables from the database. + * Remove all tables from the database. * * @synopsis [--yes] */ @@ -64,7 +64,7 @@ function reset( $args, $assoc_args ) { } /** - * Optimizes the database specified in the wp-config.php file. + * Optimize the database. */ function optimize() { WP_CLI::launch( self::create_cmd( @@ -76,7 +76,7 @@ function optimize() { } /** - * Repairs the database specified in the wp-config.php file. + * Repair the database. */ function repair() { WP_CLI::launch( self::create_cmd( @@ -95,14 +95,14 @@ function connect() { } /** - * Open a SQL command-line interface using WordPress's credentials. + * Open a mysql console using the WordPress credentials. */ function cli() { WP_CLI::launch( $this->connect_string() ); } /** - * Execute a query against the site database. + * Execute a query against the database. * * @synopsis <sql> */ @@ -115,7 +115,7 @@ function query( $args, $assoc_args ) { } /** - * Exports the WordPress DB as SQL using mysqldump. + * Exports the database using mysqldump. * * @alias dump * @synopsis [<file>] @@ -132,7 +132,7 @@ function export( $args, $assoc_args ) { } /** - * Imports a database from a file. + * Import database from a file. * * @synopsis [<file>] */ @@ -148,9 +148,6 @@ function import( $args, $assoc_args ) { WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } - /** - * Return a string for connecting to the DB. - */ private function connect_string() { return self::create_cmd( 'mysql --host=%s --user=%s --password=%s --database=%s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 4fd4a1672d..d6f6d98409 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -110,7 +110,7 @@ function toggle( $args, $assoc_args = array() ) { } /** - * Get a plugin path. + * Get the path to a plugin or to the plugin directory. * * @synopsis [<plugin>] [--dir] */ @@ -221,7 +221,7 @@ protected function get_item_list() { } /** - * Install a plugin from wordpress.org or from a zip file. + * Install a plugin. * * @synopsis <plugin|zip> [--version=<version>] [--activate] */ diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index a10dadb992..733c6b2b8e 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -81,7 +81,7 @@ private function is_active_theme( $stylesheet ) { } /** - * Get a theme path. + * Get the path to a theme or to the theme directory. * * @synopsis [<theme>] [--dir] */ @@ -157,7 +157,7 @@ protected function get_item_list() { } /** - * Install a theme from wordpress.org or from a zip file. + * Install a theme. * * @synopsis <theme|zip> [--version=<version>] [--activate] */ From a4d0f4e0901a471270a440fbb46664be5dedc664 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 04:55:58 +0300 Subject: [PATCH 0706/4858] remove duplicat info from doc files and generate man pages using new method --- man/blog-create.1 | 4 ++-- man/blog-delete.1 | 7 ++++--- man/cache-add.1 | 10 ++++++++++ man/cache-decr.1 | 10 ++++++++++ man/cache-delete.1 | 10 ++++++++++ man/cache-flush.1 | 10 ++++++++++ man/cache-get.1 | 10 ++++++++++ man/cache-incr.1 | 10 ++++++++++ man/cache-replace.1 | 10 ++++++++++ man/cache-set.1 | 10 ++++++++++ man/cache-type.1 | 10 ++++++++++ man/comment-approve.1 | 4 ++-- man/comment-count.1 | 6 +++--- man/comment-create.1 | 6 +++--- man/comment-delete.1 | 4 ++-- man/comment-last.1 | 2 +- man/comment-spam.1 | 6 +++--- man/comment-status.1 | 6 +++--- man/comment-trash.1 | 4 ++-- man/comment-unapprove.1 | 4 ++-- man/comment-unspam.1 | 6 +++--- man/comment-untrash.1 | 4 ++-- man/core-config.1 | 6 +++--- man/core-download.1 | 4 ++-- man/core-install-network.1 | 2 +- man/core-install.1 | 4 ++-- man/core-update.1 | 6 +++--- man/core-version.1 | 4 ++-- man/db-cli.1 | 4 ++-- man/db-connect.1 | 4 ++-- man/db-create.1 | 4 ++-- man/db-drop.1 | 4 ++-- man/db-export.1 | 4 ++-- man/db-import.1 | 4 ++-- man/db-optimize.1 | 4 ++-- man/db-query.1 | 6 +++--- man/db-repair.1 | 4 ++-- man/db-reset.1 | 4 ++-- man/eval-file.1 | 4 ++-- man/eval.1 | 4 ++-- man/export.1 | 4 ++-- man/help.1 | 10 ++++++++++ man/home.1 | 2 +- man/option-add.1 | 10 ++++++++++ man/option-delete.1 | 10 ++++++++++ man/option-get.1 | 10 ++++++++++ man/option-update.1 | 10 ++++++++++ man/plugin-activate.1 | 4 ++-- man/plugin-deactivate.1 | 4 ++-- man/plugin-delete.1 | 4 ++-- man/plugin-install.1 | 6 +++--- man/plugin-path.1 | 2 +- man/plugin-status.1 | 2 +- man/plugin-toggle.1 | 4 ++-- man/plugin-uninstall.1 | 4 ++-- man/plugin-update-all.1 | 10 ++++++++++ man/plugin-update.1 | 6 +++--- man/post-create.1 | 6 +++--- man/post-delete.1 | 4 ++-- man/post-generate.1 | 2 +- man/post-list.1 | 2 +- man/post-meta-add.1 | 10 ++++++++++ man/post-meta-delete.1 | 10 ++++++++++ man/post-meta-get.1 | 10 ++++++++++ man/post-meta-update.1 | 10 ++++++++++ man/post-update.1 | 6 +++--- man/rewrite-dump.1 | 4 ++-- man/rewrite-flush.1 | 4 ++-- man/rewrite-structure.1 | 6 +++--- man/theme-activate.1 | 4 ++-- man/theme-delete.1 | 2 +- man/theme-install.1 | 6 +++--- man/theme-path.1 | 2 +- man/theme-status.1 | 2 +- man/theme-update-all.1 | 10 ++++++++++ man/theme-update.1 | 6 +++--- man/transient-delete.1 | 10 ++++++++++ man/transient-get.1 | 10 ++++++++++ man/transient-set.1 | 10 ++++++++++ man/transient-type.1 | 10 ++++++++++ man/user-create.1 | 4 ++-- man/user-delete.1 | 6 +++--- man/user-generate.1 | 2 +- man/user-list.1 | 4 ++-- man/user-meta-add.1 | 10 ++++++++++ man/user-meta-delete.1 | 10 ++++++++++ man/user-meta-get.1 | 10 ++++++++++ man/user-meta-update.1 | 10 ++++++++++ man/user-update.1 | 6 +++--- src/docs/blog-create.txt | 7 ------- src/docs/blog-delete.txt | 8 -------- src/docs/comment-approve.txt | 7 ------- src/docs/comment-count.txt | 7 ------- src/docs/comment-create.txt | 7 ------- src/docs/comment-delete.txt | 7 ------- src/docs/comment-last.txt | 7 ------- src/docs/comment-spam.txt | 7 ------- src/docs/comment-status.txt | 7 ------- src/docs/comment-trash.txt | 7 ------- src/docs/comment-unapprove.txt | 7 ------- src/docs/comment-unspam.txt | 7 ------- src/docs/comment-untrash.txt | 7 ------- src/docs/core-config.txt | 7 ------- src/docs/core-download.txt | 7 ------- src/docs/core-install-network.txt | 8 -------- src/docs/core-install.txt | 7 ------- src/docs/core-update-db.txt | 6 ------ src/docs/core-update.txt | 7 ------- src/docs/core-version.txt | 7 ------- src/docs/db-cli.txt | 6 ------ src/docs/db-connect.txt | 6 ------ src/docs/db-create.txt | 6 ------ src/docs/db-drop.txt | 7 ------- src/docs/db-export.txt | 7 ------- src/docs/db-import.txt | 7 ------- src/docs/db-optimize.txt | 6 ------ src/docs/db-query.txt | 7 ------- src/docs/db-repair.txt | 6 ------ src/docs/db-reset.txt | 7 ------- src/docs/eval-file.txt | 7 ------- src/docs/eval.txt | 7 ------- src/docs/export.txt | 7 ------- src/docs/home.txt | 6 ------ src/docs/plugin-activate.txt | 7 ------- src/docs/plugin-deactivate.txt | 7 ------- src/docs/plugin-delete.txt | 7 ------- src/docs/plugin-install.txt | 7 ------- src/docs/plugin-path.txt | 7 ------- src/docs/plugin-status.txt | 7 ------- src/docs/plugin-toggle.txt | 7 ------- src/docs/plugin-uninstall.txt | 7 ------- src/docs/plugin-update.txt | 7 ------- src/docs/post-create.txt | 7 ------- src/docs/post-delete.txt | 7 ------- src/docs/post-generate.txt | 8 -------- src/docs/post-list.txt | 7 ------- src/docs/post-update.txt | 7 ------- src/docs/rewrite-dump.txt | 7 ------- src/docs/rewrite-flush.txt | 7 ------- src/docs/rewrite-structure.txt | 7 ------- src/docs/theme-activate.txt | 7 ------- src/docs/theme-delete.txt | 7 ------- src/docs/theme-install.txt | 7 ------- src/docs/theme-path.txt | 7 ------- src/docs/theme-status.txt | 7 ------- src/docs/theme-update.txt | 7 ------- src/docs/user-create.txt | 7 ------- src/docs/user-delete.txt | 7 ------- src/docs/user-generate.txt | 7 ------- src/docs/user-list.txt | 7 ------- src/docs/user-update.txt | 7 ------- 151 files changed, 410 insertions(+), 559 deletions(-) create mode 100644 man/cache-add.1 create mode 100644 man/cache-decr.1 create mode 100644 man/cache-delete.1 create mode 100644 man/cache-flush.1 create mode 100644 man/cache-get.1 create mode 100644 man/cache-incr.1 create mode 100644 man/cache-replace.1 create mode 100644 man/cache-set.1 create mode 100644 man/cache-type.1 create mode 100644 man/help.1 create mode 100644 man/option-add.1 create mode 100644 man/option-delete.1 create mode 100644 man/option-get.1 create mode 100644 man/option-update.1 create mode 100644 man/plugin-update-all.1 create mode 100644 man/post-meta-add.1 create mode 100644 man/post-meta-delete.1 create mode 100644 man/post-meta-get.1 create mode 100644 man/post-meta-update.1 create mode 100644 man/theme-update-all.1 create mode 100644 man/transient-delete.1 create mode 100644 man/transient-get.1 create mode 100644 man/transient-set.1 create mode 100644 man/transient-type.1 create mode 100644 man/user-meta-add.1 create mode 100644 man/user-meta-delete.1 create mode 100644 man/user-meta-get.1 create mode 100644 man/user-meta-update.1 delete mode 100644 src/docs/core-update-db.txt delete mode 100644 src/docs/db-cli.txt delete mode 100644 src/docs/db-connect.txt delete mode 100644 src/docs/db-create.txt delete mode 100644 src/docs/db-optimize.txt delete mode 100644 src/docs/db-repair.txt delete mode 100644 src/docs/home.txt diff --git a/man/blog-create.1 b/man/blog-create.1 index 574670f93a..0245da7c14 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -4,10 +4,10 @@ .TH "WP\-BLOG\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-blog\-create\fR \- Create a new blog in a multisite install\. +\fBwp\-blog\-create\fR \- Create a blog in a multisite install\. . .SH "SYNOPSIS" -\fBwp blog create\fR \-\-slug=\fIslug\fR \-\-title=\fITitle\fR [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-public=true] +\fBwp blog create\fR \-\-slug=\fIslug\fR \-\-title=\fItitle\fR [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-public] . .SH "OPTIONS" . diff --git a/man/blog-delete.1 b/man/blog-delete.1 index b8f45e50be..556bb95c7f 100644 --- a/man/blog-delete.1 +++ b/man/blog-delete.1 @@ -1,9 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 -wp\-blog\-delete(1) \-\- Delete a blog in a multisite install\. . -.P -==== +.TH "WP\-BLOG\-DELETE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-blog\-delete\fR \- Delete a blog in a multisite install\. . .SH "SYNOPSIS" \fBwp blog delete\fR \-\-slug=\fIslug\fR [\-\-yes] [\-\-keep\-tables] diff --git a/man/cache-add.1 b/man/cache-add.1 new file mode 100644 index 0000000000..1ba98a2b05 --- /dev/null +++ b/man/cache-add.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-ADD" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-add\fR \- Add a value to the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache add\fR \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cache-decr.1 b/man/cache-decr.1 new file mode 100644 index 0000000000..7b77e71112 --- /dev/null +++ b/man/cache-decr.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-DECR" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-decr\fR \- Decrement a value in the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache decr\fR \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] diff --git a/man/cache-delete.1 b/man/cache-delete.1 new file mode 100644 index 0000000000..180dd95d4f --- /dev/null +++ b/man/cache-delete.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-DELETE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-delete\fR \- Remove a value from the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache delete\fR \fIkey\fR \fIgroup\fR diff --git a/man/cache-flush.1 b/man/cache-flush.1 new file mode 100644 index 0000000000..68fa2e169e --- /dev/null +++ b/man/cache-flush.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-FLUSH" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-flush\fR \- Flush the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache flush\fR diff --git a/man/cache-get.1 b/man/cache-get.1 new file mode 100644 index 0000000000..eb27a251c7 --- /dev/null +++ b/man/cache-get.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-GET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-get\fR \- Get a value from the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache get\fR \fIkey\fR [\fIgroup\fR] diff --git a/man/cache-incr.1 b/man/cache-incr.1 new file mode 100644 index 0000000000..fc2e886a56 --- /dev/null +++ b/man/cache-incr.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-INCR" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-incr\fR \- Increment a value in the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache incr\fR \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] diff --git a/man/cache-replace.1 b/man/cache-replace.1 new file mode 100644 index 0000000000..d332695011 --- /dev/null +++ b/man/cache-replace.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-REPLACE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-replace\fR \- Replace an existing value in the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache replace\fR \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cache-set.1 b/man/cache-set.1 new file mode 100644 index 0000000000..d40e0c0e6d --- /dev/null +++ b/man/cache-set.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-SET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-set\fR \- Set a value to the object cache\. +. +.SH "SYNOPSIS" +\fBwp cache set\fR \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cache-type.1 b/man/cache-type.1 new file mode 100644 index 0000000000..a6c7c2a476 --- /dev/null +++ b/man/cache-type.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CACHE\-TYPE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cache\-type\fR \- Attempts to determine which object cache is being used\. +. +.SH "SYNOPSIS" +\fBwp cache type\fR diff --git a/man/comment-approve.1 b/man/comment-approve.1 index 5fbb4caa7c..06ecb02c8a 100644 --- a/man/comment-approve.1 +++ b/man/comment-approve.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-APPROVE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-APPROVE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-approve\fR \- Approve a comment\. . .SH "SYNOPSIS" -\fBwp comment approve\fR \fIID\fR +\fBwp comment approve\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-count.1 b/man/comment-count.1 index 733606c17b..eda8c40ae9 100644 --- a/man/comment-count.1 +++ b/man/comment-count.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-COUNT" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-COUNT" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-comment\-count\fR \- Get total comments for blog or single post +\fBwp\-comment\-count\fR \- Count comments, on whole blog or on a given post\. . .SH "SYNOPSIS" -\fBwp comment count\fR [\fIID\fR] +\fBwp comment count\fR [\fIpost\-id\fR] . .SH "OPTIONS" . diff --git a/man/comment-create.1 b/man/comment-create.1 index b164b96e7a..2d7510f366 100644 --- a/man/comment-create.1 +++ b/man/comment-create.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-CREATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-comment\-create\fR \- Create a new comment\. +\fBwp\-comment\-create\fR \- Insert a comment\. . .SH "SYNOPSIS" -\fBwp comment create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] [\-\-porcelain] +\fBwp comment create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/comment-delete.1 b/man/comment-delete.1 index e7daaf6d6f..14f31ffeca 100644 --- a/man/comment-delete.1 +++ b/man/comment-delete.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-DELETE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-DELETE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-delete\fR \- Delete a comment\. . .SH "SYNOPSIS" -\fBwp comment delete\fR \fIID\fR [\-\-force] +\fBwp comment delete\fR \fIid\fR [\-\-force] . .SH "OPTIONS" . diff --git a/man/comment-last.1 b/man/comment-last.1 index f1c4809d25..298df14862 100644 --- a/man/comment-last.1 +++ b/man/comment-last.1 @@ -4,7 +4,7 @@ .TH "WP\-COMMENT\-LAST" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-comment\-last\fR \- Retrieve last approved comment +\fBwp\-comment\-last\fR \- Get last approved comment\. . .SH "SYNOPSIS" \fBwp comment last\fR [\-\-id] [\-\-full] diff --git a/man/comment-spam.1 b/man/comment-spam.1 index 303d179e78..ab667d8ca1 100644 --- a/man/comment-spam.1 +++ b/man/comment-spam.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-SPAM" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-SPAM" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-comment\-spam\fR \- Mark a comment as spam\. +\fBwp\-comment\-spam\fR \- Spam a comment\. . .SH "SYNOPSIS" -\fBwp comment spam\fR \fIID\fR +\fBwp comment spam\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-status.1 b/man/comment-status.1 index 6ca168f9d0..a9256af375 100644 --- a/man/comment-status.1 +++ b/man/comment-status.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-STATUS" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-STATUS" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-comment\-status\fR \- Get status of a comment +\fBwp\-comment\-status\fR \- Get status of a comment\. . .SH "SYNOPSIS" -\fBwp comment status\fR \fIID\fR +\fBwp comment status\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-trash.1 b/man/comment-trash.1 index cf451e98f4..0b9cdbe2e0 100644 --- a/man/comment-trash.1 +++ b/man/comment-trash.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-TRASH" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-TRASH" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-trash\fR \- Trash a comment\. . .SH "SYNOPSIS" -\fBwp comment trash\fR \fIID\fR +\fBwp comment trash\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-unapprove.1 b/man/comment-unapprove.1 index 7df1204dac..01a7ae93c3 100644 --- a/man/comment-unapprove.1 +++ b/man/comment-unapprove.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-UNAPPROVE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-UNAPPROVE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-unapprove\fR \- Unapprove a comment\. . .SH "SYNOPSIS" -\fBwp comment unapprove\fR \fIID\fR +\fBwp comment unapprove\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-unspam.1 b/man/comment-unspam.1 index 4eb765e917..6b64e907da 100644 --- a/man/comment-unspam.1 +++ b/man/comment-unspam.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-UNSPAM" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-UNSPAM" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-comment\-unspam\fR \- Unmark a comment as spam\. +\fBwp\-comment\-unspam\fR \- Unspam a comment\. . .SH "SYNOPSIS" -\fBwp comment unspam\fR \fIID\fR +\fBwp comment unspam\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-untrash.1 b/man/comment-untrash.1 index 223fd5cfc5..7b62bfec32 100644 --- a/man/comment-untrash.1 +++ b/man/comment-untrash.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-UNTRASH" "1" "September 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-UNTRASH" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-untrash\fR \- Untrash a comment\. . .SH "SYNOPSIS" -\fBwp comment untrash\fR \fIID\fR +\fBwp comment untrash\fR \fIid\fR . .SH "OPTIONS" . diff --git a/man/core-config.1 b/man/core-config.1 index cc545a6659..e1f2260b75 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-CONFIG" "1" "September 2012" "" "WP-CLI" +.TH "WP\-CORE\-CONFIG" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-core\-config\fR \- Create a wp\-config\.php file\. +\fBwp\-core\-config\fR \- Set up a wp\-config\. . .SH "SYNOPSIS" -\fBwp core config\fR \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=localhost] [\-\-dbprefix=wp_] +\fBwp core config\fR \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] . .SH "OPTIONS" . diff --git a/man/core-download.1 b/man/core-download.1 index 9dc988e6d6..a654552f00 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-DOWNLOAD" "1" "September 2012" "" "WP-CLI" +.TH "WP\-CORE\-DOWNLOAD" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-download\fR \- Download core WordPress files\. . .SH "SYNOPSIS" -\fBwp core download\fR [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] +\fBwp core download\fR [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] [\-\-path=\fIpath\fR] . .SH "OPTIONS" . diff --git a/man/core-install-network.1 b/man/core-install-network.1 index d2bfef7106..f7bb75355f 100644 --- a/man/core-install-network.1 +++ b/man/core-install-network.1 @@ -4,7 +4,7 @@ .TH "WP\-CORE\-INSTALL\-NETWORK" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-core\-install\-network\fR \- Transform a single\-site install into a +\fBwp\-core\-install\-network\fR \- Transform a single\-site install into a multi\-site install\. . .SH "SYNOPSIS" \fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=\fIurl\-path\fR] diff --git a/man/core-install.1 b/man/core-install.1 index 9ba7e9e4a1..6eda4897ce 100644 --- a/man/core-install.1 +++ b/man/core-install.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-INSTALL" "1" "September 2012" "" "WP-CLI" +.TH "WP\-CORE\-INSTALL" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-core\-install\fR \- Install the WordPress tables in the database\. +\fBwp\-core\-install\fR \- Create the WordPress tables in the database\. . .SH "SYNOPSIS" \fBwp core install\fR \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_email=\fIemail\fR \-\-admin_password=\fIpassword\fR diff --git a/man/core-update.1 b/man/core-update.1 index c0b4f8c61c..aa7cd22e47 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-core\-update\fR \- Update WordPress to the latest version\. +\fBwp\-core\-update\fR \- Update WordPress\. . .SH "SYNOPSIS" -\fBwp core update\fR [\-\-version=\fInew_version\fR] [\-\-force] [<package/zip>] +\fBwp core update\fR [\fIzip\fR] [\-\-version=\fIversion\fR] [\-\-force] . .SH "OPTIONS" . diff --git a/man/core-version.1 b/man/core-version.1 index 8e910bab17..bb3bf3ca44 100644 --- a/man/core-version.1 +++ b/man/core-version.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-VERSION" "1" "September 2012" "" "WP-CLI" +.TH "WP\-CORE\-VERSION" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-core\-version\fR \- Show the WordPress version\. +\fBwp\-core\-version\fR \- Display the WordPress version\. . .SH "SYNOPSIS" \fBwp core version\fR [\-\-extra] diff --git a/man/db-cli.1 b/man/db-cli.1 index c8ae69ee69..f5d2b88da9 100644 --- a/man/db-cli.1 +++ b/man/db-cli.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-CLI" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-CLI" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-cli\fR \- Open a SQL command\-line interface to the WordPress database\. +\fBwp\-db\-cli\fR \- Open a mysql console using the WordPress credentials\. . .SH "SYNOPSIS" \fBwp db cli\fR diff --git a/man/db-connect.1 b/man/db-connect.1 index bb73c49b1e..9fea5148e5 100644 --- a/man/db-connect.1 +++ b/man/db-connect.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-CONNECT" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-CONNECT" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-connect\fR \- Print a string for connecting to the database\. +\fBwp\-db\-connect\fR \- Print a string for connecting to the DB\. . .SH "SYNOPSIS" \fBwp db connect\fR diff --git a/man/db-create.1 b/man/db-create.1 index 06d9543539..eac9c4b54f 100644 --- a/man/db-create.1 +++ b/man/db-create.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-CREATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-create\fR \- Create a database using the credentials from wp\-config\.php\. +\fBwp\-db\-create\fR \- Create the database\. . .SH "SYNOPSIS" \fBwp db create\fR diff --git a/man/db-drop.1 b/man/db-drop.1 index b3cf01108a..d84934d275 100644 --- a/man/db-drop.1 +++ b/man/db-drop.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-DROP" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-DROP" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-drop\fR \- Drop the database specified in wp\-config\.php +\fBwp\-db\-drop\fR \- Delete the database\. . .SH "SYNOPSIS" \fBwp db drop\fR [\-\-yes] diff --git a/man/db-export.1 b/man/db-export.1 index 06b28380c7..e4bbc63015 100644 --- a/man/db-export.1 +++ b/man/db-export.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-EXPORT" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-EXPORT" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-export\fR \- Export the WordPress database using mysqldump\. +\fBwp\-db\-export\fR \- Exports the database using mysqldump\. . .SH "SYNOPSIS" \fBwp db export\fR [\fIfile\fR] diff --git a/man/db-import.1 b/man/db-import.1 index 8941bbe14f..456e821c4b 100644 --- a/man/db-import.1 +++ b/man/db-import.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-IMPORT" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-IMPORT" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-import\fR \- Import a database from a text file\. +\fBwp\-db\-import\fR \- Import database from a file\. . .SH "SYNOPSIS" \fBwp db import\fR [\fIfile\fR] diff --git a/man/db-optimize.1 b/man/db-optimize.1 index 3381c63eed..50fad9af38 100644 --- a/man/db-optimize.1 +++ b/man/db-optimize.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-OPTIMIZE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-OPTIMIZE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-optimize\fR \- Optimize the database specified in the wp\-config\.php file\. +\fBwp\-db\-optimize\fR \- Optimize the database\. . .SH "SYNOPSIS" \fBwp db optimize\fR diff --git a/man/db-query.1 b/man/db-query.1 index 9ba0d685b6..c8cd72887f 100644 --- a/man/db-query.1 +++ b/man/db-query.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-QUERY" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-QUERY" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-query\fR \- Execute a query against the WordPress database\. +\fBwp\-db\-query\fR \- Execute a query against the database\. . .SH "SYNOPSIS" -\fBwp db query\fR \fISQL\fR +\fBwp db query\fR \fIsql\fR . .SH "OPTIONS" . diff --git a/man/db-repair.1 b/man/db-repair.1 index 9c96284d3d..3e6539c8dc 100644 --- a/man/db-repair.1 +++ b/man/db-repair.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-REPAIR" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-REPAIR" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-repair\fR \- Optimize the database specified in the wp\-config\.php file\. +\fBwp\-db\-repair\fR \- Repair the database\. . .SH "SYNOPSIS" \fBwp db repair\fR diff --git a/man/db-reset.1 b/man/db-reset.1 index de44c95390..d1c50d27c7 100644 --- a/man/db-reset.1 +++ b/man/db-reset.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-RESET" "1" "September 2012" "" "WP-CLI" +.TH "WP\-DB\-RESET" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-reset\fR \- Remove all data from the database specified in wp\-config\.php +\fBwp\-db\-reset\fR \- Remove all tables from the database\. . .SH "SYNOPSIS" \fBwp db reset\fR [\-\-yes] diff --git a/man/eval-file.1 b/man/eval-file.1 index b0a1694d44..6ca9e6d26c 100644 --- a/man/eval-file.1 +++ b/man/eval-file.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EVAL\-FILE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-EVAL\-FILE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-eval\-file\fR \- Loads and executes a PHP file after loading WordPress\. . .SH "SYNOPSIS" -\fBwp eval\-file\fR \fIfile\fR +\fBwp eval\-file\fR \fIpath\fR . .SH "EXAMPLES" . diff --git a/man/eval.1 b/man/eval.1 index 2a8dbdb239..8889e5f51f 100644 --- a/man/eval.1 +++ b/man/eval.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EVAL" "1" "September 2012" "" "WP-CLI" +.TH "WP\-EVAL" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-eval\fR \- Executes arbitrary PHP code after loading WordPress\. . .SH "SYNOPSIS" -\fBwp eval\fR \fIPHP\fR +\fBwp eval\fR \fIphp\-code\fR . .SH "EXAMPLES" . diff --git a/man/export.1 b/man/export.1 index 20f47f672e..77260f31fc 100644 --- a/man/export.1 +++ b/man/export.1 @@ -4,10 +4,10 @@ .TH "WP\-EXPORT" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-export\fR \- Create a WXR file\. +\fBwp\-export\fR \- Export posts to a WXR file\. . .SH "SYNOPSIS" -\fBwp export\fR \-\-dir=\fIdirname\fR [filters] [\-\-skip_comments] +\fBwp export\fR \-\-dir=\fIdir\fR [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] . .SH "OPTIONS" . diff --git a/man/help.1 b/man/help.1 new file mode 100644 index 0000000000..ec0050cb1c --- /dev/null +++ b/man/help.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-HELP" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-help\fR \- Get help on a certain topic\. +. +.SH "SYNOPSIS" +\fBwp help\fR [\fIcommand\fR] diff --git a/man/home.1 b/man/home.1 index 2dc74647ea..235d563cb5 100644 --- a/man/home.1 +++ b/man/home.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-HOME" "1" "September 2012" "" "WP-CLI" +.TH "WP\-HOME" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-home\fR \- Opens the wp\-cli homepage in your browser\. diff --git a/man/option-add.1 b/man/option-add.1 new file mode 100644 index 0000000000..249bfa0b0f --- /dev/null +++ b/man/option-add.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-OPTION\-ADD" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-option\-add\fR \- Add an option\. +. +.SH "SYNOPSIS" +\fBwp option add\fR \fIkey\fR \fIvalue\fR [\-\-json] diff --git a/man/option-delete.1 b/man/option-delete.1 new file mode 100644 index 0000000000..a625edcc9b --- /dev/null +++ b/man/option-delete.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-OPTION\-DELETE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-option\-delete\fR \- Delete an option\. +. +.SH "SYNOPSIS" +\fBwp option delete\fR \fIkey\fR diff --git a/man/option-get.1 b/man/option-get.1 new file mode 100644 index 0000000000..ad48edbd0c --- /dev/null +++ b/man/option-get.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-OPTION\-GET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-option\-get\fR \- Get an option\. +. +.SH "SYNOPSIS" +\fBwp option get\fR \fIkey\fR [\-\-json] diff --git a/man/option-update.1 b/man/option-update.1 new file mode 100644 index 0000000000..f53e10c0a9 --- /dev/null +++ b/man/option-update.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-OPTION\-UPDATE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-option\-update\fR \- Update an option\. +. +.SH "SYNOPSIS" +\fBwp option update\fR \fIkey\fR \fIvalue\fR [\-\-json] diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 index bff5b9bbe6..b4e9fce6ae 100644 --- a/man/plugin-activate.1 +++ b/man/plugin-activate.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-ACTIVATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-ACTIVATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-activate\fR \- Activate an installed plugin\. +\fBwp\-plugin\-activate\fR \- Activate a plugin\. . .SH "SYNOPSIS" \fBwp plugin activate\fR \fIplugin\fR [\-\-network] diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 index 3de02d9696..17a87783e3 100644 --- a/man/plugin-deactivate.1 +++ b/man/plugin-deactivate.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-deactivate\fR \- Deactivate an active plugin\. +\fBwp\-plugin\-deactivate\fR \- Deactivate a plugin\. . .SH "SYNOPSIS" \fBwp plugin deactivate\fR \fIplugin\fR [\-\-network] diff --git a/man/plugin-delete.1 b/man/plugin-delete.1 index 8a8834c486..b89c7ab097 100644 --- a/man/plugin-delete.1 +++ b/man/plugin-delete.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DELETE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DELETE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-delete\fR \- Delete a plugin\'s files, without removing it\'s data\. +\fBwp\-plugin\-delete\fR \- Delete plugin files\. . .SH "SYNOPSIS" \fBwp plugin delete\fR \fIplugin\fR diff --git a/man/plugin-install.1 b/man/plugin-install.1 index af740f73b9..18a07e6d2d 100644 --- a/man/plugin-install.1 +++ b/man/plugin-install.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-INSTALL" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-INSTALL" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-install\fR \- Install a plugin from wordpress\.org or from a zip file\. +\fBwp\-plugin\-install\fR \- Install a plugin\. . .SH "SYNOPSIS" -\fBwp plugin install\fR <plugin/zip> [\-\-version=\fIversion\fR] [\-\-activate] +\fBwp plugin install\fR \fIplugin|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] . .SH "OPTIONS" . diff --git a/man/plugin-path.1 b/man/plugin-path.1 index 87c1c8eb0d..d8888628c0 100644 --- a/man/plugin-path.1 +++ b/man/plugin-path.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-PATH" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-PATH" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-path\fR \- Get the path to a plugin or to the plugin directory\. diff --git a/man/plugin-status.1 b/man/plugin-status.1 index 98c1ea1776..305f7902be 100644 --- a/man/plugin-status.1 +++ b/man/plugin-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-STATUS" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-STATUS" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-status\fR \- See the status of one or all plugins\. diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 index 9764eca030..fdfd9bf611 100644 --- a/man/plugin-toggle.1 +++ b/man/plugin-toggle.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-TOGGLE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-deactivate\fR \- Activate/Deactivate an installed plugin\. +\fBwp\-plugin\-toggle\fR \- Toggle a plugin\'s activation state\. . .SH "SYNOPSIS" \fBwp plugin toggle\fR \fIplugin\fR [\-\-network] diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 index 7e6bd90437..0690bc46be 100644 --- a/man/plugin-uninstall.1 +++ b/man/plugin-uninstall.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UNINSTALL" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UNINSTALL" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-uninstall\fR \- Run the uninstallation procedure for a plugin\. +\fBwp\-plugin\-uninstall\fR \- Uninstall a plugin\. . .SH "SYNOPSIS" \fBwp plugin uninstall\fR \fIplugin\fR [\-\-no\-delete] diff --git a/man/plugin-update-all.1 b/man/plugin-update-all.1 new file mode 100644 index 0000000000..0e08069095 --- /dev/null +++ b/man/plugin-update-all.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-UPDATE\-ALL" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-update\-all\fR \- Update all plugins\. +. +.SH "SYNOPSIS" +\fBwp plugin update\-all\fR [\-\-dry\-run] diff --git a/man/plugin-update.1 b/man/plugin-update.1 index 3fcac90c5b..43d0d5705b 100644 --- a/man/plugin-update.1 +++ b/man/plugin-update.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UPDATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UPDATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-plugin\-update\fR \- Update an installed plugin\. +\fBwp\-plugin\-update\fR \- Update a plugin\. . .SH "SYNOPSIS" -\fBwp plugin update\fR [\fIplugin\fR] [\-\-all] [\-\-version=dev] +\fBwp plugin update\fR \fIplugin\fR [\-\-version=\fIversion\fR] . .SH "OPTIONS" . diff --git a/man/post-create.1 b/man/post-create.1 index 072011b4cd..4d7ca0460f 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-CREATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-POST\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-post\-create\fR \- Create a new WordPress post\. +\fBwp\-post\-create\fR \- Create a post\. . .SH "SYNOPSIS" -\fBwp post create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] [\-\-porcelain] +\fBwp post create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/post-delete.1 b/man/post-delete.1 index 616087a1e0..f2ef6523e2 100644 --- a/man/post-delete.1 +++ b/man/post-delete.1 @@ -4,10 +4,10 @@ .TH "WP\-POST\-DELETE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-post\-delete\fR \- Delete one or several posts by ID\. +\fBwp\-post\-delete\fR \- Delete a post by ID\. . .SH "SYNOPSIS" -\fBwp post delete\fR \fIID\fR\.\.\. [\-\-force] +\fBwp post delete\fR \fIid\fR\.\.\. [\-\-force] . .SH "OPTIONS" . diff --git a/man/post-generate.1 b/man/post-generate.1 index afb014a25c..93969834d0 100644 --- a/man/post-generate.1 +++ b/man/post-generate.1 @@ -4,7 +4,7 @@ .TH "WP\-POST\-GENERATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-post\-generate\fR \- Generate a bunch of posts\. +\fBwp\-post\-generate\fR \- Generate some posts\. . .SH "SYNOPSIS" \fBwp post generate\fR [\-\-count=100] [\-\-post_type=post] [\-\-post_status=publish] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIdate\fR] [\-\-max_depth=1] diff --git a/man/post-list.1 b/man/post-list.1 index b66c8137ab..e35e8d6fad 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -7,7 +7,7 @@ \fBwp\-post\-list\fR \- Get a list of posts\. . .SH "SYNOPSIS" -\fBwp post list\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] [\-\-ids] +\fBwp post list\fR [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] . .SH "OPTIONS" . diff --git a/man/post-meta-add.1 b/man/post-meta-add.1 new file mode 100644 index 0000000000..91ae02aa86 --- /dev/null +++ b/man/post-meta-add.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-META\-ADD" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-meta\-add\fR \- Add a meta field\. +. +.SH "SYNOPSIS" +\fBwp post\-meta add\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/post-meta-delete.1 b/man/post-meta-delete.1 new file mode 100644 index 0000000000..ea28519d57 --- /dev/null +++ b/man/post-meta-delete.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-META\-DELETE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-meta\-delete\fR \- Delete a meta field\. +. +.SH "SYNOPSIS" +\fBwp post\-meta delete\fR \fIid\fR \fIkey\fR diff --git a/man/post-meta-get.1 b/man/post-meta-get.1 new file mode 100644 index 0000000000..330773f18b --- /dev/null +++ b/man/post-meta-get.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-META\-GET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-meta\-get\fR \- Get meta field value\. +. +.SH "SYNOPSIS" +\fBwp post\-meta get\fR \fIid\fR \fIkey\fR [\-\-json] diff --git a/man/post-meta-update.1 b/man/post-meta-update.1 new file mode 100644 index 0000000000..a90f92c422 --- /dev/null +++ b/man/post-meta-update.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-META\-UPDATE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-meta\-update\fR \- Update a meta field\. +. +.SH "SYNOPSIS" +\fBwp post\-meta update\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/post-update.1 b/man/post-update.1 index 60d85f15b8..abadef4a08 100644 --- a/man/post-update.1 +++ b/man/post-update.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-UPDATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-POST\-UPDATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-post\-update\fR \- Update a WordPress post\. +\fBwp\-post\-update\fR \- Update a post\. . .SH "SYNOPSIS" -\fBwp post update\fR \fIID\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] +\fBwp post update\fR \fIid\fR \-\-\fIfield\fR=\fIvalue\fR . .SH "OPTIONS" . diff --git a/man/rewrite-dump.1 b/man/rewrite-dump.1 index fffedb924c..8b7432011c 100644 --- a/man/rewrite-dump.1 +++ b/man/rewrite-dump.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "REWRITE\-DUMP" "1" "September 2012" "" "WP-CLI" +.TH "WP\-REWRITE\-DUMP" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBrewrite\-dump\fR \- Print current rewrite rules to STDOUT\. +\fBwp\-rewrite\-dump\fR \- Print current rewrite rules\. . .SH "SYNOPSIS" \fBwp rewrite dump\fR [\-\-json] diff --git a/man/rewrite-flush.1 b/man/rewrite-flush.1 index 02a631a4ad..f7ba485be1 100644 --- a/man/rewrite-flush.1 +++ b/man/rewrite-flush.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "REWRITE\-FLUSH" "1" "September 2012" "" "WP-CLI" +.TH "WP\-REWRITE\-FLUSH" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBrewrite\-flush\fR \- Flush rewrite rules\. +\fBwp\-rewrite\-flush\fR \- Flush rewrite rules\. . .SH "SYNOPSIS" \fBwp rewrite flush\fR [\-\-soft] diff --git a/man/rewrite-structure.1 b/man/rewrite-structure.1 index 833cd3e3a1..8589c5ca92 100644 --- a/man/rewrite-structure.1 +++ b/man/rewrite-structure.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "REWRITE\-STRUCTURE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-REWRITE\-STRUCTURE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBrewrite\-structure\fR \- Update the permalink structure +\fBwp\-rewrite\-structure\fR \- Update the permalink structure\. . .SH "SYNOPSIS" -\fBwp rewrite structure\fR \fIpermastruct\fR [\-\-category\-base=\fIcategorybase\fR] [\-\-tag\-base=\fItagbase\fR] +\fBwp rewrite structure\fR \fIpermastruct\fR [\-\-category\-base=\fIbase\fR] [\-\-tag\-base=\fIbase\fR] . .SH "OPTIONS" . diff --git a/man/theme-activate.1 b/man/theme-activate.1 index 55861bc3dd..cb545a291f 100644 --- a/man/theme-activate.1 +++ b/man/theme-activate.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-ACTIVATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-THEME\-ACTIVATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-theme\-activate\fR \- Activate an installed theme\. +\fBwp\-theme\-activate\fR \- Activate a theme\. . .SH "SYNOPSIS" \fBwp theme activate\fR \fItheme\fR diff --git a/man/theme-delete.1 b/man/theme-delete.1 index 0514d865d2..7bf9935108 100644 --- a/man/theme-delete.1 +++ b/man/theme-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-DELETE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-THEME\-DELETE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-delete\fR \- Delete a theme\. diff --git a/man/theme-install.1 b/man/theme-install.1 index 3042b5bee8..96ea741d47 100644 --- a/man/theme-install.1 +++ b/man/theme-install.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-INSTALL" "1" "September 2012" "" "WP-CLI" +.TH "WP\-THEME\-INSTALL" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-theme\-install\fR \- Install a theme from wordpress\.org or from a zip file\. +\fBwp\-theme\-install\fR \- Install a theme\. . .SH "SYNOPSIS" -\fBwp theme install\fR <theme/zip> [\-\-activate] +\fBwp theme install\fR \fItheme|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] . .SH "OPTIONS" . diff --git a/man/theme-path.1 b/man/theme-path.1 index 90bf49d82e..64275161f1 100644 --- a/man/theme-path.1 +++ b/man/theme-path.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-PATH" "1" "September 2012" "" "WP-CLI" +.TH "WP\-THEME\-PATH" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-path\fR \- Get the path to a theme or to the theme directory\. diff --git a/man/theme-status.1 b/man/theme-status.1 index 53b68274a1..e7b10fd128 100644 --- a/man/theme-status.1 +++ b/man/theme-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-STATUS" "1" "September 2012" "" "WP-CLI" +.TH "WP\-THEME\-STATUS" "1" "October 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-status\fR \- See the status of one or all themes\. diff --git a/man/theme-update-all.1 b/man/theme-update-all.1 new file mode 100644 index 0000000000..27a2beda18 --- /dev/null +++ b/man/theme-update-all.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-UPDATE\-ALL" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-update\-all\fR \- Update all themes\. +. +.SH "SYNOPSIS" +\fBwp theme update\-all\fR [\-\-dry\-run] diff --git a/man/theme-update.1 b/man/theme-update.1 index 5ae00b078d..b186f1f811 100644 --- a/man/theme-update.1 +++ b/man/theme-update.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-UPDATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-THEME\-UPDATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-theme\-update\fR \- Update an installed theme\. +\fBwp\-theme\-update\fR \- Update a theme\. . .SH "SYNOPSIS" -\fBwp theme update\fR [\fItheme\fR] [\-\-all] +\fBwp theme update\fR \fItheme\fR . .SH "OPTIONS" . diff --git a/man/transient-delete.1 b/man/transient-delete.1 new file mode 100644 index 0000000000..490196468e --- /dev/null +++ b/man/transient-delete.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TRANSIENT\-DELETE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-transient\-delete\fR \- Delete a transient value\. +. +.SH "SYNOPSIS" +\fBwp transient delete\fR \fIkey\fR diff --git a/man/transient-get.1 b/man/transient-get.1 new file mode 100644 index 0000000000..b6895c048a --- /dev/null +++ b/man/transient-get.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TRANSIENT\-GET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-transient\-get\fR \- Get a transient value\. +. +.SH "SYNOPSIS" +\fBwp transient get\fR \fIkey\fR [\-\-json] diff --git a/man/transient-set.1 b/man/transient-set.1 new file mode 100644 index 0000000000..a3addcc597 --- /dev/null +++ b/man/transient-set.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TRANSIENT\-SET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-transient\-set\fR \- Set a transient value\. +. +.SH "SYNOPSIS" +\fBwp transient set\fR \fIkey\fR \fIvalue\fR [\fIexpiration\fR] diff --git a/man/transient-type.1 b/man/transient-type.1 new file mode 100644 index 0000000000..bdd4b06770 --- /dev/null +++ b/man/transient-type.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TRANSIENT\-TYPE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-transient\-type\fR \- See wether the transients API is using an object cache or the options table\. +. +.SH "SYNOPSIS" +\fBwp transient type\fR diff --git a/man/user-create.1 b/man/user-create.1 index 67537e0c70..9f98d42963 100644 --- a/man/user-create.1 +++ b/man/user-create.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-CREATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-USER\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-create\fR \- Create a new WordPress user\. +\fBwp\-user\-create\fR \- Create a user\. . .SH "SYNOPSIS" \fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-porcelain] diff --git a/man/user-delete.1 b/man/user-delete.1 index a33d6fdd39..5f76a774ad 100644 --- a/man/user-delete.1 +++ b/man/user-delete.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-DELETE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-USER\-DELETE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-delete\fR \- Delete a WordPress user\. +\fBwp\-user\-delete\fR \- Delete a user\. . .SH "SYNOPSIS" -\fBwp user delete\fR \fIID\fR [\-\-reassign=\fIID\fR] +\fBwp user delete\fR \fIid\fR [\-\-reassign=\fIid\fR] . .SH "OPTIONS" . diff --git a/man/user-generate.1 b/man/user-generate.1 index a2331a2168..faa3c7bd1a 100644 --- a/man/user-generate.1 +++ b/man/user-generate.1 @@ -4,7 +4,7 @@ .TH "WP\-USER\-GENERATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-generate\fR \- Generate a bunch of users\. +\fBwp\-user\-generate\fR \- Generate users\. . .SH "SYNOPSIS" \fBwp user generate\fR [\-\-count=100] [\-\-role=\fIrole\fR] diff --git a/man/user-list.1 b/man/user-list.1 index 0535f8674b..c55e48fdda 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-LIST" "1" "September 2012" "" "WP-CLI" +.TH "WP\-USER\-LIST" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-list\fR \- List WordPress users\. +\fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" \fBwp user list\fR [\-\-role=\fIrole\fR] diff --git a/man/user-meta-add.1 b/man/user-meta-add.1 new file mode 100644 index 0000000000..691c7b6dca --- /dev/null +++ b/man/user-meta-add.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-META\-ADD" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-meta\-add\fR \- Add a meta field\. +. +.SH "SYNOPSIS" +\fBwp user\-meta add\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/user-meta-delete.1 b/man/user-meta-delete.1 new file mode 100644 index 0000000000..310893ccd7 --- /dev/null +++ b/man/user-meta-delete.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-META\-DELETE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-meta\-delete\fR \- Delete a meta field\. +. +.SH "SYNOPSIS" +\fBwp user\-meta delete\fR \fIid\fR \fIkey\fR diff --git a/man/user-meta-get.1 b/man/user-meta-get.1 new file mode 100644 index 0000000000..1d9ee4b8c2 --- /dev/null +++ b/man/user-meta-get.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-META\-GET" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-meta\-get\fR \- Get meta field value\. +. +.SH "SYNOPSIS" +\fBwp user\-meta get\fR \fIid\fR \fIkey\fR [\-\-json] diff --git a/man/user-meta-update.1 b/man/user-meta-update.1 new file mode 100644 index 0000000000..1e5e44f8f4 --- /dev/null +++ b/man/user-meta-update.1 @@ -0,0 +1,10 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-META\-UPDATE" "1" "October 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-meta\-update\fR \- Update a meta field\. +. +.SH "SYNOPSIS" +\fBwp user\-meta update\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/user-update.1 b/man/user-update.1 index cebdfef6b3..2cf19a5ec9 100644 --- a/man/user-update.1 +++ b/man/user-update.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-UPDATE" "1" "September 2012" "" "WP-CLI" +.TH "WP\-USER\-UPDATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-update\fR \- Update a WordPress user\. +\fBwp\-user\-update\fR \- Update a user\. . .SH "SYNOPSIS" -\fBwp user update\fR \fIID\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-\fIfield\fR=\fIvalue\fR\.\.\.] +\fBwp user update\fR \fIid\fR \-\-\fIfield\fR=\fIvalue\fR . .SH "OPTIONS" . diff --git a/src/docs/blog-create.txt b/src/docs/blog-create.txt index cfe7b2b390..3f660e3cb2 100644 --- a/src/docs/blog-create.txt +++ b/src/docs/blog-create.txt @@ -1,10 +1,3 @@ -wp-blog-create(1) -- Create a new blog in a multisite install. -==== - -## SYNOPSIS - -`wp blog create` --slug=<slug> --title=<Title> [--email=<email>] [--site_id=<site-id>] [--public=true] - ## OPTIONS * `--slug`=<slug>: diff --git a/src/docs/blog-delete.txt b/src/docs/blog-delete.txt index 18b3ac87b7..349836eb87 100644 --- a/src/docs/blog-delete.txt +++ b/src/docs/blog-delete.txt @@ -1,11 +1,3 @@ -wp-blog-delete(1) -- Delete a blog in a multisite install. - -==== - -## SYNOPSIS - -`wp blog delete` --slug=<slug> [--yes] [--keep-tables] - ## OPTIONS * `--slug`=<slug>: diff --git a/src/docs/comment-approve.txt b/src/docs/comment-approve.txt index 7ed0ac4a11..f703cd04b2 100644 --- a/src/docs/comment-approve.txt +++ b/src/docs/comment-approve.txt @@ -1,10 +1,3 @@ -wp-comment-approve(1) -- Approve a comment. -==== - -## SYNOPSIS - -`wp comment approve` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-count.txt b/src/docs/comment-count.txt index 1c2abcf86e..0c595e3701 100644 --- a/src/docs/comment-count.txt +++ b/src/docs/comment-count.txt @@ -1,10 +1,3 @@ -wp-comment-count(1) -- Get total comments for blog or single post -==== - -## SYNOPSIS - -`wp comment count` [<ID>] - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-create.txt b/src/docs/comment-create.txt index b64ecb4e0d..0b093d2f08 100644 --- a/src/docs/comment-create.txt +++ b/src/docs/comment-create.txt @@ -1,10 +1,3 @@ -wp-comment-create(1) -- Create a new comment. -==== - -## SYNOPSIS - -`wp comment create` --<field>=<value> [--<field>=<value>...] [--porcelain] - ## OPTIONS * `--<field>`=<value>: diff --git a/src/docs/comment-delete.txt b/src/docs/comment-delete.txt index 2cb016dcb7..bd39300f79 100644 --- a/src/docs/comment-delete.txt +++ b/src/docs/comment-delete.txt @@ -1,10 +1,3 @@ -wp-comment-delete(1) -- Delete a comment. -==== - -## SYNOPSIS - -`wp comment delete` <ID> [--force] - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-last.txt b/src/docs/comment-last.txt index 358fcd79a0..34504ec539 100644 --- a/src/docs/comment-last.txt +++ b/src/docs/comment-last.txt @@ -1,10 +1,3 @@ -wp-comment-last(1) -- Retrieve last approved comment -==== - -## SYNOPSIS - -`wp comment last` [--id] [--full] - ## OPTIONS * `--id`: diff --git a/src/docs/comment-spam.txt b/src/docs/comment-spam.txt index 0fcdaf9a6d..b1a446cf19 100644 --- a/src/docs/comment-spam.txt +++ b/src/docs/comment-spam.txt @@ -1,10 +1,3 @@ -wp-comment-spam(1) -- Mark a comment as spam. -==== - -## SYNOPSIS - -`wp comment spam` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-status.txt b/src/docs/comment-status.txt index ee51ec4fd5..a53c32765b 100644 --- a/src/docs/comment-status.txt +++ b/src/docs/comment-status.txt @@ -1,10 +1,3 @@ -wp-comment-status(1) -- Get status of a comment -==== - -## SYNOPSIS - -`wp comment status` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-trash.txt b/src/docs/comment-trash.txt index 791968f524..3d1388178a 100644 --- a/src/docs/comment-trash.txt +++ b/src/docs/comment-trash.txt @@ -1,10 +1,3 @@ -wp-comment-trash(1) -- Trash a comment. -==== - -## SYNOPSIS - -`wp comment trash` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-unapprove.txt b/src/docs/comment-unapprove.txt index 1fee7ac486..5569199c4c 100644 --- a/src/docs/comment-unapprove.txt +++ b/src/docs/comment-unapprove.txt @@ -1,10 +1,3 @@ -wp-comment-unapprove(1) -- Unapprove a comment. -==== - -## SYNOPSIS - -`wp comment unapprove` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-unspam.txt b/src/docs/comment-unspam.txt index 59e9ff4944..1a055d2ced 100644 --- a/src/docs/comment-unspam.txt +++ b/src/docs/comment-unspam.txt @@ -1,10 +1,3 @@ -wp-comment-unspam(1) -- Unmark a comment as spam. -==== - -## SYNOPSIS - -`wp comment unspam` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/comment-untrash.txt b/src/docs/comment-untrash.txt index d35967a3fd..54fe15eb21 100644 --- a/src/docs/comment-untrash.txt +++ b/src/docs/comment-untrash.txt @@ -1,10 +1,3 @@ -wp-comment-untrash(1) -- Untrash a comment. -==== - -## SYNOPSIS - -`wp comment untrash` <ID> - ## OPTIONS * `<ID>`: diff --git a/src/docs/core-config.txt b/src/docs/core-config.txt index 01f71b1a0e..5b3345010f 100644 --- a/src/docs/core-config.txt +++ b/src/docs/core-config.txt @@ -1,10 +1,3 @@ -wp-core-config(1) -- Create a wp-config.php file. -==== - -## SYNOPSIS - -`wp core config` --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=localhost] [--dbprefix=wp_] - ## OPTIONS * `--dbname`=<dbname>: diff --git a/src/docs/core-download.txt b/src/docs/core-download.txt index 7fbaee097d..6b85fc3afc 100644 --- a/src/docs/core-download.txt +++ b/src/docs/core-download.txt @@ -1,10 +1,3 @@ -wp-core-download(1) -- Download core WordPress files. -==== - -## SYNOPSIS - -`wp core download` [--locale=<locale>] [--version=<version>] - ## OPTIONS * `--locale`=<locale>: diff --git a/src/docs/core-install-network.txt b/src/docs/core-install-network.txt index 74fe22d988..86db38741b 100644 --- a/src/docs/core-install-network.txt +++ b/src/docs/core-install-network.txt @@ -1,11 +1,3 @@ -wp-core-install-network(1) -- Transform a single-site install into a -multi-site install. -==== - -## SYNOPSIS - -`wp core install-network` --title=<network-title> [--base_path=<url-path>] - ## OPTIONS * `--title`=<site-title>: diff --git a/src/docs/core-install.txt b/src/docs/core-install.txt index 8f65a9a00d..711410e55a 100644 --- a/src/docs/core-install.txt +++ b/src/docs/core-install.txt @@ -1,10 +1,3 @@ -wp-core-install(1) -- Install the WordPress tables in the database. -==== - -## SYNOPSIS - -`wp core install` --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> - ## OPTIONS * `--url`=<url>: diff --git a/src/docs/core-update-db.txt b/src/docs/core-update-db.txt deleted file mode 100644 index b199312fdd..0000000000 --- a/src/docs/core-update-db.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-core-update-db(1) -- Update the WordPress database. -==== - -## SYNOPSIS - -`wp core update-db` diff --git a/src/docs/core-update.txt b/src/docs/core-update.txt index abdc56e07e..50caa5f2eb 100644 --- a/src/docs/core-update.txt +++ b/src/docs/core-update.txt @@ -1,10 +1,3 @@ -wp-core-update(1) -- Update WordPress to the latest version. -==== - -## SYNOPSIS - -`wp core update` [--version=<new_version>] [--force] [<package/zip>] - ## OPTIONS * `--version=`<new_version> [package/zip]: diff --git a/src/docs/core-version.txt b/src/docs/core-version.txt index ecbdc4d48e..d1c5d6a6d9 100644 --- a/src/docs/core-version.txt +++ b/src/docs/core-version.txt @@ -1,10 +1,3 @@ -wp-core-version(1) -- Show the WordPress version. -==== - -## SYNOPSIS - -`wp core version` [--extra] - ## OPTIONS * `--extra`: diff --git a/src/docs/db-cli.txt b/src/docs/db-cli.txt deleted file mode 100644 index 10753c08be..0000000000 --- a/src/docs/db-cli.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-db-cli(1) -- Open a SQL command-line interface to the WordPress database. -==== - -## SYNOPSIS - -`wp db cli` diff --git a/src/docs/db-connect.txt b/src/docs/db-connect.txt deleted file mode 100644 index b724452e1a..0000000000 --- a/src/docs/db-connect.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-db-connect(1) -- Print a string for connecting to the database. -==== - -## SYNOPSIS - -`wp db connect` diff --git a/src/docs/db-create.txt b/src/docs/db-create.txt deleted file mode 100644 index 27a6b7c745..0000000000 --- a/src/docs/db-create.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-db-create(1) -- Create a database using the credentials from wp-config.php. -==== - -## SYNOPSIS - -`wp db create` diff --git a/src/docs/db-drop.txt b/src/docs/db-drop.txt index 76f4266ca7..f626d62dd6 100644 --- a/src/docs/db-drop.txt +++ b/src/docs/db-drop.txt @@ -1,10 +1,3 @@ -wp-db-drop(1) -- Drop the database specified in wp-config.php -==== - -## SYNOPSIS - -`wp db drop` [--yes] - ## OPTIONS * `--yes`: diff --git a/src/docs/db-export.txt b/src/docs/db-export.txt index c5019c2af7..cce48dc75e 100644 --- a/src/docs/db-export.txt +++ b/src/docs/db-export.txt @@ -1,10 +1,3 @@ -wp-db-export(1) -- Export the WordPress database using mysqldump. -==== - -## SYNOPSIS - -`wp db export` [<file>] - ## OPTIONS * `<file>`: diff --git a/src/docs/db-import.txt b/src/docs/db-import.txt index a0e65c2b9b..5770c0b1c9 100644 --- a/src/docs/db-import.txt +++ b/src/docs/db-import.txt @@ -1,10 +1,3 @@ -wp-db-import(1) -- Import a database from a text file. -==== - -## SYNOPSIS - -`wp db import` [<file>] - ## OPTIONS * `<file>`: diff --git a/src/docs/db-optimize.txt b/src/docs/db-optimize.txt deleted file mode 100644 index bd640f7f60..0000000000 --- a/src/docs/db-optimize.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-db-optimize(1) -- Optimize the database specified in the wp-config.php file. -==== - -## SYNOPSIS - -`wp db optimize` diff --git a/src/docs/db-query.txt b/src/docs/db-query.txt index b4e986ba22..7d44ae6757 100644 --- a/src/docs/db-query.txt +++ b/src/docs/db-query.txt @@ -1,10 +1,3 @@ -wp-db-query(1) -- Execute a query against the WordPress database. -==== - -## SYNOPSIS - -`wp db query` <SQL> - ## OPTIONS * `<SQL>`: diff --git a/src/docs/db-repair.txt b/src/docs/db-repair.txt deleted file mode 100644 index e882046c4f..0000000000 --- a/src/docs/db-repair.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-db-repair(1) -- Optimize the database specified in the wp-config.php file. -==== - -## SYNOPSIS - -`wp db repair` diff --git a/src/docs/db-reset.txt b/src/docs/db-reset.txt index 8ba5a5ed50..f626d62dd6 100644 --- a/src/docs/db-reset.txt +++ b/src/docs/db-reset.txt @@ -1,10 +1,3 @@ -wp-db-reset(1) -- Remove all data from the database specified in wp-config.php -==== - -## SYNOPSIS - -`wp db reset` [--yes] - ## OPTIONS * `--yes`: diff --git a/src/docs/eval-file.txt b/src/docs/eval-file.txt index 47e6764bc6..57a808c109 100644 --- a/src/docs/eval-file.txt +++ b/src/docs/eval-file.txt @@ -1,10 +1,3 @@ -wp-eval-file(1) -- Loads and executes a PHP file after loading WordPress. -==== - -## SYNOPSIS - -`wp eval-file` <file> - ## EXAMPLES wp eval-file my-code.php diff --git a/src/docs/eval.txt b/src/docs/eval.txt index 97db070a9a..699b93f2ee 100644 --- a/src/docs/eval.txt +++ b/src/docs/eval.txt @@ -1,10 +1,3 @@ -wp-eval(1) -- Executes arbitrary PHP code after loading WordPress. -==== - -## SYNOPSIS - -`wp eval` <PHP> - ## EXAMPLES wp eval 'echo WP_CONTENT_DIR;' diff --git a/src/docs/export.txt b/src/docs/export.txt index 1aafbc5b17..582a983cb0 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -1,10 +1,3 @@ -wp-export(1) -- Create a WXR file. -==== - -## SYNOPSIS - -`wp export` --dir=<dirname> [filters] [--skip_comments] - ## OPTIONS * `--dir`=<dirname>: diff --git a/src/docs/home.txt b/src/docs/home.txt deleted file mode 100644 index 32d55a2792..0000000000 --- a/src/docs/home.txt +++ /dev/null @@ -1,6 +0,0 @@ -wp-home(1) -- Opens the wp-cli homepage in your browser. -==== - -## SYNOPSIS - -`wp home` diff --git a/src/docs/plugin-activate.txt b/src/docs/plugin-activate.txt index b7207bf814..5558338912 100644 --- a/src/docs/plugin-activate.txt +++ b/src/docs/plugin-activate.txt @@ -1,10 +1,3 @@ -wp-plugin-activate(1) -- Activate an installed plugin. -==== - -## SYNOPSIS - -`wp plugin activate` <plugin> [--network] - ## OPTIONS * `<plugin>`: diff --git a/src/docs/plugin-deactivate.txt b/src/docs/plugin-deactivate.txt index d114fafed8..12be8084cb 100644 --- a/src/docs/plugin-deactivate.txt +++ b/src/docs/plugin-deactivate.txt @@ -1,10 +1,3 @@ -wp-plugin-deactivate(1) -- Deactivate an active plugin. -==== - -## SYNOPSIS - -`wp plugin deactivate` <plugin> [--network] - ## OPTIONS * `<plugin>`: diff --git a/src/docs/plugin-delete.txt b/src/docs/plugin-delete.txt index e36d303fe8..111865f594 100644 --- a/src/docs/plugin-delete.txt +++ b/src/docs/plugin-delete.txt @@ -1,10 +1,3 @@ -wp-plugin-delete(1) -- Delete a plugin's files, without removing it's data. -==== - -## SYNOPSIS - -`wp plugin delete` <plugin> - ## OPTIONS * <plugin>: diff --git a/src/docs/plugin-install.txt b/src/docs/plugin-install.txt index e39aadedb2..90f951721c 100644 --- a/src/docs/plugin-install.txt +++ b/src/docs/plugin-install.txt @@ -1,10 +1,3 @@ -wp-plugin-install(1) -- Install a plugin from wordpress.org or from a zip file. -==== - -## SYNOPSIS - -`wp plugin install` <plugin/zip> [--version=<version>] [--activate] - ## OPTIONS * <plugin>: diff --git a/src/docs/plugin-path.txt b/src/docs/plugin-path.txt index 08e804aa13..6f05ac23b7 100644 --- a/src/docs/plugin-path.txt +++ b/src/docs/plugin-path.txt @@ -1,10 +1,3 @@ -wp-plugin-path(1) -- Get the path to a plugin or to the plugin directory. -==== - -## SYNOPSIS - -`wp plugin path` [<plugin>] [--dir] - ## OPTIONS * `<plugin>`: diff --git a/src/docs/plugin-status.txt b/src/docs/plugin-status.txt index 5ee1022dc0..daf14a99e1 100644 --- a/src/docs/plugin-status.txt +++ b/src/docs/plugin-status.txt @@ -1,10 +1,3 @@ -wp-plugin-status(1) -- See the status of one or all plugins. -==== - -## SYNOPSIS - -`wp plugin status` [<plugin>] - ## OPTIONS * `<plugin>`: diff --git a/src/docs/plugin-toggle.txt b/src/docs/plugin-toggle.txt index 07c243ea27..97e284aed0 100644 --- a/src/docs/plugin-toggle.txt +++ b/src/docs/plugin-toggle.txt @@ -1,10 +1,3 @@ -wp-plugin-deactivate(1) -- Activate/Deactivate an installed plugin. -==== - -## SYNOPSIS - -`wp plugin toggle` <plugin> [--network] - ## OPTIONS * `<plugin>`: diff --git a/src/docs/plugin-uninstall.txt b/src/docs/plugin-uninstall.txt index d0783f3ddf..ea41bcbf1a 100644 --- a/src/docs/plugin-uninstall.txt +++ b/src/docs/plugin-uninstall.txt @@ -1,10 +1,3 @@ -wp-plugin-uninstall(1) -- Run the uninstallation procedure for a plugin. -==== - -## SYNOPSIS - -`wp plugin uninstall` <plugin> [--no-delete] - ## OPTIONS * <plugin>: diff --git a/src/docs/plugin-update.txt b/src/docs/plugin-update.txt index 4be28128b2..8bc68da0d3 100644 --- a/src/docs/plugin-update.txt +++ b/src/docs/plugin-update.txt @@ -1,10 +1,3 @@ -wp-plugin-update(1) -- Update an installed plugin. -==== - -## SYNOPSIS - -`wp plugin update` [<plugin>] [--all] [--version=dev] - ## OPTIONS * <plugin>: diff --git a/src/docs/post-create.txt b/src/docs/post-create.txt index 467f30501e..75c4de21f9 100644 --- a/src/docs/post-create.txt +++ b/src/docs/post-create.txt @@ -1,10 +1,3 @@ -wp-post-create(1) -- Create a new WordPress post. -==== - -## SYNOPSIS - -`wp post create` --<field>=<value> [--<field>=<value>...] [--porcelain] - ## OPTIONS * `--<field>`=<value>: diff --git a/src/docs/post-delete.txt b/src/docs/post-delete.txt index 21ce192f6a..7deed70506 100644 --- a/src/docs/post-delete.txt +++ b/src/docs/post-delete.txt @@ -1,10 +1,3 @@ -wp-post-delete(1) -- Delete one or several posts by ID. -==== - -## SYNOPSIS - -`wp post delete` <ID>... [--force] - ## OPTIONS * `<ID>`: diff --git a/src/docs/post-generate.txt b/src/docs/post-generate.txt index 3b5e282b2f..cab9b591f2 100644 --- a/src/docs/post-generate.txt +++ b/src/docs/post-generate.txt @@ -1,11 +1,3 @@ -wp-post-generate(1) -- Generate a bunch of posts. -==== - -## SYNOPSIS - -`wp post generate` [--count=100] [--post_type=post] [--post_status=publish] -[--post_author=<login>] [--post_date=<date>] [--max_depth=1] - ## OPTIONS * `--count`=<number>: diff --git a/src/docs/post-list.txt b/src/docs/post-list.txt index de04f98eae..295f102c0f 100644 --- a/src/docs/post-list.txt +++ b/src/docs/post-list.txt @@ -1,10 +1,3 @@ -wp-post-list(1) -- Get a list of posts. -==== - -## SYNOPSIS - -`wp post list` --<field>=<value> [--<field>=<value>...] [--ids] - ## OPTIONS * `--<field>`=<value>: diff --git a/src/docs/post-update.txt b/src/docs/post-update.txt index 53a454859f..0fd825e24b 100644 --- a/src/docs/post-update.txt +++ b/src/docs/post-update.txt @@ -1,10 +1,3 @@ -wp-post-update(1) -- Update a WordPress post. -==== - -## SYNOPSIS - -`wp post update` <ID> --<field>=<value> [--<field>=<value>...] - ## OPTIONS * `<ID>`: diff --git a/src/docs/rewrite-dump.txt b/src/docs/rewrite-dump.txt index 2a39b8527d..26498dbcaf 100644 --- a/src/docs/rewrite-dump.txt +++ b/src/docs/rewrite-dump.txt @@ -1,10 +1,3 @@ -rewrite-dump(1) -- Print current rewrite rules to STDOUT. -==== - -## SYNOPSIS - -`wp rewrite dump` [--json] - ## OPTIONS * `--json`: diff --git a/src/docs/rewrite-flush.txt b/src/docs/rewrite-flush.txt index e7d11dd391..60ae94af8c 100644 --- a/src/docs/rewrite-flush.txt +++ b/src/docs/rewrite-flush.txt @@ -1,10 +1,3 @@ -rewrite-flush(1) -- Flush rewrite rules. -==== - -## SYNOPSIS - -`wp rewrite flush` [--soft] - ## OPTIONS * `--soft`: diff --git a/src/docs/rewrite-structure.txt b/src/docs/rewrite-structure.txt index 8e77ea39db..9dec9d860e 100644 --- a/src/docs/rewrite-structure.txt +++ b/src/docs/rewrite-structure.txt @@ -1,10 +1,3 @@ -rewrite-structure(1) -- Update the permalink structure -==== - -## SYNOPSIS - -`wp rewrite structure` <permastruct> [--category-base=<categorybase>] [--tag-base=<tagbase>] - ## OPTIONS * <permastruct>: diff --git a/src/docs/theme-activate.txt b/src/docs/theme-activate.txt index 24a492d716..c740472400 100644 --- a/src/docs/theme-activate.txt +++ b/src/docs/theme-activate.txt @@ -1,10 +1,3 @@ -wp-theme-activate(1) -- Activate an installed theme. -==== - -## SYNOPSIS - -`wp theme activate` <theme> - ## OPTIONS * `<theme>`: diff --git a/src/docs/theme-delete.txt b/src/docs/theme-delete.txt index 94fa90cca2..22506747b4 100644 --- a/src/docs/theme-delete.txt +++ b/src/docs/theme-delete.txt @@ -1,10 +1,3 @@ -wp-theme-delete(1) -- Delete a theme. -==== - -## SYNOPSIS - -`wp theme delete` <theme> - ## OPTIONS * <theme>: diff --git a/src/docs/theme-install.txt b/src/docs/theme-install.txt index df18a80e1d..28e26a342c 100644 --- a/src/docs/theme-install.txt +++ b/src/docs/theme-install.txt @@ -1,10 +1,3 @@ -wp-theme-install(1) -- Install a theme from wordpress.org or from a zip file. -==== - -## SYNOPSIS - -`wp theme install` <theme/zip> [--activate] - ## OPTIONS * <theme>: diff --git a/src/docs/theme-path.txt b/src/docs/theme-path.txt index 32bb5c876d..9b87d96992 100644 --- a/src/docs/theme-path.txt +++ b/src/docs/theme-path.txt @@ -1,10 +1,3 @@ -wp-theme-path(1) -- Get the path to a theme or to the theme directory. -==== - -## SYNOPSIS - -`wp theme path` [<theme>] [--dir] - ## OPTIONS * `<theme>`: diff --git a/src/docs/theme-status.txt b/src/docs/theme-status.txt index 48b5dfe149..f4aa713355 100644 --- a/src/docs/theme-status.txt +++ b/src/docs/theme-status.txt @@ -1,10 +1,3 @@ -wp-theme-status(1) -- See the status of one or all themes. -==== - -## SYNOPSIS - -`wp theme status` [<theme>] - ## OPTIONS * `<theme>`: diff --git a/src/docs/theme-update.txt b/src/docs/theme-update.txt index e6f5c5e012..9c37f8229d 100644 --- a/src/docs/theme-update.txt +++ b/src/docs/theme-update.txt @@ -1,10 +1,3 @@ -wp-theme-update(1) -- Update an installed theme. -==== - -## SYNOPSIS - -`wp theme update` [<theme>] [--all] - ## OPTIONS * <theme>: diff --git a/src/docs/user-create.txt b/src/docs/user-create.txt index 0ed2e2214c..6ba889ecea 100644 --- a/src/docs/user-create.txt +++ b/src/docs/user-create.txt @@ -1,10 +1,3 @@ -wp-user-create(1) -- Create a new WordPress user. -==== - -## SYNOPSIS - -`wp user create` <user-login> <user-email> [--role=<role>] [--porcelain] - ## OPTIONS * `<user-login>`: diff --git a/src/docs/user-delete.txt b/src/docs/user-delete.txt index 6d8832c6cc..920282f7e6 100644 --- a/src/docs/user-delete.txt +++ b/src/docs/user-delete.txt @@ -1,10 +1,3 @@ -wp-user-delete(1) -- Delete a WordPress user. -==== - -## SYNOPSIS - -`wp user delete` <ID> [--reassign=<ID>] - ## OPTIONS * `<ID>`: diff --git a/src/docs/user-generate.txt b/src/docs/user-generate.txt index 52885be9f0..a2467abf0c 100644 --- a/src/docs/user-generate.txt +++ b/src/docs/user-generate.txt @@ -1,10 +1,3 @@ -wp-user-generate(1) -- Generate a bunch of users. -==== - -## SYNOPSIS - -`wp user generate` [--count=100] [--role=<role>] - ## OPTIONS * `--count`=<number>: diff --git a/src/docs/user-list.txt b/src/docs/user-list.txt index 32b88daade..631b84e282 100644 --- a/src/docs/user-list.txt +++ b/src/docs/user-list.txt @@ -1,10 +1,3 @@ -wp-user-list(1) -- List WordPress users. -==== - -## SYNOPSIS - -`wp user list` [--role=<role>] - ## OPTIONS * `--role`=<role>: diff --git a/src/docs/user-update.txt b/src/docs/user-update.txt index ca46b7e4e2..9a93a9f81a 100644 --- a/src/docs/user-update.txt +++ b/src/docs/user-update.txt @@ -1,10 +1,3 @@ -wp-user-update(1) -- Update a WordPress user. -==== - -## SYNOPSIS - -`wp user update` <ID> --<field>=<value> [--<field>=<value>...] - ## OPTIONS * `<ID>`: From 1823fc702b78e91c7ed9433028e5195bf4143208 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 05:04:44 +0300 Subject: [PATCH 0707/4858] extract add_initial_markdown() procedure --- src/php/wp-cli/man.php | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index daee08c691..4afc61321b 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -8,8 +8,8 @@ function get_path( $args ) { return WP_CLI_ROOT . "../../../man/" . implode( '-', $args ) . '.1'; } -function get_doc_path() { - return WP_CLI_ROOT . "../../docs/"; +function get_doc_path( $args ) { + return WP_CLI_ROOT . "../../docs/" . implode( '-', $args ) . '.txt'; } function generate( $command ) { @@ -33,6 +33,21 @@ function generate( $command ) { // returns a file descriptor containing markdown that will be passed to ronn function get_markdown( Dispatcher\Documentable $command ) { + $fd = fopen( "php://temp", "rw" ); + + add_initial_markdown( $fd, $command ); + + $doc_path = get_doc_path( $command->get_path() ); + + if ( file_exists( $doc_path ) ) + fwrite( $fd, file_get_contents( $doc_path ) ); + + fseek( $fd, 0 ); + + return $fd; +} + +function add_initial_markdown( $fd, Dispatcher\Documentable $command ) { $path = $command->get_path(); $shortdesc = $command->get_shortdesc(); $synopsis = $command->get_synopsis(); @@ -46,9 +61,7 @@ function get_markdown( Dispatcher\Documentable $command ) { \WP_CLI::warning( "No shortdesc for $name_s" ); } - $temp = fopen( "php://temp", "rw" ); - - fwrite( $temp, <<<DOC + fwrite( $fd, <<<DOC wp-$name_m(1) -- $shortdesc ==== @@ -58,14 +71,5 @@ function get_markdown( Dispatcher\Documentable $command ) { DOC ); - - $doc_path = get_doc_path() . "$name_m.txt"; - - if ( file_exists( $doc_path ) ) - fwrite( $temp, file_get_contents( $doc_path ) ); - - fseek( $temp, 0 ); - - return $temp; } From 2718319374d01b7349129049257ef4aff9831a14 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 05:28:48 +0300 Subject: [PATCH 0708/4858] extract call_ronn() procedure --- src/php/wp-cli/man.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index 4afc61321b..6b310fab29 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -8,7 +8,7 @@ function get_path( $args ) { return WP_CLI_ROOT . "../../../man/" . implode( '-', $args ) . '.1'; } -function get_doc_path( $args ) { +function get_src_path( $args ) { return WP_CLI_ROOT . "../../docs/" . implode( '-', $args ) . '.txt'; } @@ -20,15 +20,19 @@ function generate( $command ) { return; } + call_ronn( get_markdown( $command ), get_path( $command->get_path() ) ); +} + +function call_ronn( $markdown, $dest ) { $descriptorspec = array( - 0 => get_markdown( $command ), - 1 => array( 'file', get_path( $command->get_path() ), 'w' ), + 0 => $markdown, + 1 => array( 'file', $dest, 'w' ), 2 => STDERR ); $r = proc_close( proc_open( "ronn --roff --manual='WP-CLI'", $descriptorspec, $pipes ) ); - \WP_CLI::line( "generated man page for " . implode( '-', $command->get_path() ) ); + \WP_CLI::line( "generated " . basename( $dest ) ); } // returns a file descriptor containing markdown that will be passed to ronn @@ -37,7 +41,7 @@ function get_markdown( Dispatcher\Documentable $command ) { add_initial_markdown( $fd, $command ); - $doc_path = get_doc_path( $command->get_path() ); + $doc_path = get_src_path( $command->get_path() ); if ( file_exists( $doc_path ) ) fwrite( $fd, file_get_contents( $doc_path ) ); From 71e67cfe7e02f351dd074b475d5ac9bf987367de Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 05:35:05 +0300 Subject: [PATCH 0709/4858] call ronn for top level commands too --- src/php/wp-cli/man.php | 44 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index 6b310fab29..379f09c6ea 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -13,45 +13,36 @@ function get_src_path( $args ) { } function generate( $command ) { + call_ronn( get_markdown( $command ), get_path( $command->get_path() ) ); + if ( $command instanceof Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) { generate( $subcommand ); } - return; } - - call_ronn( get_markdown( $command ), get_path( $command->get_path() ) ); -} - -function call_ronn( $markdown, $dest ) { - $descriptorspec = array( - 0 => $markdown, - 1 => array( 'file', $dest, 'w' ), - 2 => STDERR - ); - - $r = proc_close( proc_open( "ronn --roff --manual='WP-CLI'", $descriptorspec, $pipes ) ); - - \WP_CLI::line( "generated " . basename( $dest ) ); } -// returns a file descriptor containing markdown that will be passed to ronn -function get_markdown( Dispatcher\Documentable $command ) { +// returns a file descriptor or false +function get_markdown( $command ) { $fd = fopen( "php://temp", "rw" ); - add_initial_markdown( $fd, $command ); + if ( $command instanceof Dispatcher\Documentable ) + add_initial_markdown( $fd, $command ); $doc_path = get_src_path( $command->get_path() ); if ( file_exists( $doc_path ) ) fwrite( $fd, file_get_contents( $doc_path ) ); + if ( 0 === ftell( $fd ) ) + return false; + fseek( $fd, 0 ); return $fd; } -function add_initial_markdown( $fd, Dispatcher\Documentable $command ) { +function add_initial_markdown( $fd, $command ) { $path = $command->get_path(); $shortdesc = $command->get_shortdesc(); $synopsis = $command->get_synopsis(); @@ -77,3 +68,18 @@ function add_initial_markdown( $fd, Dispatcher\Documentable $command ) { ); } +function call_ronn( $markdown, $dest ) { + if ( !$markdown ) + return; + + $descriptorspec = array( + 0 => $markdown, + 1 => array( 'file', $dest, 'w' ), + 2 => STDERR + ); + + $r = proc_close( proc_open( "ronn --roff --manual='WP-CLI'", $descriptorspec, $pipes ) ); + + \WP_CLI::line( "generated " . basename( $dest ) ); +} + From 41895dae5e02d5936f01aa40e4969e58696bef9d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 06:40:34 +0300 Subject: [PATCH 0710/4858] remove \WP_CLI\ prefix --- src/php/wp-cli/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8b259bb449..31cff1fbb4 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -19,9 +19,9 @@ class WP_CLI { */ public function add_command( $name, $class ) { if ( is_string( $class ) ) - $command = new \WP_CLI\Dispatcher\CompositeCommand( $name, $class ); + $command = new Dispatcher\CompositeCommand( $name, $class ); else - $command = new \WP_CLI\Dispatcher\SingleCommand( $name, $class ); + $command = new Dispatcher\SingleCommand( $name, $class ); self::$commands[ $name ] = $command; } From 7bb3ecacb860b05e1a6c8da7d71ab59332c2eb40 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 25 Oct 2012 07:00:33 +0300 Subject: [PATCH 0711/4858] finish shortdesc at newline, instead of dot. see #187 --- man/core-config.1 | 2 +- man/db-create.1 | 2 +- src/php/wp-cli/commands/internals/db.php | 2 +- src/php/wp-cli/dispatcher.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/core-config.1 b/man/core-config.1 index e1f2260b75..adb58494c8 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -4,7 +4,7 @@ .TH "WP\-CORE\-CONFIG" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-core\-config\fR \- Set up a wp\-config\. +\fBwp\-core\-config\fR \- Set up a wp\-config\.php file\. . .SH "SYNOPSIS" \fBwp core config\fR \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] diff --git a/man/db-create.1 b/man/db-create.1 index eac9c4b54f..4c94095c8f 100644 --- a/man/db-create.1 +++ b/man/db-create.1 @@ -4,7 +4,7 @@ .TH "WP\-DB\-CREATE" "1" "October 2012" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\-create\fR \- Create the database\. +\fBwp\-db\-create\fR \- Create the database, as specified in wp\-config\.php . .SH "SYNOPSIS" \fBwp db create\fR diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 12f6918a03..72c27d2013 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -15,7 +15,7 @@ public static function get_default_subcommand() { } /** - * Create the database. + * Create the database, as specified in wp-config.php */ function create() { WP_CLI::launch( self::create_cmd( diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 9a12b6807c..a825a6c7b5 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -297,7 +297,7 @@ private function check_unknown_assoc( $assoc_args, $accepted_params ) { function get_shortdesc() { $comment = $this->method->getDocComment(); - if ( !preg_match( '/\* ([^@\.]+\.)\s*/', $comment, $matches ) ) + if ( !preg_match( '/\* (\w.+)\n*/', $comment, $matches ) ) return false; return $matches[1]; From a431978318b73170f1d8c00c170fb3bfdada3a81 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 26 Oct 2012 16:30:47 -0400 Subject: [PATCH 0712/4858] fix --path handling --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 31cff1fbb4..a227cd7af6 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -240,7 +240,7 @@ static function before_wp_load() { // Define the WordPress location if ( !empty( self::$assoc_special['path'] ) ) { // trailingslashit() isn't available yet - define( 'WP_ROOT', rtrim( self::$assoc_args['path'], '/' ) . '/' ); + define( 'WP_ROOT', rtrim( self::$assoc_special['path'], '/' ) . '/' ); } else { define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); } From c200b42a4f814a845dc8f132e1b5956be09d4e4d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 14:40:18 -0400 Subject: [PATCH 0713/4858] correctly mark add_command() as static. fixes #193 --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index a227cd7af6..927803ed62 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -17,7 +17,7 @@ class WP_CLI { * @param string $name The name of the command that will be used in the cli * @param string $class The class to manage the command */ - public function add_command( $name, $class ) { + static function add_command( $name, $class ) { if ( is_string( $class ) ) $command = new Dispatcher\CompositeCommand( $name, $class ); else From d0f5d8cae1b0c0e7fe403c3a96918edaf12e5bfc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 15:56:46 -0400 Subject: [PATCH 0714/4858] first pass at wp repl --- src/php/wp-cli/commands/internals/repl.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/repl.php diff --git a/src/php/wp-cli/commands/internals/repl.php b/src/php/wp-cli/commands/internals/repl.php new file mode 100644 index 0000000000..49e3ce0289 --- /dev/null +++ b/src/php/wp-cli/commands/internals/repl.php @@ -0,0 +1,20 @@ +<?php + +WP_CLI::add_command( 'repl', new Repl_Command ); + +class Repl_Command extends WP_CLI_Command { + + /** + * Open an interactive shell environment. + */ + public function __invoke() { + while ( true ) { + WP_CLI::out( 'wp> ' ); + + $in = \cli\input(); + + echo eval( $in ); + } + } +} + From 41fa520d1c0542067a84493b3ff04fba9f574d25 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 15:57:25 -0400 Subject: [PATCH 0715/4858] make 'exit' exit --- src/php/wp-cli/commands/internals/repl.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/commands/internals/repl.php b/src/php/wp-cli/commands/internals/repl.php index 49e3ce0289..3571aa20dc 100644 --- a/src/php/wp-cli/commands/internals/repl.php +++ b/src/php/wp-cli/commands/internals/repl.php @@ -13,6 +13,9 @@ public function __invoke() { $in = \cli\input(); + if ( 'exit' == $in ) + return; + echo eval( $in ); } } From 01719e33ecfd767a22c34a47351a12a8f0e51a51 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 16:12:32 -0400 Subject: [PATCH 0716/4858] fix "Object of class stdClass could not be converted to string" --- src/php/wp-cli/commands/internals/repl.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/repl.php b/src/php/wp-cli/commands/internals/repl.php index 3571aa20dc..996d09aca0 100644 --- a/src/php/wp-cli/commands/internals/repl.php +++ b/src/php/wp-cli/commands/internals/repl.php @@ -16,7 +16,12 @@ public function __invoke() { if ( 'exit' == $in ) return; - echo eval( $in ); + $r = eval( $in ); + + if ( null === $r ) + WP_CLI::line(); + else + var_export( $r ); } } } From d624c9a041db489029cb634f0f754ce39cf6f521 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 16:47:45 -0400 Subject: [PATCH 0717/4858] update version of php-cli-tools --- src/php/php-cli-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/php-cli-tools b/src/php/php-cli-tools index c23ffe979c..7af88b4874 160000 --- a/src/php/php-cli-tools +++ b/src/php/php-cli-tools @@ -1 +1 @@ -Subproject commit c23ffe979c7956614fd8721c2e28e61a3cb6bad3 +Subproject commit 7af88b48747da17d95db6af8d00c51af5c5e104c From f68db53615b2e49a0d21643e0a483e70a37b3bd7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 17:28:08 -0400 Subject: [PATCH 0718/4858] rename wp repl to wp interactive --- .../wp-cli/commands/internals/{repl.php => interactive.php} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/php/wp-cli/commands/internals/{repl.php => interactive.php} (72%) diff --git a/src/php/wp-cli/commands/internals/repl.php b/src/php/wp-cli/commands/internals/interactive.php similarity index 72% rename from src/php/wp-cli/commands/internals/repl.php rename to src/php/wp-cli/commands/internals/interactive.php index 996d09aca0..5c92234917 100644 --- a/src/php/wp-cli/commands/internals/repl.php +++ b/src/php/wp-cli/commands/internals/interactive.php @@ -1,8 +1,8 @@ <?php -WP_CLI::add_command( 'repl', new Repl_Command ); +WP_CLI::add_command( 'interactive', new Interactive_Command ); -class Repl_Command extends WP_CLI_Command { +class Interactive_Command extends WP_CLI_Command { /** * Open an interactive shell environment. From d17da49bf7e8790de797e268369fc178c5b7d202 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 17:29:03 -0400 Subject: [PATCH 0719/4858] use readline(), if it's available --- .../wp-cli/commands/internals/interactive.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/interactive.php b/src/php/wp-cli/commands/internals/interactive.php index 5c92234917..61478e3d89 100644 --- a/src/php/wp-cli/commands/internals/interactive.php +++ b/src/php/wp-cli/commands/internals/interactive.php @@ -9,9 +9,7 @@ class Interactive_Command extends WP_CLI_Command { */ public function __invoke() { while ( true ) { - WP_CLI::out( 'wp> ' ); - - $in = \cli\input(); + $in = $this->read_input(); if ( 'exit' == $in ) return; @@ -24,5 +22,17 @@ public function __invoke() { var_export( $r ); } } + + private function read_input() { + if ( function_exists( 'readline' ) ) { + $line = readline( 'wp> ' ); + readline_add_history( $line ); + } else { + WP_CLI::out( 'wp> ' ); + $line = \cli\input(); + } + + return $line; + } } From 38be9492cb963f36c67309fefdb84cadc48d14c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 17:29:38 -0400 Subject: [PATCH 0720/4858] output nothing on fatal errors --- src/php/wp-cli/commands/internals/interactive.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/commands/internals/interactive.php b/src/php/wp-cli/commands/internals/interactive.php index 61478e3d89..d06e415796 100644 --- a/src/php/wp-cli/commands/internals/interactive.php +++ b/src/php/wp-cli/commands/internals/interactive.php @@ -16,6 +16,9 @@ public function __invoke() { $r = eval( $in ); + if ( false === $r ) + continue; + if ( null === $r ) WP_CLI::line(); else From ab02ad41259152fdda5e046f4c63ac4a7903aca9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 17:53:45 -0400 Subject: [PATCH 0721/4858] run function_exists( 'readline' ) only once --- .../wp-cli/commands/internals/interactive.php | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/commands/internals/interactive.php b/src/php/wp-cli/commands/internals/interactive.php index d06e415796..14cf35301e 100644 --- a/src/php/wp-cli/commands/internals/interactive.php +++ b/src/php/wp-cli/commands/internals/interactive.php @@ -1,15 +1,23 @@ <?php -WP_CLI::add_command( 'interactive', new Interactive_Command ); +namespace WP_CLI\Commands; -class Interactive_Command extends WP_CLI_Command { +\WP_CLI::add_command( 'interactive', new Interactive_Command ); + +class Interactive_Command extends \WP_CLI_Command { /** * Open an interactive shell environment. */ public function __invoke() { + if ( function_exists( 'readline' ) ) { + $repl = new REPL_Readline; + } else { + $repl = new REPL_Basic; + } + while ( true ) { - $in = $this->read_input(); + $in = $repl->prompt( 'wp> ' ); if ( 'exit' == $in ) return; @@ -20,22 +28,29 @@ public function __invoke() { continue; if ( null === $r ) - WP_CLI::line(); + \WP_CLI::line(); else var_export( $r ); } } +} - private function read_input() { - if ( function_exists( 'readline' ) ) { - $line = readline( 'wp> ' ); - readline_add_history( $line ); - } else { - WP_CLI::out( 'wp> ' ); - $line = \cli\input(); - } +class REPL_Readline { + + function prompt( $str ) { + $line = readline( $str ); + readline_add_history( $line ); return $line; } } + +class REPL_Basic { + + function prompt( $str ) { + \WP_CLI::out( $str ); + return \cli\input(); + } +} + From 7acfb595a43d31f3353dd6911ce6423693ffe3db Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 21:53:50 -0400 Subject: [PATCH 0722/4858] don't really need separate classes for the REPLs yet --- .../wp-cli/commands/internals/interactive.php | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/commands/internals/interactive.php b/src/php/wp-cli/commands/internals/interactive.php index 14cf35301e..2c8035d805 100644 --- a/src/php/wp-cli/commands/internals/interactive.php +++ b/src/php/wp-cli/commands/internals/interactive.php @@ -1,23 +1,21 @@ <?php -namespace WP_CLI\Commands; +WP_CLI::add_command( 'interactive', new Interactive_Command ); -\WP_CLI::add_command( 'interactive', new Interactive_Command ); - -class Interactive_Command extends \WP_CLI_Command { +class Interactive_Command extends WP_CLI_Command { /** * Open an interactive shell environment. */ public function __invoke() { if ( function_exists( 'readline' ) ) { - $repl = new REPL_Readline; + $repl = 'repl_readline'; } else { - $repl = new REPL_Basic; + $repl = 'repl_basic'; } while ( true ) { - $in = $repl->prompt( 'wp> ' ); + $in = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); if ( 'exit' == $in ) return; @@ -33,22 +31,14 @@ public function __invoke() { var_export( $r ); } } -} - - -class REPL_Readline { - function prompt( $str ) { + private static function repl_readline( $str ) { $line = readline( $str ); readline_add_history( $line ); return $line; } -} - - -class REPL_Basic { - function prompt( $str ) { + private static function repl_basic( $str ) { \WP_CLI::out( $str ); return \cli\input(); } From f86425ea4f4f05a469996d2e96c6e647238d081a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 23:26:05 -0400 Subject: [PATCH 0723/4858] rename to wp shell --- .../wp-cli/commands/internals/{interactive.php => shell.php} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/php/wp-cli/commands/internals/{interactive.php => shell.php} (85%) diff --git a/src/php/wp-cli/commands/internals/interactive.php b/src/php/wp-cli/commands/internals/shell.php similarity index 85% rename from src/php/wp-cli/commands/internals/interactive.php rename to src/php/wp-cli/commands/internals/shell.php index 2c8035d805..c4e7f92cef 100644 --- a/src/php/wp-cli/commands/internals/interactive.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -1,8 +1,8 @@ <?php -WP_CLI::add_command( 'interactive', new Interactive_Command ); +WP_CLI::add_command( 'shell', new Shell_Command ); -class Interactive_Command extends WP_CLI_Command { +class Shell_Command extends WP_CLI_Command { /** * Open an interactive shell environment. From 36c97a2d7824938dcbc27c48be6294475413f505 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 23:34:01 -0400 Subject: [PATCH 0724/4858] automatically return all expressions --- src/php/wp-cli/commands/internals/shell.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index c4e7f92cef..a17c342630 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -20,6 +20,9 @@ public function __invoke() { if ( 'exit' == $in ) return; + if ( !preg_match( '/^\s*(echo|return)\s+/', $in ) ) + $in = 'return ' . $in; + $r = eval( $in ); if ( false === $r ) @@ -28,7 +31,7 @@ public function __invoke() { if ( null === $r ) \WP_CLI::line(); else - var_export( $r ); + \WP_CLI::line( var_export( $r, false ) ); } } From cd47b7e02cc36e0bc48d59e403de272aeac2ba9a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 23:34:35 -0400 Subject: [PATCH 0725/4858] automatically append ; --- src/php/wp-cli/commands/internals/shell.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index a17c342630..47e45cdc92 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -23,6 +23,8 @@ public function __invoke() { if ( !preg_match( '/^\s*(echo|return)\s+/', $in ) ) $in = 'return ' . $in; + $in .= ';'; + $r = eval( $in ); if ( false === $r ) From d5bc11b61b06fab3e913d13d319f9dd2fc19b537 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 23:39:26 -0400 Subject: [PATCH 0726/4858] make $_ the implicit variable --- src/php/wp-cli/commands/internals/shell.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 47e45cdc92..72e5776a48 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -25,15 +25,12 @@ public function __invoke() { $in .= ';'; - $r = eval( $in ); + $_ = eval( $in ); - if ( false === $r ) + if ( false === $_ ) continue; - if ( null === $r ) - \WP_CLI::line(); - else - \WP_CLI::line( var_export( $r, false ) ); + \WP_CLI::line( var_export( $_, false ) ); } } From 62ab4321101e57e3d597b807e9b23bdd7bab116d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Oct 2012 23:57:11 -0400 Subject: [PATCH 0727/4858] allow bringing global variables into the scope --- src/php/wp-cli/commands/internals/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 72e5776a48..02c3202b10 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -20,7 +20,7 @@ public function __invoke() { if ( 'exit' == $in ) return; - if ( !preg_match( '/^\s*(echo|return)\s+/', $in ) ) + if ( !preg_match( '/^\s*(global|echo|return)\s+/', $in ) ) $in = 'return ' . $in; $in .= ';'; From aded6e12dcf8d98c4a952a90809b84478cac8b94 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Oct 2012 00:03:30 -0400 Subject: [PATCH 0728/4858] rename $in to $line --- src/php/wp-cli/commands/internals/shell.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 02c3202b10..8a0ee53a06 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -15,17 +15,17 @@ public function __invoke() { } while ( true ) { - $in = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); + $line = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); - if ( 'exit' == $in ) + if ( 'exit' == $line ) return; - if ( !preg_match( '/^\s*(global|echo|return)\s+/', $in ) ) - $in = 'return ' . $in; + if ( !preg_match( '/^\s*(global|echo|return)\s+/', $line ) ) + $line = 'return ' . $line; - $in .= ';'; + $line .= ';'; - $_ = eval( $in ); + $_ = eval( $line ); if ( false === $_ ) continue; From 568f2d0f0f1e28be780165057f4bdf9ebc61dcb5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Oct 2012 00:50:46 -0400 Subject: [PATCH 0729/4858] don't need the special case for 'exit' anymore --- src/php/wp-cli/commands/internals/shell.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 8a0ee53a06..f8c6d0f216 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -17,9 +17,6 @@ public function __invoke() { while ( true ) { $line = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); - if ( 'exit' == $line ) - return; - if ( !preg_match( '/^\s*(global|echo|return)\s+/', $line ) ) $line = 'return ' . $line; From 1f4b4a8cc5459bbd93f936728dd4930733069faf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Oct 2012 01:15:17 -0400 Subject: [PATCH 0730/4858] add support for more non-expressions --- src/php/wp-cli/commands/internals/shell.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index f8c6d0f216..25b5cd1ab2 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -14,10 +14,19 @@ public function __invoke() { $repl = 'repl_basic'; } + $non_expressions = array( + 'echo', 'return', 'global', + 'while', 'for', 'foreach', 'if', 'switch', + 'include', 'include\_once', 'require', 'require\_once' + ); + $non_expressions = implode( '|', $non_expressions ); + + $pattern = "/^\s*($non_expressions)\s+/"; + while ( true ) { $line = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); - if ( !preg_match( '/^\s*(global|echo|return)\s+/', $line ) ) + if ( !preg_match( $pattern, $line ) ) $line = 'return ' . $line; $line .= ';'; From 2b19970de99a810c18d9d0d8137e75e7b2119b82 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Oct 2012 01:16:13 -0400 Subject: [PATCH 0731/4858] allow echo('whatever') syntax too --- src/php/wp-cli/commands/internals/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 25b5cd1ab2..1f51ba85f1 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -21,7 +21,7 @@ public function __invoke() { ); $non_expressions = implode( '|', $non_expressions ); - $pattern = "/^\s*($non_expressions)\s+/"; + $pattern = "/^\s*($non_expressions)[\(\s]+/"; while ( true ) { $line = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); From 87f5a63afc2e224b0547018afa31ecc3986e1b48 Mon Sep 17 00:00:00 2001 From: Adrian Palmer <adrian@navitronic.co.uk> Date: Tue, 30 Oct 2012 14:57:17 +1100 Subject: [PATCH 0732/4858] Fixed typo in unknown warning --- src/php/wp-cli/dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index a825a6c7b5..83700435f8 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -290,7 +290,7 @@ private function check_unknown_assoc( $assoc_args, $accepted_params ) { $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); foreach ( $unknown_assoc as $key ) { - \WP_CLI::warning( "unkown --$key parameter" ); + \WP_CLI::warning( "unknown --$key parameter" ); } } From ac96cf43777a83c0784e34c02e4aca4499df7c9c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 10:33:55 -0400 Subject: [PATCH 0733/4858] update to upstream version of php-cli-tools --- src/php/php-cli-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/php-cli-tools b/src/php/php-cli-tools index 7af88b4874..eeddb2bbfa 160000 --- a/src/php/php-cli-tools +++ b/src/php/php-cli-tools @@ -1 +1 @@ -Subproject commit 7af88b48747da17d95db6af8d00c51af5c5e104c +Subproject commit eeddb2bbfab974fb8b7f188f08156eee6b533c7d From 05d8b5231056b3438d87b0cfbecd3559c81770d4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 12:28:51 -0400 Subject: [PATCH 0734/4858] use \cli\Streams directly --- src/php/wp-cli/class-wp-cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 927803ed62..f9a8522ec9 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -33,7 +33,7 @@ static function add_command( $name, $class ) { */ static function out( $message ) { if ( WP_CLI_QUIET ) return; - \cli\out($message); + \cli\Streams::out($message); } /** @@ -43,7 +43,7 @@ static function out( $message ) { */ static function line( $message = '' ) { if ( WP_CLI_QUIET ) return; - \cli\line($message); + \cli\Streams::line($message); } /** @@ -54,7 +54,7 @@ static function line( $message = '' ) { */ static function error( $message, $label = 'Error' ) { if ( !isset( self::$assoc_special['completions'] ) ) { - \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); + \cli\Streams::err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); } exit(1); @@ -68,7 +68,7 @@ static function error( $message, $label = 'Error' ) { */ static function success( $message, $label = 'Success' ) { if ( WP_CLI_QUIET ) return; - \cli\line( '%G' . $label . ': %n' . $message ); + \cli\Streams::line( '%G' . $label . ': %n' . $message ); } /** @@ -79,7 +79,7 @@ static function success( $message, $label = 'Success' ) { */ static function warning( $message, $label = 'Warning' ) { if ( WP_CLI_QUIET ) return; - \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); + \cli\Streams::err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } /** From 6aceb578d7ae86698cd9c1f12682078e3561df4a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 13:26:22 -0400 Subject: [PATCH 0735/4858] Revert "use \cli\Streams directly" This reverts commit 05d8b5231056b3438d87b0cfbecd3559c81770d4. --- src/php/wp-cli/class-wp-cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index f9a8522ec9..927803ed62 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -33,7 +33,7 @@ static function add_command( $name, $class ) { */ static function out( $message ) { if ( WP_CLI_QUIET ) return; - \cli\Streams::out($message); + \cli\out($message); } /** @@ -43,7 +43,7 @@ static function out( $message ) { */ static function line( $message = '' ) { if ( WP_CLI_QUIET ) return; - \cli\Streams::line($message); + \cli\line($message); } /** @@ -54,7 +54,7 @@ static function line( $message = '' ) { */ static function error( $message, $label = 'Error' ) { if ( !isset( self::$assoc_special['completions'] ) ) { - \cli\Streams::err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); + \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); } exit(1); @@ -68,7 +68,7 @@ static function error( $message, $label = 'Error' ) { */ static function success( $message, $label = 'Success' ) { if ( WP_CLI_QUIET ) return; - \cli\Streams::line( '%G' . $label . ': %n' . $message ); + \cli\line( '%G' . $label . ': %n' . $message ); } /** @@ -79,7 +79,7 @@ static function success( $message, $label = 'Success' ) { */ static function warning( $message, $label = 'Warning' ) { if ( WP_CLI_QUIET ) return; - \cli\Streams::err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); + \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); } /** From ebe75d82c96aea478e7e429c1cd8b60b8064d8bf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 13:36:12 -0400 Subject: [PATCH 0736/4858] use fix from php-cli-tools. see #195 --- src/php/php-cli-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/php-cli-tools b/src/php/php-cli-tools index eeddb2bbfa..f2abf5015c 160000 --- a/src/php/php-cli-tools +++ b/src/php/php-cli-tools @@ -1 +1 @@ -Subproject commit eeddb2bbfab974fb8b7f188f08156eee6b533c7d +Subproject commit f2abf5015c769f9603fc63e7d0a0eff00006c61e From 29d9f34c1431ed1599dbf9c99c81876868fc2b22 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 13:36:59 -0400 Subject: [PATCH 0737/4858] set php-cli-tools remote to wp-cli fork --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 44afb303c6..ec544e3d04 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "src/php/php-cli-tools"] path = src/php/php-cli-tools - url = git://github.com/jlogsdon/php-cli-tools.git + url = git://github.com/wp-cli/php-cli-tools.git From bd19d9bcdf9db12ca3ce548818f438b48c3bc5d7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 18:55:38 -0400 Subject: [PATCH 0738/4858] don't add empty lines to history. #89 --- src/php/wp-cli/commands/internals/shell.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 1f51ba85f1..c655f95729 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -21,7 +21,7 @@ public function __invoke() { ); $non_expressions = implode( '|', $non_expressions ); - $pattern = "/^\s*($non_expressions)[\(\s]+/"; + $pattern = "/^($non_expressions)[\(\s]+/"; while ( true ) { $line = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); @@ -41,8 +41,9 @@ public function __invoke() { } private static function repl_readline( $str ) { - $line = readline( $str ); - readline_add_history( $line ); + $line = trim( readline( $str ) ); + if ( !empty( $line ) ) + readline_add_history( $line ); return $line; } From 8cad2c979b7faa1e877889660a9713eb3ad0099c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 19:41:53 -0400 Subject: [PATCH 0739/4858] first pass at preserving wp shell history between sessions --- src/php/wp-cli/commands/internals/shell.php | 41 ++++++++++++++++----- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index c655f95729..f8f6e0d5bb 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -1,17 +1,19 @@ <?php -WP_CLI::add_command( 'shell', new Shell_Command ); +namespace WP_CLI\Commands; -class Shell_Command extends WP_CLI_Command { +\WP_CLI::add_command( 'shell', new Shell_Command ); + +class Shell_Command extends \WP_CLI_Command { /** * Open an interactive shell environment. */ public function __invoke() { if ( function_exists( 'readline' ) ) { - $repl = 'repl_readline'; + $repl = new REPL_Readline; } else { - $repl = 'repl_basic'; + $repl = new REPL_Basic; } $non_expressions = array( @@ -24,7 +26,7 @@ public function __invoke() { $pattern = "/^($non_expressions)[\(\s]+/"; while ( true ) { - $line = call_user_func( array( __CLASS__, $repl ), 'wp> ' ); + $line = $repl->read( 'wp> ' ); if ( !preg_match( $pattern, $line ) ) $line = 'return ' . $line; @@ -39,16 +41,37 @@ public function __invoke() { \WP_CLI::line( var_export( $_, false ) ); } } +} + + +class REPL_Readline { + + function __construct() { + $this->hist_path = getcwd() . '/.wp-cli-history'; + + readline_read_history( $this->hist_path ); + + register_shutdown_function( array( $this, 'save_history' ) ); + } - private static function repl_readline( $str ) { - $line = trim( readline( $str ) ); + function read( $prompt ) { + $line = trim( readline( $prompt ) ); if ( !empty( $line ) ) readline_add_history( $line ); + return $line; } - private static function repl_basic( $str ) { - \WP_CLI::out( $str ); + function save_history() { + readline_write_history( $this->hist_path ); + } +} + + +class REPL_Basic { + + function read( $prompt ) { + \WP_CLI::out( $prompt ); return \cli\input(); } } From b743dab38fa2ed6dc2a8ee3fcfff65c4414dcfef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Oct 2012 19:54:34 -0400 Subject: [PATCH 0740/4858] store different history files, based on current path and current user --- src/php/wp-cli/commands/internals/shell.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index f8f6e0d5bb..12a04dfafc 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -47,13 +47,19 @@ public function __invoke() { class REPL_Readline { function __construct() { - $this->hist_path = getcwd() . '/.wp-cli-history'; + $this->hist_path = self::get_history_path(); readline_read_history( $this->hist_path ); register_shutdown_function( array( $this, 'save_history' ) ); } + private static function get_history_path() { + $data = getcwd() . get_current_user(); + + return sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); + } + function read( $prompt ) { $line = trim( readline( $prompt ) ); if ( !empty( $line ) ) From 775897b32ca947914d3f3e4352e2dd26f1bab410 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Oct 2012 11:25:17 -0400 Subject: [PATCH 0741/4858] attempt to catch termination signals BUGS: * Ctrl+D still isn't handled properly * Ctrl+C now requires a RETURN because readline blocks --- src/php/wp-cli/commands/internals/shell.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 12a04dfafc..57f27519ad 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -52,6 +52,23 @@ function __construct() { readline_read_history( $this->hist_path ); register_shutdown_function( array( $this, 'save_history' ) ); + + declare( ticks = 1 ); + pcntl_signal( SIGINT, array( $this, 'catch_signal' ) ); + pcntl_signal( SIGTERM, array( $this, 'catch_signal' ) ); + pcntl_signal( SIGSEGV, array( $this, 'catch_signal' ) ); + pcntl_signal( SIGQUIT, array( $this, 'catch_signal' ) ); + } + + function catch_signal( $signo ) { + switch ( $signo ) { + case SIGTERM: + case SIGSEGV: + case SIGQUIT: + case SIGABRT: + case SIGINT: + exit; // ensures clean shutdown + } } private static function get_history_path() { From 2296c4c285fa264d997b03247538adacb993effc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Oct 2012 13:12:19 -0400 Subject: [PATCH 0742/4858] Revert "attempt to catch termination signals" This reverts commit 775897b32ca947914d3f3e4352e2dd26f1bab410. --- src/php/wp-cli/commands/internals/shell.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 57f27519ad..12a04dfafc 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -52,23 +52,6 @@ function __construct() { readline_read_history( $this->hist_path ); register_shutdown_function( array( $this, 'save_history' ) ); - - declare( ticks = 1 ); - pcntl_signal( SIGINT, array( $this, 'catch_signal' ) ); - pcntl_signal( SIGTERM, array( $this, 'catch_signal' ) ); - pcntl_signal( SIGSEGV, array( $this, 'catch_signal' ) ); - pcntl_signal( SIGQUIT, array( $this, 'catch_signal' ) ); - } - - function catch_signal( $signo ) { - switch ( $signo ) { - case SIGTERM: - case SIGSEGV: - case SIGQUIT: - case SIGABRT: - case SIGINT: - exit; // ensures clean shutdown - } } private static function get_history_path() { From e916a66e513845212723ee6fb596b6fe9e0ca531 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Oct 2012 13:14:53 -0400 Subject: [PATCH 0743/4858] add notice about correct closing method --- src/php/wp-cli/commands/internals/shell.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 12a04dfafc..38592e44b6 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -16,6 +16,8 @@ public function __invoke() { $repl = new REPL_Basic; } + \WP_CLI::line( 'Type "exit" to close session.' ); + $non_expressions = array( 'echo', 'return', 'global', 'while', 'for', 'foreach', 'if', 'switch', From 901414f92e9a2f88e4d5ae7026f10df936fbca57 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Oct 2012 14:31:38 -0400 Subject: [PATCH 0744/4858] ignore --ID parameter for wp post create, to avoid confusion --- src/php/wp-cli/commands/internals/post.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 22335357c6..11065286b9 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -15,7 +15,9 @@ class Post_Command extends WP_CLI_Command { * * @synopsis --<field>=<value> [--porcelain] */ - public function create( $args, $assoc_args ) { + public function create( $_, $assoc_args ) { + unset( $assoc_args['ID'] ); + $post_id = wp_insert_post( $assoc_args, true ); if ( is_wp_error( $post_id ) ) { From f7c61bd5dc92aa3073d2911b8276f677ea791494 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Oct 2012 14:37:31 -0400 Subject: [PATCH 0745/4858] fix wp post delete --force --- src/php/wp-cli/commands/internals/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index 11065286b9..c05c3b8d4a 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -60,7 +60,7 @@ public function delete( $post_ids, $assoc_args ) { $action = isset( $assoc_args['force'] ) ? 'Deleted' : 'Trashed'; foreach ( $post_ids as $post_id ) { - if ( wp_delete_post( $post_id, $force ) ) { + if ( wp_delete_post( $post_id, $assoc_args['force'] ) ) { WP_CLI::success( "{$action} post $post_id." ); } else { WP_CLI::error( "Failed deleting post $post_id." ); From 3ace64b97ac159ee713b5c4e024283b83f8aceee Mon Sep 17 00:00:00 2001 From: Taylor Dewey <td@tddewey.com> Date: Wed, 31 Oct 2012 22:07:10 -0700 Subject: [PATCH 0746/4858] WP Export: Add export arguments as a class variable Adds the export arguments that eventually get passed to export_wp() as a class variable. Fixes #197 --- src/php/wp-cli/commands/internals/export.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 96527aface..11439cb805 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -10,6 +10,12 @@ */ class Export_Command extends WP_CLI_Command { + /** + * Initialize the array of arguments that will be eventually be passed to export_wp + * @var array + */ + public $export_args = array(); + /** * Export posts to a WXR file. * From 06b5beeefa9176d132ac28c8fcab2919c26bf9ab Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 11:54:49 -0700 Subject: [PATCH 0747/4858] A utility method for parsing a given CSV --- src/php/wp-cli/utils.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index 1e49fcb89e..3c912d7a78 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -156,3 +156,26 @@ function get_upgrader( $class ) { return new $class( new \CLI_Upgrader_Skin ); } +function parse_csv( $filepath, $has_headers = true ) { + + if ( false == ( $csv = fopen( $filepath, 'r' ) ) ) + \WP_CLI::error( sprintf( 'Could not open csv file: %s', $filepath ) ); + + $parsed_data = array(); + $headers = array(); + while ( ( $row = fgetcsv( $csv, 10000, "," ) ) !== FALSE ) { + if ( $has_headers ) { + $headers = array_values( $row ); + $has_headers = false; + continue; + } + $row_data = array(); + foreach( $row as $index => $cell_value ) { + if ( ! empty( $headers[$index] ) ) + $index = $headers[$index]; + $row_data[$index] = $cell_value; + } + $parsed_data[] = $row_data; + } + return $parsed_data; +} From 8f48e4e92df029bd599d300f21bdc14a325f58cc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 12:00:57 -0700 Subject: [PATCH 0748/4858] New user subcommand for importing users from a CSV The behavior of the subcommand is two-fold: create the users if they don't yet exist, or assign them to the blog if they do exist but aren't yet a member See #167 --- src/docs/user-import-csv.txt | 9 ++++ src/php/wp-cli/commands/internals/user.php | 59 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/docs/user-import-csv.txt diff --git a/src/docs/user-import-csv.txt b/src/docs/user-import-csv.txt new file mode 100644 index 0000000000..ca39f28ef1 --- /dev/null +++ b/src/docs/user-import-csv.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `<file>`: + + The csv file of users to import + +## EXAMPLES + + wp user import_csv /path/to/csv.csv diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 6864fd124f..5e7451042d 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -197,4 +197,63 @@ public function generate( $args, $assoc_args ) { $notify->finish(); } + + /** + * Import users from a CSV + * + * @synopsis <file> + */ + public function import_csv( $args, $assoc_args ) { + + list( $csv ) = $args; + + $new_users = \WP_CLI\utils\parse_csv( $csv ); + + $blog_users = get_users(); + + foreach( $new_users as $new_user ) { + + $defaults = array( + 'role' => get_option('default_role'), + 'user_pass' => wp_generate_password(), + 'user_registered' => strftime( "%F %T", time() ), + 'display_name' => false, + ); + $new_user = array_merge( $new_user, $defaults ); + + if ( 'none' == $new_user['role'] ) { + $new_user['role'] = false; + } elseif ( is_null( get_role( $new_user['role'] ) ) ) { + WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); + continue; + } + + // User already exists and we just need to add them to the site if they aren't already there + if ( $existing_user = get_user_by( 'login', $new_user['user_login'] ) ) { + if ( in_array( $new_user['user_login'], wp_list_pluck( $blog_users, 'user_login' ) ) ) + WP_CLI::warning( "{$new_user['user_login']} already is a member of blog" ); + else if ( $new_user['role'] ) { + add_user_to_blog( get_current_blog_id(), $new_user['user_login'], $new_user['role'] ); + WP_CLI::line( "{$new_user['user_login']} added to blog as {$new_user['role']}" ); + } else { + WP_CLI::line( "{$new_user['user_login']} exists, but won't be added to the blog" ); + } + continue; + } + + $user_id = wp_insert_user( $new_user ); + + if ( is_wp_error( $user_id ) ) { + WP_CLI::warning( $user_id ); + } else { + if ( false === $new_user['role'] ) { + delete_user_option( $user_id, 'capabilities' ); + delete_user_option( $user_id, 'user_level' ); + } + } + + WP_CLI::line( "{$new_user['user_login']} created" ); + + } + } } From 7c2dbba1e93bd441c113c00549179cd71ac39fd2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 20:30:46 +0000 Subject: [PATCH 0749/4858] Merge in proper order so $new_user values aren't overwritten by $default --- src/php/wp-cli/commands/internals/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 5e7451042d..cdcef1aa64 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -219,7 +219,7 @@ public function import_csv( $args, $assoc_args ) { 'user_registered' => strftime( "%F %T", time() ), 'display_name' => false, ); - $new_user = array_merge( $new_user, $defaults ); + $new_user = array_merge( $defaults, $new_user ); if ( 'none' == $new_user['role'] ) { $new_user['role'] = false; From d2adba913d0445d51cb38fc9170ffbb3892b4d02 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:12:10 +0000 Subject: [PATCH 0750/4858] check_end_date() validator should set the 'end_date' argument --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 11439cb805..15ff792179 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -91,7 +91,7 @@ private function check_end_date( $date ) { WP_CLI::warning( sprintf( "The end_date %s is invalid", $date ) ); return false; } - $this->export_args['start_date'] = date( 'Y-m-d', $time ); + $this->export_args['end_date'] = date( 'Y-m-d', $time ); return true; } From 3c669482002cc898ea083beea5710fa64c0c693f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:18:25 +0000 Subject: [PATCH 0751/4858] With 'end_date' properly set, we don't need add a month to the value --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 15ff792179..55482383a0 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -266,7 +266,7 @@ private function export_wp( $args = array() ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); if ( $args['end_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime( '+1 month', strtotime( $args['end_date'] ) ) ) ); + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime( $args['end_date'] ) ) ); } // grab a snapshot of post IDs, just in case it changes during the export From 08013d6bdd4ee5d9c3e1d277fa21af133f3564c8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:31:33 +0000 Subject: [PATCH 0752/4858] Rename the 'content' argument to 'post_type' for clarity --- src/php/wp-cli/commands/internals/export.php | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 55482383a0..5d788d8973 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -104,7 +104,7 @@ private function check_post_type( $post_type ) { WP_CLI::warning( sprintf( 'The post type %s does not exists. Choose "all" or any of these existing post types instead: %s', $post_type, implode( ", ", $post_types ) ) ); return false; } - $this->export_args['content'] = $post_type; + $this->export_args['post_type'] = $post_type; return true; } @@ -213,7 +213,7 @@ private function export_wp( $args = array() ) { /** * This is mostly the original code of export_wp defined in wp-admin/includes/export.php */ - $defaults = array( 'content' => 'all', 'author' => false, 'category' => false, + $defaults = array( 'post_type' => 'all', 'author' => false, 'category' => false, 'start_date' => false, 'end_date' => false, 'status' => false, 'skip_comments' => false, ); $args = wp_parse_args( $args, $defaults ); @@ -233,32 +233,32 @@ private function export_wp( $args = array() ) { } $file_name_base = $sitename . 'wordpress.' . implode( ".", $append ); - if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) { - $ptype = get_post_type_object( $args['content'] ); + if ( 'all' != $args['post_type'] && post_type_exists( $args['post_type'] ) ) { + $ptype = get_post_type_object( $args['post_type'] ); if ( ! $ptype->can_export ) - $args['content'] = 'post'; + $args['post_type'] = 'post'; - $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['content'] ); + $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['post_type'] ); } else { $post_types = get_post_types( array( 'can_export' => true ) ); $esses = array_fill( 0, count( $post_types ), '%s' ); $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (" . implode( ',', $esses ) . ')', $post_types ); } - if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) ) + if ( $args['status'] && ( 'post' == $args['post_type'] || 'page' == $args['post_type'] ) ) $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] ); else $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'"; $join = ''; - if ( $args['category'] && 'post' == $args['content'] ) { + if ( $args['category'] && 'post' == $args['post_type'] ) { if ( $term = term_exists( $args['category'], 'category' ) ) { $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)"; $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] ); } } - if ( 'post' == $args['content'] || 'page' == $args['content'] ) { + if ( 'post' == $args['post_type'] || 'page' == $args['post_type'] ) { if ( $args['author'] ) $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); @@ -278,7 +278,7 @@ private function export_wp( $args = array() ) { $cat = get_term( $term['term_id'], 'category' ); $cats = array( $cat->term_id => $cat ); unset( $term, $cat ); - } else if ( 'all' == $args['content'] ) { + } else if ( 'all' == $args['post_type'] ) { $categories = (array) get_categories( array( 'get' => 'all' ) ); $tags = (array) get_tags( array( 'get' => 'all' ) ); @@ -364,7 +364,7 @@ private function export_wp( $args = array() ) { <?php foreach ( $terms as $t ) : ?> <wp:term><wp:term_id><?php echo $t->term_id ?></wp:term_id><wp:term_taxonomy><?php echo $t->taxonomy; ?></wp:term_taxonomy><wp:term_slug><?php echo $t->slug; ?></wp:term_slug><wp:term_parent><?php echo $t->parent ? $terms[$t->parent]->slug : ''; ?></wp:term_parent><?php wxr_term_name( $t ); ?><?php wxr_term_description( $t ); ?></wp:term> <?php endforeach; ?> -<?php if ( 'all' == $args['content'] ) wxr_nav_menu_terms(); ?> +<?php if ( 'all' == $args['post_type'] ) wxr_nav_menu_terms(); ?> <?php do_action( 'rss2_head' ); ?> From edd4dea23e8b82926ee896474f895b73a73b8c08 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:35:14 +0000 Subject: [PATCH 0753/4858] ORDER BY post_date and post_parent to avoid getting attachments stacked up front when doing an 'all' post_type export https://github.com/Automattic/WordPress-CLI-Exporter/commit/b759208e8593ce504f9934804ee582bf00d68e35 --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 5d788d8973..a90cd62af9 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -270,7 +270,7 @@ private function export_wp( $args = array() ) { } // grab a snapshot of post IDs, just in case it changes during the export - $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" ); + $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); // get the requested terms ready, empty unless posts filtered by category or all content $cats = $tags = $terms = array(); From 0378bb9ba18a5da44069d029f3f719d7ab3c1bac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:41:31 +0000 Subject: [PATCH 0754/4858] When looking up a specific post type, ensure we grab their attachments too https://github.com/Automattic/WordPress-CLI-Exporter/commit/b7cfda1c052fe64088d55f21a580d061fb6d6b03 --- src/php/wp-cli/commands/internals/export.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index a90cd62af9..e285de0954 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -378,6 +378,12 @@ private function export_wp( $args = array() ) { $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')'; $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" ); + if ( 'all' != $args['post_type'] ) { + $attachment_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent IN (". implode( ",", array_map( 'intval', $post_ids ) ) .")" ); + if ( is_array( $attachment_ids ) ) + $posts = array_merge( $posts, array_map( 'get_post', $attachment_ids ) ); + } + // Begin Loop foreach ( $posts as $post ) { From 287a4e8ab7a9faa97308655e61f9829667dbd4bd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:51:16 +0000 Subject: [PATCH 0755/4858] All post types should be able to use the 'author' and date range flags --- src/php/wp-cli/commands/internals/export.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index e285de0954..7bd66afd2d 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -258,16 +258,15 @@ private function export_wp( $args = array() ) { } } - if ( 'post' == $args['post_type'] || 'page' == $args['post_type'] ) { - if ( $args['author'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); + + if ( $args['author'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); - if ( $args['start_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); + if ( $args['start_date'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); - if ( $args['end_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime( $args['end_date'] ) ) ); - } + if ( $args['end_date'] ) + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime( $args['end_date'] ) ) ); // grab a snapshot of post IDs, just in case it changes during the export $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); From 0029888e254bb92b7507fb9125e1df0f833fc778 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:53:24 +0000 Subject: [PATCH 0756/4858] Ensure the target directory is trailing slashed, because we expect it to be later --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 7bd66afd2d..e060622b0c 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -49,7 +49,7 @@ public function __invoke( $args, $assoc_args ) { exit(1); } - $this->wxr_path = $assoc_args['dir']; + $this->wxr_path = trailingslashit( $assoc_args['dir'] ); WP_CLI::line( 'Starting export process...' ); WP_CLI::line(); From b56cd2a3b1e21ff4d3dd45d7442bf28f8cc4b87b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 22:04:20 +0000 Subject: [PATCH 0757/4858] More explicit dates for the date range --- src/php/wp-cli/commands/internals/export.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index e060622b0c..d58dceadfd 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -263,10 +263,10 @@ private function export_wp( $args = array() ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); if ( $args['start_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s 00:00:00", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); if ( $args['end_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime( $args['end_date'] ) ) ); + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date <= %s 23:59:59", date( 'Y-m-d', strtotime( $args['end_date'] ) ) ); // grab a snapshot of post IDs, just in case it changes during the export $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); From 139737224a0582849ed30b066f31a91776942153 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 22:09:23 +0000 Subject: [PATCH 0758/4858] To significantly improve the performance on export, explicitly define the functions used to generate the WXR Although the previous approach passed a dummy content type, it still had to spend a lot of time getting all of the taxonomy terms, etc. --- src/php/wp-cli/commands/internals/export.php | 126 ++++++++++++++++++- 1 file changed, 120 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index d58dceadfd..d59ae99563 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -203,12 +203,7 @@ private function stop_the_insanity() { private function export_wp( $args = array() ) { require_once ABSPATH . 'wp-admin/includes/export.php'; - global $wpdb, $post; - // call export_wp as we need the functions defined in it. - $dummy_args = array( 'content' => 'i-do-not-exist' ); - ob_start(); - export_wp( $dummy_args ); - ob_end_clean(); + global $wpdb; /** * This is mostly the original code of export_wp defined in wp-admin/includes/export.php @@ -303,6 +298,125 @@ private function export_wp( $args = array() ) { unset( $categories, $custom_taxonomies, $custom_terms ); } + /** + * Functions normally defined in wp-admin/includes/export.php + */ + function wxr_cdata( $str ) { + if ( seems_utf8( $str ) == false ) + $str = utf8_encode( $str ); + + // $str = ent2ncr(esc_html($str)); + $str = '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $str ) . ']]>'; + + return $str; + } + + function wxr_site_url() { + // ms: the base url + if ( is_multisite() ) + return network_home_url(); + // wp: the blog url + else + return get_bloginfo_rss( 'url' ); + } + + function wxr_cat_name( $category ) { + if ( empty( $category->name ) ) + return; + + echo '<wp:cat_name>' . wxr_cdata( $category->name ) . '</wp:cat_name>'; + } + + function wxr_category_description( $category ) { + if ( empty( $category->description ) ) + return; + + echo '<wp:category_description>' . wxr_cdata( $category->description ) . '</wp:category_description>'; + } + + function wxr_tag_name( $tag ) { + if ( empty( $tag->name ) ) + return; + + echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . '</wp:tag_name>'; + } + + + function wxr_tag_description( $tag ) { + if ( empty( $tag->description ) ) + return; + + echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . '</wp:tag_description>'; + } + + function wxr_term_name( $term ) { + if ( empty( $term->name ) ) + return; + + echo '<wp:term_name>' . wxr_cdata( $term->name ) . '</wp:term_name>'; + } + + function wxr_term_description( $term ) { + if ( empty( $term->description ) ) + return; + + echo '<wp:term_description>' . wxr_cdata( $term->description ) . '</wp:term_description>'; + } + + function wxr_authors_list() { + global $wpdb; + + $authors = array(); + $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft'" ); + foreach ( (array) $results as $result ) + $authors[] = get_userdata( $result->post_author ); + + $authors = array_filter( $authors ); + + foreach ( $authors as $author ) { + echo "\t<wp:author>"; + echo '<wp:author_id>' . $author->ID . '</wp:author_id>'; + echo '<wp:author_login>' . $author->user_login . '</wp:author_login>'; + echo '<wp:author_email>' . $author->user_email . '</wp:author_email>'; + echo '<wp:author_display_name>' . wxr_cdata( $author->display_name ) . '</wp:author_display_name>'; + echo '<wp:author_first_name>' . wxr_cdata( $author->user_firstname ) . '</wp:author_first_name>'; + echo '<wp:author_last_name>' . wxr_cdata( $author->user_lastname ) . '</wp:author_last_name>'; + echo "</wp:author>\n"; + } + } + + function wxr_nav_menu_terms() { + $nav_menus = wp_get_nav_menus(); + if ( empty( $nav_menus ) || ! is_array( $nav_menus ) ) + return; + + foreach ( $nav_menus as $menu ) { + echo "\t<wp:term><wp:term_id>{$menu->term_id}</wp:term_id><wp:term_taxonomy>nav_menu</wp:term_taxonomy><wp:term_slug>{$menu->slug}</wp:term_slug>"; + wxr_term_name( $menu ); + echo "</wp:term>\n"; + } + } + + function wxr_post_taxonomy() { + $post = get_post(); + + $taxonomies = get_object_taxonomies( $post->post_type ); + if ( empty( $taxonomies ) ) + return; + $terms = wp_get_object_terms( $post->ID, $taxonomies ); + + foreach ( (array) $terms as $term ) { + echo "\t\t<category domain=\"{$term->taxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "</category>\n"; + } + } + + function wxr_filter_postmeta( $return_me, $meta_key ) { + if ( '_edit_lock' == $meta_key ) + $return_me = true; + return $return_me; + } + add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 ); + WP_CLI::line( 'Exporting ' . count( $post_ids ) . ' items' ); WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); From 4d1250d31bbd898a6037790f591037a1030d207e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 22:16:24 +0000 Subject: [PATCH 0759/4858] Fix SQL syntax issue --- src/php/wp-cli/commands/internals/export.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index d59ae99563..ba3f187403 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -258,10 +258,10 @@ private function export_wp( $args = array() ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); if ( $args['start_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s 00:00:00", date( 'Y-m-d', strtotime( $args['start_date'] ) ) ); + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d 00:00:00', strtotime( $args['start_date'] ) ) ); if ( $args['end_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date <= %s 23:59:59", date( 'Y-m-d', strtotime( $args['end_date'] ) ) ); + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date <= %s", date( 'Y-m-d 23:59:59', strtotime( $args['end_date'] ) ) ); // grab a snapshot of post IDs, just in case it changes during the export $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); From 3fcd2d7cb60ac7dd8db52d3c4010418dd77fc112 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 22:16:51 +0000 Subject: [PATCH 0760/4858] WXR is a XML derivative --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index ba3f187403..53dee8b7dd 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -575,7 +575,7 @@ function wxr_filter_postmeta( $return_me, $meta_key ) { $result = ob_get_clean(); - $full_path = $this->wxr_path . $file_name_base . '.wxr'; + $full_path = $this->wxr_path . $file_name_base . '.xml'; if ( !file_exists( $full_path ) || is_writeable( $full_path ) ) { WP_CLI::line( 'Writing to ' . $full_path ); From e6d2d65357fc331042c2942bbca779a2dd50fa36 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 23:36:13 +0000 Subject: [PATCH 0761/4858] For increased performance with large datasets, automagically break the export files into sets of 1000 posts and dump the output buffer much more regularly --- src/php/wp-cli/commands/internals/export.php | 94 ++++++++++++++------ 1 file changed, 69 insertions(+), 25 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 53dee8b7dd..bef0f32003 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -19,25 +19,26 @@ class Export_Command extends WP_CLI_Command { /** * Export posts to a WXR file. * - * @synopsis --dir=<dir> [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] + * @synopsis --dir=<dir> [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] */ public function __invoke( $args, $assoc_args ) { $defaults = array( - 'dir' => NULL, - 'start_date' => NULL, - 'end_date' => NULL, - 'post_type' => NULL, - 'author' => NULL, - 'category' => NULL, - 'post_status' => NULL, - 'skip_comments' => NULL, + 'dir' => NULL, + 'start_date' => NULL, + 'end_date' => NULL, + 'post_type' => NULL, + 'author' => NULL, + 'category' => NULL, + 'post_status' => NULL, + 'skip_comments' => NULL, + 'file_item_count' => 1000, ); $args = wp_parse_args( $assoc_args, $defaults ); $has_errors = false; - - foreach( $defaults as $argument => $default_value ) { + + foreach( $args as $argument => $default_value ) { if ( is_callable( array( &$this, 'check_' . $argument ) ) ) { $result = call_user_func( array( &$this, 'check_' . $argument ), $args[$argument] ); if ( false === $result && false === $has_errors ) @@ -179,6 +180,16 @@ private function check_skip_comments( $skip ) { return true; } + private function check_file_item_count( $file_item_count ) { + + if ( ! is_numeric( $file_item_count ) ) { + WP_CLI::warning( 'File item count needs to be numeric' ); + return false; + } + $this->export_args['file_item_count'] = $file_item_count; + return true; + } + /** * Workaround to prevent memory leaks from growing variables @@ -196,6 +207,22 @@ private function stop_the_insanity() { $wp_object_cache->__remoteset(); // important } + private function start_export() { + ob_start(); + } + + private function end_export() { + ob_end_clean(); + } + + private function flush_export( $file_path, $append = true ) { + $result = ob_get_clean(); + if ( $append ) + $append = FILE_APPEND; + file_put_contents( $file_path, $result, $append ); + $this->start_export(); + } + /** * Export function as it is defined in the original code of export_wp defined in wp-admin/includes/export.php */ @@ -209,7 +236,7 @@ private function export_wp( $args = array() ) { * This is mostly the original code of export_wp defined in wp-admin/includes/export.php */ $defaults = array( 'post_type' => 'all', 'author' => false, 'category' => false, - 'start_date' => false, 'end_date' => false, 'status' => false, 'skip_comments' => false, + 'start_date' => false, 'end_date' => false, 'status' => false, 'skip_comments' => false, 'file_item_count' => 1000, ); $args = wp_parse_args( $args, $defaults ); @@ -264,7 +291,7 @@ private function export_wp( $args = array() ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date <= %s", date( 'Y-m-d 23:59:59', strtotime( $args['end_date'] ) ) ); // grab a snapshot of post IDs, just in case it changes during the export - $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); + $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); // get the requested terms ready, empty unless posts filtered by category or all content $cats = $tags = $terms = array(); @@ -418,15 +445,33 @@ function wxr_filter_postmeta( $return_me, $meta_key ) { add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 ); - WP_CLI::line( 'Exporting ' . count( $post_ids ) . ' items' ); + WP_CLI::line( 'Exporting ' . count( $all_the_post_ids ) . ' items to be broken into ' . ceil( count( $all_the_post_ids ) / $args['file_item_count'] ) . ' files' ); WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); WP_CLI::line( 'Exporting ' . count( $tags ) . ' tags' ); WP_CLI::line( 'Exporting ' . count( $terms ) . ' terms' ); WP_CLI::line(); - $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); + $file_count = 1; - ob_start(); + while ( $post_ids = array_splice( $all_the_post_ids, 0, $args['file_item_count'] ) ) { + + $full_path = $this->wxr_path . $file_name_base . '.' . str_pad( $file_count, 3, '0', STR_PAD_LEFT ) . '.xml'; + + // Create the file if it doesn't exist + if ( ! file_exists( $full_path ) ) { + touch( $full_path ); + } + + if ( ! file_exists( $full_path ) ) { + WP_CLI::error( "Failed to create file " . $full_path ); + exit; + } else { + WP_CLI::line( 'Writing to file ' . $full_path ); + } + + $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); + + $this->start_export(); echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . "\" ?>\n"; ?> @@ -480,6 +525,7 @@ function wxr_filter_postmeta( $return_me, $meta_key ) { <?php if ( 'all' == $args['post_type'] ) wxr_nav_menu_terms(); ?> <?php do_action( 'rss2_head' ); ?> + <?php $this->flush_export( $full_path, false ); ?> <?php if ( $post_ids ) { global $wp_query; @@ -565,21 +611,19 @@ function wxr_filter_postmeta( $return_me, $meta_key ) { <?php endif; ?> </item> <?php + $this->flush_export( $full_path ); } } } ?> </channel> </rss> <?php - $progress->finish(); - - $result = ob_get_clean(); - - $full_path = $this->wxr_path . $file_name_base . '.xml'; - - if ( !file_exists( $full_path ) || is_writeable( $full_path ) ) { - WP_CLI::line( 'Writing to ' . $full_path ); - file_put_contents( $full_path, $result ); + $this->flush_export( $full_path ); + $this->end_export(); + $this->stop_the_insanity(); + $progress->finish(); + $file_count++; } + WP_CLI::success( "All done with export" ); } } From 4f2098179d71a1aa61719fff8970eb99658bfca1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 23:40:11 +0000 Subject: [PATCH 0762/4858] Copy pasta fixes --- src/php/wp-cli/commands/internals/export.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index bef0f32003..ade057026e 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -156,7 +156,7 @@ private function check_post_status( $status ) { $stati = get_post_statuses(); if ( empty( $stati ) || is_wp_error( $stati ) ) { - WP_CLI::warning( sprintf( 'Could not find any post stati', $category ) ); + WP_CLI::warning( 'Could not find any post stati' ); return false; } @@ -173,7 +173,7 @@ private function check_skip_comments( $skip ) { return true; if ( (int) $skip <> 0 && (int) $skip <> 1 ) { - WP_CLI::warning( sprintf( 'skip_comments needs to be 0 (no) or 1 (yes)', $category ) ); + WP_CLI::warning( 'skip_comments needs to be 0 (no) or 1 (yes)' ); return false; } $this->export_args['skip_comments'] = $skip; From 0a842848583c774279ad113d4b1335b7c825355d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Nov 2012 19:53:14 -0400 Subject: [PATCH 0763/4858] first pass at WP_CLI::add_man_dir() --- src/php/wp-cli/class-wp-cli.php | 15 ++++++++++++++- src/php/wp-cli/commands/internals/help.php | 11 +++++++---- src/php/wp-cli/man.php | 12 +++++++----- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 927803ed62..eb2992fec3 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -10,6 +10,7 @@ class WP_CLI { private static $commands = array(); + private static $man_dirs = array(); /** * Add a command to the wp-cli list of commands @@ -26,6 +27,16 @@ static function add_command( $name, $class ) { self::$commands[ $name ] = $command; } + static function add_man_dir( $path ) { + $path = realpath( $path ) . '/'; + + self::$man_dirs[ $path ] = true; + } + + static function get_man_dirs() { + return array_keys( self::$man_dirs ); + } + /** * Display a message in the cli * @@ -218,6 +229,8 @@ static function load_command( $command ) { private static $arguments, $assoc_args, $assoc_special; static function before_wp_load() { + self::add_man_dir( WP_CLI_ROOT . "../../../man/" ); + $r = WP_CLI\Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); list( self::$arguments, self::$assoc_args ) = $r; @@ -314,7 +327,7 @@ private static function generate_man( $args ) { if ( !$command ) WP_CLI::error( sprintf( "'%s' command not found." ) ); - \WP_CLI\Man\generate( $command ); + \WP_CLI\Man\generate( key( self::$man_dirs ), $command ); } private static function render_automcomplete() { diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 16a3a2c4d7..9b555263f0 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -28,11 +28,14 @@ function __invoke( $args ) { } private static function maybe_load_man_page( $args ) { - $man_file = \WP_CLI\Man\get_path( $args ); + $man_file = \WP_CLI\Man\get_file_name( $args ); - if ( is_readable( $man_file ) ) { - exit( WP_CLI::launch( "man $man_file" ) ); + foreach ( \WP_CLI::get_man_dirs() as $dir ) { + $man_path = $dir . $man_file; + + if ( is_readable( $man_path ) ) { + exit( WP_CLI::launch( "man $man_path" ) ); + } } } } - diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index 379f09c6ea..44aafe724c 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -4,20 +4,22 @@ use \WP_CLI\Dispatcher; -function get_path( $args ) { - return WP_CLI_ROOT . "../../../man/" . implode( '-', $args ) . '.1'; +function get_file_name( $args ) { + return implode( '-', $args ) . '.1'; } function get_src_path( $args ) { return WP_CLI_ROOT . "../../docs/" . implode( '-', $args ) . '.txt'; } -function generate( $command ) { - call_ronn( get_markdown( $command ), get_path( $command->get_path() ) ); +function generate( $dir, $command ) { + $man_path = $dir . get_file_name( $command->get_path() ); + + call_ronn( get_markdown( $command ), $man_path ); if ( $command instanceof Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) { - generate( $subcommand ); + generate( $dir, $subcommand ); } } } From b77daaa3710ae2a84e993039bbcd8e8a1d526b33 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Nov 2012 19:59:14 -0400 Subject: [PATCH 0764/4858] move man source files to WP_CLI class --- src/php/wp-cli/class-wp-cli.php | 5 ++++- src/php/wp-cli/man.php | 16 ++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index eb2992fec3..ce57caf027 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -327,7 +327,10 @@ private static function generate_man( $args ) { if ( !$command ) WP_CLI::error( sprintf( "'%s' command not found." ) ); - \WP_CLI\Man\generate( key( self::$man_dirs ), $command ); + $src_dir = WP_CLI_ROOT . "../../docs/"; + $dest_dir = key( self::$man_dirs ); + + \WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); } private static function render_automcomplete() { diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index 44aafe724c..a058ab3054 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -8,30 +8,30 @@ function get_file_name( $args ) { return implode( '-', $args ) . '.1'; } -function get_src_path( $args ) { - return WP_CLI_ROOT . "../../docs/" . implode( '-', $args ) . '.txt'; +function get_src_file_name( $args ) { + return implode( '-', $args ) . '.txt'; } -function generate( $dir, $command ) { - $man_path = $dir . get_file_name( $command->get_path() ); +function generate( $src_dir, $dest_dir, $command ) { + $man_path = $dest_dir . get_file_name( $command->get_path() ); - call_ronn( get_markdown( $command ), $man_path ); + call_ronn( get_markdown( $src_dir, $command ), $man_path ); if ( $command instanceof Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) { - generate( $dir, $subcommand ); + generate( $src_dir, $dest_dir, $subcommand ); } } } // returns a file descriptor or false -function get_markdown( $command ) { +function get_markdown( $src_dir, $command ) { $fd = fopen( "php://temp", "rw" ); if ( $command instanceof Dispatcher\Documentable ) add_initial_markdown( $fd, $command ); - $doc_path = get_src_path( $command->get_path() ); + $doc_path = $src_dir . get_src_file_name( $command->get_path() ); if ( file_exists( $doc_path ) ) fwrite( $fd, file_get_contents( $doc_path ) ); From 84f535b8686c442470d34fdb518964a90c4699e3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Nov 2012 20:10:10 -0400 Subject: [PATCH 0765/4858] store man source file dir together with destination dir --- src/php/wp-cli/class-wp-cli.php | 23 +++++++++++++--------- src/php/wp-cli/commands/internals/help.php | 4 ++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index ce57caf027..dcb4131f06 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -27,14 +27,17 @@ static function add_command( $name, $class ) { self::$commands[ $name ] = $command; } - static function add_man_dir( $path ) { - $path = realpath( $path ) . '/'; + static function add_man_dir( $dest_dir, $src_dir ) { + $dest_dir = realpath( $dest_dir ) . '/'; - self::$man_dirs[ $path ] = true; + if ( $src_dir ) + $src_dir = realpath( $src_dir ) . '/'; + + self::$man_dirs[ $dest_dir ] = $src_dir; } static function get_man_dirs() { - return array_keys( self::$man_dirs ); + return self::$man_dirs; } /** @@ -229,7 +232,10 @@ static function load_command( $command ) { private static $arguments, $assoc_args, $assoc_special; static function before_wp_load() { - self::add_man_dir( WP_CLI_ROOT . "../../../man/" ); + self::add_man_dir( + WP_CLI_ROOT . "../../../man/", + WP_CLI_ROOT . "../../docs/" + ); $r = WP_CLI\Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -327,10 +333,9 @@ private static function generate_man( $args ) { if ( !$command ) WP_CLI::error( sprintf( "'%s' command not found." ) ); - $src_dir = WP_CLI_ROOT . "../../docs/"; - $dest_dir = key( self::$man_dirs ); - - \WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + foreach ( self::$man_dirs as $dest_dir => $src_dir ) { + \WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + } } private static function render_automcomplete() { diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/internals/help.php index 9b555263f0..11fa2aa6a7 100644 --- a/src/php/wp-cli/commands/internals/help.php +++ b/src/php/wp-cli/commands/internals/help.php @@ -30,8 +30,8 @@ function __invoke( $args ) { private static function maybe_load_man_page( $args ) { $man_file = \WP_CLI\Man\get_file_name( $args ); - foreach ( \WP_CLI::get_man_dirs() as $dir ) { - $man_path = $dir . $man_file; + foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { + $man_path = $dest_dir . $man_file; if ( is_readable( $man_path ) ) { exit( WP_CLI::launch( "man $man_path" ) ); From cdd88d8175ca47ae16948647ca757aee6a692d25 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Nov 2012 20:15:47 -0400 Subject: [PATCH 0766/4858] generate man only if src file exists --- src/php/wp-cli/man.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index a058ab3054..b2cc467103 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -13,9 +13,10 @@ function get_src_file_name( $args ) { } function generate( $src_dir, $dest_dir, $command ) { - $man_path = $dest_dir . get_file_name( $command->get_path() ); + $src_path = $src_dir . get_src_file_name( $command->get_path() ); + $dest_path = $dest_dir . get_file_name( $command->get_path() ); - call_ronn( get_markdown( $src_dir, $command ), $man_path ); + call_ronn( get_markdown( $src_path, $command ), $dest_path ); if ( $command instanceof Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) { @@ -25,16 +26,16 @@ function generate( $src_dir, $dest_dir, $command ) { } // returns a file descriptor or false -function get_markdown( $src_dir, $command ) { +function get_markdown( $doc_path, $command ) { + if ( !file_exists( $doc_path ) ) + return false; + $fd = fopen( "php://temp", "rw" ); if ( $command instanceof Dispatcher\Documentable ) add_initial_markdown( $fd, $command ); - $doc_path = $src_dir . get_src_file_name( $command->get_path() ); - - if ( file_exists( $doc_path ) ) - fwrite( $fd, file_get_contents( $doc_path ) ); + fwrite( $fd, file_get_contents( $doc_path ) ); if ( 0 === ftell( $fd ) ) return false; From dfbd5a3cd2243526b18fe1d3dbe8cee6eb426acd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 01:59:13 +0200 Subject: [PATCH 0767/4858] rename $class to $implementation --- src/php/wp-cli/class-wp-cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index dcb4131f06..0129f41ce4 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -16,13 +16,13 @@ class WP_CLI { * Add a command to the wp-cli list of commands * * @param string $name The name of the command that will be used in the cli - * @param string $class The class to manage the command + * @param string|object $implementation The command implementation */ - static function add_command( $name, $class ) { - if ( is_string( $class ) ) - $command = new Dispatcher\CompositeCommand( $name, $class ); + static function add_command( $name, $implementation ) { + if ( is_string( $implementation ) ) + $command = new Dispatcher\CompositeCommand( $name, $implementation ); else - $command = new Dispatcher\SingleCommand( $name, $class ); + $command = new Dispatcher\SingleCommand( $name, $implementation ); self::$commands[ $name ] = $command; } From 76746d73b321ad796d89c2368356275ff9ae0583 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 02:28:50 +0200 Subject: [PATCH 0768/4858] move static arguments to the top of the WP_CLI class --- src/php/wp-cli/class-wp-cli.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 0129f41ce4..aba3d620b0 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -11,6 +11,7 @@ class WP_CLI { private static $commands = array(); private static $man_dirs = array(); + private static $arguments, $assoc_args, $assoc_special; /** * Add a command to the wp-cli list of commands @@ -229,8 +230,6 @@ static function load_command( $command ) { return self::$commands[$command]; } - private static $arguments, $assoc_args, $assoc_special; - static function before_wp_load() { self::add_man_dir( WP_CLI_ROOT . "../../../man/", From f0e19991281eaf533b22efddd104e0e0e0846466 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 02:31:17 +0200 Subject: [PATCH 0769/4858] add 'use \WP_CLI\Utils;' directive --- src/php/wp-cli/class-wp-cli.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index aba3d620b0..a9065bec49 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -1,6 +1,7 @@ <?php use \WP_CLI\Dispatcher; +use \WP_CLI\Utils; /** * Wrapper class for WP-CLI @@ -236,11 +237,11 @@ static function before_wp_load() { WP_CLI_ROOT . "../../docs/" ); - $r = WP_CLI\Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); + $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); list( self::$arguments, self::$assoc_args ) = $r; - self::$assoc_special = WP_CLI\Utils\split_assoc( self::$assoc_args, array( + self::$assoc_special = Utils\split_assoc( self::$assoc_args, array( 'path', 'url', 'blog', 'user', 'require', 'quiet', 'completions', 'man' ) ); @@ -264,7 +265,7 @@ static function before_wp_load() { } // Handle --url and --blog parameters - WP_CLI\Utils\set_url( self::$assoc_special ); + Utils\set_url( self::$assoc_special ); if ( array( 'core', 'download' ) == self::$arguments ) { self::run_command(); @@ -282,7 +283,7 @@ static function before_wp_load() { // The db commands don't need any WP files if ( array( 'db' ) == array_slice( self::$arguments, 0, 1 ) ) { - WP_CLI\Utils\load_wp_config(); + Utils\load_wp_config(); self::run_command(); exit; } @@ -300,10 +301,10 @@ static function get_assoc_special() { static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - WP_CLI\Utils\set_user( self::$assoc_special ); + Utils\set_user( self::$assoc_special ); if ( !defined( 'WP_INSTALLING' ) && isset( self::$assoc_special['url'] ) ) - WP_CLI\Utils\set_wp_query(); + Utils\set_wp_query(); if ( isset( self::$assoc_special['require'] ) ) require self::$assoc_special['require']; From 81b0ca27d51d7fcb53aeb1f23aaa01022f1ce5f7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 02:43:59 +0200 Subject: [PATCH 0770/4858] DRY set_url_params() --- src/php/wp-cli/utils.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index 1e49fcb89e..677aa98c49 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -90,10 +90,14 @@ function set_url_params( $url ) { $url_parts = parse_url( 'http://' . $url ); } - $_SERVER['HTTP_HOST'] = isset($url_parts['host']) ? $url_parts['host'] : ''; - $_SERVER['REQUEST_URI'] = (isset($url_parts['path']) ? $url_parts['path'] : '') . (isset($url_parts['query']) ? '?' . $url_parts['query'] : ''); - $_SERVER['REQUEST_URL'] = isset($url_parts['path']) ? $url_parts['path'] : ''; - $_SERVER['QUERY_STRING'] = isset($url_parts['query']) ? $url_parts['query'] : ''; + $f = function( $key ) use ( $url_parts ) { + return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; + }; + + $_SERVER['HTTP_HOST'] = $f('host'); + $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); + $_SERVER['REQUEST_URL'] = $f('path'); + $_SERVER['QUERY_STRING'] = $f('query'); } function locate_wp_config() { From c433dc667d868731f48d30bbc0447cbfc48347d5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 02:47:11 +0200 Subject: [PATCH 0771/4858] use getcwd() instead of $_SERVER['PWD'] --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index a9065bec49..9171e5250d 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -261,7 +261,7 @@ static function before_wp_load() { // trailingslashit() isn't available yet define( 'WP_ROOT', rtrim( self::$assoc_special['path'], '/' ) . '/' ); } else { - define( 'WP_ROOT', $_SERVER['PWD'] . '/' ); + define( 'WP_ROOT', getcwd() . '/' ); } // Handle --url and --blog parameters From 53b1ed952e1cb4cfff80557d15c65fbb41e31282 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 02:59:58 +0200 Subject: [PATCH 0772/4858] introduce set_wp_root() helper --- src/php/wp-cli/class-wp-cli.php | 9 ++------- src/php/wp-cli/utils.php | 8 ++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 9171e5250d..d2ef63f966 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -256,13 +256,8 @@ static function before_wp_load() { $_SERVER['DOCUMENT_ROOT'] = getcwd(); - // Define the WordPress location - if ( !empty( self::$assoc_special['path'] ) ) { - // trailingslashit() isn't available yet - define( 'WP_ROOT', rtrim( self::$assoc_special['path'], '/' ) . '/' ); - } else { - define( 'WP_ROOT', getcwd() . '/' ); - } + // Handle --path + Utils\set_wp_root( self::$assoc_special ); // Handle --url and --blog parameters Utils\set_url( self::$assoc_special ); diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index 677aa98c49..077467702a 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -44,6 +44,14 @@ function split_assoc( &$assoc_args, $special_keys ) { return $assoc_special; } +function set_wp_root( $assoc_args ) { + if ( !empty( $assoc_args['path'] ) ) { + define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); + } else { + define( 'WP_ROOT', getcwd() . '/' ); + } +} + function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $blog = $assoc_args['url']; From 622000e9793cac40942f1f34d6f99ebf7ed416c3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 3 Nov 2012 01:11:01 +0000 Subject: [PATCH 0773/4858] Rather than redeclaring all of the commands within the method, execute the export_wp command with params that are bound to be limited. The functions within export_wp will then be available within execution scope https://github.com/Automattic/wp-cli/commit/139737224a0582849ed30b066f31a91776942153#commitcomment-2092994 --- src/php/wp-cli/commands/internals/export.php | 123 +------------------ 1 file changed, 4 insertions(+), 119 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index ade057026e..da299e8b52 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -325,125 +325,10 @@ private function export_wp( $args = array() ) { unset( $categories, $custom_taxonomies, $custom_terms ); } - /** - * Functions normally defined in wp-admin/includes/export.php - */ - function wxr_cdata( $str ) { - if ( seems_utf8( $str ) == false ) - $str = utf8_encode( $str ); - - // $str = ent2ncr(esc_html($str)); - $str = '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $str ) . ']]>'; - - return $str; - } - - function wxr_site_url() { - // ms: the base url - if ( is_multisite() ) - return network_home_url(); - // wp: the blog url - else - return get_bloginfo_rss( 'url' ); - } - - function wxr_cat_name( $category ) { - if ( empty( $category->name ) ) - return; - - echo '<wp:cat_name>' . wxr_cdata( $category->name ) . '</wp:cat_name>'; - } - - function wxr_category_description( $category ) { - if ( empty( $category->description ) ) - return; - - echo '<wp:category_description>' . wxr_cdata( $category->description ) . '</wp:category_description>'; - } - - function wxr_tag_name( $tag ) { - if ( empty( $tag->name ) ) - return; - - echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . '</wp:tag_name>'; - } - - - function wxr_tag_description( $tag ) { - if ( empty( $tag->description ) ) - return; - - echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . '</wp:tag_description>'; - } - - function wxr_term_name( $term ) { - if ( empty( $term->name ) ) - return; - - echo '<wp:term_name>' . wxr_cdata( $term->name ) . '</wp:term_name>'; - } - - function wxr_term_description( $term ) { - if ( empty( $term->description ) ) - return; - - echo '<wp:term_description>' . wxr_cdata( $term->description ) . '</wp:term_description>'; - } - - function wxr_authors_list() { - global $wpdb; - - $authors = array(); - $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft'" ); - foreach ( (array) $results as $result ) - $authors[] = get_userdata( $result->post_author ); - - $authors = array_filter( $authors ); - - foreach ( $authors as $author ) { - echo "\t<wp:author>"; - echo '<wp:author_id>' . $author->ID . '</wp:author_id>'; - echo '<wp:author_login>' . $author->user_login . '</wp:author_login>'; - echo '<wp:author_email>' . $author->user_email . '</wp:author_email>'; - echo '<wp:author_display_name>' . wxr_cdata( $author->display_name ) . '</wp:author_display_name>'; - echo '<wp:author_first_name>' . wxr_cdata( $author->user_firstname ) . '</wp:author_first_name>'; - echo '<wp:author_last_name>' . wxr_cdata( $author->user_lastname ) . '</wp:author_last_name>'; - echo "</wp:author>\n"; - } - } - - function wxr_nav_menu_terms() { - $nav_menus = wp_get_nav_menus(); - if ( empty( $nav_menus ) || ! is_array( $nav_menus ) ) - return; - - foreach ( $nav_menus as $menu ) { - echo "\t<wp:term><wp:term_id>{$menu->term_id}</wp:term_id><wp:term_taxonomy>nav_menu</wp:term_taxonomy><wp:term_slug>{$menu->slug}</wp:term_slug>"; - wxr_term_name( $menu ); - echo "</wp:term>\n"; - } - } - - function wxr_post_taxonomy() { - $post = get_post(); - - $taxonomies = get_object_taxonomies( $post->post_type ); - if ( empty( $taxonomies ) ) - return; - $terms = wp_get_object_terms( $post->ID, $taxonomies ); - - foreach ( (array) $terms as $term ) { - echo "\t\t<category domain=\"{$term->taxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "</category>\n"; - } - } - - function wxr_filter_postmeta( $return_me, $meta_key ) { - if ( '_edit_lock' == $meta_key ) - $return_me = true; - return $return_me; - } - add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 ); - + // Load the functions available in wp-admin/includes/export.php + ob_start(); + export_wp( array( 'content' => 'page', 'start_date' => '1971-01-01', 'end_date' => '1971-01-02' ) ); + ob_end_clean(); WP_CLI::line( 'Exporting ' . count( $all_the_post_ids ) . ' items to be broken into ' . ceil( count( $all_the_post_ids ) / $args['file_item_count'] ) . ' files' ); WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); From 755261af2b44f51c1af2275a401afd71e383ce1f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 10:20:16 +0200 Subject: [PATCH 0774/4858] add wp core is-installed --- src/php/wp-cli/commands/internals/core.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index f16aa9f2f0..a53be97c8d 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -62,6 +62,19 @@ public function config( $args, $assoc_args ) { if ( WP_CLI_QUIET ) ob_end_clean(); } + /** + * Determine if the WordPress tables are installed. + * + * @subcommand is-installed + */ + public function is_installed() { + if ( is_blog_installed() ) { + exit( 0 ); + } else { + exit( 1 ); + } + } + /** * Create the WordPress tables in the database. * From 999e9709ed78bc1cae451e5a353f7c04c0aa05f5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 10:25:58 +0200 Subject: [PATCH 0775/4858] add example --- man/core-is-installed.1 | 26 ++++++++++++++++++++++++++ src/docs/core-is-installed.txt | 5 +++++ 2 files changed, 31 insertions(+) create mode 100644 man/core-is-installed.1 create mode 100644 src/docs/core-is-installed.txt diff --git a/man/core-is-installed.1 b/man/core-is-installed.1 new file mode 100644 index 0000000000..f2e27234ac --- /dev/null +++ b/man/core-is-installed.1 @@ -0,0 +1,26 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-IS\-INSTALLED" "1" "November 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-is\-installed\fR \- Determine if the WordPress tables are installed\. +. +.SH "SYNOPSIS" +\fBwp core is\-installed\fR +. +.SH "EXAMPLES" +if [ ! $(wp core is\-installed) ]; then +. +.IP "" 4 +. +.nf + +wp core install +. +.fi +. +.IP "" 0 +. +.P +fi diff --git a/src/docs/core-is-installed.txt b/src/docs/core-is-installed.txt new file mode 100644 index 0000000000..6432d0e669 --- /dev/null +++ b/src/docs/core-is-installed.txt @@ -0,0 +1,5 @@ +## EXAMPLES + +if [ ! $(wp core is-installed) ]; then + wp core install +fi From bf1362ebf5da5d65331c765a84beb22704a7eb50 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 12:34:21 +0200 Subject: [PATCH 0776/4858] fix unregistered command name not showing up --- src/php/wp-cli/dispatcher.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 83700435f8..a6e92b2a18 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -78,10 +78,11 @@ function invoke( $arguments, $assoc_args ) { exit; } + $cmd_name = $arguments[0]; $command = $this->find_subcommand( $arguments ); if ( !$command ) - \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $arguments[0] ) ); + \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $cmd_name ) ); $command->invoke( $arguments, $assoc_args ); } From c9e202a62085a01eb570460754cd6f9399154f7f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 12:34:37 +0200 Subject: [PATCH 0777/4858] add special --syn-list flag --- src/php/wp-cli/class-wp-cli.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index d2ef63f966..9a4eaf57d3 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -243,7 +243,7 @@ static function before_wp_load() { self::$assoc_special = Utils\split_assoc( self::$assoc_args, array( 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'completions', 'man' + 'quiet', 'completions', 'man', 'syn-list' ) ); define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); @@ -309,6 +309,19 @@ static function after_wp_load() { exit; } + // Handle --syn-list parameter + if ( isset( self::$assoc_special['syn-list'] ) ) { + foreach ( self::load_all_commands() as $command ) { + if ( $command instanceof \WP_CLI\Dispatcher\Composite ) { + foreach ( $command->get_subcommands() as $subcommand ) + $subcommand->show_usage( '' ); + } else { + $command->show_usage( '' ); + } + } + exit; + } + if ( isset( self::$assoc_special['completions'] ) ) { self::render_automcomplete(); exit; From a370086365ad4ed316c56db2197da9babef167a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 3 Nov 2012 12:44:34 +0200 Subject: [PATCH 0778/4858] add utils/compare-cmd --- utils/compare-cmd | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 utils/compare-cmd diff --git a/utils/compare-cmd b/utils/compare-cmd new file mode 100755 index 0000000000..92a291b30c --- /dev/null +++ b/utils/compare-cmd @@ -0,0 +1,18 @@ +#!/bin/bash + +if [ $# -lt 3 ]; then + echo 'usage: <version-a> <version-b> <wp-path>' + exit 1 +fi + +ver_a=$1 +ver_b=$2 +wp_path=$3 + +git checkout $ver_a +wp --path=$wp_path --syn-list > /tmp/wp-cli-a + +git checkout $ver_b +wp --path=$wp_path --syn-list > /tmp/wp-cli-b + +diff /tmp/wp-cli-a /tmp/wp-cli-b From 5276d070bffe6bd3ba45a14c30fd96dc496856bc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 02:55:46 +0200 Subject: [PATCH 0779/4858] Assign expression result directly to $_, instead of relying on eval()'s return value, which returns false on error. see #89 --- src/php/wp-cli/commands/internals/shell.php | 26 ++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 38592e44b6..ce33a60129 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -19,30 +19,34 @@ public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); $non_expressions = array( - 'echo', 'return', 'global', + 'echo', 'global', 'while', 'for', 'foreach', 'if', 'switch', 'include', 'include\_once', 'require', 'require\_once' ); $non_expressions = implode( '|', $non_expressions ); - $pattern = "/^($non_expressions)[\(\s]+/"; - while ( true ) { $line = $repl->read( 'wp> ' ); - - if ( !preg_match( $pattern, $line ) ) - $line = 'return ' . $line; - $line .= ';'; - $_ = eval( $line ); + if ( self::starts_with( $non_expressions, $line ) ) { + eval( $line ); + } else { + if ( self::starts_with( 'return', $line ) ) + $line = substr( $line, strlen( 'return' ) ); - if ( false === $_ ) - continue; + $line = '$_ = ' . $line; - \WP_CLI::line( var_export( $_, false ) ); + eval( $line ); + + \WP_CLI::line( var_export( $_, false ) ); + } } } + + private static function starts_with( $tokens, $line ) { + return preg_match( "/^($tokens)[\(\s]+/", $line ); + } } From a6bff727833a6da81a21844056233eeddeaf0a33 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 03:09:02 +0200 Subject: [PATCH 0780/4858] trim extra semicolons --- src/php/wp-cli/commands/internals/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index ce33a60129..4a10264dc2 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -27,7 +27,7 @@ public function __invoke() { while ( true ) { $line = $repl->read( 'wp> ' ); - $line .= ';'; + $line = rtrim( $line, ';' ) . ';'; if ( self::starts_with( $non_expressions, $line ) ) { eval( $line ); From ef2655ee8092f6d4082eed37b0501afa738a8b81 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 04:15:34 +0200 Subject: [PATCH 0781/4858] move get_history_path() to Shell_Command class --- src/php/wp-cli/commands/internals/shell.php | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 4a10264dc2..02ddfd7844 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -10,10 +10,12 @@ class Shell_Command extends \WP_CLI_Command { * Open an interactive shell environment. */ public function __invoke() { + $history_path = self::get_history_path(); + if ( function_exists( 'readline' ) ) { - $repl = new REPL_Readline; + $repl = new REPL_Readline( $history_path ); } else { - $repl = new REPL_Basic; + $repl = new REPL_Basic( $history_path ); } \WP_CLI::line( 'Type "exit" to close session.' ); @@ -47,25 +49,25 @@ public function __invoke() { private static function starts_with( $tokens, $line ) { return preg_match( "/^($tokens)[\(\s]+/", $line ); } + + private static function get_history_path() { + $data = getcwd() . get_current_user(); + + return sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); + } } class REPL_Readline { - function __construct() { - $this->hist_path = self::get_history_path(); + function __construct( $history_path ) { + $this->hist_path = $history_path; readline_read_history( $this->hist_path ); register_shutdown_function( array( $this, 'save_history' ) ); } - private static function get_history_path() { - $data = getcwd() . get_current_user(); - - return sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); - } - function read( $prompt ) { $line = trim( readline( $prompt ) ); if ( !empty( $line ) ) From 962dd9bfde2c9de957e04a737479bea1779a450d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 04:26:58 +0200 Subject: [PATCH 0782/4858] introduce create_repl() helper --- src/php/wp-cli/commands/internals/shell.php | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 02ddfd7844..949ea9d6e7 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -6,20 +6,16 @@ class Shell_Command extends \WP_CLI_Command { + private $repl; + /** * Open an interactive shell environment. */ public function __invoke() { - $history_path = self::get_history_path(); - - if ( function_exists( 'readline' ) ) { - $repl = new REPL_Readline( $history_path ); - } else { - $repl = new REPL_Basic( $history_path ); - } - \WP_CLI::line( 'Type "exit" to close session.' ); + $this->repl = self::create_repl(); + $non_expressions = array( 'echo', 'global', 'while', 'for', 'foreach', 'if', 'switch', @@ -28,7 +24,7 @@ public function __invoke() { $non_expressions = implode( '|', $non_expressions ); while ( true ) { - $line = $repl->read( 'wp> ' ); + $line = $this->repl->read( 'wp> ' ); $line = rtrim( $line, ';' ) . ';'; if ( self::starts_with( $non_expressions, $line ) ) { @@ -46,6 +42,18 @@ public function __invoke() { } } + private static function create_repl() { + $class = __NAMESPACE__ . '\\'; + + if ( function_exists( 'readline' ) ) { + $class .= 'REPL_Readline'; + } else { + $class .= 'REPL_Basic'; + } + + return new $class( self::get_history_path() ); + } + private static function starts_with( $tokens, $line ) { return preg_match( "/^($tokens)[\(\s]+/", $line ); } From 4edf7e80ffb4096b0a68dfaba9356cfd9c9af955 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 04:52:24 +0200 Subject: [PATCH 0783/4858] add 'unset' to list of non-expression tokens --- src/php/wp-cli/commands/internals/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 949ea9d6e7..738bf0b2a8 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -17,7 +17,7 @@ public function __invoke() { $this->repl = self::create_repl(); $non_expressions = array( - 'echo', 'global', + 'echo', 'global', 'unset', 'while', 'for', 'foreach', 'if', 'switch', 'include', 'include\_once', 'require', 'require\_once' ); From 88b2f6fc170c0f6b536b4aad1a85cdd5f1427c60 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 04:43:43 +0200 Subject: [PATCH 0784/4858] Use bash builtins for reading user input. PHP's readline extension doesn't implement all the features from the native GNU readline library, such as Ctrl+u. Plus, a large percentage of PHP installs probably don't even have `--with-readline` enabled. The method used in this commit was inspired by wpshell. see #89 --- src/php/wp-cli/commands/internals/shell.php | 69 +++++++-------------- 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 738bf0b2a8..42fb10e2f1 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -6,16 +6,12 @@ class Shell_Command extends \WP_CLI_Command { - private $repl; - /** * Open an interactive shell environment. */ public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); - $this->repl = self::create_repl(); - $non_expressions = array( 'echo', 'global', 'unset', 'while', 'for', 'foreach', 'if', 'switch', @@ -24,7 +20,11 @@ public function __invoke() { $non_expressions = implode( '|', $non_expressions ); while ( true ) { - $line = $this->repl->read( 'wp> ' ); + $line = self::prompt( 'wp> ', self::get_history_path() ); + + if ( '' === $line ) + continue; + $line = rtrim( $line, ';' ) . ';'; if ( self::starts_with( $non_expressions, $line ) ) { @@ -42,20 +42,24 @@ public function __invoke() { } } - private static function create_repl() { - $class = __NAMESPACE__ . '\\'; + private static function prompt( $prompt, $history_path ) { + $cmds = array( + 'set -f', + sprintf( 'history -r %s', escapeshellarg( $history_path ) ), + 'LINE=""', + sprintf( 'read -re -p %s LINE', escapeshellarg( $prompt ) ), + 'history -s "$LINE"', + sprintf( 'history -w %s', escapeshellarg( $history_path ) ), + 'echo $LINE' + ); - if ( function_exists( 'readline' ) ) { - $class .= 'REPL_Readline'; - } else { - $class .= 'REPL_Basic'; - } + $cmd = implode( '; ', $cmds ); - return new $class( self::get_history_path() ); - } + $fp = popen( '/bin/bash -c ' . escapeshellarg( $cmd ), 'r' ); - private static function starts_with( $tokens, $line ) { - return preg_match( "/^($tokens)[\(\s]+/", $line ); + $line = fgets( $fp ); + + return trim( $line ); } private static function get_history_path() { @@ -63,38 +67,9 @@ private static function get_history_path() { return sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); } -} - - -class REPL_Readline { - - function __construct( $history_path ) { - $this->hist_path = $history_path; - readline_read_history( $this->hist_path ); - - register_shutdown_function( array( $this, 'save_history' ) ); - } - - function read( $prompt ) { - $line = trim( readline( $prompt ) ); - if ( !empty( $line ) ) - readline_add_history( $line ); - - return $line; - } - - function save_history() { - readline_write_history( $this->hist_path ); - } -} - - -class REPL_Basic { - - function read( $prompt ) { - \WP_CLI::out( $prompt ); - return \cli\input(); + private static function starts_with( $tokens, $line ) { + return preg_match( "/^($tokens)[\(\s]+/", $line ); } } From 556218c2fcc1f3d504108d49fe7c6440c4a840dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 06:02:03 +0200 Subject: [PATCH 0785/4858] generate prompt command only once --- src/php/wp-cli/commands/internals/shell.php | 30 +++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index 42fb10e2f1..cc1e413b8d 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -20,7 +20,7 @@ public function __invoke() { $non_expressions = implode( '|', $non_expressions ); while ( true ) { - $line = self::prompt( 'wp> ', self::get_history_path() ); + $line = self::prompt(); if ( '' === $line ) continue; @@ -42,8 +42,22 @@ public function __invoke() { } } - private static function prompt( $prompt, $history_path ) { - $cmds = array( + private static function prompt() { + static $cmd; + + if ( !$cmd ) { + $cmd = self::create_prompt_cmd( 'wp> ', self::get_history_path() ); + } + + $fp = popen( $cmd, 'r' ); + + $line = fgets( $fp ); + + return trim( $line ); + } + + private static function create_prompt_cmd( $prompt, $history_path ) { + $cmd = implode( '; ', array( 'set -f', sprintf( 'history -r %s', escapeshellarg( $history_path ) ), 'LINE=""', @@ -51,15 +65,9 @@ private static function prompt( $prompt, $history_path ) { 'history -s "$LINE"', sprintf( 'history -w %s', escapeshellarg( $history_path ) ), 'echo $LINE' - ); - - $cmd = implode( '; ', $cmds ); - - $fp = popen( '/bin/bash -c ' . escapeshellarg( $cmd ), 'r' ); + ) ); - $line = fgets( $fp ); - - return trim( $line ); + return '/bin/bash -c ' . escapeshellarg( $cmd ); } private static function get_history_path() { From f913727626bdfda0cc93f04b3c27935a57e85438 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Nov 2012 06:04:44 +0200 Subject: [PATCH 0786/4858] create non_expressions() helper --- src/php/wp-cli/commands/internals/shell.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/internals/shell.php index cc1e413b8d..b3f75f2622 100644 --- a/src/php/wp-cli/commands/internals/shell.php +++ b/src/php/wp-cli/commands/internals/shell.php @@ -12,13 +12,6 @@ class Shell_Command extends \WP_CLI_Command { public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); - $non_expressions = array( - 'echo', 'global', 'unset', - 'while', 'for', 'foreach', 'if', 'switch', - 'include', 'include\_once', 'require', 'require\_once' - ); - $non_expressions = implode( '|', $non_expressions ); - while ( true ) { $line = self::prompt(); @@ -27,7 +20,7 @@ public function __invoke() { $line = rtrim( $line, ';' ) . ';'; - if ( self::starts_with( $non_expressions, $line ) ) { + if ( self::starts_with( self::non_expressions(), $line ) ) { eval( $line ); } else { if ( self::starts_with( 'return', $line ) ) @@ -42,6 +35,14 @@ public function __invoke() { } } + private static function non_expressions() { + return implode( '|', array( + 'echo', 'global', 'unset', + 'while', 'for', 'foreach', 'if', 'switch', + 'include', 'include\_once', 'require', 'require\_once' + ) ); + } + private static function prompt() { static $cmd; From 7790c987267e95ceb501994a54a4ec3d8889d9f0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Nov 2012 02:02:45 +0200 Subject: [PATCH 0787/4858] leave documentation for wp-cli.org --- README.md | 200 ++---------------------------------------------------- 1 file changed, 7 insertions(+), 193 deletions(-) diff --git a/README.md b/README.md index 7dc46db18a..b2888d0f7b 100644 --- a/README.md +++ b/README.md @@ -1,196 +1,10 @@ -What is wp-cli? --------------- +wp-cli is a set of command-line tools for managing WordPress installations. -wp-cli is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs, update posts and much more. +For documentation, usage, and examples, see: +http://wp-cli.org/ -Visit the [wiki](https://github.com/wp-cli/wp-cli/wiki) for more information. +To suggest a feature, report a bug, or general discussion: +https://github.com/wp-cli/wp-cli/issues -Requirements -============ - -* PHP >= 5.3 -* WP >= 3.3 - -Installing -========== - -**Via PEAR:** - -```sh -sudo pear config-set auto_discover 1 -sudo pear install wp-cli.github.com/pear/wpcli -``` - -**Via GIT:** - -```sh -git clone --recursive git://github.com/wp-cli/wp-cli.git ~/git/wp-cli -cd ~/git/wp-cli -sudo utils/dev-build -``` - -You can replace `~/git/wp-cli` with whatever you want. - -MAMP, XAMP, etc. ------------ - -If the `php` command is not available, you can try finding an appropriate binary: - -```sh -./utils/find-php -``` - -Then, create an environment variable called `WP_CLI_PHP` with the path found by `find-php`. - -In a UNIX environment, you would do this by adding the following line to your `.bashrc` file: - -```sh -WP_CLI_PHP=/path/to/php-binary -``` - -Using -===== - -Go into a WordPress root folder: - -``` -cd /var/www/wp/ -``` - -Typing `wp help` should show you an output similar to this: - -``` -Example usage: - wp google-sitemap [build|help] ... - wp core [update|help] ... - wp home [help] ... - wp option [add|update|delete|get|help] ... - wp plugin [status|activate|deactivate|install|delete|update|help] ... - wp theme [status|details|activate|help] ... -``` - -So this tells us which commands are installed: eg. google-sitemap, core, home, ... -Between brackets you can see their sub commands. - -Let's for example try to install the hello dolly plugin from wordpress.org: - -``` -wp plugin install hello-dolly -``` - -Output: - -``` -Installing Hello Dolly (1.5) - -Downloading install package from http://downloads.WordPress.org/plugin/hello-dolly.1.5.zip ... -Unpacking the package ... -Installing the plugin ... - -Success: The plugin is successfully installed -``` - -Multisite ---------- - -On a multisite installation, you need to pass a --blog parameter, so that WP knows which site it's supposed to be operating on: - -``` -wp theme status --blog=localhost/wp/test -``` - -If you have a subdomain installation, it would look like this: - -``` -wp theme status --blog=test.example.com -``` - -If you're usually working on the same site most of the time, you can put the url of that site in a file called 'wp-cli-blog' in your root WP dir: - -``` -echo 'test.example.com' > wp-cli-blog -``` - -Then, you can call `wp` without the --blog parameter again: - -``` -wp theme status -``` - -Adding commands -=============== - -Adding commands to wp-cli is very easy. You can even add them from within your own plugin. -You can find more information about adding commands in the [Commands Cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook) on our Wiki. - -**Please share the commands you make, issue a pull request to get them included in wp-cli by default.** - -Changelog -========= - -**0.6** - -- added `wp post` and `wp post-meta` -- added `wp user-meta` -- added `wp blog create` -- added `wp export` -- added `wp transient` -- added `wp db optimize` and `wp db repair` -- added `wp db create`, `wp db drop` and `wp db reset` -- added `wp db import` -- added `wp theme install` and `wp theme update` -- added `wp core install_network` -- added `wp core update_db` -- added `--json` option to several subcommands -- added `--network` option to `wp plugin activate` -- added `--require` global parameter -- fixed `wp plugin update` -- fixed "out of memory" error -- misc bugfixes and optimizations -- man pages (not in PEAR package) - -**0.5** - -- added `wp user` -- added `wp core download` -- added `wp core config` -- added `wp plugin update --all` -- added `wp theme update` -- added `wp db import` -- added `--url` `--path` and `--user` global parameters -- various bugfixes - -**0.4** - -- added `wp eval` and `wp eval-file` -- added `wp export` -- added `wp core install` -- fixed `wp core update` -- added `--dev` flag to `wp plugin install` -- added `wp plugin uninstall` -- fixed `wp plugin install` and `wp plugin update` - -**0.3** - -- added `wp sql` -- improved `wp option` -- pear installer - -**0.2** - -- added multisite support -- improved `wp plugin` and `wp theme` -- added `wp generate` -- added `wp core version` -- added `wp --version` -- added bash completion script - -**0.1** - -- initial release - -Contributors ------------- - -- [Contributor list](https://github.com/wp-cli/wp-cli/contributors) -- [Contributor guide](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook) +All contributors are listed here: +https://github.com/wp-cli/wp-cli/contributors From 7d12559e2b77b5c03057e7805e0033d2fba64df4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Nov 2012 19:02:40 +0200 Subject: [PATCH 0788/4858] update URL to pear channel --- build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 2bc7131b07..5c51b0ceb9 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,5 @@ project.name=wpcli -project.channel=wp-cli.github.com/pear +project.channel=wp-cli.org/pear project.majorVersion=0 project.minorVersion=6 project.patchLevel=0 From 9eb46fcf3f409e1feef2e897b6204021a6a89af0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Nov 2012 19:09:59 +0200 Subject: [PATCH 0789/4858] .git is a text file when checked out as a submodule --- utils/pear-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/pear-build b/utils/pear-build index e044a8c4d0..300d83ef40 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -9,7 +9,7 @@ mkdir -p src/www # temporarily move the .git dir, because phing is stupid git_dir=src/php/php-cli-tools/.git -if [ -d $git_dir ]; then +if [ -f $git_dir ]; then mv $git_dir /tmp/php-cli-tools-git fi From d2ad080ce8c1e282c87faf8d310b4c9500dfccd4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Nov 2012 02:06:19 +0200 Subject: [PATCH 0790/4858] show plugin/theme count. fixes #205 --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index a8a9d96453..bfe6e4dc31 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -39,7 +39,7 @@ function status( $args ) { private function status_all() { $items = $this->get_all_items(); - WP_CLI::line( "Installed {$this->item_type}s:" ); + WP_CLI::line( count( $items ) . " installed {$this->item_type}s:" ); foreach ( $items as $file => $details ) { if ( $details['update'] ) { From b5e33de4de1299e444b6d66b298bdbf0c8fe7831 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Nov 2012 02:45:45 +0200 Subject: [PATCH 0791/4858] avoid '1 installed plugins:' situation. see #205 --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index bfe6e4dc31..b4953557e4 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -39,7 +39,10 @@ function status( $args ) { private function status_all() { $items = $this->get_all_items(); - WP_CLI::line( count( $items ) . " installed {$this->item_type}s:" ); + $n = count( $items ); + + // Not interested in the translation, just the number logic + WP_CLI::line( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); foreach ( $items as $file => $details ) { if ( $details['update'] ) { From 228ff11365ce6853f20f090efa1451661030a04b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Nov 2012 20:37:44 +0000 Subject: [PATCH 0792/4858] Only call the remoteset method if it exists. Most of the time it doesn't --- src/php/wp-cli/commands/internals/export.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index da299e8b52..057433fbc9 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -204,7 +204,8 @@ private function stop_the_insanity() { $wp_object_cache->stats = array(); $wp_object_cache->memcache_debug = array(); $wp_object_cache->cache = array(); - $wp_object_cache->__remoteset(); // important + if ( method_exists( $wp_object_cache, '__remoteset' ) ) + $wp_object_cache->__remoteset(); } private function start_export() { From 6611ca97efc3062537f8087db576c4181e1a5505 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Nov 2012 20:49:41 +0000 Subject: [PATCH 0793/4858] If there are attachments to export as well, pre-load them on the original set of post IDs so the cli progress bar is accurate https://github.com/wp-cli/wp-cli/pull/203#issuecomment-10035187 --- src/php/wp-cli/commands/internals/export.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 057433fbc9..e76be99fbb 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -294,6 +294,16 @@ private function export_wp( $args = array() ) { // grab a snapshot of post IDs, just in case it changes during the export $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); + // Make sure we're getting all of the attachments for these posts too + if ( 'all' != $args['post_type'] ) { + $all_post_ids_with_attachments = array(); + while ( $post_ids = array_splice( $all_the_post_ids, 0, 100 ) ) { + $attachment_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent IN (". implode( ",", array_map( 'intval', $post_ids ) ) .")" ); + $all_post_ids_with_attachments = array_merge( $all_post_ids_with_attachments, $post_ids, (array)$attachment_ids ); + } + $all_the_post_ids = $all_post_ids_with_attachments; + } + // get the requested terms ready, empty unless posts filtered by category or all content $cats = $tags = $terms = array(); if ( isset( $term ) && $term ) { @@ -423,12 +433,6 @@ private function export_wp( $args = array() ) { $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')'; $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" ); - if ( 'all' != $args['post_type'] ) { - $attachment_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent IN (". implode( ",", array_map( 'intval', $post_ids ) ) .")" ); - if ( is_array( $attachment_ids ) ) - $posts = array_merge( $posts, array_map( 'get_post', $attachment_ids ) ); - } - // Begin Loop foreach ( $posts as $post ) { From d0536e93239184d0399460e8a4bcf517f32e90f1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Nov 2012 17:11:36 -0800 Subject: [PATCH 0794/4858] Globalize $post so the global $post variable is properly set. Fixes a PHP warning when calling wxr_post_taxonomy(): [08-Nov-2012 01:06:32 UTC] PHP Notice: Trying to get property of non-object in /Users/danielbachhuber/wp-cli/src/php/wp-cli/commands/internals/export.php on line 466 [08-Nov-2012 01:06:32 UTC] PHP Notice: Undefined variable: post in /Users/danielbachhuber/wp-cli/src/php/wp-cli/commands/internals/export.php on line 467 --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index e76be99fbb..b0511d4c1f 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -424,7 +424,7 @@ private function export_wp( $args = array() ) { <?php $this->flush_export( $full_path, false ); ?> <?php if ( $post_ids ) { - global $wp_query; + global $wp_query, $post; $wp_query->in_the_loop = true; // Fake being in the loop. // fetch 20 posts at a time rather than loading the entire table into memory From 9520cf00eb2f71e629913b459c22ab5da3eb50a2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 8 Nov 2012 22:24:08 +0000 Subject: [PATCH 0795/4858] Add missing reference to 'file_item_count' param --- src/docs/export.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/docs/export.txt b/src/docs/export.txt index 582a983cb0..42542a3c18 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -8,6 +8,10 @@ Don't export comments. +* `--file_item_count`=<count> + + Break export into files with N posts + ## FILTERS * `--start_date`=<date>: From d06ec3da3933cb5d53a52b422cceb3fb99080bf0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Nov 2012 22:19:32 +0000 Subject: [PATCH 0796/4858] export: Default the export path to the current working directory Closes #206 --- src/docs/export.txt | 2 +- src/php/wp-cli/commands/internals/export.php | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/docs/export.txt b/src/docs/export.txt index 582a983cb0..362ae699b6 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -2,7 +2,7 @@ * `--dir`=<dirname>: - Full Path to directory where WXR export files should be stored. + Full Path to directory where WXR export files should be stored. Defaults to current working directory * `--skip_comments`: diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index b0511d4c1f..4cd2eeb0f1 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -19,7 +19,7 @@ class Export_Command extends WP_CLI_Command { /** * Export posts to a WXR file. * - * @synopsis --dir=<dir> [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] + * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] */ public function __invoke( $args, $assoc_args ) { $defaults = array( @@ -50,7 +50,8 @@ public function __invoke( $args, $assoc_args ) { exit(1); } - $this->wxr_path = trailingslashit( $assoc_args['dir'] ); + $this->wxr_path = trailingslashit( $this->export_args['dir'] ); + unset( $this->export_args['dir'] ); WP_CLI::line( 'Starting export process...' ); WP_CLI::line(); @@ -59,14 +60,15 @@ public function __invoke( $args, $assoc_args ) { private function check_dir( $path ) { if ( empty( $path ) ) { - WP_CLI::warning( 'missing --dir parameter' ); - return false; + $this->export_args['dir'] = getcwd(); + return true; } if ( !is_dir( $path ) ) { WP_CLI::error( sprintf( "The directory %s does not exist", $path ) ); } + $this->export_args['dir'] = $path; return true; } From 98dd8f60f410f2851f7e6bfc76f1426bf64dd170 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 00:23:37 +0200 Subject: [PATCH 0797/4858] add missing colon and generate man file. see #208 --- man/export.1 | 10 ++++++++-- src/docs/export.txt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/man/export.1 b/man/export.1 index 77260f31fc..07870c3580 100644 --- a/man/export.1 +++ b/man/export.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EXPORT" "1" "October 2012" "" "WP-CLI" +.TH "WP\-EXPORT" "1" "November 2012" "" "WP-CLI" . .SH "NAME" \fBwp\-export\fR \- Export posts to a WXR file\. . .SH "SYNOPSIS" -\fBwp export\fR \-\-dir=\fIdir\fR [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] +\fBwp export\fR \-\-dir=\fIdir\fR [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] . .SH "OPTIONS" . @@ -23,6 +23,12 @@ Full Path to directory where WXR export files should be stored\. .IP Don\'t export comments\. . +.TP +\fB\-\-file_item_count\fR=\fIcount\fR: +. +.IP +Break export into files with N posts +. .SH "FILTERS" . .TP diff --git a/src/docs/export.txt b/src/docs/export.txt index 42542a3c18..ca5b1a65c7 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -8,7 +8,7 @@ Don't export comments. -* `--file_item_count`=<count> +* `--file_item_count`=<count>: Break export into files with N posts From 71fa0ce88fba4881508fddcd00f988f0d48ee745 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 00:27:48 +0200 Subject: [PATCH 0798/4858] clean up arg handling in export.php --- src/php/wp-cli/commands/internals/export.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index b0511d4c1f..340147d623 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -21,7 +21,7 @@ class Export_Command extends WP_CLI_Command { * * @synopsis --dir=<dir> [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] */ - public function __invoke( $args, $assoc_args ) { + public function __invoke( $_, $assoc_args ) { $defaults = array( 'dir' => NULL, 'start_date' => NULL, @@ -37,11 +37,11 @@ public function __invoke( $args, $assoc_args ) { $args = wp_parse_args( $assoc_args, $defaults ); $has_errors = false; - - foreach( $args as $argument => $default_value ) { - if ( is_callable( array( &$this, 'check_' . $argument ) ) ) { - $result = call_user_func( array( &$this, 'check_' . $argument ), $args[$argument] ); - if ( false === $result && false === $has_errors ) + + foreach ( $args as $key => $value ) { + if ( is_callable( array( $this, 'check_' . $key ) ) ) { + $result = call_user_func( array( &$this, 'check_' . $key ), $value ); + if ( false === $result ) $has_errors = true; } } @@ -281,7 +281,7 @@ private function export_wp( $args = array() ) { } } - + if ( $args['author'] ) $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); From 5eee5df2847de7510ea0a19aa26a5be1648075d8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 00:29:15 +0200 Subject: [PATCH 0799/4858] remove $this pass-by-reference --- src/php/wp-cli/commands/internals/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 340147d623..7495106e1f 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -40,7 +40,7 @@ public function __invoke( $_, $assoc_args ) { foreach ( $args as $key => $value ) { if ( is_callable( array( $this, 'check_' . $key ) ) ) { - $result = call_user_func( array( &$this, 'check_' . $key ), $value ); + $result = call_user_func( array( $this, 'check_' . $key ), $value ); if ( false === $result ) $has_errors = true; } From 881c4f307dda8b9e2382f1a76a8c572960aa5151 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 00:35:24 +0200 Subject: [PATCH 0800/4858] dots and commands for export man file --- man/export.1 | 10 +++++----- src/docs/export.txt | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/man/export.1 b/man/export.1 index 07870c3580..b580328262 100644 --- a/man/export.1 +++ b/man/export.1 @@ -7,7 +7,7 @@ \fBwp\-export\fR \- Export posts to a WXR file\. . .SH "SYNOPSIS" -\fBwp export\fR \-\-dir=\fIdir\fR [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] +\fBwp export\fR [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] . .SH "OPTIONS" . @@ -15,7 +15,7 @@ \fB\-\-dir\fR=\fIdirname\fR: . .IP -Full Path to directory where WXR export files should be stored\. +Full path to directory where WXR export files should be stored\. Defaults to current working directory\. . .TP \fB\-\-skip_comments\fR: @@ -27,7 +27,7 @@ Don\'t export comments\. \fB\-\-file_item_count\fR=\fIcount\fR: . .IP -Break export into files with N posts +Break export into files with N posts\. . .SH "FILTERS" . @@ -35,13 +35,13 @@ Break export into files with N posts \fB\-\-start_date\fR=\fIdate\fR: . .IP -Export only posts newer than this date in format YYYY\-MM\-DD\. +Export only posts newer than this date, in format YYYY\-MM\-DD\. . .TP \fB\-\-end_date\fR=\fIdate\fR: . .IP -Export only posts older than this date in format YYYY\-MM\-DD\. +Export only posts older than this date, in format YYYY\-MM\-DD\. . .TP \fB\-\-post_type\fR=\fIpost_type\fR: diff --git a/src/docs/export.txt b/src/docs/export.txt index cd289bf105..ea92cb7f4a 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -2,7 +2,8 @@ * `--dir`=<dirname>: - Full Path to directory where WXR export files should be stored. Defaults to current working directory + Full path to directory where WXR export files should be stored. Defaults +to current working directory. * `--skip_comments`: @@ -10,17 +11,17 @@ * `--file_item_count`=<count>: - Break export into files with N posts + Break export into files with N posts. ## FILTERS * `--start_date`=<date>: - Export only posts newer than this date in format YYYY-MM-DD. + Export only posts newer than this date, in format YYYY-MM-DD. * `--end_date`=<date>: - Export only posts older than this date in format YYYY-MM-DD. + Export only posts older than this date, in format YYYY-MM-DD. * `--post_type`=<post_type>: From 7f430ce2a457fb2c66523bf60309bd28ca3ca128 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Nov 2012 23:06:50 +0000 Subject: [PATCH 0801/4858] Subcommand should be named 'import-csv' --- src/php/wp-cli/commands/internals/user.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index cdcef1aa64..f6d6e643dd 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -201,6 +201,7 @@ public function generate( $args, $assoc_args ) { /** * Import users from a CSV * + * @subcommand import-csv * @synopsis <file> */ public function import_csv( $args, $assoc_args ) { From 35ce814afd8e21c6e36d0333f34076f0ce01ac04 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Nov 2012 23:23:01 +0000 Subject: [PATCH 0802/4858] Include sample CSV --- src/docs/user-import-csv.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/docs/user-import-csv.txt b/src/docs/user-import-csv.txt index ca39f28ef1..6601facf6d 100644 --- a/src/docs/user-import-csv.txt +++ b/src/docs/user-import-csv.txt @@ -7,3 +7,8 @@ ## EXAMPLES wp user import_csv /path/to/csv.csv + + user_login, user_email, display_name, role + bobjones, bobjones@domain.com, Bob Jones, contributor + newuser1, newuser1@domain.com, New User, author + existinguser, existinguser@domain.com, Existing User, administrator \ No newline at end of file From 7020f4e063707cee6354fbbfb0c0f8054d9c737a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Nov 2012 23:28:51 +0000 Subject: [PATCH 0803/4858] Email address is a better check to see if this user already exists. Checking by email address instead of user_login will help avoid adding users to a site that aren't supposed to be on a site --- src/php/wp-cli/commands/internals/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index f6d6e643dd..d4b56d9b50 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -230,7 +230,7 @@ public function import_csv( $args, $assoc_args ) { } // User already exists and we just need to add them to the site if they aren't already there - if ( $existing_user = get_user_by( 'login', $new_user['user_login'] ) ) { + if ( $existing_user = get_user_by( 'email', $new_user['user_email'] ) ) { if ( in_array( $new_user['user_login'], wp_list_pluck( $blog_users, 'user_login' ) ) ) WP_CLI::warning( "{$new_user['user_login']} already is a member of blog" ); else if ( $new_user['role'] ) { From 0a3a237d66fd05f5b3365f10b43f9865ece754e2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Nov 2012 16:22:20 -0800 Subject: [PATCH 0804/4858] Remove preceeding spaces in example CSV. The values end up being misinterpreted --- src/docs/user-import-csv.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/docs/user-import-csv.txt b/src/docs/user-import-csv.txt index 6601facf6d..6c02912e71 100644 --- a/src/docs/user-import-csv.txt +++ b/src/docs/user-import-csv.txt @@ -8,7 +8,7 @@ wp user import_csv /path/to/csv.csv - user_login, user_email, display_name, role - bobjones, bobjones@domain.com, Bob Jones, contributor - newuser1, newuser1@domain.com, New User, author - existinguser, existinguser@domain.com, Existing User, administrator \ No newline at end of file + user_login,user_email,display_name,role + bobjones,bobjones@domain.com,Bob Jones,contributor + newuser1,newuser1@domain.com,New User,author + existinguser,existinguser@domain.com,Existing User,administrator \ No newline at end of file From bc285919285a2d149768a47ea634ec5f063a78fc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 1 Nov 2012 21:08:03 -0700 Subject: [PATCH 0805/4858] Adding and removing users from a blog becomes set_role and remove_role. Also, support both multisite and single --- src/docs/user-add_to_blog.txt | 20 --------- src/docs/user-remove_from_blog.txt | 16 ------- src/docs/user-remove_role.txt | 16 +++++++ src/docs/user-set_role.txt | 20 +++++++++ src/php/wp-cli/commands/internals/user.php | 52 +++++++++++----------- 5 files changed, 63 insertions(+), 61 deletions(-) delete mode 100644 src/docs/user-add_to_blog.txt delete mode 100644 src/docs/user-remove_from_blog.txt create mode 100644 src/docs/user-remove_role.txt create mode 100644 src/docs/user-set_role.txt diff --git a/src/docs/user-add_to_blog.txt b/src/docs/user-add_to_blog.txt deleted file mode 100644 index 76a3056c48..0000000000 --- a/src/docs/user-add_to_blog.txt +++ /dev/null @@ -1,20 +0,0 @@ -wp-user-add_to_blog(1) -- Add an existing WordPress user to an existing blog -==== - -## SYNOPSIS - -`wp user add_to_blog` <user-login> [--role=<role>] - -## OPTIONS - -* `<user-login>`: - - The login of the user to add to the blog. - -* `--role`=<role>: - - Add the user with the specified role. Defaults to blog default. - -## EXAMPLES - - wp user add_to_blog bob --role=author diff --git a/src/docs/user-remove_from_blog.txt b/src/docs/user-remove_from_blog.txt deleted file mode 100644 index 619ab98404..0000000000 --- a/src/docs/user-remove_from_blog.txt +++ /dev/null @@ -1,16 +0,0 @@ -wp-user-remove_from_blog(1) -- Remove a WordPress user from a blog -==== - -## SYNOPSIS - -`wp user remove_from_blog` <user-login> - -## OPTIONS - -* `<user-login>`: - - The login of the user to remove from the blog. - -## EXAMPLES - - wp user remove_from_blog bob diff --git a/src/docs/user-remove_role.txt b/src/docs/user-remove_role.txt new file mode 100644 index 0000000000..98e8cf0453 --- /dev/null +++ b/src/docs/user-remove_role.txt @@ -0,0 +1,16 @@ +wp-user-remove_role(1) -- Remove a user's role on a blog +==== + +## SYNOPSIS + +`wp user remove_role` <user-login> + +## OPTIONS + +* `<user-login>`: + + The login of the user to remove from the blog. + +## EXAMPLES + + wp user remove_role bob diff --git a/src/docs/user-set_role.txt b/src/docs/user-set_role.txt new file mode 100644 index 0000000000..c17611ffae --- /dev/null +++ b/src/docs/user-set_role.txt @@ -0,0 +1,20 @@ +wp-user-set_role(1) -- Set the user's role +==== + +## SYNOPSIS + +`wp user set_role` <user-login> [<role>] [--blog=<blog>] + +## OPTIONS + +* `<user-login>`: + + The login of the user to add to the blog. + +* `<role>`: + + Add the user with the specified role. Defaults to blog default. + +## EXAMPLES + + wp user set_role bob author diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index e9fed335a7..92c0c07fb3 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -212,28 +212,28 @@ public function generate( $args, $assoc_args ) { * @param array $args * @param array $assoc_args **/ - public function add_to_blog( $args, $assoc_args ) { + public function set_role( $args, $assoc_args ) { - $defaults = array( - 'id_or_login' => $args[0], - 'role' => $args[1], - ); - $args = array_merge( $assoc_args, $defaults ); + list( $id_or_login, $role ) = $args; - if ( is_numeric( $args['id_or_login'] ) ) - $user = get_user_by( 'id', $args['id_or_login'] ); + if ( is_numeric( $id_or_login ) ) + $user = get_user_by( 'id', $id_or_login ); else - $user = get_user_by( 'login', $args['id_or_login'] ); + $user = get_user_by( 'login', $id_or_login ); - if ( empty( $args['id_or_login'] ) || empty( $user ) ) + if ( ! $user ) WP_CLI::error( "Please specify a valid user ID or user login to add to this blog" ); - global $wp_roles; - if ( empty( $args['role'] ) || ! array_key_exists( $args['role'], $wp_roles->roles ) ) - $args['role'] = get_option( 'default_role' ); + if ( ! get_role( $role ) ) + $role = get_option( 'default_role' ); + + // Multisite + if ( function_exists( 'add_user_to_blog' ) ) + add_user_to_blog( get_current_blog_id(), $user->ID, $role ); + else + $user->set_role( $role ); - add_user_to_blog( get_current_blog_id(), $user->ID, $args['role'] ); - WP_CLI::success( "Added {$user->user_login} ({$user->ID}) to " . site_url() . " as {$args['role']}" ); + WP_CLI::success( "Added {$user->user_login} ({$user->ID}) to " . site_url() . " as {$role}" ); } /** @@ -242,22 +242,24 @@ public function add_to_blog( $args, $assoc_args ) { * @param array $args * @param array $assoc_args **/ - public function remove_from_blog( $args, $assoc_args ) { + public function remove_role( $args, $assoc_args ) { - $defaults = array( - 'id_or_login' => $args[0], - ); - $args = array_merge( $assoc_args, $defaults ); + list( $id_or_login ) = $args; - if ( is_numeric( $args['id_or_login'] ) ) - $user = get_user_by( 'id', $args['id_or_login'] ); + if ( is_numeric( $id_or_login ) ) + $user = get_user_by( 'id', $id_or_login ); else - $user = get_user_by( 'login', $args['id_or_login'] ); + $user = get_user_by( 'login', $id_or_login ); - if ( empty( $args['id_or_login'] ) || empty( $user ) ) + if ( ! $user ) WP_CLI::error( "Please specify a valid user ID or user login to remove from this blog" ); - remove_user_from_blog( $user->ID, get_current_blog_id() ); + // Multisite + if ( function_exists( 'remove_user_from_blog' ) ) + remove_user_from_blog( $user->ID, get_current_blog_id() ); + else + $user->remove_all_caps(); + WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); } From a34f62f0f9452e042d83bfba15c5086155fc76ca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 8 Nov 2012 19:24:04 -0800 Subject: [PATCH 0806/4858] Move synopsis for commants to PHPdoc https://github.com/wp-cli/wp-cli/pull/176#issuecomment-10035053 --- src/docs/user-remove_role.txt | 7 ------- src/docs/user-set_role.txt | 9 +-------- src/php/wp-cli/commands/internals/user.php | 6 ++---- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/docs/user-remove_role.txt b/src/docs/user-remove_role.txt index 98e8cf0453..f0d6bb6bdf 100644 --- a/src/docs/user-remove_role.txt +++ b/src/docs/user-remove_role.txt @@ -1,10 +1,3 @@ -wp-user-remove_role(1) -- Remove a user's role on a blog -==== - -## SYNOPSIS - -`wp user remove_role` <user-login> - ## OPTIONS * `<user-login>`: diff --git a/src/docs/user-set_role.txt b/src/docs/user-set_role.txt index c17611ffae..0421625815 100644 --- a/src/docs/user-set_role.txt +++ b/src/docs/user-set_role.txt @@ -1,17 +1,10 @@ -wp-user-set_role(1) -- Set the user's role -==== - -## SYNOPSIS - -`wp user set_role` <user-login> [<role>] [--blog=<blog>] - ## OPTIONS * `<user-login>`: The login of the user to add to the blog. -* `<role>`: +* `[<role>]`: Add the user with the specified role. Defaults to blog default. diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 92c0c07fb3..5475c9a791 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -209,8 +209,7 @@ public function generate( $args, $assoc_args ) { /** * Add a user to a blog * - * @param array $args - * @param array $assoc_args + * @synopsis <user-login> [<role>] [--blog=<blog>] **/ public function set_role( $args, $assoc_args ) { @@ -239,8 +238,7 @@ public function set_role( $args, $assoc_args ) { /** * Remove a user from a blog * - * @param array $args - * @param array $assoc_args + * @synopsis <user-login> **/ public function remove_role( $args, $assoc_args ) { From 5ef5798eb21e116eadcdff0e0b4a4c577dca66bd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Nov 2012 16:57:42 -0800 Subject: [PATCH 0807/4858] Rename to 'set-role' and 'remove-role' --- src/docs/{user-remove_role.txt => user-remove-role.txt} | 0 src/docs/{user-set_role.txt => user-set-role.txt} | 0 src/php/wp-cli/commands/internals/user.php | 2 ++ 3 files changed, 2 insertions(+) rename src/docs/{user-remove_role.txt => user-remove-role.txt} (100%) rename src/docs/{user-set_role.txt => user-set-role.txt} (100%) diff --git a/src/docs/user-remove_role.txt b/src/docs/user-remove-role.txt similarity index 100% rename from src/docs/user-remove_role.txt rename to src/docs/user-remove-role.txt diff --git a/src/docs/user-set_role.txt b/src/docs/user-set-role.txt similarity index 100% rename from src/docs/user-set_role.txt rename to src/docs/user-set-role.txt diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 5475c9a791..c38e5807c8 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -209,6 +209,7 @@ public function generate( $args, $assoc_args ) { /** * Add a user to a blog * + * @subcommand set-role * @synopsis <user-login> [<role>] [--blog=<blog>] **/ public function set_role( $args, $assoc_args ) { @@ -238,6 +239,7 @@ public function set_role( $args, $assoc_args ) { /** * Remove a user from a blog * + * @subcommand remove-role * @synopsis <user-login> **/ public function remove_role( $args, $assoc_args ) { From cc7b0d1b5dc2e904a7d97b9181806a460a583646 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 10:02:25 +0200 Subject: [PATCH 0808/4858] formatting fixes. see #176 --- src/php/wp-cli/commands/internals/user.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 8ea13229b1..d0994d54b5 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -199,11 +199,11 @@ public function generate( $args, $assoc_args ) { } /** - * Add a user to a blog + * Add a user to a blog. * * @subcommand set-role * @synopsis <user-login> [<role>] [--blog=<blog>] - **/ + */ public function set_role( $args, $assoc_args ) { list( $id_or_login, $role ) = $args; @@ -229,13 +229,12 @@ public function set_role( $args, $assoc_args ) { } /** - * Remove a user from a blog + * Remove a user from a blog. * * @subcommand remove-role * @synopsis <user-login> - **/ + */ public function remove_role( $args, $assoc_args ) { - list( $id_or_login ) = $args; if ( is_numeric( $id_or_login ) ) From a1797019a7b7bddc18d51ade0df7b5d5c48d601c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 10:03:06 +0200 Subject: [PATCH 0809/4858] role is an optional parameter, so don't assume it's always there see #176 --- src/php/wp-cli/commands/internals/user.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index d0994d54b5..95a5f78386 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -205,8 +205,7 @@ public function generate( $args, $assoc_args ) { * @synopsis <user-login> [<role>] [--blog=<blog>] */ public function set_role( $args, $assoc_args ) { - - list( $id_or_login, $role ) = $args; + list( $id_or_login ) = $args; if ( is_numeric( $id_or_login ) ) $user = get_user_by( 'id', $id_or_login ); @@ -216,8 +215,7 @@ public function set_role( $args, $assoc_args ) { if ( ! $user ) WP_CLI::error( "Please specify a valid user ID or user login to add to this blog" ); - if ( ! get_role( $role ) ) - $role = get_option( 'default_role' ); + $role = isset( $args[1] ) ? $args[1] : get_option( 'default_role' ); // Multisite if ( function_exists( 'add_user_to_blog' ) ) From b775da1b2d8a225aa6db52bb07119992370f4b1f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 10:05:51 +0200 Subject: [PATCH 0810/4858] add get_user_from_first_arg() helper. see #176 --- src/php/wp-cli/commands/internals/user.php | 32 ++++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 95a5f78386..6dc80d224e 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -205,15 +205,7 @@ public function generate( $args, $assoc_args ) { * @synopsis <user-login> [<role>] [--blog=<blog>] */ public function set_role( $args, $assoc_args ) { - list( $id_or_login ) = $args; - - if ( is_numeric( $id_or_login ) ) - $user = get_user_by( 'id', $id_or_login ); - else - $user = get_user_by( 'login', $id_or_login ); - - if ( ! $user ) - WP_CLI::error( "Please specify a valid user ID or user login to add to this blog" ); + $user = self::get_user_from_first_arg( $args[0] ); $role = isset( $args[1] ) ? $args[1] : get_option( 'default_role' ); @@ -233,15 +225,7 @@ public function set_role( $args, $assoc_args ) { * @synopsis <user-login> */ public function remove_role( $args, $assoc_args ) { - list( $id_or_login ) = $args; - - if ( is_numeric( $id_or_login ) ) - $user = get_user_by( 'id', $id_or_login ); - else - $user = get_user_by( 'login', $id_or_login ); - - if ( ! $user ) - WP_CLI::error( "Please specify a valid user ID or user login to remove from this blog" ); + $user = self::get_user_from_first_arg( $args[0] ); // Multisite if ( function_exists( 'remove_user_from_blog' ) ) @@ -252,4 +236,16 @@ public function remove_role( $args, $assoc_args ) { WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); } + private static function get_user_from_first_arg( $id_or_login ) { + if ( is_numeric( $id_or_login ) ) + $user = get_user_by( 'id', $id_or_login ); + else + $user = get_user_by( 'login', $id_or_login ); + + if ( ! $user ) + WP_CLI::error( "Please specify a valid user ID or user login to remove from this blog" ); + + return $user; + } } + From 06ccc557935a77fea28584ccf643a836d84e8340 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 10:09:22 +0200 Subject: [PATCH 0811/4858] update docs and generate man files. see #176 --- man/user-remove-role.1 | 28 ++++++++++++++++++++++++++++ man/user-set-role.1 | 34 ++++++++++++++++++++++++++++++++++ src/docs/user-remove-role.txt | 5 +++-- src/docs/user-set-role.txt | 5 +++-- 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 man/user-remove-role.1 create mode 100644 man/user-set-role.1 diff --git a/man/user-remove-role.1 b/man/user-remove-role.1 new file mode 100644 index 0000000000..ca9a77b0de --- /dev/null +++ b/man/user-remove-role.1 @@ -0,0 +1,28 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-REMOVE\-ROLE" "1" "November 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-remove\-role\fR \- Remove a user from a blog\. +. +.SH "SYNOPSIS" +\fBwp user remove\-role\fR \fIuser\-login\fR +. +.SH "OPTIONS" +. +.TP +\fB<user\-login>\fR: +. +.IP +User ID or user login\. +. +.SH "EXAMPLES" +. +.nf + +wp user remove\-role bob +wp user remove\-role 12 +. +.fi + diff --git a/man/user-set-role.1 b/man/user-set-role.1 new file mode 100644 index 0000000000..b73d837c68 --- /dev/null +++ b/man/user-set-role.1 @@ -0,0 +1,34 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-SET\-ROLE" "1" "November 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-set\-role\fR \- Add a user to a blog\. +. +.SH "SYNOPSIS" +\fBwp user set\-role\fR \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] +. +.SH "OPTIONS" +. +.TP +\fB<user\-login>\fR: +. +.IP +User ID or user login\. +. +.TP +\fB[<role>]\fR: +. +.IP +Add the user with the specified role\. Defaults to blog default\. +. +.SH "EXAMPLES" +. +.nf + +wp user set\-role bob author +wp user set\-role 12 author +. +.fi + diff --git a/src/docs/user-remove-role.txt b/src/docs/user-remove-role.txt index f0d6bb6bdf..c85990bd4e 100644 --- a/src/docs/user-remove-role.txt +++ b/src/docs/user-remove-role.txt @@ -2,8 +2,9 @@ * `<user-login>`: - The login of the user to remove from the blog. + User ID or user login. ## EXAMPLES - wp user remove_role bob + wp user remove-role bob + wp user remove-role 12 diff --git a/src/docs/user-set-role.txt b/src/docs/user-set-role.txt index 0421625815..3c5050f0e6 100644 --- a/src/docs/user-set-role.txt +++ b/src/docs/user-set-role.txt @@ -2,7 +2,7 @@ * `<user-login>`: - The login of the user to add to the blog. + User ID or user login. * `[<role>]`: @@ -10,4 +10,5 @@ ## EXAMPLES - wp user set_role bob author + wp user set-role bob author + wp user set-role 12 author From 0f06d44f7770bcaf9ab1f3ba7f1c90dab8684fbc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 10 Nov 2012 11:18:24 -0800 Subject: [PATCH 0812/4858] If there was an issue creating the user, kick out of the loop instead of proceeding to the success message https://github.com/wp-cli/wp-cli/pull/201#issuecomment-10252908 --- src/php/wp-cli/commands/internals/user.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index d4b56d9b50..af42432358 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -246,6 +246,7 @@ public function import_csv( $args, $assoc_args ) { if ( is_wp_error( $user_id ) ) { WP_CLI::warning( $user_id ); + continue; } else { if ( false === $new_user['role'] ) { delete_user_option( $user_id, 'capabilities' ); From d3e65fd08f9aff98626faa59d882b8c9561be0fd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 22:37:35 +0200 Subject: [PATCH 0813/4858] clean up doc and generate man page. see #201 --- man/user-import-csv.1 | 34 ++++++++++++++++++++++ src/docs/user-import-csv.txt | 8 +++-- src/php/wp-cli/commands/internals/user.php | 5 ++-- 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 man/user-import-csv.1 diff --git a/man/user-import-csv.1 b/man/user-import-csv.1 new file mode 100644 index 0000000000..4c2f7d280e --- /dev/null +++ b/man/user-import-csv.1 @@ -0,0 +1,34 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-USER\-IMPORT\-CSV" "1" "November 2012" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-user\-import\-csv\fR \- Import users from a CSV file\. +. +.SH "SYNOPSIS" +\fBwp user import\-csv\fR \fIfile\fR +. +.SH "OPTIONS" +. +.TP +\fB<file>\fR: +. +.IP +The CSV file of users to import\. +. +.SH "EXAMPLES" +. +.nf + +wp user import\-csv /path/to/users\.csv + +Sample users\.csv file: + +user_login,user_email,display_name,role +bobjones,bobjones@domain\.com,Bob Jones,contributor +newuser1,newuser1@domain\.com,New User,author +existinguser,existinguser@domain\.com,Existing User,administrator +. +.fi + diff --git a/src/docs/user-import-csv.txt b/src/docs/user-import-csv.txt index 6c02912e71..e8963372a1 100644 --- a/src/docs/user-import-csv.txt +++ b/src/docs/user-import-csv.txt @@ -2,13 +2,15 @@ * `<file>`: - The csv file of users to import + The CSV file of users to import. ## EXAMPLES - wp user import_csv /path/to/csv.csv + wp user import-csv /path/to/users.csv + + Sample users.csv file: user_login,user_email,display_name,role bobjones,bobjones@domain.com,Bob Jones,contributor newuser1,newuser1@domain.com,New User,author - existinguser,existinguser@domain.com,Existing User,administrator \ No newline at end of file + existinguser,existinguser@domain.com,Existing User,administrator diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 3241d81dde..aaa39ad29f 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -249,7 +249,7 @@ private static function get_user_from_first_arg( $id_or_login ) { } /** - * Import users from a CSV + * Import users from a CSV file. * * @subcommand import-csv * @synopsis <file> @@ -304,8 +304,7 @@ public function import_csv( $args, $assoc_args ) { } } - WP_CLI::line( "{$new_user['user_login']} created" ); - + WP_CLI::line( $new_user['user_login'] . " created" ); } } } From c9f45e85b15e88ab6eb3fdcf5f1be9cd20d0ca5e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 23:18:58 +0200 Subject: [PATCH 0814/4858] extract WP_CLI::parse_args() helper --- src/php/wp-cli/class-wp-cli.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 9a4eaf57d3..13930c0d64 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -231,12 +231,7 @@ static function load_command( $command ) { return self::$commands[$command]; } - static function before_wp_load() { - self::add_man_dir( - WP_CLI_ROOT . "../../../man/", - WP_CLI_ROOT . "../../docs/" - ); - + private static function parse_args() { $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); list( self::$arguments, self::$assoc_args ) = $r; @@ -245,8 +240,19 @@ static function before_wp_load() { 'path', 'url', 'blog', 'user', 'require', 'quiet', 'completions', 'man', 'syn-list' ) ); + } - define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); + static function get_assoc_special() { + return self::$assoc_special; + } + + static function before_wp_load() { + self::add_man_dir( + WP_CLI_ROOT . "../../../man/", + WP_CLI_ROOT . "../../docs/" + ); + + self::parse_args(); // Handle --version parameter if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { @@ -254,6 +260,8 @@ static function before_wp_load() { exit; } + define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); + $_SERVER['DOCUMENT_ROOT'] = getcwd(); // Handle --path @@ -289,10 +297,6 @@ static function before_wp_load() { } } - static function get_assoc_special() { - return self::$assoc_special; - } - static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); From ab053e6f8601c3778c1b568bac686020f141ce86 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 23:22:16 +0200 Subject: [PATCH 0815/4858] add back --help flag --- src/php/wp-cli/class-wp-cli.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 13930c0d64..cbc59bcc4a 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -236,6 +236,11 @@ private static function parse_args() { list( self::$arguments, self::$assoc_args ) = $r; + if ( isset( self::$assoc_args['help'] ) ) { + array_unshift( self::$arguments, 'help' ); + unset( self::$assoc_args['help'] ); + } + self::$assoc_special = Utils\split_assoc( self::$assoc_args, array( 'path', 'url', 'blog', 'user', 'require', 'quiet', 'completions', 'man', 'syn-list' From 20625bd49f3009765628b41baa61b23bda756952 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 23:56:17 +0200 Subject: [PATCH 0816/4858] don't show date when the man page was last generated --- src/php/wp-cli/man.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index b2cc467103..515a88c6c4 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -81,7 +81,13 @@ function call_ronn( $markdown, $dest ) { 2 => STDERR ); - $r = proc_close( proc_open( "ronn --roff --manual='WP-CLI'", $descriptorspec, $pipes ) ); + $cmd = "ronn --date=2012-01-01 --roff --manual='WP-CLI'"; + + $r = proc_close( proc_open( $cmd, $descriptorspec, $pipes ) ); + + $roff = file_get_contents( $dest ); + $roff = str_replace( ' "January 2012"', '', $roff ); + file_put_contents( $dest, $roff ); \WP_CLI::line( "generated " . basename( $dest ) ); } From a9180270d4d1d7953de8b54bc5a18a1d2dd0d971 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Nov 2012 23:57:53 +0200 Subject: [PATCH 0817/4858] re-generate all man pages --- man/blog-create.1 | 2 +- man/blog-delete.1 | 2 +- man/cache.1 | 2 +- man/comment-approve.1 | 2 +- man/comment-count.1 | 2 +- man/comment-create.1 | 2 +- man/comment-delete.1 | 2 +- man/comment-last.1 | 2 +- man/comment-spam.1 | 2 +- man/comment-status.1 | 2 +- man/comment-trash.1 | 2 +- man/comment-unapprove.1 | 2 +- man/comment-unspam.1 | 2 +- man/comment-untrash.1 | 2 +- man/core-config.1 | 2 +- man/core-download.1 | 2 +- man/core-install-network.1 | 2 +- man/core-install.1 | 2 +- man/core-is-installed.1 | 2 +- man/core-update.1 | 2 +- man/core-version.1 | 2 +- man/db-drop.1 | 2 +- man/db-export.1 | 2 +- man/db-import.1 | 2 +- man/db-query.1 | 2 +- man/db-reset.1 | 2 +- man/eval-file.1 | 2 +- man/eval.1 | 2 +- man/export.1 | 2 +- man/option.1 | 2 +- man/plugin-activate.1 | 2 +- man/plugin-deactivate.1 | 2 +- man/plugin-delete.1 | 2 +- man/plugin-install.1 | 2 +- man/plugin-path.1 | 2 +- man/plugin-status.1 | 2 +- man/plugin-toggle.1 | 2 +- man/plugin-uninstall.1 | 2 +- man/plugin-update.1 | 2 +- man/post-create.1 | 2 +- man/post-delete.1 | 2 +- man/post-generate.1 | 2 +- man/post-list.1 | 2 +- man/post-meta.1 | 2 +- man/post-update.1 | 2 +- man/rewrite-dump.1 | 2 +- man/rewrite-flush.1 | 2 +- man/rewrite-structure.1 | 2 +- man/theme-activate.1 | 2 +- man/theme-delete.1 | 2 +- man/theme-install.1 | 2 +- man/theme-path.1 | 2 +- man/theme-status.1 | 2 +- man/theme-update.1 | 2 +- man/transient.1 | 2 +- man/user-create.1 | 2 +- man/user-delete.1 | 2 +- man/user-generate.1 | 2 +- man/user-import-csv.1 | 2 +- man/user-list.1 | 2 +- man/user-meta.1 | 2 +- man/user-remove-role.1 | 2 +- man/user-set-role.1 | 2 +- man/user-update.1 | 2 +- 64 files changed, 64 insertions(+), 64 deletions(-) diff --git a/man/blog-create.1 b/man/blog-create.1 index 0245da7c14..7e30d4d820 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-CREATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-BLOG\-CREATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-blog\-create\fR \- Create a blog in a multisite install\. diff --git a/man/blog-delete.1 b/man/blog-delete.1 index 556bb95c7f..da5747d997 100644 --- a/man/blog-delete.1 +++ b/man/blog-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-DELETE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-BLOG\-DELETE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-blog\-delete\fR \- Delete a blog in a multisite install\. diff --git a/man/cache.1 b/man/cache.1 index 0788dfb513..c0d6cde143 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CACHE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CACHE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-cache\fR \- Manage WordPress the object cache\. diff --git a/man/comment-approve.1 b/man/comment-approve.1 index 06ecb02c8a..2f05beb712 100644 --- a/man/comment-approve.1 +++ b/man/comment-approve.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-APPROVE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-APPROVE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-approve\fR \- Approve a comment\. diff --git a/man/comment-count.1 b/man/comment-count.1 index eda8c40ae9..499179b7d2 100644 --- a/man/comment-count.1 +++ b/man/comment-count.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-COUNT" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-COUNT" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-count\fR \- Count comments, on whole blog or on a given post\. diff --git a/man/comment-create.1 b/man/comment-create.1 index 2d7510f366..72b010be5b 100644 --- a/man/comment-create.1 +++ b/man/comment-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-CREATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-CREATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-create\fR \- Insert a comment\. diff --git a/man/comment-delete.1 b/man/comment-delete.1 index 14f31ffeca..7a90702d1a 100644 --- a/man/comment-delete.1 +++ b/man/comment-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-DELETE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-DELETE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-delete\fR \- Delete a comment\. diff --git a/man/comment-last.1 b/man/comment-last.1 index 298df14862..9f0ceb2987 100644 --- a/man/comment-last.1 +++ b/man/comment-last.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-LAST" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-LAST" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-last\fR \- Get last approved comment\. diff --git a/man/comment-spam.1 b/man/comment-spam.1 index ab667d8ca1..780872b1ac 100644 --- a/man/comment-spam.1 +++ b/man/comment-spam.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-SPAM" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-SPAM" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-spam\fR \- Spam a comment\. diff --git a/man/comment-status.1 b/man/comment-status.1 index a9256af375..556f6ad279 100644 --- a/man/comment-status.1 +++ b/man/comment-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-STATUS" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-STATUS" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-status\fR \- Get status of a comment\. diff --git a/man/comment-trash.1 b/man/comment-trash.1 index 0b9cdbe2e0..282d823413 100644 --- a/man/comment-trash.1 +++ b/man/comment-trash.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-TRASH" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-TRASH" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-trash\fR \- Trash a comment\. diff --git a/man/comment-unapprove.1 b/man/comment-unapprove.1 index 01a7ae93c3..986377f42f 100644 --- a/man/comment-unapprove.1 +++ b/man/comment-unapprove.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-UNAPPROVE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-UNAPPROVE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-unapprove\fR \- Unapprove a comment\. diff --git a/man/comment-unspam.1 b/man/comment-unspam.1 index 6b64e907da..ce9c72b99b 100644 --- a/man/comment-unspam.1 +++ b/man/comment-unspam.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-UNSPAM" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-UNSPAM" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-unspam\fR \- Unspam a comment\. diff --git a/man/comment-untrash.1 b/man/comment-untrash.1 index 7b62bfec32..ec9735a93b 100644 --- a/man/comment-untrash.1 +++ b/man/comment-untrash.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-COMMENT\-UNTRASH" "1" "October 2012" "" "WP-CLI" +.TH "WP\-COMMENT\-UNTRASH" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-comment\-untrash\fR \- Untrash a comment\. diff --git a/man/core-config.1 b/man/core-config.1 index adb58494c8..c950991e24 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-CONFIG" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-CONFIG" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-config\fR \- Set up a wp\-config\.php file\. diff --git a/man/core-download.1 b/man/core-download.1 index a654552f00..02414cb40a 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-DOWNLOAD" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-DOWNLOAD" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-download\fR \- Download core WordPress files\. diff --git a/man/core-install-network.1 b/man/core-install-network.1 index f7bb75355f..d76fc582d6 100644 --- a/man/core-install-network.1 +++ b/man/core-install-network.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-INSTALL\-NETWORK" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-INSTALL\-NETWORK" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-install\-network\fR \- Transform a single\-site install into a multi\-site install\. diff --git a/man/core-install.1 b/man/core-install.1 index 6eda4897ce..7a5e0b9a9c 100644 --- a/man/core-install.1 +++ b/man/core-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-INSTALL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-INSTALL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-install\fR \- Create the WordPress tables in the database\. diff --git a/man/core-is-installed.1 b/man/core-is-installed.1 index f2e27234ac..76a37ddda8 100644 --- a/man/core-is-installed.1 +++ b/man/core-is-installed.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-IS\-INSTALLED" "1" "November 2012" "" "WP-CLI" +.TH "WP\-CORE\-IS\-INSTALLED" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-is\-installed\fR \- Determine if the WordPress tables are installed\. diff --git a/man/core-update.1 b/man/core-update.1 index aa7cd22e47..4d69900ae0 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-update\fR \- Update WordPress\. diff --git a/man/core-version.1 b/man/core-version.1 index bb3bf3ca44..4e9599f47c 100644 --- a/man/core-version.1 +++ b/man/core-version.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-VERSION" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-VERSION" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-version\fR \- Display the WordPress version\. diff --git a/man/db-drop.1 b/man/db-drop.1 index d84934d275..3a0a06b651 100644 --- a/man/db-drop.1 +++ b/man/db-drop.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-DROP" "1" "October 2012" "" "WP-CLI" +.TH "WP\-DB\-DROP" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-drop\fR \- Delete the database\. diff --git a/man/db-export.1 b/man/db-export.1 index e4bbc63015..5dd6301427 100644 --- a/man/db-export.1 +++ b/man/db-export.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-EXPORT" "1" "October 2012" "" "WP-CLI" +.TH "WP\-DB\-EXPORT" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-export\fR \- Exports the database using mysqldump\. diff --git a/man/db-import.1 b/man/db-import.1 index 456e821c4b..c98ce4f709 100644 --- a/man/db-import.1 +++ b/man/db-import.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-IMPORT" "1" "October 2012" "" "WP-CLI" +.TH "WP\-DB\-IMPORT" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-import\fR \- Import database from a file\. diff --git a/man/db-query.1 b/man/db-query.1 index c8cd72887f..db0962429a 100644 --- a/man/db-query.1 +++ b/man/db-query.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-QUERY" "1" "October 2012" "" "WP-CLI" +.TH "WP\-DB\-QUERY" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-query\fR \- Execute a query against the database\. diff --git a/man/db-reset.1 b/man/db-reset.1 index d1c50d27c7..f8ca22aa8a 100644 --- a/man/db-reset.1 +++ b/man/db-reset.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-DB\-RESET" "1" "October 2012" "" "WP-CLI" +.TH "WP\-DB\-RESET" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-db\-reset\fR \- Remove all tables from the database\. diff --git a/man/eval-file.1 b/man/eval-file.1 index 6ca9e6d26c..bfcb674544 100644 --- a/man/eval-file.1 +++ b/man/eval-file.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EVAL\-FILE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-EVAL\-FILE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-eval\-file\fR \- Loads and executes a PHP file after loading WordPress\. diff --git a/man/eval.1 b/man/eval.1 index 8889e5f51f..558bf38e76 100644 --- a/man/eval.1 +++ b/man/eval.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EVAL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-EVAL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-eval\fR \- Executes arbitrary PHP code after loading WordPress\. diff --git a/man/export.1 b/man/export.1 index b580328262..5a3d58584e 100644 --- a/man/export.1 +++ b/man/export.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-EXPORT" "1" "November 2012" "" "WP-CLI" +.TH "WP\-EXPORT" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-export\fR \- Export posts to a WXR file\. diff --git a/man/option.1 b/man/option.1 index 678c77b487..b333c91196 100644 --- a/man/option.1 +++ b/man/option.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-OPTION" "1" "September 2012" "" "WP-CLI" +.TH "WP\-OPTION" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-option\fR \- Manage WordPress options\. diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 index b4e9fce6ae..489019db5b 100644 --- a/man/plugin-activate.1 +++ b/man/plugin-activate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-ACTIVATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-ACTIVATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-activate\fR \- Activate a plugin\. diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 index 17a87783e3..6b435292cb 100644 --- a/man/plugin-deactivate.1 +++ b/man/plugin-deactivate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DEACTIVATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-deactivate\fR \- Deactivate a plugin\. diff --git a/man/plugin-delete.1 b/man/plugin-delete.1 index b89c7ab097..3c77f7e85a 100644 --- a/man/plugin-delete.1 +++ b/man/plugin-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-DELETE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-DELETE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-delete\fR \- Delete plugin files\. diff --git a/man/plugin-install.1 b/man/plugin-install.1 index 18a07e6d2d..af58aea058 100644 --- a/man/plugin-install.1 +++ b/man/plugin-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-INSTALL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-INSTALL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-install\fR \- Install a plugin\. diff --git a/man/plugin-path.1 b/man/plugin-path.1 index d8888628c0..fe019d7188 100644 --- a/man/plugin-path.1 +++ b/man/plugin-path.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-PATH" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-PATH" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-path\fR \- Get the path to a plugin or to the plugin directory\. diff --git a/man/plugin-status.1 b/man/plugin-status.1 index 305f7902be..cb7f9b00de 100644 --- a/man/plugin-status.1 +++ b/man/plugin-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-STATUS" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-STATUS" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-status\fR \- See the status of one or all plugins\. diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 index fdfd9bf611..532fb87bd0 100644 --- a/man/plugin-toggle.1 +++ b/man/plugin-toggle.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-TOGGLE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-TOGGLE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-toggle\fR \- Toggle a plugin\'s activation state\. diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 index 0690bc46be..b837b52efd 100644 --- a/man/plugin-uninstall.1 +++ b/man/plugin-uninstall.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UNINSTALL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UNINSTALL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-uninstall\fR \- Uninstall a plugin\. diff --git a/man/plugin-update.1 b/man/plugin-update.1 index 43d0d5705b..13a769112e 100644 --- a/man/plugin-update.1 +++ b/man/plugin-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UPDATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UPDATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-update\fR \- Update a plugin\. diff --git a/man/post-create.1 b/man/post-create.1 index 4d7ca0460f..76536d6e39 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-CREATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-POST\-CREATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-create\fR \- Create a post\. diff --git a/man/post-delete.1 b/man/post-delete.1 index f2ef6523e2..45a8fa30a6 100644 --- a/man/post-delete.1 +++ b/man/post-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-DELETE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-POST\-DELETE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-delete\fR \- Delete a post by ID\. diff --git a/man/post-generate.1 b/man/post-generate.1 index 93969834d0..6fa88536df 100644 --- a/man/post-generate.1 +++ b/man/post-generate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-GENERATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-POST\-GENERATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-generate\fR \- Generate some posts\. diff --git a/man/post-list.1 b/man/post-list.1 index e35e8d6fad..c965fc51fc 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-LIST" "1" "October 2012" "" "WP-CLI" +.TH "WP\-POST\-LIST" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-list\fR \- Get a list of posts\. diff --git a/man/post-meta.1 b/man/post-meta.1 index 6107d180ab..97e8253193 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-META" "1" "September 2012" "" "WP-CLI" +.TH "WP\-POST\-META" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-meta\fR \- Manage post custom fields\. diff --git a/man/post-update.1 b/man/post-update.1 index abadef4a08..fc8249fae7 100644 --- a/man/post-update.1 +++ b/man/post-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-POST\-UPDATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-POST\-UPDATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-post\-update\fR \- Update a post\. diff --git a/man/rewrite-dump.1 b/man/rewrite-dump.1 index 8b7432011c..80d34e0730 100644 --- a/man/rewrite-dump.1 +++ b/man/rewrite-dump.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-REWRITE\-DUMP" "1" "October 2012" "" "WP-CLI" +.TH "WP\-REWRITE\-DUMP" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-rewrite\-dump\fR \- Print current rewrite rules\. diff --git a/man/rewrite-flush.1 b/man/rewrite-flush.1 index f7ba485be1..db0163863a 100644 --- a/man/rewrite-flush.1 +++ b/man/rewrite-flush.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-REWRITE\-FLUSH" "1" "October 2012" "" "WP-CLI" +.TH "WP\-REWRITE\-FLUSH" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-rewrite\-flush\fR \- Flush rewrite rules\. diff --git a/man/rewrite-structure.1 b/man/rewrite-structure.1 index 8589c5ca92..9775f55c36 100644 --- a/man/rewrite-structure.1 +++ b/man/rewrite-structure.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-REWRITE\-STRUCTURE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-REWRITE\-STRUCTURE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-rewrite\-structure\fR \- Update the permalink structure\. diff --git a/man/theme-activate.1 b/man/theme-activate.1 index cb545a291f..b408317f01 100644 --- a/man/theme-activate.1 +++ b/man/theme-activate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-ACTIVATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-ACTIVATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-activate\fR \- Activate a theme\. diff --git a/man/theme-delete.1 b/man/theme-delete.1 index 7bf9935108..6d82f601a1 100644 --- a/man/theme-delete.1 +++ b/man/theme-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-DELETE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-DELETE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-delete\fR \- Delete a theme\. diff --git a/man/theme-install.1 b/man/theme-install.1 index 96ea741d47..2665ed6715 100644 --- a/man/theme-install.1 +++ b/man/theme-install.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-INSTALL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-INSTALL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-install\fR \- Install a theme\. diff --git a/man/theme-path.1 b/man/theme-path.1 index 64275161f1..87a2c0dc75 100644 --- a/man/theme-path.1 +++ b/man/theme-path.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-PATH" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-PATH" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-path\fR \- Get the path to a theme or to the theme directory\. diff --git a/man/theme-status.1 b/man/theme-status.1 index e7b10fd128..576c274aee 100644 --- a/man/theme-status.1 +++ b/man/theme-status.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-STATUS" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-STATUS" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-status\fR \- See the status of one or all themes\. diff --git a/man/theme-update.1 b/man/theme-update.1 index b186f1f811..9f5ec07d8b 100644 --- a/man/theme-update.1 +++ b/man/theme-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-UPDATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-UPDATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-update\fR \- Update a theme\. diff --git a/man/transient.1 b/man/transient.1 index 0d10b8a23f..10077576e9 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-TRANSIENT" "1" "September 2012" "" "WP-CLI" +.TH "WP\-TRANSIENT" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-transient\fR \- Manage WordPress transients\. diff --git a/man/user-create.1 b/man/user-create.1 index 9f98d42963..99e2fd9641 100644 --- a/man/user-create.1 +++ b/man/user-create.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-CREATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-USER\-CREATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-create\fR \- Create a user\. diff --git a/man/user-delete.1 b/man/user-delete.1 index 5f76a774ad..b9b44d191e 100644 --- a/man/user-delete.1 +++ b/man/user-delete.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-DELETE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-USER\-DELETE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-delete\fR \- Delete a user\. diff --git a/man/user-generate.1 b/man/user-generate.1 index faa3c7bd1a..6e6bd54471 100644 --- a/man/user-generate.1 +++ b/man/user-generate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-GENERATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-USER\-GENERATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-generate\fR \- Generate users\. diff --git a/man/user-import-csv.1 b/man/user-import-csv.1 index 4c2f7d280e..7f8e09d260 100644 --- a/man/user-import-csv.1 +++ b/man/user-import-csv.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-IMPORT\-CSV" "1" "November 2012" "" "WP-CLI" +.TH "WP\-USER\-IMPORT\-CSV" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-import\-csv\fR \- Import users from a CSV file\. diff --git a/man/user-list.1 b/man/user-list.1 index c55e48fdda..b5bba57b7a 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-LIST" "1" "October 2012" "" "WP-CLI" +.TH "WP\-USER\-LIST" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-list\fR \- List users\. diff --git a/man/user-meta.1 b/man/user-meta.1 index 73130d87e1..4a2ab314ee 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-META" "1" "September 2012" "" "WP-CLI" +.TH "WP\-USER\-META" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-meta\fR \- Manage user custom fields\. diff --git a/man/user-remove-role.1 b/man/user-remove-role.1 index ca9a77b0de..ffa374538c 100644 --- a/man/user-remove-role.1 +++ b/man/user-remove-role.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-REMOVE\-ROLE" "1" "November 2012" "" "WP-CLI" +.TH "WP\-USER\-REMOVE\-ROLE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-remove\-role\fR \- Remove a user from a blog\. diff --git a/man/user-set-role.1 b/man/user-set-role.1 index b73d837c68..c4b99a9804 100644 --- a/man/user-set-role.1 +++ b/man/user-set-role.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-SET\-ROLE" "1" "November 2012" "" "WP-CLI" +.TH "WP\-USER\-SET\-ROLE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-set\-role\fR \- Add a user to a blog\. diff --git a/man/user-update.1 b/man/user-update.1 index 2cf19a5ec9..1e0a7ebc0b 100644 --- a/man/user-update.1 +++ b/man/user-update.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-USER\-UPDATE" "1" "October 2012" "" "WP-CLI" +.TH "WP\-USER\-UPDATE" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-user\-update\fR \- Update a user\. From 940a00e5d9070a10291ae4b2b1218e748c44e553 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Nov 2012 20:33:37 +0200 Subject: [PATCH 0818/4858] bump version to 0.7.0-beta --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 295dadc4a8..5723b4046f 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.7.0-alpha' ); +define( 'WP_CLI_VERSION', '0.7.0-beta' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 92ae99396edd454f2739e2f68b183cdb180eee12 Mon Sep 17 00:00:00 2001 From: Andreas Creten <andreas@madewithlove.be> Date: Tue, 13 Nov 2012 20:12:13 +0100 Subject: [PATCH 0819/4858] Updated README --- README.md | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b2888d0f7b..afd2cd42d0 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,23 @@ -wp-cli is a set of command-line tools for managing WordPress installations. +WP-CLI +======== +wp-cli is a set of command-line tools for managing WordPress installations. -For documentation, usage, and examples, see: -http://wp-cli.org/ +Where can I get more info? +-------------------------- +For documentation, usage, and examples, check out [wp-cli.org](http://wp-cli.org/). -To suggest a feature, report a bug, or general discussion: -https://github.com/wp-cli/wp-cli/issues +I'm running into troubles, what can I do? +----------------------------------------- -All contributors are listed here: -https://github.com/wp-cli/wp-cli/contributors +To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). + +Who's behind this thing? +------------------------ + +We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. + +A complete list of contibuters can be found [here](https://github.com/wp-cli/wp-cli/contributors). + +Need even more info? +-------------------- +Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). \ No newline at end of file From c100e6ec619873f94ff4c03531c84208904a4d1a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Nov 2012 21:14:08 +0200 Subject: [PATCH 0820/4858] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index afd2cd42d0..a2c3087697 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Who's behind this thing? We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. -A complete list of contibuters can be found [here](https://github.com/wp-cli/wp-cli/contributors). +A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). Need even more info? -------------------- From 44a0db8b8ff1fb24ffdb17edb14bd57286ceb80f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Nov 2012 10:33:35 +0200 Subject: [PATCH 0821/4858] add link to wp-cli-commits mailing list --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a2c3087697..1095531af7 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,6 @@ A complete list of contributors can be found [here](https://github.com/wp-cli/wp Need even more info? -------------------- -Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). \ No newline at end of file +Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). + +If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. From 43106793fd366f7241fd687d03ba3a90f67487e0 Mon Sep 17 00:00:00 2001 From: Andreas Creten <andreas@madewithlove.be> Date: Wed, 14 Nov 2012 20:15:44 +0100 Subject: [PATCH 0822/4858] Changed order of php lookup in find-php, give priority to custom ones --- utils/find-php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/utils/find-php b/utils/find-php index 6c4d115cf3..e1a82c470a 100755 --- a/utils/find-php +++ b/utils/find-php @@ -1,11 +1,5 @@ #!/usr/bin/env sh -which php || which php-cli - -if [ $? -eq 0 ]; then - exit -fi - # Special case for *AMP installers, since they normally don't set themselves # as the default cli php out of the box. for amp_php in $(cat $(dirname $0)/amp-paths.txt); do @@ -15,5 +9,11 @@ for amp_php in $(cat $(dirname $0)/amp-paths.txt); do fi done +which php || which php-cli + +if [ $? -eq 0 ]; then + exit +fi + echo "no php binary found" exit 1 From 9285bde6804d71d068f292d7a3c6a0c5a637c1b6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 14:05:43 +0200 Subject: [PATCH 0823/4858] remove support for default subcommands it had an inelegant implementation and it made for an inconsistent user experience --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 4 ---- src/php/wp-cli/class-wp-cli-command.php | 4 ---- src/php/wp-cli/commands/internals/db.php | 4 ---- src/php/wp-cli/dispatcher.php | 8 +------- 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index b4953557e4..13c7d1105b 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -2,10 +2,6 @@ abstract class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { - public static function get_default_subcommand() { - return 'status'; - } - protected $item_type; protected $upgrader; protected $upgrade_refresh; diff --git a/src/php/wp-cli/class-wp-cli-command.php b/src/php/wp-cli/class-wp-cli-command.php index 0bd4e12473..0cccc51a45 100644 --- a/src/php/wp-cli/class-wp-cli-command.php +++ b/src/php/wp-cli/class-wp-cli-command.php @@ -7,10 +7,6 @@ */ abstract class WP_CLI_Command { - public static function get_default_subcommand() { - return false; - } - public function __construct() {} } diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 72c27d2013..de4f35bc4f 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -10,10 +10,6 @@ */ class DB_Command extends WP_CLI_Command { - public static function get_default_subcommand() { - return 'cli'; - } - /** * Create the database, as specified in wp-config.php */ diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index a6e92b2a18..4c4cde1693 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -144,13 +144,7 @@ function invoke( $args, $assoc_args ) { } function find_subcommand( &$args ) { - $class = $this->class; - - if ( empty( $args ) ) { - $name = $class::get_default_subcommand(); - } else { - $name = array_shift( $args ); - } + $name = array_shift( $args ); $subcommands = $this->get_subcommands(); From f45e0065bda96770f81363a187f1ecdfde20143b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 14:16:49 +0200 Subject: [PATCH 0824/4858] use parent->get_path() instead of accessing parent->name directly --- src/php/wp-cli/dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 4c4cde1693..0dba97862c 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -373,7 +373,7 @@ function __construct( $method, $parent ) { } function get_path() { - return array( $this->parent->name, $this->get_name() ); + return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); } private function get_tag( $name ) { From ceb02ee7086d7b6fdc1e5a02a004f019f3dd643a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 14:28:16 +0200 Subject: [PATCH 0825/4858] hoist get_path() method up to Subcommand class --- src/php/wp-cli/class-wp-cli.php | 11 +++++++---- src/php/wp-cli/dispatcher.php | 28 ++++++++++------------------ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index cbc59bcc4a..bc9a550bd0 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -10,7 +10,10 @@ */ class WP_CLI { + public static $root; + private static $commands = array(); + private static $man_dirs = array(); private static $arguments, $assoc_args, $assoc_special; @@ -24,7 +27,7 @@ static function add_command( $name, $implementation ) { if ( is_string( $implementation ) ) $command = new Dispatcher\CompositeCommand( $name, $implementation ); else - $command = new Dispatcher\SingleCommand( $name, $implementation ); + $command = new Dispatcher\SingleCommand( $name, $implementation, self::$root ); self::$commands[ $name ] = $command; } @@ -340,9 +343,7 @@ static function after_wp_load() { } private static function run_command() { - $root = new Dispatcher\RootCommand; - - $root->invoke( self::$arguments, self::$assoc_args ); + self::$root->invoke( self::$arguments, self::$assoc_args ); } private static function generate_man( $args ) { @@ -369,3 +370,5 @@ static function addCommand( $name, $class ) { } } +WP_CLI::$root = new Dispatcher\RootCommand; + diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 0dba97862c..481a656cb2 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -5,7 +5,7 @@ function traverse( &$args ) { $args_copy = $args; - $command = new RootCommand; + $command = \WP_CLI::$root; while ( !empty( $args ) && $command && $command instanceof Composite ) { $command = $command->find_subcommand( $args ); @@ -199,7 +199,9 @@ private static function _is_good_method( $method ) { abstract class Subcommand implements Command, Documentable { - function __construct( $method ) { + function __construct( $method, $parent ) { + $this->parent = $parent; + $this->method = $method; } @@ -214,6 +216,10 @@ function get_subcommands() { return array(); } + function get_path() { + return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); + } + abstract function get_name(); protected function check_args( $args, $assoc_args ) { @@ -366,16 +372,6 @@ private static function get_patterns() { class MethodSubcommand extends Subcommand { - function __construct( $method, $parent ) { - $this->parent = $parent; - - parent::__construct( $method ); - } - - function get_path() { - return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); - } - private function get_tag( $name ) { $comment = $this->method->getDocComment(); @@ -409,23 +405,19 @@ function invoke( $args, $assoc_args ) { class SingleCommand extends Subcommand { - function __construct( $name, $callable ) { + function __construct( $name, $callable, $parent ) { $this->name = $name; $this->callable = $callable; $method = new \ReflectionMethod( $this->callable, '__invoke' ); - parent::__construct( $method ); + parent::__construct( $method, $parent ); } function get_name() { return $this->name; } - function get_path() { - return array( $this->name ); - } - function invoke( $args, $assoc_args ) { $this->check_args( $args, $assoc_args ); From c4bd5ec5ed70521623c823f75801e4f694837cb7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 14:55:32 +0200 Subject: [PATCH 0826/4858] collect subcommands in the constructor, not in find_subcommand() --- src/php/wp-cli/dispatcher.php | 79 +++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 481a656cb2..2f7343bf63 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -108,9 +108,31 @@ function get_subcommands() { class CompositeCommand implements Command, Composite { - function __construct( $name, $class ) { + protected $name; + + protected $subcommands; + + public function __construct( $name, $class ) { $this->name = $name; - $this->class = $class; + + $this->subcommands = $this->collect_subcommands( $class ); + } + + private function collect_subcommands( $class ) { + $reflection = new \ReflectionClass( $class ); + + $subcommands = array(); + + foreach ( $reflection->getMethods() as $method ) { + if ( !self::_is_good_method( $method ) ) + continue; + + $subcommand = new MethodSubcommand( $class, $method, $this ); + + $subcommands[ $subcommand->get_name() ] = $subcommand; + } + + return $subcommands; } function get_path() { @@ -175,20 +197,7 @@ private static function get_aliases( $subcommands ) { } public function get_subcommands() { - $reflection = new \ReflectionClass( $this->class ); - - $subcommands = array(); - - foreach ( $reflection->getMethods() as $method ) { - if ( !self::_is_good_method( $method ) ) - continue; - - $subcommand = new MethodSubcommand( $method, $this ); - - $subcommands[ $subcommand->get_name() ] = $subcommand; - } - - return $subcommands; + return $this->subcommands; } private static function _is_good_method( $method ) { @@ -199,10 +208,10 @@ private static function _is_good_method( $method ) { abstract class Subcommand implements Command, Documentable { - function __construct( $method, $parent ) { - $this->parent = $parent; - + function __construct( $callable, $method, $parent ) { + $this->callable = $callable; $this->method = $method; + $this->parent = $parent; } function show_usage( $prefix = 'usage: ' ) { @@ -212,6 +221,12 @@ function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $prefix . "wp $full_name $synopsis" ); } + function invoke( $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + + call_user_func( $this->callable, $args, $assoc_args ); + } + function get_subcommands() { return array(); } @@ -372,6 +387,12 @@ private static function get_patterns() { class MethodSubcommand extends Subcommand { + function __construct( $class, $method, $parent ) { + $callable = array( new $class, $method->name ); + + parent::__construct( $callable, $method, $parent ); + } + private function get_tag( $name ) { $comment = $this->method->getDocComment(); @@ -391,15 +412,6 @@ function get_name() { function get_alias() { return $this->get_tag( 'alias' ); } - - function invoke( $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - - $class = $this->parent->class; - $instance = new $class; - - $this->method->invoke( $instance, $args, $assoc_args ); - } } @@ -407,21 +419,14 @@ class SingleCommand extends Subcommand { function __construct( $name, $callable, $parent ) { $this->name = $name; - $this->callable = $callable; - $method = new \ReflectionMethod( $this->callable, '__invoke' ); + $method = new \ReflectionMethod( $callable, '__invoke' ); - parent::__construct( $method, $parent ); + parent::__construct( $callable, $method, $parent ); } function get_name() { return $this->name; } - - function invoke( $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - - $this->method->invoke( $this->callable, $args, $assoc_args ); - } } From f434aafb9ddd348395f51787d330e5f739f695b8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 15:49:14 +0200 Subject: [PATCH 0827/4858] store commands in RootCommand instead of on WP_CLI --- src/php/wp-cli/class-wp-cli.php | 47 ++---------------------------- src/php/wp-cli/dispatcher.php | 51 +++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index bc9a550bd0..7798ba50ea 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -12,8 +12,6 @@ class WP_CLI { public static $root; - private static $commands = array(); - private static $man_dirs = array(); private static $arguments, $assoc_args, $assoc_special; @@ -24,12 +22,7 @@ class WP_CLI { * @param string|object $implementation The command implementation */ static function add_command( $name, $implementation ) { - if ( is_string( $implementation ) ) - $command = new Dispatcher\CompositeCommand( $name, $implementation ); - else - $command = new Dispatcher\SingleCommand( $name, $implementation, self::$root ); - - self::$commands[ $name ] = $command; + self::$root->add_command( $name, $implementation ); } static function add_man_dir( $dest_dir, $src_dir ) { @@ -200,40 +193,6 @@ static function launch( $command, $exit_on_error = true ) { return $r; } - static function load_all_commands() { - foreach ( array( 'internals', 'community' ) as $dir ) { - foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { - $command = substr( basename( $filename ), 0, -4 ); - - if ( isset( self::$commands[ $command ] ) ) - continue; - - include $filename; - } - } - - return self::$commands; - } - - static function load_command( $command ) { - if ( !isset( self::$commands[$command] ) ) { - foreach ( array( 'internals', 'community' ) as $dir ) { - $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; - - if ( is_readable( $path ) ) { - include $path; - break; - } - } - } - - if ( !isset( self::$commands[$command] ) ) { - return false; - } - - return self::$commands[$command]; - } - private static function parse_args() { $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -323,7 +282,7 @@ static function after_wp_load() { // Handle --syn-list parameter if ( isset( self::$assoc_special['syn-list'] ) ) { - foreach ( self::load_all_commands() as $command ) { + foreach ( self::$root->get_subcommands() as $command ) { if ( $command instanceof \WP_CLI\Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) $subcommand->show_usage( '' ); @@ -357,7 +316,7 @@ private static function generate_man( $args ) { } private static function render_automcomplete() { - foreach ( self::load_all_commands() as $name => $command ) { + foreach ( self::$root->get_subcommands() as $name => $command ) { $subcommands = $command->get_subcommands(); self::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 2f7343bf63..135e2becc8 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -43,6 +43,8 @@ function get_synopsis(); class RootCommand implements Command, Composite { + protected $subcommands = array(); + function get_path() { return array(); } @@ -50,7 +52,7 @@ function get_path() { function show_usage() { \WP_CLI::line( 'Available commands:' ); - foreach ( \WP_CLI::load_all_commands() as $command ) { + foreach ( $this->get_subcommands() as $command ) { \WP_CLI::line( sprintf( " wp %s %s", implode( ' ', $command->get_path() ), implode( '|', array_keys( $command->get_subcommands() ) ) @@ -97,11 +99,54 @@ function find_subcommand( &$arguments ) { if ( isset( $aliases[ $command ] ) ) $command = $aliases[ $command ]; - return \WP_CLI::load_command( $command ); + return $this->load_command( $command ); + } + + function add_command( $name, $implementation ) { + if ( is_string( $implementation ) ) + $command = new CompositeCommand( $name, $implementation ); + else + $command = new SingleCommand( $name, $implementation, $this ); + + $this->subcommands[ $name ] = $command; } function get_subcommands() { - return \WP_CLI::load_all_commands(); + $this->load_all_commands(); + + return $this->subcommands; + } + + protected function load_all_commands() { + foreach ( array( 'internals', 'community' ) as $dir ) { + foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { + $command = substr( basename( $filename ), 0, -4 ); + + if ( isset( $this->subcommands[ $command ] ) ) + continue; + + include $filename; + } + } + } + + function load_command( $command ) { + if ( !isset( $this->subcommands[$command] ) ) { + foreach ( array( 'internals', 'community' ) as $dir ) { + $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + + if ( is_readable( $path ) ) { + include $path; + break; + } + } + } + + if ( !isset( $this->subcommands[$command] ) ) { + return false; + } + + return $this->subcommands[$command]; } } From 3613d05b9cab75bf1b7b6c2f63834d504b9b3ecb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 16:05:51 +0200 Subject: [PATCH 0828/4858] shorten path to Composite --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 7798ba50ea..5c7b551a90 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -283,7 +283,7 @@ static function after_wp_load() { // Handle --syn-list parameter if ( isset( self::$assoc_special['syn-list'] ) ) { foreach ( self::$root->get_subcommands() as $command ) { - if ( $command instanceof \WP_CLI\Dispatcher\Composite ) { + if ( $command instanceof Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) $subcommand->show_usage( '' ); } else { From 61134ecae758adbc0bbbaefae6a7343054f117a8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 16:06:17 +0200 Subject: [PATCH 0829/4858] calculate method name only once --- src/php/wp-cli/dispatcher.php | 39 ++++++++++++++++------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 135e2becc8..99358700a5 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -253,7 +253,8 @@ private static function _is_good_method( $method ) { abstract class Subcommand implements Command, Documentable { - function __construct( $callable, $method, $parent ) { + function __construct( $name, $callable, $method, $parent ) { + $this->name = $name; $this->callable = $callable; $this->method = $method; $this->parent = $parent; @@ -276,12 +277,14 @@ function get_subcommands() { return array(); } + function get_name() { + return $this->name; + } + function get_path() { return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); } - abstract function get_name(); - protected function check_args( $args, $assoc_args ) { $synopsis = $this->get_synopsis(); if ( !$synopsis ) @@ -435,11 +438,18 @@ class MethodSubcommand extends Subcommand { function __construct( $class, $method, $parent ) { $callable = array( new $class, $method->name ); - parent::__construct( $callable, $method, $parent ); + parent::__construct( self::_get_name( $method ), $callable, $method, $parent ); } - private function get_tag( $name ) { - $comment = $this->method->getDocComment(); + private static function _get_name( $method ) { + if ( $name = self::get_tag( $method, 'subcommand' ) ) + return $name; + + return $method->name; + } + + private static function get_tag( $method, $name ) { + $comment = $method->getDocComment(); if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $comment, $matches ) ) return $matches[1]; @@ -447,15 +457,8 @@ private function get_tag( $name ) { return false; } - function get_name() { - if ( $name = $this->get_tag( 'subcommand' ) ) - return $name; - - return $this->method->name; - } - function get_alias() { - return $this->get_tag( 'alias' ); + return self::get_tag( $this->method, 'alias' ); } } @@ -463,15 +466,9 @@ function get_alias() { class SingleCommand extends Subcommand { function __construct( $name, $callable, $parent ) { - $this->name = $name; - $method = new \ReflectionMethod( $callable, '__invoke' ); - parent::__construct( $callable, $method, $parent ); - } - - function get_name() { - return $this->name; + parent::__construct( $name, $callable, $method, $parent ); } } From 00f9b3db2bbde09091de11a7cc422b86c5211e11 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Nov 2012 16:09:29 +0200 Subject: [PATCH 0830/4858] dismantle SingleCommand class --- src/php/wp-cli/dispatcher.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 99358700a5..810830d794 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -105,8 +105,11 @@ function find_subcommand( &$arguments ) { function add_command( $name, $implementation ) { if ( is_string( $implementation ) ) $command = new CompositeCommand( $name, $implementation ); - else - $command = new SingleCommand( $name, $implementation, $this ); + else { + $method = new \ReflectionMethod( $implementation, '__invoke' ); + + $command = new Subcommand( $name, $implementation, $method, $this ); + } $this->subcommands[ $name ] = $command; } @@ -251,7 +254,7 @@ private static function _is_good_method( $method ) { } -abstract class Subcommand implements Command, Documentable { +class Subcommand implements Command, Documentable { function __construct( $name, $callable, $method, $parent ) { $this->name = $name; @@ -462,13 +465,3 @@ function get_alias() { } } - -class SingleCommand extends Subcommand { - - function __construct( $name, $callable, $parent ) { - $method = new \ReflectionMethod( $callable, '__invoke' ); - - parent::__construct( $name, $callable, $method, $parent ); - } -} - From 91702b5a6d9eefc1cc4871408cc833418dd75a70 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Nov 2012 10:53:11 +0200 Subject: [PATCH 0831/4858] set version to 0.7.0 --- build.properties | 2 +- src/php/wp-cli/wp-cli.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.properties b/build.properties index 5c51b0ceb9..27ad66bcea 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.name=wpcli project.channel=wp-cli.org/pear project.majorVersion=0 -project.minorVersion=6 +project.minorVersion=7 project.patchLevel=0 project.snapshot=false diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 5723b4046f..69d4d870af 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.7.0-beta' ); +define( 'WP_CLI_VERSION', '0.7.0' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 0ac2da0bc4518f80e5c37e71734370609c2a67d5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Nov 2012 14:13:40 +0200 Subject: [PATCH 0832/4858] define WP_CLI_QUIET before handling --version. fixes #213 --- src/php/wp-cli/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 5c7b551a90..6a9801ad60 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -221,14 +221,14 @@ static function before_wp_load() { self::parse_args(); + define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); + // Handle --version parameter if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { self::line( 'wp-cli ' . WP_CLI_VERSION ); exit; } - define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); - $_SERVER['DOCUMENT_ROOT'] = getcwd(); // Handle --path From f436dd1cc631c704e45d131ba5e04d1bcd887b72 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 16 Nov 2012 18:00:39 +0000 Subject: [PATCH 0833/4858] Apply the 'wxr_export_skip_postmeta' filter used in core for skipping post meta --- src/php/wp-cli/commands/internals/export.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index b2578cae22..32b4ff5b47 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -469,12 +469,15 @@ private function export_wp( $args = array() ) { <?php endif; ?> <?php wxr_post_taxonomy(); ?> <?php $postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) ); - foreach ( $postmeta as $meta ) : if ( $meta->meta_key != '_edit_lock' ) : ?> + foreach ( $postmeta as $meta ) : + if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) ) + continue; + ?> <wp:postmeta> <wp:meta_key><?php echo $meta->meta_key; ?></wp:meta_key> <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value> </wp:postmeta> -<?php endif; endforeach; ?> +<?php endforeach; ?> <?php if ( false === $args['skip_comments'] ): ?> <?php $comments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); foreach ( $comments as $c ) : ?> From df0c1e7e705dc619d4cd26590b75605d0cee5b85 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Nov 2012 20:24:03 +0200 Subject: [PATCH 0834/4858] bump version to 0.8.0-alpha --- src/php/wp-cli/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index 69d4d870af..c7a3ea82ec 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.7.0' ); +define( 'WP_CLI_VERSION', '0.8.0-alpha' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 75732ae6025432025dc942095ccf209eb50e16d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=20Burc=C4=83?= <scribu@gmail.com> Date: Sat, 17 Nov 2012 17:27:27 +0200 Subject: [PATCH 0835/4858] uppercase WP-CLI in license text --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 745e84216b..bd624ddd0e 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ ======================================== -wp-cli is licensed under the MIT License +WP-CLI is licensed under the MIT License ======================================== Copyright (C) 2011-2012 WP-CLI Development Group (https://github.com/wp-cli/wp-cli/contributors) From 7a391c2deae82d1e3678447975c14280f07849c1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 20 Nov 2012 05:55:40 +0200 Subject: [PATCH 0836/4858] introduce pre_invoke() method --- src/php/wp-cli/class-wp-cli.php | 3 ++- src/php/wp-cli/dispatcher.php | 37 +++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 6a9801ad60..062692b6d7 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -302,7 +302,8 @@ static function after_wp_load() { } private static function run_command() { - self::$root->invoke( self::$arguments, self::$assoc_args ); + $command = Dispatcher\traverse( self::$arguments, 'pre_invoke' ); + $command->invoke( self::$arguments, self::$assoc_args ); } private static function generate_man( $args ) { diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 810830d794..0b97691f5e 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -2,13 +2,13 @@ namespace WP_CLI\Dispatcher; -function traverse( &$args ) { +function traverse( &$args, $method = 'find_subcommand' ) { $args_copy = $args; $command = \WP_CLI::$root; while ( !empty( $args ) && $command && $command instanceof Composite ) { - $command = $command->find_subcommand( $args ); + $command = $command->$method( $args ); } if ( !$command ) @@ -24,13 +24,14 @@ function get_path(); function get_subcommands(); function show_usage(); - function invoke( $arguments, $assoc_args ); + function invoke( $args, $assoc_args ); } interface Composite { - function find_subcommand( &$arguments ); + function pre_invoke( &$args ); + function find_subcommand( &$args ); } @@ -74,23 +75,28 @@ function show_usage() { ); } - function invoke( $arguments, $assoc_args ) { - if ( empty( $arguments ) || array( 'help' ) == $arguments ) { + function invoke( $args, $assoc_args ) { + $subcommand = $this->pre_invoke( $args ); + $subcommand->invoke( $args, $assoc_args ); + } + + function pre_invoke( &$args ) { + if ( empty( $args ) || array( 'help' ) == $args ) { $this->show_usage(); exit; } - $cmd_name = $arguments[0]; - $command = $this->find_subcommand( $arguments ); + $cmd_name = $args[0]; + $command = $this->find_subcommand( $args ); if ( !$command ) \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $cmd_name ) ); - $command->invoke( $arguments, $assoc_args ); + return $command; } - function find_subcommand( &$arguments ) { - $command = array_shift( $arguments ); + function find_subcommand( &$args ) { + $command = array_shift( $args ); $aliases = array( 'sql' => 'db' @@ -203,14 +209,19 @@ function show_usage() { } function invoke( $args, $assoc_args ) { + $subcommand = $this->pre_invoke( $args ); + $subcommand->invoke( $args, $assoc_args ); + } + + function pre_invoke( &$args ) { $subcommand = $this->find_subcommand( $args ); if ( !$subcommand ) { $this->show_usage(); - return; + exit; } - $subcommand->invoke( $args, $assoc_args ); + return $subcommand; } function find_subcommand( &$args ) { From 32bcd448cba0859a68118e1c2492da22b2070d08 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 20 Nov 2012 06:23:12 +0200 Subject: [PATCH 0837/4858] replace --version global param with --info. fixes #219 --- src/bin/wp | 2 ++ src/php/wp-cli/class-wp-cli.php | 16 +++++++++++++--- src/php/wp-cli/dispatcher.php | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/bin/wp b/src/bin/wp index d0fbdb4ea7..fd25093a82 100755 --- a/src/bin/wp +++ b/src/bin/wp @@ -77,6 +77,8 @@ if [ "x$wp_cli_php_override" != "x" ] ; then php="$php $wp_cli_override_vars" fi +export WP_CLI_PHP_USED=$php + # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands exec $php "$SCRIPT_PATH" "$@" diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 062692b6d7..513aaf2a62 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -223,9 +223,9 @@ static function before_wp_load() { define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); - // Handle --version parameter - if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { - self::line( 'wp-cli ' . WP_CLI_VERSION ); + // Handle --info parameter + if ( isset( self::$assoc_args['info'] ) && empty( self::$arguments ) ) { + self::show_info(); exit; } @@ -306,6 +306,16 @@ private static function run_command() { $command->invoke( self::$arguments, self::$assoc_args ); } + private static function show_info() { + $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + + WP_CLI::line( "PHP binary:\t" . $php_bin ); + WP_CLI::line( "PHP version:\t" . PHP_VERSION ); + WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); + WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); + WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); + } + private static function generate_man( $args ) { $command = Dispatcher\traverse( $args ); if ( !$command ) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 0b97691f5e..7bb0b3b519 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -70,7 +70,7 @@ function show_usage() { --path=<path> set the current path to the WP install --require=<path> load a certain file before running the command --quiet suppress informational messages ---version print wp-cli version +--info print wp-cli information EOB ); } From 38580b810eb60107c8487695f020b13f945761d1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 20 Nov 2012 06:42:07 +0200 Subject: [PATCH 0838/4858] add back --version parameter. see #219 --- src/php/wp-cli/class-wp-cli.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 513aaf2a62..04c147352a 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -223,6 +223,12 @@ static function before_wp_load() { define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); + // Handle --version parameter + if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { + self::line( 'wp-cli ' . WP_CLI_VERSION ); + exit; + } + // Handle --info parameter if ( isset( self::$assoc_args['info'] ) && empty( self::$arguments ) ) { self::show_info(); From b68046b8b6923f0681e058bd7939617e8601f1d2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 Nov 2012 04:58:48 +0000 Subject: [PATCH 0839/4858] user import-csv: If the email address for a new user is already registered with an existing user, use the existing user's WP_User object instead. The prior code didn't work at all because: 1) The user_login in the CSV for the new user may not have been the same as the existing user 2) add_user_to_blog() accepts a user ID, not a user_login --- src/php/wp-cli/commands/internals/user.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index aaa39ad29f..f686ad08e9 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -281,13 +281,13 @@ public function import_csv( $args, $assoc_args ) { // User already exists and we just need to add them to the site if they aren't already there if ( $existing_user = get_user_by( 'email', $new_user['user_email'] ) ) { - if ( in_array( $new_user['user_login'], wp_list_pluck( $blog_users, 'user_login' ) ) ) - WP_CLI::warning( "{$new_user['user_login']} already is a member of blog" ); + if ( in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) ) + WP_CLI::warning( "{$existing_user->user_login} already is a member of blog" ); else if ( $new_user['role'] ) { - add_user_to_blog( get_current_blog_id(), $new_user['user_login'], $new_user['role'] ); - WP_CLI::line( "{$new_user['user_login']} added to blog as {$new_user['role']}" ); + add_user_to_blog( get_current_blog_id(), $existing_user->ID, $new_user['role'] ); + WP_CLI::line( "{$existing_user->user_login} added to blog as {$new_user['role']}" ); } else { - WP_CLI::line( "{$new_user['user_login']} exists, but won't be added to the blog" ); + WP_CLI::line( "{$existing_user->user_login} exists, but won't be added to the blog" ); } continue; } From 2cbdb22451c9368e9455271c98855ab6bd0be28b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 21 Nov 2012 15:09:53 +0200 Subject: [PATCH 0840/4858] rename `wp cli connect` to `wp cli connect-str` keep `connect` as alias, for backwards compatibility --- src/php/wp-cli/commands/internals/db.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index de4f35bc4f..f616494800 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -85,6 +85,9 @@ function repair() { /** * Print a string for connecting to the DB. + * + * @subcommand connect-str + * @subcommand connect */ function connect() { WP_CLI::line( $this->connect_string() ); From 070b77da8e5af481f95a882374eb73882291afce Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Nov 2012 03:03:21 +0200 Subject: [PATCH 0841/4858] add --ids flag to `wp user list`. fixes #223 --- man/user-list.1 | 8 +++++++- src/docs/user-list.txt | 5 +++++ src/php/wp-cli/commands/internals/user.php | 10 ++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/man/user-list.1 b/man/user-list.1 index b5bba57b7a..265b308935 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -7,7 +7,7 @@ \fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" -\fBwp user list\fR [\-\-role=\fIrole\fR] +\fBwp user list\fR [\-\-role=\fIrole\fR] [\-\-ids] . .SH "OPTIONS" . @@ -16,4 +16,10 @@ . .IP Only display users with a certain role\. +. +.TP +\fB\-\-ids\fR: +. +.IP +Return only the IDs of the found users, separated by spaces\. diff --git a/src/docs/user-list.txt b/src/docs/user-list.txt index 631b84e282..68c4eb6a76 100644 --- a/src/docs/user-list.txt +++ b/src/docs/user-list.txt @@ -3,3 +3,8 @@ * `--role`=<role>: Only display users with a certain role. + +* `--ids`: + + Return only the IDs of the found users, separated by spaces. + diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index f686ad08e9..91651512fb 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -14,14 +14,14 @@ class User_Command extends WP_CLI_Command { * List users. * * @subcommand list - * @synopsis [--role=<role>] + * @synopsis [--role=<role>] [--ids] */ public function _list( $args, $assoc_args ) { global $blog_id; $params = array( 'blog_id' => $blog_id, - 'fields' => 'all_with_meta', + 'fields' => isset( $assoc_args['ids'] ) ? 'ids' : 'all_with_meta', ); if ( array_key_exists('role', $assoc_args) ) { @@ -29,6 +29,12 @@ public function _list( $args, $assoc_args ) { } $users = get_users( $params ); + + if ( isset( $assoc_args['ids'] ) ) { + WP_CLI::out( implode( ' ', $users ) ); + return; + } + $fields = array('ID', 'user_login', 'display_name', 'user_email', 'user_registered'); From 65997186901dc849ecfcdf2c0521090c563eb30f Mon Sep 17 00:00:00 2001 From: Jaime Martinez <jmslbam@gmail.com> Date: Fri, 23 Nov 2012 17:00:25 +0100 Subject: [PATCH 0842/4858] Init commit into wp-cli --- .../wp-cli/commands/internals/scaffold.php | 160 ++++++++++++++++++ .../skeletons/post_type_skeleton.php | 79 +++++++++ .../internals/skeletons/taxonomy_skeleton.php | 47 +++++ 3 files changed, 286 insertions(+) create mode 100755 src/php/wp-cli/commands/internals/scaffold.php create mode 100755 src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php create mode 100755 src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php new file mode 100755 index 0000000000..b7e556adb4 --- /dev/null +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -0,0 +1,160 @@ +<?php +/** + * Implement Scaffold Command + * + * @package wp-cli + * @subpackage commands/community + * @maintainer LinePress (http://www.linespress.org) + */ +WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); + +class Scaffold_Command extends WP_CLI_Command { + + /** + * Subcommand custom post type + * + * @param string $args Name of custom post type + * @param array $assoc_args + * + */ + + function custom_post_type( $args, $assoc_args ) { + if( !isset( $args[0] ) ) WP_CLI::error( "Please provide a cpt name" ); + + // set the args to variables with normal names to keep our sanity + $post_type = strtolower( $args[0] ); + // we use the machine name for function declarations + $machine_name = preg_replace('/-/', '_', $post_type ); + + // if no label is given use the slug and prettify it as good as possible + if( !isset($assoc_args['label'])){ + $label = preg_replace('/_|-/', ' ', ucfirst( strtolower( $post_type ) ) ); + } + + // set up defaults and merge theme with assoc_args + $defaults = array( + 'description' => "", + 'public' => 'true', + 'exclude_from_search' => 'false', + 'show_ui' => 'true', + 'show_in_nav_menus' => 'true', + 'show_in_menu' => 'true', + 'show_in_admin_bar' => 'true', + 'menu_position' => 'null', + 'menu_icon' => 'null', + 'capability_type' => 'post', + 'hierarchical' => 'false', + 'supports' => "'title', 'editor'", + 'has_archive' => 'true', + 'rewrite' => "array( 'slug' => '{$post_type}', 'feeds' => true, 'pages' => true )", + 'query_var' => 'true', + 'can_export' => 'true', + 'context' => strtolower( wp_get_theme()->template ), + ); + + // generate the variables from the defaults and associated arguments if they are set + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + $path = TEMPLATEPATH . '/custom-post-types/'; + if(! is_dir($path) ) + mkdir( $path ); + + $file = $path . $post_type .'.php'; + $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); + + include 'skeletons/post_type_skeleton.php'; + + fwrite( $handle, $output ); + fclose( $handle ); + } + + /** + * Subcommand cpt + * Alias for custom_post_type + * + * @param string $args Name of custom post type + * @param array $assoc_args + * + */ + function cpt ( $args, $assoc_args ) { + $this->custom_post_type( $args, $assoc_args ); + } + + /** + * Subcommand taxonomy + * + * @param string $args Name of taxonomy + * @param array $assoc_args + * + */ + function taxonomy( $args, $assoc_args ) { + + if( !isset($args[0])) WP_CLI::error( "Please provide a taxonomy" ); + + // set the args to variables with normal names to keep our sanity + $taxonomy = strtolower( $args[0] ); + + // we use the machine name for function declarations + $machine_name = preg_replace('/-/', '_', $taxonomy ); + + // if no label is given use the slug and prettify it as good as possible + if( !isset($assoc_args['label'])){ + $label = preg_replace('/_|-/', ' ', ucfirst( strtolower( $taxonomy ) ) ); + } + + // set up defaults and merge theme with assoc_args + $defaults = array( + 'public' => 'true', + 'show_in_nav_menus' => 'true', + 'show_ui' => 'true', + 'show_tagcloud' => 'true', + 'hierarchical' => 'false', + 'rewrite' => 'true', + 'query_var' => 'true', + 'slug' => $taxonomy, + 'hierarchical' => 'true', + 'context' => strtolower( wp_get_theme()->template ), + 'post_types' => 'post' + ); + + // generate the variables from the defaults and associated arguments if they are set + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + $path = TEMPLATEPATH . '/taxonomies/'; + if(! is_dir($path) ) + mkdir( $path ); + + $file = $path . $taxonomy .'.php'; + $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); + + include 'skeletons/taxonomy_skeleton.php'; + + fwrite( $handle, $output ); + fclose( $handle ); + } + + /** + * Subcommand tax + * Alias for taxonomy + * + * @param string $args Name of taxonomy + * @param array $assoc_args + * + */ + function tax ( $args, $assoc_args ) { + $this->taxonomy( $args, $assoc_args ); + } + + function status( $args, $assoc_args ) { + WP_CLI::success( "status command executed \n" ); + } + + static function help() { + WP_CLI::line( 'Welcome to wp-cli scaffold' ); + WP_CLI::line( 'Possible subcommando: cpt, tax' ); + WP_CLI::line( 'Example: cpt zombie' ); + WP_CLI::line( 'Example: tax zombie_speed --post_types=zombie' ); + + } + +} \ No newline at end of file diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php new file mode 100755 index 0000000000..110f843255 --- /dev/null +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -0,0 +1,79 @@ +<?php + $output = "<?php + + if (!post_type_exists( '{$post_type}' ) ) : + register_post_type( '{$post_type}', + array( + 'label' => __( '{$label}s', '{$context}' ), + 'description' => __( '{$description}', '{$context}' ), + 'public' => {$public}, + 'exclude_from_search' => {$exclude_from_search}, + 'show_ui' => {$show_ui}, + 'show_in_nav_menus' => {$show_in_nav_menus}, + 'show_in_menu' => {$show_in_menu}, + 'show_in_admin_bar' => {$show_in_admin_bar}, + 'menu_position' => {$menu_position}, + 'menu_icon' => {$menu_icon}, + 'capability_type' => '{$capability_type}', + 'hierarchical' => {$hierarchical}, + 'supports' => {$supports}, + 'has_archive' => {$has_archive}, + 'rewrite' => array( 'slug' => '{$post_type}' ), + 'query_var' => {$query_var}, + 'can_export' => {$can_export}, + 'labels' => array( + 'name' => __( '{$label}s', '{$context}' ), + 'singular_name' => __( '{$label}', '{$context}' ), + 'add_new' => __( 'Add new {$label}', '{$context}' ), + 'all_items' => __( '{$label}s', '{$context}' ), + 'add_new_item' => __( 'Add new {$label}', '{$context}' ), + 'edit_item' => __( 'Edit {$label}', '{$context}' ), + 'new_item' => __( 'New {$label}', '{$context}' ), + 'view_item' => __( 'View {$label}', '{$context}' ), + 'search_items' => __( 'Search {$label}s', '{$context}' ), + 'not_found' => __( 'No {$label}s found', '{$context}' ), + 'not_found_in_trash' => __( 'No {$label}s found in trash', '{$context}' ), + 'parent_item_colon' => __( 'Parent {$label}', '{$context}' ), + 'menu_name' => __( '{$label}s', '{$context}' ), + ), + ) + ); + endif; + + function lp_{$machine_name}_updated_messages( \$messages ) { + global \$post, \$post_ID; + + \$messages['{$post_type}'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => sprintf( __('{$label} updated. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), + 2 => __('Custom field updated.', '{$context}'), + 3 => __('Custom field deleted.', '{$context}'), + 4 => __('{$label} updated.', '{$context}'), + /* translators: %s: date and time of the revision */ + 5 => isset(\$_GET['revision']) ? sprintf( __('{$label} restored to revision from %s', '{$context}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, + 6 => sprintf( __('{$label} published. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), + 7 => __('{$label} saved.', '{$context}'), + 8 => sprintf( __('{$label} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 9 => sprintf( __('{$label} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$context}'), + // translators: Publish box date format, see http://php.net/date + date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), + 10 => sprintf( __('{$label} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + ); + + return \$messages; + } + add_filter( 'post_updated_messages', 'lp_{$machine_name}_updated_messages' ); + + function lp_pre_single_{$machine_name}( \$query ) { + if ( get_post_type() == '{$post_type}' && \$query->is_main_query() ) { + + } + } + add_action( 'pre_get_posts', 'lp_pre_single_{$post_type}' ); + + function lp_pre_archive_{$machine_name}( \$query ) { + if ( is_post_type_archive( '{$post_type}' ) ) { + + } + } + add_action( 'pre_get_posts', 'lp_pre_archive_{$machine_name}' );"; \ No newline at end of file diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php new file mode 100755 index 0000000000..4829627820 --- /dev/null +++ b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php @@ -0,0 +1,47 @@ +<?php + $output = "<?php + + if ( !taxonomy_exists( '{$taxonomy}' ) ) : + \$labels = array( + 'name' => __( '{$taxonomy}', '{$context}' ), + 'singular_name' => __( '{$taxonomy}', '{$context}' ), + 'search_items' => __( 'Search {$taxonomy}', '{$context}' ), + 'popular_items' => __( 'Popular {$taxonomy}', '{$context}' ), + 'all_items' => __( 'All {$taxonomy}', '{$context}' ), + 'parent_item' => __( 'Parent {$taxonomy}', '{$context}' ), + 'parent_item_colon' => __( 'Parent {$taxonomy}:', '{$context}' ), + 'edit_item' => __( 'Edit {$taxonomy}', '{$context}' ), + 'update_item' => __( 'Update {$taxonomy}', '{$context}' ), + 'add_new_item' => __( 'New {$taxonomy}', '{$context}' ), + 'new_item_name' => __( 'New {$taxonomy}', '{$context}' ), + 'separate_items_with_commas' => __( '{$taxonomy}s seperated by comma', '{$context}' ), + 'add_or_remove_items' => __( 'Add or remove {$taxonomy}s', '{$context}' ), + 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$context}' ), + 'menu_name' => __( '{$taxonomy}s', '{$context}' ), + ); + + \$args = array( + 'labels' => \$labels, + 'public' => {$public}, + 'show_in_nav_menus' => {$show_in_nav_menus}, + 'show_ui' => {$show_ui}, + 'show_tagcloud' => {$show_tagcloud}, + 'hierarchical' => {$hierarchical}, + 'update_count_callback' => '_update_post_term_count', + 'rewrite' => {$rewrite}, + 'query_var' => {$query_var}, + 'capabilities' => array ( + 'manage_terms' => 'edit_posts', + 'edit_terms' => 'edit_posts', + 'delete_terms' => 'edit_posts', + 'assign_terms' => 'edit_posts' + ), + 'rewrite' => array( + 'slug' => '{$taxonomy}', + 'hierarchical' => {$hierarchical} + ), + ); + + register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args ); + + endif;"; \ No newline at end of file From 3bedbc86e31a54c575e65f563384caee79251e5f Mon Sep 17 00:00:00 2001 From: Jaime Martinez <jmslbam@gmail.com> Date: Fri, 23 Nov 2012 17:05:00 +0100 Subject: [PATCH 0843/4858] changed subpackes to internals --- src/php/wp-cli/commands/internals/scaffold.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index b7e556adb4..915f6096e0 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -1,11 +1,12 @@ <?php /** - * Implement Scaffold Command + * Implement scaffold command * * @package wp-cli - * @subpackage commands/community + * @subpackage commands/internals * @maintainer LinePress (http://www.linespress.org) */ + WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); class Scaffold_Command extends WP_CLI_Command { From 19cb1210c833c4f8e6d98d8b478af889fb4136ef Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sat, 24 Nov 2012 00:25:49 +0100 Subject: [PATCH 0844/4858] Removed command aliasses and renamed custom post type to post type because everywhere in WP they use post type --- .../wp-cli/commands/internals/scaffold.php | 36 ++++--------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 915f6096e0..16616d2477 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -12,15 +12,15 @@ class Scaffold_Command extends WP_CLI_Command { /** - * Subcommand custom post type + * Subcommand post type * - * @param string $args Name of custom post type + * @param string $args Name of post type * @param array $assoc_args * */ - function custom_post_type( $args, $assoc_args ) { - if( !isset( $args[0] ) ) WP_CLI::error( "Please provide a cpt name" ); + function post_type( $args, $assoc_args ) { + if( !isset( $args[0] ) ) WP_CLI::error( "Please provide a post type name" ); // set the args to variables with normal names to keep our sanity $post_type = strtolower( $args[0] ); @@ -56,7 +56,7 @@ function custom_post_type( $args, $assoc_args ) { // generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - $path = TEMPLATEPATH . '/custom-post-types/'; + $path = TEMPLATEPATH . '/post-types/'; if(! is_dir($path) ) mkdir( $path ); @@ -69,18 +69,6 @@ function custom_post_type( $args, $assoc_args ) { fclose( $handle ); } - /** - * Subcommand cpt - * Alias for custom_post_type - * - * @param string $args Name of custom post type - * @param array $assoc_args - * - */ - function cpt ( $args, $assoc_args ) { - $this->custom_post_type( $args, $assoc_args ); - } - /** * Subcommand taxonomy * @@ -134,20 +122,8 @@ function taxonomy( $args, $assoc_args ) { fclose( $handle ); } - /** - * Subcommand tax - * Alias for taxonomy - * - * @param string $args Name of taxonomy - * @param array $assoc_args - * - */ - function tax ( $args, $assoc_args ) { - $this->taxonomy( $args, $assoc_args ); - } - function status( $args, $assoc_args ) { - WP_CLI::success( "status command executed \n" ); + WP_CLI::success( "Status command executed \n" ); } static function help() { From 8891c2d9c21f76824e30241b0253a77b72c306be Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sat, 24 Nov 2012 00:29:45 +0100 Subject: [PATCH 0845/4858] Edited help text --- src/php/wp-cli/commands/internals/scaffold.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 16616d2477..0ad8625167 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -12,7 +12,7 @@ class Scaffold_Command extends WP_CLI_Command { /** - * Subcommand post type + * Subcommand posttype * * @param string $args Name of post type * @param array $assoc_args @@ -128,9 +128,9 @@ function status( $args, $assoc_args ) { static function help() { WP_CLI::line( 'Welcome to wp-cli scaffold' ); - WP_CLI::line( 'Possible subcommando: cpt, tax' ); - WP_CLI::line( 'Example: cpt zombie' ); - WP_CLI::line( 'Example: tax zombie_speed --post_types=zombie' ); + WP_CLI::line( 'Possible subcommando: post_type, taxonomy' ); + WP_CLI::line( 'Example: post_type zombie' ); + WP_CLI::line( 'Example: taxonomy zombie_speed --post_types=zombie' ); } From 39e2375982201d3a6418db3ef276910e1f83547d Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sat, 24 Nov 2012 00:43:28 +0100 Subject: [PATCH 0846/4858] Remove status command --- src/php/wp-cli/commands/internals/scaffold.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 0ad8625167..50805fa254 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -122,16 +122,11 @@ function taxonomy( $args, $assoc_args ) { fclose( $handle ); } - function status( $args, $assoc_args ) { - WP_CLI::success( "Status command executed \n" ); - } - static function help() { WP_CLI::line( 'Welcome to wp-cli scaffold' ); WP_CLI::line( 'Possible subcommando: post_type, taxonomy' ); WP_CLI::line( 'Example: post_type zombie' ); WP_CLI::line( 'Example: taxonomy zombie_speed --post_types=zombie' ); - } } \ No newline at end of file From 9fb37ae144b9e9aacacfab395595e8fa4dc4a00e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 24 Nov 2012 02:43:13 +0200 Subject: [PATCH 0847/4858] clean up post generate synopsis and man page --- man/post-generate.1 | 14 ++++++++++---- src/docs/post-generate.txt | 10 +++++++--- src/php/wp-cli/commands/internals/post.php | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/man/post-generate.1 b/man/post-generate.1 index 6fa88536df..a5a78c5e7c 100644 --- a/man/post-generate.1 +++ b/man/post-generate.1 @@ -7,7 +7,7 @@ \fBwp\-post\-generate\fR \- Generate some posts\. . .SH "SYNOPSIS" -\fBwp post generate\fR [\-\-count=100] [\-\-post_type=post] [\-\-post_status=publish] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIdate\fR] [\-\-max_depth=1] +\fBwp post generate\fR [\-\-count=100] [\-\-post_type=\fItype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIyyyy\-mm\-dd\fR] [\-\-max_depth=1] . .SH "OPTIONS" . @@ -18,24 +18,30 @@ How many posts to generate\. Default: 100 . .TP -\fB\-\-type\fR=\fIpost_type\fR: +\fB\-\-post_type\fR=\fItype\fR: . .IP The type of the generated posts\. Default: \'post\' . .TP -\fB\-\-status\fR=\fIpost_status\fR: +\fB\-\-post_status\fR=\fIstatus\fR: . .IP The status of the generated posts\. Default: \'publish\' . .TP -\fB\-\-author\fR=\fIlogin\fR: +\fB\-\-post_author\fR=\fIlogin\fR: . .IP The author of the generated posts\. Default: none . .TP +\fB\-\-post_date\fR=\fIyyyy\-mm\-dd\fR: +. +.IP +The date of the generated posts\. Default: current date +. +.TP \fB\-\-max_depth\fR=\fInumber\fR: . .IP diff --git a/src/docs/post-generate.txt b/src/docs/post-generate.txt index cab9b591f2..7dba04a6f6 100644 --- a/src/docs/post-generate.txt +++ b/src/docs/post-generate.txt @@ -4,18 +4,22 @@ How many posts to generate. Default: 100 -* `--type`=<post_type>: +* `--post_type`=<type>: The type of the generated posts. Default: 'post' -* `--status`=<post_status>: +* `--post_status`=<status>: The status of the generated posts. Default: 'publish' -* `--author`=<login>: +* `--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 + * `--max_depth`=<number>: For hierarchical post types, generate child posts down to a certain depth. Default: 1 diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index c05c3b8d4a..dd84c51db4 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -117,7 +117,7 @@ public function _list( $_, $assoc_args ) { /** * Generate some posts. * - * @synopsis [--count=100] [--post_type=post] [--post_status=publish] [--post_author=<login>] [--post_date=<date>] [--max_depth=1] + * @synopsis [--count=100] [--post_type=<type>] [--post_status=<status>] [--post_author=<login>] [--post_date=<yyyy-mm-dd>] [--max_depth=1] */ public function generate( $args, $assoc_args ) { global $wpdb; From c25ac12673898cdfe2cbba079a8b075dac70e7c2 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sat, 24 Nov 2012 14:40:12 +0100 Subject: [PATCH 0848/4858] Use wp_cli launch instead of php to mkdir --- src/php/wp-cli/commands/internals/scaffold.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 50805fa254..6f908ea33e 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -58,7 +58,7 @@ function post_type( $args, $assoc_args ) { $path = TEMPLATEPATH . '/post-types/'; if(! is_dir($path) ) - mkdir( $path ); + WP_CLI::launch('mkdir ' . $path); $file = $path . $post_type .'.php'; $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); @@ -111,7 +111,7 @@ function taxonomy( $args, $assoc_args ) { $path = TEMPLATEPATH . '/taxonomies/'; if(! is_dir($path) ) - mkdir( $path ); + WP_CLI::launch('mkdir ' . $path); $file = $path . $taxonomy .'.php'; $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); From 52b8ecb0e88ec9f2eaf136ff1fada6ddab5664c7 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sat, 24 Nov 2012 14:52:26 +0100 Subject: [PATCH 0849/4858] Cleanup, spaces and Capitalize sentences --- .../wp-cli/commands/internals/scaffold.php | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 6f908ea33e..a864e496c2 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -1,4 +1,7 @@ <?php + +WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); + /** * Implement scaffold command * @@ -6,30 +9,29 @@ * @subpackage commands/internals * @maintainer LinePress (http://www.linespress.org) */ - -WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); - class Scaffold_Command extends WP_CLI_Command { /** * Subcommand posttype * * @param string $args Name of post type - * @param array $assoc_args + * @param array $assoc_args The ussual WordPress arguments * */ - function post_type( $args, $assoc_args ) { - if( !isset( $args[0] ) ) WP_CLI::error( "Please provide a post type name" ); + if( !isset( $args[0] ) ) { + WP_CLI::error( "Please provide a post type name" ); + } - // set the args to variables with normal names to keep our sanity + // Set the args to variables with normal names to keep our sanity $post_type = strtolower( $args[0] ); - // we use the machine name for function declarations - $machine_name = preg_replace('/-/', '_', $post_type ); - // if no label is given use the slug and prettify it as good as possible - if( !isset($assoc_args['label'])){ - $label = preg_replace('/_|-/', ' ', ucfirst( strtolower( $post_type ) ) ); + // We use the machine name for function declarations + $machine_name = preg_replace( '/-/', '_', $post_type ); + + // If no label is given use the slug and prettify it as good as possible + if( !isset( $assoc_args['label'] ) ) { + $label = preg_replace( '/_|-/', ' ', ucfirst( strtolower( $post_type ) ) ); } // set up defaults and merge theme with assoc_args @@ -53,12 +55,12 @@ function post_type( $args, $assoc_args ) { 'context' => strtolower( wp_get_theme()->template ), ); - // generate the variables from the defaults and associated arguments if they are set + // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); $path = TEMPLATEPATH . '/post-types/'; - if(! is_dir($path) ) - WP_CLI::launch('mkdir ' . $path); + if(! is_dir( $path ) ) + WP_CLI::launch( 'mkdir ' . $path ); $file = $path . $post_type .'.php'; $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); @@ -73,25 +75,27 @@ function post_type( $args, $assoc_args ) { * Subcommand taxonomy * * @param string $args Name of taxonomy - * @param array $assoc_args + * @param array $assoc_args The ussual WordPress arguments * */ function taxonomy( $args, $assoc_args ) { - if( !isset($args[0])) WP_CLI::error( "Please provide a taxonomy" ); + if( !isset( $args[0] ) ) { + WP_CLI::error( "Please provide a taxonomy" ); + } - // set the args to variables with normal names to keep our sanity + // Set the args to variables with normal names to keep our sanity $taxonomy = strtolower( $args[0] ); - // we use the machine name for function declarations - $machine_name = preg_replace('/-/', '_', $taxonomy ); + // We use the machine name for function declarations + $machine_name = preg_replace( '/-/', '_', $taxonomy ); - // if no label is given use the slug and prettify it as good as possible - if( !isset($assoc_args['label'])){ - $label = preg_replace('/_|-/', ' ', ucfirst( strtolower( $taxonomy ) ) ); + // If no label is given use the slug and prettify it as good as possible + if( !isset( $assoc_args['label'] ) ){ + $label = preg_replace( '/_|-/', ' ', ucfirst( strtolower( $taxonomy ) ) ); } - // set up defaults and merge theme with assoc_args + // Set up defaults and merge theme with assoc_args $defaults = array( 'public' => 'true', 'show_in_nav_menus' => 'true', @@ -106,20 +110,20 @@ function taxonomy( $args, $assoc_args ) { 'post_types' => 'post' ); - // generate the variables from the defaults and associated arguments if they are set + // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); $path = TEMPLATEPATH . '/taxonomies/'; - if(! is_dir($path) ) - WP_CLI::launch('mkdir ' . $path); + if(! is_dir( $path ) ) + WP_CLI::launch( 'mkdir ' . $path ); $file = $path . $taxonomy .'.php'; $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); include 'skeletons/taxonomy_skeleton.php'; - fwrite( $handle, $output ); - fclose( $handle ); + fwrite( $handle, $output ); + fclose( $handle ); } static function help() { @@ -128,5 +132,4 @@ static function help() { WP_CLI::line( 'Example: post_type zombie' ); WP_CLI::line( 'Example: taxonomy zombie_speed --post_types=zombie' ); } - } \ No newline at end of file From d126da362bcb9a78a6fb92ba5f5c8d33e7d7a9ac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 24 Nov 2012 16:51:28 +0200 Subject: [PATCH 0850/4858] update description of WP_CLI::launch() --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 04c147352a..973dd0606c 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -177,7 +177,7 @@ static function compose_args( $args, $assoc_args = array() ) { } /** - * Launch an external process, closing the current one + * Launch an external process that takes over I/O. * * @param string Command to call * @param bool Whether to exit if the command returns an error status From 324a200a50d83e2f23b7181edf6b8aa803466225 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 25 Nov 2012 16:07:21 +0100 Subject: [PATCH 0851/4858] Using WP_Filesystem to create dirs and write files --- .../wp-cli/commands/internals/scaffold.php | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index a864e496c2..55ddbaa7fa 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -11,6 +11,10 @@ */ class Scaffold_Command extends WP_CLI_Command { + function __construct() { + WP_Filesystem(); + } + /** * Subcommand posttype * @@ -19,6 +23,8 @@ class Scaffold_Command extends WP_CLI_Command { * */ function post_type( $args, $assoc_args ) { + global $wp_filesystem; + if( !isset( $args[0] ) ) { WP_CLI::error( "Please provide a post type name" ); } @@ -59,16 +65,17 @@ function post_type( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); $path = TEMPLATEPATH . '/post-types/'; - if(! is_dir( $path ) ) - WP_CLI::launch( 'mkdir ' . $path ); + if( !$wp_filesystem->is_dir( $path ) ) { + $wp_filesystem->mkdir( $path ); + } + + $filename = $path . $post_type .'.php'; - $file = $path . $post_type .'.php'; - $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); - include 'skeletons/post_type_skeleton.php'; - fwrite( $handle, $output ); - fclose( $handle ); + if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { + WP_CLI::error( 'Error while saving file' ); + } } /** @@ -79,6 +86,7 @@ function post_type( $args, $assoc_args ) { * */ function taxonomy( $args, $assoc_args ) { + global $wp_filesystem; if( !isset( $args[0] ) ) { WP_CLI::error( "Please provide a taxonomy" ); @@ -91,7 +99,7 @@ function taxonomy( $args, $assoc_args ) { $machine_name = preg_replace( '/-/', '_', $taxonomy ); // If no label is given use the slug and prettify it as good as possible - if( !isset( $assoc_args['label'] ) ){ + if( !isset( $assoc_args['label'] ) ) { $label = preg_replace( '/_|-/', ' ', ucfirst( strtolower( $taxonomy ) ) ); } @@ -114,16 +122,17 @@ function taxonomy( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); $path = TEMPLATEPATH . '/taxonomies/'; - if(! is_dir( $path ) ) - WP_CLI::launch( 'mkdir ' . $path ); - - $file = $path . $taxonomy .'.php'; - $handle = fopen( $file, 'wb' ) or die( 'Cannot open file: ' . $file ); - + if( !$wp_filesystem->is_dir( $path ) ) { + $wp_filesystem->mkdir( $path ); + } + + $filename = $path . $taxonomy .'.php'; + include 'skeletons/taxonomy_skeleton.php'; - fwrite( $handle, $output ); - fclose( $handle ); + if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { + WP_CLI::error( 'Error while saving file' ); + } } static function help() { From cb8030453c71a4b0aa460805bb93d9d7bb4503ad Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 25 Nov 2012 16:10:40 +0100 Subject: [PATCH 0852/4858] Added feedback on success when creating a post type or taxonomy --- src/php/wp-cli/commands/internals/scaffold.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 55ddbaa7fa..ca20c02911 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -75,6 +75,8 @@ function post_type( $args, $assoc_args ) { if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { WP_CLI::error( 'Error while saving file' ); + } else { + WP_CLI::success( $post_type . ' created' ); } } @@ -132,6 +134,8 @@ function taxonomy( $args, $assoc_args ) { if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { WP_CLI::error( 'Error while saving file' ); + } else { + WP_CLI::success( $taxonomy . ' created' ); } } From 64cf0578fdb4168a8ca2ee6750444117c61fcfcb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 27 Nov 2012 02:17:38 +0200 Subject: [PATCH 0853/4858] user create: add user_pass, user_registered and display_name to list of accepted parameters --- man/user-create.1 | 22 ++++++++++++++++++++-- src/docs/user-create.txt | 14 +++++++++++++- src/php/wp-cli/commands/internals/user.php | 7 ++++--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/man/user-create.1 b/man/user-create.1 index 99e2fd9641..dabdae714a 100644 --- a/man/user-create.1 +++ b/man/user-create.1 @@ -7,7 +7,7 @@ \fBwp\-user\-create\fR \- Create a user\. . .SH "SYNOPSIS" -\fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-porcelain] +\fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-user_pass=\fIpassword\fR] [\-\-user_registered=\fIyyyy\-mm\-dd\fR] [\-\-display_name=\fIname\fR] [\-\-porcelain] . .SH "OPTIONS" . @@ -27,7 +27,25 @@ The email address of the user to create\. \fB\-\-role\fR=\fIrole\fR: . .IP -The role of the user to create\. +The role of the user to create\. Default: default role +. +.TP +\fB\-\-user_pass\fR=\fIpassword\fR: +. +.IP +The user password\. Default: randomly generated +. +.TP +\fB\-\-user_registered\fR=\fIyyyy\-mm\-dd\fR: +. +.IP +The date the user registered\. Default: current date +. +.TP +\fB\-\-display_name\fR=\fIname\fR: +. +.IP +The display name\. . .TP \fB\-\-porcelain\fR: diff --git a/src/docs/user-create.txt b/src/docs/user-create.txt index 6ba889ecea..8b860096b5 100644 --- a/src/docs/user-create.txt +++ b/src/docs/user-create.txt @@ -10,7 +10,19 @@ * `--role`=<role>: - The role of the user to create. + The role of the user to create. Default: default role + +* `--user_pass`=<password>: + + The user password. Default: randomly generated + +* `--user_registered`=<yyyy-mm-dd>: + + The date the user registered. Default: current date + +* `--display_name`=<name>: + + The display name. * `--porcelain`: diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 91651512fb..0e48ee65d8 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -82,7 +82,7 @@ public function delete( $args, $assoc_args ) { /** * Create a user. * - * @synopsis <user-login> <user-email> [--role=<role>] [--porcelain] + * @synopsis <user-login> <user-email> [--role=<role>] [--user_pass=<password>] [--user_registered=<yyyy-mm-dd>] [--display_name=<name>] [--porcelain] */ public function create( $args, $assoc_args ) { global $blog_id; @@ -122,10 +122,11 @@ public function create( $args, $assoc_args ) { } } - if ( isset( $assoc_args['porcelain'] ) ) + if ( isset( $assoc_args['porcelain'] ) ) { WP_CLI::line( $user_id ); - else + } else { WP_CLI::success( "Created user $user_id." ); + } } /** From b00255355b7528cf54020fd9e691bded378df674 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 27 Nov 2012 02:20:08 +0200 Subject: [PATCH 0854/4858] show generated password. fixes #227 --- src/php/wp-cli/commands/internals/user.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 0e48ee65d8..3a186402f2 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -91,7 +91,7 @@ public function create( $args, $assoc_args ) { $defaults = array( 'role' => get_option('default_role'), - 'user_pass' => wp_generate_password(), + 'user_pass' => false, 'user_registered' => strftime( "%F %T", time() ), 'display_name' => false, ); @@ -104,6 +104,11 @@ public function create( $args, $assoc_args ) { WP_CLI::error( "Invalid role." ); } + if ( !$user_pass ) { + $user_pass = wp_generate_password(); + $generated_pass = true; + } + $user_id = wp_insert_user( array( 'user_email' => $user_email, 'user_login' => $user_login, @@ -126,6 +131,8 @@ public function create( $args, $assoc_args ) { WP_CLI::line( $user_id ); } else { WP_CLI::success( "Created user $user_id." ); + if ( isset( $generated_pass ) ) + WP_CLI::line( "Password: $user_pass" ); } } From 1b9ca8b081f35d97a55896edb20b7358c214ec52 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Tue, 27 Nov 2012 18:38:24 +0100 Subject: [PATCH 0855/4858] added pluralize private function, updated the post_type_skeleton with pluralized labels and fixed the pre_get_posts hooks, fixed a bug with supports variable --- .../wp-cli/commands/internals/scaffold.php | 67 +++++++++++++++++-- .../skeletons/post_type_skeleton.php | 48 +++++++------ 2 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index ca20c02911..52553cf497 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -30,14 +30,19 @@ function post_type( $args, $assoc_args ) { } // Set the args to variables with normal names to keep our sanity - $post_type = strtolower( $args[0] ); + $post_type = strtolower( $args[0] ); // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $post_type ); + $machine_name = preg_replace( '/-/', '_', $post_type ); + $machine_name_plural = $this->pluralize( $post_type ); // If no label is given use the slug and prettify it as good as possible if( !isset( $assoc_args['label'] ) ) { - $label = preg_replace( '/_|-/', ' ', ucfirst( strtolower( $post_type ) ) ); + $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); + $label_ucfirst = ucfirst( $label ); + $label_plural = $this->pluralize( $label ); + + $label_plural_ucfirst = ucfirst( $label_plural ); } // set up defaults and merge theme with assoc_args @@ -55,7 +60,7 @@ function post_type( $args, $assoc_args ) { 'hierarchical' => 'false', 'supports' => "'title', 'editor'", 'has_archive' => 'true', - 'rewrite' => "array( 'slug' => '{$post_type}', 'feeds' => true, 'pages' => true )", + 'rewrite' => "array( 'slug' => '{$machine_name_plural}', 'feeds' => true, 'pages' => true )", 'query_var' => 'true', 'can_export' => 'true', 'context' => strtolower( wp_get_theme()->template ), @@ -145,4 +150,58 @@ static function help() { WP_CLI::line( 'Example: post_type zombie' ); WP_CLI::line( 'Example: taxonomy zombie_speed --post_types=zombie' ); } + + private function pluralize($word) { + $plural = array( + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)ix|ex$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(buffal|tomat)o$/i' => '\1oes', + '/(bu)s$/i' => '1ses', + '/(alias|status)/i' => '\1es', + '/(octop|vir)us$/i' => '1i', + '/(ax|test)is$/i' => '\1es', + '/s$/i' => 's', + '/$/' => 's'); + + $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'); + + $irregular = array( + 'person' => 'people', + 'man' => 'men', + 'woman' => 'women', + 'child' => 'children', + 'sex' => 'sexes', + 'move' => 'moves'); + + $lowercased_word = strtolower($word); + + foreach ($uncountable as $_uncountable){ + if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){ + return $word; + } + } + + foreach ($irregular as $_plural=> $_singular){ + if (preg_match('/('.$_plural.')$/i', $word, $arr)) { + return preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word); + } + } + + foreach ($plural as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + return false; + + } } \ No newline at end of file diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 110f843255..fc3edc528c 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -4,7 +4,7 @@ if (!post_type_exists( '{$post_type}' ) ) : register_post_type( '{$post_type}', array( - 'label' => __( '{$label}s', '{$context}' ), + 'label' => __( '{$label_plural_ucfirst}', '{$context}' ), 'description' => __( '{$description}', '{$context}' ), 'public' => {$public}, 'exclude_from_search' => {$exclude_from_search}, @@ -16,25 +16,25 @@ 'menu_icon' => {$menu_icon}, 'capability_type' => '{$capability_type}', 'hierarchical' => {$hierarchical}, - 'supports' => {$supports}, + 'supports' => array( {$supports} ), 'has_archive' => {$has_archive}, - 'rewrite' => array( 'slug' => '{$post_type}' ), + 'rewrite' => {$rewrite}, 'query_var' => {$query_var}, 'can_export' => {$can_export}, 'labels' => array( - 'name' => __( '{$label}s', '{$context}' ), - 'singular_name' => __( '{$label}', '{$context}' ), + 'name' => __( '{$label_plural_ucfirst}', '{$context}' ), + 'singular_name' => __( '{$label_ucfirst}', '{$context}' ), 'add_new' => __( 'Add new {$label}', '{$context}' ), - 'all_items' => __( '{$label}s', '{$context}' ), + 'all_items' => __( '{$label_plural_ucfirst}', '{$context}' ), 'add_new_item' => __( 'Add new {$label}', '{$context}' ), 'edit_item' => __( 'Edit {$label}', '{$context}' ), 'new_item' => __( 'New {$label}', '{$context}' ), 'view_item' => __( 'View {$label}', '{$context}' ), - 'search_items' => __( 'Search {$label}s', '{$context}' ), - 'not_found' => __( 'No {$label}s found', '{$context}' ), - 'not_found_in_trash' => __( 'No {$label}s found in trash', '{$context}' ), + 'search_items' => __( 'Search {$label_plural}', '{$context}' ), + 'not_found' => __( 'No {$label_plural} found', '{$context}' ), + 'not_found_in_trash' => __( 'No {$label_plural} found in trash', '{$context}' ), 'parent_item_colon' => __( 'Parent {$label}', '{$context}' ), - 'menu_name' => __( '{$label}s', '{$context}' ), + 'menu_name' => __( '{$label_plural_ucfirst}', '{$context}' ), ), ) ); @@ -45,19 +45,19 @@ function lp_{$machine_name}_updated_messages( \$messages ) { \$messages['{$post_type}'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label} updated. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), + 1 => sprintf( __('{$label_ucfirst} updated. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), 2 => __('Custom field updated.', '{$context}'), 3 => __('Custom field deleted.', '{$context}'), - 4 => __('{$label} updated.', '{$context}'), + 4 => __('{$label_ucfirst} updated.', '{$context}'), /* translators: %s: date and time of the revision */ - 5 => isset(\$_GET['revision']) ? sprintf( __('{$label} restored to revision from %s', '{$context}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label} published. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), - 7 => __('{$label} saved.', '{$context}'), - 8 => sprintf( __('{$label} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), - 9 => sprintf( __('{$label} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$context}'), + 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$context}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, + 6 => sprintf( __('{$label_ucfirst} published. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), + 7 => __('{$label_ucfirst} saved.', '{$context}'), + 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$context}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), ); return \$messages; @@ -65,14 +65,18 @@ function lp_{$machine_name}_updated_messages( \$messages ) { add_filter( 'post_updated_messages', 'lp_{$machine_name}_updated_messages' ); function lp_pre_single_{$machine_name}( \$query ) { - if ( get_post_type() == '{$post_type}' && \$query->is_main_query() ) { - + if ( !is_admin() && get_post_type() == '{$post_type}' && is_main_query() ) { + // use \$query->set() to change the main query + // or use this function to hook in some other specific code + } } - add_action( 'pre_get_posts', 'lp_pre_single_{$post_type}' ); + add_action( 'pre_get_posts', 'lp_pre_single_{$machine_name}' ); function lp_pre_archive_{$machine_name}( \$query ) { - if ( is_post_type_archive( '{$post_type}' ) ) { + if ( !is_admin() && is_post_type_archive( '{$post_type}' ) ) { + // use \$query->set() to change the main query + // or use this function to hook in some other specific code } } From 33df6d7946887cd756cb510fb2676a5eb7fd6e5a Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Tue, 27 Nov 2012 19:04:30 +0100 Subject: [PATCH 0856/4858] Split up the rewrite argument into slug, feed and pages. Adjusted the skeleton to support this --- src/php/wp-cli/commands/internals/scaffold.php | 10 +++++----- .../internals/skeletons/post_type_skeleton.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 52553cf497..fd7f36e95a 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -16,11 +16,9 @@ function __construct() { } /** - * Subcommand posttype - * - * @param string $args Name of post type - * @param array $assoc_args The ussual WordPress arguments + * @subcommand post-type * + * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [context=<context>] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -60,7 +58,9 @@ function post_type( $args, $assoc_args ) { 'hierarchical' => 'false', 'supports' => "'title', 'editor'", 'has_archive' => 'true', - 'rewrite' => "array( 'slug' => '{$machine_name_plural}', 'feeds' => true, 'pages' => true )", + 'slug' => $machine_name_plural, + 'feeds' => 'true', + 'pages' => 'true', 'query_var' => 'true', 'can_export' => 'true', 'context' => strtolower( wp_get_theme()->template ), diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index fc3edc528c..8e2adb1213 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -18,7 +18,7 @@ 'hierarchical' => {$hierarchical}, 'supports' => array( {$supports} ), 'has_archive' => {$has_archive}, - 'rewrite' => {$rewrite}, + 'rewrite' => array( 'slug' => '{$slug}', 'feeds' => {$feeds}, 'pages' => {$pages} ), 'query_var' => {$query_var}, 'can_export' => {$can_export}, 'labels' => array( From b1d709c024f45b190b8ba5b4e1e28f9712477362 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Tue, 27 Nov 2012 19:07:12 +0100 Subject: [PATCH 0857/4858] removed static help function --- src/php/wp-cli/commands/internals/scaffold.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index fd7f36e95a..7ddc207d41 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -144,13 +144,6 @@ function taxonomy( $args, $assoc_args ) { } } - static function help() { - WP_CLI::line( 'Welcome to wp-cli scaffold' ); - WP_CLI::line( 'Possible subcommando: post_type, taxonomy' ); - WP_CLI::line( 'Example: post_type zombie' ); - WP_CLI::line( 'Example: taxonomy zombie_speed --post_types=zombie' ); - } - private function pluralize($word) { $plural = array( '/(quiz)$/i' => '\1zes', From 1dadf2204677e4478eaa17182fb18afce76ade50 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 28 Nov 2012 01:40:00 +0200 Subject: [PATCH 0858/4858] add examples for `plugin path` and `theme path` --- man/plugin-path.1 | 8 ++++++++ man/theme-path.1 | 8 ++++++++ src/docs/plugin-path.txt | 4 ++++ src/docs/theme-path.txt | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/man/plugin-path.1 b/man/plugin-path.1 index fe019d7188..cadd730d94 100644 --- a/man/plugin-path.1 +++ b/man/plugin-path.1 @@ -22,4 +22,12 @@ The plugin to get the path to\. If not set, will return the path to the plugins . .IP If set, get the path to the closest parent directory, instead of the plugin file\. +. +.SH "EXAMPLES" +. +.nf + +cd $(wp theme path) +. +.fi diff --git a/man/theme-path.1 b/man/theme-path.1 index 87a2c0dc75..2243de192f 100644 --- a/man/theme-path.1 +++ b/man/theme-path.1 @@ -22,4 +22,12 @@ The theme to get the path to\. If not set, will return the path to the themes di . .IP If set, get the path to the closest parent directory, instead of the theme file\. +. +.SH "EXAMPLES" +. +.nf + +cd $(wp theme path) +. +.fi diff --git a/src/docs/plugin-path.txt b/src/docs/plugin-path.txt index 6f05ac23b7..a190a77023 100644 --- a/src/docs/plugin-path.txt +++ b/src/docs/plugin-path.txt @@ -9,3 +9,7 @@ plugins directory. If set, get the path to the closest parent directory, instead of the plugin file. + +## EXAMPLES + + cd $(wp theme path) diff --git a/src/docs/theme-path.txt b/src/docs/theme-path.txt index 9b87d96992..d54cec5b15 100644 --- a/src/docs/theme-path.txt +++ b/src/docs/theme-path.txt @@ -9,3 +9,7 @@ themes directory. If set, get the path to the closest parent directory, instead of the theme file. + +## EXAMPLES + + cd $(wp theme path) From 986d90bbe66bbec744f86505aeba7f41fec72e20 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 09:57:28 +0100 Subject: [PATCH 0859/4858] updated the synopsis for taxonomy, added an alias for taxonom, changed context to textdomain --- .../wp-cli/commands/internals/scaffold.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 7ddc207d41..5f93eb7f37 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -18,15 +18,13 @@ function __construct() { /** * @subcommand post-type * + * @alias pt + * * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [context=<context>] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; - if( !isset( $args[0] ) ) { - WP_CLI::error( "Please provide a post type name" ); - } - // Set the args to variables with normal names to keep our sanity $post_type = strtolower( $args[0] ); @@ -86,19 +84,15 @@ function post_type( $args, $assoc_args ) { } /** - * Subcommand taxonomy + * @subcommand taxonomy * - * @param string $args Name of taxonomy - * @param array $assoc_args The ussual WordPress arguments + * @alias tax * + * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; - if( !isset( $args[0] ) ) { - WP_CLI::error( "Please provide a taxonomy" ); - } - // Set the args to variables with normal names to keep our sanity $taxonomy = strtolower( $args[0] ); @@ -120,8 +114,7 @@ function taxonomy( $args, $assoc_args ) { 'rewrite' => 'true', 'query_var' => 'true', 'slug' => $taxonomy, - 'hierarchical' => 'true', - 'context' => strtolower( wp_get_theme()->template ), + 'textdomain' => strtolower( wp_get_theme()->template ), 'post_types' => 'post' ); From e6a3e5275763898b2b26fb8f3fbaf59b0ed6fb50 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 09:58:22 +0100 Subject: [PATCH 0860/4858] updated the synopsis for taxonomy, added an alias for taxonom, changed context to textdomain --- src/php/wp-cli/commands/internals/scaffold.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 5f93eb7f37..11ebd21984 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -20,7 +20,7 @@ function __construct() { * * @alias pt * - * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [context=<context>] + * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -61,7 +61,7 @@ function post_type( $args, $assoc_args ) { 'pages' => 'true', 'query_var' => 'true', 'can_export' => 'true', - 'context' => strtolower( wp_get_theme()->template ), + 'textdomain' => strtolower( wp_get_theme()->template ), ); // Generate the variables from the defaults and associated arguments if they are set From f4eb255e2aab8a7eea3aaf11a804891d88d6b4e5 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 10:06:35 +0100 Subject: [PATCH 0861/4858] Nothing really changed, just cleaned up the code formatting --- .../wp-cli/commands/internals/scaffold.php | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 11ebd21984..c617690016 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -37,7 +37,6 @@ function post_type( $args, $assoc_args ) { $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); $label_ucfirst = ucfirst( $label ); $label_plural = $this->pluralize( $label ); - $label_plural_ucfirst = ucfirst( $label_plural ); } @@ -61,7 +60,7 @@ function post_type( $args, $assoc_args ) { 'pages' => 'true', 'query_var' => 'true', 'can_export' => 'true', - 'textdomain' => strtolower( wp_get_theme()->template ), + 'textdomain' => strtolower( wp_get_theme()->template ), ); // Generate the variables from the defaults and associated arguments if they are set @@ -137,54 +136,56 @@ function taxonomy( $args, $assoc_args ) { } } - private function pluralize($word) { + private function pluralize( $word ) { $plural = array( - '/(quiz)$/i' => '\1zes', - '/^(ox)$/i' => '\1en', - '/([m|l])ouse$/i' => '\1ice', - '/(matr|vert|ind)ix|ex$/i' => '\1ices', - '/(x|ch|ss|sh)$/i' => '\1es', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive)$/i' => '\1s', - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(buffal|tomat)o$/i' => '\1oes', - '/(bu)s$/i' => '1ses', - '/(alias|status)/i' => '\1es', - '/(octop|vir)us$/i' => '1i', - '/(ax|test)is$/i' => '\1es', - '/s$/i' => 's', - '/$/' => 's'); - - $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'); + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)ix|ex$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(buffal|tomat)o$/i' => '\1oes', + '/(bu)s$/i' => '1ses', + '/(alias|status)/i' => '\1es', + '/(octop|vir)us$/i' => '1i', + '/(ax|test)is$/i' => '\1es', + '/s$/i' => 's', + '/$/' => 's' + ); + + $uncountable = array( 'equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep' ); $irregular = array( - 'person' => 'people', - 'man' => 'men', - 'woman' => 'women', - 'child' => 'children', - 'sex' => 'sexes', - 'move' => 'moves'); + 'person' => 'people', + 'man' => 'men', + 'woman' => 'women', + 'child' => 'children', + 'sex' => 'sexes', + 'move' => 'moves' + ); - $lowercased_word = strtolower($word); + $lowercased_word = strtolower( $word ); - foreach ($uncountable as $_uncountable){ - if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){ + foreach ( $uncountable as $_uncountable ){ + if( substr( $lowercased_word, ( -1 * strlen( $_uncountable) ) ) == $_uncountable ){ return $word; } } - foreach ($irregular as $_plural=> $_singular){ - if (preg_match('/('.$_plural.')$/i', $word, $arr)) { - return preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word); + foreach ( $irregular as $_plural=> $_singular ){ + if ( preg_match( '/('.$_plural.')$/i', $word, $arr ) ) { + return preg_replace( '/('.$_plural.')$/i', substr( $arr[0], 0, 1 ).substr( $_singular, 1 ), $word ); } } - foreach ($plural as $rule => $replacement) { - if (preg_match($rule, $word)) { - return preg_replace($rule, $replacement, $word); + foreach ( $plural as $rule => $replacement ) { + if ( preg_match( $rule, $word ) ) { + return preg_replace( $rule, $replacement, $word ); } } return false; From 792b33a7c1aadc9b67d51504d169721b6a20df3b Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 16:01:30 +0100 Subject: [PATCH 0862/4858] removed the lp_ prefixes --- .../internals/skeletons/post_type_skeleton.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 8e2adb1213..1b9e0018ad 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -40,7 +40,7 @@ ); endif; - function lp_{$machine_name}_updated_messages( \$messages ) { + function {$machine_name}_updated_messages( \$messages ) { global \$post, \$post_ID; \$messages['{$post_type}'] = array( @@ -62,22 +62,22 @@ function lp_{$machine_name}_updated_messages( \$messages ) { return \$messages; } - add_filter( 'post_updated_messages', 'lp_{$machine_name}_updated_messages' ); + add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' ); - function lp_pre_single_{$machine_name}( \$query ) { + function pre_single_{$machine_name}( \$query ) { if ( !is_admin() && get_post_type() == '{$post_type}' && is_main_query() ) { // use \$query->set() to change the main query // or use this function to hook in some other specific code } } - add_action( 'pre_get_posts', 'lp_pre_single_{$machine_name}' ); + add_action( 'pre_get_posts', 'pre_single_{$machine_name}' ); - function lp_pre_archive_{$machine_name}( \$query ) { + function pre_archive_{$machine_name}( \$query ) { if ( !is_admin() && is_post_type_archive( '{$post_type}' ) ) { // use \$query->set() to change the main query // or use this function to hook in some other specific code } } - add_action( 'pre_get_posts', 'lp_pre_archive_{$machine_name}' );"; \ No newline at end of file + add_action( 'pre_get_posts', 'pre_archive_{$machine_name}' );"; \ No newline at end of file From e3fabdaf87a565476270519cfe3ba2830f0132fe Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 16:08:04 +0100 Subject: [PATCH 0863/4858] changed the post type exists to a init hook --- .../commands/internals/skeletons/post_type_skeleton.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 1b9e0018ad..5a5d046792 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -1,7 +1,7 @@ <?php $output = "<?php - if (!post_type_exists( '{$post_type}' ) ) : + function {$machine_name}_init() { register_post_type( '{$post_type}', array( 'label' => __( '{$label_plural_ucfirst}', '{$context}' ), @@ -38,7 +38,7 @@ ), ) ); - endif; + add_action( 'init', '{$machine_name}_init' ); function {$machine_name}_updated_messages( \$messages ) { global \$post, \$post_ID; From 1e19b444e969e24674f4695052ad5e0531d1849f Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 16:20:15 +0100 Subject: [PATCH 0864/4858] Revoved the templating related hooks so we get a more general scaffolding command --- .../skeletons/post_type_skeleton.php | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 5a5d046792..ac0a93e488 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -62,22 +62,4 @@ function {$machine_name}_updated_messages( \$messages ) { return \$messages; } - add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' ); - - function pre_single_{$machine_name}( \$query ) { - if ( !is_admin() && get_post_type() == '{$post_type}' && is_main_query() ) { - // use \$query->set() to change the main query - // or use this function to hook in some other specific code - - } - } - add_action( 'pre_get_posts', 'pre_single_{$machine_name}' ); - - function pre_archive_{$machine_name}( \$query ) { - if ( !is_admin() && is_post_type_archive( '{$post_type}' ) ) { - // use \$query->set() to change the main query - // or use this function to hook in some other specific code - - } - } - add_action( 'pre_get_posts', 'pre_archive_{$machine_name}' );"; \ No newline at end of file + add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' ); \ No newline at end of file From 008e4dcae5979f643db047e73903b337b04e893d Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Wed, 28 Nov 2012 16:22:57 +0100 Subject: [PATCH 0865/4858] changed context to textdomain in the post type template --- .../skeletons/post_type_skeleton.php | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index ac0a93e488..2efa3b671c 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -4,8 +4,8 @@ function {$machine_name}_init() { register_post_type( '{$post_type}', array( - 'label' => __( '{$label_plural_ucfirst}', '{$context}' ), - 'description' => __( '{$description}', '{$context}' ), + 'label' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'description' => __( '{$description}', '{$textdomain}' ), 'public' => {$public}, 'exclude_from_search' => {$exclude_from_search}, 'show_ui' => {$show_ui}, @@ -22,19 +22,19 @@ function {$machine_name}_init() { 'query_var' => {$query_var}, 'can_export' => {$can_export}, 'labels' => array( - 'name' => __( '{$label_plural_ucfirst}', '{$context}' ), - 'singular_name' => __( '{$label_ucfirst}', '{$context}' ), - 'add_new' => __( 'Add new {$label}', '{$context}' ), - 'all_items' => __( '{$label_plural_ucfirst}', '{$context}' ), - 'add_new_item' => __( 'Add new {$label}', '{$context}' ), - 'edit_item' => __( 'Edit {$label}', '{$context}' ), - 'new_item' => __( 'New {$label}', '{$context}' ), - 'view_item' => __( 'View {$label}', '{$context}' ), - 'search_items' => __( 'Search {$label_plural}', '{$context}' ), - 'not_found' => __( 'No {$label_plural} found', '{$context}' ), - 'not_found_in_trash' => __( 'No {$label_plural} found in trash', '{$context}' ), - 'parent_item_colon' => __( 'Parent {$label}', '{$context}' ), - 'menu_name' => __( '{$label_plural_ucfirst}', '{$context}' ), + 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), + 'add_new' => __( 'Add new {$label}', '{$textdomain}' ), + 'all_items' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'add_new_item' => __( 'Add new {$label}', '{$textdomain}' ), + 'edit_item' => __( 'Edit {$label}', '{$textdomain}' ), + 'new_item' => __( 'New {$label}', '{$textdomain}' ), + 'view_item' => __( 'View {$label}', '{$textdomain}' ), + 'search_items' => __( 'Search {$label_plural}', '{$textdomain}' ), + 'not_found' => __( 'No {$label_plural} found', '{$textdomain}' ), + 'not_found_in_trash' => __( 'No {$label_plural} found in trash', '{$textdomain}' ), + 'parent_item_colon' => __( 'Parent {$label}', '{$textdomain}' ), + 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), ), ) ); @@ -45,19 +45,19 @@ function {$machine_name}_updated_messages( \$messages ) { \$messages['{$post_type}'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label_ucfirst} updated. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), - 2 => __('Custom field updated.', '{$context}'), - 3 => __('Custom field deleted.', '{$context}'), - 4 => __('{$label_ucfirst} updated.', '{$context}'), + 1 => sprintf( __('{$label_ucfirst} updated. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 2 => __('Custom field updated.', '{$textdomain}'), + 3 => __('Custom field deleted.', '{$textdomain}'), + 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), /* translators: %s: date and time of the revision */ - 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$context}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label_ucfirst} published. <a href=\"\">View {$label}</a>', '{$context}'), esc_url( get_permalink(\$post_ID) ) ), - 7 => __('{$label_ucfirst} saved.', '{$context}'), - 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), - 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$context}'), + 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, + 6 => sprintf( __('{$label_ucfirst} published. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), + 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$textdomain}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$context}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), ); return \$messages; From 0a00a36196f2d98c1f18bb8da6fc81868dfc8c48 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 28 Nov 2012 21:08:47 +0100 Subject: [PATCH 0866/4858] Correctly closed String at the end off the file --- .../wp-cli/commands/internals/skeletons/post_type_skeleton.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 2efa3b671c..55802cd880 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -62,4 +62,4 @@ function {$machine_name}_updated_messages( \$messages ) { return \$messages; } - add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' ); \ No newline at end of file + add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; \ No newline at end of file From 84e4949b89372fb1ec0080fdd25627a11916316a Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 28 Nov 2012 21:30:10 +0100 Subject: [PATCH 0867/4858] Added closing curly bracket for post type init --- .../wp-cli/commands/internals/skeletons/post_type_skeleton.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 55802cd880..3f1be737e0 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -38,6 +38,7 @@ function {$machine_name}_init() { ), ) ); + } add_action( 'init', '{$machine_name}_init' ); function {$machine_name}_updated_messages( \$messages ) { From db965366098421f28fafa914334fa42d5b7d01cc Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 28 Nov 2012 21:33:50 +0100 Subject: [PATCH 0868/4858] Changed getext $context to $textdomain --- .../internals/skeletons/taxonomy_skeleton.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php index 4829627820..841eb725db 100755 --- a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php @@ -3,21 +3,21 @@ if ( !taxonomy_exists( '{$taxonomy}' ) ) : \$labels = array( - 'name' => __( '{$taxonomy}', '{$context}' ), - 'singular_name' => __( '{$taxonomy}', '{$context}' ), - 'search_items' => __( 'Search {$taxonomy}', '{$context}' ), - 'popular_items' => __( 'Popular {$taxonomy}', '{$context}' ), - 'all_items' => __( 'All {$taxonomy}', '{$context}' ), - 'parent_item' => __( 'Parent {$taxonomy}', '{$context}' ), - 'parent_item_colon' => __( 'Parent {$taxonomy}:', '{$context}' ), - 'edit_item' => __( 'Edit {$taxonomy}', '{$context}' ), - 'update_item' => __( 'Update {$taxonomy}', '{$context}' ), - 'add_new_item' => __( 'New {$taxonomy}', '{$context}' ), - 'new_item_name' => __( 'New {$taxonomy}', '{$context}' ), - 'separate_items_with_commas' => __( '{$taxonomy}s seperated by comma', '{$context}' ), - 'add_or_remove_items' => __( 'Add or remove {$taxonomy}s', '{$context}' ), - 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$context}' ), - 'menu_name' => __( '{$taxonomy}s', '{$context}' ), + 'name' => __( '{$taxonomy}', '{$textdomain}' ), + 'singular_name' => __( '{$taxonomy}', '{$textdomain}' ), + 'search_items' => __( 'Search {$taxonomy}', '{$textdomain}' ), + 'popular_items' => __( 'Popular {$taxonomy}', '{$textdomain}' ), + 'all_items' => __( 'All {$taxonomy}', '{$textdomain}' ), + 'parent_item' => __( 'Parent {$taxonomy}', '{$textdomain}' ), + 'parent_item_colon' => __( 'Parent {$taxonomy}:', '{$textdomain}' ), + 'edit_item' => __( 'Edit {$taxonomy}', '{$textdomain}' ), + 'update_item' => __( 'Update {$taxonomy}', '{$textdomain}' ), + 'add_new_item' => __( 'New {$taxonomy}', '{$textdomain}' ), + 'new_item_name' => __( 'New {$taxonomy}', '{$textdomain}' ), + 'separate_items_with_commas' => __( '{$taxonomy}s seperated by comma', '{$textdomain}' ), + 'add_or_remove_items' => __( 'Add or remove {$taxonomy}s', '{$textdomain}' ), + 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$textdomain}' ), + 'menu_name' => __( '{$taxonomy}s', '{$textdomain}' ), ); \$args = array( From 0a5fa7bccf42a3022a247a5b58b8d97f96b8d0e4 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 28 Nov 2012 21:35:26 +0100 Subject: [PATCH 0869/4858] Removed unneccesary indentation --- .../skeletons/post_type_skeleton.php | 122 +++++++++--------- .../internals/skeletons/taxonomy_skeleton.php | 88 ++++++------- 2 files changed, 105 insertions(+), 105 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 3f1be737e0..613518b332 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -1,66 +1,66 @@ <?php - $output = "<?php +$output = "<?php - function {$machine_name}_init() { - register_post_type( '{$post_type}', - array( - 'label' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'description' => __( '{$description}', '{$textdomain}' ), - 'public' => {$public}, - 'exclude_from_search' => {$exclude_from_search}, - 'show_ui' => {$show_ui}, - 'show_in_nav_menus' => {$show_in_nav_menus}, - 'show_in_menu' => {$show_in_menu}, - 'show_in_admin_bar' => {$show_in_admin_bar}, - 'menu_position' => {$menu_position}, - 'menu_icon' => {$menu_icon}, - 'capability_type' => '{$capability_type}', - 'hierarchical' => {$hierarchical}, - 'supports' => array( {$supports} ), - 'has_archive' => {$has_archive}, - 'rewrite' => array( 'slug' => '{$slug}', 'feeds' => {$feeds}, 'pages' => {$pages} ), - 'query_var' => {$query_var}, - 'can_export' => {$can_export}, - 'labels' => array( - 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), - 'add_new' => __( 'Add new {$label}', '{$textdomain}' ), - 'all_items' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'add_new_item' => __( 'Add new {$label}', '{$textdomain}' ), - 'edit_item' => __( 'Edit {$label}', '{$textdomain}' ), - 'new_item' => __( 'New {$label}', '{$textdomain}' ), - 'view_item' => __( 'View {$label}', '{$textdomain}' ), - 'search_items' => __( 'Search {$label_plural}', '{$textdomain}' ), - 'not_found' => __( 'No {$label_plural} found', '{$textdomain}' ), - 'not_found_in_trash' => __( 'No {$label_plural} found in trash', '{$textdomain}' ), - 'parent_item_colon' => __( 'Parent {$label}', '{$textdomain}' ), - 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - ), - ) - ); - } - add_action( 'init', '{$machine_name}_init' ); +function {$machine_name}_init() { + register_post_type( '{$post_type}', + array( + 'label' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'description' => __( '{$description}', '{$textdomain}' ), + 'public' => {$public}, + 'exclude_from_search' => {$exclude_from_search}, + 'show_ui' => {$show_ui}, + 'show_in_nav_menus' => {$show_in_nav_menus}, + 'show_in_menu' => {$show_in_menu}, + 'show_in_admin_bar' => {$show_in_admin_bar}, + 'menu_position' => {$menu_position}, + 'menu_icon' => {$menu_icon}, + 'capability_type' => '{$capability_type}', + 'hierarchical' => {$hierarchical}, + 'supports' => array( {$supports} ), + 'has_archive' => {$has_archive}, + 'rewrite' => array( 'slug' => '{$slug}', 'feeds' => {$feeds}, 'pages' => {$pages} ), + 'query_var' => {$query_var}, + 'can_export' => {$can_export}, + 'labels' => array( + 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), + 'add_new' => __( 'Add new {$label}', '{$textdomain}' ), + 'all_items' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'add_new_item' => __( 'Add new {$label}', '{$textdomain}' ), + 'edit_item' => __( 'Edit {$label}', '{$textdomain}' ), + 'new_item' => __( 'New {$label}', '{$textdomain}' ), + 'view_item' => __( 'View {$label}', '{$textdomain}' ), + 'search_items' => __( 'Search {$label_plural}', '{$textdomain}' ), + 'not_found' => __( 'No {$label_plural} found', '{$textdomain}' ), + 'not_found_in_trash' => __( 'No {$label_plural} found in trash', '{$textdomain}' ), + 'parent_item_colon' => __( 'Parent {$label}', '{$textdomain}' ), + 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + ), + ) + ); +} +add_action( 'init', '{$machine_name}_init' ); - function {$machine_name}_updated_messages( \$messages ) { - global \$post, \$post_ID; +function {$machine_name}_updated_messages( \$messages ) { + global \$post, \$post_ID; - \$messages['{$post_type}'] = array( - 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label_ucfirst} updated. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), - 2 => __('Custom field updated.', '{$textdomain}'), - 3 => __('Custom field deleted.', '{$textdomain}'), - 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), - /* translators: %s: date and time of the revision */ - 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label_ucfirst} published. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), - 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), - 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), - 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$textdomain}'), - // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), - ); + \$messages['{$post_type}'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => sprintf( __('{$label_ucfirst} updated. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 2 => __('Custom field updated.', '{$textdomain}'), + 3 => __('Custom field deleted.', '{$textdomain}'), + 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), + /* translators: %s: date and time of the revision */ + 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, + 6 => sprintf( __('{$label_ucfirst} published. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), + 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$textdomain}'), + // translators: Publish box date format, see http://php.net/date + date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), + 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + ); - return \$messages; - } - add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; \ No newline at end of file + return \$messages; +} +add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; \ No newline at end of file diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php index 841eb725db..992f4bb7d6 100755 --- a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php @@ -1,47 +1,47 @@ <?php - $output = "<?php +$output = "<?php - if ( !taxonomy_exists( '{$taxonomy}' ) ) : - \$labels = array( - 'name' => __( '{$taxonomy}', '{$textdomain}' ), - 'singular_name' => __( '{$taxonomy}', '{$textdomain}' ), - 'search_items' => __( 'Search {$taxonomy}', '{$textdomain}' ), - 'popular_items' => __( 'Popular {$taxonomy}', '{$textdomain}' ), - 'all_items' => __( 'All {$taxonomy}', '{$textdomain}' ), - 'parent_item' => __( 'Parent {$taxonomy}', '{$textdomain}' ), - 'parent_item_colon' => __( 'Parent {$taxonomy}:', '{$textdomain}' ), - 'edit_item' => __( 'Edit {$taxonomy}', '{$textdomain}' ), - 'update_item' => __( 'Update {$taxonomy}', '{$textdomain}' ), - 'add_new_item' => __( 'New {$taxonomy}', '{$textdomain}' ), - 'new_item_name' => __( 'New {$taxonomy}', '{$textdomain}' ), - 'separate_items_with_commas' => __( '{$taxonomy}s seperated by comma', '{$textdomain}' ), - 'add_or_remove_items' => __( 'Add or remove {$taxonomy}s', '{$textdomain}' ), - 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$textdomain}' ), - 'menu_name' => __( '{$taxonomy}s', '{$textdomain}' ), - ); - - \$args = array( - 'labels' => \$labels, - 'public' => {$public}, - 'show_in_nav_menus' => {$show_in_nav_menus}, - 'show_ui' => {$show_ui}, - 'show_tagcloud' => {$show_tagcloud}, - 'hierarchical' => {$hierarchical}, - 'update_count_callback' => '_update_post_term_count', - 'rewrite' => {$rewrite}, - 'query_var' => {$query_var}, - 'capabilities' => array ( - 'manage_terms' => 'edit_posts', - 'edit_terms' => 'edit_posts', - 'delete_terms' => 'edit_posts', - 'assign_terms' => 'edit_posts' - ), - 'rewrite' => array( - 'slug' => '{$taxonomy}', - 'hierarchical' => {$hierarchical} - ), - ); - - register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args ); +if ( !taxonomy_exists( '{$taxonomy}' ) ) : + \$labels = array( + 'name' => __( '{$taxonomy}', '{$textdomain}' ), + 'singular_name' => __( '{$taxonomy}', '{$textdomain}' ), + 'search_items' => __( 'Search {$taxonomy}', '{$textdomain}' ), + 'popular_items' => __( 'Popular {$taxonomy}', '{$textdomain}' ), + 'all_items' => __( 'All {$taxonomy}', '{$textdomain}' ), + 'parent_item' => __( 'Parent {$taxonomy}', '{$textdomain}' ), + 'parent_item_colon' => __( 'Parent {$taxonomy}:', '{$textdomain}' ), + 'edit_item' => __( 'Edit {$taxonomy}', '{$textdomain}' ), + 'update_item' => __( 'Update {$taxonomy}', '{$textdomain}' ), + 'add_new_item' => __( 'New {$taxonomy}', '{$textdomain}' ), + 'new_item_name' => __( 'New {$taxonomy}', '{$textdomain}' ), + 'separate_items_with_commas' => __( '{$taxonomy}s seperated by comma', '{$textdomain}' ), + 'add_or_remove_items' => __( 'Add or remove {$taxonomy}s', '{$textdomain}' ), + 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$textdomain}' ), + 'menu_name' => __( '{$taxonomy}s', '{$textdomain}' ), + ); - endif;"; \ No newline at end of file + \$args = array( + 'labels' => \$labels, + 'public' => {$public}, + 'show_in_nav_menus' => {$show_in_nav_menus}, + 'show_ui' => {$show_ui}, + 'show_tagcloud' => {$show_tagcloud}, + 'hierarchical' => {$hierarchical}, + 'update_count_callback' => '_update_post_term_count', + 'rewrite' => {$rewrite}, + 'query_var' => {$query_var}, + 'capabilities' => array ( + 'manage_terms' => 'edit_posts', + 'edit_terms' => 'edit_posts', + 'delete_terms' => 'edit_posts', + 'assign_terms' => 'edit_posts' + ), + 'rewrite' => array( + 'slug' => '{$taxonomy}', + 'hierarchical' => {$hierarchical} + ), + ); + + register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args ); + +endif;"; \ No newline at end of file From 03f320b8212cd493e543ac455f17168ff109d981 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 28 Nov 2012 21:49:21 +0100 Subject: [PATCH 0870/4858] Removed the hardcoded S for pluralizing taxonomy name --- .../commands/internals/skeletons/taxonomy_skeleton.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php index 992f4bb7d6..75b41dfdca 100755 --- a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php @@ -14,10 +14,10 @@ 'update_item' => __( 'Update {$taxonomy}', '{$textdomain}' ), 'add_new_item' => __( 'New {$taxonomy}', '{$textdomain}' ), 'new_item_name' => __( 'New {$taxonomy}', '{$textdomain}' ), - 'separate_items_with_commas' => __( '{$taxonomy}s seperated by comma', '{$textdomain}' ), - 'add_or_remove_items' => __( 'Add or remove {$taxonomy}s', '{$textdomain}' ), + 'separate_items_with_commas' => __( '{$taxonomy} seperated by comma', '{$textdomain}' ), + 'add_or_remove_items' => __( 'Add or remove {$taxonomy}', '{$textdomain}' ), 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$textdomain}' ), - 'menu_name' => __( '{$taxonomy}s', '{$textdomain}' ), + 'menu_name' => __( '{$taxonomy}', '{$textdomain}' ), ); \$args = array( From 0b1bb6b9ec8a4fdc4bf5b54caa63a5e75603c7b1 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 28 Nov 2012 22:01:36 +0100 Subject: [PATCH 0871/4858] Using pluralize function and added beter labels to Taxonomy skeleton --- .../wp-cli/commands/internals/scaffold.php | 8 ++++-- .../internals/skeletons/taxonomy_skeleton.php | 26 +++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index c617690016..6c5883f5a3 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -96,11 +96,15 @@ function taxonomy( $args, $assoc_args ) { $taxonomy = strtolower( $args[0] ); // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $taxonomy ); + $machine_name = preg_replace( '/-/', '_', $taxonomy ); + $machine_name_plural = $this->pluralize( $taxonomy ); // If no label is given use the slug and prettify it as good as possible if( !isset( $assoc_args['label'] ) ) { - $label = preg_replace( '/_|-/', ' ', ucfirst( strtolower( $taxonomy ) ) ); + $label = preg_replace( '/_|-/', ' ', strtolower( $taxonomy ) ); + $label_ucfirst = ucfirst( $label ); + $label_plural = $this->pluralize( $label ); + $label_plural_ucfirst = ucfirst( $label_plural ); } // Set up defaults and merge theme with assoc_args diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php index 75b41dfdca..de7c5e7ad5 100755 --- a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php @@ -3,21 +3,21 @@ if ( !taxonomy_exists( '{$taxonomy}' ) ) : \$labels = array( - 'name' => __( '{$taxonomy}', '{$textdomain}' ), - 'singular_name' => __( '{$taxonomy}', '{$textdomain}' ), + 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), + 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), 'search_items' => __( 'Search {$taxonomy}', '{$textdomain}' ), 'popular_items' => __( 'Popular {$taxonomy}', '{$textdomain}' ), - 'all_items' => __( 'All {$taxonomy}', '{$textdomain}' ), - 'parent_item' => __( 'Parent {$taxonomy}', '{$textdomain}' ), - 'parent_item_colon' => __( 'Parent {$taxonomy}:', '{$textdomain}' ), - 'edit_item' => __( 'Edit {$taxonomy}', '{$textdomain}' ), - 'update_item' => __( 'Update {$taxonomy}', '{$textdomain}' ), - 'add_new_item' => __( 'New {$taxonomy}', '{$textdomain}' ), - 'new_item_name' => __( 'New {$taxonomy}', '{$textdomain}' ), - 'separate_items_with_commas' => __( '{$taxonomy} seperated by comma', '{$textdomain}' ), - 'add_or_remove_items' => __( 'Add or remove {$taxonomy}', '{$textdomain}' ), - 'choose_from_most_used' => __( 'Choose from the most used {$taxonomy}', '{$textdomain}' ), - 'menu_name' => __( '{$taxonomy}', '{$textdomain}' ), + 'all_items' => __( 'All {$label_plural}', '{$textdomain}' ), + 'parent_item' => __( 'Parent {$label}', '{$textdomain}' ), + 'parent_item_colon' => __( 'Parent {$label}:', '{$textdomain}' ), + 'edit_item' => __( 'Edit {$label}', '{$textdomain}' ), + 'update_item' => __( 'Update {$label}', '{$textdomain}' ), + 'add_new_item' => __( 'New {$label}', '{$textdomain}' ), + 'new_item_name' => __( 'New {$label}', '{$textdomain}' ), + 'separate_items_with_commas' => __( '{$label_plural_ucfirst} seperated by comma', '{$textdomain}' ), + 'add_or_remove_items' => __( 'Add or remove {$label}', '{$textdomain}' ), + 'choose_from_most_used' => __( 'Choose from the most used {$label_plural}', '{$textdomain}' ), + 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), ); \$args = array( From 9217c1f6b2ad5509ed76e9f1760683696ab1ab2f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 1 Dec 2012 22:07:05 +0200 Subject: [PATCH 0872/4858] update manpage for plugin/theme update; add manpage for update-all. fixes #228 --- man/plugin-update-all.1 | 19 ++++++++++++++++++- man/plugin-update.1 | 12 ++---------- man/theme-update-all.1 | 19 ++++++++++++++++++- man/theme-update.1 | 10 ++++------ src/docs/plugin-update-all.txt | 9 +++++++++ src/docs/plugin-update.txt | 11 ++--------- src/docs/theme-update-all.txt | 9 +++++++++ src/docs/theme-update.txt | 10 ++++------ src/php/wp-cli/commands/internals/theme.php | 2 +- 9 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 src/docs/plugin-update-all.txt create mode 100644 src/docs/theme-update-all.txt diff --git a/man/plugin-update-all.1 b/man/plugin-update-all.1 index 0e08069095..5198fd1e86 100644 --- a/man/plugin-update-all.1 +++ b/man/plugin-update-all.1 @@ -1,10 +1,27 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-PLUGIN\-UPDATE\-ALL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-PLUGIN\-UPDATE\-ALL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-plugin\-update\-all\fR \- Update all plugins\. . .SH "SYNOPSIS" \fBwp plugin update\-all\fR [\-\-dry\-run] +. +.SH "OPTIONS" +. +.TP +\fB\-\-dry\-run\fR: +. +.IP +Pretend to do the updates, to see what would happen\. +. +.SH "EXAMPLES" +. +.nf + +wp plugin update\-all +. +.fi + diff --git a/man/plugin-update.1 b/man/plugin-update.1 index 13a769112e..5f38ffda64 100644 --- a/man/plugin-update.1 +++ b/man/plugin-update.1 @@ -15,27 +15,19 @@ \fIplugin\fR: . .IP -The plugin to update\. Can be omitted when \-\-all is passed\. +The plugin to update\. . .TP \fB\-\-version=dev\fR: . .IP -If set, the plugin will be updated to the latest development version, regardless of what version is currently installed\. Not compatible with \-\-all\. -. -.TP -\fB\-\-all\fR: -. -.IP -If set, updates for all plugins will be performed\. Use \fBwp plugin status\fR to see which plugins have updates available\. +If set, the plugin will be updated to the latest development version, regardless of what version is currently installed\. . .SH "EXAMPLES" . .nf wp plugin update bbpress \-\-version=dev - -wp plugin update \-\-all . .fi diff --git a/man/theme-update-all.1 b/man/theme-update-all.1 index 27a2beda18..057f3f4c9c 100644 --- a/man/theme-update-all.1 +++ b/man/theme-update-all.1 @@ -1,10 +1,27 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-THEME\-UPDATE\-ALL" "1" "October 2012" "" "WP-CLI" +.TH "WP\-THEME\-UPDATE\-ALL" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-theme\-update\-all\fR \- Update all themes\. . .SH "SYNOPSIS" \fBwp theme update\-all\fR [\-\-dry\-run] +. +.SH "OPTIONS" +. +.TP +\fB\-\-dry\-run\fR: +. +.IP +Pretend to do the updates, to see what would happen\. +. +.SH "EXAMPLES" +. +.nf + +wp theme update\-all +. +.fi + diff --git a/man/theme-update.1 b/man/theme-update.1 index 9f5ec07d8b..cb5f09b3b9 100644 --- a/man/theme-update.1 +++ b/man/theme-update.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-update\fR \- Update a theme\. . .SH "SYNOPSIS" -\fBwp theme update\fR \fItheme\fR +\fBwp theme update\fR \fItheme\fR [\-\-version=\fIversion\fR] . .SH "OPTIONS" . @@ -15,21 +15,19 @@ \fItheme\fR: . .IP -The theme to update\. Can be omitted when \-\-all is passed\. +The theme to update\. . .TP -\fB\-\-all\fR: +\fB\-\-version=dev\fR: . .IP -If set, updates for all themes will be performed\. Use \fBwp theme status\fR to see which themes have updates available\. +If set, the theme will be updated to the latest development version, regardless of what version is currently installed\. . .SH "EXAMPLES" . .nf wp theme update twentytwelve - -wp theme update \-\-all . .fi diff --git a/src/docs/plugin-update-all.txt b/src/docs/plugin-update-all.txt new file mode 100644 index 0000000000..8ba4aaa513 --- /dev/null +++ b/src/docs/plugin-update-all.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `--dry-run`: + + Pretend to do the updates, to see what would happen. + +## EXAMPLES + + wp plugin update-all diff --git a/src/docs/plugin-update.txt b/src/docs/plugin-update.txt index 8bc68da0d3..563c303735 100644 --- a/src/docs/plugin-update.txt +++ b/src/docs/plugin-update.txt @@ -2,20 +2,13 @@ * <plugin>: - The plugin to update. Can be omitted when --all is passed. + The plugin to update. * `--version=dev`: If set, the plugin will be updated to the latest development version, -regardless of what version is currently installed. Not compatible with --all. - -* `--all`: - - If set, updates for all plugins will be performed. Use `wp plugin status` -to see which plugins have updates available. +regardless of what version is currently installed. ## EXAMPLES wp plugin update bbpress --version=dev - - wp plugin update --all diff --git a/src/docs/theme-update-all.txt b/src/docs/theme-update-all.txt new file mode 100644 index 0000000000..5d24e29a5a --- /dev/null +++ b/src/docs/theme-update-all.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `--dry-run`: + + Pretend to do the updates, to see what would happen. + +## EXAMPLES + + wp theme update-all diff --git a/src/docs/theme-update.txt b/src/docs/theme-update.txt index 9c37f8229d..d3439e48a8 100644 --- a/src/docs/theme-update.txt +++ b/src/docs/theme-update.txt @@ -2,15 +2,13 @@ * <theme>: - The theme to update. Can be omitted when --all is passed. + The theme to update. -* `--all`: +* `--version=dev`: - If set, updates for all themes will be performed. Use `wp theme status` -to see which themes have updates available. + If set, the theme will be updated to the latest development version, +regardless of what version is currently installed. ## EXAMPLES wp theme update twentytwelve - - wp theme update --all diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index 733c6b2b8e..d028937f8e 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -168,7 +168,7 @@ function install( $args, $assoc_args ) { /** * Update a theme. * - * @synopsis <theme> + * @synopsis <theme> [--version=<version>] */ function update( $args, $assoc_args ) { parent::update( $args, $assoc_args ); From b444962c3bc99993328627950d8d832bb1e679d2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 15:53:22 +0200 Subject: [PATCH 0873/4858] total-cache: remove redundant check for w3tc_pgcache_flush() function --- .../wp-cli/commands/community/total-cache.php | 110 +++++++++--------- 1 file changed, 53 insertions(+), 57 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index 8e1a35a4c7..80e5b49fa2 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -20,76 +20,72 @@ class W3TotalCache_Command extends WP_CLI_Command { * @param array $vars */ function flush( $args = array(), $vars = array() ) { - if ( function_exists( 'w3tc_pgcache_flush' ) ) { - $args = array_unique( $args ); - do { - $cache_type = array_shift($args); + $args = array_unique( $args ); + do { + $cache_type = array_shift($args); - switch($cache_type) { - case 'db': - case 'database': - if ( w3tc_dbcache_flush() ) { - WP_CLI::success( 'The database cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the database cache failed.' ); - } - break; + switch($cache_type) { + case 'db': + case 'database': + if ( w3tc_dbcache_flush() ) { + WP_CLI::success( 'The database cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the database cache failed.' ); + } + break; - case 'minify': - if ( w3tc_minify_flush() ) { - WP_CLI::success( 'The minify cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the minify cache failed.' ); - } - break; + case 'minify': + if ( w3tc_minify_flush() ) { + WP_CLI::success( 'The minify cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the minify cache failed.' ); + } + break; - case 'object': - if ( w3tc_objectcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; + case 'object': + if ( w3tc_objectcache_flush() ) { + WP_CLI::success( 'The object cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the object cache failed.' ); + } + break; - case 'page': - if ( w3tc_pgcache_flush() ) { - WP_CLI::success( 'The page cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the page cache failed.' ); - } - break; + case 'page': + if ( w3tc_pgcache_flush() ) { + WP_CLI::success( 'The page cache is flushed successfully.' ); + } else { + WP_CLI::error( 'Flushing the page cache failed.' ); + } + break; - case 'post': - default: - if ( isset($vars['post_id']) ) { - if ( is_numeric( $vars['post_id'] ) && get_post( $vars['post_id'] ) ) { - if ( w3tc_pgcache_flush_post( $vars['post_id'] ) ) { - WP_CLI::success( 'Post '.$vars['post_id'].' is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing '.$vars['post_id'].' from cache failed.' ); - } + case 'post': + default: + if ( isset($vars['post_id']) ) { + if ( is_numeric( $vars['post_id'] ) && get_post( $vars['post_id'] ) ) { + if ( w3tc_pgcache_flush_post( $vars['post_id'] ) ) { + WP_CLI::success( 'Post '.$vars['post_id'].' is flushed successfully.' ); } else { - WP_CLI::error('This is not a valid post id.'); + WP_CLI::error( 'Flushing '.$vars['post_id'].' from cache failed.' ); } + } else { + WP_CLI::error('This is not a valid post id.'); } - elseif ( isset( $vars['permalink'] ) ) { - $id = url_to_postid( $vars['permalink'] ); + } + elseif ( isset( $vars['permalink'] ) ) { + $id = url_to_postid( $vars['permalink'] ); - if ( is_numeric( $id ) && $id > 0 ) { - if ( w3tc_pgcache_flush_post( $id ) ) { - WP_CLI::success( $id.' is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing '.$id.' from cache failed.' ); - } + if ( is_numeric( $id ) && $id > 0 ) { + if ( w3tc_pgcache_flush_post( $id ) ) { + WP_CLI::success( $id.' is flushed successfully.' ); } else { - WP_CLI::error('There is no post with this permalink.'); + WP_CLI::error( 'Flushing '.$id.' from cache failed.' ); } + } else { + WP_CLI::error('There is no post with this permalink.'); } } - } while ( !empty( $args ) ); - } else { - WP_CLI::error('The W3 Total Cache could not be found, is it installed?'); - } + } + } while ( !empty( $args ) ); } /** From 7a91206f75cb0bc01c6c14ced3d29ec433a0ed37 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 15:58:22 +0200 Subject: [PATCH 0874/4858] total-cache: add `@synopsis` tag --- src/php/wp-cli/commands/community/total-cache.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index 80e5b49fa2..6f565c1983 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -5,19 +5,17 @@ } /** - * The WP Super Cache plugin + * The W3 Total Cache plugin * * @package wp-cli * @subpackage commands/community - * @maintainer Andreas Creten */ class W3TotalCache_Command extends WP_CLI_Command { /** - * Clear something from the cache + * Clear something from the cache. * - * @param array $args - * @param array $vars + * @synopsis <cache-type>... [--post_id=<post-id>] [--permalink=<permalink>] */ function flush( $args = array(), $vars = array() ) { $args = array_unique( $args ); From 63789aa3e95e976043da616b7f2a19208a1bf2e0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 16:06:51 +0200 Subject: [PATCH 0875/4858] total-cache: update static help() method --- src/php/wp-cli/commands/community/total-cache.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index 6f565c1983..e8c934d8fa 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -91,16 +91,11 @@ function flush( $args = array(), $vars = array() ) { */ public static function help() { WP_CLI::line( <<<EOB -usage: wp total-cache flush [post|database|minify|object|page] [--post_id=<post-id>] [--permalink=<post-permalink>] - Available sub-commands: flush - --post_id=<id> flush specific ID - --permalink=<post-permalink> flush specific permalink - database flushes database cache - object flush object cache - minify flush minify cache - page flush page cache + <cache-type> post|database|minify|object|page + --post_id=<id> flush post cache with specific ID + --permalink=<post-permalink> flush post cache with specific permalink EOB ); } From 641d5b03d031aa1f06129102c1e2a920ff27e065 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 16:10:05 +0200 Subject: [PATCH 0876/4858] total-cache: s/vars/assoc_args/g --- .../wp-cli/commands/community/total-cache.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php index e8c934d8fa..5bfd111620 100644 --- a/src/php/wp-cli/commands/community/total-cache.php +++ b/src/php/wp-cli/commands/community/total-cache.php @@ -17,12 +17,12 @@ class W3TotalCache_Command extends WP_CLI_Command { * * @synopsis <cache-type>... [--post_id=<post-id>] [--permalink=<permalink>] */ - function flush( $args = array(), $vars = array() ) { + function flush( $args = array(), $assoc_args = array() ) { $args = array_unique( $args ); do { - $cache_type = array_shift($args); + $cache_type = array_shift( $args ); - switch($cache_type) { + switch( $cache_type ) { case 'db': case 'database': if ( w3tc_dbcache_flush() ) { @@ -58,19 +58,19 @@ function flush( $args = array(), $vars = array() ) { case 'post': default: - if ( isset($vars['post_id']) ) { - if ( is_numeric( $vars['post_id'] ) && get_post( $vars['post_id'] ) ) { - if ( w3tc_pgcache_flush_post( $vars['post_id'] ) ) { - WP_CLI::success( 'Post '.$vars['post_id'].' is flushed successfully.' ); + if ( isset($assoc_args['post_id']) ) { + if ( is_numeric( $assoc_args['post_id'] ) && get_post( $assoc_args['post_id'] ) ) { + if ( w3tc_pgcache_flush_post( $assoc_args['post_id'] ) ) { + WP_CLI::success( 'Post '.$assoc_args['post_id'].' is flushed successfully.' ); } else { - WP_CLI::error( 'Flushing '.$vars['post_id'].' from cache failed.' ); + WP_CLI::error( 'Flushing '.$assoc_args['post_id'].' from cache failed.' ); } } else { WP_CLI::error('This is not a valid post id.'); } } - elseif ( isset( $vars['permalink'] ) ) { - $id = url_to_postid( $vars['permalink'] ); + elseif ( isset( $assoc_args['permalink'] ) ) { + $id = url_to_postid( $assoc_args['permalink'] ); if ( is_numeric( $id ) && $id > 0 ) { if ( w3tc_pgcache_flush_post( $id ) ) { From 7eb8abfbfb769c9c6507c3ec9c7078f0a801dd56 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 17:35:29 +0200 Subject: [PATCH 0877/4858] super-cache command cleanup: * removed redundant function checks * added @synopsis tags * s/$vars/$assoc_args/g --- .../wp-cli/commands/community/super-cache.php | 109 ++++++------------ 1 file changed, 37 insertions(+), 72 deletions(-) diff --git a/src/php/wp-cli/commands/community/super-cache.php b/src/php/wp-cli/commands/community/super-cache.php index a78d5918ab..4902b12bfe 100644 --- a/src/php/wp-cli/commands/community/super-cache.php +++ b/src/php/wp-cli/commands/community/super-cache.php @@ -9,50 +9,41 @@ * * @package wp-cli * @subpackage commands/community - * @maintainer Andreas Creten */ class WPSuperCache_Command extends WP_CLI_Command { /** - * Clear something from the cache + * Clear something from the cache. * - * @param array $args - * @param array $vars + * @synopsis [--post_id=<post-id>] [--permalink=<permalink>] */ - function flush( $args = array(), $vars = array() ) { - if ( function_exists( 'wp_cache_clear_cache' ) ) { - if ( isset($vars['post_id']) ) { - if ( is_numeric( $vars['post_id'] ) ) { - wp_cache_post_change( $vars['post_id'] ); - } else { - WP_CLI::error('This is not a valid post id.'); - } - - wp_cache_post_change( $vars['post_id'] ); + function flush( $args = array(), $assoc_args = array() ) { + if ( isset($assoc_args['post_id']) ) { + if ( is_numeric( $assoc_args['post_id'] ) ) { + wp_cache_post_change( $assoc_args['post_id'] ); + } else { + WP_CLI::error('This is not a valid post id.'); } - elseif ( isset( $vars['permalink'] ) ) { - $id = url_to_postid( $vars['permalink'] ); - if ( is_numeric( $id ) ) { - wp_cache_post_change( $id ); - } else { - WP_CLI::error('There is no post with this permalink.'); - } + wp_cache_post_change( $assoc_args['post_id'] ); + } + elseif ( isset( $assoc_args['permalink'] ) ) { + $id = url_to_postid( $assoc_args['permalink'] ); + + if ( is_numeric( $id ) ) { + wp_cache_post_change( $id ); } else { - wp_cache_clear_cache(); + WP_CLI::error('There is no post with this permalink.'); } } else { - WP_CLI::error('The WP Super Cache could not be found, is it installed?'); + wp_cache_clear_cache(); } } /** - * Get the status of the cache - * - * @param array $args - * @param array $vars + * Get the status of the cache. */ - function status( $args = array(), $vars = array() ) { + function status( $args = array(), $assoc_args = array() ) { $cache_stats = get_option( 'supercache_stats' ); if ( !empty( $cache_stats ) ) { @@ -77,58 +68,32 @@ function status( $args = array(), $vars = array() ) { } /** - * Enable the WP Super Cache - * - * @param array $args - * @param array $vars + * Enable the WP Super Cache. */ - function enable( $args = array(), $vars = array() ) { - if ( function_exists( 'wp_super_cache_enable' ) ) { - global $super_cache_enabled; - wp_super_cache_enable(); - if($super_cache_enabled) { - WP_CLI::success( 'The WP Super Cache is enabled.' ); - } else { - WP_CLI::error('The WP Super Cache is not enabled, check its settings page for more info.'); - } - } else { - WP_CLI::error('The WP Super Cache could not be found, is it installed?'); - } - } + function enable( $args = array(), $assoc_args = array() ) { + global $super_cache_enabled; - /** - * Disable the WP Super Cache - * - * @param array $args - * @param array $vars - */ - function disable( $args = array(), $vars = array() ) { - if ( function_exists( 'wp_super_cache_disable' ) ) { - global $super_cache_enabled; - wp_super_cache_disable(); - if(!$super_cache_enabled) { - WP_CLI::success( 'The WP Super Cache is disabled.' ); - } else { - WP_CLI::error('The WP Super Cache is still enabled, check its settings page for more info.'); - } + wp_super_cache_enable(); + + if($super_cache_enabled) { + WP_CLI::success( 'The WP Super Cache is enabled.' ); } else { - WP_CLI::error('The WP Super Cache could not be found, is it installed?'); + WP_CLI::error('The WP Super Cache is not enabled, check its settings page for more info.'); } } /** - * Help function for this command + * Disable the WP Super Cache. */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp super-cache [flush|status|enable|disable] --post_id=<id> --permalink=<post-permalink> + function disable( $args = array(), $assoc_args = array() ) { + global $super_cache_enabled; + + wp_super_cache_disable(); -Available sub-commands: - flush flushes whole cache, or post with given permalink or ID --post_id=<id> --permalink=<post-permalink> - status shows status of WP Super Cache - enable enables WP Super Cache - disable disables WP Super Cache -EOB - ); + if(!$super_cache_enabled) { + WP_CLI::success( 'The WP Super Cache is disabled.' ); + } else { + WP_CLI::error('The WP Super Cache is still enabled, check its settings page for more info.'); + } } } From 5d34ebb3649832f6ae75e91d8cbb48eb9bdef161 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 17:46:09 +0200 Subject: [PATCH 0878/4858] super-cache: use wp_cache_clean_cache() wp_cache_clear_cache() doesn't exist --- src/php/wp-cli/commands/community/super-cache.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/community/super-cache.php b/src/php/wp-cli/commands/community/super-cache.php index 4902b12bfe..5e54f3392c 100644 --- a/src/php/wp-cli/commands/community/super-cache.php +++ b/src/php/wp-cli/commands/community/super-cache.php @@ -36,7 +36,11 @@ function flush( $args = array(), $assoc_args = array() ) { WP_CLI::error('There is no post with this permalink.'); } } else { - wp_cache_clear_cache(); + global $file_prefix; + + wp_cache_clean_cache( $file_prefix, true ); + + WP_CLI::success( 'Cache cleared.' ); } } From d3ea6f0a18902cfafc26802e56cf1a446dee3e0c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Dec 2012 18:13:41 +0200 Subject: [PATCH 0879/4858] google-sitemap: cleanup --- .../commands/community/google-sitemap.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/commands/community/google-sitemap.php b/src/php/wp-cli/commands/community/google-sitemap.php index 4248373233..37bbe53c1f 100644 --- a/src/php/wp-cli/commands/community/google-sitemap.php +++ b/src/php/wp-cli/commands/community/google-sitemap.php @@ -9,30 +9,15 @@ * * @package wp-cli * @subpackage commands/community - * @maintainer Andreas Creten */ class GoogleSitemapGenerator_Command extends WP_CLI_Command { /** * Re-generate the sitemap - * - * @param array $args - * @param array $vars */ - function rebuild( $args = array(), $vars = array() ) { + function rebuild() { do_action( 'sm_rebuild' ); - } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -usage: wp google-sitemap [rebuild] -Available sub-commands: - rebuild rebuild Google sitemap -EOB - ); + WP_CLI::success( 'Sitemap rebuilt.' ); } } From e9d3cda0a7db2bfcfd35ce4f48294998b665615c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Dec 2012 01:34:39 +0000 Subject: [PATCH 0880/4858] Export: a new 'post__in' param for exporting specific posts Also sanitizes the filename, which should've been happening previously, and excludes the post__in arg from the generated filename because this particular argument can be a long list --- src/docs/export.txt | 4 +++ src/php/wp-cli/commands/internals/export.php | 29 ++++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/docs/export.txt b/src/docs/export.txt index ea92cb7f4a..473fc515a4 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -27,6 +27,10 @@ to current working directory. Export only posts with this post_type. +* `--post__in`=<pid>: + + Export all posts specified with IDs + * `--author`=<login/id>: Export only posts by this author. diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/internals/export.php index 32b4ff5b47..3ed26350ef 100644 --- a/src/php/wp-cli/commands/internals/export.php +++ b/src/php/wp-cli/commands/internals/export.php @@ -19,7 +19,7 @@ class Export_Command extends WP_CLI_Command { /** * Export posts to a WXR file. * - * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] + * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] */ public function __invoke( $_, $assoc_args ) { $defaults = array( @@ -30,6 +30,7 @@ public function __invoke( $_, $assoc_args ) { 'author' => NULL, 'category' => NULL, 'post_status' => NULL, + 'post__in' => NULL, 'skip_comments' => NULL, 'file_item_count' => 1000, ); @@ -111,6 +112,19 @@ private function check_post_type( $post_type ) { return true; } + private function check_post__in( $post__in ) { + if ( is_null( $post__in ) ) + return true; + + $post__in = array_unique( array_map( 'intval', explode( ',', $post__in ) ) ); + if ( empty( $post__in ) ) { + WP_CLI::warning( "post__in should be comma-separated post IDs" ); + return false; + } + $this->export_args['post__in'] = implode( ',', $post__in ); + return true; + } + private function check_author( $author ) { if ( is_null( $author ) ) return true; @@ -238,7 +252,7 @@ private function export_wp( $args = array() ) { /** * This is mostly the original code of export_wp defined in wp-admin/includes/export.php */ - $defaults = array( 'post_type' => 'all', 'author' => false, 'category' => false, + $defaults = array( 'post_type' => 'all', 'post__in' => false, 'author' => false, 'category' => false, 'start_date' => false, 'end_date' => false, 'status' => false, 'skip_comments' => false, 'file_item_count' => 1000, ); $args = wp_parse_args( $args, $defaults ); @@ -253,10 +267,10 @@ private function export_wp( $args = array() ) { $append = array( date( 'Y-m-d' ) ); foreach( array_keys( $args ) as $arg_key ) { - if ( $defaults[$arg_key] <> $args[$arg_key] ) + if ( $defaults[$arg_key] <> $args[$arg_key] && 'post__in' != $arg_key ) $append[]= "$arg_key-" . (string) $args[$arg_key]; } - $file_name_base = $sitename . 'wordpress.' . implode( ".", $append ); + $file_name_base = sanitize_file_name( $sitename . 'wordpress.' . implode( ".", $append ) ); if ( 'all' != $args['post_type'] && post_type_exists( $args['post_type'] ) ) { $ptype = get_post_type_object( $args['post_type'] ); @@ -294,10 +308,13 @@ private function export_wp( $args = array() ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date <= %s", date( 'Y-m-d 23:59:59', strtotime( $args['end_date'] ) ) ); // grab a snapshot of post IDs, just in case it changes during the export - $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); + if ( empty( $args['post__in'] ) ) + $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); + else + $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE ID IN ({$args['post__in']}) ORDER BY post_date ASC, post_parent ASC" ); // Make sure we're getting all of the attachments for these posts too - if ( 'all' != $args['post_type'] ) { + if ( 'all' != $args['post_type'] || ! empty( $args['post__in'] ) ) { $all_post_ids_with_attachments = array(); while ( $post_ids = array_splice( $all_the_post_ids, 0, 100 ) ) { $attachment_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent IN (". implode( ",", array_map( 'intval', $post_ids ) ) .")" ); From f28cdcc78a2d7665abd0ec3922db644e99f51a0a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Dec 2012 14:42:35 +0200 Subject: [PATCH 0881/4858] pretend we're in /wp-admin/ --- src/php/wp-cli/class-wp-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 973dd0606c..e92960893e 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -268,6 +268,10 @@ static function before_wp_load() { if ( array( 'core', 'install' ) == self::$arguments ) { define( 'WP_INSTALLING', true ); } + + // Pretend we're in WP_ADMIN, to side-step full-page caching plugins + define( 'WP_ADMIN', true ); + $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; } static function after_wp_load() { From 543dcde0f33229f80b075538a0f8557556c0947e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Dec 2012 15:00:18 +0200 Subject: [PATCH 0882/4858] add post__in usage example --- man/export.1 | 10 +++++++++- src/docs/export.txt | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/man/export.1 b/man/export.1 index 5a3d58584e..c23fee7abd 100644 --- a/man/export.1 +++ b/man/export.1 @@ -7,7 +7,7 @@ \fBwp\-export\fR \- Export posts to a WXR file\. . .SH "SYNOPSIS" -\fBwp export\fR [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] +\fBwp export\fR [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post\fI\fIin=\fRpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] . .SH "OPTIONS" . @@ -50,6 +50,12 @@ Export only posts older than this date, in format YYYY\-MM\-DD\. Export only posts with this post_type\. . .TP +\fB\-\-post__in\fR=\fIpid\fR: +. +.IP +Export all posts specified as a comma\-separated list of IDs\. +. +.TP \fB\-\-author\fR=<login/id>: . .IP @@ -72,6 +78,8 @@ Export only posts with this status\. .nf wp export \-\-dir=/tmp/ \-\-user=admin \-\-post_type=post \-\-start_date=2011\-01\-01 \-\-end_date=2011\-12\-31 + +wp export \-\-dir=/tmp/ \-\-post__in=123,124,125 . .fi diff --git a/src/docs/export.txt b/src/docs/export.txt index 473fc515a4..94e5cab4bd 100644 --- a/src/docs/export.txt +++ b/src/docs/export.txt @@ -29,7 +29,7 @@ to current working directory. * `--post__in`=<pid>: - Export all posts specified with IDs + Export all posts specified as a comma-separated list of IDs. * `--author`=<login/id>: @@ -46,3 +46,5 @@ to current working directory. ## EXAMPLES wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + + wp export --dir=/tmp/ --post__in=123,124,125 From 330d3ec0c5f852f12cd47d121d1db063b239d8af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Dec 2012 18:17:39 +0200 Subject: [PATCH 0883/4858] fix synopsis for blog create: the flag is --private, not --public --- src/php/wp-cli/commands/internals/blog.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index 4c027ef2f5..d46a55a82e 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -33,9 +33,9 @@ private function _get_site( $site_id ) { /** * Create a blog in a multisite install. * - * @synopsis --slug=<slug> --title=<title> [--email=<email>] [--site_id=<site-id>] [--public] + * @synopsis --slug=<slug> --title=<title> [--email=<email>] [--site_id=<site-id>] [--private] */ - public function create( $args, $assoc_args ) { + public function create( $_, $assoc_args ) { global $wpdb; $base = $assoc_args['slug']; @@ -52,7 +52,7 @@ public function create( $args, $assoc_args ) { $site = wpmu_current_site(); } - $public = isset( $assoc_args['private'] ) ? 0 : 1; + $public = !isset( $assoc_args['private'] ); // Sanitize if ( preg_match( '|^([a-zA-Z0-9-])+$|', $base ) ) { From 66fd2c1a318c5331cc8de110e3bbbc4f104f67a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Dec 2012 18:55:06 +0200 Subject: [PATCH 0884/4858] make --title arg optional in blog create --- man/blog-create.1 | 4 ++-- src/docs/blog-create.txt | 2 +- src/php/wp-cli/commands/internals/blog.php | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/man/blog-create.1 b/man/blog-create.1 index 7e30d4d820..34bc50c9a2 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -7,7 +7,7 @@ \fBwp\-blog\-create\fR \- Create a blog in a multisite install\. . .SH "SYNOPSIS" -\fBwp blog create\fR \-\-slug=\fIslug\fR \-\-title=\fItitle\fR [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-public] +\fBwp blog create\fR \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] . .SH "OPTIONS" . @@ -21,7 +21,7 @@ Path for the new blog\. Subdomain on subdomain installs, directory on subdirecto \fB\-\-title\fR=<title>: . .IP -Title of the new blog\. +Title of the new blog\. Default: prettified slug\. . .TP \fB\-\-email\fR=\fIemail\fR: diff --git a/src/docs/blog-create.txt b/src/docs/blog-create.txt index 3f660e3cb2..02814b8f3a 100644 --- a/src/docs/blog-create.txt +++ b/src/docs/blog-create.txt @@ -6,7 +6,7 @@ * `--title`=<title>: - Title of the new blog. + Title of the new blog. Default: prettified slug. * `--email`=<email>: diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/internals/blog.php index d46a55a82e..b73f1bd9b0 100644 --- a/src/php/wp-cli/commands/internals/blog.php +++ b/src/php/wp-cli/commands/internals/blog.php @@ -33,13 +33,14 @@ private function _get_site( $site_id ) { /** * Create a blog in a multisite install. * - * @synopsis --slug=<slug> --title=<title> [--email=<email>] [--site_id=<site-id>] [--private] + * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--site_id=<site-id>] [--private] */ public function create( $_, $assoc_args ) { global $wpdb; $base = $assoc_args['slug']; - $title = $assoc_args['title']; + $title = isset( $assoc_args['title'] ) ? $assoc_args['title'] : ucfirst( $base ); + $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; // Site if ( !empty( $assoc_args['site_id'] ) ) { From 8fe5d452f388c3026cf529f8127f18c6efa07dd1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Dec 2012 23:13:11 +0200 Subject: [PATCH 0885/4858] fix synopsis for core `install-network` --- man/core-install-network.1 | 4 ++-- src/docs/core-install-network.txt | 2 +- src/php/wp-cli/commands/internals/core.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/core-install-network.1 b/man/core-install-network.1 index d76fc582d6..78218ff9ca 100644 --- a/man/core-install-network.1 +++ b/man/core-install-network.1 @@ -7,7 +7,7 @@ \fBwp\-core\-install\-network\fR \- Transform a single\-site install into a multi\-site install\. . .SH "SYNOPSIS" -\fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base_path=\fIurl\-path\fR] +\fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base=\fIurl\-path\fR] . .SH "OPTIONS" . @@ -18,7 +18,7 @@ The title of the new network\. . .TP -\fB\-\-base_path\fR=\fIurl\-path\fR: +\fB\-\-base\fR=\fIurl\-path\fR: . .IP Base path after the domain name that each site url will start with\. Default: \'/\' diff --git a/src/docs/core-install-network.txt b/src/docs/core-install-network.txt index 86db38741b..26e2c2a955 100644 --- a/src/docs/core-install-network.txt +++ b/src/docs/core-install-network.txt @@ -4,7 +4,7 @@ The title of the new network. -* `--base_path`=<url-path>: +* `--base`=<url-path>: Base path after the domain name that each site url will start with. Default: '/' diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index a53be97c8d..40af5f6aac 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -109,7 +109,7 @@ public function install( $args, $assoc_args ) { * Transform a single-site install into a multi-site install. * * @subcommand install-network - * @synopsis --title=<network-title> [--base_path=<url-path>] + * @synopsis --title=<network-title> [--base=<url-path>] */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) From 56bfa6c4616d8421593b66e9ab5f0d279b6c6dc7 Mon Sep 17 00:00:00 2001 From: Miles Johnson <mileswjohnson@gmail.com> Date: Wed, 5 Dec 2012 15:53:51 -0800 Subject: [PATCH 0886/4858] Allow for updates during user import-csv --- src/php/wp-cli/commands/internals/user.php | 42 +++++++++++++++++----- src/php/wp-cli/utils.php | 1 + 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 3a186402f2..1aedfbac4c 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -268,7 +268,7 @@ private static function get_user_from_first_arg( $id_or_login ) { * @subcommand import-csv * @synopsis <file> */ - public function import_csv( $args, $assoc_args ) { + public function import_csv( $args, $assoc_args, $update = false ) { list( $csv ) = $args; @@ -295,31 +295,57 @@ public function import_csv( $args, $assoc_args ) { // User already exists and we just need to add them to the site if they aren't already there if ( $existing_user = get_user_by( 'email', $new_user['user_email'] ) ) { - if ( in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) ) + $new_user['ID'] = $existing_user->ID; + + if ( in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) ) { WP_CLI::warning( "{$existing_user->user_login} already is a member of blog" ); - else if ( $new_user['role'] ) { + + } else if ( $new_user['role'] ) { add_user_to_blog( get_current_blog_id(), $existing_user->ID, $new_user['role'] ); WP_CLI::line( "{$existing_user->user_login} added to blog as {$new_user['role']}" ); + } else { WP_CLI::line( "{$existing_user->user_login} exists, but won't be added to the blog" ); } - continue; - } - $user_id = wp_insert_user( $new_user ); + if (!$update) { + continue; + } + + $user_id = wp_update_user( $new_user ); + + // Create the user + } else { + $user_id = wp_insert_user( $new_user ); + } if ( is_wp_error( $user_id ) ) { WP_CLI::warning( $user_id ); continue; } else { - if ( false === $new_user['role'] ) { + if ( $new_user['role'] === false ) { delete_user_option( $user_id, 'capabilities' ); delete_user_option( $user_id, 'user_level' ); } } - WP_CLI::line( $new_user['user_login'] . " created" ); + if (!empty($existing_user)) { + WP_CLI::line( $new_user['user_login'] . " updated" ); + } else { + WP_CLI::line( $new_user['user_login'] . " created" ); + } } } + + /** + * Import users from a CSV file and allow it to update the records instead of just create. + * + * @subcommand import-csv-upsert + * @synopsis <file> + */ + public function import_csv_upsert( $args, $assoc_args ) { + $this->import_csv( $args, $assoc_args, true ); + } + } diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index 5221c12de1..f6d4045573 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -106,6 +106,7 @@ function set_url_params( $url ) { $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); $_SERVER['REQUEST_URL'] = $f('path'); $_SERVER['QUERY_STRING'] = $f('query'); + $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); } function locate_wp_config() { From 48a55d801c16f0e6c53d9f9ac5852f29b2f415c1 Mon Sep 17 00:00:00 2001 From: Miles Johnson <mileswjohnson@gmail.com> Date: Wed, 5 Dec 2012 16:03:05 -0800 Subject: [PATCH 0887/4858] Find user by email and login --- src/php/wp-cli/commands/internals/user.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 1aedfbac4c..72cf841482 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -294,7 +294,13 @@ public function import_csv( $args, $assoc_args, $update = false ) { } // User already exists and we just need to add them to the site if they aren't already there - if ( $existing_user = get_user_by( 'email', $new_user['user_email'] ) ) { + $existing_user = get_user_by( 'email', $new_user['user_email'] ); + + if ( !$existing_user ) { + $existing_user = get_user_by( 'login', $new_user['user_login'] ); + } + + if ( $existing_user ) { $new_user['ID'] = $existing_user->ID; if ( in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) ) { @@ -330,9 +336,9 @@ public function import_csv( $args, $assoc_args, $update = false ) { } if (!empty($existing_user)) { - WP_CLI::line( $new_user['user_login'] . " updated" ); + WP_CLI::success( $new_user['user_login'] . " updated" ); } else { - WP_CLI::line( $new_user['user_login'] . " created" ); + WP_CLI::success( $new_user['user_login'] . " created" ); } } } From 00cc51a5e8d4219d778a3cb9c93b696fe617effb Mon Sep 17 00:00:00 2001 From: Miles Johnson <mileswjohnson@gmail.com> Date: Thu, 6 Dec 2012 16:33:00 -0800 Subject: [PATCH 0888/4858] Updated import-csv --- src/php/wp-cli/commands/internals/user.php | 37 +++++----------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 72cf841482..552b802896 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -268,7 +268,7 @@ private static function get_user_from_first_arg( $id_or_login ) { * @subcommand import-csv * @synopsis <file> */ - public function import_csv( $args, $assoc_args, $update = false ) { + public function import_csv( $args, $assoc_args ) { list( $csv ) = $args; @@ -288,6 +288,7 @@ public function import_csv( $args, $assoc_args, $update = false ) { if ( 'none' == $new_user['role'] ) { $new_user['role'] = false; + } elseif ( is_null( get_role( $new_user['role'] ) ) ) { WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); continue; @@ -302,24 +303,13 @@ public function import_csv( $args, $assoc_args, $update = false ) { if ( $existing_user ) { $new_user['ID'] = $existing_user->ID; + $user_id = wp_update_user( $new_user ); - if ( in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) ) { - WP_CLI::warning( "{$existing_user->user_login} already is a member of blog" ); - - } else if ( $new_user['role'] ) { + if ( !in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) && $new_user['role'] ) { add_user_to_blog( get_current_blog_id(), $existing_user->ID, $new_user['role'] ); WP_CLI::line( "{$existing_user->user_login} added to blog as {$new_user['role']}" ); - - } else { - WP_CLI::line( "{$existing_user->user_login} exists, but won't be added to the blog" ); - } - - if (!$update) { - continue; } - $user_id = wp_update_user( $new_user ); - // Create the user } else { $user_id = wp_insert_user( $new_user ); @@ -328,11 +318,10 @@ public function import_csv( $args, $assoc_args, $update = false ) { if ( is_wp_error( $user_id ) ) { WP_CLI::warning( $user_id ); continue; - } else { - if ( $new_user['role'] === false ) { - delete_user_option( $user_id, 'capabilities' ); - delete_user_option( $user_id, 'user_level' ); - } + + } else if ( $new_user['role'] === false ) { + delete_user_option( $user_id, 'capabilities' ); + delete_user_option( $user_id, 'user_level' ); } if (!empty($existing_user)) { @@ -343,15 +332,5 @@ public function import_csv( $args, $assoc_args, $update = false ) { } } - /** - * Import users from a CSV file and allow it to update the records instead of just create. - * - * @subcommand import-csv-upsert - * @synopsis <file> - */ - public function import_csv_upsert( $args, $assoc_args ) { - $this->import_csv( $args, $assoc_args, true ); - } - } From f96d41326f41f66a14225b710fcaa0d759637ddb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 18:22:11 +0200 Subject: [PATCH 0889/4858] wp option docs: mention --json argument only once --- man/option.1 | 16 ++++++++++++---- src/docs/option.txt | 17 ++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/man/option.1 b/man/option.1 index b333c91196..5f88a911c0 100644 --- a/man/option.1 +++ b/man/option.1 @@ -24,19 +24,19 @@ wp option delete \fIkey\fR \fBget\fR: . .IP -Get an option value\. Passing \-\-json causes the output to be formatted as JSON\. +Get an option value\. . .TP \fBadd\fR: . .IP -Add a new option\. Pass \-\-json to decode JSON values before adding the option\. +Add a new option\. . .TP \fBupdate\fR: . .IP -Update an existing option\. Pass \-\-json to decode JSON values before updating the option\. +Update an existing option\. . .TP \fBdelete\fR: @@ -44,6 +44,14 @@ Update an existing option\. Pass \-\-json to decode JSON values before updating .IP Delete an option\. . +.SH "OPTIONS" +. +.TP +\fBjson\fR: +. +.IP +Encode/decode values as JSON\. +. .SH "EXAMPLES" . .nf @@ -52,7 +60,7 @@ wp option get siteurl wp option add my_option foobar -wp option update my_option barfoo +wp option update my_option \'{"foo": "bar"}\' \-\-json wp option delete my_option . diff --git a/src/docs/option.txt b/src/docs/option.txt index cbb7b79c69..f8629478c5 100644 --- a/src/docs/option.txt +++ b/src/docs/option.txt @@ -15,29 +15,32 @@ wp option delete <key> * `get`: - Get an option value. Passing --json causes the output to be formatted - as JSON. + Get an option value. * `add`: - Add a new option. Pass --json to decode JSON values before adding - the option. + Add a new option. * `update`: - Update an existing option. Pass --json to decode JSON values before - updating the option. + Update an existing option. * `delete`: Delete an option. +## OPTIONS + +* `json`: + + Encode/decode values as JSON. + ## EXAMPLES wp option get siteurl wp option add my_option foobar - wp option update my_option barfoo + wp option update my_option '{"foo": "bar"}' --json wp option delete my_option From 4cf34d52fc3c4773517b6c61ced88cc7a79e6963 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:16:58 +0200 Subject: [PATCH 0890/4858] introduce DocParser class --- src/php/wp-cli/dispatcher.php | 123 +++++++++++++++++++++------------- src/php/wp-cli/man.php | 4 +- 2 files changed, 79 insertions(+), 48 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index 7bb0b3b519..c56c490a45 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -18,6 +18,37 @@ function traverse( &$args, $method = 'find_subcommand' ) { } +class DocParser { + + protected $docComment; + + function __construct( $reflection ) { + $this->docComment = $reflection->getDocComment(); + } + + function get_shortdesc() { + if ( !preg_match( '/\* (\w.+)\n*/', $this->docComment, $matches ) ) + return false; + + return $matches[1]; + } + + function get_tag( $name ) { + if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $this->docComment, $matches ) ) + return $matches[1]; + + return false; + } + + function get_synopsis() { + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $this->docComment, $matches ) ) + return false; + + return $matches[1]; + } +} + + interface Command { function get_path(); @@ -38,7 +69,7 @@ function find_subcommand( &$args ); interface Documentable { function get_shortdesc(); - function get_synopsis(); + function get_full_synopsis(); } @@ -114,7 +145,9 @@ function add_command( $name, $implementation ) { else { $method = new \ReflectionMethod( $implementation, '__invoke' ); - $command = new Subcommand( $name, $implementation, $method, $this ); + $docparser = new DocParser( $method ); + + $command = new Subcommand( $name, $implementation, $docparser, $this ); } $this->subcommands[ $name ] = $command; @@ -160,21 +193,25 @@ function load_command( $command ) { } -class CompositeCommand implements Command, Composite { +class CompositeCommand implements Command, Composite, Documentable { protected $name; protected $subcommands; + protected $shortdesc; + public function __construct( $name, $class ) { $this->name = $name; - $this->subcommands = $this->collect_subcommands( $class ); - } - - private function collect_subcommands( $class ) { $reflection = new \ReflectionClass( $class ); + $this->subcommands = $this->collect_subcommands( $reflection, $class ); + + $this->docparser = new DocParser( $reflection ); + } + + private function collect_subcommands( $reflection, $class ) { $subcommands = array(); foreach ( $reflection->getMethods() as $method ) { @@ -259,6 +296,20 @@ public function get_subcommands() { return $this->subcommands; } + public function get_shortdesc() { + return $this->docparser->get_shortdesc(); + } + + public function get_full_synopsis() { + $str = array(); + + foreach ( $this->subcommands as $subcommand ) { + $str[] = $subcommand->get_full_synopsis(); + } + + return implode( "\n\n", $str ); + } + private static function _is_good_method( $method ) { return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); } @@ -267,18 +318,26 @@ private static function _is_good_method( $method ) { class Subcommand implements Command, Documentable { - function __construct( $name, $callable, $method, $parent ) { + function __construct( $name, $callable, $docparser, $parent ) { $this->name = $name; $this->callable = $callable; - $this->method = $method; + $this->docparser = $docparser; $this->parent = $parent; } function show_usage( $prefix = 'usage: ' ) { + \WP_CLI::line( $prefix . $this->get_full_synopsis() ); + } + + function get_shortdesc() { + return $this->docparser->get_shortdesc(); + } + + function get_full_synopsis() { $full_name = implode( ' ', $this->get_path() ); - $synopsis = $this->get_synopsis(); + $synopsis = $this->docparser->get_synopsis(); - \WP_CLI::line( $prefix . "wp $full_name $synopsis" ); + return "wp $full_name $synopsis"; } function invoke( $args, $assoc_args ) { @@ -300,7 +359,7 @@ function get_path() { } protected function check_args( $args, $assoc_args ) { - $synopsis = $this->get_synopsis(); + $synopsis = $this->docparser->get_synopsis(); if ( !$synopsis ) return; @@ -372,24 +431,6 @@ private function check_unknown_assoc( $assoc_args, $accepted_params ) { } } - function get_shortdesc() { - $comment = $this->method->getDocComment(); - - if ( !preg_match( '/\* (\w.+)\n*/', $comment, $matches ) ) - return false; - - return $matches[1]; - } - - public function get_synopsis() { - $comment = $this->method->getDocComment(); - - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $comment, $matches ) ) - return false; - - return $matches[1]; - } - protected function parse_synopsis( $synopsis ) { list( $patterns, $params ) = self::get_patterns(); @@ -452,27 +493,17 @@ class MethodSubcommand extends Subcommand { function __construct( $class, $method, $parent ) { $callable = array( new $class, $method->name ); - parent::__construct( self::_get_name( $method ), $callable, $method, $parent ); - } - - private static function _get_name( $method ) { - if ( $name = self::get_tag( $method, 'subcommand' ) ) - return $name; - - return $method->name; - } + $docparser = new DocParser( $method ); - private static function get_tag( $method, $name ) { - $comment = $method->getDocComment(); + $name = $docparser->get_tag( 'subcommand' ); + if ( !$name ) + $name = $method->name; - if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $comment, $matches ) ) - return $matches[1]; - - return false; + parent::__construct( $name, $callable, $docparser, $parent ); } function get_alias() { - return self::get_tag( $this->method, 'alias' ); + return $this->docparser->get_tag( 'alias' ); } } diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index 515a88c6c4..bee9fcc6f0 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -48,7 +48,7 @@ function get_markdown( $doc_path, $command ) { function add_initial_markdown( $fd, $command ) { $path = $command->get_path(); $shortdesc = $command->get_shortdesc(); - $synopsis = $command->get_synopsis(); + $synopsis = $command->get_full_synopsis(); $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); @@ -65,7 +65,7 @@ function add_initial_markdown( $fd, $command ) { ## SYNOPSIS -`wp $name_s` $synopsis +$synopsis DOC ); From 133c2dd2a2298e97131fe654a182c3feab51c10f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:23:11 +0200 Subject: [PATCH 0891/4858] add SUBCOMMANDS section automatically --- src/php/wp-cli/man.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/php/wp-cli/man.php b/src/php/wp-cli/man.php index bee9fcc6f0..6a06c169e0 100644 --- a/src/php/wp-cli/man.php +++ b/src/php/wp-cli/man.php @@ -69,6 +69,28 @@ function add_initial_markdown( $fd, $command ) { DOC ); + + if ( $command instanceof Dispatcher\Composite ) { + + fwrite( $fd, <<<DOC +## SUBCOMMANDS + +DOC + ); + + foreach ( $command->get_subcommands() as $subcommand ) { + $name = $subcommand->get_name(); + $desc = $subcommand->get_shortdesc(); + + fwrite( $fd, <<<DOC +* `$name`: + + $desc + +DOC + ); + } + } } function call_ronn( $markdown, $dest ) { From 4e7087209f87d9e5505adb1b7edafd18c71a0715 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:23:40 +0200 Subject: [PATCH 0892/4858] remove redundant data from composite command man pages --- man/option.1 | 7 ++-- man/post-meta.1 | 27 ++++++++++------ src/docs/option.txt | 31 ------------------ src/docs/post-meta.txt | 32 ++----------------- src/docs/user-meta.txt | 32 ++----------------- src/php/wp-cli/commands/internals/option.php | 2 +- .../wp-cli/commands/internals/post-meta.php | 2 +- .../wp-cli/commands/internals/user-meta.php | 2 +- 8 files changed, 31 insertions(+), 104 deletions(-) diff --git a/man/option.1 b/man/option.1 index 5f88a911c0..12b38c6b77 100644 --- a/man/option.1 +++ b/man/option.1 @@ -24,19 +24,19 @@ wp option delete \fIkey\fR \fBget\fR: . .IP -Get an option value\. +Get an option\. . .TP \fBadd\fR: . .IP -Add a new option\. +Add an option\. . .TP \fBupdate\fR: . .IP -Update an existing option\. +Update an option\. . .TP \fBdelete\fR: @@ -45,6 +45,7 @@ Update an existing option\. Delete an option\. . .SH "OPTIONS" + . .TP \fBjson\fR: diff --git a/man/post-meta.1 b/man/post-meta.1 index 97e8253193..3b3fc962fd 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -7,16 +7,16 @@ \fBwp\-post\-meta\fR \- Manage post custom fields\. . .SH "SYNOPSIS" -wp post\-meta get \fIID\fR \fIkey\fR [\-\-json] +wp post\-meta get \fIid\fR \fIkey\fR [\-\-json] . .P -wp post\-meta add \fIID\fR \fIkey\fR \fIvalue\fR +wp post\-meta delete \fIid\fR \fIkey\fR . .P -wp post\-meta update \fIID\fR \fIkey\fR \fIvalue\fR +wp post\-meta add \fIid\fR \fIkey\fR \fIvalue\fR . .P -wp post\-meta delete \fIID\fR \fIkey\fR +wp post\-meta update \fIid\fR \fIkey\fR \fIvalue\fR . .SH "SUBCOMMANDS" . @@ -24,25 +24,34 @@ wp post\-meta delete \fIID\fR \fIkey\fR \fBget\fR: . .IP -Get a custom field value\. Passing \-\-json causes the output to be formatted as JSON\. +Get meta field value\. +. +.TP +\fBdelete\fR: +. +.IP +Delete a meta field\. . .TP \fBadd\fR: . .IP -Add a new custom field\. +Add a meta field\. . .TP \fBupdate\fR: . .IP -Update an existing custom field\. +Update a meta field\. +. +.SH "OPTIONS" + . .TP -\fBdelete\fR: +\fBjson\fR: . .IP -Delete a custom field\. +Encode/decode values as JSON\. . .SH "EXAMPLES" . diff --git a/src/docs/option.txt b/src/docs/option.txt index f8629478c5..238e5f66b9 100644 --- a/src/docs/option.txt +++ b/src/docs/option.txt @@ -1,34 +1,3 @@ -wp-option(1) -- Manage WordPress options. -==== - -## SYNOPSIS - -wp option get <key> [--json] - -wp option add <key> <value> [--json] - -wp option update <key> <value> [--json] - -wp option delete <key> - -## SUBCOMMANDS - -* `get`: - - Get an option value. - -* `add`: - - Add a new option. - -* `update`: - - Update an existing option. - -* `delete`: - - Delete an option. - ## OPTIONS * `json`: diff --git a/src/docs/post-meta.txt b/src/docs/post-meta.txt index 55a0af3289..e36dcb2391 100644 --- a/src/docs/post-meta.txt +++ b/src/docs/post-meta.txt @@ -1,34 +1,8 @@ -wp-post-meta(1) -- Manage post custom fields. -==== +## OPTIONS -## SYNOPSIS +* `json`: -wp post-meta get <ID> <key> [--json] - -wp post-meta add <ID> <key> <value> - -wp post-meta update <ID> <key> <value> - -wp post-meta delete <ID> <key> - -## SUBCOMMANDS - -* `get`: - - Get a custom field value. Passing --json causes the output to be formatted - as JSON. - -* `add`: - - Add a new custom field. - -* `update`: - - Update an existing custom field. - -* `delete`: - - Delete a custom field. + Encode/decode values as JSON. ## EXAMPLES diff --git a/src/docs/user-meta.txt b/src/docs/user-meta.txt index 8a7562f0fc..ad8d85bdbb 100644 --- a/src/docs/user-meta.txt +++ b/src/docs/user-meta.txt @@ -1,34 +1,8 @@ -wp-user-meta(1) -- Manage user custom fields. -==== +## OPTIONS -## SYNOPSIS +* `json`: -wp user-meta get <ID> <key> [--json] - -wp user-meta add <ID> <key> <value> - -wp user-meta update <ID> <key> <value> - -wp user-meta delete <ID> <key> - -## SUBCOMMANDS - -* `get`: - - Get a custom field value. Passing --json causes the output to be formatted - as JSON. - -* `add`: - - Add a new custom field. - -* `update`: - - Update an existing custom field. - -* `delete`: - - Delete a custom field. + Encode/decode values as JSON. ## EXAMPLES diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/internals/option.php index cf0147f6f1..d18f4a7b4b 100644 --- a/src/php/wp-cli/commands/internals/option.php +++ b/src/php/wp-cli/commands/internals/option.php @@ -3,7 +3,7 @@ WP_CLI::add_command('option', 'Option_Command'); /** - * Implement option command + * Manage WordPress options. * * @package wp-cli * @subpackage commands/internals diff --git a/src/php/wp-cli/commands/internals/post-meta.php b/src/php/wp-cli/commands/internals/post-meta.php index 6e3b710f84..466468eab8 100644 --- a/src/php/wp-cli/commands/internals/post-meta.php +++ b/src/php/wp-cli/commands/internals/post-meta.php @@ -3,7 +3,7 @@ WP_CLI::add_command( 'post-meta', 'Post_Meta_Command' ); /** - * Implement post-meta command + * Manage post custom fields. * * @package wp-cli * @subpackage commands/internals diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/internals/user-meta.php index 317420652a..58fa75e8ca 100644 --- a/src/php/wp-cli/commands/internals/user-meta.php +++ b/src/php/wp-cli/commands/internals/user-meta.php @@ -3,7 +3,7 @@ WP_CLI::add_command( 'user-meta', 'User_Meta_Command' ); /** - * Implement user-meta command + * Manage user custom fields. * * @package wp-cli * @subpackage commands/internals From 5fe949d6d58b2001170994f7840ad1351bb2c05d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:38:45 +0200 Subject: [PATCH 0893/4858] remove redundant data from `cache` and `transient` man pages see #236 --- man/cache.1 | 23 ++++--- man/transient.1 | 5 +- src/docs/cache.txt | 61 ------------------- src/docs/transient.txt | 33 ---------- src/php/wp-cli/commands/internals/cache.php | 2 +- .../wp-cli/commands/internals/transient.php | 2 +- 6 files changed, 19 insertions(+), 107 deletions(-) diff --git a/man/cache.1 b/man/cache.1 index c0d6cde143..a0031ba3bc 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -4,7 +4,7 @@ .TH "WP\-CACHE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-cache\fR \- Manage WordPress the object cache\. +\fBwp\-cache\fR \- Manage the WordPress object cache\. . .SH "SYNOPSIS" wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] @@ -39,57 +39,60 @@ wp cache type \fBadd\fR: . .IP -Add a value to cache where \fIkey\fR in \fIgroup\fR does not already exist\. +Add a value to the object cache\. . .TP \fBdecr\fR: . .IP -Decrement the value of a cached object by 1 or the value of the \fIoffset\fR parameter\. +Decrement a value in the object cache\. . .TP \fBdelete\fR: . .IP -Remove an object from cache\. +Remove a value from the object cache\. . .TP \fBflush\fR: . .IP -Flush the cache\. +Flush the object cache\. . .TP \fBget\fR: . .IP -Get a value from cache\. +Get a value from the object cache\. . .TP \fBincr\fR: . .IP -Increment the value of a cached object by 1 or the value of the \fIoffset\fR parameter\. +Increment a value in the object cache\. . .TP \fBreplace\fR: . .IP -Replace a value in cache with a new value\. +Replace an existing value in the object cache\. . .TP \fBset\fR: . .IP -Set a value in cache\. +Set a value to the object cache\. . .TP \fBtype\fR: . .IP -Report the type of object being used\. +Attempts to determine which object cache is being used\. . .SH "EXAMPLES" + +. +.P wp cache set my_key my_value my_group 300 . .P diff --git a/man/transient.1 b/man/transient.1 index 10077576e9..d169ff381b 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -7,7 +7,7 @@ \fBwp\-transient\fR \- Manage WordPress transients\. . .SH "SYNOPSIS" -wp transient get \fIkey\fR +wp transient get \fIkey\fR [\-\-json] . .P wp transient set \fIkey\fR \fIvalue\fR [\fIexpiration\fR] @@ -45,4 +45,7 @@ Delete a transient value\. See wether the transients API is using an object cache or the options table\. . .SH "EXAMPLES" + +. +.P wp transient set my_key my_value 300 diff --git a/src/docs/cache.txt b/src/docs/cache.txt index bd2d0f2865..7b25aa6d75 100644 --- a/src/docs/cache.txt +++ b/src/docs/cache.txt @@ -1,64 +1,3 @@ -wp-cache(1) -- Manage WordPress the object cache. -==== - -## SYNOPSIS - -wp cache add <key> <value> [<group>] [<expiration>] - -wp cache decr <key> [<offset>] [<group>] - -wp cache delete <key> <group> - -wp cache flush - -wp cache get <key> [<group>] - -wp cache incr <key> [<offset>] [<group>] - -wp cache replace <key> <value> [<group>] [<expiration>] - -wp cache set <key> <value> [<group>] [<expiration>] - -wp cache type - -## SUBCOMMANDS - -* `add`: - - Add a value to cache where <key> in <group> does not already exist. - -* `decr`: - - Decrement the value of a cached object by 1 or the value of the <offset> parameter. - -* `delete`: - - Remove an object from cache. - -* `flush`: - - Flush the cache. - -* `get`: - - Get a value from cache. - -* `incr`: - - Increment the value of a cached object by 1 or the value of the <offset> parameter. - -* `replace`: - - Replace a value in cache with a new value. - -* `set`: - - Set a value in cache. - -* `type`: - - Report the type of object being used. - ## EXAMPLES wp cache set my_key my_value my_group 300 diff --git a/src/docs/transient.txt b/src/docs/transient.txt index 50dece19da..175ca9c8d3 100644 --- a/src/docs/transient.txt +++ b/src/docs/transient.txt @@ -1,36 +1,3 @@ -wp-transient(1) -- Manage WordPress transients. -==== - -## SYNOPSIS - -wp transient get <key> - -wp transient set <key> <value> [<expiration>] - -wp transient delete <key> - -wp transient type - -## SUBCOMMANDS - -* `get`: - - Get a transient value. - -* `set`: - - Set a transient value. <expiration> is the time until expiration, in -seconds. - -* `delete`: - - Delete a transient value. - -* `type`: - - See wether the transients API is using an object cache or the options -table. - ## EXAMPLES wp transient set my_key my_value 300 diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/internals/cache.php index 32cf156a49..142c234196 100644 --- a/src/php/wp-cli/commands/internals/cache.php +++ b/src/php/wp-cli/commands/internals/cache.php @@ -3,7 +3,7 @@ WP_CLI::add_command( 'cache', 'Cache_Command' ); /** - * Implement cache command + * Manage the WordPress object cache. * * @package wp-cli * @subpackage commands/internals diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/internals/transient.php index 4b6d246626..f21b935421 100644 --- a/src/php/wp-cli/commands/internals/transient.php +++ b/src/php/wp-cli/commands/internals/transient.php @@ -3,7 +3,7 @@ WP_CLI::add_command( 'transient', 'Transient_Command' ); /** - * Implement transient commands. + * Manage WordPress transients. * * @package wp-cli * @subpackage commands/internals From 2cc88d3dc9160c0e9a4ea22d6be96d8940043676 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:43:38 +0200 Subject: [PATCH 0894/4858] renegerate all man pages. see #236 --- man/blog-create.1 | 2 +- man/blog-delete.1 | 2 +- man/comment-approve.1 | 2 +- man/comment-count.1 | 2 +- man/comment-create.1 | 2 +- man/comment-delete.1 | 2 +- man/comment-last.1 | 2 +- man/comment-spam.1 | 2 +- man/comment-status.1 | 2 +- man/comment-trash.1 | 2 +- man/comment-unapprove.1 | 2 +- man/comment-unspam.1 | 2 +- man/comment-untrash.1 | 2 +- man/core-config.1 | 2 +- man/core-download.1 | 2 +- man/core-install-network.1 | 2 +- man/core-install.1 | 2 +- man/core-is-installed.1 | 2 +- man/core-update.1 | 2 +- man/core-version.1 | 2 +- man/db-drop.1 | 2 +- man/db-export.1 | 2 +- man/db-import.1 | 2 +- man/db-query.1 | 2 +- man/db-reset.1 | 2 +- man/eval-file.1 | 2 +- man/eval.1 | 2 +- man/export.1 | 2 +- man/plugin-activate.1 | 2 +- man/plugin-deactivate.1 | 2 +- man/plugin-delete.1 | 2 +- man/plugin-install.1 | 2 +- man/plugin-path.1 | 2 +- man/plugin-status.1 | 2 +- man/plugin-toggle.1 | 2 +- man/plugin-uninstall.1 | 2 +- man/plugin-update-all.1 | 2 +- man/plugin-update.1 | 2 +- man/post-create.1 | 2 +- man/post-delete.1 | 2 +- man/post-generate.1 | 2 +- man/post-list.1 | 2 +- man/post-update.1 | 2 +- man/rewrite-dump.1 | 2 +- man/rewrite-flush.1 | 2 +- man/rewrite-structure.1 | 2 +- man/theme-activate.1 | 2 +- man/theme-delete.1 | 2 +- man/theme-install.1 | 2 +- man/theme-path.1 | 2 +- man/theme-status.1 | 2 +- man/theme-update-all.1 | 2 +- man/theme-update.1 | 2 +- man/user-create.1 | 2 +- man/user-delete.1 | 2 +- man/user-generate.1 | 2 +- man/user-import-csv.1 | 2 +- man/user-list.1 | 2 +- man/user-meta.1 | 27 ++++++++++++++++++--------- man/user-remove-role.1 | 2 +- man/user-set-role.1 | 2 +- man/user-update.1 | 2 +- 62 files changed, 79 insertions(+), 70 deletions(-) diff --git a/man/blog-create.1 b/man/blog-create.1 index 34bc50c9a2..c0b207a8be 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -7,7 +7,7 @@ \fBwp\-blog\-create\fR \- Create a blog in a multisite install\. . .SH "SYNOPSIS" -\fBwp blog create\fR \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] +wp blog create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] . .SH "OPTIONS" . diff --git a/man/blog-delete.1 b/man/blog-delete.1 index da5747d997..80e3c20c1b 100644 --- a/man/blog-delete.1 +++ b/man/blog-delete.1 @@ -7,7 +7,7 @@ \fBwp\-blog\-delete\fR \- Delete a blog in a multisite install\. . .SH "SYNOPSIS" -\fBwp blog delete\fR \-\-slug=\fIslug\fR [\-\-yes] [\-\-keep\-tables] +wp blog delete \-\-slug=\fIslug\fR [\-\-yes] [\-\-keep\-tables] . .SH "OPTIONS" . diff --git a/man/comment-approve.1 b/man/comment-approve.1 index 2f05beb712..759498b75c 100644 --- a/man/comment-approve.1 +++ b/man/comment-approve.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-approve\fR \- Approve a comment\. . .SH "SYNOPSIS" -\fBwp comment approve\fR \fIid\fR +wp comment approve \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-count.1 b/man/comment-count.1 index 499179b7d2..4cb5c913b5 100644 --- a/man/comment-count.1 +++ b/man/comment-count.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-count\fR \- Count comments, on whole blog or on a given post\. . .SH "SYNOPSIS" -\fBwp comment count\fR [\fIpost\-id\fR] +wp comment count [\fIpost\-id\fR] . .SH "OPTIONS" . diff --git a/man/comment-create.1 b/man/comment-create.1 index 72b010be5b..8ca70f0cec 100644 --- a/man/comment-create.1 +++ b/man/comment-create.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-create\fR \- Insert a comment\. . .SH "SYNOPSIS" -\fBwp comment create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] +wp comment create \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/comment-delete.1 b/man/comment-delete.1 index 7a90702d1a..fe9567b793 100644 --- a/man/comment-delete.1 +++ b/man/comment-delete.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-delete\fR \- Delete a comment\. . .SH "SYNOPSIS" -\fBwp comment delete\fR \fIid\fR [\-\-force] +wp comment delete \fIid\fR [\-\-force] . .SH "OPTIONS" . diff --git a/man/comment-last.1 b/man/comment-last.1 index 9f0ceb2987..47b760f839 100644 --- a/man/comment-last.1 +++ b/man/comment-last.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-last\fR \- Get last approved comment\. . .SH "SYNOPSIS" -\fBwp comment last\fR [\-\-id] [\-\-full] +wp comment last [\-\-id] [\-\-full] . .SH "OPTIONS" . diff --git a/man/comment-spam.1 b/man/comment-spam.1 index 780872b1ac..1f07321783 100644 --- a/man/comment-spam.1 +++ b/man/comment-spam.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-spam\fR \- Spam a comment\. . .SH "SYNOPSIS" -\fBwp comment spam\fR \fIid\fR +wp comment spam \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-status.1 b/man/comment-status.1 index 556f6ad279..70c4ddd4ef 100644 --- a/man/comment-status.1 +++ b/man/comment-status.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-status\fR \- Get status of a comment\. . .SH "SYNOPSIS" -\fBwp comment status\fR \fIid\fR +wp comment status \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-trash.1 b/man/comment-trash.1 index 282d823413..2deba83bae 100644 --- a/man/comment-trash.1 +++ b/man/comment-trash.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-trash\fR \- Trash a comment\. . .SH "SYNOPSIS" -\fBwp comment trash\fR \fIid\fR +wp comment trash \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-unapprove.1 b/man/comment-unapprove.1 index 986377f42f..e6d18d043f 100644 --- a/man/comment-unapprove.1 +++ b/man/comment-unapprove.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-unapprove\fR \- Unapprove a comment\. . .SH "SYNOPSIS" -\fBwp comment unapprove\fR \fIid\fR +wp comment unapprove \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-unspam.1 b/man/comment-unspam.1 index ce9c72b99b..41d7dd87f0 100644 --- a/man/comment-unspam.1 +++ b/man/comment-unspam.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-unspam\fR \- Unspam a comment\. . .SH "SYNOPSIS" -\fBwp comment unspam\fR \fIid\fR +wp comment unspam \fIid\fR . .SH "OPTIONS" . diff --git a/man/comment-untrash.1 b/man/comment-untrash.1 index ec9735a93b..ca2caa724c 100644 --- a/man/comment-untrash.1 +++ b/man/comment-untrash.1 @@ -7,7 +7,7 @@ \fBwp\-comment\-untrash\fR \- Untrash a comment\. . .SH "SYNOPSIS" -\fBwp comment untrash\fR \fIid\fR +wp comment untrash \fIid\fR . .SH "OPTIONS" . diff --git a/man/core-config.1 b/man/core-config.1 index c950991e24..0e53dd338f 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -7,7 +7,7 @@ \fBwp\-core\-config\fR \- Set up a wp\-config\.php file\. . .SH "SYNOPSIS" -\fBwp core config\fR \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] +wp core config \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] . .SH "OPTIONS" . diff --git a/man/core-download.1 b/man/core-download.1 index 02414cb40a..19b3e11eb3 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -7,7 +7,7 @@ \fBwp\-core\-download\fR \- Download core WordPress files\. . .SH "SYNOPSIS" -\fBwp core download\fR [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] [\-\-path=\fIpath\fR] +wp core download [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] [\-\-path=\fIpath\fR] . .SH "OPTIONS" . diff --git a/man/core-install-network.1 b/man/core-install-network.1 index 78218ff9ca..f7f4f84a8c 100644 --- a/man/core-install-network.1 +++ b/man/core-install-network.1 @@ -7,7 +7,7 @@ \fBwp\-core\-install\-network\fR \- Transform a single\-site install into a multi\-site install\. . .SH "SYNOPSIS" -\fBwp core install\-network\fR \-\-title=\fInetwork\-title\fR [\-\-base=\fIurl\-path\fR] +wp core install\-network \-\-title=\fInetwork\-title\fR [\-\-base=\fIurl\-path\fR] . .SH "OPTIONS" . diff --git a/man/core-install.1 b/man/core-install.1 index 7a5e0b9a9c..8667886296 100644 --- a/man/core-install.1 +++ b/man/core-install.1 @@ -7,7 +7,7 @@ \fBwp\-core\-install\fR \- Create the WordPress tables in the database\. . .SH "SYNOPSIS" -\fBwp core install\fR \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_email=\fIemail\fR \-\-admin_password=\fIpassword\fR +wp core install \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_email=\fIemail\fR \-\-admin_password=\fIpassword\fR . .SH "OPTIONS" . diff --git a/man/core-is-installed.1 b/man/core-is-installed.1 index 76a37ddda8..ac423ae11a 100644 --- a/man/core-is-installed.1 +++ b/man/core-is-installed.1 @@ -7,7 +7,7 @@ \fBwp\-core\-is\-installed\fR \- Determine if the WordPress tables are installed\. . .SH "SYNOPSIS" -\fBwp core is\-installed\fR +wp core is\-installed . .SH "EXAMPLES" if [ ! $(wp core is\-installed) ]; then diff --git a/man/core-update.1 b/man/core-update.1 index 4d69900ae0..cb5848fb20 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -7,7 +7,7 @@ \fBwp\-core\-update\fR \- Update WordPress\. . .SH "SYNOPSIS" -\fBwp core update\fR [\fIzip\fR] [\-\-version=\fIversion\fR] [\-\-force] +wp core update [\fIzip\fR] [\-\-version=\fIversion\fR] [\-\-force] . .SH "OPTIONS" . diff --git a/man/core-version.1 b/man/core-version.1 index 4e9599f47c..c3a37f1c15 100644 --- a/man/core-version.1 +++ b/man/core-version.1 @@ -7,7 +7,7 @@ \fBwp\-core\-version\fR \- Display the WordPress version\. . .SH "SYNOPSIS" -\fBwp core version\fR [\-\-extra] +wp core version [\-\-extra] . .SH "OPTIONS" . diff --git a/man/db-drop.1 b/man/db-drop.1 index 3a0a06b651..2f28197ff4 100644 --- a/man/db-drop.1 +++ b/man/db-drop.1 @@ -7,7 +7,7 @@ \fBwp\-db\-drop\fR \- Delete the database\. . .SH "SYNOPSIS" -\fBwp db drop\fR [\-\-yes] +wp db drop [\-\-yes] . .SH "OPTIONS" . diff --git a/man/db-export.1 b/man/db-export.1 index 5dd6301427..2f0a811fca 100644 --- a/man/db-export.1 +++ b/man/db-export.1 @@ -7,7 +7,7 @@ \fBwp\-db\-export\fR \- Exports the database using mysqldump\. . .SH "SYNOPSIS" -\fBwp db export\fR [\fIfile\fR] +wp db export [\fIfile\fR] . .SH "OPTIONS" . diff --git a/man/db-import.1 b/man/db-import.1 index c98ce4f709..eaa90697ee 100644 --- a/man/db-import.1 +++ b/man/db-import.1 @@ -7,7 +7,7 @@ \fBwp\-db\-import\fR \- Import database from a file\. . .SH "SYNOPSIS" -\fBwp db import\fR [\fIfile\fR] +wp db import [\fIfile\fR] . .SH "OPTIONS" . diff --git a/man/db-query.1 b/man/db-query.1 index db0962429a..0e0abdaf90 100644 --- a/man/db-query.1 +++ b/man/db-query.1 @@ -7,7 +7,7 @@ \fBwp\-db\-query\fR \- Execute a query against the database\. . .SH "SYNOPSIS" -\fBwp db query\fR \fIsql\fR +wp db query \fIsql\fR . .SH "OPTIONS" . diff --git a/man/db-reset.1 b/man/db-reset.1 index f8ca22aa8a..b27e41cfc0 100644 --- a/man/db-reset.1 +++ b/man/db-reset.1 @@ -7,7 +7,7 @@ \fBwp\-db\-reset\fR \- Remove all tables from the database\. . .SH "SYNOPSIS" -\fBwp db reset\fR [\-\-yes] +wp db reset [\-\-yes] . .SH "OPTIONS" . diff --git a/man/eval-file.1 b/man/eval-file.1 index bfcb674544..b6aecb6c46 100644 --- a/man/eval-file.1 +++ b/man/eval-file.1 @@ -7,7 +7,7 @@ \fBwp\-eval\-file\fR \- Loads and executes a PHP file after loading WordPress\. . .SH "SYNOPSIS" -\fBwp eval\-file\fR \fIpath\fR +wp eval\-file \fIpath\fR . .SH "EXAMPLES" . diff --git a/man/eval.1 b/man/eval.1 index 558bf38e76..190f61c1d0 100644 --- a/man/eval.1 +++ b/man/eval.1 @@ -7,7 +7,7 @@ \fBwp\-eval\fR \- Executes arbitrary PHP code after loading WordPress\. . .SH "SYNOPSIS" -\fBwp eval\fR \fIphp\-code\fR +wp eval \fIphp\-code\fR . .SH "EXAMPLES" . diff --git a/man/export.1 b/man/export.1 index c23fee7abd..1e5e9b4fa3 100644 --- a/man/export.1 +++ b/man/export.1 @@ -7,7 +7,7 @@ \fBwp\-export\fR \- Export posts to a WXR file\. . .SH "SYNOPSIS" -\fBwp export\fR [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post\fI\fIin=\fRpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] +wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post\fI\fIin=\fRpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] . .SH "OPTIONS" . diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 index 489019db5b..a5355ada74 100644 --- a/man/plugin-activate.1 +++ b/man/plugin-activate.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-activate\fR \- Activate a plugin\. . .SH "SYNOPSIS" -\fBwp plugin activate\fR \fIplugin\fR [\-\-network] +wp plugin activate \fIplugin\fR [\-\-network] . .SH "OPTIONS" . diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 index 6b435292cb..332b91a115 100644 --- a/man/plugin-deactivate.1 +++ b/man/plugin-deactivate.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-deactivate\fR \- Deactivate a plugin\. . .SH "SYNOPSIS" -\fBwp plugin deactivate\fR \fIplugin\fR [\-\-network] +wp plugin deactivate \fIplugin\fR [\-\-network] . .SH "OPTIONS" . diff --git a/man/plugin-delete.1 b/man/plugin-delete.1 index 3c77f7e85a..41b1927e0b 100644 --- a/man/plugin-delete.1 +++ b/man/plugin-delete.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-delete\fR \- Delete plugin files\. . .SH "SYNOPSIS" -\fBwp plugin delete\fR \fIplugin\fR +wp plugin delete \fIplugin\fR . .SH "OPTIONS" . diff --git a/man/plugin-install.1 b/man/plugin-install.1 index af58aea058..557ec7db76 100644 --- a/man/plugin-install.1 +++ b/man/plugin-install.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-install\fR \- Install a plugin\. . .SH "SYNOPSIS" -\fBwp plugin install\fR \fIplugin|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] +wp plugin install \fIplugin|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] . .SH "OPTIONS" . diff --git a/man/plugin-path.1 b/man/plugin-path.1 index cadd730d94..7b4b33bb07 100644 --- a/man/plugin-path.1 +++ b/man/plugin-path.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-path\fR \- Get the path to a plugin or to the plugin directory\. . .SH "SYNOPSIS" -\fBwp plugin path\fR [\fIplugin\fR] [\-\-dir] +wp plugin path [\fIplugin\fR] [\-\-dir] . .SH "OPTIONS" . diff --git a/man/plugin-status.1 b/man/plugin-status.1 index cb7f9b00de..797ffa320e 100644 --- a/man/plugin-status.1 +++ b/man/plugin-status.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-status\fR \- See the status of one or all plugins\. . .SH "SYNOPSIS" -\fBwp plugin status\fR [\fIplugin\fR] +wp plugin status [\fIplugin\fR] . .SH "OPTIONS" . diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 index 532fb87bd0..3c8e567c15 100644 --- a/man/plugin-toggle.1 +++ b/man/plugin-toggle.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-toggle\fR \- Toggle a plugin\'s activation state\. . .SH "SYNOPSIS" -\fBwp plugin toggle\fR \fIplugin\fR [\-\-network] +wp plugin toggle \fIplugin\fR [\-\-network] . .SH "OPTIONS" . diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 index b837b52efd..fa2fff4953 100644 --- a/man/plugin-uninstall.1 +++ b/man/plugin-uninstall.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-uninstall\fR \- Uninstall a plugin\. . .SH "SYNOPSIS" -\fBwp plugin uninstall\fR \fIplugin\fR [\-\-no\-delete] +wp plugin uninstall \fIplugin\fR [\-\-no\-delete] . .SH "OPTIONS" . diff --git a/man/plugin-update-all.1 b/man/plugin-update-all.1 index 5198fd1e86..ae85d459a2 100644 --- a/man/plugin-update-all.1 +++ b/man/plugin-update-all.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-update\-all\fR \- Update all plugins\. . .SH "SYNOPSIS" -\fBwp plugin update\-all\fR [\-\-dry\-run] +wp plugin update\-all [\-\-dry\-run] . .SH "OPTIONS" . diff --git a/man/plugin-update.1 b/man/plugin-update.1 index 5f38ffda64..cd26ed8e9c 100644 --- a/man/plugin-update.1 +++ b/man/plugin-update.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-update\fR \- Update a plugin\. . .SH "SYNOPSIS" -\fBwp plugin update\fR \fIplugin\fR [\-\-version=\fIversion\fR] +wp plugin update \fIplugin\fR [\-\-version=\fIversion\fR] . .SH "OPTIONS" . diff --git a/man/post-create.1 b/man/post-create.1 index 76536d6e39..7aa1f5025d 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -7,7 +7,7 @@ \fBwp\-post\-create\fR \- Create a post\. . .SH "SYNOPSIS" -\fBwp post create\fR \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] +wp post create \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/post-delete.1 b/man/post-delete.1 index 45a8fa30a6..e301e77332 100644 --- a/man/post-delete.1 +++ b/man/post-delete.1 @@ -7,7 +7,7 @@ \fBwp\-post\-delete\fR \- Delete a post by ID\. . .SH "SYNOPSIS" -\fBwp post delete\fR \fIid\fR\.\.\. [\-\-force] +wp post delete \fIid\fR\.\.\. [\-\-force] . .SH "OPTIONS" . diff --git a/man/post-generate.1 b/man/post-generate.1 index a5a78c5e7c..9aca68462d 100644 --- a/man/post-generate.1 +++ b/man/post-generate.1 @@ -7,7 +7,7 @@ \fBwp\-post\-generate\fR \- Generate some posts\. . .SH "SYNOPSIS" -\fBwp post generate\fR [\-\-count=100] [\-\-post_type=\fItype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIyyyy\-mm\-dd\fR] [\-\-max_depth=1] +wp post generate [\-\-count=100] [\-\-post_type=\fItype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIyyyy\-mm\-dd\fR] [\-\-max_depth=1] . .SH "OPTIONS" . diff --git a/man/post-list.1 b/man/post-list.1 index c965fc51fc..299c62aaa2 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -7,7 +7,7 @@ \fBwp\-post\-list\fR \- Get a list of posts\. . .SH "SYNOPSIS" -\fBwp post list\fR [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] +wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] . .SH "OPTIONS" . diff --git a/man/post-update.1 b/man/post-update.1 index fc8249fae7..4fd90c4754 100644 --- a/man/post-update.1 +++ b/man/post-update.1 @@ -7,7 +7,7 @@ \fBwp\-post\-update\fR \- Update a post\. . .SH "SYNOPSIS" -\fBwp post update\fR \fIid\fR \-\-\fIfield\fR=\fIvalue\fR +wp post update \fIid\fR \-\-\fIfield\fR=\fIvalue\fR . .SH "OPTIONS" . diff --git a/man/rewrite-dump.1 b/man/rewrite-dump.1 index 80d34e0730..932d8691a1 100644 --- a/man/rewrite-dump.1 +++ b/man/rewrite-dump.1 @@ -7,7 +7,7 @@ \fBwp\-rewrite\-dump\fR \- Print current rewrite rules\. . .SH "SYNOPSIS" -\fBwp rewrite dump\fR [\-\-json] +wp rewrite dump [\-\-json] . .SH "OPTIONS" . diff --git a/man/rewrite-flush.1 b/man/rewrite-flush.1 index db0163863a..622e11e126 100644 --- a/man/rewrite-flush.1 +++ b/man/rewrite-flush.1 @@ -7,7 +7,7 @@ \fBwp\-rewrite\-flush\fR \- Flush rewrite rules\. . .SH "SYNOPSIS" -\fBwp rewrite flush\fR [\-\-soft] +wp rewrite flush [\-\-soft] . .SH "OPTIONS" . diff --git a/man/rewrite-structure.1 b/man/rewrite-structure.1 index 9775f55c36..50272811d0 100644 --- a/man/rewrite-structure.1 +++ b/man/rewrite-structure.1 @@ -7,7 +7,7 @@ \fBwp\-rewrite\-structure\fR \- Update the permalink structure\. . .SH "SYNOPSIS" -\fBwp rewrite structure\fR \fIpermastruct\fR [\-\-category\-base=\fIbase\fR] [\-\-tag\-base=\fIbase\fR] +wp rewrite structure \fIpermastruct\fR [\-\-category\-base=\fIbase\fR] [\-\-tag\-base=\fIbase\fR] . .SH "OPTIONS" . diff --git a/man/theme-activate.1 b/man/theme-activate.1 index b408317f01..52f33f8b4d 100644 --- a/man/theme-activate.1 +++ b/man/theme-activate.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-activate\fR \- Activate a theme\. . .SH "SYNOPSIS" -\fBwp theme activate\fR \fItheme\fR +wp theme activate \fItheme\fR . .SH "OPTIONS" . diff --git a/man/theme-delete.1 b/man/theme-delete.1 index 6d82f601a1..0066624757 100644 --- a/man/theme-delete.1 +++ b/man/theme-delete.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-delete\fR \- Delete a theme\. . .SH "SYNOPSIS" -\fBwp theme delete\fR \fItheme\fR +wp theme delete \fItheme\fR . .SH "OPTIONS" . diff --git a/man/theme-install.1 b/man/theme-install.1 index 2665ed6715..df8a8ef701 100644 --- a/man/theme-install.1 +++ b/man/theme-install.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-install\fR \- Install a theme\. . .SH "SYNOPSIS" -\fBwp theme install\fR \fItheme|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] +wp theme install \fItheme|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] . .SH "OPTIONS" . diff --git a/man/theme-path.1 b/man/theme-path.1 index 2243de192f..b657808c8d 100644 --- a/man/theme-path.1 +++ b/man/theme-path.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-path\fR \- Get the path to a theme or to the theme directory\. . .SH "SYNOPSIS" -\fBwp theme path\fR [\fItheme\fR] [\-\-dir] +wp theme path [\fItheme\fR] [\-\-dir] . .SH "OPTIONS" . diff --git a/man/theme-status.1 b/man/theme-status.1 index 576c274aee..89fb262e69 100644 --- a/man/theme-status.1 +++ b/man/theme-status.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-status\fR \- See the status of one or all themes\. . .SH "SYNOPSIS" -\fBwp theme status\fR [\fItheme\fR] +wp theme status [\fItheme\fR] . .SH "OPTIONS" . diff --git a/man/theme-update-all.1 b/man/theme-update-all.1 index 057f3f4c9c..82f580ff9f 100644 --- a/man/theme-update-all.1 +++ b/man/theme-update-all.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-update\-all\fR \- Update all themes\. . .SH "SYNOPSIS" -\fBwp theme update\-all\fR [\-\-dry\-run] +wp theme update\-all [\-\-dry\-run] . .SH "OPTIONS" . diff --git a/man/theme-update.1 b/man/theme-update.1 index cb5f09b3b9..86fd820bd6 100644 --- a/man/theme-update.1 +++ b/man/theme-update.1 @@ -7,7 +7,7 @@ \fBwp\-theme\-update\fR \- Update a theme\. . .SH "SYNOPSIS" -\fBwp theme update\fR \fItheme\fR [\-\-version=\fIversion\fR] +wp theme update \fItheme\fR [\-\-version=\fIversion\fR] . .SH "OPTIONS" . diff --git a/man/user-create.1 b/man/user-create.1 index dabdae714a..6eadf9ec9c 100644 --- a/man/user-create.1 +++ b/man/user-create.1 @@ -7,7 +7,7 @@ \fBwp\-user\-create\fR \- Create a user\. . .SH "SYNOPSIS" -\fBwp user create\fR \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-user_pass=\fIpassword\fR] [\-\-user_registered=\fIyyyy\-mm\-dd\fR] [\-\-display_name=\fIname\fR] [\-\-porcelain] +wp user create \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-user_pass=\fIpassword\fR] [\-\-user_registered=\fIyyyy\-mm\-dd\fR] [\-\-display_name=\fIname\fR] [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/user-delete.1 b/man/user-delete.1 index b9b44d191e..0666e01475 100644 --- a/man/user-delete.1 +++ b/man/user-delete.1 @@ -7,7 +7,7 @@ \fBwp\-user\-delete\fR \- Delete a user\. . .SH "SYNOPSIS" -\fBwp user delete\fR \fIid\fR [\-\-reassign=\fIid\fR] +wp user delete \fIid\fR [\-\-reassign=\fIid\fR] . .SH "OPTIONS" . diff --git a/man/user-generate.1 b/man/user-generate.1 index 6e6bd54471..2acca79125 100644 --- a/man/user-generate.1 +++ b/man/user-generate.1 @@ -7,7 +7,7 @@ \fBwp\-user\-generate\fR \- Generate users\. . .SH "SYNOPSIS" -\fBwp user generate\fR [\-\-count=100] [\-\-role=\fIrole\fR] +wp user generate [\-\-count=100] [\-\-role=\fIrole\fR] . .SH "OPTIONS" . diff --git a/man/user-import-csv.1 b/man/user-import-csv.1 index 7f8e09d260..0c3d07c7a1 100644 --- a/man/user-import-csv.1 +++ b/man/user-import-csv.1 @@ -7,7 +7,7 @@ \fBwp\-user\-import\-csv\fR \- Import users from a CSV file\. . .SH "SYNOPSIS" -\fBwp user import\-csv\fR \fIfile\fR +wp user import\-csv \fIfile\fR . .SH "OPTIONS" . diff --git a/man/user-list.1 b/man/user-list.1 index 265b308935..2576b9acd5 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -7,7 +7,7 @@ \fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" -\fBwp user list\fR [\-\-role=\fIrole\fR] [\-\-ids] +wp user list [\-\-role=\fIrole\fR] [\-\-ids] . .SH "OPTIONS" . diff --git a/man/user-meta.1 b/man/user-meta.1 index 4a2ab314ee..b304a99f92 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -7,16 +7,16 @@ \fBwp\-user\-meta\fR \- Manage user custom fields\. . .SH "SYNOPSIS" -wp user\-meta get \fIID\fR \fIkey\fR [\-\-json] +wp user\-meta get \fIid\fR \fIkey\fR [\-\-json] . .P -wp user\-meta add \fIID\fR \fIkey\fR \fIvalue\fR +wp user\-meta delete \fIid\fR \fIkey\fR . .P -wp user\-meta update \fIID\fR \fIkey\fR \fIvalue\fR +wp user\-meta add \fIid\fR \fIkey\fR \fIvalue\fR . .P -wp user\-meta delete \fIID\fR \fIkey\fR +wp user\-meta update \fIid\fR \fIkey\fR \fIvalue\fR . .SH "SUBCOMMANDS" . @@ -24,25 +24,34 @@ wp user\-meta delete \fIID\fR \fIkey\fR \fBget\fR: . .IP -Get a custom field value\. Passing \-\-json causes the output to be formatted as JSON\. +Get meta field value\. +. +.TP +\fBdelete\fR: +. +.IP +Delete a meta field\. . .TP \fBadd\fR: . .IP -Add a new custom field\. +Add a meta field\. . .TP \fBupdate\fR: . .IP -Update an existing custom field\. +Update a meta field\. +. +.SH "OPTIONS" + . .TP -\fBdelete\fR: +\fBjson\fR: . .IP -Delete a custom field\. +Encode/decode values as JSON\. . .SH "EXAMPLES" . diff --git a/man/user-remove-role.1 b/man/user-remove-role.1 index ffa374538c..232a68c91c 100644 --- a/man/user-remove-role.1 +++ b/man/user-remove-role.1 @@ -7,7 +7,7 @@ \fBwp\-user\-remove\-role\fR \- Remove a user from a blog\. . .SH "SYNOPSIS" -\fBwp user remove\-role\fR \fIuser\-login\fR +wp user remove\-role \fIuser\-login\fR . .SH "OPTIONS" . diff --git a/man/user-set-role.1 b/man/user-set-role.1 index c4b99a9804..bb8ca46701 100644 --- a/man/user-set-role.1 +++ b/man/user-set-role.1 @@ -7,7 +7,7 @@ \fBwp\-user\-set\-role\fR \- Add a user to a blog\. . .SH "SYNOPSIS" -\fBwp user set\-role\fR \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] +wp user set\-role \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] . .SH "OPTIONS" . diff --git a/man/user-update.1 b/man/user-update.1 index 1e0a7ebc0b..4750f707ef 100644 --- a/man/user-update.1 +++ b/man/user-update.1 @@ -7,7 +7,7 @@ \fBwp\-user\-update\fR \- Update a user\. . .SH "SYNOPSIS" -\fBwp user update\fR \fIid\fR \-\-\fIfield\fR=\fIvalue\fR +wp user update \fIid\fR \-\-\fIfield\fR=\fIvalue\fR . .SH "OPTIONS" . From 2ae2356ed0797cc2f3f5545faa65bd952db74f49 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 17:51:42 +0200 Subject: [PATCH 0895/4858] add --str flag to most `db` subcommands --- src/php/wp-cli/commands/internals/db.php | 80 +++++++++++++----------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index f616494800..778eb85908 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -12,9 +12,11 @@ class DB_Command extends WP_CLI_Command { /** * Create the database, as specified in wp-config.php + * + * @synopsis [--str] */ - function create() { - WP_CLI::launch( self::create_cmd( + function create( $_, $assoc_args ) { + self::run( $assoc_args, self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME ) ); @@ -25,12 +27,12 @@ function create() { /** * Delete the database. * - * @synopsis [--yes] + * @synopsis [--yes] [--str] */ - function drop( $args, $assoc_args ) { + function drop( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); - WP_CLI::launch( self::create_cmd( + self::run( $assoc_args, self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE ' . DB_NAME ) ); @@ -43,7 +45,7 @@ function drop( $args, $assoc_args ) { * * @synopsis [--yes] */ - function reset( $args, $assoc_args ) { + function reset( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); WP_CLI::launch( self::create_cmd( @@ -61,9 +63,11 @@ function reset( $args, $assoc_args ) { /** * Optimize the database. + * + * @synopsis [--str] */ - function optimize() { - WP_CLI::launch( self::create_cmd( + function optimize( $_, $assoc_args ) { + self::run( $assoc_args, self::create_cmd( 'mysqlcheck --optimize --host=%s --user=%s --password=%s %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -73,9 +77,11 @@ function optimize() { /** * Repair the database. + * + * @synopsis [--str] */ - function repair() { - WP_CLI::launch( self::create_cmd( + function repair( $_, $assoc_args ) { + self::run( $assoc_args, self::create_cmd( 'mysqlcheck --repair --host=%s --user=%s --password=%s %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -83,49 +89,41 @@ function repair() { WP_CLI::success( "Database repaired." ); } - /** - * Print a string for connecting to the DB. - * - * @subcommand connect-str - * @subcommand connect - */ - function connect() { - WP_CLI::line( $this->connect_string() ); - } - /** * Open a mysql console using the WordPress credentials. + * + * @alias cli + * + * @synopsis [--str] */ - function cli() { - WP_CLI::launch( $this->connect_string() ); + function connect( $_, $assoc_args ) { + self::run( $assoc_args, $this->connect_string() ); } /** * Execute a query against the database. * - * @synopsis <sql> + * @synopsis <sql> [--str] */ function query( $args, $assoc_args ) { - $query = $args[0]; - - $command = $this->connect_string() . self::create_cmd( ' --execute=%s', $query ); + list( $query ) = $args; - WP_CLI::launch( $command ); + self::run( $assoc_args, $this->connect_string() . self::create_cmd( + ' --execute=%s', $query ) ); } /** * Exports the database using mysqldump. * * @alias dump - * @synopsis [<file>] + * @synopsis [<file>] [--str] */ function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $command = self::create_cmd( 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', - DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - - WP_CLI::launch( $command ); + self::run( $assoc_args, self::create_cmd( + 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', + DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } @@ -133,16 +131,14 @@ function export( $args, $assoc_args ) { /** * Import database from a file. * - * @synopsis [<file>] + * @synopsis [<file>] [--str] */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $command = self::create_cmd( + self::run( $assoc_args, self::create_cmd( 'mysql %s --user=%s --password=%s --host=%s < %s', - DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ); - - WP_CLI::launch( $command ); + DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } @@ -170,4 +166,14 @@ private static function create_cmd( $cmd ) { return vsprintf( $cmd, array_map( 'escapeshellarg', $args ) ); } + + private static function run( $assoc_args, $cmd ) { + if ( isset( $assoc_args['str'] ) ) { + WP_CLI::line( $cmd ); + exit; + } + + WP_CLI::launch( $cmd ); + } } + From 9b147f085407ed13ad094f1450c2e4bde1aa1bcd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 17:59:53 +0200 Subject: [PATCH 0896/4858] db drop: skip confirmation if --str is set --- src/php/wp-cli/commands/internals/db.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 778eb85908..28349178a1 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -30,14 +30,18 @@ function create( $_, $assoc_args ) { * @synopsis [--yes] [--str] */ function drop( $_, $assoc_args ) { - WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); - - self::run( $assoc_args, self::create_cmd( + $command = self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE ' . DB_NAME - ) ); - - WP_CLI::success( "Database dropped." ); + ); + + if ( !isset( $assoc_args['str'] ) ) { + WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); + WP_CLI::launch( $command ); + WP_CLI::success( "Database dropped." ); + } else { + WP_CLI::line( $command ); + } } /** From 2a49bbe056f17ca9a7829205e0678f24617a5944 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 18:02:04 +0200 Subject: [PATCH 0897/4858] db reset: add --str flag --- src/php/wp-cli/commands/internals/db.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/internals/db.php index 28349178a1..e9bccf921c 100644 --- a/src/php/wp-cli/commands/internals/db.php +++ b/src/php/wp-cli/commands/internals/db.php @@ -47,22 +47,28 @@ function drop( $_, $assoc_args ) { /** * Remove all tables from the database. * - * @synopsis [--yes] + * @synopsis [--yes] [--str] */ function reset( $_, $assoc_args ) { - WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); - - WP_CLI::launch( self::create_cmd( + $drop_cmd = self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE IF EXISTS ' . DB_NAME - ) ); + ); - WP_CLI::launch( self::create_cmd( + $create_cmd = self::create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME - ) ); + ); - WP_CLI::success( "Database reset." ); + if ( !isset( $assoc_args['str'] ) ) { + WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); + WP_CLI::launch( $drop_cmd ); + WP_CLI::launch( $create_cmd ); + WP_CLI::success( "Database reset." ); + } else { + WP_CLI::line( $drop_cmd ); + WP_CLI::line( $create_cmd ); + } } /** From 84c92bf3970c2211b870515a2f776a2f0a5d1db2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:36:44 +0200 Subject: [PATCH 0898/4858] unify db man pages --- man/db.1 | 112 +++++++++++++++++++++++++++++ src/docs/db-drop.txt | 5 -- src/docs/db-import.txt | 5 -- src/docs/db-query.txt | 5 -- src/docs/db-reset.txt | 5 -- src/docs/{db-export.txt => db.txt} | 8 +++ 6 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 man/db.1 delete mode 100644 src/docs/db-drop.txt delete mode 100644 src/docs/db-import.txt delete mode 100644 src/docs/db-query.txt delete mode 100644 src/docs/db-reset.txt rename src/docs/{db-export.txt => db.txt} (53%) diff --git a/man/db.1 b/man/db.1 new file mode 100644 index 0000000000..19b758990c --- /dev/null +++ b/man/db.1 @@ -0,0 +1,112 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-DB" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-db\fR \- Implement db command +. +.SH "SYNOPSIS" +wp db create [\-\-str] +. +.P +wp db drop [\-\-yes] [\-\-str] +. +.P +wp db reset [\-\-yes] [\-\-str] +. +.P +wp db optimize [\-\-str] +. +.P +wp db repair [\-\-str] +. +.P +wp db connect [\-\-str] +. +.P +wp db query \fIsql\fR [\-\-str] +. +.P +wp db export [\fIfile\fR] [\-\-str] +. +.P +wp db import [\fIfile\fR] [\-\-str] +. +.SH "SUBCOMMANDS" +. +.TP +\fBcreate\fR: +. +.IP +Create the database, as specified in wp\-config\.php +. +.TP +\fBdrop\fR: +. +.IP +Delete the database\. +. +.TP +\fBreset\fR: +. +.IP +Remove all tables from the database\. +. +.TP +\fBoptimize\fR: +. +.IP +Optimize the database\. +. +.TP +\fBrepair\fR: +. +.IP +Repair the database\. +. +.TP +\fBconnect\fR: +. +.IP +Open a mysql console using the WordPress credentials\. +. +.TP +\fBquery\fR: +. +.IP +Execute a query against the database\. +. +.TP +\fBexport\fR: +. +.IP +Exports the database using mysqldump\. +. +.TP +\fBimport\fR: +. +.IP +Import database from a file\. +. +.SH "OPTIONS" + +. +.TP +\fB\-\-yes\fR: +. +.IP +Answer yes to the confirmation message\. +. +.TP +\fB<file>\fR: +. +.IP +The name of the export file\. If omitted, it will be \'{dbname}\.sql\' +. +.TP +\fB<SQL>\fR: +. +.IP +A SQL query\. + diff --git a/src/docs/db-drop.txt b/src/docs/db-drop.txt deleted file mode 100644 index f626d62dd6..0000000000 --- a/src/docs/db-drop.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `--yes`: - - Answer yes to the confirmation message. diff --git a/src/docs/db-import.txt b/src/docs/db-import.txt deleted file mode 100644 index 5770c0b1c9..0000000000 --- a/src/docs/db-import.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `<file>`: - - The name of the import file. If omitted, it will be '{dbname}.sql' diff --git a/src/docs/db-query.txt b/src/docs/db-query.txt deleted file mode 100644 index 7d44ae6757..0000000000 --- a/src/docs/db-query.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `<SQL>`: - - A SQL query. diff --git a/src/docs/db-reset.txt b/src/docs/db-reset.txt deleted file mode 100644 index f626d62dd6..0000000000 --- a/src/docs/db-reset.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `--yes`: - - Answer yes to the confirmation message. diff --git a/src/docs/db-export.txt b/src/docs/db.txt similarity index 53% rename from src/docs/db-export.txt rename to src/docs/db.txt index cce48dc75e..e60509350b 100644 --- a/src/docs/db-export.txt +++ b/src/docs/db.txt @@ -1,5 +1,13 @@ ## OPTIONS +* `--yes`: + + Answer yes to the confirmation message. + * `<file>`: The name of the export file. If omitted, it will be '{dbname}.sql' + +* `<SQL>`: + + A SQL query. From 0e209078a2d04b3f0076d0fd3129fa68c6d33937 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Dec 2012 19:47:53 +0200 Subject: [PATCH 0899/4858] db docs: document --str option --- man/db.1 | 6 ++++++ src/docs/db.txt | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/man/db.1 b/man/db.1 index 19b758990c..7c16d0827c 100644 --- a/man/db.1 +++ b/man/db.1 @@ -91,6 +91,12 @@ Import database from a file\. . .SH "OPTIONS" +. +.TP +\fB\-\-str\fR: +. +.IP +Show the mysql command, instead of executing it\. . .TP \fB\-\-yes\fR: diff --git a/src/docs/db.txt b/src/docs/db.txt index e60509350b..f160ad01a3 100644 --- a/src/docs/db.txt +++ b/src/docs/db.txt @@ -1,5 +1,9 @@ ## OPTIONS +* `--str`: + + Show the mysql command, instead of executing it. + * `--yes`: Answer yes to the confirmation message. From dec733ce8044b03b97640957c1fe23ee90ec04a0 Mon Sep 17 00:00:00 2001 From: Miles Johnson <mileswjohnson@gmail.com> Date: Fri, 7 Dec 2012 16:33:35 -0800 Subject: [PATCH 0900/4858] Add more server vars --- src/php/wp-cli/utils.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index f6d4045573..4e6432f827 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -107,6 +107,9 @@ function set_url_params( $url ) { $_SERVER['REQUEST_URL'] = $f('path'); $_SERVER['QUERY_STRING'] = $f('query'); $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); + $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; + $_SERVER['HTTP_USER_AGENT'] = ''; + $_SERVER['REQUEST_METHOD'] = 'GET'; } function locate_wp_config() { From b75fcbadb092573284108fb7810e688ab9cda92e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Dec 2012 21:18:14 +0200 Subject: [PATCH 0901/4858] theme upgrader expects the theme name, while the plugin upgrader expects the basename. see #237 --- src/php/wp-cli/class-wp-cli-command-with-upgrade.php | 6 ++---- src/php/wp-cli/commands/internals/plugin.php | 4 +++- src/php/wp-cli/commands/internals/theme.php | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php index 13c7d1105b..b84bcb7e1d 100644 --- a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php +++ b/src/php/wp-cli/class-wp-cli-command-with-upgrade.php @@ -119,12 +119,10 @@ function install( $args, $assoc_args ) { } } - function update( $args, $assoc_args ) { + protected function _update( $item ) { call_user_func( $this->upgrade_refresh ); - list( $file, $name ) = $this->parse_name( $args ); - - WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $file ); + WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $item ); } function update_all( $args, $assoc_args ) { diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index d6f6d98409..4a474d5df1 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -191,7 +191,9 @@ function update( $args, $assoc_args ) { $this->delete( $args, array(), false ); $this->install( $args, $assoc_args ); } else { - parent::update( $args, $assoc_args ); + list( $basename ) = $this->parse_name( $args ); + + parent::_update( $basename ); } } diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/internals/theme.php index d028937f8e..5f64beb662 100644 --- a/src/php/wp-cli/commands/internals/theme.php +++ b/src/php/wp-cli/commands/internals/theme.php @@ -171,7 +171,9 @@ function install( $args, $assoc_args ) { * @synopsis <theme> [--version=<version>] */ function update( $args, $assoc_args ) { - parent::update( $args, $assoc_args ); + list( $_, $name ) = $this->parse_name( $args ); + + parent::_update( $name ); } /** From c6d5ef84c0b00aac9c522e1cc3444054699a4450 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Dec 2012 21:24:10 +0200 Subject: [PATCH 0902/4858] don't try to use WP_Error object as array key --- src/php/wp-cli/class-cli-upgrader-skin.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/src/php/wp-cli/class-cli-upgrader-skin.php index 580ab02d12..0b9871a904 100644 --- a/src/php/wp-cli/class-cli-upgrader-skin.php +++ b/src/php/wp-cli/class-cli-upgrader-skin.php @@ -16,13 +16,11 @@ function error( $error ) { if ( !$error ) return; - if ( isset( $this->upgrader->strings[$error] ) ) - $string = $this->upgrader->strings[$error]; - else - $string = $error; + if ( is_string( $error ) && isset( $this->upgrader->strings[ $error ] ) ) + $error = $this->upgrader->strings[ $error ]; // TODO: show all errors, not just the first one - WP_CLI::warning( $string ); + WP_CLI::warning( $error ); } function feedback( $string ) { From 54ad66e046f6755f55692072ab64aa8cff34ee39 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Dec 2012 21:35:44 +0200 Subject: [PATCH 0903/4858] silently convert {plugin|theme} update --all to {plugin|theme} update-all. closes #237 --- src/php/wp-cli/class-wp-cli.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index e92960893e..94b8024fda 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -198,11 +198,21 @@ private static function parse_args() { list( self::$arguments, self::$assoc_args ) = $r; + // foo --help -> help foo if ( isset( self::$assoc_args['help'] ) ) { array_unshift( self::$arguments, 'help' ); unset( self::$assoc_args['help'] ); } + // {plugin|theme} update --all -> {plugin|theme} update-all + if ( in_array( self::$arguments[0], array( 'plugin', 'theme' ) ) + && self::$arguments[1] == 'update' + && isset( self::$assoc_args['all'] ) + ) { + self::$arguments[1] = 'update-all'; + unset( self::$assoc_args['all'] ); + } + self::$assoc_special = Utils\split_assoc( self::$assoc_args, array( 'path', 'url', 'blog', 'user', 'require', 'quiet', 'completions', 'man', 'syn-list' From 2a24cdf23c845b595c224c7c30f469291df579da Mon Sep 17 00:00:00 2001 From: Eric Mann <eric@eamann.com> Date: Tue, 11 Dec 2012 16:02:16 -0800 Subject: [PATCH 0904/4858] Fix Undefined Offset Message. If no arguments are passed aside from a -- flag (i.e. `wp --version`), the new plugin/theme logic triggers an undefined offset notice. This patch checks first that the arguments array has elements before trying to read them. see #237. closes #238 --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 94b8024fda..560c46f63d 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -205,7 +205,7 @@ private static function parse_args() { } // {plugin|theme} update --all -> {plugin|theme} update-all - if ( in_array( self::$arguments[0], array( 'plugin', 'theme' ) ) + if ( count( self::$arguments ) > 1 && in_array( self::$arguments[0], array( 'plugin', 'theme' ) ) && self::$arguments[1] == 'update' && isset( self::$assoc_args['all'] ) ) { From 0c3b62f4dc5fe2f5b4bfcc0360c11f652a142e1c Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 10:30:31 +0000 Subject: [PATCH 0905/4858] Add dev dependency on phpunit --- .gitignore | 2 ++ composer.json | 5 +++++ 2 files changed, 7 insertions(+) create mode 100644 composer.json diff --git a/.gitignore b/.gitignore index d9cdde38e6..851cd11405 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /.build /dist +/vendor +/composer.lock diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000..90f5a3d050 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "phpunit/phpunit": "3.7.x" + } +} From e3e922fc49ab6ed22286a978cc16136ec546c4bb Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 10:30:48 +0000 Subject: [PATCH 0906/4858] Add test for wp core is-installed when WordPress is not installed --- tests/core-Test.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/core-Test.php diff --git a/tests/core-Test.php b/tests/core-Test.php new file mode 100644 index 0000000000..66e1ae6ad9 --- /dev/null +++ b/tests/core-Test.php @@ -0,0 +1,34 @@ +<?php +class CoreTest extends PHPUnit_Framework_TestCase { + public function testIsInstalledExitsWith1IfWordPressNotInstalled() { + $temp_dir = self::create_temporary_directory(); + $result = self::run_wp_cli("core is-installed --path=$temp_dir"); + $this->assertEquals(1, $result->return_code); + } + + private static function create_temporary_directory() { + return sys_get_temp_dir() . '/' . uniqid("wp-cli-test-", TRUE); + } + + private static function run_wp_cli( $wp_cli_command ) { + $wp_cli_path = self::find_wp_cli(); + return self::run_command("$wp_cli_path $wp_cli_command"); + } + + private static function find_wp_cli() { + return "src/bin/wp"; + } + + private static function run_command( $command ) { + $output = array(); + $return_code = 0; + exec( $command, $output, $return_code ); + return new ExecutionResult( $return_code ); + } +} + +class ExecutionResult { + public function __construct( $return_code ) { + $this->return_code = $return_code; + } +} From d5d95f216c3a84a9fdded6fbee2a5e47ad39ccaa Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:29:11 +0000 Subject: [PATCH 0907/4858] Add tests for installing WordPress --- tests/core-Test.php | 76 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/tests/core-Test.php b/tests/core-Test.php index 66e1ae6ad9..bc874c4ce8 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -1,34 +1,90 @@ <?php class CoreTest extends PHPUnit_Framework_TestCase { + + public function testIsInstalledExitsWith1IfWordPressNotInstalled() { $temp_dir = self::create_temporary_directory(); - $result = self::run_wp_cli("core is-installed --path=$temp_dir"); + $command_runner = new CommandRunner( $temp_dir ); + $result = $command_runner->run_wp_cli("core is-installed"); $this->assertEquals(1, $result->return_code); } + public function testIsInstalledExitsWith0AfterRunningInstallCommand() { + $command_runner = $this->install_wp_cli(); + $result = $command_runner->run_wp_cli("core is-installed"); + $this->assertEquals(0, $result->return_code); + } + + public function testInstallCommandCreatesDefaultBlogPost() { + $command_runner = $this->install_wp_cli(); + $result = $command_runner->run_wp_cli( "post list --ids" ); + $this->assertEquals( "1", $result->output ); + } + + private function install_wp_cli() { + $temp_dir = self::create_temporary_directory(); + $command_runner = new CommandRunner( $temp_dir ); + self::download_wordpress_files( $temp_dir ); + $dbname = "wp_cli_test"; + $dbuser = "wp_cli_test"; + $dbpass = "password1"; + exec( "mysql -u$dbname -p$dbpass -e 'DROP DATABASE $dbname'" ); + exec( "mysql -u$dbname -p$dbpass -e 'CREATE DATABASE $dbname'" ); + $command_runner->run_wp_cli( "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); + $command_runner->run_wp_cli( + "core install --url=http://example.com/ --title=WordPress " . + " --admin_email=admin@example.com --admin_password=password1" + ); + return $command_runner; + } + + private static function download_wordpress_files( $target_dir ) { + // We cache the results of "wp core download" to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + if ( !file_exists( $cache_dir ) ) { + mkdir($cache_dir); + $command_runner = new CommandRunner( $cache_dir ); + $command_runner->run_wp_cli( "core download" ); + } + exec( "cp -r '$cache_dir/'* '$target_dir/'" ); + } + private static function create_temporary_directory() { - return sys_get_temp_dir() . '/' . uniqid("wp-cli-test-", TRUE); + $dir = sys_get_temp_dir() . '/' . uniqid("wp-cli-test-", TRUE); + mkdir($dir); + return $dir; + } +} + +class CommandRunner { + private $cwd; + + public function __construct( $cwd ) { + $this->cwd = $cwd; } - private static function run_wp_cli( $wp_cli_command ) { + public function run_wp_cli( $wp_cli_command ) { $wp_cli_path = self::find_wp_cli(); - return self::run_command("$wp_cli_path $wp_cli_command"); + return self::run_command( "$wp_cli_path $wp_cli_command" ); } - private static function find_wp_cli() { - return "src/bin/wp"; + private function find_wp_cli() { + return getcwd() . "/src/bin/wp"; } - private static function run_command( $command ) { + private function run_command( $command ) { $output = array(); $return_code = 0; - exec( $command, $output, $return_code ); - return new ExecutionResult( $return_code ); + $cwd = $this->cwd; + exec( "sh -c 'cd $cwd; $command'", $output, $return_code ); + return new ExecutionResult( $return_code, implode( "\n", $output ) ); } } class ExecutionResult { - public function __construct( $return_code ) { + public function __construct( $return_code, $output ) { $this->return_code = $return_code; + $this->output = $output; } } From 3c43036af660ae03acf1b34d394c4eeafa62effe Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:31:51 +0000 Subject: [PATCH 0908/4858] Split command runner class into a separate file --- tests/class-command-runner.php | 33 ++++++++++++++++++++++++++++ tests/core-Test.php | 39 ++++------------------------------ 2 files changed, 37 insertions(+), 35 deletions(-) create mode 100644 tests/class-command-runner.php diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php new file mode 100644 index 0000000000..e4af390303 --- /dev/null +++ b/tests/class-command-runner.php @@ -0,0 +1,33 @@ +<?php + +class Command_Runner { + private $cwd; + + public function __construct( $cwd ) { + $this->cwd = $cwd; + } + + public function run_wp_cli( $wp_cli_command ) { + $wp_cli_path = self::find_wp_cli(); + return self::run_command( "$wp_cli_path $wp_cli_command" ); + } + + private function find_wp_cli() { + return getcwd() . "/src/bin/wp"; + } + + private function run_command( $command ) { + $output = array(); + $return_code = 0; + $cwd = $this->cwd; + exec( "sh -c 'cd $cwd; $command'", $output, $return_code ); + return new Execution_Result( $return_code, implode( "\n", $output ) ); + } +} + +class Execution_Result { + public function __construct( $return_code, $output ) { + $this->return_code = $return_code; + $this->output = $output; + } +} diff --git a/tests/core-Test.php b/tests/core-Test.php index bc874c4ce8..94b1a9e263 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -1,7 +1,8 @@ <?php + +require __DIR__ . '/class-command-runner.php'; + class CoreTest extends PHPUnit_Framework_TestCase { - - public function testIsInstalledExitsWith1IfWordPressNotInstalled() { $temp_dir = self::create_temporary_directory(); $command_runner = new CommandRunner( $temp_dir ); @@ -23,7 +24,7 @@ public function testInstallCommandCreatesDefaultBlogPost() { private function install_wp_cli() { $temp_dir = self::create_temporary_directory(); - $command_runner = new CommandRunner( $temp_dir ); + $command_runner = new Command_Runner( $temp_dir ); self::download_wordpress_files( $temp_dir ); $dbname = "wp_cli_test"; $dbuser = "wp_cli_test"; @@ -56,35 +57,3 @@ private static function create_temporary_directory() { return $dir; } } - -class CommandRunner { - private $cwd; - - public function __construct( $cwd ) { - $this->cwd = $cwd; - } - - public function run_wp_cli( $wp_cli_command ) { - $wp_cli_path = self::find_wp_cli(); - return self::run_command( "$wp_cli_path $wp_cli_command" ); - } - - private function find_wp_cli() { - return getcwd() . "/src/bin/wp"; - } - - private function run_command( $command ) { - $output = array(); - $return_code = 0; - $cwd = $this->cwd; - exec( "sh -c 'cd $cwd; $command'", $output, $return_code ); - return new ExecutionResult( $return_code, implode( "\n", $output ) ); - } -} - -class ExecutionResult { - public function __construct( $return_code, $output ) { - $this->return_code = $return_code; - $this->output = $output; - } -} From 431127a4f10045ea86c330aa4103a66c2f02f862 Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:37:30 +0000 Subject: [PATCH 0909/4858] Add instructions for running tests to README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 1095531af7..3121780200 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,24 @@ Need even more info? Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. + +Running tests +------------- + +The tests use PHPUnit, which can be installed using [composer](http://getcomposer.org/). +Once you've composer installed, run: + + composer.phar install --dev + +Before running the tests, you'll need a MySQL user called wp_cli_test with the password password1 that +has full privileges on the MySQL database wp_cli_test. Running the following +as root in MySQL should do the trick: + + GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" + IDENTIFIED BY "password1"; + +Finally, to run the tests: + + vendor/bin/phpunit tests + + From b9339bdc2bc2a0bd32ec64bfeb8cdf3b5d6163dd Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:38:19 +0000 Subject: [PATCH 0910/4858] Add missing word to test instructions in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3121780200..4ef7a34ea9 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Running tests ------------- The tests use PHPUnit, which can be installed using [composer](http://getcomposer.org/). -Once you've composer installed, run: +Once you've got composer installed, run: composer.phar install --dev From 9296c4d57d98b423a02e415ca024796614d9ad10 Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:39:05 +0000 Subject: [PATCH 0911/4858] Clarify README.md by marking database name/username/password using backticks --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4ef7a34ea9..4f30b007b4 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ Once you've got composer installed, run: composer.phar install --dev -Before running the tests, you'll need a MySQL user called wp_cli_test with the password password1 that -has full privileges on the MySQL database wp_cli_test. Running the following -as root in MySQL should do the trick: +Before running the tests, you'll need a MySQL user called `wp_cli_test` with the +password `password1` that has full privileges on the MySQL database `wp_cli_test`. +Running the following as root in MySQL should do the trick: GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; From 759bf9b0aab8a0e95fef3ebee7b33cd2fe1074bd Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:40:54 +0000 Subject: [PATCH 0912/4858] Add spaces around function arguments --- tests/core-Test.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core-Test.php b/tests/core-Test.php index 94b1a9e263..7a71ef12d3 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -6,13 +6,13 @@ class CoreTest extends PHPUnit_Framework_TestCase { public function testIsInstalledExitsWith1IfWordPressNotInstalled() { $temp_dir = self::create_temporary_directory(); $command_runner = new CommandRunner( $temp_dir ); - $result = $command_runner->run_wp_cli("core is-installed"); + $result = $command_runner->run_wp_cli( "core is-installed" ); $this->assertEquals(1, $result->return_code); } public function testIsInstalledExitsWith0AfterRunningInstallCommand() { $command_runner = $this->install_wp_cli(); - $result = $command_runner->run_wp_cli("core is-installed"); + $result = $command_runner->run_wp_cli( "core is-installed" ); $this->assertEquals(0, $result->return_code); } @@ -44,7 +44,7 @@ private static function download_wordpress_files( $target_dir ) { // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; if ( !file_exists( $cache_dir ) ) { - mkdir($cache_dir); + mkdir( $cache_dir ); $command_runner = new CommandRunner( $cache_dir ); $command_runner->run_wp_cli( "core download" ); } @@ -52,8 +52,8 @@ private static function download_wordpress_files( $target_dir ) { } private static function create_temporary_directory() { - $dir = sys_get_temp_dir() . '/' . uniqid("wp-cli-test-", TRUE); - mkdir($dir); + $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $dir ); return $dir; } } From 89873085450fc3b3aebfb874c540a12f65ac1d11 Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:41:44 +0000 Subject: [PATCH 0913/4858] Fix test due to rename of class --- tests/core-Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core-Test.php b/tests/core-Test.php index 7a71ef12d3..79de8a0d7d 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -5,7 +5,7 @@ class CoreTest extends PHPUnit_Framework_TestCase { public function testIsInstalledExitsWith1IfWordPressNotInstalled() { $temp_dir = self::create_temporary_directory(); - $command_runner = new CommandRunner( $temp_dir ); + $command_runner = new Command_Runner( $temp_dir ); $result = $command_runner->run_wp_cli( "core is-installed" ); $this->assertEquals(1, $result->return_code); } From e40b85574ac763093abf017fa02d421ce318d9f4 Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:43:20 +0000 Subject: [PATCH 0914/4858] Rename tests to use underscores instead of lowerCamelCase --- tests/core-Test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core-Test.php b/tests/core-Test.php index 79de8a0d7d..c605c112ec 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -3,20 +3,20 @@ require __DIR__ . '/class-command-runner.php'; class CoreTest extends PHPUnit_Framework_TestCase { - public function testIsInstalledExitsWith1IfWordPressNotInstalled() { + public function test_is_installed_exits_with_1_if_wordpress_not_installed() { $temp_dir = self::create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); $result = $command_runner->run_wp_cli( "core is-installed" ); $this->assertEquals(1, $result->return_code); } - public function testIsInstalledExitsWith0AfterRunningInstallCommand() { + public function test_is_installed_exits_with_0_after_running_install_command() { $command_runner = $this->install_wp_cli(); $result = $command_runner->run_wp_cli( "core is-installed" ); $this->assertEquals(0, $result->return_code); } - public function testInstallCommandCreatesDefaultBlogPost() { + public function test_install_command_creates_default_blog_post() { $command_runner = $this->install_wp_cli(); $result = $command_runner->run_wp_cli( "post list --ids" ); $this->assertEquals( "1", $result->output ); From 64fa735b026106dbbd1c274e2d88bb5dc3b1761a Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:45:13 +0000 Subject: [PATCH 0915/4858] Add documentation for running specific test --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4f30b007b4..22cda5bf85 100644 --- a/README.md +++ b/README.md @@ -43,4 +43,7 @@ Finally, to run the tests: vendor/bin/phpunit tests +Each test installs WordPress from scratch. Since this is pretty slow, you can +use arguments to `phpunit` to only run the test that you're interested in: + vendor/bin/phpunit --filter test_function_you_want_to_run tests From 912703a777df8d426d70331824fd23ba1f2fef5a Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 11:46:34 +0000 Subject: [PATCH 0916/4858] Correct documentation -- most, but not all, tests install WordPress --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22cda5bf85..c6d3179f16 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Finally, to run the tests: vendor/bin/phpunit tests -Each test installs WordPress from scratch. Since this is pretty slow, you can +Most tests install WordPress from scratch. Since this is pretty slow, you can use arguments to `phpunit` to only run the test that you're interested in: vendor/bin/phpunit --filter test_function_you_want_to_run tests From 1ea7c5f6f1e50a919078d69e6c23bab3bded5d6c Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 12:25:18 +0000 Subject: [PATCH 0917/4858] Display error in "wp core install" when wp-config.php is missing --- src/php/wp-cli/class-wp-cli.php | 5 +++++ tests/class-command-runner.php | 16 +++++++++++++--- tests/core-Test.php | 14 +++++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 560c46f63d..b07c1a899c 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -277,6 +277,11 @@ static function before_wp_load() { // Set installer flag before loading any WP files if ( array( 'core', 'install' ) == self::$arguments ) { define( 'WP_INSTALLING', true ); + + if ( !file_exists( WP_ROOT . '/wp-config.php' ) ) { + WP_CLI::error( "wp-config.php not found\n" . + "Either create one manually or use wp core config" ); + } } // Pretend we're in WP_ADMIN, to side-step full-page caching plugins diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php index e4af390303..f39b360075 100644 --- a/tests/class-command-runner.php +++ b/tests/class-command-runner.php @@ -17,11 +17,21 @@ private function find_wp_cli() { } private function run_command( $command ) { - $output = array(); + $output_dummy = array(); + $output_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); + $output_binary_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); $return_code = 0; $cwd = $this->cwd; - exec( "sh -c 'cd $cwd; $command'", $output, $return_code ); - return new Execution_Result( $return_code, implode( "\n", $output ) ); + $sh_command = "cd $cwd;" . + "$command > $output_binary_file 2>&1;" . + 'RETURN_CODE=$?;' . + "cat -v $output_binary_file > $output_file;" . + 'exit $RETURN_CODE'; + exec("sh -c '$sh_command'", $output_dummy, $return_code ); + $output = file_get_contents( $output_file); + unlink( $output_file ); + unlink( $output_binary_file ); + return new Execution_Result( $return_code, $output ); } } diff --git a/tests/core-Test.php b/tests/core-Test.php index c605c112ec..816e4d9b02 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -22,6 +22,18 @@ public function test_install_command_creates_default_blog_post() { $this->assertEquals( "1", $result->output ); } + public function test_message_explains_that_config_must_be_present_before_install() { + $temp_dir = self::create_temporary_directory(); + $command_runner = new Command_Runner( $temp_dir ); + self::download_wordpress_files( $temp_dir ); + $result = $command_runner->run_wp_cli( "core install" ); + $this->assertEquals( + "^[[31;1mError: ^[[0mwp-config.php not found\n" . + "Either create one manually or use wp core config\n", + $result->output + ); + } + private function install_wp_cli() { $temp_dir = self::create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); @@ -45,7 +57,7 @@ private static function download_wordpress_files( $target_dir ) { $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; if ( !file_exists( $cache_dir ) ) { mkdir( $cache_dir ); - $command_runner = new CommandRunner( $cache_dir ); + $command_runner = new Command_Runner( $cache_dir ); $command_runner->run_wp_cli( "core download" ); } exec( "cp -r '$cache_dir/'* '$target_dir/'" ); From f7df0541588e3da3ff9829feb00eaef37a82ed64 Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 12:34:52 +0000 Subject: [PATCH 0918/4858] Move general testing functionality into base class --- tests/class-wp-cli-test-case.php | 40 +++++++++++++++++++++++++++ tests/core-Test.php | 46 +++++--------------------------- 2 files changed, 46 insertions(+), 40 deletions(-) create mode 100644 tests/class-wp-cli-test-case.php diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php new file mode 100644 index 0000000000..be7e998412 --- /dev/null +++ b/tests/class-wp-cli-test-case.php @@ -0,0 +1,40 @@ +<?php + +require_once __DIR__ . '/class-command-runner.php'; + +abstract class Wp_Cli_Test_Case extends PHPUnit_Framework_TestCase { + public function install_wp_cli() { + $temp_dir = $this->create_temporary_directory(); + $command_runner = new Command_Runner( $temp_dir ); + $this->download_wordpress_files( $temp_dir ); + $dbname = "wp_cli_test"; + $dbuser = "wp_cli_test"; + $dbpass = "password1"; + exec( "mysql -u$dbname -p$dbpass -e 'DROP DATABASE $dbname'" ); + exec( "mysql -u$dbname -p$dbpass -e 'CREATE DATABASE $dbname'" ); + $command_runner->run_wp_cli( "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); + $command_runner->run_wp_cli( + "core install --url=http://example.com/ --title=WordPress " . + " --admin_email=admin@example.com --admin_password=password1" + ); + return $command_runner; + } + + public function download_wordpress_files( $target_dir ) { + // We cache the results of "wp core download" to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + if ( !file_exists( $cache_dir ) ) { + mkdir( $cache_dir ); + $command_runner = new Command_Runner( $cache_dir ); + $command_runner->run_wp_cli( "core download" ); + } + exec( "cp -r '$cache_dir/'* '$target_dir/'" ); + } + + public function create_temporary_directory() { + $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $dir ); + return $dir; + } +} diff --git a/tests/core-Test.php b/tests/core-Test.php index 816e4d9b02..3c79f97609 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -1,10 +1,11 @@ <?php -require __DIR__ . '/class-command-runner.php'; +require_once __DIR__ . '/class-command-runner.php'; +require_once __DIR__ . '/class-wp-cli-test-case.php'; -class CoreTest extends PHPUnit_Framework_TestCase { +class CoreTest extends Wp_Cli_Test_Case { public function test_is_installed_exits_with_1_if_wordpress_not_installed() { - $temp_dir = self::create_temporary_directory(); + $temp_dir = $this->create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); $result = $command_runner->run_wp_cli( "core is-installed" ); $this->assertEquals(1, $result->return_code); @@ -23,9 +24,9 @@ public function test_install_command_creates_default_blog_post() { } public function test_message_explains_that_config_must_be_present_before_install() { - $temp_dir = self::create_temporary_directory(); + $temp_dir = $this->create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); - self::download_wordpress_files( $temp_dir ); + $this->download_wordpress_files( $temp_dir ); $result = $command_runner->run_wp_cli( "core install" ); $this->assertEquals( "^[[31;1mError: ^[[0mwp-config.php not found\n" . @@ -33,39 +34,4 @@ public function test_message_explains_that_config_must_be_present_before_install $result->output ); } - - private function install_wp_cli() { - $temp_dir = self::create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - self::download_wordpress_files( $temp_dir ); - $dbname = "wp_cli_test"; - $dbuser = "wp_cli_test"; - $dbpass = "password1"; - exec( "mysql -u$dbname -p$dbpass -e 'DROP DATABASE $dbname'" ); - exec( "mysql -u$dbname -p$dbpass -e 'CREATE DATABASE $dbname'" ); - $command_runner->run_wp_cli( "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); - $command_runner->run_wp_cli( - "core install --url=http://example.com/ --title=WordPress " . - " --admin_email=admin@example.com --admin_password=password1" - ); - return $command_runner; - } - - private static function download_wordpress_files( $target_dir ) { - // We cache the results of "wp core download" to improve test performance - // Ideally, we'd cache at the HTTP layer for more reliable tests - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - if ( !file_exists( $cache_dir ) ) { - mkdir( $cache_dir ); - $command_runner = new Command_Runner( $cache_dir ); - $command_runner->run_wp_cli( "core download" ); - } - exec( "cp -r '$cache_dir/'* '$target_dir/'" ); - } - - private static function create_temporary_directory() { - $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $dir ); - return $dir; - } } From 7a296f7628b3c403ebe6508a6f1f6028b237b3a2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Dec 2012 15:43:32 +0200 Subject: [PATCH 0919/4858] make `post update` accept multiple ids. see #229 --- src/php/wp-cli/commands/internals/post.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/internals/post.php index dd84c51db4..12ca8e0948 100644 --- a/src/php/wp-cli/commands/internals/post.php +++ b/src/php/wp-cli/commands/internals/post.php @@ -33,21 +33,23 @@ public function create( $_, $assoc_args ) { /** * Update a post. * - * @synopsis <id> --<field>=<value> + * @synopsis <id>... --<field>=<value> */ public function update( $args, $assoc_args ) { - list( $post_id ) = $args; + foreach ( $args as $post_id ) { + if ( empty( $assoc_args ) ) { + WP_CLI::error( "Need some fields to update." ); + } - if ( empty( $assoc_args ) ) { - WP_CLI::error( "Need some fields to update." ); - } + $params = array_merge( $assoc_args, array( 'ID' => $post_id ) ); - $params = array_merge( $assoc_args, array( 'ID' => $post_id ) ); + $r = wp_update_post( $params, true ); - if ( wp_update_post( $params ) ) { - WP_CLI::success( "Updated post $post_id." ); - } else { - WP_CLI::error( "Failed updating post $post_id" ); + if ( is_wp_error( $r ) ) { + WP_CLI::error( "Post $post_id: " . $r->get_error_message() ); + } else { + WP_CLI::success( "Updated post $post_id." ); + } } } From 9b482fd88d15413e5ce9239423e2d45373ec9d1d Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 16:06:31 +0000 Subject: [PATCH 0920/4858] Split off installation commands to dedicated class --- tests/class-wp-cli-test-case.php | 57 +++++++++++++++++++++++--------- tests/core-Test.php | 3 +- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index be7e998412..1c0cbe3891 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -6,21 +6,51 @@ abstract class Wp_Cli_Test_Case extends PHPUnit_Framework_TestCase { public function install_wp_cli() { $temp_dir = $this->create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); - $this->download_wordpress_files( $temp_dir ); - $dbname = "wp_cli_test"; - $dbuser = "wp_cli_test"; - $dbpass = "password1"; - exec( "mysql -u$dbname -p$dbpass -e 'DROP DATABASE $dbname'" ); - exec( "mysql -u$dbname -p$dbpass -e 'CREATE DATABASE $dbname'" ); - $command_runner->run_wp_cli( "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); - $command_runner->run_wp_cli( + $installer = new Wordpress_Installer( $temp_dir, $command_runner ); + $installer->download_wordpress_files( $temp_dir ); + $installer->reset_database(); + $installer->create_config(); + $installer->run_install(); + return $command_runner; + } + + public function create_temporary_directory() { + $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $dir ); + return $dir; + } +} + +class Wordpress_Installer { + private $dbname = "wp_cli_test"; + private $dbuser = "wp_cli_test"; + private $dbpass = "password1"; + private $install_dir; + private $command_runner; + + public function __construct( $install_dir, $command_runner ) { + $this->install_dir = $install_dir; + $this->command_runner = $command_runner; + } + + public function reset_database() { + exec( "mysql -u$this->dbname -p$this->dbpass -e 'DROP DATABASE $this->dbname'" ); + exec( "mysql -u$this->dbname -p$this->dbpass -e 'CREATE DATABASE $this->dbname'" ); + } + + public function create_config() { + $this->command_runner->run_wp_cli( + "core config --dbname=$this->dbname --dbuser=$this->dbuser --dbpass=$this->dbpass" ); + } + + public function run_install() { + $this->command_runner->run_wp_cli( "core install --url=http://example.com/ --title=WordPress " . " --admin_email=admin@example.com --admin_password=password1" ); - return $command_runner; } - public function download_wordpress_files( $target_dir ) { + public function download_wordpress_files() { // We cache the results of "wp core download" to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; @@ -29,12 +59,7 @@ public function download_wordpress_files( $target_dir ) { $command_runner = new Command_Runner( $cache_dir ); $command_runner->run_wp_cli( "core download" ); } - exec( "cp -r '$cache_dir/'* '$target_dir/'" ); + exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } - public function create_temporary_directory() { - $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $dir ); - return $dir; - } } diff --git a/tests/core-Test.php b/tests/core-Test.php index 3c79f97609..5a6bd8a590 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -26,7 +26,8 @@ public function test_install_command_creates_default_blog_post() { public function test_message_explains_that_config_must_be_present_before_install() { $temp_dir = $this->create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); - $this->download_wordpress_files( $temp_dir ); + $installer = new Wordpress_Installer( $temp_dir, $command_runner ); + $installer->download_wordpress_files( $temp_dir ); $result = $command_runner->run_wp_cli( "core install" ); $this->assertEquals( "^[[31;1mError: ^[[0mwp-config.php not found\n" . From 9399daca3dcdbd96fcef445263bc9d059b899743 Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Thu, 13 Dec 2012 16:31:06 +0000 Subject: [PATCH 0921/4858] Update detection of wp-config.php to match WordPress itself --- src/php/wp-cli/class-wp-cli.php | 18 +++++++++--- tests/class-wp-cli-test-case.php | 49 +++++++++++++++++++++++--------- tests/core-Test.php | 14 +++++++++ 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index b07c1a899c..0782011930 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -278,16 +278,26 @@ static function before_wp_load() { if ( array( 'core', 'install' ) == self::$arguments ) { define( 'WP_INSTALLING', true ); - if ( !file_exists( WP_ROOT . '/wp-config.php' ) ) { - WP_CLI::error( "wp-config.php not found\n" . - "Either create one manually or use wp core config" ); - } + if ( !self::wp_config_is_present() ) { + WP_CLI::error( "wp-config.php not found\n" . + "Either create one manually or use wp core config" ); + } } // Pretend we're in WP_ADMIN, to side-step full-page caching plugins define( 'WP_ADMIN', true ); $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; } + + private static function wp_config_is_present() { + if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { + return TRUE; + } + if ( file_exists( dirname(WP_ROOT) . '/wp-config.php' ) && ! file_exists( dirname(WP_ROOT) . '/wp-settings.php' ) ) { + return TRUE; + } + return FALSE; + } static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 1c0cbe3891..702bb5fe6b 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -3,13 +3,34 @@ require_once __DIR__ . '/class-command-runner.php'; abstract class Wp_Cli_Test_Case extends PHPUnit_Framework_TestCase { + protected $database_settings = array( + "dbname" => "wp_cli_test", + "dbuser" => "wp_cli_test", + "dbpass" => "password1" + ); + + protected function setUp() { + $this->reset_database(); + } + + private function reset_database() { + $dbname = $this->database_settings["dbname"]; + $this->run_sql( "DROP DATABASE $dbname" ); + $this->run_sql( "CREATE DATABASE $dbname" ); + } + + private function run_sql( $sql ) { + $dbuser = $this->database_settings["dbuser"]; + $dbpass = $this->database_settings["dbpass"]; + exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); + } + public function install_wp_cli() { $temp_dir = $this->create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); $installer = new Wordpress_Installer( $temp_dir, $command_runner ); $installer->download_wordpress_files( $temp_dir ); - $installer->reset_database(); - $installer->create_config(); + $installer->create_config( $this->database_settings ); $installer->run_install(); return $command_runner; } @@ -22,9 +43,6 @@ public function create_temporary_directory() { } class Wordpress_Installer { - private $dbname = "wp_cli_test"; - private $dbuser = "wp_cli_test"; - private $dbpass = "password1"; private $install_dir; private $command_runner; @@ -33,21 +51,20 @@ public function __construct( $install_dir, $command_runner ) { $this->command_runner = $command_runner; } - public function reset_database() { - exec( "mysql -u$this->dbname -p$this->dbpass -e 'DROP DATABASE $this->dbname'" ); - exec( "mysql -u$this->dbname -p$this->dbpass -e 'CREATE DATABASE $this->dbname'" ); - } - - public function create_config() { + public function create_config( $database_settings ) { + $dbname = $database_settings["dbname"]; + $dbuser = $database_settings["dbuser"]; + $dbpass = $database_settings["dbpass"]; $this->command_runner->run_wp_cli( - "core config --dbname=$this->dbname --dbuser=$this->dbuser --dbpass=$this->dbpass" ); + "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); } public function run_install() { - $this->command_runner->run_wp_cli( + $install_result = $this->command_runner->run_wp_cli( "core install --url=http://example.com/ --title=WordPress " . " --admin_email=admin@example.com --admin_password=password1" ); + $this->assert_process_exited_successfully( $install_result ); } public function download_wordpress_files() { @@ -62,4 +79,10 @@ public function download_wordpress_files() { exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } + private function assert_process_exited_successfully( $result ) { + if ( $result->return_code !== 0 ) { + $message = "return code was $result->return_code, output was: $result->output"; + throw new Exception( $message ); + } + } } diff --git a/tests/core-Test.php b/tests/core-Test.php index 5a6bd8a590..eb37feb0f8 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -35,4 +35,18 @@ public function test_message_explains_that_config_must_be_present_before_install $result->output ); } + + public function test_wp_config_can_be_placed_in_parent_directory() { + $temp_dir = $this->create_temporary_directory(); + $install_dir = $temp_dir . '/www-root'; + mkdir( $install_dir ); + $command_runner = new Command_Runner( $install_dir ); + $installer = new Wordpress_Installer( $install_dir, $command_runner ); + $installer->download_wordpress_files( $install_dir ); + $installer->create_config( $this->database_settings ); + rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); + $installer->run_install(); + $result = $command_runner->run_wp_cli( "post list --ids" ); + $this->assertEquals( "1", $result->output ); + } } From 88f1faeed23e867f26cc87b630b4eccf2c1e665a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Dec 2012 22:59:16 +0200 Subject: [PATCH 0922/4858] use Utils\locate_wp_config(). see #241 --- src/php/wp-cli/class-wp-cli.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 0782011930..8da8b9f36a 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -278,9 +278,9 @@ static function before_wp_load() { if ( array( 'core', 'install' ) == self::$arguments ) { define( 'WP_INSTALLING', true ); - if ( !self::wp_config_is_present() ) { + if ( !Utils\locate_wp_config() ) { WP_CLI::error( "wp-config.php not found\n" . - "Either create one manually or use wp core config" ); + "Either create one manually or use `wp core config`." ); } } @@ -288,16 +288,6 @@ static function before_wp_load() { define( 'WP_ADMIN', true ); $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; } - - private static function wp_config_is_present() { - if ( file_exists( WP_ROOT . '/wp-config.php' ) ) { - return TRUE; - } - if ( file_exists( dirname(WP_ROOT) . '/wp-config.php' ) && ! file_exists( dirname(WP_ROOT) . '/wp-settings.php' ) ) { - return TRUE; - } - return FALSE; - } static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); From 0809d64b8c28fc27188e6c946ed93e9fa63d5a58 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Dec 2012 23:20:12 +0200 Subject: [PATCH 0923/4858] make wp-cli a Composer library --- composer.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 90f5a3d050..85854aa80b 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,10 @@ { - "require-dev": { - "phpunit/phpunit": "3.7.x" - } + "name": "wp-cli/wp-cli", + "description": "A command line interface for WordPress", + "keywords": [ "cli", "wordpress" ], + "homepage": "http://wp-cli.org", + "license": "MIT", + "require-dev": { + "phpunit/phpunit": "3.7.x" + } } From 0e3be8953aed546b75f64a6448431f48e3204bac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Dec 2012 23:23:29 +0200 Subject: [PATCH 0924/4858] specify required PHP version --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index 85854aa80b..da2185fe3c 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,9 @@ "keywords": [ "cli", "wordpress" ], "homepage": "http://wp-cli.org", "license": "MIT", + "require": { + "php": ">=5.3" + }, "require-dev": { "phpunit/phpunit": "3.7.x" } From 533c9d804852cb1e83cc39496c6defe01b1fc294 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Dec 2012 23:32:56 +0200 Subject: [PATCH 0925/4858] register binary --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index da2185fe3c..3ec42c39aa 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,9 @@ "keywords": [ "cli", "wordpress" ], "homepage": "http://wp-cli.org", "license": "MIT", + "bin": [ + "src/bin/wp" + ], "require": { "php": ">=5.3" }, From d9154186df521bdf5bc72af8f4ac1248844cc7e3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Dec 2012 23:44:00 +0200 Subject: [PATCH 0926/4858] add php-cli-tools dependency --- composer.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3ec42c39aa..a3636d881c 100644 --- a/composer.json +++ b/composer.json @@ -7,8 +7,15 @@ "bin": [ "src/bin/wp" ], + "repositories": [ + { + "type": "vcs", + "url": "http://github.com/wp-cli/php-cli-tools" + } + ], "require": { - "php": ">=5.3" + "php": ">=5.3", + "jlogsdon/cli": "v0.9.2-alpha" }, "require-dev": { "phpunit/phpunit": "3.7.x" From e8de957456d2e20b0ea52b63cff850cb66c18faf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Dec 2012 00:02:19 +0200 Subject: [PATCH 0927/4858] use php-cli-tools from Packagist --- composer.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index a3636d881c..3092b1c426 100644 --- a/composer.json +++ b/composer.json @@ -7,17 +7,12 @@ "bin": [ "src/bin/wp" ], - "repositories": [ - { - "type": "vcs", - "url": "http://github.com/wp-cli/php-cli-tools" - } - ], "require": { "php": ">=5.3", - "jlogsdon/cli": "v0.9.2-alpha" + "wp-cli/php-cli-tools": "dev-master" }, "require-dev": { "phpunit/phpunit": "3.7.x" - } + }, + "minimum-stability": "dev" } From 21a3b981a7c45da56cf077b41a430af81f4989b6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Dec 2012 00:52:02 +0200 Subject: [PATCH 0928/4858] load php-cli-tools from vendor dir, when available --- src/php/wp-cli/utils.php | 12 ++++++++++++ src/php/wp-cli/wp-cli.php | 3 +-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index 5221c12de1..dae02d5731 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -2,6 +2,18 @@ namespace WP_CLI\Utils; +function load_cli_tools() { + $vendor_path = WP_CLI_ROOT . '../../../vendor'; + + if ( file_exists( $vendor_path . '/autoload.php' ) ) { + require $vendor_path . '/autoload.php'; + include $vendor_path . '/wp-cli/php-cli-tools/lib/cli/cli.php'; + } else { + include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; + \cli\register_autoload(); + } +} + /** * Splits $argv into positional and associative arguments. * diff --git a/src/php/wp-cli/wp-cli.php b/src/php/wp-cli/wp-cli.php index c7a3ea82ec..0f7fe59862 100755 --- a/src/php/wp-cli/wp-cli.php +++ b/src/php/wp-cli/wp-cli.php @@ -15,8 +15,7 @@ include WP_CLI_ROOT . 'class-wp-cli-command-with-upgrade.php'; include WP_CLI_ROOT . 'man.php'; -include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; -\cli\register_autoload(); +\WP_CLI\Utils\load_cli_tools(); WP_CLI::before_wp_load(); From 59c3806ec7cc20857dc9e25a7ba3b99bbfa35c28 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Dec 2012 02:32:55 +0200 Subject: [PATCH 0929/4858] handle both possible Composer scenarios --- src/php/wp-cli/utils.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index dae02d5731..c78ebbe534 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -3,12 +3,23 @@ namespace WP_CLI\Utils; function load_cli_tools() { - $vendor_path = WP_CLI_ROOT . '../../../vendor'; + $vendor_paths = array( + WP_CLI_ROOT . '../../../../../../vendor', // part of a larger project + WP_CLI_ROOT . '../../../vendor', // top-level project + ); + + $found = true; + + foreach ( $vendor_paths as $vendor_path ) { + if ( file_exists( $vendor_path . '/autoload.php' ) ) { + require $vendor_path . '/autoload.php'; + include $vendor_path . '/wp-cli/php-cli-tools/lib/cli/cli.php'; + $found = true; + break; + } + } - if ( file_exists( $vendor_path . '/autoload.php' ) ) { - require $vendor_path . '/autoload.php'; - include $vendor_path . '/wp-cli/php-cli-tools/lib/cli/cli.php'; - } else { + if ( !$found ) { include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); } From c905c0320ec8afb3e52b8915e0926ccba9c150ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Dec 2012 22:14:24 +0200 Subject: [PATCH 0930/4858] assume the vendor directory doesn't exist. see #242 --- src/php/wp-cli/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/utils.php b/src/php/wp-cli/utils.php index c78ebbe534..4d1969575f 100644 --- a/src/php/wp-cli/utils.php +++ b/src/php/wp-cli/utils.php @@ -8,7 +8,7 @@ function load_cli_tools() { WP_CLI_ROOT . '../../../vendor', // top-level project ); - $found = true; + $found = false; foreach ( $vendor_paths as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { From a3fca4689ab2f908013cc2d4020e0647c7b1e17e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 05:40:19 +0200 Subject: [PATCH 0931/4858] implement wp cap list --- src/php/wp-cli/commands/internals/cap.php | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/php/wp-cli/commands/internals/cap.php diff --git a/src/php/wp-cli/commands/internals/cap.php b/src/php/wp-cli/commands/internals/cap.php new file mode 100644 index 0000000000..315b4ffe18 --- /dev/null +++ b/src/php/wp-cli/commands/internals/cap.php @@ -0,0 +1,33 @@ +<?php + +WP_CLI::add_command( 'cap', 'Capabilities_Command' ); + +/** + * Manage capabilities. + * + * @package wp-cli + * @subpackage commands/internals + */ +class Capabilities_Command extends WP_CLI_Command { + + /** + * List capabilities for a given role. + * + * @subcommand list + * @synopsis <role> + */ + public function _list( $args ) { + global $wp_roles; + + list( $role ) = $args; + + $role_obj = $wp_roles->get_role( $role ); + + if ( !$role_obj ) + WP_CLI::error( "$role does not exist" ); + + foreach ( array_keys( $role_obj->capabilities ) as $cap ) + WP_CLI::line( $cap ); + } +} + From e31cb1941eaf9eb33b5cf2d1024755ec73a0b5db Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 06:14:37 +0200 Subject: [PATCH 0932/4858] implement `wp cap add` and `wp cap remove` --- src/php/wp-cli/commands/internals/cap.php | 73 +++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/cap.php b/src/php/wp-cli/commands/internals/cap.php index 315b4ffe18..f496acc705 100644 --- a/src/php/wp-cli/commands/internals/cap.php +++ b/src/php/wp-cli/commands/internals/cap.php @@ -17,17 +17,80 @@ class Capabilities_Command extends WP_CLI_Command { * @synopsis <role> */ public function _list( $args ) { - global $wp_roles; + $role_obj = self::get_role( $args[0] ); + + foreach ( array_keys( $role_obj->capabilities ) as $cap ) + WP_CLI::line( $cap ); + } + + /** + * Add capabilities to a given role. + * + * @synopsis <role> <cap>... + */ + public function add( $args ) { + self::persistence_check(); + + $role = array_shift( $args ); + + $role_obj = self::get_role( $role ); + + $count = 0; + + foreach ( $args as $cap ) { + if ( $role_obj->has_cap( $cap ) ) + continue; + + $role_obj->add_cap( $cap ); + + $count++; + } + + WP_CLI::success( sprintf( "Added %d capabilities to '%s' role." , $count, $role ) ); + } + + /** + * Add capabilities to a given role. + * + * @synopsis <role> <cap>... + */ + public function remove( $args ) { + self::persistence_check(); + + $role = array_shift( $args ); + + $role_obj = self::get_role( $role ); + + $count = 0; + + foreach ( $args as $cap ) { + if ( !$role_obj->has_cap( $cap ) ) + continue; + + $role_obj->remove_cap( $cap ); + + $count++; + } - list( $role ) = $args; + WP_CLI::success( sprintf( "Removed %d capabilities from '%s' role." , $count, $role ) ); + } + + private static function get_role( $role ) { + global $wp_roles; $role_obj = $wp_roles->get_role( $role ); if ( !$role_obj ) - WP_CLI::error( "$role does not exist" ); + WP_CLI::error( "'$role' role not found." ); - foreach ( array_keys( $role_obj->capabilities ) as $cap ) - WP_CLI::line( $cap ); + return $role_obj; + } + + private static function persistence_check() { + global $wp_roles; + + if ( !$wp_roles->use_db ) + WP_CLI::error( "Role definitions are not persistent." ); } } From 55d86f3041836e4393c9762527e9cf19adae08f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 06:53:48 +0200 Subject: [PATCH 0933/4858] add a few examples --- man/cap.1 | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ src/docs/cap.txt | 10 +++++++++ 2 files changed, 67 insertions(+) create mode 100644 man/cap.1 create mode 100644 src/docs/cap.txt diff --git a/man/cap.1 b/man/cap.1 new file mode 100644 index 0000000000..c129040464 --- /dev/null +++ b/man/cap.1 @@ -0,0 +1,57 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CAP" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-cap\fR \- Manage capabilities\. +. +.SH "SYNOPSIS" +wp cap list \fIrole\fR +. +.P +wp cap add \fIrole\fR \fIcap\fR\.\.\. +. +.P +wp cap remove \fIrole\fR \fIcap\fR\.\.\. +. +.SH "SUBCOMMANDS" +. +.TP +\fBlist\fR: +. +.IP +List capabilities for a given role\. +. +.TP +\fBadd\fR: +. +.IP +Add capabilities to a given role\. +. +.TP +\fBremove\fR: +. +.IP +Add capabilities to a given role\. +. +.SH "EXAMPLES" +. +.IP +# Add \'spectate\' capability to \'author\' role +. +.br +wp cap add \'author\' \'spectate\' +. +.IP +# Add all caps from \'editor\' role to \'author\' role +. +.br +wp cap list \'editor\' | xargs wp cap add \'author\' +. +.IP +# Remove all caps from \'editor\' role that also appear in \'author\' role +. +.br +wp cap list \'author\' | xargs wp cap remove \'editor\' + diff --git a/src/docs/cap.txt b/src/docs/cap.txt new file mode 100644 index 0000000000..73b0921b18 --- /dev/null +++ b/src/docs/cap.txt @@ -0,0 +1,10 @@ +## EXAMPLES + + # Add 'spectate' capability to 'author' role + wp cap add 'author' 'spectate' + + # Add all caps from 'editor' role to 'author' role + wp cap list 'editor' | xargs wp cap add 'author' + + # Remove all caps from 'editor' role that also appear in 'author' role + wp cap list 'author' | xargs wp cap remove 'editor' From 3ce29907c6b2ba1913bfe4e980105d110f55cb3f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 08:22:52 +0200 Subject: [PATCH 0934/4858] implement `wp user add-role` --- src/php/wp-cli/commands/internals/user.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index 3a186402f2..b35624b192 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -213,7 +213,7 @@ public function generate( $args, $assoc_args ) { } /** - * Add a user to a blog. + * Set the user role (for a particular blog). * * @subcommand set-role * @synopsis <user-login> [<role>] [--blog=<blog>] @@ -232,6 +232,22 @@ public function set_role( $args, $assoc_args ) { WP_CLI::success( "Added {$user->user_login} ({$user->ID}) to " . site_url() . " as {$role}" ); } + /** + * Add a role for a user. + * + * @subcommand add-role + * @synopsis <user-login> <role> [--blog=<blog>] + */ + public function add_role( $args, $assoc_args ) { + $user = self::get_user_from_first_arg( $args[0] ); + + $role = $args[1]; + + $user->add_role( $role ); + + WP_CLI::success( sprintf( "Added '%s' role for %s (%d).", $role, $user->user_login, $user->ID ) ); + } + /** * Remove a user from a blog. * From 965573ee8bee8f2ff90863317517d748a028d87b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 08:29:37 +0200 Subject: [PATCH 0935/4858] add optional <role> arg to `wp user remove-role` --- src/php/wp-cli/commands/internals/user.php | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/internals/user.php index b35624b192..da0f1c167a 100644 --- a/src/php/wp-cli/commands/internals/user.php +++ b/src/php/wp-cli/commands/internals/user.php @@ -249,21 +249,29 @@ public function add_role( $args, $assoc_args ) { } /** - * Remove a user from a blog. + * Remove a user's role. * * @subcommand remove-role - * @synopsis <user-login> + * @synopsis <user-login> [<role>] [--blog=<blog>] */ public function remove_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); - // Multisite - if ( function_exists( 'remove_user_from_blog' ) ) - remove_user_from_blog( $user->ID, get_current_blog_id() ); - else - $user->remove_all_caps(); + if ( isset( $args[1] ) ) { + $role = $args[1]; + + $user->remove_role( $role ); - WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); + WP_CLI::success( sprintf( "Removed '%s' role for %s (%d).", $role, $user->user_login, $user->ID ) ); + } else { + // Multisite + if ( function_exists( 'remove_user_from_blog' ) ) + remove_user_from_blog( $user->ID, get_current_blog_id() ); + else + $user->remove_all_caps(); + + WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); + } } private static function get_user_from_first_arg( $id_or_login ) { From ed71807f4613183f5d990ff640cf68d4483eb9fc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:03:06 +0200 Subject: [PATCH 0936/4858] first pass at reactivating a plugin after an update --- src/php/wp-cli/commands/internals/plugin.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/internals/plugin.php index 4a474d5df1..06780e8340 100644 --- a/src/php/wp-cli/commands/internals/plugin.php +++ b/src/php/wp-cli/commands/internals/plugin.php @@ -193,7 +193,20 @@ function update( $args, $assoc_args ) { } else { list( $basename ) = $this->parse_name( $args ); + $was_active = is_plugin_active( $basename ); + $was_network_active = is_plugin_active_for_network( $basename ); + parent::_update( $basename ); + + if ( $was_active ) { + $new_args = array( $args[0] ); + + $new_assoc_args = array(); + if ( $was_network_active ) + $new_assoc_args['network'] = true; + + $this->activate( $new_args, $new_assoc_args ); + } } } From 188e114abab1268d9afb8da154e297298e758e5d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:21:43 +0200 Subject: [PATCH 0937/4858] extract modify_wp_config() helper --- src/php/wp-cli/commands/internals/core.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/internals/core.php index 40af5f6aac..5b1d3b653d 100644 --- a/src/php/wp-cli/commands/internals/core.php +++ b/src/php/wp-cli/commands/internals/core.php @@ -150,17 +150,21 @@ public function install_network( $args, $assoc_args ) { <?php $ms_config = ob_get_clean(); + self::modify_wp_config( $ms_config ); + + wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); + + WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); + } + + private static function modify_wp_config( $content ) { $wp_config_path = WP_CLI\Utils\locate_wp_config(); $token = "/* That's all, stop editing!"; list( $before, $after ) = explode( $token, file_get_contents( $wp_config_path ) ); - file_put_contents( $wp_config_path, $before . $ms_config . $token . $after ); - - wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); - - WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); + file_put_contents( $wp_config_path, $before . $content . $token . $after ); } private static function get_clean_basedomain() { From b5f2607e4470c671391f9168543df49a4211ad19 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:25:05 +0200 Subject: [PATCH 0938/4858] tests: tabs, not spaces --- tests/class-command-runner.php | 72 +++++++------- tests/class-wp-cli-test-case.php | 158 +++++++++++++++---------------- tests/core-Test.php | 90 +++++++++--------- 3 files changed, 160 insertions(+), 160 deletions(-) diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php index f39b360075..f8f87b5117 100644 --- a/tests/class-command-runner.php +++ b/tests/class-command-runner.php @@ -1,43 +1,43 @@ <?php class Command_Runner { - private $cwd; - - public function __construct( $cwd ) { - $this->cwd = $cwd; - } - - public function run_wp_cli( $wp_cli_command ) { - $wp_cli_path = self::find_wp_cli(); - return self::run_command( "$wp_cli_path $wp_cli_command" ); - } - - private function find_wp_cli() { - return getcwd() . "/src/bin/wp"; - } - - private function run_command( $command ) { - $output_dummy = array(); - $output_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); - $output_binary_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); - $return_code = 0; - $cwd = $this->cwd; - $sh_command = "cd $cwd;" . - "$command > $output_binary_file 2>&1;" . - 'RETURN_CODE=$?;' . - "cat -v $output_binary_file > $output_file;" . - 'exit $RETURN_CODE'; - exec("sh -c '$sh_command'", $output_dummy, $return_code ); - $output = file_get_contents( $output_file); - unlink( $output_file ); - unlink( $output_binary_file ); - return new Execution_Result( $return_code, $output ); - } + private $cwd; + + public function __construct( $cwd ) { + $this->cwd = $cwd; + } + + public function run_wp_cli( $wp_cli_command ) { + $wp_cli_path = self::find_wp_cli(); + return self::run_command( "$wp_cli_path $wp_cli_command" ); + } + + private function find_wp_cli() { + return getcwd() . "/src/bin/wp"; + } + + private function run_command( $command ) { + $output_dummy = array(); + $output_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); + $output_binary_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); + $return_code = 0; + $cwd = $this->cwd; + $sh_command = "cd $cwd;" . + "$command > $output_binary_file 2>&1;" . + 'RETURN_CODE=$?;' . + "cat -v $output_binary_file > $output_file;" . + 'exit $RETURN_CODE'; + exec("sh -c '$sh_command'", $output_dummy, $return_code ); + $output = file_get_contents( $output_file); + unlink( $output_file ); + unlink( $output_binary_file ); + return new Execution_Result( $return_code, $output ); + } } class Execution_Result { - public function __construct( $return_code, $output ) { - $this->return_code = $return_code; - $this->output = $output; - } + public function __construct( $return_code, $output ) { + $this->return_code = $return_code; + $this->output = $output; + } } diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 702bb5fe6b..047d174b83 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -3,86 +3,86 @@ require_once __DIR__ . '/class-command-runner.php'; abstract class Wp_Cli_Test_Case extends PHPUnit_Framework_TestCase { - protected $database_settings = array( - "dbname" => "wp_cli_test", - "dbuser" => "wp_cli_test", - "dbpass" => "password1" - ); - - protected function setUp() { - $this->reset_database(); - } - - private function reset_database() { - $dbname = $this->database_settings["dbname"]; - $this->run_sql( "DROP DATABASE $dbname" ); - $this->run_sql( "CREATE DATABASE $dbname" ); - } - - private function run_sql( $sql ) { - $dbuser = $this->database_settings["dbuser"]; - $dbpass = $this->database_settings["dbpass"]; - exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); - } - - public function install_wp_cli() { - $temp_dir = $this->create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $command_runner ); - $installer->download_wordpress_files( $temp_dir ); - $installer->create_config( $this->database_settings ); - $installer->run_install(); - return $command_runner; - } - - public function create_temporary_directory() { - $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $dir ); - return $dir; - } + protected $database_settings = array( + "dbname" => "wp_cli_test", + "dbuser" => "wp_cli_test", + "dbpass" => "password1" + ); + + protected function setUp() { + $this->reset_database(); + } + + private function reset_database() { + $dbname = $this->database_settings["dbname"]; + $this->run_sql( "DROP DATABASE $dbname" ); + $this->run_sql( "CREATE DATABASE $dbname" ); + } + + private function run_sql( $sql ) { + $dbuser = $this->database_settings["dbuser"]; + $dbpass = $this->database_settings["dbpass"]; + exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); + } + + public function install_wp_cli() { + $temp_dir = $this->create_temporary_directory(); + $command_runner = new Command_Runner( $temp_dir ); + $installer = new Wordpress_Installer( $temp_dir, $command_runner ); + $installer->download_wordpress_files( $temp_dir ); + $installer->create_config( $this->database_settings ); + $installer->run_install(); + return $command_runner; + } + + public function create_temporary_directory() { + $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $dir ); + return $dir; + } } class Wordpress_Installer { - private $install_dir; - private $command_runner; - - public function __construct( $install_dir, $command_runner ) { - $this->install_dir = $install_dir; - $this->command_runner = $command_runner; - } - - public function create_config( $database_settings ) { - $dbname = $database_settings["dbname"]; - $dbuser = $database_settings["dbuser"]; - $dbpass = $database_settings["dbpass"]; - $this->command_runner->run_wp_cli( - "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); - } - - public function run_install() { - $install_result = $this->command_runner->run_wp_cli( - "core install --url=http://example.com/ --title=WordPress " . - " --admin_email=admin@example.com --admin_password=password1" - ); - $this->assert_process_exited_successfully( $install_result ); - } - - public function download_wordpress_files() { - // We cache the results of "wp core download" to improve test performance - // Ideally, we'd cache at the HTTP layer for more reliable tests - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - if ( !file_exists( $cache_dir ) ) { - mkdir( $cache_dir ); - $command_runner = new Command_Runner( $cache_dir ); - $command_runner->run_wp_cli( "core download" ); - } - exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); - } - - private function assert_process_exited_successfully( $result ) { - if ( $result->return_code !== 0 ) { - $message = "return code was $result->return_code, output was: $result->output"; - throw new Exception( $message ); - } - } + private $install_dir; + private $command_runner; + + public function __construct( $install_dir, $command_runner ) { + $this->install_dir = $install_dir; + $this->command_runner = $command_runner; + } + + public function create_config( $database_settings ) { + $dbname = $database_settings["dbname"]; + $dbuser = $database_settings["dbuser"]; + $dbpass = $database_settings["dbpass"]; + $this->command_runner->run_wp_cli( + "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); + } + + public function run_install() { + $install_result = $this->command_runner->run_wp_cli( + "core install --url=http://example.com/ --title=WordPress " . + " --admin_email=admin@example.com --admin_password=password1" + ); + $this->assert_process_exited_successfully( $install_result ); + } + + public function download_wordpress_files() { + // We cache the results of "wp core download" to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + if ( !file_exists( $cache_dir ) ) { + mkdir( $cache_dir ); + $command_runner = new Command_Runner( $cache_dir ); + $command_runner->run_wp_cli( "core download" ); + } + exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); + } + + private function assert_process_exited_successfully( $result ) { + if ( $result->return_code !== 0 ) { + $message = "return code was $result->return_code, output was: $result->output"; + throw new Exception( $message ); + } + } } diff --git a/tests/core-Test.php b/tests/core-Test.php index eb37feb0f8..80fc7d22d6 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -4,49 +4,49 @@ require_once __DIR__ . '/class-wp-cli-test-case.php'; class CoreTest extends Wp_Cli_Test_Case { - public function test_is_installed_exits_with_1_if_wordpress_not_installed() { - $temp_dir = $this->create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - $result = $command_runner->run_wp_cli( "core is-installed" ); - $this->assertEquals(1, $result->return_code); - } - - public function test_is_installed_exits_with_0_after_running_install_command() { - $command_runner = $this->install_wp_cli(); - $result = $command_runner->run_wp_cli( "core is-installed" ); - $this->assertEquals(0, $result->return_code); - } - - public function test_install_command_creates_default_blog_post() { - $command_runner = $this->install_wp_cli(); - $result = $command_runner->run_wp_cli( "post list --ids" ); - $this->assertEquals( "1", $result->output ); - } - - public function test_message_explains_that_config_must_be_present_before_install() { - $temp_dir = $this->create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $command_runner ); - $installer->download_wordpress_files( $temp_dir ); - $result = $command_runner->run_wp_cli( "core install" ); - $this->assertEquals( - "^[[31;1mError: ^[[0mwp-config.php not found\n" . - "Either create one manually or use wp core config\n", - $result->output - ); - } - - public function test_wp_config_can_be_placed_in_parent_directory() { - $temp_dir = $this->create_temporary_directory(); - $install_dir = $temp_dir . '/www-root'; - mkdir( $install_dir ); - $command_runner = new Command_Runner( $install_dir ); - $installer = new Wordpress_Installer( $install_dir, $command_runner ); - $installer->download_wordpress_files( $install_dir ); - $installer->create_config( $this->database_settings ); - rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); - $installer->run_install(); - $result = $command_runner->run_wp_cli( "post list --ids" ); - $this->assertEquals( "1", $result->output ); - } + public function test_is_installed_exits_with_1_if_wordpress_not_installed() { + $temp_dir = $this->create_temporary_directory(); + $command_runner = new Command_Runner( $temp_dir ); + $result = $command_runner->run_wp_cli( "core is-installed" ); + $this->assertEquals(1, $result->return_code); + } + + public function test_is_installed_exits_with_0_after_running_install_command() { + $command_runner = $this->install_wp_cli(); + $result = $command_runner->run_wp_cli( "core is-installed" ); + $this->assertEquals(0, $result->return_code); + } + + public function test_install_command_creates_default_blog_post() { + $command_runner = $this->install_wp_cli(); + $result = $command_runner->run_wp_cli( "post list --ids" ); + $this->assertEquals( "1", $result->output ); + } + + public function test_message_explains_that_config_must_be_present_before_install() { + $temp_dir = $this->create_temporary_directory(); + $command_runner = new Command_Runner( $temp_dir ); + $installer = new Wordpress_Installer( $temp_dir, $command_runner ); + $installer->download_wordpress_files( $temp_dir ); + $result = $command_runner->run_wp_cli( "core install" ); + $this->assertEquals( + "^[[31;1mError: ^[[0mwp-config.php not found\n" . + "Either create one manually or use wp core config\n", + $result->output + ); + } + + public function test_wp_config_can_be_placed_in_parent_directory() { + $temp_dir = $this->create_temporary_directory(); + $install_dir = $temp_dir . '/www-root'; + mkdir( $install_dir ); + $command_runner = new Command_Runner( $install_dir ); + $installer = new Wordpress_Installer( $install_dir, $command_runner ); + $installer->download_wordpress_files( $install_dir ); + $installer->create_config( $this->database_settings ); + rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); + $installer->run_install(); + $result = $command_runner->run_wp_cli( "post list --ids" ); + $this->assertEquals( "1", $result->output ); + } } From d71972b39f3e5bc74da3f3499ccf815d1753936b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:28:12 +0200 Subject: [PATCH 0939/4858] remove compare-cmd utility. using PHP's version_compare() now --- utils/compare-cmd | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100755 utils/compare-cmd diff --git a/utils/compare-cmd b/utils/compare-cmd deleted file mode 100755 index 92a291b30c..0000000000 --- a/utils/compare-cmd +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -if [ $# -lt 3 ]; then - echo 'usage: <version-a> <version-b> <wp-path>' - exit 1 -fi - -ver_a=$1 -ver_b=$2 -wp_path=$3 - -git checkout $ver_a -wp --path=$wp_path --syn-list > /tmp/wp-cli-a - -git checkout $ver_b -wp --path=$wp_path --syn-list > /tmp/wp-cli-b - -diff /tmp/wp-cli-a /tmp/wp-cli-b From 8e5cb553c7997b7d4f7e7219bf60d09cfb062ce0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:32:59 +0200 Subject: [PATCH 0940/4858] tests: coding standards --- tests/class-command-runner.php | 5 +++-- tests/core-Test.php | 31 ++++++++++++++++--------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php index f8f87b5117..7b6e9b30d0 100644 --- a/tests/class-command-runner.php +++ b/tests/class-command-runner.php @@ -27,8 +27,8 @@ private function run_command( $command ) { 'RETURN_CODE=$?;' . "cat -v $output_binary_file > $output_file;" . 'exit $RETURN_CODE'; - exec("sh -c '$sh_command'", $output_dummy, $return_code ); - $output = file_get_contents( $output_file); + exec( "sh -c '$sh_command'", $output_dummy, $return_code ); + $output = file_get_contents( $output_file ); unlink( $output_file ); unlink( $output_binary_file ); return new Execution_Result( $return_code, $output ); @@ -36,6 +36,7 @@ private function run_command( $command ) { } class Execution_Result { + public function __construct( $return_code, $output ) { $this->return_code = $return_code; $this->output = $output; diff --git a/tests/core-Test.php b/tests/core-Test.php index 80fc7d22d6..d268d5866d 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -4,31 +4,32 @@ require_once __DIR__ . '/class-wp-cli-test-case.php'; class CoreTest extends Wp_Cli_Test_Case { - public function test_is_installed_exits_with_1_if_wordpress_not_installed() { + + public function test_is_installed_exits_with_1_if_empty_dir() { $temp_dir = $this->create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - $result = $command_runner->run_wp_cli( "core is-installed" ); - $this->assertEquals(1, $result->return_code); + $runner = new Command_Runner( $temp_dir ); + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 1, $result->return_code ); } public function test_is_installed_exits_with_0_after_running_install_command() { - $command_runner = $this->install_wp_cli(); - $result = $command_runner->run_wp_cli( "core is-installed" ); - $this->assertEquals(0, $result->return_code); + $runner = $this->install_wp_cli(); + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 0, $result->return_code ); } public function test_install_command_creates_default_blog_post() { - $command_runner = $this->install_wp_cli(); - $result = $command_runner->run_wp_cli( "post list --ids" ); + $runner = $this->install_wp_cli(); + $result = $runner->run_wp_cli( "post list --ids" ); $this->assertEquals( "1", $result->output ); } public function test_message_explains_that_config_must_be_present_before_install() { $temp_dir = $this->create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $command_runner ); + $runner = new Command_Runner( $temp_dir ); + $installer = new Wordpress_Installer( $temp_dir, $runner ); $installer->download_wordpress_files( $temp_dir ); - $result = $command_runner->run_wp_cli( "core install" ); + $result = $runner->run_wp_cli( "core install" ); $this->assertEquals( "^[[31;1mError: ^[[0mwp-config.php not found\n" . "Either create one manually or use wp core config\n", @@ -40,13 +41,13 @@ public function test_wp_config_can_be_placed_in_parent_directory() { $temp_dir = $this->create_temporary_directory(); $install_dir = $temp_dir . '/www-root'; mkdir( $install_dir ); - $command_runner = new Command_Runner( $install_dir ); - $installer = new Wordpress_Installer( $install_dir, $command_runner ); + $runner = new Command_Runner( $install_dir ); + $installer = new Wordpress_Installer( $install_dir, $runner ); $installer->download_wordpress_files( $install_dir ); $installer->create_config( $this->database_settings ); rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); $installer->run_install(); - $result = $command_runner->run_wp_cli( "post list --ids" ); + $result = $runner->run_wp_cli( "post list --ids" ); $this->assertEquals( "1", $result->output ); } } From 86ebfcbe8be7f970f142404fa2fe0341c5539f92 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:36:58 +0200 Subject: [PATCH 0941/4858] fix test_message_explains_that_config_must_be_present_before_install() --- tests/core-Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core-Test.php b/tests/core-Test.php index d268d5866d..948cc820b2 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -32,7 +32,7 @@ public function test_message_explains_that_config_must_be_present_before_install $result = $runner->run_wp_cli( "core install" ); $this->assertEquals( "^[[31;1mError: ^[[0mwp-config.php not found\n" . - "Either create one manually or use wp core config\n", + "Either create one manually or use `wp core config`.\n", $result->output ); } From 439d825c720e4b090f0b71d8cfb5d8c27ab2329c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:39:56 +0200 Subject: [PATCH 0942/4858] tests: rename install_wp_cli() to full_wp_install() --- tests/class-wp-cli-test-case.php | 2 +- tests/core-Test.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 047d174b83..63a42ed787 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -25,7 +25,7 @@ private function run_sql( $sql ) { exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); } - public function install_wp_cli() { + public function full_wp_install() { $temp_dir = $this->create_temporary_directory(); $command_runner = new Command_Runner( $temp_dir ); $installer = new Wordpress_Installer( $temp_dir, $command_runner ); diff --git a/tests/core-Test.php b/tests/core-Test.php index 948cc820b2..1cbab37e4e 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -13,13 +13,13 @@ public function test_is_installed_exits_with_1_if_empty_dir() { } public function test_is_installed_exits_with_0_after_running_install_command() { - $runner = $this->install_wp_cli(); + $runner = $this->full_wp_install(); $result = $runner->run_wp_cli( "core is-installed" ); $this->assertEquals( 0, $result->return_code ); } public function test_install_command_creates_default_blog_post() { - $runner = $this->install_wp_cli(); + $runner = $this->full_wp_install(); $result = $runner->run_wp_cli( "post list --ids" ); $this->assertEquals( "1", $result->output ); } From 9cb3bb54ca54be54701874543eed7dfb82c43184 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:43:48 +0200 Subject: [PATCH 0943/4858] rename command_runner to runner --- tests/class-wp-cli-test-case.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 63a42ed787..54831a2667 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -27,12 +27,12 @@ private function run_sql( $sql ) { public function full_wp_install() { $temp_dir = $this->create_temporary_directory(); - $command_runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $command_runner ); + $runner = new Command_Runner( $temp_dir ); + $installer = new Wordpress_Installer( $temp_dir, $runner ); $installer->download_wordpress_files( $temp_dir ); $installer->create_config( $this->database_settings ); $installer->run_install(); - return $command_runner; + return $runner; } public function create_temporary_directory() { @@ -44,23 +44,23 @@ public function create_temporary_directory() { class Wordpress_Installer { private $install_dir; - private $command_runner; + private $runner; - public function __construct( $install_dir, $command_runner ) { + public function __construct( $install_dir, $runner ) { $this->install_dir = $install_dir; - $this->command_runner = $command_runner; + $this->runner = $runner; } public function create_config( $database_settings ) { $dbname = $database_settings["dbname"]; $dbuser = $database_settings["dbuser"]; $dbpass = $database_settings["dbpass"]; - $this->command_runner->run_wp_cli( + $this->runner->run_wp_cli( "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); } public function run_install() { - $install_result = $this->command_runner->run_wp_cli( + $install_result = $this->runner->run_wp_cli( "core install --url=http://example.com/ --title=WordPress " . " --admin_email=admin@example.com --admin_password=password1" ); @@ -73,8 +73,8 @@ public function download_wordpress_files() { $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; if ( !file_exists( $cache_dir ) ) { mkdir( $cache_dir ); - $command_runner = new Command_Runner( $cache_dir ); - $command_runner->run_wp_cli( "core download" ); + $runner = new Command_Runner( $cache_dir ); + $runner->run_wp_cli( "core download" ); } exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } From 2ae0589c0c823f3105ae077d23e2cb732611b350 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:46:10 +0200 Subject: [PATCH 0944/4858] add more tests for core is-installed. see #232 --- tests/core-Test.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/core-Test.php b/tests/core-Test.php index 1cbab37e4e..55d1050e93 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -12,6 +12,31 @@ public function test_is_installed_exits_with_1_if_empty_dir() { $this->assertEquals( 1, $result->return_code ); } + public function test_is_installed_exits_with_1_if_missing_wp_config() { + $temp_dir = $this->create_temporary_directory(); + + $runner = new Command_Runner( $temp_dir ); + + $installer = new Wordpress_Installer( $temp_dir, $runner ); + $installer->download_wordpress_files( $temp_dir ); + + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 1, $result->return_code ); + } + + public function test_is_installed_exits_with_1_if_db_not_installed() { + $temp_dir = $this->create_temporary_directory(); + + $runner = new Command_Runner( $temp_dir ); + + $installer = new Wordpress_Installer( $temp_dir, $runner ); + $installer->download_wordpress_files( $temp_dir ); + $installer->create_config( $this->database_settings ); + + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 1, $result->return_code ); + } + public function test_is_installed_exits_with_0_after_running_install_command() { $runner = $this->full_wp_install(); $result = $runner->run_wp_cli( "core is-installed" ); From 58cfbfcbd5540e42daefd4a47a3036a774958798 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 22:58:26 +0200 Subject: [PATCH 0945/4858] special handling for core is-installed. fixes #232 --- src/php/wp-cli/class-wp-cli.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 8da8b9f36a..09b3bb130f 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -274,14 +274,17 @@ static function before_wp_load() { exit; } - // Set installer flag before loading any WP files - if ( array( 'core', 'install' ) == self::$arguments ) { - define( 'WP_INSTALLING', true ); - + if ( 'core' == self::$arguments[0] && in_array( self::$arguments[1], array( 'install', 'is-installed' ) ) ) { if ( !Utils\locate_wp_config() ) { WP_CLI::error( "wp-config.php not found\n" . "Either create one manually or use `wp core config`." ); } + + define( 'WP_INSTALLING', true ); + + if ( !isset( $_SERVER['HTTP_HOST'] ) ) { + define( 'WP_SITEURL', 'http://example.com' ); + } } // Pretend we're in WP_ADMIN, to side-step full-page caching plugins From 115ff24885be2875338ffcc71a825d6a47158f4d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 23:17:00 +0200 Subject: [PATCH 0946/4858] introduce cmd_starts_with() helper --- src/php/wp-cli/class-wp-cli.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 09b3bb130f..f6af741744 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -267,14 +267,16 @@ static function before_wp_load() { exit; } - // The db commands don't need any WP files - if ( array( 'db' ) == array_slice( self::$arguments, 0, 1 ) ) { + if ( self::cmd_starts_with( array( 'db' ) ) ) { Utils\load_wp_config(); self::run_command(); exit; } - if ( 'core' == self::$arguments[0] && in_array( self::$arguments[1], array( 'install', 'is-installed' ) ) ) { + if ( + self::cmd_starts_with( array( 'core', 'install' ) ) || + self::cmd_starts_with( array( 'core', 'is-installed' ) ) + ) { if ( !Utils\locate_wp_config() ) { WP_CLI::error( "wp-config.php not found\n" . "Either create one manually or use `wp core config`." ); @@ -292,6 +294,10 @@ static function before_wp_load() { $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; } + private static function cmd_starts_with( $prefix ) { + return $prefix == array_slice( self::$arguments, 0, count( $prefix ) ); + } + static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); From 182e7ae099329e270773176c4eb91cc54d2e228a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 23:20:14 +0200 Subject: [PATCH 0947/4858] use Utils\set_url_params() in case WP_SITEURL is already defined. see #232 --- src/php/wp-cli/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index f6af741744..b330cd8f75 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -285,7 +285,7 @@ static function before_wp_load() { define( 'WP_INSTALLING', true ); if ( !isset( $_SERVER['HTTP_HOST'] ) ) { - define( 'WP_SITEURL', 'http://example.com' ); + Utils\set_url_params( 'http://example.com' ); } } From e830377c431cd68643e108bcd7cf1878e9943d6f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 23:32:57 +0200 Subject: [PATCH 0948/4858] WP_CLI::error() - replace unused $label parameter with $exit boolean --- src/php/wp-cli/class-wp-cli.php | 17 +++++++++++------ tests/core-Test.php | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index b330cd8f75..05994f1840 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -62,14 +62,16 @@ static function line( $message = '' ) { * Display an error in the CLI and end with a newline * * @param string $message - * @param string $label + * @param bool $exit */ - static function error( $message, $label = 'Error' ) { + static function error( $message, $exit = true ) { if ( !isset( self::$assoc_special['completions'] ) ) { + $label = 'Error'; \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); } - exit(1); + if ( $exit ) + exit(1); } /** @@ -259,7 +261,9 @@ static function before_wp_load() { } if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { - WP_CLI::error( 'This does not seem to be a WordPress install. Pass --path=`path/to/wordpress` or run `wp core download`.' ); + WP_CLI::error( "This does not seem to be a WordPress install.", false ); + WP_CLI::line( "Pass --path=`path/to/wordpress` or run `wp core download`." ); + exit(1); } if ( array( 'core', 'config' ) == self::$arguments ) { @@ -278,8 +282,9 @@ static function before_wp_load() { self::cmd_starts_with( array( 'core', 'is-installed' ) ) ) { if ( !Utils\locate_wp_config() ) { - WP_CLI::error( "wp-config.php not found\n" . - "Either create one manually or use `wp core config`." ); + WP_CLI::error( "wp-config.php not found.", false ); + WP_CLI::line( "Either create one manually or use `wp core config`." ); + exit(1); } define( 'WP_INSTALLING', true ); diff --git a/tests/core-Test.php b/tests/core-Test.php index 55d1050e93..73eb8efcf6 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -56,7 +56,7 @@ public function test_message_explains_that_config_must_be_present_before_install $installer->download_wordpress_files( $temp_dir ); $result = $runner->run_wp_cli( "core install" ); $this->assertEquals( - "^[[31;1mError: ^[[0mwp-config.php not found\n" . + "^[[31;1mError: ^[[0mwp-config.php not found.\n" . "Either create one manually or use `wp core config`.\n", $result->output ); From 4705b6167754b43c2b776337d2aced9b6e1cbc16 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Dec 2012 23:33:14 +0200 Subject: [PATCH 0949/4858] tests: s/database_settings/db_settings/g --- tests/class-wp-cli-test-case.php | 18 +++++++++--------- tests/core-Test.php | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 54831a2667..578b493454 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -3,7 +3,7 @@ require_once __DIR__ . '/class-command-runner.php'; abstract class Wp_Cli_Test_Case extends PHPUnit_Framework_TestCase { - protected $database_settings = array( + protected $db_settings = array( "dbname" => "wp_cli_test", "dbuser" => "wp_cli_test", "dbpass" => "password1" @@ -14,14 +14,14 @@ protected function setUp() { } private function reset_database() { - $dbname = $this->database_settings["dbname"]; + $dbname = $this->db_settings["dbname"]; $this->run_sql( "DROP DATABASE $dbname" ); $this->run_sql( "CREATE DATABASE $dbname" ); } private function run_sql( $sql ) { - $dbuser = $this->database_settings["dbuser"]; - $dbpass = $this->database_settings["dbpass"]; + $dbuser = $this->db_settings["dbuser"]; + $dbpass = $this->db_settings["dbpass"]; exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); } @@ -30,7 +30,7 @@ public function full_wp_install() { $runner = new Command_Runner( $temp_dir ); $installer = new Wordpress_Installer( $temp_dir, $runner ); $installer->download_wordpress_files( $temp_dir ); - $installer->create_config( $this->database_settings ); + $installer->create_config( $this->db_settings ); $installer->run_install(); return $runner; } @@ -51,10 +51,10 @@ public function __construct( $install_dir, $runner ) { $this->runner = $runner; } - public function create_config( $database_settings ) { - $dbname = $database_settings["dbname"]; - $dbuser = $database_settings["dbuser"]; - $dbpass = $database_settings["dbpass"]; + public function create_config( $db_settings ) { + $dbname = $db_settings["dbname"]; + $dbuser = $db_settings["dbuser"]; + $dbpass = $db_settings["dbpass"]; $this->runner->run_wp_cli( "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); } diff --git a/tests/core-Test.php b/tests/core-Test.php index 73eb8efcf6..20ba5bc89b 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -31,7 +31,7 @@ public function test_is_installed_exits_with_1_if_db_not_installed() { $installer = new Wordpress_Installer( $temp_dir, $runner ); $installer->download_wordpress_files( $temp_dir ); - $installer->create_config( $this->database_settings ); + $installer->create_config( $this->db_settings ); $result = $runner->run_wp_cli( "core is-installed" ); $this->assertEquals( 1, $result->return_code ); @@ -69,7 +69,7 @@ public function test_wp_config_can_be_placed_in_parent_directory() { $runner = new Command_Runner( $install_dir ); $installer = new Wordpress_Installer( $install_dir, $runner ); $installer->download_wordpress_files( $install_dir ); - $installer->create_config( $this->database_settings ); + $installer->create_config( $this->db_settings ); rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); $installer->run_install(); $result = $runner->run_wp_cli( "post list --ids" ); From 8415c828af419fed6411f84736c192dc9a359dd4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 17 Dec 2012 00:02:06 +0200 Subject: [PATCH 0950/4858] Re-add compare-cmd utility, with description. This reverts commit d71972b39f3e5bc74da3f3499ccf815d1753936b. --- utils/compare-cmd | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 utils/compare-cmd diff --git a/utils/compare-cmd b/utils/compare-cmd new file mode 100755 index 0000000000..21f6bc9b57 --- /dev/null +++ b/utils/compare-cmd @@ -0,0 +1,22 @@ +#!/bin/bash + +# utility for comparing commands between two different wp-cli versions. + +if [ $# -lt 3 ]; then + echo 'usage: <version-a> <version-b> <wp-path>' + exit 1 +fi + +ver_a=$1 +ver_b=$2 +wp_path=$3 + +git checkout $ver_a +wp --path=$wp_path --syn-list > /tmp/wp-cli-a + +git checkout $ver_b +wp --path=$wp_path --syn-list > /tmp/wp-cli-b + +diff /tmp/wp-cli-a /tmp/wp-cli-b > cmd.diff + +echo 'Generated cmd.diff' From eb84c54ccf22b0f295bb825553d578d5d8e9ab10 Mon Sep 17 00:00:00 2001 From: Jaime Martinez <jmslbam@gmail.com> Date: Fri, 21 Dec 2012 17:54:16 +0100 Subject: [PATCH 0951/4858] Update src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php Added %1\$s to href attribute so the do open to the permalink. And a new window --- .../internals/skeletons/post_type_skeleton.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 613518b332..d3c5e7dfc1 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -46,21 +46,21 @@ function {$machine_name}_updated_messages( \$messages ) { \$messages['{$post_type}'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label_ucfirst} updated. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 1 => sprintf( __('{$label_ucfirst} updated. <a target=\"_blank\" href=\"%1\$s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), 2 => __('Custom field updated.', '{$textdomain}'), 3 => __('Custom field deleted.', '{$textdomain}'), 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), /* translators: %s: date and time of the revision */ 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label_ucfirst} published. <a href=\"\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 6 => sprintf( __('{$label_ucfirst} published. <a href=\"%1\$s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), - 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"%1\$s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$textdomain}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"%1\$s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), ); return \$messages; } -add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; \ No newline at end of file +add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; From 6466bcadbf2e6050a897aa3758ab32b95e8a65f3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Dec 2012 10:09:19 +0200 Subject: [PATCH 0952/4858] check wp-config.php before running most commands. fixes #246 --- src/php/wp-cli/class-wp-cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 05994f1840..314470aca0 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -271,6 +271,12 @@ static function before_wp_load() { exit; } + if ( !Utils\locate_wp_config() ) { + WP_CLI::error( "wp-config.php not found.", false ); + WP_CLI::line( "Either create one manually or use `wp core config`." ); + exit(1); + } + if ( self::cmd_starts_with( array( 'db' ) ) ) { Utils\load_wp_config(); self::run_command(); @@ -281,12 +287,6 @@ static function before_wp_load() { self::cmd_starts_with( array( 'core', 'install' ) ) || self::cmd_starts_with( array( 'core', 'is-installed' ) ) ) { - if ( !Utils\locate_wp_config() ) { - WP_CLI::error( "wp-config.php not found.", false ); - WP_CLI::line( "Either create one manually or use `wp core config`." ); - exit(1); - } - define( 'WP_INSTALLING', true ); if ( !isset( $_SERVER['HTTP_HOST'] ) ) { From bb38c23f8a54d9df63fd1ab78ae4975c06f72ac7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Dec 2012 14:23:06 +0200 Subject: [PATCH 0953/4858] remove community commands --- .../commands/community/google-sitemap.php | 23 ---- .../wp-cli/commands/community/super-cache.php | 103 ------------------ .../wp-cli/commands/community/total-cache.php | 102 ----------------- 3 files changed, 228 deletions(-) delete mode 100644 src/php/wp-cli/commands/community/google-sitemap.php delete mode 100644 src/php/wp-cli/commands/community/super-cache.php delete mode 100644 src/php/wp-cli/commands/community/total-cache.php diff --git a/src/php/wp-cli/commands/community/google-sitemap.php b/src/php/wp-cli/commands/community/google-sitemap.php deleted file mode 100644 index 37bbe53c1f..0000000000 --- a/src/php/wp-cli/commands/community/google-sitemap.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -if( class_exists( 'GoogleSitemapGeneratorLoader' ) ) { - WP_CLI::add_command( 'google-sitemap', 'GoogleSitemapGenerator_Command' ); -} - -/** - * Manage the Google XML Sitemap plugin - * - * @package wp-cli - * @subpackage commands/community - */ -class GoogleSitemapGenerator_Command extends WP_CLI_Command { - - /** - * Re-generate the sitemap - */ - function rebuild() { - do_action( 'sm_rebuild' ); - - WP_CLI::success( 'Sitemap rebuilt.' ); - } -} diff --git a/src/php/wp-cli/commands/community/super-cache.php b/src/php/wp-cli/commands/community/super-cache.php deleted file mode 100644 index 5e54f3392c..0000000000 --- a/src/php/wp-cli/commands/community/super-cache.php +++ /dev/null @@ -1,103 +0,0 @@ -<?php - -if ( function_exists( 'wp_super_cache_enable' ) ) { - WP_CLI::add_command( 'super-cache', 'WPSuperCache_Command' ); -} - -/** - * The WP Super Cache plugin - * - * @package wp-cli - * @subpackage commands/community - */ -class WPSuperCache_Command extends WP_CLI_Command { - - /** - * Clear something from the cache. - * - * @synopsis [--post_id=<post-id>] [--permalink=<permalink>] - */ - function flush( $args = array(), $assoc_args = array() ) { - if ( isset($assoc_args['post_id']) ) { - if ( is_numeric( $assoc_args['post_id'] ) ) { - wp_cache_post_change( $assoc_args['post_id'] ); - } else { - WP_CLI::error('This is not a valid post id.'); - } - - wp_cache_post_change( $assoc_args['post_id'] ); - } - elseif ( isset( $assoc_args['permalink'] ) ) { - $id = url_to_postid( $assoc_args['permalink'] ); - - if ( is_numeric( $id ) ) { - wp_cache_post_change( $id ); - } else { - WP_CLI::error('There is no post with this permalink.'); - } - } else { - global $file_prefix; - - wp_cache_clean_cache( $file_prefix, true ); - - WP_CLI::success( 'Cache cleared.' ); - } - } - - /** - * Get the status of the cache. - */ - function status( $args = array(), $assoc_args = array() ) { - $cache_stats = get_option( 'supercache_stats' ); - - if ( !empty( $cache_stats ) ) { - if ( $cache_stats['generated'] > time() - 3600 * 24 ) { - global $super_cache_enabled; - WP_CLI::line( 'Cache status: ' . ($super_cache_enabled ? '%gOn%n' : '%rOff%n') ); - WP_CLI::line( 'Cache content on ' . date('r', $cache_stats['generated'] ) . ': ' ); - WP_CLI::line(); - WP_CLI::line( ' WordPress cache:' ); - WP_CLI::line( ' Cached: ' . $cache_stats[ 'wpcache' ][ 'cached' ] ); - WP_CLI::line( ' Expired: ' . $cache_stats[ 'wpcache' ][ 'expired' ] ); - WP_CLI::line(); - WP_CLI::line( ' WP Super Cache:' ); - WP_CLI::line( ' Cached: ' . $cache_stats[ 'supercache' ][ 'cached' ] ); - WP_CLI::line( ' Expired: ' . $cache_stats[ 'supercache' ][ 'expired' ] ); - } else { - WP_CLI::error('The WP Super Cache stats are too old to work with (older than 24 hours).'); - } - } else { - WP_CLI::error('No WP Super Cache stats found.'); - } - } - - /** - * Enable the WP Super Cache. - */ - function enable( $args = array(), $assoc_args = array() ) { - global $super_cache_enabled; - - wp_super_cache_enable(); - - if($super_cache_enabled) { - WP_CLI::success( 'The WP Super Cache is enabled.' ); - } else { - WP_CLI::error('The WP Super Cache is not enabled, check its settings page for more info.'); - } - } - - /** - * Disable the WP Super Cache. - */ - function disable( $args = array(), $assoc_args = array() ) { - global $super_cache_enabled; - - wp_super_cache_disable(); - - if(!$super_cache_enabled) { - WP_CLI::success( 'The WP Super Cache is disabled.' ); - } else { - WP_CLI::error('The WP Super Cache is still enabled, check its settings page for more info.'); - } - } -} diff --git a/src/php/wp-cli/commands/community/total-cache.php b/src/php/wp-cli/commands/community/total-cache.php deleted file mode 100644 index 5bfd111620..0000000000 --- a/src/php/wp-cli/commands/community/total-cache.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php - -if ( function_exists( 'w3tc_pgcache_flush' ) ) { - WP_CLI::add_command( 'total-cache', 'W3TotalCache_Command' ); -} - -/** - * The W3 Total Cache plugin - * - * @package wp-cli - * @subpackage commands/community - */ -class W3TotalCache_Command extends WP_CLI_Command { - - /** - * Clear something from the cache. - * - * @synopsis <cache-type>... [--post_id=<post-id>] [--permalink=<permalink>] - */ - function flush( $args = array(), $assoc_args = array() ) { - $args = array_unique( $args ); - do { - $cache_type = array_shift( $args ); - - switch( $cache_type ) { - case 'db': - case 'database': - if ( w3tc_dbcache_flush() ) { - WP_CLI::success( 'The database cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the database cache failed.' ); - } - break; - - case 'minify': - if ( w3tc_minify_flush() ) { - WP_CLI::success( 'The minify cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the minify cache failed.' ); - } - break; - - case 'object': - if ( w3tc_objectcache_flush() ) { - WP_CLI::success( 'The object cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the object cache failed.' ); - } - break; - - case 'page': - if ( w3tc_pgcache_flush() ) { - WP_CLI::success( 'The page cache is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing the page cache failed.' ); - } - break; - - case 'post': - default: - if ( isset($assoc_args['post_id']) ) { - if ( is_numeric( $assoc_args['post_id'] ) && get_post( $assoc_args['post_id'] ) ) { - if ( w3tc_pgcache_flush_post( $assoc_args['post_id'] ) ) { - WP_CLI::success( 'Post '.$assoc_args['post_id'].' is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing '.$assoc_args['post_id'].' from cache failed.' ); - } - } else { - WP_CLI::error('This is not a valid post id.'); - } - } - elseif ( isset( $assoc_args['permalink'] ) ) { - $id = url_to_postid( $assoc_args['permalink'] ); - - if ( is_numeric( $id ) && $id > 0 ) { - if ( w3tc_pgcache_flush_post( $id ) ) { - WP_CLI::success( $id.' is flushed successfully.' ); - } else { - WP_CLI::error( 'Flushing '.$id.' from cache failed.' ); - } - } else { - WP_CLI::error('There is no post with this permalink.'); - } - } - } - } while ( !empty( $args ) ); - } - - /** - * Help function for this command - */ - public static function help() { - WP_CLI::line( <<<EOB -Available sub-commands: - flush - <cache-type> post|database|minify|object|page - --post_id=<id> flush post cache with specific ID - --permalink=<post-permalink> flush post cache with specific permalink -EOB - ); - } -} From 7bf6a7c66a09cfd546fc6840b6596382d7f2ad80 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Dec 2012 14:21:47 +0200 Subject: [PATCH 0954/4858] make dispatcher look in /commands/ folder, instead of subfolders --- src/php/wp-cli/dispatcher.php | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/php/wp-cli/dispatcher.php b/src/php/wp-cli/dispatcher.php index c56c490a45..6077a49c86 100644 --- a/src/php/wp-cli/dispatcher.php +++ b/src/php/wp-cli/dispatcher.php @@ -160,27 +160,22 @@ function get_subcommands() { } protected function load_all_commands() { - foreach ( array( 'internals', 'community' ) as $dir ) { - foreach ( glob( WP_CLI_ROOT . "/commands/$dir/*.php" ) as $filename ) { - $command = substr( basename( $filename ), 0, -4 ); + foreach ( glob( WP_CLI_ROOT . "/commands/*.php" ) as $filename ) { + $command = substr( basename( $filename ), 0, -4 ); - if ( isset( $this->subcommands[ $command ] ) ) - continue; + if ( isset( $this->subcommands[ $command ] ) ) + continue; - include $filename; - } + include $filename; } } function load_command( $command ) { if ( !isset( $this->subcommands[$command] ) ) { - foreach ( array( 'internals', 'community' ) as $dir ) { - $path = WP_CLI_ROOT . "/commands/$dir/$command.php"; + $path = WP_CLI_ROOT . "/commands/$command.php"; - if ( is_readable( $path ) ) { - include $path; - break; - } + if ( is_readable( $path ) ) { + include $path; } } From e1c5de41ee5d78fb816f3716ed4d06aa74ce5ee7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Dec 2012 14:24:58 +0200 Subject: [PATCH 0955/4858] move internal commands to /commands/ folder --- src/php/wp-cli/commands/{internals => }/blog.php | 0 src/php/wp-cli/commands/{internals => }/cache.php | 0 src/php/wp-cli/commands/{internals => }/cap.php | 0 src/php/wp-cli/commands/{internals => }/comment.php | 0 src/php/wp-cli/commands/{internals => }/core.php | 0 src/php/wp-cli/commands/{internals => }/db.php | 0 src/php/wp-cli/commands/{internals => }/eval-file.php | 0 src/php/wp-cli/commands/{internals => }/eval.php | 0 src/php/wp-cli/commands/{internals => }/export.php | 0 src/php/wp-cli/commands/{internals => }/help.php | 0 src/php/wp-cli/commands/{internals => }/home.php | 0 src/php/wp-cli/commands/{internals => }/option.php | 0 src/php/wp-cli/commands/{internals => }/plugin.php | 0 src/php/wp-cli/commands/{internals => }/post-meta.php | 0 src/php/wp-cli/commands/{internals => }/post.php | 0 src/php/wp-cli/commands/{internals => }/rewrite.php | 0 src/php/wp-cli/commands/{internals => }/shell.php | 0 src/php/wp-cli/commands/{internals => }/theme.php | 0 src/php/wp-cli/commands/{internals => }/transient.php | 0 src/php/wp-cli/commands/{internals => }/user-meta.php | 0 src/php/wp-cli/commands/{internals => }/user.php | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename src/php/wp-cli/commands/{internals => }/blog.php (100%) rename src/php/wp-cli/commands/{internals => }/cache.php (100%) rename src/php/wp-cli/commands/{internals => }/cap.php (100%) rename src/php/wp-cli/commands/{internals => }/comment.php (100%) rename src/php/wp-cli/commands/{internals => }/core.php (100%) rename src/php/wp-cli/commands/{internals => }/db.php (100%) rename src/php/wp-cli/commands/{internals => }/eval-file.php (100%) rename src/php/wp-cli/commands/{internals => }/eval.php (100%) rename src/php/wp-cli/commands/{internals => }/export.php (100%) rename src/php/wp-cli/commands/{internals => }/help.php (100%) rename src/php/wp-cli/commands/{internals => }/home.php (100%) rename src/php/wp-cli/commands/{internals => }/option.php (100%) rename src/php/wp-cli/commands/{internals => }/plugin.php (100%) rename src/php/wp-cli/commands/{internals => }/post-meta.php (100%) rename src/php/wp-cli/commands/{internals => }/post.php (100%) rename src/php/wp-cli/commands/{internals => }/rewrite.php (100%) rename src/php/wp-cli/commands/{internals => }/shell.php (100%) rename src/php/wp-cli/commands/{internals => }/theme.php (100%) rename src/php/wp-cli/commands/{internals => }/transient.php (100%) rename src/php/wp-cli/commands/{internals => }/user-meta.php (100%) rename src/php/wp-cli/commands/{internals => }/user.php (100%) diff --git a/src/php/wp-cli/commands/internals/blog.php b/src/php/wp-cli/commands/blog.php similarity index 100% rename from src/php/wp-cli/commands/internals/blog.php rename to src/php/wp-cli/commands/blog.php diff --git a/src/php/wp-cli/commands/internals/cache.php b/src/php/wp-cli/commands/cache.php similarity index 100% rename from src/php/wp-cli/commands/internals/cache.php rename to src/php/wp-cli/commands/cache.php diff --git a/src/php/wp-cli/commands/internals/cap.php b/src/php/wp-cli/commands/cap.php similarity index 100% rename from src/php/wp-cli/commands/internals/cap.php rename to src/php/wp-cli/commands/cap.php diff --git a/src/php/wp-cli/commands/internals/comment.php b/src/php/wp-cli/commands/comment.php similarity index 100% rename from src/php/wp-cli/commands/internals/comment.php rename to src/php/wp-cli/commands/comment.php diff --git a/src/php/wp-cli/commands/internals/core.php b/src/php/wp-cli/commands/core.php similarity index 100% rename from src/php/wp-cli/commands/internals/core.php rename to src/php/wp-cli/commands/core.php diff --git a/src/php/wp-cli/commands/internals/db.php b/src/php/wp-cli/commands/db.php similarity index 100% rename from src/php/wp-cli/commands/internals/db.php rename to src/php/wp-cli/commands/db.php diff --git a/src/php/wp-cli/commands/internals/eval-file.php b/src/php/wp-cli/commands/eval-file.php similarity index 100% rename from src/php/wp-cli/commands/internals/eval-file.php rename to src/php/wp-cli/commands/eval-file.php diff --git a/src/php/wp-cli/commands/internals/eval.php b/src/php/wp-cli/commands/eval.php similarity index 100% rename from src/php/wp-cli/commands/internals/eval.php rename to src/php/wp-cli/commands/eval.php diff --git a/src/php/wp-cli/commands/internals/export.php b/src/php/wp-cli/commands/export.php similarity index 100% rename from src/php/wp-cli/commands/internals/export.php rename to src/php/wp-cli/commands/export.php diff --git a/src/php/wp-cli/commands/internals/help.php b/src/php/wp-cli/commands/help.php similarity index 100% rename from src/php/wp-cli/commands/internals/help.php rename to src/php/wp-cli/commands/help.php diff --git a/src/php/wp-cli/commands/internals/home.php b/src/php/wp-cli/commands/home.php similarity index 100% rename from src/php/wp-cli/commands/internals/home.php rename to src/php/wp-cli/commands/home.php diff --git a/src/php/wp-cli/commands/internals/option.php b/src/php/wp-cli/commands/option.php similarity index 100% rename from src/php/wp-cli/commands/internals/option.php rename to src/php/wp-cli/commands/option.php diff --git a/src/php/wp-cli/commands/internals/plugin.php b/src/php/wp-cli/commands/plugin.php similarity index 100% rename from src/php/wp-cli/commands/internals/plugin.php rename to src/php/wp-cli/commands/plugin.php diff --git a/src/php/wp-cli/commands/internals/post-meta.php b/src/php/wp-cli/commands/post-meta.php similarity index 100% rename from src/php/wp-cli/commands/internals/post-meta.php rename to src/php/wp-cli/commands/post-meta.php diff --git a/src/php/wp-cli/commands/internals/post.php b/src/php/wp-cli/commands/post.php similarity index 100% rename from src/php/wp-cli/commands/internals/post.php rename to src/php/wp-cli/commands/post.php diff --git a/src/php/wp-cli/commands/internals/rewrite.php b/src/php/wp-cli/commands/rewrite.php similarity index 100% rename from src/php/wp-cli/commands/internals/rewrite.php rename to src/php/wp-cli/commands/rewrite.php diff --git a/src/php/wp-cli/commands/internals/shell.php b/src/php/wp-cli/commands/shell.php similarity index 100% rename from src/php/wp-cli/commands/internals/shell.php rename to src/php/wp-cli/commands/shell.php diff --git a/src/php/wp-cli/commands/internals/theme.php b/src/php/wp-cli/commands/theme.php similarity index 100% rename from src/php/wp-cli/commands/internals/theme.php rename to src/php/wp-cli/commands/theme.php diff --git a/src/php/wp-cli/commands/internals/transient.php b/src/php/wp-cli/commands/transient.php similarity index 100% rename from src/php/wp-cli/commands/internals/transient.php rename to src/php/wp-cli/commands/transient.php diff --git a/src/php/wp-cli/commands/internals/user-meta.php b/src/php/wp-cli/commands/user-meta.php similarity index 100% rename from src/php/wp-cli/commands/internals/user-meta.php rename to src/php/wp-cli/commands/user-meta.php diff --git a/src/php/wp-cli/commands/internals/user.php b/src/php/wp-cli/commands/user.php similarity index 100% rename from src/php/wp-cli/commands/internals/user.php rename to src/php/wp-cli/commands/user.php From a400beeaf550fd870c4b08aa2635b75195f566e1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Dec 2012 14:51:03 +0200 Subject: [PATCH 0956/4858] disable colors if output is not a TTY --- src/php/wp-cli/class-wp-cli.php | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/php/wp-cli/class-wp-cli.php b/src/php/wp-cli/class-wp-cli.php index 314470aca0..176066587f 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/src/php/wp-cli/class-wp-cli.php @@ -43,9 +43,11 @@ static function get_man_dirs() { * * @param string $message */ - static function out( $message ) { - if ( WP_CLI_QUIET ) return; - \cli\out($message); + static function out( $message, $handle = STDOUT ) { + if ( WP_CLI_QUIET ) + return; + + fwrite( $handle, \cli\Colors::colorize( $message, ! \cli\Shell::isPiped() ) ); } /** @@ -54,8 +56,7 @@ static function out( $message ) { * @param string $message */ static function line( $message = '' ) { - if ( WP_CLI_QUIET ) return; - \cli\line($message); + self::out( $message . "\n" ); } /** @@ -67,7 +68,8 @@ static function line( $message = '' ) { static function error( $message, $exit = true ) { if ( !isset( self::$assoc_special['completions'] ) ) { $label = 'Error'; - \cli\err( '%R' . $label . ': %n' . self::error_to_string( $message ) ); + $msg = '%R' . $label . ': %n' . self::error_to_string( $message ); + self::out( $msg . "\n", STDERR ); } if ( $exit ) @@ -81,8 +83,10 @@ static function error( $message, $exit = true ) { * @param string $label */ static function success( $message, $label = 'Success' ) { - if ( WP_CLI_QUIET ) return; - \cli\line( '%G' . $label . ': %n' . $message ); + if ( WP_CLI_QUIET ) + return; + + self::line( '%G' . $label . ': %n' . $message ); } /** @@ -92,8 +96,11 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { - if ( WP_CLI_QUIET ) return; - \cli\err( '%C' . $label . ': %n' . self::error_to_string( $message ) ); + if ( WP_CLI_QUIET ) + return; + + $msg = '%C' . $label . ': %n' . self::error_to_string( $message ); + self::out( $msg . "\n", STDERR ); } /** @@ -101,7 +108,7 @@ static function warning( $message, $label = 'Warning' ) { */ static function confirm( $question, $assoc_args ) { if ( !isset( $assoc_args['yes'] ) ) { - WP_CLI::out( $question . " [y/n] " ); + self::out( $question . " [y/n] " ); $answer = trim( fgets( STDIN ) ); From 3c854d0d54c8d6d0cb1bd53ad40e729035cef5e3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Dec 2012 10:56:00 +0200 Subject: [PATCH 0957/4858] move everything from src/ into the top level --- .gitmodules | 4 ++-- {src/bin => bin}/wp | 0 composer.json | 2 +- {src/docs => man-src}/blog-create.txt | 0 {src/docs => man-src}/blog-delete.txt | 0 {src/docs => man-src}/cache.txt | 0 {src/docs => man-src}/cap.txt | 0 {src/docs => man-src}/comment-approve.txt | 0 {src/docs => man-src}/comment-count.txt | 0 {src/docs => man-src}/comment-create.txt | 0 {src/docs => man-src}/comment-delete.txt | 0 {src/docs => man-src}/comment-last.txt | 0 {src/docs => man-src}/comment-spam.txt | 0 {src/docs => man-src}/comment-status.txt | 0 {src/docs => man-src}/comment-trash.txt | 0 {src/docs => man-src}/comment-unapprove.txt | 0 {src/docs => man-src}/comment-unspam.txt | 0 {src/docs => man-src}/comment-untrash.txt | 0 {src/docs => man-src}/core-config.txt | 0 {src/docs => man-src}/core-download.txt | 0 {src/docs => man-src}/core-install-network.txt | 0 {src/docs => man-src}/core-install.txt | 0 {src/docs => man-src}/core-is-installed.txt | 0 {src/docs => man-src}/core-update.txt | 0 {src/docs => man-src}/core-version.txt | 0 {src/docs => man-src}/db.txt | 0 {src/docs => man-src}/eval-file.txt | 0 {src/docs => man-src}/eval.txt | 0 {src/docs => man-src}/export.txt | 0 {src/docs => man-src}/option.txt | 0 {src/docs => man-src}/plugin-activate.txt | 0 {src/docs => man-src}/plugin-deactivate.txt | 0 {src/docs => man-src}/plugin-delete.txt | 0 {src/docs => man-src}/plugin-install.txt | 0 {src/docs => man-src}/plugin-path.txt | 0 {src/docs => man-src}/plugin-status.txt | 0 {src/docs => man-src}/plugin-toggle.txt | 0 {src/docs => man-src}/plugin-uninstall.txt | 0 {src/docs => man-src}/plugin-update-all.txt | 0 {src/docs => man-src}/plugin-update.txt | 0 {src/docs => man-src}/post-create.txt | 0 {src/docs => man-src}/post-delete.txt | 0 {src/docs => man-src}/post-generate.txt | 0 {src/docs => man-src}/post-list.txt | 0 {src/docs => man-src}/post-meta.txt | 0 {src/docs => man-src}/post-update.txt | 0 {src/docs => man-src}/rewrite-dump.txt | 0 {src/docs => man-src}/rewrite-flush.txt | 0 {src/docs => man-src}/rewrite-structure.txt | 0 {src/docs => man-src}/theme-activate.txt | 0 {src/docs => man-src}/theme-delete.txt | 0 {src/docs => man-src}/theme-install.txt | 0 {src/docs => man-src}/theme-path.txt | 0 {src/docs => man-src}/theme-status.txt | 0 {src/docs => man-src}/theme-update-all.txt | 0 {src/docs => man-src}/theme-update.txt | 0 {src/docs => man-src}/transient.txt | 0 {src/docs => man-src}/user-create.txt | 0 {src/docs => man-src}/user-delete.txt | 0 {src/docs => man-src}/user-generate.txt | 0 {src/docs => man-src}/user-import-csv.txt | 0 {src/docs => man-src}/user-list.txt | 0 {src/docs => man-src}/user-meta.txt | 0 {src/docs => man-src}/user-remove-role.txt | 0 {src/docs => man-src}/user-set-role.txt | 0 {src/docs => man-src}/user-update.txt | 0 php/php-cli-tools | 1 + {src/php => php}/wp-cli/class-cli-upgrader-skin.php | 0 {src/php => php}/wp-cli/class-wp-cli-command-with-meta.php | 0 .../wp-cli/class-wp-cli-command-with-upgrade.php | 0 {src/php => php}/wp-cli/class-wp-cli-command.php | 0 {src/php => php}/wp-cli/class-wp-cli.php | 4 ++-- {src/php => php}/wp-cli/commands/blog.php | 0 {src/php => php}/wp-cli/commands/cache.php | 0 {src/php => php}/wp-cli/commands/cap.php | 0 {src/php => php}/wp-cli/commands/comment.php | 0 {src/php => php}/wp-cli/commands/core.php | 0 {src/php => php}/wp-cli/commands/db.php | 0 {src/php => php}/wp-cli/commands/eval-file.php | 0 {src/php => php}/wp-cli/commands/eval.php | 0 {src/php => php}/wp-cli/commands/export.php | 0 {src/php => php}/wp-cli/commands/help.php | 0 {src/php => php}/wp-cli/commands/home.php | 0 {src/php => php}/wp-cli/commands/option.php | 0 {src/php => php}/wp-cli/commands/plugin.php | 0 {src/php => php}/wp-cli/commands/post-meta.php | 0 {src/php => php}/wp-cli/commands/post.php | 0 {src/php => php}/wp-cli/commands/rewrite.php | 0 {src/php => php}/wp-cli/commands/shell.php | 0 {src/php => php}/wp-cli/commands/theme.php | 0 {src/php => php}/wp-cli/commands/transient.php | 0 {src/php => php}/wp-cli/commands/user-meta.php | 0 {src/php => php}/wp-cli/commands/user.php | 0 {src/php => php}/wp-cli/dispatcher.php | 0 {src/php => php}/wp-cli/man.php | 0 {src/php => php}/wp-cli/utils.php | 4 ++-- {src/php => php}/wp-cli/wp-cli-boot.php | 0 {src/php => php}/wp-cli/wp-cli.php | 0 {src/php => php}/wp-cli/wp-settings.php | 0 src/php/php-cli-tools | 1 - tests/class-command-runner.php | 2 +- utils/dev-build | 2 +- utils/local-build | 2 +- utils/pear-build | 6 ++---- 104 files changed, 13 insertions(+), 15 deletions(-) rename {src/bin => bin}/wp (100%) rename {src/docs => man-src}/blog-create.txt (100%) rename {src/docs => man-src}/blog-delete.txt (100%) rename {src/docs => man-src}/cache.txt (100%) rename {src/docs => man-src}/cap.txt (100%) rename {src/docs => man-src}/comment-approve.txt (100%) rename {src/docs => man-src}/comment-count.txt (100%) rename {src/docs => man-src}/comment-create.txt (100%) rename {src/docs => man-src}/comment-delete.txt (100%) rename {src/docs => man-src}/comment-last.txt (100%) rename {src/docs => man-src}/comment-spam.txt (100%) rename {src/docs => man-src}/comment-status.txt (100%) rename {src/docs => man-src}/comment-trash.txt (100%) rename {src/docs => man-src}/comment-unapprove.txt (100%) rename {src/docs => man-src}/comment-unspam.txt (100%) rename {src/docs => man-src}/comment-untrash.txt (100%) rename {src/docs => man-src}/core-config.txt (100%) rename {src/docs => man-src}/core-download.txt (100%) rename {src/docs => man-src}/core-install-network.txt (100%) rename {src/docs => man-src}/core-install.txt (100%) rename {src/docs => man-src}/core-is-installed.txt (100%) rename {src/docs => man-src}/core-update.txt (100%) rename {src/docs => man-src}/core-version.txt (100%) rename {src/docs => man-src}/db.txt (100%) rename {src/docs => man-src}/eval-file.txt (100%) rename {src/docs => man-src}/eval.txt (100%) rename {src/docs => man-src}/export.txt (100%) rename {src/docs => man-src}/option.txt (100%) rename {src/docs => man-src}/plugin-activate.txt (100%) rename {src/docs => man-src}/plugin-deactivate.txt (100%) rename {src/docs => man-src}/plugin-delete.txt (100%) rename {src/docs => man-src}/plugin-install.txt (100%) rename {src/docs => man-src}/plugin-path.txt (100%) rename {src/docs => man-src}/plugin-status.txt (100%) rename {src/docs => man-src}/plugin-toggle.txt (100%) rename {src/docs => man-src}/plugin-uninstall.txt (100%) rename {src/docs => man-src}/plugin-update-all.txt (100%) rename {src/docs => man-src}/plugin-update.txt (100%) rename {src/docs => man-src}/post-create.txt (100%) rename {src/docs => man-src}/post-delete.txt (100%) rename {src/docs => man-src}/post-generate.txt (100%) rename {src/docs => man-src}/post-list.txt (100%) rename {src/docs => man-src}/post-meta.txt (100%) rename {src/docs => man-src}/post-update.txt (100%) rename {src/docs => man-src}/rewrite-dump.txt (100%) rename {src/docs => man-src}/rewrite-flush.txt (100%) rename {src/docs => man-src}/rewrite-structure.txt (100%) rename {src/docs => man-src}/theme-activate.txt (100%) rename {src/docs => man-src}/theme-delete.txt (100%) rename {src/docs => man-src}/theme-install.txt (100%) rename {src/docs => man-src}/theme-path.txt (100%) rename {src/docs => man-src}/theme-status.txt (100%) rename {src/docs => man-src}/theme-update-all.txt (100%) rename {src/docs => man-src}/theme-update.txt (100%) rename {src/docs => man-src}/transient.txt (100%) rename {src/docs => man-src}/user-create.txt (100%) rename {src/docs => man-src}/user-delete.txt (100%) rename {src/docs => man-src}/user-generate.txt (100%) rename {src/docs => man-src}/user-import-csv.txt (100%) rename {src/docs => man-src}/user-list.txt (100%) rename {src/docs => man-src}/user-meta.txt (100%) rename {src/docs => man-src}/user-remove-role.txt (100%) rename {src/docs => man-src}/user-set-role.txt (100%) rename {src/docs => man-src}/user-update.txt (100%) create mode 160000 php/php-cli-tools rename {src/php => php}/wp-cli/class-cli-upgrader-skin.php (100%) rename {src/php => php}/wp-cli/class-wp-cli-command-with-meta.php (100%) rename {src/php => php}/wp-cli/class-wp-cli-command-with-upgrade.php (100%) rename {src/php => php}/wp-cli/class-wp-cli-command.php (100%) rename {src/php => php}/wp-cli/class-wp-cli.php (99%) rename {src/php => php}/wp-cli/commands/blog.php (100%) rename {src/php => php}/wp-cli/commands/cache.php (100%) rename {src/php => php}/wp-cli/commands/cap.php (100%) rename {src/php => php}/wp-cli/commands/comment.php (100%) rename {src/php => php}/wp-cli/commands/core.php (100%) rename {src/php => php}/wp-cli/commands/db.php (100%) rename {src/php => php}/wp-cli/commands/eval-file.php (100%) rename {src/php => php}/wp-cli/commands/eval.php (100%) rename {src/php => php}/wp-cli/commands/export.php (100%) rename {src/php => php}/wp-cli/commands/help.php (100%) rename {src/php => php}/wp-cli/commands/home.php (100%) rename {src/php => php}/wp-cli/commands/option.php (100%) rename {src/php => php}/wp-cli/commands/plugin.php (100%) rename {src/php => php}/wp-cli/commands/post-meta.php (100%) rename {src/php => php}/wp-cli/commands/post.php (100%) rename {src/php => php}/wp-cli/commands/rewrite.php (100%) rename {src/php => php}/wp-cli/commands/shell.php (100%) rename {src/php => php}/wp-cli/commands/theme.php (100%) rename {src/php => php}/wp-cli/commands/transient.php (100%) rename {src/php => php}/wp-cli/commands/user-meta.php (100%) rename {src/php => php}/wp-cli/commands/user.php (100%) rename {src/php => php}/wp-cli/dispatcher.php (100%) rename {src/php => php}/wp-cli/man.php (100%) rename {src/php => php}/wp-cli/utils.php (97%) rename {src/php => php}/wp-cli/wp-cli-boot.php (100%) rename {src/php => php}/wp-cli/wp-cli.php (100%) rename {src/php => php}/wp-cli/wp-settings.php (100%) delete mode 160000 src/php/php-cli-tools diff --git a/.gitmodules b/.gitmodules index ec544e3d04..bf7ca3df3d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "src/php/php-cli-tools"] - path = src/php/php-cli-tools +[submodule "php/php-cli-tools"] + path = php/php-cli-tools url = git://github.com/wp-cli/php-cli-tools.git diff --git a/src/bin/wp b/bin/wp similarity index 100% rename from src/bin/wp rename to bin/wp diff --git a/composer.json b/composer.json index 3092b1c426..2cb9f8c819 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "http://wp-cli.org", "license": "MIT", "bin": [ - "src/bin/wp" + "bin/wp" ], "require": { "php": ">=5.3", diff --git a/src/docs/blog-create.txt b/man-src/blog-create.txt similarity index 100% rename from src/docs/blog-create.txt rename to man-src/blog-create.txt diff --git a/src/docs/blog-delete.txt b/man-src/blog-delete.txt similarity index 100% rename from src/docs/blog-delete.txt rename to man-src/blog-delete.txt diff --git a/src/docs/cache.txt b/man-src/cache.txt similarity index 100% rename from src/docs/cache.txt rename to man-src/cache.txt diff --git a/src/docs/cap.txt b/man-src/cap.txt similarity index 100% rename from src/docs/cap.txt rename to man-src/cap.txt diff --git a/src/docs/comment-approve.txt b/man-src/comment-approve.txt similarity index 100% rename from src/docs/comment-approve.txt rename to man-src/comment-approve.txt diff --git a/src/docs/comment-count.txt b/man-src/comment-count.txt similarity index 100% rename from src/docs/comment-count.txt rename to man-src/comment-count.txt diff --git a/src/docs/comment-create.txt b/man-src/comment-create.txt similarity index 100% rename from src/docs/comment-create.txt rename to man-src/comment-create.txt diff --git a/src/docs/comment-delete.txt b/man-src/comment-delete.txt similarity index 100% rename from src/docs/comment-delete.txt rename to man-src/comment-delete.txt diff --git a/src/docs/comment-last.txt b/man-src/comment-last.txt similarity index 100% rename from src/docs/comment-last.txt rename to man-src/comment-last.txt diff --git a/src/docs/comment-spam.txt b/man-src/comment-spam.txt similarity index 100% rename from src/docs/comment-spam.txt rename to man-src/comment-spam.txt diff --git a/src/docs/comment-status.txt b/man-src/comment-status.txt similarity index 100% rename from src/docs/comment-status.txt rename to man-src/comment-status.txt diff --git a/src/docs/comment-trash.txt b/man-src/comment-trash.txt similarity index 100% rename from src/docs/comment-trash.txt rename to man-src/comment-trash.txt diff --git a/src/docs/comment-unapprove.txt b/man-src/comment-unapprove.txt similarity index 100% rename from src/docs/comment-unapprove.txt rename to man-src/comment-unapprove.txt diff --git a/src/docs/comment-unspam.txt b/man-src/comment-unspam.txt similarity index 100% rename from src/docs/comment-unspam.txt rename to man-src/comment-unspam.txt diff --git a/src/docs/comment-untrash.txt b/man-src/comment-untrash.txt similarity index 100% rename from src/docs/comment-untrash.txt rename to man-src/comment-untrash.txt diff --git a/src/docs/core-config.txt b/man-src/core-config.txt similarity index 100% rename from src/docs/core-config.txt rename to man-src/core-config.txt diff --git a/src/docs/core-download.txt b/man-src/core-download.txt similarity index 100% rename from src/docs/core-download.txt rename to man-src/core-download.txt diff --git a/src/docs/core-install-network.txt b/man-src/core-install-network.txt similarity index 100% rename from src/docs/core-install-network.txt rename to man-src/core-install-network.txt diff --git a/src/docs/core-install.txt b/man-src/core-install.txt similarity index 100% rename from src/docs/core-install.txt rename to man-src/core-install.txt diff --git a/src/docs/core-is-installed.txt b/man-src/core-is-installed.txt similarity index 100% rename from src/docs/core-is-installed.txt rename to man-src/core-is-installed.txt diff --git a/src/docs/core-update.txt b/man-src/core-update.txt similarity index 100% rename from src/docs/core-update.txt rename to man-src/core-update.txt diff --git a/src/docs/core-version.txt b/man-src/core-version.txt similarity index 100% rename from src/docs/core-version.txt rename to man-src/core-version.txt diff --git a/src/docs/db.txt b/man-src/db.txt similarity index 100% rename from src/docs/db.txt rename to man-src/db.txt diff --git a/src/docs/eval-file.txt b/man-src/eval-file.txt similarity index 100% rename from src/docs/eval-file.txt rename to man-src/eval-file.txt diff --git a/src/docs/eval.txt b/man-src/eval.txt similarity index 100% rename from src/docs/eval.txt rename to man-src/eval.txt diff --git a/src/docs/export.txt b/man-src/export.txt similarity index 100% rename from src/docs/export.txt rename to man-src/export.txt diff --git a/src/docs/option.txt b/man-src/option.txt similarity index 100% rename from src/docs/option.txt rename to man-src/option.txt diff --git a/src/docs/plugin-activate.txt b/man-src/plugin-activate.txt similarity index 100% rename from src/docs/plugin-activate.txt rename to man-src/plugin-activate.txt diff --git a/src/docs/plugin-deactivate.txt b/man-src/plugin-deactivate.txt similarity index 100% rename from src/docs/plugin-deactivate.txt rename to man-src/plugin-deactivate.txt diff --git a/src/docs/plugin-delete.txt b/man-src/plugin-delete.txt similarity index 100% rename from src/docs/plugin-delete.txt rename to man-src/plugin-delete.txt diff --git a/src/docs/plugin-install.txt b/man-src/plugin-install.txt similarity index 100% rename from src/docs/plugin-install.txt rename to man-src/plugin-install.txt diff --git a/src/docs/plugin-path.txt b/man-src/plugin-path.txt similarity index 100% rename from src/docs/plugin-path.txt rename to man-src/plugin-path.txt diff --git a/src/docs/plugin-status.txt b/man-src/plugin-status.txt similarity index 100% rename from src/docs/plugin-status.txt rename to man-src/plugin-status.txt diff --git a/src/docs/plugin-toggle.txt b/man-src/plugin-toggle.txt similarity index 100% rename from src/docs/plugin-toggle.txt rename to man-src/plugin-toggle.txt diff --git a/src/docs/plugin-uninstall.txt b/man-src/plugin-uninstall.txt similarity index 100% rename from src/docs/plugin-uninstall.txt rename to man-src/plugin-uninstall.txt diff --git a/src/docs/plugin-update-all.txt b/man-src/plugin-update-all.txt similarity index 100% rename from src/docs/plugin-update-all.txt rename to man-src/plugin-update-all.txt diff --git a/src/docs/plugin-update.txt b/man-src/plugin-update.txt similarity index 100% rename from src/docs/plugin-update.txt rename to man-src/plugin-update.txt diff --git a/src/docs/post-create.txt b/man-src/post-create.txt similarity index 100% rename from src/docs/post-create.txt rename to man-src/post-create.txt diff --git a/src/docs/post-delete.txt b/man-src/post-delete.txt similarity index 100% rename from src/docs/post-delete.txt rename to man-src/post-delete.txt diff --git a/src/docs/post-generate.txt b/man-src/post-generate.txt similarity index 100% rename from src/docs/post-generate.txt rename to man-src/post-generate.txt diff --git a/src/docs/post-list.txt b/man-src/post-list.txt similarity index 100% rename from src/docs/post-list.txt rename to man-src/post-list.txt diff --git a/src/docs/post-meta.txt b/man-src/post-meta.txt similarity index 100% rename from src/docs/post-meta.txt rename to man-src/post-meta.txt diff --git a/src/docs/post-update.txt b/man-src/post-update.txt similarity index 100% rename from src/docs/post-update.txt rename to man-src/post-update.txt diff --git a/src/docs/rewrite-dump.txt b/man-src/rewrite-dump.txt similarity index 100% rename from src/docs/rewrite-dump.txt rename to man-src/rewrite-dump.txt diff --git a/src/docs/rewrite-flush.txt b/man-src/rewrite-flush.txt similarity index 100% rename from src/docs/rewrite-flush.txt rename to man-src/rewrite-flush.txt diff --git a/src/docs/rewrite-structure.txt b/man-src/rewrite-structure.txt similarity index 100% rename from src/docs/rewrite-structure.txt rename to man-src/rewrite-structure.txt diff --git a/src/docs/theme-activate.txt b/man-src/theme-activate.txt similarity index 100% rename from src/docs/theme-activate.txt rename to man-src/theme-activate.txt diff --git a/src/docs/theme-delete.txt b/man-src/theme-delete.txt similarity index 100% rename from src/docs/theme-delete.txt rename to man-src/theme-delete.txt diff --git a/src/docs/theme-install.txt b/man-src/theme-install.txt similarity index 100% rename from src/docs/theme-install.txt rename to man-src/theme-install.txt diff --git a/src/docs/theme-path.txt b/man-src/theme-path.txt similarity index 100% rename from src/docs/theme-path.txt rename to man-src/theme-path.txt diff --git a/src/docs/theme-status.txt b/man-src/theme-status.txt similarity index 100% rename from src/docs/theme-status.txt rename to man-src/theme-status.txt diff --git a/src/docs/theme-update-all.txt b/man-src/theme-update-all.txt similarity index 100% rename from src/docs/theme-update-all.txt rename to man-src/theme-update-all.txt diff --git a/src/docs/theme-update.txt b/man-src/theme-update.txt similarity index 100% rename from src/docs/theme-update.txt rename to man-src/theme-update.txt diff --git a/src/docs/transient.txt b/man-src/transient.txt similarity index 100% rename from src/docs/transient.txt rename to man-src/transient.txt diff --git a/src/docs/user-create.txt b/man-src/user-create.txt similarity index 100% rename from src/docs/user-create.txt rename to man-src/user-create.txt diff --git a/src/docs/user-delete.txt b/man-src/user-delete.txt similarity index 100% rename from src/docs/user-delete.txt rename to man-src/user-delete.txt diff --git a/src/docs/user-generate.txt b/man-src/user-generate.txt similarity index 100% rename from src/docs/user-generate.txt rename to man-src/user-generate.txt diff --git a/src/docs/user-import-csv.txt b/man-src/user-import-csv.txt similarity index 100% rename from src/docs/user-import-csv.txt rename to man-src/user-import-csv.txt diff --git a/src/docs/user-list.txt b/man-src/user-list.txt similarity index 100% rename from src/docs/user-list.txt rename to man-src/user-list.txt diff --git a/src/docs/user-meta.txt b/man-src/user-meta.txt similarity index 100% rename from src/docs/user-meta.txt rename to man-src/user-meta.txt diff --git a/src/docs/user-remove-role.txt b/man-src/user-remove-role.txt similarity index 100% rename from src/docs/user-remove-role.txt rename to man-src/user-remove-role.txt diff --git a/src/docs/user-set-role.txt b/man-src/user-set-role.txt similarity index 100% rename from src/docs/user-set-role.txt rename to man-src/user-set-role.txt diff --git a/src/docs/user-update.txt b/man-src/user-update.txt similarity index 100% rename from src/docs/user-update.txt rename to man-src/user-update.txt diff --git a/php/php-cli-tools b/php/php-cli-tools new file mode 160000 index 0000000000..f3def25b86 --- /dev/null +++ b/php/php-cli-tools @@ -0,0 +1 @@ +Subproject commit f3def25b862bb0c5330a6347c6c04d62a99eb217 diff --git a/src/php/wp-cli/class-cli-upgrader-skin.php b/php/wp-cli/class-cli-upgrader-skin.php similarity index 100% rename from src/php/wp-cli/class-cli-upgrader-skin.php rename to php/wp-cli/class-cli-upgrader-skin.php diff --git a/src/php/wp-cli/class-wp-cli-command-with-meta.php b/php/wp-cli/class-wp-cli-command-with-meta.php similarity index 100% rename from src/php/wp-cli/class-wp-cli-command-with-meta.php rename to php/wp-cli/class-wp-cli-command-with-meta.php diff --git a/src/php/wp-cli/class-wp-cli-command-with-upgrade.php b/php/wp-cli/class-wp-cli-command-with-upgrade.php similarity index 100% rename from src/php/wp-cli/class-wp-cli-command-with-upgrade.php rename to php/wp-cli/class-wp-cli-command-with-upgrade.php diff --git a/src/php/wp-cli/class-wp-cli-command.php b/php/wp-cli/class-wp-cli-command.php similarity index 100% rename from src/php/wp-cli/class-wp-cli-command.php rename to php/wp-cli/class-wp-cli-command.php diff --git a/src/php/wp-cli/class-wp-cli.php b/php/wp-cli/class-wp-cli.php similarity index 99% rename from src/php/wp-cli/class-wp-cli.php rename to php/wp-cli/class-wp-cli.php index 176066587f..0e5c2dd1b2 100644 --- a/src/php/wp-cli/class-wp-cli.php +++ b/php/wp-cli/class-wp-cli.php @@ -234,8 +234,8 @@ static function get_assoc_special() { static function before_wp_load() { self::add_man_dir( - WP_CLI_ROOT . "../../../man/", - WP_CLI_ROOT . "../../docs/" + WP_CLI_ROOT . "../../man/", + WP_CLI_ROOT . "../../man-src/" ); self::parse_args(); diff --git a/src/php/wp-cli/commands/blog.php b/php/wp-cli/commands/blog.php similarity index 100% rename from src/php/wp-cli/commands/blog.php rename to php/wp-cli/commands/blog.php diff --git a/src/php/wp-cli/commands/cache.php b/php/wp-cli/commands/cache.php similarity index 100% rename from src/php/wp-cli/commands/cache.php rename to php/wp-cli/commands/cache.php diff --git a/src/php/wp-cli/commands/cap.php b/php/wp-cli/commands/cap.php similarity index 100% rename from src/php/wp-cli/commands/cap.php rename to php/wp-cli/commands/cap.php diff --git a/src/php/wp-cli/commands/comment.php b/php/wp-cli/commands/comment.php similarity index 100% rename from src/php/wp-cli/commands/comment.php rename to php/wp-cli/commands/comment.php diff --git a/src/php/wp-cli/commands/core.php b/php/wp-cli/commands/core.php similarity index 100% rename from src/php/wp-cli/commands/core.php rename to php/wp-cli/commands/core.php diff --git a/src/php/wp-cli/commands/db.php b/php/wp-cli/commands/db.php similarity index 100% rename from src/php/wp-cli/commands/db.php rename to php/wp-cli/commands/db.php diff --git a/src/php/wp-cli/commands/eval-file.php b/php/wp-cli/commands/eval-file.php similarity index 100% rename from src/php/wp-cli/commands/eval-file.php rename to php/wp-cli/commands/eval-file.php diff --git a/src/php/wp-cli/commands/eval.php b/php/wp-cli/commands/eval.php similarity index 100% rename from src/php/wp-cli/commands/eval.php rename to php/wp-cli/commands/eval.php diff --git a/src/php/wp-cli/commands/export.php b/php/wp-cli/commands/export.php similarity index 100% rename from src/php/wp-cli/commands/export.php rename to php/wp-cli/commands/export.php diff --git a/src/php/wp-cli/commands/help.php b/php/wp-cli/commands/help.php similarity index 100% rename from src/php/wp-cli/commands/help.php rename to php/wp-cli/commands/help.php diff --git a/src/php/wp-cli/commands/home.php b/php/wp-cli/commands/home.php similarity index 100% rename from src/php/wp-cli/commands/home.php rename to php/wp-cli/commands/home.php diff --git a/src/php/wp-cli/commands/option.php b/php/wp-cli/commands/option.php similarity index 100% rename from src/php/wp-cli/commands/option.php rename to php/wp-cli/commands/option.php diff --git a/src/php/wp-cli/commands/plugin.php b/php/wp-cli/commands/plugin.php similarity index 100% rename from src/php/wp-cli/commands/plugin.php rename to php/wp-cli/commands/plugin.php diff --git a/src/php/wp-cli/commands/post-meta.php b/php/wp-cli/commands/post-meta.php similarity index 100% rename from src/php/wp-cli/commands/post-meta.php rename to php/wp-cli/commands/post-meta.php diff --git a/src/php/wp-cli/commands/post.php b/php/wp-cli/commands/post.php similarity index 100% rename from src/php/wp-cli/commands/post.php rename to php/wp-cli/commands/post.php diff --git a/src/php/wp-cli/commands/rewrite.php b/php/wp-cli/commands/rewrite.php similarity index 100% rename from src/php/wp-cli/commands/rewrite.php rename to php/wp-cli/commands/rewrite.php diff --git a/src/php/wp-cli/commands/shell.php b/php/wp-cli/commands/shell.php similarity index 100% rename from src/php/wp-cli/commands/shell.php rename to php/wp-cli/commands/shell.php diff --git a/src/php/wp-cli/commands/theme.php b/php/wp-cli/commands/theme.php similarity index 100% rename from src/php/wp-cli/commands/theme.php rename to php/wp-cli/commands/theme.php diff --git a/src/php/wp-cli/commands/transient.php b/php/wp-cli/commands/transient.php similarity index 100% rename from src/php/wp-cli/commands/transient.php rename to php/wp-cli/commands/transient.php diff --git a/src/php/wp-cli/commands/user-meta.php b/php/wp-cli/commands/user-meta.php similarity index 100% rename from src/php/wp-cli/commands/user-meta.php rename to php/wp-cli/commands/user-meta.php diff --git a/src/php/wp-cli/commands/user.php b/php/wp-cli/commands/user.php similarity index 100% rename from src/php/wp-cli/commands/user.php rename to php/wp-cli/commands/user.php diff --git a/src/php/wp-cli/dispatcher.php b/php/wp-cli/dispatcher.php similarity index 100% rename from src/php/wp-cli/dispatcher.php rename to php/wp-cli/dispatcher.php diff --git a/src/php/wp-cli/man.php b/php/wp-cli/man.php similarity index 100% rename from src/php/wp-cli/man.php rename to php/wp-cli/man.php diff --git a/src/php/wp-cli/utils.php b/php/wp-cli/utils.php similarity index 97% rename from src/php/wp-cli/utils.php rename to php/wp-cli/utils.php index 5187139280..070ade815d 100644 --- a/src/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -4,8 +4,8 @@ function load_cli_tools() { $vendor_paths = array( - WP_CLI_ROOT . '../../../../../../vendor', // part of a larger project - WP_CLI_ROOT . '../../../vendor', // top-level project + WP_CLI_ROOT . '../../../../../vendor', // part of a larger project + WP_CLI_ROOT . '../../vendor', // top-level project ); $found = false; diff --git a/src/php/wp-cli/wp-cli-boot.php b/php/wp-cli/wp-cli-boot.php similarity index 100% rename from src/php/wp-cli/wp-cli-boot.php rename to php/wp-cli/wp-cli-boot.php diff --git a/src/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php similarity index 100% rename from src/php/wp-cli/wp-cli.php rename to php/wp-cli/wp-cli.php diff --git a/src/php/wp-cli/wp-settings.php b/php/wp-cli/wp-settings.php similarity index 100% rename from src/php/wp-cli/wp-settings.php rename to php/wp-cli/wp-settings.php diff --git a/src/php/php-cli-tools b/src/php/php-cli-tools deleted file mode 160000 index f2abf5015c..0000000000 --- a/src/php/php-cli-tools +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f2abf5015c769f9603fc63e7d0a0eff00006c61e diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php index 7b6e9b30d0..7139cfb3b1 100644 --- a/tests/class-command-runner.php +++ b/tests/class-command-runner.php @@ -13,7 +13,7 @@ public function run_wp_cli( $wp_cli_command ) { } private function find_wp_cli() { - return getcwd() . "/src/bin/wp"; + return getcwd() . "/bin/wp"; } private function run_command( $command ) { diff --git a/utils/dev-build b/utils/dev-build index ea70e6be63..b8ad05819f 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -2,7 +2,7 @@ for dir in /usr/bin /usr/local/bin; do if [ -d $dir ]; then - ln -sf $(pwd)/src/bin/wp $dir/wp + ln -sf $(pwd)/bin/wp $dir/wp break fi done diff --git a/utils/local-build b/utils/local-build index edf89736e7..fab82fddf7 100755 --- a/utils/local-build +++ b/utils/local-build @@ -12,6 +12,6 @@ fi DIR=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) -alias wp='$DIR/../src/bin/wp' +alias wp='$DIR/../bin/wp' . $DIR/wp-completion.bash diff --git a/utils/pear-build b/utils/pear-build index 300d83ef40..758cadd5c7 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -3,12 +3,10 @@ set -ex # create bunch of directories that phing complains about -mkdir -p src/data -mkdir -p src/tests/unit-tests/php -mkdir -p src/www +mkdir -p data www tests/unit-tests/php # temporarily move the .git dir, because phing is stupid -git_dir=src/php/php-cli-tools/.git +git_dir=php/php-cli-tools/.git if [ -f $git_dir ]; then mv $git_dir /tmp/php-cli-tools-git fi From 3166e02d3de15a6d671a2a400688d65e73e6fc1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Dec 2012 16:43:02 +0200 Subject: [PATCH 0958/4858] fix pear-build --- .gitignore | 1 + utils/pear-build | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 851cd11405..8b2103e777 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.build +/src /dist /vendor /composer.lock diff --git a/utils/pear-build b/utils/pear-build index 758cadd5c7..1d0d661666 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -2,8 +2,16 @@ set -ex +# create src dir +rm -rf src +mkdir src +cp -r php src/ +cp -r bin src/ + # create bunch of directories that phing complains about -mkdir -p data www tests/unit-tests/php +cd src +mkdir -p docs data www tests/unit-tests/php +cd - # temporarily move the .git dir, because phing is stupid git_dir=php/php-cli-tools/.git From 5e8f2410b29a9201df6313d9eb82f1e74e709781 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Dec 2012 16:49:53 +0200 Subject: [PATCH 0959/4858] update path in build.xml instead of creating src dir. see #248 --- build.xml | 2 +- utils/pear-build | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/build.xml b/build.xml index a3b5079217..932336fb43 100644 --- a/build.xml +++ b/build.xml @@ -22,7 +22,7 @@ <property name="project.apiversion" value="${project.majorVersion}.${project.minorVersion}" /> <!-- Paths to the directories that we work with --> - <property name="project.srcdir" value="${project.basedir}/src" override="true" /> + <property name="project.srcdir" value="${project.basedir}" override="true" /> <property name="project.src.phpdir" value="${project.srcdir}/php" override="true" /> <property name="project.src.bindir" value="${project.srcdir}/bin" override="true" /> <property name="project.src.datadir" value="${project.srcdir}/data" override="true" /> diff --git a/utils/pear-build b/utils/pear-build index 1d0d661666..c4e404784f 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -2,16 +2,8 @@ set -ex -# create src dir -rm -rf src -mkdir src -cp -r php src/ -cp -r bin src/ - # create bunch of directories that phing complains about -cd src mkdir -p docs data www tests/unit-tests/php -cd - # temporarily move the .git dir, because phing is stupid git_dir=php/php-cli-tools/.git From 6c018aae76f7ae6adfdda24f2b724e651a061235 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 07:46:58 +0200 Subject: [PATCH 0960/4858] add query iterators as submodule --- .gitmodules | 3 +++ php/query-iterators | 1 + 2 files changed, 4 insertions(+) create mode 160000 php/query-iterators diff --git a/.gitmodules b/.gitmodules index bf7ca3df3d..d70ec97df1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "php/php-cli-tools"] path = php/php-cli-tools url = git://github.com/wp-cli/php-cli-tools.git +[submodule "php/query-iterators"] + path = php/query-iterators + url = https://gist.github.com/4378217.git diff --git a/php/query-iterators b/php/query-iterators new file mode 160000 index 0000000000..7cb209489a --- /dev/null +++ b/php/query-iterators @@ -0,0 +1 @@ +Subproject commit 7cb209489a356c6b18bb910a291df13a6c258b96 From b1bd56dd5e2bdc106603c1034affc6a953b5e6b1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 08:56:37 +0200 Subject: [PATCH 0961/4858] first pass at search-replace command --- php/wp-cli/commands/search-replace.php | 101 +++++++++++++++++++++++++ php/wp-cli/utils.php | 60 +++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 php/wp-cli/commands/search-replace.php diff --git a/php/wp-cli/commands/search-replace.php b/php/wp-cli/commands/search-replace.php new file mode 100644 index 0000000000..cec0d29ddb --- /dev/null +++ b/php/wp-cli/commands/search-replace.php @@ -0,0 +1,101 @@ +<?php + +WP_CLI::add_command( 'search-replace', new Search_Replace_Command ); + +/** + * Search/Replace strings in the database. + * + * @package wp-cli + */ +class Search_Replace_Command extends WP_CLI_Command { + + /** + * @synopsis <old> <new> + */ + public function __invoke( $args, $assoc_args ) { + require_once WP_CLI_ROOT . '../query-iterators/class-table-iterator.php'; + + global $wpdb; + + list( $old, $new ) = $args; + + $tables = $wpdb->tables( 'blog' ); + + $total = 0; + + foreach ( $tables as $table ) { + list( $primary_key, $columns ) = self::get_columns( $table ); + + foreach ( $columns as $col ) { + $count = self::handle_col( $col, $primary_key, $table, $old, $new ); + + WP_CLI::line( "$table.$col: $count" ); + + $total += $count; + } + } + + WP_CLI::success( "Made $total replacements." ); + } + + private static function handle_col( $col, $primary_key, $table, $old, $new ) { + global $wpdb; + + $args = array( + 'table' => $table, + 'fields' => array( $primary_key, $col ), + 'where' => $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', + 'limit' => 1000 + ); + + $it = new TableIterator( $args ); + + $count = 0; + + foreach ( $it as $row ) { + if ( '' === $row->$col ) + continue; + + $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); + + $count += $wpdb->update( $table, + array( $col => $value ), + array( $primary_key => $row->$primary_key ) + ); + } + + return $count; + } + + private static function get_columns( $table ) { + global $wpdb; + + $primary_key = null; + + $columns = array(); + + foreach ( $wpdb->get_results( "DESCRIBE $table" ) as $col ) { + if ( 'PRI' === $col->Key ) { + $primary_key = $col->Field; + continue; + } + + if ( !self::is_text_col( $col->Type ) ) + continue; + + $columns[] = $col->Field; + } + + return array( $primary_key, $columns ); + } + + private static function is_text_col( $type ) { + foreach ( array( 'text', 'varchar' ) as $token ) { + if ( false !== strpos( $type, $token ) ) + return true; + } + + return false; + } +} + diff --git a/php/wp-cli/utils.php b/php/wp-cli/utils.php index 070ade815d..344e14f522 100644 --- a/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -218,3 +218,63 @@ function parse_csv( $filepath, $has_headers = true ) { } return $parsed_data; } + +/** + * Take a serialised array and unserialise it replacing elements as needed and + * unserialising any subordinate arrays and performing the replace on those too. + * + * @source https://github.com/interconnectit/Search-Replace-DB + * + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with + * @param array $data Used to pass any subordinate arrays back to in. + * @param bool $serialised Does the array passed via $data need serialising. + * + * @return array The original array with all elements replaced as needed. + */ +function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) { + + // some unseriliased data cannot be re-serialised eg. SimpleXMLElements + try { + + if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { + $data = recursive_unserialize_replace( $from, $to, $unserialized, true ); + } + + elseif ( is_array( $data ) ) { + $_tmp = array( ); + foreach ( $data as $key => $value ) { + $_tmp[ $key ] = recursive_unserialize_replace( $from, $to, $value, false ); + } + + $data = $_tmp; + unset( $_tmp ); + } + + // Submitted by Tina Matter + elseif ( is_object( $data ) ) { + $dataClass = get_class( $data ); + $_tmp = new $dataClass( ); + foreach ( $data as $key => $value ) { + $_tmp->$key = recursive_unserialize_replace( $from, $to, $value, false ); + } + + $data = $_tmp; + unset( $_tmp ); + } + + else { + if ( is_string( $data ) ) + $data = str_replace( $from, $to, $data ); + } + + if ( $serialised ) + return serialize( $data ); + + } catch( Exception $error ) { + + } + + return $data; +} + From ad7418703eba1890cb0e1cb1cd7f304b1550f318 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 09:02:04 +0200 Subject: [PATCH 0962/4858] use \cli\Table for displaying the report --- php/wp-cli/commands/search-replace.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/php/wp-cli/commands/search-replace.php b/php/wp-cli/commands/search-replace.php index cec0d29ddb..e0f2f0e767 100644 --- a/php/wp-cli/commands/search-replace.php +++ b/php/wp-cli/commands/search-replace.php @@ -23,18 +23,25 @@ public function __invoke( $args, $assoc_args ) { $total = 0; + $report = array(); + foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); foreach ( $columns as $col ) { $count = self::handle_col( $col, $primary_key, $table, $old, $new ); - WP_CLI::line( "$table.$col: $count" ); + $report[] = array( $table, $col, $count ); $total += $count; } } + $table = new \cli\Table(); + $table->setHeaders( array( 'Table', 'Column', 'Replacements' ) ); + $table->setRows( $report ); + $table->display(); + WP_CLI::success( "Made $total replacements." ); } From d7015fa9acd4248da607506ce8484e2500194127 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 09:15:50 +0200 Subject: [PATCH 0963/4858] add --dry-run flag --- php/wp-cli/commands/search-replace.php | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/php/wp-cli/commands/search-replace.php b/php/wp-cli/commands/search-replace.php index e0f2f0e767..71bb7d5241 100644 --- a/php/wp-cli/commands/search-replace.php +++ b/php/wp-cli/commands/search-replace.php @@ -10,7 +10,7 @@ class Search_Replace_Command extends WP_CLI_Command { /** - * @synopsis <old> <new> + * @synopsis <old> <new> [--dry-run] */ public function __invoke( $args, $assoc_args ) { require_once WP_CLI_ROOT . '../query-iterators/class-table-iterator.php'; @@ -25,11 +25,14 @@ public function __invoke( $args, $assoc_args ) { $report = array(); + $dry_run = isset( $assoc_args['dry-run'] ); + foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); foreach ( $columns as $col ) { - $count = self::handle_col( $col, $primary_key, $table, $old, $new ); + $count = self::handle_col( $col, $primary_key, $table, $old, $new, + $dry_run ); $report[] = array( $table, $col, $count ); @@ -42,10 +45,11 @@ public function __invoke( $args, $assoc_args ) { $table->setRows( $report ); $table->display(); - WP_CLI::success( "Made $total replacements." ); + if ( !$dry_run ) + WP_CLI::success( "Made $total replacements." ); } - private static function handle_col( $col, $primary_key, $table, $old, $new ) { + private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { global $wpdb; $args = array( @@ -65,10 +69,15 @@ private static function handle_col( $col, $primary_key, $table, $old, $new ) { $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); - $count += $wpdb->update( $table, - array( $col => $value ), - array( $primary_key => $row->$primary_key ) - ); + if ( $dry_run ) { + if ( $value != $row->$col ) + $count++; + } else { + $count += $wpdb->update( $table, + array( $col => $value ), + array( $primary_key => $row->$primary_key ) + ); + } } return $count; From ede01c951807b17cbcd640dab01bbb66e35f45ce Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 10:06:14 +0200 Subject: [PATCH 0964/4858] move class-*.php to classes/*.php --- .../cli-upgrader-skin.php} | 0 .../wp-cli-command-with-meta.php} | 0 .../wp-cli-command-with-upgrade.php} | 0 .../wp-cli-command.php} | 0 php/wp-cli/{class-wp-cli.php => classes/wp-cli.php} | 0 php/wp-cli/wp-cli.php | 8 ++++---- 6 files changed, 4 insertions(+), 4 deletions(-) rename php/wp-cli/{class-cli-upgrader-skin.php => classes/cli-upgrader-skin.php} (100%) rename php/wp-cli/{class-wp-cli-command-with-meta.php => classes/wp-cli-command-with-meta.php} (100%) rename php/wp-cli/{class-wp-cli-command-with-upgrade.php => classes/wp-cli-command-with-upgrade.php} (100%) rename php/wp-cli/{class-wp-cli-command.php => classes/wp-cli-command.php} (100%) rename php/wp-cli/{class-wp-cli.php => classes/wp-cli.php} (100%) diff --git a/php/wp-cli/class-cli-upgrader-skin.php b/php/wp-cli/classes/cli-upgrader-skin.php similarity index 100% rename from php/wp-cli/class-cli-upgrader-skin.php rename to php/wp-cli/classes/cli-upgrader-skin.php diff --git a/php/wp-cli/class-wp-cli-command-with-meta.php b/php/wp-cli/classes/wp-cli-command-with-meta.php similarity index 100% rename from php/wp-cli/class-wp-cli-command-with-meta.php rename to php/wp-cli/classes/wp-cli-command-with-meta.php diff --git a/php/wp-cli/class-wp-cli-command-with-upgrade.php b/php/wp-cli/classes/wp-cli-command-with-upgrade.php similarity index 100% rename from php/wp-cli/class-wp-cli-command-with-upgrade.php rename to php/wp-cli/classes/wp-cli-command-with-upgrade.php diff --git a/php/wp-cli/class-wp-cli-command.php b/php/wp-cli/classes/wp-cli-command.php similarity index 100% rename from php/wp-cli/class-wp-cli-command.php rename to php/wp-cli/classes/wp-cli-command.php diff --git a/php/wp-cli/class-wp-cli.php b/php/wp-cli/classes/wp-cli.php similarity index 100% rename from php/wp-cli/class-wp-cli.php rename to php/wp-cli/classes/wp-cli.php diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php index 0f7fe59862..a1975559be 100755 --- a/php/wp-cli/wp-cli.php +++ b/php/wp-cli/wp-cli.php @@ -9,10 +9,10 @@ include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; -include WP_CLI_ROOT . 'class-wp-cli.php'; -include WP_CLI_ROOT . 'class-wp-cli-command.php'; -include WP_CLI_ROOT . 'class-wp-cli-command-with-meta.php'; -include WP_CLI_ROOT . 'class-wp-cli-command-with-upgrade.php'; +include WP_CLI_ROOT . 'classes/wp-cli.php'; +include WP_CLI_ROOT . 'classes/wp-cli-command.php'; +include WP_CLI_ROOT . 'classes/wp-cli-command-with-meta.php'; +include WP_CLI_ROOT . 'classes/wp-cli-command-with-upgrade.php'; include WP_CLI_ROOT . 'man.php'; \WP_CLI\Utils\load_cli_tools(); From 05982206e7d5ee1d830716b86af3ef1773c3d4a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 10:37:28 +0200 Subject: [PATCH 0965/4858] add basic autoloader for WP_CLI namespace --- php/wp-cli/utils.php | 17 +++++++++++++++++ php/wp-cli/wp-cli.php | 1 + 2 files changed, 18 insertions(+) diff --git a/php/wp-cli/utils.php b/php/wp-cli/utils.php index 344e14f522..c6344d9615 100644 --- a/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -25,6 +25,23 @@ function load_cli_tools() { } } +function register_autoload() { + spl_autoload_register( function($class) { + // Only attempt to load classes in our namespace + if ( 0 !== strpos( $class, 'WP_CLI\\' ) ) { + return; + } + + $base = WP_CLI_ROOT . 'classes/'; + + $path = $base . str_replace( 'WP_CLI\\', '', $class ) . '.php'; + + if ( is_file( $path ) ) { + require_once $path; + } + } ); +} + /** * Splits $argv into positional and associative arguments. * diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php index a1975559be..93f2fe0332 100755 --- a/php/wp-cli/wp-cli.php +++ b/php/wp-cli/wp-cli.php @@ -15,6 +15,7 @@ include WP_CLI_ROOT . 'classes/wp-cli-command-with-upgrade.php'; include WP_CLI_ROOT . 'man.php'; +\WP_CLI\Utils\register_autoload(); \WP_CLI\Utils\load_cli_tools(); WP_CLI::before_wp_load(); From 20fb2432bb52e2354322bb0f41d5d47fe591af80 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 10:38:28 +0200 Subject: [PATCH 0966/4858] autoload upgrader classes CLI_Upgrader_Skin -> WP_CLI\UpgraderSkin Non_Destructive_Core_Upgrader -> WP_CLI\NonDestructiveCoreUpgrader --- .../classes/NonDestructiveCoreUpgrader.php | 15 +++++++++++++++ ...{cli-upgrader-skin.php => UpgraderSkin.php} | 18 +++++------------- php/wp-cli/commands/core.php | 2 +- php/wp-cli/utils.php | 4 +--- 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 php/wp-cli/classes/NonDestructiveCoreUpgrader.php rename php/wp-cli/classes/{cli-upgrader-skin.php => UpgraderSkin.php} (68%) diff --git a/php/wp-cli/classes/NonDestructiveCoreUpgrader.php b/php/wp-cli/classes/NonDestructiveCoreUpgrader.php new file mode 100644 index 0000000000..41ba059493 --- /dev/null +++ b/php/wp-cli/classes/NonDestructiveCoreUpgrader.php @@ -0,0 +1,15 @@ +<?php + +namespace WP_CLI; + +/** + * A Core Upgrader class that leaves packages intact by default. + * + * @package wp-cli + */ +class NonDestructiveCoreUpgrader extends \Core_Upgrader { + function unpack_package($package, $delete_package = false) { + return parent::unpack_package( $package, $delete_package ); + } +} + diff --git a/php/wp-cli/classes/cli-upgrader-skin.php b/php/wp-cli/classes/UpgraderSkin.php similarity index 68% rename from php/wp-cli/classes/cli-upgrader-skin.php rename to php/wp-cli/classes/UpgraderSkin.php index 0b9871a904..aa56b43486 100644 --- a/php/wp-cli/classes/cli-upgrader-skin.php +++ b/php/wp-cli/classes/UpgraderSkin.php @@ -1,11 +1,13 @@ <?php +namespace WP_CLI; + /** * A Upgrader Skin for WordPress that only generates plain-text * * @package wp-cli */ -class CLI_Upgrader_Skin extends WP_Upgrader_Skin { +class UpgraderSkin extends \WP_Upgrader_Skin { function header() {} function footer() {} @@ -20,7 +22,7 @@ function error( $error ) { $error = $this->upgrader->strings[ $error ]; // TODO: show all errors, not just the first one - WP_CLI::warning( $error ); + \WP_CLI::warning( $error ); } function feedback( $string ) { @@ -39,17 +41,7 @@ function feedback( $string ) { $string = str_replace( '…', '...', strip_tags( $string ) ); - WP_CLI::line( $string ); + \WP_CLI::line( $string ); } } -/** - * A Core Upgrader class that leaves packages intact by default. - * - * @package wp-cli - */ -class Non_Destructive_Core_Upgrader extends Core_Upgrader { - function unpack_package($package, $delete_package = false) { - return parent::unpack_package( $package, $delete_package ); - } -} diff --git a/php/wp-cli/commands/core.php b/php/wp-cli/commands/core.php index 5b1d3b653d..63894f4c09 100644 --- a/php/wp-cli/commands/core.php +++ b/php/wp-cli/commands/core.php @@ -243,7 +243,7 @@ function update( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { $new_package = $args[0]; - $upgrader = 'Non_Destructive_Core_Upgrader'; + $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; } $update = (object) array( diff --git a/php/wp-cli/utils.php b/php/wp-cli/utils.php index c6344d9615..1703ba4a01 100644 --- a/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -207,9 +207,7 @@ function get_upgrader( $class ) { if ( !class_exists( '\WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - require WP_CLI_ROOT . '/class-cli-upgrader-skin.php'; - - return new $class( new \CLI_Upgrader_Skin ); + return new $class( new \WP_CLI\UpgraderSkin ); } function parse_csv( $filepath, $has_headers = true ) { From 053c40b66a53c9aeceffb2e0c7ed2c90eebdf01d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 10:48:11 +0200 Subject: [PATCH 0967/4858] WP_CLI_Command_With_Meta -> \WP_CLI\CommandWithMeta --- ...mand-with-meta.php => CommandWithMeta.php} | 26 ++++++++++--------- php/wp-cli/commands/post-meta.php | 6 ++--- php/wp-cli/commands/user-meta.php | 6 ++--- php/wp-cli/wp-cli.php | 1 - 4 files changed, 20 insertions(+), 19 deletions(-) rename php/wp-cli/classes/{wp-cli-command-with-meta.php => CommandWithMeta.php} (56%) diff --git a/php/wp-cli/classes/wp-cli-command-with-meta.php b/php/wp-cli/classes/CommandWithMeta.php similarity index 56% rename from php/wp-cli/classes/wp-cli-command-with-meta.php rename to php/wp-cli/classes/CommandWithMeta.php index 7a18853b3c..3ec480e14f 100644 --- a/php/wp-cli/classes/wp-cli-command-with-meta.php +++ b/php/wp-cli/classes/CommandWithMeta.php @@ -1,11 +1,13 @@ <?php +namespace WP_CLI; + /** * Base class for WP-CLI commands that deal with metadata * * @package wp-cli */ -abstract class WP_CLI_Command_With_Meta extends WP_CLI_Command { +abstract class CommandWithMeta extends \WP_CLI_Command { protected $meta_type; @@ -17,12 +19,12 @@ abstract class WP_CLI_Command_With_Meta extends WP_CLI_Command { public function get( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $value = get_metadata( $this->meta_type, $object_id, $meta_key, true ); + $value = \get_metadata( $this->meta_type, $object_id, $meta_key, true ); if ( '' === $value ) die(1); - WP_CLI::print_value( $value, $assoc_args ); + \WP_CLI::print_value( $value, $assoc_args ); } /** @@ -33,12 +35,12 @@ public function get( $args, $assoc_args ) { public function delete( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $success = delete_metadata( $this->meta_type, $object_id, $meta_key ); + $success = \delete_metadata( $this->meta_type, $object_id, $meta_key ); if ( $success ) { - WP_CLI::success( "Deleted custom field." ); + \WP_CLI::success( "Deleted custom field." ); } else { - WP_CLI::error( "Failed to delete custom field." ); + \WP_CLI::error( "Failed to delete custom field." ); } } @@ -50,12 +52,12 @@ public function delete( $args, $assoc_args ) { public function add( $args, $assoc_args ) { list( $object_id, $meta_key, $meta_value ) = $args; - $success = add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $success = \add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { - WP_CLI::success( "Added custom field." ); + \WP_CLI::success( "Added custom field." ); } else { - WP_CLI::error( "Failed to add custom field." ); + \WP_CLI::error( "Failed to add custom field." ); } } @@ -68,12 +70,12 @@ public function add( $args, $assoc_args ) { public function update( $args, $assoc_args ) { list( $object_id, $meta_key, $meta_value ) = $args; - $success = update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { - WP_CLI::success( "Updated custom field." ); + \WP_CLI::success( "Updated custom field." ); } else { - WP_CLI::error( "Failed to update custom field." ); + \WP_CLI::error( "Failed to update custom field." ); } } } diff --git a/php/wp-cli/commands/post-meta.php b/php/wp-cli/commands/post-meta.php index 466468eab8..a987ac4b35 100644 --- a/php/wp-cli/commands/post-meta.php +++ b/php/wp-cli/commands/post-meta.php @@ -1,14 +1,14 @@ <?php -WP_CLI::add_command( 'post-meta', 'Post_Meta_Command' ); - /** * Manage post custom fields. * * @package wp-cli * @subpackage commands/internals */ -class Post_Meta_Command extends WP_CLI_Command_With_Meta { +class Post_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'post'; } +WP_CLI::add_command( 'post-meta', 'Post_Meta_Command' ); + diff --git a/php/wp-cli/commands/user-meta.php b/php/wp-cli/commands/user-meta.php index 58fa75e8ca..6fe4ed794d 100644 --- a/php/wp-cli/commands/user-meta.php +++ b/php/wp-cli/commands/user-meta.php @@ -1,14 +1,14 @@ <?php -WP_CLI::add_command( 'user-meta', 'User_Meta_Command' ); - /** * Manage user custom fields. * * @package wp-cli * @subpackage commands/internals */ -class User_Meta_Command extends WP_CLI_Command_With_Meta { +class User_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'user'; } +WP_CLI::add_command( 'user-meta', 'User_Meta_Command' ); + diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php index 93f2fe0332..9d90a68e27 100755 --- a/php/wp-cli/wp-cli.php +++ b/php/wp-cli/wp-cli.php @@ -11,7 +11,6 @@ include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'classes/wp-cli.php'; include WP_CLI_ROOT . 'classes/wp-cli-command.php'; -include WP_CLI_ROOT . 'classes/wp-cli-command-with-meta.php'; include WP_CLI_ROOT . 'classes/wp-cli-command-with-upgrade.php'; include WP_CLI_ROOT . 'man.php'; From dfaa657a931eb54d4b9f817ad7e125a9735ddcd7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 10:52:47 +0200 Subject: [PATCH 0968/4858] WP_CLI_Command_With_Upgrade -> \WP_CLI\CommandWithUpgrade --- ...ith-upgrade.php => CommandWithUpgrade.php} | 30 ++++++++++--------- php/wp-cli/commands/plugin.php | 7 +++-- php/wp-cli/commands/theme.php | 7 +++-- php/wp-cli/wp-cli.php | 1 - 4 files changed, 24 insertions(+), 21 deletions(-) rename php/wp-cli/classes/{wp-cli-command-with-upgrade.php => CommandWithUpgrade.php} (85%) diff --git a/php/wp-cli/classes/wp-cli-command-with-upgrade.php b/php/wp-cli/classes/CommandWithUpgrade.php similarity index 85% rename from php/wp-cli/classes/wp-cli-command-with-upgrade.php rename to php/wp-cli/classes/CommandWithUpgrade.php index b84bcb7e1d..1cf052645f 100644 --- a/php/wp-cli/classes/wp-cli-command-with-upgrade.php +++ b/php/wp-cli/classes/CommandWithUpgrade.php @@ -1,6 +1,8 @@ <?php -abstract class WP_CLI_Command_With_Upgrade extends WP_CLI_Command { +namespace WP_CLI; + +abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $item_type; protected $upgrader; @@ -38,7 +40,7 @@ private function status_all() { $n = count( $items ); // Not interested in the translation, just the number logic - WP_CLI::line( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); + \WP_CLI::line( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); foreach ( $items as $file => $details ) { if ( $details['update'] ) { @@ -50,10 +52,10 @@ private function status_all() { $line .= $this->format_status( $details['status'], 'short' ); $line .= " " . $details['name'] . "%n"; - WP_CLI::line( $line ); + \WP_CLI::line( $line ); } - WP_CLI::line(); + \WP_CLI::line(); $this->show_legend( $items ); } @@ -74,7 +76,7 @@ private function show_legend( $items ) { if ( in_array( true, wp_list_pluck( $items, 'update' ) ) ) $legend_line[] = '%yU = Update Available%n'; - WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); + \WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } private function status_single( $file, $name ) { @@ -92,7 +94,7 @@ private function status_single( $file, $name ) { function install( $args, $assoc_args ) { if ( empty( $args ) ) { - WP_CLI::line( "usage: wp $this->item_type install <slug>" ); + \WP_CLI::line( "usage: wp $this->item_type install <slug>" ); exit; } @@ -102,13 +104,13 @@ function install( $args, $assoc_args ) { $slug = stripslashes( $args[0] ); if ( '.zip' == substr( $slug, -4 ) ) { - $file_upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); + $file_upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); if ( $file_upgrader->install( $slug ) ) { $slug = $file_upgrader->result['destination_name']; if ( isset( $assoc_args['activate'] ) ) { - WP_CLI::line( "Activating '$slug'..." ); + \WP_CLI::line( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } } else { @@ -122,7 +124,7 @@ function install( $args, $assoc_args ) { protected function _update( $item ) { call_user_func( $this->upgrade_refresh ); - WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $item ); + \WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $item ); } function update_all( $args, $assoc_args ) { @@ -143,11 +145,11 @@ function update_all( $args, $assoc_args ) { } } - WP_CLI::line( $item_list ); + \WP_CLI::line( $item_list ); return; } - $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); + $upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); // Let the user know the results. @@ -157,11 +159,11 @@ function update_all( $args, $assoc_args ) { $line = "Updated $num_updated/$num_to_update {$this->item_type}s."; if ( $num_to_update == $num_updated ) { - WP_CLI::success( $line ); + \WP_CLI::success( $line ); } else if ( $num_updated > 0 ) { - WP_CLI::warning( $line ); + \WP_CLI::warning( $line ); } else { - WP_CLI::error( $line ); + \WP_CLI::error( $line ); } } diff --git a/php/wp-cli/commands/plugin.php b/php/wp-cli/commands/plugin.php index 06780e8340..047401d8fe 100644 --- a/php/wp-cli/commands/plugin.php +++ b/php/wp-cli/commands/plugin.php @@ -1,14 +1,12 @@ <?php -WP_CLI::add_command('plugin', 'Plugin_Command'); - /** * Implement plugin command * * @package wp-cli * @subpackage commands/internals */ -class Plugin_Command extends WP_CLI_Command_With_Upgrade { +class Plugin_Command extends \WP_CLI\CommandWithUpgrade { protected $item_type = 'plugin'; protected $upgrader = 'Plugin_Upgrader'; @@ -347,3 +345,6 @@ private function get_name( $file ) { return $name; } } + +WP_CLI::add_command( 'plugin', 'Plugin_Command' ); + diff --git a/php/wp-cli/commands/theme.php b/php/wp-cli/commands/theme.php index 5f64beb662..8837f8c997 100644 --- a/php/wp-cli/commands/theme.php +++ b/php/wp-cli/commands/theme.php @@ -1,14 +1,12 @@ <?php -WP_CLI::add_command('theme', 'Theme_Command'); - /** * Implement theme command * * @package wp-cli * @subpackage commands/internals */ -class Theme_Command extends WP_CLI_Command_With_Upgrade { +class Theme_Command extends \WP_CLI\CommandWithUpgrade { protected $item_type = 'theme'; protected $upgrader = 'Theme_Upgrader'; @@ -223,3 +221,6 @@ protected function get_stylesheet_path( $theme ) { return WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'; } } + +WP_CLI::add_command( 'theme', 'Theme_Command' ); + diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php index 9d90a68e27..81056eb3bf 100755 --- a/php/wp-cli/wp-cli.php +++ b/php/wp-cli/wp-cli.php @@ -11,7 +11,6 @@ include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'classes/wp-cli.php'; include WP_CLI_ROOT . 'classes/wp-cli-command.php'; -include WP_CLI_ROOT . 'classes/wp-cli-command-with-upgrade.php'; include WP_CLI_ROOT . 'man.php'; \WP_CLI\Utils\register_autoload(); From 5f3a5cec36acec6a0460084f0bf80c22450e9b72 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 10:56:17 +0200 Subject: [PATCH 0969/4858] move DocParser class to separate file --- php/wp-cli/classes/DocParser.php | 34 +++++++++++++++++++++++++++++ php/wp-cli/dispatcher.php | 37 +++----------------------------- 2 files changed, 37 insertions(+), 34 deletions(-) create mode 100644 php/wp-cli/classes/DocParser.php diff --git a/php/wp-cli/classes/DocParser.php b/php/wp-cli/classes/DocParser.php new file mode 100644 index 0000000000..cb891d19d5 --- /dev/null +++ b/php/wp-cli/classes/DocParser.php @@ -0,0 +1,34 @@ +<?php + +namespace WP_CLI; + +class DocParser { + + protected $docComment; + + function __construct( $reflection ) { + $this->docComment = $reflection->getDocComment(); + } + + function get_shortdesc() { + if ( !preg_match( '/\* (\w.+)\n*/', $this->docComment, $matches ) ) + return false; + + return $matches[1]; + } + + function get_tag( $name ) { + if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $this->docComment, $matches ) ) + return $matches[1]; + + return false; + } + + function get_synopsis() { + if ( !preg_match( '/@synopsis\s+([^\n]+)/', $this->docComment, $matches ) ) + return false; + + return $matches[1]; + } +} + diff --git a/php/wp-cli/dispatcher.php b/php/wp-cli/dispatcher.php index 6077a49c86..20b71a3988 100644 --- a/php/wp-cli/dispatcher.php +++ b/php/wp-cli/dispatcher.php @@ -18,37 +18,6 @@ function traverse( &$args, $method = 'find_subcommand' ) { } -class DocParser { - - protected $docComment; - - function __construct( $reflection ) { - $this->docComment = $reflection->getDocComment(); - } - - function get_shortdesc() { - if ( !preg_match( '/\* (\w.+)\n*/', $this->docComment, $matches ) ) - return false; - - return $matches[1]; - } - - function get_tag( $name ) { - if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $this->docComment, $matches ) ) - return $matches[1]; - - return false; - } - - function get_synopsis() { - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $this->docComment, $matches ) ) - return false; - - return $matches[1]; - } -} - - interface Command { function get_path(); @@ -145,7 +114,7 @@ function add_command( $name, $implementation ) { else { $method = new \ReflectionMethod( $implementation, '__invoke' ); - $docparser = new DocParser( $method ); + $docparser = new \WP_CLI\DocParser( $method ); $command = new Subcommand( $name, $implementation, $docparser, $this ); } @@ -203,7 +172,7 @@ public function __construct( $name, $class ) { $this->subcommands = $this->collect_subcommands( $reflection, $class ); - $this->docparser = new DocParser( $reflection ); + $this->docparser = new \WP_CLI\DocParser( $reflection ); } private function collect_subcommands( $reflection, $class ) { @@ -488,7 +457,7 @@ class MethodSubcommand extends Subcommand { function __construct( $class, $method, $parent ) { $callable = array( new $class, $method->name ); - $docparser = new DocParser( $method ); + $docparser = new \WP_CLI\DocParser( $method ); $name = $docparser->get_tag( 'subcommand' ); if ( !$name ) From 4de395b07ff73066f8f36d21f21e32741b95e951 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 11:18:28 +0200 Subject: [PATCH 0970/4858] move Dispatcher classes to separate files --- .../classes/Dispatcher/CompositeCommand.php | 126 +++++ .../classes/Dispatcher/MethodSubcommand.php | 23 + php/wp-cli/classes/Dispatcher/RootCommand.php | 118 +++++ php/wp-cli/classes/Dispatcher/Subcommand.php | 175 +++++++ php/wp-cli/classes/wp-cli.php | 6 +- php/wp-cli/dispatcher.php | 430 ------------------ php/wp-cli/utils.php | 4 +- 7 files changed, 448 insertions(+), 434 deletions(-) create mode 100644 php/wp-cli/classes/Dispatcher/CompositeCommand.php create mode 100644 php/wp-cli/classes/Dispatcher/MethodSubcommand.php create mode 100644 php/wp-cli/classes/Dispatcher/RootCommand.php create mode 100644 php/wp-cli/classes/Dispatcher/Subcommand.php diff --git a/php/wp-cli/classes/Dispatcher/CompositeCommand.php b/php/wp-cli/classes/Dispatcher/CompositeCommand.php new file mode 100644 index 0000000000..23ff3cf36d --- /dev/null +++ b/php/wp-cli/classes/Dispatcher/CompositeCommand.php @@ -0,0 +1,126 @@ +<?php + +namespace WP_CLI\Dispatcher; + +class CompositeCommand implements Command, Composite, Documentable { + + protected $name; + + protected $subcommands; + + protected $shortdesc; + + public function __construct( $name, $class ) { + $this->name = $name; + + $reflection = new \ReflectionClass( $class ); + + $this->subcommands = $this->collect_subcommands( $reflection, $class ); + + $this->docparser = new \WP_CLI\DocParser( $reflection ); + } + + private function collect_subcommands( $reflection, $class ) { + $subcommands = array(); + + foreach ( $reflection->getMethods() as $method ) { + if ( !self::_is_good_method( $method ) ) + continue; + + $subcommand = new MethodSubcommand( $class, $method, $this ); + + $subcommands[ $subcommand->get_name() ] = $subcommand; + } + + return $subcommands; + } + + function get_path() { + return array( $this->name ); + } + + function show_usage() { + $methods = $this->get_subcommands(); + + $i = 0; + + foreach ( $methods as $name => $subcommand ) { + $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; + + $subcommand->show_usage( $prefix ); + } + + \WP_CLI::line(); + \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); + } + + function invoke( $args, $assoc_args ) { + $subcommand = $this->pre_invoke( $args ); + $subcommand->invoke( $args, $assoc_args ); + } + + function pre_invoke( &$args ) { + $subcommand = $this->find_subcommand( $args ); + + if ( !$subcommand ) { + $this->show_usage(); + exit; + } + + return $subcommand; + } + + function find_subcommand( &$args ) { + $name = array_shift( $args ); + + $subcommands = $this->get_subcommands(); + + if ( !isset( $subcommands[ $name ] ) ) { + $aliases = self::get_aliases( $subcommands ); + + if ( isset( $aliases[ $name ] ) ) { + $name = $aliases[ $name ]; + } + } + + if ( !isset( $subcommands[ $name ] ) ) + return false; + + return $subcommands[ $name ]; + } + + private static function get_aliases( $subcommands ) { + $aliases = array(); + + foreach ( $subcommands as $name => $subcommand ) { + $alias = $subcommand->get_alias(); + if ( $alias ) + $aliases[ $alias ] = $name; + } + + return $aliases; + } + + public function get_subcommands() { + return $this->subcommands; + } + + public function get_shortdesc() { + return $this->docparser->get_shortdesc(); + } + + public function get_full_synopsis() { + $str = array(); + + foreach ( $this->subcommands as $subcommand ) { + $str[] = $subcommand->get_full_synopsis(); + } + + return implode( "\n\n", $str ); + } + + private static function _is_good_method( $method ) { + return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); + } +} + diff --git a/php/wp-cli/classes/Dispatcher/MethodSubcommand.php b/php/wp-cli/classes/Dispatcher/MethodSubcommand.php new file mode 100644 index 0000000000..5ef500c567 --- /dev/null +++ b/php/wp-cli/classes/Dispatcher/MethodSubcommand.php @@ -0,0 +1,23 @@ +<?php + +namespace WP_CLI\Dispatcher; + +class MethodSubcommand extends Subcommand { + + function __construct( $class, $method, $parent ) { + $callable = array( new $class, $method->name ); + + $docparser = new \WP_CLI\DocParser( $method ); + + $name = $docparser->get_tag( 'subcommand' ); + if ( !$name ) + $name = $method->name; + + parent::__construct( $name, $callable, $docparser, $parent ); + } + + function get_alias() { + return $this->docparser->get_tag( 'alias' ); + } +} + diff --git a/php/wp-cli/classes/Dispatcher/RootCommand.php b/php/wp-cli/classes/Dispatcher/RootCommand.php new file mode 100644 index 0000000000..ce8dd38d0a --- /dev/null +++ b/php/wp-cli/classes/Dispatcher/RootCommand.php @@ -0,0 +1,118 @@ +<?php + +namespace WP_CLI\Dispatcher; + +class RootCommand implements Command, Composite { + + protected $subcommands = array(); + + function get_path() { + return array(); + } + + function show_usage() { + \WP_CLI::line( 'Available commands:' ); + + foreach ( $this->get_subcommands() as $command ) { + \WP_CLI::line( sprintf( " wp %s %s", + implode( ' ', $command->get_path() ), + implode( '|', array_keys( $command->get_subcommands() ) ) + ) ); + } + + \WP_CLI::line(<<<EOB + +See 'wp help <command>' for more information on a specific command. + +Global parameters: +--user=<id|login> set the current user +--url=<url> set the current URL +--path=<path> set the current path to the WP install +--require=<path> load a certain file before running the command +--quiet suppress informational messages +--info print wp-cli information +EOB + ); + } + + function invoke( $args, $assoc_args ) { + $subcommand = $this->pre_invoke( $args ); + $subcommand->invoke( $args, $assoc_args ); + } + + function pre_invoke( &$args ) { + if ( empty( $args ) || array( 'help' ) == $args ) { + $this->show_usage(); + exit; + } + + $cmd_name = $args[0]; + $command = $this->find_subcommand( $args ); + + if ( !$command ) + \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $cmd_name ) ); + + return $command; + } + + function find_subcommand( &$args ) { + $command = array_shift( $args ); + + $aliases = array( + 'sql' => 'db' + ); + + if ( isset( $aliases[ $command ] ) ) + $command = $aliases[ $command ]; + + return $this->load_command( $command ); + } + + function add_command( $name, $implementation ) { + if ( is_string( $implementation ) ) + $command = new CompositeCommand( $name, $implementation ); + else { + $method = new \ReflectionMethod( $implementation, '__invoke' ); + + $docparser = new \WP_CLI\DocParser( $method ); + + $command = new Subcommand( $name, $implementation, $docparser, $this ); + } + + $this->subcommands[ $name ] = $command; + } + + function get_subcommands() { + $this->load_all_commands(); + + return $this->subcommands; + } + + protected function load_all_commands() { + foreach ( glob( WP_CLI_ROOT . "/commands/*.php" ) as $filename ) { + $command = substr( basename( $filename ), 0, -4 ); + + if ( isset( $this->subcommands[ $command ] ) ) + continue; + + include $filename; + } + } + + function load_command( $command ) { + if ( !isset( $this->subcommands[$command] ) ) { + $path = WP_CLI_ROOT . "/commands/$command.php"; + + if ( is_readable( $path ) ) { + include $path; + } + } + + if ( !isset( $this->subcommands[$command] ) ) { + return false; + } + + return $this->subcommands[$command]; + } +} + diff --git a/php/wp-cli/classes/Dispatcher/Subcommand.php b/php/wp-cli/classes/Dispatcher/Subcommand.php new file mode 100644 index 0000000000..a6a3d1f976 --- /dev/null +++ b/php/wp-cli/classes/Dispatcher/Subcommand.php @@ -0,0 +1,175 @@ +<?php + +namespace WP_CLI\Dispatcher; + +class Subcommand implements Command, Documentable { + + function __construct( $name, $callable, $docparser, $parent ) { + $this->name = $name; + $this->callable = $callable; + $this->docparser = $docparser; + $this->parent = $parent; + } + + function show_usage( $prefix = 'usage: ' ) { + \WP_CLI::line( $prefix . $this->get_full_synopsis() ); + } + + function get_shortdesc() { + return $this->docparser->get_shortdesc(); + } + + function get_full_synopsis() { + $full_name = implode( ' ', $this->get_path() ); + $synopsis = $this->docparser->get_synopsis(); + + return "wp $full_name $synopsis"; + } + + function invoke( $args, $assoc_args ) { + $this->check_args( $args, $assoc_args ); + + call_user_func( $this->callable, $args, $assoc_args ); + } + + function get_subcommands() { + return array(); + } + + function get_name() { + return $this->name; + } + + function get_path() { + return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); + } + + protected function check_args( $args, $assoc_args ) { + $synopsis = $this->docparser->get_synopsis(); + if ( !$synopsis ) + return; + + $accepted_params = $this->parse_synopsis( $synopsis ); + + $this->check_positional( $args, $accepted_params ); + + $this->check_assoc( $assoc_args, $accepted_params ); + + if ( empty( $accepted_params['generic'] ) ) + $this->check_unknown_assoc( $assoc_args, $accepted_params ); + } + + private function check_positional( $args, $accepted_params ) { + $count = 0; + + foreach ( $accepted_params['positional'] as $param ) { + if ( !$param['optional'] ) + $count++; + } + + if ( count( $args ) < $count ) { + $this->show_usage(); + exit(1); + } + } + + private function check_assoc( $assoc_args, $accepted_params ) { + $mandatory_assoc = array(); + + $assoc_args += \WP_CLI::get_assoc_special(); + + foreach ( $accepted_params['assoc'] as $param ) { + if ( !$param['optional'] ) + $mandatory_assoc[] = $param['name']; + } + + $errors = array(); + + foreach ( $mandatory_assoc as $key ) { + if ( !isset( $assoc_args[ $key ] ) ) + $errors[] = "missing --$key parameter"; + elseif ( true === $assoc_args[ $key ] ) + $errors[] = "--$key parameter needs a value"; + } + + if ( !empty( $errors ) ) { + foreach ( $errors as $error ) { + \WP_CLI::warning( $error ); + } + $this->show_usage(); + exit(1); + } + } + + private function check_unknown_assoc( $assoc_args, $accepted_params ) { + $known_assoc = array(); + + foreach ( array( 'assoc', 'flag' ) as $type ) { + foreach ( $accepted_params[$type] as $param ) { + $known_assoc[] = $param['name']; + } + } + + $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); + + foreach ( $unknown_assoc as $key ) { + \WP_CLI::warning( "unknown --$key parameter" ); + } + } + + protected function parse_synopsis( $synopsis ) { + list( $patterns, $params ) = self::get_patterns(); + + $tokens = preg_split( '/[\s\t]+/', $synopsis ); + + foreach ( $tokens as $token ) { + foreach ( $patterns as $regex => $desc ) { + if ( preg_match( $regex, $token, $matches ) ) { + $type = $desc['type']; + $params[$type][] = array_merge( $matches, $desc ); + break; + } + } + } + + return $params; + } + + private static function get_patterns() { + $p_name = '(?P<name>[a-z-_]+)'; + $p_value = '(?P<value>[a-z-|]+)'; + + $param_types = array( + array( 'positional', "<$p_value>", 1, 1 ), + array( 'generic', "--<field>=<value>", 1, 1 ), + array( 'assoc', "--$p_name=<$p_value>", 1, 1 ), + array( 'flag', "--$p_name", 1, 0 ), + ); + + $patterns = array(); + $params = array(); + + foreach ( $param_types as $pt ) { + list( $type, $pattern, $optional, $mandatory ) = $pt; + + if ( $mandatory ) { + $patterns[ "/^$pattern$/" ] = array( + 'type' => $type, + 'optional' => false + ); + } + + if ( $optional ) { + $patterns[ "/^\[$pattern\]$/" ] = array( + 'type' => $type, + 'optional' => true + ); + } + + $params[ $type ] = array(); + } + + return array( $patterns, $params ); + } +} + diff --git a/php/wp-cli/classes/wp-cli.php b/php/wp-cli/classes/wp-cli.php index 0e5c2dd1b2..652d86a2fb 100644 --- a/php/wp-cli/classes/wp-cli.php +++ b/php/wp-cli/classes/wp-cli.php @@ -1,7 +1,7 @@ <?php -use \WP_CLI\Dispatcher; use \WP_CLI\Utils; +use \WP_CLI\Dispatcher; /** * Wrapper class for WP-CLI @@ -233,6 +233,8 @@ static function get_assoc_special() { } static function before_wp_load() { + self::$root = new Dispatcher\RootCommand; + self::add_man_dir( WP_CLI_ROOT . "../../man/", WP_CLI_ROOT . "../../man-src/" @@ -386,5 +388,3 @@ static function addCommand( $name, $class ) { } } -WP_CLI::$root = new Dispatcher\RootCommand; - diff --git a/php/wp-cli/dispatcher.php b/php/wp-cli/dispatcher.php index 20b71a3988..78e12d4428 100644 --- a/php/wp-cli/dispatcher.php +++ b/php/wp-cli/dispatcher.php @@ -41,433 +41,3 @@ function get_shortdesc(); function get_full_synopsis(); } - -class RootCommand implements Command, Composite { - - protected $subcommands = array(); - - function get_path() { - return array(); - } - - function show_usage() { - \WP_CLI::line( 'Available commands:' ); - - foreach ( $this->get_subcommands() as $command ) { - \WP_CLI::line( sprintf( " wp %s %s", - implode( ' ', $command->get_path() ), - implode( '|', array_keys( $command->get_subcommands() ) ) - ) ); - } - - \WP_CLI::line(<<<EOB - -See 'wp help <command>' for more information on a specific command. - -Global parameters: ---user=<id|login> set the current user ---url=<url> set the current URL ---path=<path> set the current path to the WP install ---require=<path> load a certain file before running the command ---quiet suppress informational messages ---info print wp-cli information -EOB - ); - } - - function invoke( $args, $assoc_args ) { - $subcommand = $this->pre_invoke( $args ); - $subcommand->invoke( $args, $assoc_args ); - } - - function pre_invoke( &$args ) { - if ( empty( $args ) || array( 'help' ) == $args ) { - $this->show_usage(); - exit; - } - - $cmd_name = $args[0]; - $command = $this->find_subcommand( $args ); - - if ( !$command ) - \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $cmd_name ) ); - - return $command; - } - - function find_subcommand( &$args ) { - $command = array_shift( $args ); - - $aliases = array( - 'sql' => 'db' - ); - - if ( isset( $aliases[ $command ] ) ) - $command = $aliases[ $command ]; - - return $this->load_command( $command ); - } - - function add_command( $name, $implementation ) { - if ( is_string( $implementation ) ) - $command = new CompositeCommand( $name, $implementation ); - else { - $method = new \ReflectionMethod( $implementation, '__invoke' ); - - $docparser = new \WP_CLI\DocParser( $method ); - - $command = new Subcommand( $name, $implementation, $docparser, $this ); - } - - $this->subcommands[ $name ] = $command; - } - - function get_subcommands() { - $this->load_all_commands(); - - return $this->subcommands; - } - - protected function load_all_commands() { - foreach ( glob( WP_CLI_ROOT . "/commands/*.php" ) as $filename ) { - $command = substr( basename( $filename ), 0, -4 ); - - if ( isset( $this->subcommands[ $command ] ) ) - continue; - - include $filename; - } - } - - function load_command( $command ) { - if ( !isset( $this->subcommands[$command] ) ) { - $path = WP_CLI_ROOT . "/commands/$command.php"; - - if ( is_readable( $path ) ) { - include $path; - } - } - - if ( !isset( $this->subcommands[$command] ) ) { - return false; - } - - return $this->subcommands[$command]; - } -} - - -class CompositeCommand implements Command, Composite, Documentable { - - protected $name; - - protected $subcommands; - - protected $shortdesc; - - public function __construct( $name, $class ) { - $this->name = $name; - - $reflection = new \ReflectionClass( $class ); - - $this->subcommands = $this->collect_subcommands( $reflection, $class ); - - $this->docparser = new \WP_CLI\DocParser( $reflection ); - } - - private function collect_subcommands( $reflection, $class ) { - $subcommands = array(); - - foreach ( $reflection->getMethods() as $method ) { - if ( !self::_is_good_method( $method ) ) - continue; - - $subcommand = new MethodSubcommand( $class, $method, $this ); - - $subcommands[ $subcommand->get_name() ] = $subcommand; - } - - return $subcommands; - } - - function get_path() { - return array( $this->name ); - } - - function show_usage() { - $methods = $this->get_subcommands(); - - $i = 0; - - foreach ( $methods as $name => $subcommand ) { - $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; - - $subcommand->show_usage( $prefix ); - } - - \WP_CLI::line(); - \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); - } - - function invoke( $args, $assoc_args ) { - $subcommand = $this->pre_invoke( $args ); - $subcommand->invoke( $args, $assoc_args ); - } - - function pre_invoke( &$args ) { - $subcommand = $this->find_subcommand( $args ); - - if ( !$subcommand ) { - $this->show_usage(); - exit; - } - - return $subcommand; - } - - function find_subcommand( &$args ) { - $name = array_shift( $args ); - - $subcommands = $this->get_subcommands(); - - if ( !isset( $subcommands[ $name ] ) ) { - $aliases = self::get_aliases( $subcommands ); - - if ( isset( $aliases[ $name ] ) ) { - $name = $aliases[ $name ]; - } - } - - if ( !isset( $subcommands[ $name ] ) ) - return false; - - return $subcommands[ $name ]; - } - - private static function get_aliases( $subcommands ) { - $aliases = array(); - - foreach ( $subcommands as $name => $subcommand ) { - $alias = $subcommand->get_alias(); - if ( $alias ) - $aliases[ $alias ] = $name; - } - - return $aliases; - } - - public function get_subcommands() { - return $this->subcommands; - } - - public function get_shortdesc() { - return $this->docparser->get_shortdesc(); - } - - public function get_full_synopsis() { - $str = array(); - - foreach ( $this->subcommands as $subcommand ) { - $str[] = $subcommand->get_full_synopsis(); - } - - return implode( "\n\n", $str ); - } - - private static function _is_good_method( $method ) { - return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); - } -} - - -class Subcommand implements Command, Documentable { - - function __construct( $name, $callable, $docparser, $parent ) { - $this->name = $name; - $this->callable = $callable; - $this->docparser = $docparser; - $this->parent = $parent; - } - - function show_usage( $prefix = 'usage: ' ) { - \WP_CLI::line( $prefix . $this->get_full_synopsis() ); - } - - function get_shortdesc() { - return $this->docparser->get_shortdesc(); - } - - function get_full_synopsis() { - $full_name = implode( ' ', $this->get_path() ); - $synopsis = $this->docparser->get_synopsis(); - - return "wp $full_name $synopsis"; - } - - function invoke( $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); - - call_user_func( $this->callable, $args, $assoc_args ); - } - - function get_subcommands() { - return array(); - } - - function get_name() { - return $this->name; - } - - function get_path() { - return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); - } - - protected function check_args( $args, $assoc_args ) { - $synopsis = $this->docparser->get_synopsis(); - if ( !$synopsis ) - return; - - $accepted_params = $this->parse_synopsis( $synopsis ); - - $this->check_positional( $args, $accepted_params ); - - $this->check_assoc( $assoc_args, $accepted_params ); - - if ( empty( $accepted_params['generic'] ) ) - $this->check_unknown_assoc( $assoc_args, $accepted_params ); - } - - private function check_positional( $args, $accepted_params ) { - $count = 0; - - foreach ( $accepted_params['positional'] as $param ) { - if ( !$param['optional'] ) - $count++; - } - - if ( count( $args ) < $count ) { - $this->show_usage(); - exit(1); - } - } - - private function check_assoc( $assoc_args, $accepted_params ) { - $mandatory_assoc = array(); - - $assoc_args += \WP_CLI::get_assoc_special(); - - foreach ( $accepted_params['assoc'] as $param ) { - if ( !$param['optional'] ) - $mandatory_assoc[] = $param['name']; - } - - $errors = array(); - - foreach ( $mandatory_assoc as $key ) { - if ( !isset( $assoc_args[ $key ] ) ) - $errors[] = "missing --$key parameter"; - elseif ( true === $assoc_args[ $key ] ) - $errors[] = "--$key parameter needs a value"; - } - - if ( !empty( $errors ) ) { - foreach ( $errors as $error ) { - \WP_CLI::warning( $error ); - } - $this->show_usage(); - exit(1); - } - } - - private function check_unknown_assoc( $assoc_args, $accepted_params ) { - $known_assoc = array(); - - foreach ( array( 'assoc', 'flag' ) as $type ) { - foreach ( $accepted_params[$type] as $param ) { - $known_assoc[] = $param['name']; - } - } - - $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); - - foreach ( $unknown_assoc as $key ) { - \WP_CLI::warning( "unknown --$key parameter" ); - } - } - - protected function parse_synopsis( $synopsis ) { - list( $patterns, $params ) = self::get_patterns(); - - $tokens = preg_split( '/[\s\t]+/', $synopsis ); - - foreach ( $tokens as $token ) { - foreach ( $patterns as $regex => $desc ) { - if ( preg_match( $regex, $token, $matches ) ) { - $type = $desc['type']; - $params[$type][] = array_merge( $matches, $desc ); - break; - } - } - } - - return $params; - } - - private static function get_patterns() { - $p_name = '(?P<name>[a-z-_]+)'; - $p_value = '(?P<value>[a-z-|]+)'; - - $param_types = array( - array( 'positional', "<$p_value>", 1, 1 ), - array( 'generic', "--<field>=<value>", 1, 1 ), - array( 'assoc', "--$p_name=<$p_value>", 1, 1 ), - array( 'flag', "--$p_name", 1, 0 ), - ); - - $patterns = array(); - $params = array(); - - foreach ( $param_types as $pt ) { - list( $type, $pattern, $optional, $mandatory ) = $pt; - - if ( $mandatory ) { - $patterns[ "/^$pattern$/" ] = array( - 'type' => $type, - 'optional' => false - ); - } - - if ( $optional ) { - $patterns[ "/^\[$pattern\]$/" ] = array( - 'type' => $type, - 'optional' => true - ); - } - - $params[ $type ] = array(); - } - - return array( $patterns, $params ); - } -} - - -class MethodSubcommand extends Subcommand { - - function __construct( $class, $method, $parent ) { - $callable = array( new $class, $method->name ); - - $docparser = new \WP_CLI\DocParser( $method ); - - $name = $docparser->get_tag( 'subcommand' ); - if ( !$name ) - $name = $method->name; - - parent::__construct( $name, $callable, $docparser, $parent ); - } - - function get_alias() { - return $this->docparser->get_tag( 'alias' ); - } -} - diff --git a/php/wp-cli/utils.php b/php/wp-cli/utils.php index 1703ba4a01..1224db9909 100644 --- a/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -34,7 +34,9 @@ function register_autoload() { $base = WP_CLI_ROOT . 'classes/'; - $path = $base . str_replace( 'WP_CLI\\', '', $class ) . '.php'; + $class = str_replace( 'WP_CLI\\', '', $class ); + + $path = $base . str_replace( '\\', DIRECTORY_SEPARATOR, $class ) . '.php'; if ( is_file( $path ) ) { require_once $path; From 113a3760f185faef7924b9a2291c0848d6193571 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 11:20:19 +0200 Subject: [PATCH 0971/4858] move non-namespaceable classes out of /classes/ folder --- .../{classes/wp-cli-command.php => class-wp-cli-command.php} | 0 php/wp-cli/{classes/wp-cli.php => class-wp-cli.php} | 0 php/wp-cli/wp-cli.php | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename php/wp-cli/{classes/wp-cli-command.php => class-wp-cli-command.php} (100%) rename php/wp-cli/{classes/wp-cli.php => class-wp-cli.php} (100%) diff --git a/php/wp-cli/classes/wp-cli-command.php b/php/wp-cli/class-wp-cli-command.php similarity index 100% rename from php/wp-cli/classes/wp-cli-command.php rename to php/wp-cli/class-wp-cli-command.php diff --git a/php/wp-cli/classes/wp-cli.php b/php/wp-cli/class-wp-cli.php similarity index 100% rename from php/wp-cli/classes/wp-cli.php rename to php/wp-cli/class-wp-cli.php diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php index 81056eb3bf..ff4987d5ba 100755 --- a/php/wp-cli/wp-cli.php +++ b/php/wp-cli/wp-cli.php @@ -9,8 +9,8 @@ include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; -include WP_CLI_ROOT . 'classes/wp-cli.php'; -include WP_CLI_ROOT . 'classes/wp-cli-command.php'; +include WP_CLI_ROOT . 'class-wp-cli.php'; +include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'man.php'; \WP_CLI\Utils\register_autoload(); From 4f7a23cf440c88c201a2655a849d854bf1f2ec10 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 11:24:10 +0200 Subject: [PATCH 0972/4858] make autoloader PSR-0 --- php/wp-cli/{classes => WP_CLI}/CommandWithMeta.php | 0 php/wp-cli/{classes => WP_CLI}/CommandWithUpgrade.php | 0 .../{classes => WP_CLI}/Dispatcher/CompositeCommand.php | 0 .../{classes => WP_CLI}/Dispatcher/MethodSubcommand.php | 0 php/wp-cli/{classes => WP_CLI}/Dispatcher/RootCommand.php | 0 php/wp-cli/{classes => WP_CLI}/Dispatcher/Subcommand.php | 0 php/wp-cli/{classes => WP_CLI}/DocParser.php | 0 .../{classes => WP_CLI}/NonDestructiveCoreUpgrader.php | 0 php/wp-cli/{classes => WP_CLI}/UpgraderSkin.php | 0 php/wp-cli/utils.php | 6 +----- 10 files changed, 1 insertion(+), 5 deletions(-) rename php/wp-cli/{classes => WP_CLI}/CommandWithMeta.php (100%) rename php/wp-cli/{classes => WP_CLI}/CommandWithUpgrade.php (100%) rename php/wp-cli/{classes => WP_CLI}/Dispatcher/CompositeCommand.php (100%) rename php/wp-cli/{classes => WP_CLI}/Dispatcher/MethodSubcommand.php (100%) rename php/wp-cli/{classes => WP_CLI}/Dispatcher/RootCommand.php (100%) rename php/wp-cli/{classes => WP_CLI}/Dispatcher/Subcommand.php (100%) rename php/wp-cli/{classes => WP_CLI}/DocParser.php (100%) rename php/wp-cli/{classes => WP_CLI}/NonDestructiveCoreUpgrader.php (100%) rename php/wp-cli/{classes => WP_CLI}/UpgraderSkin.php (100%) diff --git a/php/wp-cli/classes/CommandWithMeta.php b/php/wp-cli/WP_CLI/CommandWithMeta.php similarity index 100% rename from php/wp-cli/classes/CommandWithMeta.php rename to php/wp-cli/WP_CLI/CommandWithMeta.php diff --git a/php/wp-cli/classes/CommandWithUpgrade.php b/php/wp-cli/WP_CLI/CommandWithUpgrade.php similarity index 100% rename from php/wp-cli/classes/CommandWithUpgrade.php rename to php/wp-cli/WP_CLI/CommandWithUpgrade.php diff --git a/php/wp-cli/classes/Dispatcher/CompositeCommand.php b/php/wp-cli/WP_CLI/Dispatcher/CompositeCommand.php similarity index 100% rename from php/wp-cli/classes/Dispatcher/CompositeCommand.php rename to php/wp-cli/WP_CLI/Dispatcher/CompositeCommand.php diff --git a/php/wp-cli/classes/Dispatcher/MethodSubcommand.php b/php/wp-cli/WP_CLI/Dispatcher/MethodSubcommand.php similarity index 100% rename from php/wp-cli/classes/Dispatcher/MethodSubcommand.php rename to php/wp-cli/WP_CLI/Dispatcher/MethodSubcommand.php diff --git a/php/wp-cli/classes/Dispatcher/RootCommand.php b/php/wp-cli/WP_CLI/Dispatcher/RootCommand.php similarity index 100% rename from php/wp-cli/classes/Dispatcher/RootCommand.php rename to php/wp-cli/WP_CLI/Dispatcher/RootCommand.php diff --git a/php/wp-cli/classes/Dispatcher/Subcommand.php b/php/wp-cli/WP_CLI/Dispatcher/Subcommand.php similarity index 100% rename from php/wp-cli/classes/Dispatcher/Subcommand.php rename to php/wp-cli/WP_CLI/Dispatcher/Subcommand.php diff --git a/php/wp-cli/classes/DocParser.php b/php/wp-cli/WP_CLI/DocParser.php similarity index 100% rename from php/wp-cli/classes/DocParser.php rename to php/wp-cli/WP_CLI/DocParser.php diff --git a/php/wp-cli/classes/NonDestructiveCoreUpgrader.php b/php/wp-cli/WP_CLI/NonDestructiveCoreUpgrader.php similarity index 100% rename from php/wp-cli/classes/NonDestructiveCoreUpgrader.php rename to php/wp-cli/WP_CLI/NonDestructiveCoreUpgrader.php diff --git a/php/wp-cli/classes/UpgraderSkin.php b/php/wp-cli/WP_CLI/UpgraderSkin.php similarity index 100% rename from php/wp-cli/classes/UpgraderSkin.php rename to php/wp-cli/WP_CLI/UpgraderSkin.php diff --git a/php/wp-cli/utils.php b/php/wp-cli/utils.php index 1224db9909..752758d3e1 100644 --- a/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -32,11 +32,7 @@ function register_autoload() { return; } - $base = WP_CLI_ROOT . 'classes/'; - - $class = str_replace( 'WP_CLI\\', '', $class ); - - $path = $base . str_replace( '\\', DIRECTORY_SEPARATOR, $class ) . '.php'; + $path = WP_CLI_ROOT . str_replace( '\\', DIRECTORY_SEPARATOR, $class ) . '.php'; if ( is_file( $path ) ) { require_once $path; From 9873b894b2844e46a3165d11904ec561a1eba9b4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 11:28:22 +0200 Subject: [PATCH 0973/4858] Use Composer's autoloader, when available --- composer.json | 3 +++ php/wp-cli/utils.php | 9 +++++---- php/wp-cli/wp-cli.php | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 2cb9f8c819..62e97907db 100644 --- a/composer.json +++ b/composer.json @@ -14,5 +14,8 @@ "require-dev": { "phpunit/phpunit": "3.7.x" }, + "autoload": { + "psr-0": { "WP_CLI": "php/wp-cli" } + }, "minimum-stability": "dev" } diff --git a/php/wp-cli/utils.php b/php/wp-cli/utils.php index 752758d3e1..a10ba516ad 100644 --- a/php/wp-cli/utils.php +++ b/php/wp-cli/utils.php @@ -2,26 +2,27 @@ namespace WP_CLI\Utils; -function load_cli_tools() { +function bootstrap() { $vendor_paths = array( WP_CLI_ROOT . '../../../../../vendor', // part of a larger project WP_CLI_ROOT . '../../vendor', // top-level project ); - $found = false; + $has_autoload = false; foreach ( $vendor_paths as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; include $vendor_path . '/wp-cli/php-cli-tools/lib/cli/cli.php'; - $found = true; + $has_autoload = true; break; } } - if ( !$found ) { + if ( !$has_autoload ) { include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); + register_autoload(); } } diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli/wp-cli.php index ff4987d5ba..a248bdb28a 100755 --- a/php/wp-cli/wp-cli.php +++ b/php/wp-cli/wp-cli.php @@ -13,8 +13,7 @@ include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'man.php'; -\WP_CLI\Utils\register_autoload(); -\WP_CLI\Utils\load_cli_tools(); +\WP_CLI\Utils\bootstrap(); WP_CLI::before_wp_load(); From be8b90833e89dc8bb1ee16001fe4d616630f488d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 11:48:00 +0200 Subject: [PATCH 0974/4858] autoload query iterator classes --- .gitmodules | 3 - php/query-iterators | 1 - php/wp-cli/WP_CLI/QueryIterator.php | 100 +++++++++++++++++++++++++ php/wp-cli/WP_CLI/TableIterator.php | 81 ++++++++++++++++++++ php/wp-cli/commands/search-replace.php | 4 +- 5 files changed, 182 insertions(+), 7 deletions(-) delete mode 160000 php/query-iterators create mode 100644 php/wp-cli/WP_CLI/QueryIterator.php create mode 100644 php/wp-cli/WP_CLI/TableIterator.php diff --git a/.gitmodules b/.gitmodules index d70ec97df1..bf7ca3df3d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "php/php-cli-tools"] path = php/php-cli-tools url = git://github.com/wp-cli/php-cli-tools.git -[submodule "php/query-iterators"] - path = php/query-iterators - url = https://gist.github.com/4378217.git diff --git a/php/query-iterators b/php/query-iterators deleted file mode 160000 index 7cb209489a..0000000000 --- a/php/query-iterators +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7cb209489a356c6b18bb910a291df13a6c258b96 diff --git a/php/wp-cli/WP_CLI/QueryIterator.php b/php/wp-cli/WP_CLI/QueryIterator.php new file mode 100644 index 0000000000..3962d11088 --- /dev/null +++ b/php/wp-cli/WP_CLI/QueryIterator.php @@ -0,0 +1,100 @@ +<?php + +namespace WP_CLI; + +/** + * Iterates over results of a query, split into many queries via LIMIT and OFFSET + * + * @source https://gist.github.com/4060005 + */ +class QueryIterator implements \Iterator { + + private $limit = 500; + private $query = ''; + + private $global_index = 0; + private $index_in_results = 0; + private $results = array(); + private $offset = 0; + private $db = null; + private $depleted = false; + + /** + * Creates a new query iterator + * + * This will loop over all users, but will retrieve them 100 by 100: + * <code> + * foreach( new QueryIterator( array( 'query' => 'SELECT * FROM users', 'limit' => 100 ) ) as $user ) { + * tickle( $user ); + * } + * </code> + * + * + * @param array $args Supported arguments: + * query – the query as a string. It shouldn't include any LIMIT clauses + * limit – (optional) how many rows to retrieve at once, default value is 500 + */ + function __construct( $args = array() ) { + $this->db = $GLOBALS['wpdb']; + foreach( $args as $key => $value ) { + $this->$key = $value; + } + if ( !$this->query ) { + throw new InvalidArgumentException( 'Missing query argument.' ); + } + } + + function load_items_from_db() { + $query = $this->query . sprintf( ' LIMIT %d OFFSET %d', $this->limit, $this->offset ); + $this->results = $this->db->get_results( $query ); + if ( !$this->results ) { + if ( $this->db->last_error ) { + throw new QueryIteratorException( 'Database error: '.$this->db->last_error ); + } else { + return false; + } + } + $this->offset += $this->limit; + return true; + } + + function current() { + return $this->results[$this->index_in_results]; + } + + function key() { + return $this->global_index; + } + + function next() { + $this->index_in_results++; + $this->global_index++; + } + + function rewind() { + $this->results = array(); + $this->global_index = 0; + $this->index_in_results = 0; + $this->offset = 0; + $this->depleted = false; + } + + function valid() { + if ( $this->depleted ) { + return false; + } + if ( !isset( $this->results[$this->index_in_results] ) ) { + $items_loaded = $this->load_items_from_db(); + if ( !$items_loaded ) { + $this->rewind(); + $this->depleted = true; + return false; + } + $this->index_in_results = 0; + } + return true; + } +} + +class QueryIteratorException extends \RuntimeException {} + diff --git a/php/wp-cli/WP_CLI/TableIterator.php b/php/wp-cli/WP_CLI/TableIterator.php new file mode 100644 index 0000000000..ef8bf8905c --- /dev/null +++ b/php/wp-cli/WP_CLI/TableIterator.php @@ -0,0 +1,81 @@ +<?php + +namespace WP_CLI; + +/** + * @source https://gist.github.com/4060005 + */ +class TableIterator extends QueryIterator { + + /** + * Creates an iterator over a database table + * + * <code> + * foreach( new TableIterator( array( 'table' => $wpdb->posts, 'fields' => array( 'ID', 'post_content' ) ) ) as $post ) { + * count_words_for( $post->ID, $post->post_content ); + * } + * </code> + * + * <code> + * foreach( new TableIterator( array( 'table' => $wpdb->posts, 'where' => 'ID = 8 OR post_status = "publish"' ) ) as $post ) { + * … + * } + * </code> + * + * <code> + * foreach( new PostIterator( array( 'table' => $wpdb->posts, 'where' => array( 'post_status' => 'publish', 'post_date_gmt BETWEEN x AND y' ) ) ) as $post ) { + * … + * } + * </code> + * + * + * @param array $args Supported arguments: + * table – the name of the database table + * fields – an array of columns to get from the posst table, * is a valid value and the default + * where – conditions for filtering rows. Supports two formats: + * = string – this will be the where clause + * = array – each element is treated as a condition if it's positional, or as column => value if + * it's a key/value pair. In the latter case the value is automatically quoted and escaped + */ + function __construct( $args = array() ) { + global $wpdb; + + $defaults = array( + 'fields' => array( '*' ), + 'where' => array(), + 'table' => null, + ); + $table = $args['table']; + $args = array_merge( $defaults, $args ); + + $fields = self::build_fields( $args['fields'] ); + $conditions = self::build_where_conditions( $args['where'] ); + $where_sql = $conditions? " WHERE $conditions" : ''; + $query = "SELECT $fields FROM $table $where_sql"; + $parent_args = compact( 'query' ); + if ( isset( $args['limit'] ) ) { + $parent_args['limit'] = $args['limit']; + } + parent::__construct( $parent_args ); + } + + static function build_fields( $fields ) { + return implode( ', ', $fields ); + } + + static function build_where_conditions( $where ) { + global $wpdb; + if ( is_array( $where ) ) { + $conditions = array(); + foreach( $where as $key => $value ) { + if ( is_numeric( $key ) ) + $conditions[] = $value; + else + $conditions[] = $key . ' = "' . $wpdb->escape( $value ) .'"'; + } + $where = implode( ' AND ', $conditions ); + } + return $where; + } +} + diff --git a/php/wp-cli/commands/search-replace.php b/php/wp-cli/commands/search-replace.php index 71bb7d5241..963b211247 100644 --- a/php/wp-cli/commands/search-replace.php +++ b/php/wp-cli/commands/search-replace.php @@ -13,8 +13,6 @@ class Search_Replace_Command extends WP_CLI_Command { * @synopsis <old> <new> [--dry-run] */ public function __invoke( $args, $assoc_args ) { - require_once WP_CLI_ROOT . '../query-iterators/class-table-iterator.php'; - global $wpdb; list( $old, $new ) = $args; @@ -59,7 +57,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry 'limit' => 1000 ); - $it = new TableIterator( $args ); + $it = new \WP_CLI\TableIterator( $args ); $count = 0; From 01dcff1ccad5e9656c67c14b5be05a45642b5414 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 11:56:09 +0200 Subject: [PATCH 0975/4858] move everything from /php/wp-cli/ to /php/ --- bin/wp | 2 +- composer.json | 2 +- php/{wp-cli => }/WP_CLI/CommandWithMeta.php | 0 php/{wp-cli => }/WP_CLI/CommandWithUpgrade.php | 0 php/{wp-cli => }/WP_CLI/Dispatcher/CompositeCommand.php | 0 php/{wp-cli => }/WP_CLI/Dispatcher/MethodSubcommand.php | 0 php/{wp-cli => }/WP_CLI/Dispatcher/RootCommand.php | 0 php/{wp-cli => }/WP_CLI/Dispatcher/Subcommand.php | 0 php/{wp-cli => }/WP_CLI/DocParser.php | 0 php/{wp-cli => }/WP_CLI/NonDestructiveCoreUpgrader.php | 0 php/{wp-cli => }/WP_CLI/QueryIterator.php | 0 php/{wp-cli => }/WP_CLI/TableIterator.php | 0 php/{wp-cli => }/WP_CLI/UpgraderSkin.php | 0 php/{wp-cli => }/class-wp-cli-command.php | 0 php/{wp-cli => }/class-wp-cli.php | 0 php/{wp-cli => }/commands/blog.php | 0 php/{wp-cli => }/commands/cache.php | 0 php/{wp-cli => }/commands/cap.php | 0 php/{wp-cli => }/commands/comment.php | 0 php/{wp-cli => }/commands/core.php | 0 php/{wp-cli => }/commands/db.php | 0 php/{wp-cli => }/commands/eval-file.php | 0 php/{wp-cli => }/commands/eval.php | 0 php/{wp-cli => }/commands/export.php | 0 php/{wp-cli => }/commands/help.php | 0 php/{wp-cli => }/commands/home.php | 0 php/{wp-cli => }/commands/option.php | 0 php/{wp-cli => }/commands/plugin.php | 0 php/{wp-cli => }/commands/post-meta.php | 0 php/{wp-cli => }/commands/post.php | 0 php/{wp-cli => }/commands/rewrite.php | 0 php/{wp-cli => }/commands/search-replace.php | 0 php/{wp-cli => }/commands/shell.php | 0 php/{wp-cli => }/commands/theme.php | 0 php/{wp-cli => }/commands/transient.php | 0 php/{wp-cli => }/commands/user-meta.php | 0 php/{wp-cli => }/commands/user.php | 0 php/{wp-cli => }/dispatcher.php | 0 php/{wp-cli => }/man.php | 0 php/{wp-cli => }/utils.php | 6 +++--- php/{wp-cli => }/wp-cli-boot.php | 0 php/{wp-cli => }/wp-cli.php | 0 php/{wp-cli => }/wp-settings.php | 0 43 files changed, 5 insertions(+), 5 deletions(-) rename php/{wp-cli => }/WP_CLI/CommandWithMeta.php (100%) rename php/{wp-cli => }/WP_CLI/CommandWithUpgrade.php (100%) rename php/{wp-cli => }/WP_CLI/Dispatcher/CompositeCommand.php (100%) rename php/{wp-cli => }/WP_CLI/Dispatcher/MethodSubcommand.php (100%) rename php/{wp-cli => }/WP_CLI/Dispatcher/RootCommand.php (100%) rename php/{wp-cli => }/WP_CLI/Dispatcher/Subcommand.php (100%) rename php/{wp-cli => }/WP_CLI/DocParser.php (100%) rename php/{wp-cli => }/WP_CLI/NonDestructiveCoreUpgrader.php (100%) rename php/{wp-cli => }/WP_CLI/QueryIterator.php (100%) rename php/{wp-cli => }/WP_CLI/TableIterator.php (100%) rename php/{wp-cli => }/WP_CLI/UpgraderSkin.php (100%) rename php/{wp-cli => }/class-wp-cli-command.php (100%) rename php/{wp-cli => }/class-wp-cli.php (100%) rename php/{wp-cli => }/commands/blog.php (100%) rename php/{wp-cli => }/commands/cache.php (100%) rename php/{wp-cli => }/commands/cap.php (100%) rename php/{wp-cli => }/commands/comment.php (100%) rename php/{wp-cli => }/commands/core.php (100%) rename php/{wp-cli => }/commands/db.php (100%) rename php/{wp-cli => }/commands/eval-file.php (100%) rename php/{wp-cli => }/commands/eval.php (100%) rename php/{wp-cli => }/commands/export.php (100%) rename php/{wp-cli => }/commands/help.php (100%) rename php/{wp-cli => }/commands/home.php (100%) rename php/{wp-cli => }/commands/option.php (100%) rename php/{wp-cli => }/commands/plugin.php (100%) rename php/{wp-cli => }/commands/post-meta.php (100%) rename php/{wp-cli => }/commands/post.php (100%) rename php/{wp-cli => }/commands/rewrite.php (100%) rename php/{wp-cli => }/commands/search-replace.php (100%) rename php/{wp-cli => }/commands/shell.php (100%) rename php/{wp-cli => }/commands/theme.php (100%) rename php/{wp-cli => }/commands/transient.php (100%) rename php/{wp-cli => }/commands/user-meta.php (100%) rename php/{wp-cli => }/commands/user.php (100%) rename php/{wp-cli => }/dispatcher.php (100%) rename php/{wp-cli => }/man.php (100%) rename php/{wp-cli => }/utils.php (97%) rename php/{wp-cli => }/wp-cli-boot.php (100%) rename php/{wp-cli => }/wp-cli.php (100%) rename php/{wp-cli => }/wp-settings.php (100%) diff --git a/bin/wp b/bin/wp index fd25093a82..aeebd4d50f 100755 --- a/bin/wp +++ b/bin/wp @@ -28,7 +28,7 @@ if [ ! -d $SCRIPT_PATH ]; then SCRIPT_PATH=$(dirname "$SELF_PATH")/../php fi -SCRIPT_PATH=$SCRIPT_PATH/wp-cli/wp-cli-boot.php +SCRIPT_PATH=$SCRIPT_PATH/wp-cli-boot.php case $(uname -a) in CYGWIN*) diff --git a/composer.json b/composer.json index 62e97907db..c4d8fec422 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "phpunit/phpunit": "3.7.x" }, "autoload": { - "psr-0": { "WP_CLI": "php/wp-cli" } + "psr-0": { "WP_CLI": "php" } }, "minimum-stability": "dev" } diff --git a/php/wp-cli/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php similarity index 100% rename from php/wp-cli/WP_CLI/CommandWithMeta.php rename to php/WP_CLI/CommandWithMeta.php diff --git a/php/wp-cli/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php similarity index 100% rename from php/wp-cli/WP_CLI/CommandWithUpgrade.php rename to php/WP_CLI/CommandWithUpgrade.php diff --git a/php/wp-cli/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php similarity index 100% rename from php/wp-cli/WP_CLI/Dispatcher/CompositeCommand.php rename to php/WP_CLI/Dispatcher/CompositeCommand.php diff --git a/php/wp-cli/WP_CLI/Dispatcher/MethodSubcommand.php b/php/WP_CLI/Dispatcher/MethodSubcommand.php similarity index 100% rename from php/wp-cli/WP_CLI/Dispatcher/MethodSubcommand.php rename to php/WP_CLI/Dispatcher/MethodSubcommand.php diff --git a/php/wp-cli/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php similarity index 100% rename from php/wp-cli/WP_CLI/Dispatcher/RootCommand.php rename to php/WP_CLI/Dispatcher/RootCommand.php diff --git a/php/wp-cli/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php similarity index 100% rename from php/wp-cli/WP_CLI/Dispatcher/Subcommand.php rename to php/WP_CLI/Dispatcher/Subcommand.php diff --git a/php/wp-cli/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php similarity index 100% rename from php/wp-cli/WP_CLI/DocParser.php rename to php/WP_CLI/DocParser.php diff --git a/php/wp-cli/WP_CLI/NonDestructiveCoreUpgrader.php b/php/WP_CLI/NonDestructiveCoreUpgrader.php similarity index 100% rename from php/wp-cli/WP_CLI/NonDestructiveCoreUpgrader.php rename to php/WP_CLI/NonDestructiveCoreUpgrader.php diff --git a/php/wp-cli/WP_CLI/QueryIterator.php b/php/WP_CLI/QueryIterator.php similarity index 100% rename from php/wp-cli/WP_CLI/QueryIterator.php rename to php/WP_CLI/QueryIterator.php diff --git a/php/wp-cli/WP_CLI/TableIterator.php b/php/WP_CLI/TableIterator.php similarity index 100% rename from php/wp-cli/WP_CLI/TableIterator.php rename to php/WP_CLI/TableIterator.php diff --git a/php/wp-cli/WP_CLI/UpgraderSkin.php b/php/WP_CLI/UpgraderSkin.php similarity index 100% rename from php/wp-cli/WP_CLI/UpgraderSkin.php rename to php/WP_CLI/UpgraderSkin.php diff --git a/php/wp-cli/class-wp-cli-command.php b/php/class-wp-cli-command.php similarity index 100% rename from php/wp-cli/class-wp-cli-command.php rename to php/class-wp-cli-command.php diff --git a/php/wp-cli/class-wp-cli.php b/php/class-wp-cli.php similarity index 100% rename from php/wp-cli/class-wp-cli.php rename to php/class-wp-cli.php diff --git a/php/wp-cli/commands/blog.php b/php/commands/blog.php similarity index 100% rename from php/wp-cli/commands/blog.php rename to php/commands/blog.php diff --git a/php/wp-cli/commands/cache.php b/php/commands/cache.php similarity index 100% rename from php/wp-cli/commands/cache.php rename to php/commands/cache.php diff --git a/php/wp-cli/commands/cap.php b/php/commands/cap.php similarity index 100% rename from php/wp-cli/commands/cap.php rename to php/commands/cap.php diff --git a/php/wp-cli/commands/comment.php b/php/commands/comment.php similarity index 100% rename from php/wp-cli/commands/comment.php rename to php/commands/comment.php diff --git a/php/wp-cli/commands/core.php b/php/commands/core.php similarity index 100% rename from php/wp-cli/commands/core.php rename to php/commands/core.php diff --git a/php/wp-cli/commands/db.php b/php/commands/db.php similarity index 100% rename from php/wp-cli/commands/db.php rename to php/commands/db.php diff --git a/php/wp-cli/commands/eval-file.php b/php/commands/eval-file.php similarity index 100% rename from php/wp-cli/commands/eval-file.php rename to php/commands/eval-file.php diff --git a/php/wp-cli/commands/eval.php b/php/commands/eval.php similarity index 100% rename from php/wp-cli/commands/eval.php rename to php/commands/eval.php diff --git a/php/wp-cli/commands/export.php b/php/commands/export.php similarity index 100% rename from php/wp-cli/commands/export.php rename to php/commands/export.php diff --git a/php/wp-cli/commands/help.php b/php/commands/help.php similarity index 100% rename from php/wp-cli/commands/help.php rename to php/commands/help.php diff --git a/php/wp-cli/commands/home.php b/php/commands/home.php similarity index 100% rename from php/wp-cli/commands/home.php rename to php/commands/home.php diff --git a/php/wp-cli/commands/option.php b/php/commands/option.php similarity index 100% rename from php/wp-cli/commands/option.php rename to php/commands/option.php diff --git a/php/wp-cli/commands/plugin.php b/php/commands/plugin.php similarity index 100% rename from php/wp-cli/commands/plugin.php rename to php/commands/plugin.php diff --git a/php/wp-cli/commands/post-meta.php b/php/commands/post-meta.php similarity index 100% rename from php/wp-cli/commands/post-meta.php rename to php/commands/post-meta.php diff --git a/php/wp-cli/commands/post.php b/php/commands/post.php similarity index 100% rename from php/wp-cli/commands/post.php rename to php/commands/post.php diff --git a/php/wp-cli/commands/rewrite.php b/php/commands/rewrite.php similarity index 100% rename from php/wp-cli/commands/rewrite.php rename to php/commands/rewrite.php diff --git a/php/wp-cli/commands/search-replace.php b/php/commands/search-replace.php similarity index 100% rename from php/wp-cli/commands/search-replace.php rename to php/commands/search-replace.php diff --git a/php/wp-cli/commands/shell.php b/php/commands/shell.php similarity index 100% rename from php/wp-cli/commands/shell.php rename to php/commands/shell.php diff --git a/php/wp-cli/commands/theme.php b/php/commands/theme.php similarity index 100% rename from php/wp-cli/commands/theme.php rename to php/commands/theme.php diff --git a/php/wp-cli/commands/transient.php b/php/commands/transient.php similarity index 100% rename from php/wp-cli/commands/transient.php rename to php/commands/transient.php diff --git a/php/wp-cli/commands/user-meta.php b/php/commands/user-meta.php similarity index 100% rename from php/wp-cli/commands/user-meta.php rename to php/commands/user-meta.php diff --git a/php/wp-cli/commands/user.php b/php/commands/user.php similarity index 100% rename from php/wp-cli/commands/user.php rename to php/commands/user.php diff --git a/php/wp-cli/dispatcher.php b/php/dispatcher.php similarity index 100% rename from php/wp-cli/dispatcher.php rename to php/dispatcher.php diff --git a/php/wp-cli/man.php b/php/man.php similarity index 100% rename from php/wp-cli/man.php rename to php/man.php diff --git a/php/wp-cli/utils.php b/php/utils.php similarity index 97% rename from php/wp-cli/utils.php rename to php/utils.php index a10ba516ad..a474693447 100644 --- a/php/wp-cli/utils.php +++ b/php/utils.php @@ -4,8 +4,8 @@ function bootstrap() { $vendor_paths = array( - WP_CLI_ROOT . '../../../../../vendor', // part of a larger project - WP_CLI_ROOT . '../../vendor', // top-level project + WP_CLI_ROOT . '../../../../vendor', // part of a larger project + WP_CLI_ROOT . '../vendor', // top-level project ); $has_autoload = false; @@ -20,7 +20,7 @@ function bootstrap() { } if ( !$has_autoload ) { - include WP_CLI_ROOT . '../php-cli-tools/lib/cli/cli.php'; + include WP_CLI_ROOT . 'php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); register_autoload(); } diff --git a/php/wp-cli/wp-cli-boot.php b/php/wp-cli-boot.php similarity index 100% rename from php/wp-cli/wp-cli-boot.php rename to php/wp-cli-boot.php diff --git a/php/wp-cli/wp-cli.php b/php/wp-cli.php similarity index 100% rename from php/wp-cli/wp-cli.php rename to php/wp-cli.php diff --git a/php/wp-cli/wp-settings.php b/php/wp-settings.php similarity index 100% rename from php/wp-cli/wp-settings.php rename to php/wp-settings.php From f477b06701e0169fa6add54d0ee203754a553f5c Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 27 Dec 2012 22:28:59 +0100 Subject: [PATCH 0976/4858] Corrected the paramaters of the sprintf within post_update_messages --- .../internals/skeletons/post_type_skeleton.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index d3c5e7dfc1..1b06f2c647 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -46,19 +46,19 @@ function {$machine_name}_updated_messages( \$messages ) { \$messages['{$post_type}'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label_ucfirst} updated. <a target=\"_blank\" href=\"%1\$s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 1 => sprintf( __('{$label_ucfirst} updated. <a target=\"_blank\" href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), 2 => __('Custom field updated.', '{$textdomain}'), 3 => __('Custom field deleted.', '{$textdomain}'), 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), /* translators: %s: date and time of the revision */ 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label_ucfirst} published. <a href=\"%1\$s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 6 => sprintf( __('{$label_ucfirst} published. <a href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), - 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"%1\$s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), - 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"\">Preview {$label}</a>', '{$textdomain}'), + 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"%2\$s\">Preview {$label}</a>', '{$textdomain}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"%1\$s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), ); return \$messages; From b9a397ef94c6e1e9f3cce2ace7630f4929e600b3 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 01:16:35 +0100 Subject: [PATCH 0977/4858] Added a init for each taxonomy just like the post types have --- src/php/wp-cli/commands/internals/scaffold.php | 2 +- .../commands/internals/skeletons/taxonomy_skeleton.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 6c5883f5a3..6764e409da 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -87,7 +87,7 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] + * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php index de7c5e7ad5..1d299b7d18 100755 --- a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php @@ -1,7 +1,7 @@ <?php $output = "<?php -if ( !taxonomy_exists( '{$taxonomy}' ) ) : +function {$machine_name}_init() { \$labels = array( 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), @@ -44,4 +44,5 @@ register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args ); -endif;"; \ No newline at end of file +} +add_action( 'init', '{$machine_name}_init' );"; \ No newline at end of file From 64a876ea8c2c17ebfc6071a8cbb4492769007865 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 28 Dec 2012 01:47:48 +0000 Subject: [PATCH 0978/4858] Always return the list of subcommands as alphabetically sorted. This ensures commands added by plugins are added in their proper place. --- php/WP_CLI/Dispatcher/RootCommand.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index ce8dd38d0a..a98683e121 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -85,6 +85,8 @@ function add_command( $name, $implementation ) { function get_subcommands() { $this->load_all_commands(); + ksort( $this->subcommands ); + return $this->subcommands; } From c4edcfa1e737cfb29d40b91a70b239288f1d96eb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 12:16:35 +0200 Subject: [PATCH 0979/4858] fix path to man dirs; see #250 --- php/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 652d86a2fb..04ea5cf68d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -236,8 +236,8 @@ static function before_wp_load() { self::$root = new Dispatcher\RootCommand; self::add_man_dir( - WP_CLI_ROOT . "../../man/", - WP_CLI_ROOT . "../../man-src/" + WP_CLI_ROOT . "../man/", + WP_CLI_ROOT . "../man-src/" ); self::parse_args(); From 78fdf15f2f5ec0ac1d7004506178b7ca77f5ca32 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 12:17:58 +0200 Subject: [PATCH 0980/4858] add search-replace man txt. see #249 --- man-src/search-replace.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 man-src/search-replace.txt diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt new file mode 100644 index 0000000000..0e7f4cff10 --- /dev/null +++ b/man-src/search-replace.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `--dry-run`: + + Show report, but don't perform the changes. + +## EXAMPLES + + wp search-replace 'http://example.dev' 'http://example.com' --dry-run From 0305a32720a8bf6fc5dcb0de4ffe79aae6e7236e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 26 Dec 2012 12:18:20 +0200 Subject: [PATCH 0981/4858] refresh man pages --- man-src/option.txt | 2 +- man-src/post-meta.txt | 2 +- man-src/user-meta.txt | 2 +- man/option.1 | 2 +- man/post-meta.1 | 2 +- man/post-update.1 | 2 +- man/search-replace.1 | 27 +++++++++++++++++++++++++++ man/user-meta.1 | 2 +- man/user-remove-role.1 | 4 ++-- man/user-set-role.1 | 2 +- php/commands/search-replace.php | 4 ++-- 11 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 man/search-replace.1 diff --git a/man-src/option.txt b/man-src/option.txt index 238e5f66b9..423e816694 100644 --- a/man-src/option.txt +++ b/man-src/option.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `json`: +* `--json`: Encode/decode values as JSON. diff --git a/man-src/post-meta.txt b/man-src/post-meta.txt index e36dcb2391..974a2bd7b6 100644 --- a/man-src/post-meta.txt +++ b/man-src/post-meta.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `json`: +* `--json`: Encode/decode values as JSON. diff --git a/man-src/user-meta.txt b/man-src/user-meta.txt index ad8d85bdbb..9db91bbf1a 100644 --- a/man-src/user-meta.txt +++ b/man-src/user-meta.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `json`: +* `--json`: Encode/decode values as JSON. diff --git a/man/option.1 b/man/option.1 index 12b38c6b77..b22d66884e 100644 --- a/man/option.1 +++ b/man/option.1 @@ -48,7 +48,7 @@ Delete an option\. . .TP -\fBjson\fR: +\fB\-\-json\fR: . .IP Encode/decode values as JSON\. diff --git a/man/post-meta.1 b/man/post-meta.1 index 3b3fc962fd..c6cc6067eb 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -48,7 +48,7 @@ Update a meta field\. . .TP -\fBjson\fR: +\fB\-\-json\fR: . .IP Encode/decode values as JSON\. diff --git a/man/post-update.1 b/man/post-update.1 index 4fd90c4754..534a319d48 100644 --- a/man/post-update.1 +++ b/man/post-update.1 @@ -7,7 +7,7 @@ \fBwp\-post\-update\fR \- Update a post\. . .SH "SYNOPSIS" -wp post update \fIid\fR \-\-\fIfield\fR=\fIvalue\fR +wp post update \fIid\fR\.\.\. \-\-\fIfield\fR=\fIvalue\fR . .SH "OPTIONS" . diff --git a/man/search-replace.1 b/man/search-replace.1 new file mode 100644 index 0000000000..b22472392e --- /dev/null +++ b/man/search-replace.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SEARCH\-REPLACE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-search\-replace\fR \- Search/replace strings in the database\. +. +.SH "SYNOPSIS" +wp search\-replace \fIold\fR \fInew\fR [\-\-dry\-run] +. +.SH "OPTIONS" +. +.TP +\fB\-\-dry\-run\fR: +. +.IP +Show report, but don\'t perform the changes\. +. +.SH "EXAMPLES" +. +.nf + +wp search\-replace \'http://example\.dev\' \'http://example\.com\' \-\-dry\-run +. +.fi + diff --git a/man/user-meta.1 b/man/user-meta.1 index b304a99f92..25719cdbce 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -48,7 +48,7 @@ Update a meta field\. . .TP -\fBjson\fR: +\fB\-\-json\fR: . .IP Encode/decode values as JSON\. diff --git a/man/user-remove-role.1 b/man/user-remove-role.1 index 232a68c91c..e6e0360a9c 100644 --- a/man/user-remove-role.1 +++ b/man/user-remove-role.1 @@ -4,10 +4,10 @@ .TH "WP\-USER\-REMOVE\-ROLE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-remove\-role\fR \- Remove a user from a blog\. +\fBwp\-user\-remove\-role\fR \- Remove a user\'s role\. . .SH "SYNOPSIS" -wp user remove\-role \fIuser\-login\fR +wp user remove\-role \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] . .SH "OPTIONS" . diff --git a/man/user-set-role.1 b/man/user-set-role.1 index bb8ca46701..edd5ea550a 100644 --- a/man/user-set-role.1 +++ b/man/user-set-role.1 @@ -4,7 +4,7 @@ .TH "WP\-USER\-SET\-ROLE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-set\-role\fR \- Add a user to a blog\. +\fBwp\-user\-set\-role\fR \- Set the user role (for a particular blog)\. . .SH "SYNOPSIS" wp user set\-role \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 963b211247..0b88b388fd 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -3,13 +3,13 @@ WP_CLI::add_command( 'search-replace', new Search_Replace_Command ); /** - * Search/Replace strings in the database. - * * @package wp-cli */ class Search_Replace_Command extends WP_CLI_Command { /** + * Search/replace strings in the database. + * * @synopsis <old> <new> [--dry-run] */ public function __invoke( $args, $assoc_args ) { From e006bd60bcde54e64eeea1788748b8db22988d9c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 07:44:53 +0200 Subject: [PATCH 0982/4858] add optional <table>... param to search-replace. see #249 --- man-src/search-replace.txt | 2 ++ man/search-replace.1 | 2 +- php/commands/search-replace.php | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index 0e7f4cff10..a106c1762c 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -7,3 +7,5 @@ ## EXAMPLES wp search-replace 'http://example.dev' 'http://example.com' --dry-run + + wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms diff --git a/man/search-replace.1 b/man/search-replace.1 index b22472392e..618339b312 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -7,7 +7,7 @@ \fBwp\-search\-replace\fR \- Search/replace strings in the database\. . .SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\-\-dry\-run] +wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] . .SH "OPTIONS" . diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0b88b388fd..722d48d63b 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,14 +10,19 @@ class Search_Replace_Command extends WP_CLI_Command { /** * Search/replace strings in the database. * - * @synopsis <old> <new> [--dry-run] + * @synopsis <old> <new> [<table>...] [--dry-run] */ public function __invoke( $args, $assoc_args ) { global $wpdb; - list( $old, $new ) = $args; + $old = array_shift( $args ); + $new = array_shift( $args ); - $tables = $wpdb->tables( 'blog' ); + if ( !empty( $args ) ) { + $tables = $args; + } else { + $tables = $wpdb->tables( 'blog' ); + } $total = 0; From 2a6c356c1217bc4a6ae1ba6f21b28266cd8a9f9b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 07:45:28 +0200 Subject: [PATCH 0983/4858] regenerate search-replace manpage --- man/search-replace.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/man/search-replace.1 b/man/search-replace.1 index 618339b312..9ac08c7b66 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -22,6 +22,8 @@ Show report, but don\'t perform the changes\. .nf wp search\-replace \'http://example\.dev\' \'http://example\.com\' \-\-dry\-run + +wp search\-replace \'foo\' \'bar\' wp_posts wp_postmeta wp_terms . .fi From 9df4cd9519f27c324f5b9788e0383088ae5b848e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 09:32:40 +0200 Subject: [PATCH 0984/4858] add Spyc YAML parser --- php/Spyc.php | 1033 +++++++++++++++++++++++++++++++++++++++++++++++++ php/utils.php | 2 + 2 files changed, 1035 insertions(+) create mode 100644 php/Spyc.php diff --git a/php/Spyc.php b/php/Spyc.php new file mode 100644 index 0000000000..b6a42af675 --- /dev/null +++ b/php/Spyc.php @@ -0,0 +1,1033 @@ +<?php +/** + * Spyc -- A Simple PHP YAML Class + * @version 0.5 + * @author Vlad Andersen <vlad.andersen@gmail.com> + * @author Chris Wanstrath <chris@ozmm.org> + * @link http://code.google.com/p/spyc/ + * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc + */ + +if (!function_exists('spyc_load')) { + /** + * Parses YAML to array. + * @param string $string YAML string. + * @return array + */ + function spyc_load ($string) { + return Spyc::YAMLLoadString($string); + } +} + +if (!function_exists('spyc_load_file')) { + /** + * Parses YAML to array. + * @param string $file Path to YAML file. + * @return array + */ + function spyc_load_file ($file) { + return Spyc::YAMLLoad($file); + } +} + +/** + * The Simple PHP YAML Class. + * + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. + * + * Usage: + * <code> + * $Spyc = new Spyc; + * $array = $Spyc->load($file); + * </code> + * or: + * <code> + * $array = Spyc::YAMLLoad($file); + * </code> + * or: + * <code> + * $array = spyc_load_file($file); + * </code> + * @package Spyc + */ +class Spyc { + + // SETTINGS + + const REMPTY = "\0\0\0\0\0"; + + /** + * Setting this to true will force YAMLDump to enclose any string value in + * quotes. False by default. + * + * @var bool + */ + public $setting_dump_force_quotes = false; + + /** + * Setting this to true will forse YAMLLoad to use syck_load function when + * possible. False by default. + * @var bool + */ + public $setting_use_syck_is_possible = false; + + + + /**#@+ + * @access private + * @var mixed + */ + private $_dumpIndent; + private $_dumpWordWrap; + private $_containsGroupAnchor = false; + private $_containsGroupAlias = false; + private $path; + private $result; + private $LiteralPlaceHolder = '___YAML_Literal_Block___'; + private $SavedGroups = array(); + private $indent; + /** + * Path modifier that should be applied after adding current element. + * @var array + */ + private $delayedPath = array(); + + /**#@+ + * @access public + * @var mixed + */ + public $_nodeId; + +/** + * Load a valid YAML string to Spyc. + * @param string $input + * @return array + */ + public function load ($input) { + return $this->__loadString($input); + } + + /** + * Load a valid YAML file to Spyc. + * @param string $file + * @return array + */ + public function loadFile ($file) { + return $this->__load($file); + } + + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * <code> + * $array = Spyc::YAMLLoad('lucky.yaml'); + * print_r($array); + * </code> + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + public static function YAMLLoad($input) { + $Spyc = new Spyc; + return $Spyc->__load($input); + } + + /** + * Load a string of YAML into a PHP array statically + * + * The load method, when supplied with a YAML string, will do its best + * to convert YAML in a string into a PHP array. Pretty simple. + * + * Note: use this function if you don't want files from the file system + * loaded and processed as YAML. This is of interest to people concerned + * about security whose input is from a string. + * + * Usage: + * <code> + * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); + * print_r($array); + * </code> + * @access public + * @return array + * @param string $input String containing YAML + */ + public static function YAMLLoadString($input) { + $Spyc = new Spyc; + return $Spyc->__loadString($input); + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public static function YAMLDump($array,$indent = false,$wordwrap = false) { + $spyc = new Spyc; + return $spyc->dump($array,$indent,$wordwrap); + } + + + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function dump($array,$indent = false,$wordwrap = false) { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) { + $this->_dumpIndent = 2; + } else { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) { + $this->_dumpWordWrap = 40; + } else { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = "---\n"; + + // Start at the base of the array and move through it. + if ($array) { + $array = (array)$array; + $previous_key = -1; + foreach ($array as $key => $value) { + if (!isset($first_key)) $first_key = $key; + $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array); + $previous_key = $key; + } + } + return $string; + } + + /** + * Attempts to convert a key / value array item to YAML + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { + if (is_array($value)) { + if (empty ($value)) + return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value,$indent); + } elseif (!is_array($value)) { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array); + } + return $string; + } + + /** + * Attempts to convert an array to YAML + * @access private + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + private function _yamlizeArray($array,$indent) { + if (is_array($array)) { + $string = ''; + $previous_key = -1; + foreach ($array as $key => $value) { + if (!isset($first_key)) $first_key = $key; + $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array); + $previous_key = $key; + } + return $string; + } else { + return false; + } + } + + /** + * Returns YAML from a key and a value + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) { + // do some folding here, for blocks + if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || + strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false || + strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 || + substr ($value, -1, 1) == ':') + ) { + $value = $this->_doLiteralBlock($value,$indent); + } else { + $value = $this->_doFolding($value,$indent); + } + + if ($value === array()) $value = '[ ]'; + if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) { + $value = $this->_doLiteralBlock($value,$indent); + } + if (trim ($value) != $value) + $value = $this->_doLiteralBlock($value,$indent); + + if (is_bool($value)) { + $value = ($value) ? "true" : "false"; + } + + if ($value === null) $value = 'null'; + if ($value === "'" . self::REMPTY . "'") $value = null; + + $spaces = str_repeat(' ',$indent); + + //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { + if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } else { + // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); + // It's mapped + if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; } + $string = rtrim ($spaces.$key.': '.$value)."\n"; + } + return $string; + } + + /** + * Creates a literal block for dumping + * @access private + * @return string + * @param $value + * @param $indent int The value of the indent + */ + private function _doLiteralBlock($value,$indent) { + if ($value === "\n") return '\n'; + if (strpos($value, "\n") === false && strpos($value, "'") === false) { + return sprintf ("'%s'", $value); + } + if (strpos($value, "\n") === false && strpos($value, '"') === false) { + return sprintf ('"%s"', $value); + } + $exploded = explode("\n",$value); + $newValue = '|'; + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ',$indent); + foreach ($exploded as $line) { + $newValue .= "\n" . $spaces . ($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * @access private + * @return string + * @param $value The string you wish to fold + */ + private function _doFolding($value,$indent) { + // Don't do anything if wordwrap is set to 0 + + if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ',$indent); + $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); + $value = ">\n".$indent.$wrapped; + } else { + if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY) + $value = '"' . $value . '"'; + } + + + return $value; + } + +// LOADING FUNCTIONS + + private function __load($input) { + $Source = $this->loadFromSource($input); + return $this->loadWithSource($Source); + } + + private function __loadString($input) { + $Source = $this->loadFromString($input); + return $this->loadWithSource($Source); + } + + private function loadWithSource($Source) { + if (empty ($Source)) return array(); + if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { + $array = syck_load (implode ('', $Source)); + return is_array($array) ? $array : array(); + } + + $this->path = array(); + $this->result = array(); + + $cnt = count($Source); + for ($i = 0; $i < $cnt; $i++) { + $line = $Source[$i]; + + $this->indent = strlen($line) - strlen(ltrim($line)); + $tempPath = $this->getParentPathByIndent($this->indent); + $line = self::stripIndent($line, $this->indent); + if (self::isComment($line)) continue; + if (self::isEmpty($line)) continue; + $this->path = $tempPath; + + $literalBlockStyle = self::startsLiteralBlock($line); + if ($literalBlockStyle) { + $line = rtrim ($line, $literalBlockStyle . " \n"); + $literalBlock = ''; + $line .= $this->LiteralPlaceHolder; + $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1])); + while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { + $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent); + } + $i--; + } + + while (++$i < $cnt && self::greedilyNeedNextLine($line)) { + $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); + } + $i--; + + + + if (strpos ($line, '#')) { + if (strpos ($line, '"') === false && strpos ($line, "'") === false) + $line = preg_replace('/\s+#(.+)$/','',$line); + } + + $lineArray = $this->_parseLine($line); + + if ($literalBlockStyle) + $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); + + $this->addArray($lineArray, $this->indent); + + foreach ($this->delayedPath as $indent => $delayedPath) + $this->path[$indent] = $delayedPath; + + $this->delayedPath = array(); + + } + return $this->result; + } + + private function loadFromSource ($input) { + if (!empty($input) && strpos($input, "\n") === false && file_exists($input)) + return file($input); + + return $this->loadFromString($input); + } + + private function loadFromString ($input) { + $lines = explode("\n",$input); + foreach ($lines as $k => $_) { + $lines[$k] = rtrim ($_, "\r"); + } + return $lines; + } + + /** + * Parses YAML code and returns an array for a node + * @access private + * @return array + * @param string $line A line from the YAML file + */ + private function _parseLine($line) { + if (!$line) return array(); + $line = trim($line); + if (!$line) return array(); + + $array = array(); + + $group = $this->nodeContainsGroup($line); + if ($group) { + $this->addGroup($line, $group); + $line = $this->stripGroup ($line, $group); + } + + if ($this->startsMappedSequence($line)) + return $this->returnMappedSequence($line); + + if ($this->startsMappedValue($line)) + return $this->returnMappedValue($line); + + if ($this->isArrayElement($line)) + return $this->returnArrayElement($line); + + if ($this->isPlainArray($line)) + return $this->returnPlainArray($line); + + + return $this->returnKeyValuePair($line); + + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * @access private + * @param string $value + * @return mixed + */ + private function _toType($value) { + if ($value === '') return null; + $first_character = $value[0]; + $last_character = substr($value, -1, 1); + + $is_quoted = false; + do { + if (!$value) break; + if ($first_character != '"' && $first_character != "'") break; + if ($last_character != '"' && $last_character != "'") break; + $is_quoted = true; + } while (0); + + if ($is_quoted) + return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\'')); + + if (strpos($value, ' #') !== false && !$is_quoted) + $value = preg_replace('/\s+#(.+)$/','',$value); + + if (!$is_quoted) $value = str_replace('\n', "\n", $value); + + if ($first_character == '[' && $last_character == ']') { + // Take out strings sequences and mappings + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $value = array(); + foreach ($explode as $v) { + $value[] = $this->_toType($v); + } + return $value; + } + + if (strpos($value,': ')!==false && $first_character != '{') { + $array = explode(': ',$value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ',$array)); + $value = $this->_toType($value); + return array($key => $value); + } + + if ($first_character == '{' && $last_character == '}') { + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + // Inline Mapping + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $array = array(); + foreach ($explode as $v) { + $SubArr = $this->_toType($v); + if (empty($SubArr)) continue; + if (is_array ($SubArr)) { + $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; + } + $array[] = $SubArr; + } + return $array; + } + + if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { + return null; + } + + if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){ + $intvalue = (int)$value; + if ($intvalue != PHP_INT_MAX) + $value = $intvalue; + return $value; + } + + if (in_array($value, + array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) { + return true; + } + + if (in_array(strtolower($value), + array('false', 'off', '-', 'no', 'n'))) { + return false; + } + + if (is_numeric($value)) { + if ($value === '0') return 0; + if (rtrim ($value, 0) === $value) + $value = (float)$value; + return $value; + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * @access private + * @return array + */ + private function _inlineEscape($inline) { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + $seqs = array(); + $maps = array(); + $saved_strings = array(); + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $saved_strings = $strings[0]; + $inline = preg_replace($regex,'YAMLString',$inline); + } + unset($regex); + + $i = 0; + do { + + // Check for sequences + while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { + $seqs[] = $matchseqs[0]; + $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); + } + + // Check for mappings + while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { + $maps[] = $matchmaps[0]; + $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); + } + + if ($i++ >= 10) break; + + } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); + + $explode = explode(', ',$inline); + $stringi = 0; $i = 0; + + while (1) { + + // Re-add the sequences + if (!empty($seqs)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + foreach ($seqs as $seqk => $seq) { + $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); + $value = $explode[$key]; + } + } + } + } + + // Re-add the mappings + if (!empty($maps)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLMap') !== false) { + foreach ($maps as $mapk => $map) { + $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); + $value = $explode[$key]; + } + } + } + } + + + // Re-add the strings + if (!empty($saved_strings)) { + foreach ($explode as $key => $value) { + while (strpos($value,'YAMLString') !== false) { + $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); + unset($saved_strings[$stringi]); + ++$stringi; + $value = $explode[$key]; + } + } + } + + $finished = true; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLMap') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLString') !== false) { + $finished = false; break; + } + } + if ($finished) break; + + $i++; + if ($i > 10) + break; // Prevent infinite loops. + } + + return $explode; + } + + private function literalBlockContinues ($line, $lineIndent) { + if (!trim($line)) return true; + if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true; + return false; + } + + private function referenceContentsByAlias ($alias) { + do { + if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } + $groupPath = $this->SavedGroups[$alias]; + $value = $this->result; + foreach ($groupPath as $k) { + $value = $value[$k]; + } + } while (false); + return $value; + } + + private function addArrayInline ($array, $indent) { + $CommonGroupPath = $this->path; + if (empty ($array)) return false; + + foreach ($array as $k => $_) { + $this->addArray(array($k => $_), $indent); + $this->path = $CommonGroupPath; + } + return true; + } + + private function addArray ($incoming_data, $incoming_indent) { + + // print_r ($incoming_data); + + if (count ($incoming_data) > 1) + return $this->addArrayInline ($incoming_data, $incoming_indent); + + $key = key ($incoming_data); + $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; + if ($key === '__!YAMLZero') $key = '0'; + + if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. + if ($key || $key === '' || $key === '0') { + $this->result[$key] = $value; + } else { + $this->result[] = $value; end ($this->result); $key = key ($this->result); + } + $this->path[$incoming_indent] = $key; + return; + } + + + + $history = array(); + // Unfolding inner array tree. + $history[] = $_arr = $this->result; + foreach ($this->path as $k) { + $history[] = $_arr = $_arr[$k]; + } + + if ($this->_containsGroupAlias) { + $value = $this->referenceContentsByAlias($this->_containsGroupAlias); + $this->_containsGroupAlias = false; + } + + + // Adding string or numeric key to the innermost level or $this->arr. + if (is_string($key) && $key == '<<') { + if (!is_array ($_arr)) { $_arr = array (); } + + $_arr = array_merge ($_arr, $value); + } else if ($key || $key === '' || $key === '0') { + if (!is_array ($_arr)) + $_arr = array ($key=>$value); + else + $_arr[$key] = $value; + } else { + if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } + else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } + } + + $reverse_path = array_reverse($this->path); + $reverse_history = array_reverse ($history); + $reverse_history[0] = $_arr; + $cnt = count($reverse_history) - 1; + for ($i = 0; $i < $cnt; $i++) { + $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; + } + $this->result = $reverse_history[$cnt]; + + $this->path[$incoming_indent] = $key; + + if ($this->_containsGroupAnchor) { + $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; + if (is_array ($value)) { + $k = key ($value); + if (!is_int ($k)) { + $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; + } + } + $this->_containsGroupAnchor = false; + } + + } + + private static function startsLiteralBlock ($line) { + $lastChar = substr (trim($line), -1); + if ($lastChar != '>' && $lastChar != '|') return false; + if ($lastChar == '|') return $lastChar; + // HTML tags should not be counted as literal blocks. + if (preg_match ('#<.*?>$#', $line)) return false; + return $lastChar; + } + + private static function greedilyNeedNextLine($line) { + $line = trim ($line); + if (!strlen($line)) return false; + if (substr ($line, -1, 1) == ']') return false; + if ($line[0] == '[') return true; + if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true; + return false; + } + + private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) { + $line = self::stripIndent($line, $indent); + if ($literalBlockStyle !== '|') { + $line = self::stripIndent($line); + } + $line = rtrim ($line, "\r\n\t ") . "\n"; + if ($literalBlockStyle == '|') { + return $literalBlock . $line; + } + if (strlen($line) == 0) + return rtrim($literalBlock, ' ') . "\n"; + if ($line == "\n" && $literalBlockStyle == '>') { + return rtrim ($literalBlock, " \t") . "\n"; + } + if ($line != "\n") + $line = trim ($line, "\r\n ") . " "; + return $literalBlock . $line; + } + + function revertLiteralPlaceHolder ($lineArray, $literalBlock) { + foreach ($lineArray as $k => $_) { + if (is_array($_)) + $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); + else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) + $lineArray[$k] = rtrim ($literalBlock, " \r\n"); + } + return $lineArray; + } + + private static function stripIndent ($line, $indent = -1) { + if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line)); + return substr ($line, $indent); + } + + private function getParentPathByIndent ($indent) { + if ($indent == 0) return array(); + $linePath = $this->path; + do { + end($linePath); $lastIndentInParentPath = key($linePath); + if ($indent <= $lastIndentInParentPath) array_pop ($linePath); + } while ($indent <= $lastIndentInParentPath); + return $linePath; + } + + + private function clearBiggerPathValues ($indent) { + + + if ($indent == 0) $this->path = array(); + if (empty ($this->path)) return true; + + foreach ($this->path as $k => $_) { + if ($k > $indent) unset ($this->path[$k]); + } + + return true; + } + + + private static function isComment ($line) { + if (!$line) return false; + if ($line[0] == '#') return true; + if (trim($line, " \r\n\t") == '---') return true; + return false; + } + + private static function isEmpty ($line) { + return (trim ($line) === ''); + } + + + private function isArrayElement ($line) { + if (!$line) return false; + if ($line[0] != '-') return false; + if (strlen ($line) > 3) + if (substr($line,0,3) == '---') return false; + + return true; + } + + private function isHashElement ($line) { + return strpos($line, ':'); + } + + private function isLiteral ($line) { + if ($this->isArrayElement($line)) return false; + if ($this->isHashElement($line)) return false; + return true; + } + + + private static function unquote ($value) { + if (!$value) return $value; + if (!is_string($value)) return $value; + if ($value[0] == '\'') return trim ($value, '\''); + if ($value[0] == '"') return trim ($value, '"'); + return $value; + } + + private function startsMappedSequence ($line) { + return ($line[0] == '-' && substr ($line, -1, 1) == ':'); + } + + private function returnMappedSequence ($line) { + $array = array(); + $key = self::unquote(trim(substr($line,1,-1))); + $array[$key] = array(); + $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); + return array($array); + } + + private function returnMappedValue ($line) { + $array = array(); + $key = self::unquote (trim(substr($line,0,-1))); + $array[$key] = ''; + return $array; + } + + private function startsMappedValue ($line) { + return (substr ($line, -1, 1) == ':'); + } + + private function isPlainArray ($line) { + return ($line[0] == '[' && substr ($line, -1, 1) == ']'); + } + + private function returnPlainArray ($line) { + return $this->_toType($line); + } + + private function returnKeyValuePair ($line) { + $array = array(); + $key = ''; + if (strpos ($line, ':')) { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { + $value = trim(str_replace($matches[1],'',$line)); + $key = $matches[2]; + } else { + // Do some guesswork as to the key and the value + $explode = explode(':',$line); + $key = trim($explode[0]); + array_shift($explode); + $value = trim(implode(':',$explode)); + } + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + if ($key === '0') $key = '__!YAMLZero'; + $array[$key] = $value; + } else { + $array = array ($line); + } + return $array; + + } + + + private function returnArrayElement ($line) { + if (strlen($line) <= 1) return array(array()); // Weird %) + $array = array(); + $value = trim(substr($line,1)); + $value = $this->_toType($value); + $array[] = $value; + return $array; + } + + + private function nodeContainsGroup ($line) { + $symbolsForReference = 'A-z0-9_\-'; + if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-) + if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1]; + if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1]; + if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1]; + return false; + + } + + private function addGroup ($line, $group) { + if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1); + if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1); + //print_r ($this->path); + } + + private function stripGroup ($line, $group) { + $line = trim(str_replace($group, '', $line)); + return $line; + } +} + diff --git a/php/utils.php b/php/utils.php index a474693447..41e6228891 100644 --- a/php/utils.php +++ b/php/utils.php @@ -24,6 +24,8 @@ function bootstrap() { \cli\register_autoload(); register_autoload(); } + + include WP_CLI_ROOT . 'Spyc.php'; } function register_autoload() { From 29d47eb9b4d40485e46c6d85eacaf92162363c84 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 09:43:35 +0200 Subject: [PATCH 0985/4858] load wp-cli.yaml file --- php/class-wp-cli.php | 14 +++++++++++++- php/utils.php | 31 ++++++++++++------------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 04ea5cf68d..fee8087556 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -13,6 +13,7 @@ class WP_CLI { public static $root; private static $man_dirs = array(); + private static $arguments, $assoc_args, $assoc_special; /** @@ -222,12 +223,21 @@ private static function parse_args() { unset( self::$assoc_args['all'] ); } - self::$assoc_special = Utils\split_assoc( self::$assoc_args, array( + self::split_special( array( 'path', 'url', 'blog', 'user', 'require', 'quiet', 'completions', 'man', 'syn-list' ) ); } + private static function split_special( $special_keys ) { + foreach ( $special_keys as $key ) { + if ( isset( self::$assoc_args[ $key ] ) ) { + self::$assoc_special[ $key ] = self::$assoc_args[ $key ]; + unset( self::$assoc_args[ $key ] ); + } + } + } + static function get_assoc_special() { return self::$assoc_special; } @@ -240,6 +250,8 @@ static function before_wp_load() { WP_CLI_ROOT . "../man-src/" ); + self::$assoc_special = Utils\load_config(); + self::parse_args(); define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); diff --git a/php/utils.php b/php/utils.php index 41e6228891..ac3858aa45 100644 --- a/php/utils.php +++ b/php/utils.php @@ -43,6 +43,18 @@ function register_autoload() { } ); } +function load_config() { + foreach ( array( 'wp-cli.local.yaml', 'wp-cli.yaml' ) as $fname ) { + $path = getcwd() . '/' . $fname; + + if ( file_exists( $path ) ) { + return spyc_load_file( $path ); + } + } + + return array(); +} + /** * Splits $argv into positional and associative arguments. * @@ -66,25 +78,6 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args ); } -/** - * Splits $argv into positional and associative arguments. - * - * @param string - * @return array - */ -function split_assoc( &$assoc_args, $special_keys ) { - $assoc_special = array(); - - foreach ( $special_keys as $key ) { - if ( isset( $assoc_args[ $key ] ) ) { - $assoc_special[ $key ] = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); - } - } - - return $assoc_special; -} - function set_wp_root( $assoc_args ) { if ( !empty( $assoc_args['path'] ) ) { define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); From df80ca0ff7da6b590dda5c274ba35930fc93462c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 09:47:38 +0200 Subject: [PATCH 0986/4858] rename $assoc_special to $config --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/class-wp-cli.php | 34 +++++++++++++++------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index a6a3d1f976..9f4259f99a 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -76,7 +76,7 @@ private function check_positional( $args, $accepted_params ) { private function check_assoc( $assoc_args, $accepted_params ) { $mandatory_assoc = array(); - $assoc_args += \WP_CLI::get_assoc_special(); + $assoc_args += \WP_CLI::get_config(); foreach ( $accepted_params['assoc'] as $param ) { if ( !$param['optional'] ) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index fee8087556..7928827818 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -14,7 +14,9 @@ class WP_CLI { private static $man_dirs = array(); - private static $arguments, $assoc_args, $assoc_special; + private static $config; + + private static $arguments, $assoc_args; /** * Add a command to the wp-cli list of commands @@ -67,7 +69,7 @@ static function line( $message = '' ) { * @param bool $exit */ static function error( $message, $exit = true ) { - if ( !isset( self::$assoc_special['completions'] ) ) { + if ( !isset( self::$config['completions'] ) ) { $label = 'Error'; $msg = '%R' . $label . ': %n' . self::error_to_string( $message ); self::out( $msg . "\n", STDERR ); @@ -232,14 +234,14 @@ private static function parse_args() { private static function split_special( $special_keys ) { foreach ( $special_keys as $key ) { if ( isset( self::$assoc_args[ $key ] ) ) { - self::$assoc_special[ $key ] = self::$assoc_args[ $key ]; + self::$config[ $key ] = self::$assoc_args[ $key ]; unset( self::$assoc_args[ $key ] ); } } } - static function get_assoc_special() { - return self::$assoc_special; + static function get_config() { + return self::$config; } static function before_wp_load() { @@ -250,11 +252,11 @@ static function before_wp_load() { WP_CLI_ROOT . "../man-src/" ); - self::$assoc_special = Utils\load_config(); + self::$config = Utils\load_config(); self::parse_args(); - define( 'WP_CLI_QUIET', isset( self::$assoc_special['quiet'] ) ); + define( 'WP_CLI_QUIET', isset( self::$config['quiet'] ) ); // Handle --version parameter if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { @@ -271,10 +273,10 @@ static function before_wp_load() { $_SERVER['DOCUMENT_ROOT'] = getcwd(); // Handle --path - Utils\set_wp_root( self::$assoc_special ); + Utils\set_wp_root( self::$config ); // Handle --url and --blog parameters - Utils\set_url( self::$assoc_special ); + Utils\set_url( self::$config ); if ( array( 'core', 'download' ) == self::$arguments ) { self::run_command(); @@ -327,21 +329,21 @@ private static function cmd_starts_with( $prefix ) { static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - Utils\set_user( self::$assoc_special ); + Utils\set_user( self::$config ); - if ( !defined( 'WP_INSTALLING' ) && isset( self::$assoc_special['url'] ) ) + if ( !defined( 'WP_INSTALLING' ) && isset( self::$config['url'] ) ) Utils\set_wp_query(); - if ( isset( self::$assoc_special['require'] ) ) - require self::$assoc_special['require']; + if ( isset( self::$config['require'] ) ) + require self::$config['require']; - if ( isset( self::$assoc_special['man'] ) ) { + if ( isset( self::$config['man'] ) ) { self::generate_man( self::$arguments ); exit; } // Handle --syn-list parameter - if ( isset( self::$assoc_special['syn-list'] ) ) { + if ( isset( self::$config['syn-list'] ) ) { foreach ( self::$root->get_subcommands() as $command ) { if ( $command instanceof Dispatcher\Composite ) { foreach ( $command->get_subcommands() as $subcommand ) @@ -353,7 +355,7 @@ static function after_wp_load() { exit; } - if ( isset( self::$assoc_special['completions'] ) ) { + if ( isset( self::$config['completions'] ) ) { self::render_automcomplete(); exit; } From cb92930237ab893aa906fa38cb64b286ea46ec24 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 10:06:37 +0200 Subject: [PATCH 0987/4858] correct extension is .yml, not .yaml --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index ac3858aa45..96e8b22f82 100644 --- a/php/utils.php +++ b/php/utils.php @@ -44,7 +44,7 @@ function register_autoload() { } function load_config() { - foreach ( array( 'wp-cli.local.yaml', 'wp-cli.yaml' ) as $fname ) { + foreach ( array( 'wp-cli.local.yml', 'wp-cli.yml' ) as $fname ) { $path = getcwd() . '/' . $fname; if ( file_exists( $path ) ) { From 7601ec85446507386a878b7ea518a57da7ca5ecf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 10:17:19 +0200 Subject: [PATCH 0988/4858] whitelist config keys --- php/class-wp-cli.php | 4 +++- php/utils.php | 13 +++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7928827818..30f6fc89bf 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -252,7 +252,9 @@ static function before_wp_load() { WP_CLI_ROOT . "../man-src/" ); - self::$config = Utils\load_config(); + self::$config = Utils\load_config( array( + 'path', 'url', 'user' + ) ); self::parse_args(); diff --git a/php/utils.php b/php/utils.php index 96e8b22f82..c7f18b0a3b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -43,12 +43,21 @@ function register_autoload() { } ); } -function load_config() { +function load_config( $allowed_keys ) { foreach ( array( 'wp-cli.local.yml', 'wp-cli.yml' ) as $fname ) { $path = getcwd() . '/' . $fname; if ( file_exists( $path ) ) { - return spyc_load_file( $path ); + $config = spyc_load_file( $path ); + + $sanitized_config = array(); + + foreach ( $allowed_keys as $key ) { + if ( isset( $config[ $key ] ) ) + $sanitized_config[ $key ] = $config[ $key ]; + } + + return $sanitized_config; } } From 43f6097120bf27b5b1e749f3a7db115e49eb4260 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 13:46:06 +0200 Subject: [PATCH 0989/4858] separate wp-dependent utilities from independent ones --- php/class-wp-cli.php | 2 ++ php/utils-wp.php | 38 ++++++++++++++++++++++++++++++++++++++ php/utils.php | 40 ++-------------------------------------- 3 files changed, 42 insertions(+), 38 deletions(-) create mode 100644 php/utils-wp.php diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 30f6fc89bf..b23be480e7 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -329,6 +329,8 @@ private static function cmd_starts_with( $prefix ) { } static function after_wp_load() { + require WP_CLI_ROOT . 'utils-wp.php'; + add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); Utils\set_user( self::$config ); diff --git a/php/utils-wp.php b/php/utils-wp.php new file mode 100644 index 0000000000..3eafb3035d --- /dev/null +++ b/php/utils-wp.php @@ -0,0 +1,38 @@ +<?php + +// Utilities that depend on WordPress code. + +namespace WP_CLI\Utils; + +// Handle --user parameter +function set_user( $assoc_args ) { + if ( !isset( $assoc_args['user'] ) ) + return; + + $user = $assoc_args['user']; + + if ( is_numeric( $user ) ) { + $user_id = (int) $user; + } else { + $user_id = (int) username_exists( $user ); + } + + if ( !$user_id || !wp_set_current_user( $user_id ) ) { + \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); + } +} + +function set_wp_query() { + if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { + $GLOBALS['wp']->parse_request(); + $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); + } +} + +function get_upgrader( $class ) { + if ( !class_exists( '\WP_Upgrader' ) ) + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + + return new $class( new \WP_CLI\UpgraderSkin ); +} + diff --git a/php/utils.php b/php/utils.php index c7f18b0a3b..12dc881729 100644 --- a/php/utils.php +++ b/php/utils.php @@ -1,5 +1,7 @@ <?php +// Utilities that do NOT depend on WordPress code. + namespace WP_CLI\Utils; function bootstrap() { @@ -175,44 +177,6 @@ function load_wp_config() { \WP_CLI::error( 'No wp-config.php file.' ); } - - -// ---- AFTER WORDPRESS IS LOADED ---- // - - - -// Handle --user parameter -function set_user( $assoc_args ) { - if ( !isset( $assoc_args['user'] ) ) - return; - - $user = $assoc_args['user']; - - if ( is_numeric( $user ) ) { - $user_id = (int) $user; - } else { - $user_id = (int) username_exists( $user ); - } - - if ( !$user_id || !wp_set_current_user( $user_id ) ) { - \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); - } -} - -function set_wp_query() { - if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { - $GLOBALS['wp']->parse_request(); - $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); - } -} - -function get_upgrader( $class ) { - if ( !class_exists( '\WP_Upgrader' ) ) - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - - return new $class( new \WP_CLI\UpgraderSkin ); -} - function parse_csv( $filepath, $has_headers = true ) { if ( false == ( $csv = fopen( $filepath, 'r' ) ) ) From 50cbbdbeea5d154e5b793d37289b7137e2326988 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 13:51:28 +0200 Subject: [PATCH 0990/4858] move set_wp_root() closer to locate_wp_config() --- php/utils.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/php/utils.php b/php/utils.php index 12dc881729..88c83e187e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -89,14 +89,6 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args ); } -function set_wp_root( $assoc_args ) { - if ( !empty( $assoc_args['path'] ) ) { - define( 'WP_ROOT', rtrim( $assoc_args['path'], '/' ) . '/' ); - } else { - define( 'WP_ROOT', getcwd() . '/' ); - } -} - function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $blog = $assoc_args['url']; @@ -157,14 +149,22 @@ function set_url_params( $url ) { $_SERVER['REQUEST_METHOD'] = 'GET'; } +function set_wp_root( $config ) { + if ( !empty( $config['path'] ) ) { + define( 'WP_ROOT', rtrim( $config['path'], '/' ) . '/' ); + } else { + define( 'WP_ROOT', getcwd() . '/' ); + } +} + function locate_wp_config() { - if ( file_exists( WP_ROOT . 'wp-config.php' ) ) { + if ( file_exists( WP_ROOT . 'wp-config.php' ) ) return WP_ROOT . 'wp-config.php'; - } elseif ( file_exists( WP_ROOT . '/../wp-config.php' ) && ! file_exists( WP_ROOT . '/../wp-settings.php' ) ) { + + if ( file_exists( WP_ROOT . '/../wp-config.php' ) && ! file_exists( WP_ROOT . '/../wp-settings.php' ) ) return WP_ROOT . '/../wp-config.php'; - } else { - return false; - } + + return false; } // Loads wp-config.php without loading the rest of WP From c0226e0e69384476157b30eef7d34786fa86a677 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 14:15:17 +0200 Subject: [PATCH 0991/4858] replace parse_csv() with CSVIterator class --- php/WP_CLI/CSVIterator.php | 58 ++++++++++++++++++++++++++++++++++++++ php/commands/user.php | 10 +++---- php/utils.php | 24 ---------------- 3 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 php/WP_CLI/CSVIterator.php diff --git a/php/WP_CLI/CSVIterator.php b/php/WP_CLI/CSVIterator.php new file mode 100644 index 0000000000..339044b065 --- /dev/null +++ b/php/WP_CLI/CSVIterator.php @@ -0,0 +1,58 @@ +<?php + +namespace WP_CLI; + +class CSVIterator implements \Iterator { + + const ROW_SIZE = 4096; + + private $filePointer; + + private $delimiter; + private $columns; + + private $currentIndex; + private $currentElement; + + public function __construct( $file, $delimiter = ',' ) { + $this->filePointer = fopen( $file, 'r' ); + $this->delimiter = $delimiter; + } + + private function read_line() { + return fgetcsv( $this->filePointer, self::ROW_SIZE, $this->delimiter ); + } + + public function rewind() { + rewind( $this->filePointer ); + + $this->columns = $this->read_line(); + + $this->currentIndex = -1; + $this->next(); + } + + public function current() { + return $this->currentElement; + } + + public function key() { + return $this->currentIndex; + } + + public function next() { + $row = $this->read_line(); + + if ( !is_array( $row ) ) { + $this->currentElement = false; + } else { + $this->currentElement = array_combine( $this->columns, $row ); + $this->currentIndex++; + } + } + + public function valid() { + return is_array( $this->currentElement ); + } +} + diff --git a/php/commands/user.php b/php/commands/user.php index 7d998c592f..11dc707c9d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -294,14 +294,14 @@ private static function get_user_from_first_arg( $id_or_login ) { */ public function import_csv( $args, $assoc_args ) { - list( $csv ) = $args; - - $new_users = \WP_CLI\utils\parse_csv( $csv ); - $blog_users = get_users(); - foreach( $new_users as $new_user ) { + $filename = $args[0]; + + if ( !is_readable( $filename ) ) + \WP_CLI::error( sprintf( 'Could not open file: %s', $filename ) ); + foreach ( new \WP_CLI\CSVIterator( $filename ) as $i => $new_user ) { $defaults = array( 'role' => get_option('default_role'), 'user_pass' => wp_generate_password(), diff --git a/php/utils.php b/php/utils.php index 88c83e187e..aac36c5b2c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -177,30 +177,6 @@ function load_wp_config() { \WP_CLI::error( 'No wp-config.php file.' ); } -function parse_csv( $filepath, $has_headers = true ) { - - if ( false == ( $csv = fopen( $filepath, 'r' ) ) ) - \WP_CLI::error( sprintf( 'Could not open csv file: %s', $filepath ) ); - - $parsed_data = array(); - $headers = array(); - while ( ( $row = fgetcsv( $csv, 10000, "," ) ) !== FALSE ) { - if ( $has_headers ) { - $headers = array_values( $row ); - $has_headers = false; - continue; - } - $row_data = array(); - foreach( $row as $index => $cell_value ) { - if ( ! empty( $headers[$index] ) ) - $index = $headers[$index]; - $row_data[$index] = $cell_value; - } - $parsed_data[] = $row_data; - } - return $parsed_data; -} - /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. From 2db8a6acabd555ffef1eaa97c80467bf3af9c755 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 16:13:39 +0200 Subject: [PATCH 0992/4858] make iterator more lenient * don't bail on empty lines * allow columns to be skipped --- php/WP_CLI/CSVIterator.php | 40 +++++++++++++++++++++++++------------- php/commands/user.php | 3 --- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/php/WP_CLI/CSVIterator.php b/php/WP_CLI/CSVIterator.php index 339044b065..46a3bf9c0e 100644 --- a/php/WP_CLI/CSVIterator.php +++ b/php/WP_CLI/CSVIterator.php @@ -14,19 +14,18 @@ class CSVIterator implements \Iterator { private $currentIndex; private $currentElement; - public function __construct( $file, $delimiter = ',' ) { - $this->filePointer = fopen( $file, 'r' ); - $this->delimiter = $delimiter; - } + public function __construct( $filename, $delimiter = ',' ) { + $this->filePointer = fopen( $filename, 'r' ); + if ( !is_readable( $filename ) ) + \WP_CLI::error( sprintf( 'Could not open file: %s', $filename ) ); - private function read_line() { - return fgetcsv( $this->filePointer, self::ROW_SIZE, $this->delimiter ); + $this->delimiter = $delimiter; } public function rewind() { rewind( $this->filePointer ); - $this->columns = $this->read_line(); + $this->columns = fgetcsv( $this->filePointer, self::ROW_SIZE, $this->delimiter ); $this->currentIndex = -1; $this->next(); @@ -41,13 +40,28 @@ public function key() { } public function next() { - $row = $this->read_line(); + $this->currentElement = false; + + while ( true ) { + $str = fgets( $this->filePointer ); + + if ( false === $str ) + break; + + $row = str_getcsv( $str, $this->delimiter ); + + $element = array(); + foreach ( $this->columns as $i => $key ) { + if ( isset( $row[ $i ] ) ) + $element[ $key ] = $row[ $i ]; + } + + if ( !empty( $element ) ) { + $this->currentElement = $element; + $this->currentIndex++; - if ( !is_array( $row ) ) { - $this->currentElement = false; - } else { - $this->currentElement = array_combine( $this->columns, $row ); - $this->currentIndex++; + break; + } } } diff --git a/php/commands/user.php b/php/commands/user.php index 11dc707c9d..a1a8c1d12b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -298,9 +298,6 @@ public function import_csv( $args, $assoc_args ) { $filename = $args[0]; - if ( !is_readable( $filename ) ) - \WP_CLI::error( sprintf( 'Could not open file: %s', $filename ) ); - foreach ( new \WP_CLI\CSVIterator( $filename ) as $i => $new_user ) { $defaults = array( 'role' => get_option('default_role'), From 2ff2cf8509d4d164c53c8e0a2bb48eaf06403c1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 16:33:11 +0200 Subject: [PATCH 0993/4858] make wp user delete accept multiple ids. see #229 --- php/commands/user.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index a1a8c1d12b..8d0e77fb0e 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -59,24 +59,28 @@ public function _list( $args, $assoc_args ) { } /** - * Delete a user. + * Delete one or more users. * - * @synopsis <id> [--reassign=<id>] + * @synopsis <id>... [--reassign=<id>] */ public function delete( $args, $assoc_args ) { - global $blog_id; - - list( $user_id ) = $args; - - $defaults = array( 'reassign' => NULL ); + $defaults = array( + 'reassign' => null + ); extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - if ( wp_delete_user( $user_id, $reassign ) ) { - WP_CLI::success( "Deleted user $user_id." ); - } else { - WP_CLI::error( "Failed deleting user $user_id." ); + foreach ( $args as $user_id ) { + if ( wp_delete_user( $user_id, $reassign ) ) { + WP_CLI::success( "Deleted user $user_id." ); + $status = 0; + } else { + WP_CLI::error( "Failed deleting user $user_id.", false ); + $status = 1; + } } + + exit( $status ); } /** From ce99707c049945f10f26bc513b2ac82fefae3721 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 28 Dec 2012 19:46:38 +0200 Subject: [PATCH 0994/4858] introduce CommandWithDBObject class - make `wp user update` accept multiple IDs. see #229 - use wpmu_user_delete() when on multisite - return correct error status --- php/WP_CLI/CommandWithDBObject.php | 82 +++++++++++++++++++++++++ php/commands/post.php | 70 ++++++++++------------ php/commands/user.php | 96 ++++++++++++++---------------- 3 files changed, 158 insertions(+), 90 deletions(-) create mode 100644 php/WP_CLI/CommandWithDBObject.php diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php new file mode 100644 index 0000000000..8b252663ad --- /dev/null +++ b/php/WP_CLI/CommandWithDBObject.php @@ -0,0 +1,82 @@ +<?php + +namespace WP_CLI; + +/** + * Base class for WP-CLI commands that deal with database objects. + * + * @package wp-cli + */ +abstract class CommandWithDBObject extends \WP_CLI_Command { + + abstract protected function _create( $params ); + abstract protected function _update( $params ); + abstract protected function _delete( $obj_id, $assoc_args ); + + public function create( $assoc_args ) { + unset( $assoc_args['ID'] ); + + $obj_id = $this->_create( $assoc_args ); + + if ( is_wp_error( $obj_id ) ) { + \WP_CLI::error( $obj_id ); + } + + if ( isset( $assoc_args['porcelain'] ) ) + \WP_CLI::line( $obj_id ); + else + \WP_CLI::success( "Created $this->obj_type $obj_id." ); + } + + public function update( $args, $assoc_args ) { + $status = 0; + + if ( empty( $assoc_args ) ) { + \WP_CLI::error( "Need some fields to update." ); + } + + foreach ( $args as $obj_id ) { + $params = array_merge( $assoc_args, array( 'ID' => $obj_id ) ); + + $status = $this->success_or_failure( $this->wp_error_to_resp( + $this->_update( $params ), + "Updated $this->obj_type $obj_id." + ) ); + } + + exit( $status ); + } + + protected function wp_error_to_resp( $r, $success_msg ) { + if ( is_wp_error( $r ) ) + return array( 'error', $r->get_error_message() ); + else + return array( 'success', $success_msg ); + } + + protected function success_or_failure( $r ) { + list( $type, $msg ) = $r; + + if ( 'success' == $type ) { + \WP_CLI::success( $msg ); + $status = 0; + } else { + \WP_CLI::error( $msg, false ); + $status = 1; + } + + return $status; + } + + public function delete( $args, $assoc_args ) { + $status = 0; + + foreach ( $args as $obj_id ) { + $r = $this->_delete( $obj_id, $assoc_args ); + $status = $this->success_or_failure( $r ); + } + + exit( $status ); + } +} + diff --git a/php/commands/post.php b/php/commands/post.php index 12ca8e0948..b7652676bd 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -1,14 +1,14 @@ <?php -WP_CLI::add_command( 'post', 'Post_Command' ); - /** * Implement post command * * @package wp-cli * @subpackage commands/internals */ -class Post_Command extends WP_CLI_Command { +class Post_Command extends \WP_CLI\CommandWithDBObject { + + protected $obj_type = 'post'; /** * Create a post. @@ -16,41 +16,24 @@ class Post_Command extends WP_CLI_Command { * @synopsis --<field>=<value> [--porcelain] */ public function create( $_, $assoc_args ) { - unset( $assoc_args['ID'] ); - - $post_id = wp_insert_post( $assoc_args, true ); - - if ( is_wp_error( $post_id ) ) { - WP_CLI::error( $post_id ); - } + parent::create( $assoc_args ); + } - if ( isset( $assoc_args['porcelain'] ) ) - WP_CLI::line( $post_id ); - else - WP_CLI::success( "Created post $post_id." ); + protected function _create( $params ) { + return wp_insert_post( $params, true ); } /** - * Update a post. + * Update one or more posts. * * @synopsis <id>... --<field>=<value> */ public function update( $args, $assoc_args ) { - foreach ( $args as $post_id ) { - if ( empty( $assoc_args ) ) { - WP_CLI::error( "Need some fields to update." ); - } - - $params = array_merge( $assoc_args, array( 'ID' => $post_id ) ); - - $r = wp_update_post( $params, true ); + parent::update( $args, $assoc_args ); + } - if ( is_wp_error( $r ) ) { - WP_CLI::error( "Post $post_id: " . $r->get_error_message() ); - } else { - WP_CLI::success( "Updated post $post_id." ); - } - } + protected function _update( $params ) { + return wp_update_post( $params, true ); } /** @@ -58,15 +41,23 @@ public function update( $args, $assoc_args ) { * * @synopsis <id>... [--force] */ - public function delete( $post_ids, $assoc_args ) { - $action = isset( $assoc_args['force'] ) ? 'Deleted' : 'Trashed'; - - foreach ( $post_ids as $post_id ) { - if ( wp_delete_post( $post_id, $assoc_args['force'] ) ) { - WP_CLI::success( "{$action} post $post_id." ); - } else { - WP_CLI::error( "Failed deleting post $post_id." ); - } + public function delete( $args, $assoc_args ) { + $assoc_args = wp_parse_args( $assoc_args, array( + 'force' => false + ) ); + + parent::delete( $args, $assoc_args ); + } + + protected function _delete( $post_id, $assoc_args ) { + $r = wp_delete_post( $post_id, $assoc_args['force'] ); + + if ( $r ) { + $action = $assoc_args['force'] ? 'Deleted' : 'Trashed'; + + return array( 'success', "$action post $post_id." ); + } else { + return array( 'error', "Failed deleting post $post_id." ); } } @@ -206,3 +197,6 @@ private function maybe_reset_depth() { return ( mt_rand(1,10) == 7 ) ? true : false; } } + +WP_CLI::add_command( 'post', 'Post_Command' ); + diff --git a/php/commands/user.php b/php/commands/user.php index 8d0e77fb0e..fb69f14d4f 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -1,14 +1,12 @@ <?php -WP_CLI::add_command('user', 'User_Command'); - /** * Implement user command * * @package wp-cli * @subpackage commands/internals */ -class User_Command extends WP_CLI_Command { +class User_Command extends \WP_CLI\CommandWithDBObject { /** * List users. @@ -24,7 +22,7 @@ public function _list( $args, $assoc_args ) { 'fields' => isset( $assoc_args['ids'] ) ? 'ids' : 'all_with_meta', ); - if ( array_key_exists('role', $assoc_args) ) { + if ( array_key_exists( 'role', $assoc_args ) ) { $params['role'] = $assoc_args['role']; } @@ -32,30 +30,29 @@ public function _list( $args, $assoc_args ) { if ( isset( $assoc_args['ids'] ) ) { WP_CLI::out( implode( ' ', $users ) ); - return; - } + } else { + $fields = array('ID', 'user_login', 'display_name', 'user_email', + 'user_registered'); - $fields = array('ID', 'user_login', 'display_name', 'user_email', - 'user_registered'); + $table = new \cli\Table(); - $table = new \cli\Table(); + $table->setHeaders( array_merge( $fields, array('roles') ) ); - $table->setHeaders( array_merge($fields, array('roles')) ); + foreach ( $users as $user ) { + $line = array(); - foreach ( $users as $user ) { - $line = array(); + foreach ( $fields as $field ) { + $line[] = $user->$field; + } + $line[] = implode( ',', $user->roles ); - foreach ( $fields as $field ) { - $line[] = $user->$field; + $table->addRow( $line ); } - $line[] = implode( ',', $user->roles ); - $table->addRow($line); - } - - $table->display(); + $table->display(); - WP_CLI::line( 'Total: ' . count($users) . ' users' ); + WP_CLI::line( 'Total: ' . count( $users ) . ' users' ); + } } /** @@ -64,23 +61,25 @@ public function _list( $args, $assoc_args ) { * @synopsis <id>... [--reassign=<id>] */ public function delete( $args, $assoc_args ) { - $defaults = array( + $assoc_args = wp_parse_args( $assoc_args, array( 'reassign' => null - ); + ) ); - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + parent::delete( $args, $assoc_args ); + } - foreach ( $args as $user_id ) { - if ( wp_delete_user( $user_id, $reassign ) ) { - WP_CLI::success( "Deleted user $user_id." ); - $status = 0; - } else { - WP_CLI::error( "Failed deleting user $user_id.", false ); - $status = 1; - } + protected function _delete( $user_id, $assoc_args ) { + if ( is_multisite() ) { + $r = wpmu_delete_user( $user_id ); + } else { + $r = wp_delete_user( $user_id, $assoc_args['reassign'] ); } - exit( $status ); + if ( $r ) { + return array( 'success', "Deleted user $user_id." ); + } else { + return array( 'error', "Failed deleting user $user_id." ); + } } /** @@ -89,8 +88,6 @@ public function delete( $args, $assoc_args ) { * @synopsis <user-login> <user-email> [--role=<role>] [--user_pass=<password>] [--user_registered=<yyyy-mm-dd>] [--display_name=<name>] [--porcelain] */ public function create( $args, $assoc_args ) { - global $blog_id; - list( $user_login, $user_email ) = $args; $defaults = array( @@ -113,7 +110,7 @@ public function create( $args, $assoc_args ) { $generated_pass = true; } - $user_id = wp_insert_user( array( + $user_id = $this->_create( array( 'user_email' => $user_email, 'user_login' => $user_login, 'user_pass' => $user_pass, @@ -122,7 +119,7 @@ public function create( $args, $assoc_args ) { 'role' => $role, ) ); - if ( is_wp_error($user_id) ) { + if ( is_wp_error( $user_id ) ) { WP_CLI::error( $user_id ); } else { if ( false === $role ) { @@ -140,27 +137,21 @@ public function create( $args, $assoc_args ) { } } + protected function _create( $params ) { + return wp_insert_user( $params ); + } + /** * Update a user. * - * @synopsis <id> --<field>=<value> + * @synopsis <id>... --<field>=<value> */ public function update( $args, $assoc_args ) { - list( $user_id ) = $args; - - if ( empty( $assoc_args ) ) { - WP_CLI::error( "Need some fields to update." ); - } - - $params = array_merge( array( 'ID' => $user_id ), $assoc_args ); - - $updated_id = wp_update_user( $params ); + parent::update( $args, $assoc_args, 'user' ); + } - if ( is_wp_error( $updated_id ) ) { - WP_CLI::error( $updated_id ); - } else { - WP_CLI::success( "Updated user $updated_id." ); - } + protected function _update( $params ) { + return wp_update_user( $params ); } /** @@ -356,6 +347,7 @@ public function import_csv( $args, $assoc_args ) { } } } - } +WP_CLI::add_command( 'user', 'User_Command' ); + From e47c6d526039ce75b0bcd9bf84ccb404de49905a Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 20:54:27 +0100 Subject: [PATCH 0995/4858] Implemented the STDOUT --theme flag and or --plugin="" for post_types --- .../wp-cli/commands/internals/scaffold.php | 86 +++++++++++++++---- .../skeletons/post_type_skeleton.php | 2 +- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 6764e409da..9c9d415c4a 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -20,7 +20,7 @@ function __construct() { * * @alias pt * - * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] + * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin-name>] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -61,24 +61,23 @@ function post_type( $args, $assoc_args ) { 'query_var' => 'true', 'can_export' => 'true', 'textdomain' => strtolower( wp_get_theme()->template ), + 'theme' => false, + 'plugin' => false ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - $path = TEMPLATEPATH . '/post-types/'; - if( !$wp_filesystem->is_dir( $path ) ) { - $wp_filesystem->mkdir( $path ); - } - - $filename = $path . $post_type .'.php'; - - include 'skeletons/post_type_skeleton.php'; - - if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { - WP_CLI::error( 'Error while saving file' ); + + include "skeletons/post_type_skeleton.php"; + $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin' => $plugin, 'machine_name' => $machine_name, 'path' => false ); + + if ( $theme || !empty( $plugin ) ) { + // Write file to theme or (given) plugin path + $assoc_args['path'] = $this->get_output_path( $assoc_args ); + $this->parse_skeleton( $assoc_args ); } else { - WP_CLI::success( $post_type . ' created' ); + // STDOUT + echo $this->parse_skeleton( $assoc_args ); } } @@ -129,7 +128,7 @@ function taxonomy( $args, $assoc_args ) { $wp_filesystem->mkdir( $path ); } - $filename = $path . $taxonomy .'.php'; + $filename = $path . $taxonomy . '.php'; include 'skeletons/taxonomy_skeleton.php'; @@ -140,6 +139,62 @@ function taxonomy( $args, $assoc_args ) { } } + private function get_output_path( $assoc_args ) { + global $wp_filesystem; + + extract( $assoc_args, EXTR_SKIP ); + + // Implements the --theme flag || --plugin=<plugin-name> + if( $theme ) { + //Here we assume you got a theme installed + $path = TEMPLATEPATH; + } elseif ( !empty( $plugin ) ){ + $path = WP_PLUGIN_DIR . '/' . $plugin; //Faking recursive mkdir for down the line + $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin ); //Faking recursive mkdir for down the line + } else { + // STDOUT + return false; + } + + if ( $type === "post_type") { + $path .= '/post-types/'; + } elseif ( $type === "taxonomy" ) { + $path .= '/taxonomies/'; + } + + // If it doesn't exists create it + if( !$wp_filesystem->is_dir( $path ) ) { + $wp_filesystem->mkdir( $path ); + WP_CLI::success( "Created dir: {$path}" ); + } elseif( $wp_filesystem->is_dir( $path ) ) { + WP_CLI::success( "Dir already exists: {$path}" ); + } else { + WP_CLI::error( "Couldn't create dir exists: {$path}" ); + } + + return $path; + } + + private function parse_skeleton( $assoc_args = array() ) { + global $wp_filesystem; + + extract( $assoc_args, EXTR_SKIP ); + + // Write to file + if( $path ) { + $filename = $path . $machine_name .'.php'; + + if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { + WP_CLI::error( "Error while saving file: {$filename}" ); + } else { + WP_CLI::success( $machine_name . ' created' ); + } + } else { + // Return for STDOUT + return $output; + } + } + private function pluralize( $word ) { $plural = array( '/(quiz)$/i' => '\1zes', @@ -193,6 +248,5 @@ private function pluralize( $word ) { } } return false; - } } \ No newline at end of file diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php index 1b06f2c647..e92355d2bc 100755 --- a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php +++ b/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php @@ -63,4 +63,4 @@ function {$machine_name}_updated_messages( \$messages ) { return \$messages; } -add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; +add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; \ No newline at end of file From 11de929dbf8014fdd9143d15f30c3a2575fb04f0 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 21:02:19 +0100 Subject: [PATCH 0996/4858] Implemented the STDOUT --theme flag and or --plugin="" for taxonomies --- .../wp-cli/commands/internals/scaffold.php | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 9c9d415c4a..7047b4b44f 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -86,7 +86,7 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] + * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin=<plugin-name>] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; @@ -117,25 +117,24 @@ function taxonomy( $args, $assoc_args ) { 'query_var' => 'true', 'slug' => $taxonomy, 'textdomain' => strtolower( wp_get_theme()->template ), - 'post_types' => 'post' + 'post_types' => 'post', + 'theme' => false, + 'plugin' => false ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - $path = TEMPLATEPATH . '/taxonomies/'; - if( !$wp_filesystem->is_dir( $path ) ) { - $wp_filesystem->mkdir( $path ); - } - - $filename = $path . $taxonomy . '.php'; - include 'skeletons/taxonomy_skeleton.php'; - - if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { - WP_CLI::error( 'Error while saving file' ); + $assoc_args = array('type' => 'taxonomy', 'output' => $output, 'theme' => $theme, 'plugin' => $plugin, 'machine_name' => $machine_name, 'path' => false ); + + if ( $theme || !empty( $plugin ) ) { + // Write file to theme or (given) plugin path + $assoc_args['path'] = $this->get_output_path( $assoc_args ); + $this->parse_skeleton( $assoc_args ); } else { - WP_CLI::success( $taxonomy . ' created' ); + // STDOUT + echo $this->parse_skeleton( $assoc_args ); } } @@ -187,7 +186,7 @@ private function parse_skeleton( $assoc_args = array() ) { if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { WP_CLI::error( "Error while saving file: {$filename}" ); } else { - WP_CLI::success( $machine_name . ' created' ); + WP_CLI::success( ucfirst($type) . " {$machine_name} created" ); } } else { // Return for STDOUT From 970ce971a396f4cdd7770baf26874cb904c56fad Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 21:21:45 +0100 Subject: [PATCH 0997/4858] Use theme, plugin name or YOUR-TEXTDOMAIN as textdomain, closes #5 --- src/php/wp-cli/commands/internals/scaffold.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 7047b4b44f..31d869580b 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -39,7 +39,7 @@ function post_type( $args, $assoc_args ) { $label_plural = $this->pluralize( $label ); $label_plural_ucfirst = ucfirst( $label_plural ); } - + // set up defaults and merge theme with assoc_args $defaults = array( 'description' => "", @@ -60,13 +60,23 @@ function post_type( $args, $assoc_args ) { 'pages' => 'true', 'query_var' => 'true', 'can_export' => 'true', - 'textdomain' => strtolower( wp_get_theme()->template ), + 'textdomain' => '', 'theme' => false, 'plugin' => false ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + // Because if you're writing your files to your theme directory your textdomain also needs to be the same + // Same goes for when plugin is being used + if( empty($textdomain) && $theme ) { + $textdomain = strtolower( wp_get_theme()->template ); + } elseif ( empty($textdomain) && $plugin) { + $textdomain = $plugin; + } else { + $textdomain = 'YOUR_TEXTDOMAIN'; + } include "skeletons/post_type_skeleton.php"; $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin' => $plugin, 'machine_name' => $machine_name, 'path' => false ); From 56f3ac0124c6a6ce842434065c0618118c10c751 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 22:30:13 +0100 Subject: [PATCH 0998/4858] Renamed the --plugin to --plugin_name and also really fixed #5 so it always return the default --- .../wp-cli/commands/internals/scaffold.php | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 31d869580b..760a9cde82 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -20,7 +20,7 @@ function __construct() { * * @alias pt * - * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin-name>] + * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -62,27 +62,19 @@ function post_type( $args, $assoc_args ) { 'can_export' => 'true', 'textdomain' => '', 'theme' => false, - 'plugin' => false + 'plugin_name' => false ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - // Because if you're writing your files to your theme directory your textdomain also needs to be the same - // Same goes for when plugin is being used - if( empty($textdomain) && $theme ) { - $textdomain = strtolower( wp_get_theme()->template ); - } elseif ( empty($textdomain) && $plugin) { - $textdomain = $plugin; - } else { - $textdomain = 'YOUR_TEXTDOMAIN'; - } + $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); include "skeletons/post_type_skeleton.php"; - $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin' => $plugin, 'machine_name' => $machine_name, 'path' => false ); + $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name, 'path' => false ); - if ( $theme || !empty( $plugin ) ) { - // Write file to theme or (given) plugin path + if ( $theme || !empty( $plugin_name ) ) { + // Write file to theme or given plugin_name $assoc_args['path'] = $this->get_output_path( $assoc_args ); $this->parse_skeleton( $assoc_args ); } else { @@ -96,7 +88,7 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin=<plugin-name>] + * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; @@ -126,20 +118,22 @@ function taxonomy( $args, $assoc_args ) { 'rewrite' => 'true', 'query_var' => 'true', 'slug' => $taxonomy, - 'textdomain' => strtolower( wp_get_theme()->template ), 'post_types' => 'post', + 'textdomain' => '', 'theme' => false, - 'plugin' => false + 'plugin_name' => false ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); + include 'skeletons/taxonomy_skeleton.php'; - $assoc_args = array('type' => 'taxonomy', 'output' => $output, 'theme' => $theme, 'plugin' => $plugin, 'machine_name' => $machine_name, 'path' => false ); + $assoc_args = array('type' => 'taxonomy', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name, 'path' => false ); - if ( $theme || !empty( $plugin ) ) { - // Write file to theme or (given) plugin path + if ( $theme || !empty( $plugin_name ) ) { + // Write file to theme or given plugin_name $assoc_args['path'] = $this->get_output_path( $assoc_args ); $this->parse_skeleton( $assoc_args ); } else { @@ -153,13 +147,13 @@ private function get_output_path( $assoc_args ) { extract( $assoc_args, EXTR_SKIP ); - // Implements the --theme flag || --plugin=<plugin-name> + // Implements the --theme flag || --plugin_name=<plugin_name> if( $theme ) { //Here we assume you got a theme installed $path = TEMPLATEPATH; - } elseif ( !empty( $plugin ) ){ - $path = WP_PLUGIN_DIR . '/' . $plugin; //Faking recursive mkdir for down the line - $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin ); //Faking recursive mkdir for down the line + } elseif ( !empty( $plugin_name ) ){ + $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line + $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line } else { // STDOUT return false; @@ -204,6 +198,22 @@ private function parse_skeleton( $assoc_args = array() ) { } } + /** + * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. + * Same goes for when plugin_name is being used. + */ + private function get_textdomain( $textdomain, $theme, $plugin_name ) { + if( empty( $textdomain ) && $theme ) { + $textdomain = strtolower( wp_get_theme()->template ); + } elseif ( empty( $textdomain ) && $plugin_name) { + $textdomain = $plugin_name; + } elseif ( empty( $textdomain ) || gettype($textdomain) == 'boolean' ) { //This mean just a flag + $textdomain = 'YOUR-TEXTDOMAIN'; + } + + return $textdomain; + } + private function pluralize( $word ) { $plural = array( '/(quiz)$/i' => '\1zes', From 3cb8f4558e9a400b13ec945022c5a7bfa842339b Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 22:56:49 +0100 Subject: [PATCH 0999/4858] Cleaned up and kind of closes #2 --- .../wp-cli/commands/internals/scaffold.php | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/src/php/wp-cli/commands/internals/scaffold.php index 760a9cde82..9e39d2ad86 100755 --- a/src/php/wp-cli/commands/internals/scaffold.php +++ b/src/php/wp-cli/commands/internals/scaffold.php @@ -70,16 +70,16 @@ function post_type( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - include "skeletons/post_type_skeleton.php"; - $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name, 'path' => false ); - + include 'skeletons/post_type_skeleton.php'; + if ( $theme || !empty( $plugin_name ) ) { // Write file to theme or given plugin_name + $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name ); $assoc_args['path'] = $this->get_output_path( $assoc_args ); - $this->parse_skeleton( $assoc_args ); + $this->save_skeleton_output( $assoc_args ); } else { // STDOUT - echo $this->parse_skeleton( $assoc_args ); + echo $output; } } @@ -130,15 +130,15 @@ function taxonomy( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); include 'skeletons/taxonomy_skeleton.php'; - $assoc_args = array('type' => 'taxonomy', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name, 'path' => false ); - + if ( $theme || !empty( $plugin_name ) ) { // Write file to theme or given plugin_name + $assoc_args = array('type' => 'taxonomy', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name ); $assoc_args['path'] = $this->get_output_path( $assoc_args ); - $this->parse_skeleton( $assoc_args ); + $this->save_skeleton_output( $assoc_args ); } else { // STDOUT - echo $this->parse_skeleton( $assoc_args ); + echo $output; } } @@ -178,7 +178,7 @@ private function get_output_path( $assoc_args ) { return $path; } - private function parse_skeleton( $assoc_args = array() ) { + private function save_skeleton_output( $assoc_args ) { global $wp_filesystem; extract( $assoc_args, EXTR_SKIP ); @@ -190,11 +190,8 @@ private function parse_skeleton( $assoc_args = array() ) { if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { WP_CLI::error( "Error while saving file: {$filename}" ); } else { - WP_CLI::success( ucfirst($type) . " {$machine_name} created" ); + WP_CLI::success( "{$type} {$machine_name} created" ); } - } else { - // Return for STDOUT - return $output; } } From e6764f260e9a177f9d8544dbd75129c36f38d8d2 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 23:30:11 +0100 Subject: [PATCH 1000/4858] Moved scaffold from src/php/wp-cli/commands/internals to php/commands --- {src/php/wp-cli/commands/internals => php/commands}/scaffold.php | 0 .../internals => php/commands}/skeletons/post_type_skeleton.php | 0 .../internals => php/commands}/skeletons/taxonomy_skeleton.php | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {src/php/wp-cli/commands/internals => php/commands}/scaffold.php (100%) rename {src/php/wp-cli/commands/internals => php/commands}/skeletons/post_type_skeleton.php (100%) rename {src/php/wp-cli/commands/internals => php/commands}/skeletons/taxonomy_skeleton.php (100%) diff --git a/src/php/wp-cli/commands/internals/scaffold.php b/php/commands/scaffold.php similarity index 100% rename from src/php/wp-cli/commands/internals/scaffold.php rename to php/commands/scaffold.php diff --git a/src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php b/php/commands/skeletons/post_type_skeleton.php similarity index 100% rename from src/php/wp-cli/commands/internals/skeletons/post_type_skeleton.php rename to php/commands/skeletons/post_type_skeleton.php diff --git a/src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php b/php/commands/skeletons/taxonomy_skeleton.php similarity index 100% rename from src/php/wp-cli/commands/internals/skeletons/taxonomy_skeleton.php rename to php/commands/skeletons/taxonomy_skeleton.php From c3b5195983e4ced20dfeabf9e00f5a6e45a4e14e Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 28 Dec 2012 23:59:18 +0100 Subject: [PATCH 1001/4858] A little bit of WordPress Conding Standards --- php/commands/scaffold.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 9e39d2ad86..c1b832d093 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -72,9 +72,15 @@ function post_type( $args, $assoc_args ) { include 'skeletons/post_type_skeleton.php'; - if ( $theme || !empty( $plugin_name ) ) { + if ( $theme || ! empty( $plugin_name ) ) { // Write file to theme or given plugin_name - $assoc_args = array('type' => 'post_type', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name ); + $assoc_args = array( + 'type' => 'post_type', + 'output' => $output, + 'theme' => $theme, + 'plugin_name' => $plugin_name, + 'machine_name' => $machine_name, + ); $assoc_args['path'] = $this->get_output_path( $assoc_args ); $this->save_skeleton_output( $assoc_args ); } else { @@ -133,7 +139,13 @@ function taxonomy( $args, $assoc_args ) { if ( $theme || !empty( $plugin_name ) ) { // Write file to theme or given plugin_name - $assoc_args = array('type' => 'taxonomy', 'output' => $output, 'theme' => $theme, 'plugin_name' => $plugin_name, 'machine_name' => $machine_name ); + $assoc_args = array( + 'type' => 'taxonomy', + 'output' => $output, + 'theme' => $theme, + 'plugin_name' => $plugin_name, + 'machine_name' => $machine_name, + ); $assoc_args['path'] = $this->get_output_path( $assoc_args ); $this->save_skeleton_output( $assoc_args ); } else { @@ -151,7 +163,7 @@ private function get_output_path( $assoc_args ) { if( $theme ) { //Here we assume you got a theme installed $path = TEMPLATEPATH; - } elseif ( !empty( $plugin_name ) ){ + } elseif ( ! empty( $plugin_name ) ){ $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line } else { @@ -166,7 +178,7 @@ private function get_output_path( $assoc_args ) { } // If it doesn't exists create it - if( !$wp_filesystem->is_dir( $path ) ) { + if( ! $wp_filesystem->is_dir( $path ) ) { $wp_filesystem->mkdir( $path ); WP_CLI::success( "Created dir: {$path}" ); } elseif( $wp_filesystem->is_dir( $path ) ) { From 9454028630f93c9614441509a439b4558be3708c Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sat, 29 Dec 2012 01:25:46 +0100 Subject: [PATCH 1002/4858] Implemented --raw flag so that one only gets the registration of a taxonomy or post type WITH labels. Without these you will also get a init and update messages. But I think update messages also need to be a part of the --raw flag --- php/commands/scaffold.php | 32 +++++++++++++------ php/commands/skeletons/post_type_skeleton.php | 30 +---------------- .../skeletons/post_type_skeleton_extended.php | 32 +++++++++++++++++++ php/commands/skeletons/taxonomy_skeleton.php | 11 ++----- .../skeletons/taxonomy_skeleton_extended.php | 8 +++++ 5 files changed, 67 insertions(+), 46 deletions(-) mode change 100755 => 100644 php/commands/skeletons/post_type_skeleton.php create mode 100755 php/commands/skeletons/post_type_skeleton_extended.php mode change 100755 => 100644 php/commands/skeletons/taxonomy_skeleton.php create mode 100755 php/commands/skeletons/taxonomy_skeleton_extended.php diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c1b832d093..ee11f0c8f8 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -20,7 +20,7 @@ function __construct() { * * @alias pt * - * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] + * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -33,7 +33,7 @@ function post_type( $args, $assoc_args ) { $machine_name_plural = $this->pluralize( $post_type ); // If no label is given use the slug and prettify it as good as possible - if( !isset( $assoc_args['label'] ) ) { + if( ! isset( $assoc_args['label'] ) ) { $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); $label_ucfirst = ucfirst( $label ); $label_plural = $this->pluralize( $label ); @@ -62,7 +62,8 @@ function post_type( $args, $assoc_args ) { 'can_export' => 'true', 'textdomain' => '', 'theme' => false, - 'plugin_name' => false + 'plugin_name' => false, + 'raw' => false, ); // Generate the variables from the defaults and associated arguments if they are set @@ -70,7 +71,13 @@ function post_type( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - include 'skeletons/post_type_skeleton.php'; + if( ! $raw ) { + include 'skeletons/post_type_skeleton.php'; + $output = str_replace( "<?php", "", $output); + include 'skeletons/post_type_skeleton_extended.php'; + } else { + include 'skeletons/post_type_skeleton.php'; + } if ( $theme || ! empty( $plugin_name ) ) { // Write file to theme or given plugin_name @@ -94,7 +101,7 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] + * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] [--raw] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; @@ -107,7 +114,7 @@ function taxonomy( $args, $assoc_args ) { $machine_name_plural = $this->pluralize( $taxonomy ); // If no label is given use the slug and prettify it as good as possible - if( !isset( $assoc_args['label'] ) ) { + if( ! isset( $assoc_args['label'] ) ) { $label = preg_replace( '/_|-/', ' ', strtolower( $taxonomy ) ); $label_ucfirst = ucfirst( $label ); $label_plural = $this->pluralize( $label ); @@ -127,7 +134,8 @@ function taxonomy( $args, $assoc_args ) { 'post_types' => 'post', 'textdomain' => '', 'theme' => false, - 'plugin_name' => false + 'plugin_name' => false, + 'raw' => false, ); // Generate the variables from the defaults and associated arguments if they are set @@ -135,9 +143,15 @@ function taxonomy( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - include 'skeletons/taxonomy_skeleton.php'; + if( ! $raw ) { + include 'skeletons/taxonomy_skeleton.php'; + $output = str_replace( "<?php", "", $output); + include 'skeletons/taxonomy_skeleton_extended.php'; + } else { + include 'skeletons/taxonomy_skeleton.php'; + } - if ( $theme || !empty( $plugin_name ) ) { + if ( $theme || ! empty( $plugin_name ) ) { // Write file to theme or given plugin_name $assoc_args = array( 'type' => 'taxonomy', diff --git a/php/commands/skeletons/post_type_skeleton.php b/php/commands/skeletons/post_type_skeleton.php old mode 100755 new mode 100644 index e92355d2bc..21253f9391 --- a/php/commands/skeletons/post_type_skeleton.php +++ b/php/commands/skeletons/post_type_skeleton.php @@ -1,7 +1,5 @@ <?php $output = "<?php - -function {$machine_name}_init() { register_post_type( '{$post_type}', array( 'label' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), @@ -37,30 +35,4 @@ function {$machine_name}_init() { 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), ), ) - ); -} -add_action( 'init', '{$machine_name}_init' ); - -function {$machine_name}_updated_messages( \$messages ) { - global \$post, \$post_ID; - - \$messages['{$post_type}'] = array( - 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label_ucfirst} updated. <a target=\"_blank\" href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), - 2 => __('Custom field updated.', '{$textdomain}'), - 3 => __('Custom field deleted.', '{$textdomain}'), - 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), - /* translators: %s: date and time of the revision */ - 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label_ucfirst} published. <a href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), - 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), - 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), - 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"%2\$s\">Preview {$label}</a>', '{$textdomain}'), - // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), - ); - - return \$messages; -} -add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; \ No newline at end of file + );"; \ No newline at end of file diff --git a/php/commands/skeletons/post_type_skeleton_extended.php b/php/commands/skeletons/post_type_skeleton_extended.php new file mode 100755 index 0000000000..3d541d8d91 --- /dev/null +++ b/php/commands/skeletons/post_type_skeleton_extended.php @@ -0,0 +1,32 @@ +<?php +$output = "<?php + +function {$machine_name}_init() { + {$output} +} +add_action( 'init', '{$machine_name}_init' ); + +function {$machine_name}_updated_messages( \$messages ) { + global \$post, \$post_ID; + + \$messages['{$post_type}'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => sprintf( __('{$label_ucfirst} updated. <a target=\"_blank\" href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 2 => __('Custom field updated.', '{$textdomain}'), + 3 => __('Custom field deleted.', '{$textdomain}'), + 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), + /* translators: %s: date and time of the revision */ + 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, + 6 => sprintf( __('{$label_ucfirst} published. <a href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), + 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), + 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), + 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"%2\$s\">Preview {$label}</a>', '{$textdomain}'), + // translators: Publish box date format, see http://php.net/date + date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), + 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), + ); + + return \$messages; +} +add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; +?> \ No newline at end of file diff --git a/php/commands/skeletons/taxonomy_skeleton.php b/php/commands/skeletons/taxonomy_skeleton.php old mode 100755 new mode 100644 index 1d299b7d18..e098f77f5d --- a/php/commands/skeletons/taxonomy_skeleton.php +++ b/php/commands/skeletons/taxonomy_skeleton.php @@ -1,7 +1,5 @@ <?php $output = "<?php - -function {$machine_name}_init() { \$labels = array( 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), @@ -20,8 +18,8 @@ function {$machine_name}_init() { 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), ); - \$args = array( - 'labels' => \$labels, + \$args = array( + 'labels' => \$labels, 'public' => {$public}, 'show_in_nav_menus' => {$show_in_nav_menus}, 'show_ui' => {$show_ui}, @@ -42,7 +40,4 @@ function {$machine_name}_init() { ), ); - register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args ); - -} -add_action( 'init', '{$machine_name}_init' );"; \ No newline at end of file + register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args );"; \ No newline at end of file diff --git a/php/commands/skeletons/taxonomy_skeleton_extended.php b/php/commands/skeletons/taxonomy_skeleton_extended.php new file mode 100755 index 0000000000..d4015c73ed --- /dev/null +++ b/php/commands/skeletons/taxonomy_skeleton_extended.php @@ -0,0 +1,8 @@ +<?php +$output = "<?php + +function {$machine_name}_init() { + {$output} + +} +add_action( 'init', '{$machine_name}_init' );"; \ No newline at end of file From b0a5a21a9224f6fd30d23a5a31479186bb472c38 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 12:48:54 +0200 Subject: [PATCH 1003/4858] rename Composite interface to CommandContainer Command containers don't need to have an invoke() method, since they don't have any implementation of their own. --- php/WP_CLI/Dispatcher/CompositeCommand.php | 16 ++-------------- php/WP_CLI/Dispatcher/RootCommand.php | 10 +++------- php/class-wp-cli.php | 8 ++++++-- php/dispatcher.php | 9 ++++++--- php/man.php | 4 ++-- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 23ff3cf36d..05f973ec97 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class CompositeCommand implements Command, Composite, Documentable { +class CompositeCommand implements CommandContainer, Documentable { protected $name; @@ -54,20 +54,8 @@ function show_usage() { \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); } - function invoke( $args, $assoc_args ) { - $subcommand = $this->pre_invoke( $args ); - $subcommand->invoke( $args, $assoc_args ); - } - function pre_invoke( &$args ) { - $subcommand = $this->find_subcommand( $args ); - - if ( !$subcommand ) { - $this->show_usage(); - exit; - } - - return $subcommand; + return $this->find_subcommand( $args ); } function find_subcommand( &$args ) { diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index a98683e121..9b19204b1b 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class RootCommand implements Command, Composite { +class RootCommand implements CommandContainer { protected $subcommands = array(); @@ -35,18 +35,14 @@ function show_usage() { ); } - function invoke( $args, $assoc_args ) { - $subcommand = $this->pre_invoke( $args ); - $subcommand->invoke( $args, $assoc_args ); - } - function pre_invoke( &$args ) { - if ( empty( $args ) || array( 'help' ) == $args ) { + if ( array( 'help' ) == $args ) { $this->show_usage(); exit; } $cmd_name = $args[0]; + $command = $this->find_subcommand( $args ); if ( !$command ) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index b23be480e7..653429add3 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -349,7 +349,7 @@ static function after_wp_load() { // Handle --syn-list parameter if ( isset( self::$config['syn-list'] ) ) { foreach ( self::$root->get_subcommands() as $command ) { - if ( $command instanceof Dispatcher\Composite ) { + if ( $command instanceof Dispatcher\CommandContainer ) { foreach ( $command->get_subcommands() as $subcommand ) $subcommand->show_usage( '' ); } else { @@ -369,7 +369,11 @@ static function after_wp_load() { private static function run_command() { $command = Dispatcher\traverse( self::$arguments, 'pre_invoke' ); - $command->invoke( self::$arguments, self::$assoc_args ); + + if ( $command instanceof Dispatcher\CommandContainer ) + $command->show_usage(); + else + $command->invoke( self::$arguments, self::$assoc_args ); } private static function show_info() { diff --git a/php/dispatcher.php b/php/dispatcher.php index 78e12d4428..95bcd0891a 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -7,7 +7,7 @@ function traverse( &$args, $method = 'find_subcommand' ) { $command = \WP_CLI::$root; - while ( !empty( $args ) && $command && $command instanceof Composite ) { + while ( !empty( $args ) && $command && $command instanceof CommandContainer ) { $command = $command->$method( $args ); } @@ -28,10 +28,13 @@ function invoke( $args, $assoc_args ); } -interface Composite { +interface CommandContainer { + + function show_usage(); - function pre_invoke( &$args ); function find_subcommand( &$args ); + + function pre_invoke( &$args ); } diff --git a/php/man.php b/php/man.php index 6a06c169e0..2e40ec4b76 100644 --- a/php/man.php +++ b/php/man.php @@ -18,7 +18,7 @@ function generate( $src_dir, $dest_dir, $command ) { call_ronn( get_markdown( $src_path, $command ), $dest_path ); - if ( $command instanceof Dispatcher\Composite ) { + if ( $command instanceof Dispatcher\CommandContainer ) { foreach ( $command->get_subcommands() as $subcommand ) { generate( $src_dir, $dest_dir, $subcommand ); } @@ -70,7 +70,7 @@ function add_initial_markdown( $fd, $command ) { DOC ); - if ( $command instanceof Dispatcher\Composite ) { + if ( $command instanceof Dispatcher\CommandContainer ) { fwrite( $fd, <<<DOC ## SUBCOMMANDS From f249ee30601133e90f4440dc9df2e83f5352919b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 12:52:25 +0200 Subject: [PATCH 1004/4858] regenerate man pages. see #229 --- man/post-update.1 | 2 +- man/user-delete.1 | 4 ++-- man/user-update.1 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/post-update.1 b/man/post-update.1 index 534a319d48..91b69b6b52 100644 --- a/man/post-update.1 +++ b/man/post-update.1 @@ -4,7 +4,7 @@ .TH "WP\-POST\-UPDATE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-post\-update\fR \- Update a post\. +\fBwp\-post\-update\fR \- Update one or more posts\. . .SH "SYNOPSIS" wp post update \fIid\fR\.\.\. \-\-\fIfield\fR=\fIvalue\fR diff --git a/man/user-delete.1 b/man/user-delete.1 index 0666e01475..d498eb4153 100644 --- a/man/user-delete.1 +++ b/man/user-delete.1 @@ -4,10 +4,10 @@ .TH "WP\-USER\-DELETE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-user\-delete\fR \- Delete a user\. +\fBwp\-user\-delete\fR \- Delete one or more users\. . .SH "SYNOPSIS" -wp user delete \fIid\fR [\-\-reassign=\fIid\fR] +wp user delete \fIid\fR\.\.\. [\-\-reassign=\fIid\fR] . .SH "OPTIONS" . diff --git a/man/user-update.1 b/man/user-update.1 index 4750f707ef..965501ff58 100644 --- a/man/user-update.1 +++ b/man/user-update.1 @@ -7,7 +7,7 @@ \fBwp\-user\-update\fR \- Update a user\. . .SH "SYNOPSIS" -wp user update \fIid\fR \-\-\fIfield\fR=\fIvalue\fR +wp user update \fIid\fR\.\.\. \-\-\fIfield\fR=\fIvalue\fR . .SH "OPTIONS" . From d19f323ec005d85864c7c409e1f7bdf67c7398d3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 12:59:09 +0200 Subject: [PATCH 1005/4858] only command containers can have subcommands --- php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/WP_CLI/Dispatcher/Subcommand.php | 4 ---- php/class-wp-cli.php | 2 +- php/dispatcher.php | 13 ++++++++++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 9b19204b1b..4df759aed3 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -16,7 +16,7 @@ function show_usage() { foreach ( $this->get_subcommands() as $command ) { \WP_CLI::line( sprintf( " wp %s %s", implode( ' ', $command->get_path() ), - implode( '|', array_keys( $command->get_subcommands() ) ) + implode( '|', array_keys( get_subcommands( $command ) ) ) ) ); } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 9f4259f99a..88be1f5958 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -32,10 +32,6 @@ function invoke( $args, $assoc_args ) { call_user_func( $this->callable, $args, $assoc_args ); } - function get_subcommands() { - return array(); - } - function get_name() { return $this->name; } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 653429add3..c91297eeb8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -398,7 +398,7 @@ private static function generate_man( $args ) { private static function render_automcomplete() { foreach ( self::$root->get_subcommands() as $name => $command ) { - $subcommands = $command->get_subcommands(); + $subcommands = Dispatcher\get_subcommands( $command ); self::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); } diff --git a/php/dispatcher.php b/php/dispatcher.php index 95bcd0891a..8c94d65053 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -17,23 +17,30 @@ function traverse( &$args, $method = 'find_subcommand' ) { return $command; } +function get_subcommands( $command ) { + if ( $command instanceof CommandContainer ) + return $command->get_subcommands(); + + return array(); +} + interface Command { function get_path(); - function get_subcommands(); - function show_usage(); + function invoke( $args, $assoc_args ); } interface CommandContainer { + function get_subcommands(); + function show_usage(); function find_subcommand( &$args ); - function pre_invoke( &$args ); } From 3de7e636a40118ed47e428821f1012a9439b92ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 13:51:44 +0200 Subject: [PATCH 1006/4858] transform get_path() method into a standalone function also introduce AtomicCommand interface --- php/WP_CLI/Dispatcher/CompositeCommand.php | 10 +++++++--- php/WP_CLI/Dispatcher/RootCommand.php | 14 +++++++++----- php/WP_CLI/Dispatcher/Subcommand.php | 10 +++++----- php/dispatcher.php | 20 +++++++++++++++++--- php/man.php | 12 ++++++++---- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 05f973ec97..2f3ccafb9e 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class CompositeCommand implements CommandContainer, Documentable { +class CompositeCommand implements Command, CommandContainer, Documentable { protected $name; @@ -35,8 +35,12 @@ private function collect_subcommands( $reflection, $class ) { return $subcommands; } - function get_path() { - return array( $this->name ); + function get_name() { + return $this->name; + } + + function get_parent() { + return \WP_CLI::$root; } function show_usage() { diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 4df759aed3..40a6ad8d6e 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -2,20 +2,24 @@ namespace WP_CLI\Dispatcher; -class RootCommand implements CommandContainer { +class RootCommand implements Command, CommandContainer { protected $subcommands = array(); - function get_path() { - return array(); + function get_name() { + return 'wp'; + } + + function get_parent() { + return false; } function show_usage() { \WP_CLI::line( 'Available commands:' ); foreach ( $this->get_subcommands() as $command ) { - \WP_CLI::line( sprintf( " wp %s %s", - implode( ' ', $command->get_path() ), + \WP_CLI::line( sprintf( " %s %s", + implode( ' ', get_path( $command ) ), implode( '|', array_keys( get_subcommands( $command ) ) ) ) ); } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 88be1f5958..21238a1ff6 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class Subcommand implements Command, Documentable { +class Subcommand implements Command, AtomicCommand, Documentable { function __construct( $name, $callable, $docparser, $parent ) { $this->name = $name; @@ -20,10 +20,10 @@ function get_shortdesc() { } function get_full_synopsis() { - $full_name = implode( ' ', $this->get_path() ); + $full_name = implode( ' ', get_path( $this ) ); $synopsis = $this->docparser->get_synopsis(); - return "wp $full_name $synopsis"; + return "$full_name $synopsis"; } function invoke( $args, $assoc_args ) { @@ -36,8 +36,8 @@ function get_name() { return $this->name; } - function get_path() { - return array_merge( $this->parent->get_path(), array( $this->get_name() ) ); + function get_parent() { + return $this->parent; } protected function check_args( $args, $assoc_args ) { diff --git a/php/dispatcher.php b/php/dispatcher.php index 8c94d65053..48aa9b22a5 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -24,11 +24,27 @@ function get_subcommands( $command ) { return array(); } +function get_path( Command $command ) { + $path = array(); + + do { + array_unshift( $path, $command->get_name() ); + } while ( $command = $command->get_parent() ); + + return $path; +} + interface Command { - function get_path(); + function get_name(); + function get_parent(); + function show_usage(); +} + + +interface AtomicCommand { function invoke( $args, $assoc_args ); } @@ -38,8 +54,6 @@ interface CommandContainer { function get_subcommands(); - function show_usage(); - function find_subcommand( &$args ); function pre_invoke( &$args ); } diff --git a/php/man.php b/php/man.php index 2e40ec4b76..64f9fd69be 100644 --- a/php/man.php +++ b/php/man.php @@ -13,8 +13,11 @@ function get_src_file_name( $args ) { } function generate( $src_dir, $dest_dir, $command ) { - $src_path = $src_dir . get_src_file_name( $command->get_path() ); - $dest_path = $dest_dir . get_file_name( $command->get_path() ); + $cmd_path = Dispatcher\get_path( $command ); + array_shift( $cmd_path ); // discard 'wp' + + $src_path = $src_dir . get_src_file_name( $cmd_path ); + $dest_path = $dest_dir . get_file_name( $cmd_path ); call_ronn( get_markdown( $src_path, $command ), $dest_path ); @@ -46,7 +49,8 @@ function get_markdown( $doc_path, $command ) { } function add_initial_markdown( $fd, $command ) { - $path = $command->get_path(); + $path = Dispatcher\get_path( $command ); + $shortdesc = $command->get_shortdesc(); $synopsis = $command->get_full_synopsis(); @@ -60,7 +64,7 @@ function add_initial_markdown( $fd, $command ) { } fwrite( $fd, <<<DOC -wp-$name_m(1) -- $shortdesc +$name_m(1) -- $shortdesc ==== ## SYNOPSIS From ec34284e2c848e483b7fc87a52527ea37a71b452 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 14:32:08 +0200 Subject: [PATCH 1007/4858] make load_command() protected --- php/WP_CLI/Dispatcher/RootCommand.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 40a6ad8d6e..47b5b24179 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -69,9 +69,9 @@ function find_subcommand( &$args ) { } function add_command( $name, $implementation ) { - if ( is_string( $implementation ) ) + if ( is_string( $implementation ) ) { $command = new CompositeCommand( $name, $implementation ); - else { + } else { $method = new \ReflectionMethod( $implementation, '__invoke' ); $docparser = new \WP_CLI\DocParser( $method ); @@ -92,7 +92,7 @@ function get_subcommands() { protected function load_all_commands() { foreach ( glob( WP_CLI_ROOT . "/commands/*.php" ) as $filename ) { - $command = substr( basename( $filename ), 0, -4 ); + $command = str_replace( '.php', '', $filename ); if ( isset( $this->subcommands[ $command ] ) ) continue; @@ -101,7 +101,7 @@ protected function load_all_commands() { } } - function load_command( $command ) { + protected function load_command( $command ) { if ( !isset( $this->subcommands[$command] ) ) { $path = WP_CLI_ROOT . "/commands/$command.php"; From 9c6231c331c5951066207b9c6b17660006ba0da4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 14:39:27 +0200 Subject: [PATCH 1008/4858] add_command(): move logic back to WP_CLI class --- php/WP_CLI/Dispatcher/RootCommand.php | 12 +----------- php/class-wp-cli.php | 12 +++++++++++- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 47b5b24179..e1319b2303 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -68,17 +68,7 @@ function find_subcommand( &$args ) { return $this->load_command( $command ); } - function add_command( $name, $implementation ) { - if ( is_string( $implementation ) ) { - $command = new CompositeCommand( $name, $implementation ); - } else { - $method = new \ReflectionMethod( $implementation, '__invoke' ); - - $docparser = new \WP_CLI\DocParser( $method ); - - $command = new Subcommand( $name, $implementation, $docparser, $this ); - } - + function add_command( $name, Command $command ) { $this->subcommands[ $name ] = $command; } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index c91297eeb8..74072460de 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -25,7 +25,17 @@ class WP_CLI { * @param string|object $implementation The command implementation */ static function add_command( $name, $implementation ) { - self::$root->add_command( $name, $implementation ); + if ( is_string( $implementation ) ) { + $command = new Dispatcher\CompositeCommand( $name, $implementation ); + } else { + $method = new \ReflectionMethod( $implementation, '__invoke' ); + + $docparser = new \WP_CLI\DocParser( $method ); + + $command = new Dispatcher\Subcommand( $name, $implementation, $docparser, self::$root ); + } + + self::$root->add_command( $name, $command ); } static function add_man_dir( $dest_dir, $src_dir ) { From 0371ceebbed83a41e059d028149140a4c8a189ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 14:45:50 +0200 Subject: [PATCH 1009/4858] introduce AbstractCommandContainer class --- .../Dispatcher/AbstractCommandContainer.php | 19 +++++++++++++++++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 8 +------- php/WP_CLI/Dispatcher/RootCommand.php | 12 ++---------- php/class-wp-cli.php | 2 +- php/dispatcher.php | 1 + 5 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 php/WP_CLI/Dispatcher/AbstractCommandContainer.php diff --git a/php/WP_CLI/Dispatcher/AbstractCommandContainer.php b/php/WP_CLI/Dispatcher/AbstractCommandContainer.php new file mode 100644 index 0000000000..29136f9206 --- /dev/null +++ b/php/WP_CLI/Dispatcher/AbstractCommandContainer.php @@ -0,0 +1,19 @@ +<?php + +namespace WP_CLI\Dispatcher; + +abstract class AbstractCommandContainer implements Command, CommandContainer { + + protected $subcommands = array(); + + function add_subcommand( $name, Command $command ) { + $this->subcommands[ $name ] = $command; + } + + function get_subcommands() { + ksort( $this->subcommands ); + + return $this->subcommands; + } +} + diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 2f3ccafb9e..40ed2ea720 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -2,12 +2,10 @@ namespace WP_CLI\Dispatcher; -class CompositeCommand implements Command, CommandContainer, Documentable { +class CompositeCommand extends AbstractCommandContainer implements Documentable { protected $name; - protected $subcommands; - protected $shortdesc; public function __construct( $name, $class ) { @@ -93,10 +91,6 @@ private static function get_aliases( $subcommands ) { return $aliases; } - public function get_subcommands() { - return $this->subcommands; - } - public function get_shortdesc() { return $this->docparser->get_shortdesc(); } diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index e1319b2303..080ad4cbca 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -2,9 +2,7 @@ namespace WP_CLI\Dispatcher; -class RootCommand implements Command, CommandContainer { - - protected $subcommands = array(); +class RootCommand extends AbstractCommandContainer { function get_name() { return 'wp'; @@ -68,16 +66,10 @@ function find_subcommand( &$args ) { return $this->load_command( $command ); } - function add_command( $name, Command $command ) { - $this->subcommands[ $name ] = $command; - } - function get_subcommands() { $this->load_all_commands(); - ksort( $this->subcommands ); - - return $this->subcommands; + return parent::get_subcommands(); } protected function load_all_commands() { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 74072460de..217addfe06 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -35,7 +35,7 @@ static function add_command( $name, $implementation ) { $command = new Dispatcher\Subcommand( $name, $implementation, $docparser, self::$root ); } - self::$root->add_command( $name, $command ); + self::$root->add_subcommand( $name, $command ); } static function add_man_dir( $dest_dir, $src_dir ) { diff --git a/php/dispatcher.php b/php/dispatcher.php index 48aa9b22a5..f599144898 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -52,6 +52,7 @@ function invoke( $args, $assoc_args ); interface CommandContainer { + function add_subcommand( $name, Command $command ); function get_subcommands(); function find_subcommand( &$args ); From 37a3b95f0b345cadec1df40de063cbc104c7d069 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 15:23:34 +0200 Subject: [PATCH 1010/4858] introduce 'disabled_commands' config key --- php/class-wp-cli.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 217addfe06..d708dc6cfb 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -263,7 +263,7 @@ static function before_wp_load() { ); self::$config = Utils\load_config( array( - 'path', 'url', 'user' + 'path', 'url', 'user', 'disabled_commands' ) ); self::parse_args(); @@ -380,10 +380,25 @@ static function after_wp_load() { private static function run_command() { $command = Dispatcher\traverse( self::$arguments, 'pre_invoke' ); - if ( $command instanceof Dispatcher\CommandContainer ) + self::check_disabled_commands( $command ); + + if ( $command instanceof Dispatcher\CommandContainer ) { $command->show_usage(); - else + } else { $command->invoke( self::$arguments, self::$assoc_args ); + } + } + + private static function check_disabled_commands( Dispatcher\Command $command ) { + if ( !isset( self::$config['disabled_commands'] ) ) + return; + + $path = Dispatcher\get_path( $command ); + array_shift( $path ); + $cmd_str = implode( ' ', $path ); + + if ( in_array( $cmd_str, self::$config['disabled_commands'] ) ) + WP_CLI::error( "The '$cmd_str' command is disabled." ); } private static function show_info() { From 01c53757549105c19fb63cc06c134c3ff5d10947 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 16:22:00 +0200 Subject: [PATCH 1011/4858] create new command instance on each invocation. fixes #257 --- php/WP_CLI/Dispatcher/CompositeCommand.php | 2 +- php/WP_CLI/Dispatcher/MethodSubcommand.php | 8 ++++---- php/WP_CLI/Dispatcher/Subcommand.php | 6 ++++-- php/class-wp-cli.php | 20 ++++++++++++++------ php/dispatcher.php | 15 +++++++++++++++ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 40ed2ea720..52b6dfa8b2 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -25,7 +25,7 @@ private function collect_subcommands( $reflection, $class ) { if ( !self::_is_good_method( $method ) ) continue; - $subcommand = new MethodSubcommand( $class, $method, $this ); + $subcommand = new MethodSubcommand( $this, $class, $method ); $subcommands[ $subcommand->get_name() ] = $subcommand; } diff --git a/php/WP_CLI/Dispatcher/MethodSubcommand.php b/php/WP_CLI/Dispatcher/MethodSubcommand.php index 5ef500c567..f66329bc2a 100644 --- a/php/WP_CLI/Dispatcher/MethodSubcommand.php +++ b/php/WP_CLI/Dispatcher/MethodSubcommand.php @@ -4,16 +4,16 @@ class MethodSubcommand extends Subcommand { - function __construct( $class, $method, $parent ) { - $callable = array( new $class, $method->name ); - + function __construct( CommandContainer $parent, $class, \ReflectionMethod $method ) { $docparser = new \WP_CLI\DocParser( $method ); $name = $docparser->get_tag( 'subcommand' ); if ( !$name ) $name = $method->name; - parent::__construct( $name, $callable, $docparser, $parent ); + $callable = new CallableMethod( $class, $method->name ); + + parent::__construct( $parent, $name, $callable, $docparser ); } function get_alias() { diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 21238a1ff6..0432e7a830 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -4,11 +4,13 @@ class Subcommand implements Command, AtomicCommand, Documentable { - function __construct( $name, $callable, $docparser, $parent ) { + function __construct( CommandContainer $parent, $name, $callable, $docparser ) { + $this->parent = $parent; $this->name = $name; + $this->callable = $callable; + $this->docparser = $docparser; - $this->parent = $parent; } function show_usage( $prefix = 'usage: ' ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d708dc6cfb..cfcf815c8f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -26,18 +26,26 @@ class WP_CLI { */ static function add_command( $name, $implementation ) { if ( is_string( $implementation ) ) { - $command = new Dispatcher\CompositeCommand( $name, $implementation ); + $command = self::create_composite_command( $name, $implementation ); } else { - $method = new \ReflectionMethod( $implementation, '__invoke' ); - - $docparser = new \WP_CLI\DocParser( $method ); - - $command = new Dispatcher\Subcommand( $name, $implementation, $docparser, self::$root ); + $command = self::create_atomic_command( $name, $implementation ); } self::$root->add_subcommand( $name, $command ); } + private static function create_composite_command( $name, $class ) { + return new Dispatcher\CompositeCommand( $name, $class ); + } + + private static function create_atomic_command( $name, $implementation ) { + $method = new \ReflectionMethod( $implementation, '__invoke' ); + + $docparser = new \WP_CLI\DocParser( $method ); + + return new Dispatcher\Subcommand( self::$root, $name, $implementation, $docparser ); + } + static function add_man_dir( $dest_dir, $src_dir ) { $dest_dir = realpath( $dest_dir ) . '/'; diff --git a/php/dispatcher.php b/php/dispatcher.php index f599144898..148704fb42 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -66,3 +66,18 @@ function get_shortdesc(); function get_full_synopsis(); } + +class CallableMethod { + + function __construct( $class, $method ) { + $this->class = $class; + $this->method = $method; + } + + function __invoke( $args, $assoc_args ) { + $instance = new $this->class; + + call_user_func( array( $instance, $this->method ), $args, $assoc_args ); + } +} + From 25eb311bf1df96de37301661aec2dea36f1edb7a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 16:54:09 +0200 Subject: [PATCH 1012/4858] move logic from CompositeCommand constructor to WP_CLI class --- php/WP_CLI/Dispatcher/CompositeCommand.php | 31 +++------------------- php/class-wp-cli.php | 21 ++++++++++++++- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 52b6dfa8b2..e0ff1f6708 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -5,32 +5,11 @@ class CompositeCommand extends AbstractCommandContainer implements Documentable { protected $name; - protected $shortdesc; - public function __construct( $name, $class ) { + public function __construct( $name, $shortdesc ) { $this->name = $name; - - $reflection = new \ReflectionClass( $class ); - - $this->subcommands = $this->collect_subcommands( $reflection, $class ); - - $this->docparser = new \WP_CLI\DocParser( $reflection ); - } - - private function collect_subcommands( $reflection, $class ) { - $subcommands = array(); - - foreach ( $reflection->getMethods() as $method ) { - if ( !self::_is_good_method( $method ) ) - continue; - - $subcommand = new MethodSubcommand( $this, $class, $method ); - - $subcommands[ $subcommand->get_name() ] = $subcommand; - } - - return $subcommands; + $this->shortdesc = $shortdesc; } function get_name() { @@ -92,7 +71,7 @@ private static function get_aliases( $subcommands ) { } public function get_shortdesc() { - return $this->docparser->get_shortdesc(); + return $this->shortdesc; } public function get_full_synopsis() { @@ -104,9 +83,5 @@ public function get_full_synopsis() { return implode( "\n\n", $str ); } - - private static function _is_good_method( $method ) { - return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); - } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index cfcf815c8f..2830322383 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -35,7 +35,26 @@ static function add_command( $name, $implementation ) { } private static function create_composite_command( $name, $class ) { - return new Dispatcher\CompositeCommand( $name, $class ); + $reflection = new \ReflectionClass( $class ); + + $docparser = new \WP_CLI\DocParser( $reflection ); + + $container = new Dispatcher\CompositeCommand( $name, $docparser->get_shortdesc() ); + + foreach ( $reflection->getMethods() as $method ) { + if ( !self::_is_good_method( $method ) ) + continue; + + $subcommand = new Dispatcher\MethodSubcommand( $container, $class, $method ); + + $container->add_subcommand( $subcommand->get_name(), $subcommand ); + } + + return $container; + } + + private static function _is_good_method( $method ) { + return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); } private static function create_atomic_command( $name, $implementation ) { From 275867dbb876b30a8c274687dafd2f213440bb69 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 17:07:23 +0200 Subject: [PATCH 1013/4858] check disabled commands during registration, instead of during invocation --- php/class-wp-cli.php | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 2830322383..2ea75d2e22 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -25,6 +25,9 @@ class WP_CLI { * @param string|object $implementation The command implementation */ static function add_command( $name, $implementation ) { + if ( in_array( $name, self::$config['disabled_commands'] ) ) + return; + if ( is_string( $implementation ) ) { $command = self::create_composite_command( $name, $implementation ); } else { @@ -47,12 +50,25 @@ private static function create_composite_command( $name, $class ) { $subcommand = new Dispatcher\MethodSubcommand( $container, $class, $method ); - $container->add_subcommand( $subcommand->get_name(), $subcommand ); + $subcommand_name = $subcommand->get_name(); + $full_name = self::get_full_name( $subcommand ); + + if ( in_array( $full_name, self::$config['disabled_commands'] ) ) + continue; + + $container->add_subcommand( $subcommand_name, $subcommand ); } return $container; } + private static function get_full_name( Dispatcher\Command $command ) { + $path = Dispatcher\get_path( $command ); + array_shift( $path ); + + return implode( ' ', $path ); + } + private static function _is_good_method( $method ) { return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); } @@ -293,6 +309,9 @@ static function before_wp_load() { 'path', 'url', 'user', 'disabled_commands' ) ); + if ( !isset( self::$config['disabled_commands'] ) ) + self::$config['disabled_commands'] = array(); + self::parse_args(); define( 'WP_CLI_QUIET', isset( self::$config['quiet'] ) ); @@ -407,8 +426,6 @@ static function after_wp_load() { private static function run_command() { $command = Dispatcher\traverse( self::$arguments, 'pre_invoke' ); - self::check_disabled_commands( $command ); - if ( $command instanceof Dispatcher\CommandContainer ) { $command->show_usage(); } else { @@ -416,18 +433,6 @@ private static function run_command() { } } - private static function check_disabled_commands( Dispatcher\Command $command ) { - if ( !isset( self::$config['disabled_commands'] ) ) - return; - - $path = Dispatcher\get_path( $command ); - array_shift( $path ); - $cmd_str = implode( ' ', $path ); - - if ( in_array( $cmd_str, self::$config['disabled_commands'] ) ) - WP_CLI::error( "The '$cmd_str' command is disabled." ); - } - private static function show_info() { $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); From 882c629fbdb294fdb226a5678c1b7fb92227df7a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 17:32:32 +0200 Subject: [PATCH 1014/4858] fix test_message_explains_that_config_must_be_present_before_install(). see #170 --- tests/core-Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core-Test.php b/tests/core-Test.php index 20ba5bc89b..af2f071121 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -56,7 +56,7 @@ public function test_message_explains_that_config_must_be_present_before_install $installer->download_wordpress_files( $temp_dir ); $result = $runner->run_wp_cli( "core install" ); $this->assertEquals( - "^[[31;1mError: ^[[0mwp-config.php not found.\n" . + "Error: wp-config.php not found.\n" . "Either create one manually or use `wp core config`.\n", $result->output ); From 8d1214be042131e0f319c454c6058042244731c8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 17:38:09 +0200 Subject: [PATCH 1015/4858] add phpunit.xml file --- README.md | 6 ++-- tests/bootstrap.php | 5 +++ tests/core-Test.php | 3 -- tests/phpunit.xml | 13 ++++++++ tests/test_core.php | 78 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 tests/bootstrap.php create mode 100644 tests/phpunit.xml create mode 100644 tests/test_core.php diff --git a/README.md b/README.md index c6d3179f16..10c52eeee0 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,12 @@ Running the following as root in MySQL should do the trick: GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; - + Finally, to run the tests: - vendor/bin/phpunit tests + vendor/bin/phpunit -c tests/phpunit.xml Most tests install WordPress from scratch. Since this is pretty slow, you can use arguments to `phpunit` to only run the test that you're interested in: - vendor/bin/phpunit --filter test_function_you_want_to_run tests + vendor/bin/phpunit -c tests/phpunit.xml --filter test_function_you_want_to_run tests diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000000..ac6ee71957 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,5 @@ +<?php + +require __DIR__ . '/class-command-runner.php'; +require __DIR__ . '/class-wp-cli-test-case.php'; + diff --git a/tests/core-Test.php b/tests/core-Test.php index af2f071121..ded886a6ee 100644 --- a/tests/core-Test.php +++ b/tests/core-Test.php @@ -1,8 +1,5 @@ <?php -require_once __DIR__ . '/class-command-runner.php'; -require_once __DIR__ . '/class-wp-cli-test-case.php'; - class CoreTest extends Wp_Cli_Test_Case { public function test_is_installed_exits_with_1_if_empty_dir() { diff --git a/tests/phpunit.xml b/tests/phpunit.xml new file mode 100644 index 0000000000..4ea00f4df3 --- /dev/null +++ b/tests/phpunit.xml @@ -0,0 +1,13 @@ +<phpunit + bootstrap="bootstrap.php" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + > + <testsuites> + <testsuite> + <directory prefix="test_" suffix=".php">./</directory> + </testsuite> + </testsuites> +</phpunit> diff --git a/tests/test_core.php b/tests/test_core.php new file mode 100644 index 0000000000..af2f071121 --- /dev/null +++ b/tests/test_core.php @@ -0,0 +1,78 @@ +<?php + +require_once __DIR__ . '/class-command-runner.php'; +require_once __DIR__ . '/class-wp-cli-test-case.php'; + +class CoreTest extends Wp_Cli_Test_Case { + + public function test_is_installed_exits_with_1_if_empty_dir() { + $temp_dir = $this->create_temporary_directory(); + $runner = new Command_Runner( $temp_dir ); + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 1, $result->return_code ); + } + + public function test_is_installed_exits_with_1_if_missing_wp_config() { + $temp_dir = $this->create_temporary_directory(); + + $runner = new Command_Runner( $temp_dir ); + + $installer = new Wordpress_Installer( $temp_dir, $runner ); + $installer->download_wordpress_files( $temp_dir ); + + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 1, $result->return_code ); + } + + public function test_is_installed_exits_with_1_if_db_not_installed() { + $temp_dir = $this->create_temporary_directory(); + + $runner = new Command_Runner( $temp_dir ); + + $installer = new Wordpress_Installer( $temp_dir, $runner ); + $installer->download_wordpress_files( $temp_dir ); + $installer->create_config( $this->db_settings ); + + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 1, $result->return_code ); + } + + public function test_is_installed_exits_with_0_after_running_install_command() { + $runner = $this->full_wp_install(); + $result = $runner->run_wp_cli( "core is-installed" ); + $this->assertEquals( 0, $result->return_code ); + } + + public function test_install_command_creates_default_blog_post() { + $runner = $this->full_wp_install(); + $result = $runner->run_wp_cli( "post list --ids" ); + $this->assertEquals( "1", $result->output ); + } + + public function test_message_explains_that_config_must_be_present_before_install() { + $temp_dir = $this->create_temporary_directory(); + $runner = new Command_Runner( $temp_dir ); + $installer = new Wordpress_Installer( $temp_dir, $runner ); + $installer->download_wordpress_files( $temp_dir ); + $result = $runner->run_wp_cli( "core install" ); + $this->assertEquals( + "Error: wp-config.php not found.\n" . + "Either create one manually or use `wp core config`.\n", + $result->output + ); + } + + public function test_wp_config_can_be_placed_in_parent_directory() { + $temp_dir = $this->create_temporary_directory(); + $install_dir = $temp_dir . '/www-root'; + mkdir( $install_dir ); + $runner = new Command_Runner( $install_dir ); + $installer = new Wordpress_Installer( $install_dir, $runner ); + $installer->download_wordpress_files( $install_dir ); + $installer->create_config( $this->db_settings ); + rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); + $installer->run_install(); + $result = $runner->run_wp_cli( "post list --ids" ); + $this->assertEquals( "1", $result->output ); + } +} From 0857778911cff25a82c8e1ea323bacca4a8598d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 17:41:13 +0200 Subject: [PATCH 1016/4858] move phpunit.xml to the root dir --- .gitignore | 1 + README.md | 4 ++-- tests/phpunit.xml => phpunit.xml.dist | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) rename tests/phpunit.xml => phpunit.xml.dist (67%) diff --git a/.gitignore b/.gitignore index 8b2103e777..8e2a674313 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /dist /vendor /composer.lock +/phpunit.xml diff --git a/README.md b/README.md index 10c52eeee0..2f9ec0ff27 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ Running the following as root in MySQL should do the trick: Finally, to run the tests: - vendor/bin/phpunit -c tests/phpunit.xml + vendor/bin/phpunit Most tests install WordPress from scratch. Since this is pretty slow, you can use arguments to `phpunit` to only run the test that you're interested in: - vendor/bin/phpunit -c tests/phpunit.xml --filter test_function_you_want_to_run tests + vendor/bin/phpunit --filter test_function_you_want_to_run diff --git a/tests/phpunit.xml b/phpunit.xml.dist similarity index 67% rename from tests/phpunit.xml rename to phpunit.xml.dist index 4ea00f4df3..77cb7d28d3 100644 --- a/tests/phpunit.xml +++ b/phpunit.xml.dist @@ -1,5 +1,5 @@ <phpunit - bootstrap="bootstrap.php" + bootstrap="tests/bootstrap.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" @@ -7,7 +7,7 @@ > <testsuites> <testsuite> - <directory prefix="test_" suffix=".php">./</directory> + <directory prefix="test_" suffix=".php">tests/</directory> </testsuite> </testsuites> </phpunit> From ca0dcbed5c983e65a8c5e93054a1734a5031b18f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 17:59:41 +0200 Subject: [PATCH 1017/4858] dismantle Dispatcher\traverse() --- php/class-wp-cli.php | 26 ++++++++++++++++++++++---- php/commands/help.php | 12 ++++++++++-- php/dispatcher.php | 15 --------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 2ea75d2e22..426c8afff5 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -424,12 +424,22 @@ static function after_wp_load() { } private static function run_command() { - $command = Dispatcher\traverse( self::$arguments, 'pre_invoke' ); + $command = \WP_CLI::$root; + + $args = self::$arguments; + + while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { + $subcommand = $command->pre_invoke( $args ); + if ( !$subcommand ) + break; + + $command = $subcommand; + } if ( $command instanceof Dispatcher\CommandContainer ) { $command->show_usage(); } else { - $command->invoke( self::$arguments, self::$assoc_args ); + $command->invoke( $args, self::$assoc_args ); } } @@ -444,9 +454,17 @@ private static function show_info() { } private static function generate_man( $args ) { - $command = Dispatcher\traverse( $args ); + $arg_copy = $args; + + $command = \WP_CLI::$root; + + while ( !empty( $args ) && $command && $command instanceof Dispatcher\CommandContainer ) { + $command = $command->find_subcommand( $args ); + } + if ( !$command ) - WP_CLI::error( sprintf( "'%s' command not found." ) ); + WP_CLI::error( sprintf( "'%s' command not found.", + implode( ' ', $arg_copy ) ) ); foreach ( self::$man_dirs as $dest_dir => $src_dir ) { \WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); diff --git a/php/commands/help.php b/php/commands/help.php index 11fa2aa6a7..1d83ba1596 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -2,6 +2,8 @@ WP_CLI::add_command( 'help', new Help_Command ); +use \WP_CLI\Dispatcher\CommandContainer; + /** * Implement help command * @@ -18,10 +20,16 @@ class Help_Command extends WP_CLI_Command { function __invoke( $args ) { self::maybe_load_man_page( $args ); - $command = \WP_CLI\Dispatcher\traverse( $args ); + $arg_copy = $args; + + $command = \WP_CLI::$root; + + while ( !empty( $args ) && $command && $command instanceof CommandContainer ) { + $command = $command->find_subcommand( $args ); + } if ( !$command ) { - \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); + \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $arg_copy[0] ) ); } $command->show_usage(); diff --git a/php/dispatcher.php b/php/dispatcher.php index 148704fb42..7b7907675c 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -2,21 +2,6 @@ namespace WP_CLI\Dispatcher; -function traverse( &$args, $method = 'find_subcommand' ) { - $args_copy = $args; - - $command = \WP_CLI::$root; - - while ( !empty( $args ) && $command && $command instanceof CommandContainer ) { - $command = $command->$method( $args ); - } - - if ( !$command ) - $args = $args_copy; - - return $command; -} - function get_subcommands( $command ) { if ( $command instanceof CommandContainer ) return $command->get_subcommands(); From 0a59b5b43a2bd82e9add5aae28865f67e3854500 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 18:28:56 +0200 Subject: [PATCH 1018/4858] tests: use system(), instead of futzing with sh and temp files --- tests/class-command-runner.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php index 7139cfb3b1..9b72beba94 100644 --- a/tests/class-command-runner.php +++ b/tests/class-command-runner.php @@ -17,20 +17,13 @@ private function find_wp_cli() { } private function run_command( $command ) { - $output_dummy = array(); - $output_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); - $output_binary_file = tempnam( sys_get_temp_dir(), "wp-cli-test" ); - $return_code = 0; $cwd = $this->cwd; - $sh_command = "cd $cwd;" . - "$command > $output_binary_file 2>&1;" . - 'RETURN_CODE=$?;' . - "cat -v $output_binary_file > $output_file;" . - 'exit $RETURN_CODE'; - exec( "sh -c '$sh_command'", $output_dummy, $return_code ); - $output = file_get_contents( $output_file ); - unlink( $output_file ); - unlink( $output_binary_file ); + $sh_command = "cd $cwd; $command 2>&1;"; + + ob_start(); + system( $sh_command, $return_code ); + $output = ob_get_clean(); + return new Execution_Result( $return_code, $output ); } } From b60e6c17b10291a5565304c88c9cd1e149135079 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 18:31:37 +0200 Subject: [PATCH 1019/4858] don't really need an Execution_Result class --- tests/class-command-runner.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php index 9b72beba94..241f16aa35 100644 --- a/tests/class-command-runner.php +++ b/tests/class-command-runner.php @@ -24,14 +24,7 @@ private function run_command( $command ) { system( $sh_command, $return_code ); $output = ob_get_clean(); - return new Execution_Result( $return_code, $output ); + return (object) compact( 'return_code', 'output' ); } } -class Execution_Result { - - public function __construct( $return_code, $output ) { - $this->return_code = $return_code; - $this->output = $output; - } -} From 0ed20196e6acd91d164aa7807de8712dbc6972c0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 18:39:39 +0200 Subject: [PATCH 1020/4858] use wp_insert_post() in `wp post generate` again. fixes #217 --- php/commands/post.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index b7652676bd..be907ed8aa 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -178,8 +178,7 @@ public function generate( $args, $assoc_args ) { 'post_date' => $post_date, ); - // Not using wp_insert_post() because it's slow - $wpdb->insert( $wpdb->posts, $args ); + wp_insert_post( $args, true ); $notify->tick(); } From a57e88f6b9ed23d1b60cb08c51deca30a2aa3c8d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 19:14:53 +0200 Subject: [PATCH 1021/4858] minor cleanup in `wp post generate` --- php/commands/post.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index be907ed8aa..49bc35e3d8 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -188,12 +188,12 @@ public function generate( $args, $assoc_args ) { private function maybe_make_child() { // 50% chance of making child post - return ( mt_rand(1,2) == 1 ) ? true: false; + return ( mt_rand(1, 2) == 1 ); } private function maybe_reset_depth() { // 10% chance of reseting to root depth - return ( mt_rand(1,10) == 7 ) ? true : false; + return ( mt_rand(1, 10) == 7 ); } } From 6da13d0cf6d311191817f4e5d6c0db3586ee0196 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 19:20:15 +0200 Subject: [PATCH 1022/4858] remove old core-Test.php file --- tests/core-Test.php | 75 --------------------------------------------- tests/test_core.php | 3 -- 2 files changed, 78 deletions(-) delete mode 100644 tests/core-Test.php diff --git a/tests/core-Test.php b/tests/core-Test.php deleted file mode 100644 index ded886a6ee..0000000000 --- a/tests/core-Test.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -class CoreTest extends Wp_Cli_Test_Case { - - public function test_is_installed_exits_with_1_if_empty_dir() { - $temp_dir = $this->create_temporary_directory(); - $runner = new Command_Runner( $temp_dir ); - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 1, $result->return_code ); - } - - public function test_is_installed_exits_with_1_if_missing_wp_config() { - $temp_dir = $this->create_temporary_directory(); - - $runner = new Command_Runner( $temp_dir ); - - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 1, $result->return_code ); - } - - public function test_is_installed_exits_with_1_if_db_not_installed() { - $temp_dir = $this->create_temporary_directory(); - - $runner = new Command_Runner( $temp_dir ); - - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - $installer->create_config( $this->db_settings ); - - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 1, $result->return_code ); - } - - public function test_is_installed_exits_with_0_after_running_install_command() { - $runner = $this->full_wp_install(); - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 0, $result->return_code ); - } - - public function test_install_command_creates_default_blog_post() { - $runner = $this->full_wp_install(); - $result = $runner->run_wp_cli( "post list --ids" ); - $this->assertEquals( "1", $result->output ); - } - - public function test_message_explains_that_config_must_be_present_before_install() { - $temp_dir = $this->create_temporary_directory(); - $runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - $result = $runner->run_wp_cli( "core install" ); - $this->assertEquals( - "Error: wp-config.php not found.\n" . - "Either create one manually or use `wp core config`.\n", - $result->output - ); - } - - public function test_wp_config_can_be_placed_in_parent_directory() { - $temp_dir = $this->create_temporary_directory(); - $install_dir = $temp_dir . '/www-root'; - mkdir( $install_dir ); - $runner = new Command_Runner( $install_dir ); - $installer = new Wordpress_Installer( $install_dir, $runner ); - $installer->download_wordpress_files( $install_dir ); - $installer->create_config( $this->db_settings ); - rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); - $installer->run_install(); - $result = $runner->run_wp_cli( "post list --ids" ); - $this->assertEquals( "1", $result->output ); - } -} diff --git a/tests/test_core.php b/tests/test_core.php index af2f071121..ded886a6ee 100644 --- a/tests/test_core.php +++ b/tests/test_core.php @@ -1,8 +1,5 @@ <?php -require_once __DIR__ . '/class-command-runner.php'; -require_once __DIR__ . '/class-wp-cli-test-case.php'; - class CoreTest extends Wp_Cli_Test_Case { public function test_is_installed_exits_with_1_if_empty_dir() { From 87fab1a5c1494b359234cb568a816e64bffe2285 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 19:43:08 +0200 Subject: [PATCH 1023/4858] don't require passing a runner to Wordpress_Installer --- tests/class-wp-cli-test-case.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 578b493454..1a4302ab71 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -43,12 +43,13 @@ public function create_temporary_directory() { } class Wordpress_Installer { + private $install_dir; private $runner; - public function __construct( $install_dir, $runner ) { + public function __construct( $install_dir ) { $this->install_dir = $install_dir; - $this->runner = $runner; + $this->runner = new Command_Runner( $install_dir ); } public function create_config( $db_settings ) { From ec279ecdf01317f466337d3c4a7dd0e4f373c109 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 19:17:43 +0200 Subject: [PATCH 1024/4858] add phpunit-story as a dev dependency --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c4d8fec422..abdda1a446 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "wp-cli/php-cli-tools": "dev-master" }, "require-dev": { - "phpunit/phpunit": "3.7.x" + "phpunit/phpunit": "3.7.x", + "phpunit/phpunit-story": "1.0.x" }, "autoload": { "psr-0": { "WP_CLI": "php" } From 7340ce31f953c90efaec1b89aaa8a4f825d0212b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 19:30:07 +0200 Subject: [PATCH 1025/4858] update phpunit.xml to run the spec tests --- phpunit.xml.dist | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 77cb7d28d3..49615945a8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,11 @@ <phpunit bootstrap="tests/bootstrap.php" colors="true" - convertErrorsToExceptions="true" - convertNoticesToExceptions="true" - convertWarningsToExceptions="true" + printerClass="PHPUnit_Extensions_Story_ResultPrinter_Text" > <testsuites> <testsuite> - <directory prefix="test_" suffix=".php">tests/</directory> + <directory prefix="spec-" suffix=".php">tests/</directory> </testsuite> </testsuites> </phpunit> From acafdc6ffba8e05b5535a10dfc28bc8b520caad9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 19:31:30 +0200 Subject: [PATCH 1026/4858] add first scenario --- tests/spec-core.php | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/spec-core.php diff --git a/tests/spec-core.php b/tests/spec-core.php new file mode 100644 index 0000000000..40dc2993d2 --- /dev/null +++ b/tests/spec-core.php @@ -0,0 +1,88 @@ +<?php + +class CoreCommandSpec extends PHPUnit_Extensions_Story_TestCase { + + /** + * @scenario + */ + public function emptyDir() { + $this + ->given( 'empty dir' ) + ->when( 'invoking core is-installed' ) + ->then( 'return code should be', 1 ); + } + + /** + * @scenario + */ + public function noWpConfig() { + $this + ->given( 'empty dir' ) + ->and( 'wp files' ) + ->when( 'invoking core is-installed' ) + ->then( 'return code should be', 1 ); + } + + /** + * @scenario + */ + public function notInstalled() { + $this + ->given( 'empty dir' ) + ->and( 'wp files' ) + ->and( 'wp config' ) + ->when( 'invoking core is-installed' ) + ->then( 'return code should be', 1 ); + } + + public function runGiven( &$world, $action, $arguments ) { + switch ( $action ) { + case 'empty dir': { + $world['temp_dir'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $world['temp_dir'] ); + } + break; + + case 'wp files': { + $installer = new Wordpress_Installer( $world['temp_dir'] ); + $installer->download_wordpress_files(); + } + break; + + case 'wp config': { + $installer = new Wordpress_Installer( $world['temp_dir'] ); + $installer->create_config( array( + 'dbname' => 'wp_cli_test', + 'dbuser' => 'wp_cli_test', + 'dbpass' => 'password1' + ) ); + } + break; + + default: { + return $this->notImplemented( $action ); + } + } + } + + public function runWhen( &$world, $action, $arguments ) { + $cmd = str_replace( 'invoking ', '', $action ); + + $runner = new Command_Runner( $world['temp_dir'] ); + $world['result'] = $runner->run_wp_cli( $cmd ); + } + + public function runThen( &$world, $action, $arguments ) { + switch ( $action ) { + case 'return code should be': { + $this->assertEquals( $arguments[0], $world['result']->return_code ); + } + break; + + default: { + return $this->notImplemented( $action ); + } + } + } +} + From 8bf23eeeb66efa6ba8fc16ace29c5ca4cf11b405 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 20:10:53 +0200 Subject: [PATCH 1027/4858] reset database between scenarios --- tests/spec-core.php | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/spec-core.php b/tests/spec-core.php index 40dc2993d2..832c76c989 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -35,6 +35,25 @@ public function notInstalled() { ->then( 'return code should be', 1 ); } + protected static $db_settings = array( + 'dbname' => 'wp_cli_test', + 'dbuser' => 'wp_cli_test', + 'dbpass' => 'password1' + ); + + private static function run_sql( $sql ) { + $dbuser = self::$db_settings['dbuser']; + $dbpass = self::$db_settings['dbpass']; + + exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); + } + + protected function setUp() { + $dbname = self::$db_settings['dbname']; + $this->run_sql( "DROP DATABASE $dbname" ); + $this->run_sql( "CREATE DATABASE $dbname" ); + } + public function runGiven( &$world, $action, $arguments ) { switch ( $action ) { case 'empty dir': { @@ -51,11 +70,7 @@ public function runGiven( &$world, $action, $arguments ) { case 'wp config': { $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->create_config( array( - 'dbname' => 'wp_cli_test', - 'dbuser' => 'wp_cli_test', - 'dbpass' => 'password1' - ) ); + $installer->create_config( self::$db_settings ); } break; From c750bf3e5da9553bf02f9f3ab3510525c271081f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 20:29:13 +0200 Subject: [PATCH 1028/4858] add full_install() method to WordPress_Installer --- tests/class-wp-cli-test-case.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php index 1a4302ab71..7215c9ed33 100644 --- a/tests/class-wp-cli-test-case.php +++ b/tests/class-wp-cli-test-case.php @@ -27,12 +27,9 @@ private function run_sql( $sql ) { public function full_wp_install() { $temp_dir = $this->create_temporary_directory(); - $runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - $installer->create_config( $this->db_settings ); - $installer->run_install(); - return $runner; + $installer = new Wordpress_Installer( $temp_dir ); + $installer->full_install( $this->db_settings ); + return new Command_Runner( $temp_dir ); } public function create_temporary_directory() { @@ -80,6 +77,12 @@ public function download_wordpress_files() { exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } + public function full_install( $db_settings ) { + $this->download_wordpress_files(); + $this->create_config( $db_settings ); + $this->run_install(); + } + private function assert_process_exited_successfully( $result ) { if ( $result->return_code !== 0 ) { $message = "return code was $result->return_code, output was: $result->output"; From caf32c9a0fcc033114bb0e76a10b994deab03880 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 20:29:46 +0200 Subject: [PATCH 1029/4858] more scenarios --- tests/spec-core.php | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/tests/spec-core.php b/tests/spec-core.php index 832c76c989..593389e8b6 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -8,6 +8,7 @@ class CoreCommandSpec extends PHPUnit_Extensions_Story_TestCase { public function emptyDir() { $this ->given( 'empty dir' ) + ->when( 'invoking core is-installed' ) ->then( 'return code should be', 1 ); } @@ -19,22 +20,45 @@ public function noWpConfig() { $this ->given( 'empty dir' ) ->and( 'wp files' ) + ->when( 'invoking core is-installed' ) - ->then( 'return code should be', 1 ); + ->then( 'return code should be', 1 ) + + ->when( 'invoking core install' ) + ->then( 'output should be', + "Error: wp-config.php not found.\n" . + "Either create one manually or use `wp core config`.\n" + ); } /** * @scenario */ - public function notInstalled() { + public function dbTablesNotInstalled() { $this ->given( 'empty dir' ) ->and( 'wp files' ) ->and( 'wp config' ) + ->when( 'invoking core is-installed' ) ->then( 'return code should be', 1 ); } + /** + * @scenario + */ + public function fullInstall() { + $this + ->given( 'empty dir' ) + ->and( 'wp install' ) + + ->when( 'invoking core is-installed' ) + ->then( 'return code should be', 0 ) + + ->when( 'invoking post list --ids' ) + ->then( 'output should be', 1 ); + } + protected static $db_settings = array( 'dbname' => 'wp_cli_test', 'dbuser' => 'wp_cli_test', @@ -74,6 +98,12 @@ public function runGiven( &$world, $action, $arguments ) { } break; + case 'wp install': { + $installer = new Wordpress_Installer( $world['temp_dir'] ); + $installer->full_install( self::$db_settings ); + } + break; + default: { return $this->notImplemented( $action ); } @@ -94,6 +124,11 @@ public function runThen( &$world, $action, $arguments ) { } break; + case 'output should be': { + $this->assertEquals( $arguments[0], $world['result']->output ); + } + break; + default: { return $this->notImplemented( $action ); } From 7e842fc564afe137d2537b7da73964ea384c3cf8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 20:50:52 +0200 Subject: [PATCH 1030/4858] remove old test cases and move all supporting code to bootstrap.php --- tests/bootstrap.php | 80 ++++++++++++++++++++++++++- tests/class-command-runner.php | 30 ----------- tests/class-wp-cli-test-case.php | 92 -------------------------------- tests/test_core.php | 75 -------------------------- 4 files changed, 78 insertions(+), 199 deletions(-) delete mode 100644 tests/class-command-runner.php delete mode 100644 tests/class-wp-cli-test-case.php delete mode 100644 tests/test_core.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index ac6ee71957..c7ce8ec8c7 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,5 +1,81 @@ <?php -require __DIR__ . '/class-command-runner.php'; -require __DIR__ . '/class-wp-cli-test-case.php'; +class Command_Runner { + private $cwd; + public function __construct( $cwd ) { + $this->cwd = $cwd; + } + + public function run_wp_cli( $wp_cli_command ) { + $wp_cli_path = self::find_wp_cli(); + return self::run_command( "$wp_cli_path $wp_cli_command" ); + } + + private function find_wp_cli() { + return getcwd() . "/bin/wp"; + } + + private function run_command( $command ) { + $cwd = $this->cwd; + $sh_command = "cd $cwd; $command 2>&1;"; + + ob_start(); + system( $sh_command, $return_code ); + $output = ob_get_clean(); + + return (object) compact( 'return_code', 'output' ); + } +} + +class Wordpress_Installer { + + private $install_dir; + private $runner; + + public function __construct( $install_dir ) { + $this->install_dir = $install_dir; + $this->runner = new Command_Runner( $install_dir ); + } + + public function create_config( $db_settings ) { + $dbname = $db_settings["dbname"]; + $dbuser = $db_settings["dbuser"]; + $dbpass = $db_settings["dbpass"]; + $this->runner->run_wp_cli( + "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); + } + + public function run_install() { + $install_result = $this->runner->run_wp_cli( + "core install --url=http://example.com/ --title=WordPress " . + " --admin_email=admin@example.com --admin_password=password1" + ); + $this->assert_process_exited_successfully( $install_result ); + } + + public function download_wordpress_files() { + // We cache the results of "wp core download" to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + if ( !file_exists( $cache_dir ) ) { + mkdir( $cache_dir ); + $runner = new Command_Runner( $cache_dir ); + $runner->run_wp_cli( "core download" ); + } + exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); + } + + public function full_install( $db_settings ) { + $this->download_wordpress_files(); + $this->create_config( $db_settings ); + $this->run_install(); + } + + private function assert_process_exited_successfully( $result ) { + if ( $result->return_code !== 0 ) { + $message = "return code was $result->return_code, output was: $result->output"; + throw new Exception( $message ); + } + } +} diff --git a/tests/class-command-runner.php b/tests/class-command-runner.php deleted file mode 100644 index 241f16aa35..0000000000 --- a/tests/class-command-runner.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -class Command_Runner { - private $cwd; - - public function __construct( $cwd ) { - $this->cwd = $cwd; - } - - public function run_wp_cli( $wp_cli_command ) { - $wp_cli_path = self::find_wp_cli(); - return self::run_command( "$wp_cli_path $wp_cli_command" ); - } - - private function find_wp_cli() { - return getcwd() . "/bin/wp"; - } - - private function run_command( $command ) { - $cwd = $this->cwd; - $sh_command = "cd $cwd; $command 2>&1;"; - - ob_start(); - system( $sh_command, $return_code ); - $output = ob_get_clean(); - - return (object) compact( 'return_code', 'output' ); - } -} - diff --git a/tests/class-wp-cli-test-case.php b/tests/class-wp-cli-test-case.php deleted file mode 100644 index 7215c9ed33..0000000000 --- a/tests/class-wp-cli-test-case.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php - -require_once __DIR__ . '/class-command-runner.php'; - -abstract class Wp_Cli_Test_Case extends PHPUnit_Framework_TestCase { - protected $db_settings = array( - "dbname" => "wp_cli_test", - "dbuser" => "wp_cli_test", - "dbpass" => "password1" - ); - - protected function setUp() { - $this->reset_database(); - } - - private function reset_database() { - $dbname = $this->db_settings["dbname"]; - $this->run_sql( "DROP DATABASE $dbname" ); - $this->run_sql( "CREATE DATABASE $dbname" ); - } - - private function run_sql( $sql ) { - $dbuser = $this->db_settings["dbuser"]; - $dbpass = $this->db_settings["dbpass"]; - exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); - } - - public function full_wp_install() { - $temp_dir = $this->create_temporary_directory(); - $installer = new Wordpress_Installer( $temp_dir ); - $installer->full_install( $this->db_settings ); - return new Command_Runner( $temp_dir ); - } - - public function create_temporary_directory() { - $dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $dir ); - return $dir; - } -} - -class Wordpress_Installer { - - private $install_dir; - private $runner; - - public function __construct( $install_dir ) { - $this->install_dir = $install_dir; - $this->runner = new Command_Runner( $install_dir ); - } - - public function create_config( $db_settings ) { - $dbname = $db_settings["dbname"]; - $dbuser = $db_settings["dbuser"]; - $dbpass = $db_settings["dbpass"]; - $this->runner->run_wp_cli( - "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); - } - - public function run_install() { - $install_result = $this->runner->run_wp_cli( - "core install --url=http://example.com/ --title=WordPress " . - " --admin_email=admin@example.com --admin_password=password1" - ); - $this->assert_process_exited_successfully( $install_result ); - } - - public function download_wordpress_files() { - // We cache the results of "wp core download" to improve test performance - // Ideally, we'd cache at the HTTP layer for more reliable tests - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - if ( !file_exists( $cache_dir ) ) { - mkdir( $cache_dir ); - $runner = new Command_Runner( $cache_dir ); - $runner->run_wp_cli( "core download" ); - } - exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); - } - - public function full_install( $db_settings ) { - $this->download_wordpress_files(); - $this->create_config( $db_settings ); - $this->run_install(); - } - - private function assert_process_exited_successfully( $result ) { - if ( $result->return_code !== 0 ) { - $message = "return code was $result->return_code, output was: $result->output"; - throw new Exception( $message ); - } - } -} diff --git a/tests/test_core.php b/tests/test_core.php deleted file mode 100644 index ded886a6ee..0000000000 --- a/tests/test_core.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -class CoreTest extends Wp_Cli_Test_Case { - - public function test_is_installed_exits_with_1_if_empty_dir() { - $temp_dir = $this->create_temporary_directory(); - $runner = new Command_Runner( $temp_dir ); - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 1, $result->return_code ); - } - - public function test_is_installed_exits_with_1_if_missing_wp_config() { - $temp_dir = $this->create_temporary_directory(); - - $runner = new Command_Runner( $temp_dir ); - - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 1, $result->return_code ); - } - - public function test_is_installed_exits_with_1_if_db_not_installed() { - $temp_dir = $this->create_temporary_directory(); - - $runner = new Command_Runner( $temp_dir ); - - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - $installer->create_config( $this->db_settings ); - - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 1, $result->return_code ); - } - - public function test_is_installed_exits_with_0_after_running_install_command() { - $runner = $this->full_wp_install(); - $result = $runner->run_wp_cli( "core is-installed" ); - $this->assertEquals( 0, $result->return_code ); - } - - public function test_install_command_creates_default_blog_post() { - $runner = $this->full_wp_install(); - $result = $runner->run_wp_cli( "post list --ids" ); - $this->assertEquals( "1", $result->output ); - } - - public function test_message_explains_that_config_must_be_present_before_install() { - $temp_dir = $this->create_temporary_directory(); - $runner = new Command_Runner( $temp_dir ); - $installer = new Wordpress_Installer( $temp_dir, $runner ); - $installer->download_wordpress_files( $temp_dir ); - $result = $runner->run_wp_cli( "core install" ); - $this->assertEquals( - "Error: wp-config.php not found.\n" . - "Either create one manually or use `wp core config`.\n", - $result->output - ); - } - - public function test_wp_config_can_be_placed_in_parent_directory() { - $temp_dir = $this->create_temporary_directory(); - $install_dir = $temp_dir . '/www-root'; - mkdir( $install_dir ); - $runner = new Command_Runner( $install_dir ); - $installer = new Wordpress_Installer( $install_dir, $runner ); - $installer->download_wordpress_files( $install_dir ); - $installer->create_config( $this->db_settings ); - rename( $install_dir . '/wp-config.php', $temp_dir . '/wp-config.php' ); - $installer->run_install(); - $result = $runner->run_wp_cli( "post list --ids" ); - $this->assertEquals( "1", $result->output ); - } -} From 653fe6bd5618ca3055bf8c82f9611a01d35a6154 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 21:01:24 +0200 Subject: [PATCH 1031/4858] move supporting code to a WP_CLI_Spec class --- tests/bootstrap.php | 2 + tests/class-wp-cli-spec.php | 81 +++++++++++++++++++++++++++++++++++++ tests/spec-core.php | 78 +---------------------------------- 3 files changed, 84 insertions(+), 77 deletions(-) create mode 100644 tests/class-wp-cli-spec.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c7ce8ec8c7..bac8b968c7 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,5 +1,7 @@ <?php +require_once __DIR__ . '/class-wp-cli-spec.php'; + class Command_Runner { private $cwd; diff --git a/tests/class-wp-cli-spec.php b/tests/class-wp-cli-spec.php new file mode 100644 index 0000000000..76e8ab45a9 --- /dev/null +++ b/tests/class-wp-cli-spec.php @@ -0,0 +1,81 @@ +<?php + +abstract class WP_CLI_Spec extends PHPUnit_Extensions_Story_TestCase { + + protected static $db_settings = array( + 'dbname' => 'wp_cli_test', + 'dbuser' => 'wp_cli_test', + 'dbpass' => 'password1' + ); + + private static function run_sql( $sql ) { + $dbuser = self::$db_settings['dbuser']; + $dbpass = self::$db_settings['dbpass']; + + exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); + } + + protected function setUp() { + $dbname = self::$db_settings['dbname']; + $this->run_sql( "DROP DATABASE $dbname" ); + $this->run_sql( "CREATE DATABASE $dbname" ); + } + + public function runGiven( &$world, $action, $arguments ) { + switch ( $action ) { + case 'empty dir': { + $world['temp_dir'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $world['temp_dir'] ); + } + break; + + case 'wp files': { + $installer = new Wordpress_Installer( $world['temp_dir'] ); + $installer->download_wordpress_files(); + } + break; + + case 'wp config': { + $installer = new Wordpress_Installer( $world['temp_dir'] ); + $installer->create_config( self::$db_settings ); + } + break; + + case 'wp install': { + $installer = new Wordpress_Installer( $world['temp_dir'] ); + $installer->full_install( self::$db_settings ); + } + break; + + default: { + return $this->notImplemented( $action ); + } + } + } + + public function runWhen( &$world, $action, $arguments ) { + $cmd = str_replace( 'invoking ', '', $action ); + + $runner = new Command_Runner( $world['temp_dir'] ); + $world['result'] = $runner->run_wp_cli( $cmd ); + } + + public function runThen( &$world, $action, $arguments ) { + switch ( $action ) { + case 'return code should be': { + $this->assertEquals( $arguments[0], $world['result']->return_code ); + } + break; + + case 'output should be': { + $this->assertEquals( $arguments[0], $world['result']->output ); + } + break; + + default: { + return $this->notImplemented( $action ); + } + } + } +} + diff --git a/tests/spec-core.php b/tests/spec-core.php index 593389e8b6..250fb9bc29 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -1,6 +1,6 @@ <?php -class CoreCommandSpec extends PHPUnit_Extensions_Story_TestCase { +class CoreCommandSpec extends WP_CLI_Spec { /** * @scenario @@ -58,81 +58,5 @@ public function fullInstall() { ->when( 'invoking post list --ids' ) ->then( 'output should be', 1 ); } - - protected static $db_settings = array( - 'dbname' => 'wp_cli_test', - 'dbuser' => 'wp_cli_test', - 'dbpass' => 'password1' - ); - - private static function run_sql( $sql ) { - $dbuser = self::$db_settings['dbuser']; - $dbpass = self::$db_settings['dbpass']; - - exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); - } - - protected function setUp() { - $dbname = self::$db_settings['dbname']; - $this->run_sql( "DROP DATABASE $dbname" ); - $this->run_sql( "CREATE DATABASE $dbname" ); - } - - public function runGiven( &$world, $action, $arguments ) { - switch ( $action ) { - case 'empty dir': { - $world['temp_dir'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $world['temp_dir'] ); - } - break; - - case 'wp files': { - $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->download_wordpress_files(); - } - break; - - case 'wp config': { - $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->create_config( self::$db_settings ); - } - break; - - case 'wp install': { - $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->full_install( self::$db_settings ); - } - break; - - default: { - return $this->notImplemented( $action ); - } - } - } - - public function runWhen( &$world, $action, $arguments ) { - $cmd = str_replace( 'invoking ', '', $action ); - - $runner = new Command_Runner( $world['temp_dir'] ); - $world['result'] = $runner->run_wp_cli( $cmd ); - } - - public function runThen( &$world, $action, $arguments ) { - switch ( $action ) { - case 'return code should be': { - $this->assertEquals( $arguments[0], $world['result']->return_code ); - } - break; - - case 'output should be': { - $this->assertEquals( $arguments[0], $world['result']->output ); - } - break; - - default: { - return $this->notImplemented( $action ); - } - } - } } From cae01a899a86d5ea6d3e9e2d5b507306cd669332 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 21:06:11 +0200 Subject: [PATCH 1032/4858] dismantle full_install() method --- tests/bootstrap.php | 6 ------ tests/class-wp-cli-spec.php | 4 +++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index bac8b968c7..9a794706f9 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -68,12 +68,6 @@ public function download_wordpress_files() { exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } - public function full_install( $db_settings ) { - $this->download_wordpress_files(); - $this->create_config( $db_settings ); - $this->run_install(); - } - private function assert_process_exited_successfully( $result ) { if ( $result->return_code !== 0 ) { $message = "return code was $result->return_code, output was: $result->output"; diff --git a/tests/class-wp-cli-spec.php b/tests/class-wp-cli-spec.php index 76e8ab45a9..56dcf170c1 100644 --- a/tests/class-wp-cli-spec.php +++ b/tests/class-wp-cli-spec.php @@ -43,7 +43,9 @@ public function runGiven( &$world, $action, $arguments ) { case 'wp install': { $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->full_install( self::$db_settings ); + $installer->download_wordpress_files(); + $installer->create_config( self::$db_settings ); + $installer->run_install(); } break; From 7321cf63a7aa69643ee8d4eca684fd4aaec15d93 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 21:19:55 +0200 Subject: [PATCH 1033/4858] PHPUnit_Extensions_Story_ResultPrinter_Text is not that great --- phpunit.xml.dist | 1 - 1 file changed, 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 49615945a8..917a7d50ad 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,6 @@ <phpunit bootstrap="tests/bootstrap.php" colors="true" - printerClass="PHPUnit_Extensions_Story_ResultPrinter_Text" > <testsuites> <testsuite> From 6960f7a3d01c116a48406576b3a262a56535e6b8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 21:28:57 +0200 Subject: [PATCH 1034/4858] set @scenarion annotation on a single line --- tests/spec-core.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/spec-core.php b/tests/spec-core.php index 250fb9bc29..5cfdb6d497 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -2,9 +2,7 @@ class CoreCommandSpec extends WP_CLI_Spec { - /** - * @scenario - */ + /** @scenario */ public function emptyDir() { $this ->given( 'empty dir' ) @@ -13,9 +11,7 @@ public function emptyDir() { ->then( 'return code should be', 1 ); } - /** - * @scenario - */ + /** @scenario */ public function noWpConfig() { $this ->given( 'empty dir' ) @@ -31,9 +27,7 @@ public function noWpConfig() { ); } - /** - * @scenario - */ + /** @scenario */ public function dbTablesNotInstalled() { $this ->given( 'empty dir' ) @@ -44,9 +38,7 @@ public function dbTablesNotInstalled() { ->then( 'return code should be', 1 ); } - /** - * @scenario - */ + /** @scenario */ public function fullInstall() { $this ->given( 'empty dir' ) From 2e50648b8cedbf25f12f7983c295252b2edd3ca1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 21:54:52 +0200 Subject: [PATCH 1035/4858] transform Command_Runner class into run_wp_cli() method --- tests/bootstrap.php | 49 +++++++++++++------------------------ tests/class-wp-cli-spec.php | 3 +-- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9a794706f9..35f6b28a6b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,57 +2,43 @@ require_once __DIR__ . '/class-wp-cli-spec.php'; -class Command_Runner { - private $cwd; +function run_wp_cli( $command, $cwd ) { + $wp_cli_path = getcwd() . "/bin/wp"; - public function __construct( $cwd ) { - $this->cwd = $cwd; - } - - public function run_wp_cli( $wp_cli_command ) { - $wp_cli_path = self::find_wp_cli(); - return self::run_command( "$wp_cli_path $wp_cli_command" ); - } - - private function find_wp_cli() { - return getcwd() . "/bin/wp"; - } - - private function run_command( $command ) { - $cwd = $this->cwd; - $sh_command = "cd $cwd; $command 2>&1;"; + $sh_command = "cd $cwd; $wp_cli_path $command 2>&1;"; - ob_start(); - system( $sh_command, $return_code ); - $output = ob_get_clean(); + ob_start(); + system( $sh_command, $return_code ); + $output = ob_get_clean(); - return (object) compact( 'return_code', 'output' ); - } + return (object) compact( 'return_code', 'output' ); } class Wordpress_Installer { private $install_dir; - private $runner; public function __construct( $install_dir ) { $this->install_dir = $install_dir; - $this->runner = new Command_Runner( $install_dir ); } public function create_config( $db_settings ) { $dbname = $db_settings["dbname"]; $dbuser = $db_settings["dbuser"]; $dbpass = $db_settings["dbpass"]; - $this->runner->run_wp_cli( - "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass" ); + + $cmd = "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass"; + + run_wp_cli( $cmd, $this->install_dir ); } public function run_install() { - $install_result = $this->runner->run_wp_cli( + $cmd = "core install --url=http://example.com/ --title=WordPress " . - " --admin_email=admin@example.com --admin_password=password1" - ); + " --admin_email=admin@example.com --admin_password=password1"; + + $install_result = run_wp_cli( $cmd, $this->install_dir ); + $this->assert_process_exited_successfully( $install_result ); } @@ -62,8 +48,7 @@ public function download_wordpress_files() { $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; if ( !file_exists( $cache_dir ) ) { mkdir( $cache_dir ); - $runner = new Command_Runner( $cache_dir ); - $runner->run_wp_cli( "core download" ); + run_wp_cli( "core download", $cache_dir ); } exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } diff --git a/tests/class-wp-cli-spec.php b/tests/class-wp-cli-spec.php index 56dcf170c1..e12ba92771 100644 --- a/tests/class-wp-cli-spec.php +++ b/tests/class-wp-cli-spec.php @@ -58,8 +58,7 @@ public function runGiven( &$world, $action, $arguments ) { public function runWhen( &$world, $action, $arguments ) { $cmd = str_replace( 'invoking ', '', $action ); - $runner = new Command_Runner( $world['temp_dir'] ); - $world['result'] = $runner->run_wp_cli( $cmd ); + $world['result'] = run_wp_cli( $cmd, $world['temp_dir'] ); } public function runThen( &$world, $action, $arguments ) { From afe4348d121a16f6ddf309fea661cc6eeae3c595 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 22:04:38 +0200 Subject: [PATCH 1036/4858] WP_CLI::compose_args() -> Utils\compose_args() --- php/class-wp-cli.php | 19 ------------------- php/utils.php | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 426c8afff5..232f6dc4b3 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -222,25 +222,6 @@ static function error_to_string( $errors ) { } } - /** - * Composes positional and associative arguments into a string. - * - * @param array - * @return string - */ - static function compose_args( $args, $assoc_args = array() ) { - $str = ' ' . implode( ' ', array_map( 'escapeshellarg', $args ) ); - - foreach ( $assoc_args as $key => $value ) { - if ( true === $value ) - $str .= " --$key"; - else - $str .= " --$key=" . escapeshellarg( $value ); - } - - return $str; - } - /** * Launch an external process that takes over I/O. * diff --git a/php/utils.php b/php/utils.php index aac36c5b2c..b0d8f0894f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -89,6 +89,26 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args ); } +/** + * Composes positional and associative arguments into a string. + * + * @param array Positional args + * @param array Associative args + * @return string + */ +function compose_args( $args, $assoc_args = array() ) { + $str = ' ' . implode( ' ', array_map( 'escapeshellarg', $args ) ); + + foreach ( $assoc_args as $key => $value ) { + if ( true === $value ) + $str .= " --$key"; + else + $str .= " --$key=" . escapeshellarg( $value ); + } + + return $str; +} + function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $blog = $assoc_args['url']; From d88192f8b4eeda2911a2c5fcb7f483339d488b75 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 22:16:23 +0200 Subject: [PATCH 1037/4858] break out compose_assoc_args() utility and use in test runner --- php/utils.php | 19 ++++++++++++++----- tests/bootstrap.php | 18 ++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/php/utils.php b/php/utils.php index b0d8f0894f..0ade39ee7c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -90,14 +90,23 @@ function parse_args( $arguments ) { } /** - * Composes positional and associative arguments into a string. + * Composes positional arguments into a command string. * - * @param array Positional args - * @param array Associative args + * @param array * @return string */ -function compose_args( $args, $assoc_args = array() ) { - $str = ' ' . implode( ' ', array_map( 'escapeshellarg', $args ) ); +function compose_args( $args ) { + return ' ' . implode( ' ', array_map( 'escapeshellarg', $args ) ); +} + +/** + * Composes associative arguments into a command string. + * + * @param array + * @return string + */ +function compose_assoc_args( $assoc_args ) { + $str = ''; foreach ( $assoc_args as $key => $value ) { if ( true === $value ) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 35f6b28a6b..c9393cd591 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,5 +1,7 @@ <?php +require_once getcwd() . '/php/utils.php'; + require_once __DIR__ . '/class-wp-cli-spec.php'; function run_wp_cli( $command, $cwd ) { @@ -23,19 +25,18 @@ public function __construct( $install_dir ) { } public function create_config( $db_settings ) { - $dbname = $db_settings["dbname"]; - $dbuser = $db_settings["dbuser"]; - $dbpass = $db_settings["dbpass"]; - - $cmd = "core config --dbname=$dbname --dbuser=$dbuser --dbpass=$dbpass"; + $cmd = 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ); run_wp_cli( $cmd, $this->install_dir ); } public function run_install() { - $cmd = - "core install --url=http://example.com/ --title=WordPress " . - " --admin_email=admin@example.com --admin_password=password1"; + $cmd = 'core install' . \WP_CLI\Utils\compose_assoc_args( array( + 'url' => 'http://example.com', + 'title' => 'WP CLI Tests', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1' + ) ); $install_result = run_wp_cli( $cmd, $this->install_dir ); @@ -50,6 +51,7 @@ public function download_wordpress_files() { mkdir( $cache_dir ); run_wp_cli( "core download", $cache_dir ); } + exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } From d222caa169ed9a80c7169d1dcb95830d4656ab5f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 22:50:28 +0200 Subject: [PATCH 1038/4858] Wordpress_Installer + run_wp_cli() = WP_CLI_Command_Runner --- tests/bootstrap.php | 36 +++++++++++++++++++----------------- tests/class-wp-cli-spec.php | 18 +++++++----------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c9393cd591..936875e7b4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -4,30 +4,32 @@ require_once __DIR__ . '/class-wp-cli-spec.php'; -function run_wp_cli( $command, $cwd ) { - $wp_cli_path = getcwd() . "/bin/wp"; +class WP_CLI_Command_Runner { - $sh_command = "cd $cwd; $wp_cli_path $command 2>&1;"; + private $install_dir; - ob_start(); - system( $sh_command, $return_code ); - $output = ob_get_clean(); + public function __construct() { + $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $this->install_dir ); + } - return (object) compact( 'return_code', 'output' ); -} + public function run( $command, $cwd = false ) { + if ( !$cwd ) + $cwd = $this->install_dir; -class Wordpress_Installer { + $wp_cli_path = getcwd() . "/bin/wp"; - private $install_dir; + $sh_command = "cd $cwd; $wp_cli_path $command 2>&1;"; + + ob_start(); + system( $sh_command, $return_code ); + $output = ob_get_clean(); - public function __construct( $install_dir ) { - $this->install_dir = $install_dir; + return (object) compact( 'return_code', 'output' ); } public function create_config( $db_settings ) { - $cmd = 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ); - - run_wp_cli( $cmd, $this->install_dir ); + $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); } public function run_install() { @@ -38,7 +40,7 @@ public function run_install() { 'admin_password' => 'password1' ) ); - $install_result = run_wp_cli( $cmd, $this->install_dir ); + $install_result = $this->run( $cmd ); $this->assert_process_exited_successfully( $install_result ); } @@ -49,7 +51,7 @@ public function download_wordpress_files() { $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; if ( !file_exists( $cache_dir ) ) { mkdir( $cache_dir ); - run_wp_cli( "core download", $cache_dir ); + $this->run( "core download", $cache_dir ); } exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); diff --git a/tests/class-wp-cli-spec.php b/tests/class-wp-cli-spec.php index e12ba92771..de7e798396 100644 --- a/tests/class-wp-cli-spec.php +++ b/tests/class-wp-cli-spec.php @@ -24,28 +24,24 @@ protected function setUp() { public function runGiven( &$world, $action, $arguments ) { switch ( $action ) { case 'empty dir': { - $world['temp_dir'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $world['temp_dir'] ); + $world['runner'] = new WP_CLI_Command_Runner; } break; case 'wp files': { - $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->download_wordpress_files(); + $world['runner']->download_wordpress_files(); } break; case 'wp config': { - $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->create_config( self::$db_settings ); + $world['runner']->create_config( self::$db_settings ); } break; case 'wp install': { - $installer = new Wordpress_Installer( $world['temp_dir'] ); - $installer->download_wordpress_files(); - $installer->create_config( self::$db_settings ); - $installer->run_install(); + $world['runner']->download_wordpress_files(); + $world['runner']->create_config( self::$db_settings ); + $world['runner']->run_install(); } break; @@ -58,7 +54,7 @@ public function runGiven( &$world, $action, $arguments ) { public function runWhen( &$world, $action, $arguments ) { $cmd = str_replace( 'invoking ', '', $action ); - $world['result'] = run_wp_cli( $cmd, $world['temp_dir'] ); + $world['result'] = $world['runner']->run( $cmd ); } public function runThen( &$world, $action, $arguments ) { From da73c0167a886022d679d285497fd3a4101fb058 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 23:03:14 +0200 Subject: [PATCH 1039/4858] explicitly test creating config file and running install --- tests/bootstrap.php | 13 ++----------- tests/class-wp-cli-spec.php | 18 ++++++++++++++++-- tests/spec-core.php | 18 ++++++++++++------ 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 936875e7b4..8a095f88c4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -29,7 +29,7 @@ public function run( $command, $cwd = false ) { } public function create_config( $db_settings ) { - $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); + return $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); } public function run_install() { @@ -40,9 +40,7 @@ public function run_install() { 'admin_password' => 'password1' ) ); - $install_result = $this->run( $cmd ); - - $this->assert_process_exited_successfully( $install_result ); + return $this->run( $cmd ); } public function download_wordpress_files() { @@ -56,11 +54,4 @@ public function download_wordpress_files() { exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); } - - private function assert_process_exited_successfully( $result ) { - if ( $result->return_code !== 0 ) { - $message = "return code was $result->return_code, output was: $result->output"; - throw new Exception( $message ); - } - } } diff --git a/tests/class-wp-cli-spec.php b/tests/class-wp-cli-spec.php index de7e798396..6c4c6ca956 100644 --- a/tests/class-wp-cli-spec.php +++ b/tests/class-wp-cli-spec.php @@ -52,9 +52,23 @@ public function runGiven( &$world, $action, $arguments ) { } public function runWhen( &$world, $action, $arguments ) { - $cmd = str_replace( 'invoking ', '', $action ); + switch ( $action ) { + case 'invoking core install': { + $world['result'] = $world['runner']->run_install(); + } + break; + + case 'invoking core config': { + $world['result'] = $world['runner']->create_config( self::$db_settings ); + } + break; + + default: { + $cmd = str_replace( 'invoking ', '', $action ); - $world['result'] = $world['runner']->run( $cmd ); + $world['result'] = $world['runner']->run( $cmd ); + } + } } public function runThen( &$world, $action, $arguments ) { diff --git a/tests/spec-core.php b/tests/spec-core.php index 5cfdb6d497..1993613008 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -24,7 +24,10 @@ public function noWpConfig() { ->then( 'output should be', "Error: wp-config.php not found.\n" . "Either create one manually or use `wp core config`.\n" - ); + ) + + ->when( 'invoking core config' ) + ->then( 'return code should be', 0 ); } /** @scenario */ @@ -35,7 +38,13 @@ public function dbTablesNotInstalled() { ->and( 'wp config' ) ->when( 'invoking core is-installed' ) - ->then( 'return code should be', 1 ); + ->then( 'return code should be', 1 ) + + ->when( 'invoking core install' ) + ->then( 'return code should be', 0 ) + + ->when( 'invoking post list --ids' ) + ->then( 'output should be', 1 ); } /** @scenario */ @@ -45,10 +54,7 @@ public function fullInstall() { ->and( 'wp install' ) ->when( 'invoking core is-installed' ) - ->then( 'return code should be', 0 ) - - ->when( 'invoking post list --ids' ) - ->then( 'output should be', 1 ); + ->then( 'return code should be', 0 ); } } From e40e5f4a5c586559efc9df701c61d3ecff437b7d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 29 Dec 2012 23:06:12 +0200 Subject: [PATCH 1040/4858] move WP_CLI_Command_Runner class out of bootstrap.php --- ...lass-wp-cli-spec.php => abstract-spec.php} | 0 tests/bootstrap.php | 54 +------------------ tests/command-runner.php | 53 ++++++++++++++++++ 3 files changed, 55 insertions(+), 52 deletions(-) rename tests/{class-wp-cli-spec.php => abstract-spec.php} (100%) create mode 100644 tests/command-runner.php diff --git a/tests/class-wp-cli-spec.php b/tests/abstract-spec.php similarity index 100% rename from tests/class-wp-cli-spec.php rename to tests/abstract-spec.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8a095f88c4..4e82b7fa56 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,56 +2,6 @@ require_once getcwd() . '/php/utils.php'; -require_once __DIR__ . '/class-wp-cli-spec.php'; +require_once __DIR__ . '/abstract-spec.php'; +require_once __DIR__ . '/command-runner.php'; -class WP_CLI_Command_Runner { - - private $install_dir; - - public function __construct() { - $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $this->install_dir ); - } - - public function run( $command, $cwd = false ) { - if ( !$cwd ) - $cwd = $this->install_dir; - - $wp_cli_path = getcwd() . "/bin/wp"; - - $sh_command = "cd $cwd; $wp_cli_path $command 2>&1;"; - - ob_start(); - system( $sh_command, $return_code ); - $output = ob_get_clean(); - - return (object) compact( 'return_code', 'output' ); - } - - public function create_config( $db_settings ) { - return $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); - } - - public function run_install() { - $cmd = 'core install' . \WP_CLI\Utils\compose_assoc_args( array( - 'url' => 'http://example.com', - 'title' => 'WP CLI Tests', - 'admin_email' => 'admin@example.com', - 'admin_password' => 'password1' - ) ); - - return $this->run( $cmd ); - } - - public function download_wordpress_files() { - // We cache the results of "wp core download" to improve test performance - // Ideally, we'd cache at the HTTP layer for more reliable tests - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - if ( !file_exists( $cache_dir ) ) { - mkdir( $cache_dir ); - $this->run( "core download", $cache_dir ); - } - - exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); - } -} diff --git a/tests/command-runner.php b/tests/command-runner.php new file mode 100644 index 0000000000..d232c91118 --- /dev/null +++ b/tests/command-runner.php @@ -0,0 +1,53 @@ +<?php + +class WP_CLI_Command_Runner { + + private $install_dir; + + public function __construct() { + $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $this->install_dir ); + } + + public function run( $command, $cwd = false ) { + if ( !$cwd ) + $cwd = $this->install_dir; + + $wp_cli_path = getcwd() . "/bin/wp"; + + $sh_command = "cd $cwd; $wp_cli_path $command 2>&1;"; + + ob_start(); + system( $sh_command, $return_code ); + $output = ob_get_clean(); + + return (object) compact( 'return_code', 'output' ); + } + + public function create_config( $db_settings ) { + return $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); + } + + public function run_install() { + $cmd = 'core install' . \WP_CLI\Utils\compose_assoc_args( array( + 'url' => 'http://example.com', + 'title' => 'WP CLI Tests', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1' + ) ); + + return $this->run( $cmd ); + } + + public function download_wordpress_files() { + // We cache the results of "wp core download" to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + if ( !file_exists( $cache_dir ) ) { + mkdir( $cache_dir ); + $this->run( "core download", $cache_dir ); + } + + exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); + } +} From f85b7693c0ae8b39a73089604a7856f08016ef7f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 10:09:45 +0200 Subject: [PATCH 1041/4858] add test for when db tables aren't installed --- tests/abstract-spec.php | 5 +++++ tests/spec-core.php | 3 +++ 2 files changed, 8 insertions(+) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 6c4c6ca956..746a647be1 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -83,6 +83,11 @@ public function runThen( &$world, $action, $arguments ) { } break; + case 'should have output': { + $this->assertNotEmpty( $world['result']->output ); + } + break; + default: { return $this->notImplemented( $action ); } diff --git a/tests/spec-core.php b/tests/spec-core.php index 1993613008..dbbcfbf681 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -40,6 +40,9 @@ public function dbTablesNotInstalled() { ->when( 'invoking core is-installed' ) ->then( 'return code should be', 1 ) + ->when( 'invoking help' ) + ->then( 'should have output' ) + ->when( 'invoking core install' ) ->then( 'return code should be', 0 ) From 15f1eb937686a4e12770418e87959f74076bc54f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 10:15:05 +0200 Subject: [PATCH 1042/4858] pass action as message for assertions --- tests/abstract-spec.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 746a647be1..8b83235699 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -74,17 +74,17 @@ public function runWhen( &$world, $action, $arguments ) { public function runThen( &$world, $action, $arguments ) { switch ( $action ) { case 'return code should be': { - $this->assertEquals( $arguments[0], $world['result']->return_code ); + $this->assertEquals( $arguments[0], $world['result']->return_code, $action ); } break; case 'output should be': { - $this->assertEquals( $arguments[0], $world['result']->output ); + $this->assertEquals( $arguments[0], $world['result']->output, $action ); } break; case 'should have output': { - $this->assertNotEmpty( $world['result']->output ); + $this->assertNotEmpty( $world['result']->output, $action ); } break; From c8ea8cad0ed32cf9c298958de98ecd024be92b11 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 11:12:37 +0200 Subject: [PATCH 1043/4858] Tame wp-config.php Frustratingly, wp-config.php insists on defining ABSPATH and on require()ing wp-settings.php. So, we comb through each line of code from wp-config.php, skipping what we don't like, and then we explicitly eval() the result. Afterwards, we're free to require() our own version of wp-settings.php etc. --- php/class-wp-cli.php | 2 +- php/utils.php | 29 +++++++++++++++++++++-------- php/wp-cli.php | 6 +++++- php/wp-settings.php | 4 ---- 4 files changed, 27 insertions(+), 14 deletions(-) delete mode 100644 php/wp-settings.php diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 232f6dc4b3..1e5e023e52 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -340,7 +340,7 @@ static function before_wp_load() { } if ( self::cmd_starts_with( array( 'db' ) ) ) { - Utils\load_wp_config(); + eval( Utils\get_wp_config_code() ); self::run_command(); exit; } diff --git a/php/utils.php b/php/utils.php index 0ade39ee7c..70079b0cfa 100644 --- a/php/utils.php +++ b/php/utils.php @@ -196,14 +196,27 @@ function locate_wp_config() { return false; } -// Loads wp-config.php without loading the rest of WP -function load_wp_config() { - define( 'ABSPATH', dirname(__FILE__) . '/' ); - - if ( $wp_config_path = locate_wp_config() ) - require locate_wp_config(); - else - \WP_CLI::error( 'No wp-config.php file.' ); +/** + * Returns wp-config.php code, skipping the loading of wp-settings.php + * + * @return string + */ +function get_wp_config_code() { + $wp_config_code = file_get_contents( locate_wp_config() ); + + $lines_to_run = array(); + + foreach ( explode( "\n", $wp_config_code ) as $line ) { + if ( 0 === strpos( $line, '<?php' ) ) + continue; + + if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) + continue; + + $lines_to_run[] = $line; + } + + return implode( "\n", $lines_to_run ); } /** diff --git a/php/wp-cli.php b/php/wp-cli.php index a248bdb28a..0528fc67e4 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -18,7 +18,11 @@ WP_CLI::before_wp_load(); // Load WordPress, in the global scope -require WP_ROOT . 'wp-load.php'; +define( 'ABSPATH', WP_ROOT ); + +eval( \WP_CLI\Utils\get_wp_config_code() ); + +require ABSPATH . 'wp-settings.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); diff --git a/php/wp-settings.php b/php/wp-settings.php deleted file mode 100644 index 648622d87c..0000000000 --- a/php/wp-settings.php +++ /dev/null @@ -1,4 +0,0 @@ -<?php - -// This is a dummy file necessary for loading wp-config.php without going through wp-load.php - From ec6eaa1467612381c70b76b60abb228866f2b735 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 12:18:35 +0200 Subject: [PATCH 1044/4858] copy wp-settings.php from WP 3.5 --- php/wp-cli.php | 2 +- php/wp-settings-cli.php | 327 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 php/wp-settings-cli.php diff --git a/php/wp-cli.php b/php/wp-cli.php index 0528fc67e4..57df1df426 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -22,7 +22,7 @@ eval( \WP_CLI\Utils\get_wp_config_code() ); -require ABSPATH . 'wp-settings.php'; +require WP_CLI_ROOT . 'wp-settings-cli.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php new file mode 100644 index 0000000000..65485a8410 --- /dev/null +++ b/php/wp-settings-cli.php @@ -0,0 +1,327 @@ +<?php +/** + * Used to set up and fix common variables and include + * the WordPress procedural and class library. + * + * Allows for some configuration in wp-config.php (see default-constants.php) + * + * @internal This file must be parsable by PHP4. + * + * @package WordPress + */ + +/** + * Stores the location of the WordPress directory of functions, classes, and core content. + * + * @since 1.0.0 + */ +define( 'WPINC', 'wp-includes' ); + +// Include files required for initialization. +require( ABSPATH . WPINC . '/load.php' ); +require( ABSPATH . WPINC . '/default-constants.php' ); +require( ABSPATH . WPINC . '/version.php' ); + +// Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, WP_CONTENT_DIR and WP_CACHE. +wp_initial_constants( ); + +// Check for the required PHP version and for the MySQL extension or a database drop-in. +wp_check_php_mysql_versions(); + +// Disable magic quotes at runtime. Magic quotes are added using wpdb later in wp-settings.php. +@ini_set( 'magic_quotes_runtime', 0 ); +@ini_set( 'magic_quotes_sybase', 0 ); + +// WordPress calculates offsets from UTC. +date_default_timezone_set( 'UTC' ); + +// Turn register_globals off. +wp_unregister_GLOBALS(); + +// Standardize $_SERVER variables across setups. +wp_fix_server_vars(); + +// Check if we have received a request due to missing favicon.ico +wp_favicon_request(); + +// Check if we're in maintenance mode. +wp_maintenance(); + +// Start loading timer. +timer_start(); + +// Check if we're in WP_DEBUG mode. +wp_debug_mode(); + +// For an advanced caching plugin to use. Uses a static drop-in because you would only want one. +if ( WP_CACHE ) + WP_DEBUG ? include( WP_CONTENT_DIR . '/advanced-cache.php' ) : @include( WP_CONTENT_DIR . '/advanced-cache.php' ); + +// Define WP_LANG_DIR if not set. +wp_set_lang_dir(); + +// Load early WordPress files. +require( ABSPATH . WPINC . '/compat.php' ); +require( ABSPATH . WPINC . '/functions.php' ); +require( ABSPATH . WPINC . '/class-wp.php' ); +require( ABSPATH . WPINC . '/class-wp-error.php' ); +require( ABSPATH . WPINC . '/plugin.php' ); +require( ABSPATH . WPINC . '/pomo/mo.php' ); + +// Include the wpdb class and, if present, a db.php database drop-in. +require_wp_db(); + +// Set the database table prefix and the format specifiers for database table columns. +$GLOBALS['table_prefix'] = $table_prefix; +wp_set_wpdb_vars(); + +// Start the WordPress object cache, or an external object cache if the drop-in is present. +wp_start_object_cache(); + +// Attach the default filters. +require( ABSPATH . WPINC . '/default-filters.php' ); + +// Initialize multisite if enabled. +if ( is_multisite() ) { + require( ABSPATH . WPINC . '/ms-blogs.php' ); + require( ABSPATH . WPINC . '/ms-settings.php' ); +} elseif ( ! defined( 'MULTISITE' ) ) { + define( 'MULTISITE', false ); +} + +register_shutdown_function( 'shutdown_action_hook' ); + +// Stop most of WordPress from being loaded if we just want the basics. +if ( SHORTINIT ) + return false; + +// Load the L10n library. +require_once( ABSPATH . WPINC . '/l10n.php' ); + +// Run the installer if WordPress is not installed. +wp_not_installed(); + +// Load most of WordPress. +require( ABSPATH . WPINC . '/class-wp-walker.php' ); +require( ABSPATH . WPINC . '/class-wp-ajax-response.php' ); +require( ABSPATH . WPINC . '/formatting.php' ); +require( ABSPATH . WPINC . '/capabilities.php' ); +require( ABSPATH . WPINC . '/query.php' ); +require( ABSPATH . WPINC . '/theme.php' ); +require( ABSPATH . WPINC . '/class-wp-theme.php' ); +require( ABSPATH . WPINC . '/template.php' ); +require( ABSPATH . WPINC . '/user.php' ); +require( ABSPATH . WPINC . '/meta.php' ); +require( ABSPATH . WPINC . '/general-template.php' ); +require( ABSPATH . WPINC . '/link-template.php' ); +require( ABSPATH . WPINC . '/author-template.php' ); +require( ABSPATH . WPINC . '/post.php' ); +require( ABSPATH . WPINC . '/post-template.php' ); +require( ABSPATH . WPINC . '/post-thumbnail-template.php' ); +require( ABSPATH . WPINC . '/category.php' ); +require( ABSPATH . WPINC . '/category-template.php' ); +require( ABSPATH . WPINC . '/comment.php' ); +require( ABSPATH . WPINC . '/comment-template.php' ); +require( ABSPATH . WPINC . '/rewrite.php' ); +require( ABSPATH . WPINC . '/feed.php' ); +require( ABSPATH . WPINC . '/bookmark.php' ); +require( ABSPATH . WPINC . '/bookmark-template.php' ); +require( ABSPATH . WPINC . '/kses.php' ); +require( ABSPATH . WPINC . '/cron.php' ); +require( ABSPATH . WPINC . '/deprecated.php' ); +require( ABSPATH . WPINC . '/script-loader.php' ); +require( ABSPATH . WPINC . '/taxonomy.php' ); +require( ABSPATH . WPINC . '/update.php' ); +require( ABSPATH . WPINC . '/canonical.php' ); +require( ABSPATH . WPINC . '/shortcodes.php' ); +require( ABSPATH . WPINC . '/class-wp-embed.php' ); +require( ABSPATH . WPINC . '/media.php' ); +require( ABSPATH . WPINC . '/http.php' ); +require( ABSPATH . WPINC . '/class-http.php' ); +require( ABSPATH . WPINC . '/widgets.php' ); +require( ABSPATH . WPINC . '/nav-menu.php' ); +require( ABSPATH . WPINC . '/nav-menu-template.php' ); +require( ABSPATH . WPINC . '/admin-bar.php' ); + +// Load multisite-specific files. +if ( is_multisite() ) { + require( ABSPATH . WPINC . '/ms-functions.php' ); + require( ABSPATH . WPINC . '/ms-default-filters.php' ); + require( ABSPATH . WPINC . '/ms-deprecated.php' ); +} + +// Define constants that rely on the API to obtain the default value. +// Define must-use plugin directory constants, which may be overridden in the sunrise.php drop-in. +wp_plugin_directory_constants( ); + +// Load must-use plugins. +foreach ( wp_get_mu_plugins() as $mu_plugin ) { + include_once( $mu_plugin ); +} +unset( $mu_plugin ); + +// Load network activated plugins. +if ( is_multisite() ) { + foreach( wp_get_active_network_plugins() as $network_plugin ) { + include_once( $network_plugin ); + } + unset( $network_plugin ); +} + +do_action( 'muplugins_loaded' ); + +if ( is_multisite() ) + ms_cookie_constants( ); + +// Define constants after multisite is loaded. Cookie-related constants may be overridden in ms_network_cookies(). +wp_cookie_constants( ); + +// Define and enforce our SSL constants +wp_ssl_constants( ); + +// Create common globals. +require( ABSPATH . WPINC . '/vars.php' ); + +// Make taxonomies and posts available to plugins and themes. +// @plugin authors: warning: these get registered again on the init hook. +create_initial_taxonomies(); +create_initial_post_types(); + +// Register the default theme directory root +register_theme_directory( get_theme_root() ); + +// Load active plugins. +foreach ( wp_get_active_and_valid_plugins() as $plugin ) + include_once( $plugin ); +unset( $plugin ); + +// Load pluggable functions. +require( ABSPATH . WPINC . '/pluggable.php' ); +require( ABSPATH . WPINC . '/pluggable-deprecated.php' ); + +// Set internal encoding. +wp_set_internal_encoding(); + +// Run wp_cache_postload() if object cache is enabled and the function exists. +if ( WP_CACHE && function_exists( 'wp_cache_postload' ) ) + wp_cache_postload(); + +do_action( 'plugins_loaded' ); + +// Define constants which affect functionality if not already defined. +wp_functionality_constants( ); + +// Add magic quotes and set up $_REQUEST ( $_GET + $_POST ) +wp_magic_quotes(); + +do_action( 'sanitize_comment_cookies' ); + +/** + * WordPress Query object + * @global object $wp_the_query + * @since 2.0.0 + */ +$wp_the_query = new WP_Query(); + +/** + * Holds the reference to @see $wp_the_query + * Use this global for WordPress queries + * @global object $wp_query + * @since 1.5.0 + */ +$wp_query = $wp_the_query; + +/** + * Holds the WordPress Rewrite object for creating pretty URLs + * @global object $wp_rewrite + * @since 1.5.0 + */ +$GLOBALS['wp_rewrite'] = new WP_Rewrite(); + +/** + * WordPress Object + * @global object $wp + * @since 2.0.0 + */ +$wp = new WP(); + +/** + * WordPress Widget Factory Object + * @global object $wp_widget_factory + * @since 2.8.0 + */ +$GLOBALS['wp_widget_factory'] = new WP_Widget_Factory(); + +/** + * WordPress User Roles + * @global object $wp_roles + * @since 2.0.0 + */ +$GLOBALS['wp_roles'] = new WP_Roles(); + +do_action( 'setup_theme' ); + +// Define the template related constants. +wp_templating_constants( ); + +// Load the default text localization domain. +load_default_textdomain(); + +$locale = get_locale(); +$locale_file = WP_LANG_DIR . "/$locale.php"; +if ( ( 0 === validate_file( $locale ) ) && is_readable( $locale_file ) ) + require( $locale_file ); +unset( $locale_file ); + +// Pull in locale data after loading text domain. +require_once( ABSPATH . WPINC . '/locale.php' ); + +/** + * WordPress Locale object for loading locale domain date and various strings. + * @global object $wp_locale + * @since 2.1.0 + */ +$GLOBALS['wp_locale'] = new WP_Locale(); + +// Load the functions for the active theme, for both parent and child theme if applicable. +if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) { + if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) + include( STYLESHEETPATH . '/functions.php' ); + if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) + include( TEMPLATEPATH . '/functions.php' ); +} + +do_action( 'after_setup_theme' ); + +// Set up current user. +$wp->init(); + +/** + * Most of WP is loaded at this stage, and the user is authenticated. WP continues + * to load on the init hook that follows (e.g. widgets), and many plugins instantiate + * themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.). + * + * If you wish to plug an action once WP is loaded, use the wp_loaded hook below. + */ +do_action( 'init' ); + +// Check site status +if ( is_multisite() ) { + if ( true !== ( $file = ms_site_check() ) ) { + require( $file ); + die(); + } + unset($file); +} + +/** + * This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated. + * + * AJAX requests should use wp-admin/admin-ajax.php. admin-ajax.php can handle requests for + * users not logged in. + * + * @link http://codex.wordpress.org/AJAX_in_Plugins + * + * @since 3.0.0 + */ +do_action('wp_loaded'); From cb89a50a33306e5173b320e8f0f34491ea0138c3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 12:20:46 +0200 Subject: [PATCH 1045/4858] change header for wp-settings-cli.php --- php/wp-settings-cli.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 65485a8410..11ef5bb326 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -1,13 +1,6 @@ <?php /** - * Used to set up and fix common variables and include - * the WordPress procedural and class library. - * - * Allows for some configuration in wp-config.php (see default-constants.php) - * - * @internal This file must be parsable by PHP4. - * - * @package WordPress + * A modified version of wp-settings.php, tailored for CLI use. */ /** @@ -23,7 +16,7 @@ require( ABSPATH . WPINC . '/version.php' ); // Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, WP_CONTENT_DIR and WP_CACHE. -wp_initial_constants( ); +wp_initial_constants(); // Check for the required PHP version and for the MySQL extension or a database drop-in. wp_check_php_mysql_versions(); From 2d5ccb249f10d6da642a248d790accb64cae46ea Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 12:34:41 +0200 Subject: [PATCH 1046/4858] remove irrelevant checks: wp_favicon_request() and wp_maintenance() --- php/wp-settings-cli.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 11ef5bb326..aa051802c8 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -34,12 +34,6 @@ // Standardize $_SERVER variables across setups. wp_fix_server_vars(); -// Check if we have received a request due to missing favicon.ico -wp_favicon_request(); - -// Check if we're in maintenance mode. -wp_maintenance(); - // Start loading timer. timer_start(); From 8f3b6601377f4e7230a1275833ada39bfa182c50 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 12:41:25 +0200 Subject: [PATCH 1047/4858] never load advanced-cache.php. see #164 --- php/class-wp-cli.php | 2 +- php/wp-settings-cli.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1e5e023e52..b6b5e2d2df 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -356,7 +356,7 @@ static function before_wp_load() { } } - // Pretend we're in WP_ADMIN, to side-step full-page caching plugins + // Pretend we're in WP_ADMIN define( 'WP_ADMIN', true ); $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; } diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index aa051802c8..aa079547e9 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -40,10 +40,6 @@ // Check if we're in WP_DEBUG mode. wp_debug_mode(); -// For an advanced caching plugin to use. Uses a static drop-in because you would only want one. -if ( WP_CACHE ) - WP_DEBUG ? include( WP_CONTENT_DIR . '/advanced-cache.php' ) : @include( WP_CONTENT_DIR . '/advanced-cache.php' ); - // Define WP_LANG_DIR if not set. wp_set_lang_dir(); From 29cd328ca7b9be7f716e573f2525c4f53060c84a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 13:06:02 +0200 Subject: [PATCH 1048/4858] use our own version of wp_not_installed(). see #93 --- php/class-wp-cli.php | 2 -- php/utils-wp.php | 8 ++++++++ php/wp-settings-cli.php | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index b6b5e2d2df..0c17283ac3 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -366,8 +366,6 @@ private static function cmd_starts_with( $prefix ) { } static function after_wp_load() { - require WP_CLI_ROOT . 'utils-wp.php'; - add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); Utils\set_user( self::$config ); diff --git a/php/utils-wp.php b/php/utils-wp.php index 3eafb3035d..0dd4bf62a0 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -4,6 +4,14 @@ namespace WP_CLI\Utils; +function wp_not_installed() { + if ( !is_blog_installed() && !defined( 'WP_INSTALLING' ) ) { + \WP_CLI::error( 'The site you have requested is not installed.', false ); + \WP_CLI::line( 'Run `wp core install`.' ); + exit( 1 ); + } +} + // Handle --user parameter function set_user( $assoc_args ) { if ( !isset( $assoc_args['user'] ) ) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index aa079547e9..a001e293cb 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -78,11 +78,14 @@ if ( SHORTINIT ) return false; +// Load WP-CLI utilities +require WP_CLI_ROOT . 'utils-wp.php'; + // Load the L10n library. require_once( ABSPATH . WPINC . '/l10n.php' ); // Run the installer if WordPress is not installed. -wp_not_installed(); +\WP_CLI\Utils\wp_not_installed(); // Load most of WordPress. require( ABSPATH . WPINC . '/class-wp-walker.php' ); From ec9198202d0f5dc6700ee3e8339f1a2b9fe4595d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 13:13:50 +0200 Subject: [PATCH 1049/4858] make wp-settings-cli.php compatible with WP 3.4 --- php/utils.php | 5 +++++ php/wp-settings-cli.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 70079b0cfa..4ebaec2888 100644 --- a/php/utils.php +++ b/php/utils.php @@ -219,6 +219,11 @@ function get_wp_config_code() { return implode( "\n", $lines_to_run ); } +function maybe_require( $path ) { + if ( file_exists( $path ) ) + require $path; +} + /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index a001e293cb..4e8fe3e3a7 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -120,7 +120,7 @@ require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); -require( ABSPATH . WPINC . '/class-wp-embed.php' ); +\WP_CLI\Utils\maybe_require( ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); require( ABSPATH . WPINC . '/class-http.php' ); From 74215cb623b76ff76328266d01cbeca6d80d0576 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 13:14:48 +0200 Subject: [PATCH 1050/4858] add use \WP_CLI\Utils to wp-settings-cli.php --- php/wp-settings-cli.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 4e8fe3e3a7..3b074bab01 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -3,6 +3,8 @@ * A modified version of wp-settings.php, tailored for CLI use. */ +use \WP_CLI\Utils; + /** * Stores the location of the WordPress directory of functions, classes, and core content. * @@ -85,7 +87,7 @@ require_once( ABSPATH . WPINC . '/l10n.php' ); // Run the installer if WordPress is not installed. -\WP_CLI\Utils\wp_not_installed(); +Utils\wp_not_installed(); // Load most of WordPress. require( ABSPATH . WPINC . '/class-wp-walker.php' ); @@ -120,7 +122,7 @@ require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); -\WP_CLI\Utils\maybe_require( ABSPATH . WPINC . '/class-wp-embed.php' ); +Utils\maybe_require( ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); require( ABSPATH . WPINC . '/class-http.php' ); From fa92f5f8a29db3de3a81af433825fa40e841708b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 13:22:27 +0200 Subject: [PATCH 1051/4858] make wp-settings-cli.php compatible with WP 3.3 --- php/wp-settings-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 3b074bab01..2dc0f07111 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -96,8 +96,8 @@ require( ABSPATH . WPINC . '/capabilities.php' ); require( ABSPATH . WPINC . '/query.php' ); require( ABSPATH . WPINC . '/theme.php' ); -require( ABSPATH . WPINC . '/class-wp-theme.php' ); -require( ABSPATH . WPINC . '/template.php' ); +Utils\maybe_require( ABSPATH . WPINC . '/class-wp-theme.php' ); +Utils\maybe_require( ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); require( ABSPATH . WPINC . '/meta.php' ); require( ABSPATH . WPINC . '/general-template.php' ); From 6ba6689a548f0f411143ccde0a59713fc5b72021 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 13:25:33 +0200 Subject: [PATCH 1052/4858] pass WP version to maybe_require() --- php/utils-wp.php | 7 +++++++ php/utils.php | 5 ----- php/wp-settings-cli.php | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index 0dd4bf62a0..01777c211a 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -12,6 +12,13 @@ function wp_not_installed() { } } +function maybe_require( $since, $path ) { + global $wp_version; + + if ( version_compare( $wp_version, $since, '>=' ) ) + require $path; +} + // Handle --user parameter function set_user( $assoc_args ) { if ( !isset( $assoc_args['user'] ) ) diff --git a/php/utils.php b/php/utils.php index 4ebaec2888..70079b0cfa 100644 --- a/php/utils.php +++ b/php/utils.php @@ -219,11 +219,6 @@ function get_wp_config_code() { return implode( "\n", $lines_to_run ); } -function maybe_require( $path ) { - if ( file_exists( $path ) ) - require $path; -} - /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 2dc0f07111..30769553df 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -96,8 +96,8 @@ require( ABSPATH . WPINC . '/capabilities.php' ); require( ABSPATH . WPINC . '/query.php' ); require( ABSPATH . WPINC . '/theme.php' ); -Utils\maybe_require( ABSPATH . WPINC . '/class-wp-theme.php' ); -Utils\maybe_require( ABSPATH . WPINC . '/template.php' ); +Utils\maybe_require( '3.4', ABSPATH . WPINC . '/class-wp-theme.php' ); +Utils\maybe_require( '3.4', ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); require( ABSPATH . WPINC . '/meta.php' ); require( ABSPATH . WPINC . '/general-template.php' ); @@ -122,7 +122,7 @@ require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); -Utils\maybe_require( ABSPATH . WPINC . '/class-wp-embed.php' ); +Utils\maybe_require( '3.5', ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); require( ABSPATH . WPINC . '/class-http.php' ); From 136d4911b1ebae5047499cdee6880c6eb60281af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 14:20:58 +0200 Subject: [PATCH 1053/4858] tests: pass wp-cli command as a parameter --- tests/abstract-spec.php | 29 +++++++++++++++++++---------- tests/spec-core.php | 18 +++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 8b83235699..11effab3c2 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -53,20 +53,29 @@ public function runGiven( &$world, $action, $arguments ) { public function runWhen( &$world, $action, $arguments ) { switch ( $action ) { - case 'invoking core install': { - $world['result'] = $world['runner']->run_install(); - } - break; - - case 'invoking core config': { - $world['result'] = $world['runner']->create_config( self::$db_settings ); + case 'invoking': { + $cmd = $arguments[0]; + + switch ( $cmd ) { + case 'core install': { + $world['result'] = $world['runner']->run_install(); + } + break; + + case 'core config': { + $world['result'] = $world['runner']->create_config( self::$db_settings ); + } + break; + + default: { + $world['result'] = $world['runner']->run( $cmd ); + } + } } break; default: { - $cmd = str_replace( 'invoking ', '', $action ); - - $world['result'] = $world['runner']->run( $cmd ); + return $this->notImplemented( $action ); } } } diff --git a/tests/spec-core.php b/tests/spec-core.php index dbbcfbf681..4221919d90 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -7,7 +7,7 @@ public function emptyDir() { $this ->given( 'empty dir' ) - ->when( 'invoking core is-installed' ) + ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 1 ); } @@ -17,16 +17,16 @@ public function noWpConfig() { ->given( 'empty dir' ) ->and( 'wp files' ) - ->when( 'invoking core is-installed' ) + ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 1 ) - ->when( 'invoking core install' ) + ->when( 'invoking', 'core install' ) ->then( 'output should be', "Error: wp-config.php not found.\n" . "Either create one manually or use `wp core config`.\n" ) - ->when( 'invoking core config' ) + ->when( 'invoking', 'core config' ) ->then( 'return code should be', 0 ); } @@ -37,16 +37,16 @@ public function dbTablesNotInstalled() { ->and( 'wp files' ) ->and( 'wp config' ) - ->when( 'invoking core is-installed' ) + ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 1 ) - ->when( 'invoking help' ) + ->when( 'invoking', 'help' ) ->then( 'should have output' ) - ->when( 'invoking core install' ) + ->when( 'invoking', 'core install' ) ->then( 'return code should be', 0 ) - ->when( 'invoking post list --ids' ) + ->when( 'invoking', 'post list --ids' ) ->then( 'output should be', 1 ); } @@ -56,7 +56,7 @@ public function fullInstall() { ->given( 'empty dir' ) ->and( 'wp install' ) - ->when( 'invoking core is-installed' ) + ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 0 ); } } From 398af1ceea87bf96396e9825792c0c30ff0cf2cd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 14:57:36 +0200 Subject: [PATCH 1054/4858] add test case for custom WP_CONTENT dirs --- tests/abstract-spec.php | 5 +++++ tests/command-runner.php | 31 +++++++++++++++++++++++++++++++ tests/spec-core.php | 14 ++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 11effab3c2..e49239ddbb 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -45,6 +45,11 @@ public function runGiven( &$world, $action, $arguments ) { } break; + case 'custom wp-content dir': { + $world['runner']->define_custom_wp_content_dir(); + } + break; + default: { return $this->notImplemented( $action ); } diff --git a/tests/command-runner.php b/tests/command-runner.php index d232c91118..26133fd912 100644 --- a/tests/command-runner.php +++ b/tests/command-runner.php @@ -28,6 +28,37 @@ public function create_config( $db_settings ) { return $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); } + public function define_custom_wp_content_dir() { + $wp_config_path = $this->install_dir . '/wp-config.php'; + + $wp_config_code = file_get_contents( $wp_config_path ); + + $this->add_line_to_wp_config( $wp_config_code, + "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); + + $this->move_files( 'wp-content', 'my-content' ); + + $this->add_line_to_wp_config( $wp_config_code, + "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); + + $this->move_files( 'my-content/plugins', 'my-plugins' ); + + file_put_contents( $wp_config_path, $wp_config_code ); + } + + private function move_files( $src, $dest ) { + rename( + $this->install_dir . '/' . $src, + $this->install_dir . '/' . $dest + ); + } + + private function add_line_to_wp_config( &$wp_config_code, $line ) { + $token = "/* That's all, stop editing!"; + + $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); + } + public function run_install() { $cmd = 'core install' . \WP_CLI\Utils\compose_assoc_args( array( 'url' => 'http://example.com', diff --git a/tests/spec-core.php b/tests/spec-core.php index 4221919d90..adb4c574dc 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -59,5 +59,19 @@ public function fullInstall() { ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 0 ); } + + /** @scenario */ + public function customWpContentDir() { + $this + ->given( 'empty dir' ) + ->and( 'wp install' ) + ->and( 'custom wp-content dir' ) + + ->when( 'invoking', 'theme status twentytwelve' ) + ->then( 'return code should be', 0 ) + + ->when( 'invoking', 'plugin status hello' ) + ->then( 'return code should be', 0 ); + } } From d167367ccaf8b4f3ec7406d907d3d83cfa02522c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 30 Dec 2012 15:06:25 +0200 Subject: [PATCH 1055/4858] replace __FILE__ and __DIR__ before calling eval() --- php/utils.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 70079b0cfa..6e43689547 100644 --- a/php/utils.php +++ b/php/utils.php @@ -202,18 +202,28 @@ function locate_wp_config() { * @return string */ function get_wp_config_code() { - $wp_config_code = file_get_contents( locate_wp_config() ); + $wp_config_path = locate_wp_config(); + + $replacements = array( + '__FILE__' => "'$wp_config_path'", + '__DIR__' => "'" . dirname( $wp_config_path ) . "'" + ); + + $old = array_keys( $replacements ); + $new = array_values( $replacements ); + + $wp_config_code = explode( "\n", file_get_contents( $wp_config_path ) ); $lines_to_run = array(); - foreach ( explode( "\n", $wp_config_code ) as $line ) { + foreach ( $wp_config_code as $line ) { if ( 0 === strpos( $line, '<?php' ) ) continue; if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) continue; - $lines_to_run[] = $line; + $lines_to_run[] = str_replace( $old, $new, $line ); } return implode( "\n", $lines_to_run ); From 0a8c543e3468cf22e0b772526bd3ef9da8a5937d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 14:40:41 +0200 Subject: [PATCH 1056/4858] move dispatching logic to a standalone utility function --- php/class-wp-cli.php | 18 +----------------- php/utils.php | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0c17283ac3..34848dbc1b 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -403,23 +403,7 @@ static function after_wp_load() { } private static function run_command() { - $command = \WP_CLI::$root; - - $args = self::$arguments; - - while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { - $subcommand = $command->pre_invoke( $args ); - if ( !$subcommand ) - break; - - $command = $subcommand; - } - - if ( $command instanceof Dispatcher\CommandContainer ) { - $command->show_usage(); - } else { - $command->invoke( $args, self::$assoc_args ); - } + Utils\run_command( self::$arguments, self::$assoc_args ); } private static function show_info() { diff --git a/php/utils.php b/php/utils.php index 6e43689547..bf0b6d0502 100644 --- a/php/utils.php +++ b/php/utils.php @@ -4,6 +4,8 @@ namespace WP_CLI\Utils; +use \WP_CLI\Dispatcher; + function bootstrap() { $vendor_paths = array( WP_CLI_ROOT . '../../../../vendor', // part of a larger project @@ -118,6 +120,30 @@ function compose_assoc_args( $assoc_args ) { return $str; } +/** + * Run a given command. + * + * @param array + * @param array + */ +function run_command( $args, $assoc_args ) { + $command = \WP_CLI::$root; + + while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { + $subcommand = $command->pre_invoke( $args ); + if ( !$subcommand ) + break; + + $command = $subcommand; + } + + if ( $command instanceof Dispatcher\CommandContainer ) { + $command->show_usage(); + } else { + $command->invoke( $args, $assoc_args ); + } +} + function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $blog = $assoc_args['url']; From d71537e0bcc91042787d84a80b5315424b2985fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 14:46:17 +0200 Subject: [PATCH 1057/4858] compose_args() -> args_to_str() --- php/utils.php | 4 ++-- tests/command-runner.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/utils.php b/php/utils.php index bf0b6d0502..799dca696f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -97,7 +97,7 @@ function parse_args( $arguments ) { * @param array * @return string */ -function compose_args( $args ) { +function args_to_str( $args ) { return ' ' . implode( ' ', array_map( 'escapeshellarg', $args ) ); } @@ -107,7 +107,7 @@ function compose_args( $args ) { * @param array * @return string */ -function compose_assoc_args( $assoc_args ) { +function assoc_args_to_str( $assoc_args ) { $str = ''; foreach ( $assoc_args as $key => $value ) { diff --git a/tests/command-runner.php b/tests/command-runner.php index 26133fd912..a54cd7f197 100644 --- a/tests/command-runner.php +++ b/tests/command-runner.php @@ -25,7 +25,7 @@ public function run( $command, $cwd = false ) { } public function create_config( $db_settings ) { - return $this->run( 'core config' . \WP_CLI\Utils\compose_assoc_args( $db_settings ) ); + return $this->run( 'core config' . \WP_CLI\Utils\assoc_args_to_str( $db_settings ) ); } public function define_custom_wp_content_dir() { @@ -60,7 +60,7 @@ private function add_line_to_wp_config( &$wp_config_code, $line ) { } public function run_install() { - $cmd = 'core install' . \WP_CLI\Utils\compose_assoc_args( array( + $cmd = 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( 'url' => 'http://example.com', 'title' => 'WP CLI Tests', 'admin_email' => 'admin@example.com', From 6377865c83d8fedd0dcf66ae541425206cec38c5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 14:51:42 +0200 Subject: [PATCH 1058/4858] run_command(): make $assoc_args parameter optional --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 799dca696f..5e3d8f8a8c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -126,7 +126,7 @@ function assoc_args_to_str( $assoc_args ) { * @param array * @param array */ -function run_command( $args, $assoc_args ) { +function run_command( $args, $assoc_args = array() ) { $command = \WP_CLI::$root; while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { From e192796d3d5e00315457532709a5e57d0b93fdb9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 15:05:48 +0200 Subject: [PATCH 1059/4858] s/$blog/$url/ --- php/utils.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/php/utils.php b/php/utils.php index 5e3d8f8a8c..5a012498eb 100644 --- a/php/utils.php +++ b/php/utils.php @@ -146,14 +146,14 @@ function run_command( $args, $assoc_args = array() ) { function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { - $blog = $assoc_args['url']; + $url = $assoc_args['url']; } elseif ( isset( $assoc_args['blog'] ) ) { - $blog = $assoc_args['blog']; - if ( true === $blog ) { + $url = $assoc_args['blog']; + if ( true === $url ) { \WP_CLI::line( 'usage: wp --blog=example.com' ); } } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { - $blog = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); + $url = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); } elseif ( $wp_config_path = locate_wp_config() ) { // Try to find the blog parameter in the wp-config file $wp_config_file = file_get_contents( $wp_config_path ); @@ -168,13 +168,13 @@ function set_url( $assoc_args ) { } if ( !empty( $hit ) && isset( $hit['domain'] ) ) - $blog = $hit['domain']; + $url = $hit['domain']; if ( !empty( $hit ) && isset( $hit['path'] ) ) - $blog .= $hit['path']; + $url .= $hit['path']; } - if ( isset( $blog ) ) { - set_url_params( $blog ); + if ( isset( $url ) ) { + set_url_params( $url ); } } From 1f8a43c8796ee60c45cbb2264e5587f3ce8b3990 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 15:08:33 +0200 Subject: [PATCH 1060/4858] add deprecation warnings for --blog and wp-cli-blog. see #254 --- php/utils.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/utils.php b/php/utils.php index 5a012498eb..e23bdda90c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -148,11 +148,15 @@ function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $url = $assoc_args['url']; } elseif ( isset( $assoc_args['blog'] ) ) { + \WP_CLI::warning( 'The --blog parameter is deprecated. use --url instead' ); + $url = $assoc_args['blog']; if ( true === $url ) { \WP_CLI::line( 'usage: wp --blog=example.com' ); } } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { + \WP_CLI::warning( 'The wp-cli-blog file is deprecated. use wp-cli.yml instead' ); + $url = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); } elseif ( $wp_config_path = locate_wp_config() ) { // Try to find the blog parameter in the wp-config file From ea80ac02b1268b9962804ce6fa94a83a8fc9c57e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 15:10:01 +0200 Subject: [PATCH 1061/4858] fix punctuation for deprecation messages --- php/utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index e23bdda90c..c69406165b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -148,14 +148,14 @@ function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $url = $assoc_args['url']; } elseif ( isset( $assoc_args['blog'] ) ) { - \WP_CLI::warning( 'The --blog parameter is deprecated. use --url instead' ); + \WP_CLI::warning( 'The --blog parameter is deprecated. Use --url instead.' ); $url = $assoc_args['blog']; if ( true === $url ) { \WP_CLI::line( 'usage: wp --blog=example.com' ); } } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { - \WP_CLI::warning( 'The wp-cli-blog file is deprecated. use wp-cli.yml instead' ); + \WP_CLI::warning( 'The wp-cli-blog file is deprecated. Use wp-cli.yml instead.' ); $url = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); } elseif ( $wp_config_path = locate_wp_config() ) { From 2e6b1f83c62a1da309c150cac9e98e7e8e83d593 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:08:37 +0200 Subject: [PATCH 1062/4858] change alias from 'pt' to 'cpt', which is more familiar --- php/commands/scaffold.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ee11f0c8f8..7dac8f4025 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -10,7 +10,7 @@ * @maintainer LinePress (http://www.linespress.org) */ class Scaffold_Command extends WP_CLI_Command { - + function __construct() { WP_Filesystem(); } @@ -18,7 +18,7 @@ function __construct() { /** * @subcommand post-type * - * @alias pt + * @alias cpt * * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] */ @@ -28,7 +28,7 @@ function post_type( $args, $assoc_args ) { // Set the args to variables with normal names to keep our sanity $post_type = strtolower( $args[0] ); - // We use the machine name for function declarations + // We use the machine name for function declarations $machine_name = preg_replace( '/-/', '_', $post_type ); $machine_name_plural = $this->pluralize( $post_type ); @@ -39,7 +39,7 @@ function post_type( $args, $assoc_args ) { $label_plural = $this->pluralize( $label ); $label_plural_ucfirst = ucfirst( $label_plural ); } - + // set up defaults and merge theme with assoc_args $defaults = array( 'description' => "", @@ -70,7 +70,7 @@ function post_type( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - + if( ! $raw ) { include 'skeletons/post_type_skeleton.php'; $output = str_replace( "<?php", "", $output); @@ -109,7 +109,7 @@ function taxonomy( $args, $assoc_args ) { // Set the args to variables with normal names to keep our sanity $taxonomy = strtolower( $args[0] ); - // We use the machine name for function declarations + // We use the machine name for function declarations $machine_name = preg_replace( '/-/', '_', $taxonomy ); $machine_name_plural = $this->pluralize( $taxonomy ); @@ -137,7 +137,7 @@ function taxonomy( $args, $assoc_args ) { 'plugin_name' => false, 'raw' => false, ); - + // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); @@ -176,7 +176,7 @@ private function get_output_path( $assoc_args ) { // Implements the --theme flag || --plugin_name=<plugin_name> if( $theme ) { //Here we assume you got a theme installed - $path = TEMPLATEPATH; + $path = TEMPLATEPATH; } elseif ( ! empty( $plugin_name ) ){ $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line @@ -227,7 +227,7 @@ private function save_skeleton_output( $assoc_args ) { */ private function get_textdomain( $textdomain, $theme, $plugin_name ) { if( empty( $textdomain ) && $theme ) { - $textdomain = strtolower( wp_get_theme()->template ); + $textdomain = strtolower( wp_get_theme()->template ); } elseif ( empty( $textdomain ) && $plugin_name) { $textdomain = $plugin_name; } elseif ( empty( $textdomain ) || gettype($textdomain) == 'boolean' ) { //This mean just a flag @@ -291,4 +291,4 @@ private function pluralize( $word ) { } return false; } -} \ No newline at end of file +} From 74abf21f6071a36da9bfd9560e687f08add3ccac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:10:36 +0200 Subject: [PATCH 1063/4858] scaffold.php: tabs, not spaces --- php/commands/scaffold.php | 561 +++++++++++++++++++------------------- 1 file changed, 281 insertions(+), 280 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 7dac8f4025..26157b158f 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -11,284 +11,285 @@ */ class Scaffold_Command extends WP_CLI_Command { - function __construct() { - WP_Filesystem(); - } - - /** - * @subcommand post-type - * - * @alias cpt - * - * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] - */ - function post_type( $args, $assoc_args ) { - global $wp_filesystem; - - // Set the args to variables with normal names to keep our sanity - $post_type = strtolower( $args[0] ); - - // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $post_type ); - $machine_name_plural = $this->pluralize( $post_type ); - - // If no label is given use the slug and prettify it as good as possible - if( ! isset( $assoc_args['label'] ) ) { - $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); - $label_ucfirst = ucfirst( $label ); - $label_plural = $this->pluralize( $label ); - $label_plural_ucfirst = ucfirst( $label_plural ); - } - - // set up defaults and merge theme with assoc_args - $defaults = array( - 'description' => "", - 'public' => 'true', - 'exclude_from_search' => 'false', - 'show_ui' => 'true', - 'show_in_nav_menus' => 'true', - 'show_in_menu' => 'true', - 'show_in_admin_bar' => 'true', - 'menu_position' => 'null', - 'menu_icon' => 'null', - 'capability_type' => 'post', - 'hierarchical' => 'false', - 'supports' => "'title', 'editor'", - 'has_archive' => 'true', - 'slug' => $machine_name_plural, - 'feeds' => 'true', - 'pages' => 'true', - 'query_var' => 'true', - 'can_export' => 'true', - 'textdomain' => '', - 'theme' => false, - 'plugin_name' => false, - 'raw' => false, - ); - - // Generate the variables from the defaults and associated arguments if they are set - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - - if( ! $raw ) { - include 'skeletons/post_type_skeleton.php'; - $output = str_replace( "<?php", "", $output); - include 'skeletons/post_type_skeleton_extended.php'; - } else { - include 'skeletons/post_type_skeleton.php'; - } - - if ( $theme || ! empty( $plugin_name ) ) { - // Write file to theme or given plugin_name - $assoc_args = array( - 'type' => 'post_type', - 'output' => $output, - 'theme' => $theme, - 'plugin_name' => $plugin_name, - 'machine_name' => $machine_name, - ); - $assoc_args['path'] = $this->get_output_path( $assoc_args ); - $this->save_skeleton_output( $assoc_args ); - } else { - // STDOUT - echo $output; - } - } - - /** - * @subcommand taxonomy - * - * @alias tax - * - * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] [--raw] - */ - function taxonomy( $args, $assoc_args ) { - global $wp_filesystem; - - // Set the args to variables with normal names to keep our sanity - $taxonomy = strtolower( $args[0] ); - - // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $taxonomy ); - $machine_name_plural = $this->pluralize( $taxonomy ); - - // If no label is given use the slug and prettify it as good as possible - if( ! isset( $assoc_args['label'] ) ) { - $label = preg_replace( '/_|-/', ' ', strtolower( $taxonomy ) ); - $label_ucfirst = ucfirst( $label ); - $label_plural = $this->pluralize( $label ); - $label_plural_ucfirst = ucfirst( $label_plural ); - } - - // Set up defaults and merge theme with assoc_args - $defaults = array( - 'public' => 'true', - 'show_in_nav_menus' => 'true', - 'show_ui' => 'true', - 'show_tagcloud' => 'true', - 'hierarchical' => 'false', - 'rewrite' => 'true', - 'query_var' => 'true', - 'slug' => $taxonomy, - 'post_types' => 'post', - 'textdomain' => '', - 'theme' => false, - 'plugin_name' => false, - 'raw' => false, - ); - - // Generate the variables from the defaults and associated arguments if they are set - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - - if( ! $raw ) { - include 'skeletons/taxonomy_skeleton.php'; - $output = str_replace( "<?php", "", $output); - include 'skeletons/taxonomy_skeleton_extended.php'; - } else { - include 'skeletons/taxonomy_skeleton.php'; - } - - if ( $theme || ! empty( $plugin_name ) ) { - // Write file to theme or given plugin_name - $assoc_args = array( - 'type' => 'taxonomy', - 'output' => $output, - 'theme' => $theme, - 'plugin_name' => $plugin_name, - 'machine_name' => $machine_name, - ); - $assoc_args['path'] = $this->get_output_path( $assoc_args ); - $this->save_skeleton_output( $assoc_args ); - } else { - // STDOUT - echo $output; - } - } - - private function get_output_path( $assoc_args ) { - global $wp_filesystem; - - extract( $assoc_args, EXTR_SKIP ); - - // Implements the --theme flag || --plugin_name=<plugin_name> - if( $theme ) { - //Here we assume you got a theme installed - $path = TEMPLATEPATH; - } elseif ( ! empty( $plugin_name ) ){ - $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line - $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line - } else { - // STDOUT - return false; - } - - if ( $type === "post_type") { - $path .= '/post-types/'; - } elseif ( $type === "taxonomy" ) { - $path .= '/taxonomies/'; - } - - // If it doesn't exists create it - if( ! $wp_filesystem->is_dir( $path ) ) { - $wp_filesystem->mkdir( $path ); - WP_CLI::success( "Created dir: {$path}" ); - } elseif( $wp_filesystem->is_dir( $path ) ) { - WP_CLI::success( "Dir already exists: {$path}" ); - } else { - WP_CLI::error( "Couldn't create dir exists: {$path}" ); - } - - return $path; - } - - private function save_skeleton_output( $assoc_args ) { - global $wp_filesystem; - - extract( $assoc_args, EXTR_SKIP ); - - // Write to file - if( $path ) { - $filename = $path . $machine_name .'.php'; - - if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { - WP_CLI::error( "Error while saving file: {$filename}" ); - } else { - WP_CLI::success( "{$type} {$machine_name} created" ); - } - } - } - - /** - * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. - * Same goes for when plugin_name is being used. - */ - private function get_textdomain( $textdomain, $theme, $plugin_name ) { - if( empty( $textdomain ) && $theme ) { - $textdomain = strtolower( wp_get_theme()->template ); - } elseif ( empty( $textdomain ) && $plugin_name) { - $textdomain = $plugin_name; - } elseif ( empty( $textdomain ) || gettype($textdomain) == 'boolean' ) { //This mean just a flag - $textdomain = 'YOUR-TEXTDOMAIN'; - } - - return $textdomain; - } - - private function pluralize( $word ) { - $plural = array( - '/(quiz)$/i' => '\1zes', - '/^(ox)$/i' => '\1en', - '/([m|l])ouse$/i' => '\1ice', - '/(matr|vert|ind)ix|ex$/i' => '\1ices', - '/(x|ch|ss|sh)$/i' => '\1es', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive)$/i' => '\1s', - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(buffal|tomat)o$/i' => '\1oes', - '/(bu)s$/i' => '1ses', - '/(alias|status)/i' => '\1es', - '/(octop|vir)us$/i' => '1i', - '/(ax|test)is$/i' => '\1es', - '/s$/i' => 's', - '/$/' => 's' - ); - - $uncountable = array( 'equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep' ); - - $irregular = array( - 'person' => 'people', - 'man' => 'men', - 'woman' => 'women', - 'child' => 'children', - 'sex' => 'sexes', - 'move' => 'moves' - ); - - $lowercased_word = strtolower( $word ); - - foreach ( $uncountable as $_uncountable ){ - if( substr( $lowercased_word, ( -1 * strlen( $_uncountable) ) ) == $_uncountable ){ - return $word; - } - } - - foreach ( $irregular as $_plural=> $_singular ){ - if ( preg_match( '/('.$_plural.')$/i', $word, $arr ) ) { - return preg_replace( '/('.$_plural.')$/i', substr( $arr[0], 0, 1 ).substr( $_singular, 1 ), $word ); - } - } - - foreach ( $plural as $rule => $replacement ) { - if ( preg_match( $rule, $word ) ) { - return preg_replace( $rule, $replacement, $word ); - } - } - return false; - } + function __construct() { + WP_Filesystem(); + } + + /** + * @subcommand post-type + * + * @alias cpt + * + * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] + */ + function post_type( $args, $assoc_args ) { + global $wp_filesystem; + + // Set the args to variables with normal names to keep our sanity + $post_type = strtolower( $args[0] ); + + // We use the machine name for function declarations + $machine_name = preg_replace( '/-/', '_', $post_type ); + $machine_name_plural = $this->pluralize( $post_type ); + + // If no label is given use the slug and prettify it as good as possible + if( ! isset( $assoc_args['label'] ) ) { + $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); + $label_ucfirst = ucfirst( $label ); + $label_plural = $this->pluralize( $label ); + $label_plural_ucfirst = ucfirst( $label_plural ); + } + + // set up defaults and merge theme with assoc_args + $defaults = array( + 'description' => "", + 'public' => 'true', + 'exclude_from_search' => 'false', + 'show_ui' => 'true', + 'show_in_nav_menus' => 'true', + 'show_in_menu' => 'true', + 'show_in_admin_bar' => 'true', + 'menu_position' => 'null', + 'menu_icon' => 'null', + 'capability_type' => 'post', + 'hierarchical' => 'false', + 'supports' => "'title', 'editor'", + 'has_archive' => 'true', + 'slug' => $machine_name_plural, + 'feeds' => 'true', + 'pages' => 'true', + 'query_var' => 'true', + 'can_export' => 'true', + 'textdomain' => '', + 'theme' => false, + 'plugin_name' => false, + 'raw' => false, + ); + + // Generate the variables from the defaults and associated arguments if they are set + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); + + if( ! $raw ) { + include 'skeletons/post_type_skeleton.php'; + $output = str_replace( "<?php", "", $output); + include 'skeletons/post_type_skeleton_extended.php'; + } else { + include 'skeletons/post_type_skeleton.php'; + } + + if ( $theme || ! empty( $plugin_name ) ) { + // Write file to theme or given plugin_name + $assoc_args = array( + 'type' => 'post_type', + 'output' => $output, + 'theme' => $theme, + 'plugin_name' => $plugin_name, + 'machine_name' => $machine_name, + ); + $assoc_args['path'] = $this->get_output_path( $assoc_args ); + $this->save_skeleton_output( $assoc_args ); + } else { + // STDOUT + echo $output; + } + } + + /** + * @subcommand taxonomy + * + * @alias tax + * + * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] [--raw] + */ + function taxonomy( $args, $assoc_args ) { + global $wp_filesystem; + + // Set the args to variables with normal names to keep our sanity + $taxonomy = strtolower( $args[0] ); + + // We use the machine name for function declarations + $machine_name = preg_replace( '/-/', '_', $taxonomy ); + $machine_name_plural = $this->pluralize( $taxonomy ); + + // If no label is given use the slug and prettify it as good as possible + if( ! isset( $assoc_args['label'] ) ) { + $label = preg_replace( '/_|-/', ' ', strtolower( $taxonomy ) ); + $label_ucfirst = ucfirst( $label ); + $label_plural = $this->pluralize( $label ); + $label_plural_ucfirst = ucfirst( $label_plural ); + } + + // Set up defaults and merge theme with assoc_args + $defaults = array( + 'public' => 'true', + 'show_in_nav_menus' => 'true', + 'show_ui' => 'true', + 'show_tagcloud' => 'true', + 'hierarchical' => 'false', + 'rewrite' => 'true', + 'query_var' => 'true', + 'slug' => $taxonomy, + 'post_types' => 'post', + 'textdomain' => '', + 'theme' => false, + 'plugin_name' => false, + 'raw' => false, + ); + + // Generate the variables from the defaults and associated arguments if they are set + extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + + $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); + + if( ! $raw ) { + include 'skeletons/taxonomy_skeleton.php'; + $output = str_replace( "<?php", "", $output); + include 'skeletons/taxonomy_skeleton_extended.php'; + } else { + include 'skeletons/taxonomy_skeleton.php'; + } + + if ( $theme || ! empty( $plugin_name ) ) { + // Write file to theme or given plugin_name + $assoc_args = array( + 'type' => 'taxonomy', + 'output' => $output, + 'theme' => $theme, + 'plugin_name' => $plugin_name, + 'machine_name' => $machine_name, + ); + $assoc_args['path'] = $this->get_output_path( $assoc_args ); + $this->save_skeleton_output( $assoc_args ); + } else { + // STDOUT + echo $output; + } + } + + private function get_output_path( $assoc_args ) { + global $wp_filesystem; + + extract( $assoc_args, EXTR_SKIP ); + + // Implements the --theme flag || --plugin_name=<plugin_name> + if( $theme ) { + //Here we assume you got a theme installed + $path = TEMPLATEPATH; + } elseif ( ! empty( $plugin_name ) ){ + $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line + $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line + } else { + // STDOUT + return false; + } + + if ( $type === "post_type") { + $path .= '/post-types/'; + } elseif ( $type === "taxonomy" ) { + $path .= '/taxonomies/'; + } + + // If it doesn't exists create it + if( ! $wp_filesystem->is_dir( $path ) ) { + $wp_filesystem->mkdir( $path ); + WP_CLI::success( "Created dir: {$path}" ); + } elseif( $wp_filesystem->is_dir( $path ) ) { + WP_CLI::success( "Dir already exists: {$path}" ); + } else { + WP_CLI::error( "Couldn't create dir exists: {$path}" ); + } + + return $path; + } + + private function save_skeleton_output( $assoc_args ) { + global $wp_filesystem; + + extract( $assoc_args, EXTR_SKIP ); + + // Write to file + if( $path ) { + $filename = $path . $machine_name .'.php'; + + if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { + WP_CLI::error( "Error while saving file: {$filename}" ); + } else { + WP_CLI::success( "{$type} {$machine_name} created" ); + } + } + } + + /** + * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. + * Same goes for when plugin_name is being used. + */ + private function get_textdomain( $textdomain, $theme, $plugin_name ) { + if( empty( $textdomain ) && $theme ) { + $textdomain = strtolower( wp_get_theme()->template ); + } elseif ( empty( $textdomain ) && $plugin_name) { + $textdomain = $plugin_name; + } elseif ( empty( $textdomain ) || gettype($textdomain) == 'boolean' ) { //This mean just a flag + $textdomain = 'YOUR-TEXTDOMAIN'; + } + + return $textdomain; + } + + private function pluralize( $word ) { + $plural = array( + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)ix|ex$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(buffal|tomat)o$/i' => '\1oes', + '/(bu)s$/i' => '1ses', + '/(alias|status)/i' => '\1es', + '/(octop|vir)us$/i' => '1i', + '/(ax|test)is$/i' => '\1es', + '/s$/i' => 's', + '/$/' => 's' + ); + + $uncountable = array( 'equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep' ); + + $irregular = array( + 'person' => 'people', + 'man' => 'men', + 'woman' => 'women', + 'child' => 'children', + 'sex' => 'sexes', + 'move' => 'moves' + ); + + $lowercased_word = strtolower( $word ); + + foreach ( $uncountable as $_uncountable ){ + if( substr( $lowercased_word, ( -1 * strlen( $_uncountable) ) ) == $_uncountable ){ + return $word; + } + } + + foreach ( $irregular as $_plural=> $_singular ){ + if ( preg_match( '/('.$_plural.')$/i', $word, $arr ) ) { + return preg_replace( '/('.$_plural.')$/i', substr( $arr[0], 0, 1 ).substr( $_singular, 1 ), $word ); + } + } + + foreach ( $plural as $rule => $replacement ) { + if ( preg_match( $rule, $word ) ) { + return preg_replace( $rule, $replacement, $word ); + } + } + return false; + } } + From ac6a92bf3e02c265cb05cf658320c22309966b1d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:12:17 +0200 Subject: [PATCH 1064/4858] spacing fixes --- php/commands/scaffold.php | 41 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 26157b158f..078353cc52 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -16,6 +16,8 @@ function __construct() { } /** + * + * * @subcommand post-type * * @alias cpt @@ -33,7 +35,7 @@ function post_type( $args, $assoc_args ) { $machine_name_plural = $this->pluralize( $post_type ); // If no label is given use the slug and prettify it as good as possible - if( ! isset( $assoc_args['label'] ) ) { + if ( ! isset( $assoc_args['label'] ) ) { $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); $label_ucfirst = ucfirst( $label ); $label_plural = $this->pluralize( $label ); @@ -71,9 +73,9 @@ function post_type( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - if( ! $raw ) { + if ( ! $raw ) { include 'skeletons/post_type_skeleton.php'; - $output = str_replace( "<?php", "", $output); + $output = str_replace( "<?php", "", $output ); include 'skeletons/post_type_skeleton_extended.php'; } else { include 'skeletons/post_type_skeleton.php'; @@ -97,6 +99,8 @@ function post_type( $args, $assoc_args ) { } /** + * + * * @subcommand taxonomy * * @alias tax @@ -114,7 +118,7 @@ function taxonomy( $args, $assoc_args ) { $machine_name_plural = $this->pluralize( $taxonomy ); // If no label is given use the slug and prettify it as good as possible - if( ! isset( $assoc_args['label'] ) ) { + if ( ! isset( $assoc_args['label'] ) ) { $label = preg_replace( '/_|-/', ' ', strtolower( $taxonomy ) ); $label_ucfirst = ucfirst( $label ); $label_plural = $this->pluralize( $label ); @@ -143,9 +147,9 @@ function taxonomy( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); - if( ! $raw ) { + if ( ! $raw ) { include 'skeletons/taxonomy_skeleton.php'; - $output = str_replace( "<?php", "", $output); + $output = str_replace( "<?php", "", $output ); include 'skeletons/taxonomy_skeleton_extended.php'; } else { include 'skeletons/taxonomy_skeleton.php'; @@ -174,10 +178,10 @@ private function get_output_path( $assoc_args ) { extract( $assoc_args, EXTR_SKIP ); // Implements the --theme flag || --plugin_name=<plugin_name> - if( $theme ) { + if ( $theme ) { //Here we assume you got a theme installed $path = TEMPLATEPATH; - } elseif ( ! empty( $plugin_name ) ){ + } elseif ( ! empty( $plugin_name ) ) { $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line } else { @@ -185,17 +189,17 @@ private function get_output_path( $assoc_args ) { return false; } - if ( $type === "post_type") { + if ( $type === "post_type" ) { $path .= '/post-types/'; } elseif ( $type === "taxonomy" ) { $path .= '/taxonomies/'; } // If it doesn't exists create it - if( ! $wp_filesystem->is_dir( $path ) ) { + if ( ! $wp_filesystem->is_dir( $path ) ) { $wp_filesystem->mkdir( $path ); WP_CLI::success( "Created dir: {$path}" ); - } elseif( $wp_filesystem->is_dir( $path ) ) { + } elseif ( $wp_filesystem->is_dir( $path ) ) { WP_CLI::success( "Dir already exists: {$path}" ); } else { WP_CLI::error( "Couldn't create dir exists: {$path}" ); @@ -210,7 +214,7 @@ private function save_skeleton_output( $assoc_args ) { extract( $assoc_args, EXTR_SKIP ); // Write to file - if( $path ) { + if ( $path ) { $filename = $path . $machine_name .'.php'; if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { @@ -226,11 +230,11 @@ private function save_skeleton_output( $assoc_args ) { * Same goes for when plugin_name is being used. */ private function get_textdomain( $textdomain, $theme, $plugin_name ) { - if( empty( $textdomain ) && $theme ) { + if ( empty( $textdomain ) && $theme ) { $textdomain = strtolower( wp_get_theme()->template ); - } elseif ( empty( $textdomain ) && $plugin_name) { + } elseif ( empty( $textdomain ) && $plugin_name ) { $textdomain = $plugin_name; - } elseif ( empty( $textdomain ) || gettype($textdomain) == 'boolean' ) { //This mean just a flag + } elseif ( empty( $textdomain ) || gettype( $textdomain ) == 'boolean' ) { //This mean just a flag $textdomain = 'YOUR-TEXTDOMAIN'; } @@ -272,13 +276,13 @@ private function pluralize( $word ) { $lowercased_word = strtolower( $word ); - foreach ( $uncountable as $_uncountable ){ - if( substr( $lowercased_word, ( -1 * strlen( $_uncountable) ) ) == $_uncountable ){ + foreach ( $uncountable as $_uncountable ) { + if ( substr( $lowercased_word, ( -1 * strlen( $_uncountable ) ) ) == $_uncountable ) { return $word; } } - foreach ( $irregular as $_plural=> $_singular ){ + foreach ( $irregular as $_plural=> $_singular ) { if ( preg_match( '/('.$_plural.')$/i', $word, $arr ) ) { return preg_replace( '/('.$_plural.')$/i', substr( $arr[0], 0, 1 ).substr( $_singular, 1 ), $word ); } @@ -292,4 +296,3 @@ private function pluralize( $word ) { return false; } } - From 98cdec7d6e56a1f99131ef1944be61714c39200a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:14:00 +0200 Subject: [PATCH 1065/4858] add shortdesc and mention <slug> in synopsis --- php/commands/scaffold.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 078353cc52..d25896d625 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -16,13 +16,13 @@ function __construct() { } /** - * + * Generate PHP code for registering a custom post type. * * @subcommand post-type * * @alias cpt * - * @synopsis [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] + * @synopsis <slug> [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -99,13 +99,13 @@ function post_type( $args, $assoc_args ) { } /** - * + * Generate PHP code for registering a custom taxonomy. * * @subcommand taxonomy * * @alias tax * - * @synopsis [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] [--raw] + * @synopsis <slug> [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] [--raw] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; From 487f728009f19a94e42a2e03b593b23f41b72080 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:26:58 +0200 Subject: [PATCH 1066/4858] rename --plugin_name arg to --plugin --- php/commands/scaffold.php | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d25896d625..42f1790fae 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -22,7 +22,7 @@ function __construct() { * * @alias cpt * - * @synopsis <slug> [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin_name=<plugin_name>] [--raw] + * @synopsis <slug> [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function post_type( $args, $assoc_args ) { global $wp_filesystem; @@ -64,14 +64,14 @@ function post_type( $args, $assoc_args ) { 'can_export' => 'true', 'textdomain' => '', 'theme' => false, - 'plugin_name' => false, + 'plugin' => false, 'raw' => false, ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); + $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin ); if ( ! $raw ) { include 'skeletons/post_type_skeleton.php'; @@ -81,13 +81,13 @@ function post_type( $args, $assoc_args ) { include 'skeletons/post_type_skeleton.php'; } - if ( $theme || ! empty( $plugin_name ) ) { - // Write file to theme or given plugin_name + if ( $theme || ! empty( $plugin ) ) { + // Write file to theme or given plugin $assoc_args = array( 'type' => 'post_type', 'output' => $output, 'theme' => $theme, - 'plugin_name' => $plugin_name, + 'plugin' => $plugin, 'machine_name' => $machine_name, ); $assoc_args['path'] = $this->get_output_path( $assoc_args ); @@ -105,7 +105,7 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis <slug> [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin_name=<plugin_name>] [--raw] + * @synopsis <slug> [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin=<plugin>] [--raw] */ function taxonomy( $args, $assoc_args ) { global $wp_filesystem; @@ -138,14 +138,14 @@ function taxonomy( $args, $assoc_args ) { 'post_types' => 'post', 'textdomain' => '', 'theme' => false, - 'plugin_name' => false, + 'plugin' => false, 'raw' => false, ); // Generate the variables from the defaults and associated arguments if they are set extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin_name ); + $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin ); if ( ! $raw ) { include 'skeletons/taxonomy_skeleton.php'; @@ -155,13 +155,13 @@ function taxonomy( $args, $assoc_args ) { include 'skeletons/taxonomy_skeleton.php'; } - if ( $theme || ! empty( $plugin_name ) ) { - // Write file to theme or given plugin_name + if ( $theme || ! empty( $plugin ) ) { + // Write file to theme or given plugin $assoc_args = array( 'type' => 'taxonomy', 'output' => $output, 'theme' => $theme, - 'plugin_name' => $plugin_name, + 'plugin' => $plugin, 'machine_name' => $machine_name, ); $assoc_args['path'] = $this->get_output_path( $assoc_args ); @@ -177,13 +177,13 @@ private function get_output_path( $assoc_args ) { extract( $assoc_args, EXTR_SKIP ); - // Implements the --theme flag || --plugin_name=<plugin_name> + // Implements the --theme flag || --plugin=<plugin> if ( $theme ) { //Here we assume you got a theme installed $path = TEMPLATEPATH; - } elseif ( ! empty( $plugin_name ) ) { - $path = WP_PLUGIN_DIR . '/' . $plugin_name; //Faking recursive mkdir for down the line - $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin_name ); //Faking recursive mkdir for down the line + } elseif ( ! empty( $plugin ) ) { + $path = WP_PLUGIN_DIR . '/' . $plugin; //Faking recursive mkdir for down the line + $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin ); //Faking recursive mkdir for down the line } else { // STDOUT return false; @@ -227,13 +227,13 @@ private function save_skeleton_output( $assoc_args ) { /** * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. - * Same goes for when plugin_name is being used. + * Same goes for when plugin is being used. */ - private function get_textdomain( $textdomain, $theme, $plugin_name ) { + private function get_textdomain( $textdomain, $theme, $plugin ) { if ( empty( $textdomain ) && $theme ) { $textdomain = strtolower( wp_get_theme()->template ); - } elseif ( empty( $textdomain ) && $plugin_name ) { - $textdomain = $plugin_name; + } elseif ( empty( $textdomain ) && $plugin ) { + $textdomain = $plugin; } elseif ( empty( $textdomain ) || gettype( $textdomain ) == 'boolean' ) { //This mean just a flag $textdomain = 'YOUR-TEXTDOMAIN'; } From 0058ae757d882a9748d2428a45053ce91f8072fc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:32:35 +0200 Subject: [PATCH 1067/4858] add man pages --- man-src/scaffold-post-type.txt | 19 +++++++++++++++++ man-src/scaffold-taxonomy.txt | 19 +++++++++++++++++ man/scaffold-post-type.1 | 37 ++++++++++++++++++++++++++++++++++ man/scaffold-taxonomy.1 | 37 ++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 man-src/scaffold-post-type.txt create mode 100644 man-src/scaffold-taxonomy.txt create mode 100644 man/scaffold-post-type.1 create mode 100644 man/scaffold-taxonomy.1 diff --git a/man-src/scaffold-post-type.txt b/man-src/scaffold-post-type.txt new file mode 100644 index 0000000000..e78108cde7 --- /dev/null +++ b/man-src/scaffold-post-type.txt @@ -0,0 +1,19 @@ +## OPTIONS + +* `--textdomain=<textdomain>`: + + The textdomain to use for the labels. + +* `--theme`: + + Create a file in the current theme directory, instead of sending to +STDOUT. + +* `--plugin=<plugin>`: + + Create a file in the given plugin's directory, instead of sending to +STDOUT. + +* `--raw`: + + Just generate the `register_post_type()` call and nothing else. diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt new file mode 100644 index 0000000000..5eac94157e --- /dev/null +++ b/man-src/scaffold-taxonomy.txt @@ -0,0 +1,19 @@ +## OPTIONS + +* `--textdomain=<textdomain>`: + + The textdomain to use for the labels. + +* `--theme`: + + Create a file in the current theme directory, instead of sending to +STDOUT. + +* `--plugin=<plugin>`: + + Create a file in the given plugin's directory, instead of sending to +STDOUT. + +* `--raw`: + + Just generate the `register_taxonomy()` call and nothing else. diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 new file mode 100644 index 0000000000..0ecd3f15dd --- /dev/null +++ b/man/scaffold-post-type.1 @@ -0,0 +1,37 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SCAFFOLD\-POST\-TYPE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-scaffold\-post\-type\fR \- Generate PHP code for registering a custom post type\. +. +.SH "SYNOPSIS" +wp scaffold post\-type \fIslug\fR [\-\-description=\fIdescription\fR] [\-\-public=\fIpublic\fR] [\-\-exclude_from_search=\fIexclude_from_search\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_in_menu=\fIshow_in_menu\fR] [\-\-show_in_admin_bar=\fIshow_in_admin_bar\fR] [\-\-menu_position=\fImenu_position\fR] [\-\-menu_icon=\fImenu_icon\fR] [\-\-capability_type=\fIcapability_type\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-supports=\fIsupports\fR] [\-\-has_archive=\fIhas_archive\fR] [\-\-slug=\fIslug\fR] [\-\-feed=\fIfeed\fR] [\-\-pages=\fIpages\fR] [\-\-query_var=\fIquery_var\fR] [\-\-can_export=\fIcan_export\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +. +.SH "OPTIONS" +. +.TP +\fB\-\-textdomain=<textdomain>\fR: +. +.IP +The textdomain to use for the labels\. +. +.TP +\fB\-\-theme\fR: +. +.IP +Create a file in the current theme directory, instead of sending to STDOUT\. +. +.TP +\fB\-\-plugin=<plugin>\fR: +. +.IP +Create a file in the given plugin\'s directory, instead of sending to STDOUT\. +. +.TP +\fB\-\-raw\fR: +. +.IP +Just generate the \fBregister_post_type()\fR call and nothing else\. + diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 new file mode 100644 index 0000000000..0b82901868 --- /dev/null +++ b/man/scaffold-taxonomy.1 @@ -0,0 +1,37 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SCAFFOLD\-TAXONOMY" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-scaffold\-taxonomy\fR \- Generate PHP code for registering a custom taxonomy\. +. +.SH "SYNOPSIS" +wp scaffold taxonomy \fIslug\fR [\-\-public=\fIpublic\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_tagcloud=\fIshow_tagcloud\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-rewrite=\fIrewrite\fR] [\-\-query_var=\fIquery_var\fR] [\-\-slug=\fIslug\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-post_types=\fIpost_types\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +. +.SH "OPTIONS" +. +.TP +\fB\-\-textdomain=<textdomain>\fR: +. +.IP +The textdomain to use for the labels\. +. +.TP +\fB\-\-theme\fR: +. +.IP +Create a file in the current theme directory, instead of sending to STDOUT\. +. +.TP +\fB\-\-plugin=<plugin>\fR: +. +.IP +Create a file in the given plugin\'s directory, instead of sending to STDOUT\. +. +.TP +\fB\-\-raw\fR: +. +.IP +Just generate the \fBregister_taxonomy()\fR call and nothing else\. + From 6b2080185a2eaff83e53c0af8c18d9726be4300c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 16:42:45 +0200 Subject: [PATCH 1068/4858] php/commands/skeletons -> php/templates --- php/commands/scaffold.php | 12 ++++++------ .../post_type.php} | 0 .../post_type_extended.php} | 0 .../taxonomy_skeleton.php => templates/taxonomy.php} | 0 .../taxonomy_extended.php} | 0 5 files changed, 6 insertions(+), 6 deletions(-) rename php/{commands/skeletons/post_type_skeleton.php => templates/post_type.php} (100%) rename php/{commands/skeletons/post_type_skeleton_extended.php => templates/post_type_extended.php} (100%) rename php/{commands/skeletons/taxonomy_skeleton.php => templates/taxonomy.php} (100%) rename php/{commands/skeletons/taxonomy_skeleton_extended.php => templates/taxonomy_extended.php} (100%) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 42f1790fae..209351abe8 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -74,11 +74,11 @@ function post_type( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin ); if ( ! $raw ) { - include 'skeletons/post_type_skeleton.php'; + include WP_CLI_ROOT . '/templates/post_type.php'; $output = str_replace( "<?php", "", $output ); - include 'skeletons/post_type_skeleton_extended.php'; + include WP_CLI_ROOT . '/templates/post_type_extended.php'; } else { - include 'skeletons/post_type_skeleton.php'; + include WP_CLI_ROOT . '/templates/post_type.php'; } if ( $theme || ! empty( $plugin ) ) { @@ -148,11 +148,11 @@ function taxonomy( $args, $assoc_args ) { $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin ); if ( ! $raw ) { - include 'skeletons/taxonomy_skeleton.php'; + include WP_CLI_ROOT . '/templates/taxonomy.php'; $output = str_replace( "<?php", "", $output ); - include 'skeletons/taxonomy_skeleton_extended.php'; + include WP_CLI_ROOT . '/templates/taxonomy_extended.php'; } else { - include 'skeletons/taxonomy_skeleton.php'; + include WP_CLI_ROOT . '/templates/taxonomy.php'; } if ( $theme || ! empty( $plugin ) ) { diff --git a/php/commands/skeletons/post_type_skeleton.php b/php/templates/post_type.php similarity index 100% rename from php/commands/skeletons/post_type_skeleton.php rename to php/templates/post_type.php diff --git a/php/commands/skeletons/post_type_skeleton_extended.php b/php/templates/post_type_extended.php similarity index 100% rename from php/commands/skeletons/post_type_skeleton_extended.php rename to php/templates/post_type_extended.php diff --git a/php/commands/skeletons/taxonomy_skeleton.php b/php/templates/taxonomy.php similarity index 100% rename from php/commands/skeletons/taxonomy_skeleton.php rename to php/templates/taxonomy.php diff --git a/php/commands/skeletons/taxonomy_skeleton_extended.php b/php/templates/taxonomy_extended.php similarity index 100% rename from php/commands/skeletons/taxonomy_skeleton_extended.php rename to php/templates/taxonomy_extended.php From ac0e100424b904a5a827e6276f2d04221ea7935d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 13:30:43 +0200 Subject: [PATCH 1069/4858] add Mustache dependency --- .gitmodules | 3 +++ composer.json | 3 ++- php/mustache | 1 + php/utils.php | 4 ++++ 4 files changed, 10 insertions(+), 1 deletion(-) create mode 160000 php/mustache diff --git a/.gitmodules b/.gitmodules index bf7ca3df3d..05f4715b98 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "php/php-cli-tools"] path = php/php-cli-tools url = git://github.com/wp-cli/php-cli-tools.git +[submodule "php/mustache"] + path = php/mustache + url = git://github.com/bobthecow/mustache.php.git diff --git a/composer.json b/composer.json index abdda1a446..dbb99f17bc 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ ], "require": { "php": ">=5.3", - "wp-cli/php-cli-tools": "dev-master" + "wp-cli/php-cli-tools": "dev-master", + "mustache/mustache": "2.0.x" }, "require-dev": { "phpunit/phpunit": "3.7.x", diff --git a/php/mustache b/php/mustache new file mode 160000 index 0000000000..d99be3444e --- /dev/null +++ b/php/mustache @@ -0,0 +1 @@ +Subproject commit d99be3444e5b2f0fb605941d7e692d3b5159360c diff --git a/php/utils.php b/php/utils.php index c69406165b..8e27e5cbd8 100644 --- a/php/utils.php +++ b/php/utils.php @@ -26,6 +26,10 @@ function bootstrap() { if ( !$has_autoload ) { include WP_CLI_ROOT . 'php-cli-tools/lib/cli/cli.php'; \cli\register_autoload(); + + include WP_CLI_ROOT . 'mustache/src/Mustache/Autoloader.php'; + \Mustache_Autoloader::register(); + register_autoload(); } From 69f62d17013d9e54f904c3e95a10bee980b48cf9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 19:51:28 +0200 Subject: [PATCH 1070/4858] transform scaffold raw php templates into mustache templates * move common code into helper method * make taxonomy template more consistent with cpt template * rename --label to --singular --- php/commands/scaffold.php | 186 +++++++++++++-------------- php/templates/post_type.php | 70 +++++----- php/templates/post_type_extended.php | 48 ++++--- php/templates/taxonomy.php | 75 +++++------ php/templates/taxonomy_extended.php | 8 +- 5 files changed, 184 insertions(+), 203 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 209351abe8..ee23397d23 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -22,29 +22,11 @@ function __construct() { * * @alias cpt * - * @synopsis <slug> [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--slug=<slug>] [--feed=<feed>] [--pages=<pages>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] + * @synopsis <slug> [--singular=<label>] [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function post_type( $args, $assoc_args ) { - global $wp_filesystem; - - // Set the args to variables with normal names to keep our sanity - $post_type = strtolower( $args[0] ); - - // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $post_type ); - $machine_name_plural = $this->pluralize( $post_type ); - - // If no label is given use the slug and prettify it as good as possible - if ( ! isset( $assoc_args['label'] ) ) { - $label = preg_replace( '/_|-/', ' ', strtolower( $post_type ) ); - $label_ucfirst = ucfirst( $label ); - $label_plural = $this->pluralize( $label ); - $label_plural_ucfirst = ucfirst( $label_plural ); - } - - // set up defaults and merge theme with assoc_args $defaults = array( - 'description' => "", + 'description' => '', 'public' => 'true', 'exclude_from_search' => 'false', 'show_ui' => 'true', @@ -57,45 +39,16 @@ function post_type( $args, $assoc_args ) { 'hierarchical' => 'false', 'supports' => "'title', 'editor'", 'has_archive' => 'true', - 'slug' => $machine_name_plural, - 'feeds' => 'true', - 'pages' => 'true', + 'rewrite' => 'true', 'query_var' => 'true', 'can_export' => 'true', 'textdomain' => '', - 'theme' => false, - 'plugin' => false, - 'raw' => false, ); - // Generate the variables from the defaults and associated arguments if they are set - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin ); - - if ( ! $raw ) { - include WP_CLI_ROOT . '/templates/post_type.php'; - $output = str_replace( "<?php", "", $output ); - include WP_CLI_ROOT . '/templates/post_type_extended.php'; - } else { - include WP_CLI_ROOT . '/templates/post_type.php'; - } - - if ( $theme || ! empty( $plugin ) ) { - // Write file to theme or given plugin - $assoc_args = array( - 'type' => 'post_type', - 'output' => $output, - 'theme' => $theme, - 'plugin' => $plugin, - 'machine_name' => $machine_name, - ); - $assoc_args['path'] = $this->get_output_path( $assoc_args ); - $this->save_skeleton_output( $assoc_args ); - } else { - // STDOUT - echo $output; - } + $this->_scaffold( $args[0], $assoc_args, $defaults, array( + 'post_type.php', + 'post_type_extended.php' + ) ); } /** @@ -105,27 +58,9 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis <slug> [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--slug=<slug>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin=<plugin>] [--raw] + * @synopsis <slug> [--singular=<label>] [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin=<plugin>] [--raw] */ function taxonomy( $args, $assoc_args ) { - global $wp_filesystem; - - // Set the args to variables with normal names to keep our sanity - $taxonomy = strtolower( $args[0] ); - - // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $taxonomy ); - $machine_name_plural = $this->pluralize( $taxonomy ); - - // If no label is given use the slug and prettify it as good as possible - if ( ! isset( $assoc_args['label'] ) ) { - $label = preg_replace( '/_|-/', ' ', strtolower( $taxonomy ) ); - $label_ucfirst = ucfirst( $label ); - $label_plural = $this->pluralize( $label ); - $label_plural_ucfirst = ucfirst( $label_plural ); - } - - // Set up defaults and merge theme with assoc_args $defaults = array( 'public' => 'true', 'show_in_nav_menus' => 'true', @@ -134,7 +69,6 @@ function taxonomy( $args, $assoc_args ) { 'hierarchical' => 'false', 'rewrite' => 'true', 'query_var' => 'true', - 'slug' => $taxonomy, 'post_types' => 'post', 'textdomain' => '', 'theme' => false, @@ -142,24 +76,65 @@ function taxonomy( $args, $assoc_args ) { 'raw' => false, ); - // Generate the variables from the defaults and associated arguments if they are set - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + $this->_scaffold( $args[0], $assoc_args, $defaults, array( + 'taxonomy.php', + 'taxonomy_extended.php' + ) ); + } + + private function _scaffold( $slug, $assoc_args, $defaults, $templates ) { + global $wp_filesystem; + + $control_args = $this->extract_args( $assoc_args, array( + 'theme' => false, + 'plugin' => false, + 'raw' => false, + ) ); + + $vars = $this->extract_args( $assoc_args, $defaults ); + + $vars['slug'] = $slug; + + $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); + + // If no label is given use the slug and prettify it as good as possible + if ( isset( $assoc_args['singular'] ) ) { + $vars['label'] = $assoc_args['singular']; + } else { + $vars['label'] = preg_replace( '/_|-/', ' ', strtolower( $slug ) ); + } + + $vars['label_ucfirst'] = ucfirst( $vars['label'] ); + $vars['label_plural'] = $this->pluralize( $vars['label'] ); + $vars['label_plural_ucfirst'] = ucfirst( $vars['label_plural'] ); + + // We use the machine name for function declarations + $machine_name = preg_replace( '/-/', '_', $slug ); + $machine_name_plural = $this->pluralize( $slug ); + + list( $raw_template, $extended_template ) = $templates; - $textdomain = $this->get_textdomain( $textdomain, $theme, $plugin ); + $raw_output = $this->render( $raw_template, $vars ); + $raw_output = str_replace( "<?php", '', $raw_output ); + + extract( $control_args ); if ( ! $raw ) { - include WP_CLI_ROOT . '/templates/taxonomy.php'; - $output = str_replace( "<?php", "", $output ); - include WP_CLI_ROOT . '/templates/taxonomy_extended.php'; + $vars = array_merge( $vars, array( + 'machine_name' => $machine_name, + 'output' => $raw_output + ) ); + + $final_output = $this->render( $extended_template, $vars ); } else { - include WP_CLI_ROOT . '/templates/taxonomy.php'; + $final_output = $raw_output; } if ( $theme || ! empty( $plugin ) ) { - // Write file to theme or given plugin + // Write file to theme or plugin dir $assoc_args = array( - 'type' => 'taxonomy', - 'output' => $output, + 'type' => 'post_type', + 'output' => $final_output, 'theme' => $theme, 'plugin' => $plugin, 'machine_name' => $machine_name, @@ -168,7 +143,7 @@ function taxonomy( $args, $assoc_args ) { $this->save_skeleton_output( $assoc_args ); } else { // STDOUT - echo $output; + echo $final_output; } } @@ -229,16 +204,17 @@ private function save_skeleton_output( $assoc_args ) { * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. * Same goes for when plugin is being used. */ - private function get_textdomain( $textdomain, $theme, $plugin ) { - if ( empty( $textdomain ) && $theme ) { - $textdomain = strtolower( wp_get_theme()->template ); - } elseif ( empty( $textdomain ) && $plugin ) { - $textdomain = $plugin; - } elseif ( empty( $textdomain ) || gettype( $textdomain ) == 'boolean' ) { //This mean just a flag - $textdomain = 'YOUR-TEXTDOMAIN'; - } + private function get_textdomain( $textdomain, $args ) { + if ( strlen( $textdomain ) ) + return $textdomain; - return $textdomain; + if ( $args['theme'] ) + return strtolower( wp_get_theme()->template ); + + if ( $args['plugin'] && true !== $args['plugin'] ) + return $args['plugin']; + + return 'YOUR-TEXTDOMAIN'; } private function pluralize( $word ) { @@ -295,4 +271,26 @@ private function pluralize( $word ) { } return false; } + + protected function extract_args( $assoc_args, $defaults ) { + $out = array(); + + foreach ( $defaults as $key => $value ) { + $out[ $key ] = isset( $assoc_args[ $key ] ) + ? $assoc_args[ $key ] + : $value; + } + + return $out; + } + + private function render( $template, $data ) { + $scaffolds_dir = WP_CLI_ROOT . 'templates'; + + $template = file_get_contents( $scaffolds_dir . '/' . $template ); + + $m = new Mustache_Engine; + + return $m->render( $template, $data ); + } } diff --git a/php/templates/post_type.php b/php/templates/post_type.php index 21253f9391..323460d4f8 100644 --- a/php/templates/post_type.php +++ b/php/templates/post_type.php @@ -1,38 +1,34 @@ <?php -$output = "<?php - register_post_type( '{$post_type}', - array( - 'label' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'description' => __( '{$description}', '{$textdomain}' ), - 'public' => {$public}, - 'exclude_from_search' => {$exclude_from_search}, - 'show_ui' => {$show_ui}, - 'show_in_nav_menus' => {$show_in_nav_menus}, - 'show_in_menu' => {$show_in_menu}, - 'show_in_admin_bar' => {$show_in_admin_bar}, - 'menu_position' => {$menu_position}, - 'menu_icon' => {$menu_icon}, - 'capability_type' => '{$capability_type}', - 'hierarchical' => {$hierarchical}, - 'supports' => array( {$supports} ), - 'has_archive' => {$has_archive}, - 'rewrite' => array( 'slug' => '{$slug}', 'feeds' => {$feeds}, 'pages' => {$pages} ), - 'query_var' => {$query_var}, - 'can_export' => {$can_export}, - 'labels' => array( - 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), - 'add_new' => __( 'Add new {$label}', '{$textdomain}' ), - 'all_items' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'add_new_item' => __( 'Add new {$label}', '{$textdomain}' ), - 'edit_item' => __( 'Edit {$label}', '{$textdomain}' ), - 'new_item' => __( 'New {$label}', '{$textdomain}' ), - 'view_item' => __( 'View {$label}', '{$textdomain}' ), - 'search_items' => __( 'Search {$label_plural}', '{$textdomain}' ), - 'not_found' => __( 'No {$label_plural} found', '{$textdomain}' ), - 'not_found_in_trash' => __( 'No {$label_plural} found in trash', '{$textdomain}' ), - 'parent_item_colon' => __( 'Parent {$label}', '{$textdomain}' ), - 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - ), - ) - );"; \ No newline at end of file + register_post_type( '{{slug}}', array( + 'description' => __( '{{description}}', '{{textdomain}}' ), + 'public' => {{public}}, + 'exclude_from_search' => {{exclude_from_search}}, + 'show_ui' => {{show_ui}}, + 'show_in_nav_menus' => {{show_in_nav_menus}}, + 'show_in_menu' => {{show_in_menu}}, + 'show_in_admin_bar' => {{show_in_admin_bar}}, + 'menu_position' => {{menu_position}}, + 'menu_icon' => {{menu_icon}}, + 'capability_type' => '{{capability_type}}', + 'hierarchical' => {{hierarchical}}, + 'supports' => array( {{supports}} ), + 'has_archive' => {{has_archive}}, + 'rewrite' => {{rewrite}}, + 'query_var' => {{query_var}}, + 'can_export' => {{can_export}}, + 'labels' => array( + 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), + 'add_new' => __( 'Add new {{label}}', '{{textdomain}}' ), + 'all_items' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'add_new_item' => __( 'Add new {{label}}', '{{textdomain}}' ), + 'edit_item' => __( 'Edit {{label}}', '{{textdomain}}' ), + 'new_item' => __( 'New {{label}}', '{{textdomain}}' ), + 'view_item' => __( 'View {{label}}', '{{textdomain}}' ), + 'search_items' => __( 'Search {{label_plural}}', '{{textdomain}}' ), + 'not_found' => __( 'No {{label_plural}} found', '{{textdomain}}' ), + 'not_found_in_trash' => __( 'No {{label_plural}} found in trash', '{{textdomain}}' ), + 'parent_item_colon' => __( 'Parent {{label}}', '{{textdomain}}' ), + 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + ), + ) ); diff --git a/php/templates/post_type_extended.php b/php/templates/post_type_extended.php index 3d541d8d91..e4503f9969 100755 --- a/php/templates/post_type_extended.php +++ b/php/templates/post_type_extended.php @@ -1,32 +1,30 @@ <?php -$output = "<?php -function {$machine_name}_init() { - {$output} +function {{machine_name}}_init() { + {{{output}}} } -add_action( 'init', '{$machine_name}_init' ); +add_action( 'init', '{{machine_name}}_init' ); -function {$machine_name}_updated_messages( \$messages ) { - global \$post, \$post_ID; +function {{machine_name}}_updated_messages( $messages ) { + global $post, $post_ID; - \$messages['{$post_type}'] = array( - 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{$label_ucfirst} updated. <a target=\"_blank\" href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), - 2 => __('Custom field updated.', '{$textdomain}'), - 3 => __('Custom field deleted.', '{$textdomain}'), - 4 => __('{$label_ucfirst} updated.', '{$textdomain}'), - /* translators: %s: date and time of the revision */ - 5 => isset(\$_GET['revision']) ? sprintf( __('{$label_ucfirst} restored to revision from %s', '{$textdomain}'), wp_post_revision_title( (int) \$_GET['revision'], false ) ) : false, - 6 => sprintf( __('{$label_ucfirst} published. <a href=\"%s\">View {$label}</a>', '{$textdomain}'), esc_url( get_permalink(\$post_ID) ) ), - 7 => __('{$label_ucfirst} saved.', '{$textdomain}'), - 8 => sprintf( __('{$label_ucfirst} submitted. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink(\$post_ID) ) ) ), - 9 => sprintf( __('{$label_ucfirst} scheduled for: <strong>%1\$s</strong>. <a target=\"_blank\" href=\"%2\$s\">Preview {$label}</a>', '{$textdomain}'), - // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i' ), strtotime( \$post->post_date ) ), esc_url( get_permalink( \$post_ID ) ) ), - 10 => sprintf( __('{$label_ucfirst} draft updated. <a target=\"_blank\" href=\"%s\">Preview {$post_type}</a>', '{$textdomain}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( \$post_ID ) ) ) ), - ); + $messages['{{post_type}}'] = array( + 0 => '', // Unused. Messages start at index 1. + 1 => sprintf( __('{{label_ucfirst}} updated. <a target=\"_blank\" href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), + 2 => __('Custom field updated.', '{{textdomain}}'), + 3 => __('Custom field deleted.', '{{textdomain}}'), + 4 => __('{{label_ucfirst}} updated.', '{{textdomain}}'), + /* translators: %s: date and time of the revision */ + 5 => isset($_GET['revision']) ? sprintf( __('{{label_ucfirst}} restored to revision from %s', '{{textdomain}}'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => sprintf( __('{{label_ucfirst}} published. <a href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), + 7 => __('{{label_ucfirst}} saved.', '{{textdomain}}'), + 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{post_type}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), + 9 => sprintf( __('{{label_ucfirst}} scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s\">Preview {{label}}</a>', '{{textdomain}}'), + // translators: Publish box date format, see http://php.net/date + date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ), + 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{post_type}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), + ); - return \$messages; + return $messages; } -add_filter( 'post_updated_messages', '{$machine_name}_updated_messages' );"; -?> \ No newline at end of file +add_filter( 'post_updated_messages', '{{machine_name}}_updated_messages' ); diff --git a/php/templates/taxonomy.php b/php/templates/taxonomy.php index e098f77f5d..7c1003a51d 100644 --- a/php/templates/taxonomy.php +++ b/php/templates/taxonomy.php @@ -1,43 +1,34 @@ <?php -$output = "<?php - \$labels = array( - 'name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - 'singular_name' => __( '{$label_ucfirst}', '{$textdomain}' ), - 'search_items' => __( 'Search {$taxonomy}', '{$textdomain}' ), - 'popular_items' => __( 'Popular {$taxonomy}', '{$textdomain}' ), - 'all_items' => __( 'All {$label_plural}', '{$textdomain}' ), - 'parent_item' => __( 'Parent {$label}', '{$textdomain}' ), - 'parent_item_colon' => __( 'Parent {$label}:', '{$textdomain}' ), - 'edit_item' => __( 'Edit {$label}', '{$textdomain}' ), - 'update_item' => __( 'Update {$label}', '{$textdomain}' ), - 'add_new_item' => __( 'New {$label}', '{$textdomain}' ), - 'new_item_name' => __( 'New {$label}', '{$textdomain}' ), - 'separate_items_with_commas' => __( '{$label_plural_ucfirst} seperated by comma', '{$textdomain}' ), - 'add_or_remove_items' => __( 'Add or remove {$label}', '{$textdomain}' ), - 'choose_from_most_used' => __( 'Choose from the most used {$label_plural}', '{$textdomain}' ), - 'menu_name' => __( '{$label_plural_ucfirst}', '{$textdomain}' ), - ); - - \$args = array( - 'labels' => \$labels, - 'public' => {$public}, - 'show_in_nav_menus' => {$show_in_nav_menus}, - 'show_ui' => {$show_ui}, - 'show_tagcloud' => {$show_tagcloud}, - 'hierarchical' => {$hierarchical}, - 'update_count_callback' => '_update_post_term_count', - 'rewrite' => {$rewrite}, - 'query_var' => {$query_var}, - 'capabilities' => array ( - 'manage_terms' => 'edit_posts', - 'edit_terms' => 'edit_posts', - 'delete_terms' => 'edit_posts', - 'assign_terms' => 'edit_posts' - ), - 'rewrite' => array( - 'slug' => '{$taxonomy}', - 'hierarchical' => {$hierarchical} - ), - ); - - register_taxonomy( '{$taxonomy}', array( '{$post_types}' ), \$args );"; \ No newline at end of file + register_taxonomy( '{{slug}}', array( '{{post_types}}' ), array( + 'public' => {{public}}, + 'show_in_nav_menus' => {{show_in_nav_menus}}, + 'show_ui' => {{show_ui}}, + 'show_tagcloud' => {{show_tagcloud}}, + 'hierarchical' => {{hierarchical}}, + 'update_count_callback' => '_update_post_term_count', + 'query_var' => {{query_var}}, + 'rewrite' => {{rewrite}}, + 'capabilities' => array ( + 'manage_terms' => 'edit_posts', + 'edit_terms' => 'edit_posts', + 'delete_terms' => 'edit_posts', + 'assign_terms' => 'edit_posts' + ), + 'labels' => array( + 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), + 'search_items' => __( 'Search {{label_plural}}', '{{textdomain}}' ), + 'popular_items' => __( 'Popular {{label_plural}}', '{{textdomain}}' ), + 'all_items' => __( 'All {{label_plural}}', '{{textdomain}}' ), + 'parent_item' => __( 'Parent {{label}}', '{{textdomain}}' ), + 'parent_item_colon' => __( 'Parent {{label}}:', '{{textdomain}}' ), + 'edit_item' => __( 'Edit {{label}}', '{{textdomain}}' ), + 'update_item' => __( 'Update {{label}}', '{{textdomain}}' ), + 'add_new_item' => __( 'New {{label}}', '{{textdomain}}' ), + 'new_item_name' => __( 'New {{label}}', '{{textdomain}}' ), + 'separate_items_with_commas' => __( '{{label_plural_ucfirst}} separated by comma', '{{textdomain}}' ), + 'add_or_remove_items' => __( 'Add or remove {{label_plural}}', '{{textdomain}}' ), + 'choose_from_most_used' => __( 'Choose from the most used {{label_plural}}', '{{textdomain}}' ), + 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + ), + ) ); diff --git a/php/templates/taxonomy_extended.php b/php/templates/taxonomy_extended.php index d4015c73ed..0805563514 100755 --- a/php/templates/taxonomy_extended.php +++ b/php/templates/taxonomy_extended.php @@ -1,8 +1,6 @@ <?php -$output = "<?php - -function {$machine_name}_init() { - {$output} +function {{machine_name}}_init() { + {{{output}}} } -add_action( 'init', '{$machine_name}_init' );"; \ No newline at end of file +add_action( 'init', '{{machine_name}}_init' ); From f6136555c5b3824992e1c58a04b3ab2bc16c5af0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 21:06:34 +0200 Subject: [PATCH 1071/4858] replace {{post_type}} with {{slug}} --- php/templates/post_type_extended.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/templates/post_type_extended.php b/php/templates/post_type_extended.php index e4503f9969..b7be67ec72 100755 --- a/php/templates/post_type_extended.php +++ b/php/templates/post_type_extended.php @@ -8,7 +8,7 @@ function {{machine_name}}_init() { function {{machine_name}}_updated_messages( $messages ) { global $post, $post_ID; - $messages['{{post_type}}'] = array( + $messages['{{slug}}'] = array( 0 => '', // Unused. Messages start at index 1. 1 => sprintf( __('{{label_ucfirst}} updated. <a target=\"_blank\" href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), 2 => __('Custom field updated.', '{{textdomain}}'), @@ -18,11 +18,11 @@ function {{machine_name}}_updated_messages( $messages ) { 5 => isset($_GET['revision']) ? sprintf( __('{{label_ucfirst}} restored to revision from %s', '{{textdomain}}'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, 6 => sprintf( __('{{label_ucfirst}} published. <a href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), 7 => __('{{label_ucfirst}} saved.', '{{textdomain}}'), - 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{post_type}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), + 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{slug}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), 9 => sprintf( __('{{label_ucfirst}} scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s\">Preview {{label}}</a>', '{{textdomain}}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ), - 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{post_type}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), + 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{slug}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), ); return $messages; From ab0e03b0e7e9c21bfaa8af74a9b99cc58dcfe52f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 21:08:39 +0200 Subject: [PATCH 1072/4858] use {{label}} instead of {{slug}}, where appropriate --- php/templates/post_type_extended.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/templates/post_type_extended.php b/php/templates/post_type_extended.php index b7be67ec72..bb2c2bfc8c 100755 --- a/php/templates/post_type_extended.php +++ b/php/templates/post_type_extended.php @@ -18,11 +18,11 @@ function {{machine_name}}_updated_messages( $messages ) { 5 => isset($_GET['revision']) ? sprintf( __('{{label_ucfirst}} restored to revision from %s', '{{textdomain}}'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, 6 => sprintf( __('{{label_ucfirst}} published. <a href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), 7 => __('{{label_ucfirst}} saved.', '{{textdomain}}'), - 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{slug}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), + 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), 9 => sprintf( __('{{label_ucfirst}} scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s\">Preview {{label}}</a>', '{{textdomain}}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ), - 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{slug}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), + 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), ); return $messages; From a880c4e4e1aa06b60c0a09efeeca54ba98987010 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 31 Dec 2012 21:13:18 +0200 Subject: [PATCH 1073/4858] pass whole post to get_permalink() and cache the result --- php/templates/post_type_extended.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/php/templates/post_type_extended.php b/php/templates/post_type_extended.php index bb2c2bfc8c..48cef1b3e5 100755 --- a/php/templates/post_type_extended.php +++ b/php/templates/post_type_extended.php @@ -6,23 +6,25 @@ function {{machine_name}}_init() { add_action( 'init', '{{machine_name}}_init' ); function {{machine_name}}_updated_messages( $messages ) { - global $post, $post_ID; + global $post; + + $permalink = get_permalink( $post ); $messages['{{slug}}'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{{label_ucfirst}} updated. <a target=\"_blank\" href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), + 1 => sprintf( __('{{label_ucfirst}} updated. <a target=\"_blank\" href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( $permalink ) ), 2 => __('Custom field updated.', '{{textdomain}}'), 3 => __('Custom field deleted.', '{{textdomain}}'), 4 => __('{{label_ucfirst}} updated.', '{{textdomain}}'), /* translators: %s: date and time of the revision */ 5 => isset($_GET['revision']) ? sprintf( __('{{label_ucfirst}} restored to revision from %s', '{{textdomain}}'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - 6 => sprintf( __('{{label_ucfirst}} published. <a href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( get_permalink($post_ID) ) ), + 6 => sprintf( __('{{label_ucfirst}} published. <a href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( $permalink ) ), 7 => __('{{label_ucfirst}} saved.', '{{textdomain}}'), - 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), + 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', $permalink ) ) ), 9 => sprintf( __('{{label_ucfirst}} scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s\">Preview {{label}}</a>', '{{textdomain}}'), // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ), - 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), + date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( $permalink ) ), + 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', $permalink ) ) ), ); return $messages; From 5a7727f0a1600c2a630a6ff665f406e92d4d1945 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Jan 2013 00:12:56 +0000 Subject: [PATCH 1074/4858] Require the file based on when the file was actually committed to core. --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 30769553df..04b784a895 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -122,7 +122,7 @@ require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); -Utils\maybe_require( '3.5', ABSPATH . WPINC . '/class-wp-embed.php' ); +Utils\maybe_require( '3.5-alpha-22024', ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); require( ABSPATH . WPINC . '/class-http.php' ); From 6a7b36c640bc00713c9a3df8f5d9f6d88294d7e2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 14:18:30 +0200 Subject: [PATCH 1075/4858] remove @maintainer and @subpackage tags --- php/commands/scaffold.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ee23397d23..e6d640fd1c 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -1,13 +1,9 @@ <?php -WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); - /** - * Implement scaffold command + * Generate code for post types, taxonomies, etc. * * @package wp-cli - * @subpackage commands/internals - * @maintainer LinePress (http://www.linespress.org) */ class Scaffold_Command extends WP_CLI_Command { @@ -294,3 +290,6 @@ private function render( $template, $data ) { return $m->render( $template, $data ); } } + +WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); + From a8abbefb27b4496873f0b0c2147abfc7b7c09b1c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 14:28:32 +0200 Subject: [PATCH 1076/4858] first pass at `wp scaffold plugin` --- php/commands/scaffold.php | 35 +++++++++++++++++++++++++++++++++++ php/templates/plugin.php | 12 ++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 php/templates/plugin.php diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index e6d640fd1c..52cb985c06 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -179,6 +179,33 @@ private function get_output_path( $assoc_args ) { return $path; } + /** + * Generate starter code for a plugin. + * + * @synopsis <slug> [--plugin_name=<title>] [--activate] + */ + function plugin( $args, $assoc_args ) { + $plugin_slug = $args[0]; + + $data = wp_parse_args( $assoc_args, array( + 'plugin_name' => ucfirst( $plugin_slug ), + 'textdomain' => $plugin_slug + ) ); + + $plugin_contents = $this->render( 'plugin.php', $data ); + + $plugin_path = WP_PLUGIN_DIR . "/$plugin_slug/$plugin_slug.php"; + + if ( ! $this->create_file( $plugin_path, $plugin_contents ) ) { + WP_CLI::error( "Error creating file: $plugin_path" ); + } + + WP_CLI::success( "Plugin scaffold created: $plugin_path" ); + + if ( isset( $assoc_args['activate'] ) ) + \WP_CLI\Utils\run_command( array( 'plugin', 'activate', $plugin_slug ) ); + } + private function save_skeleton_output( $assoc_args ) { global $wp_filesystem; @@ -196,6 +223,14 @@ private function save_skeleton_output( $assoc_args ) { } } + private function create_file( $filename, $contents ) { + global $wp_filesystem; + + $wp_filesystem->mkdir( dirname( $filename ) ); + + return $wp_filesystem->put_contents( $filename, $contents ); + } + /** * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. * Same goes for when plugin is being used. diff --git a/php/templates/plugin.php b/php/templates/plugin.php new file mode 100644 index 0000000000..d992cd094e --- /dev/null +++ b/php/templates/plugin.php @@ -0,0 +1,12 @@ +<?php +/* +Plugin Name: {{plugin_name}} +Version: 0.1-alpha +Description: PLUGIN DESCRIPTION HERE +Author: YOUR NAME HERE +Author URI: YOUR SITE HERE +Plugin URI: PLUGIN SITE HERE +Text Domain: {{textdomain}} +Domain Path: /languages +*/ + From 16d7ed340381fb4e6bdc70ad708d2cbbd512bb12 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 14:46:05 +0200 Subject: [PATCH 1077/4858] use create_file() for cpt and tax scaffolds --- php/commands/scaffold.php | 78 +++++++++------------------------------ 1 file changed, 17 insertions(+), 61 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 52cb985c06..d5a9f6ed0d 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -41,7 +41,7 @@ function post_type( $args, $assoc_args ) { 'textdomain' => '', ); - $this->_scaffold( $args[0], $assoc_args, $defaults, array( + $this->_scaffold( $args[0], $assoc_args, $defaults, '/post-types/', array( 'post_type.php', 'post_type_extended.php' ) ); @@ -72,13 +72,13 @@ function taxonomy( $args, $assoc_args ) { 'raw' => false, ); - $this->_scaffold( $args[0], $assoc_args, $defaults, array( + $this->_scaffold( $args[0], $assoc_args, $defaults, '/taxonomies/', array( 'taxonomy.php', 'taxonomy_extended.php' ) ); } - private function _scaffold( $slug, $assoc_args, $defaults, $templates ) { + private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) { global $wp_filesystem; $control_args = $this->extract_args( $assoc_args, array( @@ -113,9 +113,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $templates ) { $raw_output = $this->render( $raw_template, $vars ); $raw_output = str_replace( "<?php", '', $raw_output ); - extract( $control_args ); - - if ( ! $raw ) { + if ( ! $control_args['raw'] ) { $vars = array_merge( $vars, array( 'machine_name' => $machine_name, 'output' => $raw_output @@ -126,55 +124,30 @@ private function _scaffold( $slug, $assoc_args, $defaults, $templates ) { $final_output = $raw_output; } - if ( $theme || ! empty( $plugin ) ) { - // Write file to theme or plugin dir - $assoc_args = array( - 'type' => 'post_type', - 'output' => $final_output, - 'theme' => $theme, - 'plugin' => $plugin, - 'machine_name' => $machine_name, - ); - $assoc_args['path'] = $this->get_output_path( $assoc_args ); - $this->save_skeleton_output( $assoc_args ); + if ( $path = $this->get_output_path( $control_args, $subdir ) ) { + $filename = $path . $machine_name .'.php'; + + $this->create_file( $filename, $final_output ); + + WP_CLI::success( "Created $filename" ); } else { // STDOUT echo $final_output; } } - private function get_output_path( $assoc_args ) { - global $wp_filesystem; - + private function get_output_path( $assoc_args, $subdir ) { extract( $assoc_args, EXTR_SKIP ); - // Implements the --theme flag || --plugin=<plugin> if ( $theme ) { - //Here we assume you got a theme installed $path = TEMPLATEPATH; } elseif ( ! empty( $plugin ) ) { - $path = WP_PLUGIN_DIR . '/' . $plugin; //Faking recursive mkdir for down the line - $wp_filesystem->mkdir( WP_PLUGIN_DIR . '/' . $plugin ); //Faking recursive mkdir for down the line + $path = WP_PLUGIN_DIR . '/' . $plugin; } else { - // STDOUT return false; } - if ( $type === "post_type" ) { - $path .= '/post-types/'; - } elseif ( $type === "taxonomy" ) { - $path .= '/taxonomies/'; - } - - // If it doesn't exists create it - if ( ! $wp_filesystem->is_dir( $path ) ) { - $wp_filesystem->mkdir( $path ); - WP_CLI::success( "Created dir: {$path}" ); - } elseif ( $wp_filesystem->is_dir( $path ) ) { - WP_CLI::success( "Dir already exists: {$path}" ); - } else { - WP_CLI::error( "Couldn't create dir exists: {$path}" ); - } + $path .= $subdir; return $path; } @@ -196,9 +169,7 @@ function plugin( $args, $assoc_args ) { $plugin_path = WP_PLUGIN_DIR . "/$plugin_slug/$plugin_slug.php"; - if ( ! $this->create_file( $plugin_path, $plugin_contents ) ) { - WP_CLI::error( "Error creating file: $plugin_path" ); - } + $this->create_file( $plugin_path, $plugin_contents ); WP_CLI::success( "Plugin scaffold created: $plugin_path" ); @@ -206,29 +177,14 @@ function plugin( $args, $assoc_args ) { \WP_CLI\Utils\run_command( array( 'plugin', 'activate', $plugin_slug ) ); } - private function save_skeleton_output( $assoc_args ) { - global $wp_filesystem; - - extract( $assoc_args, EXTR_SKIP ); - - // Write to file - if ( $path ) { - $filename = $path . $machine_name .'.php'; - - if ( ! $wp_filesystem->put_contents( $filename, $output ) ) { - WP_CLI::error( "Error while saving file: {$filename}" ); - } else { - WP_CLI::success( "{$type} {$machine_name} created" ); - } - } - } - private function create_file( $filename, $contents ) { global $wp_filesystem; $wp_filesystem->mkdir( dirname( $filename ) ); - return $wp_filesystem->put_contents( $filename, $contents ); + if ( !$wp_filesystem->put_contents( $filename, $contents ) ) { + WP_CLI::error( "Error creating file: $filename" ); + } } /** From 11c74b7e8898265fb2fd8e2bcec146e280030005 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 14:52:31 +0200 Subject: [PATCH 1078/4858] add man page for `wp scaffold plugin` --- man-src/scaffold-plugin.txt | 9 +++++++++ man/scaffold-plugin.1 | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 man-src/scaffold-plugin.txt create mode 100644 man/scaffold-plugin.1 diff --git a/man-src/scaffold-plugin.txt b/man-src/scaffold-plugin.txt new file mode 100644 index 0000000000..bea18ef97e --- /dev/null +++ b/man-src/scaffold-plugin.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `--activate`: + + Activate the newly generated plugin. + +* `--plugin_name=<title>`: + + What to put in the 'Plugin Name:' header diff --git a/man/scaffold-plugin.1 b/man/scaffold-plugin.1 new file mode 100644 index 0000000000..f91ec221e5 --- /dev/null +++ b/man/scaffold-plugin.1 @@ -0,0 +1,25 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SCAFFOLD\-PLUGIN" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-scaffold\-plugin\fR \- Generate starter code for a plugin\. +. +.SH "SYNOPSIS" +wp scaffold plugin \fIslug\fR [\-\-plugin_name=\fItitle\fR] [\-\-activate] +. +.SH "OPTIONS" +. +.TP +\fB\-\-activate\fR: +. +.IP +Activate the newly generated plugin\. +. +.TP +\fB\-\-plugin_name=<title>\fR: +. +.IP +What to put in the \'Plugin Name:\' header + From 5fc65beb331c025024459cac31fb3723e5dcb06a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 14:55:03 +0200 Subject: [PATCH 1079/4858] always use the plugin slug for the textdomain --- php/commands/scaffold.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d5a9f6ed0d..401c1a97c2 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -162,9 +162,10 @@ function plugin( $args, $assoc_args ) { $data = wp_parse_args( $assoc_args, array( 'plugin_name' => ucfirst( $plugin_slug ), - 'textdomain' => $plugin_slug ) ); + $data['textdomain'] = $plugin_slug; + $plugin_contents = $this->render( 'plugin.php', $data ); $plugin_path = WP_PLUGIN_DIR . "/$plugin_slug/$plugin_slug.php"; From cd187c2278a09256be430b135dcac7484dde9da1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 22:31:20 +0200 Subject: [PATCH 1080/4858] update top-level command descriptions and move add_command() below the class definitions --- php/commands/blog.php | 10 +++++----- php/commands/cache.php | 6 +++--- php/commands/cap.php | 6 +++--- php/commands/comment.php | 6 +++--- php/commands/core.php | 7 ++++--- php/commands/db.php | 6 +++--- php/commands/eval-file.php | 4 ++-- php/commands/eval.php | 4 ++-- php/commands/export.php | 13 ++++--------- php/commands/help.php | 11 +++-------- php/commands/home.php | 10 ++-------- php/commands/option.php | 5 +++-- php/commands/plugin.php | 2 +- php/commands/post.php | 2 +- php/commands/rewrite.php | 10 ++++++++-- php/commands/search-replace.php | 6 ++++-- php/commands/shell.php | 6 +++--- php/commands/theme.php | 2 +- php/commands/transient.php | 5 +++-- php/commands/user.php | 2 +- 20 files changed, 59 insertions(+), 64 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index b73f1bd9b0..7e3291435e 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -1,11 +1,7 @@ <?php -if ( is_multisite() ) { - WP_CLI::add_command( 'blog', 'Blog_Command' ); -} - /** - * Implement core command + * Manage blogs in a multisite install. * * @package wp-cli * @subpackage commands/internals @@ -154,3 +150,7 @@ protected static function get_blog_id_by_slug( $slug ) { } } +if ( is_multisite() ) { + WP_CLI::add_command( 'blog', 'Blog_Command' ); +} + diff --git a/php/commands/cache.php b/php/commands/cache.php index 142c234196..3142295960 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -1,9 +1,7 @@ <?php -WP_CLI::add_command( 'cache', 'Cache_Command' ); - /** - * Manage the WordPress object cache. + * Manage the object cache. * * @package wp-cli * @subpackage commands/internals @@ -219,3 +217,5 @@ public function type( $args, $assoc_args ) { } } +WP_CLI::add_command( 'cache', 'Cache_Command' ); + diff --git a/php/commands/cap.php b/php/commands/cap.php index f496acc705..29fe264628 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -1,9 +1,7 @@ <?php -WP_CLI::add_command( 'cap', 'Capabilities_Command' ); - /** - * Manage capabilities. + * Manage user capabilities. * * @package wp-cli * @subpackage commands/internals @@ -94,3 +92,5 @@ private static function persistence_check() { } } +WP_CLI::add_command( 'cap', 'Capabilities_Command' ); + diff --git a/php/commands/comment.php b/php/commands/comment.php index 0604b8e255..2db3c0a0e0 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -1,9 +1,7 @@ <?php -WP_CLI::add_command( 'comment', 'Comment_Command' ); - /** - * Implement 'comment' command + * Manage comments. * * @package wp-cli * @subpackage commands/internals @@ -193,3 +191,5 @@ function last( $args = array(), $assoc_args = array() ) { } } +WP_CLI::add_command( 'comment', 'Comment_Command' ); + diff --git a/php/commands/core.php b/php/commands/core.php index 63894f4c09..86daef297d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1,9 +1,7 @@ <?php -WP_CLI::add_command('core', 'Core_Command'); - /** - * Implement core command + * Download, install, update and otherwise manage WordPress proper. * * @package wp-cli * @subpackage commands/internals @@ -290,3 +288,6 @@ function update_db() { WP_CLI::success( 'WordPress database upgraded successfully.' ); } } + +WP_CLI::add_command( 'core', 'Core_Command' ); + diff --git a/php/commands/db.php b/php/commands/db.php index e9bccf921c..2d204d44de 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -1,9 +1,7 @@ <?php -WP_CLI::add_command( 'db', 'DB_Command' ); - /** - * Implement db command + * Perform basic database operations. * * @package wp-cli * @subpackage commands/internals @@ -187,3 +185,5 @@ private static function run( $assoc_args, $cmd ) { } } +WP_CLI::add_command( 'db', 'DB_Command' ); + diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 1887930d24..d5d2a4204d 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -1,7 +1,5 @@ <?php -WP_CLI::add_command( 'eval-file', new EvalFile_Command ); - class EvalFile_Command extends WP_CLI_Command { /** @@ -20,3 +18,5 @@ public function __invoke( $args, $assoc_args ) { } } +WP_CLI::add_command( 'eval-file', new EvalFile_Command ); + diff --git a/php/commands/eval.php b/php/commands/eval.php index fe8ae5f176..131ca8455c 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -1,7 +1,5 @@ <?php -WP_CLI::add_command( 'eval', new Eval_Command ); - class Eval_Command extends WP_CLI_Command { /** @@ -14,3 +12,5 @@ public function __invoke( $args, $assoc_args ) { } } +WP_CLI::add_command( 'eval', new Eval_Command ); + diff --git a/php/commands/export.php b/php/commands/export.php index 3ed26350ef..8a08f3bf70 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -1,13 +1,5 @@ <?php -WP_CLI::add_command( 'export', new Export_Command ); - -/** - * Implement export command - * - * @package wp-cli - * @subpackage commands/internals - */ class Export_Command extends WP_CLI_Command { /** @@ -17,7 +9,7 @@ class Export_Command extends WP_CLI_Command { public $export_args = array(); /** - * Export posts to a WXR file. + * Export content to a WXR file. * * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] */ @@ -539,3 +531,6 @@ private function export_wp( $args = array() ) { WP_CLI::success( "All done with export" ); } } + +WP_CLI::add_command( 'export', new Export_Command ); + diff --git a/php/commands/help.php b/php/commands/help.php index 1d83ba1596..bd1234a198 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -1,15 +1,7 @@ <?php -WP_CLI::add_command( 'help', new Help_Command ); - use \WP_CLI\Dispatcher\CommandContainer; -/** - * Implement help command - * - * @package wp-cli - * @subpackage commands/internals - */ class Help_Command extends WP_CLI_Command { /** @@ -47,3 +39,6 @@ private static function maybe_load_man_page( $args ) { } } } + +WP_CLI::add_command( 'help', new Help_Command ); + diff --git a/php/commands/home.php b/php/commands/home.php index 730ce8d2c2..a5ca3e6d33 100644 --- a/php/commands/home.php +++ b/php/commands/home.php @@ -1,13 +1,5 @@ <?php -WP_CLI::add_command( 'home', new Home_Command ); - -/** - * Implement home command - * - * @package wp-cli - * @subpackage commands/internals - */ class Home_Command extends WP_CLI_Command { /** @@ -33,3 +25,5 @@ function __invoke() { } } +WP_CLI::add_command( 'home', new Home_Command ); + diff --git a/php/commands/option.php b/php/commands/option.php index d18f4a7b4b..b5f63da426 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -1,7 +1,5 @@ <?php -WP_CLI::add_command('option', 'Option_Command'); - /** * Manage WordPress options. * @@ -73,3 +71,6 @@ public function delete( $args ) { } } } + +WP_CLI::add_command( 'option', 'Option_Command' ); + diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 047401d8fe..b133665942 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -1,7 +1,7 @@ <?php /** - * Implement plugin command + * Manage plugins. * * @package wp-cli * @subpackage commands/internals diff --git a/php/commands/post.php b/php/commands/post.php index 49bc35e3d8..e0a082e6c0 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -1,7 +1,7 @@ <?php /** - * Implement post command + * Manage posts. * * @package wp-cli * @subpackage commands/internals diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 67ca9313d3..0709e9f0ff 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -1,7 +1,10 @@ <?php -WP_CLI:: add_command( 'rewrite', 'Rewrite_Command' ); - +/** + * Manage rewrite rules. + * + * @package wp-cli + */ class Rewrite_Command extends WP_CLI_Command { /** @@ -79,3 +82,6 @@ public function dump( $args, $assoc_args ) { } } + +WP_CLI:: add_command( 'rewrite', 'Rewrite_Command' ); + diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 722d48d63b..f46cc27906 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -1,8 +1,8 @@ <?php -WP_CLI::add_command( 'search-replace', new Search_Replace_Command ); - /** + * Search and replace strings in the database. + * * @package wp-cli */ class Search_Replace_Command extends WP_CLI_Command { @@ -118,3 +118,5 @@ private static function is_text_col( $type ) { } } +WP_CLI::add_command( 'search-replace', new Search_Replace_Command ); + diff --git a/php/commands/shell.php b/php/commands/shell.php index b3f75f2622..c0e73760ff 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -2,12 +2,10 @@ namespace WP_CLI\Commands; -\WP_CLI::add_command( 'shell', new Shell_Command ); - class Shell_Command extends \WP_CLI_Command { /** - * Open an interactive shell environment. + * Interactive PHP console. */ public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); @@ -82,3 +80,5 @@ private static function starts_with( $tokens, $line ) { } } +\WP_CLI::add_command( 'shell', new Shell_Command ); + diff --git a/php/commands/theme.php b/php/commands/theme.php index 8837f8c997..ca016ddcbd 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -1,7 +1,7 @@ <?php /** - * Implement theme command + * Manage themes. * * @package wp-cli * @subpackage commands/internals diff --git a/php/commands/transient.php b/php/commands/transient.php index f21b935421..8c2ee6a5ff 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -1,7 +1,5 @@ <?php -WP_CLI::add_command( 'transient', 'Transient_Command' ); - /** * Manage WordPress transients. * @@ -76,3 +74,6 @@ public function type() { WP_CLI::line( $message ); } } + +WP_CLI::add_command( 'transient', 'Transient_Command' ); + diff --git a/php/commands/user.php b/php/commands/user.php index fb69f14d4f..fe878a65ea 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -1,7 +1,7 @@ <?php /** - * Implement user command + * Manage users. * * @package wp-cli * @subpackage commands/internals From 42ff9afcbb3f30fdd23e2e0e9105c307edc95406 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 22:35:58 +0200 Subject: [PATCH 1081/4858] remove @subpackage commands/internals --- php/commands/blog.php | 1 - php/commands/cache.php | 1 - php/commands/cap.php | 1 - php/commands/comment.php | 1 - php/commands/core.php | 1 - php/commands/db.php | 1 - php/commands/option.php | 1 - php/commands/plugin.php | 1 - php/commands/post-meta.php | 1 - php/commands/post.php | 1 - php/commands/theme.php | 1 - php/commands/transient.php | 1 - php/commands/user-meta.php | 1 - php/commands/user.php | 1 - 14 files changed, 14 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index 7e3291435e..52b868538d 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -4,7 +4,6 @@ * Manage blogs in a multisite install. * * @package wp-cli - * @subpackage commands/internals */ class Blog_Command extends WP_CLI_Command { diff --git a/php/commands/cache.php b/php/commands/cache.php index 3142295960..00b93b254e 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -4,7 +4,6 @@ * Manage the object cache. * * @package wp-cli - * @subpackage commands/internals */ class Cache_Command extends WP_CLI_Command { diff --git a/php/commands/cap.php b/php/commands/cap.php index 29fe264628..aea5a2f73a 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -4,7 +4,6 @@ * Manage user capabilities. * * @package wp-cli - * @subpackage commands/internals */ class Capabilities_Command extends WP_CLI_Command { diff --git a/php/commands/comment.php b/php/commands/comment.php index 2db3c0a0e0..dd5442cda8 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -4,7 +4,6 @@ * Manage comments. * * @package wp-cli - * @subpackage commands/internals */ class Comment_Command extends WP_CLI_Command { diff --git a/php/commands/core.php b/php/commands/core.php index 86daef297d..f3d70f48d7 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -4,7 +4,6 @@ * Download, install, update and otherwise manage WordPress proper. * * @package wp-cli - * @subpackage commands/internals */ class Core_Command extends WP_CLI_Command { diff --git a/php/commands/db.php b/php/commands/db.php index 2d204d44de..104516728a 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -4,7 +4,6 @@ * Perform basic database operations. * * @package wp-cli - * @subpackage commands/internals */ class DB_Command extends WP_CLI_Command { diff --git a/php/commands/option.php b/php/commands/option.php index b5f63da426..525a89a36e 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -4,7 +4,6 @@ * Manage WordPress options. * * @package wp-cli - * @subpackage commands/internals */ class Option_Command extends WP_CLI_Command { diff --git a/php/commands/plugin.php b/php/commands/plugin.php index b133665942..189dad344c 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -4,7 +4,6 @@ * Manage plugins. * * @package wp-cli - * @subpackage commands/internals */ class Plugin_Command extends \WP_CLI\CommandWithUpgrade { diff --git a/php/commands/post-meta.php b/php/commands/post-meta.php index a987ac4b35..08a1052f0d 100644 --- a/php/commands/post-meta.php +++ b/php/commands/post-meta.php @@ -4,7 +4,6 @@ * Manage post custom fields. * * @package wp-cli - * @subpackage commands/internals */ class Post_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'post'; diff --git a/php/commands/post.php b/php/commands/post.php index e0a082e6c0..1e69d24b7e 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -4,7 +4,6 @@ * Manage posts. * * @package wp-cli - * @subpackage commands/internals */ class Post_Command extends \WP_CLI\CommandWithDBObject { diff --git a/php/commands/theme.php b/php/commands/theme.php index ca016ddcbd..2367658013 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -4,7 +4,6 @@ * Manage themes. * * @package wp-cli - * @subpackage commands/internals */ class Theme_Command extends \WP_CLI\CommandWithUpgrade { diff --git a/php/commands/transient.php b/php/commands/transient.php index 8c2ee6a5ff..c7dae59610 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -4,7 +4,6 @@ * Manage WordPress transients. * * @package wp-cli - * @subpackage commands/internals */ class Transient_Command extends WP_CLI_Command { diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php index 6fe4ed794d..59b4b739f6 100644 --- a/php/commands/user-meta.php +++ b/php/commands/user-meta.php @@ -4,7 +4,6 @@ * Manage user custom fields. * * @package wp-cli - * @subpackage commands/internals */ class User_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'user'; diff --git a/php/commands/user.php b/php/commands/user.php index fe878a65ea..c3cff0cd9b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -4,7 +4,6 @@ * Manage users. * * @package wp-cli - * @subpackage commands/internals */ class User_Command extends \WP_CLI\CommandWithDBObject { From 10b35f3d34b8bf060f3b5267c90802e587ae9cfa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 18:56:53 +0200 Subject: [PATCH 1082/4858] replace --syn-list with --cmd-dump --- php/WP_CLI/Dispatcher/RootCommand.php | 10 +++++++- php/WP_CLI/Dispatcher/Subcommand.php | 8 ++++-- php/class-wp-cli.php | 37 +++++++++++++++++++-------- php/dispatcher.php | 1 + 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 080ad4cbca..0e721678ca 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class RootCommand extends AbstractCommandContainer { +class RootCommand extends AbstractCommandContainer implements Documentable { function get_name() { return 'wp'; @@ -12,6 +12,14 @@ function get_parent() { return false; } + function get_shortdesc() { + return ''; + } + + function get_full_synopsis() { + return ''; + } + function show_usage() { \WP_CLI::line( 'Available commands:' ); diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 0432e7a830..e725199dd3 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -23,11 +23,15 @@ function get_shortdesc() { function get_full_synopsis() { $full_name = implode( ' ', get_path( $this ) ); - $synopsis = $this->docparser->get_synopsis(); + $synopsis = $this->get_synopsis(); return "$full_name $synopsis"; } + function get_synopsis() { + return $this->docparser->get_synopsis(); + } + function invoke( $args, $assoc_args ) { $this->check_args( $args, $assoc_args ); @@ -43,7 +47,7 @@ function get_parent() { } protected function check_args( $args, $assoc_args ) { - $synopsis = $this->docparser->get_synopsis(); + $synopsis = $this->get_synopsis(); if ( !$synopsis ) return; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 34848dbc1b..407d255577 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -261,7 +261,7 @@ private static function parse_args() { self::split_special( array( 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'completions', 'man', 'syn-list' + 'quiet', 'completions', 'man', 'cmd-dump' ) ); } @@ -381,16 +381,8 @@ static function after_wp_load() { exit; } - // Handle --syn-list parameter - if ( isset( self::$config['syn-list'] ) ) { - foreach ( self::$root->get_subcommands() as $command ) { - if ( $command instanceof Dispatcher\CommandContainer ) { - foreach ( $command->get_subcommands() as $subcommand ) - $subcommand->show_usage( '' ); - } else { - $command->show_usage( '' ); - } - } + if ( isset( self::$config['cmd-dump'] ) ) { + self::cmd_dump(); exit; } @@ -402,6 +394,29 @@ static function after_wp_load() { self::run_command(); } + private static function cmd_dump() { + $dump = self::command_to_array( self::$root ); + + echo json_encode( $dump['subcommands'] ); + } + + private static function command_to_array( $command ) { + $dump = array( + 'name' => $command->get_name(), + 'description' => $command->get_shortdesc(), + ); + + if ( $command instanceof Dispatcher\AtomicCommand ) { + $dump['synopsis'] = $command->get_synopsis(); + } else { + foreach ( Dispatcher\get_subcommands( $command ) as $subcommand ) { + $dump['subcommands'][] = self::command_to_array( $subcommand ); + } + } + + return $dump; + } + private static function run_command() { Utils\run_command( self::$arguments, self::$assoc_args ); } diff --git a/php/dispatcher.php b/php/dispatcher.php index 7b7907675c..da4e1b0ff4 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -31,6 +31,7 @@ function show_usage(); interface AtomicCommand { + function get_synopsis(); function invoke( $args, $assoc_args ); } From 853783999fd0ed66f925fac4f894b84554faa65e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 19:37:44 +0200 Subject: [PATCH 1083/4858] add external syn-list.php utility --- utils/syn-list.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 utils/syn-list.php diff --git a/utils/syn-list.php b/utils/syn-list.php new file mode 100644 index 0000000000..5f7cf5cdc3 --- /dev/null +++ b/utils/syn-list.php @@ -0,0 +1,41 @@ +<?php +# Given a list of commands as JSON on STDIN, generates a list of synopses. +# +# Example usage: +# +# wp --cmd-dump | php /path/to/wp-cli/utils/syn-list.php + +function read_json() { + $input = ''; + + while ( false !== ( $line = fgets( STDIN ) ) ) { + $input .= $line; + } + + $json = json_decode( $input, true ); + if ( !$json ) { + echo "Invalid JSON."; + exit(1); + } + + return $json; +} + +function generate_synopsis( $command, $path ) { + $full_path = $path . ' ' . $command['name']; + + if ( !isset( $command['subcommands'] ) ) { + echo $full_path . ' ' . $command['synopsis'] . "\n"; + } else { + foreach ( $command['subcommands'] as $subcommand ) { + generate_synopsis( $subcommand, $full_path ); + } + } +} + +$commands = read_json(); + +foreach ( $commands as $command ) { + generate_synopsis( $command, 'wp' ); +} + From 4b1273a5ed695731ae84023e1a11b2b68ea7d7b7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 20:18:42 +0200 Subject: [PATCH 1084/4858] synopsis should always be a string --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 407d255577..a3097a1534 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -407,7 +407,7 @@ private static function command_to_array( $command ) { ); if ( $command instanceof Dispatcher\AtomicCommand ) { - $dump['synopsis'] = $command->get_synopsis(); + $dump['synopsis'] = (string) $command->get_synopsis(); } else { foreach ( Dispatcher\get_subcommands( $command ) as $subcommand ) { $dump['subcommands'][] = self::command_to_array( $subcommand ); From b63b1638d20bf63b1aea117a902fefede50d8b1b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 21:44:57 +0200 Subject: [PATCH 1085/4858] it's actually easier if we pass the whole 'wp' command --- php/class-wp-cli.php | 2 +- utils/syn-list.php | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index a3097a1534..085cb8fd16 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -397,7 +397,7 @@ static function after_wp_load() { private static function cmd_dump() { $dump = self::command_to_array( self::$root ); - echo json_encode( $dump['subcommands'] ); + echo json_encode( $dump ); } private static function command_to_array( $command ) { diff --git a/utils/syn-list.php b/utils/syn-list.php index 5f7cf5cdc3..02e69b0a16 100644 --- a/utils/syn-list.php +++ b/utils/syn-list.php @@ -21,7 +21,7 @@ function read_json() { return $json; } -function generate_synopsis( $command, $path ) { +function generate_synopsis( $command, $path = '' ) { $full_path = $path . ' ' . $command['name']; if ( !isset( $command['subcommands'] ) ) { @@ -33,9 +33,5 @@ function generate_synopsis( $command, $path ) { } } -$commands = read_json(); - -foreach ( $commands as $command ) { - generate_synopsis( $command, 'wp' ); -} +generate_synopsis( read_json() ); From b8f9cf653c717832703cab025d7c476f6dcac7ae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 21:49:30 +0200 Subject: [PATCH 1086/4858] move read_json() to separate file --- utils/syn-list.php | 16 +--------------- utils/utils.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 utils/utils.php diff --git a/utils/syn-list.php b/utils/syn-list.php index 02e69b0a16..4534d69c18 100644 --- a/utils/syn-list.php +++ b/utils/syn-list.php @@ -5,21 +5,7 @@ # # wp --cmd-dump | php /path/to/wp-cli/utils/syn-list.php -function read_json() { - $input = ''; - - while ( false !== ( $line = fgets( STDIN ) ) ) { - $input .= $line; - } - - $json = json_decode( $input, true ); - if ( !$json ) { - echo "Invalid JSON."; - exit(1); - } - - return $json; -} +include __DIR__ . '/utils.php'; function generate_synopsis( $command, $path = '' ) { $full_path = $path . ' ' . $command['name']; diff --git a/utils/utils.php b/utils/utils.php new file mode 100644 index 0000000000..eda9c6e19a --- /dev/null +++ b/utils/utils.php @@ -0,0 +1,18 @@ +<?php + +function read_json() { + $input = ''; + + while ( false !== ( $line = fgets( STDIN ) ) ) { + $input .= $line; + } + + $json = json_decode( $input, true ); + if ( !$json ) { + echo "Invalid JSON."; + exit(1); + } + + return $json; +} + From e95d0a0c149a940c824db5d8b99e04098f6c730f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 22:00:28 +0200 Subject: [PATCH 1087/4858] add cmd-list.php utility --- utils/cmd-list.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 utils/cmd-list.php diff --git a/utils/cmd-list.php b/utils/cmd-list.php new file mode 100644 index 0000000000..fe4b9e0723 --- /dev/null +++ b/utils/cmd-list.php @@ -0,0 +1,23 @@ +<?php + +# Given a list of commands as JSON on STDIN, generates an HTML table with the +# top-level commands. +# +# Example usage: +# +# wp --cmd-dump | php /path/to/wp-cli/utils/cmd-list.php + +include __DIR__ . '/utils.php'; + +$wp = read_json(); + +foreach ( $wp['subcommands'] as $command ) { + echo <<<EOB + <tr> + <td><a href="https://github.com/wp-cli/wp-cli/blob/master/php/commands/{$command['name']}.php">{$command['name']}</a></td> + <td>{$command['description']}</td> + </tr> + +EOB; +} + From da3099096f14c9c13de5e9e0a928d0366d7e8d03 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 22:46:00 +0200 Subject: [PATCH 1088/4858] convert all top-level command descriptions to the imperative mood --- php/commands/eval-file.php | 2 +- php/commands/eval.php | 2 +- php/commands/home.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index d5d2a4204d..8ee5b6e33d 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -3,7 +3,7 @@ class EvalFile_Command extends WP_CLI_Command { /** - * Loads and executes a PHP file after loading WordPress. + * Load and execute a PHP file after loading WordPress. * * @synopsis <path> */ diff --git a/php/commands/eval.php b/php/commands/eval.php index 131ca8455c..b8cd803cf5 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -3,7 +3,7 @@ class Eval_Command extends WP_CLI_Command { /** - * Executes arbitrary PHP code after loading WordPress. + * Execute arbitrary PHP code after loading WordPress. * * @synopsis <php-code> */ diff --git a/php/commands/home.php b/php/commands/home.php index a5ca3e6d33..fbb3b2fdcb 100644 --- a/php/commands/home.php +++ b/php/commands/home.php @@ -3,7 +3,7 @@ class Home_Command extends WP_CLI_Command { /** - * Opens the wp-cli homepage in your browser. + * Open the wp-cli homepage in your browser. */ function __invoke() { // The url for the wp-cli repository From 4996b66949204717ef889a9fb78574fef2c23f7c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 23:02:42 +0200 Subject: [PATCH 1089/4858] add 'internal' key and put it to use --- php/WP_CLI/Dispatcher/RootCommand.php | 11 ++++------- php/class-wp-cli.php | 1 + php/utils.php | 10 ++++++++++ utils/cmd-list.php | 3 +++ utils/syn-list.php | 3 +++ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 0e721678ca..e8ac4e532c 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -92,19 +92,16 @@ protected function load_all_commands() { } protected function load_command( $command ) { - if ( !isset( $this->subcommands[$command] ) ) { - $path = WP_CLI_ROOT . "/commands/$command.php"; - - if ( is_readable( $path ) ) { + if ( !isset( $this->subcommands[ $command ] ) ) { + if ( $path = \WP_CLI\Utils\get_command_file( $command ) ) include $path; - } } - if ( !isset( $this->subcommands[$command] ) ) { + if ( !isset( $this->subcommands[ $command ] ) ) { return false; } - return $this->subcommands[$command]; + return $this->subcommands[ $command ]; } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 085cb8fd16..432eb90039 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -404,6 +404,7 @@ private static function command_to_array( $command ) { $dump = array( 'name' => $command->get_name(), 'description' => $command->get_shortdesc(), + 'internal' => (bool) Utils\get_command_file( $command->get_name() ) ); if ( $command instanceof Dispatcher\AtomicCommand ) { diff --git a/php/utils.php b/php/utils.php index 8e27e5cbd8..bacf010206 100644 --- a/php/utils.php +++ b/php/utils.php @@ -124,6 +124,16 @@ function assoc_args_to_str( $assoc_args ) { return $str; } +function get_command_file( $command ) { + $path = WP_CLI_ROOT . "/commands/$command.php"; + + if ( !is_readable( $path ) ) { + return false; + } + + return $path; +} + /** * Run a given command. * diff --git a/utils/cmd-list.php b/utils/cmd-list.php index fe4b9e0723..a24a657882 100644 --- a/utils/cmd-list.php +++ b/utils/cmd-list.php @@ -12,6 +12,9 @@ $wp = read_json(); foreach ( $wp['subcommands'] as $command ) { + if ( !$command['internal'] ) + continue; + echo <<<EOB <tr> <td><a href="https://github.com/wp-cli/wp-cli/blob/master/php/commands/{$command['name']}.php">{$command['name']}</a></td> diff --git a/utils/syn-list.php b/utils/syn-list.php index 4534d69c18..218511cc08 100644 --- a/utils/syn-list.php +++ b/utils/syn-list.php @@ -8,6 +8,9 @@ include __DIR__ . '/utils.php'; function generate_synopsis( $command, $path = '' ) { + if ( isset( $command['internal'] ) && !$command['internal'] ) + continue; + $full_path = $path . ' ' . $command['name']; if ( !isset( $command['subcommands'] ) ) { From 54aecec3da553741aeeeef5a1c04ebba02439797 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 23:03:41 +0200 Subject: [PATCH 1090/4858] remove intermediate value in cmd_dump() --- php/class-wp-cli.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 432eb90039..7ab423d2c7 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -395,9 +395,7 @@ static function after_wp_load() { } private static function cmd_dump() { - $dump = self::command_to_array( self::$root ); - - echo json_encode( $dump ); + echo json_encode( self::command_to_array( self::$root ) ); } private static function command_to_array( $command ) { From 4c8326bfc65d5dc796d08b9fc5b64f132aad5da9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Jan 2013 23:17:23 +0200 Subject: [PATCH 1091/4858] move non-wp-related code out of after_wp_load() --- php/class-wp-cli.php | 2 ++ php/wp-cli.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7ab423d2c7..60a79659fc 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -372,7 +372,9 @@ static function after_wp_load() { if ( !defined( 'WP_INSTALLING' ) && isset( self::$config['url'] ) ) Utils\set_wp_query(); + } + static function run() { if ( isset( self::$config['require'] ) ) require self::$config['require']; diff --git a/php/wp-cli.php b/php/wp-cli.php index 57df1df426..0e28698e38 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -32,3 +32,5 @@ WP_CLI::after_wp_load(); +WP_CLI::run(); + From b1506d51b8dddfe397a3aea967e67385bd23fb6b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 Jan 2013 00:04:37 +0200 Subject: [PATCH 1092/4858] re-generate man pages --- man/cache.1 | 2 +- man/cap.1 | 10 +++++----- man/db.1 | 34 +++++++++++++++++----------------- man/export.1 | 2 +- man/option.1 | 16 ++++++++-------- man/post-meta.1 | 8 ++++---- man/scaffold-post-type.1 | 2 +- man/scaffold-taxonomy.1 | 2 +- man/transient.1 | 12 ++++++------ man/user-meta.1 | 8 ++++---- 10 files changed, 48 insertions(+), 48 deletions(-) diff --git a/man/cache.1 b/man/cache.1 index a0031ba3bc..19d4886d6c 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -4,7 +4,7 @@ .TH "WP\-CACHE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-cache\fR \- Manage the WordPress object cache\. +\fBwp\-cache\fR \- Manage the object cache\. . .SH "SYNOPSIS" wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cap.1 b/man/cap.1 index c129040464..5dfefa6548 100644 --- a/man/cap.1 +++ b/man/cap.1 @@ -4,7 +4,7 @@ .TH "WP\-CAP" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-cap\fR \- Manage capabilities\. +\fBwp\-cap\fR \- Manage user capabilities\. . .SH "SYNOPSIS" wp cap list \fIrole\fR @@ -18,16 +18,16 @@ wp cap remove \fIrole\fR \fIcap\fR\.\.\. .SH "SUBCOMMANDS" . .TP -\fBlist\fR: +\fBadd\fR: . .IP -List capabilities for a given role\. +Add capabilities to a given role\. . .TP -\fBadd\fR: +\fBlist\fR: . .IP -Add capabilities to a given role\. +List capabilities for a given role\. . .TP \fBremove\fR: diff --git a/man/db.1 b/man/db.1 index 7c16d0827c..319076f6e0 100644 --- a/man/db.1 +++ b/man/db.1 @@ -4,7 +4,7 @@ .TH "WP\-DB" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-db\fR \- Implement db command +\fBwp\-db\fR \- Perform basic database operations\. . .SH "SYNOPSIS" wp db create [\-\-str] @@ -36,40 +36,40 @@ wp db import [\fIfile\fR] [\-\-str] .SH "SUBCOMMANDS" . .TP -\fBcreate\fR: +\fBconnect\fR: . .IP -Create the database, as specified in wp\-config\.php +Open a mysql console using the WordPress credentials\. . .TP -\fBdrop\fR: +\fBcreate\fR: . .IP -Delete the database\. +Create the database, as specified in wp\-config\.php . .TP -\fBreset\fR: +\fBdrop\fR: . .IP -Remove all tables from the database\. +Delete the database\. . .TP -\fBoptimize\fR: +\fBexport\fR: . .IP -Optimize the database\. +Exports the database using mysqldump\. . .TP -\fBrepair\fR: +\fBimport\fR: . .IP -Repair the database\. +Import database from a file\. . .TP -\fBconnect\fR: +\fBoptimize\fR: . .IP -Open a mysql console using the WordPress credentials\. +Optimize the database\. . .TP \fBquery\fR: @@ -78,16 +78,16 @@ Open a mysql console using the WordPress credentials\. Execute a query against the database\. . .TP -\fBexport\fR: +\fBrepair\fR: . .IP -Exports the database using mysqldump\. +Repair the database\. . .TP -\fBimport\fR: +\fBreset\fR: . .IP -Import database from a file\. +Remove all tables from the database\. . .SH "OPTIONS" diff --git a/man/export.1 b/man/export.1 index 1e5e9b4fa3..17d770ab30 100644 --- a/man/export.1 +++ b/man/export.1 @@ -4,7 +4,7 @@ .TH "WP\-EXPORT" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-export\fR \- Export posts to a WXR file\. +\fBwp\-export\fR \- Export content to a WXR file\. . .SH "SYNOPSIS" wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post\fI\fIin=\fRpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] diff --git a/man/option.1 b/man/option.1 index b22d66884e..531d1c2c80 100644 --- a/man/option.1 +++ b/man/option.1 @@ -21,28 +21,28 @@ wp option delete \fIkey\fR .SH "SUBCOMMANDS" . .TP -\fBget\fR: +\fBadd\fR: . .IP -Get an option\. +Add an option\. . .TP -\fBadd\fR: +\fBdelete\fR: . .IP -Add an option\. +Delete an option\. . .TP -\fBupdate\fR: +\fBget\fR: . .IP -Update an option\. +Get an option\. . .TP -\fBdelete\fR: +\fBupdate\fR: . .IP -Delete an option\. +Update an option\. . .SH "OPTIONS" diff --git a/man/post-meta.1 b/man/post-meta.1 index c6cc6067eb..3a2cd20404 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -21,10 +21,10 @@ wp post\-meta update \fIid\fR \fIkey\fR \fIvalue\fR .SH "SUBCOMMANDS" . .TP -\fBget\fR: +\fBadd\fR: . .IP -Get meta field value\. +Add a meta field\. . .TP \fBdelete\fR: @@ -33,10 +33,10 @@ Get meta field value\. Delete a meta field\. . .TP -\fBadd\fR: +\fBget\fR: . .IP -Add a meta field\. +Get meta field value\. . .TP \fBupdate\fR: diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 index 0ecd3f15dd..208d21cda9 100644 --- a/man/scaffold-post-type.1 +++ b/man/scaffold-post-type.1 @@ -7,7 +7,7 @@ \fBwp\-scaffold\-post\-type\fR \- Generate PHP code for registering a custom post type\. . .SH "SYNOPSIS" -wp scaffold post\-type \fIslug\fR [\-\-description=\fIdescription\fR] [\-\-public=\fIpublic\fR] [\-\-exclude_from_search=\fIexclude_from_search\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_in_menu=\fIshow_in_menu\fR] [\-\-show_in_admin_bar=\fIshow_in_admin_bar\fR] [\-\-menu_position=\fImenu_position\fR] [\-\-menu_icon=\fImenu_icon\fR] [\-\-capability_type=\fIcapability_type\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-supports=\fIsupports\fR] [\-\-has_archive=\fIhas_archive\fR] [\-\-slug=\fIslug\fR] [\-\-feed=\fIfeed\fR] [\-\-pages=\fIpages\fR] [\-\-query_var=\fIquery_var\fR] [\-\-can_export=\fIcan_export\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +wp scaffold post\-type \fIslug\fR [\-\-singular=\fIlabel\fR] [\-\-description=\fIdescription\fR] [\-\-public=\fIpublic\fR] [\-\-exclude_from_search=\fIexclude_from_search\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_in_menu=\fIshow_in_menu\fR] [\-\-show_in_admin_bar=\fIshow_in_admin_bar\fR] [\-\-menu_position=\fImenu_position\fR] [\-\-menu_icon=\fImenu_icon\fR] [\-\-capability_type=\fIcapability_type\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-supports=\fIsupports\fR] [\-\-has_archive=\fIhas_archive\fR] [\-\-query_var=\fIquery_var\fR] [\-\-can_export=\fIcan_export\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] . .SH "OPTIONS" . diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index 0b82901868..d6f65ef62b 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -7,7 +7,7 @@ \fBwp\-scaffold\-taxonomy\fR \- Generate PHP code for registering a custom taxonomy\. . .SH "SYNOPSIS" -wp scaffold taxonomy \fIslug\fR [\-\-public=\fIpublic\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_tagcloud=\fIshow_tagcloud\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-rewrite=\fIrewrite\fR] [\-\-query_var=\fIquery_var\fR] [\-\-slug=\fIslug\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-post_types=\fIpost_types\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +wp scaffold taxonomy \fIslug\fR [\-\-singular=\fIlabel\fR] [\-\-public=\fIpublic\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_tagcloud=\fIshow_tagcloud\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-rewrite=\fIrewrite\fR] [\-\-query_var=\fIquery_var\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-post_types=\fIpost_types\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] . .SH "OPTIONS" . diff --git a/man/transient.1 b/man/transient.1 index d169ff381b..6c267b4391 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -21,22 +21,22 @@ wp transient type .SH "SUBCOMMANDS" . .TP -\fBget\fR: +\fBdelete\fR: . .IP -Get a transient value\. +Delete a transient value\. . .TP -\fBset\fR: +\fBget\fR: . .IP -Set a transient value\. \fIexpiration\fR is the time until expiration, in seconds\. +Get a transient value\. . .TP -\fBdelete\fR: +\fBset\fR: . .IP -Delete a transient value\. +Set a transient value\. \fIexpiration\fR is the time until expiration, in seconds\. . .TP \fBtype\fR: diff --git a/man/user-meta.1 b/man/user-meta.1 index 25719cdbce..b88a027f4f 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -21,10 +21,10 @@ wp user\-meta update \fIid\fR \fIkey\fR \fIvalue\fR .SH "SUBCOMMANDS" . .TP -\fBget\fR: +\fBadd\fR: . .IP -Get meta field value\. +Add a meta field\. . .TP \fBdelete\fR: @@ -33,10 +33,10 @@ Get meta field value\. Delete a meta field\. . .TP -\fBadd\fR: +\fBget\fR: . .IP -Add a meta field\. +Get meta field value\. . .TP \fBupdate\fR: From c53616eb2d7baee028e0c3eeeb178bff9322a474 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 Jan 2013 00:16:23 +0200 Subject: [PATCH 1093/4858] use --cmd-dump in compare-cmd --- utils/compare-cmd | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/utils/compare-cmd b/utils/compare-cmd index 21f6bc9b57..744d512b81 100755 --- a/utils/compare-cmd +++ b/utils/compare-cmd @@ -7,15 +7,15 @@ if [ $# -lt 3 ]; then exit 1 fi -ver_a=$1 -ver_b=$2 wp_path=$3 -git checkout $ver_a -wp --path=$wp_path --syn-list > /tmp/wp-cli-a +get_syn_list() { + git checkout $1 + wp --path=$wp_path --cmd-dump | php $(dirname $0)/syn-list.php +} -git checkout $ver_b -wp --path=$wp_path --syn-list > /tmp/wp-cli-b +get_syn_list $1 > /tmp/wp-cli-a +get_syn_list $2 > /tmp/wp-cli-b diff /tmp/wp-cli-a /tmp/wp-cli-b > cmd.diff From 285d651dd2d3dec1a779cdec7e3c5b7d68c41939 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 Jan 2013 10:15:32 +0200 Subject: [PATCH 1094/4858] remove site-related utilities (moved to site repo) --- utils/cmd-list.php | 26 -------------------------- utils/compare-cmd | 22 ---------------------- utils/syn-list.php | 26 -------------------------- utils/utils.php | 18 ------------------ 4 files changed, 92 deletions(-) delete mode 100644 utils/cmd-list.php delete mode 100755 utils/compare-cmd delete mode 100644 utils/syn-list.php delete mode 100644 utils/utils.php diff --git a/utils/cmd-list.php b/utils/cmd-list.php deleted file mode 100644 index a24a657882..0000000000 --- a/utils/cmd-list.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php - -# Given a list of commands as JSON on STDIN, generates an HTML table with the -# top-level commands. -# -# Example usage: -# -# wp --cmd-dump | php /path/to/wp-cli/utils/cmd-list.php - -include __DIR__ . '/utils.php'; - -$wp = read_json(); - -foreach ( $wp['subcommands'] as $command ) { - if ( !$command['internal'] ) - continue; - - echo <<<EOB - <tr> - <td><a href="https://github.com/wp-cli/wp-cli/blob/master/php/commands/{$command['name']}.php">{$command['name']}</a></td> - <td>{$command['description']}</td> - </tr> - -EOB; -} - diff --git a/utils/compare-cmd b/utils/compare-cmd deleted file mode 100755 index 744d512b81..0000000000 --- a/utils/compare-cmd +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# utility for comparing commands between two different wp-cli versions. - -if [ $# -lt 3 ]; then - echo 'usage: <version-a> <version-b> <wp-path>' - exit 1 -fi - -wp_path=$3 - -get_syn_list() { - git checkout $1 - wp --path=$wp_path --cmd-dump | php $(dirname $0)/syn-list.php -} - -get_syn_list $1 > /tmp/wp-cli-a -get_syn_list $2 > /tmp/wp-cli-b - -diff /tmp/wp-cli-a /tmp/wp-cli-b > cmd.diff - -echo 'Generated cmd.diff' diff --git a/utils/syn-list.php b/utils/syn-list.php deleted file mode 100644 index 218511cc08..0000000000 --- a/utils/syn-list.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -# Given a list of commands as JSON on STDIN, generates a list of synopses. -# -# Example usage: -# -# wp --cmd-dump | php /path/to/wp-cli/utils/syn-list.php - -include __DIR__ . '/utils.php'; - -function generate_synopsis( $command, $path = '' ) { - if ( isset( $command['internal'] ) && !$command['internal'] ) - continue; - - $full_path = $path . ' ' . $command['name']; - - if ( !isset( $command['subcommands'] ) ) { - echo $full_path . ' ' . $command['synopsis'] . "\n"; - } else { - foreach ( $command['subcommands'] as $subcommand ) { - generate_synopsis( $subcommand, $full_path ); - } - } -} - -generate_synopsis( read_json() ); - diff --git a/utils/utils.php b/utils/utils.php deleted file mode 100644 index eda9c6e19a..0000000000 --- a/utils/utils.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -function read_json() { - $input = ''; - - while ( false !== ( $line = fgets( STDIN ) ) ) { - $input .= $line; - } - - $json = json_decode( $input, true ); - if ( !$json ) { - echo "Invalid JSON."; - exit(1); - } - - return $json; -} - From ead705851091c7c2b576f94f24659d065fd8d9f3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 Jan 2013 10:33:18 +0200 Subject: [PATCH 1095/4858] run --cmd-dump without needing WP files --- php/class-wp-cli.php | 12 ++++++------ php/commands/blog.php | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 60a79659fc..930f837bf1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -309,6 +309,12 @@ static function before_wp_load() { exit; } + // Handle --cmd-dump parameter + if ( isset( self::$config['cmd-dump'] ) ) { + self::cmd_dump(); + exit; + } + $_SERVER['DOCUMENT_ROOT'] = getcwd(); // Handle --path @@ -383,11 +389,6 @@ static function run() { exit; } - if ( isset( self::$config['cmd-dump'] ) ) { - self::cmd_dump(); - exit; - } - if ( isset( self::$config['completions'] ) ) { self::render_automcomplete(); exit; @@ -404,7 +405,6 @@ private static function command_to_array( $command ) { $dump = array( 'name' => $command->get_name(), 'description' => $command->get_shortdesc(), - 'internal' => (bool) Utils\get_command_file( $command->get_name() ) ); if ( $command instanceof Dispatcher\AtomicCommand ) { diff --git a/php/commands/blog.php b/php/commands/blog.php index 52b868538d..92be6de203 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -149,7 +149,8 @@ protected static function get_blog_id_by_slug( $slug ) { } } -if ( is_multisite() ) { - WP_CLI::add_command( 'blog', 'Blog_Command' ); -} +if ( function_exists( 'is_multisite' ) && !is_multisite() ) + return; + +WP_CLI::add_command( 'blog', 'Blog_Command' ); From 1d06e0bd2cec69c3538eb0cded56ce02247dbeb8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 Jan 2013 10:48:12 +0200 Subject: [PATCH 1096/4858] replace just '<?php', instead of ignoring the whole line. fixes #271 --- php/utils.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index bacf010206..f1f19de2af 100644 --- a/php/utils.php +++ b/php/utils.php @@ -261,12 +261,11 @@ function get_wp_config_code() { $lines_to_run = array(); foreach ( $wp_config_code as $line ) { - if ( 0 === strpos( $line, '<?php' ) ) - continue; - if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) continue; + $line = preg_replace( '|^\s*\<\?php\s*|', '', $line ); + $lines_to_run[] = str_replace( $old, $new, $line ); } From 16ee34bc3619fea769b4318209006296e326d009 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 2 Jan 2013 10:50:34 +0200 Subject: [PATCH 1097/4858] run preg_replace() only once, on the whole string. see #271 --- php/utils.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index f1f19de2af..2405f394b5 100644 --- a/php/utils.php +++ b/php/utils.php @@ -264,12 +264,10 @@ function get_wp_config_code() { if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) continue; - $line = preg_replace( '|^\s*\<\?php\s*|', '', $line ); - $lines_to_run[] = str_replace( $old, $new, $line ); } - return implode( "\n", $lines_to_run ); + return preg_replace( '|^\s*\<\?php\s*|', '', implode( "\n", $lines_to_run ) ); } /** From eb813fae9911eebbdce3ec0ca3a40d5f6c10a0e6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 Jan 2013 01:44:58 +0200 Subject: [PATCH 1098/4858] change template extensions from .php to .mustache, to avoid compatibility issues with pre-commit linters etc. --- php/commands/scaffold.php | 10 +++++----- php/templates/{plugin.php => plugin.mustache} | 0 php/templates/{post_type.php => post_type.mustache} | 0 ...t_type_extended.php => post_type_extended.mustache} | 0 php/templates/{taxonomy.php => taxonomy.mustache} | 0 ...axonomy_extended.php => taxonomy_extended.mustache} | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename php/templates/{plugin.php => plugin.mustache} (100%) rename php/templates/{post_type.php => post_type.mustache} (100%) rename php/templates/{post_type_extended.php => post_type_extended.mustache} (100%) rename php/templates/{taxonomy.php => taxonomy.mustache} (100%) rename php/templates/{taxonomy_extended.php => taxonomy_extended.mustache} (100%) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 401c1a97c2..73584b000c 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -42,8 +42,8 @@ function post_type( $args, $assoc_args ) { ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/post-types/', array( - 'post_type.php', - 'post_type_extended.php' + 'post_type.mustache', + 'post_type_extended.mustache' ) ); } @@ -73,8 +73,8 @@ function taxonomy( $args, $assoc_args ) { ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/taxonomies/', array( - 'taxonomy.php', - 'taxonomy_extended.php' + 'taxonomy.mustache', + 'taxonomy_extended.mustache' ) ); } @@ -166,7 +166,7 @@ function plugin( $args, $assoc_args ) { $data['textdomain'] = $plugin_slug; - $plugin_contents = $this->render( 'plugin.php', $data ); + $plugin_contents = $this->render( 'plugin.mustache', $data ); $plugin_path = WP_PLUGIN_DIR . "/$plugin_slug/$plugin_slug.php"; diff --git a/php/templates/plugin.php b/php/templates/plugin.mustache similarity index 100% rename from php/templates/plugin.php rename to php/templates/plugin.mustache diff --git a/php/templates/post_type.php b/php/templates/post_type.mustache similarity index 100% rename from php/templates/post_type.php rename to php/templates/post_type.mustache diff --git a/php/templates/post_type_extended.php b/php/templates/post_type_extended.mustache similarity index 100% rename from php/templates/post_type_extended.php rename to php/templates/post_type_extended.mustache diff --git a/php/templates/taxonomy.php b/php/templates/taxonomy.mustache similarity index 100% rename from php/templates/taxonomy.php rename to php/templates/taxonomy.mustache diff --git a/php/templates/taxonomy_extended.php b/php/templates/taxonomy_extended.mustache similarity index 100% rename from php/templates/taxonomy_extended.php rename to php/templates/taxonomy_extended.mustache From 546dd84c34062ba4b7b1296a5dae4266900087e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 Jan 2013 01:49:32 +0200 Subject: [PATCH 1099/4858] remove unused '<?php' from templates was only used to get syntax highlighting, when the templates ended in .php --- php/commands/scaffold.php | 1 - php/templates/post_type.mustache | 1 - php/templates/taxonomy.mustache | 1 - 3 files changed, 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 73584b000c..d14567cdbc 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -111,7 +111,6 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) list( $raw_template, $extended_template ) = $templates; $raw_output = $this->render( $raw_template, $vars ); - $raw_output = str_replace( "<?php", '', $raw_output ); if ( ! $control_args['raw'] ) { $vars = array_merge( $vars, array( diff --git a/php/templates/post_type.mustache b/php/templates/post_type.mustache index 323460d4f8..00e9d652d0 100644 --- a/php/templates/post_type.mustache +++ b/php/templates/post_type.mustache @@ -1,4 +1,3 @@ -<?php register_post_type( '{{slug}}', array( 'description' => __( '{{description}}', '{{textdomain}}' ), 'public' => {{public}}, diff --git a/php/templates/taxonomy.mustache b/php/templates/taxonomy.mustache index 7c1003a51d..db2ba2e370 100644 --- a/php/templates/taxonomy.mustache +++ b/php/templates/taxonomy.mustache @@ -1,4 +1,3 @@ -<?php register_taxonomy( '{{slug}}', array( '{{post_types}}' ), array( 'public' => {{public}}, 'show_in_nav_menus' => {{show_in_nav_menus}}, From c479691ed04311a4d641ab0bdbb39d79ac5172f3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 3 Jan 2013 01:50:43 +0200 Subject: [PATCH 1100/4858] scaffold taxonomy: remove control args from defaults --- php/commands/scaffold.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d14567cdbc..939ed05bc5 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -67,9 +67,6 @@ function taxonomy( $args, $assoc_args ) { 'query_var' => 'true', 'post_types' => 'post', 'textdomain' => '', - 'theme' => false, - 'plugin' => false, - 'raw' => false, ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/taxonomies/', array( From 2eba6a2107edb698db2d8a9ed32949d8121ef7ba Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 15 Jan 2013 15:29:49 +0200 Subject: [PATCH 1101/4858] move run_command() back into the WP_CLI class --- php/class-wp-cli.php | 36 ++++++++++++++++++++++++++++++------ php/commands/scaffold.php | 2 +- php/utils.php | 24 ------------------------ 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 930f837bf1..0ff541dbc8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -324,7 +324,7 @@ static function before_wp_load() { Utils\set_url( self::$config ); if ( array( 'core', 'download' ) == self::$arguments ) { - self::run_command(); + self::_run_command(); exit; } @@ -335,7 +335,7 @@ static function before_wp_load() { } if ( array( 'core', 'config' ) == self::$arguments ) { - self::run_command(); + self::_run_command(); exit; } @@ -347,7 +347,7 @@ static function before_wp_load() { if ( self::cmd_starts_with( array( 'db' ) ) ) { eval( Utils\get_wp_config_code() ); - self::run_command(); + self::_run_command(); exit; } @@ -394,7 +394,7 @@ static function run() { exit; } - self::run_command(); + self::_run_command(); } private static function cmd_dump() { @@ -418,8 +418,32 @@ private static function command_to_array( $command ) { return $dump; } - private static function run_command() { - Utils\run_command( self::$arguments, self::$assoc_args ); + private static function _run_command() { + self::run_command( self::$arguments, self::$assoc_args ); + } + + /** + * Run a given command. + * + * @param array + * @param array + */ + public static function run_command( $args, $assoc_args = array() ) { + $command = self::$root; + + while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { + $subcommand = $command->pre_invoke( $args ); + if ( !$subcommand ) + break; + + $command = $subcommand; + } + + if ( $command instanceof Dispatcher\CommandContainer ) { + $command->show_usage(); + } else { + $command->invoke( $args, $assoc_args ); + } } private static function show_info() { diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 939ed05bc5..b5511feb23 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -171,7 +171,7 @@ function plugin( $args, $assoc_args ) { WP_CLI::success( "Plugin scaffold created: $plugin_path" ); if ( isset( $assoc_args['activate'] ) ) - \WP_CLI\Utils\run_command( array( 'plugin', 'activate', $plugin_slug ) ); + WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); } private function create_file( $filename, $contents ) { diff --git a/php/utils.php b/php/utils.php index 2405f394b5..4c87eb9082 100644 --- a/php/utils.php +++ b/php/utils.php @@ -134,30 +134,6 @@ function get_command_file( $command ) { return $path; } -/** - * Run a given command. - * - * @param array - * @param array - */ -function run_command( $args, $assoc_args = array() ) { - $command = \WP_CLI::$root; - - while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { - $subcommand = $command->pre_invoke( $args ); - if ( !$subcommand ) - break; - - $command = $subcommand; - } - - if ( $command instanceof Dispatcher\CommandContainer ) { - $command->show_usage(); - } else { - $command->invoke( $args, $assoc_args ); - } -} - function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $url = $assoc_args['url']; From 4db02be698fb47c4cd4eb10fe1d24b0fdab30257 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 19 Jan 2013 15:14:16 +0200 Subject: [PATCH 1102/4858] add 'color' config option. fixes #267 --- php/class-wp-cli.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0ff541dbc8..d3729e97e8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -103,7 +103,7 @@ static function out( $message, $handle = STDOUT ) { if ( WP_CLI_QUIET ) return; - fwrite( $handle, \cli\Colors::colorize( $message, ! \cli\Shell::isPiped() ) ); + fwrite( $handle, \cli\Colors::colorize( $message, self::$config['color'] ) ); } /** @@ -287,12 +287,15 @@ static function before_wp_load() { ); self::$config = Utils\load_config( array( - 'path', 'url', 'user', 'disabled_commands' + 'path', 'url', 'user', 'disabled_commands', 'color' ) ); if ( !isset( self::$config['disabled_commands'] ) ) self::$config['disabled_commands'] = array(); + if ( !isset( self::$config['colors'] ) ) + self::$config['colors'] = ! \cli\Shell::isPiped(); + self::parse_args(); define( 'WP_CLI_QUIET', isset( self::$config['quiet'] ) ); From 64f26b484c6fd14aaf8c6c2f92f7bac0d0738fd3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 19 Jan 2013 15:19:56 +0200 Subject: [PATCH 1103/4858] 'color', not 'colors'. see #267 --- php/class-wp-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d3729e97e8..4b07b295c0 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -293,8 +293,8 @@ static function before_wp_load() { if ( !isset( self::$config['disabled_commands'] ) ) self::$config['disabled_commands'] = array(); - if ( !isset( self::$config['colors'] ) ) - self::$config['colors'] = ! \cli\Shell::isPiped(); + if ( !isset( self::$config['color'] ) ) + self::$config['color'] = ! \cli\Shell::isPiped(); self::parse_args(); From 945a57c764969fdbe0d53e930ecec10e263f170a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 19 Jan 2013 15:45:52 +0200 Subject: [PATCH 1104/4858] add --config global parameter. fixes #272 --- php/WP_CLI/Dispatcher/RootCommand.php | 9 +++--- php/class-wp-cli.php | 21 ++++++++------ php/utils.php | 40 ++++++++++++++++++--------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index e8ac4e532c..84c5a19db7 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -35,10 +35,11 @@ function show_usage() { See 'wp help <command>' for more information on a specific command. Global parameters: ---user=<id|login> set the current user ---url=<url> set the current URL ---path=<path> set the current path to the WP install ---require=<path> load a certain file before running the command +--user=<id|login> set the WordPress user +--url=<url> set the URL +--path=<path> set the path to the WP install +--config=<path> set the path to the wp-cli config file +--require=<path> load a certain PHP file before running the command --quiet suppress informational messages --info print wp-cli information EOB diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 4b07b295c0..d4ae0b4049 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -14,7 +14,7 @@ class WP_CLI { private static $man_dirs = array(); - private static $config; + private static $config_path, $config; private static $arguments, $assoc_args; @@ -258,11 +258,6 @@ private static function parse_args() { self::$arguments[1] = 'update-all'; unset( self::$assoc_args['all'] ); } - - self::split_special( array( - 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'completions', 'man', 'cmd-dump' - ) ); } private static function split_special( $special_keys ) { @@ -286,18 +281,25 @@ static function before_wp_load() { WP_CLI_ROOT . "../man-src/" ); - self::$config = Utils\load_config( array( + self::parse_args(); + + self::$config_path = Utils\get_config_path( self::$assoc_args ); + + self::$config = Utils\load_config( self::$config_path, array( 'path', 'url', 'user', 'disabled_commands', 'color' ) ); + self::split_special( array( + 'path', 'url', 'blog', 'user', 'require', + 'quiet', 'completions', 'man', 'cmd-dump' + ) ); + if ( !isset( self::$config['disabled_commands'] ) ) self::$config['disabled_commands'] = array(); if ( !isset( self::$config['color'] ) ) self::$config['color'] = ! \cli\Shell::isPiped(); - self::parse_args(); - define( 'WP_CLI_QUIET', isset( self::$config['quiet'] ) ); // Handle --version parameter @@ -456,6 +458,7 @@ private static function show_info() { WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); + WP_CLI::line( "wp-cli config:\t" . self::$config_path ); WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); } diff --git a/php/utils.php b/php/utils.php index 4c87eb9082..d6e3449a63 100644 --- a/php/utils.php +++ b/php/utils.php @@ -51,25 +51,39 @@ function register_autoload() { } ); } -function load_config( $allowed_keys ) { - foreach ( array( 'wp-cli.local.yml', 'wp-cli.yml' ) as $fname ) { - $path = getcwd() . '/' . $fname; +function load_config( $path, $allowed_keys ) { + if ( !$path ) + return array(); - if ( file_exists( $path ) ) { - $config = spyc_load_file( $path ); + $config = spyc_load_file( $path ); - $sanitized_config = array(); + $sanitized_config = array(); - foreach ( $allowed_keys as $key ) { - if ( isset( $config[ $key ] ) ) - $sanitized_config[ $key ] = $config[ $key ]; - } + foreach ( $allowed_keys as $key ) { + if ( isset( $config[ $key ] ) ) + $sanitized_config[ $key ] = $config[ $key ]; + } - return $sanitized_config; - } + return $sanitized_config; +} + +function get_config_path( $assoc_args ) { + if ( isset( $assoc_args['config'] ) ) { + $paths = array( $assoc_args['config'] ); + unset( $assoc_args['config'] ); + } else { + $paths = array( + getcwd() . '/wp-cli.local.yml', + getcwd() . 'wp-cli.yml' + ); + } + + foreach ( $paths as $path ) { + if ( file_exists( $path ) ) + return $path; } - return array(); + return false; } /** From 27c17f3e3aabe7af53ecc6271bf07e3d0ecec496 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 19 Jan 2013 21:34:51 +0200 Subject: [PATCH 1105/4858] fix path to wp-cli.yml. see #267 --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index d6e3449a63..92a6062f3d 100644 --- a/php/utils.php +++ b/php/utils.php @@ -74,7 +74,7 @@ function get_config_path( $assoc_args ) { } else { $paths = array( getcwd() . '/wp-cli.local.yml', - getcwd() . 'wp-cli.yml' + getcwd() . '/wp-cli.yml' ); } From 372c8f15f40664f41e5e6870c5cb6f4b71c78a24 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 19 Jan 2013 21:36:05 +0200 Subject: [PATCH 1106/4858] add --debug global param. fixes #177 --- php/WP_CLI/Dispatcher/RootCommand.php | 1 + php/class-wp-cli.php | 22 ++++++++++++++++++---- php/utils-wp.php | 9 +++++++++ php/wp-cli.php | 2 ++ php/wp-settings-cli.php | 8 ++++---- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 84c5a19db7..a0712ca80c 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -41,6 +41,7 @@ function show_usage() { --config=<path> set the path to the wp-cli config file --require=<path> load a certain PHP file before running the command --quiet suppress informational messages +--debug show all PHP errors --info print wp-cli information EOB ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d4ae0b4049..d8e2c9dde7 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -269,8 +269,14 @@ private static function split_special( $special_keys ) { } } - static function get_config() { - return self::$config; + static function get_config( $key = null ) { + if ( null === $key ) + return self::$config; + + if ( !isset( self::$config[ $key ] ) ) + return null; + + return self::$config[ $key ]; } static function before_wp_load() { @@ -286,12 +292,13 @@ static function before_wp_load() { self::$config_path = Utils\get_config_path( self::$assoc_args ); self::$config = Utils\load_config( self::$config_path, array( - 'path', 'url', 'user', 'disabled_commands', 'color' + 'path', 'url', 'user', 'debug', 'disabled_commands', 'color' ) ); self::split_special( array( 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'completions', 'man', 'cmd-dump' + 'quiet', 'debug', + 'completions', 'man', 'cmd-dump' ) ); if ( !isset( self::$config['disabled_commands'] ) ) @@ -376,6 +383,13 @@ private static function cmd_starts_with( $prefix ) { return $prefix == array_slice( self::$arguments, 0, count( $prefix ) ); } + static function after_wp_config_load() { + if ( isset( self::$config['debug'] ) ) { + if ( !defined( 'WP_DEBUG' ) ) + define( 'WP_DEBUG', true ); + } + } + static function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); diff --git a/php/utils-wp.php b/php/utils-wp.php index 01777c211a..0fb19ff060 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -12,6 +12,15 @@ function wp_not_installed() { } } +function wp_debug_mode() { + if ( \WP_CLI::get_config( 'debug' ) ) { + error_reporting( E_ALL & ~E_DEPRECATED & ~E_STRICT ); + ini_set( 'display_errors', true ); + } else { + \wp_debug_mode(); + } +} + function maybe_require( $since, $path ) { global $wp_version; diff --git a/php/wp-cli.php b/php/wp-cli.php index 0e28698e38..995c549f61 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -22,6 +22,8 @@ eval( \WP_CLI\Utils\get_wp_config_code() ); +WP_CLI::after_wp_config_load(); + require WP_CLI_ROOT . 'wp-settings-cli.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 04b784a895..7855768a52 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -39,8 +39,11 @@ // Start loading timer. timer_start(); +// Load WP-CLI utilities +require WP_CLI_ROOT . 'utils-wp.php'; + // Check if we're in WP_DEBUG mode. -wp_debug_mode(); +Utils\wp_debug_mode(); // Define WP_LANG_DIR if not set. wp_set_lang_dir(); @@ -80,9 +83,6 @@ if ( SHORTINIT ) return false; -// Load WP-CLI utilities -require WP_CLI_ROOT . 'utils-wp.php'; - // Load the L10n library. require_once( ABSPATH . WPINC . '/l10n.php' ); From c1e9a983c443e2d73285ce0fe6d74af2437878b1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 20 Jan 2013 06:05:39 +0200 Subject: [PATCH 1107/4858] merge back run() method into after_wp_load() not needed and avoids confusion with run_command() --- php/class-wp-cli.php | 2 -- php/wp-cli.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d8e2c9dde7..a4b8c266a6 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -397,9 +397,7 @@ static function after_wp_load() { if ( !defined( 'WP_INSTALLING' ) && isset( self::$config['url'] ) ) Utils\set_wp_query(); - } - static function run() { if ( isset( self::$config['require'] ) ) require self::$config['require']; diff --git a/php/wp-cli.php b/php/wp-cli.php index 995c549f61..5799cf04ac 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -34,5 +34,3 @@ WP_CLI::after_wp_load(); -WP_CLI::run(); - From d3be4048c2871717e887383ae5ffbd4fdc7070b4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 20 Jan 2013 18:53:28 +0200 Subject: [PATCH 1108/4858] replace WP_ROOT with ABSPATH --- php/class-wp-cli.php | 2 +- php/commands/core.php | 4 ++-- php/utils.php | 16 ++++++++-------- php/wp-cli.php | 2 -- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index a4b8c266a6..e8e97001a1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -340,7 +340,7 @@ static function before_wp_load() { exit; } - if ( !is_readable( WP_ROOT . 'wp-load.php' ) ) { + if ( !is_readable( ABSPATH . 'wp-load.php' ) ) { WP_CLI::error( "This does not seem to be a WordPress install.", false ); WP_CLI::line( "Pass --path=`path/to/wordpress` or run `wp core download`." ); exit(1); diff --git a/php/commands/core.php b/php/commands/core.php index f3d70f48d7..3b442f5df4 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -13,7 +13,7 @@ class Core_Command extends WP_CLI_Command { * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] */ public function download( $args, $assoc_args ) { - if ( is_readable( WP_ROOT . 'wp-load.php' ) ) + if ( is_readable( ABSPATH . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); if ( isset( $assoc_args['path'] ) ) @@ -55,7 +55,7 @@ public function config( $args, $assoc_args ) { $_GET['step'] = 2; if ( WP_CLI_QUIET ) ob_start(); - require WP_ROOT . '/wp-admin/setup-config.php'; + require ABSPATH . '/wp-admin/setup-config.php'; if ( WP_CLI_QUIET ) ob_end_clean(); } diff --git a/php/utils.php b/php/utils.php index 92a6062f3d..974b81c2b3 100644 --- a/php/utils.php +++ b/php/utils.php @@ -158,10 +158,10 @@ function set_url( $assoc_args ) { if ( true === $url ) { \WP_CLI::line( 'usage: wp --blog=example.com' ); } - } elseif ( is_readable( WP_ROOT . 'wp-cli-blog' ) ) { + } elseif ( is_readable( ABSPATH . 'wp-cli-blog' ) ) { \WP_CLI::warning( 'The wp-cli-blog file is deprecated. Use wp-cli.yml instead.' ); - $url = trim( file_get_contents( WP_ROOT . 'wp-cli-blog' ) ); + $url = trim( file_get_contents( ABSPATH . 'wp-cli-blog' ) ); } elseif ( $wp_config_path = locate_wp_config() ) { // Try to find the blog parameter in the wp-config file $wp_config_file = file_get_contents( $wp_config_path ); @@ -214,18 +214,18 @@ function set_url_params( $url ) { function set_wp_root( $config ) { if ( !empty( $config['path'] ) ) { - define( 'WP_ROOT', rtrim( $config['path'], '/' ) . '/' ); + define( 'ABSPATH', rtrim( $config['path'], '/' ) . '/' ); } else { - define( 'WP_ROOT', getcwd() . '/' ); + define( 'ABSPATH', getcwd() . '/' ); } } function locate_wp_config() { - if ( file_exists( WP_ROOT . 'wp-config.php' ) ) - return WP_ROOT . 'wp-config.php'; + if ( file_exists( ABSPATH . 'wp-config.php' ) ) + return ABSPATH . 'wp-config.php'; - if ( file_exists( WP_ROOT . '/../wp-config.php' ) && ! file_exists( WP_ROOT . '/../wp-settings.php' ) ) - return WP_ROOT . '/../wp-config.php'; + if ( file_exists( ABSPATH . '/../wp-config.php' ) && ! file_exists( ABSPATH . '/../wp-settings.php' ) ) + return ABSPATH . '/../wp-config.php'; return false; } diff --git a/php/wp-cli.php b/php/wp-cli.php index 5799cf04ac..d9b16b3bda 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -18,8 +18,6 @@ WP_CLI::before_wp_load(); // Load WordPress, in the global scope -define( 'ABSPATH', WP_ROOT ); - eval( \WP_CLI\Utils\get_wp_config_code() ); WP_CLI::after_wp_config_load(); From d921490e71c185965d61e9911d802fc71fb9acc1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 20 Jan 2013 06:03:34 +0200 Subject: [PATCH 1109/4858] add config spec --- php/class-wp-cli.php | 27 +++++----------- php/config-spec.php | 74 ++++++++++++++++++++++++++++++++++++++++++++ php/utils.php | 48 ++++++++++++++++++++++------ 3 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 php/config-spec.php diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e8e97001a1..6bc586414a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -260,15 +260,6 @@ private static function parse_args() { } } - private static function split_special( $special_keys ) { - foreach ( $special_keys as $key ) { - if ( isset( self::$assoc_args[ $key ] ) ) { - self::$config[ $key ] = self::$assoc_args[ $key ]; - unset( self::$assoc_args[ $key ] ); - } - } - } - static function get_config( $key = null ) { if ( null === $key ) return self::$config; @@ -289,17 +280,13 @@ static function before_wp_load() { self::parse_args(); + $config_spec = Utils\get_config_spec(); + self::$config_path = Utils\get_config_path( self::$assoc_args ); - self::$config = Utils\load_config( self::$config_path, array( - 'path', 'url', 'user', 'debug', 'disabled_commands', 'color' - ) ); + self::$config = Utils\load_config( self::$config_path, $config_spec ); - self::split_special( array( - 'path', 'url', 'blog', 'user', 'require', - 'quiet', 'debug', - 'completions', 'man', 'cmd-dump' - ) ); + Utils\split_special( self::$assoc_args, self::$config, $config_spec ); if ( !isset( self::$config['disabled_commands'] ) ) self::$config['disabled_commands'] = array(); @@ -322,7 +309,7 @@ static function before_wp_load() { } // Handle --cmd-dump parameter - if ( isset( self::$config['cmd-dump'] ) ) { + if ( isset( self::$assoc_args['cmd-dump'] ) ) { self::cmd_dump(); exit; } @@ -401,12 +388,12 @@ static function after_wp_load() { if ( isset( self::$config['require'] ) ) require self::$config['require']; - if ( isset( self::$config['man'] ) ) { + if ( isset( self::$assoc_args['man'] ) ) { self::generate_man( self::$arguments ); exit; } - if ( isset( self::$config['completions'] ) ) { + if ( isset( self::$assoc_args['completions'] ) ) { self::render_automcomplete(); exit; } diff --git a/php/config-spec.php b/php/config-spec.php new file mode 100644 index 0000000000..885ffeee03 --- /dev/null +++ b/php/config-spec.php @@ -0,0 +1,74 @@ +<?php + +return array( + 'path' => array( + 'runtime' => true, + 'file' => true, + 'default' => null, + 'desc' => 'Path to the WordPress files', + 'synopsis' => '<path>' + ), + + 'url' => array( + 'runtime' => true, + 'file' => true, + 'default' => null, + 'desc' => 'Pretend request came from given URL', + 'synopsis' => '<url>' + ), + 'blog' => array( + 'deprecated' => 'Use --url instead', + 'runtime' => true, + 'file' => false, + 'default' => null, + 'synopsis' => '<url>', + ), + + 'user' => array( + 'runtime' => true, + 'file' => true, + 'default' => null, + 'desc' => 'Set the WordPress user', + 'synopsis' => '<id|login>' + ), + + 'require' => array( + 'runtime' => true, + 'file' => true, + 'default' => null, + 'desc' => 'Load given PHP file before running the command', + 'synopsis' => '<path>' + ), + + 'disabled_commands' => array( + 'runtime' => false, + 'file' => true, + 'default' => array(), + 'desc' => '(Sub)commands to disable', + ), + + 'color' => array( + 'runtime' => true, + 'file' => true, + 'default' => false, + 'desc' => 'Show all PHP errors.', + 'synopsis' => '<bool>', + ), + + 'debug' => array( + 'runtime' => true, + 'file' => true, + 'default' => false, + 'desc' => 'Show all PHP errors.', + 'synopsis' => '', + ), + + 'quiet' => array( + 'runtime' => true, + 'file' => true, + 'default' => false, + 'desc' => 'Show all PHP errors.', + 'synopsis' => '<bool>', + ), +); + diff --git a/php/utils.php b/php/utils.php index 974b81c2b3..88a49f4c95 100644 --- a/php/utils.php +++ b/php/utils.php @@ -51,20 +51,25 @@ function register_autoload() { } ); } -function load_config( $path, $allowed_keys ) { - if ( !$path ) - return array(); +function get_config_spec() { + static $spec; - $config = spyc_load_file( $path ); + if ( !$spec ) { + $spec = include __DIR__ . '/config-spec.php'; - $sanitized_config = array(); + $defaults = array( + 'runtime' => false, + 'file' => false, + 'synopsis' => '', + 'default' => null, + ); - foreach ( $allowed_keys as $key ) { - if ( isset( $config[ $key ] ) ) - $sanitized_config[ $key ] = $config[ $key ]; + foreach ( $spec as &$option ) { + $option = array_merge( $defaults, $option ); + } } - return $sanitized_config; + return $spec; } function get_config_path( $assoc_args ) { @@ -86,6 +91,31 @@ function get_config_path( $assoc_args ) { return false; } +function load_config( $path, $spec ) { + if ( !$path ) + return array(); + + $config = spyc_load_file( $path ); + + $sanitized_config = array(); + + foreach ( $spec as $key => $details ) { + if ( $details['file'] && isset( $config[ $key ] ) ) + $sanitized_config[ $key ] = $config[ $key ]; + } + + return $sanitized_config; +} + +function split_special( &$assoc_args, &$config, $spec ) { + foreach ( $spec as $key => $details ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } + } +} + /** * Splits $argv into positional and associative arguments. * From 3bac46f3e48fc793fc9e8bfdd16683691f9bdecf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 20 Jan 2013 18:30:50 +0200 Subject: [PATCH 1110/4858] add tests for --quiet flag and don't suppress output on fatal error --- php/class-wp-cli.php | 10 ++-------- tests/spec-flags.php | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 tests/spec-flags.php diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 6bc586414a..91405b4a86 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -124,8 +124,8 @@ static function line( $message = '' ) { static function error( $message, $exit = true ) { if ( !isset( self::$config['completions'] ) ) { $label = 'Error'; - $msg = '%R' . $label . ': %n' . self::error_to_string( $message ); - self::out( $msg . "\n", STDERR ); + $msg = '%R' . $label . ': %n' . self::error_to_string( $message ) . "\n"; + fwrite( STDERR, \cli\Colors::colorize( $msg, self::$config['color'] ) ); } if ( $exit ) @@ -139,9 +139,6 @@ static function error( $message, $exit = true ) { * @param string $label */ static function success( $message, $label = 'Success' ) { - if ( WP_CLI_QUIET ) - return; - self::line( '%G' . $label . ': %n' . $message ); } @@ -152,9 +149,6 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { - if ( WP_CLI_QUIET ) - return; - $msg = '%C' . $label . ': %n' . self::error_to_string( $message ); self::out( $msg . "\n", STDERR ); } diff --git a/tests/spec-flags.php b/tests/spec-flags.php new file mode 100644 index 0000000000..6ca84276b6 --- /dev/null +++ b/tests/spec-flags.php @@ -0,0 +1,24 @@ +<?php + +class FlagsSpec extends WP_CLI_Spec { + + /** @scenario */ + public function quietRun() { + $this + ->given( 'empty dir' ) + ->and( 'wp install' ) + + ->when( 'invoking', '' ) + ->then( 'return code should be', 0 ) + ->and( 'should have output' ) + + ->when( 'invoking', '--quiet' ) + ->then( 'return code should be', 0 ) + ->and( 'output should be', '' ) + + ->when( 'invoking', 'wp non-existing-command --quiet' ) + ->then( 'return code should be', 1 ) + ->and( 'should have output' ); + } +} + From e95fae9d35193bbaffcc3d3d6617744cd1e70c99 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 20 Jan 2013 18:35:44 +0200 Subject: [PATCH 1111/4858] replace WP_CLI_QUIET with WP_CLI::get_config('quiet') --- php/class-wp-cli.php | 4 +--- php/commands/core.php | 8 +++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 91405b4a86..61f1cb6c75 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -100,7 +100,7 @@ static function get_man_dirs() { * @param string $message */ static function out( $message, $handle = STDOUT ) { - if ( WP_CLI_QUIET ) + if ( self::get_config('quiet') ) return; fwrite( $handle, \cli\Colors::colorize( $message, self::$config['color'] ) ); @@ -288,8 +288,6 @@ static function before_wp_load() { if ( !isset( self::$config['color'] ) ) self::$config['color'] = ! \cli\Shell::isPiped(); - define( 'WP_CLI_QUIET', isset( self::$config['quiet'] ) ); - // Handle --version parameter if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { self::line( 'wp-cli ' . WP_CLI_VERSION ); diff --git a/php/commands/core.php b/php/commands/core.php index 3b442f5df4..ac9600ebfd 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -34,7 +34,9 @@ public function download( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - WP_CLI::launch( 'curl -f' . (WP_CLI_QUIET ? ' --silent ' : ' ') . escapeshellarg( $download_url ) . ' | tar xz' ); + $silent = WP_CLI::get_config('quiet') ? ' --silent ' : ' '; + + WP_CLI::launch( 'curl -f' . $silent . escapeshellarg( $download_url ) . ' | tar xz' ); WP_CLI::launch( 'mv wordpress/* . && rm -rf wordpress' ); WP_CLI::success( 'WordPress downloaded.' ); @@ -54,9 +56,9 @@ public function config( $args, $assoc_args ) { $_GET['step'] = 2; - if ( WP_CLI_QUIET ) ob_start(); + if ( WP_CLI::get_config('quiet') ) ob_start(); require ABSPATH . '/wp-admin/setup-config.php'; - if ( WP_CLI_QUIET ) ob_end_clean(); + if ( WP_CLI::get_config('quiet') ) ob_end_clean(); } /** From 7db452324528def6086473b9587e33dc5209153a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 20 Jan 2013 19:08:39 +0200 Subject: [PATCH 1112/4858] make use of defaults --- php/class-wp-cli.php | 9 ++++----- php/config-spec.php | 2 +- php/utils.php | 10 ++++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 61f1cb6c75..4b0f68a9a1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -258,8 +258,10 @@ static function get_config( $key = null ) { if ( null === $key ) return self::$config; - if ( !isset( self::$config[ $key ] ) ) + if ( !isset( self::$config[ $key ] ) ) { + self::warning( "Unknown config option '$key'." ); return null; + } return self::$config[ $key ]; } @@ -282,10 +284,7 @@ static function before_wp_load() { Utils\split_special( self::$assoc_args, self::$config, $config_spec ); - if ( !isset( self::$config['disabled_commands'] ) ) - self::$config['disabled_commands'] = array(); - - if ( !isset( self::$config['color'] ) ) + if ( 'auto' == self::$config['color'] ) self::$config['color'] = ! \cli\Shell::isPiped(); // Handle --version parameter diff --git a/php/config-spec.php b/php/config-spec.php index 885ffeee03..07c3aa1308 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -50,7 +50,7 @@ 'color' => array( 'runtime' => true, 'file' => true, - 'default' => false, + 'default' => 'auto', 'desc' => 'Show all PHP errors.', 'synopsis' => '<bool>', ), diff --git a/php/utils.php b/php/utils.php index 88a49f4c95..3145e405d2 100644 --- a/php/utils.php +++ b/php/utils.php @@ -92,16 +92,18 @@ function get_config_path( $assoc_args ) { } function load_config( $path, $spec ) { - if ( !$path ) - return array(); - - $config = spyc_load_file( $path ); + if ( $path ) + $config = spyc_load_file( $path ); + else + $config = array(); $sanitized_config = array(); foreach ( $spec as $key => $details ) { if ( $details['file'] && isset( $config[ $key ] ) ) $sanitized_config[ $key ] = $config[ $key ]; + else + $sanitized_config[ $key ] = $details['default']; } return $sanitized_config; From 1505e0d97eaa969e79748b441fff45efffcb8dda Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Jan 2013 22:47:19 +0200 Subject: [PATCH 1113/4858] move special args handling to separate class --- php/WP_CLI/InternalAssoc.php | 73 ++++++++++++++++++++++++++++++++++++ php/class-wp-cli.php | 72 +++++------------------------------ 2 files changed, 82 insertions(+), 63 deletions(-) create mode 100644 php/WP_CLI/InternalAssoc.php diff --git a/php/WP_CLI/InternalAssoc.php b/php/WP_CLI/InternalAssoc.php new file mode 100644 index 0000000000..2652ed7745 --- /dev/null +++ b/php/WP_CLI/InternalAssoc.php @@ -0,0 +1,73 @@ +<?php + +namespace WP_CLI; +use \WP_CLI; + +/** + * Class that handles special assoc parameters + */ +class InternalAssoc { + + static function version() { + WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); + } + + static function info() { + $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + + WP_CLI::line( "PHP binary:\t" . $php_bin ); + WP_CLI::line( "PHP version:\t" . PHP_VERSION ); + WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); + WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); + WP_CLI::line( "wp-cli config:\t" . WP_CLI::get_config_path() ); + WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); + } + + static function cmd_dump() { + echo json_encode( self::command_to_array( WP_CLI::$root ) ); + } + + private static function command_to_array( $command ) { + $dump = array( + 'name' => $command->get_name(), + 'description' => $command->get_shortdesc(), + ); + + if ( $command instanceof Dispatcher\AtomicCommand ) { + $dump['synopsis'] = (string) $command->get_synopsis(); + } else { + foreach ( Dispatcher\get_subcommands( $command ) as $subcommand ) { + $dump['subcommands'][] = self::command_to_array( $subcommand ); + } + } + + return $dump; + } + + static function completions() { + foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { + $subcommands = Dispatcher\get_subcommands( $command ); + + WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); + } + } + + static function man( $args ) { + $arg_copy = $args; + + $command = WP_CLI::$root; + + while ( !empty( $args ) && $command && $command instanceof Dispatcher\CommandContainer ) { + $command = $command->find_subcommand( $args ); + } + + if ( !$command ) + WP_CLI::error( sprintf( "'%s' command not found.", + implode( ' ', $arg_copy ) ) ); + + foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { + WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + } + } +} + diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 4b0f68a9a1..6167cd1d93 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -254,6 +254,10 @@ private static function parse_args() { } } + static function get_config_path() { + return self::$config_path; + } + static function get_config( $key = null ) { if ( null === $key ) return self::$config; @@ -289,19 +293,19 @@ static function before_wp_load() { // Handle --version parameter if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { - self::line( 'wp-cli ' . WP_CLI_VERSION ); + \WP_CLI\InternalAssoc::version(); exit; } // Handle --info parameter if ( isset( self::$assoc_args['info'] ) && empty( self::$arguments ) ) { - self::show_info(); + \WP_CLI\InternalAssoc::info(); exit; } // Handle --cmd-dump parameter if ( isset( self::$assoc_args['cmd-dump'] ) ) { - self::cmd_dump(); + \WP_CLI\InternalAssoc::cmd_dump(); exit; } @@ -380,39 +384,18 @@ static function after_wp_load() { require self::$config['require']; if ( isset( self::$assoc_args['man'] ) ) { - self::generate_man( self::$arguments ); + \WP_CLI\InternalAssoc::man( self::$arguments ); exit; } if ( isset( self::$assoc_args['completions'] ) ) { - self::render_automcomplete(); + \WP_CLI\InternalAssoc::completions(); exit; } self::_run_command(); } - private static function cmd_dump() { - echo json_encode( self::command_to_array( self::$root ) ); - } - - private static function command_to_array( $command ) { - $dump = array( - 'name' => $command->get_name(), - 'description' => $command->get_shortdesc(), - ); - - if ( $command instanceof Dispatcher\AtomicCommand ) { - $dump['synopsis'] = (string) $command->get_synopsis(); - } else { - foreach ( Dispatcher\get_subcommands( $command ) as $subcommand ) { - $dump['subcommands'][] = self::command_to_array( $subcommand ); - } - } - - return $dump; - } - private static function _run_command() { self::run_command( self::$arguments, self::$assoc_args ); } @@ -441,43 +424,6 @@ public static function run_command( $args, $assoc_args = array() ) { } } - private static function show_info() { - $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); - - WP_CLI::line( "PHP binary:\t" . $php_bin ); - WP_CLI::line( "PHP version:\t" . PHP_VERSION ); - WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); - WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); - WP_CLI::line( "wp-cli config:\t" . self::$config_path ); - WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); - } - - private static function generate_man( $args ) { - $arg_copy = $args; - - $command = \WP_CLI::$root; - - while ( !empty( $args ) && $command && $command instanceof Dispatcher\CommandContainer ) { - $command = $command->find_subcommand( $args ); - } - - if ( !$command ) - WP_CLI::error( sprintf( "'%s' command not found.", - implode( ' ', $arg_copy ) ) ); - - foreach ( self::$man_dirs as $dest_dir => $src_dir ) { - \WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); - } - } - - private static function render_automcomplete() { - foreach ( self::$root->get_subcommands() as $name => $command ) { - $subcommands = Dispatcher\get_subcommands( $command ); - - self::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); - } - } - // back-compat static function addCommand( $name, $class ) { self::add_command( $name, $class ); From 88e446e906beef2325e116a2969deda72186b562 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Jan 2013 22:48:52 +0200 Subject: [PATCH 1114/4858] rename bootstrap() to load_depdencies() --- php/utils.php | 2 +- php/wp-cli.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index 3145e405d2..124e7494e8 100644 --- a/php/utils.php +++ b/php/utils.php @@ -6,7 +6,7 @@ use \WP_CLI\Dispatcher; -function bootstrap() { +function load_dependencies() { $vendor_paths = array( WP_CLI_ROOT . '../../../../vendor', // part of a larger project WP_CLI_ROOT . '../vendor', // top-level project diff --git a/php/wp-cli.php b/php/wp-cli.php index d9b16b3bda..41fef873de 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -13,7 +13,7 @@ include WP_CLI_ROOT . 'class-wp-cli-command.php'; include WP_CLI_ROOT . 'man.php'; -\WP_CLI\Utils\bootstrap(); +\WP_CLI\Utils\load_dependencies(); WP_CLI::before_wp_load(); From 6d300b5ab42e6c88441986a0b0bbd37e3b92440c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Jan 2013 23:23:06 +0200 Subject: [PATCH 1115/4858] introduce WP_CLI\Runner class It contains all the logic related to argument handling and WP loading. --- php/WP_CLI/Runner.php | 205 ++++++++++++++++++++++++++++++++++++++++++ php/class-wp-cli.php | 188 +++++--------------------------------- php/utils.php | 46 ---------- php/wp-cli.php | 8 +- 4 files changed, 233 insertions(+), 214 deletions(-) create mode 100644 php/WP_CLI/Runner.php diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php new file mode 100644 index 0000000000..86cf92ba97 --- /dev/null +++ b/php/WP_CLI/Runner.php @@ -0,0 +1,205 @@ +<?php + +namespace WP_CLI; + +use WP_CLI; +use WP_CLI\Utils; + + +class Runner { + + private $config_path, $config; + + private $arguments, $assoc_args; + + public function __get( $key ) { + return $this->$key; + } + + private static function get_config_path( &$assoc_args ) { + if ( isset( $assoc_args['config'] ) ) { + $paths = array( $assoc_args['config'] ); + unset( $assoc_args['config'] ); + } else { + $paths = array( + getcwd() . '/wp-cli.local.yml', + getcwd() . '/wp-cli.yml' + ); + } + + foreach ( $paths as $path ) { + if ( file_exists( $path ) ) + return $path; + } + + return false; + } + + private static function load_config( $path, $spec ) { + if ( $path ) + $config = spyc_load_file( $path ); + else + $config = array(); + + $sanitized_config = array(); + + foreach ( $spec as $key => $details ) { + if ( $details['file'] && isset( $config[ $key ] ) ) + $sanitized_config[ $key ] = $config[ $key ]; + else + $sanitized_config[ $key ] = $details['default']; + } + + return $sanitized_config; + } + + private static function split_special( &$assoc_args, &$config, $spec ) { + foreach ( $spec as $key => $details ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } + } + } + + public function before_wp_load() { + $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); + + list( $this->arguments, $this->assoc_args ) = $r; + + // foo --help -> help foo + if ( isset( $this->assoc_args['help'] ) ) { + array_unshift( $this->arguments, 'help' ); + unset( $this->assoc_args['help'] ); + } + + // {plugin|theme} update --all -> {plugin|theme} update-all + if ( count( $this->arguments ) > 1 && in_array( $this->arguments[0], array( 'plugin', 'theme' ) ) + && $this->arguments[1] == 'update' + && isset( $this->assoc_args['all'] ) + ) { + $this->arguments[1] = 'update-all'; + unset( $this->assoc_args['all'] ); + } + + $config_spec = Utils\get_config_spec(); + + $this->config_path = self::get_config_path( $this->assoc_args ); + + $this->config = self::load_config( $this->config_path, $config_spec ); + + self::split_special( $this->assoc_args, $this->config, $config_spec ); + + if ( 'auto' == $this->config['color'] ) + $this->config['color'] = ! \cli\Shell::isPiped(); + + // Handle --version parameter + if ( isset( $this->assoc_args['version'] ) && empty( $this->arguments ) ) { + \WP_CLI\InternalAssoc::version(); + exit; + } + + // Handle --info parameter + if ( isset( $this->assoc_args['info'] ) && empty( $this->arguments ) ) { + \WP_CLI\InternalAssoc::info(); + exit; + } + + // Handle --cmd-dump parameter + if ( isset( $this->assoc_args['cmd-dump'] ) ) { + \WP_CLI\InternalAssoc::cmd_dump(); + exit; + } + + $_SERVER['DOCUMENT_ROOT'] = getcwd(); + + // Handle --path + Utils\set_wp_root( $this->config ); + + // Handle --url and --blog parameters + Utils\set_url( $this->config ); + + if ( array( 'core', 'download' ) == $this->arguments ) { + $this->_run_command(); + exit; + } + + if ( !is_readable( ABSPATH . 'wp-load.php' ) ) { + WP_CLI::error( "This does not seem to be a WordPress install.", false ); + WP_CLI::line( "Pass --path=`path/to/wordpress` or run `wp core download`." ); + exit(1); + } + + if ( array( 'core', 'config' ) == $this->arguments ) { + $this->_run_command(); + exit; + } + + if ( !Utils\locate_wp_config() ) { + WP_CLI::error( "wp-config.php not found.", false ); + WP_CLI::line( "Either create one manually or use `wp core config`." ); + exit(1); + } + + if ( $this->cmd_starts_with( array( 'db' ) ) ) { + eval( Utils\get_wp_config_code() ); + $this->_run_command(); + exit; + } + + if ( + $this->cmd_starts_with( array( 'core', 'install' ) ) || + $this->cmd_starts_with( array( 'core', 'is-installed' ) ) + ) { + define( 'WP_INSTALLING', true ); + + if ( !isset( $_SERVER['HTTP_HOST'] ) ) { + Utils\set_url_params( 'http://example.com' ); + } + } + + // Pretend we're in WP_ADMIN + define( 'WP_ADMIN', true ); + $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; + } + + private function cmd_starts_with( $prefix ) { + return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); + } + + function after_wp_config_load() { + if ( isset( $this->config['debug'] ) ) { + if ( !defined( 'WP_DEBUG' ) ) + define( 'WP_DEBUG', true ); + } + } + + function after_wp_load() { + add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); + + Utils\set_user( $this->config ); + + if ( !defined( 'WP_INSTALLING' ) && isset( $this->config['url'] ) ) + Utils\set_wp_query(); + + if ( isset( $this->config['require'] ) ) + require $this->config['require']; + + if ( isset( $this->assoc_args['man'] ) ) { + \WP_CLI\InternalAssoc::man( $this->arguments ); + exit; + } + + if ( isset( $this->assoc_args['completions'] ) ) { + \WP_CLI\InternalAssoc::completions(); + exit; + } + + $this->_run_command(); + } + + private function _run_command() { + WP_CLI::run_command( $this->arguments, $this->assoc_args ); + } +} + diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 6167cd1d93..64069ab1da 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -4,19 +4,28 @@ use \WP_CLI\Dispatcher; /** - * Wrapper class for WP-CLI - * - * @package wp-cli + * Various utilities for WP-CLI commands. */ class WP_CLI { public static $root; + public static $runner; + private static $man_dirs = array(); - private static $config_path, $config; + /** + * Initialize WP_CLI static variables. + */ + static function init() { + self::add_man_dir( + WP_CLI_ROOT . "../man/", + WP_CLI_ROOT . "../man-src/" + ); - private static $arguments, $assoc_args; + self::$root = new Dispatcher\RootCommand; + self::$runner = new WP_CLI\Runner; + } /** * Add a command to the wp-cli list of commands @@ -25,7 +34,7 @@ class WP_CLI { * @param string|object $implementation The command implementation */ static function add_command( $name, $implementation ) { - if ( in_array( $name, self::$config['disabled_commands'] ) ) + if ( in_array( $name, self::get_config('disabled_commands') ) ) return; if ( is_string( $implementation ) ) { @@ -53,7 +62,7 @@ private static function create_composite_command( $name, $class ) { $subcommand_name = $subcommand->get_name(); $full_name = self::get_full_name( $subcommand ); - if ( in_array( $full_name, self::$config['disabled_commands'] ) ) + if ( in_array( $full_name, self::get_config('disabled_commands') ) ) continue; $container->add_subcommand( $subcommand_name, $subcommand ); @@ -103,7 +112,7 @@ static function out( $message, $handle = STDOUT ) { if ( self::get_config('quiet') ) return; - fwrite( $handle, \cli\Colors::colorize( $message, self::$config['color'] ) ); + fwrite( $handle, \cli\Colors::colorize( $message, self::get_config('color') ) ); } /** @@ -122,10 +131,10 @@ static function line( $message = '' ) { * @param bool $exit */ static function error( $message, $exit = true ) { - if ( !isset( self::$config['completions'] ) ) { + if ( ! self::get_config('completions') ) { $label = 'Error'; $msg = '%R' . $label . ': %n' . self::error_to_string( $message ) . "\n"; - fwrite( STDERR, \cli\Colors::colorize( $msg, self::$config['color'] ) ); + fwrite( STDERR, \cli\Colors::colorize( $msg, self::get_config('color') ) ); } if ( $exit ) @@ -233,171 +242,20 @@ static function launch( $command, $exit_on_error = true ) { return $r; } - private static function parse_args() { - $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); - - list( self::$arguments, self::$assoc_args ) = $r; - - // foo --help -> help foo - if ( isset( self::$assoc_args['help'] ) ) { - array_unshift( self::$arguments, 'help' ); - unset( self::$assoc_args['help'] ); - } - - // {plugin|theme} update --all -> {plugin|theme} update-all - if ( count( self::$arguments ) > 1 && in_array( self::$arguments[0], array( 'plugin', 'theme' ) ) - && self::$arguments[1] == 'update' - && isset( self::$assoc_args['all'] ) - ) { - self::$arguments[1] = 'update-all'; - unset( self::$assoc_args['all'] ); - } - } - static function get_config_path() { - return self::$config_path; + return self::$runner->config_path; } static function get_config( $key = null ) { if ( null === $key ) - return self::$config; + return self::$runner->config; - if ( !isset( self::$config[ $key ] ) ) { + if ( !isset( self::$runner->config[ $key ] ) ) { self::warning( "Unknown config option '$key'." ); return null; } - return self::$config[ $key ]; - } - - static function before_wp_load() { - self::$root = new Dispatcher\RootCommand; - - self::add_man_dir( - WP_CLI_ROOT . "../man/", - WP_CLI_ROOT . "../man-src/" - ); - - self::parse_args(); - - $config_spec = Utils\get_config_spec(); - - self::$config_path = Utils\get_config_path( self::$assoc_args ); - - self::$config = Utils\load_config( self::$config_path, $config_spec ); - - Utils\split_special( self::$assoc_args, self::$config, $config_spec ); - - if ( 'auto' == self::$config['color'] ) - self::$config['color'] = ! \cli\Shell::isPiped(); - - // Handle --version parameter - if ( isset( self::$assoc_args['version'] ) && empty( self::$arguments ) ) { - \WP_CLI\InternalAssoc::version(); - exit; - } - - // Handle --info parameter - if ( isset( self::$assoc_args['info'] ) && empty( self::$arguments ) ) { - \WP_CLI\InternalAssoc::info(); - exit; - } - - // Handle --cmd-dump parameter - if ( isset( self::$assoc_args['cmd-dump'] ) ) { - \WP_CLI\InternalAssoc::cmd_dump(); - exit; - } - - $_SERVER['DOCUMENT_ROOT'] = getcwd(); - - // Handle --path - Utils\set_wp_root( self::$config ); - - // Handle --url and --blog parameters - Utils\set_url( self::$config ); - - if ( array( 'core', 'download' ) == self::$arguments ) { - self::_run_command(); - exit; - } - - if ( !is_readable( ABSPATH . 'wp-load.php' ) ) { - WP_CLI::error( "This does not seem to be a WordPress install.", false ); - WP_CLI::line( "Pass --path=`path/to/wordpress` or run `wp core download`." ); - exit(1); - } - - if ( array( 'core', 'config' ) == self::$arguments ) { - self::_run_command(); - exit; - } - - if ( !Utils\locate_wp_config() ) { - WP_CLI::error( "wp-config.php not found.", false ); - WP_CLI::line( "Either create one manually or use `wp core config`." ); - exit(1); - } - - if ( self::cmd_starts_with( array( 'db' ) ) ) { - eval( Utils\get_wp_config_code() ); - self::_run_command(); - exit; - } - - if ( - self::cmd_starts_with( array( 'core', 'install' ) ) || - self::cmd_starts_with( array( 'core', 'is-installed' ) ) - ) { - define( 'WP_INSTALLING', true ); - - if ( !isset( $_SERVER['HTTP_HOST'] ) ) { - Utils\set_url_params( 'http://example.com' ); - } - } - - // Pretend we're in WP_ADMIN - define( 'WP_ADMIN', true ); - $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; - } - - private static function cmd_starts_with( $prefix ) { - return $prefix == array_slice( self::$arguments, 0, count( $prefix ) ); - } - - static function after_wp_config_load() { - if ( isset( self::$config['debug'] ) ) { - if ( !defined( 'WP_DEBUG' ) ) - define( 'WP_DEBUG', true ); - } - } - - static function after_wp_load() { - add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - - Utils\set_user( self::$config ); - - if ( !defined( 'WP_INSTALLING' ) && isset( self::$config['url'] ) ) - Utils\set_wp_query(); - - if ( isset( self::$config['require'] ) ) - require self::$config['require']; - - if ( isset( self::$assoc_args['man'] ) ) { - \WP_CLI\InternalAssoc::man( self::$arguments ); - exit; - } - - if ( isset( self::$assoc_args['completions'] ) ) { - \WP_CLI\InternalAssoc::completions(); - exit; - } - - self::_run_command(); - } - - private static function _run_command() { - self::run_command( self::$arguments, self::$assoc_args ); + return self::$runner->config[ $key ]; } /** diff --git a/php/utils.php b/php/utils.php index 124e7494e8..49121da12c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -72,52 +72,6 @@ function get_config_spec() { return $spec; } -function get_config_path( $assoc_args ) { - if ( isset( $assoc_args['config'] ) ) { - $paths = array( $assoc_args['config'] ); - unset( $assoc_args['config'] ); - } else { - $paths = array( - getcwd() . '/wp-cli.local.yml', - getcwd() . '/wp-cli.yml' - ); - } - - foreach ( $paths as $path ) { - if ( file_exists( $path ) ) - return $path; - } - - return false; -} - -function load_config( $path, $spec ) { - if ( $path ) - $config = spyc_load_file( $path ); - else - $config = array(); - - $sanitized_config = array(); - - foreach ( $spec as $key => $details ) { - if ( $details['file'] && isset( $config[ $key ] ) ) - $sanitized_config[ $key ] = $config[ $key ]; - else - $sanitized_config[ $key ] = $details['default']; - } - - return $sanitized_config; -} - -function split_special( &$assoc_args, &$config, $spec ) { - foreach ( $spec as $key => $details ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $key ] = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); - } - } -} - /** * Splits $argv into positional and associative arguments. * diff --git a/php/wp-cli.php b/php/wp-cli.php index 41fef873de..75413548be 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -15,12 +15,14 @@ \WP_CLI\Utils\load_dependencies(); -WP_CLI::before_wp_load(); +WP_CLI::init(); + +WP_CLI::$runner->before_wp_load(); // Load WordPress, in the global scope eval( \WP_CLI\Utils\get_wp_config_code() ); -WP_CLI::after_wp_config_load(); +WP_CLI::$runner->after_wp_config_load(); require WP_CLI_ROOT . 'wp-settings-cli.php'; @@ -30,5 +32,5 @@ // Load all admin utilities require ABSPATH . 'wp-admin/includes/admin.php'; -WP_CLI::after_wp_load(); +WP_CLI::$runner->after_wp_load(); From 25c6f36bc388523db7b60bd1c237a40a6a01c5da Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Jan 2013 23:51:49 +0200 Subject: [PATCH 1116/4858] move even more code from utils.php into WP_CLI\Runner --- php/WP_CLI/Runner.php | 85 +++++++++++++++++++++++++++++++++++++++++-- php/utils.php | 76 -------------------------------------- php/wp-cli.php | 2 +- 3 files changed, 83 insertions(+), 80 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 86cf92ba97..dd68d6ecbb 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -62,6 +62,85 @@ private static function split_special( &$assoc_args, &$config, $spec ) { } } + private static function set_wp_root( $config ) { + if ( !empty( $config['path'] ) ) { + define( 'ABSPATH', rtrim( $config['path'], '/' ) . '/' ); + } else { + define( 'ABSPATH', getcwd() . '/' ); + } + } + + private static function set_url( $assoc_args ) { + if ( isset( $assoc_args['url'] ) ) { + $url = $assoc_args['url']; + } elseif ( isset( $assoc_args['blog'] ) ) { + WP_CLI::warning( 'The --blog parameter is deprecated. Use --url instead.' ); + + $url = $assoc_args['blog']; + if ( true === $url ) { + WP_CLI::line( 'usage: wp --blog=example.com' ); + } + } elseif ( is_readable( ABSPATH . 'wp-cli-blog' ) ) { + WP_CLI::warning( 'The wp-cli-blog file is deprecated. Use wp-cli.yml instead.' ); + + $url = trim( file_get_contents( ABSPATH . 'wp-cli-blog' ) ); + } elseif ( $wp_config_path = Utils\locate_wp_config() ) { + // Try to find the blog parameter in the wp-config file + $wp_config_file = file_get_contents( $wp_config_path ); + $hit = array(); + + $re_define = "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU"; + + if ( preg_match_all( $re_define, $wp_config_file, $matches ) ) { + foreach ( $matches[2] as $def_key => $def_name ) { + if ( 'DOMAIN_CURRENT_SITE' == $def_name ) + $hit['domain'] = $matches[5][$def_key]; + if ( 'PATH_CURRENT_SITE' == $def_name ) + $hit['path'] = $matches[5][$def_key]; + } + } + + if ( !empty( $hit ) && isset( $hit['domain'] ) ) + $url = $hit['domain']; + if ( !empty( $hit ) && isset( $hit['path'] ) ) + $url .= $hit['path']; + } + + if ( isset( $url ) ) { + Utils\set_url_params( $url ); + } + } + + /** + * Returns wp-config.php code, skipping the loading of wp-settings.php + * + * @return string + */ + function get_wp_config_code() { + $wp_config_path = Utils\locate_wp_config(); + + $replacements = array( + '__FILE__' => "'$wp_config_path'", + '__DIR__' => "'" . dirname( $wp_config_path ) . "'" + ); + + $old = array_keys( $replacements ); + $new = array_values( $replacements ); + + $wp_config_code = explode( "\n", file_get_contents( $wp_config_path ) ); + + $lines_to_run = array(); + + foreach ( $wp_config_code as $line ) { + if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) + continue; + + $lines_to_run[] = str_replace( $old, $new, $line ); + } + + return preg_replace( '|^\s*\<\?php\s*|', '', implode( "\n", $lines_to_run ) ); + } + public function before_wp_load() { $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -114,10 +193,10 @@ public function before_wp_load() { $_SERVER['DOCUMENT_ROOT'] = getcwd(); // Handle --path - Utils\set_wp_root( $this->config ); + self::set_wp_root( $this->config ); // Handle --url and --blog parameters - Utils\set_url( $this->config ); + self::set_url( $this->config ); if ( array( 'core', 'download' ) == $this->arguments ) { $this->_run_command(); @@ -142,7 +221,7 @@ public function before_wp_load() { } if ( $this->cmd_starts_with( array( 'db' ) ) ) { - eval( Utils\get_wp_config_code() ); + eval( $this->get_wp_config_code() ); $this->_run_command(); exit; } diff --git a/php/utils.php b/php/utils.php index 49121da12c..2119bb05de 100644 --- a/php/utils.php +++ b/php/utils.php @@ -134,44 +134,6 @@ function get_command_file( $command ) { return $path; } -function set_url( $assoc_args ) { - if ( isset( $assoc_args['url'] ) ) { - $url = $assoc_args['url']; - } elseif ( isset( $assoc_args['blog'] ) ) { - \WP_CLI::warning( 'The --blog parameter is deprecated. Use --url instead.' ); - - $url = $assoc_args['blog']; - if ( true === $url ) { - \WP_CLI::line( 'usage: wp --blog=example.com' ); - } - } elseif ( is_readable( ABSPATH . 'wp-cli-blog' ) ) { - \WP_CLI::warning( 'The wp-cli-blog file is deprecated. Use wp-cli.yml instead.' ); - - $url = trim( file_get_contents( ABSPATH . 'wp-cli-blog' ) ); - } elseif ( $wp_config_path = locate_wp_config() ) { - // Try to find the blog parameter in the wp-config file - $wp_config_file = file_get_contents( $wp_config_path ); - $hit = array(); - if ( preg_match_all( "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU", $wp_config_file, $matches ) ) { - foreach ( $matches[2] as $def_key => $def_name ) { - if ( 'DOMAIN_CURRENT_SITE' == $def_name ) - $hit['domain'] = $matches[5][$def_key]; - if ( 'PATH_CURRENT_SITE' == $def_name ) - $hit['path'] = $matches[5][$def_key]; - } - } - - if ( !empty( $hit ) && isset( $hit['domain'] ) ) - $url = $hit['domain']; - if ( !empty( $hit ) && isset( $hit['path'] ) ) - $url .= $hit['path']; - } - - if ( isset( $url ) ) { - set_url_params( $url ); - } -} - /** * Sets the appropriate $_SERVER keys based on a given string * @@ -198,14 +160,6 @@ function set_url_params( $url ) { $_SERVER['REQUEST_METHOD'] = 'GET'; } -function set_wp_root( $config ) { - if ( !empty( $config['path'] ) ) { - define( 'ABSPATH', rtrim( $config['path'], '/' ) . '/' ); - } else { - define( 'ABSPATH', getcwd() . '/' ); - } -} - function locate_wp_config() { if ( file_exists( ABSPATH . 'wp-config.php' ) ) return ABSPATH . 'wp-config.php'; @@ -216,36 +170,6 @@ function locate_wp_config() { return false; } -/** - * Returns wp-config.php code, skipping the loading of wp-settings.php - * - * @return string - */ -function get_wp_config_code() { - $wp_config_path = locate_wp_config(); - - $replacements = array( - '__FILE__' => "'$wp_config_path'", - '__DIR__' => "'" . dirname( $wp_config_path ) . "'" - ); - - $old = array_keys( $replacements ); - $new = array_values( $replacements ); - - $wp_config_code = explode( "\n", file_get_contents( $wp_config_path ) ); - - $lines_to_run = array(); - - foreach ( $wp_config_code as $line ) { - if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) - continue; - - $lines_to_run[] = str_replace( $old, $new, $line ); - } - - return preg_replace( '|^\s*\<\?php\s*|', '', implode( "\n", $lines_to_run ) ); -} - /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. diff --git a/php/wp-cli.php b/php/wp-cli.php index 75413548be..b3eeae39a0 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -20,7 +20,7 @@ WP_CLI::$runner->before_wp_load(); // Load WordPress, in the global scope -eval( \WP_CLI\Utils\get_wp_config_code() ); +eval( WP_CLI::$runner->get_wp_config_code() ); WP_CLI::$runner->after_wp_config_load(); From ea2f548367f66f9f355d044375f423351f7af9a3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 01:30:39 +0200 Subject: [PATCH 1117/4858] storing the config spec in a static variable is not needed get_config_spec() is only called once per instantiation, or at most 2 times. --- php/utils.php | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/php/utils.php b/php/utils.php index 2119bb05de..93065817de 100644 --- a/php/utils.php +++ b/php/utils.php @@ -52,21 +52,17 @@ function register_autoload() { } function get_config_spec() { - static $spec; + $spec = include __DIR__ . '/config-spec.php'; - if ( !$spec ) { - $spec = include __DIR__ . '/config-spec.php'; - - $defaults = array( - 'runtime' => false, - 'file' => false, - 'synopsis' => '', - 'default' => null, - ); + $defaults = array( + 'runtime' => false, + 'file' => false, + 'synopsis' => '', + 'default' => null, + ); - foreach ( $spec as &$option ) { - $option = array_merge( $defaults, $option ); - } + foreach ( $spec as &$option ) { + $option = array_merge( $defaults, $option ); } return $spec; From 60aa13881acef0a4f85227b966de8237c205f8c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 01:33:01 +0200 Subject: [PATCH 1118/4858] add --param-dump --- php/WP_CLI/InternalAssoc.php | 4 ++++ php/WP_CLI/Runner.php | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/php/WP_CLI/InternalAssoc.php b/php/WP_CLI/InternalAssoc.php index 2652ed7745..6ceae0b099 100644 --- a/php/WP_CLI/InternalAssoc.php +++ b/php/WP_CLI/InternalAssoc.php @@ -23,6 +23,10 @@ static function info() { WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); } + static function param_dump() { + echo json_encode( Utils\get_config_spec() ); + } + static function cmd_dump() { echo json_encode( self::command_to_array( WP_CLI::$root ) ); } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index dd68d6ecbb..e4e94d7b8c 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -184,6 +184,12 @@ public function before_wp_load() { exit; } + // Handle --cmd-dump parameter + if ( isset( $this->assoc_args['param-dump'] ) ) { + \WP_CLI\InternalAssoc::param_dump(); + exit; + } + // Handle --cmd-dump parameter if ( isset( $this->assoc_args['cmd-dump'] ) ) { \WP_CLI\InternalAssoc::cmd_dump(); From 05c57d481982046f8b533234b67701182e46684f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 04:44:34 +0200 Subject: [PATCH 1119/4858] support --color and --no-color special args. closes #267 --- php/WP_CLI/Runner.php | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e4e94d7b8c..9876d31798 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -53,11 +53,30 @@ private static function load_config( $path, $spec ) { return $sanitized_config; } + private static function handle_boolean_param( &$assoc_args, &$config, $param ) { + $subkeys = array( + "$param" => true, + "no-$param" => false + ); + + foreach ( $subkeys as $key => $value ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $param ] = $value; + } + + unset( $assoc_args[ $key ] ); + } + } + private static function split_special( &$assoc_args, &$config, $spec ) { foreach ( $spec as $key => $details ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $key ] = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); + if ( true == $details['runtime'] ) { + self::handle_boolean_param( $assoc_args, $config, $key ); + } elseif ( false !== $details['runtime'] ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } } } } @@ -169,8 +188,12 @@ public function before_wp_load() { self::split_special( $this->assoc_args, $this->config, $config_spec ); - if ( 'auto' == $this->config['color'] ) + if ( isset( $this->assoc_args['no-color'] ) ) { + $this->config['color'] = false; + unset( $this->assoc_args['no-color'] ); + } elseif ( 'auto' == $this->config['color'] ) { $this->config['color'] = ! \cli\Shell::isPiped(); + } // Handle --version parameter if ( isset( $this->assoc_args['version'] ) && empty( $this->arguments ) ) { From cc517b06e3a7ca487c46d1b82446567faf7c67c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 04:46:53 +0200 Subject: [PATCH 1120/4858] update config-spec.php. see #267 --- php/config-spec.php | 51 ++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index 07c3aa1308..2a8652e0cc 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -2,73 +2,58 @@ return array( 'path' => array( - 'runtime' => true, - 'file' => true, - 'default' => null, + 'runtime' => '=<path>', + 'file' => '<path>', 'desc' => 'Path to the WordPress files', - 'synopsis' => '<path>' ), 'url' => array( - 'runtime' => true, - 'file' => true, - 'default' => null, + 'runtime' => '=<url>', + 'file' => '<url>', 'desc' => 'Pretend request came from given URL', - 'synopsis' => '<url>' ), 'blog' => array( 'deprecated' => 'Use --url instead', - 'runtime' => true, - 'file' => false, - 'default' => null, - 'synopsis' => '<url>', + 'runtime' => '', ), 'user' => array( - 'runtime' => true, - 'file' => true, - 'default' => null, + 'runtime' => '=<id|login>', + 'file' => '<id|login>', 'desc' => 'Set the WordPress user', - 'synopsis' => '<id|login>' ), 'require' => array( - 'runtime' => true, - 'file' => true, - 'default' => null, + 'runtime' => '=<path>', + 'file' => '<path>', 'desc' => 'Load given PHP file before running the command', - 'synopsis' => '<path>' ), 'disabled_commands' => array( - 'runtime' => false, - 'file' => true, + 'file' => '<list>', 'default' => array(), 'desc' => '(Sub)commands to disable', ), 'color' => array( 'runtime' => true, - 'file' => true, + 'file' => '<bool>', 'default' => 'auto', - 'desc' => 'Show all PHP errors.', - 'synopsis' => '<bool>', + 'desc' => 'Whether to colozire the output', ), 'debug' => array( - 'runtime' => true, - 'file' => true, + 'runtime' => '', + 'file' => '<bool>', 'default' => false, - 'desc' => 'Show all PHP errors.', - 'synopsis' => '', + 'desc' => 'Show all PHP errors', ), 'quiet' => array( - 'runtime' => true, - 'file' => true, + 'runtime' => '', + 'file' => '<bool>', 'default' => false, - 'desc' => 'Show all PHP errors.', - 'synopsis' => '<bool>', + 'desc' => 'Suppress informational messages', ), ); From 3c598b476f60f7f52577f63a8f2ea0388f54f30f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 05:14:15 +0200 Subject: [PATCH 1121/4858] generate synopsis for global command from config-spec --- php/WP_CLI/Dispatcher/RootCommand.php | 43 +++++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index a0712ca80c..989faa2cff 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -35,16 +35,41 @@ function show_usage() { See 'wp help <command>' for more information on a specific command. Global parameters: ---user=<id|login> set the WordPress user ---url=<url> set the URL ---path=<path> set the path to the WP install ---config=<path> set the path to the wp-cli config file ---require=<path> load a certain PHP file before running the command ---quiet suppress informational messages ---debug show all PHP errors ---info print wp-cli information EOB - ); + ); + + \WP_CLI::line( self::generate_synopsis() ); + } + + private static function generate_synopsis() { + $max_len = 0; + + $lines = array(); + + foreach ( \WP_CLI\Utils\get_config_spec() as $key => $details ) { + if ( false === $details['runtime'] ) + continue; + + if ( isset( $details['deprecated'] ) ) + continue; + + $synopsis = ( true === $details['runtime'] ) + ? "--$key/--no-$key" + : "--$key" . $details['runtime']; + + $cur_len = strlen( $synopsis ); + + if ( $max_len < $cur_len ) + $max_len = $cur_len; + + $lines[] = array( $synopsis, $details['desc'] ); + } + + foreach ( $lines as $line ) { + list( $synopsis, $desc ) = $line; + + \WP_CLI::line( ' ' . str_pad( $synopsis, $max_len ) . ' ' . $desc ); + } } function pre_invoke( &$args ) { From 309b2d6aacf66cf70e5e22c8672690ac95c2c98b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 05:15:27 +0200 Subject: [PATCH 1122/4858] add --config global param --- php/config-spec.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/config-spec.php b/php/config-spec.php index 2a8652e0cc..8879434b26 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -1,6 +1,12 @@ <?php return array( + 'config' => array( + 'runtime' => '=<path>', + 'file' => false, + 'desc' => 'Path to the wp-cli config file', + ), + 'path' => array( 'runtime' => '=<path>', 'file' => '<path>', From ba13113ffdc43e34c0193f9f68c33eefe94cd389 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 05:23:46 +0200 Subject: [PATCH 1123/4858] fix check for completions in WP_CLI::error() --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 64069ab1da..884327447d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -131,7 +131,7 @@ static function line( $message = '' ) { * @param bool $exit */ static function error( $message, $exit = true ) { - if ( ! self::get_config('completions') ) { + if ( ! isset( self::$runner->assoc_args[ 'completions' ] ) ) { $label = 'Error'; $msg = '%R' . $label . ': %n' . self::error_to_string( $message ) . "\n"; fwrite( STDERR, \cli\Colors::colorize( $msg, self::get_config('color') ) ); From c7da7bceef309c547de62021d825016df5c8eb2d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 05:37:39 +0200 Subject: [PATCH 1124/4858] strict comparison for 'runtime' key. see #277 --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9876d31798..ce1287e7e3 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -70,7 +70,7 @@ private static function handle_boolean_param( &$assoc_args, &$config, $param ) { private static function split_special( &$assoc_args, &$config, $spec ) { foreach ( $spec as $key => $details ) { - if ( true == $details['runtime'] ) { + if ( true === $details['runtime'] ) { self::handle_boolean_param( $assoc_args, $config, $key ); } elseif ( false !== $details['runtime'] ) { if ( isset( $assoc_args[ $key ] ) ) { From b96ad80a5e85ac3c8eb7ba75ab48886f9fc2af62 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Jan 2013 05:44:00 +0200 Subject: [PATCH 1125/4858] bump version to 0.8.0-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index b3eeae39a0..3fd88af136 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.8.0-alpha' ); +define( 'WP_CLI_VERSION', '0.8.0-beta' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); From b15b8042427b85e7e9a8a91851cbf7484351d107 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 03:49:14 +0100 Subject: [PATCH 1126/4858] remove unnecessary leading slash in locate_wp_config() --- php/utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index 93065817de..6fb20fdc72 100644 --- a/php/utils.php +++ b/php/utils.php @@ -160,8 +160,8 @@ function locate_wp_config() { if ( file_exists( ABSPATH . 'wp-config.php' ) ) return ABSPATH . 'wp-config.php'; - if ( file_exists( ABSPATH . '/../wp-config.php' ) && ! file_exists( ABSPATH . '/../wp-settings.php' ) ) - return ABSPATH . '/../wp-config.php'; + if ( file_exists( ABSPATH . '../wp-config.php' ) && ! file_exists( ABSPATH . '/../wp-settings.php' ) ) + return ABSPATH . '../wp-config.php'; return false; } From 0c6850417f67e416873b40f8e31cf70178436267 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 03:57:06 +0100 Subject: [PATCH 1127/4858] normalize and cache path returned by locate_wp_config() --- php/utils.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/php/utils.php b/php/utils.php index 6fb20fdc72..663c4254db 100644 --- a/php/utils.php +++ b/php/utils.php @@ -157,13 +157,21 @@ function set_url_params( $url ) { } function locate_wp_config() { - if ( file_exists( ABSPATH . 'wp-config.php' ) ) - return ABSPATH . 'wp-config.php'; + static $path; - if ( file_exists( ABSPATH . '../wp-config.php' ) && ! file_exists( ABSPATH . '/../wp-settings.php' ) ) - return ABSPATH . '../wp-config.php'; + if ( null === $path ) { + if ( file_exists( ABSPATH . 'wp-config.php' ) ) + $path = ABSPATH . 'wp-config.php'; + elseif ( file_exists( ABSPATH . '../wp-config.php' ) && ! file_exists( ABSPATH . '/../wp-settings.php' ) ) + $path = ABSPATH . '../wp-config.php'; + else + $path = false; + + if ( $path ) + $path = realpath( $path ); + } - return false; + return $path; } /** From 0be188895f742af6dfae0520e45511b65cefceb8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 04:03:24 +0100 Subject: [PATCH 1128/4858] scaffold plugin: made success msg consistent with other scaffolds --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index b5511feb23..45ee281fc8 100755 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -168,7 +168,7 @@ function plugin( $args, $assoc_args ) { $this->create_file( $plugin_path, $plugin_contents ); - WP_CLI::success( "Plugin scaffold created: $plugin_path" ); + WP_CLI::success( "Created $plugin_path" ); if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); From 8fccb8649d104576947bc343352225a7da0c33c1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 04:06:05 +0100 Subject: [PATCH 1129/4858] remove extra tab from extended scaffolds --- php/templates/post_type_extended.mustache | 2 +- php/templates/taxonomy_extended.mustache | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/templates/post_type_extended.mustache b/php/templates/post_type_extended.mustache index 48cef1b3e5..240746970a 100755 --- a/php/templates/post_type_extended.mustache +++ b/php/templates/post_type_extended.mustache @@ -1,7 +1,7 @@ <?php function {{machine_name}}_init() { - {{{output}}} +{{{output}}} } add_action( 'init', '{{machine_name}}_init' ); diff --git a/php/templates/taxonomy_extended.mustache b/php/templates/taxonomy_extended.mustache index 0805563514..8e0e1a5c73 100755 --- a/php/templates/taxonomy_extended.mustache +++ b/php/templates/taxonomy_extended.mustache @@ -1,6 +1,6 @@ <?php function {{machine_name}}_init() { - {{{output}}} +{{{output}}} } add_action( 'init', '{{machine_name}}_init' ); From 8acc57dcb3ec545b948f3f39b79f577e548a32fb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 15:22:14 +0100 Subject: [PATCH 1130/4858] set version to 0.8.0 --- build.properties | 2 +- php/wp-cli.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.properties b/build.properties index 27ad66bcea..dcab1de8e1 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ project.name=wpcli project.channel=wp-cli.org/pear project.majorVersion=0 -project.minorVersion=7 +project.minorVersion=8 project.patchLevel=0 project.snapshot=false diff --git a/php/wp-cli.php b/php/wp-cli.php index 3fd88af136..343184614b 100755 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.8.0-beta' ); +define( 'WP_CLI_VERSION', '0.8.0' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); From 27e5f83b00fc1d3f9fd72f08a147184a54f946d6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 17:07:55 +0100 Subject: [PATCH 1131/4858] exclude .git files via build.xml --- build.xml | 12 ++++++------ utils/pear-build | 10 ---------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/build.xml b/build.xml index 932336fb43..96905b8ca8 100644 --- a/build.xml +++ b/build.xml @@ -75,37 +75,37 @@ <include name="**/**"/> <exclude name="**/.DS_Store"/> <exclude name="**/.empty"/> - <exclude name="**/.svn"/> + <exclude name="**/.git*"/> </fileset> <fileset dir="${project.src.datadir}" id="datafiles"> <include name="**/**"/> <exclude name="**/.DS_Store"/> <exclude name="**/.empty"/> - <exclude name="**/.svn"/> + <exclude name="**/.git*"/> </fileset> <fileset dir="${project.src.phpdir}" id="phpfiles"> <include name="**/**"/> <exclude name="**/.DS_Store"/> <exclude name="**/.empty"/> - <exclude name="**/.svn"/> + <exclude name="**/.git*"/> </fileset> <fileset dir="${project.src.testunitdir}/php" id="testfiles"> <include name="**/**"/> <exclude name="**/.DS_Store"/> <exclude name="**/.empty"/> - <exclude name="**/.svn"/> + <exclude name="**/.git*"/> </fileset> <fileset dir="${project.src.wwwdir}" id="wwwfiles"> <include name="**/**" /> <exclude name="**/.DS_Store"/> <exclude name="**/.empty"/> - <exclude name="**/.svn"/> + <exclude name="**/.git*"/> </fileset> <fileset dir="${project.src.docdir}" id="docfiles"> <include name="**/**" /> <exclude name="**/.DS_Store"/> <exclude name="**/.empty"/> - <exclude name="**/.svn"/> + <exclude name="**/.git*"/> </fileset> <fileset dir="${project.basedir}" id="topleveldocfiles"> <include name="*.txt" /> diff --git a/utils/pear-build b/utils/pear-build index c4e404784f..d7ce29dc52 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -5,20 +5,10 @@ set -ex # create bunch of directories that phing complains about mkdir -p docs data www tests/unit-tests/php -# temporarily move the .git dir, because phing is stupid -git_dir=php/php-cli-tools/.git -if [ -f $git_dir ]; then - mv $git_dir /tmp/php-cli-tools-git -fi - # generate package find -name '*~' -delete phing pear-package -if [ ! -d $git_dir ]; then - mv /tmp/php-cli-tools-git $git_dir -fi - version=$(cat dist/lastBuilt) version="${version/*wpcli-/}" version="${version/.tgz/}" From 46ff75de61ac8906b0fd2e441f2694a7e27d5268 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Jan 2013 19:43:50 +0100 Subject: [PATCH 1132/4858] include only php files in build.xml --- build.xml | 5 +---- utils/pear-build | 10 ++++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build.xml b/build.xml index 96905b8ca8..4264119d33 100644 --- a/build.xml +++ b/build.xml @@ -84,10 +84,7 @@ <exclude name="**/.git*"/> </fileset> <fileset dir="${project.src.phpdir}" id="phpfiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.git*"/> + <include name="**/*.php"/> </fileset> <fileset dir="${project.src.testunitdir}/php" id="testfiles"> <include name="**/**"/> diff --git a/utils/pear-build b/utils/pear-build index d7ce29dc52..f2be1b3fdc 100755 --- a/utils/pear-build +++ b/utils/pear-build @@ -6,7 +6,6 @@ set -ex mkdir -p docs data www tests/unit-tests/php # generate package -find -name '*~' -delete phing pear-package version=$(cat dist/lastBuilt) @@ -16,11 +15,14 @@ version="${version/.tgz/}" #sudo phing install-system # update channel files -cd ../wp-cli-pear -pirum add . ../wp-cli/dist/wpcli-$version.tgz -pirum build . +pear_repo=../wp-cli-pear + +pirum add $pear_repo ../wp-cli/dist/wpcli-$version.tgz +pirum build $pear_repo # push changes +cd $pear_repo + git add -A git ci -m "release $version" git push origin gh-pages From 9f514b6d5dc1601a162908074518682df3e57169 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 27 Jan 2013 17:19:12 +0100 Subject: [PATCH 1133/4858] PHP files don't need to be executable --- php/commands/scaffold.php | 0 php/wp-cli.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 php/commands/scaffold.php mode change 100755 => 100644 php/wp-cli.php diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php old mode 100755 new mode 100644 diff --git a/php/wp-cli.php b/php/wp-cli.php old mode 100755 new mode 100644 From 0bd67df80b8c07d993f5fb5a4c4c1527ce29c2bc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 27 Jan 2013 17:25:30 +0100 Subject: [PATCH 1134/4858] check that the plugin directory exists. fixes #281 --- php/commands/scaffold.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 45ee281fc8..0061ac5716 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -139,6 +139,9 @@ private function get_output_path( $assoc_args, $subdir ) { $path = TEMPLATEPATH; } elseif ( ! empty( $plugin ) ) { $path = WP_PLUGIN_DIR . '/' . $plugin; + if ( !is_dir( $path ) ) { + WP_CLI::error( "Can't find '$plugin' plugin." ); + } } else { return false; } From a9a98991565973a4b5f6d9d1c801d5f63a1b526a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 27 Jan 2013 17:26:21 +0100 Subject: [PATCH 1135/4858] bump version to 0.9.0-dev --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 343184614b..c1443fd6a5 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.8.0' ); +define( 'WP_CLI_VERSION', '0.9.0-dev' ); define( 'WP_CLI_ROOT', __DIR__ . '/' ); From b5dcdfdaa6f9c53a0c1c6ff1dea06de750b53313 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 31 Jan 2013 22:36:18 +0100 Subject: [PATCH 1136/4858] Added command file and skeleton for methods --- php/commands/media.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 php/commands/media.php diff --git a/php/commands/media.php b/php/commands/media.php new file mode 100644 index 0000000000..f1468cc8b8 --- /dev/null +++ b/php/commands/media.php @@ -0,0 +1,32 @@ +<?php + +/** + * Functionality to control the media library and its attachments + * + * @package wp-cli + */ +class Media_Command extends WP_CLI_Command { + + function __construct() { + WP_Filesystem(); + } + + /** + * Import a file into the media library. + * + * @synopsis <filename> [--blog] + */ + function import( $args, $assoc_args = array() ) { + } + /** + * Regenerate thumbnail(s) + * + * @synopsis [--all] [--file=<file>] [--id=<id>] + */ + function regenerate( $args, $assoc_args = array() ) { + + } + +} + +WP_CLI::add_command( 'media', 'Media_Command' ); \ No newline at end of file From 4da5e6199399b4d3f793a2250b430cf2fd57be7d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Feb 2013 11:42:39 -0800 Subject: [PATCH 1137/4858] Output a list of users as CSV or JSON with a new CSV helper utility --- php/commands/user.php | 75 ++++++++++++++++++++++++++++++++----------- php/utils.php | 24 ++++++++++++++ 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index c3cff0cd9b..bea3a5c556 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -11,15 +11,16 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * List users. * * @subcommand list - * @synopsis [--role=<role>] [--ids] + * @synopsis [--role=<role>] [--ids] [--format=<format>] */ public function _list( $args, $assoc_args ) { - global $blog_id; - $params = array( - 'blog_id' => $blog_id, - 'fields' => isset( $assoc_args['ids'] ) ? 'ids' : 'all_with_meta', + $defaults = array( + 'blog_id' => get_current_blog_id(), + 'fields' => isset( $assoc_args['ids'] ) ? 'ids' : 'all_with_meta', + 'format' => 'table', ); + $params = array_merge( $defaults, $assoc_args ); if ( array_key_exists( 'role', $assoc_args ) ) { $params['role'] = $assoc_args['role']; @@ -29,29 +30,65 @@ public function _list( $args, $assoc_args ) { if ( isset( $assoc_args['ids'] ) ) { WP_CLI::out( implode( ' ', $users ) ); - } else { - $fields = array('ID', 'user_login', 'display_name', 'user_email', - 'user_registered'); + } + + $fields = array( + 'ID', + 'user_login', + 'display_name', + 'user_email', + 'user_registered' + ); + + switch( $params['format'] ) { + case 'table': + $table = new \cli\Table(); - $table = new \cli\Table(); + $table->setHeaders( array_merge( $fields, array('roles') ) ); - $table->setHeaders( array_merge( $fields, array('roles') ) ); + foreach ( $users as $user ) { + $line = array(); - foreach ( $users as $user ) { - $line = array(); + foreach ( $fields as $field ) { + $line[] = $user->$field; + } + $line[] = implode( ',', $user->roles ); - foreach ( $fields as $field ) { - $line[] = $user->$field; + $table->addRow( $line ); } - $line[] = implode( ',', $user->roles ); - $table->addRow( $line ); - } + $table->display(); + + WP_CLI::line( 'Total: ' . count( $users ) . ' users' ); + break; + case 'json': + $json_users = array(); + + foreach( $users as $user ) { + $json_user = new stdClass; + foreach( $fields as $field ) { + $json_user->$field = $user->$field; + } + $json_users[] = $json_user; + } - $table->display(); + echo json_encode( $json_users ); + break; + case 'csv': + $csv_users = array(); + + foreach( $users as $user ) { + $csv_user = array(); + foreach( $fields as $field ) { + $csv_user[$field] = $user->$field; + } + $csv_users[] = $csv_user; + } - WP_CLI::line( 'Total: ' . count( $users ) . ' users' ); + WP_CLI\Utils\output_csv( $fields, $csv_users ); + break; } + } /** diff --git a/php/utils.php b/php/utils.php index 663c4254db..ad4f16a1b2 100644 --- a/php/utils.php +++ b/php/utils.php @@ -233,3 +233,27 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria return $data; } +/** + * Output data as CSV + * + * @param array $headers Headers for the CSV (optional) + * @param array $data Data for each row + */ +function output_csv( $headers = array(), $data = array() ) { + + // Prepare the headers if they were specified + if ( ! empty( $headers ) ) { + echo '"' . implode( '","', $headers ) . '"' . PHP_EOL; + } + + foreach( $data as $row ) { + + if ( ! empty( $headers ) ) { + $build_row = array(); + foreach( $headers as $key ) { + $build_row[] = $row[$key]; + } + } + echo '"' . implode( '","', $row ) . '"' . PHP_EOL; + } +} From 6f46c74196e53cf9923559b0b8a79c574bf658f6 Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Sat, 2 Feb 2013 16:04:16 -0800 Subject: [PATCH 1138/4858] Added initial version of wp scaffold _s --- php/commands/scaffold.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 0061ac5716..8a64ab07d8 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -132,6 +132,40 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) } } + /** + * Generate starter code for a theme. + * + * @synopsis <slug> [--theme_name=<title>] [--author=<full name>] [--author_uri=<http url>] [--activate] + */ + function _s( $args, $assoc_args ) { + + $theme_slug = $args[0]; + $theme_path = WP_CONTENT_DIR . "/themes"; + $data = wp_parse_args( $assoc_args, array( + 'theme_name' => ucfirst( $theme_slug ), + 'author' => "Me", + 'author_uri' => "", + ) ); + $theme_description = "Custom theme ".$data['theme_name']."developed by: ".$data['author']; + $prepare = 'curl -d underscoresme_name="'.$data['theme_name'].'"'; + $prepare .= ' -d underscoresme_slug="'.$theme_slug.'"'; + $prepare .= ' -d underscoresme_author="'.$data['author'].'"'; + $prepare .= ' -d underscoresme_author_uri="'.$data['author_uri'].'"'; + $prepare .= ' -d underscoresme_description="'.$theme_description.'"'; + $prepare .= ' -d underscoresme_generate_submit="Generate"'; + $prepare .= ' -d underscoresme_generate="1"'; + $prepare .= ' http://underscores.me > '.$theme_path.'/underscores.zip'; + $prepare .= ' && unzip -d '.$theme_path.' '.$theme_path.'/underscores.zip && rm '.$theme_path.'/underscores.zip'; + + shell_exec($prepare); // Don't know the WordPress way of doing this. + + WP_CLI::success( "Created Theme: ".$data['theme_name'] ); + + + if ( isset( $assoc_args['activate'] ) ) + WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + } + private function get_output_path( $assoc_args, $subdir ) { extract( $assoc_args, EXTR_SKIP ); From cba6678cf88ed0dd3389e3e7ba8dd50f78d972d8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 10:14:18 -0800 Subject: [PATCH 1139/4858] If only --ids are requested, we don't need to do anything else --- php/commands/user.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/user.php b/php/commands/user.php index bea3a5c556..407b27a71d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -30,6 +30,7 @@ public function _list( $args, $assoc_args ) { if ( isset( $assoc_args['ids'] ) ) { WP_CLI::out( implode( ' ', $users ) ); + exit; } $fields = array( From 4495f7838624c2693b5046ac38d8d445ac2a03ee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 10:20:55 -0800 Subject: [PATCH 1140/4858] Simplify the code to generate CSV and JSON output by typecasting. Feels a little dirty, but no harm no fowl. --- php/commands/user.php | 25 ++++++++----------------- php/utils.php | 1 + 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 407b27a71d..21f39165cc 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -63,30 +63,21 @@ public function _list( $args, $assoc_args ) { WP_CLI::line( 'Total: ' . count( $users ) . ' users' ); break; case 'json': - $json_users = array(); - - foreach( $users as $user ) { - $json_user = new stdClass; - foreach( $fields as $field ) { - $json_user->$field = $user->$field; - } - $json_users[] = $json_user; - } - - echo json_encode( $json_users ); - break; case 'csv': - $csv_users = array(); + $output_users = array(); foreach( $users as $user ) { - $csv_user = array(); + $output_user = new stdClass; foreach( $fields as $field ) { - $csv_user[$field] = $user->$field; + $output_user->$field = $user->$field; } - $csv_users[] = $csv_user; + $output_users[] = $output_user; } - WP_CLI\Utils\output_csv( $fields, $csv_users ); + if ( 'json' == $params['format'] ) + echo json_encode( $output_users ); + else + WP_CLI\Utils\output_csv( $fields, $output_users ); break; } diff --git a/php/utils.php b/php/utils.php index ad4f16a1b2..63f1247158 100644 --- a/php/utils.php +++ b/php/utils.php @@ -247,6 +247,7 @@ function output_csv( $headers = array(), $data = array() ) { } foreach( $data as $row ) { + $row = (array)$row; if ( ! empty( $headers ) ) { $build_row = array(); From 319cfab8f9769fd0843d98a07bd885de24c0d89c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 10:25:17 -0800 Subject: [PATCH 1141/4858] Update man doc --- man-src/user-list.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man-src/user-list.txt b/man-src/user-list.txt index 68c4eb6a76..90e4ddb205 100644 --- a/man-src/user-list.txt +++ b/man-src/user-list.txt @@ -8,3 +8,6 @@ Return only the IDs of the found users, separated by spaces. +* `--format`=<format>: + + Output list as table, CSV or JSON From 4d213b1f493f9e740072ef6d0e1fd16b1fea40d8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 10:51:15 -0800 Subject: [PATCH 1142/4858] Mention default output --- man-src/user-list.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man-src/user-list.txt b/man-src/user-list.txt index 90e4ddb205..f725025c3c 100644 --- a/man-src/user-list.txt +++ b/man-src/user-list.txt @@ -10,4 +10,4 @@ * `--format`=<format>: - Output list as table, CSV or JSON + Output list as table, CSV or JSON. Defaults to table. From ad58fc9411dbe9e96811d6ff93c42321bdc5c3fa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 10:52:02 -0800 Subject: [PATCH 1143/4858] Use the row we built to make sure we're only presenting data that correlates to headers --- php/utils.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/utils.php b/php/utils.php index 63f1247158..f800312f32 100644 --- a/php/utils.php +++ b/php/utils.php @@ -254,6 +254,7 @@ function output_csv( $headers = array(), $data = array() ) { foreach( $headers as $key ) { $build_row[] = $row[$key]; } + $row = $build_row; } echo '"' . implode( '","', $row ) . '"' . PHP_EOL; } From b24c271aadd1d6e1ac279dcfa88bdec35b209730 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 12:23:14 -0800 Subject: [PATCH 1144/4858] Use fputcsv with STDOUT instead of building our own CSV. Props @scribu --- php/utils.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/utils.php b/php/utils.php index f800312f32..fa878df3a9 100644 --- a/php/utils.php +++ b/php/utils.php @@ -242,9 +242,8 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria function output_csv( $headers = array(), $data = array() ) { // Prepare the headers if they were specified - if ( ! empty( $headers ) ) { - echo '"' . implode( '","', $headers ) . '"' . PHP_EOL; - } + if ( ! empty( $headers ) ) + fputcsv( STDOUT, $headers ); foreach( $data as $row ) { $row = (array)$row; @@ -256,6 +255,6 @@ function output_csv( $headers = array(), $data = array() ) { } $row = $build_row; } - echo '"' . implode( '","', $row ) . '"' . PHP_EOL; + fputcsv( STDOUT, $row ); } } From a0727cb643077f5bba7695321b79208f8c0cfd9c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Feb 2013 22:31:50 +0200 Subject: [PATCH 1145/4858] add some examples for user list and regenerate manpage --- man-src/user-list.txt | 6 ++++++ man/user-list.1 | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/man-src/user-list.txt b/man-src/user-list.txt index f725025c3c..8fc98a0131 100644 --- a/man-src/user-list.txt +++ b/man-src/user-list.txt @@ -11,3 +11,9 @@ * `--format`=<format>: Output list as table, CSV or JSON. Defaults to table. + +## EXAMPLES + + wp user list + + wp user list --role=administrator --format=csv diff --git a/man/user-list.1 b/man/user-list.1 index 2576b9acd5..251e9f254f 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -7,7 +7,7 @@ \fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" -wp user list [\-\-role=\fIrole\fR] [\-\-ids] +wp user list [\-\-role=\fIrole\fR] [\-\-ids] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -22,4 +22,20 @@ Only display users with a certain role\. . .IP Return only the IDs of the found users, separated by spaces\. +. +.TP +\fB\-\-format\fR=\fIformat\fR: +. +.IP +Output list as table, CSV or JSON\. Defaults to table\. +. +.SH "EXAMPLES" +. +.nf + +wp user list + +wp user list \-\-role=administrator \-\-format=csv +. +.fi From 8d2b26235a000b7136b328e9e76185f4d7b0c820 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Feb 2013 22:37:16 +0200 Subject: [PATCH 1146/4858] Reverse parameter order in output_csv() utility ... so that $headers can actually be optional. Also fix coding standards violations. --- php/commands/user.php | 15 +++++++-------- php/utils.php | 15 ++++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 21f39165cc..7ded9497d8 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -34,12 +34,12 @@ public function _list( $args, $assoc_args ) { } $fields = array( - 'ID', - 'user_login', - 'display_name', - 'user_email', - 'user_registered' - ); + 'ID', + 'user_login', + 'display_name', + 'user_email', + 'user_registered' + ); switch( $params['format'] ) { case 'table': @@ -77,10 +77,9 @@ public function _list( $args, $assoc_args ) { if ( 'json' == $params['format'] ) echo json_encode( $output_users ); else - WP_CLI\Utils\output_csv( $fields, $output_users ); + WP_CLI\Utils\output_csv( $output_users, $fields ); break; } - } /** diff --git a/php/utils.php b/php/utils.php index fa878df3a9..4e06615c73 100644 --- a/php/utils.php +++ b/php/utils.php @@ -236,25 +236,26 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria /** * Output data as CSV * - * @param array $headers Headers for the CSV (optional) - * @param array $data Data for each row + * @param array $rows Array of rows to output + * @param array $headers List of CSV columns (optional) */ -function output_csv( $headers = array(), $data = array() ) { +function output_csv( $rows, $headers = array() ) { // Prepare the headers if they were specified if ( ! empty( $headers ) ) fputcsv( STDOUT, $headers ); - foreach( $data as $row ) { - $row = (array)$row; + foreach ( $rows as $row ) { + $row = (array) $row; if ( ! empty( $headers ) ) { $build_row = array(); - foreach( $headers as $key ) { - $build_row[] = $row[$key]; + foreach ( $headers as $key ) { + $build_row[] = $row[ $key ]; } $row = $build_row; } fputcsv( STDOUT, $row ); } } + From ef47ed38f5abea346987c59caa26c341a1efd539 Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Mon, 4 Feb 2013 19:40:41 -0800 Subject: [PATCH 1147/4858] Instead of using bash unzip, using WP_CLI native theme install, with optional activate --- php/commands/scaffold.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 8a64ab07d8..5e5f466e45 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -141,6 +141,9 @@ function _s( $args, $assoc_args ) { $theme_slug = $args[0]; $theme_path = WP_CONTENT_DIR . "/themes"; + $zip_path = $theme_path.'/underscores.zip'; + $activate = ( isset( $assoc_args['activate'] ) ) ? 1 : 0; + $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), 'author' => "Me", @@ -154,18 +157,15 @@ function _s( $args, $assoc_args ) { $prepare .= ' -d underscoresme_description="'.$theme_description.'"'; $prepare .= ' -d underscoresme_generate_submit="Generate"'; $prepare .= ' -d underscoresme_generate="1"'; - $prepare .= ' http://underscores.me > '.$theme_path.'/underscores.zip'; - $prepare .= ' && unzip -d '.$theme_path.' '.$theme_path.'/underscores.zip && rm '.$theme_path.'/underscores.zip'; - - shell_exec($prepare); // Don't know the WordPress way of doing this. - - WP_CLI::success( "Created Theme: ".$data['theme_name'] ); + $prepare .= ' http://underscores.me > '.$zip_path; + shell_exec($prepare); + + WP_CLI::run_command( array( 'theme', 'install', $zip_path ), array( 'activate' => $activate ) ); - if ( isset( $assoc_args['activate'] ) ) - WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); } + private function get_output_path( $assoc_args, $subdir ) { extract( $assoc_args, EXTR_SKIP ); From 99982e5597ead78ed21004773f8fbcc6bee36868 Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Tue, 5 Feb 2013 12:06:43 -0800 Subject: [PATCH 1148/4858] changed shell_exec to properly use wp_remote_post, unzip, and unlink the temp file --- php/commands/scaffold.php | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5e5f466e45..dd8b288e3b 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -141,27 +141,38 @@ function _s( $args, $assoc_args ) { $theme_slug = $args[0]; $theme_path = WP_CONTENT_DIR . "/themes"; - $zip_path = $theme_path.'/underscores.zip'; - $activate = ( isset( $assoc_args['activate'] ) ) ? 1 : 0; + $url = "http://underscores.me"; $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), 'author' => "Me", 'author_uri' => "", ) ); - $theme_description = "Custom theme ".$data['theme_name']."developed by: ".$data['author']; - $prepare = 'curl -d underscoresme_name="'.$data['theme_name'].'"'; - $prepare .= ' -d underscoresme_slug="'.$theme_slug.'"'; - $prepare .= ' -d underscoresme_author="'.$data['author'].'"'; - $prepare .= ' -d underscoresme_author_uri="'.$data['author_uri'].'"'; - $prepare .= ' -d underscoresme_description="'.$theme_description.'"'; - $prepare .= ' -d underscoresme_generate_submit="Generate"'; - $prepare .= ' -d underscoresme_generate="1"'; - $prepare .= ' http://underscores.me > '.$zip_path; - shell_exec($prepare); + $body['underscoresme_name'] = $data['theme_name']; + $body['underscoresme_slug'] = $theme_slug; + $body['underscoresme_author'] = $data['author']; + $body['underscoresme_author_uri'] = $data['author_uri']; + $body['underscoresme_description'] = $theme_description; + $body['underscoresme_generate_submit'] = "Generate"; + $body['underscoresme_generate'] = "1"; + + // Request Array + $request = array( + 'method' => 'POST', + 'stream' => true, + 'body' => $body, + 'sslverify' => false + ); + + $tmpfname = wp_tempnam($url); + $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); + + unzip_file( $tmpfname, $theme_path ); + unlink($tmpfname); - WP_CLI::run_command( array( 'theme', 'install', $zip_path ), array( 'activate' => $activate ) ); + if ( isset( $assoc_args['activate'] ) ) + WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); } From 59d4752c04ed0e0769d9c8fc0787aaa6cf0f797e Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Tue, 5 Feb 2013 14:17:35 -0800 Subject: [PATCH 1149/4858] added man-src page for scaffold _s, tidied up formatting. --- man-src/scaffold-_s.txt | 21 +++++++++++++++++++++ php/commands/scaffold.php | 12 ++---------- 2 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 man-src/scaffold-_s.txt diff --git a/man-src/scaffold-_s.txt b/man-src/scaffold-_s.txt new file mode 100644 index 0000000000..82c57a8abb --- /dev/null +++ b/man-src/scaffold-_s.txt @@ -0,0 +1,21 @@ +## OPTIONS + +* <slug>: + + The slug for the new theme, used for prefixing functions. + +* `--activate`: + + Activate the newly downloaded theme. + +* `--theme_name=<title>`: + + What to put in the 'Theme Name:' header in style.css + +* `--author=<full name>`: + + What to put in the 'Author:' header in style.css + +* `--author_uri=<http url>`: + + What to put in the 'Author URI:' header in style.css \ No newline at end of file diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index dd8b288e3b..4597a7c75a 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -157,22 +157,14 @@ function _s( $args, $assoc_args ) { $body['underscoresme_generate_submit'] = "Generate"; $body['underscoresme_generate'] = "1"; - // Request Array - $request = array( - 'method' => 'POST', - 'stream' => true, - 'body' => $body, - 'sslverify' => false - ); - $tmpfname = wp_tempnam($url); $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); unzip_file( $tmpfname, $theme_path ); - unlink($tmpfname); + unlink( $tmpfname ); if ( isset( $assoc_args['activate'] ) ) - WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); } From 89b46de270d7e08f399b2b8638cbe47cd8ec9109 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 5 Feb 2013 23:29:32 +0100 Subject: [PATCH 1150/4858] Merged code from @benmay, would have liked to merge his commit but time aint on my side --- php/commands/media.php | 131 +++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 18 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index f1468cc8b8..da73d0acf4 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -6,27 +6,122 @@ * @package wp-cli */ class Media_Command extends WP_CLI_Command { + var $errors = false; + function __construct() { + WP_Filesystem(); + } - function __construct() { - WP_Filesystem(); - } + /** + * Import a file into the media library. + * + * @synopsis <filename> [--blog] [--zip=<zip>] + */ + function import( $args, $assoc_args = array() ) { + } - /** - * Import a file into the media library. - * - * @synopsis <filename> [--blog] - */ - function import( $args, $assoc_args = array() ) { - } - /** - * Regenerate thumbnail(s) - * - * @synopsis [--all] [--file=<file>] [--id=<id>] - */ - function regenerate( $args, $assoc_args = array() ) { + /** + * Regenerate thumbnail(s) + * + * @synopsis [--all] + * @todo [--file=<file>] [--id=<id>] + */ + function regenerate( $args, $assoc_args = array() ) { + global $wpdb; + + if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { + WP_CLI::error( "Unable to find any images. Are you sure some exist?" ); + return; + } + + WP_CLI::line( 'Found ' . count( $images ) . ' pictures to regenerate!' ); + + foreach ( $images as $image ) + $this->_process_regeneration( $image->ID ); + + if ( $this->errors ) + WP_CLI::error( 'Finished regenerating images - however, there were some errors throughout.' ); + else + WP_CLI::success( 'Finished - without any errors either!' ); + } - } - + private function _process_regeneration( $id ) { + // Don't break the JSON result + @error_reporting( 0 ); + + $image = get_post( $id ); + + if ( !$image || 'attachment' != $image->post_type || 'image/' != substr( $image->post_mime_type, 0, 6 ) ) { + $this->errors = true; + WP_CLI::line( "FAILED: {$image->post_title} - invalid image ID" ); + return; + } + + $fullsizepath = get_attached_file( $image->ID ); + + if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { + $this->errors = true; + WP_CLI::line( "FAILED: {$image->post_title} - Can't find it $fullsizepath" ); + return; + } + + // 5 minutes per image should be PLENTY + @set_time_limit( 900 ); + + $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); + $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); + + $imageFormat = $array_file[ count( $array_file ) - 1 ]; + + unset( $array_path[ count( $array_path ) - 1 ] ); + unset( $array_file[ count( $array_file ) - 1 ] ); + + $imagePath = implode( DIRECTORY_SEPARATOR, $array_path ) . DIRECTORY_SEPARATOR . implode( '.', $array_file ); + + + /** + * Continue + */ + $dirPath = explode( DIRECTORY_SEPARATOR, $imagePath ); + $imageName = sprintf( "%s-", $dirPath[ count( $dirPath ) - 1 ] ); + unset( $dirPath[ count( $dirPath ) - 1 ] ); + $dirPath = sprintf( "%s%s", implode( DIRECTORY_SEPARATOR, $dirPath ), DIRECTORY_SEPARATOR ); + + // Read and delete files + $dir = opendir( $dirPath ); + $files = array(); + while ( $file = readdir( $dir ) ) { + if ( !( strrpos( $file, $imageName ) === false ) ) { + $thumbnail = explode( $imageName, $file ); + if ( $thumbnail[ 0 ] == "" ) { + $thumbnailFormat = substr( $thumbnail[ 1 ], -4 ); + $thumbnail = substr( $thumbnail[ 1 ], 0, strlen( $thumbnail[ 1 ] ) - 4 ); + $thumbnail = explode( 'x', $thumbnail ); + if ( count( $thumbnail ) == 2 ) { + if ( is_numeric( $thumbnail[ 0 ] ) && is_numeric( $thumbnail[ 1 ] ) ) { + WP_CLI::line( "Thumbnail: {$thumbnail[0]} x {$thumbnail[1]} was deleted." ); + @unlink( $dirPath . $imageName . $thumbnail[ 0 ] . 'x' . $thumbnail[ 1 ] . $thumbnailFormat ); + } + } + } + } + } + + $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); + + if ( is_wp_error( $metadata ) ) { + WP_CLI::line( $metadata->get_error_message() ); + return; + } + + if ( empty( $metadata ) ) { + $this->errors = true; + WP_CLI::line( 'Unknown failure reason.' ); + return; + } + wp_update_attachment_metadata( $image->ID, $metadata ); + WP_CLI::success( esc_html( get_the_title( $image->ID ) ) . " (ID {$image->ID}): All thumbnails were successfully regenerated in " . timer_stop() . " seconds " ); + } + } WP_CLI::add_command( 'media', 'Media_Command' ); \ No newline at end of file From 5244e2a29b3009aa165a9507ff79bb168cf16e23 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 5 Feb 2013 23:30:22 +0100 Subject: [PATCH 1151/4858] Cleaned up error --- php/commands/media.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index da73d0acf4..0ded0a2b4f 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -22,12 +22,13 @@ function import( $args, $assoc_args = array() ) { /** * Regenerate thumbnail(s) * - * @synopsis [--all] + * @synopsis [--all] * @todo [--file=<file>] [--id=<id>] + * props @benmay */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; - + if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { WP_CLI::error( "Unable to find any images. Are you sure some exist?" ); return; From eefef9d7b001031c34c8ed8a2b8208cfe4fe81ef Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 6 Feb 2013 00:35:28 +0100 Subject: [PATCH 1152/4858] Added the regenerate --id= --- php/commands/media.php | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 0ded0a2b4f..f80ac4f665 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -22,15 +22,28 @@ function import( $args, $assoc_args = array() ) { /** * Regenerate thumbnail(s) * - * @synopsis [--all] - * @todo [--file=<file>] [--id=<id>] + * @synopsis [--id=<id>] + * @todo [--file=<file>] * props @benmay */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; - if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { - WP_CLI::error( "Unable to find any images. Are you sure some exist?" ); + $vars = wp_parse_args( $assoc_args, array( + 'id' => false, + ) ); + + extract($vars, EXTR_SKIP); + + $where_clause = ( $id ) ? "AND ID = $id" : 'bla'; + + if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { + if ( $id ) { + WP_CLI::error( "Unable to find the image. Are you sure some it exists?" ); + } else { + WP_CLI::error( "Unable to find any images. Are you sure some exist?" ); + } + return; } @@ -122,6 +135,18 @@ private function _process_regeneration( $id ) { wp_update_attachment_metadata( $image->ID, $metadata ); WP_CLI::success( esc_html( get_the_title( $image->ID ) ) . " (ID {$image->ID}): All thumbnails were successfully regenerated in " . timer_stop() . " seconds " ); } + + protected function extract_args( $assoc_args, $defaults ) { + $out = array(); + + foreach ( $defaults as $key => $value ) { + $out[ $key ] = isset( $assoc_args[ $key ] ) + ? $assoc_args[ $key ] + : $value; + } + + return $out; + } } From a98c6bbc9aa98e82bf7ac7ce76a5e615a04101ae Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 6 Feb 2013 00:38:37 +0100 Subject: [PATCH 1153/4858] Removed unused coded and the bla --- php/commands/media.php | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index f80ac4f665..f612cf80ff 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -35,7 +35,7 @@ function regenerate( $args, $assoc_args = array() ) { extract($vars, EXTR_SKIP); - $where_clause = ( $id ) ? "AND ID = $id" : 'bla'; + $where_clause = ( $id ) ? "AND ID = $id" : ''; if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { if ( $id ) { @@ -135,19 +135,6 @@ private function _process_regeneration( $id ) { wp_update_attachment_metadata( $image->ID, $metadata ); WP_CLI::success( esc_html( get_the_title( $image->ID ) ) . " (ID {$image->ID}): All thumbnails were successfully regenerated in " . timer_stop() . " seconds " ); } - - protected function extract_args( $assoc_args, $defaults ) { - $out = array(); - - foreach ( $defaults as $key => $value ) { - $out[ $key ] = isset( $assoc_args[ $key ] ) - ? $assoc_args[ $key ] - : $value; - } - - return $out; - } - } WP_CLI::add_command( 'media', 'Media_Command' ); \ No newline at end of file From c292153e47b17f57576728979ea7ac5cc7e5c59a Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Tue, 5 Feb 2013 16:45:44 -0800 Subject: [PATCH 1154/4858] added default timeout and generic theme description from author and theme name. --- php/commands/scaffold.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 4597a7c75a..bb7f473ab7 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -142,13 +142,15 @@ function _s( $args, $assoc_args ) { $theme_slug = $args[0]; $theme_path = WP_CONTENT_DIR . "/themes"; $url = "http://underscores.me"; + $theme_description = "Custom theme: ".$data['theme_name']." developed by, ".$data['author']; + $timeout = 30; $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), 'author' => "Me", 'author_uri' => "", ) ); - + $body['underscoresme_name'] = $data['theme_name']; $body['underscoresme_slug'] = $theme_slug; $body['underscoresme_author'] = $data['author']; From fa2229fe06ad7bebbf71ef21824bc615728e5e7e Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Tue, 5 Feb 2013 18:06:18 -0800 Subject: [PATCH 1155/4858] removed spaces in the synopsis --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index bb7f473ab7..23067d53cf 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -135,7 +135,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) /** * Generate starter code for a theme. * - * @synopsis <slug> [--theme_name=<title>] [--author=<full name>] [--author_uri=<http url>] [--activate] + * @synopsis <slug> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--activate] */ function _s( $args, $assoc_args ) { From f8ebaf6f92d97a3e16d38ba6d06662ca3602418e Mon Sep 17 00:00:00 2001 From: Jaime Martinez <jmslbam@gmail.com> Date: Wed, 6 Feb 2013 18:16:42 +0100 Subject: [PATCH 1156/4858] Changed filename from machinename to slug Because `wp scaffold post-type jm-foo` scaffolds a file name jm_foo.php bacause the machinename hyphens get replaced by underscores. Same behaviour as the plugin scaffold. Hyphens should separate words. --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 0061ac5716..06378544df 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -121,7 +121,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) } if ( $path = $this->get_output_path( $control_args, $subdir ) ) { - $filename = $path . $machine_name .'.php'; + $filename = $path . $slug .'.php'; $this->create_file( $filename, $final_output ); From 6451d4af9d9e1b3eb2178135fe85c222f70049ce Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Wed, 6 Feb 2013 09:20:46 -0800 Subject: [PATCH 1157/4858] fixed undefined variables --- php/commands/scaffold.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 23067d53cf..baf9e8bed4 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -142,7 +142,6 @@ function _s( $args, $assoc_args ) { $theme_slug = $args[0]; $theme_path = WP_CONTENT_DIR . "/themes"; $url = "http://underscores.me"; - $theme_description = "Custom theme: ".$data['theme_name']." developed by, ".$data['author']; $timeout = 30; $data = wp_parse_args( $assoc_args, array( @@ -151,6 +150,8 @@ function _s( $args, $assoc_args ) { 'author_uri' => "", ) ); + $theme_description = "Custom theme: ".$data['theme_name']." developed by, ".$data['author']; + $body['underscoresme_name'] = $data['theme_name']; $body['underscoresme_slug'] = $theme_slug; $body['underscoresme_author'] = $data['author']; From ecf4f74cfc9be7aa61a66cecff1c41f98ca33a80 Mon Sep 17 00:00:00 2001 From: Brandon Lavigne <B@Brandons-Mac-Pro-4.local> Date: Wed, 6 Feb 2013 09:51:21 -0800 Subject: [PATCH 1158/4858] added success message if remote request code is 200 --- php/commands/scaffold.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index baf9e8bed4..662fedeedf 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -163,6 +163,9 @@ function _s( $args, $assoc_args ) { $tmpfname = wp_tempnam($url); $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); + if ( $response['response']['code'] == 200 ) + WP_CLI::success( "Created theme '".$data['theme_name']."'." ); + unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); From 4a71b8cadd0b03ce84dfe3606b7b49758fa69d2d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 6 Feb 2013 20:04:00 +0200 Subject: [PATCH 1159/4858] generate manpage for scaffold _s. see #285 --- man/scaffold-_s.1 | 43 +++++++++++++++++++++++++++++++++++++++++++ php/man.php | 1 + 2 files changed, 44 insertions(+) create mode 100644 man/scaffold-_s.1 diff --git a/man/scaffold-_s.1 b/man/scaffold-_s.1 new file mode 100644 index 0000000000..d6ee0407ce --- /dev/null +++ b/man/scaffold-_s.1 @@ -0,0 +1,43 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SCAFFOLD\-_S" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-scaffold\-_s\fR \- Generate starter code for a theme\. +. +.SH "SYNOPSIS" +wp scaffold _s \fIslug\fR [\-\-theme_name=\fItitle\fR] [\-\-author=\fIfull\-name\fR] [\-\-author_uri=\fIhttp\-url\fR] [\-\-activate] +. +.SH "OPTIONS" +. +.TP +\fIslug\fR: +. +.IP +The slug for the new theme, used for prefixing functions\. +. +.TP +\fB\-\-activate\fR: +. +.IP +Activate the newly downloaded theme\. +. +.TP +\fB\-\-theme_name=<title>\fR: +. +.IP +What to put in the \'Theme Name:\' header in style\.css +. +.TP +\fB\-\-author=<full name>\fR: +. +.IP +What to put in the \'Author:\' header in style\.css +. +.TP +\fB\-\-author_uri=<http url>\fR: +. +.IP +What to put in the \'Author URI:\' header in style\.css + diff --git a/php/man.php b/php/man.php index 64f9fd69be..e2578fc8f5 100644 --- a/php/man.php +++ b/php/man.php @@ -54,6 +54,7 @@ function add_initial_markdown( $fd, $command ) { $shortdesc = $command->get_shortdesc(); $synopsis = $command->get_full_synopsis(); + $synopsis = str_replace( '_', '\_', $synopsis ); $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); $name_m = implode( '-', $path ); From cd8fd14b185b9c283085b35fdfbeb41b93cdb824 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 6 Feb 2013 20:08:38 +0200 Subject: [PATCH 1160/4858] regenerate some manpages --- man/eval-file.1 | 2 +- man/eval.1 | 2 +- man/export.1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man/eval-file.1 b/man/eval-file.1 index b6aecb6c46..fc8fb2cafd 100644 --- a/man/eval-file.1 +++ b/man/eval-file.1 @@ -4,7 +4,7 @@ .TH "WP\-EVAL\-FILE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-eval\-file\fR \- Loads and executes a PHP file after loading WordPress\. +\fBwp\-eval\-file\fR \- Load and execute a PHP file after loading WordPress\. . .SH "SYNOPSIS" wp eval\-file \fIpath\fR diff --git a/man/eval.1 b/man/eval.1 index 190f61c1d0..644451e322 100644 --- a/man/eval.1 +++ b/man/eval.1 @@ -4,7 +4,7 @@ .TH "WP\-EVAL" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-eval\fR \- Executes arbitrary PHP code after loading WordPress\. +\fBwp\-eval\fR \- Execute arbitrary PHP code after loading WordPress\. . .SH "SYNOPSIS" wp eval \fIphp\-code\fR diff --git a/man/export.1 b/man/export.1 index 17d770ab30..a11fc78cbd 100644 --- a/man/export.1 +++ b/man/export.1 @@ -7,7 +7,7 @@ \fBwp\-export\fR \- Export content to a WXR file\. . .SH "SYNOPSIS" -wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post\fI\fIin=\fRpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] +wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post__in=\fIpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] . .SH "OPTIONS" . From f93b73ca35350e48c727fc5a6862d3f7e2c31b33 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 7 Feb 2013 03:14:50 +0200 Subject: [PATCH 1161/4858] move /templates/ out of /php/ since it doesn't contain PHP files --- php/commands/scaffold.php | 4 ++-- {php/templates => templates}/plugin.mustache | 0 {php/templates => templates}/post_type.mustache | 0 {php/templates => templates}/post_type_extended.mustache | 0 {php/templates => templates}/taxonomy.mustache | 0 {php/templates => templates}/taxonomy_extended.mustache | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename {php/templates => templates}/plugin.mustache (100%) rename {php/templates => templates}/post_type.mustache (100%) rename {php/templates => templates}/post_type_extended.mustache (100%) rename {php/templates => templates}/taxonomy.mustache (100%) rename {php/templates => templates}/taxonomy_extended.mustache (100%) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 0b5c137710..08996cdecd 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -162,7 +162,7 @@ function _s( $args, $assoc_args ) { $tmpfname = wp_tempnam($url); $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); - + if ( $response['response']['code'] == 200 ) WP_CLI::success( "Created theme '".$data['theme_name']."'." ); @@ -315,7 +315,7 @@ protected function extract_args( $assoc_args, $defaults ) { } private function render( $template, $data ) { - $scaffolds_dir = WP_CLI_ROOT . 'templates'; + $scaffolds_dir = WP_CLI_ROOT . '../templates'; $template = file_get_contents( $scaffolds_dir . '/' . $template ); diff --git a/php/templates/plugin.mustache b/templates/plugin.mustache similarity index 100% rename from php/templates/plugin.mustache rename to templates/plugin.mustache diff --git a/php/templates/post_type.mustache b/templates/post_type.mustache similarity index 100% rename from php/templates/post_type.mustache rename to templates/post_type.mustache diff --git a/php/templates/post_type_extended.mustache b/templates/post_type_extended.mustache similarity index 100% rename from php/templates/post_type_extended.mustache rename to templates/post_type_extended.mustache diff --git a/php/templates/taxonomy.mustache b/templates/taxonomy.mustache similarity index 100% rename from php/templates/taxonomy.mustache rename to templates/taxonomy.mustache diff --git a/php/templates/taxonomy_extended.mustache b/templates/taxonomy_extended.mustache similarity index 100% rename from php/templates/taxonomy_extended.mustache rename to templates/taxonomy_extended.mustache From b590c7eceae68e2e788a97bc0644cf259414e55c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Feb 2013 00:19:34 +0200 Subject: [PATCH 1162/4858] add test case --- tests/abstract-spec.php | 14 ++++++++++++-- tests/spec-core.php | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index e49239ddbb..6a40f9b748 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -15,9 +15,13 @@ private static function run_sql( $sql ) { exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); } - protected function setUp() { + protected function tearDown() { + $dbname = self::$db_settings['dbname']; + $this->run_sql( "DROP DATABASE IF EXISTS $dbname" ); + } + + private function create_db() { $dbname = self::$db_settings['dbname']; - $this->run_sql( "DROP DATABASE $dbname" ); $this->run_sql( "CREATE DATABASE $dbname" ); } @@ -28,6 +32,11 @@ public function runGiven( &$world, $action, $arguments ) { } break; + case 'database': { + $this->create_db(); + } + break; + case 'wp files': { $world['runner']->download_wordpress_files(); } @@ -39,6 +48,7 @@ public function runGiven( &$world, $action, $arguments ) { break; case 'wp install': { + $this->create_db(); $world['runner']->download_wordpress_files(); $world['runner']->create_config( self::$db_settings ); $world['runner']->run_install(); diff --git a/tests/spec-core.php b/tests/spec-core.php index adb4c574dc..0824a401ed 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -30,12 +30,28 @@ public function noWpConfig() { ->then( 'return code should be', 0 ); } + /** @scenario */ + public function dbDoesntExist() { + $this + ->given( 'empty dir' ) + ->and( 'wp files' ) + ->and( 'wp config' ) + + ->when( 'invoking', 'wp' ) + ->then( 'return code should be', 1 ) + ->and( 'output should be', "Error: Can't connect to the database." ) + + ->when( 'invoking', 'db create' ) + ->then( 'return code should be', 0 ); + } + /** @scenario */ public function dbTablesNotInstalled() { $this ->given( 'empty dir' ) ->and( 'wp files' ) ->and( 'wp config' ) + ->and( 'database' ) ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 1 ) @@ -47,7 +63,7 @@ public function dbTablesNotInstalled() { ->then( 'return code should be', 0 ) ->when( 'invoking', 'post list --ids' ) - ->then( 'output should be', 1 ); + ->then( 'output should be', "1" ); } /** @scenario */ From cd542d30d3580131a9619e76b0f11b849794e8fd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Feb 2013 00:21:55 +0200 Subject: [PATCH 1163/4858] make 'wp install' imply 'empty dir' --- tests/abstract-spec.php | 1 + tests/spec-core.php | 6 ++---- tests/spec-flags.php | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 6a40f9b748..1e438b945f 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -49,6 +49,7 @@ public function runGiven( &$world, $action, $arguments ) { case 'wp install': { $this->create_db(); + $world['runner'] = new WP_CLI_Command_Runner; $world['runner']->download_wordpress_files(); $world['runner']->create_config( self::$db_settings ); $world['runner']->run_install(); diff --git a/tests/spec-core.php b/tests/spec-core.php index 0824a401ed..8913a448e0 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -69,8 +69,7 @@ public function dbTablesNotInstalled() { /** @scenario */ public function fullInstall() { $this - ->given( 'empty dir' ) - ->and( 'wp install' ) + ->given( 'wp install' ) ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 0 ); @@ -79,8 +78,7 @@ public function fullInstall() { /** @scenario */ public function customWpContentDir() { $this - ->given( 'empty dir' ) - ->and( 'wp install' ) + ->given( 'wp install' ) ->and( 'custom wp-content dir' ) ->when( 'invoking', 'theme status twentytwelve' ) diff --git a/tests/spec-flags.php b/tests/spec-flags.php index 6ca84276b6..79bd5fc415 100644 --- a/tests/spec-flags.php +++ b/tests/spec-flags.php @@ -5,8 +5,7 @@ class FlagsSpec extends WP_CLI_Spec { /** @scenario */ public function quietRun() { $this - ->given( 'empty dir' ) - ->and( 'wp install' ) + ->given( 'wp install' ) ->when( 'invoking', '' ) ->then( 'return code should be', 0 ) From 14f7085497670ce74008fd4cb08f34d9daf7540a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Feb 2013 02:28:07 +0200 Subject: [PATCH 1164/4858] add our own wp_die() handler --- php/utils-wp.php | 19 +++++++++++++++++++ php/wp-settings-cli.php | 2 ++ tests/spec-core.php | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index 0fb19ff060..4609617a5f 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -21,6 +21,25 @@ function wp_debug_mode() { } } +function replace_wp_die_handler() { + \remove_filter( 'wp_die_handler', '_default_wp_die_handler' ); + \add_filter( 'wp_die_handler', function() { return __NAMESPACE__ . '\\' . 'wp_die_handler'; } ); +} + +function wp_die_handler( $message ) { + if ( is_wp_error( $message ) ) { + $message = $message->get_error_message(); + } + + if ( preg_match( '|^\<h1>(.+?)</h1>|', $message, $matches ) ) { + $message = $matches[1]; + } + + $message = html_entity_decode( $message ); + + \WP_CLI::error( $message ); +} + function maybe_require( $since, $path ) { global $wp_version; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 7855768a52..e58ea0d835 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -56,6 +56,8 @@ require( ABSPATH . WPINC . '/plugin.php' ); require( ABSPATH . WPINC . '/pomo/mo.php' ); +Utils\replace_wp_die_handler(); + // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); diff --git a/tests/spec-core.php b/tests/spec-core.php index 8913a448e0..95b3fce5fd 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -39,7 +39,7 @@ public function dbDoesntExist() { ->when( 'invoking', 'wp' ) ->then( 'return code should be', 1 ) - ->and( 'output should be', "Error: Can't connect to the database." ) + ->and( 'output should be', "Error: Can’t select database\n" ) ->when( 'invoking', 'db create' ) ->then( 'return code should be', 0 ); From 44cfc2a99514fce23179375322cbccb9f8d3e78b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Feb 2013 03:12:09 +0200 Subject: [PATCH 1165/4858] tests: separate stdout from stderr The more precise assertions expose several buggy tests. Also reverts WP_CLI::error() second parameter to $label, since sending the first line to STDERR and subsequent ones to STDOUT is confusing. If you want to have a multiline error message, just insert \n characters. --- php/WP_CLI/Runner.php | 6 +++--- php/class-wp-cli.php | 5 ++--- php/utils-wp.php | 6 +++--- tests/abstract-spec.php | 13 ++++++++++--- tests/command-runner.php | 20 +++++++++++++++----- tests/spec-core.php | 15 +++++++++------ tests/spec-flags.php | 8 +++++--- 7 files changed, 47 insertions(+), 26 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ce1287e7e3..7dbd8637d0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -244,9 +244,9 @@ public function before_wp_load() { } if ( !Utils\locate_wp_config() ) { - WP_CLI::error( "wp-config.php not found.", false ); - WP_CLI::line( "Either create one manually or use `wp core config`." ); - exit(1); + WP_CLI::error( + "wp-config.php not found.\n" . + "Either create one manually or use `wp core config`." ); } if ( $this->cmd_starts_with( array( 'db' ) ) ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 884327447d..02f65c21b5 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -128,11 +128,10 @@ static function line( $message = '' ) { * Display an error in the CLI and end with a newline * * @param string $message - * @param bool $exit + * @param string $label */ - static function error( $message, $exit = true ) { + static function error( $message, $label = 'Error' ) { if ( ! isset( self::$runner->assoc_args[ 'completions' ] ) ) { - $label = 'Error'; $msg = '%R' . $label . ': %n' . self::error_to_string( $message ) . "\n"; fwrite( STDERR, \cli\Colors::colorize( $msg, self::get_config('color') ) ); } diff --git a/php/utils-wp.php b/php/utils-wp.php index 4609617a5f..2153d3feeb 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -6,9 +6,9 @@ function wp_not_installed() { if ( !is_blog_installed() && !defined( 'WP_INSTALLING' ) ) { - \WP_CLI::error( 'The site you have requested is not installed.', false ); - \WP_CLI::line( 'Run `wp core install`.' ); - exit( 1 ); + \WP_CLI::error( + "The site you have requested is not installed.\n" . + 'Run `wp core install`.' ); } } diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 1e438b945f..08a1e27ad2 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -103,13 +103,20 @@ public function runThen( &$world, $action, $arguments ) { } break; - case 'output should be': { - $this->assertEquals( $arguments[0], $world['result']->output, $action ); + case 'stdout': { + $this->assertEquals( $arguments[0], $world['result']->stdout, $action ); + } + break; + + case 'stderr': { + $this->assertEquals( $arguments[0], $world['result']->stderr, $action ); } break; case 'should have output': { - $this->assertNotEmpty( $world['result']->output, $action ); + if ( empty( $world['result']->stdout ) ) + var_dump($world['result']); + $this->assertNotEmpty( $world['result']->stdout, $action ); } break; diff --git a/tests/command-runner.php b/tests/command-runner.php index a54cd7f197..3901991ac5 100644 --- a/tests/command-runner.php +++ b/tests/command-runner.php @@ -15,13 +15,23 @@ public function run( $command, $cwd = false ) { $wp_cli_path = getcwd() . "/bin/wp"; - $sh_command = "cd $cwd; $wp_cli_path $command 2>&1;"; + $sh_command = "cd $cwd; $wp_cli_path $command"; - ob_start(); - system( $sh_command, $return_code ); - $output = ob_get_clean(); + $process = proc_open( $sh_command, array( + 0 => STDIN, + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ), $pipes ); - return (object) compact( 'return_code', 'output' ); + $stdout = stream_get_contents( $pipes[1] ); + fclose( $pipes[1] ); + + $stderr = stream_get_contents( $pipes[2] ); + fclose( $pipes[2] ); + + $return_code = proc_close( $process ); + + return (object) compact( 'return_code', 'stdout', 'stderr' ); } public function create_config( $db_settings ) { diff --git a/tests/spec-core.php b/tests/spec-core.php index 95b3fce5fd..90a83bdafa 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -21,7 +21,7 @@ public function noWpConfig() { ->then( 'return code should be', 1 ) ->when( 'invoking', 'core install' ) - ->then( 'output should be', + ->then( 'stderr', "Error: wp-config.php not found.\n" . "Either create one manually or use `wp core config`.\n" ) @@ -37,9 +37,9 @@ public function dbDoesntExist() { ->and( 'wp files' ) ->and( 'wp config' ) - ->when( 'invoking', 'wp' ) + ->when( 'invoking', '' ) ->then( 'return code should be', 1 ) - ->and( 'output should be', "Error: Can’t select database\n" ) + ->and( 'stderr', "Error: Can’t select database\n" ) ->when( 'invoking', 'db create' ) ->then( 'return code should be', 0 ); @@ -56,14 +56,17 @@ public function dbTablesNotInstalled() { ->when( 'invoking', 'core is-installed' ) ->then( 'return code should be', 1 ) - ->when( 'invoking', 'help' ) - ->then( 'should have output' ) + ->when( 'invoking', '' ) + ->then( 'stderr', + "Error: The site you have requested is not installed.\n" . + "Run `wp core install`.\n" + ) ->when( 'invoking', 'core install' ) ->then( 'return code should be', 0 ) ->when( 'invoking', 'post list --ids' ) - ->then( 'output should be', "1" ); + ->then( 'stdout', "1" ); } /** @scenario */ diff --git a/tests/spec-flags.php b/tests/spec-flags.php index 79bd5fc415..c720fda61c 100644 --- a/tests/spec-flags.php +++ b/tests/spec-flags.php @@ -13,11 +13,13 @@ public function quietRun() { ->when( 'invoking', '--quiet' ) ->then( 'return code should be', 0 ) - ->and( 'output should be', '' ) + ->and( 'stdout', '' ) - ->when( 'invoking', 'wp non-existing-command --quiet' ) + ->when( 'invoking', 'non-existing-command --quiet' ) ->then( 'return code should be', 1 ) - ->and( 'should have output' ); + ->and( 'stderr', + "Error: 'non-existing-command' is not a registered wp command. See 'wp help'.\n" + ); } } From 9782a3490126dbb2a0a756b00772a8443e8b1a4c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Feb 2013 04:14:44 +0200 Subject: [PATCH 1166/4858] fix WP_CLI::error() not exiting --- php/class-wp-cli.php | 3 +-- tests/spec-core.php | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 02f65c21b5..ad70c61c16 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -136,8 +136,7 @@ static function error( $message, $label = 'Error' ) { fwrite( STDERR, \cli\Colors::colorize( $msg, self::get_config('color') ) ); } - if ( $exit ) - exit(1); + exit(1); } /** diff --git a/tests/spec-core.php b/tests/spec-core.php index 90a83bdafa..d7dab9ed41 100644 --- a/tests/spec-core.php +++ b/tests/spec-core.php @@ -40,6 +40,7 @@ public function dbDoesntExist() { ->when( 'invoking', '' ) ->then( 'return code should be', 1 ) ->and( 'stderr', "Error: Can’t select database\n" ) + ->and( 'stdout', '' ) ->when( 'invoking', 'db create' ) ->then( 'return code should be', 0 ); From 131943b36753e001f1c555df055b4f183d63d09d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 15:00:30 -0800 Subject: [PATCH 1167/4858] A term command with subcommands for creating, updating, deleting and listing taxonomy terms --- php/commands/term.php | 153 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 php/commands/term.php diff --git a/php/commands/term.php b/php/commands/term.php new file mode 100644 index 0000000000..c52db45bed --- /dev/null +++ b/php/commands/term.php @@ -0,0 +1,153 @@ +<?php +/** + * Manage terms. + * + * @package wp-cli + */ +class Term_Command extends WP_CLI_Command { + + /** + * List terms in a taxonomy. + * + * @subcommand list + * @synopsis <taxonomy> [--format=<format>] + */ + public function _list( $args, $assoc_args ) { + + list( $taxonomy ) = $args; + + $defaults = array( + 'format' => 'table', + 'hide_empty' => false, + ); + $assoc_args = wp_parse_args( $assoc_args, $defaults ); + + $terms = get_terms( array( $taxonomy ), $assoc_args ); + + $fields = array( + 'term_id', + 'term_taxonomy_id', + 'name', + 'slug', + 'description', + 'parent', + 'count', + ); + + switch ( $assoc_args['format'] ) { + case 'table': + $table = new \cli\Table(); + + $table->setHeaders( $fields ); + + foreach ( $terms as $term ) { + $line = array(); + + foreach ( $fields as $field ) { + $line[] = $term->$field; + } + + $table->addRow( $line ); + } + + $table->display(); + + WP_CLI::line( 'Total: ' . count( $terms ) . ' terms.' ); + break; + case 'csv': + case 'json': + $output_terms = array(); + + foreach( $terms as $term ) { + $output_term = new stdClass; + foreach( $fields as $field ) { + $output_term->$field = $term->$field; + } + $output_terms[] = $output_term; + } + + if ( 'json' == $assoc_args['format'] ) + echo json_encode( $output_terms ); + else + WP_CLI\Utils\output_csv( $output_terms, $fields ); + break; + } + + } + + /** + * Create a term. + * + * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] + */ + public function create( $args, $assoc_args ) { + + list( $term, $taxonomy ) = $args; + + $defaults = array( + 'slug' => sanitize_title( $term ), + 'description' => '', + ); + $assoc_args = wp_parse_args( $assoc_args, $defaults ); + + $ret = wp_insert_term( $term, $taxonomy, $assoc_args ); + + if ( is_wp_error( $ret ) ) + WP_CLI::error( $ret->get_error_message() ); + else + WP_CLI::success( "Term created." ); + } + + /** + * Update a term. + * + * @synopsis <term-id> <taxonomy> [--name=<name>] [--slug=<slug>] [--description=<description>] [--parent=<parent>] + */ + public function update( $args, $assoc_args ) { + + list( $term_id, $taxonomy ) = $args; + + $defaults = array( + 'name' => null, + 'slug' => null, + 'description' => null, + 'parent' => null, + ); + $assoc_args = wp_parse_args( $assoc_args, $defaults ); + + foreach( $assoc_args as $key => $value ) { + if ( is_null( $value ) ) + unset( $assoc_args[$key] ); + } + + $ret = wp_update_term( $term_id, $taxonomy, $assoc_args ); + + if ( is_wp_error( $ret ) ) + WP_CLI::error( $ret->get_error_message() ); + else + WP_CLI::success( "Term updated." ); + + } + + /** + * Delete a term. + * + * @synopsis <term-id> <taxonomy> + */ + public function delete( $args ) { + + list( $term_id, $taxonomy ) = $args; + + $ret = wp_delete_term( $term_id, $taxonomy ); + + if ( is_wp_error( $ret ) ) + WP_CLI::error( $ret->get_error_message() ); + else if ( $ret ) + WP_CLI::success( "Term deleted." ); + else + WP_CLI::error( "Error deleting term." ); + } + +} + +WP_CLI::add_command( 'term', 'Term_Command' ); \ No newline at end of file From fc211aeba0840796b1320a99cc3ee0a85a338edf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 15:31:14 -0800 Subject: [PATCH 1168/4858] Abstract output of data to a format_items() utility function --- php/commands/term.php | 40 +----------------------------------- php/utils.php | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c52db45bed..d6c9ffb34e 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -34,45 +34,7 @@ public function _list( $args, $assoc_args ) { 'count', ); - switch ( $assoc_args['format'] ) { - case 'table': - $table = new \cli\Table(); - - $table->setHeaders( $fields ); - - foreach ( $terms as $term ) { - $line = array(); - - foreach ( $fields as $field ) { - $line[] = $term->$field; - } - - $table->addRow( $line ); - } - - $table->display(); - - WP_CLI::line( 'Total: ' . count( $terms ) . ' terms.' ); - break; - case 'csv': - case 'json': - $output_terms = array(); - - foreach( $terms as $term ) { - $output_term = new stdClass; - foreach( $fields as $field ) { - $output_term->$field = $term->$field; - } - $output_terms[] = $output_term; - } - - if ( 'json' == $assoc_args['format'] ) - echo json_encode( $output_terms ); - else - WP_CLI\Utils\output_csv( $output_terms, $fields ); - break; - } - + WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); } /** diff --git a/php/utils.php b/php/utils.php index 4e06615c73..10b7604c3f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -233,6 +233,53 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria return $data; } +/** + * Output items in a table, JSON, or CSV + * + * @param string $format Format to use: 'table', 'json', 'csv' + * @param array $fields Named fields for each item of data + * @param array $items Data to output + */ +function format_items( $format, $fields, $items ) { + + switch ( $format ) { + case 'table': + $table = new \cli\Table(); + + $table->setHeaders( $fields ); + + foreach ( $items as $item ) { + $line = array(); + + foreach ( $fields as $field ) { + $line[] = $item->$field; + } + + $table->addRow( $line ); + } + + $table->display(); + break; + case 'csv': + case 'json': + $output_items = array(); + + foreach( $items as $item ) { + $output_item = new \stdClass; + foreach( $fields as $field ) { + $output_item->$field = $item->$field; + } + $output_items[] = $output_item; + } + + if ( 'json' == $format ) + echo json_encode( $output_items ); + else + output_csv( $output_items, $fields ); + break; + } +} + /** * Output data as CSV * From 8ace75225c7868deec378e0cf51e20f0add23964 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 16:34:57 -0800 Subject: [PATCH 1169/4858] Man pages --- man-src/term-create.txt | 21 +++++++++++++++++++++ man-src/term-delete.txt | 13 +++++++++++++ man-src/term-list.txt | 13 +++++++++++++ man-src/term-update.txt | 29 +++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 man-src/term-create.txt create mode 100644 man-src/term-delete.txt create mode 100644 man-src/term-list.txt create mode 100644 man-src/term-update.txt diff --git a/man-src/term-create.txt b/man-src/term-create.txt new file mode 100644 index 0000000000..19fe84d8e1 --- /dev/null +++ b/man-src/term-create.txt @@ -0,0 +1,21 @@ +## OPTIONS + +* `<term>`: + + A name for the new term. + +* `<taxonomy>`: + + Taxonomy for the new term. + +* `--slug`=<slug>: + + A unique slug for the new term. Defaults to sanitized version of name. + +* `--description`=<description>: + + A description for the new term. + +## EXAMPLES + + wp term create Apple category --description="A type of fruit" \ No newline at end of file diff --git a/man-src/term-delete.txt b/man-src/term-delete.txt new file mode 100644 index 0000000000..03f23097d2 --- /dev/null +++ b/man-src/term-delete.txt @@ -0,0 +1,13 @@ +## OPTIONS + +* `<term-id>`: + + ID for the term to delete. + +* `<taxonomy>`: + + Taxonomy of the term to delete. + +## EXAMPLES + + wp term delete 15 category \ No newline at end of file diff --git a/man-src/term-list.txt b/man-src/term-list.txt new file mode 100644 index 0000000000..f991f2558f --- /dev/null +++ b/man-src/term-list.txt @@ -0,0 +1,13 @@ +## OPTIONS + +* `<taxonomy>`: + + List terms of a given taxonomy. + +* `--format`=<format>: + + Output list as table, CSV or JSON. Defaults to table. + +## EXAMPLES + + wp term list category --format=csv \ No newline at end of file diff --git a/man-src/term-update.txt b/man-src/term-update.txt new file mode 100644 index 0000000000..82ae9a1135 --- /dev/null +++ b/man-src/term-update.txt @@ -0,0 +1,29 @@ +## OPTIONS + +* `<term-id>`: + + ID for the term to update. + +* `<taxonomy>`: + + Taxonomy of the term to update. + +* `--name`=<name>: + + A new name for the term. + +* `--slug`=<slug>: + + A new slug for the term. + +* `--description`=<description>: + + A new description for the term. + +* `--parent`=<parent>: + + A new parent for the term. + +## EXAMPLES + + wp term update 15 category --name=Apple \ No newline at end of file From 669849fdd3fadd8510edcb409635ea8373dc5568 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Feb 2013 18:40:19 -0800 Subject: [PATCH 1170/4858] Accept a parent when creating a new term --- man-src/term-create.txt | 4 ++++ php/commands/term.php | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/man-src/term-create.txt b/man-src/term-create.txt index 19fe84d8e1..31ca3a4ee9 100644 --- a/man-src/term-create.txt +++ b/man-src/term-create.txt @@ -16,6 +16,10 @@ A description for the new term. +* `--parent`=<parent>: + + A parent for the new term. + ## EXAMPLES wp term create Apple category --description="A type of fruit" \ No newline at end of file diff --git a/php/commands/term.php b/php/commands/term.php index d6c9ffb34e..888ef2da55 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -40,7 +40,7 @@ public function _list( $args, $assoc_args ) { /** * Create a term. * - * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] + * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<parent>] */ public function create( $args, $assoc_args ) { @@ -49,6 +49,7 @@ public function create( $args, $assoc_args ) { $defaults = array( 'slug' => sanitize_title( $term ), 'description' => '', + 'parent' => '', ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); From f5f1ff1f38990c8d34f4a6736c585272972a2b1c Mon Sep 17 00:00:00 2001 From: Dominik Schilling <dominikschilling+git@gmail.com> Date: Sun, 10 Feb 2013 11:53:33 +0100 Subject: [PATCH 1171/4858] Fix error output if no WordPress install exists --- php/WP_CLI/Runner.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7dbd8637d0..1daa7ef482 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -233,9 +233,9 @@ public function before_wp_load() { } if ( !is_readable( ABSPATH . 'wp-load.php' ) ) { - WP_CLI::error( "This does not seem to be a WordPress install.", false ); - WP_CLI::line( "Pass --path=`path/to/wordpress` or run `wp core download`." ); - exit(1); + WP_CLI::error( + "This does not seem to be a WordPress install.\n" . + "Pass --path=`path/to/wordpress` or run `wp core download`." ); } if ( array( 'core', 'config' ) == $this->arguments ) { @@ -310,4 +310,3 @@ private function _run_command() { WP_CLI::run_command( $this->arguments, $this->assoc_args ); } } - From 78e00cb423e556712aa012b30893cf3dd76cfcc3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Feb 2013 17:35:17 +0200 Subject: [PATCH 1172/4858] Use `cp -r` instead of `mv` for moving WP files into the current dir This allows installing WP into a directory that already has a wp-content dir. Props @carlalexander. Closes #293 --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index ac9600ebfd..dc1f2dbb77 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -37,7 +37,7 @@ public function download( $args, $assoc_args ) { $silent = WP_CLI::get_config('quiet') ? ' --silent ' : ' '; WP_CLI::launch( 'curl -f' . $silent . escapeshellarg( $download_url ) . ' | tar xz' ); - WP_CLI::launch( 'mv wordpress/* . && rm -rf wordpress' ); + WP_CLI::launch( 'cp -r wordpress/* . && rm -rf wordpress' ); WP_CLI::success( 'WordPress downloaded.' ); } From 2fdc22ba73cc8ba3fe3c854a4ab25ccab17e6ffb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Feb 2013 18:31:33 +0200 Subject: [PATCH 1173/4858] add --force flag to wp core download. fixes #221 --- man/core-download.1 | 2 +- php/commands/core.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man/core-download.1 b/man/core-download.1 index 19b3e11eb3..956e22cdc5 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -7,7 +7,7 @@ \fBwp\-core\-download\fR \- Download core WordPress files\. . .SH "SYNOPSIS" -wp core download [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] [\-\-path=\fIpath\fR] +wp core download [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] [\-\-path=\fIpath\fR] [\-\-force] . .SH "OPTIONS" . diff --git a/php/commands/core.php b/php/commands/core.php index dc1f2dbb77..20502c90a5 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -10,10 +10,10 @@ class Core_Command extends WP_CLI_Command { /** * Download core WordPress files. * - * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] + * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] [--force] */ public function download( $args, $assoc_args ) { - if ( is_readable( ABSPATH . 'wp-load.php' ) ) + if ( !isset( $assoc_args['force'] ) && is_readable( ABSPATH . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); if ( isset( $assoc_args['path'] ) ) From d7f29cbec8dae69f1e75310d3395d89f1757abf6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 20:10:31 +0200 Subject: [PATCH 1174/4858] make cmd runner return command string, for easy debugging --- tests/command-runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/command-runner.php b/tests/command-runner.php index 3901991ac5..d35e4d1a63 100644 --- a/tests/command-runner.php +++ b/tests/command-runner.php @@ -31,7 +31,7 @@ public function run( $command, $cwd = false ) { $return_code = proc_close( $process ); - return (object) compact( 'return_code', 'stdout', 'stderr' ); + return (object) compact( 'command', 'return_code', 'stdout', 'stderr' ); } public function create_config( $db_settings ) { From 4a4f3805bdff96b63ecc769948fd31699768bdda Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 20:53:55 +0200 Subject: [PATCH 1175/4858] introduce SynopsisParser class --- php/WP_CLI/Dispatcher/Subcommand.php | 56 +---------------------- php/WP_CLI/SynopsisParser.php | 66 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 55 deletions(-) create mode 100644 php/WP_CLI/SynopsisParser.php diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index e725199dd3..47ebb6f21d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -51,7 +51,7 @@ protected function check_args( $args, $assoc_args ) { if ( !$synopsis ) return; - $accepted_params = $this->parse_synopsis( $synopsis ); + $accepted_params = \WP_CLI\SynopsisParser::parse( $synopsis ); $this->check_positional( $args, $accepted_params ); @@ -119,59 +119,5 @@ private function check_unknown_assoc( $assoc_args, $accepted_params ) { } } - protected function parse_synopsis( $synopsis ) { - list( $patterns, $params ) = self::get_patterns(); - - $tokens = preg_split( '/[\s\t]+/', $synopsis ); - - foreach ( $tokens as $token ) { - foreach ( $patterns as $regex => $desc ) { - if ( preg_match( $regex, $token, $matches ) ) { - $type = $desc['type']; - $params[$type][] = array_merge( $matches, $desc ); - break; - } - } - } - - return $params; - } - - private static function get_patterns() { - $p_name = '(?P<name>[a-z-_]+)'; - $p_value = '(?P<value>[a-z-|]+)'; - - $param_types = array( - array( 'positional', "<$p_value>", 1, 1 ), - array( 'generic', "--<field>=<value>", 1, 1 ), - array( 'assoc', "--$p_name=<$p_value>", 1, 1 ), - array( 'flag', "--$p_name", 1, 0 ), - ); - - $patterns = array(); - $params = array(); - - foreach ( $param_types as $pt ) { - list( $type, $pattern, $optional, $mandatory ) = $pt; - - if ( $mandatory ) { - $patterns[ "/^$pattern$/" ] = array( - 'type' => $type, - 'optional' => false - ); - } - - if ( $optional ) { - $patterns[ "/^\[$pattern\]$/" ] = array( - 'type' => $type, - 'optional' => true - ); - } - - $params[ $type ] = array(); - } - - return array( $patterns, $params ); - } } diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php new file mode 100644 index 0000000000..bc594df3d4 --- /dev/null +++ b/php/WP_CLI/SynopsisParser.php @@ -0,0 +1,66 @@ +<?php + +namespace WP_CLI; + +class SynopsisParser { + + /** + * @param string + * @return array List of parameters + */ + static function parse( $synopsis ) { + list( $patterns, $params ) = self::get_patterns(); + + $tokens = preg_split( '/[\s\t]+/', $synopsis ); + + foreach ( $tokens as $token ) { + foreach ( $patterns as $regex => $desc ) { + if ( preg_match( $regex, $token, $matches ) ) { + $type = $desc['type']; + $params[$type][] = array_merge( $matches, $desc ); + break; + } + } + } + + return $params; + } + + private static function get_patterns() { + $p_name = '(?P<name>[a-z-_]+)'; + $p_value = '(?P<value>[a-z-|]+)'; + + $param_types = array( + array( 'positional', "<$p_value>", 1, 1 ), + array( 'generic', "--<field>=<value>", 1, 1 ), + array( 'assoc', "--$p_name=<$p_value>", 1, 1 ), + array( 'flag', "--$p_name", 1, 0 ), + ); + + $patterns = array(); + $params = array(); + + foreach ( $param_types as $pt ) { + list( $type, $pattern, $optional, $mandatory ) = $pt; + + if ( $mandatory ) { + $patterns[ "/^$pattern$/" ] = array( + 'type' => $type, + 'optional' => false + ); + } + + if ( $optional ) { + $patterns[ "/^\[$pattern\]$/" ] = array( + 'type' => $type, + 'optional' => true + ); + } + + $params[ $type ] = array(); + } + + return array( $patterns, $params ); + } +} + From 68a33aeccff175d412cccbc256e4cd5549420870 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 19:14:07 +0200 Subject: [PATCH 1176/4858] add tests for SynopsisParser --- phpunit.xml.dist | 1 + tests/bootstrap.php | 1 + tests/test-synopsis.php | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/test-synopsis.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 917a7d50ad..529dae0efd 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,6 +5,7 @@ <testsuites> <testsuite> <directory prefix="spec-" suffix=".php">tests/</directory> + <directory prefix="test-" suffix=".php">tests/</directory> </testsuite> </testsuites> </phpunit> diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 4e82b7fa56..c24b94614e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,5 +1,6 @@ <?php +require_once getcwd() . '/vendor/autoload.php'; require_once getcwd() . '/php/utils.php'; require_once __DIR__ . '/abstract-spec.php'; diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php new file mode 100644 index 0000000000..59f4771203 --- /dev/null +++ b/tests/test-synopsis.php @@ -0,0 +1,37 @@ +<?php + +use WP_CLI\SynopsisParser; + +class SynopsisParserTest extends PHPUnit_Framework_TestCase { + + function testPositional() { + $r = SynopsisParser::parse( '<foo> [<bar>]' ); + + $this->assertEquals( 2, count( $r['positional'] ) ); + $this->assertFalse( $r['positional'][0]['optional'] ); + $this->assertTrue( $r['positional'][1]['optional'] ); + } + + function testFlag() { + $r = SynopsisParser::parse( '--foo' ); + $this->assertEquals( 0, count( $r['flag'] ) ); // flags can't be mandatory + + $r = SynopsisParser::parse( '[--foo]' ); + $this->assertEquals( 1, count( $r['flag'] ) ); + } + + function testGeneric() { + $r = SynopsisParser::parse( '--<field>=<value>' ); + + $this->assertEquals( 1, count( $r['generic'] ) ); + } + + function testAssoc() { + $r = SynopsisParser::parse( '--foo=<value> [--bar=<value>]' ); + + $this->assertEquals( 2, count( $r['assoc'] ) ); + $this->assertFalse( $r['assoc'][0]['optional'] ); + $this->assertTrue( $r['assoc'][1]['optional'] ); + } +} + From 535d85d4e6386d58f44453e6d17ebef0b5995260 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 21:41:05 +0200 Subject: [PATCH 1177/4858] check that other parameter types are 0 --- tests/test-synopsis.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 59f4771203..5649d80ab4 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -7,31 +7,39 @@ class SynopsisParserTest extends PHPUnit_Framework_TestCase { function testPositional() { $r = SynopsisParser::parse( '<foo> [<bar>]' ); - $this->assertEquals( 2, count( $r['positional'] ) ); + $this->assertFoundParameters( 2, 'positional', $r ); $this->assertFalse( $r['positional'][0]['optional'] ); $this->assertTrue( $r['positional'][1]['optional'] ); } function testFlag() { $r = SynopsisParser::parse( '--foo' ); - $this->assertEquals( 0, count( $r['flag'] ) ); // flags can't be mandatory + $this->assertFoundParameters( 0, 'flag', $r ); // flags can't be mandatory $r = SynopsisParser::parse( '[--foo]' ); - $this->assertEquals( 1, count( $r['flag'] ) ); + $this->assertFoundParameters( 1, 'flag', $r ); } function testGeneric() { $r = SynopsisParser::parse( '--<field>=<value>' ); - $this->assertEquals( 1, count( $r['generic'] ) ); + $this->assertFoundParameters( 1, 'generic', $r ); } function testAssoc() { $r = SynopsisParser::parse( '--foo=<value> [--bar=<value>]' ); - $this->assertEquals( 2, count( $r['assoc'] ) ); + $this->assertFoundParameters( 2, 'assoc', $r ); $this->assertFalse( $r['assoc'][0]['optional'] ); $this->assertTrue( $r['assoc'][1]['optional'] ); } + + protected function assertFoundParameters( $count, $type, $r ) { + foreach ( $r as $key => $params ) { + $expected = ( $key == $type ) ? $count : 0; + + $this->assertEquals( $expected, count( $params ) ); + } + } } From 6d339aa93cf491f281d549998cc00d0d115d6fb5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 21:51:12 +0200 Subject: [PATCH 1178/4858] add test for combined param types --- tests/test-synopsis.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 5649d80ab4..01322b007c 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -21,9 +21,11 @@ function testFlag() { } function testGeneric() { - $r = SynopsisParser::parse( '--<field>=<value>' ); + $r = SynopsisParser::parse( '--<field>=<value> [--<field>=<value>]' ); - $this->assertFoundParameters( 1, 'generic', $r ); + $this->assertFoundParameters( 2, 'generic', $r ); + $this->assertFalse( $r['generic'][0]['optional'] ); + $this->assertTrue( $r['generic'][1]['optional'] ); } function testAssoc() { @@ -34,6 +36,15 @@ function testAssoc() { $this->assertTrue( $r['assoc'][1]['optional'] ); } + function testCombined() { + $r = SynopsisParser::parse( '<positional> --assoc=<someval> --<field>=<value> [--flag]' ); + + $this->assertEquals( 1, count( $r['positional'] ) ); + $this->assertEquals( 1, count( $r['assoc'] ) ); + $this->assertEquals( 1, count( $r['generic'] ) ); + $this->assertEquals( 1, count( $r['flag'] ) ); + } + protected function assertFoundParameters( $count, $type, $r ) { foreach ( $r as $key => $params ) { $expected = ( $key == $type ) ? $count : 0; From 13e64ddee6bef85c3421d7a0e4353573f12ca085 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 21:53:28 +0200 Subject: [PATCH 1179/4858] use assertCount() instead of assertEquals() --- tests/test-synopsis.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 01322b007c..624cc45cf0 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -39,17 +39,17 @@ function testAssoc() { function testCombined() { $r = SynopsisParser::parse( '<positional> --assoc=<someval> --<field>=<value> [--flag]' ); - $this->assertEquals( 1, count( $r['positional'] ) ); - $this->assertEquals( 1, count( $r['assoc'] ) ); - $this->assertEquals( 1, count( $r['generic'] ) ); - $this->assertEquals( 1, count( $r['flag'] ) ); + $this->assertCount( 1, $r['positional'] ); + $this->assertCount( 1, $r['assoc'] ); + $this->assertCount( 1, $r['generic'] ); + $this->assertCount( 1, $r['flag'] ); } protected function assertFoundParameters( $count, $type, $r ) { foreach ( $r as $key => $params ) { $expected = ( $key == $type ) ? $count : 0; - $this->assertEquals( $expected, count( $params ) ); + $this->assertCount( $expected, $params ); } } } From f0d3d349d6faa9c62263bcea33e15a03248ec0c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 22:17:43 +0200 Subject: [PATCH 1180/4858] make synopsis parser return unknown tokens --- php/WP_CLI/SynopsisParser.php | 6 ++++++ tests/test-synopsis.php | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index bc594df3d4..94cb05440e 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -14,6 +14,8 @@ static function parse( $synopsis ) { $tokens = preg_split( '/[\s\t]+/', $synopsis ); foreach ( $tokens as $token ) { + $type = false; + foreach ( $patterns as $regex => $desc ) { if ( preg_match( $regex, $token, $matches ) ) { $type = $desc['type']; @@ -21,6 +23,10 @@ static function parse( $synopsis ) { break; } } + + if ( !$type ) { + $params['unknown'][] = $token; + } } return $params; diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 624cc45cf0..a92c7c3507 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -13,11 +13,12 @@ function testPositional() { } function testFlag() { - $r = SynopsisParser::parse( '--foo' ); - $this->assertFoundParameters( 0, 'flag', $r ); // flags can't be mandatory - $r = SynopsisParser::parse( '[--foo]' ); $this->assertFoundParameters( 1, 'flag', $r ); + + // flags can't be mandatory + $r = SynopsisParser::parse( '--foo' ); + $this->assertFoundParameters( 1, 'unknown', $r ); } function testGeneric() { @@ -34,6 +35,10 @@ function testAssoc() { $this->assertFoundParameters( 2, 'assoc', $r ); $this->assertFalse( $r['assoc'][0]['optional'] ); $this->assertTrue( $r['assoc'][1]['optional'] ); + + // shouldn't pass defaults to assoc parameters + $r = SynopsisParser::parse( '--count=100' ); + $this->assertFoundParameters( 1, 'unknown', $r ); } function testCombined() { From 9e4ee5864299da3b661b325aef868b250e01e9c8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 23:14:28 +0200 Subject: [PATCH 1181/4858] show warnings for invalid tokens when generating man pages --- php/WP_CLI/Dispatcher/Subcommand.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 47ebb6f21d..b8b758bc2d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -14,17 +14,25 @@ function __construct( CommandContainer $parent, $name, $callable, $docparser ) { } function show_usage( $prefix = 'usage: ' ) { - \WP_CLI::line( $prefix . $this->get_full_synopsis() ); + \WP_CLI::line( $prefix . $this->get_full_synopsis( false ) ); } function get_shortdesc() { return $this->docparser->get_shortdesc(); } - function get_full_synopsis() { + function get_full_synopsis( $validate = true ) { $full_name = implode( ' ', get_path( $this ) ); $synopsis = $this->get_synopsis(); + $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); + if ( isset( $tokens['unknown'] ) ) { + foreach ( $tokens['unknown'] as $token ) { + \WP_CLI::warning( sprintf( "Invalid token '%s' in synopsis for '%s'", + $token, $full_name ) ); + } + } + return "$full_name $synopsis"; } From 40a1e8b9a9048137c392ba9643d5ae27b72f560a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Feb 2013 23:24:34 +0200 Subject: [PATCH 1182/4858] ignore empty synopsis tokens --- php/WP_CLI/SynopsisParser.php | 2 +- tests/test-synopsis.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 94cb05440e..5ae4a162d9 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -11,7 +11,7 @@ class SynopsisParser { static function parse( $synopsis ) { list( $patterns, $params ) = self::get_patterns(); - $tokens = preg_split( '/[\s\t]+/', $synopsis ); + $tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) ); foreach ( $tokens as $token ) { $type = false; diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index a92c7c3507..33d2a1daec 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -4,6 +4,12 @@ class SynopsisParserTest extends PHPUnit_Framework_TestCase { + function testEmpty() { + $r = SynopsisParser::parse( ' ' ); + + $this->assertFoundParameters( 0, 'positional', $r ); + } + function testPositional() { $r = SynopsisParser::parse( '<foo> [<bar>]' ); From 831b8b0d581235e24c8e967d62265900a1a8446d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 00:12:57 +0200 Subject: [PATCH 1183/4858] refactor pattern generation --- php/WP_CLI/SynopsisParser.php | 46 ++++++++++++++++------------------- tests/test-synopsis.php | 6 ++--- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 5ae4a162d9..a8f4cfaeb7 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -32,41 +32,37 @@ static function parse( $synopsis ) { return $params; } + private static $patterns = array(); + private static $params = array(); + private static function get_patterns() { $p_name = '(?P<name>[a-z-_]+)'; $p_value = '(?P<value>[a-z-|]+)'; - $param_types = array( - array( 'positional', "<$p_value>", 1, 1 ), - array( 'generic', "--<field>=<value>", 1, 1 ), - array( 'assoc', "--$p_name=<$p_value>", 1, 1 ), - array( 'flag', "--$p_name", 1, 0 ), - ); - - $patterns = array(); - $params = array(); + self::gen_patterns( 'positional', "<$p_value>", array( 'mandatory', 'optional' ) ); + self::gen_patterns( 'generic', "--<field>=<value>", array( 'mandatory', 'optional' ) ); + self::gen_patterns( 'assoc', "--$p_name=<$p_value>", array( 'mandatory', 'optional' ) ); + self::gen_patterns( 'flag', "--$p_name", array( 'optional' ) ); - foreach ( $param_types as $pt ) { - list( $type, $pattern, $optional, $mandatory ) = $pt; + return array( self::$patterns, self::$params ); + } - if ( $mandatory ) { - $patterns[ "/^$pattern$/" ] = array( - 'type' => $type, - 'optional' => false - ); - } + private function gen_patterns( $type, $pattern, $flavour_types ) { + static $flavours = array( + 'mandatory' => "/^:pattern:$/", + 'optional' => "/^\[:pattern:\]$/", + ); - if ( $optional ) { - $patterns[ "/^\[$pattern\]$/" ] = array( - 'type' => $type, - 'optional' => true - ); - } + foreach ( $flavour_types as $flavour_type ) { + $flavour = $flavours[ $flavour_type ]; - $params[ $type ] = array(); + self::$patterns[ str_replace( ':pattern:', $pattern, $flavour ) ] = array( + 'type' => $type, + $flavour_type => true + ); } - return array( $patterns, $params ); + self::$params[ $type ] = array(); } } diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 33d2a1daec..0408769366 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -14,7 +14,7 @@ function testPositional() { $r = SynopsisParser::parse( '<foo> [<bar>]' ); $this->assertFoundParameters( 2, 'positional', $r ); - $this->assertFalse( $r['positional'][0]['optional'] ); + $this->assertTrue( $r['positional'][0]['mandatory'] ); $this->assertTrue( $r['positional'][1]['optional'] ); } @@ -31,7 +31,7 @@ function testGeneric() { $r = SynopsisParser::parse( '--<field>=<value> [--<field>=<value>]' ); $this->assertFoundParameters( 2, 'generic', $r ); - $this->assertFalse( $r['generic'][0]['optional'] ); + $this->assertTrue( $r['generic'][0]['mandatory'] ); $this->assertTrue( $r['generic'][1]['optional'] ); } @@ -39,7 +39,7 @@ function testAssoc() { $r = SynopsisParser::parse( '--foo=<value> [--bar=<value>]' ); $this->assertFoundParameters( 2, 'assoc', $r ); - $this->assertFalse( $r['assoc'][0]['optional'] ); + $this->assertTrue( $r['assoc'][0]['mandatory'] ); $this->assertTrue( $r['assoc'][1]['optional'] ); // shouldn't pass defaults to assoc parameters From 4c38ebe4652a2ede387b926aa9bd999c6ec8ebcd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 02:41:06 +0200 Subject: [PATCH 1184/4858] first pass at moving arg checking into SynopsisParser Also, doesn't nest accepted parameters by type --- php/WP_CLI/Dispatcher/Subcommand.php | 92 +++---------------- php/WP_CLI/SynopsisParser.php | 131 ++++++++++++++++++++++++--- tests/test-synopsis.php | 60 +++++++----- 3 files changed, 167 insertions(+), 116 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index b8b758bc2d..db17c4dfbf 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -26,10 +26,13 @@ function get_full_synopsis( $validate = true ) { $synopsis = $this->get_synopsis(); $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); - if ( isset( $tokens['unknown'] ) ) { - foreach ( $tokens['unknown'] as $token ) { - \WP_CLI::warning( sprintf( "Invalid token '%s' in synopsis for '%s'", - $token, $full_name ) ); + + foreach ( $tokens as $token ) { + if ( 'unknown' == $token['type'] ) { + \WP_CLI::warning( sprintf( + "Invalid token '%s' in synopsis for '%s'", + $token['token'], $full_name + ) ); } } @@ -41,7 +44,12 @@ function get_synopsis() { } function invoke( $args, $assoc_args ) { - $this->check_args( $args, $assoc_args ); + $synopsis = $this->get_synopsis(); + + if ( $synopsis ) { + \WP_CLI\SynopsisParser::validate_args( $synopsis, $args, $assoc_args, + array( $this, 'show_usage' ) ); + } call_user_func( $this->callable, $args, $assoc_args ); } @@ -53,79 +61,5 @@ function get_name() { function get_parent() { return $this->parent; } - - protected function check_args( $args, $assoc_args ) { - $synopsis = $this->get_synopsis(); - if ( !$synopsis ) - return; - - $accepted_params = \WP_CLI\SynopsisParser::parse( $synopsis ); - - $this->check_positional( $args, $accepted_params ); - - $this->check_assoc( $assoc_args, $accepted_params ); - - if ( empty( $accepted_params['generic'] ) ) - $this->check_unknown_assoc( $assoc_args, $accepted_params ); - } - - private function check_positional( $args, $accepted_params ) { - $count = 0; - - foreach ( $accepted_params['positional'] as $param ) { - if ( !$param['optional'] ) - $count++; - } - - if ( count( $args ) < $count ) { - $this->show_usage(); - exit(1); - } - } - - private function check_assoc( $assoc_args, $accepted_params ) { - $mandatory_assoc = array(); - - $assoc_args += \WP_CLI::get_config(); - - foreach ( $accepted_params['assoc'] as $param ) { - if ( !$param['optional'] ) - $mandatory_assoc[] = $param['name']; - } - - $errors = array(); - - foreach ( $mandatory_assoc as $key ) { - if ( !isset( $assoc_args[ $key ] ) ) - $errors[] = "missing --$key parameter"; - elseif ( true === $assoc_args[ $key ] ) - $errors[] = "--$key parameter needs a value"; - } - - if ( !empty( $errors ) ) { - foreach ( $errors as $error ) { - \WP_CLI::warning( $error ); - } - $this->show_usage(); - exit(1); - } - } - - private function check_unknown_assoc( $assoc_args, $accepted_params ) { - $known_assoc = array(); - - foreach ( array( 'assoc', 'flag' ) as $type ) { - foreach ( $accepted_params[$type] as $param ) { - $known_assoc[] = $param['name']; - } - } - - $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); - - foreach ( $unknown_assoc as $key ) { - \WP_CLI::warning( "unknown --$key parameter" ); - } - } - } diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index a8f4cfaeb7..248f7c72d3 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -4,38 +4,120 @@ class SynopsisParser { + private static $patterns = array(); + + private $params = array(); + + /** + * @param string Synopsis + * @param array Positional args + * @param array Associative args + * @param callback What to do on a critical failure + */ + static function validate_args( $synopsis, $args, $assoc_args, $callback ) { + $instance = new self( $synopsis ); + + $instance->check_positional( $args, $callback ); + + $instance->check_assoc( $assoc_args, $callback ); + + $instance->check_unknown_assoc( $assoc_args ); + } + + private function __construct( $synopsis ) { + $this->params = $this->parse( $synopsis ); + } + + private function check_positional( $args, $callback ) { + $positional = $this->query_params( array( + 'type' => 'positional', + 'flavour' => 'mandatory' + ) ); + + if ( count( $args ) < count( $positional ) ) { + call_user_func( $callback ); + exit(1); + } + } + + private function check_assoc( $assoc_args, $callback ) { + $assoc_args += \WP_CLI::get_config(); + + $errors = array(); + + $mandatory_assoc = $this->query_params( array( + 'type' => 'assoc', + 'flavour' => 'mandatory' + ) ); + + foreach ( $mandatory_assoc as $param ) { + $key = $param['name']; + + if ( !isset( $assoc_args[ $key ] ) ) + $errors[] = "missing --$key parameter"; + elseif ( true === $assoc_args[ $key ] ) + $errors[] = "--$key parameter needs a value"; + } + + if ( !empty( $errors ) ) { + foreach ( $errors as $error ) { + \WP_CLI::warning( $error ); + } + call_user_func( $callback ); + exit(1); + } + } + + private function check_unknown_assoc( $assoc_args ) { + $known_assoc = array(); + + foreach ( $this->params as $param ) { + if ( in_array( $param['type'], array( 'assoc', 'flag' ) ) ) + $known_assoc[] = $param['name']; + } + + $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); + + foreach ( $unknown_assoc as $key ) { + \WP_CLI::warning( "unknown --$key parameter" ); + } + } + /** * @param string * @return array List of parameters */ static function parse( $synopsis ) { - list( $patterns, $params ) = self::get_patterns(); + if ( empty( self::$patterns ) ) + self::init_patterns(); $tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) ); + $params = array(); + foreach ( $tokens as $token ) { $type = false; - foreach ( $patterns as $regex => $desc ) { + foreach ( self::$patterns as $regex => $desc ) { if ( preg_match( $regex, $token, $matches ) ) { $type = $desc['type']; - $params[$type][] = array_merge( $matches, $desc ); + $params[] = array_merge( $matches, $desc ); break; } } if ( !$type ) { - $params['unknown'][] = $token; + $params[] = array( + 'type' => 'unknown', + 'token' => $token + ); } } return $params; } - private static $patterns = array(); - private static $params = array(); - - private static function get_patterns() { + private static function init_patterns() { $p_name = '(?P<name>[a-z-_]+)'; $p_value = '(?P<value>[a-z-|]+)'; @@ -43,8 +125,6 @@ private static function get_patterns() { self::gen_patterns( 'generic', "--<field>=<value>", array( 'mandatory', 'optional' ) ); self::gen_patterns( 'assoc', "--$p_name=<$p_value>", array( 'mandatory', 'optional' ) ); self::gen_patterns( 'flag', "--$p_name", array( 'optional' ) ); - - return array( self::$patterns, self::$params ); } private function gen_patterns( $type, $pattern, $flavour_types ) { @@ -58,11 +138,38 @@ private function gen_patterns( $type, $pattern, $flavour_types ) { self::$patterns[ str_replace( ':pattern:', $pattern, $flavour ) ] = array( 'type' => $type, - $flavour_type => true + 'flavour' => $flavour_type ); } + } + + /** + * Filters a list of associatve arrays, based on a set of key => value arguments. + * + * @param array $args An array of key => value arguments to match against + * @param string $operator + * @return array + */ + private function query_params( $args, $operator = 'AND' ) { + $operator = strtoupper( $operator ); + $count = count( $args ); + $filtered = array(); + + foreach ( $this->params as $key => $to_match ) { + $matched = 0; + foreach ( $args as $m_key => $m_value ) { + if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) + $matched++; + } + + if ( ( 'AND' == $operator && $matched == $count ) + || ( 'OR' == $operator && $matched > 0 ) + || ( 'NOT' == $operator && 0 == $matched ) ) { + $filtered[$key] = $to_match; + } + } - self::$params[ $type ] = array(); + return $filtered; } } diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 0408769366..80bef8c2c6 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -7,61 +7,71 @@ class SynopsisParserTest extends PHPUnit_Framework_TestCase { function testEmpty() { $r = SynopsisParser::parse( ' ' ); - $this->assertFoundParameters( 0, 'positional', $r ); + $this->assertEmpty( $r ); } function testPositional() { $r = SynopsisParser::parse( '<foo> [<bar>]' ); - $this->assertFoundParameters( 2, 'positional', $r ); - $this->assertTrue( $r['positional'][0]['mandatory'] ); - $this->assertTrue( $r['positional'][1]['optional'] ); + $this->assertCount( 2, $r ); + + $this->assertEquals( 'positional', $r[0]['type'] ); + $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + + $this->assertEquals( 'positional', $r[1]['type'] ); + $this->assertEquals( 'optional', $r[1]['flavour'] ); } function testFlag() { $r = SynopsisParser::parse( '[--foo]' ); - $this->assertFoundParameters( 1, 'flag', $r ); + + $this->assertCount( 1, $r ); + $this->assertEquals( 'flag', $r[0]['type'] ); + $this->assertEquals( 'optional', $r[0]['flavour'] ); // flags can't be mandatory $r = SynopsisParser::parse( '--foo' ); - $this->assertFoundParameters( 1, 'unknown', $r ); + + $this->assertCount( 1, $r ); + $this->assertEquals( 'unknown', $r[0]['type'] ); } function testGeneric() { $r = SynopsisParser::parse( '--<field>=<value> [--<field>=<value>]' ); - $this->assertFoundParameters( 2, 'generic', $r ); - $this->assertTrue( $r['generic'][0]['mandatory'] ); - $this->assertTrue( $r['generic'][1]['optional'] ); + $this->assertCount( 2, $r ); + + $this->assertEquals( 'generic', $r[0]['type'] ); + $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + + $this->assertEquals( 'generic', $r[1]['type'] ); + $this->assertEquals( 'optional', $r[1]['flavour'] ); } function testAssoc() { $r = SynopsisParser::parse( '--foo=<value> [--bar=<value>]' ); - $this->assertFoundParameters( 2, 'assoc', $r ); - $this->assertTrue( $r['assoc'][0]['mandatory'] ); - $this->assertTrue( $r['assoc'][1]['optional'] ); + $this->assertCount( 2, $r ); + + $this->assertEquals( 'assoc', $r[0]['type'] ); + $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + + $this->assertEquals( 'assoc', $r[1]['type'] ); + $this->assertEquals( 'optional', $r[1]['flavour'] ); // shouldn't pass defaults to assoc parameters $r = SynopsisParser::parse( '--count=100' ); - $this->assertFoundParameters( 1, 'unknown', $r ); + $this->assertCount( 1, $r ); + $this->assertEquals( 'unknown', $r[0]['type'] ); } function testCombined() { $r = SynopsisParser::parse( '<positional> --assoc=<someval> --<field>=<value> [--flag]' ); - $this->assertCount( 1, $r['positional'] ); - $this->assertCount( 1, $r['assoc'] ); - $this->assertCount( 1, $r['generic'] ); - $this->assertCount( 1, $r['flag'] ); - } - - protected function assertFoundParameters( $count, $type, $r ) { - foreach ( $r as $key => $params ) { - $expected = ( $key == $type ) ? $count : 0; - - $this->assertCount( $expected, $params ); - } + $this->assertEquals( 'positional', $r[0]['type'] ); + $this->assertEquals( 'assoc', $r[1]['type'] ); + $this->assertEquals( 'generic', $r[2]['type'] ); + $this->assertEquals( 'flag', $r[3]['type'] ); } } From b18652ba586a086082b69a7c4dc8fdf5935a045e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 03:40:20 +0200 Subject: [PATCH 1185/4858] add 'repeating' flavour --- php/WP_CLI/SynopsisParser.php | 13 ++++++++----- tests/test-synopsis.php | 8 ++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 248f7c72d3..66552ec026 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -121,22 +121,25 @@ private static function init_patterns() { $p_name = '(?P<name>[a-z-_]+)'; $p_value = '(?P<value>[a-z-|]+)'; - self::gen_patterns( 'positional', "<$p_value>", array( 'mandatory', 'optional' ) ); - self::gen_patterns( 'generic', "--<field>=<value>", array( 'mandatory', 'optional' ) ); + self::gen_patterns( 'positional', "<$p_value>", array( 'mandatory', 'optional', 'repeating' ) ); + self::gen_patterns( 'generic', "--<field>=<value>", array( 'mandatory', 'optional', 'repeating' ) ); self::gen_patterns( 'assoc', "--$p_name=<$p_value>", array( 'mandatory', 'optional' ) ); self::gen_patterns( 'flag', "--$p_name", array( 'optional' ) ); } private function gen_patterns( $type, $pattern, $flavour_types ) { static $flavours = array( - 'mandatory' => "/^:pattern:$/", - 'optional' => "/^\[:pattern:\]$/", + 'mandatory' => ":pattern:", + 'optional' => "\[:pattern:\]", + 'repeating' => ":pattern:...", ); foreach ( $flavour_types as $flavour_type ) { $flavour = $flavours[ $flavour_type ]; - self::$patterns[ str_replace( ':pattern:', $pattern, $flavour ) ] = array( + $final_pattern = str_replace( ':pattern:', $pattern, $flavour ); + + self::$patterns[ '/^' . $final_pattern . '$/' ] = array( 'type' => $type, 'flavour' => $flavour_type ); diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 80bef8c2c6..f27bcd72c8 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -65,6 +65,14 @@ function testAssoc() { $this->assertEquals( 'unknown', $r[0]['type'] ); } + function testRepeating() { + $r = SynopsisParser::parse( '<positional>...' ); + + $this->assertCount( 1, $r ); + $this->assertEquals( 'positional', $r[0]['type'] ); + $this->assertEquals( 'repeating', $r[0]['flavour'] ); + } + function testCombined() { $r = SynopsisParser::parse( '<positional> --assoc=<someval> --<field>=<value> [--flag]' ); From 8f91cc17cefcf516cd78ad680ecaa357ac0f1562 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 03:59:19 +0200 Subject: [PATCH 1186/4858] the 'repeating' flavour can also be optional --- php/WP_CLI/SynopsisParser.php | 20 ++++++++++---------- tests/test-synopsis.php | 8 ++++++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 66552ec026..7512ce112f 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -129,20 +129,20 @@ private static function init_patterns() { private function gen_patterns( $type, $pattern, $flavour_types ) { static $flavours = array( - 'mandatory' => ":pattern:", - 'optional' => "\[:pattern:\]", - 'repeating' => ":pattern:...", + 'mandatory' => ':pattern:', + 'optional' => '\[:pattern:\]', + 'repeating' => array( ':pattern:...', '\[:pattern:...\]' ) ); foreach ( $flavour_types as $flavour_type ) { - $flavour = $flavours[ $flavour_type ]; + foreach ( (array) $flavours[ $flavour_type ] as $flavour ) { + $final_pattern = str_replace( ':pattern:', $pattern, $flavour ); - $final_pattern = str_replace( ':pattern:', $pattern, $flavour ); - - self::$patterns[ '/^' . $final_pattern . '$/' ] = array( - 'type' => $type, - 'flavour' => $flavour_type - ); + self::$patterns[ '/^' . $final_pattern . '$/' ] = array( + 'type' => $type, + 'flavour' => $flavour_type + ); + } } } diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index f27bcd72c8..d54f9df2a9 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -66,11 +66,15 @@ function testAssoc() { } function testRepeating() { - $r = SynopsisParser::parse( '<positional>...' ); + $r = SynopsisParser::parse( '<positional>... [--<field>=<value>...]' ); + + $this->assertCount( 2, $r ); - $this->assertCount( 1, $r ); $this->assertEquals( 'positional', $r[0]['type'] ); $this->assertEquals( 'repeating', $r[0]['flavour'] ); + + $this->assertEquals( 'generic', $r[1]['type'] ); + $this->assertEquals( 'repeating', $r[1]['flavour'] ); } function testCombined() { From a8bcee0998f12eb00104d04cbec6f70c4798e3c5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 04:17:01 +0200 Subject: [PATCH 1187/4858] fix post generate and user generate synopses closes #296 --- man/post-generate.1 | 2 +- man/user-generate.1 | 2 +- php/commands/post.php | 2 +- php/commands/user.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/post-generate.1 b/man/post-generate.1 index 9aca68462d..d89efebe9d 100644 --- a/man/post-generate.1 +++ b/man/post-generate.1 @@ -7,7 +7,7 @@ \fBwp\-post\-generate\fR \- Generate some posts\. . .SH "SYNOPSIS" -wp post generate [\-\-count=100] [\-\-post_type=\fItype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIyyyy\-mm\-dd\fR] [\-\-max_depth=1] +wp post generate [\-\-count=\fInumber\fR] [\-\-post_type=\fItype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIyyyy\-mm\-dd\fR] [\-\-max_depth=\fInumber\fR] . .SH "OPTIONS" . diff --git a/man/user-generate.1 b/man/user-generate.1 index 2acca79125..3c87b5c76b 100644 --- a/man/user-generate.1 +++ b/man/user-generate.1 @@ -7,7 +7,7 @@ \fBwp\-user\-generate\fR \- Generate users\. . .SH "SYNOPSIS" -wp user generate [\-\-count=100] [\-\-role=\fIrole\fR] +wp user generate [\-\-count=\fInumber\fR] [\-\-role=\fIrole\fR] . .SH "OPTIONS" . diff --git a/php/commands/post.php b/php/commands/post.php index 1e69d24b7e..00809403f7 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -109,7 +109,7 @@ public function _list( $_, $assoc_args ) { /** * Generate some posts. * - * @synopsis [--count=100] [--post_type=<type>] [--post_status=<status>] [--post_author=<login>] [--post_date=<yyyy-mm-dd>] [--max_depth=1] + * @synopsis [--count=<number>] [--post_type=<type>] [--post_status=<status>] [--post_author=<login>] [--post_date=<yyyy-mm-dd>] [--max_depth=<number>] */ public function generate( $args, $assoc_args ) { global $wpdb; diff --git a/php/commands/user.php b/php/commands/user.php index 7ded9497d8..fd4aac632d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -184,7 +184,7 @@ protected function _update( $params ) { /** * Generate users. * - * @synopsis [--count=100] [--role=<role>] + * @synopsis [--count=<number>] [--role=<role>] */ public function generate( $args, $assoc_args ) { global $blog_id; From ca7e87d56a4ed8c5d00fdacd6be43823d9185aa8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 04:27:01 +0200 Subject: [PATCH 1188/4858] show validation warnings only when generating man pages. see #298 --- php/WP_CLI/Dispatcher/CompositeCommand.php | 2 +- php/WP_CLI/Dispatcher/Subcommand.php | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index e0ff1f6708..897992bbe7 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -78,7 +78,7 @@ public function get_full_synopsis() { $str = array(); foreach ( $this->subcommands as $subcommand ) { - $str[] = $subcommand->get_full_synopsis(); + $str[] = $subcommand->get_full_synopsis( true ); } return implode( "\n\n", $str ); diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index db17c4dfbf..80d43f620d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -14,25 +14,27 @@ function __construct( CommandContainer $parent, $name, $callable, $docparser ) { } function show_usage( $prefix = 'usage: ' ) { - \WP_CLI::line( $prefix . $this->get_full_synopsis( false ) ); + \WP_CLI::line( $prefix . $this->get_full_synopsis() ); } function get_shortdesc() { return $this->docparser->get_shortdesc(); } - function get_full_synopsis( $validate = true ) { + function get_full_synopsis( $validate = false ) { $full_name = implode( ' ', get_path( $this ) ); $synopsis = $this->get_synopsis(); - $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); + if ( $validate ) { + $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); - foreach ( $tokens as $token ) { - if ( 'unknown' == $token['type'] ) { - \WP_CLI::warning( sprintf( - "Invalid token '%s' in synopsis for '%s'", - $token['token'], $full_name - ) ); + foreach ( $tokens as $token ) { + if ( 'unknown' == $token['type'] ) { + \WP_CLI::warning( sprintf( + "Invalid token '%s' in synopsis for '%s'", + $token['token'], $full_name + ) ); + } } } From 678855fc62b7e58262a26297d264e1306858f4be Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 00:07:53 +0200 Subject: [PATCH 1189/4858] first pass at creating a Phar archive --- .gitignore | 1 + bin/wp | 2 +- php/{wp-cli-boot.php => boot-fs.php} | 2 ++ php/boot-phar.php | 6 +++++ php/wp-cli.php | 2 -- utils/make-phar.php | 36 ++++++++++++++++++++++++++++ 6 files changed, 46 insertions(+), 3 deletions(-) rename php/{wp-cli-boot.php => boot-fs.php} (89%) create mode 100644 php/boot-phar.php create mode 100644 utils/make-phar.php diff --git a/.gitignore b/.gitignore index 8e2a674313..31c4b786ee 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /vendor /composer.lock /phpunit.xml +/wp-cli.phar diff --git a/bin/wp b/bin/wp index aeebd4d50f..d2cfa79f8c 100755 --- a/bin/wp +++ b/bin/wp @@ -28,7 +28,7 @@ if [ ! -d $SCRIPT_PATH ]; then SCRIPT_PATH=$(dirname "$SELF_PATH")/../php fi -SCRIPT_PATH=$SCRIPT_PATH/wp-cli-boot.php +SCRIPT_PATH=$SCRIPT_PATH/boot-fs.php case $(uname -a) in CYGWIN*) diff --git a/php/wp-cli-boot.php b/php/boot-fs.php similarity index 89% rename from php/wp-cli-boot.php rename to php/boot-fs.php index b7c8de526a..a3311c887d 100644 --- a/php/wp-cli-boot.php +++ b/php/boot-fs.php @@ -12,5 +12,7 @@ die(-1); } +define( 'WP_CLI_ROOT', __DIR__ . '/' ); + include dirname(__FILE__) . '/wp-cli.php'; diff --git a/php/boot-phar.php b/php/boot-phar.php new file mode 100644 index 0000000000..be8cfdcb20 --- /dev/null +++ b/php/boot-phar.php @@ -0,0 +1,6 @@ +<?php + +define( 'WP_CLI_ROOT', 'phar://wp-cli.phar/php/' ); + +include WP_CLI_ROOT . 'wp-cli.php'; + diff --git a/php/wp-cli.php b/php/wp-cli.php index c1443fd6a5..c0000d100a 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -5,8 +5,6 @@ define( 'WP_CLI_VERSION', '0.9.0-dev' ); -define( 'WP_CLI_ROOT', __DIR__ . '/' ); - include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; diff --git a/utils/make-phar.php b/utils/make-phar.php new file mode 100644 index 0000000000..e6cd3f6673 --- /dev/null +++ b/utils/make-phar.php @@ -0,0 +1,36 @@ +<?php + +// php -dphar.readonly=0 utils/make-phar.php + +$iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( './php', FilesystemIterator::SKIP_DOTS ) +); + +$phar = new Phar( 'wp-cli.phar', 0, 'wp-cli.phar' ); + +$phar->startBuffering(); + +foreach ( $iterator as $path ) { + if ( !preg_match( '/\.php$/', $path ) ) + continue; + + $key = str_replace( './', '', $path ); + + echo "$key - $path\n"; + + $phar[ $key ] = file_get_contents( $path ); +} + +$phar->setStub( <<<EOB +<?php +Phar::mapPhar(); +include 'phar://wp-cli.phar/php/boot-phar.php'; +__HALT_COMPILER(); +?> +EOB +); + +$phar->stopBuffering(); + +echo "Generated wp-cli.phar.\n"; + From 669c72026f8d3176cb7b7e0e7c9cdd9407a610db Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 00:20:53 +0200 Subject: [PATCH 1190/4858] add ignored paths --- utils/make-phar.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index e6cd3f6673..8fc8746d06 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -10,7 +10,19 @@ $phar->startBuffering(); +$ignored_paths = array( + '/mustache/bin/', + '/mustache/test/', + '/mustache/vendor/', + '/php-cli-tools/examples/' +); + foreach ( $iterator as $path ) { + foreach ( $ignored_paths as $ignore ) { + if ( strpos( $path, $ignore ) ) + continue 2; + } + if ( !preg_match( '/\.php$/', $path ) ) continue; From 5c0bea0f970ce3c9e8da7655db281fb503a08317 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 00:26:14 +0200 Subject: [PATCH 1191/4858] handle --quiet parameter --- utils/make-phar.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index 8fc8746d06..7de3b17eba 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -1,6 +1,8 @@ <?php -// php -dphar.readonly=0 utils/make-phar.php +// php -dphar.readonly=0 utils/make-phar.php [--quiet] + +define( 'BE_QUIET', isset( $argv[1] ) && '--quiet' == $argv[1] ); $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( './php', FilesystemIterator::SKIP_DOTS ) @@ -28,7 +30,8 @@ $key = str_replace( './', '', $path ); - echo "$key - $path\n"; + if ( !BE_QUIET ) + echo "$key - $path\n"; $phar[ $key ] = file_get_contents( $path ); } From d824eeda952e79a7d4f49ad924f7072b8f01bf48 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 00:43:56 +0200 Subject: [PATCH 1192/4858] use DirectoryIterator, since glob() doesn't work on Phar archives --- php/WP_CLI/Dispatcher/RootCommand.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 989faa2cff..654d4fca51 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -108,13 +108,20 @@ function get_subcommands() { } protected function load_all_commands() { - foreach ( glob( WP_CLI_ROOT . "/commands/*.php" ) as $filename ) { - $command = str_replace( '.php', '', $filename ); + $cmd_dir = WP_CLI_ROOT . "commands"; + + $iterator = new \DirectoryIterator( $cmd_dir ); + + foreach ( $iterator as $filename ) { + if ( '.php' != substr( $filename, -4 ) ) + continue; + + $command = substr( $filename, 0, -4 ); if ( isset( $this->subcommands[ $command ] ) ) continue; - include $filename; + include "$cmd_dir/$filename"; } } From 6c5a05897445c778ae3fb4c16e7340fac478affe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 01:32:18 +0200 Subject: [PATCH 1193/4858] add shebang to Phar stub --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 7de3b17eba..ece45d38f1 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -37,6 +37,7 @@ } $phar->setStub( <<<EOB +#!/usr/bin/env php <?php Phar::mapPhar(); include 'phar://wp-cli.phar/php/boot-phar.php'; From a464817eb27c9c44aa20b92a56f0fb0235187edf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 01:33:50 +0200 Subject: [PATCH 1194/4858] make manpages work from a Phar archive --- php/class-wp-cli.php | 5 ----- php/commands/help.php | 21 ++++++++++++++++++++- utils/make-phar.php | 28 +++++++++++++++++++--------- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ad70c61c16..1f453e1c7f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -91,11 +91,6 @@ private static function create_atomic_command( $name, $implementation ) { } static function add_man_dir( $dest_dir, $src_dir ) { - $dest_dir = realpath( $dest_dir ) . '/'; - - if ( $src_dir ) - $src_dir = realpath( $src_dir ) . '/'; - self::$man_dirs[ $dest_dir ] = $src_dir; } diff --git a/php/commands/help.php b/php/commands/help.php index bd1234a198..7b3490abc5 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -34,10 +34,29 @@ private static function maybe_load_man_page( $args ) { $man_path = $dest_dir . $man_file; if ( is_readable( $man_path ) ) { - exit( WP_CLI::launch( "man $man_path" ) ); + self::show_manpage( $man_path ); } } } + + private static function show_manpage( $path ) { + // to make compatible with Phar archives, need to write to a temporary file + $fd = fopen( 'php://temp', 'rw' ); + fwrite( $fd, file_get_contents( $path ) ); + fseek( $fd, 0 ); + + $descriptorspec = array( + 0 => $fd, + 1 => STDOUT, + 2 => STDERR + ); + + $cmd = 'man -l -'; + + $r = proc_close( proc_open( $cmd, $descriptorspec, $pipes ) ); + + exit( $r ); + } } WP_CLI::add_command( 'help', new Help_Command ); diff --git a/utils/make-phar.php b/utils/make-phar.php index ece45d38f1..8f61ee0d54 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -4,9 +4,20 @@ define( 'BE_QUIET', isset( $argv[1] ) && '--quiet' == $argv[1] ); -$iterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator( './php', FilesystemIterator::SKIP_DOTS ) -); +function get_iterator( $dir ) { + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ) + ); +} + +function add_file( $phar, $path ) { + $key = str_replace( './', '', $path ); + + if ( !BE_QUIET ) + echo "$key - $path\n"; + + $phar[ $key ] = file_get_contents( $path ); +} $phar = new Phar( 'wp-cli.phar', 0, 'wp-cli.phar' ); @@ -19,7 +30,7 @@ '/php-cli-tools/examples/' ); -foreach ( $iterator as $path ) { +foreach ( get_iterator( './php' ) as $path ) { foreach ( $ignored_paths as $ignore ) { if ( strpos( $path, $ignore ) ) continue 2; @@ -28,12 +39,11 @@ if ( !preg_match( '/\.php$/', $path ) ) continue; - $key = str_replace( './', '', $path ); - - if ( !BE_QUIET ) - echo "$key - $path\n"; + add_file( $phar, $path ); +} - $phar[ $key ] = file_get_contents( $path ); +foreach ( get_iterator( './man' ) as $path ) { + add_file( $phar, $path ); } $phar->setStub( <<<EOB From dea703e54245560a26458b05de8e6a8b84c7c1f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 01:57:58 +0200 Subject: [PATCH 1195/4858] add templates to phar archive --- utils/make-phar.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 8f61ee0d54..bb5a8feaaf 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -42,6 +42,10 @@ function add_file( $phar, $path ) { add_file( $phar, $path ); } +foreach ( get_iterator( './templates' ) as $path ) { + add_file( $phar, $path ); +} + foreach ( get_iterator( './man' ) as $path ) { add_file( $phar, $path ); } From a402e7c994fbcfb6fc689ad866b9d00cb113aa7e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 02:07:32 +0200 Subject: [PATCH 1196/4858] allow specifying where to create the phar archive --- .gitignore | 1 - utils/make-phar.php | 13 +++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 31c4b786ee..8e2a674313 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ /vendor /composer.lock /phpunit.xml -/wp-cli.phar diff --git a/utils/make-phar.php b/utils/make-phar.php index bb5a8feaaf..b928bd1081 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -1,8 +1,13 @@ <?php -// php -dphar.readonly=0 utils/make-phar.php [--quiet] +if ( !isset( $argv[1] ) ) { + echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet]\n"; + exit(1); +} + +define( 'DEST_PATH', $argv[1] ); -define( 'BE_QUIET', isset( $argv[1] ) && '--quiet' == $argv[1] ); +define( 'BE_QUIET', in_array( '--quiet', $argv ) ); function get_iterator( $dir ) { return new \RecursiveIteratorIterator( @@ -19,7 +24,7 @@ function add_file( $phar, $path ) { $phar[ $key ] = file_get_contents( $path ); } -$phar = new Phar( 'wp-cli.phar', 0, 'wp-cli.phar' ); +$phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' ); $phar->startBuffering(); @@ -62,5 +67,5 @@ function add_file( $phar, $path ) { $phar->stopBuffering(); -echo "Generated wp-cli.phar.\n"; +echo "\nGenerated " . DEST_PATH . "\n"; From 0de47afc45ff0b42b496bb23d602293ef9967482 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 02:20:42 +0200 Subject: [PATCH 1197/4858] set version to 0.9.0-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index c0000d100a..9c28fbe355 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.0-dev' ); +define( 'WP_CLI_VERSION', '0.9.0-alpha' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From c097bd27dcf879213288096dcfafbdac1d85a0f7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Feb 2013 06:37:07 +0200 Subject: [PATCH 1198/4858] delete files used for generating pear packages. see #301. closes #39 --- .gitignore | 3 - build.local.xml | 6 - build.properties | 13 -- build.xml | 437 ----------------------------------------------- package.xml | 71 -------- utils/pear-build | 28 --- 6 files changed, 558 deletions(-) delete mode 100644 build.local.xml delete mode 100644 build.properties delete mode 100644 build.xml delete mode 100644 package.xml delete mode 100755 utils/pear-build diff --git a/.gitignore b/.gitignore index 8e2a674313..abb9c75a11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -/.build -/src -/dist /vendor /composer.lock /phpunit.xml diff --git a/build.local.xml b/build.local.xml deleted file mode 100644 index 90aa3bc92e..0000000000 --- a/build.local.xml +++ /dev/null @@ -1,6 +0,0 @@ -<project name="local" default="help"> - <target name="help"> - <echo message="This component has no local build targets." /> - </target> -</project> -<!-- vim: set tabstop=2 shiftwidth=2 expandtab: --> diff --git a/build.properties b/build.properties deleted file mode 100644 index dcab1de8e1..0000000000 --- a/build.properties +++ /dev/null @@ -1,13 +0,0 @@ -project.name=wpcli -project.channel=wp-cli.org/pear -project.majorVersion=0 -project.minorVersion=8 -project.patchLevel=0 -project.snapshot=false - -checkstyle.standard=Zend - -component.type=php-library -component.version=10 - -pear.local=/var/www/${project.channel} diff --git a/build.xml b/build.xml deleted file mode 100644 index 4264119d33..0000000000 --- a/build.xml +++ /dev/null @@ -1,437 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- build file for phing --> -<project default="help" basedir="."> - <!-- Human-readable info about our component --> - <property file="build.properties" /> - <taskdef name="now" classname="Phix_Project.ComponentManager.Phing.NowTask" /> - <now name="date.now"/> - <if> - <and> - <isset property="project.snapshot"/> - <istrue value="${project.snapshot}"/> - </and> - <then> - <property name="project.version" value="${project.majorVersion}.${project.minorVersion}.${project.patchLevel}snapshot${date.now}" /> - <property name="project.stability" value="snapshot" /> - </then> - <else> - <property name="project.version" value="${project.majorVersion}.${project.minorVersion}.${project.patchLevel}" /> - <property name="project.stability" value="stable" /> - </else> - </if> - <property name="project.apiversion" value="${project.majorVersion}.${project.minorVersion}" /> - - <!-- Paths to the directories that we work with --> - <property name="project.srcdir" value="${project.basedir}" override="true" /> - <property name="project.src.phpdir" value="${project.srcdir}/php" override="true" /> - <property name="project.src.bindir" value="${project.srcdir}/bin" override="true" /> - <property name="project.src.datadir" value="${project.srcdir}/data" override="true" /> - <property name="project.src.docdir" value="${project.srcdir}/docs" override="true" /> - <property name="project.src.testdir" value="${project.srcdir}/tests" override="true" /> - <property name="project.src.wwwdir" value="${project.srcdir}/www" override="true" /> - <property name="project.src.testunitdir" value="${project.src.testdir}/unit-tests" override="true" /> - <property name="project.src.testintdir" value="${project.src.testdir}/integration-tests" override="true" /> - <property name="project.src.testfuncdir" value="${project.src.testdir}/functional-tests" override="true" /> - - <property name="project.reviewdir" value="${project.basedir}/review" override="true" /> - <property name="project.review.logsdir" value="${project.basedir}/review/logs" override="true" /> - <property name="project.review.docsdir" value="${project.reviewdir}/docs" override="true" /> - <property name="project.review.codebrowserdir" value="${project.reviewdir}/code-browser" override="true" /> - <property name="project.review.codecoveragedir" value="${project.reviewdir}/code-coverage" override="true" /> - - <property name="project.builddir" value="${project.basedir}/.build" override="true" /> - <property name="project.pkgdir" value="${project.builddir}/${project.name}-${project.version}" override="true" /> - <property name="project.tmpdir" value="${project.basedir}/.tmp" override="true" /> - - <property name="project.vendordir" value="${project.basedir}/vendor" override="true" /> - <property name="project.vendor.bindir" value="${project.vendordir}/bin" override="true" /> - <property name="project.vendor.datadir" value="${project.vendordir}/data" override="true" /> - <property name="project.vendor.phpdir" value="${project.vendordir}/php" override="true" /> - <property name="project.vendor.testdir" value="${project.vendordir}/tests" override="true" /> - <property name="project.vendor.docdir" value="${project.vendordir}/docs" override="true" /> - <property name="project.vendor.wwwdir" value="${project.vendordir}/www" override="true" /> - - <property name="project.distdir" value="${project.basedir}/dist" /> - <property name="project.distdir.lastBuilt" value="${project.basedir}/dist/lastBuilt" /> - <property name="project.tarfilename" value="${project.name}-${project.version}.tgz" /> - <property name="project.tarfile" value="${project.distdir}/${project.tarfilename}" /> - - <!-- what was the last PEAR package we created, if any? --> - <if> - <available file="${project.distdir.lastBuilt}"/> - <then> - <property file="${project.distdir.lastBuilt}"/> - </then> - <else> - <property name="project.lastBuiltTarfile" value="false"/> - </else> - </if> - - <!-- override this if you want to run additional PEAR commands --> - <property name="pear.cmd" value="" override="true" /> - - <!-- lists of the files that make up our package --> - <fileset dir="${project.src.bindir}" id="binfiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.git*"/> - </fileset> - <fileset dir="${project.src.datadir}" id="datafiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.git*"/> - </fileset> - <fileset dir="${project.src.phpdir}" id="phpfiles"> - <include name="**/*.php"/> - </fileset> - <fileset dir="${project.src.testunitdir}/php" id="testfiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.git*"/> - </fileset> - <fileset dir="${project.src.wwwdir}" id="wwwfiles"> - <include name="**/**" /> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.git*"/> - </fileset> - <fileset dir="${project.src.docdir}" id="docfiles"> - <include name="**/**" /> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.git*"/> - </fileset> - <fileset dir="${project.basedir}" id="topleveldocfiles"> - <include name="*.txt" /> - <include name="*.md" /> - </fileset> - - <taskdef name="phingcallifexists" classname="Phix_Project.ComponentManager.Phing.PhingCallIfExistsTask" /> - <import file="build.local.xml"/> - - <!-- Tell the user what this build file supports --> - <target name="help"> - <echo message="${project.name} ${project.version}: build.xml targets:" /> - <echo message="" /> - <echo message="Setup your dev environment:" /> - <echo message="" /> - <echo message=" build-vendor" /> - <echo message=" Populate vendor/ with this package's dependencies" /> - <echo message=" vendor-pear" /> - <echo message=" Run additional PEAR commands inside the vendor folder" /> - <echo message="" /> - <echo message="Develop your code:" /> - <echo message="" /> - <echo message=" lint" /> - <echo message=" Check the PHP files for syntax errors" /> - <echo message=" test" /> - <echo message=" Run the component's PHPUnit tests" /> - <echo message=" code-review" /> - <echo message=" Run all of the code quality targets:" /> - <echo message="" /> - <echo message=" code-browser" /> - <echo message=" Run code quality tests for PHP_CodeBrowser" /> - <echo message=" phpcpd" /> - <echo message=" Check for cut and paste problems" /> - <echo message=" phpdoc" /> - <echo message=" Create the PHP docs from source code" /> - <echo message="" /> - <echo message="Publish your component:" /> - <echo message="" /> - <echo message=" pear-package" /> - <echo message=" Create a PEAR-compatible package" /> - <echo message=" publish-local" /> - <echo message=" Publish your PEAR-compatible package into a local copy" /> - <echo message=" of your PEAR channel" /> - <echo message=" install-vendor" /> - <echo message=" Install this component from source into vendor/" /> - <echo message=" install-system" /> - <echo message=" Install this component from source for all local users" /> - <echo message=" You must be root to run this target on Linux!!" /> - <echo message=""/> - <echo message="Maintain your component:"/> - <echo message=""/> - <echo message=" upgrade-skeleton"/> - <echo message=" Upgrade the skeleton files for this component"/> - <echo message=""/> - <echo message="Additional targets:" /> - <echo message=""/> - <echo message=" clean" /> - <echo message=" Remove all temporary folders created by this build file" /> - <echo message=" version" /> - <echo message=" Show this component's version from build.properties" /> - <echo message="" /> - <phingcallifexists target="local.help" /> - </target> - - <!-- Show the current version, as set in build.properties --> - <!-- This is just to be a time-saver --> - <target name="version"> - <echo message="${project.version}" /> - </target> - - <!-- Run PHP lint on all of the source code --> - <target name="lint"> - <phplint> - <fileset dir="${project.src.phpdir}"> - <include name="**/*.php" /> - </fileset> - </phplint> - <phingcallifexists target="local.lint" /> - </target> - - <!-- Run the unit tests for this module --> - <target name="run-unittests" depends="lint"> - <!-- Make sure vendor/ folder exists --> - <if> - <not> - <available file="${project.vendordir}" type="dir"/> - </not> - <then> - <phingcall target="build-vendor"/> - </then> - </if> - - <!-- do we have any tests? --> - <!-- currently cannot think of a reliable way to test this in phing --> - - <!-- run the tests --> - <delete dir="${project.review.codecoveragedir}" /> - <mkdir dir="${project.review.codecoveragedir}" /> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpunit --configuration=phpunit.xml ${project.src.testunitdir}" checkreturn="true" logoutput="true"/> - <echo/> - <echo>The code coverage report is in file://${project.review.codecoveragedir}</echo> - <echo/> - </target> - - <!-- Run all the tests for this module --> - <target name="test" depends="run-unittests"> - <phingcallifexists target="local.test"/> - </target> - - <!-- Run the code review quality tests --> - <target name="code-review" depends="run-unittests, code-browser, phpcpd, pdepend"> - <phingcallifexists target="local.code-review"/> - </target> - - <!-- Run all of the targets for setting up the code browser --> - <target name="code-browser" depends="phpmd, phpcs, phpcb"> - <phingcallifexists target="local.code-browser"/> - </target> - - <target name="pdepend"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="pdepend --phpunit-xml=${project.review.logsdir}/pdepend.xml --jdepend-xml=${project.review.logsdir}/jdepend.xml --jdepend-chart=${project.review.logsdir}/dependencies.svg --overview-pyramid=${project.review.logsdir}/overview-pyramid.svg ${project.src.phpdir}" logoutput="true"/> - </target> - - <!-- Generate package docs --> - <target name="phpdoc"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpdoc -d ${project.src.phpdir} -t ${project.review.docsdir}" logoutput="true"/> - <echo message="You will find the PHPDoc for your project at: ${project.review.docsdir}/index.html"/> - <phingcallifexists target="local.phpdoc"/> - </target> - - <!-- Check code for code smells --> - <target name="phpmd"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpmd ${project.src.phpdir} xml codesize,design,naming,unusedcode --reportfile ${project.review.logsdir}/phpmd.xml" logoutput="true" /> - </target> - - <target name="phpcpd"> - <mkdir dir="${project.review.logsdir}"/> - <exec command="phpcpd --log-pmd ${project.review.logsdir}/pmd-cpd.xml ${project.src.phpdir}" logoutput="true" /> - </target> - - <!-- Check the code for style violations --> - <target name="phpcs"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpcs --report=xml --report-file=${project.review.logsdir}/checkstyle.xml --standard=${checkstyle.standard} --extensions=php ${project.src.phpdir}" logoutput="true"/> - </target> - - <!-- Build the code-browser files --> - <target name="phpcb" depends="phpmd"> - <delete dir="${project.review.codebrowserdir}" /> - <mkdir dir="${project.review.codebrowserdir}" /> - <exec command="phpcb --log ${project.review.logsdir} --source ${project.src.phpdir} --output ${project.review.codebrowserdir}" logoutput="true" /> - </target> - - <!-- Populate vendor with the dependencies for this component --> - <target name="build-vendor" depends="pear-package,setup-vendor"> - <echo>Populating vendor/ with dependencies</echo> - <exec command="phix pear:register-channels" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config install --alldeps ${project.tarfile}" logoutput="true" checkreturn="true"/> - <echo/> - <echo>Your vendor/ folder has been built.</echo> - <echo>You only need to run 'phing build-vendor' again if you change the</echo> - <echo>dependencies listed in your package.xml file.</echo> - <echo/> - <phingcallifexists target="local.buildvendor"/> - </target> - - <!-- Setup the vendor folder --> - <target name="setup-vendor"> - <echo>Creating vendor/ as a sandboxed PEAR install folder</echo> - <delete dir="${project.vendordir}" /> - <mkdir dir="${project.vendordir}" /> - <delete dir="${project.tmpdir}" /> - <mkdir dir="${project.tmpdir}" /> - <exec command="pear config-create ${project.tmpdir} ${project.tmpdir}/pear-config" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set preferred_state alpha" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set php_dir ${project.vendor.phpdir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set bin_dir ${project.vendor.bindir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set data_dir ${project.vendor.datadir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set doc_dir ${project.vendor.docdir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set test_dir ${project.vendor.testdir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set www_dir ${project.vendor.wwwdir}" checkreturn="true" logoutput="true" /> - </target> - - <!-- Create the PEAR package, ready for release --> - <target name="pear-package"> - <echo>Building release directory</echo> - <delete dir="${project.builddir}" /> - <mkdir dir="${project.pkgdir}" /> - <copy todir="${project.pkgdir}"> - <fileset refid="binfiles"/> - <fileset refid="datafiles"/> - <fileset refid="phpfiles"/> - <fileset refid="testfiles"/> - <fileset refid="wwwfiles"/> - <fileset refid="docfiles"/> - <fileset refid="topleveldocfiles"/> - </copy> - <copy todir="${project.builddir}"> - <fileset dir="."> - <include name="package.xml" /> - </fileset> - </copy> - - <exec command="phix pear:expand-package-xml" checkreturn="yes" logoutput="yes"/> - - <echo>Creating ${project.tarfile} PEAR package</echo> - - <mkdir dir="${project.distdir}" /> - <delete file="${project.tarfile}" /> - <tar destfile="${project.tarfile}" compression="gzip"> - <fileset dir="${project.builddir}"> - <include name="**/**" /> - </fileset> - </tar> - - <!-- remember the tarball we have just build --> - <property name="project.lastBuiltTarfile" value="${project.tarfile}" override="true"/> - <echo file="${project.distdir.lastBuilt}" append="false">project.lastBuiltTarfile=${project.tarfile}</echo> - - <!-- write a message to say which file we built last --> - <echo>Your PEAR package is in ${project.tarfile}</echo> - <phingcallifexists target="local.pear-package"/> - </target> - - <!-- Install the code --> - <target name="install-vendor"> - <if> - <not> - <contains string="${project.lastBuiltTarfile}" substring="${project.name}"/> - </not> - <then> - <echo>Please run 'phing pear-package' first, then try again.</echo> - </then> - <elseif> - <available file="${project.lastBuiltTarfile}"/> - <then> - <exec command="pear -c ${project.tmpdir}/pear-config install --alldeps -f ${project.lastBuiltTarfile}" logoutput="true" checkreturn="true"/> - <phingcallifexists target="local.install-vendor"/> - </then> - </elseif> - <else> - <echo>Cannot find PEAR package file ${project.lastBuiltTarfile}</echo> - <echo>Run 'phing pear-package' to create a new PEAR package, then try again</echo> - </else> - </if> - </target> - - <!-- install a package system-wide --> - <target name="install-system"> - <if> - <not> - <contains string="${project.lastBuiltTarfile}" substring="${project.name}"/> - </not> - <then> - <echo>Please run 'phing pear-package' first, then try again.</echo> - </then> - <elseif> - <available file="${project.lastBuiltTarfile}"/> - <then> - <exec command="pear install -f -a ${project.lastBuiltTarfile}" checkreturn="true" logoutput="true" /> - <phingcallifexists target="local.install-system"/> - </then> - </elseif> - <else> - <echo>Cannot find PEAR package file ${project.lastBuiltTarfile}</echo> - <echo>Run 'phing pear-package' to create a new PEAR package, then try again</echo> - </else> - </if> - </target> - - <!-- Publish to local copy of PEAR channel --> - <target name="publish-local" depends="pear-package"> - <if> - <not> - <contains string="${project.lastBuiltTarfile}" substring="${project.name}"/> - </not> - <then> - <echo>Please run 'phing pear-package' first, then try again.</echo> - </then> - <elseif> - <available file="${project.lastBuiltTarfile}"/> - <then> - <!-- get rid of any existing snapshots we may have published --> - <foreach param="packagefile" absparam="abspackagefile" target="pirum-remove-package"> - <fileset dir="${pear.local}/get"> - <include name="${project.name}*snapshot*.tgz" /> - </fileset> - </foreach> - - <!-- publish the new PEAR package --> - <exec command="pirum add ${pear.local} ${project.lastBuiltTarfile}" checkreturn="true" logoutput="true" /> - <phingcallifexists target="local.publish-local"/> - </then> - </elseif> - <else> - <echo>Cannot find PEAR package file ${project.lastBuiltTarfile}</echo> - <echo>Run 'phing pear-package' to create a new PEAR package, then try again</echo> - </else> - </if> - </target> - - <target name="pirum-remove-package"> - <exec command="pirum remove ${pear.local} ${packagefile}" logoutput="true" checkreturn="true" /> - </target> - - <!-- Run additional PEAR commands in the vendor folder --> - <target name="vendor-pear"> - <exec command="pear -c ${project.tmpdir}/pear-config ${pear.cmd}" logoutput="true" checkreturn="true" /> - </target> - - <!-- Upgrade the skeleton files here and now --> - <target name="upgrade-skeleton"> - <exec command="phix ${component.type}:upgrade ." logoutput="true" checkreturn="true" /> - <phingcallifexists target="local.upgrade-skeleton"/> - </target> - - <!-- Clean up the mess --> - <target name="clean"> - <delete dir="${project.builddir}" /> - <delete dir="${project.distdir}" /> - <delete dir="${project.reviewdir}" /> - <delete dir="${project.pkgdir}" /> - <delete dir="${project.distdir}" /> - <delete dir="${project.tmpdir}" /> - <phingcallifexists target="local.clean"/> - </target> -</project> -<!-- vim: set tabstop=2 shiftwidth=2 expandtab: --> diff --git a/package.xml b/package.xml deleted file mode 100644 index 852e8c4b14..0000000000 --- a/package.xml +++ /dev/null @@ -1,71 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<package packagerversion="1.9.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 - http://pear.php.net/dtd/tasks-1.0.xsd - http://pear.php.net/dtd/package-2.0 - http://pear.php.net/dtd/package-2.0.xsd"> - <name>${project.name}</name> - <channel>${project.channel}</channel> - <summary>WordPress CLI interface</summary> - <description> - A tool for controlling WordPress through the command line. - </description> - <lead> - <name>Andreas Creten</name> - <user>andreascreten</user> - <email></email> - <active>yes</active> - </lead> - <lead> - <name>scribu</name> - <user>scribu</user> - <email>mail@scribu.net</email> - <active>yes</active> - </lead> - <date>${build.date}</date> - <time>${build.time}</time> - <version> - <release>${project.version}</release> - <api>${project.majorVersion}.${project.minorVersion}</api> - </version> - <stability> - <release>${project.stability}</release> - <api>stable</api> - </stability> - <license>MIT</license> - <notes> - No notes. - </notes> - <contents> - <dir baseinstalldir="/" name="/"> -${contents} - </dir> - </contents> - <dependencies> - <required> - <php> - <min>5.3.0</min> - </php> - <pearinstaller> - <min>1.9.4</min> - </pearinstaller> - </required> - </dependencies> - <phprelease /> - <changelog> - <release> - <version> - <release>X.Y.Z</release> - <api>X.Y</api> - </version> - <stability> - <release>stable</release> - <api>stable</api> - </stability> - <date>Your release date</date> - <license>All rights reserved</license> - <notes> - </notes> - </release> - </changelog> -</package> -<!-- vim: set tabstop=2 shiftwidth=2 expandtab: --> diff --git a/utils/pear-build b/utils/pear-build deleted file mode 100755 index f2be1b3fdc..0000000000 --- a/utils/pear-build +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -set -ex - -# create bunch of directories that phing complains about -mkdir -p docs data www tests/unit-tests/php - -# generate package -phing pear-package - -version=$(cat dist/lastBuilt) -version="${version/*wpcli-/}" -version="${version/.tgz/}" - -#sudo phing install-system - -# update channel files -pear_repo=../wp-cli-pear - -pirum add $pear_repo ../wp-cli/dist/wpcli-$version.tgz -pirum build $pear_repo - -# push changes -cd $pear_repo - -git add -A -git ci -m "release $version" -git push origin gh-pages From bd0ad30c018b3f33ed9b7bb1f4eece7536a511ce Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 8 Feb 2013 15:33:54 -0800 Subject: [PATCH 1199/4858] Introduce system editor function in \WP_CLI\Utils Adds a function called `launch_editor_for_input()` which launches the system's editor to allow file editing of post content, etc. Should account for system line-endings properly, but probably needs testing on Windows to be sure. Function returns false if no change (ie user :q!'s out of vim), or updated content if any change is made. Also adds two new subcommands to `wp post`: - `wp post create --edit` Launches the editor to build the post content before creating post. - `wp post edit <id>` Edits post <id>'s content in system editor. --- php/commands/post.php | 37 ++++++++++++++++++++++++++++++++++++- php/utils.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 1e69d24b7e..d741b885d1 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -12,9 +12,21 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { /** * Create a post. * - * @synopsis --<field>=<value> [--porcelain] + * @synopsis --<field>=<value> [--edit] [--porcelain] */ public function create( $_, $assoc_args ) { + if ( isset( $assoc_args['edit'] ) ) { + + $input = ( isset( $assoc_args['post_content'] ) ) ? + $assoc_args['post_content'] : ''; + + if ( $output = \WP_CLI\Utils\launch_editor_for_input( $input ) ) + $assoc_args['post_content'] = $output; + else + $assoc_args['post_content'] = $input; + + } + parent::create( $assoc_args ); } @@ -35,6 +47,29 @@ protected function _update( $params ) { return wp_update_post( $params, true ); } + /** + * Launch system editor to edit post content + * + * @synopsis <id>... + */ + public function edit( $args, $assoc_args ) { + $post_id = $args[0]; + if ( !$post_id || !$post = get_post( $post_id ) ) { + \WP_CLI::error( "Failed opening post $post_id to edit.", false ); + return; + } + + $r = \WP_CLI\Utils\launch_editor_for_input( $post->post_content ); + + if ( !$r ) { + \WP_CLI::error( "Aborting. No change made to post.", false ); + return; + } + + $assoc_args['post_content'] = $r; + parent::update( $args, $assoc_args ); + } + /** * Delete a post by ID. * diff --git a/php/utils.php b/php/utils.php index 4e06615c73..c68545a16b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -257,5 +257,35 @@ function output_csv( $rows, $headers = array() ) { } fputcsv( STDOUT, $row ); } + } +/** + * Launch system's $EDITOR to edit text + * + * @param str $content Text to edit (eg post content) + * @return str|bool Edited text, if file is saved from editor + */ +function launch_editor_for_input( $input ) { + + $tmpfile = tempnam( '/tmp', 'wp-cli' ); + + if ( !$tmpfile ) + die( 'Error creating temporary file.' ); + + $handle = fopen( $tmpfile, 'w+t' ); + fwrite( $handle, $input ); + fclose( $handle ); + + $out = `\${EDITOR:-vi} "$tmpfile" 3>&1 1>&2 2>&3 || exit $?`; + + $handle = fopen( $tmpfile, 'r' ); + $output = fread( $handle, filesize( $tmpfile ) ); + fclose( $handle ); + unlink( $tmpfile ); + + if ( $output === $input ) + return false; + + return $output; +} From 32b851e3cc405c067d2eee59c716c90b229d5523 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 17:07:24 +0200 Subject: [PATCH 1200/4858] replace <parent> with <term-id> --- man-src/term-create.txt | 4 ++-- php/commands/term.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/man-src/term-create.txt b/man-src/term-create.txt index 31ca3a4ee9..e34cd38421 100644 --- a/man-src/term-create.txt +++ b/man-src/term-create.txt @@ -16,10 +16,10 @@ A description for the new term. -* `--parent`=<parent>: +* `--parent`=<term-id>: A parent for the new term. ## EXAMPLES - wp term create Apple category --description="A type of fruit" \ No newline at end of file + wp term create Apple category --description="A type of fruit" diff --git a/php/commands/term.php b/php/commands/term.php index 888ef2da55..148559e1a7 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -40,7 +40,7 @@ public function _list( $args, $assoc_args ) { /** * Create a term. * - * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<parent>] + * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<term-id>] */ public function create( $args, $assoc_args ) { @@ -63,7 +63,7 @@ public function create( $args, $assoc_args ) { /** * Update a term. - * + * * @synopsis <term-id> <taxonomy> [--name=<name>] [--slug=<slug>] [--description=<description>] [--parent=<parent>] */ public function update( $args, $assoc_args ) { @@ -113,4 +113,4 @@ public function delete( $args ) { } -WP_CLI::add_command( 'term', 'Term_Command' ); \ No newline at end of file +WP_CLI::add_command( 'term', 'Term_Command' ); From 5599b00beffb1bf21cd4e5cc1837536bac7cc8c0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 17:18:28 +0200 Subject: [PATCH 1201/4858] use format_items() utility in wp user list --- php/commands/user.php | 44 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 7ded9497d8..7c71e42ad5 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -41,45 +41,23 @@ public function _list( $args, $assoc_args ) { 'user_registered' ); - switch( $params['format'] ) { - case 'table': - $table = new \cli\Table(); + $output_users = array(); - $table->setHeaders( array_merge( $fields, array('roles') ) ); + foreach ( $users as $user ) { + $output_user = new stdClass; - foreach ( $users as $user ) { - $line = array(); - - foreach ( $fields as $field ) { - $line[] = $user->$field; - } - $line[] = implode( ',', $user->roles ); - - $table->addRow( $line ); - } + foreach ( $fields as $field ) { + $output_user->$field = $user->$field; + } - $table->display(); + $output_user->roles = implode( ',', $user->roles ); - WP_CLI::line( 'Total: ' . count( $users ) . ' users' ); - break; - case 'json': - case 'csv': - $output_users = array(); + $output_users[] = $output_user; + } - foreach( $users as $user ) { - $output_user = new stdClass; - foreach( $fields as $field ) { - $output_user->$field = $user->$field; - } - $output_users[] = $output_user; - } + $fields[] = 'roles'; - if ( 'json' == $params['format'] ) - echo json_encode( $output_users ); - else - WP_CLI\Utils\output_csv( $output_users, $fields ); - break; - } + WP_CLI\Utils\format_items( $params['format'], $fields, $output_users ); } /** From e2fcc550e5bc8822f1ed8955c7814dc15c5280bb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 17:23:14 +0200 Subject: [PATCH 1202/4858] replace <parent> with <term-id> for wp term update --- man-src/term-update.txt | 4 ++-- php/commands/term.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man-src/term-update.txt b/man-src/term-update.txt index 82ae9a1135..cc6bc6cf91 100644 --- a/man-src/term-update.txt +++ b/man-src/term-update.txt @@ -20,10 +20,10 @@ A new description for the term. -* `--parent`=<parent>: +* `--parent`=<term-id>: A new parent for the term. ## EXAMPLES - wp term update 15 category --name=Apple \ No newline at end of file + wp term update 15 category --name=Apple diff --git a/php/commands/term.php b/php/commands/term.php index 148559e1a7..f8c999c599 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -64,7 +64,7 @@ public function create( $args, $assoc_args ) { /** * Update a term. * - * @synopsis <term-id> <taxonomy> [--name=<name>] [--slug=<slug>] [--description=<description>] [--parent=<parent>] + * @synopsis <term-id> <taxonomy> [--name=<name>] [--slug=<slug>] [--description=<description>] [--parent=<term-id>] */ public function update( $args, $assoc_args ) { From 30ded5cb06b1638527efab4ab2096b15f3aa3b4c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 17:23:46 +0200 Subject: [PATCH 1203/4858] add generated man pages --- man/term-create.1 | 51 ++++++++++++++++++++++++++++++++++++++++++ man/term-delete.1 | 33 +++++++++++++++++++++++++++ man/term-list.1 | 33 +++++++++++++++++++++++++++ man/term-update.1 | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 man/term-create.1 create mode 100644 man/term-delete.1 create mode 100644 man/term-list.1 create mode 100644 man/term-update.1 diff --git a/man/term-create.1 b/man/term-create.1 new file mode 100644 index 0000000000..a5cf4ad564 --- /dev/null +++ b/man/term-create.1 @@ -0,0 +1,51 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TERM\-CREATE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-term\-create\fR \- Create a term\. +. +.SH "SYNOPSIS" +wp term create \fIterm\fR \fItaxonomy\fR [\-\-slug=\fIslug\fR] [\-\-description=\fIdescription\fR] [\-\-parent=\fIterm\-id\fR] +. +.SH "OPTIONS" +. +.TP +\fB<term>\fR: +. +.IP +A name for the new term\. +. +.TP +\fB<taxonomy>\fR: +. +.IP +Taxonomy for the new term\. +. +.TP +\fB\-\-slug\fR=\fIslug\fR: +. +.IP +A unique slug for the new term\. Defaults to sanitized version of name\. +. +.TP +\fB\-\-description\fR=\fIdescription\fR: +. +.IP +A description for the new term\. +. +.TP +\fB\-\-parent\fR=\fIterm\-id\fR: +. +.IP +A parent for the new term\. +. +.SH "EXAMPLES" +. +.nf + +wp term create Apple category \-\-description="A type of fruit" +. +.fi + diff --git a/man/term-delete.1 b/man/term-delete.1 new file mode 100644 index 0000000000..1a9700510f --- /dev/null +++ b/man/term-delete.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TERM\-DELETE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-term\-delete\fR \- Delete a term\. +. +.SH "SYNOPSIS" +wp term delete \fIterm\-id\fR \fItaxonomy\fR +. +.SH "OPTIONS" +. +.TP +\fB<term\-id>\fR: +. +.IP +ID for the term to delete\. +. +.TP +\fB<taxonomy>\fR: +. +.IP +Taxonomy of the term to delete\. +. +.SH "EXAMPLES" +. +.nf + +wp term delete 15 category +. +.fi + diff --git a/man/term-list.1 b/man/term-list.1 new file mode 100644 index 0000000000..060772fdd5 --- /dev/null +++ b/man/term-list.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TERM\-LIST" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-term\-list\fR \- List terms in a taxonomy\. +. +.SH "SYNOPSIS" +wp term list \fItaxonomy\fR [\-\-format=\fIformat\fR] +. +.SH "OPTIONS" +. +.TP +\fB<taxonomy>\fR: +. +.IP +List terms of a given taxonomy\. +. +.TP +\fB\-\-format\fR=\fIformat\fR: +. +.IP +Output list as table, CSV or JSON\. Defaults to table\. +. +.SH "EXAMPLES" +. +.nf + +wp term list category \-\-format=csv +. +.fi + diff --git a/man/term-update.1 b/man/term-update.1 new file mode 100644 index 0000000000..34bf099def --- /dev/null +++ b/man/term-update.1 @@ -0,0 +1,57 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-TERM\-UPDATE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-term\-update\fR \- Update a term\. +. +.SH "SYNOPSIS" +wp term update \fIterm\-id\fR \fItaxonomy\fR [\-\-name=\fIname\fR] [\-\-slug=\fIslug\fR] [\-\-description=\fIdescription\fR] [\-\-parent=\fIterm\-id\fR] +. +.SH "OPTIONS" +. +.TP +\fB<term\-id>\fR: +. +.IP +ID for the term to update\. +. +.TP +\fB<taxonomy>\fR: +. +.IP +Taxonomy of the term to update\. +. +.TP +\fB\-\-name\fR=\fIname\fR: +. +.IP +A new name for the term\. +. +.TP +\fB\-\-slug\fR=\fIslug\fR: +. +.IP +A new slug for the term\. +. +.TP +\fB\-\-description\fR=\fIdescription\fR: +. +.IP +A new description for the term\. +. +.TP +\fB\-\-parent\fR=\fIterm\-id\fR: +. +.IP +A new parent for the term\. +. +.SH "EXAMPLES" +. +.nf + +wp term update 15 category \-\-name=Apple +. +.fi + From 30f83685104b1a3c07026c004fba22519444a2a9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 17:47:05 +0200 Subject: [PATCH 1204/4858] fix indenting for term command. see #286 --- php/commands/term.php | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index f8c999c599..9c4e82a1e4 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -17,22 +17,22 @@ public function _list( $args, $assoc_args ) { list( $taxonomy ) = $args; $defaults = array( - 'format' => 'table', - 'hide_empty' => false, - ); + 'format' => 'table', + 'hide_empty' => false, + ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); $terms = get_terms( array( $taxonomy ), $assoc_args ); $fields = array( - 'term_id', - 'term_taxonomy_id', - 'name', - 'slug', - 'description', - 'parent', - 'count', - ); + 'term_id', + 'term_taxonomy_id', + 'name', + 'slug', + 'description', + 'parent', + 'count', + ); WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); } @@ -47,10 +47,10 @@ public function create( $args, $assoc_args ) { list( $term, $taxonomy ) = $args; $defaults = array( - 'slug' => sanitize_title( $term ), - 'description' => '', - 'parent' => '', - ); + 'slug' => sanitize_title( $term ), + 'description' => '', + 'parent' => '', + ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); $ret = wp_insert_term( $term, $taxonomy, $assoc_args ); @@ -71,11 +71,11 @@ public function update( $args, $assoc_args ) { list( $term_id, $taxonomy ) = $args; $defaults = array( - 'name' => null, - 'slug' => null, - 'description' => null, - 'parent' => null, - ); + 'name' => null, + 'slug' => null, + 'description' => null, + 'parent' => null, + ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); foreach( $assoc_args as $key => $value ) { @@ -89,7 +89,6 @@ public function update( $args, $assoc_args ) { WP_CLI::error( $ret->get_error_message() ); else WP_CLI::success( "Term updated." ); - } /** @@ -114,3 +113,4 @@ public function delete( $args ) { } WP_CLI::add_command( 'term', 'Term_Command' ); + From d74537e2e5df5dab9fb02f62165e08cd9c194793 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 18:17:39 +0200 Subject: [PATCH 1205/4858] remove superfluous parameters from post and taxonomy scaffolds --- php/commands/scaffold.php | 40 ++++++------------------------------ templates/post_type.mustache | 24 ++++++++-------------- templates/taxonomy.mustache | 16 +++++++-------- 3 files changed, 21 insertions(+), 59 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 08996cdecd..36be7ab545 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -18,27 +18,11 @@ function __construct() { * * @alias cpt * - * @synopsis <slug> [--singular=<label>] [--description=<description>] [--public=<public>] [--exclude_from_search=<exclude_from_search>] [--show_ui=<show_ui>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_in_menu=<show_in_menu>] [--show_in_admin_bar=<show_in_admin_bar>] [--menu_position=<menu_position>] [--menu_icon=<menu_icon>] [--capability_type=<capability_type>] [--hierarchical=<hierarchical>] [--supports=<supports>] [--has_archive=<has_archive>] [--query_var=<query_var>] [--can_export=<can_export>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] + * @synopsis <slug> [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function post_type( $args, $assoc_args ) { $defaults = array( - 'description' => '', - 'public' => 'true', - 'exclude_from_search' => 'false', - 'show_ui' => 'true', - 'show_in_nav_menus' => 'true', - 'show_in_menu' => 'true', - 'show_in_admin_bar' => 'true', - 'menu_position' => 'null', - 'menu_icon' => 'null', - 'capability_type' => 'post', - 'hierarchical' => 'false', - 'supports' => "'title', 'editor'", - 'has_archive' => 'true', - 'rewrite' => 'true', - 'query_var' => 'true', - 'can_export' => 'true', - 'textdomain' => '', + 'textdomain' => '', ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/post-types/', array( @@ -54,19 +38,12 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis <slug> [--singular=<label>] [--public=<public>] [--show_in_nav_menus=<show_in_nav_menus>] [--show_ui=<show_ui>] [--show_tagcloud=<show_tagcloud>] [--hierarchical=<hierarchical>] [--rewrite=<rewrite>] [--query_var=<query_var>] [--textdomain=<textdomain>] [--post_types=<post_types>] [--theme] [--plugin=<plugin>] [--raw] + * @synopsis <slug> [--post_types=<post-types>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function taxonomy( $args, $assoc_args ) { $defaults = array( - 'public' => 'true', - 'show_in_nav_menus' => 'true', - 'show_ui' => 'true', - 'show_tagcloud' => 'true', - 'hierarchical' => 'false', - 'rewrite' => 'true', - 'query_var' => 'true', - 'post_types' => 'post', - 'textdomain' => '', + 'textdomain' => '', + 'post_types' => 'post' ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/taxonomies/', array( @@ -90,12 +67,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); - // If no label is given use the slug and prettify it as good as possible - if ( isset( $assoc_args['singular'] ) ) { - $vars['label'] = $assoc_args['singular']; - } else { - $vars['label'] = preg_replace( '/_|-/', ' ', strtolower( $slug ) ); - } + $vars['label'] = preg_replace( '/_|-/', ' ', strtolower( $slug ) ); $vars['label_ucfirst'] = ucfirst( $vars['label'] ); $vars['label_plural'] = $this->pluralize( $vars['label'] ); diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 00e9d652d0..44ebb048ee 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -1,20 +1,12 @@ register_post_type( '{{slug}}', array( - 'description' => __( '{{description}}', '{{textdomain}}' ), - 'public' => {{public}}, - 'exclude_from_search' => {{exclude_from_search}}, - 'show_ui' => {{show_ui}}, - 'show_in_nav_menus' => {{show_in_nav_menus}}, - 'show_in_menu' => {{show_in_menu}}, - 'show_in_admin_bar' => {{show_in_admin_bar}}, - 'menu_position' => {{menu_position}}, - 'menu_icon' => {{menu_icon}}, - 'capability_type' => '{{capability_type}}', - 'hierarchical' => {{hierarchical}}, - 'supports' => array( {{supports}} ), - 'has_archive' => {{has_archive}}, - 'rewrite' => {{rewrite}}, - 'query_var' => {{query_var}}, - 'can_export' => {{can_export}}, + 'hierarchical' => false, + 'public' => true, + 'show_in_nav_menus' => true, + 'show_ui' => true, + 'supports' => array( 'title', 'editor' ), + 'has_archive' => true, + 'query_var' => {{slug}}, + 'rewrite' => true, 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index db2ba2e370..20747a722a 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -1,13 +1,11 @@ register_taxonomy( '{{slug}}', array( '{{post_types}}' ), array( - 'public' => {{public}}, - 'show_in_nav_menus' => {{show_in_nav_menus}}, - 'show_ui' => {{show_ui}}, - 'show_tagcloud' => {{show_tagcloud}}, - 'hierarchical' => {{hierarchical}}, - 'update_count_callback' => '_update_post_term_count', - 'query_var' => {{query_var}}, - 'rewrite' => {{rewrite}}, - 'capabilities' => array ( + 'hierarchical' => false, + 'public' => true, + 'show_in_nav_menus' => true, + 'show_ui' => true, + 'query_var' => {{slug}}, + 'rewrite' => true, + 'capabilities' => array( 'manage_terms' => 'edit_posts', 'edit_terms' => 'edit_posts', 'delete_terms' => 'edit_posts', From 79efd4e08a88cf8aa012cfff99564fca0440d4d8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 18:19:46 +0200 Subject: [PATCH 1206/4858] regenerate manpages --- man/scaffold-post-type.1 | 2 +- man/scaffold-taxonomy.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 index 208d21cda9..5e9223561f 100644 --- a/man/scaffold-post-type.1 +++ b/man/scaffold-post-type.1 @@ -7,7 +7,7 @@ \fBwp\-scaffold\-post\-type\fR \- Generate PHP code for registering a custom post type\. . .SH "SYNOPSIS" -wp scaffold post\-type \fIslug\fR [\-\-singular=\fIlabel\fR] [\-\-description=\fIdescription\fR] [\-\-public=\fIpublic\fR] [\-\-exclude_from_search=\fIexclude_from_search\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_in_menu=\fIshow_in_menu\fR] [\-\-show_in_admin_bar=\fIshow_in_admin_bar\fR] [\-\-menu_position=\fImenu_position\fR] [\-\-menu_icon=\fImenu_icon\fR] [\-\-capability_type=\fIcapability_type\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-supports=\fIsupports\fR] [\-\-has_archive=\fIhas_archive\fR] [\-\-query_var=\fIquery_var\fR] [\-\-can_export=\fIcan_export\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +wp scaffold post\-type \fIslug\fR [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] . .SH "OPTIONS" . diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index d6f65ef62b..6af8faf4fb 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -7,7 +7,7 @@ \fBwp\-scaffold\-taxonomy\fR \- Generate PHP code for registering a custom taxonomy\. . .SH "SYNOPSIS" -wp scaffold taxonomy \fIslug\fR [\-\-singular=\fIlabel\fR] [\-\-public=\fIpublic\fR] [\-\-show_in_nav_menus=\fIshow_in_nav_menus\fR] [\-\-show_ui=\fIshow_ui\fR] [\-\-show_tagcloud=\fIshow_tagcloud\fR] [\-\-hierarchical=\fIhierarchical\fR] [\-\-rewrite=\fIrewrite\fR] [\-\-query_var=\fIquery_var\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-post_types=\fIpost_types\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] . .SH "OPTIONS" . From 478d21235b0deeda574f5666e0bf2903ce6f2b7b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Feb 2013 18:43:11 +0200 Subject: [PATCH 1207/4858] remove @@PHP_DIR@@ reference. see #301 --- bin/wp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/bin/wp b/bin/wp index d2cfa79f8c..0ae1dabd59 100755 --- a/bin/wp +++ b/bin/wp @@ -23,12 +23,7 @@ done cd "$ORIGDIR" # Build the path to the root PHP file -SCRIPT_PATH='@@PHP_DIR@@' -if [ ! -d $SCRIPT_PATH ]; then - SCRIPT_PATH=$(dirname "$SELF_PATH")/../php -fi - -SCRIPT_PATH=$SCRIPT_PATH/boot-fs.php +SCRIPT_PATH=$(dirname "$SELF_PATH")/../php/boot-fs.php case $(uname -a) in CYGWIN*) From 4d3fcccebc36a20115ad927dd83aef0b6ef5cbdd Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Wed, 13 Feb 2013 11:21:20 -0800 Subject: [PATCH 1208/4858] Use WP_CLI::launch to open editor Also use wp_tempnam to create file, and give the created file a meaningful name rather than just using system or php's tempfile name. --- php/commands/post.php | 4 ++-- php/utils.php | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index d741b885d1..f4b8f0b2d0 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -20,7 +20,7 @@ public function create( $_, $assoc_args ) { $input = ( isset( $assoc_args['post_content'] ) ) ? $assoc_args['post_content'] : ''; - if ( $output = \WP_CLI\Utils\launch_editor_for_input( $input ) ) + if ( $output = \WP_CLI\Utils\launch_editor_for_input( $input, 'WP-CLI: New Post' ) ) $assoc_args['post_content'] = $output; else $assoc_args['post_content'] = $input; @@ -59,7 +59,7 @@ public function edit( $args, $assoc_args ) { return; } - $r = \WP_CLI\Utils\launch_editor_for_input( $post->post_content ); + $r = \WP_CLI\Utils\launch_editor_for_input( $post->post_content, "WP-CLI post $post_id" ); if ( !$r ) { \WP_CLI::error( "Aborting. No change made to post.", false ); diff --git a/php/utils.php b/php/utils.php index c68545a16b..68cc356ef4 100644 --- a/php/utils.php +++ b/php/utils.php @@ -265,10 +265,11 @@ function output_csv( $rows, $headers = array() ) { * * @param str $content Text to edit (eg post content) * @return str|bool Edited text, if file is saved from editor + * False, if no change to file */ -function launch_editor_for_input( $input ) { +function launch_editor_for_input( $input, $title = 'WP-CLI' ) { - $tmpfile = tempnam( '/tmp', 'wp-cli' ); + $tmpfile = wp_tempnam( $title ); if ( !$tmpfile ) die( 'Error creating temporary file.' ); @@ -277,7 +278,7 @@ function launch_editor_for_input( $input ) { fwrite( $handle, $input ); fclose( $handle ); - $out = `\${EDITOR:-vi} "$tmpfile" 3>&1 1>&2 2>&3 || exit $?`; + \WP_CLI::launch( "\${EDITOR:-vi} '$tmpfile'" ); $handle = fopen( $tmpfile, 'r' ); $output = fread( $handle, filesize( $tmpfile ) ); From b295e89e57fce49d04e83a4d559fa51abd3f43e8 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Wed, 13 Feb 2013 11:23:45 -0800 Subject: [PATCH 1209/4858] Handle error caused by reading empty file `fread()` will throw an error if trying to read an empty file (ie if user deleted all post content or quit the editor on `wp post create`. Detect that and fail gracefully. --- php/utils.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 68cc356ef4..bb0ee3de81 100644 --- a/php/utils.php +++ b/php/utils.php @@ -280,8 +280,13 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { \WP_CLI::launch( "\${EDITOR:-vi} '$tmpfile'" ); + $filesize = filesize( $tmpfile ); + + if ( $filesize === 0 ) + return false; + $handle = fopen( $tmpfile, 'r' ); - $output = fread( $handle, filesize( $tmpfile ) ); + $output = fread( $handle, $filesize ); fclose( $handle ); unlink( $tmpfile ); From 479a1788d09783b9b8817b172b03f3c9cc85001d Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Wed, 13 Feb 2013 15:59:24 -0800 Subject: [PATCH 1210/4858] Use file_put_contents/file_get_contents instead of fwrite/fread Much simpler this way. Also does away with the need to check for empty output, although now we have to check the return value of `launch_editor_for_input` strictly against false, since its possible for it to return an empty string now (editing a post and deleting all the content). --- php/commands/post.php | 2 +- php/utils.php | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index f4b8f0b2d0..8714b7cba2 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -61,7 +61,7 @@ public function edit( $args, $assoc_args ) { $r = \WP_CLI\Utils\launch_editor_for_input( $post->post_content, "WP-CLI post $post_id" ); - if ( !$r ) { + if ( $r === false ) { \WP_CLI::error( "Aborting. No change made to post.", false ); return; } diff --git a/php/utils.php b/php/utils.php index bb0ee3de81..2f3f5e6de1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -274,20 +274,12 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { if ( !$tmpfile ) die( 'Error creating temporary file.' ); - $handle = fopen( $tmpfile, 'w+t' ); - fwrite( $handle, $input ); - fclose( $handle ); + file_put_contents( $tmpfile, $input ); \WP_CLI::launch( "\${EDITOR:-vi} '$tmpfile'" ); - $filesize = filesize( $tmpfile ); + $output = file_get_contents( $tmpfile ); - if ( $filesize === 0 ) - return false; - - $handle = fopen( $tmpfile, 'r' ); - $output = fread( $handle, $filesize ); - fclose( $handle ); unlink( $tmpfile ); if ( $output === $input ) From e5433ecaf4b838a589560c25cb960de4a89333c8 Mon Sep 17 00:00:00 2001 From: Nikolay Bachiyski <nb@nikolay.bg> Date: Thu, 14 Feb 2013 16:28:40 +0200 Subject: [PATCH 1211/4858] Exit on end-of-file It's a common practice shells to exit on end-of-file. WP-CLI doesn't do this. I traced the reason to the fact we're not checking the exit code from the `read` builtin. If it timeouts or receives end-of-file, it's non-zero. In both these cases it makes sense to exit. --- php/commands/shell.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/shell.php b/php/commands/shell.php index c0e73760ff..75a90151d9 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -52,6 +52,10 @@ private static function prompt() { $line = fgets( $fp ); + if ( !$line ) { + $line = 'exit'; + } + return trim( $line ); } @@ -61,6 +65,7 @@ private static function create_prompt_cmd( $prompt, $history_path ) { sprintf( 'history -r %s', escapeshellarg( $history_path ) ), 'LINE=""', sprintf( 'read -re -p %s LINE', escapeshellarg( $prompt ) ), + '[ $? -eq 0 ] || exit', 'history -s "$LINE"', sprintf( 'history -w %s', escapeshellarg( $history_path ) ), 'echo $LINE' From eeba0afaf5005101a92cc9b60ec3adf882561c1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 14 Feb 2013 17:09:01 +0200 Subject: [PATCH 1212/4858] allow whitespace before the 'require' statement in wp-config.php. see #288 --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 1daa7ef482..1683393fdd 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -151,7 +151,7 @@ function get_wp_config_code() { $lines_to_run = array(); foreach ( $wp_config_code as $line ) { - if ( preg_match( '/^require.+wp-settings\.php/', $line ) ) + if ( preg_match( '/^\s*require.+wp-settings\.php/', $line ) ) continue; $lines_to_run[] = str_replace( $old, $new, $line ); From e9f17aa732cdd393ede0400316bb97b2b697ebcb Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 14 Feb 2013 15:29:16 -0800 Subject: [PATCH 1213/4858] Make error messages and output codes more logical Use `WP_CLI::error` for any fatal errors. Output a warning rather than an error if user aborts the editor (At this point it exits without performing any action just like an error would, but it shouldn't be considered an error. Also, its possible that commands using the editor function will go on to perform other actions.) Also, whitespace cleanup and minor refactoring... making a helper method `_edit()` in post.php to make editor functions more reusable. --- php/commands/post.php | 27 +++++++++++++-------------- php/utils.php | 2 +- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 8714b7cba2..5a27d54ef6 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -20,7 +20,7 @@ public function create( $_, $assoc_args ) { $input = ( isset( $assoc_args['post_content'] ) ) ? $assoc_args['post_content'] : ''; - if ( $output = \WP_CLI\Utils\launch_editor_for_input( $input, 'WP-CLI: New Post' ) ) + if ( $output = $this->_edit( $input, 'WP-CLI: New Post' ) ) $assoc_args['post_content'] = $output; else $assoc_args['post_content'] = $input; @@ -50,24 +50,23 @@ protected function _update( $params ) { /** * Launch system editor to edit post content * - * @synopsis <id>... + * @synopsis <id> */ - public function edit( $args, $assoc_args ) { + public function edit( $args, $_ ) { $post_id = $args[0]; - if ( !$post_id || !$post = get_post( $post_id ) ) { - \WP_CLI::error( "Failed opening post $post_id to edit.", false ); - return; - } + if ( !$post_id || !$post = get_post( $post_id ) ) + \WP_CLI::error( "Failed opening post $post_id to edit." ); - $r = \WP_CLI\Utils\launch_editor_for_input( $post->post_content, "WP-CLI post $post_id" ); + $r = $this->_edit( $post->post_content, "WP-CLI post $post_id" ); - if ( $r === false ) { - \WP_CLI::error( "Aborting. No change made to post.", false ); - return; - } + if ( $r === false ) + \WP_CLI::warning( 'No change made to post content.', 'Aborted' ); + else + parent::update( $args, array( 'post_content' => $r ) ); + } - $assoc_args['post_content'] = $r; - parent::update( $args, $assoc_args ); + protected function _edit( $content, $title ) { + return \WP_CLI\Utils\launch_editor_for_input( $content, $title ); } /** diff --git a/php/utils.php b/php/utils.php index 2f3f5e6de1..26be917cab 100644 --- a/php/utils.php +++ b/php/utils.php @@ -272,7 +272,7 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { $tmpfile = wp_tempnam( $title ); if ( !$tmpfile ) - die( 'Error creating temporary file.' ); + \WP_CLI::error( 'Error creating temporary file.' ); file_put_contents( $tmpfile, $input ); From 270f75222e4b00c95628cfcaad7a1daf29ea1bbf Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 14 Feb 2013 15:34:22 -0800 Subject: [PATCH 1214/4858] Whitespace cleanup Use spaces for inner-line spacing --- php/utils.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 26be917cab..30d09dc3a2 100644 --- a/php/utils.php +++ b/php/utils.php @@ -263,9 +263,9 @@ function output_csv( $rows, $headers = array() ) { /** * Launch system's $EDITOR to edit text * - * @param str $content Text to edit (eg post content) - * @return str|bool Edited text, if file is saved from editor - * False, if no change to file + * @param str $content Text to edit (eg post content) + * @return str|bool Edited text, if file is saved from editor + * False, if no change to file */ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { From a57f4496a8e83d45d521cdbc6fd98c3fa2024758 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Feb 2013 02:00:54 +0200 Subject: [PATCH 1215/4858] add man page for wp post edit. see #302 --- man-src/post-edit.txt | 9 +++++++++ man/post-create.1 | 2 +- man/post-edit.1 | 27 +++++++++++++++++++++++++++ php/commands/post.php | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 man-src/post-edit.txt create mode 100644 man/post-edit.1 diff --git a/man-src/post-edit.txt b/man-src/post-edit.txt new file mode 100644 index 0000000000..6e3607984e --- /dev/null +++ b/man-src/post-edit.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `<id>`: + + The ID of the post to edit. + +## EXAMPLES + + wp post edit 123 diff --git a/man/post-create.1 b/man/post-create.1 index 7aa1f5025d..88d81eae3f 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -7,7 +7,7 @@ \fBwp\-post\-create\fR \- Create a post\. . .SH "SYNOPSIS" -wp post create \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] +wp post create \-\-\fIfield\fR=\fIvalue\fR [\-\-edit] [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/post-edit.1 b/man/post-edit.1 new file mode 100644 index 0000000000..9ce9629024 --- /dev/null +++ b/man/post-edit.1 @@ -0,0 +1,27 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-EDIT" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-edit\fR \- Launch system editor to edit post content\. +. +.SH "SYNOPSIS" +wp post edit \fIid\fR +. +.SH "OPTIONS" +. +.TP +\fB<id>\fR: +. +.IP +The ID of the post to edit\. +. +.SH "EXAMPLES" +. +.nf + +wp post edit 123 +. +.fi + diff --git a/php/commands/post.php b/php/commands/post.php index bba7dfca3b..625f3306ce 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -48,7 +48,7 @@ protected function _update( $params ) { } /** - * Launch system editor to edit post content + * Launch system editor to edit post content. * * @synopsis <id> */ From c47fafe50b83d555f1cb257b2bc91393b2642d37 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 14 Feb 2013 16:18:59 -0800 Subject: [PATCH 1216/4858] Allow `wp post create` to read from file or STDIN If a filename is passed as the first argument to `wp post create`, that file will be read for the post's content. If the first argument is '-', then post content will be read from STDIN. If an unreadable filename is given, `wp post create` exits with an error. --- php/commands/post.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 625f3306ce..fe7950729f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -12,9 +12,17 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { /** * Create a post. * - * @synopsis --<field>=<value> [--edit] [--porcelain] + * @synopsis [<file>] --<field>=<value> [--porcelain] */ - public function create( $_, $assoc_args ) { + public function create( $args, $assoc_args ) { + if ( ! empty( $args[0] ) ) { + $readfile = ( $args[0] === '-' ) ? 'php://stdin' : $args[0]; + + if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) + \WP_CLI::error( "Unable to read content from $readfile." ); + + $assoc_args['post_content'] = file_get_contents( $readfile ); + } if ( isset( $assoc_args['edit'] ) ) { $input = ( isset( $assoc_args['post_content'] ) ) ? @@ -26,7 +34,6 @@ public function create( $_, $assoc_args ) { $assoc_args['post_content'] = $input; } - parent::create( $assoc_args ); } From 99016736ce9e97d7eed6ae3e69be07d20cb1806e Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 15 Feb 2013 10:29:04 -0800 Subject: [PATCH 1217/4858] Update man page for `wp post create` Still can't get synopsis to render correctly though. After adding optional positional argument to synopsis, all calls generate an 'unknown parameter' warning. --- man-src/post-create.txt | 21 +++++++++++++++++++-- man/post-create.1 | 28 +++++++++++++++++++++++----- php/commands/post.php | 2 +- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/man-src/post-create.txt b/man-src/post-create.txt index 75c4de21f9..0a2bb1e06d 100644 --- a/man-src/post-create.txt +++ b/man-src/post-create.txt @@ -1,14 +1,31 @@ ## OPTIONS +* `<filename>`: + + Read post content from <filename>. If this value is present, the + `--post_content` argument will be ignored. + + Passing `-` as the filename will cause post content to + be read from STDIN. + * `--<field>`=<value>: Field values for the new post. See wp_insert_post(). +* `--edit`: + + Immediately open system's editor to write or edit post content. + + (If content is read from a file, from STDIN, or from the `--post_content` + argument, that text will be loaded into the editor; otherwise, an empty + file will be opened.) + * `--porcelain`: Output just the new post id. ## EXAMPLES - wp post create --post_type=page --post_status=publish --post_title='A new -page' + wp post create --post_type=page --post_status=publish --post_title='A new page' + + wp post create file.txt --post_type=post --post_title='Post from file' diff --git a/man/post-create.1 b/man/post-create.1 index 88d81eae3f..12e7be4085 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -7,17 +7,35 @@ \fBwp\-post\-create\fR \- Create a post\. . .SH "SYNOPSIS" -wp post create \-\-\fIfield\fR=\fIvalue\fR [\-\-edit] [\-\-porcelain] +wp post create [\fIfilename\fR] \-\-\fIfield\fR=\fIvalue\fR [\-\-edit] [\-\-porcelain] . .SH "OPTIONS" . .TP +\fB<filename>\fR: +. +.IP +Read post content from \fIfilename\fR\. If this value is present, the \fB\-\-post_content\fR argument will be ignored\. +. +.IP +Passing \fB\-\fR as the filename will cause post content to be read from STDIN\. +. +.TP \fB\-\-<field>\fR=\fIvalue\fR: . .IP Field values for the new post\. See wp_insert_post()\. . .TP +\fB\-\-edit\fR: +. +.IP +Immediately open system\'s editor to write or edit post content\. +. +.IP +(If content is read from a file, from STDIN, or from the \fB\-\-post_content\fR argument, that text will be loaded into the editor; otherwise, an empty file will be opened\.) +. +.TP \fB\-\-porcelain\fR: . .IP @@ -27,9 +45,9 @@ Output just the new post id\. . .nf -wp post create \-\-post_type=page \-\-post_status=publish \-\-post_title=\'A new +wp post create \-\-post_type=page \-\-post_status=publish \-\-post_title=\'A new page\' + +wp post create file\.txt \-\-post_type=post \-\-post_title=\'Post from file\' . .fi -. -.P -page\' + diff --git a/php/commands/post.php b/php/commands/post.php index fe7950729f..7be856bcb5 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -12,7 +12,7 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { /** * Create a post. * - * @synopsis [<file>] --<field>=<value> [--porcelain] + * @synopsis [<filename>] --<field>=<value> [--edit] [--porcelain] */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { From d11071ab41b8dd72e1579fbe0cf5c9c780b02561 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 14 Feb 2013 17:28:08 -0800 Subject: [PATCH 1218/4858] Add filename completion for `wp post create` command Uses bash default filename completion for `wp post create` --- utils/wp-completion.bash | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) mode change 100644 => 100755 utils/wp-completion.bash diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash old mode 100644 new mode 100755 index 2e7e420258..f3822d3503 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -12,6 +12,10 @@ _wp() { opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2- | tr '\n' ' ') fi - COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + if [[ 'create' = $prev ]]; then + COMPREPLY=( $(compgen -f "$cur") ) + else + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + fi } complete -F _wp wp From 4958e7494a5c8ee5fac465ab2441b233ef0387b9 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 15 Feb 2013 12:59:13 -0800 Subject: [PATCH 1219/4858] Don't check if php://stdin is_file It'll let you down every time. --- php/commands/post.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 7be856bcb5..9073c4ed5a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -16,10 +16,13 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { - $readfile = ( $args[0] === '-' ) ? 'php://stdin' : $args[0]; - if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) - \WP_CLI::error( "Unable to read content from $readfile." ); + if ( $args[0] !== '-' ) { + $readfile = $args[0]; + if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) + \WP_CLI::error( "Unable to read content from $readfile." ); + } else + $readfile = 'php://stdin'; $assoc_args['post_content'] = file_get_contents( $readfile ); } From 4a9c02f0847842d6379b7253523b889d8a9ff2ec Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 16 Feb 2013 22:55:48 +0200 Subject: [PATCH 1220/4858] move db commands to Command_Runner --- tests/abstract-spec.php | 33 +++++---------------------------- tests/command-runner.php | 29 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php index 08a1e27ad2..2183b40838 100644 --- a/tests/abstract-spec.php +++ b/tests/abstract-spec.php @@ -2,29 +2,6 @@ abstract class WP_CLI_Spec extends PHPUnit_Extensions_Story_TestCase { - protected static $db_settings = array( - 'dbname' => 'wp_cli_test', - 'dbuser' => 'wp_cli_test', - 'dbpass' => 'password1' - ); - - private static function run_sql( $sql ) { - $dbuser = self::$db_settings['dbuser']; - $dbpass = self::$db_settings['dbpass']; - - exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); - } - - protected function tearDown() { - $dbname = self::$db_settings['dbname']; - $this->run_sql( "DROP DATABASE IF EXISTS $dbname" ); - } - - private function create_db() { - $dbname = self::$db_settings['dbname']; - $this->run_sql( "CREATE DATABASE $dbname" ); - } - public function runGiven( &$world, $action, $arguments ) { switch ( $action ) { case 'empty dir': { @@ -33,7 +10,7 @@ public function runGiven( &$world, $action, $arguments ) { break; case 'database': { - $this->create_db(); + $world['runner']->create_db(); } break; @@ -43,15 +20,15 @@ public function runGiven( &$world, $action, $arguments ) { break; case 'wp config': { - $world['runner']->create_config( self::$db_settings ); + $world['runner']->create_config(); } break; case 'wp install': { - $this->create_db(); $world['runner'] = new WP_CLI_Command_Runner; + $world['runner']->create_db(); $world['runner']->download_wordpress_files(); - $world['runner']->create_config( self::$db_settings ); + $world['runner']->create_config(); $world['runner']->run_install(); } break; @@ -79,7 +56,7 @@ public function runWhen( &$world, $action, $arguments ) { break; case 'core config': { - $world['result'] = $world['runner']->create_config( self::$db_settings ); + $world['result'] = $world['runner']->create_config(); } break; diff --git a/tests/command-runner.php b/tests/command-runner.php index d35e4d1a63..98d695571d 100644 --- a/tests/command-runner.php +++ b/tests/command-runner.php @@ -2,11 +2,36 @@ class WP_CLI_Command_Runner { + protected static $db_settings = array( + 'dbname' => 'wp_cli_test', + 'dbuser' => 'wp_cli_test', + 'dbpass' => 'password1' + ); + private $install_dir; public function __construct() { $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); mkdir( $this->install_dir ); + + $this->drop_db(); + } + + public function create_db() { + $dbname = self::$db_settings['dbname']; + self::run_sql( "CREATE DATABASE $dbname" ); + } + + public function drop_db() { + $dbname = self::$db_settings['dbname']; + self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); + } + + private static function run_sql( $sql ) { + $dbuser = self::$db_settings['dbuser']; + $dbpass = self::$db_settings['dbpass']; + + exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); } public function run( $command, $cwd = false ) { @@ -34,8 +59,8 @@ public function run( $command, $cwd = false ) { return (object) compact( 'command', 'return_code', 'stdout', 'stderr' ); } - public function create_config( $db_settings ) { - return $this->run( 'core config' . \WP_CLI\Utils\assoc_args_to_str( $db_settings ) ); + public function create_config() { + return $this->run( 'core config' . \WP_CLI\Utils\assoc_args_to_str( self::$db_settings ) ); } public function define_custom_wp_content_dir() { From 0b2923849bcda6ef1a7958da9b135801072c7f35 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 16 Feb 2013 23:23:23 +0200 Subject: [PATCH 1221/4858] dependencies: replace phpunit-story with behat --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dbb99f17bc..2acd3fad1c 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ }, "require-dev": { "phpunit/phpunit": "3.7.x", - "phpunit/phpunit-story": "1.0.x" + "behat/behat": "2.4.*@stable" }, "autoload": { "psr-0": { "WP_CLI": "php" } From 106d894effba7c2d1d3ecc6cf1f68389f636140d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 16 Feb 2013 23:44:56 +0200 Subject: [PATCH 1222/4858] convert PHPUnit Story specs to Behat features --- .../bootstrap/CommandRunner.php | 14 +- features/bootstrap/FeatureContext.php | 144 ++++++++++++++++++ features/core.feature | 84 ++++++++++ features/flags.feature | 24 +++ tests/abstract-spec.php | 106 ------------- tests/bootstrap.php | 3 - tests/spec-core.php | 95 ------------ tests/spec-flags.php | 25 --- 8 files changed, 262 insertions(+), 233 deletions(-) rename tests/command-runner.php => features/bootstrap/CommandRunner.php (91%) create mode 100644 features/bootstrap/FeatureContext.php create mode 100644 features/core.feature create mode 100644 features/flags.feature delete mode 100644 tests/abstract-spec.php delete mode 100644 tests/spec-core.php delete mode 100644 tests/spec-flags.php diff --git a/tests/command-runner.php b/features/bootstrap/CommandRunner.php similarity index 91% rename from tests/command-runner.php rename to features/bootstrap/CommandRunner.php index 98d695571d..15da72f70a 100644 --- a/tests/command-runner.php +++ b/features/bootstrap/CommandRunner.php @@ -11,10 +11,16 @@ class WP_CLI_Command_Runner { private $install_dir; public function __construct() { + $this->drop_db(); + } + + public function create_empty_dir() { $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); mkdir( $this->install_dir ); + } - $this->drop_db(); + public function get_path( $file ) { + return $this->install_dir . '/' . $file; } public function create_db() { @@ -48,15 +54,15 @@ public function run( $command, $cwd = false ) { 2 => array( 'pipe', 'w' ), ), $pipes ); - $stdout = stream_get_contents( $pipes[1] ); + $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); - $stderr = stream_get_contents( $pipes[2] ); + $STDERR = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); $return_code = proc_close( $process ); - return (object) compact( 'command', 'return_code', 'stdout', 'stderr' ); + return (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); } public function create_config() { diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php new file mode 100644 index 0000000000..dda8354d25 --- /dev/null +++ b/features/bootstrap/FeatureContext.php @@ -0,0 +1,144 @@ +<?php + +use Behat\Behat\Context\ClosuredContextInterface, + Behat\Behat\Context\TranslatedContextInterface, + Behat\Behat\Context\BehatContext, + Behat\Behat\Exception\PendingException; +use Behat\Gherkin\Node\PyStringNode, + Behat\Gherkin\Node\TableNode; + +require_once 'PHPUnit/Autoload.php'; +require_once 'PHPUnit/Framework/Assert/Functions.php'; + +require_once __DIR__ . '/../../php/utils.php'; + +/** + * Features context. + */ +class FeatureContext extends BehatContext +{ + /** + * Initializes context. + * Every scenario gets it's own context object. + * + * @param array $parameters context parameters (set them up through behat.yml) + */ + public function __construct(array $parameters) + { + $this->runner = new WP_CLI_Command_Runner; + } + + /** + * @Given /^an empty directory$/ + */ + public function anEmptyDirectory() + { + $this->runner->create_empty_dir(); + } + + /** + * @Given /^WP files$/ + */ + public function wordpressFiles() + { + $this->runner->download_wordpress_files(); + } + + /** + * @Given /^wp-config\.php$/ + */ + public function wpConfigPhp() + { + $this->runner->create_config(); + } + + /** + * @Given /^a database$/ + */ + public function aDatabase() + { + $this->runner->create_db(); + } + + /** + * @Given /^WP install$/ + */ + public function wpInstall() + { + $this->runner->create_db(); + $this->runner->create_empty_dir(); + $this->runner->download_wordpress_files(); + $this->runner->create_config(); + $this->runner->run_install(); + } + + /** + * @Given /^custom wp-content directory$/ + */ + public function customWpContentDirectory() + { + $this->runner->define_custom_wp_content_dir(); + } + + /** + * @When /^I run `(.+)`$/ + */ + public function iRun( $cmd ) + { + $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); + + switch ( $cmd ) + { + case 'core install': + $this->result = $this->runner->run_install(); + break; + + case 'core config': + $this->result = $this->runner->create_config(); + break; + + default: + $this->result = $this->runner->run( $cmd ); + } + } + + /** + * @Then /^the return code should be (\d+)$/ + */ + public function theReturnCodeShouldBe( $return_code ) + { + assertEquals( $return_code, $this->result->return_code ); + } + + /** + * @Then /^(STDOUT|STDERR) should be:$/ + */ + public function outputShouldBe( $stream, PyStringNode $output ) + { + assertEquals( (string) $output, rtrim( $this->result->$stream, "\n" ) ); + } + + /** + * @Then /^(STDOUT|STDERR) should not be empty$/ + */ + public function outputShouldNotBeEmpty( $stream ) + { + assertNotEmpty( rtrim( $this->result->$stream, "\n" ) ); + } + + /** + * @Then /^the (.+) file should exist$/ + */ + public function fileShouldExist( $path ) + { + assertFileExists( $this->runner->get_path( $path ) ); + } + + /** + * @Then /^database exists$/ + */ + public function databaseExists() + { + throw new PendingException(); + } +} diff --git a/features/core.feature b/features/core.feature new file mode 100644 index 0000000000..37b40a0913 --- /dev/null +++ b/features/core.feature @@ -0,0 +1,84 @@ +Feature: core + In order to manage WordPress + As a UNIX user + I need to be able to install it + + Scenario: Empty dir + Given an empty directory + When I run `wp core is-installed` + Then the return code should be 1 + + Scenario: No wp-config.php + Given an empty directory + And WP files + + When I run `wp core is-installed` + Then the return code should be 1 + + When I run `wp core install` + Then STDERR should be: + """ + Error: wp-config.php not found. + Either create one manually or use `wp core config`. + """ + + When I run `wp core config` + Then the return code should be 0 + And the wp-config.php file should exist + + Scenario: Database doesn't exist + Given an empty directory + And WP files + And wp-config.php + + When I run `wp` + Then the return code should be 1 + And STDERR should be: + """ + Error: Can’t select database + """ + + When I run `wp db create` + Then the return code should be 0 + + Scenario: Database tables not installed + Given an empty directory + And WP files + And wp-config.php + And a database + + When I run `wp core is-installed` + Then the return code should be 1 + + When I run `wp` + Then the return code should be 1 + And STDERR should be: + """ + Error: The site you have requested is not installed. + Run `wp core install`. + """ + + When I run `wp core install` + Then the return code should be 0 + + When I run `wp post list --ids` + Then STDOUT should be: + """ + 1 + """ + + Scenario: Full install + Given WP install + + When I run `wp core is-installed` + Then the return code should be 0 + + Scenario: Custom wp-content directory + Given WP install + And custom wp-content directory + + When I run `wp theme status twentytwelve` + Then the return code should be 0 + + When I run `wp plugin status hello` + Then the return code should be 0 diff --git a/features/flags.feature b/features/flags.feature new file mode 100644 index 0000000000..f5643f9ee9 --- /dev/null +++ b/features/flags.feature @@ -0,0 +1,24 @@ +Feature: flags + In order to manage WordPress + As a UNIX user + I need to be able to use various flags + + Scenario: Quiet run + Given WP install + + When I run `wp` + Then the return code should be 0 + And STDOUT should not be empty + + When I run `wp --quiet` + Then the return code should be 0 + And STDOUT should be: + """ + """ + + When I run `wp non-existing-command --quiet` + Then the return code should be 1 + And STDERR should be: + """ + Error: 'non-existing-command' is not a registered wp command. See 'wp help'. + """ diff --git a/tests/abstract-spec.php b/tests/abstract-spec.php deleted file mode 100644 index 2183b40838..0000000000 --- a/tests/abstract-spec.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php - -abstract class WP_CLI_Spec extends PHPUnit_Extensions_Story_TestCase { - - public function runGiven( &$world, $action, $arguments ) { - switch ( $action ) { - case 'empty dir': { - $world['runner'] = new WP_CLI_Command_Runner; - } - break; - - case 'database': { - $world['runner']->create_db(); - } - break; - - case 'wp files': { - $world['runner']->download_wordpress_files(); - } - break; - - case 'wp config': { - $world['runner']->create_config(); - } - break; - - case 'wp install': { - $world['runner'] = new WP_CLI_Command_Runner; - $world['runner']->create_db(); - $world['runner']->download_wordpress_files(); - $world['runner']->create_config(); - $world['runner']->run_install(); - } - break; - - case 'custom wp-content dir': { - $world['runner']->define_custom_wp_content_dir(); - } - break; - - default: { - return $this->notImplemented( $action ); - } - } - } - - public function runWhen( &$world, $action, $arguments ) { - switch ( $action ) { - case 'invoking': { - $cmd = $arguments[0]; - - switch ( $cmd ) { - case 'core install': { - $world['result'] = $world['runner']->run_install(); - } - break; - - case 'core config': { - $world['result'] = $world['runner']->create_config(); - } - break; - - default: { - $world['result'] = $world['runner']->run( $cmd ); - } - } - } - break; - - default: { - return $this->notImplemented( $action ); - } - } - } - - public function runThen( &$world, $action, $arguments ) { - switch ( $action ) { - case 'return code should be': { - $this->assertEquals( $arguments[0], $world['result']->return_code, $action ); - } - break; - - case 'stdout': { - $this->assertEquals( $arguments[0], $world['result']->stdout, $action ); - } - break; - - case 'stderr': { - $this->assertEquals( $arguments[0], $world['result']->stderr, $action ); - } - break; - - case 'should have output': { - if ( empty( $world['result']->stdout ) ) - var_dump($world['result']); - $this->assertNotEmpty( $world['result']->stdout, $action ); - } - break; - - default: { - return $this->notImplemented( $action ); - } - } - } -} - diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c24b94614e..cea88d887f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -3,6 +3,3 @@ require_once getcwd() . '/vendor/autoload.php'; require_once getcwd() . '/php/utils.php'; -require_once __DIR__ . '/abstract-spec.php'; -require_once __DIR__ . '/command-runner.php'; - diff --git a/tests/spec-core.php b/tests/spec-core.php deleted file mode 100644 index d7dab9ed41..0000000000 --- a/tests/spec-core.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php - -class CoreCommandSpec extends WP_CLI_Spec { - - /** @scenario */ - public function emptyDir() { - $this - ->given( 'empty dir' ) - - ->when( 'invoking', 'core is-installed' ) - ->then( 'return code should be', 1 ); - } - - /** @scenario */ - public function noWpConfig() { - $this - ->given( 'empty dir' ) - ->and( 'wp files' ) - - ->when( 'invoking', 'core is-installed' ) - ->then( 'return code should be', 1 ) - - ->when( 'invoking', 'core install' ) - ->then( 'stderr', - "Error: wp-config.php not found.\n" . - "Either create one manually or use `wp core config`.\n" - ) - - ->when( 'invoking', 'core config' ) - ->then( 'return code should be', 0 ); - } - - /** @scenario */ - public function dbDoesntExist() { - $this - ->given( 'empty dir' ) - ->and( 'wp files' ) - ->and( 'wp config' ) - - ->when( 'invoking', '' ) - ->then( 'return code should be', 1 ) - ->and( 'stderr', "Error: Can’t select database\n" ) - ->and( 'stdout', '' ) - - ->when( 'invoking', 'db create' ) - ->then( 'return code should be', 0 ); - } - - /** @scenario */ - public function dbTablesNotInstalled() { - $this - ->given( 'empty dir' ) - ->and( 'wp files' ) - ->and( 'wp config' ) - ->and( 'database' ) - - ->when( 'invoking', 'core is-installed' ) - ->then( 'return code should be', 1 ) - - ->when( 'invoking', '' ) - ->then( 'stderr', - "Error: The site you have requested is not installed.\n" . - "Run `wp core install`.\n" - ) - - ->when( 'invoking', 'core install' ) - ->then( 'return code should be', 0 ) - - ->when( 'invoking', 'post list --ids' ) - ->then( 'stdout', "1" ); - } - - /** @scenario */ - public function fullInstall() { - $this - ->given( 'wp install' ) - - ->when( 'invoking', 'core is-installed' ) - ->then( 'return code should be', 0 ); - } - - /** @scenario */ - public function customWpContentDir() { - $this - ->given( 'wp install' ) - ->and( 'custom wp-content dir' ) - - ->when( 'invoking', 'theme status twentytwelve' ) - ->then( 'return code should be', 0 ) - - ->when( 'invoking', 'plugin status hello' ) - ->then( 'return code should be', 0 ); - } -} - diff --git a/tests/spec-flags.php b/tests/spec-flags.php deleted file mode 100644 index c720fda61c..0000000000 --- a/tests/spec-flags.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -class FlagsSpec extends WP_CLI_Spec { - - /** @scenario */ - public function quietRun() { - $this - ->given( 'wp install' ) - - ->when( 'invoking', '' ) - ->then( 'return code should be', 0 ) - ->and( 'should have output' ) - - ->when( 'invoking', '--quiet' ) - ->then( 'return code should be', 0 ) - ->and( 'stdout', '' ) - - ->when( 'invoking', 'non-existing-command --quiet' ) - ->then( 'return code should be', 1 ) - ->and( 'stderr', - "Error: 'non-existing-command' is not a registered wp command. See 'wp help'.\n" - ); - } -} - From 9f2126c05ddd88441411780322bed0894a746f0d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 00:58:19 +0200 Subject: [PATCH 1223/4858] update readme --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2f9ec0ff27..a607afe72b 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,12 @@ If you want to receive an email for every single commit, you can subscribe to th Running tests ------------- -The tests use PHPUnit, which can be installed using [composer](http://getcomposer.org/). -Once you've got composer installed, run: +There are two types of tests: + +* unit tests, implemented using [PHPUnit](http://phpunit.de/) +* functional tests, implemented using [Behat](http://behat.org) + +All the test dependencies can be installed using [composer](http://getcomposer.org/): composer.phar install --dev @@ -39,11 +43,10 @@ Running the following as root in MySQL should do the trick: GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; -Finally, to run the tests: +Finally, to run the unit tests: vendor/bin/phpunit -Most tests install WordPress from scratch. Since this is pretty slow, you can -use arguments to `phpunit` to only run the test that you're interested in: +And to run the functional tests: - vendor/bin/phpunit --filter test_function_you_want_to_run + vendor/bin/behat From 4c5b7e9d9569fd9f9bb4888c92136c486df23f2e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 01:38:45 +0200 Subject: [PATCH 1224/4858] add function test for wp user create --- features/bootstrap/CommandRunner.php | 15 ++++++++++++ features/bootstrap/FeatureContext.php | 33 ++++++++++++++++----------- features/user.feature | 11 +++++++++ 3 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 features/user.feature diff --git a/features/bootstrap/CommandRunner.php b/features/bootstrap/CommandRunner.php index 15da72f70a..b81d5e54a0 100644 --- a/features/bootstrap/CommandRunner.php +++ b/features/bootstrap/CommandRunner.php @@ -41,6 +41,21 @@ private static function run_sql( $sql ) { } public function run( $command, $cwd = false ) { + switch ( $command ) { + case 'core install': + return $this->run_install(); + break; + + case 'core config': + return $this->create_config(); + break; + + default: + return $this->_run( $command, $cwd ); + } + } + + private function _run( $command, $cwd ) { if ( !$cwd ) $cwd = $this->install_dir; diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index dda8354d25..4a077a2af7 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -87,19 +87,18 @@ public function iRun( $cmd ) { $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); - switch ( $cmd ) - { - case 'core install': - $this->result = $this->runner->run_install(); - break; - - case 'core config': - $this->result = $this->runner->create_config(); - break; - - default: - $this->result = $this->runner->run( $cmd ); - } + $this->result = $this->runner->run( $cmd ); + } + + /** + * @When /^I run the previous command again$/ + */ + public function iRunThePreviousCommandAgain() + { + if ( !isset( $this->result ) ) + throw new \Exception( 'No previous command.' ); + + $this->result = $this->runner->run( $this->result->command ); } /** @@ -118,6 +117,14 @@ public function outputShouldBe( $stream, PyStringNode $output ) assertEquals( (string) $output, rtrim( $this->result->$stream, "\n" ) ); } + /** + * @Then /^(STDOUT|STDERR) should match \'([^\']+)\'$/ + */ + public function outputShouldMatch( $stream, $format ) + { + assertStringMatchesFormat( $format, $this->result->$stream ); + } + /** * @Then /^(STDOUT|STDERR) should not be empty$/ */ diff --git a/features/user.feature b/features/user.feature new file mode 100644 index 0000000000..2523ef5571 --- /dev/null +++ b/features/user.feature @@ -0,0 +1,11 @@ +Feature: Manage WordPress users + + Scenario: Creating/deleting users + Given WP install + + When I run `wp user create testuser testuser@example.com --porcelain` + Then the return code should be 0 + And STDOUT should match '%d' + + When I run the previous command again + Then the return code should be 1 From 683fdf77382d706ae40385b0054219e119325d60 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 01:58:49 +0200 Subject: [PATCH 1225/4858] test deleting the previously created user --- features/bootstrap/FeatureContext.php | 7 +++++++ features/user.feature | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 4a077a2af7..0fde4e5652 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -85,6 +85,13 @@ public function customWpContentDirectory() */ public function iRun( $cmd ) { + if ( false !== strpos( $cmd, '<STDOUT>' ) ) { + if ( !isset( $this->result ) ) + throw new \Exception( 'No previous command.' ); + + $cmd = str_replace( '<STDOUT>', trim( $this->result->STDOUT ), $cmd ); + } + $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); $this->result = $this->runner->run( $cmd ); diff --git a/features/user.feature b/features/user.feature index 2523ef5571..4f2530b0d4 100644 --- a/features/user.feature +++ b/features/user.feature @@ -7,5 +7,6 @@ Feature: Manage WordPress users Then the return code should be 0 And STDOUT should match '%d' - When I run the previous command again - Then the return code should be 1 + When I run `wp user delete <STDOUT>` + Then the return code should be 0 + And STDOUT should not be empty From 5448727c231d81b82258954364f7a9e3e8fa1b06 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 01:59:09 +0200 Subject: [PATCH 1226/4858] use WP_CLI::warning() instead of passing false to WP_CLI::error() --- php/WP_CLI/CommandWithDBObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 8b252663ad..773f81d44d 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -61,7 +61,7 @@ protected function success_or_failure( $r ) { \WP_CLI::success( $msg ); $status = 0; } else { - \WP_CLI::error( $msg, false ); + \WP_CLI::warning( $msg ); $status = 1; } From 5a90ea64a9d89c8eadfb1d8ccdd2c3380ef63e6d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 02:00:07 +0200 Subject: [PATCH 1227/4858] remove boilerplate feature description --- features/core.feature | 5 +---- features/flags.feature | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/features/core.feature b/features/core.feature index 37b40a0913..8f65bd441d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -1,7 +1,4 @@ -Feature: core - In order to manage WordPress - As a UNIX user - I need to be able to install it +Feature: Manage WordPress installation Scenario: Empty dir Given an empty directory diff --git a/features/flags.feature b/features/flags.feature index f5643f9ee9..b3b8484b59 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -1,7 +1,4 @@ -Feature: flags - In order to manage WordPress - As a UNIX user - I need to be able to use various flags +Feature: Global flags Scenario: Quiet run Given WP install From 2f67346e29380023635b342cba7f57ead9068e4a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 02:09:53 +0200 Subject: [PATCH 1228/4858] add test for wp user generate --- features/user.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/features/user.feature b/features/user.feature index 4f2530b0d4..45a3dac1ad 100644 --- a/features/user.feature +++ b/features/user.feature @@ -10,3 +10,24 @@ Feature: Manage WordPress users When I run `wp user delete <STDOUT>` Then the return code should be 0 And STDOUT should not be empty + + Scenario: Generating users + Given WP install + + # Delete all users + When I run `wp user list --ids` + And I run `wp user delete <STDOUT>` + When I run `wp user list --ids` + Then the return code should be 0 + And STDOUT should be: + """ + """ + + When I run `wp user generate --count=10` + Then the return code should be 0 + + When I run `wp user list | wc -l` + Then STDOUT should be: + """ + 11 + """ From 2ac359a8cd7ded1e090ab40199ba006afcdc471b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 02:34:46 +0200 Subject: [PATCH 1229/4858] add ability to save result from previous command --- features/bootstrap/FeatureContext.php | 29 ++++++++++++++++++++------- features/user.feature | 9 +++++++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 0fde4e5652..8f18c417fb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -17,6 +17,8 @@ */ class FeatureContext extends BehatContext { + private $variables = array(); + /** * Initializes context. * Every scenario gets it's own context object. @@ -85,18 +87,23 @@ public function customWpContentDirectory() */ public function iRun( $cmd ) { - if ( false !== strpos( $cmd, '<STDOUT>' ) ) { - if ( !isset( $this->result ) ) - throw new \Exception( 'No previous command.' ); - - $cmd = str_replace( '<STDOUT>', trim( $this->result->STDOUT ), $cmd ); - } - $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); + $cmd = preg_replace_callback( '/\{(\w+)\}/', array( $this, 'replace_var' ), $cmd ); + $this->result = $this->runner->run( $cmd ); } + private function replace_var( $matches ) { + $cmd = $matches[0]; + + foreach ( array_slice( $matches, 1 ) as $key ) { + $cmd = str_replace( '{' . $key . '}', $this->variables[ $key ], $cmd ); + } + + return $cmd; + } + /** * @When /^I run the previous command again$/ */ @@ -108,6 +115,14 @@ public function iRunThePreviousCommandAgain() $this->result = $this->runner->run( $this->result->command ); } + /** + * @Given /^save (STDOUT|STDERR) as \{(\w+)\}$/ + */ + public function saveStreamAsVariable( $stream, $key ) + { + $this->variables[ $key ] = rtrim( $this->result->$stream, "\n" ); + } + /** * @Then /^the return code should be (\d+)$/ */ diff --git a/features/user.feature b/features/user.feature index 45a3dac1ad..62ad8dbe1b 100644 --- a/features/user.feature +++ b/features/user.feature @@ -6,8 +6,12 @@ Feature: Manage WordPress users When I run `wp user create testuser testuser@example.com --porcelain` Then the return code should be 0 And STDOUT should match '%d' + And save STDOUT as {USER_ID} - When I run `wp user delete <STDOUT>` + When I run the previous command again + Then the return code should be 1 + + When I run `wp user delete {USER_ID}` Then the return code should be 0 And STDOUT should not be empty @@ -16,7 +20,8 @@ Feature: Manage WordPress users # Delete all users When I run `wp user list --ids` - And I run `wp user delete <STDOUT>` + And save STDOUT as {USER_IDS} + And I run `wp user delete {USER_IDS}` When I run `wp user list --ids` Then the return code should be 0 And STDOUT should be: From 6317e87b610d49dea64b8240ce2256a8cc325f88 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 03:11:01 +0200 Subject: [PATCH 1230/4858] replace 'return code should be 0' with 'it should run without errors' --- features/bootstrap/FeatureContext.php | 9 +++++++++ features/core.feature | 12 ++++++------ features/flags.feature | 4 ++-- features/user.feature | 9 ++++----- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 8f18c417fb..93f9593d94 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -131,6 +131,15 @@ public function theReturnCodeShouldBe( $return_code ) assertEquals( $return_code, $this->result->return_code ); } + /** + * @Then /^it should run without errors$/ + */ + public function itShouldRunWithoutErrors() + { + assertEquals( 0, $this->result->return_code ); + assertEmpty( $this->result->STDERR ); + } + /** * @Then /^(STDOUT|STDERR) should be:$/ */ diff --git a/features/core.feature b/features/core.feature index 8f65bd441d..02ad41f6e1 100644 --- a/features/core.feature +++ b/features/core.feature @@ -20,7 +20,7 @@ Feature: Manage WordPress installation """ When I run `wp core config` - Then the return code should be 0 + Then it should run without errors And the wp-config.php file should exist Scenario: Database doesn't exist @@ -36,7 +36,7 @@ Feature: Manage WordPress installation """ When I run `wp db create` - Then the return code should be 0 + Then it should run without errors Scenario: Database tables not installed Given an empty directory @@ -56,7 +56,7 @@ Feature: Manage WordPress installation """ When I run `wp core install` - Then the return code should be 0 + Then it should run without errors When I run `wp post list --ids` Then STDOUT should be: @@ -68,14 +68,14 @@ Feature: Manage WordPress installation Given WP install When I run `wp core is-installed` - Then the return code should be 0 + Then it should run without errors Scenario: Custom wp-content directory Given WP install And custom wp-content directory When I run `wp theme status twentytwelve` - Then the return code should be 0 + Then it should run without errors When I run `wp plugin status hello` - Then the return code should be 0 + Then it should run without errors diff --git a/features/flags.feature b/features/flags.feature index b3b8484b59..63362b5d15 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -4,11 +4,11 @@ Feature: Global flags Given WP install When I run `wp` - Then the return code should be 0 + Then it should run without errors And STDOUT should not be empty When I run `wp --quiet` - Then the return code should be 0 + Then it should run without errors And STDOUT should be: """ """ diff --git a/features/user.feature b/features/user.feature index 62ad8dbe1b..73d42122f2 100644 --- a/features/user.feature +++ b/features/user.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress users Given WP install When I run `wp user create testuser testuser@example.com --porcelain` - Then the return code should be 0 + Then it should run without errors And STDOUT should match '%d' And save STDOUT as {USER_ID} @@ -12,8 +12,7 @@ Feature: Manage WordPress users Then the return code should be 1 When I run `wp user delete {USER_ID}` - Then the return code should be 0 - And STDOUT should not be empty + Then it should run without errors Scenario: Generating users Given WP install @@ -23,13 +22,13 @@ Feature: Manage WordPress users And save STDOUT as {USER_IDS} And I run `wp user delete {USER_IDS}` When I run `wp user list --ids` - Then the return code should be 0 + Then it should run without errors And STDOUT should be: """ """ When I run `wp user generate --count=10` - Then the return code should be 0 + Then it should run without errors When I run `wp user list | wc -l` Then STDOUT should be: From 02e91fbd96eda9b8acffacbd6241c7b2e1149296 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 03:49:53 +0200 Subject: [PATCH 1231/4858] make 'should run without errors' failure more descriptive --- features/bootstrap/FeatureContext.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 93f9593d94..daaa5ab3f8 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -136,8 +136,11 @@ public function theReturnCodeShouldBe( $return_code ) */ public function itShouldRunWithoutErrors() { - assertEquals( 0, $this->result->return_code ); - assertEmpty( $this->result->STDERR ); + if ( !empty( $this->result->STDERR ) ) + throw new \Exception( $this->result->STDERR ); + + if ( 0 != $this->result->return_code ) + throw new \Exception( "Return code was $this->result->return_code" ); } /** From 417e1379ba53ee13a0a4380e0ef40c40bda3f7cc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 03:58:18 +0200 Subject: [PATCH 1232/4858] add missing $obj_type property to User_Command --- php/commands/user.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index d3f21b449c..f867204e17 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -7,6 +7,8 @@ */ class User_Command extends \WP_CLI\CommandWithDBObject { + protected $obj_type = 'user'; + /** * List users. * From 07b1dba826e1259a5c7be5327969039c27877f4d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 04:08:24 +0200 Subject: [PATCH 1233/4858] disable unkown assoc warnings when a generic assoc specifier is present in the synopsis --- php/WP_CLI/SynopsisParser.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 7512ce112f..e96d2d05dd 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -69,6 +69,13 @@ private function check_assoc( $assoc_args, $callback ) { } private function check_unknown_assoc( $assoc_args ) { + $generic = $this->query_params( array( + 'type' => 'generic', + ) ); + + if ( count( $generic ) ) + return; + $known_assoc = array(); foreach ( $this->params as $param ) { From b3683376126a24a7bde0e354cf1bdcfba79dbc50 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 04:14:02 +0200 Subject: [PATCH 1234/4858] throw stream output instead of using assertEquals() --- features/bootstrap/FeatureContext.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index daaa5ab3f8..87661bfa3a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -148,7 +148,11 @@ public function itShouldRunWithoutErrors() */ public function outputShouldBe( $stream, PyStringNode $output ) { - assertEquals( (string) $output, rtrim( $this->result->$stream, "\n" ) ); + $result = rtrim( $this->result->$stream, "\n" ); + + if ( (string) $output != $result ) { + throw new \Exception( $this->result->$stream ); + } } /** From ed5860748ca67973779a8a6a879eb16b325f03ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 04:17:58 +0200 Subject: [PATCH 1235/4858] test wp user update --- features/bootstrap/FeatureContext.php | 32 +++++++++++++++++---------- features/user.feature | 9 +++++++- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 87661bfa3a..4d4e85b0af 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -25,11 +25,27 @@ class FeatureContext extends BehatContext * * @param array $parameters context parameters (set them up through behat.yml) */ - public function __construct(array $parameters) + public function __construct( array $parameters ) { $this->runner = new WP_CLI_Command_Runner; } + private function replace_variables( &$str ) + { + $str = preg_replace_callback( '/\{(\w+)\}/', array( $this, '_replace_var' ), $str ); + } + + private function _replace_var( $matches ) + { + $cmd = $matches[0]; + + foreach ( array_slice( $matches, 1 ) as $key ) { + $cmd = str_replace( '{' . $key . '}', $this->variables[ $key ], $cmd ); + } + + return $cmd; + } + /** * @Given /^an empty directory$/ */ @@ -89,21 +105,11 @@ public function iRun( $cmd ) { $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); - $cmd = preg_replace_callback( '/\{(\w+)\}/', array( $this, 'replace_var' ), $cmd ); + $this->replace_variables( $cmd ); $this->result = $this->runner->run( $cmd ); } - private function replace_var( $matches ) { - $cmd = $matches[0]; - - foreach ( array_slice( $matches, 1 ) as $key ) { - $cmd = str_replace( '{' . $key . '}', $this->variables[ $key ], $cmd ); - } - - return $cmd; - } - /** * @When /^I run the previous command again$/ */ @@ -148,6 +154,8 @@ public function itShouldRunWithoutErrors() */ public function outputShouldBe( $stream, PyStringNode $output ) { + $this->replace_variables( $output ); + $result = rtrim( $this->result->$stream, "\n" ); if ( (string) $output != $result ) { diff --git a/features/user.feature b/features/user.feature index 73d42122f2..ec16aa4309 100644 --- a/features/user.feature +++ b/features/user.feature @@ -1,6 +1,6 @@ Feature: Manage WordPress users - Scenario: Creating/deleting users + Scenario: Creating/updating/deleting users Given WP install When I run `wp user create testuser testuser@example.com --porcelain` @@ -11,6 +11,13 @@ Feature: Manage WordPress users When I run the previous command again Then the return code should be 1 + When I run `wp user update {USER_ID} --displayname=Foo` + Then it should run without errors + And STDOUT should be: + """ + Success: Updated user {USER_ID}. + """ + When I run `wp user delete {USER_ID}` Then it should run without errors From 846bb295eb67cbe5514c8f1353db9ed24f98bf40 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 04:46:18 +0200 Subject: [PATCH 1236/4858] add 'should be empty' step definition --- features/bootstrap/FeatureContext.php | 10 ++++++++++ features/flags.feature | 4 +--- features/user.feature | 4 +--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 4d4e85b0af..7eefe89b03 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -171,6 +171,16 @@ public function outputShouldMatch( $stream, $format ) assertStringMatchesFormat( $format, $this->result->$stream ); } + /** + * @Then /^(STDOUT|STDERR) should be empty$/ + */ + public function outputShouldBeEmpty( $stream ) + { + if ( !empty( $this->result->$stream ) ) { + throw new \Exception( $this->result->$stream ); + } + } + /** * @Then /^(STDOUT|STDERR) should not be empty$/ */ diff --git a/features/flags.feature b/features/flags.feature index 63362b5d15..684b370fb2 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -9,9 +9,7 @@ Feature: Global flags When I run `wp --quiet` Then it should run without errors - And STDOUT should be: - """ - """ + And STDOUT should be empty When I run `wp non-existing-command --quiet` Then the return code should be 1 diff --git a/features/user.feature b/features/user.feature index ec16aa4309..0c68fd9cbd 100644 --- a/features/user.feature +++ b/features/user.feature @@ -30,9 +30,7 @@ Feature: Manage WordPress users And I run `wp user delete {USER_IDS}` When I run `wp user list --ids` Then it should run without errors - And STDOUT should be: - """ - """ + And STDOUT should be empty When I run `wp user generate --count=10` Then it should run without errors From a077fee11c22ec893d05734e39ec6c9113d37683 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 04:59:50 +0200 Subject: [PATCH 1237/4858] add test for --debug flag --- features/bootstrap/FeatureContext.php | 10 ++++++++++ features/flags.feature | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 7eefe89b03..31bff785d5 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -163,6 +163,16 @@ public function outputShouldBe( $stream, PyStringNode $output ) } } + /** + * @Then /^(STDOUT|STDERR) should contain:$/ + */ + public function outputShouldContain( $stream, PyStringNode $output ) + { + if ( false === strpos( $this->result->$stream, (string) $output ) ) { + throw new \Exception( $this->result->$stream ); + } + } + /** * @Then /^(STDOUT|STDERR) should match \'([^\']+)\'$/ */ diff --git a/features/flags.feature b/features/flags.feature index 684b370fb2..82ec10aeef 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -17,3 +17,20 @@ Feature: Global flags """ Error: 'non-existing-command' is not a registered wp command. See 'wp help'. """ + + Scenario: Debug run + Given WP install + + When I run `wp eval 'echo CONST_WITHOUT_QUOTES;'` + Then it should run without errors + And STDOUT should be: + """ + CONST_WITHOUT_QUOTES + """ + + When I run `wp --debug eval 'echo CONST_WITHOUT_QUOTES;'` + Then the return code should be 0 + And STDOUT should contain: + """ + Notice: Use of undefined constant CONST_WITHOUT_QUOTES + """ From 5e555d3185d3b34b2053e3955ce2a189e39289a3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 05:11:02 +0200 Subject: [PATCH 1238/4858] add tests for creating/updating/deleting a post --- features/post.feature | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 features/post.feature diff --git a/features/post.feature b/features/post.feature new file mode 100644 index 0000000000..2ecfe9b8d0 --- /dev/null +++ b/features/post.feature @@ -0,0 +1,29 @@ +Feature: Manage WordPress posts + + Scenario: Creating/updating/deleting posts + Given WP install + + When I run `wp post create --post_title='Test post' --porcelain` + Then it should run without errors + And STDOUT should match '%d' + And save STDOUT as {POST_ID} + + When I run `wp post update {POST_ID} --post_title='Updated post'` + Then it should run without errors + And STDOUT should be: + """ + Success: Updated post {POST_ID}. + """ + + When I run `wp post delete {POST_ID}` + Then it should run without errors + And STDOUT should be: + """ + Success: Trashed post {POST_ID}. + """ + + When I run the previous command again + Then it should run without errors + + When I run the previous command again + Then the return code should be 1 From 056c226073868a6f85baf4bacbb743762c2d73e0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 05:59:26 +0200 Subject: [PATCH 1239/4858] define steps using closures --- features/bootstrap/FeatureContext.php | 191 ++------------------------ features/steps/basic_steps.php | 99 +++++++++++++ 2 files changed, 114 insertions(+), 176 deletions(-) create mode 100644 features/steps/basic_steps.php diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 31bff785d5..7b9be635d1 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -2,10 +2,7 @@ use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\TranslatedContextInterface, - Behat\Behat\Context\BehatContext, - Behat\Behat\Exception\PendingException; -use Behat\Gherkin\Node\PyStringNode, - Behat\Gherkin\Node\TableNode; + Behat\Behat\Context\BehatContext; require_once 'PHPUnit/Autoload.php'; require_once 'PHPUnit/Framework/Assert/Functions.php'; @@ -15,9 +12,9 @@ /** * Features context. */ -class FeatureContext extends BehatContext +class FeatureContext extends BehatContext implements ClosuredContextInterface { - private $variables = array(); + public $variables = array(); /** * Initializes context. @@ -30,188 +27,30 @@ public function __construct( array $parameters ) $this->runner = new WP_CLI_Command_Runner; } - private function replace_variables( &$str ) + public function getStepDefinitionResources() { - $str = preg_replace_callback( '/\{(\w+)\}/', array( $this, '_replace_var' ), $str ); - } - - private function _replace_var( $matches ) - { - $cmd = $matches[0]; - - foreach ( array_slice( $matches, 1 ) as $key ) { - $cmd = str_replace( '{' . $key . '}', $this->variables[ $key ], $cmd ); - } - - return $cmd; - } - - /** - * @Given /^an empty directory$/ - */ - public function anEmptyDirectory() - { - $this->runner->create_empty_dir(); - } - - /** - * @Given /^WP files$/ - */ - public function wordpressFiles() - { - $this->runner->download_wordpress_files(); - } - - /** - * @Given /^wp-config\.php$/ - */ - public function wpConfigPhp() - { - $this->runner->create_config(); - } - - /** - * @Given /^a database$/ - */ - public function aDatabase() - { - $this->runner->create_db(); - } - - /** - * @Given /^WP install$/ - */ - public function wpInstall() - { - $this->runner->create_db(); - $this->runner->create_empty_dir(); - $this->runner->download_wordpress_files(); - $this->runner->create_config(); - $this->runner->run_install(); - } - - /** - * @Given /^custom wp-content directory$/ - */ - public function customWpContentDirectory() - { - $this->runner->define_custom_wp_content_dir(); - } - - /** - * @When /^I run `(.+)`$/ - */ - public function iRun( $cmd ) - { - $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); - - $this->replace_variables( $cmd ); - - $this->result = $this->runner->run( $cmd ); - } - - /** - * @When /^I run the previous command again$/ - */ - public function iRunThePreviousCommandAgain() - { - if ( !isset( $this->result ) ) - throw new \Exception( 'No previous command.' ); - - $this->result = $this->runner->run( $this->result->command ); - } - - /** - * @Given /^save (STDOUT|STDERR) as \{(\w+)\}$/ - */ - public function saveStreamAsVariable( $stream, $key ) - { - $this->variables[ $key ] = rtrim( $this->result->$stream, "\n" ); + return array( __DIR__ . '/../steps/basic_steps.php' ); } - /** - * @Then /^the return code should be (\d+)$/ - */ - public function theReturnCodeShouldBe( $return_code ) + public function getHookDefinitionResources() { - assertEquals( $return_code, $this->result->return_code ); + return array(); } - /** - * @Then /^it should run without errors$/ - */ - public function itShouldRunWithoutErrors() + public function replace_variables( &$str ) { - if ( !empty( $this->result->STDERR ) ) - throw new \Exception( $this->result->STDERR ); - - if ( 0 != $this->result->return_code ) - throw new \Exception( "Return code was $this->result->return_code" ); - } - - /** - * @Then /^(STDOUT|STDERR) should be:$/ - */ - public function outputShouldBe( $stream, PyStringNode $output ) - { - $this->replace_variables( $output ); - - $result = rtrim( $this->result->$stream, "\n" ); - - if ( (string) $output != $result ) { - throw new \Exception( $this->result->$stream ); - } - } - - /** - * @Then /^(STDOUT|STDERR) should contain:$/ - */ - public function outputShouldContain( $stream, PyStringNode $output ) - { - if ( false === strpos( $this->result->$stream, (string) $output ) ) { - throw new \Exception( $this->result->$stream ); - } + $str = preg_replace_callback( '/\{(\w+)\}/', array( $this, '_replace_var' ), $str ); } - /** - * @Then /^(STDOUT|STDERR) should match \'([^\']+)\'$/ - */ - public function outputShouldMatch( $stream, $format ) + private function _replace_var( $matches ) { - assertStringMatchesFormat( $format, $this->result->$stream ); - } + $cmd = $matches[0]; - /** - * @Then /^(STDOUT|STDERR) should be empty$/ - */ - public function outputShouldBeEmpty( $stream ) - { - if ( !empty( $this->result->$stream ) ) { - throw new \Exception( $this->result->$stream ); + foreach ( array_slice( $matches, 1 ) as $key ) { + $cmd = str_replace( '{' . $key . '}', $this->variables[ $key ], $cmd ); } - } - - /** - * @Then /^(STDOUT|STDERR) should not be empty$/ - */ - public function outputShouldNotBeEmpty( $stream ) - { - assertNotEmpty( rtrim( $this->result->$stream, "\n" ) ); - } - /** - * @Then /^the (.+) file should exist$/ - */ - public function fileShouldExist( $path ) - { - assertFileExists( $this->runner->get_path( $path ) ); - } - - /** - * @Then /^database exists$/ - */ - public function databaseExists() - { - throw new PendingException(); + return $cmd; } } + diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php new file mode 100644 index 0000000000..cd1651ef02 --- /dev/null +++ b/features/steps/basic_steps.php @@ -0,0 +1,99 @@ +<?php + +use Behat\Behat\Exception\PendingException, + Behat\Gherkin\Node\PyStringNode, + Behat\Gherkin\Node\TableNode; + +$steps->Given( '/^an empty directory$/', function( $world ) { + $world->runner->create_empty_dir(); +} ); + +$steps->Given( '/^WP files$/', function ( $world ) { + $world->runner->download_wordpress_files(); +} ); + +$steps->Given( '/^wp-config\.php$/', function ( $world ) { + $world->runner->create_config(); +} ); + +$steps->Given( '/^a database$/', function( $world ) { + $world->runner->create_db(); +} ); + +$steps->Given( '/^WP install$/', function( $world ) { + $world->runner->create_db(); + $world->runner->create_empty_dir(); + $world->runner->download_wordpress_files(); + $world->runner->create_config(); + $world->runner->run_install(); +} ); + +$steps->Given( '/^custom wp-content directory$/', function( $world ) { + $world->runner->define_custom_wp_content_dir(); +} ); + +$steps->When( '/^I run `(.+)`$/', function( $world, $cmd ) { + $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); + + $world->replace_variables( $cmd ); + + $world->result = $world->runner->run( $cmd ); +} ); + +$steps->When( '/^I run the previous command again$/', function( $world ) { + if ( !isset( $world->result ) ) + throw new \Exception( 'No previous command.' ); + + $world->result = $world->runner->run( $world->result->command ); +} ); + +$steps->Given( '/^save (STDOUT|STDERR) as \{(\w+)\}$/', function( $world, $stream, $key ) { + $world->variables[ $key ] = rtrim( $world->result->$stream, "\n" ); +} ); + +$steps->Then( '/^the return code should be (\d+)$/', function( $world, $return_code ) { + assertEquals( $return_code, $world->result->return_code ); +} ); + +$steps->Then( '/^it should run without errors$/', function( $world ) { + if ( !empty( $world->result->STDERR ) ) + throw new \Exception( $world->result->STDERR ); + + if ( 0 != $world->result->return_code ) + throw new \Exception( "Return code was $world->result->return_code" ); +} ); + +$steps->Then( '/^(STDOUT|STDERR) should be:$/', function( $world, $stream, PyStringNode $output ) { + $world->replace_variables( $output ); + + $result = rtrim( $world->result->$stream, "\n" ); + + if ( (string) $output != $result ) { + throw new \Exception( $world->result->$stream ); + } +} ); + +$steps->Then( '/^(STDOUT|STDERR) should contain:$/', +function( $world, $stream, PyStringNode $output ) { + if ( false === strpos( $world->result->$stream, (string) $output ) ) { + throw new \Exception( $world->result->$stream ); + } +} ); + +$steps->Then( '/^(STDOUT|STDERR) should match \'([^\']+)\'$/', function( $world, $stream, $format ) { + assertStringMatchesFormat( $format, $world->result->$stream ); +} ); + +$steps->Then( '/^(STDOUT|STDERR) should be empty$/', function( $world, $stream ) { + if ( !empty( $world->result->$stream ) ) { + throw new \Exception( $world->result->$stream ); + } +} ); + +$steps->Then( '/^(STDOUT|STDERR) should not be empty$/', function( $world, $stream ) { + assertNotEmpty( rtrim( $world->result->$stream, "\n" ) ); +} ); + +$steps->Then( '/^the (.+) file should exist$/', function( $world, $path ) { + assertFileExists( $world->runner->get_path( $path ) ); +} ); From b007bd8c7b6d49f559d176c399ff64bbcdeb7681 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 06:07:45 +0200 Subject: [PATCH 1240/4858] merge WP_CLI_Command_Runner into FeatureContext --- features/bootstrap/CommandRunner.php | 140 -------------------------- features/bootstrap/FeatureContext.php | 134 +++++++++++++++++++++++- features/steps/basic_steps.php | 26 ++--- 3 files changed, 146 insertions(+), 154 deletions(-) delete mode 100644 features/bootstrap/CommandRunner.php diff --git a/features/bootstrap/CommandRunner.php b/features/bootstrap/CommandRunner.php deleted file mode 100644 index b81d5e54a0..0000000000 --- a/features/bootstrap/CommandRunner.php +++ /dev/null @@ -1,140 +0,0 @@ -<?php - -class WP_CLI_Command_Runner { - - protected static $db_settings = array( - 'dbname' => 'wp_cli_test', - 'dbuser' => 'wp_cli_test', - 'dbpass' => 'password1' - ); - - private $install_dir; - - public function __construct() { - $this->drop_db(); - } - - public function create_empty_dir() { - $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $this->install_dir ); - } - - public function get_path( $file ) { - return $this->install_dir . '/' . $file; - } - - public function create_db() { - $dbname = self::$db_settings['dbname']; - self::run_sql( "CREATE DATABASE $dbname" ); - } - - public function drop_db() { - $dbname = self::$db_settings['dbname']; - self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); - } - - private static function run_sql( $sql ) { - $dbuser = self::$db_settings['dbuser']; - $dbpass = self::$db_settings['dbpass']; - - exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); - } - - public function run( $command, $cwd = false ) { - switch ( $command ) { - case 'core install': - return $this->run_install(); - break; - - case 'core config': - return $this->create_config(); - break; - - default: - return $this->_run( $command, $cwd ); - } - } - - private function _run( $command, $cwd ) { - if ( !$cwd ) - $cwd = $this->install_dir; - - $wp_cli_path = getcwd() . "/bin/wp"; - - $sh_command = "cd $cwd; $wp_cli_path $command"; - - $process = proc_open( $sh_command, array( - 0 => STDIN, - 1 => array( 'pipe', 'w' ), - 2 => array( 'pipe', 'w' ), - ), $pipes ); - - $STDOUT = stream_get_contents( $pipes[1] ); - fclose( $pipes[1] ); - - $STDERR = stream_get_contents( $pipes[2] ); - fclose( $pipes[2] ); - - $return_code = proc_close( $process ); - - return (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); - } - - public function create_config() { - return $this->run( 'core config' . \WP_CLI\Utils\assoc_args_to_str( self::$db_settings ) ); - } - - public function define_custom_wp_content_dir() { - $wp_config_path = $this->install_dir . '/wp-config.php'; - - $wp_config_code = file_get_contents( $wp_config_path ); - - $this->add_line_to_wp_config( $wp_config_code, - "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); - - $this->move_files( 'wp-content', 'my-content' ); - - $this->add_line_to_wp_config( $wp_config_code, - "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); - - $this->move_files( 'my-content/plugins', 'my-plugins' ); - - file_put_contents( $wp_config_path, $wp_config_code ); - } - - private function move_files( $src, $dest ) { - rename( - $this->install_dir . '/' . $src, - $this->install_dir . '/' . $dest - ); - } - - private function add_line_to_wp_config( &$wp_config_code, $line ) { - $token = "/* That's all, stop editing!"; - - $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); - } - - public function run_install() { - $cmd = 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( - 'url' => 'http://example.com', - 'title' => 'WP CLI Tests', - 'admin_email' => 'admin@example.com', - 'admin_password' => 'password1' - ) ); - - return $this->run( $cmd ); - } - - public function download_wordpress_files() { - // We cache the results of "wp core download" to improve test performance - // Ideally, we'd cache at the HTTP layer for more reliable tests - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - if ( !file_exists( $cache_dir ) ) { - mkdir( $cache_dir ); - $this->run( "core download", $cache_dir ); - } - - exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); - } -} diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 7b9be635d1..9250c312f9 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -14,6 +14,14 @@ */ class FeatureContext extends BehatContext implements ClosuredContextInterface { + protected static $db_settings = array( + 'dbname' => 'wp_cli_test', + 'dbuser' => 'wp_cli_test', + 'dbpass' => 'password1' + ); + + private $install_dir; + public $variables = array(); /** @@ -24,7 +32,7 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface */ public function __construct( array $parameters ) { - $this->runner = new WP_CLI_Command_Runner; + $this->drop_db(); } public function getStepDefinitionResources() @@ -52,5 +60,129 @@ private function _replace_var( $matches ) return $cmd; } + + public function create_empty_dir() { + $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $this->install_dir ); + } + + public function get_path( $file ) { + return $this->install_dir . '/' . $file; + } + + private static function run_sql( $sql ) { + $dbuser = self::$db_settings['dbuser']; + $dbpass = self::$db_settings['dbpass']; + + exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); + } + + public function create_db() { + $dbname = self::$db_settings['dbname']; + self::run_sql( "CREATE DATABASE $dbname" ); + } + + public function drop_db() { + $dbname = self::$db_settings['dbname']; + self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); + } + + private function _run( $command, $cwd ) { + if ( !$cwd ) + $cwd = $this->install_dir; + + $wp_cli_path = getcwd() . "/bin/wp"; + + $sh_command = "cd $cwd; $wp_cli_path $command"; + + $process = proc_open( $sh_command, array( + 0 => STDIN, + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ), $pipes ); + + $STDOUT = stream_get_contents( $pipes[1] ); + fclose( $pipes[1] ); + + $STDERR = stream_get_contents( $pipes[2] ); + fclose( $pipes[2] ); + + $return_code = proc_close( $process ); + + return (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); + } + + public function run( $command, $cwd = false ) { + switch ( $command ) { + case 'core install': + return $this->run_install(); + break; + + case 'core config': + return $this->create_config(); + break; + + default: + return $this->_run( $command, $cwd ); + } + } + + public function create_config() { + return $this->run( 'core config' . \WP_CLI\Utils\assoc_args_to_str( self::$db_settings ) ); + } + + public function define_custom_wp_content_dir() { + $wp_config_path = $this->install_dir . '/wp-config.php'; + + $wp_config_code = file_get_contents( $wp_config_path ); + + $this->add_line_to_wp_config( $wp_config_code, + "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); + + $this->move_files( 'wp-content', 'my-content' ); + + $this->add_line_to_wp_config( $wp_config_code, + "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); + + $this->move_files( 'my-content/plugins', 'my-plugins' ); + + file_put_contents( $wp_config_path, $wp_config_code ); + } + + private function move_files( $src, $dest ) { + rename( + $this->install_dir . '/' . $src, + $this->install_dir . '/' . $dest + ); + } + + private function add_line_to_wp_config( &$wp_config_code, $line ) { + $token = "/* That's all, stop editing!"; + + $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); + } + + public function run_install() { + $cmd = 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( + 'url' => 'http://example.com', + 'title' => 'WP CLI Tests', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1' + ) ); + + return $this->run( $cmd ); + } + + public function download_wordpress_files() { + // We cache the results of "wp core download" to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + if ( !file_exists( $cache_dir ) ) { + mkdir( $cache_dir ); + $this->run( "core download", $cache_dir ); + } + + exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); + } } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index cd1651ef02..97cb6cd75b 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -5,31 +5,31 @@ Behat\Gherkin\Node\TableNode; $steps->Given( '/^an empty directory$/', function( $world ) { - $world->runner->create_empty_dir(); + $world->create_empty_dir(); } ); $steps->Given( '/^WP files$/', function ( $world ) { - $world->runner->download_wordpress_files(); + $world->download_wordpress_files(); } ); $steps->Given( '/^wp-config\.php$/', function ( $world ) { - $world->runner->create_config(); + $world->create_config(); } ); $steps->Given( '/^a database$/', function( $world ) { - $world->runner->create_db(); + $world->create_db(); } ); $steps->Given( '/^WP install$/', function( $world ) { - $world->runner->create_db(); - $world->runner->create_empty_dir(); - $world->runner->download_wordpress_files(); - $world->runner->create_config(); - $world->runner->run_install(); + $world->create_db(); + $world->create_empty_dir(); + $world->download_wordpress_files(); + $world->create_config(); + $world->run_install(); } ); $steps->Given( '/^custom wp-content directory$/', function( $world ) { - $world->runner->define_custom_wp_content_dir(); + $world->define_custom_wp_content_dir(); } ); $steps->When( '/^I run `(.+)`$/', function( $world, $cmd ) { @@ -37,14 +37,14 @@ $world->replace_variables( $cmd ); - $world->result = $world->runner->run( $cmd ); + $world->result = $world->run( $cmd ); } ); $steps->When( '/^I run the previous command again$/', function( $world ) { if ( !isset( $world->result ) ) throw new \Exception( 'No previous command.' ); - $world->result = $world->runner->run( $world->result->command ); + $world->result = $world->run( $world->result->command ); } ); $steps->Given( '/^save (STDOUT|STDERR) as \{(\w+)\}$/', function( $world, $stream, $key ) { @@ -95,5 +95,5 @@ function( $world, $stream, PyStringNode $output ) { } ); $steps->Then( '/^the (.+) file should exist$/', function( $world, $path ) { - assertFileExists( $world->runner->get_path( $path ) ); + assertFileExists( $world->get_path( $path ) ); } ); From d4913f26ed46ef4889879a08bb5ed4f4e11e30ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 06:25:46 +0200 Subject: [PATCH 1241/4858] improve indentation for step definitions --- features/steps/basic_steps.php | 169 ++++++++++++++++++++------------- 1 file changed, 101 insertions(+), 68 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 97cb6cd75b..436667ddf8 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -4,96 +4,129 @@ Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; -$steps->Given( '/^an empty directory$/', function( $world ) { - $world->create_empty_dir(); -} ); - -$steps->Given( '/^WP files$/', function ( $world ) { - $world->download_wordpress_files(); -} ); +$steps->Given( '/^an empty directory$/', + function ( $world ) { + $world->create_empty_dir(); + } +); -$steps->Given( '/^wp-config\.php$/', function ( $world ) { - $world->create_config(); -} ); +$steps->Given( '/^WP files$/', + function ( $world ) { + $world->download_wordpress_files(); + } +); -$steps->Given( '/^a database$/', function( $world ) { - $world->create_db(); -} ); +$steps->Given( '/^wp-config\.php$/', + function ( $world ) { + $world->create_config(); + } +); -$steps->Given( '/^WP install$/', function( $world ) { - $world->create_db(); - $world->create_empty_dir(); - $world->download_wordpress_files(); - $world->create_config(); - $world->run_install(); -} ); +$steps->Given( '/^a database$/', + function ( $world ) { + $world->create_db(); + } +); + +$steps->Given( '/^WP install$/', + function ( $world ) { + $world->create_db(); + $world->create_empty_dir(); + $world->download_wordpress_files(); + $world->create_config(); + $world->run_install(); + } +); -$steps->Given( '/^custom wp-content directory$/', function( $world ) { - $world->define_custom_wp_content_dir(); -} ); +$steps->Given( '/^custom wp-content directory$/', + function ( $world ) { + $world->define_custom_wp_content_dir(); + } +); -$steps->When( '/^I run `(.+)`$/', function( $world, $cmd ) { - $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); +$steps->When( '/^I run `(.+)`$/', + function ( $world, $cmd ) { + $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); - $world->replace_variables( $cmd ); + $world->replace_variables( $cmd ); - $world->result = $world->run( $cmd ); -} ); + $world->result = $world->run( $cmd ); + } +); -$steps->When( '/^I run the previous command again$/', function( $world ) { - if ( !isset( $world->result ) ) - throw new \Exception( 'No previous command.' ); +$steps->When( '/^I run the previous command again$/', + function ( $world ) { + if ( !isset( $world->result ) ) + throw new \Exception( 'No previous command.' ); - $world->result = $world->run( $world->result->command ); -} ); + $world->result = $world->run( $world->result->command ); + } +); -$steps->Given( '/^save (STDOUT|STDERR) as \{(\w+)\}$/', function( $world, $stream, $key ) { - $world->variables[ $key ] = rtrim( $world->result->$stream, "\n" ); -} ); +$steps->Given( '/^save (STDOUT|STDERR) as \{(\w+)\}$/', + function ( $world, $stream, $key ) { + $world->variables[ $key ] = rtrim( $world->result->$stream, "\n" ); + } +); -$steps->Then( '/^the return code should be (\d+)$/', function( $world, $return_code ) { - assertEquals( $return_code, $world->result->return_code ); -} ); +$steps->Then( '/^the return code should be (\d+)$/', + function ( $world, $return_code ) { + assertEquals( $return_code, $world->result->return_code ); + } +); -$steps->Then( '/^it should run without errors$/', function( $world ) { - if ( !empty( $world->result->STDERR ) ) - throw new \Exception( $world->result->STDERR ); +$steps->Then( '/^it should run without errors$/', + function ( $world ) { + if ( !empty( $world->result->STDERR ) ) + throw new \Exception( $world->result->STDERR ); - if ( 0 != $world->result->return_code ) - throw new \Exception( "Return code was $world->result->return_code" ); -} ); + if ( 0 != $world->result->return_code ) + throw new \Exception( "Return code was $world->result->return_code" ); + } +); -$steps->Then( '/^(STDOUT|STDERR) should be:$/', function( $world, $stream, PyStringNode $output ) { - $world->replace_variables( $output ); +$steps->Then( '/^(STDOUT|STDERR) should be:$/', + function ( $world, $stream, PyStringNode $output ) { + $world->replace_variables( $output ); - $result = rtrim( $world->result->$stream, "\n" ); + $result = rtrim( $world->result->$stream, "\n" ); - if ( (string) $output != $result ) { - throw new \Exception( $world->result->$stream ); + if ( (string) $output != $result ) { + throw new \Exception( $world->result->$stream ); + } } -} ); +); $steps->Then( '/^(STDOUT|STDERR) should contain:$/', -function( $world, $stream, PyStringNode $output ) { - if ( false === strpos( $world->result->$stream, (string) $output ) ) { - throw new \Exception( $world->result->$stream ); + function ( $world, $stream, PyStringNode $output ) { + if ( false === strpos( $world->result->$stream, (string) $output ) ) { + throw new \Exception( $world->result->$stream ); + } } -} ); +); -$steps->Then( '/^(STDOUT|STDERR) should match \'([^\']+)\'$/', function( $world, $stream, $format ) { - assertStringMatchesFormat( $format, $world->result->$stream ); -} ); +$steps->Then( '/^(STDOUT|STDERR) should match \'([^\']+)\'$/', + function ( $world, $stream, $format ) { + assertStringMatchesFormat( $format, $world->result->$stream ); + } +); -$steps->Then( '/^(STDOUT|STDERR) should be empty$/', function( $world, $stream ) { - if ( !empty( $world->result->$stream ) ) { - throw new \Exception( $world->result->$stream ); +$steps->Then( '/^(STDOUT|STDERR) should be empty$/', + function ( $world, $stream ) { + if ( !empty( $world->result->$stream ) ) { + throw new \Exception( $world->result->$stream ); + } } -} ); +); -$steps->Then( '/^(STDOUT|STDERR) should not be empty$/', function( $world, $stream ) { - assertNotEmpty( rtrim( $world->result->$stream, "\n" ) ); -} ); +$steps->Then( '/^(STDOUT|STDERR) should not be empty$/', + function ( $world, $stream ) { + assertNotEmpty( rtrim( $world->result->$stream, "\n" ) ); + } +); -$steps->Then( '/^the (.+) file should exist$/', function( $world, $path ) { - assertFileExists( $world->get_path( $path ) ); -} ); +$steps->Then( '/^the (.+) file should exist$/', + function ( $world, $path ) { + assertFileExists( $world->get_path( $path ) ); + } +); From c87c69638e4c0d46eee48b48a9d5a6a7ae41036c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 06:36:44 +0200 Subject: [PATCH 1242/4858] add test for --user global parameter --- features/flags.feature | 24 ++++++++++++++++++++++++ features/steps/basic_steps.php | 4 +++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/features/flags.feature b/features/flags.feature index 82ec10aeef..47c9d00148 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -34,3 +34,27 @@ Feature: Global flags """ Notice: Use of undefined constant CONST_WITHOUT_QUOTES """ + + Scenario: Setting the WP user + Given WP install + + When I run `wp eval 'echo (int) is_user_logged_in();'` + Then it should run without errors + And STDOUT should be: + """ + 0 + """ + + When I run `wp --user=admin eval 'echo wp_get_current_user()->user_login;'` + Then it should run without errors + And STDOUT should be: + """ + admin + """ + + When I run `wp --user=non-existing-user` + Then the return code should be 1 + And STDERR should be: + """ + Error: Could not get a user_id for this user: 'non-existing-user' + """ diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 436667ddf8..9e19360ab2 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -46,7 +46,9 @@ function ( $world ) { $steps->When( '/^I run `(.+)`$/', function ( $world, $cmd ) { - $cmd = ltrim( str_replace( 'wp', '', $cmd ) ); + if ( 0 === strpos( $cmd, 'wp' ) ) { + $cmd = ltrim( substr( $cmd, 2 ) ); + } $world->replace_variables( $cmd ); From 3bdc1cb43ddebd3bf890dc6dd8e11dd711e6354e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 07:37:23 +0200 Subject: [PATCH 1243/4858] add tests for --color/--no-color --- features/flags.feature | 15 +++++++++++++++ php/WP_CLI/Runner.php | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/features/flags.feature b/features/flags.feature index 47c9d00148..9ef0db43f9 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -58,3 +58,18 @@ Feature: Global flags """ Error: Could not get a user_id for this user: 'non-existing-user' """ + + Scenario: Enabling/disabling color + Given WP install + + When I run `wp --no-color non-existant-command` + Then STDERR should be: + """ + Error: 'non-existant-command' is not a registered wp command. See 'wp help'. + """ + + When I run `wp --color non-existant-command` + Then STDERR should contain: + """ + [31;1mError: + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 1683393fdd..433507c31f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -191,7 +191,7 @@ public function before_wp_load() { if ( isset( $this->assoc_args['no-color'] ) ) { $this->config['color'] = false; unset( $this->assoc_args['no-color'] ); - } elseif ( 'auto' == $this->config['color'] ) { + } elseif ( 'auto' === $this->config['color'] ) { $this->config['color'] = ! \cli\Shell::isPiped(); } From ff0dff7224d9390e0d0deff8883d4d988b983e30 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 7 Feb 2013 03:46:14 +0200 Subject: [PATCH 1244/4858] add files for plugin unit testing --- php/commands/scaffold.php | 35 +++++++++++++++++++++++++++++------ templates/.travis.yml | 33 +++++++++++++++++++++++++++++++++ templates/bootstrap.mustache | 8 ++++++++ templates/phpunit.xml | 20 ++++++++++++++++++++ 4 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 templates/.travis.yml create mode 100644 templates/bootstrap.mustache create mode 100644 templates/phpunit.xml diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 36be7ab545..300d37ba9f 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -180,11 +180,12 @@ function plugin( $args, $assoc_args ) { $data['textdomain'] = $plugin_slug; - $plugin_contents = $this->render( 'plugin.mustache', $data ); + $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + $plugin_path = "$plugin_dir/$plugin_slug.php"; - $plugin_path = WP_PLUGIN_DIR . "/$plugin_slug/$plugin_slug.php"; + $this->create_file( $plugin_path, $this->render( 'plugin.mustache', $data ) ); - $this->create_file( $plugin_path, $plugin_contents ); + $this->add_testing_files( $plugin_dir, $plugin_slug ); WP_CLI::success( "Created $plugin_path" ); @@ -192,6 +193,26 @@ function plugin( $args, $assoc_args ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); } + private function add_testing_files( $plugin_dir, $plugin_slug ) { + global $wp_filesystem; + + $tests_dir = "$plugin_dir/tests"; + + $wp_filesystem->mkdir( $tests_dir ); + + $this->create_file( "$tests_dir/bootstrap.php", + $this->render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ); + + $to_copy = array( + 'phpunit.xml' => $plugin_dir, + '.travis.yml' => $plugin_dir, + ); + + foreach ( $to_copy as $file => $dir ) { + $wp_filesystem->copy( $this->get_template_path( $file ), "$dir/$file" ); + } + } + private function create_file( $filename, $contents ) { global $wp_filesystem; @@ -287,14 +308,16 @@ protected function extract_args( $assoc_args, $defaults ) { } private function render( $template, $data ) { - $scaffolds_dir = WP_CLI_ROOT . '../templates'; - - $template = file_get_contents( $scaffolds_dir . '/' . $template ); + $template = file_get_contents( $this->get_template_path( $template ) ); $m = new Mustache_Engine; return $m->render( $template, $data ); } + + private function get_template_path( $template ) { + return WP_CLI_ROOT . "../templates/$template"; + } } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); diff --git a/templates/.travis.yml b/templates/.travis.yml new file mode 100644 index 0000000000..e5c59aee38 --- /dev/null +++ b/templates/.travis.yml @@ -0,0 +1,33 @@ +language: php + +php: + - 5.3 + - 5.4 + +env: + - WP_VERSION=master WP_MULTISITE=0 + - WP_VERSION=3.4.2 WP_MULTISITE=0 + - WP_VERSION=master WP_MULTISITE=1 + - WP_VERSION=3.4.2 WP_MULTISITE=1 + +before_install: + - git submodule update --init --recursive + +before_script: + - WP_CORE_DIR=/tmp/wordpress/ + - plugin_slug=$(basename $(pwd)) + - plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug + - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION + - mkdir -p $WP_CORE_DIR + - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + - cd .. + - mv $plugin_slug $plugin_dir + - wget -nv -O $plugin_dir/tests/wp-tests-config.php http://unit-test.svn.wordpress.org/trunk/wp-tests-config-sample.php + - cd $plugin_dir + - sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" tests/wp-tests-config.php + - sed -i "s/yourdbnamehere/wordpress_test/" tests/wp-tests-config.php + - sed -i "s/yourusernamehere/root/" tests/wp-tests-config.php + - sed -i "s/yourpasswordhere//" tests/wp-tests-config.php + - mysql -e 'CREATE DATABASE wordpress_test;' -uroot + +script: phpunit diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache new file mode 100644 index 0000000000..9c9405abc6 --- /dev/null +++ b/templates/bootstrap.mustache @@ -0,0 +1,8 @@ +<?php + +$GLOBALS['wp_tests_options'] = array( + 'active_plugins' => array( basename( dirname( dirname( __FILE__ ) ) ) . '/{{plugin_slug}}.php' ), +); + +require dirname( __FILE__ ) . '/lib/bootstrap.php'; + diff --git a/templates/phpunit.xml b/templates/phpunit.xml new file mode 100644 index 0000000000..8b8c4f0859 --- /dev/null +++ b/templates/phpunit.xml @@ -0,0 +1,20 @@ +<phpunit + bootstrap="tests/bootstrap.php" + backupGlobals="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + > + <testsuites> + <testsuite> + <directory prefix="test-" suffix=".php">./tests/</directory> + </testsuite> + </testsuites> + <filter> + <whitelist> + <directory suffix=".php">./core</directory> + <directory suffix=".php">./admin</directory> + </whitelist> + </filter> +</phpunit> From 63ab03262c46e09eb793b197ab5c45ed2216541a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 7 Feb 2013 04:01:14 +0200 Subject: [PATCH 1245/4858] show plugin dir, instead of path on success message, since there's more than one generated file now --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 300d37ba9f..f21135c131 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -187,7 +187,7 @@ function plugin( $args, $assoc_args ) { $this->add_testing_files( $plugin_dir, $plugin_slug ); - WP_CLI::success( "Created $plugin_path" ); + WP_CLI::success( "Created $plugin_dir" ); if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); From 82d76de77b07f36c6a0b5c4d5a0c10cecbd6b848 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Feb 2013 22:21:46 +0200 Subject: [PATCH 1246/4858] transform add_testing_files() method into a proper subcommand --- php/commands/scaffold.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f21135c131..baff9f30e7 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -185,17 +185,28 @@ function plugin( $args, $assoc_args ) { $this->create_file( $plugin_path, $this->render( 'plugin.mustache', $data ) ); - $this->add_testing_files( $plugin_dir, $plugin_slug ); - WP_CLI::success( "Created $plugin_dir" ); + WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ) ); + if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); } - private function add_testing_files( $plugin_dir, $plugin_slug ) { + /** + * Generate files needed for running PHPUnit tests. + * + * @subcommand plugin-tests + * + * @synopsis <plugin> + */ + function plugin_tests( $args, $assoc_args ) { global $wp_filesystem; + $plugin_slug = $args[0]; + + $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + $tests_dir = "$plugin_dir/tests"; $wp_filesystem->mkdir( $tests_dir ); @@ -211,6 +222,8 @@ private function add_testing_files( $plugin_dir, $plugin_slug ) { foreach ( $to_copy as $file => $dir ) { $wp_filesystem->copy( $this->get_template_path( $file ), "$dir/$file" ); } + + WP_CLI::success( "Created test files in $plugin_dir" ); } private function create_file( $filename, $contents ) { From c58c439382de8cfb883a5272b8d1bc04d7e7e2e3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 18 Feb 2013 12:50:35 +0200 Subject: [PATCH 1247/4858] add test-sample.php file --- php/commands/scaffold.php | 1 + templates/test-sample.php | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 templates/test-sample.php diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index baff9f30e7..75b7a22517 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -217,6 +217,7 @@ function plugin_tests( $args, $assoc_args ) { $to_copy = array( 'phpunit.xml' => $plugin_dir, '.travis.yml' => $plugin_dir, + 'test-sample.php' => $tests_dir, ); foreach ( $to_copy as $file => $dir ) { diff --git a/templates/test-sample.php b/templates/test-sample.php new file mode 100644 index 0000000000..1a23460d39 --- /dev/null +++ b/templates/test-sample.php @@ -0,0 +1,10 @@ +<?php + +class SampleTest extends WP_UnitTestCase { + + function testSample() { + // replace this with some actual testing code + $this->assertTrue( true ); + } +} + From b7693e07ab9d29618b3d43890276ed1f03e86b31 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 18 Feb 2013 15:03:13 +0200 Subject: [PATCH 1248/4858] revert to using the official unit testing suite --- templates/.travis.yml | 23 +++++++++++++++-------- templates/bootstrap.mustache | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index e5c59aee38..0f2425e31c 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -14,20 +14,27 @@ before_install: - git submodule update --init --recursive before_script: + # set up WP install - WP_CORE_DIR=/tmp/wordpress/ - - plugin_slug=$(basename $(pwd)) - - plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION - mkdir -p $WP_CORE_DIR - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + - plugin_slug=$(basename $(pwd)) + - plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug - cd .. - mv $plugin_slug $plugin_dir - - wget -nv -O $plugin_dir/tests/wp-tests-config.php http://unit-test.svn.wordpress.org/trunk/wp-tests-config-sample.php - - cd $plugin_dir - - sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" tests/wp-tests-config.php - - sed -i "s/yourdbnamehere/wordpress_test/" tests/wp-tests-config.php - - sed -i "s/yourusernamehere/root/" tests/wp-tests-config.php - - sed -i "s/yourpasswordhere//" tests/wp-tests-config.php + # set up testing suite + - export WP_TESTS_DIR=/tmp/wordpress-tests/ + - svn co --ignore-externals http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR + - cd $WP_TESTS_DIR + - cp wp-tests-config-sample.php wp-tests-config.php + - sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php + - sed -i "s/yourdbnamehere/wordpress_test/" wp-tests-config.php + - sed -i "s/yourusernamehere/root/" wp-tests-config.php + - sed -i "s/yourpasswordhere//" wp-tests-config.php + # set up database - mysql -e 'CREATE DATABASE wordpress_test;' -uroot + # prepare for running the tests + - cd $plugin_dir script: phpunit diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index 9c9405abc6..382f740134 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -4,5 +4,5 @@ $GLOBALS['wp_tests_options'] = array( 'active_plugins' => array( basename( dirname( dirname( __FILE__ ) ) ) . '/{{plugin_slug}}.php' ), ); -require dirname( __FILE__ ) . '/lib/bootstrap.php'; +require getenv( 'WP_TESTS_DIR' ) . '/includes/bootstrap.php'; From c51eecdca8587b31249251ccbb0bc81aa7310d60 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Feb 2013 01:10:11 +0200 Subject: [PATCH 1249/4858] add manpage for `wp scaffold plugin-tests` --- man-src/scaffold-plugin-tests.txt | 17 ++++++++++++++++ man/scaffold-plugin-tests.1 | 33 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 man-src/scaffold-plugin-tests.txt create mode 100644 man/scaffold-plugin-tests.1 diff --git a/man-src/scaffold-plugin-tests.txt b/man-src/scaffold-plugin-tests.txt new file mode 100644 index 0000000000..927c7fea48 --- /dev/null +++ b/man-src/scaffold-plugin-tests.txt @@ -0,0 +1,17 @@ +## DESCRIPTION + +These are the files that are generated: + +* `phpunit.xml` is the configuration file for PHPUnit +* `.travis.yml` is the configuration file for Travis CI +* `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite +* `tests/test-sample.php` is a sample file containing the actual tests + +## ENVIRONMENT + +The `tests/bootstrap.php` file looks for the WP_TESTS_DIR environment +variable. + +## EXAMPLE + +wp scaffold plugin-tests hello diff --git a/man/scaffold-plugin-tests.1 b/man/scaffold-plugin-tests.1 new file mode 100644 index 0000000000..1e1e7cd26c --- /dev/null +++ b/man/scaffold-plugin-tests.1 @@ -0,0 +1,33 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SCAFFOLD\-PLUGIN\-TESTS" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-scaffold\-plugin\-tests\fR \- Generate files needed for running PHPUnit tests\. +. +.SH "SYNOPSIS" +wp scaffold plugin\-tests \fIplugin\fR +. +.SH "DESCRIPTION" +These are the files that are generated: +. +.IP "\(bu" 4 +\fBphpunit\.xml\fR is the configuration file for PHPUnit +. +.IP "\(bu" 4 +\fB\.travis\.yml\fR is the configuration file for Travis CI +. +.IP "\(bu" 4 +\fBtests/bootstrap\.php\fR is the file that makes the current plugin active when running the test suite +. +.IP "\(bu" 4 +\fBtests/test\-sample\.php\fR is a sample file containing the actual tests +. +.IP "" 0 +. +.SH "ENVIRONMENT" +The \fBtests/bootstrap\.php\fR file looks for the WP_TESTS_DIR environment variable\. +. +.SH "EXAMPLE" +wp scaffold plugin\-tests hello From f2a7bec206a9ea40c0ff4315df45cbf73c2eaa4c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 18 Feb 2013 13:52:23 +0200 Subject: [PATCH 1250/4858] add `wp core init-tests` --- php/commands/core.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 20502c90a5..85c78f3763 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -288,6 +288,36 @@ function update_db() { wp_upgrade(); WP_CLI::success( 'WordPress database upgraded successfully.' ); } + + /** + * Set up the test suite using the current WP instance. + * + * @subcommand init-tests + * + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] + */ + function init_tests( $args, $assoc_args ) { + $tests_dir = ABSPATH . 'unit-tests/'; + + WP_CLI::launch( 'svn co https://unit-test.svn.wordpress.org/trunk/ ' . escapeshellarg( $tests_dir ) ); + + $config_file = file_get_contents( $tests_dir . 'wp-tests-config-sample.php' ); + + $replacements = array( + "dirname( __FILE__ ) . '/wordpress/'" => "'" . ABSPATH . "'", + "yourdbnamehere" => $assoc_args['dbname'], + "yourusernamehere" => $assoc_args['dbuser'], + "yourpasswordhere" => isset( $assoc_args['dbpass'] ) ? $assoc_args['dbpass'] : '' + ); + + $config_file = str_replace( array_keys( $replacements ), array_values( $replacements ), $config_file ); + + $config_file_path = $tests_dir . 'wp-tests-config.php'; + + file_put_contents( $config_file_path, $config_file ); + + WP_CLI::success( "Created $config_file_path" ); + } } WP_CLI::add_command( 'core', 'Core_Command' ); From 013ef39184ac08476df19d2b83731aa606f68cc0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Feb 2013 01:45:45 +0200 Subject: [PATCH 1251/4858] add optional path parameter --- php/commands/core.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 85c78f3763..4845bbf0a1 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -294,10 +294,13 @@ function update_db() { * * @subcommand init-tests * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] + * @synopsis [<path>] --dbname=<name> --dbuser=<user> [--dbpass=<password>] */ function init_tests( $args, $assoc_args ) { - $tests_dir = ABSPATH . 'unit-tests/'; + if ( isset( $args[0] ) ) + $tests_dir = trailingslashit( $args[0] ); + else + $tests_dir = ABSPATH . 'unit-tests/'; WP_CLI::launch( 'svn co https://unit-test.svn.wordpress.org/trunk/ ' . escapeshellarg( $tests_dir ) ); From 9a59ab682f47f364b22a6489243f69195d283b43 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Feb 2013 01:50:26 +0200 Subject: [PATCH 1252/4858] add manpage --- man-src/core-init-tests.txt | 14 ++++++++++++++ man/core-init-tests.1 | 31 +++++++++++++++++++++++++++++++ php/commands/core.php | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 man-src/core-init-tests.txt create mode 100644 man/core-init-tests.1 diff --git a/man-src/core-init-tests.txt b/man-src/core-init-tests.txt new file mode 100644 index 0000000000..e06ef024f7 --- /dev/null +++ b/man-src/core-init-tests.txt @@ -0,0 +1,14 @@ +## OPTIONS + +* `--dbname`=<dbname>: + + Set the database name. **WARNING**: The database will be whipped every time +you run the tests. + +* `--dbuser`=<dbuser>: + + Set the database user. + +* `--dbpass`=<dbpass>: + + Set the database user password. diff --git a/man/core-init-tests.1 b/man/core-init-tests.1 new file mode 100644 index 0000000000..66ac80a3da --- /dev/null +++ b/man/core-init-tests.1 @@ -0,0 +1,31 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-INIT\-TESTS" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-init\-tests\fR \- Set up the official test suite using the current WordPress instance\. +. +.SH "SYNOPSIS" +wp core init\-tests [\fIpath\fR] \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\-\-dbpass=\fIpassword\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-dbname\fR=\fIdbname\fR: +. +.IP +Set the database name\. \fBWARNING\fR: The database will be whipped every time you run the tests\. +. +.TP +\fB\-\-dbuser\fR=\fIdbuser\fR: +. +.IP +Set the database user\. +. +.TP +\fB\-\-dbpass\fR=\fIdbpass\fR: +. +.IP +Set the database user password\. + diff --git a/php/commands/core.php b/php/commands/core.php index 4845bbf0a1..38bd290408 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -290,7 +290,7 @@ function update_db() { } /** - * Set up the test suite using the current WP instance. + * Set up the official test suite using the current WordPress instance. * * @subcommand init-tests * From e8a4bcda74999cc1651cbbd7ba7236dd68f46ec2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Feb 2013 01:58:44 +0200 Subject: [PATCH 1253/4858] document path parameter and add example --- man-src/core-init-tests.txt | 8 ++++++++ man/core-init-tests.1 | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/man-src/core-init-tests.txt b/man-src/core-init-tests.txt index e06ef024f7..9f55ec5cc4 100644 --- a/man-src/core-init-tests.txt +++ b/man-src/core-init-tests.txt @@ -1,5 +1,9 @@ ## OPTIONS +* `<path>`: + + The directory in which to download the testing suite files. (Optional) + * `--dbname`=<dbname>: Set the database name. **WARNING**: The database will be whipped every time @@ -12,3 +16,7 @@ you run the tests. * `--dbpass`=<dbpass>: Set the database user password. + +## EXAMPLE + +wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test diff --git a/man/core-init-tests.1 b/man/core-init-tests.1 index 66ac80a3da..7e5c481958 100644 --- a/man/core-init-tests.1 +++ b/man/core-init-tests.1 @@ -12,6 +12,12 @@ wp core init\-tests [\fIpath\fR] \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\- .SH "OPTIONS" . .TP +\fB<path>\fR: +. +.IP +The directory in which to download the testing suite files\. (Optional) +. +.TP \fB\-\-dbname\fR=\fIdbname\fR: . .IP @@ -28,4 +34,6 @@ Set the database user\. . .IP Set the database user password\. - +. +.SH "EXAMPLE" +wp core init\-tests ~/svn/wp\-tests \-\-dbname=wp_test \-\-dbuser=wp_test From 076ffbae41aca91e34cf3623ad3144726bbf20cf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Feb 2013 02:49:55 +0200 Subject: [PATCH 1254/4858] bump version to 0.9.0-alpha2 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 9c28fbe355..7e040cbeca 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.0-alpha' ); +define( 'WP_CLI_VERSION', '0.9.0-alpha2' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 6e0c833c9eb6dbf3584f3e4f558a0ad80786c7c8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Feb 2013 22:43:39 +0200 Subject: [PATCH 1255/4858] avoid using the -l option for man, which doesn't exist on OSX fixes #311 --- php/commands/help.php | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 7b3490abc5..a875f7a281 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -40,22 +40,14 @@ private static function maybe_load_man_page( $args ) { } private static function show_manpage( $path ) { - // to make compatible with Phar archives, need to write to a temporary file - $fd = fopen( 'php://temp', 'rw' ); - fwrite( $fd, file_get_contents( $path ) ); - fseek( $fd, 0 ); + // man can't read phar://, so need to copy to a temporary file + $tmp_path = tempnam( sys_get_temp_dir(), 'wp-cli-man-' ); - $descriptorspec = array( - 0 => $fd, - 1 => STDOUT, - 2 => STDERR - ); + copy( $path, $tmp_path ); - $cmd = 'man -l -'; + WP_CLI::launch( "man $tmp_path" ); - $r = proc_close( proc_open( $cmd, $descriptorspec, $pipes ) ); - - exit( $r ); + unlink( $tmp_path ); } } From ebada77fca3583308fbe8a01999708f73e5914d5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Feb 2013 08:43:01 +0200 Subject: [PATCH 1256/4858] remove P2P specific <filter> from phpunit.xml see #270 --- templates/phpunit.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/templates/phpunit.xml b/templates/phpunit.xml index 8b8c4f0859..44f0fdb69c 100644 --- a/templates/phpunit.xml +++ b/templates/phpunit.xml @@ -11,10 +11,4 @@ <directory prefix="test-" suffix=".php">./tests/</directory> </testsuite> </testsuites> - <filter> - <whitelist> - <directory suffix=".php">./core</directory> - <directory suffix=".php">./admin</directory> - </whitelist> - </filter> </phpunit> From 245fa1f5f6c2335a1c91bb7782f7b4d4d303ae3c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Feb 2013 09:44:20 +0200 Subject: [PATCH 1257/4858] add utils/update-phar --- utils/update-phar | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 utils/update-phar diff --git a/utils/update-phar b/utils/update-phar new file mode 100755 index 0000000000..8105be91de --- /dev/null +++ b/utils/update-phar @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -ex + +current_rev=$(git rev-parse HEAD) +current_rev=${current_rev:0:10} + +php -dphar.readonly=0 ./utils/make-phar.php ../wp-cli-packages/phar/wp-cli.phar --quiet + +cd ../wp-cli-packages + +new_commit_subj="update wp-cli.phar to $current_rev" + +current_commit_subj=$(git show -s --pretty=format:%s HEAD) + +if [ "$new_commit_subj" = "$current_commit_subj" ]; then + echo "already at latest revision" + exit 1 +fi + +git add phar/wp-cli.phar + +git commit -m "$new_commit_subj" + +git push From 50012843429d92da36b95746c53161dcadcb5dd9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Feb 2013 14:12:24 +0200 Subject: [PATCH 1258/4858] quiet down svn checkout in travis script. see #270 --- templates/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 0f2425e31c..89d1fe964c 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -25,7 +25,7 @@ before_script: - mv $plugin_slug $plugin_dir # set up testing suite - export WP_TESTS_DIR=/tmp/wordpress-tests/ - - svn co --ignore-externals http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR + - svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR - cd $WP_TESTS_DIR - cp wp-tests-config-sample.php wp-tests-config.php - sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php From c4e9bc870ca2e03adca6f9b0542ee82f9e3a7844 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 22 Feb 2013 09:57:54 +0200 Subject: [PATCH 1259/4858] make shell readline script more readable, using a heredoc --- php/commands/shell.php | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 75a90151d9..2cdcecbedf 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -60,16 +60,21 @@ private static function prompt() { } private static function create_prompt_cmd( $prompt, $history_path ) { - $cmd = implode( '; ', array( - 'set -f', - sprintf( 'history -r %s', escapeshellarg( $history_path ) ), - 'LINE=""', - sprintf( 'read -re -p %s LINE', escapeshellarg( $prompt ) ), - '[ $? -eq 0 ] || exit', - 'history -s "$LINE"', - sprintf( 'history -w %s', escapeshellarg( $history_path ) ), - 'echo $LINE' - ) ); + $prompt = escapeshellarg( $prompt ); + $history_path = escapeshellarg( $history_path ); + + $cmd = <<<BASH +set -f +history -r $history_path +LINE="" +read -re -p $prompt LINE +[ $? -eq 0 ] || exit +history -s "\$LINE" +history -w $history_path +echo \$LINE +BASH; + + $cmd = str_replace( "\n", '; ', $cmd ); return '/bin/bash -c ' . escapeshellarg( $cmd ); } From d562b974a667adad0422970c268dbea89fdfc3e6 Mon Sep 17 00:00:00 2001 From: Dominik Schilling <dominikschilling+git@gmail.com> Date: Sun, 24 Feb 2013 15:05:23 +0100 Subject: [PATCH 1260/4858] Fix fatal error, because of new files, see https://core.trac.wordpress.org/changeset/23466 --- php/wp-settings-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index e58ea0d835..ac988a49d4 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -107,6 +107,8 @@ require( ABSPATH . WPINC . '/author-template.php' ); require( ABSPATH . WPINC . '/post.php' ); require( ABSPATH . WPINC . '/post-template.php' ); +Utils\maybe_require( '3.5-alpha-23466', ABSPATH . WPINC . '/revision.php' ); +Utils\maybe_require( '3.5-alpha-23466', ABSPATH . WPINC . '/post-formats.php' ); require( ABSPATH . WPINC . '/post-thumbnail-template.php' ); require( ABSPATH . WPINC . '/category.php' ); require( ABSPATH . WPINC . '/category-template.php' ); From 943149031f2d4d0a07ddcaa02a49c38fd2913cc2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 18:22:49 +0200 Subject: [PATCH 1261/4858] fix version check for revision.php and post-formats.php * 3.6-alpha, not 3.5-alpha * 23451, because $wp_version wasn't updated with r23466 fixes #322. see #318 --- php/wp-settings-cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index ac988a49d4..dd64be7d3a 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -107,8 +107,8 @@ require( ABSPATH . WPINC . '/author-template.php' ); require( ABSPATH . WPINC . '/post.php' ); require( ABSPATH . WPINC . '/post-template.php' ); -Utils\maybe_require( '3.5-alpha-23466', ABSPATH . WPINC . '/revision.php' ); -Utils\maybe_require( '3.5-alpha-23466', ABSPATH . WPINC . '/post-formats.php' ); +Utils\maybe_require( '3.6-alpha-23451', ABSPATH . WPINC . '/revision.php' ); +Utils\maybe_require( '3.6-alpha-23451', ABSPATH . WPINC . '/post-formats.php' ); require( ABSPATH . WPINC . '/post-thumbnail-template.php' ); require( ABSPATH . WPINC . '/category.php' ); require( ABSPATH . WPINC . '/category-template.php' ); From b21d0efeb6840d76868e307608ccbf645782166c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 18:52:28 +0200 Subject: [PATCH 1262/4858] re-order lines in .travis.yml template to make them more readable --- templates/.travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 89d1fe964c..a34cedf751 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -6,9 +6,9 @@ php: env: - WP_VERSION=master WP_MULTISITE=0 - - WP_VERSION=3.4.2 WP_MULTISITE=0 - WP_VERSION=master WP_MULTISITE=1 - - WP_VERSION=3.4.2 WP_MULTISITE=1 + - WP_VERSION=3.5.1 WP_MULTISITE=0 + - WP_VERSION=3.5.1 WP_MULTISITE=1 before_install: - git submodule update --init --recursive @@ -16,8 +16,8 @@ before_install: before_script: # set up WP install - WP_CORE_DIR=/tmp/wordpress/ - - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION - mkdir -p $WP_CORE_DIR + - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - plugin_slug=$(basename $(pwd)) - plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug From 65e1bbf3ab1dff99c28bb0a3fb0b0e0b52c23cb5 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 25 Feb 2013 17:52:33 +0100 Subject: [PATCH 1263/4858] Cleanup before pull request and add props to Viperbond007 --- php/commands/media.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index f612cf80ff..5b11fb50e1 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -6,25 +6,18 @@ * @package wp-cli */ class Media_Command extends WP_CLI_Command { + var $errors = false; + function __construct() { WP_Filesystem(); } - /** - * Import a file into the media library. - * - * @synopsis <filename> [--blog] [--zip=<zip>] - */ - function import( $args, $assoc_args = array() ) { - } - /** * Regenerate thumbnail(s) * - * @synopsis [--id=<id>] - * @todo [--file=<file>] - * props @benmay + * @synopsis [--id=<id>] + * props @benmay & @Viper007Bond */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; From 69ebc70a3ae21cff734797436258589c55e704b0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 18:55:16 +0200 Subject: [PATCH 1264/4858] running the tests: fix example mysql command --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a607afe72b..8285acd30a 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,7 @@ Before running the tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: - GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" - IDENTIFIED BY "password1"; + GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; Finally, to run the unit tests: From 7eb90a2a7c804416a8a9a50eba69032916fd8007 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 18:57:48 +0200 Subject: [PATCH 1265/4858] first pass at .travis.yml file --- .travis.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..c47713fe7c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,33 @@ +language: php + +php: + - 5.3 + - 5.4 + +env: + - WP_VERSION=master WP_MULTISITE=0 + - WP_VERSION=master WP_MULTISITE=1 + - WP_VERSION=3.5.1 WP_MULTISITE=0 + - WP_VERSION=3.5.1 WP_MULTISITE=1 + - WP_VERSION=3.4.2 WP_MULTISITE=0 + - WP_VERSION=3.4.2 WP_MULTISITE=1 + +before_install: + - git submodule update --init --recursive + +before_script: + # install dependencies + - curl -sS https://getcomposer.org/installer | php + - php composer.phar install --dev + # set up WP install + - WP_CORE_DIR=/tmp/wp-cli-test-core-download-cache/ + - mkdir -p $WP_CORE_DIR + - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION + - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + # set up database + - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot + - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot + +script: + - vendor/bin/phpunit + - vendor/bin/behat From 6a9776f9dd442742e8d0183b227e917f21dcb1ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 19:02:48 +0200 Subject: [PATCH 1266/4858] don't run Behat tests if unit tests fail --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c47713fe7c..b2bab1cbce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,4 @@ before_script: - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot -script: - - vendor/bin/phpunit - - vendor/bin/behat +script: vendor/bin/phpunit && vendor/bin/behat From 2c14f9f5e18cbc43afc7efe553466b013b14b7d2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 19:13:03 +0200 Subject: [PATCH 1267/4858] mark SynopsisParser::gen_patterns() as static --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index e96d2d05dd..b488c71957 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -134,7 +134,7 @@ private static function init_patterns() { self::gen_patterns( 'flag', "--$p_name", array( 'optional' ) ); } - private function gen_patterns( $type, $pattern, $flavour_types ) { + private static function gen_patterns( $type, $pattern, $flavour_types ) { static $flavours = array( 'mandatory' => ':pattern:', 'optional' => '\[:pattern:\]', From bd57b99fa70d50def2971fab2f51808378e7aa6a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 19:32:30 +0200 Subject: [PATCH 1268/4858] make wp core install check less strict, to avoid error from sendmail --- features/core.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 02ad41f6e1..2c41160e43 100644 --- a/features/core.feature +++ b/features/core.feature @@ -56,7 +56,7 @@ Feature: Manage WordPress installation """ When I run `wp core install` - Then it should run without errors + Then the return code should be 0 When I run `wp post list --ids` Then STDOUT should be: From f238f48dc75e22d1443288218478fe18b5fd157a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 20:01:28 +0200 Subject: [PATCH 1269/4858] remove `wp theme status twentytwelve` check Twentytwelve is not available in WP 3.4. --- features/core.feature | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index 2c41160e43..22d59e908d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -74,8 +74,5 @@ Feature: Manage WordPress installation Given WP install And custom wp-content directory - When I run `wp theme status twentytwelve` - Then it should run without errors - When I run `wp plugin status hello` Then it should run without errors From b7e2111dbf7f3b7f05b57ac27273032893b5e51f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 20:05:41 +0200 Subject: [PATCH 1270/4858] 'Db doesn't exist scenarion: make check less strict, to avoid issues with encodings --- features/core.feature | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index 22d59e908d..7c27c5f141 100644 --- a/features/core.feature +++ b/features/core.feature @@ -30,10 +30,7 @@ Feature: Manage WordPress installation When I run `wp` Then the return code should be 1 - And STDERR should be: - """ - Error: Can’t select database - """ + And STDERR should not be empty When I run `wp db create` Then it should run without errors From 4993db4b5642371086c7cd9d96340f732ed241c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Feb 2013 20:30:59 +0200 Subject: [PATCH 1271/4858] add Build Status image to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 8285acd30a..f72337f642 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ WP-CLI ======== + +[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) + wp-cli is a set of command-line tools for managing WordPress installations. Where can I get more info? From 7f905b465f0d3146784fd5756cf2e056f3709026 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 25 Feb 2013 23:42:51 +0100 Subject: [PATCH 1272/4858] Added confirmation check before regenerating all images --- php/commands/media.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 5b11fb50e1..28cb8b42c5 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -16,18 +16,20 @@ function __construct() { /** * Regenerate thumbnail(s) * - * @synopsis [--id=<id>] + * @synopsis [--id=<id>] [--yes] * props @benmay & @Viper007Bond */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; $vars = wp_parse_args( $assoc_args, array( - 'id' => false, + 'id' => false ) ); extract($vars, EXTR_SKIP); + WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); + $where_clause = ( $id ) ? "AND ID = $id" : ''; if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { From 222eacbc1a6dfd64abe4efa597338668238ce31e Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 25 Feb 2013 23:59:27 +0100 Subject: [PATCH 1273/4858] Skip confirmation if `id` arg is given --- php/commands/media.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 28cb8b42c5..31003ba2fa 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -23,11 +23,16 @@ function regenerate( $args, $assoc_args = array() ) { global $wpdb; $vars = wp_parse_args( $assoc_args, array( - 'id' => false + 'id' => false ) ); extract($vars, EXTR_SKIP); + // If id is given, skip confirm because it is only one file + if( !empty( $id ) ) { + $assoc_args['yes'] = true; + } + WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); $where_clause = ( $id ) ? "AND ID = $id" : ''; From 41df238f39248414f93bdc1c47d9fe3a35052cf7 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 26 Feb 2013 01:07:36 +0100 Subject: [PATCH 1274/4858] First start better naming --- php/commands/media.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 31003ba2fa..fafdf11b57 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -106,14 +106,20 @@ private function _process_regeneration( $id ) { while ( $file = readdir( $dir ) ) { if ( !( strrpos( $file, $imageName ) === false ) ) { $thumbnail = explode( $imageName, $file ); - if ( $thumbnail[ 0 ] == "" ) { - $thumbnailFormat = substr( $thumbnail[ 1 ], -4 ); - $thumbnail = substr( $thumbnail[ 1 ], 0, strlen( $thumbnail[ 1 ] ) - 4 ); - $thumbnail = explode( 'x', $thumbnail ); - if ( count( $thumbnail ) == 2 ) { - if ( is_numeric( $thumbnail[ 0 ] ) && is_numeric( $thumbnail[ 1 ] ) ) { - WP_CLI::line( "Thumbnail: {$thumbnail[0]} x {$thumbnail[1]} was deleted." ); - @unlink( $dirPath . $imageName . $thumbnail[ 0 ] . 'x' . $thumbnail[ 1 ] . $thumbnailFormat ); + $filename = $thumbnail[ 1 ]; + + if ( "" == $thumbnail[ 0 ] ) { + $thumbnailFormat = substr( $filename, -4 ); + $thumbnail = substr( $filename, 0, strlen( $filename ) - 4 ); + + $sizes = explode( 'x', $thumbnail ); + $width = $sizes[0]; + $height = $sizes[1]; + + if ( 2 == count( $sizes ) ) { + if ( is_numeric( $width ) && is_numeric( $height ) ) { + WP_CLI::line( "Thumbnail: {$width} x {$height} was deleted." ); + @unlink( $dirPath . $imageName . $width . 'x' . $thumbnail[ 1 ] . $thumbnailFormat ); } } } From f46a6a5f1eefdab8ed8fd0737c9c2387efffacd8 Mon Sep 17 00:00:00 2001 From: Tracy Rotton <tracy@taupecat.com> Date: Mon, 25 Feb 2013 21:53:46 -0500 Subject: [PATCH 1275/4858] Update php/config-spec.php Fixed the spelling of "colorize." --- php/config-spec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/config-spec.php b/php/config-spec.php index 8879434b26..41332d9a3f 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -45,7 +45,7 @@ 'runtime' => true, 'file' => '<bool>', 'default' => 'auto', - 'desc' => 'Whether to colozire the output', + 'desc' => 'Whether to colorize the output', ), 'debug' => array( From 547a3e4379df5087fcd2507fd116b71c14d34874 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Feb 2013 23:03:16 +0200 Subject: [PATCH 1276/4858] rely on --path, instead of using chdir() --- features/bootstrap/FeatureContext.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 9250c312f9..006fd08e8b 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -87,13 +87,16 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - private function _run( $command, $cwd ) { - if ( !$cwd ) - $cwd = $this->install_dir; - + private function _run( $command ) { $wp_cli_path = getcwd() . "/bin/wp"; - $sh_command = "cd $cwd; $wp_cli_path $command"; + if ( false === strpos( $command, '--path' ) ) { + $command .= \WP_CLI\Utils\assoc_args_to_str( array( + 'path' => $this->install_dir + ) ); + } + + $sh_command = "$wp_cli_path $command"; $process = proc_open( $sh_command, array( 0 => STDIN, @@ -112,7 +115,7 @@ private function _run( $command, $cwd ) { return (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); } - public function run( $command, $cwd = false ) { + public function run( $command ) { switch ( $command ) { case 'core install': return $this->run_install(); @@ -123,7 +126,7 @@ public function run( $command, $cwd = false ) { break; default: - return $this->_run( $command, $cwd ); + return $this->_run( $command ); } } @@ -179,10 +182,12 @@ public function download_wordpress_files() { $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; if ( !file_exists( $cache_dir ) ) { mkdir( $cache_dir ); - $this->run( "core download", $cache_dir ); + $this->run( 'core download' . \WP_CLI\Utils\assoc_args_to_str( array( + 'path' => $cache_dir + ) ) ); } - exec( "cp -r '$cache_dir/'* '$this->install_dir/'" ); + exec( sprintf( "cp -r '%s/'* '%s/'", $cache_dir, $this->install_dir ) ); } } From ef46d1129ae3e836ad56ed88b5e61c592006d6ec Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Feb 2013 23:03:34 +0200 Subject: [PATCH 1277/4858] add core download check in 'Empty dir' scenario --- features/core.feature | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/core.feature b/features/core.feature index 7c27c5f141..ea5910fa08 100644 --- a/features/core.feature +++ b/features/core.feature @@ -5,6 +5,10 @@ Feature: Manage WordPress installation When I run `wp core is-installed` Then the return code should be 1 + When I run `wp core download --quiet` + Then it should run without errors + And the wp-settings.php file should exist + Scenario: No wp-config.php Given an empty directory And WP files From 0aa3e59d2b80d17c4aff227a03b5b90c833233d3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Feb 2013 23:06:37 +0200 Subject: [PATCH 1278/4858] use ABSPATH in `core download`, instead of '.' --- php/commands/core.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 38bd290408..21e9633401 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -16,11 +16,6 @@ public function download( $args, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && is_readable( ABSPATH . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); - if ( isset( $assoc_args['path'] ) ) - $docroot = $assoc_args['path']; - else - $docroot = './'; - if ( isset( $assoc_args['locale'] ) ) { exec( 'curl -s ' . escapeshellarg( 'https://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); if ($r) exit($r); @@ -37,7 +32,7 @@ public function download( $args, $assoc_args ) { $silent = WP_CLI::get_config('quiet') ? ' --silent ' : ' '; WP_CLI::launch( 'curl -f' . $silent . escapeshellarg( $download_url ) . ' | tar xz' ); - WP_CLI::launch( 'cp -r wordpress/* . && rm -rf wordpress' ); + WP_CLI::launch( sprintf( 'cp -r wordpress/* %s && rm -rf wordpress', escapeshellarg( ABSPATH ) ) ); WP_CLI::success( 'WordPress downloaded.' ); } From fe7683f6f535b4610315bc665734a7a9c5f3e616 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Feb 2013 23:38:53 +0200 Subject: [PATCH 1279/4858] create ABSPATH if it doesn't exist. props @erwanlr --- php/commands/core.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 21e9633401..6176571e83 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -16,6 +16,11 @@ public function download( $args, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && is_readable( ABSPATH . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); + if ( !is_dir( ABSPATH ) ) { + WP_CLI::line( sprintf( 'Creating directory %s', ABSPATH ) ); + WP_CLI::launch( 'mkdir -p ' . escapeshellarg( ABSPATH ) ); + } + if ( isset( $assoc_args['locale'] ) ) { exec( 'curl -s ' . escapeshellarg( 'https://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); if ($r) exit($r); From f4260a522c9573163e744b622c199c614899e032 Mon Sep 17 00:00:00 2001 From: erwanlr <erwan.lr@gmail.com> Date: Tue, 26 Feb 2013 22:55:40 +0100 Subject: [PATCH 1280/4858] Fixes Runner::set_wp_root to handle absolute & relative path --- php/WP_CLI/Runner.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 433507c31f..ff9ecb276e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -82,11 +82,20 @@ private static function split_special( &$assoc_args, &$config, $spec ) { } private static function set_wp_root( $config ) { - if ( !empty( $config['path'] ) ) { - define( 'ABSPATH', rtrim( $config['path'], '/' ) . '/' ); - } else { - define( 'ABSPATH', getcwd() . '/' ); + $path = getcwd(); + + if ( !empty( $config['path'] ) ) + { + if ( self::is_absolute_path( $config['path'] ) ) + $path = $config['path']; + else + $path .= $config['path']; } + define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); + } + + private static function is_absolute_path( $path ) { + return $path[0] === '/' ? true : false; } private static function set_url( $assoc_args ) { From d7d15c53bb3f5d983fcad0b8acbe0420d809a538 Mon Sep 17 00:00:00 2001 From: erwanlr <erwan.lr@gmail.com> Date: Wed, 27 Feb 2013 10:15:22 +0100 Subject: [PATCH 1281/4858] '/' missing --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ff9ecb276e..621e9577ed 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -89,7 +89,7 @@ private static function set_wp_root( $config ) { if ( self::is_absolute_path( $config['path'] ) ) $path = $config['path']; else - $path .= $config['path']; + $path .= '/' . $config['path']; } define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); } From 2c9dae3d43b76d0e5e8a5fc5e6a02084a332897f Mon Sep 17 00:00:00 2001 From: erwanlr <erwan.lr@gmail.com> Date: Wed, 27 Feb 2013 10:22:52 +0100 Subject: [PATCH 1282/4858] Fixes #321 db create / drop / reset syntax error with some dbnames (like wordpress-3.5.1) --- php/commands/db.php | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 104516728a..bed80acbf4 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -13,9 +13,8 @@ class DB_Command extends WP_CLI_Command { * @synopsis [--str] */ function create( $_, $assoc_args ) { - self::run( $assoc_args, self::create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=%s', - DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME + self::run( $assoc_args, self::create_execute_cmd( + sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ) ); WP_CLI::success( "Database created." ); @@ -27,10 +26,7 @@ function create( $_, $assoc_args ) { * @synopsis [--yes] [--str] */ function drop( $_, $assoc_args ) { - $command = self::create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=%s', - DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE ' . DB_NAME - ); + $command = self::create_execute_cmd( sprintf( 'DROP DATABASE `%s`', DB_NAME ) ); if ( !isset( $assoc_args['str'] ) ) { WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); @@ -47,15 +43,9 @@ function drop( $_, $assoc_args ) { * @synopsis [--yes] [--str] */ function reset( $_, $assoc_args ) { - $drop_cmd = self::create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=%s', - DB_HOST, DB_USER, DB_PASSWORD, 'DROP DATABASE IF EXISTS ' . DB_NAME - ); + $drop_cmd = self::create_execute_cmd( sprintf( 'DROP DATABASE IF EXISTS `%s`', DB_NAME ) ); - $create_cmd = self::create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=%s', - DB_HOST, DB_USER, DB_PASSWORD, 'CREATE DATABASE ' . DB_NAME - ); + $create_cmd = self::create_execute_cmd( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); if ( !isset( $assoc_args['str'] ) ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); @@ -162,6 +152,13 @@ private function get_file_name( $args ) { return $args[0]; } + private static function create_execute_cmd( $execute_statement ) { + return self::create_cmd( + 'mysql --host=%s --user=%s --password=%s --execute=%s', + DB_HOST, DB_USER, DB_PASSWORD, $execute_statement + ); + } + /** * Given a formatted string and an arbitrary number of arguments, * returns the final command, with the parameters escaped @@ -185,4 +182,3 @@ private static function run( $assoc_args, $cmd ) { } WP_CLI::add_command( 'db', 'DB_Command' ); - From 8863f0052173ab01a31bd6ab2f5eb8a2dc26477b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Feb 2013 11:45:26 +0200 Subject: [PATCH 1283/4858] fix coding standards. see #329 --- php/WP_CLI/Runner.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 621e9577ed..e4d04c266e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -84,18 +84,18 @@ private static function split_special( &$assoc_args, &$config, $spec ) { private static function set_wp_root( $config ) { $path = getcwd(); - if ( !empty( $config['path'] ) ) - { + if ( !empty( $config['path'] ) ) { if ( self::is_absolute_path( $config['path'] ) ) $path = $config['path']; else $path .= '/' . $config['path']; } + define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); } private static function is_absolute_path( $path ) { - return $path[0] === '/' ? true : false; + return $path[0] === '/'; } private static function set_url( $assoc_args ) { From fdac555f5a951f9a620e585cfa98c25d431bb4ae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Feb 2013 12:09:39 +0200 Subject: [PATCH 1284/4858] Ignore `wp ` prefix straigth from step definition. This makes it clearer that running arbitrary commands is not supported. --- features/steps/basic_steps.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 9e19360ab2..2dbbdf160d 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -44,12 +44,14 @@ function ( $world ) { } ); -$steps->When( '/^I run `(.+)`$/', - function ( $world, $cmd ) { - if ( 0 === strpos( $cmd, 'wp' ) ) { - $cmd = ltrim( substr( $cmd, 2 ) ); - } +$steps->When( '/^I run `wp`$/', + function ( $world ) { + $world->result = $world->run( '' ); + } +); +$steps->When( '/^I run `wp (.+)`$/', + function ( $world, $cmd ) { $world->replace_variables( $cmd ); $world->result = $world->run( $cmd ); From 232407508086aee09b8a3033e8124d406b8dc1ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Feb 2013 12:15:22 +0200 Subject: [PATCH 1285/4858] Prepend `--path`, instead of appending it, so that piping works. --- features/bootstrap/FeatureContext.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 006fd08e8b..57c05cda10 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -91,9 +91,9 @@ private function _run( $command ) { $wp_cli_path = getcwd() . "/bin/wp"; if ( false === strpos( $command, '--path' ) ) { - $command .= \WP_CLI\Utils\assoc_args_to_str( array( + $command = \WP_CLI\Utils\assoc_args_to_str( array( 'path' => $this->install_dir - ) ); + ) ) . ' ' . $command; } $sh_command = "$wp_cli_path $command"; From b76c44f4b05d540a0ead7ba9cd0af192a2125597 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Feb 2013 12:52:27 +0200 Subject: [PATCH 1286/4858] travis: add --no-interaction flag to Composer call Should at least make stalled builds fail faster. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b2bab1cbce..dfe12aa7af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_install: before_script: # install dependencies - curl -sS https://getcomposer.org/installer | php - - php composer.phar install --dev + - php composer.phar install --dev --no-interaction # set up WP install - WP_CORE_DIR=/tmp/wp-cli-test-core-download-cache/ - mkdir -p $WP_CORE_DIR From 2d905eaf2d99279120476ad33f44b911f1769e87 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Feb 2013 13:00:35 +0200 Subject: [PATCH 1287/4858] shorten synopsis for boolean parameters --- php/WP_CLI/Dispatcher/RootCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 654d4fca51..e1db3ce16d 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -54,7 +54,7 @@ private static function generate_synopsis() { continue; $synopsis = ( true === $details['runtime'] ) - ? "--$key/--no-$key" + ? "--[no-]$key" : "--$key" . $details['runtime']; $cur_len = strlen( $synopsis ); From 2a162669c958675b3163b61f609edb6a33fd32e1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Feb 2013 20:39:24 +0200 Subject: [PATCH 1288/4858] use `wp core version` instead of `wp post list` to check if the install was successful. --- features/core.feature | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index ea5910fa08..fe5dbd3951 100644 --- a/features/core.feature +++ b/features/core.feature @@ -59,11 +59,9 @@ Feature: Manage WordPress installation When I run `wp core install` Then the return code should be 0 - When I run `wp post list --ids` - Then STDOUT should be: - """ - 1 - """ + When I run `wp core version` + Then it should run without errors + And STDOUT should not be empty Scenario: Full install Given WP install From 5775f17c98ba825a5829a798cee9969bd927f02d Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Thu, 28 Feb 2013 10:42:31 +0100 Subject: [PATCH 1289/4858] made dbpass parameter optional for core config command --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 6176571e83..66aa421444 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -45,12 +45,12 @@ public function download( $args, $assoc_args ) { /** * Set up a wp-config.php file. * - * @synopsis --dbname=<name> --dbuser=<user> --dbpass=<password> [--dbhost=<host>] [--dbprefix=<prefix>] + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] */ public function config( $args, $assoc_args ) { $_POST['dbname'] = $assoc_args['dbname']; $_POST['uname'] = $assoc_args['dbuser']; - $_POST['pwd'] = $assoc_args['dbpass']; + $_POST['pwd'] = isset( $assoc_args['dbpass'] ) ? $assoc_args['dbpass'] : ''; $_POST['dbhost'] = isset( $assoc_args['dbhost'] ) ? $assoc_args['dbhost'] : 'localhost'; $_POST['prefix'] = isset( $assoc_args['dbprefix'] ) ? $assoc_args['dbprefix'] : 'wp_'; From a0dff2f22a28b26767e43229f544106e0f972683 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Thu, 28 Feb 2013 10:44:43 +0100 Subject: [PATCH 1290/4858] regenerated the man page for core config command --- man/core-config.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/core-config.1 b/man/core-config.1 index 0e53dd338f..47e893b7b7 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -7,7 +7,7 @@ \fBwp\-core\-config\fR \- Set up a wp\-config\.php file\. . .SH "SYNOPSIS" -wp core config \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR \-\-dbpass=\fIpassword\fR [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] +wp core config \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\-\-dbpass=\fIpassword\fR] [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] . .SH "OPTIONS" . From 85e10be065a462d44df0a58c934675abb46bd0c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Feb 2013 20:34:21 +0200 Subject: [PATCH 1291/4858] delete submodules --- .gitmodules | 6 ------ php/mustache | 1 - php/php-cli-tools | 1 - 3 files changed, 8 deletions(-) delete mode 100644 .gitmodules delete mode 160000 php/mustache delete mode 160000 php/php-cli-tools diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 05f4715b98..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "php/php-cli-tools"] - path = php/php-cli-tools - url = git://github.com/wp-cli/php-cli-tools.git -[submodule "php/mustache"] - path = php/mustache - url = git://github.com/bobthecow/mustache.php.git diff --git a/php/mustache b/php/mustache deleted file mode 160000 index d99be3444e..0000000000 --- a/php/mustache +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d99be3444e5b2f0fb605941d7e692d3b5159360c diff --git a/php/php-cli-tools b/php/php-cli-tools deleted file mode 160000 index f3def25b86..0000000000 --- a/php/php-cli-tools +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f3def25b862bb0c5330a6347c6c04d62a99eb217 From 41cd47f4053e3fbf51c05a15ab6810d4aef1a923 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Feb 2013 20:38:01 +0200 Subject: [PATCH 1292/4858] add composer.lock --- .gitignore | 1 - composer.lock | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index abb9c75a11..0e7aef9033 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /vendor -/composer.lock /phpunit.xml diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..c395f5b8ef --- /dev/null +++ b/composer.lock @@ -0,0 +1,98 @@ +{ + "hash": "dd697246fcbfe8ce5e5654c9898ae115", + "packages": [ + { + "name": "mustache/mustache", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/mustache.php", + "reference": "v2.0.2" + }, + "dist": { + "type": "zip", + "url": "https://github.com/bobthecow/mustache.php/zipball/v2.0.2", + "reference": "v2.0.2", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "type": "library", + "autoload": { + "psr-0": { + "Mustache": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "A Mustache implementation in PHP.", + "homepage": "https://github.com/bobthecow/mustache.php", + "keywords": [ + "mustache", + "templating" + ], + "time": "2012-09-12 09:13:06" + }, + { + "name": "wp-cli/php-cli-tools", + "version": "dev-master", + "source": { + "type": "git", + "url": "http://github.com/wp-cli/php-cli-tools", + "reference": "f3def25b862bb0c5330a6347c6c04d62a99eb217" + }, + "dist": { + "type": "zip", + "url": "https://github.com/wp-cli/php-cli-tools/archive/f3def25b862bb0c5330a6347c6c04d62a99eb217.zip", + "reference": "f3def25b862bb0c5330a6347c6c04d62a99eb217", + "shasum": "" + }, + "require": { + "php": ">= 5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "cli": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Logsdon", + "email": "jlogsdon@php.net", + "role": "Developer" + } + ], + "description": "Console utilities for PHP", + "homepage": "http://github.com/jlogsdon/php-cli-tools", + "keywords": [ + "cli", + "console" + ], + "time": "2012-12-13 22:18:34" + } + ], + "packages-dev": null, + "aliases": [ + + ], + "minimum-stability": "dev", + "stability-flags": { + "wp-cli/php-cli-tools": 20, + "behat/behat": 0 + } +} From ec82ee6abc981084ac95b691873efdbfd160b0e2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Feb 2013 20:58:24 +0200 Subject: [PATCH 1293/4858] travis: no more submodules to initialize --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index dfe12aa7af..bb6c74de77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,6 @@ env: - WP_VERSION=3.4.2 WP_MULTISITE=0 - WP_VERSION=3.4.2 WP_MULTISITE=1 -before_install: - - git submodule update --init --recursive - before_script: # install dependencies - curl -sS https://getcomposer.org/installer | php From 853323672ea45a425363cde82d0ade6e83e09177 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Feb 2013 21:25:07 +0200 Subject: [PATCH 1294/4858] install and use Composer in utils/dev-build --- utils/dev-build | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utils/dev-build b/utils/dev-build index b8ad05819f..bffbaf168b 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -1,5 +1,15 @@ #!/usr/bin/env bash +# install Composer +command -v composer > /dev/null || { + curl -sS https://getcomposer.org/installer | php + mv composer.phar /usr/local/bin/composer +} + +# install dependencies +composer install + +# add symlink to wp binary for dir in /usr/bin /usr/local/bin; do if [ -d $dir ]; then ln -sf $(pwd)/bin/wp $dir/wp @@ -7,6 +17,7 @@ for dir in /usr/bin /usr/local/bin; do fi done +# install bash completion file for dir in /etc/bash_completion.d /usr/local/etc/bash_completion.d; do if [ -d $dir ]; then ln -sf $(pwd)/utils/wp-completion.bash $dir/wp From 1317f6b81d8464022a49aae7c96f097cb3da37fc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Feb 2013 21:38:57 +0200 Subject: [PATCH 1295/4858] remove loading from submodules --- php/utils.php | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/php/utils.php b/php/utils.php index ba2882aa72..49834755ce 100644 --- a/php/utils.php +++ b/php/utils.php @@ -23,34 +23,9 @@ function load_dependencies() { } } - if ( !$has_autoload ) { - include WP_CLI_ROOT . 'php-cli-tools/lib/cli/cli.php'; - \cli\register_autoload(); - - include WP_CLI_ROOT . 'mustache/src/Mustache/Autoloader.php'; - \Mustache_Autoloader::register(); - - register_autoload(); - } - include WP_CLI_ROOT . 'Spyc.php'; } -function register_autoload() { - spl_autoload_register( function($class) { - // Only attempt to load classes in our namespace - if ( 0 !== strpos( $class, 'WP_CLI\\' ) ) { - return; - } - - $path = WP_CLI_ROOT . str_replace( '\\', DIRECTORY_SEPARATOR, $class ) . '.php'; - - if ( is_file( $path ) ) { - require_once $path; - } - } ); -} - function get_config_spec() { $spec = include __DIR__ . '/config-spec.php'; From 07c32925eaba785e179fdcf5c787a8f4580b4c3f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Feb 2013 21:54:55 +0200 Subject: [PATCH 1296/4858] update make-phar.php to use vendor dir --- utils/make-phar.php | 48 +++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index b928bd1081..96c66abb8f 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -28,31 +28,45 @@ function add_file( $phar, $path ) { $phar->startBuffering(); -$ignored_paths = array( - '/mustache/bin/', - '/mustache/test/', - '/mustache/vendor/', - '/php-cli-tools/examples/' -); - +// php files foreach ( get_iterator( './php' ) as $path ) { - foreach ( $ignored_paths as $ignore ) { - if ( strpos( $path, $ignore ) ) - continue 2; - } - if ( !preg_match( '/\.php$/', $path ) ) continue; add_file( $phar, $path ); } -foreach ( get_iterator( './templates' ) as $path ) { - add_file( $phar, $path ); +// non-php files +$additional_dirs = array( + './templates', + './man' +); + +foreach ( $additional_dirs as $dir ) { + foreach ( get_iterator( $dir ) as $path ) { + add_file( $phar, $path ); + } } -foreach ( get_iterator( './man' ) as $path ) { - add_file( $phar, $path ); +// dependencies +$ignored_paths = array( + '/.git', +); + +$vendor_dirs = array( + './vendor/mustache', + './vendor/wp-cli', +); + +foreach ( $vendor_dirs as $vendor_dir ) { + foreach ( get_iterator( $vendor_dir ) as $path ) { + foreach ( $ignored_paths as $ignore ) { + if ( strpos( $path, $ignore ) ) + continue 2; + } + + add_file( $phar, $path ); + } } $phar->setStub( <<<EOB @@ -67,5 +81,5 @@ function add_file( $phar, $path ) { $phar->stopBuffering(); -echo "\nGenerated " . DEST_PATH . "\n"; +echo "Generated " . DEST_PATH . "\n"; From 4cbc752a12e02ed33deda4801237a5377aad1683 Mon Sep 17 00:00:00 2001 From: Gleb Kalinin <glebis@gmail.com> Date: Sat, 2 Mar 2013 00:17:57 +0400 Subject: [PATCH 1297/4858] Adds scaffolding for child theme (based on Twenty Twelve by default) Apart from creating an empty underscore theme, it would be cool to be able to create an empty child theme. I've implemented a very basic command for this. It created a theme folder and style.css which imports parent theme's styles --- php/commands/scaffold.php | 33 +++++++++++++++++++++++++++++++++ templates/child_theme.mustache | 11 +++++++++++ 2 files changed, 44 insertions(+) create mode 100644 templates/child_theme.mustache diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 75b7a22517..b637201485 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -146,6 +146,39 @@ function _s( $args, $assoc_args ) { } + /** + * Generate empty child theme (twentytwelve by default). + * + * @synopsis <slug> [--theme_name=<title>] [--parent_theme=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] + */ + function child_theme( $args, $assoc_args ) { + + $theme_slug = $args[0]; + $theme_path = WP_CONTENT_DIR . "/themes"; + + $data = wp_parse_args( $assoc_args, array( + 'theme_name' => ucfirst( $theme_slug ), + 'parent_theme' => 'twentytwelve', + 'author' => "Me", + 'author_uri' => "", + 'theme_uri' => "" + ) ); + + $data['theme_description'] = ucfirst($data['parent_theme']) . " child theme. "; + + + $theme_dir = $theme_path . "/$theme_slug"; + $theme_style_path = "$theme_dir/style.css"; + + $this->create_file( $theme_style_path, $this->render( 'child_theme.mustache', $data ) ); + + WP_CLI::success( "Created $theme_dir" ); + + + if ( isset( $assoc_args['activate'] ) ) + WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + + } private function get_output_path( $assoc_args, $subdir ) { extract( $assoc_args, EXTR_SKIP ); diff --git a/templates/child_theme.mustache b/templates/child_theme.mustache new file mode 100644 index 0000000000..a6b182b828 --- /dev/null +++ b/templates/child_theme.mustache @@ -0,0 +1,11 @@ +/* +Theme Name: {{theme_name}} +Theme URI: {{theme_uri}} +Description: {{theme_description}} +Author: {{author}} +Author URI: {{author_uri}} +Template: {{parent_theme}} +Version: 0.1.0 +*/ + +@import '../{{parent_theme}}/style.css'; \ No newline at end of file From 047e890a29f69964c15e3ceb112ae434598f44b2 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 1 Mar 2013 22:07:58 +0100 Subject: [PATCH 1298/4858] Optimizing looping and unlinking of the resized images --- php/commands/media.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index fafdf11b57..0862cc8bd6 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -99,27 +99,32 @@ private function _process_regeneration( $id ) { $imageName = sprintf( "%s-", $dirPath[ count( $dirPath ) - 1 ] ); unset( $dirPath[ count( $dirPath ) - 1 ] ); $dirPath = sprintf( "%s%s", implode( DIRECTORY_SEPARATOR, $dirPath ), DIRECTORY_SEPARATOR ); - + // Read and delete files $dir = opendir( $dirPath ); $files = array(); while ( $file = readdir( $dir ) ) { + if ( !( strrpos( $file, $imageName ) === false ) ) { + $thumbnail = explode( $imageName, $file ); $filename = $thumbnail[ 1 ]; + //If we got the original / full image if ( "" == $thumbnail[ 0 ] ) { - $thumbnailFormat = substr( $filename, -4 ); - $thumbnail = substr( $filename, 0, strlen( $filename ) - 4 ); + preg_match('/\.[^\.]+$/i', $file, $ext); + $thumbnailFormat = $ext[0]; + $thumbnail = basename( $file, $thumbnailFormat ); - $sizes = explode( 'x', $thumbnail ); - $width = $sizes[0]; - $height = $sizes[1]; + $sizes = explode( 'x', $thumbnail ); + // If not cropped by WP if ( 2 == count( $sizes ) ) { + $width = $sizes[0]; + $height = $sizes[1]; if ( is_numeric( $width ) && is_numeric( $height ) ) { WP_CLI::line( "Thumbnail: {$width} x {$height} was deleted." ); - @unlink( $dirPath . $imageName . $width . 'x' . $thumbnail[ 1 ] . $thumbnailFormat ); + @unlink( $dirPath . $imageName . $width . 'x' . $thumbnail . $thumbnailFormat ); } } } From db585a5fb0344bc1b27269ada86dc4294053fb71 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Mar 2013 13:21:39 +0200 Subject: [PATCH 1299/4858] show error message when vendor directory is missing see #336 --- php/utils.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/utils.php b/php/utils.php index 49834755ce..efd1411cb7 100644 --- a/php/utils.php +++ b/php/utils.php @@ -23,6 +23,11 @@ function load_dependencies() { } } + if ( !$has_autoload ) { + fputs( STDERR, "Internal error: Can't find Composer autoloader.\n" ); + exit(2); + } + include WP_CLI_ROOT . 'Spyc.php'; } From c69b7a45cff56923079cd2d6610ab2dceb256037 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Mar 2013 01:04:03 +0200 Subject: [PATCH 1300/4858] leave minimum stability to stable --- composer.json | 3 +- composer.lock | 842 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 838 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 2acd3fad1c..46ed157254 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,5 @@ }, "autoload": { "psr-0": { "WP_CLI": "php" } - }, - "minimum-stability": "dev" + } } diff --git a/composer.lock b/composer.lock index c395f5b8ef..bdbb23f0b8 100644 --- a/composer.lock +++ b/composer.lock @@ -1,5 +1,5 @@ { - "hash": "dd697246fcbfe8ce5e5654c9898ae115", + "hash": "f2b06fd19e26795775358b054c6fb09d", "packages": [ { "name": "mustache/mustache", @@ -48,12 +48,12 @@ "version": "dev-master", "source": { "type": "git", - "url": "http://github.com/wp-cli/php-cli-tools", + "url": "https://github.com/wp-cli/php-cli-tools.git", "reference": "f3def25b862bb0c5330a6347c6c04d62a99eb217" }, "dist": { "type": "zip", - "url": "https://github.com/wp-cli/php-cli-tools/archive/f3def25b862bb0c5330a6347c6c04d62a99eb217.zip", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/f3def25b862bb0c5330a6347c6c04d62a99eb217", "reference": "f3def25b862bb0c5330a6347c6c04d62a99eb217", "shasum": "" }, @@ -86,11 +86,843 @@ "time": "2012-12-13 22:18:34" } ], - "packages-dev": null, + "packages-dev": [ + { + "name": "behat/behat", + "version": "v2.4.5", + "source": { + "type": "git", + "url": "git://github.com/Behat/Behat.git", + "reference": "v2.4.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/Behat/Behat/archive/v2.4.5.zip", + "reference": "v2.4.5", + "shasum": "" + }, + "require": { + "behat/gherkin": ">=2.2.4,<2.3-dev", + "php": ">=5.3.1", + "symfony/config": ">=2.0,<2.3-dev", + "symfony/console": ">=2.0,<2.3-dev", + "symfony/dependency-injection": ">=2.0,<2.3-dev", + "symfony/event-dispatcher": ">=2.0,<2.3-dev", + "symfony/finder": ">=2.0,<2.3-dev", + "symfony/translation": ">=2.0,<2.3-dev", + "symfony/yaml": ">=2.0,<2.3-dev" + }, + "suggest": { + "behat/mink-extension": "for integration with Mink testing framework", + "behat/symfony2-extension": "for integration with Symfony2 web framework", + "behat/yii-extension": "for integration with Yii web framework" + }, + "bin": [ + "bin/behat" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "2.4-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Behat": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Scenario-oriented BDD framework for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Symfony2" + ], + "time": "2013-01-27 14:45:41" + }, + { + "name": "behat/gherkin", + "version": "v2.2.9", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "v2.2.9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/v2.2.9", + "reference": "v2.2.9", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/finder": ">=2.0,<2.4-dev" + }, + "require-dev": { + "symfony/config": ">=2.0,<2.4-dev", + "symfony/translation": ">=2.0,<2.4-dev", + "symfony/yaml": ">=2.0,<2.4-dev" + }, + "suggest": { + "symfony/config": "If you want to use Config component to manage resources", + "symfony/translation": "If you want to use Symfony2 translations adapter", + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "DSL", + "Symfony2", + "parser" + ], + "time": "2013-03-02 10:38:40" + }, + { + "name": "phpunit/php-code-coverage", + "version": "1.2.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "1.2.9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.9", + "reference": "1.2.9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": ">=1.3.0@stable", + "phpunit/php-text-template": ">=1.1.1@stable", + "phpunit/php-token-stream": ">=1.1.3@stable" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.0.5" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2013-02-26 18:55:56" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "1.3.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", + "reference": "1.3.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2012-10-11 04:44:38" + }, + { + "name": "phpunit/php-text-template", + "version": "1.1.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-text-template.git", + "reference": "1.1.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", + "reference": "1.1.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2012-10-31 11:15:28" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-timer.git", + "reference": "1.0.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", + "reference": "1.0.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "timer" + ], + "time": "2012-10-11 04:45:58" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.1.5", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1.1.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", + "reference": "1.1.5", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "tokenizer" + ], + "time": "2012-10-11 04:47:14" + }, + { + "name": "phpunit/phpunit", + "version": "3.7.15", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3.7.15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.15", + "reference": "3.7.15", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": ">=1.2.1,<1.3.0", + "phpunit/php-file-iterator": ">=1.3.1", + "phpunit/php-text-template": ">=1.1.1", + "phpunit/php-timer": ">=1.0.2,<1.1.0", + "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", + "symfony/yaml": ">=2.2.0" + }, + "require-dev": { + "pear-pear/pear": "1.9.4" + }, + "suggest": { + "ext-json": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "phpunit/php-invoker": ">=1.1.0,<1.2.0" + }, + "bin": [ + "composer/bin/phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2013-03-01 11:55:06" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "1.2.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "1.2.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip", + "reference": "1.2.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-text-template": ">=1.1.1@stable" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2013-01-13 10:24:48" + }, + { + "name": "symfony/config", + "version": "v2.2.0", + "target-dir": "Symfony/Component/Config", + "source": { + "type": "git", + "url": "https://github.com/symfony/Config.git", + "reference": "v2.2.0-RC3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.0-RC3", + "reference": "v2.2.0-RC3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "http://symfony.com", + "time": "2013-02-17 12:27:42" + }, + { + "name": "symfony/console", + "version": "v2.2.0", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "v2.2.0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.0", + "reference": "v2.2.0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2013-03-01 06:43:14" + }, + { + "name": "symfony/dependency-injection", + "version": "v2.2.0", + "target-dir": "Symfony/Component/DependencyInjection", + "source": { + "type": "git", + "url": "https://github.com/symfony/DependencyInjection.git", + "reference": "v2.2.0-RC3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.0-RC3", + "reference": "v2.2.0-RC3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/config": ">=2.2,<2.3-dev", + "symfony/yaml": ">=2.0,<3.0" + }, + "suggest": { + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\DependencyInjection\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "http://symfony.com", + "time": "2013-02-11 11:43:49" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.2.0", + "target-dir": "Symfony/Component/EventDispatcher", + "source": { + "type": "git", + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "v2.2.0-RC3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.0-RC3", + "reference": "v2.2.0-RC3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/dependency-injection": ">=2.0,<3.0" + }, + "suggest": { + "symfony/dependency-injection": "2.2.*", + "symfony/http-kernel": "2.2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2013-02-11 11:26:43" + }, + { + "name": "symfony/finder", + "version": "v2.2.0", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "v2.2.0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.2.0", + "reference": "v2.2.0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Finder\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "http://symfony.com", + "time": "2013-02-28 14:06:36" + }, + { + "name": "symfony/translation", + "version": "v2.2.0", + "target-dir": "Symfony/Component/Translation", + "source": { + "type": "git", + "url": "https://github.com/symfony/Translation.git", + "reference": "v2.2.0-RC3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.0-RC3", + "reference": "v2.2.0-RC3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/config": ">=2.0,<2.3-dev", + "symfony/yaml": ">=2.2,<3.0" + }, + "suggest": { + "symfony/config": "2.2.*", + "symfony/yaml": "2.2.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "http://symfony.com", + "time": "2013-02-08 16:10:57" + }, + { + "name": "symfony/yaml", + "version": "v2.2.0", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "v2.2.0-RC3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.0-RC3", + "reference": "v2.2.0-RC3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2013-01-27 16:49:19" + } + ], "aliases": [ ], - "minimum-stability": "dev", + "minimum-stability": "stable", "stability-flags": { "wp-cli/php-cli-tools": 20, "behat/behat": 0 From 61a81205df1accf69d3d5d0979fa5f389070438f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Mar 2013 02:28:38 +0200 Subject: [PATCH 1301/4858] remove unnecessary loading of PHPUnit/Autoload.php --- features/bootstrap/FeatureContext.php | 1 - 1 file changed, 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 57c05cda10..80bcba82f7 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -4,7 +4,6 @@ Behat\Behat\Context\TranslatedContextInterface, Behat\Behat\Context\BehatContext; -require_once 'PHPUnit/Autoload.php'; require_once 'PHPUnit/Framework/Assert/Functions.php'; require_once __DIR__ . '/../../php/utils.php'; From 2fcb19477aa5839814fb3a6f67a0582ca25b20ae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Mar 2013 02:39:22 +0200 Subject: [PATCH 1302/4858] don't check if the cache directory exists `core download` takes care of it --- features/bootstrap/FeatureContext.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 80bcba82f7..bbdb336911 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -179,12 +179,10 @@ public function download_wordpress_files() { // We cache the results of "wp core download" to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - if ( !file_exists( $cache_dir ) ) { - mkdir( $cache_dir ); - $this->run( 'core download' . \WP_CLI\Utils\assoc_args_to_str( array( - 'path' => $cache_dir - ) ) ); - } + + $r = $this->run( 'core download' . \WP_CLI\Utils\assoc_args_to_str( array( + 'path' => $cache_dir + ) ) ); exec( sprintf( "cp -r '%s/'* '%s/'", $cache_dir, $this->install_dir ) ); } From ea8b72394eaf08eb6ac25dcb2f68c122fa4323fa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 2 Mar 2013 20:00:41 +0200 Subject: [PATCH 1303/4858] make update-phar generate a checksum [ci skip] --- utils/update-phar | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/utils/update-phar b/utils/update-phar index 8105be91de..0f208844cf 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -5,10 +5,12 @@ set -ex current_rev=$(git rev-parse HEAD) current_rev=${current_rev:0:10} +# generate archive php -dphar.readonly=0 ./utils/make-phar.php ../wp-cli-packages/phar/wp-cli.phar --quiet cd ../wp-cli-packages +# check which wp-cli commit the previous Phar archive was based on new_commit_subj="update wp-cli.phar to $current_rev" current_commit_subj=$(git show -s --pretty=format:%s HEAD) @@ -18,7 +20,12 @@ if [ "$new_commit_subj" = "$current_commit_subj" ]; then exit 1 fi -git add phar/wp-cli.phar +fname="phar/wp-cli.phar" + +# generate md5 checksum +md5sum $fname | cut -d ' ' -f 1 > $fname.md5 + +git add $fname $fname.md5 git commit -m "$new_commit_subj" From f4ef6a0c2c9a081dbc22f1d938602f32d7326a51 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 17:10:00 +0100 Subject: [PATCH 1304/4858] Removed use of $error --- php/commands/media.php | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 0862cc8bd6..e25cd4d611 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -6,9 +6,7 @@ * @package wp-cli */ class Media_Command extends WP_CLI_Command { - - var $errors = false; - + function __construct() { WP_Filesystem(); } @@ -49,23 +47,18 @@ function regenerate( $args, $assoc_args = array() ) { WP_CLI::line( 'Found ' . count( $images ) . ' pictures to regenerate!' ); - foreach ( $images as $image ) + foreach ( $images as $image ) { $this->_process_regeneration( $image->ID ); + } - if ( $this->errors ) - WP_CLI::error( 'Finished regenerating images - however, there were some errors throughout.' ); - else - WP_CLI::success( 'Finished - without any errors either!' ); + WP_CLI::success( 'Finished regenerating images' ); } private function _process_regeneration( $id ) { - // Don't break the JSON result - @error_reporting( 0 ); $image = get_post( $id ); if ( !$image || 'attachment' != $image->post_type || 'image/' != substr( $image->post_mime_type, 0, 6 ) ) { - $this->errors = true; WP_CLI::line( "FAILED: {$image->post_title} - invalid image ID" ); return; } @@ -73,7 +66,6 @@ private function _process_regeneration( $id ) { $fullsizepath = get_attached_file( $image->ID ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - $this->errors = true; WP_CLI::line( "FAILED: {$image->post_title} - Can't find it $fullsizepath" ); return; } @@ -139,7 +131,6 @@ private function _process_regeneration( $id ) { } if ( empty( $metadata ) ) { - $this->errors = true; WP_CLI::line( 'Unknown failure reason.' ); return; } From 6e173a8c06436564464d7c4fc8e17c60eecd7aa9 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 17:10:23 +0100 Subject: [PATCH 1305/4858] Removed settings timeout --- php/commands/media.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index e25cd4d611..b1bd073fff 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -70,9 +70,6 @@ private function _process_regeneration( $id ) { return; } - // 5 minutes per image should be PLENTY - @set_time_limit( 900 ); - $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); From 03979a48356c4061d412aa038009c4e93d3f10cc Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 17:16:34 +0100 Subject: [PATCH 1306/4858] Use concate instead of sprintf --- php/commands/media.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index b1bd073fff..a9b6c9a3e3 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -79,15 +79,10 @@ private function _process_regeneration( $id ) { unset( $array_file[ count( $array_file ) - 1 ] ); $imagePath = implode( DIRECTORY_SEPARATOR, $array_path ) . DIRECTORY_SEPARATOR . implode( '.', $array_file ); - - - /** - * Continue - */ $dirPath = explode( DIRECTORY_SEPARATOR, $imagePath ); - $imageName = sprintf( "%s-", $dirPath[ count( $dirPath ) - 1 ] ); + $imageName = $dirPath[ count( $dirPath ) - 1 ] . "-"; unset( $dirPath[ count( $dirPath ) - 1 ] ); - $dirPath = sprintf( "%s%s", implode( DIRECTORY_SEPARATOR, $dirPath ), DIRECTORY_SEPARATOR ); + $dirPath = implode( DIRECTORY_SEPARATOR, $dirPath ) . DIRECTORY_SEPARATOR; // Read and delete files $dir = opendir( $dirPath ); From 4cdfc0e061c30fa9423ac2535fc4330c3c600a88 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 17:17:45 +0100 Subject: [PATCH 1307/4858] Using WP_CLI::warning --- php/commands/media.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index a9b6c9a3e3..67ac71d58e 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -59,14 +59,14 @@ private function _process_regeneration( $id ) { $image = get_post( $id ); if ( !$image || 'attachment' != $image->post_type || 'image/' != substr( $image->post_mime_type, 0, 6 ) ) { - WP_CLI::line( "FAILED: {$image->post_title} - invalid image ID" ); + WP_CLI::warning( "FAILED: {$image->post_title} - invalid image ID" ); return; } $fullsizepath = get_attached_file( $image->ID ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - WP_CLI::line( "FAILED: {$image->post_title} - Can't find it $fullsizepath" ); + WP_CLI::warning( "FAILED: {$image->post_title} - Can't find it $fullsizepath" ); return; } From 798aeac310e0a4d175e1265f656e3c587a83956f Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 17:20:12 +0100 Subject: [PATCH 1308/4858] Using WP_CLI::warning --- php/commands/media.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 67ac71d58e..0380849829 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -59,14 +59,14 @@ private function _process_regeneration( $id ) { $image = get_post( $id ); if ( !$image || 'attachment' != $image->post_type || 'image/' != substr( $image->post_mime_type, 0, 6 ) ) { - WP_CLI::warning( "FAILED: {$image->post_title} - invalid image ID" ); + WP_CLI::warning( "{$image->post_title} - invalid image ID" ); return; } $fullsizepath = get_attached_file( $image->ID ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - WP_CLI::warning( "FAILED: {$image->post_title} - Can't find it $fullsizepath" ); + WP_CLI::warning( "{$image->post_title} - Can't find it $fullsizepath" ); return; } @@ -118,12 +118,12 @@ private function _process_regeneration( $id ) { $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); if ( is_wp_error( $metadata ) ) { - WP_CLI::line( $metadata->get_error_message() ); + WP_CLI::warning( $metadata->get_error_message() ); return; } if ( empty( $metadata ) ) { - WP_CLI::line( 'Unknown failure reason.' ); + WP_CLI::warning( 'Unknown failure reason.' ); return; } wp_update_attachment_metadata( $image->ID, $metadata ); From eb904e498318025e65cf3e6f830ac03f543cdabe Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 17:36:14 +0100 Subject: [PATCH 1309/4858] Polished some feedback messages --- php/commands/media.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 0380849829..ffe9f53234 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -59,14 +59,14 @@ private function _process_regeneration( $id ) { $image = get_post( $id ); if ( !$image || 'attachment' != $image->post_type || 'image/' != substr( $image->post_mime_type, 0, 6 ) ) { - WP_CLI::warning( "{$image->post_title} - invalid image ID" ); + WP_CLI::warning( "{$image->post_title} - invalid image ID." ); return; } $fullsizepath = get_attached_file( $image->ID ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - WP_CLI::warning( "{$image->post_title} - Can't find it $fullsizepath" ); + WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); return; } @@ -123,11 +123,11 @@ private function _process_regeneration( $id ) { } if ( empty( $metadata ) ) { - WP_CLI::warning( 'Unknown failure reason.' ); + WP_CLI::warning( "Couldn't regenerate image." ); return; } wp_update_attachment_metadata( $image->ID, $metadata ); - WP_CLI::success( esc_html( get_the_title( $image->ID ) ) . " (ID {$image->ID}): All thumbnails were successfully regenerated in " . timer_stop() . " seconds " ); + WP_CLI::success( esc_html( get_the_title( $image->ID ) ) . " (ID {$image->ID}): All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); } } From 9ff48b6f2259151b2c0f493e93889ccc0a374003 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 18:10:00 +0100 Subject: [PATCH 1310/4858] Cleaned up unused code --- php/commands/media.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index ffe9f53234..8bfb5f3455 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -69,12 +69,10 @@ private function _process_regeneration( $id ) { WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); return; } - + //wp_upload_dir() $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); - - $imageFormat = $array_file[ count( $array_file ) - 1 ]; - + unset( $array_path[ count( $array_path ) - 1 ] ); unset( $array_file[ count( $array_file ) - 1 ] ); From 8dba6eb248e367502012c5ab19ba2419fa131947 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 18:40:23 +0100 Subject: [PATCH 1311/4858] Better grammar --- php/commands/media.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 8bfb5f3455..77e6f7e89b 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -37,7 +37,7 @@ function regenerate( $args, $assoc_args = array() ) { if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { if ( $id ) { - WP_CLI::error( "Unable to find the image. Are you sure some it exists?" ); + WP_CLI::error( "Unable to find the image. Are you sure it exists?" ); } else { WP_CLI::error( "Unable to find any images. Are you sure some exist?" ); } @@ -45,7 +45,7 @@ function regenerate( $args, $assoc_args = array() ) { return; } - WP_CLI::line( 'Found ' . count( $images ) . ' pictures to regenerate!' ); + WP_CLI::line( 'Found ' . count( $images ) . ' images to regenerate.' ); foreach ( $images as $image ) { $this->_process_regeneration( $image->ID ); @@ -72,7 +72,7 @@ private function _process_regeneration( $id ) { //wp_upload_dir() $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); - + unset( $array_path[ count( $array_path ) - 1 ] ); unset( $array_file[ count( $array_file ) - 1 ] ); From cd49ab9aa939a1ca028133255103cf9842074842 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 19:26:03 +0100 Subject: [PATCH 1312/4858] Fixed variable name so thumbnails get unlinked again --- php/commands/media.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 77e6f7e89b..05ad83a9d8 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -69,7 +69,7 @@ private function _process_regeneration( $id ) { WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); return; } - //wp_upload_dir() + $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); @@ -96,7 +96,7 @@ private function _process_regeneration( $id ) { if ( "" == $thumbnail[ 0 ] ) { preg_match('/\.[^\.]+$/i', $file, $ext); $thumbnailFormat = $ext[0]; - $thumbnail = basename( $file, $thumbnailFormat ); + $thumbnail = basename( $filename, $thumbnailFormat ); $sizes = explode( 'x', $thumbnail ); From 7b9033d8f6c819bb1b4a17288da5898fe27c7ec3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Mar 2013 23:26:24 +0200 Subject: [PATCH 1313/4858] install composer dependencies in local-build too see #342 --- utils/local-build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/local-build b/utils/local-build index fab82fddf7..4fd798d20d 100755 --- a/utils/local-build +++ b/utils/local-build @@ -10,6 +10,10 @@ if [ "$BASH_SOURCE" = "$0" ]; then exit 1 fi +[ -f composer.phar ] || curl -sS https://getcomposer.org/installer | php + +php composer.phar install + DIR=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) alias wp='$DIR/../bin/wp' From 2124bedecfaa9a069404ebdee99001c4b8b328f9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 3 Mar 2013 23:44:16 +0200 Subject: [PATCH 1314/4858] make local-build embedable into .bashrc again see #342 --- utils/local-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/local-build b/utils/local-build index 4fd798d20d..9d92ea8758 100755 --- a/utils/local-build +++ b/utils/local-build @@ -12,7 +12,7 @@ fi [ -f composer.phar ] || curl -sS https://getcomposer.org/installer | php -php composer.phar install +[ -d vendor/ ] || php composer.phar install DIR=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) From 11d8a246b5b40e8e6b14c56abe823e0725931656 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 22:59:18 +0100 Subject: [PATCH 1315/4858] Added position paramater `wp media regenerate 21 45 56` and better messages --- php/commands/media.php | 49 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 05ad83a9d8..eff128ef70 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -14,44 +14,38 @@ function __construct() { /** * Regenerate thumbnail(s) * - * @synopsis [--id=<id>] [--yes] + * @synopsis <id>... [--yes] * props @benmay & @Viper007Bond */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; - - $vars = wp_parse_args( $assoc_args, array( - 'id' => false - ) ); - - extract($vars, EXTR_SKIP); - + $count = 0; + // If id is given, skip confirm because it is only one file - if( !empty( $id ) ) { + if( !empty( $args ) ) { $assoc_args['yes'] = true; } WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); - $where_clause = ( $id ) ? "AND ID = $id" : ''; + $where_clause = ( !empty( $args ) ) ? "AND ID = " . implode(" OR ID = ", $args) . " " : ''; - if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC" ) ) { - if ( $id ) { - WP_CLI::error( "Unable to find the image. Are you sure it exists?" ); - } else { - WP_CLI::error( "Unable to find any images. Are you sure some exist?" ); - } - - return; + if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC", ARRAY_A ) ) { + //No images, so all keys in $args are not found within WP + WP_CLI::error( $this->_not_found_message( $args ) ); } - - WP_CLI::line( 'Found ' . count( $images ) . ' images to regenerate.' ); + $count = count($images); + + WP_CLI::line( "Found {$count} " . ngettext('image', 'images', $count) . " to regenerate." ); + + $not_found = array_diff( $args, wp_list_pluck( $images, 'ID' ) ); + WP_CLI::warning( $this->_not_found_message( $not_found ) ); foreach ( $images as $image ) { - $this->_process_regeneration( $image->ID ); + $this->_process_regeneration( $image['ID'] ); } - WP_CLI::success( 'Finished regenerating images' ); + WP_CLI::success( "Finished regenerating " . ngettext('the image', 'all images', $count) . "."); } private function _process_regeneration( $id ) { @@ -69,7 +63,9 @@ private function _process_regeneration( $id ) { WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); return; } - + + WP_CLI::line( "Start processing of \"" . get_the_title( $image->ID ) . " (ID: {$image->ID})\"" ); + $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); @@ -125,7 +121,12 @@ private function _process_regeneration( $id ) { return; } wp_update_attachment_metadata( $image->ID, $metadata ); - WP_CLI::success( esc_html( get_the_title( $image->ID ) ) . " (ID {$image->ID}): All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); + WP_CLI::success( "{$image->ID} All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); + } + + private function _not_found_message( $not_found_ids ){ + $count = count($not_found_ids); + return "Unable to find the " . ngettext('image', 'images', $count) . " (" . implode(", ", $not_found_ids) . "). Are you sure " . ngettext('it', 'they', $count) . " " . ngettext('exist', 'exists', $count) . "?"; } } From 7adeca7ecc3741870818cac2627bc3a2953ff3d8 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 23:00:57 +0100 Subject: [PATCH 1316/4858] Polished message --- php/commands/media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index eff128ef70..4f9cd9d909 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -121,7 +121,7 @@ private function _process_regeneration( $id ) { return; } wp_update_attachment_metadata( $image->ID, $metadata ); - WP_CLI::success( "{$image->ID} All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); + WP_CLI::success( "All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); } private function _not_found_message( $not_found_ids ){ From 91d80ecc28ea648eef6c7ec4355d34faab757225 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 3 Mar 2013 23:16:44 +0100 Subject: [PATCH 1317/4858] renamed parameter --- php/commands/media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 4f9cd9d909..e2de098e08 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -14,7 +14,7 @@ function __construct() { /** * Regenerate thumbnail(s) * - * @synopsis <id>... [--yes] + * @synopsis <attachment-id>... [--yes] * props @benmay & @Viper007Bond */ function regenerate( $args, $assoc_args = array() ) { From d63290d8b2357aafe6779d799acf27e9e9e1c212 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 4 Mar 2013 01:24:30 +0100 Subject: [PATCH 1318/4858] Use WP_Query instead of custom select --- php/commands/media.php | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index e2de098e08..96e46a952d 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -19,7 +19,6 @@ function __construct() { */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; - $count = 0; // If id is given, skip confirm because it is only one file if( !empty( $args ) ) { @@ -28,23 +27,35 @@ function regenerate( $args, $assoc_args = array() ) { WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); - $where_clause = ( !empty( $args ) ) ? "AND ID = " . implode(" OR ID = ", $args) . " " : ''; + $query_args = array( + 'post_type' => 'attachment', + 'post__in' => $args, + 'post_mime_type' => 'image', + 'post_status' => 'any', + 'posts_per_page' => -1, + 'fields' => 'ids' + ); - if ( !$images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' $where_clause AND post_mime_type LIKE 'image/%' ORDER BY ID DESC", ARRAY_A ) ) { + $images = new WP_Query( $query_args ); + + if ( $images->post_count == 0 ) { //No images, so all keys in $args are not found within WP WP_CLI::error( $this->_not_found_message( $args ) ); } - $count = count($images); + $count = $images->post_count; WP_CLI::line( "Found {$count} " . ngettext('image', 'images', $count) . " to regenerate." ); + + $not_found = array_diff( $args, $images->posts ); + if( !empty($not_found) ) { + WP_CLI::warning( $this->_not_found_message( $not_found ) ); + } - $not_found = array_diff( $args, wp_list_pluck( $images, 'ID' ) ); - WP_CLI::warning( $this->_not_found_message( $not_found ) ); - - foreach ( $images as $image ) { - $this->_process_regeneration( $image['ID'] ); + foreach ( $images->posts as $id ) { + $this->_process_regeneration( $id ); } - + + wp_reset_postdata(); WP_CLI::success( "Finished regenerating " . ngettext('the image', 'all images', $count) . "."); } From b8c3f86e7af8bbea12a995ea6c38345187bd0151 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Mon, 4 Mar 2013 15:06:33 +0100 Subject: [PATCH 1319/4858] set default value for query_var to true, same as the codex --- templates/post_type.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 44ebb048ee..429e002264 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -5,7 +5,7 @@ 'show_ui' => true, 'supports' => array( 'title', 'editor' ), 'has_archive' => true, - 'query_var' => {{slug}}, + 'query_var' => true, 'rewrite' => true, 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), From e539d6f3399ad9e39ca6ccd05f886de0e8e07306 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Mon, 4 Mar 2013 15:16:51 +0100 Subject: [PATCH 1320/4858] fixed escaped quotes that caused wrong urls on output --- templates/post_type_extended.mustache | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/post_type_extended.mustache b/templates/post_type_extended.mustache index 240746970a..9acbbb5d20 100755 --- a/templates/post_type_extended.mustache +++ b/templates/post_type_extended.mustache @@ -12,19 +12,19 @@ function {{machine_name}}_updated_messages( $messages ) { $messages['{{slug}}'] = array( 0 => '', // Unused. Messages start at index 1. - 1 => sprintf( __('{{label_ucfirst}} updated. <a target=\"_blank\" href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( $permalink ) ), + 1 => sprintf( __('{{label_ucfirst}} updated. <a target="_blank" href="%s">View {{label}}</a>', '{{textdomain}}'), esc_url( $permalink ) ), 2 => __('Custom field updated.', '{{textdomain}}'), 3 => __('Custom field deleted.', '{{textdomain}}'), 4 => __('{{label_ucfirst}} updated.', '{{textdomain}}'), /* translators: %s: date and time of the revision */ 5 => isset($_GET['revision']) ? sprintf( __('{{label_ucfirst}} restored to revision from %s', '{{textdomain}}'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - 6 => sprintf( __('{{label_ucfirst}} published. <a href=\"%s\">View {{label}}</a>', '{{textdomain}}'), esc_url( $permalink ) ), + 6 => sprintf( __('{{label_ucfirst}} published. <a href="%s">View {{label}}</a>', '{{textdomain}}'), esc_url( $permalink ) ), 7 => __('{{label_ucfirst}} saved.', '{{textdomain}}'), - 8 => sprintf( __('{{label_ucfirst}} submitted. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', $permalink ) ) ), - 9 => sprintf( __('{{label_ucfirst}} scheduled for: <strong>%1$s</strong>. <a target=\"_blank\" href=\"%2$s\">Preview {{label}}</a>', '{{textdomain}}'), + 8 => sprintf( __('{{label_ucfirst}} submitted. <a target="_blank" href="%s">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', $permalink ) ) ), + 9 => sprintf( __('{{label_ucfirst}} scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview {{label}}</a>', '{{textdomain}}'), // translators: Publish box date format, see http://php.net/date date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( $permalink ) ), - 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target=\"_blank\" href=\"%s\">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', $permalink ) ) ), + 10 => sprintf( __('{{label_ucfirst}} draft updated. <a target="_blank" href="%s">Preview {{label}}</a>', '{{textdomain}}'), esc_url( add_query_arg( 'preview', 'true', $permalink ) ) ), ); return $messages; From fb0cfe745cbedecc20a60f394ca4d288b254921f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 4 Mar 2013 17:35:35 +0200 Subject: [PATCH 1321/4858] add smoke test to utils/update-phar --- utils/update-phar | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/utils/update-phar b/utils/update-phar index 0f208844cf..1d910bd1ad 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -5,12 +5,21 @@ set -ex current_rev=$(git rev-parse HEAD) current_rev=${current_rev:0:10} +packages_repo=../wp-cli-packages + +fname="phar/wp-cli.phar" + # generate archive -php -dphar.readonly=0 ./utils/make-phar.php ../wp-cli-packages/phar/wp-cli.phar --quiet +php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet -cd ../wp-cli-packages +cd $packages_repo + +# smoke test +php $fname --version # check which wp-cli commit the previous Phar archive was based on +# can't use the md5 hash, since it will be different each time the +# archive is generated new_commit_subj="update wp-cli.phar to $current_rev" current_commit_subj=$(git show -s --pretty=format:%s HEAD) @@ -20,8 +29,6 @@ if [ "$new_commit_subj" = "$current_commit_subj" ]; then exit 1 fi -fname="phar/wp-cli.phar" - # generate md5 checksum md5sum $fname | cut -d ' ' -f 1 > $fname.md5 From 0c6c0bb90ddf738632004e15e2fb6226cc360b4a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 4 Mar 2013 17:38:01 +0200 Subject: [PATCH 1322/4858] add missing Composer files to phar archive --- utils/make-phar.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 96c66abb8f..1911b8f36a 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -56,6 +56,7 @@ function add_file( $phar, $path ) { $vendor_dirs = array( './vendor/mustache', './vendor/wp-cli', + './vendor/composer', ); foreach ( $vendor_dirs as $vendor_dir ) { @@ -69,6 +70,8 @@ function add_file( $phar, $path ) { } } +add_file( $phar, './vendor/autoload.php' ); + $phar->setStub( <<<EOB #!/usr/bin/env php <?php From 2cacbdc3a0153c41ed4d67f829c8252203daa047 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 4 Mar 2013 17:57:06 +0200 Subject: [PATCH 1323/4858] add utils/test-phar-download. see #340 --- utils/test-phar-download | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 utils/test-phar-download diff --git a/utils/test-phar-download b/utils/test-phar-download new file mode 100755 index 0000000000..f1a47e5190 --- /dev/null +++ b/utils/test-phar-download @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +actual_checksum=$(curl http://wp-cli.org/packages/phar/wp-cli.phar | md5sum | cut -d ' ' -f 1) + +echo "expected:" $(curl -s http://wp-cli.org/packages/phar/wp-cli.phar.md5) +echo "actual: " $actual_checksum From a815e13dd4d3c35f0e3c53992e3f4c0db7b6162d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 4 Mar 2013 20:48:19 +0200 Subject: [PATCH 1324/4858] use tests_add_filter() in bootstrap.mustache see https://core.trac.wordpress.org/ticket/23690 --- templates/bootstrap.mustache | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index 382f740134..18f87a91a5 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -1,8 +1,11 @@ <?php -$GLOBALS['wp_tests_options'] = array( - 'active_plugins' => array( basename( dirname( dirname( __FILE__ ) ) ) . '/{{plugin_slug}}.php' ), -); +require_once getenv( 'WP_TESTS_DIR' ) . '/includes/functions.php'; + +function _manually_load_plugin() { + require dirname( __FILE__ ) . '/../{{plugin_slug}}.php'; +} +tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); require getenv( 'WP_TESTS_DIR' ) . '/includes/bootstrap.php'; From 18d6a32abf4a00518e6361dc843bebea4619bc1e Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 4 Mar 2013 21:19:47 +0100 Subject: [PATCH 1325/4858] Removed query reset --- php/commands/media.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 96e46a952d..9942c9b538 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -55,7 +55,6 @@ function regenerate( $args, $assoc_args = array() ) { $this->_process_regeneration( $id ); } - wp_reset_postdata(); WP_CLI::success( "Finished regenerating " . ngettext('the image', 'all images', $count) . "."); } From 2d6853bb030d94f77ab3e54ca0a3e5528b6251be Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 4 Mar 2013 22:08:59 +0100 Subject: [PATCH 1326/4858] Cleanup regenerating thumbnails and use more WP function --- php/commands/media.php | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 9942c9b538..2b0fa663d3 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -76,35 +76,33 @@ private function _process_regeneration( $id ) { WP_CLI::line( "Start processing of \"" . get_the_title( $image->ID ) . " (ID: {$image->ID})\"" ); - $array_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); - $array_file = explode( '.', $array_path[ count( $array_path ) - 1 ] ); + $a_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); + $a_file = explode( '.', $a_path[ count( $a_path ) - 1 ] ); - unset( $array_path[ count( $array_path ) - 1 ] ); - unset( $array_file[ count( $array_file ) - 1 ] ); - - $imagePath = implode( DIRECTORY_SEPARATOR, $array_path ) . DIRECTORY_SEPARATOR . implode( '.', $array_file ); - $dirPath = explode( DIRECTORY_SEPARATOR, $imagePath ); - $imageName = $dirPath[ count( $dirPath ) - 1 ] . "-"; - unset( $dirPath[ count( $dirPath ) - 1 ] ); - $dirPath = implode( DIRECTORY_SEPARATOR, $dirPath ) . DIRECTORY_SEPARATOR; + unset( $a_path ); + unset( $a_file[ count( $a_file ) - 1 ] ); + + $image_name = $a_file[ count( $a_file ) - 1 ] . '-'; + $dir_path = wp_upload_dir(); // Read and delete files - $dir = opendir( $dirPath ); + $dir = opendir( $dir_path['basedir'] ); $files = array(); + while ( $file = readdir( $dir ) ) { - - if ( !( strrpos( $file, $imageName ) === false ) ) { + + if ( !( strrpos( $file, $image_name ) === false ) ) { - $thumbnail = explode( $imageName, $file ); - $filename = $thumbnail[ 1 ]; + $thumbnail = explode( $image_name, $file ); + $filename = $thumbnail[ 1 ]; //If we got the original / full image if ( "" == $thumbnail[ 0 ] ) { - preg_match('/\.[^\.]+$/i', $file, $ext); - $thumbnailFormat = $ext[0]; - $thumbnail = basename( $filename, $thumbnailFormat ); - - $sizes = explode( 'x', $thumbnail ); + $filetype = wp_check_filetype($file); + $thumbnail_ext = ".{$filetype['ext']}"; + $thumbnail_name = basename( $filename, $thumbnail_ext ); + + $sizes = explode( 'x', $thumbnail_name ); // If not cropped by WP if ( 2 == count( $sizes ) ) { @@ -112,7 +110,7 @@ private function _process_regeneration( $id ) { $height = $sizes[1]; if ( is_numeric( $width ) && is_numeric( $height ) ) { WP_CLI::line( "Thumbnail: {$width} x {$height} was deleted." ); - @unlink( $dirPath . $imageName . $width . 'x' . $thumbnail . $thumbnailFormat ); + @unlink( $dir_path['basedir'] . DIRECTORY_SEPARATOR . $image_name . $thumbnail_name . $thumbnail_ext ); } } } From 2517635d5b7a6440008c2bba6085afffd02926e3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 5 Mar 2013 00:33:08 +0200 Subject: [PATCH 1327/4858] don't need to place the plugin directory inside the plugins folder anymore see http://core.trac.wordpress.org/ticket/23690 --- templates/.travis.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index a34cedf751..a2020ad18f 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -19,10 +19,6 @@ before_script: - mkdir -p $WP_CORE_DIR - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - - plugin_slug=$(basename $(pwd)) - - plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug - - cd .. - - mv $plugin_slug $plugin_dir # set up testing suite - export WP_TESTS_DIR=/tmp/wordpress-tests/ - svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR @@ -32,9 +28,8 @@ before_script: - sed -i "s/yourdbnamehere/wordpress_test/" wp-tests-config.php - sed -i "s/yourusernamehere/root/" wp-tests-config.php - sed -i "s/yourpasswordhere//" wp-tests-config.php + - cd - # set up database - mysql -e 'CREATE DATABASE wordpress_test;' -uroot - # prepare for running the tests - - cd $plugin_dir script: phpunit From 991a2e53181a5c388fdb8df600e9071c1aeeb8a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 5 Mar 2013 00:43:21 +0200 Subject: [PATCH 1328/4858] plugin init-tests: always overwrite existing files the assumption is that the plugin will already be under version control --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 75b7a22517..4697c47fb0 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -221,7 +221,7 @@ function plugin_tests( $args, $assoc_args ) { ); foreach ( $to_copy as $file => $dir ) { - $wp_filesystem->copy( $this->get_template_path( $file ), "$dir/$file" ); + $wp_filesystem->copy( $this->get_template_path( $file ), "$dir/$file", true ); } WP_CLI::success( "Created test files in $plugin_dir" ); From d1e6faa7ce99e134cbc834f887ed1b7de9100835 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 5 Mar 2013 20:26:36 +0100 Subject: [PATCH 1329/4858] Added @unlink and merged from upstream master --- php/commands/media.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 2b0fa663d3..b6b247c3de 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -90,12 +90,12 @@ private function _process_regeneration( $id ) { $files = array(); while ( $file = readdir( $dir ) ) { - + WP_CLI::print_value( $dir_path ); if ( !( strrpos( $file, $image_name ) === false ) ) { $thumbnail = explode( $image_name, $file ); $filename = $thumbnail[ 1 ]; - +//WP_CLI::print_value( $dir ); //If we got the original / full image if ( "" == $thumbnail[ 0 ] ) { $filetype = wp_check_filetype($file); @@ -110,7 +110,7 @@ private function _process_regeneration( $id ) { $height = $sizes[1]; if ( is_numeric( $width ) && is_numeric( $height ) ) { WP_CLI::line( "Thumbnail: {$width} x {$height} was deleted." ); - @unlink( $dir_path['basedir'] . DIRECTORY_SEPARATOR . $image_name . $thumbnail_name . $thumbnail_ext ); + unlink( $dir_path['basedir'] . DIRECTORY_SEPARATOR . $image_name . $thumbnail_name . $thumbnail_ext ); } } } From 812afd6627b8b7e9ceb90878a726841f6022e293 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 5 Mar 2013 20:31:37 +0100 Subject: [PATCH 1330/4858] Removed print_r and finalized to generate man page --- php/commands/media.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index b6b247c3de..b61a28dd36 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -74,7 +74,7 @@ private function _process_regeneration( $id ) { return; } - WP_CLI::line( "Start processing of \"" . get_the_title( $image->ID ) . " (ID: {$image->ID})\"" ); + WP_CLI::line( "Start processing of \"" . get_the_title( $image->ID ) . "\" (ID: {$image->ID})" ); $a_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $a_file = explode( '.', $a_path[ count( $a_path ) - 1 ] ); @@ -90,12 +90,12 @@ private function _process_regeneration( $id ) { $files = array(); while ( $file = readdir( $dir ) ) { - WP_CLI::print_value( $dir_path ); + if ( !( strrpos( $file, $image_name ) === false ) ) { $thumbnail = explode( $image_name, $file ); $filename = $thumbnail[ 1 ]; -//WP_CLI::print_value( $dir ); + //If we got the original / full image if ( "" == $thumbnail[ 0 ] ) { $filetype = wp_check_filetype($file); From 2e95438b01d4bc7dc6c02445152d19f86a700716 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 5 Mar 2013 21:07:18 +0100 Subject: [PATCH 1331/4858] Added man pages --- man-src/media-regenerate.txt | 15 +++++++++++++++ man/media-regenerate.1 | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 man-src/media-regenerate.txt create mode 100644 man/media-regenerate.1 diff --git a/man-src/media-regenerate.txt b/man-src/media-regenerate.txt new file mode 100644 index 0000000000..92ba35b326 --- /dev/null +++ b/man-src/media-regenerate.txt @@ -0,0 +1,15 @@ +## OPTIONS + +* `--yes`: + + Answer yes to the confirmation message. + +* `<attachment-id>`: + + One or more IDs of the attachment to regenerate. + +## EXAMPLES + + wp media regenerate 123 1337 + + wp media regenerate --yes \ No newline at end of file diff --git a/man/media-regenerate.1 b/man/media-regenerate.1 new file mode 100644 index 0000000000..082157a6a3 --- /dev/null +++ b/man/media-regenerate.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-MEDIA\-REGENERATE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-media\-regenerate\fR \- Regenerate thumbnail(s) +. +.SH "SYNOPSIS" +wp media regenerate \fIattachment\-id\fR\.\.\. [\-\-yes] +. +.SH "OPTIONS" +. +.TP +\fB\-\-yes\fR: +. +.IP +Answer yes to the confirmation message\. +. +.TP +\fB<attachment\-id>\fR: +. +.IP +One or more IDs of the attachment to regenerate\. +. +.SH "EXAMPLES" +. +.nf + +wp media regenerate 123 1337 + +wp media regenerate \-\-yes +. +.fi + From 941959b1d4e08dc76dc183c6da19c055ff92b5f3 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 5 Mar 2013 21:08:42 +0100 Subject: [PATCH 1332/4858] Typo --- man-src/media-regenerate.txt | 2 +- man/media-regenerate.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/media-regenerate.txt b/man-src/media-regenerate.txt index 92ba35b326..f873f53494 100644 --- a/man-src/media-regenerate.txt +++ b/man-src/media-regenerate.txt @@ -6,7 +6,7 @@ * `<attachment-id>`: - One or more IDs of the attachment to regenerate. + One or more IDs of the attachments to regenerate. ## EXAMPLES diff --git a/man/media-regenerate.1 b/man/media-regenerate.1 index 082157a6a3..8591e809a3 100644 --- a/man/media-regenerate.1 +++ b/man/media-regenerate.1 @@ -21,7 +21,7 @@ Answer yes to the confirmation message\. \fB<attachment\-id>\fR: . .IP -One or more IDs of the attachment to regenerate\. +One or more IDs of the attachments to regenerate\. . .SH "EXAMPLES" . From a18cbccbaabbcdd1f1ec10db6551c8da3688ebca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 6 Mar 2013 15:21:46 +0200 Subject: [PATCH 1333/4858] update-phar: make wp-cli revision linkable --- utils/update-phar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/update-phar b/utils/update-phar index 1d910bd1ad..e7cf98c223 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -20,7 +20,7 @@ php $fname --version # check which wp-cli commit the previous Phar archive was based on # can't use the md5 hash, since it will be different each time the # archive is generated -new_commit_subj="update wp-cli.phar to $current_rev" +new_commit_subj="update wp-cli.phar to wp-cli/wp-cli@$current_rev" current_commit_subj=$(git show -s --pretty=format:%s HEAD) From 84e575251177efae8ac3b3af41fae9e5235be597 Mon Sep 17 00:00:00 2001 From: Andrew Nacin <andrewnacin@gmail.com> Date: Thu, 7 Mar 2013 10:30:45 -0500 Subject: [PATCH 1334/4858] When populate_network() returns a wildcard DNS error, treat it as a warning, not an error. See http://core.trac.wordpress.org/ticket/23709. --- php/commands/core.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 66aa421444..19f7774dd0 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -133,8 +133,12 @@ public function install_network( $args, $assoc_args ) { $result = populate_network( 1, $hostname, get_option( 'admin_email' ), $assoc_args['title'], $base, $subdomain_install ); - if ( is_wp_error( $result ) ) - WP_CLI::error( $result ); + if ( is_wp_error( $result ) ) { + if ( $result->get_error_codes() === array( 'no_wildcard_dns' ) ) + WP_CLI::warning( __( 'Wildcard DNS may not be configured correctly.' ) ); + else + WP_CLI::error( $result ); + } ob_start(); ?> From feb50436e1423f7fbd2d2d35c6b7b0f9de0b8656 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 15:14:28 +0200 Subject: [PATCH 1335/4858] make `core upgrade` an alias of `core update` --- php/commands/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 19f7774dd0..85a4bcf5e5 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -219,6 +219,8 @@ public function version( $args = array(), $assoc_args = array() ) { /** * Update WordPress. * + * @alias upgrade + * * @synopsis [<zip>] [--version=<version>] [--force] */ function update( $args, $assoc_args ) { From c759b00c148001be500d18e9176357b794038361 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Fri, 8 Mar 2013 11:15:08 +0000 Subject: [PATCH 1336/4858] Avoid warning if no rewrite rules exist --- php/commands/rewrite.php | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 0709e9f0ff..d04344dd22 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -74,12 +74,20 @@ public function dump( $args, $assoc_args ) { $rules = get_option( 'rewrite_rules' ); - if ( isset( $assoc_args['json'] ) ) - echo json_encode( $rules ); - else - foreach ( $rules as $route => $rule ) - WP_CLI::line( $route . "\t" . $rule ); - + if ( isset( $assoc_args['json'] ) ) { + if ( ! $rules ) { + echo json_encode( "No rules" ); + } else { + echo json_encode( $rules ); + } + } else { + if ( ! $rules ) { + WP_CLI::line( "No rules" ); + } else { + foreach ( $rules as $route => $rule ) + WP_CLI::line( $route . "\t" . $rule ); + } + } } } From 315e68b14d7a366548756e56aeac547acce2ac3b Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Fri, 8 Mar 2013 15:02:52 +0000 Subject: [PATCH 1337/4858] Show messages as warnings, and change JSON output to empty array, not string --- php/commands/rewrite.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index d04344dd22..0b24f8bd0b 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -76,13 +76,14 @@ public function dump( $args, $assoc_args ) { if ( isset( $assoc_args['json'] ) ) { if ( ! $rules ) { - echo json_encode( "No rules" ); + WP_CLI::warning( 'No rewrite rules' ); + echo json_encode( array() ); } else { echo json_encode( $rules ); } } else { if ( ! $rules ) { - WP_CLI::line( "No rules" ); + WP_CLI::warning( 'No rewrite rules' ); } else { foreach ( $rules as $route => $rule ) WP_CLI::line( $route . "\t" . $rule ); From 88bb9ecb1f4dae89697e6f964f274ca741138aa8 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Fri, 8 Mar 2013 15:17:30 +0000 Subject: [PATCH 1338/4858] Clean up logic --- php/commands/rewrite.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 0b24f8bd0b..41ae7d61b2 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -73,22 +73,18 @@ public function structure( $args, $assoc_args ) { public function dump( $args, $assoc_args ) { $rules = get_option( 'rewrite_rules' ); + if ( ! $rules ) { + $rules = array(); + WP_CLI::warning( 'No rewrite rules' ); + } if ( isset( $assoc_args['json'] ) ) { - if ( ! $rules ) { - WP_CLI::warning( 'No rewrite rules' ); - echo json_encode( array() ); - } else { - echo json_encode( $rules ); - } + echo json_encode( $rules ); } else { - if ( ! $rules ) { - WP_CLI::warning( 'No rewrite rules' ); - } else { - foreach ( $rules as $route => $rule ) - WP_CLI::line( $route . "\t" . $rule ); - } + foreach ( $rules as $route => $rule ) + WP_CLI::line( $route . "\t" . $rule ); } + } } From 1bf64de634f2918374b1c4106d4e39bffcbc5572 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Fri, 8 Mar 2013 15:28:00 +0000 Subject: [PATCH 1339/4858] . --- php/commands/rewrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 41ae7d61b2..7f464ae0ac 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -75,7 +75,7 @@ public function dump( $args, $assoc_args ) { $rules = get_option( 'rewrite_rules' ); if ( ! $rules ) { $rules = array(); - WP_CLI::warning( 'No rewrite rules' ); + WP_CLI::warning( 'No rewrite rules.' ); } if ( isset( $assoc_args['json'] ) ) { From ac0d89c38b55f772f0016ebbcb7e70b8cb1bde17 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 17:55:36 +0200 Subject: [PATCH 1340/4858] move create_cmd() utility out of DB_Command --- php/commands/db.php | 26 +++++++------------------- php/utils.php | 12 ++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index bed80acbf4..f304902d4f 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -64,7 +64,7 @@ function reset( $_, $assoc_args ) { * @synopsis [--str] */ function optimize( $_, $assoc_args ) { - self::run( $assoc_args, self::create_cmd( + self::run( $assoc_args, \WP_CLI\Utils\create_cmd( 'mysqlcheck --optimize --host=%s --user=%s --password=%s %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -78,7 +78,7 @@ function optimize( $_, $assoc_args ) { * @synopsis [--str] */ function repair( $_, $assoc_args ) { - self::run( $assoc_args, self::create_cmd( + self::run( $assoc_args, \WP_CLI\Utils\create_cmd( 'mysqlcheck --repair --host=%s --user=%s --password=%s %s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ) ); @@ -105,7 +105,7 @@ function connect( $_, $assoc_args ) { function query( $args, $assoc_args ) { list( $query ) = $args; - self::run( $assoc_args, $this->connect_string() . self::create_cmd( + self::run( $assoc_args, $this->connect_string() . \WP_CLI\Utils\create_cmd( ' --execute=%s', $query ) ); } @@ -118,7 +118,7 @@ function query( $args, $assoc_args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( $assoc_args, self::create_cmd( + self::run( $assoc_args, \WP_CLI\Utils\create_cmd( 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ) ); @@ -133,7 +133,7 @@ function export( $args, $assoc_args ) { function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( $assoc_args, self::create_cmd( + self::run( $assoc_args, \WP_CLI\Utils\create_cmd( 'mysql %s --user=%s --password=%s --host=%s < %s', DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ) ); @@ -141,7 +141,7 @@ function import( $args, $assoc_args ) { } private function connect_string() { - return self::create_cmd( 'mysql --host=%s --user=%s --password=%s --database=%s', + return \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --password=%s --database=%s', DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); } @@ -153,24 +153,12 @@ private function get_file_name( $args ) { } private static function create_execute_cmd( $execute_statement ) { - return self::create_cmd( + return \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --password=%s --execute=%s', DB_HOST, DB_USER, DB_PASSWORD, $execute_statement ); } - /** - * Given a formatted string and an arbitrary number of arguments, - * returns the final command, with the parameters escaped - */ - private static function create_cmd( $cmd ) { - $args = func_get_args(); - - $cmd = array_shift( $args ); - - return vsprintf( $cmd, array_map( 'escapeshellarg', $args ) ); - } - private static function run( $assoc_args, $cmd ) { if ( isset( $assoc_args['str'] ) ) { WP_CLI::line( $cmd ); diff --git a/php/utils.php b/php/utils.php index efd1411cb7..451085e7ea 100644 --- a/php/utils.php +++ b/php/utils.php @@ -100,6 +100,18 @@ function assoc_args_to_str( $assoc_args ) { return $str; } +/** + * Given a template string and an arbitrary number of arguments, + * returns the final command, with the parameters escaped. + */ +function create_cmd( $cmd ) { + $args = func_get_args(); + + $cmd = array_shift( $args ); + + return vsprintf( $cmd, array_map( 'escapeshellarg', $args ) ); +} + function get_command_file( $command ) { $path = WP_CLI_ROOT . "/commands/$command.php"; From 3b33c81cc3a3dcdc8d2c47ed6494b15949637f08 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 21:07:42 +0200 Subject: [PATCH 1341/4858] behat: unify and standardize output testing steps: * always run replace_variables() and restrict variable names * add 'not contain' option --- features/bootstrap/FeatureContext.php | 4 +-- features/steps/basic_steps.php | 38 ++++++++++++++++----------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index bbdb336911..d45f895553 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -44,9 +44,9 @@ public function getHookDefinitionResources() return array(); } - public function replace_variables( &$str ) + public function replace_variables( $str ) { - $str = preg_replace_callback( '/\{(\w+)\}/', array( $this, '_replace_var' ), $str ); + return preg_replace_callback( '/\{([A-Z_]+)\}/', array( $this, '_replace_var' ), $str ); } private function _replace_var( $matches ) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 2dbbdf160d..28551fb894 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -52,9 +52,7 @@ function ( $world ) { $steps->When( '/^I run `wp (.+)`$/', function ( $world, $cmd ) { - $world->replace_variables( $cmd ); - - $world->result = $world->run( $cmd ); + $world->result = $world->run( $world->replace_variables( $cmd ) ); } ); @@ -89,22 +87,32 @@ function ( $world ) { } ); -$steps->Then( '/^(STDOUT|STDERR) should be:$/', - function ( $world, $stream, PyStringNode $output ) { - $world->replace_variables( $output ); +$steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', + function ( $world, $stream, $action, PyStringNode $expected ) { + $output = $world->replace_variables( $world->result->$stream ); - $result = rtrim( $world->result->$stream, "\n" ); + $expected = (string) $expected; - if ( (string) $output != $result ) { - throw new \Exception( $world->result->$stream ); + switch ( $action ) { + + case 'be': + $r = $expected === rtrim( $output, "\n" ); + break; + + case 'contain': + $r = false !== strpos( $output, $expected ); + break; + + case 'not contain': + $r = false === strpos( $output, $expected ); + break; + + default: + throw new PendingException(); } - } -); -$steps->Then( '/^(STDOUT|STDERR) should contain:$/', - function ( $world, $stream, PyStringNode $output ) { - if ( false === strpos( $world->result->$stream, (string) $output ) ) { - throw new \Exception( $world->result->$stream ); + if ( !$r ) { + throw new \Exception( $output ); } } ); From 2ece4d5699b3d1ac1399bd0f1a8ae526b879f1e7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 16:48:47 +0200 Subject: [PATCH 1342/4858] first pass at theme tests --- features/theme.feature | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 features/theme.feature diff --git a/features/theme.feature b/features/theme.feature new file mode 100644 index 0000000000..6552e04eda --- /dev/null +++ b/features/theme.feature @@ -0,0 +1,49 @@ +Feature: Manage WordPress themes + + Scenario: Checking the theme list + Given WP install + + When I run `wp theme status` + Then it should run without errors + And STDOUT should not be empty + + Scenario: Installing a theme + Given WP install + + When I run `wp theme install p2` + Then it should run without errors + + When I run the previous command again + Then the return code should be 1 + + When I run `wp theme status p2` + Then it should run without errors + And STDOUT should contain: + """ + Theme p2 details: + Name: P2 + """ + + When I run `wp theme path p2` + Then it should run without errors + And STDOUT should contain: + """ + /themes/p2/style.css + """ + + When I run `wp theme activate p2` + Then it should run without errors + And STDOUT should contain: + """ + Success: Switched to 'P2' theme. + """ + + When I run `wp theme delete p2` + Then it should run without errors + + When I run the previous command again + Then the return code should be 1 + And STDERR should contain: + """ + Error: The theme 'p2' could not be found. + """ From a718da781ef0d33aa93b7b42bbc1e7be12b033e1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 15:22:25 +0200 Subject: [PATCH 1343/4858] always use wp_get_themes() --- php/commands/theme.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 2367658013..9ba7c79b3a 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -134,12 +134,7 @@ protected function install_from_repo( $slug, $assoc_args ) { protected function get_item_list() { $items = array(); - if( function_exists( 'wp_get_themes' ) ) - $themes = wp_get_themes(); - else - $themes = get_themes(); - - foreach ( $themes as $details ) { + foreach ( wp_get_themes() as $details ) { $file = $this->get_stylesheet_path( $details['Stylesheet'] ); $items[ $file ] = array( From 520f991342854b58f61525c6d74887e233d8ce37 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 15:45:41 +0200 Subject: [PATCH 1344/4858] use wp_get_theme() instead of get_theme_data() --- php/commands/theme.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 9ba7c79b3a..ee087bb2b2 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -41,7 +41,7 @@ protected function get_status( $stylesheet ) { } protected function get_details( $stylesheet ) { - return get_theme_data( $stylesheet ); + return wp_get_theme( $stylesheet ); } /** @@ -52,7 +52,7 @@ protected function get_details( $stylesheet ) { public function activate( $args = array() ) { list( $stylesheet, $child ) = $this->parse_name( $args ); - $details = get_theme_data( $stylesheet ); + $details = wp_get_theme( $stylesheet ); $parent = $details['Template']; From ec69fe9066b6c2f870f76dbc4718d58dc5a5e3ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 15:53:49 +0200 Subject: [PATCH 1345/4858] switch_theme() doesn't even accept a second parameter --- php/commands/theme.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index ee087bb2b2..f1faed1498 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -54,15 +54,7 @@ public function activate( $args = array() ) { $details = wp_get_theme( $stylesheet ); - $parent = $details['Template']; - - if ( empty( $parent ) ) { - $parent = $child; - } elseif ( !is_readable( $this->get_stylesheet_path( $parent ) ) ) { - WP_CLI::error( 'Parent theme not found.' ); - } - - switch_theme( $parent, $child ); + switch_theme( $child ); $name = $details['Title']; From 4c01e5675f4ccc377ffccb1bf817bc8eee8c3a1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 16:48:58 +0200 Subject: [PATCH 1346/4858] add tests for `plugin status` --- features/plugin.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 features/plugin.feature diff --git a/features/plugin.feature b/features/plugin.feature new file mode 100644 index 0000000000..0300fb2529 --- /dev/null +++ b/features/plugin.feature @@ -0,0 +1,23 @@ +Feature: Manage WordPress plugins + + Scenario: Checking the plugin status + Given WP install + + When I run `wp plugin status` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp plugin status hello` + Then it should run without errors + And STDOUT should contain: + """ + Plugin hello details: + Name: Hello Dolly + """ + + When I run `wp plugin status non-existent-plugin` + Then the return code should be 1 + And STDERR should contain: + """ + Error: The plugin 'non-existent-plugin' could not be found. + """ From 5b188048ab71d0fab90530a586c7da3fbcfcc9a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 16:47:50 +0200 Subject: [PATCH 1347/4858] use WP_Theme objects, instead of messing with paths --- php/WP_CLI/CommandWithUpgrade.php | 22 ++------- php/commands/plugin.php | 15 ++++++ php/commands/theme.php | 82 +++++++++++++++---------------- 3 files changed, 57 insertions(+), 62 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 1cf052645f..08b87ccfb0 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -15,9 +15,8 @@ abstract protected function get_item_list(); abstract protected function get_all_items(); abstract protected function get_status( $file ); - abstract protected function get_details( $file ); - abstract protected function _status_single( $details, $name, $version, $status ); + abstract protected function status_single( $args ); abstract protected function install_from_repo( $slug, $assoc_args ); @@ -28,9 +27,7 @@ function status( $args ) { if ( empty( $args ) ) { $this->status_all(); } else { - list( $file, $name ) = $this->parse_name( $args ); - - $this->status_single( $file, $name ); + $this->status_single( $args ); } } @@ -79,19 +76,6 @@ private function show_legend( $items ) { \WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); } - private function status_single( $file, $name ) { - $details = $this->get_details( $file ); - - $status = $this->format_status( $this->get_status( $file ), 'long' ); - - $version = $details[ 'Version' ]; - - if ( $this->has_update( $file ) ) - $version .= ' (%gUpdate available%n)'; - - $this->_status_single( $details, $name, $version, $status ); - } - function install( $args, $assoc_args ) { if ( empty( $args ) ) { \WP_CLI::line( "usage: wp $this->item_type install <slug>" ); @@ -195,7 +179,7 @@ protected function has_update( $slug ) { ) ); - private function format_status( $status, $format ) { + protected function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 189dad344c..ea01f2a9a5 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -28,6 +28,21 @@ function status( $args ) { parent::status( $args ); } + protected function status_single( $args ) { + list( $file, $name ) = $this->parse_name( $args ); + + $details = $this->get_details( $file ); + + $status = $this->format_status( $this->get_status( $file ), 'long' ); + + $version = $details[ 'Version' ]; + + if ( $this->has_update( $file ) ) + $version .= ' (%gUpdate available%n)'; + + $this->_status_single( $details, $name, $version, $status ); + } + protected function _status_single( $details, $name, $version, $status ) { WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); diff --git a/php/commands/theme.php b/php/commands/theme.php index f1faed1498..26dbdad778 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -21,27 +21,28 @@ function status( $args ) { parent::status( $args ); } - protected function _status_single( $details, $name, $version, $status ) { - WP_CLI::line( 'Theme %9' . $name . '%n details:' ); - WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); + protected function status_single( $args ) { + $theme = $this->parse_name( $args ); + + $status = $this->format_status( $this->get_status( $theme ), 'long' ); + + $version = $theme->get('Version'); + if ( $this->has_update( $theme->get_stylesheet() ) ) + $version .= ' (%gUpdate available%n)'; + + WP_CLI::line( 'Theme %9' . $theme->get_stylesheet() . '%n details:' ); + WP_CLI::line( ' Name: ' . $theme->get('Name') ); WP_CLI::line( ' Status: ' . $status .'%n' ); WP_CLI::line( ' Version: ' . $version ); - WP_CLI::line( ' Author: ' . strip_tags( $details[ 'Author' ] ) ); + WP_CLI::line( ' Author: ' . $theme->get('Author') ); } protected function get_all_items() { return $this->get_item_list(); } - protected function get_status( $stylesheet ) { - if ( $this->is_active_theme( $stylesheet ) ) - return 'active'; - - return 'inactive'; - } - - protected function get_details( $stylesheet ) { - return wp_get_theme( $stylesheet ); + protected function get_status( $theme ) { + return ( $this->is_active_theme( $theme ) ) ? 'active' : 'inactive'; } /** @@ -50,23 +51,21 @@ protected function get_details( $stylesheet ) { * @synopsis <theme> */ public function activate( $args = array() ) { - list( $stylesheet, $child ) = $this->parse_name( $args ); - - $details = wp_get_theme( $stylesheet ); + $theme = $this->parse_name( $args ); - switch_theme( $child ); + switch_theme( $theme->get_stylesheet() ); - $name = $details['Title']; + $name = $theme->get('Name'); - if ( $this->is_active_theme( $stylesheet ) ) { + if ( $this->is_active_theme( $theme ) ) { WP_CLI::success( "Switched to '$name' theme." ); } else { WP_CLI::error( "Could not switch to '$name' theme." ); } } - private function is_active_theme( $stylesheet ) { - return dirname( $stylesheet ) == get_stylesheet_directory(); + private function is_active_theme( $theme ) { + return $theme->get_stylesheet_directory() == get_stylesheet_directory(); } /** @@ -78,11 +77,12 @@ function path( $args, $assoc_args ) { if ( empty( $args ) ) { $path = WP_CONTENT_DIR . '/themes'; } else { - list( $stylesheet, $name ) = $this->parse_name( $args ); - $path = $stylesheet; + $theme = $this->parse_name( $args ); + + $path = $theme->get_stylesheet_directory(); - if ( isset( $assoc_args['dir'] ) ) - $path = dirname( $path ); + if ( !isset( $assoc_args['dir'] ) ) + $path .= '/style.css'; } WP_CLI::line( $path ); @@ -109,7 +109,7 @@ protected function install_from_repo( $slug, $assoc_args ) { * Else, if there's no update, it's either not installed, * or it's newer than what we've got. */ - } else if ( !is_readable( $this->get_stylesheet_path( $slug ) ) ) { + } else if ( !wp_get_theme( $slug )->exists() ) { WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); } else { @@ -126,14 +126,14 @@ protected function install_from_repo( $slug, $assoc_args ) { protected function get_item_list() { $items = array(); - foreach ( wp_get_themes() as $details ) { - $file = $this->get_stylesheet_path( $details['Stylesheet'] ); + foreach ( wp_get_themes() as $theme ) { + $file = $theme->get_stylesheet_directory(); $items[ $file ] = array( - 'name' => $details['Stylesheet'], - 'status' => $this->get_status( $file ), - 'update' => $this->has_update( $details['Stylesheet'] ), - 'update_id' => $details['Stylesheet'], + 'name' => $theme->get('Name'), + 'status' => $this->get_status( $theme ), + 'update' => $this->has_update( $theme->get_stylesheet() ), + 'update_id' => $theme->get_stylesheet(), ); } @@ -155,9 +155,9 @@ function install( $args, $assoc_args ) { * @synopsis <theme> [--version=<version>] */ function update( $args, $assoc_args ) { - list( $_, $name ) = $this->parse_name( $args ); + $theme = $this->parse_name( $args ); - parent::_update( $name ); + parent::_update( $theme->get_stylesheet() ); } /** @@ -176,9 +176,9 @@ function update_all( $args, $assoc_args ) { * @synopsis <theme> */ function delete( $args ) { - list( $file, $name ) = $this->parse_name( $args ); + $theme = $this->parse_name( $args ); - $r = delete_theme( $name ); + $r = delete_theme( $theme->get_stylesheet() ); if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); @@ -193,18 +193,14 @@ protected function parse_name( $args ) { $name = $args[0]; - $stylesheet = $this->get_stylesheet_path( $name ); + $theme = wp_get_theme( $name ); - if ( !is_readable( $stylesheet ) ) { + if ( !$theme->exists() ) { WP_CLI::error( "The theme '$name' could not be found." ); exit; } - return array( $stylesheet, $name ); - } - - protected function get_stylesheet_path( $theme ) { - return WP_CONTENT_DIR . '/themes/' . $theme . '/style.css'; + return $theme; } } From c902a180b5a199e13fdb0719b0ce818158c6c749 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 21:13:01 +0200 Subject: [PATCH 1348/4858] add theme updating scenario --- features/steps/basic_steps.php | 16 ++++++++++++++ features/theme.feature | 40 +++++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 28551fb894..1691794a5a 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -44,6 +44,22 @@ function ( $world ) { } ); +$steps->Given('/^a P2 theme zip$/', + function ( $world ) { + $zip_name = 'p2.1.0.1.zip'; + + $cache_dir = sys_get_temp_dir() . '/wp-cli-test-cache'; + $world->variables['THEME_ZIP'] = $cache_dir . '/' . $zip_name; + + $zip_url = 'http://wordpress.org/extend/themes/download/' . $zip_name; + + system( \WP_CLI\Utils\create_cmd( 'mkdir -p %s', $cache_dir ) ); + + system( \WP_CLI\Utils\create_cmd( 'curl -s %s > %s', $zip_url, + $world->variables['THEME_ZIP'] ) ); + } +); + $steps->When( '/^I run `wp`$/', function ( $world ) { $world->result = $world->run( '' ); diff --git a/features/theme.feature b/features/theme.feature index 6552e04eda..6b5ef69849 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -1,12 +1,5 @@ Feature: Manage WordPress themes - Scenario: Checking the theme list - Given WP install - - When I run `wp theme status` - Then it should run without errors - And STDOUT should not be empty - Scenario: Installing a theme Given WP install @@ -20,7 +13,7 @@ Feature: Manage WordPress themes Then it should run without errors And STDOUT should contain: """ - Theme p2 details: + Theme p2 details: Name: P2 """ @@ -47,3 +40,34 @@ Feature: Manage WordPress themes """ Error: The theme 'p2' could not be found. """ + + Scenario: Upgrading a theme + Given WP install + And a P2 theme zip + + When I run `wp theme install {THEME_ZIP}` + Then it should run without errors + + When I run `wp theme status` + Then it should run without errors + And STDOUT should contain: + """ + U = Update Available + """ + + When I run `wp theme status p2` + Then it should run without errors + And STDOUT should contain: + """ + Version: 1.0.1 (Update available) + """ + + When I run `wp theme update p2` + Then it should run without errors + + When I run `wp theme status p2` + Then it should run without errors + And STDOUT should not contain: + """ + (Update available) + """ From ba857d212c6e8a497e3abc4ae64f06908598a3dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 21:39:17 +0200 Subject: [PATCH 1349/4858] fix indentation for feature files --- features/plugin.feature | 18 +++++++++--------- features/theme.feature | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 0300fb2529..dcd4034da5 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -9,15 +9,15 @@ Feature: Manage WordPress plugins When I run `wp plugin status hello` Then it should run without errors - And STDOUT should contain: - """ - Plugin hello details: - Name: Hello Dolly - """ + And STDOUT should contain: + """ + Plugin hello details: + Name: Hello Dolly + """ When I run `wp plugin status non-existent-plugin` Then the return code should be 1 - And STDERR should contain: - """ - Error: The plugin 'non-existent-plugin' could not be found. - """ + And STDERR should contain: + """ + Error: The plugin 'non-existent-plugin' could not be found. + """ diff --git a/features/theme.feature b/features/theme.feature index 6b5ef69849..a60d22ed10 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -52,14 +52,14 @@ Feature: Manage WordPress themes Then it should run without errors And STDOUT should contain: """ - U = Update Available + U = Update Available """ When I run `wp theme status p2` Then it should run without errors And STDOUT should contain: """ - Version: 1.0.1 (Update available) + Version: 1.0.1 (Update available) """ When I run `wp theme update p2` @@ -69,5 +69,5 @@ Feature: Manage WordPress themes Then it should run without errors And STDOUT should not contain: """ - (Update available) + (Update available) """ From 83ec424ff3dae2e4994ae51f7c56f56f690b0cdd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 21:50:12 +0200 Subject: [PATCH 1350/4858] replace variables in expected output, not in current output --- features/steps/basic_steps.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 1691794a5a..218326b127 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -105,9 +105,9 @@ function ( $world ) { $steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', function ( $world, $stream, $action, PyStringNode $expected ) { - $output = $world->replace_variables( $world->result->$stream ); + $output = $world->result->$stream; - $expected = (string) $expected; + $expected = $world->replace_variables( (string) $expected ); switch ( $action ) { From d862ebd563493bcf8610aa8400c860eb33a1c71e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 21:50:39 +0200 Subject: [PATCH 1351/4858] replace 'Given WP install' with 'Given a WP install' --- features/core.feature | 4 ++-- features/flags.feature | 8 ++++---- features/plugin.feature | 2 +- features/post.feature | 2 +- features/steps/basic_steps.php | 2 +- features/theme.feature | 4 ++-- features/user.feature | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/features/core.feature b/features/core.feature index fe5dbd3951..d333fbaab7 100644 --- a/features/core.feature +++ b/features/core.feature @@ -64,13 +64,13 @@ Feature: Manage WordPress installation And STDOUT should not be empty Scenario: Full install - Given WP install + Given a WP install When I run `wp core is-installed` Then it should run without errors Scenario: Custom wp-content directory - Given WP install + Given a WP install And custom wp-content directory When I run `wp plugin status hello` diff --git a/features/flags.feature b/features/flags.feature index 9ef0db43f9..676729004b 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -1,7 +1,7 @@ Feature: Global flags Scenario: Quiet run - Given WP install + Given a WP install When I run `wp` Then it should run without errors @@ -19,7 +19,7 @@ Feature: Global flags """ Scenario: Debug run - Given WP install + Given a WP install When I run `wp eval 'echo CONST_WITHOUT_QUOTES;'` Then it should run without errors @@ -36,7 +36,7 @@ Feature: Global flags """ Scenario: Setting the WP user - Given WP install + Given a WP install When I run `wp eval 'echo (int) is_user_logged_in();'` Then it should run without errors @@ -60,7 +60,7 @@ Feature: Global flags """ Scenario: Enabling/disabling color - Given WP install + Given a WP install When I run `wp --no-color non-existant-command` Then STDERR should be: diff --git a/features/plugin.feature b/features/plugin.feature index dcd4034da5..88dbf0548a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -1,7 +1,7 @@ Feature: Manage WordPress plugins Scenario: Checking the plugin status - Given WP install + Given a WP install When I run `wp plugin status` Then it should run without errors diff --git a/features/post.feature b/features/post.feature index 2ecfe9b8d0..af7999f42a 100644 --- a/features/post.feature +++ b/features/post.feature @@ -1,7 +1,7 @@ Feature: Manage WordPress posts Scenario: Creating/updating/deleting posts - Given WP install + Given a WP install When I run `wp post create --post_title='Test post' --porcelain` Then it should run without errors diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 218326b127..6e48c3bb81 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -28,7 +28,7 @@ function ( $world ) { } ); -$steps->Given( '/^WP install$/', +$steps->Given( '/^a WP install$/', function ( $world ) { $world->create_db(); $world->create_empty_dir(); diff --git a/features/theme.feature b/features/theme.feature index a60d22ed10..086659d66c 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -1,7 +1,7 @@ Feature: Manage WordPress themes Scenario: Installing a theme - Given WP install + Given a WP install When I run `wp theme install p2` Then it should run without errors @@ -42,7 +42,7 @@ Feature: Manage WordPress themes """ Scenario: Upgrading a theme - Given WP install + Given a WP install And a P2 theme zip When I run `wp theme install {THEME_ZIP}` diff --git a/features/user.feature b/features/user.feature index 0c68fd9cbd..d1d034a9ea 100644 --- a/features/user.feature +++ b/features/user.feature @@ -1,7 +1,7 @@ Feature: Manage WordPress users Scenario: Creating/updating/deleting users - Given WP install + Given a WP install When I run `wp user create testuser testuser@example.com --porcelain` Then it should run without errors @@ -22,7 +22,7 @@ Feature: Manage WordPress users Then it should run without errors Scenario: Generating users - Given WP install + Given a WP install # Delete all users When I run `wp user list --ids` From ed565f301c1112ba8e604e4843583c1c33195b3e Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 8 Mar 2013 21:44:14 +0100 Subject: [PATCH 1352/4858] Removed future wp filesystem --- php/commands/media.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index b61a28dd36..c8e74e00c0 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -6,10 +6,6 @@ * @package wp-cli */ class Media_Command extends WP_CLI_Command { - - function __construct() { - WP_Filesystem(); - } /** * Regenerate thumbnail(s) From 285e6a2ff8a7568aea5878372a7722ed5d5b5f8c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 Mar 2013 22:44:29 +0200 Subject: [PATCH 1353/4858] don't allow deletion of the current theme WSODs are bad, mkay. --- php/commands/theme.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 26dbdad778..4f5a8dee95 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -178,6 +178,10 @@ function update_all( $args, $assoc_args ) { function delete( $args ) { $theme = $this->parse_name( $args ); + if ( $this->is_active_theme( $theme ) ) { + WP_CLI::error( "Can't delete the currently active theme." ); + } + $r = delete_theme( $theme->get_stylesheet() ); if ( is_wp_error( $r ) ) { From c7978365ccebaad852ac36627f386860acbb761d Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 8 Mar 2013 22:22:24 +0100 Subject: [PATCH 1354/4858] Put back the sprintf --- php/commands/media.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index c8e74e00c0..3833779487 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -40,7 +40,7 @@ function regenerate( $args, $assoc_args = array() ) { } $count = $images->post_count; - WP_CLI::line( "Found {$count} " . ngettext('image', 'images', $count) . " to regenerate." ); + WP_CLI::line( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); $not_found = array_diff( $args, $images->posts ); if( !empty($not_found) ) { @@ -51,7 +51,7 @@ function regenerate( $args, $assoc_args = array() ) { $this->_process_regeneration( $id ); } - WP_CLI::success( "Finished regenerating " . ngettext('the image', 'all images', $count) . "."); + WP_CLI::success( sprintf( 'Finished regenerating %1$s.', ngettext('the image', 'all images', $count) ) ); } private function _process_regeneration( $id ) { @@ -70,7 +70,7 @@ private function _process_regeneration( $id ) { return; } - WP_CLI::line( "Start processing of \"" . get_the_title( $image->ID ) . "\" (ID: {$image->ID})" ); + WP_CLI::line( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); $a_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); $a_file = explode( '.', $a_path[ count( $a_path ) - 1 ] ); @@ -130,7 +130,12 @@ private function _process_regeneration( $id ) { private function _not_found_message( $not_found_ids ){ $count = count($not_found_ids); - return "Unable to find the " . ngettext('image', 'images', $count) . " (" . implode(", ", $not_found_ids) . "). Are you sure " . ngettext('it', 'they', $count) . " " . ngettext('exist', 'exists', $count) . "?"; + return vsprintf( 'Unable to find the %1$s (%2$s). Are you sure %3$s %4$s?', array( + ngettext('image', 'images', $count), + implode(", ", $not_found_ids), + ngettext('it', 'they', $count), + ngettext('exists', 'exist', $count), + )); } } From da28c063a2150c0ecee0fcb045ddf489c9b14d4c Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 8 Mar 2013 22:25:26 +0100 Subject: [PATCH 1355/4858] Removed obsolete check --- php/commands/media.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 3833779487..77c6a10751 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -57,12 +57,7 @@ function regenerate( $args, $assoc_args = array() ) { private function _process_regeneration( $id ) { $image = get_post( $id ); - - if ( !$image || 'attachment' != $image->post_type || 'image/' != substr( $image->post_mime_type, 0, 6 ) ) { - WP_CLI::warning( "{$image->post_title} - invalid image ID." ); - return; - } - + $fullsizepath = get_attached_file( $image->ID ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { From e2d0534e2abc0fd49269e0ddaded2e3fa8a579ff Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sat, 9 Mar 2013 15:31:08 +0000 Subject: [PATCH 1356/4858] Correct documentation for capability removal function --- php/commands/cap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index aea5a2f73a..31004285ca 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -47,7 +47,7 @@ public function add( $args ) { } /** - * Add capabilities to a given role. + * Remove capabilities from a given role. * * @synopsis <role> <cap>... */ From 8ac5bbfb4cd2a9c32d394c01da91cf578de3afb6 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sat, 9 Mar 2013 16:18:01 +0000 Subject: [PATCH 1357/4858] Add new roles command. Implements list, create, delete --- php/commands/roles.php | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 php/commands/roles.php diff --git a/php/commands/roles.php b/php/commands/roles.php new file mode 100644 index 0000000000..c7123d8a25 --- /dev/null +++ b/php/commands/roles.php @@ -0,0 +1,88 @@ +<?php + +/** + * Manage user roles. + * + * @package wp-cli + */ +class Roles_Command extends WP_CLI_Command { + + /** + * List one or all roles. + * + * @subcommand list + * @synopsis [<role-key>] + */ + public function _list( $args ) { + global $wp_roles; + + if ( isset ( $args[0] ) ) + $target_role = $args[0]; + else + $target_role = ''; + + foreach ( $wp_roles->roles as $key => $role ) { + if ( empty ( $target_role ) || $key == $target_role ) + WP_CLI::line( $role['name'] . " ($key)"); + } + } + + /** + * Create a new role. + * + * @subcommand create + * @synopsis <role-key> <role-name> + */ + public function _create( $args ) { + self::persistence_check(); + + $role_key = array_shift( $args ); + $role_name = array_shift( $args ); + + if ( empty ( $role_key ) || empty ( $role_name ) ) + WP_CLI::error( "Can't create role, insufficient information provided."); + + if ( ! add_role ( $role_key, $role_name ) ) + WP_CLI::error( "Role couldn't be created." ); + else + WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); + + } + + /** + * Delete an existing role + * + * @subcommand delete + * @synopsis <role-key> + */ + public function _delete( $args ) { + + global $wp_roles; + + self::persistence_check(); + + $role_key = array_shift( $args ); + + if ( empty ( $role_key ) || ! isset ( $wp_roles->roles[$role_key] ) ) + WP_CLI::error( "Role key not provided, or is invalid." ); + + remove_role ( $role_key ); + + // Note: remove_role() doesn't indicate success or otherwise, so we have to + // check ourselves + if ( ! isset ( $wp_roles->roles[$role_key] ) ) + WP_CLI::success( sprintf( "Role with key %s deleted.", $role_key ) ); + else + WP_CLI::error( sprintf( "Role with key %s could not be deleted.", $role_key ) ); + + } + + private static function persistence_check() { + global $wp_roles; + + if ( !$wp_roles->use_db ) + WP_CLI::error( "Role definitions are not persistent." ); + } +} + +WP_CLI::add_command( 'roles', 'Roles_Command' ); \ No newline at end of file From 70de7f4b857a4ee17422dc9e016a8ebb0c8fe035 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sat, 9 Mar 2013 20:25:58 +0000 Subject: [PATCH 1358/4858] Remove spaces before function calls --- php/commands/roles.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/php/commands/roles.php b/php/commands/roles.php index c7123d8a25..8372e3c998 100644 --- a/php/commands/roles.php +++ b/php/commands/roles.php @@ -16,13 +16,13 @@ class Roles_Command extends WP_CLI_Command { public function _list( $args ) { global $wp_roles; - if ( isset ( $args[0] ) ) + if ( isset( $args[0] ) ) $target_role = $args[0]; else $target_role = ''; foreach ( $wp_roles->roles as $key => $role ) { - if ( empty ( $target_role ) || $key == $target_role ) + if ( empty( $target_role ) || $key == $target_role ) WP_CLI::line( $role['name'] . " ($key)"); } } @@ -39,10 +39,10 @@ public function _create( $args ) { $role_key = array_shift( $args ); $role_name = array_shift( $args ); - if ( empty ( $role_key ) || empty ( $role_name ) ) + if ( empty( $role_key ) || empty( $role_name ) ) WP_CLI::error( "Can't create role, insufficient information provided."); - if ( ! add_role ( $role_key, $role_name ) ) + if ( ! add_role( $role_key, $role_name ) ) WP_CLI::error( "Role couldn't be created." ); else WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); @@ -63,14 +63,14 @@ public function _delete( $args ) { $role_key = array_shift( $args ); - if ( empty ( $role_key ) || ! isset ( $wp_roles->roles[$role_key] ) ) + if ( empty( $role_key ) || ! isset( $wp_roles->roles[$role_key] ) ) WP_CLI::error( "Role key not provided, or is invalid." ); - remove_role ( $role_key ); + remove_role( $role_key ); // Note: remove_role() doesn't indicate success or otherwise, so we have to // check ourselves - if ( ! isset ( $wp_roles->roles[$role_key] ) ) + if ( ! isset( $wp_roles->roles[$role_key] ) ) WP_CLI::success( sprintf( "Role with key %s deleted.", $role_key ) ); else WP_CLI::error( sprintf( "Role with key %s could not be deleted.", $role_key ) ); From f8f388c291011a24941e850299079df9cc791138 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sat, 9 Mar 2013 20:33:55 +0000 Subject: [PATCH 1359/4858] Add man src files --- man-src/roles-create.txt | 16 ++++++++++++++++ man-src/roles-delete.txt | 12 ++++++++++++ man-src/roles-list.txt | 12 ++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 man-src/roles-create.txt create mode 100644 man-src/roles-delete.txt create mode 100644 man-src/roles-list.txt diff --git a/man-src/roles-create.txt b/man-src/roles-create.txt new file mode 100644 index 0000000000..912f829ffd --- /dev/null +++ b/man-src/roles-create.txt @@ -0,0 +1,16 @@ +## OPTIONS + +* <role-key>: + + The internal name of the role, e.g. editor + +* <role-name>: + + The publically visible name of the rule, e.g. Editor + +## EXAMPLES + + wp roles create approver Approver + + wp roles create productadmin "Product Administrator" + diff --git a/man-src/roles-delete.txt b/man-src/roles-delete.txt new file mode 100644 index 0000000000..676e290fe9 --- /dev/null +++ b/man-src/roles-delete.txt @@ -0,0 +1,12 @@ +## OPTIONS + +* <role-key>: + + The internal name of the role, e.g. editor + +## EXAMPLES + + wp roles delete approver + + wp roles create productadmin + diff --git a/man-src/roles-list.txt b/man-src/roles-list.txt new file mode 100644 index 0000000000..364c1fea9c --- /dev/null +++ b/man-src/roles-list.txt @@ -0,0 +1,12 @@ +## OPTIONS + +* [<role-key>]: + + Optional. A role to return. + +## EXAMPLES + + wp roles list + + wp roles list editor + From 70583a50febec04f415369634fbfd2ae00ce5dbd Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sat, 9 Mar 2013 20:34:40 +0000 Subject: [PATCH 1360/4858] Generated man files --- man/roles-create.1 | 35 +++++++++++++++++++++++++++++++++++ man/roles-delete.1 | 29 +++++++++++++++++++++++++++++ man/roles-list.1 | 29 +++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 man/roles-create.1 create mode 100644 man/roles-delete.1 create mode 100644 man/roles-list.1 diff --git a/man/roles-create.1 b/man/roles-create.1 new file mode 100644 index 0000000000..19f92fe762 --- /dev/null +++ b/man/roles-create.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLES\-CREATE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-roles\-create\fR \- Create a new role\. +. +.SH "SYNOPSIS" +wp roles create \fIrole\-key\fR \fIrole\-name\fR +. +.SH "OPTIONS" +. +.TP +\fIrole\-key\fR: +. +.IP +The internal name of the role, e\.g\. editor +. +.TP +\fIrole\-name\fR: +. +.IP +The publically visible name of the rule, e\.g\. Editor +. +.SH "EXAMPLES" +. +.nf + +wp roles create approver Approver + +wp roles create productadmin "Product Administrator" +. +.fi + diff --git a/man/roles-delete.1 b/man/roles-delete.1 new file mode 100644 index 0000000000..5ed0e3444f --- /dev/null +++ b/man/roles-delete.1 @@ -0,0 +1,29 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLES\-DELETE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-roles\-delete\fR \- Delete an existing role +. +.SH "SYNOPSIS" +wp roles delete \fIrole\-key\fR +. +.SH "OPTIONS" +. +.TP +\fIrole\-key\fR: +. +.IP +The internal name of the role, e\.g\. editor +. +.SH "EXAMPLES" +. +.nf + +wp roles delete approver + +wp roles create productadmin +. +.fi + diff --git a/man/roles-list.1 b/man/roles-list.1 new file mode 100644 index 0000000000..4a7f5a3711 --- /dev/null +++ b/man/roles-list.1 @@ -0,0 +1,29 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLES\-LIST" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-roles\-list\fR \- List one or all roles\. +. +.SH "SYNOPSIS" +wp roles list [\fIrole\-key\fR] +. +.SH "OPTIONS" +. +.TP +[\fIrole\-key\fR]: +. +.IP +Optional\. A role to return\. +. +.SH "EXAMPLES" +. +.nf + +wp roles list + +wp roles list editor +. +.fi + From 15720e64ba83d1460eaf84bbb3a48056e5bb6ddf Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sat, 9 Mar 2013 20:37:40 +0000 Subject: [PATCH 1361/4858] Regenerated man page --- man/cap.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/cap.1 b/man/cap.1 index 5dfefa6548..5e8c620f85 100644 --- a/man/cap.1 +++ b/man/cap.1 @@ -33,7 +33,7 @@ List capabilities for a given role\. \fBremove\fR: . .IP -Add capabilities to a given role\. +Remove capabilities from a given role\. . .SH "EXAMPLES" . From 39ee2d5e4e7c7a8b0907a6e8327a01730aaa7eac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Mar 2013 22:49:56 +0200 Subject: [PATCH 1362/4858] tests: switch to previous theme before deleting the current theme --- features/theme.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 086659d66c..a6a57c252a 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -24,6 +24,10 @@ Feature: Manage WordPress themes /themes/p2/style.css """ + When I run `wp option get stylesheet` + Then it should run without errors + And save STDOUT as {PREVIOUS_THEME} + When I run `wp theme activate p2` Then it should run without errors And STDOUT should contain: @@ -31,6 +35,10 @@ Feature: Manage WordPress themes Success: Switched to 'P2' theme. """ + When I run `wp theme activate {PREVIOUS_THEME}` + Then it should run without errors + And STDOUT should not be empty + When I run `wp theme delete p2` Then it should run without errors From 70e6ab3bbe7df257d035d63876de1b5cd3a75750 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Mar 2013 23:17:58 +0200 Subject: [PATCH 1363/4858] travis: add --prefer-source, in the hope of not reaching the Github API limit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bb6c74de77..e72bb6c453 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ env: before_script: # install dependencies - curl -sS https://getcomposer.org/installer | php - - php composer.phar install --dev --no-interaction + - php composer.phar install --dev --no-interaction --prefer-source # set up WP install - WP_CORE_DIR=/tmp/wp-cli-test-core-download-cache/ - mkdir -p $WP_CORE_DIR From e99b22dce52bf70187cf3755fd80ec69375bf3ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Mar 2013 23:21:20 +0200 Subject: [PATCH 1364/4858] travis: use pre-installed Composer binary --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e72bb6c453..294495c753 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ env: before_script: # install dependencies - - curl -sS https://getcomposer.org/installer | php - - php composer.phar install --dev --no-interaction --prefer-source + - composer install --dev --no-interaction --prefer-source # set up WP install - WP_CORE_DIR=/tmp/wp-cli-test-core-download-cache/ - mkdir -p $WP_CORE_DIR From 8e4b6b70c5826f89a91dc6ba2f178a24593f6285 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 21:55:52 +0000 Subject: [PATCH 1365/4858] s/roles/role/ --- man-src/{roles-create.txt => role-create.txt} | 4 ++-- man-src/{roles-delete.txt => role-delete.txt} | 4 ++-- man-src/{roles-list.txt => role-list.txt} | 4 ++-- php/commands/{roles.php => role.php} | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename man-src/{roles-create.txt => role-create.txt} (63%) rename man-src/{roles-delete.txt => role-delete.txt} (59%) rename man-src/{roles-list.txt => role-list.txt} (66%) rename php/commands/{roles.php => role.php} (95%) diff --git a/man-src/roles-create.txt b/man-src/role-create.txt similarity index 63% rename from man-src/roles-create.txt rename to man-src/role-create.txt index 912f829ffd..6c7d2e523e 100644 --- a/man-src/roles-create.txt +++ b/man-src/role-create.txt @@ -10,7 +10,7 @@ ## EXAMPLES - wp roles create approver Approver + wp role create approver Approver - wp roles create productadmin "Product Administrator" + wp role create productadmin "Product Administrator" diff --git a/man-src/roles-delete.txt b/man-src/role-delete.txt similarity index 59% rename from man-src/roles-delete.txt rename to man-src/role-delete.txt index 676e290fe9..fafd2ac028 100644 --- a/man-src/roles-delete.txt +++ b/man-src/role-delete.txt @@ -6,7 +6,7 @@ ## EXAMPLES - wp roles delete approver + wp role delete approver - wp roles create productadmin + wp role delete productadmin diff --git a/man-src/roles-list.txt b/man-src/role-list.txt similarity index 66% rename from man-src/roles-list.txt rename to man-src/role-list.txt index 364c1fea9c..563dd3a9cd 100644 --- a/man-src/roles-list.txt +++ b/man-src/role-list.txt @@ -6,7 +6,7 @@ ## EXAMPLES - wp roles list + wp role list - wp roles list editor + wp role list editor diff --git a/php/commands/roles.php b/php/commands/role.php similarity index 95% rename from php/commands/roles.php rename to php/commands/role.php index 8372e3c998..785544ca62 100644 --- a/php/commands/roles.php +++ b/php/commands/role.php @@ -5,7 +5,7 @@ * * @package wp-cli */ -class Roles_Command extends WP_CLI_Command { +class Role_Command extends WP_CLI_Command { /** * List one or all roles. @@ -85,4 +85,4 @@ private static function persistence_check() { } } -WP_CLI::add_command( 'roles', 'Roles_Command' ); \ No newline at end of file +WP_CLI::add_command( 'role', 'Role_Command' ); \ No newline at end of file From 6db8d851944b690f5e93eee4d5f4ab2e8212f097 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 21:56:38 +0000 Subject: [PATCH 1366/4858] function rename, and remove unneeded @subcommand declarations --- php/commands/role.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 785544ca62..0846352d7d 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -30,10 +30,9 @@ public function _list( $args ) { /** * Create a new role. * - * @subcommand create * @synopsis <role-key> <role-name> */ - public function _create( $args ) { + public function create( $args ) { self::persistence_check(); $role_key = array_shift( $args ); @@ -52,10 +51,9 @@ public function _create( $args ) { /** * Delete an existing role * - * @subcommand delete * @synopsis <role-key> */ - public function _delete( $args ) { + public function delete( $args ) { global $wp_roles; From c817971bbe17b381ad4362e7fafc31fe0cbbc1ce Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 21:57:13 +0000 Subject: [PATCH 1367/4858] Doc fix --- php/commands/role.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index 0846352d7d..e70f11fff9 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -49,7 +49,7 @@ public function create( $args ) { } /** - * Delete an existing role + * Delete an existing role. * * @synopsis <role-key> */ From 6ab3a58e9fd9fe1e4661f82e59bbf12ea5f3ce9f Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 22:07:43 +0000 Subject: [PATCH 1368/4858] Correct typo in docs --- man-src/role-create.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man-src/role-create.txt b/man-src/role-create.txt index 6c7d2e523e..d041b245a8 100644 --- a/man-src/role-create.txt +++ b/man-src/role-create.txt @@ -6,7 +6,7 @@ * <role-name>: - The publically visible name of the rule, e.g. Editor + The publically visible name of the role, e.g. Editor ## EXAMPLES From dc11141b56e93a1dfa94bad6c00090721878cb1c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 00:11:02 +0200 Subject: [PATCH 1369/4858] WP_Theme was introduced in WP 3.4, but switch_theme() still requires two parameters until WP 3.5 --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 4f5a8dee95..70d8dad2ed 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -53,7 +53,7 @@ protected function get_status( $theme ) { public function activate( $args = array() ) { $theme = $this->parse_name( $args ); - switch_theme( $theme->get_stylesheet() ); + switch_theme( $theme->get_template(), $theme->get_stylesheet() ); $name = $theme->get('Name'); From 0d0febabe50144fb001a9f00ed771d2c5d7484b4 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 22:37:27 +0000 Subject: [PATCH 1370/4858] Remove old versions of generated man files --- man/roles-create.1 | 35 ----------------------------------- man/roles-delete.1 | 29 ----------------------------- man/roles-list.1 | 29 ----------------------------- 3 files changed, 93 deletions(-) delete mode 100644 man/roles-create.1 delete mode 100644 man/roles-delete.1 delete mode 100644 man/roles-list.1 diff --git a/man/roles-create.1 b/man/roles-create.1 deleted file mode 100644 index 19f92fe762..0000000000 --- a/man/roles-create.1 +++ /dev/null @@ -1,35 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLES\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-roles\-create\fR \- Create a new role\. -. -.SH "SYNOPSIS" -wp roles create \fIrole\-key\fR \fIrole\-name\fR -. -.SH "OPTIONS" -. -.TP -\fIrole\-key\fR: -. -.IP -The internal name of the role, e\.g\. editor -. -.TP -\fIrole\-name\fR: -. -.IP -The publically visible name of the rule, e\.g\. Editor -. -.SH "EXAMPLES" -. -.nf - -wp roles create approver Approver - -wp roles create productadmin "Product Administrator" -. -.fi - diff --git a/man/roles-delete.1 b/man/roles-delete.1 deleted file mode 100644 index 5ed0e3444f..0000000000 --- a/man/roles-delete.1 +++ /dev/null @@ -1,29 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLES\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-roles\-delete\fR \- Delete an existing role -. -.SH "SYNOPSIS" -wp roles delete \fIrole\-key\fR -. -.SH "OPTIONS" -. -.TP -\fIrole\-key\fR: -. -.IP -The internal name of the role, e\.g\. editor -. -.SH "EXAMPLES" -. -.nf - -wp roles delete approver - -wp roles create productadmin -. -.fi - diff --git a/man/roles-list.1 b/man/roles-list.1 deleted file mode 100644 index 4a7f5a3711..0000000000 --- a/man/roles-list.1 +++ /dev/null @@ -1,29 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLES\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-roles\-list\fR \- List one or all roles\. -. -.SH "SYNOPSIS" -wp roles list [\fIrole\-key\fR] -. -.SH "OPTIONS" -. -.TP -[\fIrole\-key\fR]: -. -.IP -Optional\. A role to return\. -. -.SH "EXAMPLES" -. -.nf - -wp roles list - -wp roles list editor -. -.fi - From efe9af065e7bc31ceb3833add248849d71e5784e Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 22:38:37 +0000 Subject: [PATCH 1371/4858] role list just lists all roles, no args --- man-src/role-list.txt | 9 --------- php/commands/role.php | 9 +-------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/man-src/role-list.txt b/man-src/role-list.txt index 563dd3a9cd..dd144391fd 100644 --- a/man-src/role-list.txt +++ b/man-src/role-list.txt @@ -1,12 +1,3 @@ -## OPTIONS - -* [<role-key>]: - - Optional. A role to return. - ## EXAMPLES wp role list - - wp role list editor - diff --git a/php/commands/role.php b/php/commands/role.php index e70f11fff9..b9419d27a6 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -8,21 +8,14 @@ class Role_Command extends WP_CLI_Command { /** - * List one or all roles. + * List all roles. * * @subcommand list - * @synopsis [<role-key>] */ public function _list( $args ) { global $wp_roles; - if ( isset( $args[0] ) ) - $target_role = $args[0]; - else - $target_role = ''; - foreach ( $wp_roles->roles as $key => $role ) { - if ( empty( $target_role ) || $key == $target_role ) WP_CLI::line( $role['name'] . " ($key)"); } } From 9352f057e8e15b7b1627976b909567faff712785 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 22:39:07 +0000 Subject: [PATCH 1372/4858] Add role exists comand --- man-src/role-exists.txt | 16 ++++++++++++++++ php/commands/role.php | 15 +++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 man-src/role-exists.txt diff --git a/man-src/role-exists.txt b/man-src/role-exists.txt new file mode 100644 index 0000000000..aac999737d --- /dev/null +++ b/man-src/role-exists.txt @@ -0,0 +1,16 @@ +## OPTIONS + +* <role-key>: + + The internal name of the role, e.g. editor + + +##DESCRIPTION + +Will return 0 if the role exists, 1 if it does not. + + +## EXAMPLES + + wp role exists editor + diff --git a/php/commands/role.php b/php/commands/role.php index b9419d27a6..11754e607a 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -20,6 +20,21 @@ public function _list( $args ) { } } + /** + * Check if a role exists. + * Will return 0 if the role exists, 1 if it does not. + * + * @subcommand exists + * @synopsis <role-key> + */ + public function _exists( $args ) { + global $wp_roles; + + if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { + WP_CLI::error( "Role not found." ); + } + } + /** * Create a new role. * From 94088d4e3c4ca8a226ef1562ed66d46df6deff4f Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Sun, 10 Mar 2013 22:40:04 +0000 Subject: [PATCH 1373/4858] Regenerate man files --- man/role-create.1 | 35 +++++++++++++++++++++++++++++++++++ man/role-delete.1 | 29 +++++++++++++++++++++++++++++ man/role-exists.1 | 30 ++++++++++++++++++++++++++++++ man/role-list.1 | 19 +++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 man/role-create.1 create mode 100644 man/role-delete.1 create mode 100644 man/role-exists.1 create mode 100644 man/role-list.1 diff --git a/man/role-create.1 b/man/role-create.1 new file mode 100644 index 0000000000..4737ed2b0c --- /dev/null +++ b/man/role-create.1 @@ -0,0 +1,35 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLE\-CREATE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-role\-create\fR \- Create a new role\. +. +.SH "SYNOPSIS" +wp role create \fIrole\-key\fR \fIrole\-name\fR +. +.SH "OPTIONS" +. +.TP +\fIrole\-key\fR: +. +.IP +The internal name of the role, e\.g\. editor +. +.TP +\fIrole\-name\fR: +. +.IP +The publically visible name of the role, e\.g\. Editor +. +.SH "EXAMPLES" +. +.nf + +wp role create approver Approver + +wp role create productadmin "Product Administrator" +. +.fi + diff --git a/man/role-delete.1 b/man/role-delete.1 new file mode 100644 index 0000000000..02375d3693 --- /dev/null +++ b/man/role-delete.1 @@ -0,0 +1,29 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLE\-DELETE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-role\-delete\fR \- Delete an existing role\. +. +.SH "SYNOPSIS" +wp role delete \fIrole\-key\fR +. +.SH "OPTIONS" +. +.TP +\fIrole\-key\fR: +. +.IP +The internal name of the role, e\.g\. editor +. +.SH "EXAMPLES" +. +.nf + +wp role delete approver + +wp role delete productadmin +. +.fi + diff --git a/man/role-exists.1 b/man/role-exists.1 new file mode 100644 index 0000000000..8478a971f4 --- /dev/null +++ b/man/role-exists.1 @@ -0,0 +1,30 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLE\-EXISTS" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-role\-exists\fR \- Check if a role exists\. +. +.SH "SYNOPSIS" +wp role exists \fIrole\-key\fR +. +.SH "OPTIONS" +. +.TP +\fIrole\-key\fR: +. +.IP +The internal name of the role, e\.g\. editor +. +.SH "DESCRIPTION" +Will return 0 if the role exists, 1 if it does not\. +. +.SH "EXAMPLES" +. +.nf + +wp role exists editor +. +.fi + diff --git a/man/role-list.1 b/man/role-list.1 new file mode 100644 index 0000000000..7998c7010d --- /dev/null +++ b/man/role-list.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-ROLE\-LIST" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-role\-list\fR \- List all roles\. +. +.SH "SYNOPSIS" +wp role list +. +.SH "EXAMPLES" +. +.nf + +wp role list +. +.fi + From 7f20dc1ca645817351901abd595574b06369a0e3 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Mon, 11 Mar 2013 07:32:40 +0000 Subject: [PATCH 1374/4858] Convert indents to be spaces consistently --- man-src/role-create.txt | 5 +- man-src/role-delete.txt | 4 +- man-src/role-exists.txt | 2 +- man-src/role-list.txt | 2 +- php/commands/role.php | 164 ++++++++++++++++++++-------------------- 5 files changed, 88 insertions(+), 89 deletions(-) diff --git a/man-src/role-create.txt b/man-src/role-create.txt index d041b245a8..dde7db553f 100644 --- a/man-src/role-create.txt +++ b/man-src/role-create.txt @@ -2,7 +2,7 @@ * <role-key>: - The internal name of the role, e.g. editor + The internal name of the role, e.g. editor * <role-name>: @@ -12,5 +12,4 @@ wp role create approver Approver - wp role create productadmin "Product Administrator" - + wp role create productadmin "Product Administrator" diff --git a/man-src/role-delete.txt b/man-src/role-delete.txt index fafd2ac028..f8519240d2 100644 --- a/man-src/role-delete.txt +++ b/man-src/role-delete.txt @@ -2,11 +2,11 @@ * <role-key>: - The internal name of the role, e.g. editor + The internal name of the role, e.g. editor ## EXAMPLES wp role delete approver - wp role delete productadmin + wp role delete productadmin diff --git a/man-src/role-exists.txt b/man-src/role-exists.txt index aac999737d..afd32a5a04 100644 --- a/man-src/role-exists.txt +++ b/man-src/role-exists.txt @@ -2,7 +2,7 @@ * <role-key>: - The internal name of the role, e.g. editor + The internal name of the role, e.g. editor ##DESCRIPTION diff --git a/man-src/role-list.txt b/man-src/role-list.txt index dd144391fd..6bc9ed2a36 100644 --- a/man-src/role-list.txt +++ b/man-src/role-list.txt @@ -1,3 +1,3 @@ ## EXAMPLES - wp role list + wp role list diff --git a/php/commands/role.php b/php/commands/role.php index 11754e607a..20c3833a41 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -7,88 +7,88 @@ */ class Role_Command extends WP_CLI_Command { - /** - * List all roles. - * - * @subcommand list - */ - public function _list( $args ) { - global $wp_roles; - - foreach ( $wp_roles->roles as $key => $role ) { - WP_CLI::line( $role['name'] . " ($key)"); - } - } - - /** - * Check if a role exists. - * Will return 0 if the role exists, 1 if it does not. - * - * @subcommand exists - * @synopsis <role-key> - */ - public function _exists( $args ) { - global $wp_roles; - - if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { - WP_CLI::error( "Role not found." ); - } - } - - /** - * Create a new role. - * - * @synopsis <role-key> <role-name> - */ - public function create( $args ) { - self::persistence_check(); - - $role_key = array_shift( $args ); - $role_name = array_shift( $args ); - - if ( empty( $role_key ) || empty( $role_name ) ) - WP_CLI::error( "Can't create role, insufficient information provided."); - - if ( ! add_role( $role_key, $role_name ) ) - WP_CLI::error( "Role couldn't be created." ); - else - WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); - - } - - /** - * Delete an existing role. - * - * @synopsis <role-key> - */ - public function delete( $args ) { - - global $wp_roles; - - self::persistence_check(); - - $role_key = array_shift( $args ); - - if ( empty( $role_key ) || ! isset( $wp_roles->roles[$role_key] ) ) - WP_CLI::error( "Role key not provided, or is invalid." ); - - remove_role( $role_key ); - - // Note: remove_role() doesn't indicate success or otherwise, so we have to - // check ourselves - if ( ! isset( $wp_roles->roles[$role_key] ) ) - WP_CLI::success( sprintf( "Role with key %s deleted.", $role_key ) ); - else - WP_CLI::error( sprintf( "Role with key %s could not be deleted.", $role_key ) ); - - } - - private static function persistence_check() { - global $wp_roles; - - if ( !$wp_roles->use_db ) - WP_CLI::error( "Role definitions are not persistent." ); - } + /** + * List all roles. + * + * @subcommand list + */ + public function _list( $args ) { + global $wp_roles; + + foreach ( $wp_roles->roles as $key => $role ) { + WP_CLI::line( $role['name'] . " ($key)"); + } + } + + /** + * Check if a role exists. + * Will return 0 if the role exists, 1 if it does not. + * + * @subcommand exists + * @synopsis <role-key> + */ + public function _exists( $args ) { + global $wp_roles; + + if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { + WP_CLI::error( "Role not found." ); + } + } + + /** + * Create a new role. + * + * @synopsis <role-key> <role-name> + */ + public function create( $args ) { + self::persistence_check(); + + $role_key = array_shift( $args ); + $role_name = array_shift( $args ); + + if ( empty( $role_key ) || empty( $role_name ) ) + WP_CLI::error( "Can't create role, insufficient information provided."); + + if ( ! add_role( $role_key, $role_name ) ) + WP_CLI::error( "Role couldn't be created." ); + else + WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); + + } + + /** + * Delete an existing role. + * + * @synopsis <role-key> + */ + public function delete( $args ) { + + global $wp_roles; + + self::persistence_check(); + + $role_key = array_shift( $args ); + + if ( empty( $role_key ) || ! isset( $wp_roles->roles[$role_key] ) ) + WP_CLI::error( "Role key not provided, or is invalid." ); + + remove_role( $role_key ); + + // Note: remove_role() doesn't indicate success or otherwise, so we have to + // check ourselves + if ( ! isset( $wp_roles->roles[$role_key] ) ) + WP_CLI::success( sprintf( "Role with key %s deleted.", $role_key ) ); + else + WP_CLI::error( sprintf( "Role with key %s could not be deleted.", $role_key ) ); + + } + + private static function persistence_check() { + global $wp_roles; + + if ( !$wp_roles->use_db ) + WP_CLI::error( "Role definitions are not persistent." ); + } } WP_CLI::add_command( 'role', 'Role_Command' ); \ No newline at end of file From 895327aacffb28cb16f40c134e5f5202e69a418f Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Mon, 11 Mar 2013 07:36:31 +0000 Subject: [PATCH 1375/4858] Make role exists produce no output --- php/commands/role.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index 20c3833a41..7d2046eab3 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -31,7 +31,7 @@ public function _exists( $args ) { global $wp_roles; if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { - WP_CLI::error( "Role not found." ); + exit(1); } } From 9bbec43bf39507846e01dd1dc1a933576d0aff02 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Mon, 11 Mar 2013 07:36:57 +0000 Subject: [PATCH 1376/4858] s/_exists/exists --- php/commands/role.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 7d2046eab3..2e1237586d 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -24,10 +24,9 @@ public function _list( $args ) { * Check if a role exists. * Will return 0 if the role exists, 1 if it does not. * - * @subcommand exists * @synopsis <role-key> */ - public function _exists( $args ) { + public function exists( $args ) { global $wp_roles; if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { From bd357e02a8bec1ebf76d0a88e973159f093648bd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 09:51:26 +0200 Subject: [PATCH 1377/4858] clarify documentation for `role exists`. see #350 --- man-src/role-exists.txt | 2 +- man/role-exists.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/role-exists.txt b/man-src/role-exists.txt index afd32a5a04..28a8ee0a50 100644 --- a/man-src/role-exists.txt +++ b/man-src/role-exists.txt @@ -7,7 +7,7 @@ ##DESCRIPTION -Will return 0 if the role exists, 1 if it does not. +Will exit with status 0 if the role exists, 1 if it does not. ## EXAMPLES diff --git a/man/role-exists.1 b/man/role-exists.1 index 8478a971f4..7db3baa31f 100644 --- a/man/role-exists.1 +++ b/man/role-exists.1 @@ -18,7 +18,7 @@ wp role exists \fIrole\-key\fR The internal name of the role, e\.g\. editor . .SH "DESCRIPTION" -Will return 0 if the role exists, 1 if it does not\. +Will exit with status 0 if the role exists, 1 if it does not\. . .SH "EXAMPLES" . From c444a0709dbe71c6607cab3da2106d2b7e576cf0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 10:16:33 +0200 Subject: [PATCH 1378/4858] download WP from wordpress.org Hopefully, it's more reliable than Github's tarball service. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 294495c753..eaf97a25e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,8 @@ php: - 5.4 env: - - WP_VERSION=master WP_MULTISITE=0 - - WP_VERSION=master WP_MULTISITE=1 + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=latest WP_MULTISITE=1 - WP_VERSION=3.5.1 WP_MULTISITE=0 - WP_VERSION=3.5.1 WP_MULTISITE=1 - WP_VERSION=3.4.2 WP_MULTISITE=0 @@ -18,7 +18,7 @@ before_script: # set up WP install - WP_CORE_DIR=/tmp/wp-cli-test-core-download-cache/ - mkdir -p $WP_CORE_DIR - - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION + - wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/wordpress-$WP_VERSION.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR # set up database - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot From 12918e6b3543bb85e9ad36c991b56e7b063c8e16 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 10:19:16 +0200 Subject: [PATCH 1379/4858] travis: latest = 3.5.1 at the moment --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index eaf97a25e1..5ccd5656bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,6 @@ php: env: - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.5.1 WP_MULTISITE=0 - - WP_VERSION=3.5.1 WP_MULTISITE=1 - WP_VERSION=3.4.2 WP_MULTISITE=0 - WP_VERSION=3.4.2 WP_MULTISITE=1 From 5b6efb9d2cb3416a51ef8efe79bdfcfe3258218a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Mar 2013 22:53:16 +0200 Subject: [PATCH 1380/4858] don't pretend we're in WP_ADMIN anymore --- php/WP_CLI/Runner.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e4d04c266e..b7da8954c2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -274,10 +274,6 @@ public function before_wp_load() { Utils\set_url_params( 'http://example.com' ); } } - - // Pretend we're in WP_ADMIN - define( 'WP_ADMIN', true ); - $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; } private function cmd_starts_with( $prefix ) { From bc40251e8bbdf2019acce104d9ab7c9193d001e0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 13:44:07 +0200 Subject: [PATCH 1381/4858] remove utils/local-build. closes #353 --- utils/local-build | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100755 utils/local-build diff --git a/utils/local-build b/utils/local-build deleted file mode 100755 index 9d92ea8758..0000000000 --- a/utils/local-build +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -if [ "$BASH_SOURCE" = "$0" ]; then - echo "This file should not be executed. It should be sourced into your current shell like this:" - echo - echo "source $BASH_SOURCE" - echo - echo "Add the above line to your .bashrc or .bash_profile to have this environment set up" - echo "automatically when you log in." - exit 1 -fi - -[ -f composer.phar ] || curl -sS https://getcomposer.org/installer | php - -[ -d vendor/ ] || php composer.phar install - -DIR=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) - -alias wp='$DIR/../bin/wp' - -. $DIR/wp-completion.bash From d19d31871f10f9b768e7f161f0fd7eb623085199 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 18:32:38 +0200 Subject: [PATCH 1382/4858] handle wpdb error ourselves, instead of waiting for dead_db() --- php/wp-settings-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index dd64be7d3a..12321c11ad 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -61,6 +61,10 @@ // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); +// WP-CLI: Handle db error ourselves, instead of waiting for dead_db() +if ( !empty( $wpdb->error ) ) + wp_die( $wpdb->error ); + // Set the database table prefix and the format specifiers for database table columns. $GLOBALS['table_prefix'] = $table_prefix; wp_set_wpdb_vars(); From c9cf0ff29072ce5f463f2329631f287c80cfaa58 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 19:36:42 +0200 Subject: [PATCH 1383/4858] minor cleanup in Runner.php --- php/WP_CLI/Runner.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b7da8954c2..93ffbae1b6 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -139,12 +139,20 @@ private static function set_url( $assoc_args ) { } } + private function cmd_starts_with( $prefix ) { + return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); + } + + private function _run_command() { + WP_CLI::run_command( $this->arguments, $this->assoc_args ); + } + /** * Returns wp-config.php code, skipping the loading of wp-settings.php * * @return string */ - function get_wp_config_code() { + public function get_wp_config_code() { $wp_config_path = Utils\locate_wp_config(); $replacements = array( @@ -276,18 +284,14 @@ public function before_wp_load() { } } - private function cmd_starts_with( $prefix ) { - return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); - } - - function after_wp_config_load() { + public function after_wp_config_load() { if ( isset( $this->config['debug'] ) ) { if ( !defined( 'WP_DEBUG' ) ) define( 'WP_DEBUG', true ); } } - function after_wp_load() { + public function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); Utils\set_user( $this->config ); @@ -310,8 +314,4 @@ function after_wp_load() { $this->_run_command(); } - - private function _run_command() { - WP_CLI::run_command( $this->arguments, $this->assoc_args ); - } } From 5264d7c30b81dcf9dfc300d1229969183fa78a0d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 20:20:38 +0200 Subject: [PATCH 1384/4858] add initial test case --- features/help.feature | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 features/help.feature diff --git a/features/help.feature b/features/help.feature new file mode 100644 index 0000000000..4c8077e16c --- /dev/null +++ b/features/help.feature @@ -0,0 +1,6 @@ +Feature: Get help about WP-CLI commands + + Scenario: Empty dir + Given an empty directory + When I run `wp help core` + Then it should run without errors From d6c10fc4fbe91a0c2c90bfdf44ae312255d3ed7a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 23:25:25 +0200 Subject: [PATCH 1385/4858] make get_command_file() a method of RootCommand It's only used there and it's very unlikely to be needed elsewhere. --- php/WP_CLI/Dispatcher/RootCommand.php | 12 +++++++++++- php/utils.php | 10 ---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index e1db3ce16d..0da342d74c 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -125,9 +125,19 @@ protected function load_all_commands() { } } + protected static function get_command_file( $command ) { + $path = WP_CLI_ROOT . "/commands/$command.php"; + + if ( !is_readable( $path ) ) { + return false; + } + + return $path; + } + protected function load_command( $command ) { if ( !isset( $this->subcommands[ $command ] ) ) { - if ( $path = \WP_CLI\Utils\get_command_file( $command ) ) + if ( $path = self::get_command_file( $command ) ) include $path; } diff --git a/php/utils.php b/php/utils.php index 451085e7ea..26ed76c23b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -112,16 +112,6 @@ function create_cmd( $cmd ) { return vsprintf( $cmd, array_map( 'escapeshellarg', $args ) ); } -function get_command_file( $command ) { - $path = WP_CLI_ROOT . "/commands/$command.php"; - - if ( !is_readable( $path ) ) { - return false; - } - - return $path; -} - /** * Sets the appropriate $_SERVER keys based on a given string * From 6324b4219e1d29f24f8ae2d44aeb0db8b15f2f75 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 11 Mar 2013 23:59:03 +0200 Subject: [PATCH 1386/4858] add show_help_early() --- php/WP_CLI/Runner.php | 23 ++++++++++++++++++++++- php/commands/help.php | 35 +++-------------------------------- php/man.php | 26 ++++++++++++++++++++++++++ php/utils.php | 11 +++++++++++ 4 files changed, 62 insertions(+), 33 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 93ffbae1b6..b18600a25f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -140,7 +140,7 @@ private static function set_url( $assoc_args ) { } private function cmd_starts_with( $prefix ) { - return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); + return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); } private function _run_command() { @@ -177,6 +177,20 @@ public function get_wp_config_code() { return preg_replace( '|^\s*\<\?php\s*|', '', implode( "\n", $lines_to_run ) ); } + private static function show_help_early( $args ) { + if ( \WP_CLI\Man\maybe_show_manpage( $args ) ) + return true; + + $command = WP_CLI\Utils\find_subcommand( $args ); + + if ( $command ) { + $command->show_usage(); + return true; + } + + return false; + } + public function before_wp_load() { $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -238,6 +252,13 @@ public function before_wp_load() { $_SERVER['DOCUMENT_ROOT'] = getcwd(); + // First try at showing man page + if ( $this->cmd_starts_with( array( 'help' ) ) ) { + if ( self::show_help_early( array_slice( $this->arguments, 1 ) ) ) { + exit; + } + } + // Handle --path self::set_wp_root( $this->config ); diff --git a/php/commands/help.php b/php/commands/help.php index a875f7a281..ef1eded1af 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -10,45 +10,16 @@ class Help_Command extends WP_CLI_Command { * @synopsis [<command>] */ function __invoke( $args ) { - self::maybe_load_man_page( $args ); + \WP_CLI\Man\maybe_show_manpage( $args ); - $arg_copy = $args; - - $command = \WP_CLI::$root; - - while ( !empty( $args ) && $command && $command instanceof CommandContainer ) { - $command = $command->find_subcommand( $args ); - } + $command = WP_CLI\Utils\find_subcommand( $args ); if ( !$command ) { - \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $arg_copy[0] ) ); + \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); } $command->show_usage(); } - - private static function maybe_load_man_page( $args ) { - $man_file = \WP_CLI\Man\get_file_name( $args ); - - foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { - $man_path = $dest_dir . $man_file; - - if ( is_readable( $man_path ) ) { - self::show_manpage( $man_path ); - } - } - } - - private static function show_manpage( $path ) { - // man can't read phar://, so need to copy to a temporary file - $tmp_path = tempnam( sys_get_temp_dir(), 'wp-cli-man-' ); - - copy( $path, $tmp_path ); - - WP_CLI::launch( "man $tmp_path" ); - - unlink( $tmp_path ); - } } WP_CLI::add_command( 'help', new Help_Command ); diff --git a/php/man.php b/php/man.php index e2578fc8f5..0d42cbfd07 100644 --- a/php/man.php +++ b/php/man.php @@ -119,3 +119,29 @@ function call_ronn( $markdown, $dest ) { \WP_CLI::line( "generated " . basename( $dest ) ); } +function show_manpage( $path ) { + // man can't read phar://, so need to copy to a temporary file + $tmp_path = tempnam( sys_get_temp_dir(), 'wp-cli-man-' ); + + copy( $path, $tmp_path ); + + \WP_CLI::launch( "man $tmp_path" ); + + unlink( $tmp_path ); +} + +function maybe_show_manpage( $args ) { + $man_file = get_file_name( $args ); + + foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { + $man_path = $dest_dir . $man_file; + + if ( is_readable( $man_path ) ) { + show_manpage( $man_path ); + return true; + } + } + + return false; +} + diff --git a/php/utils.php b/php/utils.php index 26ed76c23b..5a2718636c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -316,3 +316,14 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { return $output; } + +function find_subcommand( $args ) { + $command = \WP_CLI::$root; + + while ( !empty( $args ) && $command && $command instanceof Dispatcher\CommandContainer ) { + $command = $command->find_subcommand( $args ); + } + + return $command; +} + From 98431fbd44f09bb75fe4de6b927b4acd369d8e30 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 00:07:35 +0200 Subject: [PATCH 1387/4858] add more usages to help.feature --- features/help.feature | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/features/help.feature b/features/help.feature index 4c8077e16c..e5b216c584 100644 --- a/features/help.feature +++ b/features/help.feature @@ -2,5 +2,24 @@ Feature: Get help about WP-CLI commands Scenario: Empty dir Given an empty directory + + When I run `wp help` + Then it should run without errors + And STDOUT should contain: + """ + Available commands: + """ + When I run `wp help core` Then it should run without errors + And STDOUT should contain: + """ + usage: + """ + + When I run `wp help core download` + Then it should run without errors + And STDOUT should contain: + """ + WP-CORE-DOWNLOAD(1) + """ From 73c306dd251748828e3114d6c1c2f443b698281e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 01:12:27 +0200 Subject: [PATCH 1388/4858] fix E_STRICT error in CommandWithDBObject::create() signature --- php/WP_CLI/CommandWithDBObject.php | 2 +- php/commands/post.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 773f81d44d..fa735be9e7 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -13,7 +13,7 @@ abstract protected function _create( $params ); abstract protected function _update( $params ); abstract protected function _delete( $obj_id, $assoc_args ); - public function create( $assoc_args ) { + public function create( $args, $assoc_args ) { unset( $assoc_args['ID'] ); $obj_id = $this->_create( $assoc_args ); diff --git a/php/commands/post.php b/php/commands/post.php index 9073c4ed5a..028afbce0b 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -26,8 +26,8 @@ public function create( $args, $assoc_args ) { $assoc_args['post_content'] = file_get_contents( $readfile ); } - if ( isset( $assoc_args['edit'] ) ) { + if ( isset( $assoc_args['edit'] ) ) { $input = ( isset( $assoc_args['post_content'] ) ) ? $assoc_args['post_content'] : ''; @@ -35,9 +35,9 @@ public function create( $args, $assoc_args ) { $assoc_args['post_content'] = $output; else $assoc_args['post_content'] = $input; - } - parent::create( $assoc_args ); + + parent::create( $args, $assoc_args ); } protected function _create( $params ) { From 4fbdd4c0b285c6584f350bc469105d04784c3cef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 01:52:22 +0200 Subject: [PATCH 1389/4858] s/existant/existent/ --- features/flags.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 676729004b..f2020b9010 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -62,13 +62,13 @@ Feature: Global flags Scenario: Enabling/disabling color Given a WP install - When I run `wp --no-color non-existant-command` + When I run `wp --no-color non-existent-command` Then STDERR should be: """ - Error: 'non-existant-command' is not a registered wp command. See 'wp help'. + Error: 'non-existent-command' is not a registered wp command. See 'wp help'. """ - When I run `wp --color non-existant-command` + When I run `wp --color non-existent-command` Then STDERR should contain: """ [31;1mError: From d6a26bf156cafb3b5cce986c2134f8c87e65c699 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 01:53:49 +0200 Subject: [PATCH 1390/4858] add test for unknown command --- features/help.feature | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/help.feature b/features/help.feature index e5b216c584..53dfbb8965 100644 --- a/features/help.feature +++ b/features/help.feature @@ -23,3 +23,6 @@ Feature: Get help about WP-CLI commands """ WP-CORE-DOWNLOAD(1) """ + + When I run `wp help non-existent-command` + Then the return code should be 1 From 46e2c301de2c0091be1957ed5f0bb9178c15b69e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 02:26:29 +0200 Subject: [PATCH 1391/4858] test getting help for a third-party command --- features/bootstrap/FeatureContext.php | 15 +++++++++++++++ features/help.feature | 15 ++++++++++++++- features/steps/basic_steps.php | 18 ++++++++++++------ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d45f895553..8fb9912b2c 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -69,6 +69,21 @@ public function get_path( $file ) { return $this->install_dir . '/' . $file; } + public function get_cache_path( $file ) { + static $path; + + if ( !$path ) { + $path = sys_get_temp_dir() . '/wp-cli-test-cache'; + system( \WP_CLI\Utils\create_cmd( 'mkdir -p %s', $path ) ); + } + + return $path . '/' . $file; + } + + public function download_file( $url, $path ) { + system( \WP_CLI\Utils\create_cmd( 'curl -sSL %s > %s', $url, $path ) ); + } + private static function run_sql( $sql ) { $dbuser = self::$db_settings['dbuser']; $dbpass = self::$db_settings['dbpass']; diff --git a/features/help.feature b/features/help.feature index 53dfbb8965..432eadf009 100644 --- a/features/help.feature +++ b/features/help.feature @@ -14,7 +14,7 @@ Feature: Get help about WP-CLI commands Then it should run without errors And STDOUT should contain: """ - usage: + usage: wp core """ When I run `wp help core download` @@ -26,3 +26,16 @@ Feature: Get help about WP-CLI commands When I run `wp help non-existent-command` Then the return code should be 1 + + Scenario: Getting help for a third-party command + Given a WP install + And a google-sitemap-generator-cli plugin zip + And I run `wp plugin install --activate {PLUGIN_ZIP}` + And I run `wp plugin install --activate google-sitemap-generator` + + When I run `wp help google-sitemap` + Then it should run without errors + And STDOUT should contain: + """ + usage: wp google-sitemap + """ diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 6e48c3bb81..f16959b4cb 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -44,19 +44,25 @@ function ( $world ) { } ); -$steps->Given('/^a P2 theme zip$/', +$steps->Given( '/^a P2 theme zip$/', function ( $world ) { $zip_name = 'p2.1.0.1.zip'; - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-cache'; - $world->variables['THEME_ZIP'] = $cache_dir . '/' . $zip_name; + $world->variables['THEME_ZIP'] = $world->get_cache_path( $zip_name ); $zip_url = 'http://wordpress.org/extend/themes/download/' . $zip_name; - system( \WP_CLI\Utils\create_cmd( 'mkdir -p %s', $cache_dir ) ); + $world->download_file( $zip_url, $world->variables['THEME_ZIP'] ); + } +); + +$steps->Given( '/^a google-sitemap-generator-cli plugin zip$/', + function ( $world ) { + $zip_url = 'https://github.com/wp-cli/google-sitemap-generator-cli/archive/master.zip'; + + $world->variables['PLUGIN_ZIP'] = $world->get_cache_path( 'google-sitemap-generator-cli.zip' ); - system( \WP_CLI\Utils\create_cmd( 'curl -s %s > %s', $zip_url, - $world->variables['THEME_ZIP'] ) ); + $world->download_file( $zip_url, $world->variables['PLUGIN_ZIP'] ); } ); From 589e51debb21d2dc741518ea88398cecced6c1de Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 04:04:19 +0200 Subject: [PATCH 1392/4858] create CONTRIBUTING.md file --- CONTRIBUTING.md | 37 +++++++++++++++++++++++++++++++++++++ README.md | 26 -------------------------- 2 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..eea9813161 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +Contribute +========== + +So you've got an awesome idea to throw into WP-CLI. Great! Please keep the +following in mind: + +* If you're adding a new command or subcommand, please consider adding a functional test for it in the `features` directory. Also, please create the appropriate `.txt` file in the `man-src` directory. +* Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). + +Test Dependencies +----------------- + +There are two types of tests: + +* unit tests, implemented using [PHPUnit](http://phpunit.de/) +* functional tests, implemented using [Behat](http://behat.org) + +All the test dependencies can be installed using [Composer](http://getcomposer.org/): + + php composer.phar install --dev + +Before running the tests, you'll need a MySQL user called `wp_cli_test` with the +password `password1` that has full privileges on the MySQL database `wp_cli_test`. +Running the following as root in MySQL should do the trick: + + GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; + +Finally, to run the tests: + + vendor/bin/phpunit + vendor/bin/behat + +Finally... +---------- + +Thanks! Hacking on WP-CLI should be fun. If you find any of this hard to figure +out, let us know so we can improve our process or documentation! diff --git a/README.md b/README.md index f72337f642..7a3335d10f 100644 --- a/README.md +++ b/README.md @@ -26,29 +26,3 @@ Need even more info? Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. - -Running tests -------------- - -There are two types of tests: - -* unit tests, implemented using [PHPUnit](http://phpunit.de/) -* functional tests, implemented using [Behat](http://behat.org) - -All the test dependencies can be installed using [composer](http://getcomposer.org/): - - composer.phar install --dev - -Before running the tests, you'll need a MySQL user called `wp_cli_test` with the -password `password1` that has full privileges on the MySQL database `wp_cli_test`. -Running the following as root in MySQL should do the trick: - - GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; - -Finally, to run the unit tests: - - vendor/bin/phpunit - -And to run the functional tests: - - vendor/bin/behat From 00b06c7ff622ce0784d55780ed547e0a71813718 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 11 Mar 2013 19:41:53 -0700 Subject: [PATCH 1393/4858] role: Correct indentation style --- php/commands/role.php | 162 +++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 2e1237586d..4c1104ee81 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -7,87 +7,87 @@ */ class Role_Command extends WP_CLI_Command { - /** - * List all roles. - * - * @subcommand list - */ - public function _list( $args ) { - global $wp_roles; - - foreach ( $wp_roles->roles as $key => $role ) { - WP_CLI::line( $role['name'] . " ($key)"); - } - } - - /** - * Check if a role exists. - * Will return 0 if the role exists, 1 if it does not. - * - * @synopsis <role-key> - */ - public function exists( $args ) { - global $wp_roles; - - if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { - exit(1); - } - } - - /** - * Create a new role. - * - * @synopsis <role-key> <role-name> - */ - public function create( $args ) { - self::persistence_check(); - - $role_key = array_shift( $args ); - $role_name = array_shift( $args ); - - if ( empty( $role_key ) || empty( $role_name ) ) - WP_CLI::error( "Can't create role, insufficient information provided."); - - if ( ! add_role( $role_key, $role_name ) ) - WP_CLI::error( "Role couldn't be created." ); - else - WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); - - } - - /** - * Delete an existing role. - * - * @synopsis <role-key> - */ - public function delete( $args ) { - - global $wp_roles; - - self::persistence_check(); - - $role_key = array_shift( $args ); - - if ( empty( $role_key ) || ! isset( $wp_roles->roles[$role_key] ) ) - WP_CLI::error( "Role key not provided, or is invalid." ); - - remove_role( $role_key ); - - // Note: remove_role() doesn't indicate success or otherwise, so we have to - // check ourselves - if ( ! isset( $wp_roles->roles[$role_key] ) ) - WP_CLI::success( sprintf( "Role with key %s deleted.", $role_key ) ); - else - WP_CLI::error( sprintf( "Role with key %s could not be deleted.", $role_key ) ); - - } - - private static function persistence_check() { - global $wp_roles; - - if ( !$wp_roles->use_db ) - WP_CLI::error( "Role definitions are not persistent." ); - } + /** + * List all roles. + * + * @subcommand list + */ + public function _list( $args ) { + global $wp_roles; + + foreach ( $wp_roles->roles as $key => $role ) { + WP_CLI::line( $role['name'] . " ($key)"); + } + } + + /** + * Check if a role exists. + * Will return 0 if the role exists, 1 if it does not. + * + * @synopsis <role-key> + */ + public function exists( $args ) { + global $wp_roles; + + if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { + exit(1); + } + } + + /** + * Create a new role. + * + * @synopsis <role-key> <role-name> + */ + public function create( $args ) { + self::persistence_check(); + + $role_key = array_shift( $args ); + $role_name = array_shift( $args ); + + if ( empty( $role_key ) || empty( $role_name ) ) + WP_CLI::error( "Can't create role, insufficient information provided."); + + if ( ! add_role( $role_key, $role_name ) ) + WP_CLI::error( "Role couldn't be created." ); + else + WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); + + } + + /** + * Delete an existing role. + * + * @synopsis <role-key> + */ + public function delete( $args ) { + + global $wp_roles; + + self::persistence_check(); + + $role_key = array_shift( $args ); + + if ( empty( $role_key ) || ! isset( $wp_roles->roles[$role_key] ) ) + WP_CLI::error( "Role key not provided, or is invalid." ); + + remove_role( $role_key ); + + // Note: remove_role() doesn't indicate success or otherwise, so we have to + // check ourselves + if ( ! isset( $wp_roles->roles[$role_key] ) ) + WP_CLI::success( sprintf( "Role with key %s deleted.", $role_key ) ); + else + WP_CLI::error( sprintf( "Role with key %s could not be deleted.", $role_key ) ); + + } + + private static function persistence_check() { + global $wp_roles; + + if ( !$wp_roles->use_db ) + WP_CLI::error( "Role definitions are not persistent." ); + } } WP_CLI::add_command( 'role', 'Role_Command' ); \ No newline at end of file From 0d4cf1488e76fc87421e8bd8004bf74482d097f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 11 Mar 2013 19:50:52 -0700 Subject: [PATCH 1394/4858] role: Update role list to properly format roles in a table --- man-src/role-list.txt | 6 ++++++ php/commands/role.php | 23 +++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/man-src/role-list.txt b/man-src/role-list.txt index 6bc9ed2a36..a2dcd0cc02 100644 --- a/man-src/role-list.txt +++ b/man-src/role-list.txt @@ -1,3 +1,9 @@ +## OPTIONS + +* `--format`=<format>: + + Output list as table, CSV or JSON. Defaults to table. + ## EXAMPLES wp role list diff --git a/php/commands/role.php b/php/commands/role.php index 4c1104ee81..8f2e0765c7 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -11,13 +11,32 @@ class Role_Command extends WP_CLI_Command { * List all roles. * * @subcommand list + * @synopsis [--format=<format>] */ - public function _list( $args ) { + public function _list( $args, $assoc_args ) { global $wp_roles; + $defaults = array( + 'format' => 'table', + ); + $params = array_merge( $defaults, $assoc_args ); + + $fields = array( + 'name', + 'role', + ); + + $output_roles = array(); foreach ( $wp_roles->roles as $key => $role ) { - WP_CLI::line( $role['name'] . " ($key)"); + $output_role = new stdClass; + + $output_role->name = $role['name']; + $output_role->role = $key; + + $output_roles[] = $output_role; } + + WP_CLI\Utils\format_items( $params['format'], $fields, $output_roles ); } /** From d00b499bab77abdf257b1238dbb8a79349705a0d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 12:41:22 +0200 Subject: [PATCH 1395/4858] describe how to generate a man page --- CONTRIBUTING.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eea9813161..5ae6bc9528 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,27 @@ Contribute ========== -So you've got an awesome idea to throw into WP-CLI. Great! Please keep the -following in mind: +So you've got an awesome idea to throw into WP-CLI. Great! Please keep the following in mind: * If you're adding a new command or subcommand, please consider adding a functional test for it in the `features` directory. Also, please create the appropriate `.txt` file in the `man-src` directory. * Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). -Test Dependencies +Generating man pages +-------------------- + +To generate a man page, WP-CLI looks for `.txt` files in the `man-src` directory. It also gather information from the inline comments and the `@synopsis` annotations. + +The compiled man page is placed in the `man` directory. + +To (re)generate one or more man pages, you first need to have the [ronn](https://rubygems.org/gems/ronn) ruby gem installed. + +Then, you can run one of the following: + +* `wp --man` - regenerates all man pages +* `wp core --man` - regenerates man pages for the `core` command +* `wp core download --man` - regenerates man page only for the `core download` subcommand + +Running the tests ----------------- There are two types of tests: From 7324cccb1c05c45f68eb70fb71ce9b28342a828b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 12:44:41 +0200 Subject: [PATCH 1396/4858] s/gather/gathers/ --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5ae6bc9528..04fea31045 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ So you've got an awesome idea to throw into WP-CLI. Great! Please keep the follo Generating man pages -------------------- -To generate a man page, WP-CLI looks for `.txt` files in the `man-src` directory. It also gather information from the inline comments and the `@synopsis` annotations. +To generate a man page, WP-CLI looks for `.txt` files in the `man-src` directory. It also gathers information from the inline comments and the `@synopsis` annotations. The compiled man page is placed in the `man` directory. From a97d232eb34d8888abc5b39d31ca1e8ff1923297 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 14:44:47 +0200 Subject: [PATCH 1397/4858] add checks for plugin installs --- features/help.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/help.feature b/features/help.feature index 432eadf009..af077c730a 100644 --- a/features/help.feature +++ b/features/help.feature @@ -31,7 +31,9 @@ Feature: Get help about WP-CLI commands Given a WP install And a google-sitemap-generator-cli plugin zip And I run `wp plugin install --activate {PLUGIN_ZIP}` + And it should run without errors And I run `wp plugin install --activate google-sitemap-generator` + And it should run without errors When I run `wp help google-sitemap` Then it should run without errors From f1762dddebe7d27bd8e2609903569af55ea913d6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 15:19:53 +0200 Subject: [PATCH 1398/4858] run core install-network when WP_MULTISITE=1 --- features/bootstrap/FeatureContext.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 8fb9912b2c..91dd59fb54 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -180,14 +180,24 @@ private function add_line_to_wp_config( &$wp_config_code, $line ) { } public function run_install() { - $cmd = 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( + $install_r = $this->run( 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( 'url' => 'http://example.com', - 'title' => 'WP CLI Tests', + 'title' => 'WP CLI Site', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' - ) ); + ) ) ); + + if ( 0 !== $install_r->return_code ) { + return $install_r; + } + + if ( getenv( 'WP_MULTISITE' ) === '1' ) { + $install_r = $this->run( 'core install-network' . \WP_CLI\Utils\assoc_args_to_str( array( + 'title' => 'WP CLI Network' + ) ) ); + } - return $this->run( $cmd ); + return $install_r; } public function download_wordpress_files() { From 0d25ebf6411baeccee106cb9a418ee3ef3767ce0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 19:24:09 +0200 Subject: [PATCH 1399/4858] Add note about serialized values in search-replace man page [ci skip] --- man-src/search-replace.txt | 6 ++++++ man/search-replace.1 | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index a106c1762c..2db4c96cf7 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -1,3 +1,9 @@ +## 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. + ## OPTIONS * `--dry-run`: diff --git a/man/search-replace.1 b/man/search-replace.1 index 9ac08c7b66..0a5e342365 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -9,6 +9,12 @@ .SH "SYNOPSIS" wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] . +.SH "DESCRIPTION" +This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. +. +.P +It will correctly handle serialized values\. +. .SH "OPTIONS" . .TP From 89052b58006ebfad921bcd290f176b6f77592849 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 19:55:45 +0200 Subject: [PATCH 1400/4858] Replace WP_MULTISITE env variable with a 'Given a WP multisite install' step --- .travis.yml | 6 ++---- features/bootstrap/FeatureContext.php | 18 ++++++------------ features/steps/basic_steps.php | 8 ++++++-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ccd5656bc..a0581df5b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,8 @@ php: - 5.4 env: - - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.4.2 WP_MULTISITE=0 - - WP_VERSION=3.4.2 WP_MULTISITE=1 + - WP_VERSION=latest + - WP_VERSION=3.4.2 before_script: # install dependencies diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 91dd59fb54..fdd111d0b4 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -180,24 +180,18 @@ private function add_line_to_wp_config( &$wp_config_code, $line ) { } public function run_install() { - $install_r = $this->run( 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( + return $this->run( 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( 'url' => 'http://example.com', 'title' => 'WP CLI Site', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' ) ) ); + } - if ( 0 !== $install_r->return_code ) { - return $install_r; - } - - if ( getenv( 'WP_MULTISITE' ) === '1' ) { - $install_r = $this->run( 'core install-network' . \WP_CLI\Utils\assoc_args_to_str( array( - 'title' => 'WP CLI Network' - ) ) ); - } - - return $install_r; + public function run_install_network() { + return $this->run( 'core install-network' . \WP_CLI\Utils\assoc_args_to_str( array( + 'title' => 'WP CLI Network' + ) ) ); } public function download_wordpress_files() { diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index f16959b4cb..c9c4070272 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -28,13 +28,17 @@ function ( $world ) { } ); -$steps->Given( '/^a WP install$/', - function ( $world ) { +$steps->Given( '/^a WP (install|multisite install)$/', + function ( $world, $type ) { $world->create_db(); $world->create_empty_dir(); $world->download_wordpress_files(); $world->create_config(); $world->run_install(); + + if ( 'multisite install' == $type ) { + $world->run_install_network(); + } } ); From 2c32a5cc187d4bfdc5c1ceecdd492d10bf898cdc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 12 Mar 2013 16:11:02 -0700 Subject: [PATCH 1401/4858] Update man file --- man/role-list.1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/man/role-list.1 b/man/role-list.1 index 7998c7010d..a962ccae40 100644 --- a/man/role-list.1 +++ b/man/role-list.1 @@ -7,7 +7,15 @@ \fBwp\-role\-list\fR \- List all roles\. . .SH "SYNOPSIS" -wp role list +wp role list [\-\-format=\fIformat\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-format\fR=\fIformat\fR: +. +.IP +Output list as table, CSV or JSON\. Defaults to table\. . .SH "EXAMPLES" . From 3f23bd0b197bb22f070e62945565da3306e3dd93 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 20:26:00 +0200 Subject: [PATCH 1402/4858] tests: escape arguments passed in run_sql() --- features/bootstrap/FeatureContext.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index fdd111d0b4..f8841c84f7 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -85,10 +85,8 @@ public function download_file( $url, $path ) { } private static function run_sql( $sql ) { - $dbuser = self::$db_settings['dbuser']; - $dbpass = self::$db_settings['dbpass']; - - exec( "mysql -u$dbuser -p$dbpass -e '$sql'" ); + system( \WP_CLI\Utils\create_cmd( 'mysql -u%s -p%s -e %s', + self::$db_settings['dbuser'], self::$db_settings['dbpass'], $sql ) ); } public function create_db() { From e39d52f6cb4480d82dbb1820e72725ab5e66bdbf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Mar 2013 20:39:35 +0200 Subject: [PATCH 1403/4858] add $assoc_args parameter to _run(), for convenience --- features/bootstrap/FeatureContext.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index f8841c84f7..af3e7c46fd 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -99,8 +99,9 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - private function _run( $command ) { - $wp_cli_path = getcwd() . "/bin/wp"; + private function _run( $command, $assoc_args ) { + if ( !empty( $assoc_args ) ) + $command .= \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); if ( false === strpos( $command, '--path' ) ) { $command = \WP_CLI\Utils\assoc_args_to_str( array( @@ -108,7 +109,7 @@ private function _run( $command ) { ) ) . ' ' . $command; } - $sh_command = "$wp_cli_path $command"; + $sh_command = getcwd() . "/bin/wp $command"; $process = proc_open( $sh_command, array( 0 => STDIN, @@ -127,7 +128,7 @@ private function _run( $command ) { return (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); } - public function run( $command ) { + public function run( $command, $assoc_args = array() ) { switch ( $command ) { case 'core install': return $this->run_install(); @@ -138,12 +139,12 @@ public function run( $command ) { break; default: - return $this->_run( $command ); + return $this->_run( $command, $assoc_args ); } } public function create_config() { - return $this->run( 'core config' . \WP_CLI\Utils\assoc_args_to_str( self::$db_settings ) ); + return $this->_run( 'core config', self::$db_settings ); } public function define_custom_wp_content_dir() { @@ -178,18 +179,18 @@ private function add_line_to_wp_config( &$wp_config_code, $line ) { } public function run_install() { - return $this->run( 'core install' . \WP_CLI\Utils\assoc_args_to_str( array( + return $this->_run( 'core install', array( 'url' => 'http://example.com', 'title' => 'WP CLI Site', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' - ) ) ); + ) ); } public function run_install_network() { - return $this->run( 'core install-network' . \WP_CLI\Utils\assoc_args_to_str( array( + return $this->_run( 'core install-network', array( 'title' => 'WP CLI Network' - ) ) ); + ) ); } public function download_wordpress_files() { @@ -197,9 +198,9 @@ public function download_wordpress_files() { // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - $r = $this->run( 'core download' . \WP_CLI\Utils\assoc_args_to_str( array( + $r = $this->_run( 'core download', array( 'path' => $cache_dir - ) ) ); + ) ); exec( sprintf( "cp -r '%s/'* '%s/'", $cache_dir, $this->install_dir ) ); } From dc0f1c0c1a97cfad83656c0160d388644ef9cb54 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 17:41:35 +0200 Subject: [PATCH 1404/4858] transparently add additional assoc params to special commands, instead of having dedicated methods --- features/bootstrap/FeatureContext.php | 49 +++++++++++---------------- features/steps/basic_steps.php | 8 ++--- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index af3e7c46fd..4a9e9526c8 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -20,6 +20,7 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface ); private $install_dir; + private $additional_args; public $variables = array(); @@ -32,6 +33,21 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface public function __construct( array $parameters ) { $this->drop_db(); + + $this->additional_args = array( + 'core config' => self::$db_settings, + + 'core install' => array( + 'url' => 'http://example.com', + 'title' => 'WP CLI Site', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1' + ), + + 'core install-network', array( + 'title' => 'WP CLI Network' + ) + ); } public function getStepDefinitionResources() @@ -129,22 +145,12 @@ private function _run( $command, $assoc_args ) { } public function run( $command, $assoc_args = array() ) { - switch ( $command ) { - case 'core install': - return $this->run_install(); - break; - - case 'core config': - return $this->create_config(); - break; - - default: - return $this->_run( $command, $assoc_args ); + if ( isset( $this->additional_args[ $command ] ) ) { + $assoc_args = array_merge( $this->additional_args[ $command ], + $assoc_args ); } - } - public function create_config() { - return $this->_run( 'core config', self::$db_settings ); + return $this->_run( $command, $assoc_args ); } public function define_custom_wp_content_dir() { @@ -178,21 +184,6 @@ private function add_line_to_wp_config( &$wp_config_code, $line ) { $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); } - public function run_install() { - return $this->_run( 'core install', array( - 'url' => 'http://example.com', - 'title' => 'WP CLI Site', - 'admin_email' => 'admin@example.com', - 'admin_password' => 'password1' - ) ); - } - - public function run_install_network() { - return $this->_run( 'core install-network', array( - 'title' => 'WP CLI Network' - ) ); - } - public function download_wordpress_files() { // We cache the results of "wp core download" to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index c9c4070272..270e9fa4d7 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -18,7 +18,7 @@ function ( $world ) { $steps->Given( '/^wp-config\.php$/', function ( $world ) { - $world->create_config(); + $world->run( 'core config' ); } ); @@ -33,11 +33,11 @@ function ( $world, $type ) { $world->create_db(); $world->create_empty_dir(); $world->download_wordpress_files(); - $world->create_config(); - $world->run_install(); + $world->run( 'core config' ); + $world->run( 'core install' ); if ( 'multisite install' == $type ) { - $world->run_install_network(); + $world->run( 'core install-network' ); } } ); From cf2769fd1a8fa7d07f467e968b76261d8ce0249b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 17:50:06 +0200 Subject: [PATCH 1405/4858] use create_cmd() utility in download_wordpress_files() --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 4a9e9526c8..f4d1a9388f 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -193,7 +193,7 @@ public function download_wordpress_files() { 'path' => $cache_dir ) ); - exec( sprintf( "cp -r '%s/'* '%s/'", $cache_dir, $this->install_dir ) ); + system( \WP_CLI\Utils\create_cmd( "cp -r %s/* %s/", $cache_dir, $this->install_dir ) ); } } From ecfe4360f11a387d5eb6d39cb257d148fda41e2a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 18:36:04 +0200 Subject: [PATCH 1406/4858] first pass at multisite.feature --- features/bootstrap/FeatureContext.php | 2 +- features/multisite.feature | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 features/multisite.feature diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index f4d1a9388f..071bba1cc3 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -44,7 +44,7 @@ public function __construct( array $parameters ) 'admin_password' => 'password1' ), - 'core install-network', array( + 'core install-network' => array( 'title' => 'WP CLI Network' ) ); diff --git a/features/multisite.feature b/features/multisite.feature new file mode 100644 index 0000000000..a370e3d329 --- /dev/null +++ b/features/multisite.feature @@ -0,0 +1,17 @@ +Feature: Manage a WordPress multisite installation + + Scenario: Install multisite + Given a WP install + + When I run `wp core install-network` + Then it should run without errors + + When I run the previous command again + Then the return code should be 1 + + Scenario: Create some blogs + Given a WP multisite install + + When I run `wp blog create --slug=first --title=First` + Then it should run without errors + And STDOUT should not be empty From c118a907ada57d18ef2e71727c9d863bbc83376f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 18:51:23 +0200 Subject: [PATCH 1407/4858] don't test against WP 3.4.2 using PHP 5.4 It avoids this warning: Creating default object from empty value in /wp-admin/includes/schema.php on line 922 --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index a0581df5b3..e470d86ced 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,11 @@ env: - WP_VERSION=latest - WP_VERSION=3.4.2 +matrix: + exclude: + - php: 5.4 + env: WP_VERSION=3.4.2 + before_script: # install dependencies - composer install --dev --no-interaction --prefer-source From 80181f8dc9a1762555185e757ad9ccc1c00d5250 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 19:40:45 +0200 Subject: [PATCH 1408/4858] test deleting a blog --- features/multisite.feature | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/features/multisite.feature b/features/multisite.feature index a370e3d329..67d0e79089 100644 --- a/features/multisite.feature +++ b/features/multisite.feature @@ -12,6 +12,13 @@ Feature: Manage a WordPress multisite installation Scenario: Create some blogs Given a WP multisite install - When I run `wp blog create --slug=first --title=First` + When I run `wp blog create --slug=first --porcelain` Then it should run without errors - And STDOUT should not be empty + And STDOUT should match '%d' + And save STDOUT as {BLOG_ID} + + When I run `wp blog delete {BLOG_ID} --yes` + Then it should run without errors + + When I run the previous command again + Then the return code should be 1 From 5a0793959746cb0752630f3e8c126789910f4a54 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 19:41:48 +0200 Subject: [PATCH 1409/4858] add --porcelain flag to `blog create` --- man-src/blog-create.txt | 4 ++++ man/blog-create.1 | 8 +++++++- php/commands/blog.php | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/man-src/blog-create.txt b/man-src/blog-create.txt index 02814b8f3a..1c7e6aea59 100644 --- a/man-src/blog-create.txt +++ b/man-src/blog-create.txt @@ -19,3 +19,7 @@ * `--private`: If set, the new blog will be non-public (not indexed) + +* `--porcelain`: + + If set, only the blog id will be output on success. diff --git a/man/blog-create.1 b/man/blog-create.1 index c0b207a8be..022c1c88a1 100644 --- a/man/blog-create.1 +++ b/man/blog-create.1 @@ -7,7 +7,7 @@ \fBwp\-blog\-create\fR \- Create a blog in a multisite install\. . .SH "SYNOPSIS" -wp blog create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] +wp blog create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] [\-\-porcelain] . .SH "OPTIONS" . @@ -40,4 +40,10 @@ Site (network) to associate new blog with\. Defaults to current site (typically . .IP If set, the new blog will be non\-public (not indexed) +. +.TP +\fB\-\-porcelain\fR: +. +.IP +If set, only the blog id will be output on success\. diff --git a/php/commands/blog.php b/php/commands/blog.php index 92be6de203..6ba51a729c 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -28,7 +28,7 @@ private function _get_site( $site_id ) { /** * Create a blog in a multisite install. * - * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--site_id=<site-id>] [--private] + * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--site_id=<site-id>] [--private] [--porcelain] */ public function create( $_, $assoc_args ) { global $wpdb; From eb961c546057f04f32bb2bd325db3d7e4263c128 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 19:47:37 +0200 Subject: [PATCH 1410/4858] make `blog delete` accept a blog id as well --- php/commands/blog.php | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index 6ba51a729c..9af9fa2e4a 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -117,35 +117,40 @@ public function create( $_, $assoc_args ) { else { WP_CLI::error( $id->get_error_message() ); } - WP_CLI::success( "Blog $id created: $url" ); + + if ( isset( $assoc_args['porcelain'] ) ) + WP_CLI::line( $id ); + else + WP_CLI::success( "Blog $id created: $url" ); } /** * Delete a blog in a multisite install. * - * @synopsis --slug=<slug> [--yes] [--keep-tables] + * @synopsis [<blog-id>] [--slug=<slug>] [--yes] [--keep-tables] */ - function delete( $_, $assoc_args ) { - $slug = '/' . trim( $assoc_args['slug'], '/' ) . '/'; - - $blog_id = self::get_blog_id_by_slug( $slug ); + function delete( $args, $assoc_args ) { + if ( isset( $assoc_args['slug'] ) ) { + $blog = get_blog_details( trim( $assoc_args['slug'], '/' ) ); + } else { + if ( empty( $args ) ) { + WP_CLI::error( "Need to specify a blog id." ); + } - if ( !$blog_id ) - WP_CLI::error( sprintf( "'%s' blog not found.", $slug ) ); + $blog_id = $args[0]; - WP_CLI::confirm( "Are you sure you want to delete the '$slug' blog?", $assoc_args ); + $blog = get_blog_details( $blog_id ); + } - wpmu_delete_blog( $blog_id, !isset( $assoc_args['keep-tables'] ) ); + if ( !$blog ) { + WP_CLI::error( "Blog not found." ); + } - WP_CLI::success( "Blog '$slug' deleted." ); - } + WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl blog?", $assoc_args ); - protected static function get_blog_id_by_slug( $slug ) { - global $wpdb, $current_site; + wpmu_delete_blog( $blog_id, !isset( $assoc_args['keep-tables'] ) ); - return $wpdb->get_var( $wpdb->prepare( " - SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s" - , $current_site->domain, $slug ) ); + WP_CLI::success( "Blog 3 deleted." ); } } From 06567d64faeac03b1da70914a8f2b5f2935f5aed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 19:50:15 +0200 Subject: [PATCH 1411/4858] update man page for blog delete [ci skip] --- man-src/blog-delete.txt | 4 ++++ man/blog-delete.1 | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/man-src/blog-delete.txt b/man-src/blog-delete.txt index 349836eb87..f119826b96 100644 --- a/man-src/blog-delete.txt +++ b/man-src/blog-delete.txt @@ -1,5 +1,9 @@ ## OPTIONS +* `<blog-id>`: + + The id of the blog to delete. If not provided, you must set the --slug parameter. + * `--slug`=<slug>: Path of the blog to be deleted. Subdomain on subdomain installs, directory on subdirectory installs. diff --git a/man/blog-delete.1 b/man/blog-delete.1 index 80e3c20c1b..d90ec3e166 100644 --- a/man/blog-delete.1 +++ b/man/blog-delete.1 @@ -7,11 +7,17 @@ \fBwp\-blog\-delete\fR \- Delete a blog in a multisite install\. . .SH "SYNOPSIS" -wp blog delete \-\-slug=\fIslug\fR [\-\-yes] [\-\-keep\-tables] +wp blog delete [\fIblog\-id\fR] [\-\-slug=\fIslug\fR] [\-\-yes] [\-\-keep\-tables] . .SH "OPTIONS" . .TP +\fB<blog\-id>\fR: +. +.IP +The id of the blog to delete\. If not provided, you must set the \-\-slug parameter\. +. +.TP \fB\-\-slug\fR=\fIslug\fR: . .IP From f16b19aac20b5a3628ab5957fa47fc247f8461fd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 19:52:40 +0200 Subject: [PATCH 1412/4858] fix success message for `blog delete` --- features/multisite.feature | 4 ++++ php/commands/blog.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/features/multisite.feature b/features/multisite.feature index 67d0e79089..058d2456de 100644 --- a/features/multisite.feature +++ b/features/multisite.feature @@ -19,6 +19,10 @@ Feature: Manage a WordPress multisite installation When I run `wp blog delete {BLOG_ID} --yes` Then it should run without errors + And STDOUT should contain: + """ + Blog {BLOG_ID} deleted. + """ When I run the previous command again Then the return code should be 1 diff --git a/php/commands/blog.php b/php/commands/blog.php index 9af9fa2e4a..7bf2cf509e 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -150,7 +150,7 @@ function delete( $args, $assoc_args ) { wpmu_delete_blog( $blog_id, !isset( $assoc_args['keep-tables'] ) ); - WP_CLI::success( "Blog 3 deleted." ); + WP_CLI::success( "Blog $blog_id deleted." ); } } From 783a98a590088becc283eca5a7511daf65c5a976 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 20:07:50 +0200 Subject: [PATCH 1413/4858] add 'Delete a blog by slug' scenario --- features/multisite.feature | 21 ++++++++++++++++----- php/commands/blog.php | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/features/multisite.feature b/features/multisite.feature index 058d2456de..536fed7f51 100644 --- a/features/multisite.feature +++ b/features/multisite.feature @@ -9,7 +9,7 @@ Feature: Manage a WordPress multisite installation When I run the previous command again Then the return code should be 1 - Scenario: Create some blogs + Scenario: Delete a blog by id Given a WP multisite install When I run `wp blog create --slug=first --porcelain` @@ -19,10 +19,21 @@ Feature: Manage a WordPress multisite installation When I run `wp blog delete {BLOG_ID} --yes` Then it should run without errors - And STDOUT should contain: - """ - Blog {BLOG_ID} deleted. - """ + And STDOUT should not be empty + + When I run the previous command again + Then the return code should be 1 + + Scenario: Delete a blog by slug + Given a WP multisite install + + When I run `wp blog create --slug=first` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp blog delete --slug=first --yes` + Then it should run without errors + And STDOUT should not be empty When I run the previous command again Then the return code should be 1 diff --git a/php/commands/blog.php b/php/commands/blog.php index 7bf2cf509e..b7af961037 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -148,9 +148,9 @@ function delete( $args, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl blog?", $assoc_args ); - wpmu_delete_blog( $blog_id, !isset( $assoc_args['keep-tables'] ) ); + wpmu_delete_blog( $blog->blog_id, !isset( $assoc_args['keep-tables'] ) ); - WP_CLI::success( "Blog $blog_id deleted." ); + WP_CLI::success( "The blog at $blog->siteurl was deleted." ); } } From 682b0761bb51957e75df329effcfa1b25187dba4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 13 Mar 2013 20:56:35 +0200 Subject: [PATCH 1414/4858] bump version 0.9.0-beta [ci skip] --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 7e040cbeca..7fb1aa66f0 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.0-alpha2' ); +define( 'WP_CLI_VERSION', '0.9.0-beta' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 5a8e4bcf9a1a22576b9ba535c838dddf71a0b1d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Mar 2013 03:16:57 +0200 Subject: [PATCH 1415/4858] 'debug' option is always set, but might be false --- features/flags.feature | 2 +- php/WP_CLI/Runner.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index f2020b9010..223fda99b8 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -28,7 +28,7 @@ Feature: Global flags CONST_WITHOUT_QUOTES """ - When I run `wp --debug eval 'echo CONST_WITHOUT_QUOTES;'` + When I run `wp eval 'echo CONST_WITHOUT_QUOTES;' --debug` Then the return code should be 0 And STDOUT should contain: """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b18600a25f..ff3fbae7e7 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -306,7 +306,7 @@ public function before_wp_load() { } public function after_wp_config_load() { - if ( isset( $this->config['debug'] ) ) { + if ( $this->config['debug'] ) { if ( !defined( 'WP_DEBUG' ) ) define( 'WP_DEBUG', true ); } From fda118d320d57de4a71eeb08645d118fd5685c19 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Mar 2013 03:27:02 +0200 Subject: [PATCH 1416/4858] fix whitespace in media.php [ci skip] --- php/commands/media.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 77c6a10751..802c11971c 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -15,7 +15,7 @@ class Media_Command extends WP_CLI_Command { */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; - + // If id is given, skip confirm because it is only one file if( !empty( $args ) ) { $assoc_args['yes'] = true; @@ -41,7 +41,7 @@ function regenerate( $args, $assoc_args = array() ) { $count = $images->post_count; WP_CLI::line( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); - + $not_found = array_diff( $args, $images->posts ); if( !empty($not_found) ) { WP_CLI::warning( $this->_not_found_message( $not_found ) ); @@ -55,11 +55,10 @@ function regenerate( $args, $assoc_args = array() ) { } private function _process_regeneration( $id ) { - $image = get_post( $id ); $fullsizepath = get_attached_file( $image->ID ); - + if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); return; @@ -83,7 +82,7 @@ private function _process_regeneration( $id ) { while ( $file = readdir( $dir ) ) { if ( !( strrpos( $file, $image_name ) === false ) ) { - + $thumbnail = explode( $image_name, $file ); $filename = $thumbnail[ 1 ]; @@ -94,7 +93,7 @@ private function _process_regeneration( $id ) { $thumbnail_name = basename( $filename, $thumbnail_ext ); $sizes = explode( 'x', $thumbnail_name ); - + // If not cropped by WP if ( 2 == count( $sizes ) ) { $width = $sizes[0]; @@ -107,19 +106,21 @@ private function _process_regeneration( $id ) { } } } - + $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); - + if ( is_wp_error( $metadata ) ) { WP_CLI::warning( $metadata->get_error_message() ); return; } - + if ( empty( $metadata ) ) { WP_CLI::warning( "Couldn't regenerate image." ); return; } + wp_update_attachment_metadata( $image->ID, $metadata ); + WP_CLI::success( "All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); } @@ -134,4 +135,4 @@ private function _not_found_message( $not_found_ids ){ } } -WP_CLI::add_command( 'media', 'Media_Command' ); \ No newline at end of file +WP_CLI::add_command( 'media', 'Media_Command' ); From 83cb617e87ed7b7dbef720206f413f8a44062ece Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Mar 2013 05:06:00 +0200 Subject: [PATCH 1417/4858] media regenerate: remove inline props code has been significantly altered. will give credit in release post. --- php/commands/media.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 802c11971c..44007eec92 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -10,8 +10,7 @@ class Media_Command extends WP_CLI_Command { /** * Regenerate thumbnail(s) * - * @synopsis <attachment-id>... [--yes] - * props @benmay & @Viper007Bond + * @synopsis <attachment-id>... [--yes] */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; From f7127b540ca184d6e5549c402ab2f2fcc42a87ac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Mar 2013 05:23:18 +0200 Subject: [PATCH 1418/4858] use attachment metadata for deleting old images, instead of reading through the existing files --- php/commands/media.php | 62 +++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 44007eec92..199b1067dc 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -65,46 +65,7 @@ private function _process_regeneration( $id ) { WP_CLI::line( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); - $a_path = explode( DIRECTORY_SEPARATOR, $fullsizepath ); - $a_file = explode( '.', $a_path[ count( $a_path ) - 1 ] ); - - unset( $a_path ); - unset( $a_file[ count( $a_file ) - 1 ] ); - - $image_name = $a_file[ count( $a_file ) - 1 ] . '-'; - $dir_path = wp_upload_dir(); - - // Read and delete files - $dir = opendir( $dir_path['basedir'] ); - $files = array(); - - while ( $file = readdir( $dir ) ) { - - if ( !( strrpos( $file, $image_name ) === false ) ) { - - $thumbnail = explode( $image_name, $file ); - $filename = $thumbnail[ 1 ]; - - //If we got the original / full image - if ( "" == $thumbnail[ 0 ] ) { - $filetype = wp_check_filetype($file); - $thumbnail_ext = ".{$filetype['ext']}"; - $thumbnail_name = basename( $filename, $thumbnail_ext ); - - $sizes = explode( 'x', $thumbnail_name ); - - // If not cropped by WP - if ( 2 == count( $sizes ) ) { - $width = $sizes[0]; - $height = $sizes[1]; - if ( is_numeric( $width ) && is_numeric( $height ) ) { - WP_CLI::line( "Thumbnail: {$width} x {$height} was deleted." ); - unlink( $dir_path['basedir'] . DIRECTORY_SEPARATOR . $image_name . $thumbnail_name . $thumbnail_ext ); - } - } - } - } - } + $this->remove_old_images( $image->ID ); $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); @@ -123,6 +84,27 @@ private function _process_regeneration( $id ) { WP_CLI::success( "All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); } + private function remove_old_images( $att_id ) { + $wud = wp_upload_dir(); + + $metadata = wp_get_attachment_metadata( $att_id ); + + $dir_path = $wud['basedir'] . '/' . dirname( $metadata['file'] ) . '/'; + $original_path = $dir_path . basename( $metadata['file'] ); + + foreach ( $metadata['sizes'] as $size => $size_info ) { + $intermediate_path = $dir_path . $size_info['file']; + + if ( $intermediate_path == $original_path ) + continue; + + if ( unlink( $intermediate_path ) ) { + WP_CLI::line( sprintf( "Thumbnail %s x %s was deleted.", + $size_info['width'], $size_info['height'] ) ); + } + } + } + private function _not_found_message( $not_found_ids ){ $count = count($not_found_ids); return vsprintf( 'Unable to find the %1$s (%2$s). Are you sure %3$s %4$s?', array( From 4cdfe8cc63def17d630be532819e33a925484275 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Mar 2013 05:25:04 +0200 Subject: [PATCH 1419/4858] fix indentation for commands/media.php --- php/commands/media.php | 134 +++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 66 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 199b1067dc..c053cbca01 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -7,82 +7,82 @@ */ class Media_Command extends WP_CLI_Command { - /** - * Regenerate thumbnail(s) - * - * @synopsis <attachment-id>... [--yes] - */ - function regenerate( $args, $assoc_args = array() ) { - global $wpdb; - - // If id is given, skip confirm because it is only one file - if( !empty( $args ) ) { - $assoc_args['yes'] = true; - } + /** + * Regenerate thumbnail(s) + * + * @synopsis <attachment-id>... [--yes] + */ + function regenerate( $args, $assoc_args = array() ) { + global $wpdb; + + // If id is given, skip confirm because it is only one file + if( !empty( $args ) ) { + $assoc_args['yes'] = true; + } - WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); + WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); - $query_args = array( - 'post_type' => 'attachment', - 'post__in' => $args, - 'post_mime_type' => 'image', - 'post_status' => 'any', - 'posts_per_page' => -1, - 'fields' => 'ids' - ); + $query_args = array( + 'post_type' => 'attachment', + 'post__in' => $args, + 'post_mime_type' => 'image', + 'post_status' => 'any', + 'posts_per_page' => -1, + 'fields' => 'ids' + ); - $images = new WP_Query( $query_args ); + $images = new WP_Query( $query_args ); - if ( $images->post_count == 0 ) { - //No images, so all keys in $args are not found within WP - WP_CLI::error( $this->_not_found_message( $args ) ); - } - $count = $images->post_count; + if ( $images->post_count == 0 ) { + //No images, so all keys in $args are not found within WP + WP_CLI::error( $this->_not_found_message( $args ) ); + } + $count = $images->post_count; - WP_CLI::line( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); + WP_CLI::line( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); - $not_found = array_diff( $args, $images->posts ); - if( !empty($not_found) ) { - WP_CLI::warning( $this->_not_found_message( $not_found ) ); - } + $not_found = array_diff( $args, $images->posts ); + if( !empty($not_found) ) { + WP_CLI::warning( $this->_not_found_message( $not_found ) ); + } - foreach ( $images->posts as $id ) { - $this->_process_regeneration( $id ); - } + foreach ( $images->posts as $id ) { + $this->_process_regeneration( $id ); + } - WP_CLI::success( sprintf( 'Finished regenerating %1$s.', ngettext('the image', 'all images', $count) ) ); - } + WP_CLI::success( sprintf( 'Finished regenerating %1$s.', ngettext('the image', 'all images', $count) ) ); + } - private function _process_regeneration( $id ) { - $image = get_post( $id ); + private function _process_regeneration( $id ) { + $image = get_post( $id ); - $fullsizepath = get_attached_file( $image->ID ); + $fullsizepath = get_attached_file( $image->ID ); - if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); - return; - } + if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { + WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); + return; + } - WP_CLI::line( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); + WP_CLI::line( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); $this->remove_old_images( $image->ID ); - $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); + $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); - if ( is_wp_error( $metadata ) ) { - WP_CLI::warning( $metadata->get_error_message() ); - return; - } + if ( is_wp_error( $metadata ) ) { + WP_CLI::warning( $metadata->get_error_message() ); + return; + } - if ( empty( $metadata ) ) { - WP_CLI::warning( "Couldn't regenerate image." ); - return; - } + if ( empty( $metadata ) ) { + WP_CLI::warning( "Couldn't regenerate image." ); + return; + } - wp_update_attachment_metadata( $image->ID, $metadata ); + wp_update_attachment_metadata( $image->ID, $metadata ); - WP_CLI::success( "All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); - } + WP_CLI::success( "All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); + } private function remove_old_images( $att_id ) { $wud = wp_upload_dir(); @@ -105,15 +105,17 @@ private function remove_old_images( $att_id ) { } } - private function _not_found_message( $not_found_ids ){ - $count = count($not_found_ids); - return vsprintf( 'Unable to find the %1$s (%2$s). Are you sure %3$s %4$s?', array( - ngettext('image', 'images', $count), - implode(", ", $not_found_ids), - ngettext('it', 'they', $count), - ngettext('exists', 'exist', $count), - )); - } + private function _not_found_message( $not_found_ids ){ + $count = count( $not_found_ids ); + + return vsprintf( 'Unable to find the %1$s (%2$s). Are you sure %3$s %4$s?', array( + ngettext('image', 'images', $count), + implode(", ", $not_found_ids), + ngettext('it', 'they', $count), + ngettext('exists', 'exist', $count), + ) ); + } } WP_CLI::add_command( 'media', 'Media_Command' ); + From cf3d53bdfc0ee5213914165f0cc894a4a403f674 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 15 Mar 2013 22:40:24 +0200 Subject: [PATCH 1420/4858] add utility for generating the list of contributors [ci skip] --- .mailmap | 42 ++++++++++++++++++++++++++++++++++++++++++ utils/contrib-list | 16 ++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .mailmap create mode 100755 utils/contrib-list diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000000..cb5c30bb23 --- /dev/null +++ b/.mailmap @@ -0,0 +1,42 @@ +andreascreten <andreas@madewithlove.be> +bendoh <ben@thinkoomph.com> +builtbylane <lanegoldberg@gmail.com> +conatus <alex@recordsonribs.com> +danielbachhuber <d@danielbachhuber.com> +drrobotnik <B@Brandons-Mac-Pro-4.local> +dwightjack <marco.solazzi@gmail.com> +ericandrewlewis <eric.andrew.lewis@gmail.com> +ericmann <eric@eamann.com> +getsource <mike.schroder@dreamhost.com> +goldenapples <ntaintor@janrain.com> +jghazally <jeff@bigfish.co.uk> +jghazally <jghazally@gmail.com> +jmslbam <jmslbam@gmail.com> +johnpbloch <jbloch@John-Blochs-iMac.local> +johnpbloch <johnpbloch@gmail.com> +kidfiction <ejdanderson@gmail.com> +lackingpenguin <benjamin.j.brooks@gmail.com> +leewillis77 <leewillis77@gmail.com> +marcoceppi <marco@ceppi.net> +matiskay <matiskay@gmail.com> +mgburns <mgburns@bu.edu> +mgburns <mike@grady-etc.com> +milesj <mileswjohnson@gmail.com> +mwilliamson <michael.williamson@red-gate.com> +mwilliamson <mike@zwobble.org> +nacin <andrewnacin@gmail.com> +navitronic <adrian@navitronic.co.uk> +nb <nb@nikolay.bg> +ocean90 <dominikschilling+git@gmail.com> +roelven <roel@soundcloud.com> +scribu <scribu@gmail.com> +sebastiaandegeus <sebastiaan@hoppinger.com> +soulou <leo@soulou.fr> +spuriousdata <spuriousdata@gmail.com> +svaj <chris@chrisbot.(none)> +taupecat <tracy@taupecat.com> +tddewey <td@tddewey.com> +tollmanz <zack@zackdev.com> +toszcze <toszcze@gmail.com> +tott <tott@automattic.com> +wopr42 <john@zippykid.com> diff --git a/utils/contrib-list b/utils/contrib-list new file mode 100755 index 0000000000..76f5a1531b --- /dev/null +++ b/utils/contrib-list @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +if [ $# -lt 1 ]; then + echo "usage: $(basename $0) v0.8.0..v0.9.0 [-l]" + exit 1 +fi + +prev_version=$1 +linked=$2 + +if [ '-l' == "$linked" ] +then + git log --format="%aN" $prev_version -- | sort | uniq | sed 's#\(.*\)# [\1](http://github.com/\1)#' | tr '\n' ',' +else + git log --format="%aN <%aE>" $prev_version -- | sort | uniq +fi From 59111392b25c882af297b8fc93c12d03e3aa31ed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 18 Mar 2013 19:21:04 +0200 Subject: [PATCH 1421/4858] add link to Governance page --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 7a3335d10f..2c49bc83db 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,11 @@ For documentation, usage, and examples, check out [wp-cli.org](http://wp-cli.org I'm running into troubles, what can I do? ----------------------------------------- - To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). Who's behind this thing? ------------------------ - -We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. +We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). From 0a3a932c3d13cf9d4d4f9a6e1b9c3152c583c4d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Mar 2013 17:28:37 +0200 Subject: [PATCH 1422/4858] remote obsolete manual pages --- man/cache-add.1 | 10 ---------- man/cache-decr.1 | 10 ---------- man/cache-delete.1 | 10 ---------- man/cache-flush.1 | 10 ---------- man/cache-get.1 | 10 ---------- man/cache-incr.1 | 10 ---------- man/cache-replace.1 | 10 ---------- man/cache-set.1 | 10 ---------- man/cache-type.1 | 10 ---------- man/generate-posts.1 | 3 --- man/generate-users.1 | 3 --- man/option-add.1 | 10 ---------- man/option-delete.1 | 10 ---------- man/option-get.1 | 10 ---------- man/option-update.1 | 10 ---------- man/post-meta-add.1 | 10 ---------- man/post-meta-delete.1 | 10 ---------- man/post-meta-get.1 | 10 ---------- man/post-meta-update.1 | 10 ---------- man/transient-delete.1 | 10 ---------- man/transient-get.1 | 10 ---------- man/transient-set.1 | 10 ---------- man/transient-type.1 | 10 ---------- man/user-meta-add.1 | 10 ---------- man/user-meta-delete.1 | 10 ---------- man/user-meta-get.1 | 10 ---------- man/user-meta-update.1 | 10 ---------- 27 files changed, 256 deletions(-) delete mode 100644 man/cache-add.1 delete mode 100644 man/cache-decr.1 delete mode 100644 man/cache-delete.1 delete mode 100644 man/cache-flush.1 delete mode 100644 man/cache-get.1 delete mode 100644 man/cache-incr.1 delete mode 100644 man/cache-replace.1 delete mode 100644 man/cache-set.1 delete mode 100644 man/cache-type.1 delete mode 100644 man/generate-posts.1 delete mode 100644 man/generate-users.1 delete mode 100644 man/option-add.1 delete mode 100644 man/option-delete.1 delete mode 100644 man/option-get.1 delete mode 100644 man/option-update.1 delete mode 100644 man/post-meta-add.1 delete mode 100644 man/post-meta-delete.1 delete mode 100644 man/post-meta-get.1 delete mode 100644 man/post-meta-update.1 delete mode 100644 man/transient-delete.1 delete mode 100644 man/transient-get.1 delete mode 100644 man/transient-set.1 delete mode 100644 man/transient-type.1 delete mode 100644 man/user-meta-add.1 delete mode 100644 man/user-meta-delete.1 delete mode 100644 man/user-meta-get.1 delete mode 100644 man/user-meta-update.1 diff --git a/man/cache-add.1 b/man/cache-add.1 deleted file mode 100644 index 1ba98a2b05..0000000000 --- a/man/cache-add.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-ADD" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-add\fR \- Add a value to the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache add\fR \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cache-decr.1 b/man/cache-decr.1 deleted file mode 100644 index 7b77e71112..0000000000 --- a/man/cache-decr.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-DECR" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-decr\fR \- Decrement a value in the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache decr\fR \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] diff --git a/man/cache-delete.1 b/man/cache-delete.1 deleted file mode 100644 index 180dd95d4f..0000000000 --- a/man/cache-delete.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-DELETE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-delete\fR \- Remove a value from the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache delete\fR \fIkey\fR \fIgroup\fR diff --git a/man/cache-flush.1 b/man/cache-flush.1 deleted file mode 100644 index 68fa2e169e..0000000000 --- a/man/cache-flush.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-FLUSH" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-flush\fR \- Flush the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache flush\fR diff --git a/man/cache-get.1 b/man/cache-get.1 deleted file mode 100644 index eb27a251c7..0000000000 --- a/man/cache-get.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-GET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-get\fR \- Get a value from the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache get\fR \fIkey\fR [\fIgroup\fR] diff --git a/man/cache-incr.1 b/man/cache-incr.1 deleted file mode 100644 index fc2e886a56..0000000000 --- a/man/cache-incr.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-INCR" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-incr\fR \- Increment a value in the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache incr\fR \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] diff --git a/man/cache-replace.1 b/man/cache-replace.1 deleted file mode 100644 index d332695011..0000000000 --- a/man/cache-replace.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-REPLACE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-replace\fR \- Replace an existing value in the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache replace\fR \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cache-set.1 b/man/cache-set.1 deleted file mode 100644 index d40e0c0e6d..0000000000 --- a/man/cache-set.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-SET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-set\fR \- Set a value to the object cache\. -. -.SH "SYNOPSIS" -\fBwp cache set\fR \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] diff --git a/man/cache-type.1 b/man/cache-type.1 deleted file mode 100644 index a6c7c2a476..0000000000 --- a/man/cache-type.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE\-TYPE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\-type\fR \- Attempts to determine which object cache is being used\. -. -.SH "SYNOPSIS" -\fBwp cache type\fR diff --git a/man/generate-posts.1 b/man/generate-posts.1 deleted file mode 100644 index 995c5436f1..0000000000 --- a/man/generate-posts.1 +++ /dev/null @@ -1,3 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 - diff --git a/man/generate-users.1 b/man/generate-users.1 deleted file mode 100644 index 995c5436f1..0000000000 --- a/man/generate-users.1 +++ /dev/null @@ -1,3 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 - diff --git a/man/option-add.1 b/man/option-add.1 deleted file mode 100644 index 249bfa0b0f..0000000000 --- a/man/option-add.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-OPTION\-ADD" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-option\-add\fR \- Add an option\. -. -.SH "SYNOPSIS" -\fBwp option add\fR \fIkey\fR \fIvalue\fR [\-\-json] diff --git a/man/option-delete.1 b/man/option-delete.1 deleted file mode 100644 index a625edcc9b..0000000000 --- a/man/option-delete.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-OPTION\-DELETE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-option\-delete\fR \- Delete an option\. -. -.SH "SYNOPSIS" -\fBwp option delete\fR \fIkey\fR diff --git a/man/option-get.1 b/man/option-get.1 deleted file mode 100644 index ad48edbd0c..0000000000 --- a/man/option-get.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-OPTION\-GET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-option\-get\fR \- Get an option\. -. -.SH "SYNOPSIS" -\fBwp option get\fR \fIkey\fR [\-\-json] diff --git a/man/option-update.1 b/man/option-update.1 deleted file mode 100644 index f53e10c0a9..0000000000 --- a/man/option-update.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-OPTION\-UPDATE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-option\-update\fR \- Update an option\. -. -.SH "SYNOPSIS" -\fBwp option update\fR \fIkey\fR \fIvalue\fR [\-\-json] diff --git a/man/post-meta-add.1 b/man/post-meta-add.1 deleted file mode 100644 index 91ae02aa86..0000000000 --- a/man/post-meta-add.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-META\-ADD" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-meta\-add\fR \- Add a meta field\. -. -.SH "SYNOPSIS" -\fBwp post\-meta add\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/post-meta-delete.1 b/man/post-meta-delete.1 deleted file mode 100644 index ea28519d57..0000000000 --- a/man/post-meta-delete.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-META\-DELETE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-meta\-delete\fR \- Delete a meta field\. -. -.SH "SYNOPSIS" -\fBwp post\-meta delete\fR \fIid\fR \fIkey\fR diff --git a/man/post-meta-get.1 b/man/post-meta-get.1 deleted file mode 100644 index 330773f18b..0000000000 --- a/man/post-meta-get.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-META\-GET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-meta\-get\fR \- Get meta field value\. -. -.SH "SYNOPSIS" -\fBwp post\-meta get\fR \fIid\fR \fIkey\fR [\-\-json] diff --git a/man/post-meta-update.1 b/man/post-meta-update.1 deleted file mode 100644 index a90f92c422..0000000000 --- a/man/post-meta-update.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-META\-UPDATE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-meta\-update\fR \- Update a meta field\. -. -.SH "SYNOPSIS" -\fBwp post\-meta update\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/transient-delete.1 b/man/transient-delete.1 deleted file mode 100644 index 490196468e..0000000000 --- a/man/transient-delete.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TRANSIENT\-DELETE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-transient\-delete\fR \- Delete a transient value\. -. -.SH "SYNOPSIS" -\fBwp transient delete\fR \fIkey\fR diff --git a/man/transient-get.1 b/man/transient-get.1 deleted file mode 100644 index b6895c048a..0000000000 --- a/man/transient-get.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TRANSIENT\-GET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-transient\-get\fR \- Get a transient value\. -. -.SH "SYNOPSIS" -\fBwp transient get\fR \fIkey\fR [\-\-json] diff --git a/man/transient-set.1 b/man/transient-set.1 deleted file mode 100644 index a3addcc597..0000000000 --- a/man/transient-set.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TRANSIENT\-SET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-transient\-set\fR \- Set a transient value\. -. -.SH "SYNOPSIS" -\fBwp transient set\fR \fIkey\fR \fIvalue\fR [\fIexpiration\fR] diff --git a/man/transient-type.1 b/man/transient-type.1 deleted file mode 100644 index bdd4b06770..0000000000 --- a/man/transient-type.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TRANSIENT\-TYPE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-transient\-type\fR \- See wether the transients API is using an object cache or the options table\. -. -.SH "SYNOPSIS" -\fBwp transient type\fR diff --git a/man/user-meta-add.1 b/man/user-meta-add.1 deleted file mode 100644 index 691c7b6dca..0000000000 --- a/man/user-meta-add.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-META\-ADD" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-meta\-add\fR \- Add a meta field\. -. -.SH "SYNOPSIS" -\fBwp user\-meta add\fR \fIid\fR \fIkey\fR \fIvalue\fR diff --git a/man/user-meta-delete.1 b/man/user-meta-delete.1 deleted file mode 100644 index 310893ccd7..0000000000 --- a/man/user-meta-delete.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-META\-DELETE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-meta\-delete\fR \- Delete a meta field\. -. -.SH "SYNOPSIS" -\fBwp user\-meta delete\fR \fIid\fR \fIkey\fR diff --git a/man/user-meta-get.1 b/man/user-meta-get.1 deleted file mode 100644 index 1d9ee4b8c2..0000000000 --- a/man/user-meta-get.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-META\-GET" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-meta\-get\fR \- Get meta field value\. -. -.SH "SYNOPSIS" -\fBwp user\-meta get\fR \fIid\fR \fIkey\fR [\-\-json] diff --git a/man/user-meta-update.1 b/man/user-meta-update.1 deleted file mode 100644 index 1e5e44f8f4..0000000000 --- a/man/user-meta-update.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-META\-UPDATE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-meta\-update\fR \- Update a meta field\. -. -.SH "SYNOPSIS" -\fBwp user\-meta update\fR \fIid\fR \fIkey\fR \fIvalue\fR From 566810649598a87785a9c2ae28b9685343016b1d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 19 Mar 2013 17:33:58 +0200 Subject: [PATCH 1423/4858] add missing man src for core update-db --- man-src/core-update-db.txt | 0 man/core-update-db.1 | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 man-src/core-update-db.txt diff --git a/man-src/core-update-db.txt b/man-src/core-update-db.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/man/core-update-db.1 b/man/core-update-db.1 index 87d2dbdb9c..1dd86294fd 100644 --- a/man/core-update-db.1 +++ b/man/core-update-db.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-CORE\-UPDATE\-DB" "1" "October 2012" "" "WP-CLI" +.TH "WP\-CORE\-UPDATE\-DB" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-core\-update\-db\fR \- Update the WordPress database\. . .SH "SYNOPSIS" -\fBwp core update\-db\fR +wp core update\-db From 270b0f6497cb011cac7504fd7d52eae68738eb6f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 20 Mar 2013 18:28:27 +0200 Subject: [PATCH 1424/4858] set version to 0.9.0 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 7fb1aa66f0..e7afedfca8 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.0-beta' ); +define( 'WP_CLI_VERSION', '0.9.0' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 420605ceb444e90fdef8c30b918fa6ca0ab7443c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 20 Mar 2013 18:33:09 +0200 Subject: [PATCH 1425/4858] update description for media command --- php/commands/media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index c053cbca01..36c37ac917 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -1,7 +1,7 @@ <?php /** - * Functionality to control the media library and its attachments + * Control the media library and its attachments. * * @package wp-cli */ From 4a5f0c9d783eda0acb2c570065982b7231b05a9b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Mar 2013 07:28:39 +0200 Subject: [PATCH 1426/4858] convert output_csv() to write_csv() and make it require a file parameter --- php/utils.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/php/utils.php b/php/utils.php index 5a2718636c..3997a1547a 100644 --- a/php/utils.php +++ b/php/utils.php @@ -257,22 +257,23 @@ function format_items( $format, $fields, $items ) { if ( 'json' == $format ) echo json_encode( $output_items ); else - output_csv( $output_items, $fields ); + write_csv( STDOUT, $output_items, $fields ); break; } } /** - * Output data as CSV + * Write data as CSV to a given file. * - * @param array $rows Array of rows to output - * @param array $headers List of CSV columns (optional) + * @param resource $fd File descriptor + * @param array $rows Array of rows to output + * @param array $headers List of CSV columns (optional) */ -function output_csv( $rows, $headers = array() ) { +function write_csv( $fd, $rows, $headers = array() ) { // Prepare the headers if they were specified if ( ! empty( $headers ) ) - fputcsv( STDOUT, $headers ); + fputcsv( $fd, $headers ); foreach ( $rows as $row ) { $row = (array) $row; @@ -284,7 +285,7 @@ function output_csv( $rows, $headers = array() ) { } $row = $build_row; } - fputcsv( STDOUT, $row ); + fputcsv( $fd, $row ); } } From 46e97a5dfc1d2bc1e66332b7875f32f5057e973a Mon Sep 17 00:00:00 2001 From: Weston Ruter <westonruter@gmail.com> Date: Thu, 21 Mar 2013 17:12:00 -0700 Subject: [PATCH 1427/4858] walk up directory tree to find config file Allows WP-CLI to be invoked from anywhere within a project. You are not limited to being in the directory where the wp-cli*.yml file is. The DOCUMENT_ROOT is then set to the supplied path relative to the config file. --- php/WP_CLI/Runner.php | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ff3fbae7e7..9458614238 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -17,19 +17,29 @@ public function __get( $key ) { } private static function get_config_path( &$assoc_args ) { - if ( isset( $assoc_args['config'] ) ) { - $paths = array( $assoc_args['config'] ); + if ( isset( $assoc_args['config'] ) && file_exists( $assoc_args['config'] ) ) { + $path = $assoc_args['config']; unset( $assoc_args['config'] ); - } else { - $paths = array( - getcwd() . '/wp-cli.local.yml', - getcwd() . '/wp-cli.yml' - ); + return $path; } - foreach ( $paths as $path ) { - if ( file_exists( $path ) ) - return $path; + $dir = getcwd(); + $config_files = array( + 'wp-cli.local.yml', + 'wp-cli.yml' + ); + while ( is_readable( $dir ) ) { + foreach ( $config_files as $config_file ) { + $path = $dir . DIRECTORY_SEPARATOR . $config_file; + if ( file_exists( $path ) ) { + return $path; + } + } + $parent_dir = dirname( $dir ); + if ( empty($parent_dir) || $parent_dir === $dir ) { + break; + } + $dir = $parent_dir; } return false; @@ -50,6 +60,12 @@ private static function load_config( $path, $spec ) { $sanitized_config[ $key ] = $details['default']; } + // When invoking from a subdirectory in the project, + // make sure a config-relative 'path' is made absolute + if ( ! self::is_absolute_path( $sanitized_config['path'] ) ) { + $sanitized_config['path'] = dirname( $path ) . DIRECTORY_SEPARATOR . $sanitized_config['path']; + } + return $sanitized_config; } @@ -250,7 +266,7 @@ public function before_wp_load() { exit; } - $_SERVER['DOCUMENT_ROOT'] = getcwd(); + $_SERVER['DOCUMENT_ROOT'] = realpath( $this->config['path'] ); // First try at showing man page if ( $this->cmd_starts_with( array( 'help' ) ) ) { From 3c1059fa64af83071f974f709aab86679c4c1758 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 22 Mar 2013 02:38:50 +0200 Subject: [PATCH 1428/4858] contributing: add line about getting feedback --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 04fea31045..c90ed7c397 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,7 @@ Contribute So you've got an awesome idea to throw into WP-CLI. Great! Please keep the following in mind: +* The best way to get feedback is by opening an issue or a pull request; if you think the code shouldn't be merged yet, just say so. * If you're adding a new command or subcommand, please consider adding a functional test for it in the `features` directory. Also, please create the appropriate `.txt` file in the `man-src` directory. * Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). From 7fdf7ab4de049648f3aa8012bae1f4c2a1f1bdd5 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Fri, 22 Mar 2013 01:14:46 -0700 Subject: [PATCH 1429/4858] supply a default to the path config based on an upward search for wp-load.php Add a Utils function for find_file_upward --- php/WP_CLI/Runner.php | 22 +++++++++------------- php/utils.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9458614238..aa506acb22 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -23,23 +23,13 @@ private static function get_config_path( &$assoc_args ) { return $path; } - $dir = getcwd(); $config_files = array( 'wp-cli.local.yml', 'wp-cli.yml' ); - while ( is_readable( $dir ) ) { - foreach ( $config_files as $config_file ) { - $path = $dir . DIRECTORY_SEPARATOR . $config_file; - if ( file_exists( $path ) ) { - return $path; - } - } - $parent_dir = dirname( $dir ); - if ( empty($parent_dir) || $parent_dir === $dir ) { - break; - } - $dir = $parent_dir; + $path = Utils\find_file_upward( $config_files, getcwd() ); + if ( $path ) { + return $path; } return false; @@ -229,6 +219,12 @@ public function before_wp_load() { $config_spec = Utils\get_config_spec(); + // Set the path default to the ABSPATH + $wp_abspath = dirname( Utils\find_file_upward( 'wp-load.php' ) ); + if ( ! empty( $wp_abspath ) ) { + $config_spec['path']['default'] = $wp_abspath; + } + $this->config_path = self::get_config_path( $this->assoc_args ); $this->config = self::load_config( $this->config_path, $config_spec ); diff --git a/php/utils.php b/php/utils.php index 3997a1547a..6898e71762 100644 --- a/php/utils.php +++ b/php/utils.php @@ -48,6 +48,34 @@ function get_config_spec() { return $spec; } +/** + * Search for file by walking up the directory tree until the first file is found + * @param string|array The files (or file) to search for + * @param string|null The directory to start searching from; defaults to CWD + * @return null|string Null if the file was not found + */ +function find_file_upward($files, $dir = null) { + $files = (array) $files; + if ( is_null( $dir ) ) { + $dir = getcwd(); + } + while ( is_readable( $dir ) ) { + foreach ( $files as $file ) { + $path = $dir . DIRECTORY_SEPARATOR . $file; + if ( file_exists( $path ) ) { + return $path; + } + } + + $parent_dir = dirname( $dir ); + if ( empty($parent_dir) || $parent_dir === $dir ) { + break; + } + $dir = $parent_dir; + } + return null; +} + /** * Splits $argv into positional and associative arguments. * From ef6d541614ded739ba51e74d693c9f852464e8f2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 22 Mar 2013 18:34:45 +0200 Subject: [PATCH 1430/4858] fix brace style in Feature Context --- features/bootstrap/FeatureContext.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 071bba1cc3..9b20e4d607 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -11,8 +11,8 @@ /** * Features context. */ -class FeatureContext extends BehatContext implements ClosuredContextInterface -{ +class FeatureContext extends BehatContext implements ClosuredContextInterface { + protected static $db_settings = array( 'dbname' => 'wp_cli_test', 'dbuser' => 'wp_cli_test', @@ -30,8 +30,7 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface * * @param array $parameters context parameters (set them up through behat.yml) */ - public function __construct( array $parameters ) - { + public function __construct( array $parameters ) { $this->drop_db(); $this->additional_args = array( @@ -50,23 +49,19 @@ public function __construct( array $parameters ) ); } - public function getStepDefinitionResources() - { + public function getStepDefinitionResources() { return array( __DIR__ . '/../steps/basic_steps.php' ); } - public function getHookDefinitionResources() - { + public function getHookDefinitionResources() { return array(); } - public function replace_variables( $str ) - { + public function replace_variables( $str ) { return preg_replace_callback( '/\{([A-Z_]+)\}/', array( $this, '_replace_var' ), $str ); } - private function _replace_var( $matches ) - { + private function _replace_var( $matches ) { $cmd = $matches[0]; foreach ( array_slice( $matches, 1 ) as $key ) { From bb76c470f09a66b776908d0800a4c4bebf4970b9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 22 Mar 2013 18:36:40 +0200 Subject: [PATCH 1431/4858] move define_custom_wp_content_dir() into step definition, since it's only used once --- features/bootstrap/FeatureContext.php | 27 +++------------------------ features/steps/basic_steps.php | 14 +++++++++++++- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 9b20e4d607..1977603a34 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -148,32 +148,11 @@ public function run( $command, $assoc_args = array() ) { return $this->_run( $command, $assoc_args ); } - public function define_custom_wp_content_dir() { - $wp_config_path = $this->install_dir . '/wp-config.php'; - - $wp_config_code = file_get_contents( $wp_config_path ); - - $this->add_line_to_wp_config( $wp_config_code, - "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); - - $this->move_files( 'wp-content', 'my-content' ); - - $this->add_line_to_wp_config( $wp_config_code, - "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); - - $this->move_files( 'my-content/plugins', 'my-plugins' ); - - file_put_contents( $wp_config_path, $wp_config_code ); - } - - private function move_files( $src, $dest ) { - rename( - $this->install_dir . '/' . $src, - $this->install_dir . '/' . $dest - ); + public function move_files( $src, $dest ) { + rename( $this->get_path( $src ), $this->get_path( $dest ) ); } - private function add_line_to_wp_config( &$wp_config_code, $line ) { + public function add_line_to_wp_config( &$wp_config_code, $line ) { $token = "/* That's all, stop editing!"; $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 270e9fa4d7..83e4399be1 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -44,7 +44,19 @@ function ( $world, $type ) { $steps->Given( '/^custom wp-content directory$/', function ( $world ) { - $world->define_custom_wp_content_dir(); + $wp_config_path = $world->get_path( 'wp-config.php' ); + + $wp_config_code = file_get_contents( $wp_config_path ); + + $world->move_files( 'wp-content', 'my-content' ); + $world->add_line_to_wp_config( $wp_config_code, + "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); + + $world->move_files( 'my-content/plugins', 'my-plugins' ); + $world->add_line_to_wp_config( $wp_config_code, + "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); + + file_put_contents( $wp_config_path, $wp_config_code ); } ); From 1486d9d596d1207584e0781b11df9634e441be66 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 04:45:04 +0200 Subject: [PATCH 1432/4858] use @BeforeSuite hook to initialize $additional_args --- features/bootstrap/FeatureContext.php | 33 ++++++++++++++++----------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 1977603a34..58d300ce59 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -2,7 +2,8 @@ use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\TranslatedContextInterface, - Behat\Behat\Context\BehatContext; + Behat\Behat\Context\BehatContext, + Behat\Behat\Event\SuiteEvent; require_once 'PHPUnit/Framework/Assert/Functions.php'; @@ -13,27 +14,23 @@ */ class FeatureContext extends BehatContext implements ClosuredContextInterface { - protected static $db_settings = array( + private static $db_settings = array( 'dbname' => 'wp_cli_test', 'dbuser' => 'wp_cli_test', 'dbpass' => 'password1' ); + private static $additional_args; + private $install_dir; - private $additional_args; public $variables = array(); /** - * Initializes context. - * Every scenario gets it's own context object. - * - * @param array $parameters context parameters (set them up through behat.yml) + * @BeforeSuite */ - public function __construct( array $parameters ) { - $this->drop_db(); - - $this->additional_args = array( + public static function prepare( SuiteEvent $event ) { + self::$additional_args = array( 'core config' => self::$db_settings, 'core install' => array( @@ -49,6 +46,16 @@ public function __construct( array $parameters ) { ); } + /** + * Initializes context. + * Every scenario gets it's own context object. + * + * @param array $parameters context parameters (set them up through behat.yml) + */ + public function __construct( array $parameters ) { + $this->drop_db(); + } + public function getStepDefinitionResources() { return array( __DIR__ . '/../steps/basic_steps.php' ); } @@ -140,8 +147,8 @@ private function _run( $command, $assoc_args ) { } public function run( $command, $assoc_args = array() ) { - if ( isset( $this->additional_args[ $command ] ) ) { - $assoc_args = array_merge( $this->additional_args[ $command ], + if ( isset( self::$additional_args[ $command ] ) ) { + $assoc_args = array_merge( self::$additional_args[ $command ], $assoc_args ); } From 79ff4f68053dbbc80d33d30ccfbefb6adc7e2e61 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 04:52:13 +0200 Subject: [PATCH 1433/4858] change directory, instead of prepending --path --- features/bootstrap/FeatureContext.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 58d300ce59..d37532213b 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -81,6 +81,7 @@ private function _replace_var( $matches ) { public function create_empty_dir() { $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); mkdir( $this->install_dir ); + chdir( $this->install_dir ); } public function get_path( $file ) { @@ -121,13 +122,7 @@ private function _run( $command, $assoc_args ) { if ( !empty( $assoc_args ) ) $command .= \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); - if ( false === strpos( $command, '--path' ) ) { - $command = \WP_CLI\Utils\assoc_args_to_str( array( - 'path' => $this->install_dir - ) ) . ' ' . $command; - } - - $sh_command = getcwd() . "/bin/wp $command"; + $sh_command = __DIR__ . "/../../bin/wp $command"; $process = proc_open( $sh_command, array( 0 => STDIN, From 42120584acfdce3e2ea984f0737acfdb300cf314 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 05:01:36 +0200 Subject: [PATCH 1434/4858] make FeatureContext->get_path() return the path unmodified --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d37532213b..dfd7fc388d 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -85,7 +85,7 @@ public function create_empty_dir() { } public function get_path( $file ) { - return $this->install_dir . '/' . $file; + return $file; } public function get_cache_path( $file ) { From cc29364d4dc1682ab0c9e10d83e37c44a894a057 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 05:14:28 +0200 Subject: [PATCH 1435/4858] prepend './' to relative paths --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index dfd7fc388d..dbee25765c 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -85,7 +85,7 @@ public function create_empty_dir() { } public function get_path( $file ) { - return $file; + return './' . $file; } public function get_cache_path( $file ) { From 319d7429393bc43ad168dd9b8ddb33e1d8855e28 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 05:41:55 +0200 Subject: [PATCH 1436/4858] pass cwd directly to proc_open() and revert changes to get_path() --- features/bootstrap/FeatureContext.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index dbee25765c..2dd41e187f 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -81,11 +81,10 @@ private function _replace_var( $matches ) { public function create_empty_dir() { $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); mkdir( $this->install_dir ); - chdir( $this->install_dir ); } public function get_path( $file ) { - return './' . $file; + return $this->install_dir . '/' . $file; } public function get_cache_path( $file ) { @@ -122,13 +121,15 @@ private function _run( $command, $assoc_args ) { if ( !empty( $assoc_args ) ) $command .= \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); - $sh_command = __DIR__ . "/../../bin/wp $command"; + $cmd = __DIR__ . "/../../bin/wp $command"; - $process = proc_open( $sh_command, array( + $descriptors = array( 0 => STDIN, 1 => array( 'pipe', 'w' ), 2 => array( 'pipe', 'w' ), - ), $pipes ); + ); + + $proc = proc_open( $cmd, $descriptors, $pipes, $this->install_dir ); $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); @@ -136,9 +137,11 @@ private function _run( $command, $assoc_args ) { $STDERR = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); - $return_code = proc_close( $process ); + $return_code = proc_close( $proc ); + + $r = (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); - return (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); + return $r; } public function run( $command, $assoc_args = array() ) { From 22599b5271e340920a2869bed2e32b142cf5da08 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 05:53:33 +0200 Subject: [PATCH 1437/4858] split single site from multisite install steps --- features/bootstrap/FeatureContext.php | 8 ++++++++ features/steps/basic_steps.php | 19 +++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 2dd41e187f..d7b8740da2 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -174,5 +174,13 @@ public function download_wordpress_files() { system( \WP_CLI\Utils\create_cmd( "cp -r %s/* %s/", $cache_dir, $this->install_dir ) ); } + + public function wp_install() { + $this->create_db(); + $this->create_empty_dir(); + $this->download_wordpress_files(); + $this->run( 'core config' ); + $this->run( 'core install' ); + } } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 83e4399be1..0473c39f8f 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -28,17 +28,16 @@ function ( $world ) { } ); -$steps->Given( '/^a WP (install|multisite install)$/', - function ( $world, $type ) { - $world->create_db(); - $world->create_empty_dir(); - $world->download_wordpress_files(); - $world->run( 'core config' ); - $world->run( 'core install' ); +$steps->Given( '/^a WP install$/', + function ( $world ) { + $world->wp_install(); + } +); - if ( 'multisite install' == $type ) { - $world->run( 'core install-network' ); - } +$steps->Given( '/^a WP multisite install$/', + function ( $world ) { + $world->wp_install(); + $world->run( 'core install-network' ); } ); From d6228d520b2b084f804531762f75e9470aeeebc3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 06:43:32 +0200 Subject: [PATCH 1438/4858] add 'cwd' key to FeatureContext->_run() result --- features/bootstrap/FeatureContext.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d7b8740da2..61545f42aa 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -137,9 +137,13 @@ private function _run( $command, $assoc_args ) { $STDERR = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); - $return_code = proc_close( $proc ); - - $r = (object) compact( 'command', 'return_code', 'STDOUT', 'STDERR' ); + $r = (object) array( + 'command' => $command, + 'STDOUT' => $STDOUT, + 'STDERR' => $STDERR, + 'return_code' => proc_close( $proc ), + 'cwd' => $this->install_dir + ); return $r; } From dd553c2e7e7d8eb0881f784a55ec280d17236b48 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Mar 2013 06:52:52 +0200 Subject: [PATCH 1439/4858] add basic scenarios for wp-cli.yml --- features/config.feature | 26 ++++++++++++++++++++++++++ features/steps/basic_steps.php | 6 ++++++ 2 files changed, 32 insertions(+) create mode 100644 features/config.feature diff --git a/features/config.feature b/features/config.feature new file mode 100644 index 0000000000..c61251984d --- /dev/null +++ b/features/config.feature @@ -0,0 +1,26 @@ +Feature: Have a config file + + Scenario: No config file + Given a WP install + """ + """ + + When I run `wp --info` + Then it should run without errors + And STDOUT should not contain: + """ + wp-cli.yml + """ + + Scenario: Config file in WP Root + Given a WP install + And a wp-cli.yml file: + """ + """ + + When I run `wp --info` + Then it should run without errors + And STDOUT should contain: + """ + wp-cli.yml + """ diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 0473c39f8f..119b8a90fb 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -10,6 +10,12 @@ function ( $world ) { } ); +$steps->Given( '/^a ([^\s]+) file:$/', + function ( $world, $path, PyStringNode $content ) { + file_put_contents( $world->get_path( $path ), (string) $content ); + } +); + $steps->Given( '/^WP files$/', function ( $world ) { $world->download_wordpress_files(); From 8b8721a180439f40795b6838b2308e30d4fd1ea5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Mar 2013 17:18:33 +0200 Subject: [PATCH 1440/4858] add scenario for WP in a subdir --- features/bootstrap/FeatureContext.php | 18 ++++++++++++------ features/config.feature | 11 +++++++++++ features/steps/basic_steps.php | 6 ++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 61545f42aa..9776e56d1a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -167,7 +167,7 @@ public function add_line_to_wp_config( &$wp_config_code, $line ) { $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); } - public function download_wordpress_files() { + public function download_wordpress_files( $subdir = '' ) { // We cache the results of "wp core download" to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; @@ -176,15 +176,21 @@ public function download_wordpress_files() { 'path' => $cache_dir ) ); - system( \WP_CLI\Utils\create_cmd( "cp -r %s/* %s/", $cache_dir, $this->install_dir ) ); + $dest_dir = $this->get_path( $subdir ); + + if ( $subdir ) mkdir( $dest_dir ); + + $cmd = \WP_CLI\Utils\create_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ); + + system( $cmd ); } - public function wp_install() { + public function wp_install( $subdir = '' ) { $this->create_db(); $this->create_empty_dir(); - $this->download_wordpress_files(); - $this->run( 'core config' ); - $this->run( 'core install' ); + $this->download_wordpress_files( $subdir ); + $this->run( 'core config', array( 'path' => $subdir ) ); + $this->run( 'core install', array( 'path' => $subdir ) ); } } diff --git a/features/config.feature b/features/config.feature index c61251984d..7d3f51b29a 100644 --- a/features/config.feature +++ b/features/config.feature @@ -24,3 +24,14 @@ Feature: Have a config file """ wp-cli.yml """ + + Scenario: WP in a subdirectory + Given a WP install in 'core' + And a wp-cli.yml file: + """ + path: core + """ + + When I run `wp core version` + Then it should run without errors + And STDOUT should not be empty diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 119b8a90fb..4a962777e6 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -40,6 +40,12 @@ function ( $world ) { } ); +$steps->Given( "/^a WP install in '([^\s]+)'$/", + function ( $world, $subdir ) { + $world->wp_install( $subdir ); + } +); + $steps->Given( '/^a WP multisite install$/', function ( $world ) { $world->wp_install(); From f021f0421f55f6bceb68a93415447bf0086cd09a Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 25 Mar 2013 19:28:56 +0100 Subject: [PATCH 1441/4858] Added behat feature for media regenerate --- features/media.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 features/media.feature diff --git a/features/media.feature b/features/media.feature new file mode 100644 index 0000000000..6afe09198b --- /dev/null +++ b/features/media.feature @@ -0,0 +1,11 @@ +Feature: Manage WordPress attachments + + @images + Scenario: Regenerate all images while none exists + Given a WP install + + When I run `wp media regenerate --yes` + Then STDERR should contain: + """ + Error: Unable to find the images + """ From 6ee929c0578ce218a13fb0dbd8b371d9d5fbd68e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Mar 2013 19:42:57 +0200 Subject: [PATCH 1442/4858] 'a custom wp-content directory' --- features/core.feature | 2 +- features/steps/basic_steps.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index d333fbaab7..87d06872db 100644 --- a/features/core.feature +++ b/features/core.feature @@ -71,7 +71,7 @@ Feature: Manage WordPress installation Scenario: Custom wp-content directory Given a WP install - And custom wp-content directory + And a custom wp-content directory When I run `wp plugin status hello` Then it should run without errors diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 4a962777e6..7e9509e8db 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -53,7 +53,7 @@ function ( $world ) { } ); -$steps->Given( '/^custom wp-content directory$/', +$steps->Given( '/^a custom wp-content directory$/', function ( $world ) { $wp_config_path = $world->get_path( 'wp-config.php' ); From 576b6b60ae9c88ad46245af932fdf0b17c64d1a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Mar 2013 19:48:21 +0200 Subject: [PATCH 1443/4858] add run cmd from subdir step definition --- features/bootstrap/FeatureContext.php | 14 ++++++++------ features/steps/basic_steps.php | 6 ++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 9776e56d1a..bf493384d9 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -117,10 +117,12 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - private function _run( $command, $assoc_args ) { + private function _run( $command, $assoc_args, $subdir = '' ) { if ( !empty( $assoc_args ) ) $command .= \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); + $subdir = $this->get_path( $subdir ); + $cmd = __DIR__ . "/../../bin/wp $command"; $descriptors = array( @@ -129,7 +131,7 @@ private function _run( $command, $assoc_args ) { 2 => array( 'pipe', 'w' ), ); - $proc = proc_open( $cmd, $descriptors, $pipes, $this->install_dir ); + $proc = proc_open( $cmd, $descriptors, $pipes, $subdir ); $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); @@ -148,13 +150,13 @@ private function _run( $command, $assoc_args ) { return $r; } - public function run( $command, $assoc_args = array() ) { + public function run( $command, $assoc_args = array(), $subdir = '' ) { if ( isset( self::$additional_args[ $command ] ) ) { $assoc_args = array_merge( self::$additional_args[ $command ], $assoc_args ); } - return $this->_run( $command, $assoc_args ); + return $this->_run( $command, $assoc_args, $subdir ); } public function move_files( $src, $dest ) { @@ -189,8 +191,8 @@ public function wp_install( $subdir = '' ) { $this->create_db(); $this->create_empty_dir(); $this->download_wordpress_files( $subdir ); - $this->run( 'core config', array( 'path' => $subdir ) ); - $this->run( 'core install', array( 'path' => $subdir ) ); + $this->run( 'core config', array(), $subdir ); + $this->run( 'core install', array(), $subdir ); } } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 7e9509e8db..352bdb77a9 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -105,6 +105,12 @@ function ( $world, $cmd ) { } ); +$steps->When( "/^I run `wp (.+)` from '([^\s]+)'$/", + function ( $world, $cmd, $subdir ) { + $world->result = $world->run( $world->replace_variables( $cmd ), array(), $subdir ); + } +); + $steps->When( '/^I run the previous command again$/', function ( $world ) { if ( !isset( $world->result ) ) From 4a0e69568bef2fa148bc3f51d78a81f81c7ae99c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 27 Mar 2013 07:15:03 +0200 Subject: [PATCH 1444/4858] fix comment about param-dump [ci skip] --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ff3fbae7e7..78f1423446 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -238,7 +238,7 @@ public function before_wp_load() { exit; } - // Handle --cmd-dump parameter + // Handle --param-dump parameter if ( isset( $this->assoc_args['param-dump'] ) ) { \WP_CLI\InternalAssoc::param_dump(); exit; From 9a7e58bed838133254a0b94e897e901d20077b46 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 27 Mar 2013 09:19:54 +0100 Subject: [PATCH 1445/4858] Regenerate Man --- man-src/scaffold-post-type.txt | 4 ++++ man-src/scaffold-taxonomy.txt | 4 ++++ man/scaffold-post-type.1 | 8 +++++++- man/scaffold-taxonomy.1 | 8 +++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/man-src/scaffold-post-type.txt b/man-src/scaffold-post-type.txt index e78108cde7..e45952d06c 100644 --- a/man-src/scaffold-post-type.txt +++ b/man-src/scaffold-post-type.txt @@ -1,5 +1,9 @@ ## OPTIONS +* `--label=<label>`: + + The text used to translate the update messages + * `--textdomain=<textdomain>`: The textdomain to use for the labels. diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt index 5eac94157e..41c7ab375c 100644 --- a/man-src/scaffold-taxonomy.txt +++ b/man-src/scaffold-taxonomy.txt @@ -1,5 +1,9 @@ ## OPTIONS +* `--label=<label>`: + + The text used to translate the update messages + * `--textdomain=<textdomain>`: The textdomain to use for the labels. diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 index 5e9223561f..1fc921d042 100644 --- a/man/scaffold-post-type.1 +++ b/man/scaffold-post-type.1 @@ -7,11 +7,17 @@ \fBwp\-scaffold\-post\-type\fR \- Generate PHP code for registering a custom post type\. . .SH "SYNOPSIS" -wp scaffold post\-type \fIslug\fR [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +wp scaffold post\-type \fIslug\fR [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-label=\fIlabel\fR] [\-\-raw] . .SH "OPTIONS" . .TP +\fB\-\-label=<label>\fR: +. +.IP +The text used to translate the update messages +. +.TP \fB\-\-textdomain=<textdomain>\fR: . .IP diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index 6af8faf4fb..10f5b5e64c 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -7,11 +7,17 @@ \fBwp\-scaffold\-taxonomy\fR \- Generate PHP code for registering a custom taxonomy\. . .SH "SYNOPSIS" -wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] +wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-label=\fIlabel\fR] [\-\-raw] . .SH "OPTIONS" . .TP +\fB\-\-label=<label>\fR: +. +.IP +The text used to translate the update messages +. +.TP \fB\-\-textdomain=<textdomain>\fR: . .IP From 1cf73da8914b9cd1a1a1c4586bd60f633d434d9e Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 27 Mar 2013 09:20:09 +0100 Subject: [PATCH 1446/4858] Added label to tax and cpt --- php/commands/scaffold.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 4697c47fb0..87a88fbecd 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -18,7 +18,7 @@ function __construct() { * * @alias cpt * - * @synopsis <slug> [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] + * @synopsis <slug> [--label=<label>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function post_type( $args, $assoc_args ) { $defaults = array( @@ -38,7 +38,7 @@ function post_type( $args, $assoc_args ) { * * @alias tax * - * @synopsis <slug> [--post_types=<post-types>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] + * @synopsis <slug> [--post_types=<post-types>] [--label=<label>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function taxonomy( $args, $assoc_args ) { $defaults = array( @@ -56,6 +56,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) global $wp_filesystem; $control_args = $this->extract_args( $assoc_args, array( + 'label' => $slug, 'theme' => false, 'plugin' => false, 'raw' => false, @@ -67,7 +68,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); - $vars['label'] = preg_replace( '/_|-/', ' ', strtolower( $slug ) ); + $vars['label'] = preg_replace( '/_|-/', ' ', strtolower( $control_args['label'] ) ); $vars['label_ucfirst'] = ucfirst( $vars['label'] ); $vars['label_plural'] = $this->pluralize( $vars['label'] ); From 245278e94262f32234cf4bb552874a92e15ffc85 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 27 Mar 2013 21:01:38 +0100 Subject: [PATCH 1447/4858] Only preg_replace default $slug --- php/commands/scaffold.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 87a88fbecd..5b3fc7919f 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -56,7 +56,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) global $wp_filesystem; $control_args = $this->extract_args( $assoc_args, array( - 'label' => $slug, + 'label' => preg_replace( '/_|-/', ' ', strtolower( $slug ) ), 'theme' => false, 'plugin' => false, 'raw' => false, @@ -68,7 +68,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); - $vars['label'] = preg_replace( '/_|-/', ' ', strtolower( $control_args['label'] ) ); + $vars['label'] = $control_args['label']; $vars['label_ucfirst'] = ucfirst( $vars['label'] ); $vars['label_plural'] = $this->pluralize( $vars['label'] ); From d0e20dff194d775ea9f838abec0dfb24322fc534 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Wed, 27 Mar 2013 18:06:17 -0700 Subject: [PATCH 1448/4858] prevent absolutizing a relative config path when it is empty The result was that the config path was erroneously being set to the root / This specifically happened when downloading WordPress via `wp core download` See comment by @scribu: https://github.com/wp-cli/wp-cli/pull/362#issuecomment-15480546 --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index aa506acb22..2bbd33732e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -52,7 +52,7 @@ private static function load_config( $path, $spec ) { // When invoking from a subdirectory in the project, // make sure a config-relative 'path' is made absolute - if ( ! self::is_absolute_path( $sanitized_config['path'] ) ) { + if ( ! empty( $sanitized_config['path'] ) && ! self::is_absolute_path( $sanitized_config['path'] ) ) { $sanitized_config['path'] = dirname( $path ) . DIRECTORY_SEPARATOR . $sanitized_config['path']; } From e302d26feb78e43f013af89111bddfb7bb4eafc2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Mar 2013 04:24:31 +0200 Subject: [PATCH 1449/4858] deb-build: add sudo where appropriate see #368 --- utils/dev-build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/dev-build b/utils/dev-build index bffbaf168b..6583a472ce 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -3,7 +3,7 @@ # install Composer command -v composer > /dev/null || { curl -sS https://getcomposer.org/installer | php - mv composer.phar /usr/local/bin/composer + sudo mv composer.phar /usr/local/bin/composer } # install dependencies @@ -12,7 +12,7 @@ composer install # add symlink to wp binary for dir in /usr/bin /usr/local/bin; do if [ -d $dir ]; then - ln -sf $(pwd)/bin/wp $dir/wp + sudo ln -sf $(pwd)/bin/wp $dir/wp break fi done @@ -20,7 +20,7 @@ done # install bash completion file for dir in /etc/bash_completion.d /usr/local/etc/bash_completion.d; do if [ -d $dir ]; then - ln -sf $(pwd)/utils/wp-completion.bash $dir/wp + sudo ln -sf $(pwd)/utils/wp-completion.bash $dir/wp break fi done From 17b2315be9e9bf1d6e269bab23f81ec1f984dcde Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Mar 2013 04:54:23 +0200 Subject: [PATCH 1450/4858] use MYSQL_PWD env variable in FeatureContext->run_sql() --- features/bootstrap/FeatureContext.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index bf493384d9..d70fd2be59 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -103,8 +103,10 @@ public function download_file( $url, $path ) { } private static function run_sql( $sql ) { - system( \WP_CLI\Utils\create_cmd( 'mysql -u%s -p%s -e %s', - self::$db_settings['dbuser'], self::$db_settings['dbpass'], $sql ) ); + putenv( 'MYSQL_PWD=' . self::$db_settings['dbpass'] ); + + system( \WP_CLI\Utils\create_cmd( 'mysql -u%s -e %s', + self::$db_settings['dbuser'], $sql ) ); } public function create_db() { From 92957d18f966d6f0e14d0b314019d8a5b59bae3b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Mar 2013 07:22:19 +0200 Subject: [PATCH 1451/4858] add some functional tests for `wp db` --- features/db.feature | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 features/db.feature diff --git a/features/db.feature b/features/db.feature new file mode 100644 index 0000000000..1d440234e9 --- /dev/null +++ b/features/db.feature @@ -0,0 +1,32 @@ +Feature: Perform database operations + + Scenario: DB CRUD + Given an empty directory + And WP files + And wp-config.php + + When I run `wp db create` + Then it should run without errors + And STDOUT should not be empty + + When I run the previous command again + Then the return code should be 1 + + When I run `wp db reset --yes` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp db optimize` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp db repair` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp db query 'SELECT 42 FROM dual'` + Then it should run without errors + And STDOUT should contain: + """ + 42 + """ From f4efbe8e29e7d1413ea65ba9549b9f12a888da4b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Mar 2013 07:22:53 +0200 Subject: [PATCH 1452/4858] use MYSQL_PWD env variable, instead of passing the password as a CLI arg --- php/commands/db.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index f304902d4f..5f8d531230 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -65,8 +65,8 @@ function reset( $_, $assoc_args ) { */ function optimize( $_, $assoc_args ) { self::run( $assoc_args, \WP_CLI\Utils\create_cmd( - 'mysqlcheck --optimize --host=%s --user=%s --password=%s %s', - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + 'mysqlcheck --optimize --host=%s --user=%s %s', + DB_HOST, DB_USER, DB_NAME ) ); WP_CLI::success( "Database optimized." ); @@ -79,8 +79,8 @@ function optimize( $_, $assoc_args ) { */ function repair( $_, $assoc_args ) { self::run( $assoc_args, \WP_CLI\Utils\create_cmd( - 'mysqlcheck --repair --host=%s --user=%s --password=%s %s', - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME + 'mysqlcheck --repair --host=%s --user=%s %s', + DB_HOST, DB_USER, DB_NAME ) ); WP_CLI::success( "Database repaired." ); @@ -119,8 +119,8 @@ function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); self::run( $assoc_args, \WP_CLI\Utils\create_cmd( - 'mysqldump %s --user=%s --password=%s --host=%s --result-file %s', - DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ) ); + 'mysqldump %s --user=%s --host=%s --result-file %s', + DB_NAME, DB_USER, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } @@ -134,15 +134,15 @@ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); self::run( $assoc_args, \WP_CLI\Utils\create_cmd( - 'mysql %s --user=%s --password=%s --host=%s < %s', - DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, $result_file ) ); + 'mysql %s --user=%s --host=%s < %s', + DB_NAME, DB_USER, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } private function connect_string() { - return \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --password=%s --database=%s', - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME ); + return \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --database=%s', + DB_HOST, DB_USER, DB_NAME ); } private function get_file_name( $args ) { @@ -154,8 +154,8 @@ private function get_file_name( $args ) { private static function create_execute_cmd( $execute_statement ) { return \WP_CLI\Utils\create_cmd( - 'mysql --host=%s --user=%s --password=%s --execute=%s', - DB_HOST, DB_USER, DB_PASSWORD, $execute_statement + 'mysql --host=%s --user=%s --execute=%s', + DB_HOST, DB_USER, $execute_statement ); } @@ -165,7 +165,11 @@ private static function run( $assoc_args, $cmd ) { exit; } + $old_val = getenv( 'MYSQL_PWD' ); + + putenv( 'MYSQL_PWD=' . DB_PASSWORD ); WP_CLI::launch( $cmd ); + putenv( 'MYSQL_PWD=' . $old_val ); } } From 7287e1603f34317e276fecbd76e476f2f381af4d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Mar 2013 07:39:04 +0200 Subject: [PATCH 1453/4858] bump version to 0.9.1-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index e7afedfca8..0582ca428a 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.0' ); +define( 'WP_CLI_VERSION', '0.9.1-alpha' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 6aefeaaa84a47f7eaabd396ec93239d6f140dc04 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Sat, 30 Mar 2013 00:53:28 -0700 Subject: [PATCH 1454/4858] handle edge case finding wp-cli.yml in nested subdirectory installs See comment by @scribu: https://github.com/wp-cli/wp-cli/pull/362#issuecomment-15506011 --- php/WP_CLI/Runner.php | 11 ++++++++++- php/utils.php | 10 ++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 2bbd33732e..4c58871ad4 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -27,7 +27,16 @@ private static function get_config_path( &$assoc_args ) { 'wp-cli.local.yml', 'wp-cli.yml' ); - $path = Utils\find_file_upward( $config_files, getcwd() ); + // Stop looking upward when we find we have emerged from a subdirectory install into a parent install + $stop_check = function ( $dir ) { + static $wp_load_count = 0; + $wp_load_path = $dir . DIRECTORY_SEPARATOR . 'wp-load.php'; + if ( file_exists( $wp_load_path ) ) { + $wp_load_count += 1; + } + return $wp_load_count > 1; + }; + $path = Utils\find_file_upward( $config_files, getcwd(), $stop_check ); if ( $path ) { return $path; } diff --git a/php/utils.php b/php/utils.php index 6898e71762..eeb6f000b1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -49,17 +49,23 @@ function get_config_spec() { } /** - * Search for file by walking up the directory tree until the first file is found + * Search for file by walking up the directory tree until the first file is found or until $stop_check($dir) returns true * @param string|array The files (or file) to search for * @param string|null The directory to start searching from; defaults to CWD + * @param callable Function which is passed the current dir each time a directory level is traversed * @return null|string Null if the file was not found */ -function find_file_upward($files, $dir = null) { +function find_file_upward( $files, $dir = null, $stop_check = null ) { $files = (array) $files; if ( is_null( $dir ) ) { $dir = getcwd(); } while ( is_readable( $dir ) ) { + // Stop walking up when the supplied callable returns true being passed the $dir + if ( is_callable( $stop_check ) && call_user_func( $stop_check, $dir ) ) { + return null; + } + foreach ( $files as $file ) { $path = $dir . DIRECTORY_SEPARATOR . $file; if ( file_exists( $path ) ) { From f908a276889830cf2dd001b5a79002aa045d977b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Mar 2013 16:05:26 +0200 Subject: [PATCH 1455/4858] use slug as theme name. closes #372 --- php/commands/theme.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 70d8dad2ed..9e8ad5aff0 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -126,11 +126,11 @@ protected function install_from_repo( $slug, $assoc_args ) { protected function get_item_list() { $items = array(); - foreach ( wp_get_themes() as $theme ) { + foreach ( wp_get_themes() as $key => $theme ) { $file = $theme->get_stylesheet_directory(); $items[ $file ] = array( - 'name' => $theme->get('Name'), + 'name' => $key, 'status' => $this->get_status( $theme ), 'update' => $this->has_update( $theme->get_stylesheet() ), 'update_id' => $theme->get_stylesheet(), From 8f4a74d0ef21898a38912e6601fa024866bbd4df Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Mar 2013 16:34:19 +0200 Subject: [PATCH 1456/4858] set version to 0.9.1 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 0582ca428a..1a15556f61 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.1-alpha' ); +define( 'WP_CLI_VERSION', '0.9.1' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From a7906691d4089013202f2332706de3e31e24add9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Mar 2013 16:59:09 +0200 Subject: [PATCH 1457/4858] update-phar: OSX doesn't ship with md5sum, so use md5 -r --- utils/update-phar | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/utils/update-phar b/utils/update-phar index e7cf98c223..ea79bf1129 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -30,7 +30,14 @@ if [ "$new_commit_subj" = "$current_commit_subj" ]; then fi # generate md5 checksum -md5sum $fname | cut -d ' ' -f 1 > $fname.md5 +if [ command -v md5sum > /dev/null ] +then + md5hash=$(md5sum $fname) +else + md5hash=$(md5 -r $fname) +fi + +echo $md5hash | cut -d ' ' -f 1 > $fname.md5 git add $fname $fname.md5 From ff9db7e61b5d78dd8a19659ec6b1aca00e71d0b7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Mar 2013 17:07:01 +0200 Subject: [PATCH 1458/4858] manpages: check for ronn executable before doing anything --- php/WP_CLI/InternalAssoc.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/WP_CLI/InternalAssoc.php b/php/WP_CLI/InternalAssoc.php index 6ceae0b099..661d282f45 100644 --- a/php/WP_CLI/InternalAssoc.php +++ b/php/WP_CLI/InternalAssoc.php @@ -57,6 +57,10 @@ static function completions() { } static function man( $args ) { + if ( '' === exec( 'which ronn' ) ) { + WP_CLI::error( '`ronn` executable not found.' ); + } + $arg_copy = $args; $command = WP_CLI::$root; From 9492829660e320b7c80c3391713711da24d81fef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Mar 2013 17:12:19 +0200 Subject: [PATCH 1459/4858] document --force parameter for wp core download --- man-src/core-download.txt | 4 ++++ man/core-download.1 | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/man-src/core-download.txt b/man-src/core-download.txt index 6b85fc3afc..74448c9860 100644 --- a/man-src/core-download.txt +++ b/man-src/core-download.txt @@ -9,6 +9,10 @@ ignored in this case. Select which version you want to download. +* `--force`: + + Overwrites existing files, if present. + ## EXAMPLES Download version 3.3: wp core download --version=3.3 diff --git a/man/core-download.1 b/man/core-download.1 index 956e22cdc5..7f2725d56f 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -23,6 +23,12 @@ Select which language you want to download\. The \-\-version parameter is ignore .IP Select which version you want to download\. . +.TP +\fB\-\-force\fR: +. +.IP +Overwrites existing files, if present\. +. .SH "EXAMPLES" . .nf From 82af1db8fb3b81c1f31b892f1a8b1eb6fc4b41c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Mar 2013 20:17:06 +0200 Subject: [PATCH 1460/4858] add tests for running commands from a subdirectory see #362 --- features/config.feature | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/features/config.feature b/features/config.feature index 7d3f51b29a..9bb174d7d2 100644 --- a/features/config.feature +++ b/features/config.feature @@ -2,8 +2,6 @@ Feature: Have a config file Scenario: No config file Given a WP install - """ - """ When I run `wp --info` Then it should run without errors @@ -12,6 +10,10 @@ Feature: Have a config file wp-cli.yml """ + When I run `wp core is-installed` from 'wp-content' + Then it should run without errors + And STDOUT should be empty + Scenario: Config file in WP Root Given a WP install And a wp-cli.yml file: @@ -25,6 +27,10 @@ Feature: Have a config file wp-cli.yml """ + When I run `wp core is-installed` + Then it should run without errors + And STDOUT should be empty + Scenario: WP in a subdirectory Given a WP install in 'core' And a wp-cli.yml file: @@ -32,6 +38,31 @@ Feature: Have a config file path: core """ - When I run `wp core version` + When I run `wp --info` + Then it should run without errors + And STDOUT should contain: + """ + wp-cli.yml + """ + + When I run `wp core is-installed` Then it should run without errors - And STDOUT should not be empty + And STDOUT should be empty + + When I run `wp core is-installed` from 'core/wp-content' + Then it should run without errors + And STDOUT should be empty + + Scenario: Nested installs + Given a WP install + And a WP install in 'subsite' + And a wp-cli.yml file: + """ + """ + + When I run `wp info` from 'subsite' + And STDOUT should not contain: + """ + wp-cli.yml + """ + From 4b7060d85970761ef519d70f2dc63fafab8e8036 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Mar 2013 19:38:19 +0200 Subject: [PATCH 1461/4858] bump version to 0.10.0-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 1a15556f61..a3bc6cd67d 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.9.1' ); +define( 'WP_CLI_VERSION', '0.10.0-alpha' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 655cb3334b367f5090a05f0dbebeac27f1abf5f9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 4 Apr 2013 00:10:14 +0300 Subject: [PATCH 1462/4858] add 'history' command --- php/commands/shell.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 2cdcecbedf..3f0eac005e 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -13,8 +13,16 @@ public function __invoke() { while ( true ) { $line = self::prompt(); - if ( '' === $line ) - continue; + switch ( $line ) { + case '': { + continue 2; + } + + case 'history': { + self::print_history(); + continue 2; + } + } $line = rtrim( $line, ';' ) . ';'; @@ -79,6 +87,24 @@ private static function create_prompt_cmd( $prompt, $history_path ) { return '/bin/bash -c ' . escapeshellarg( $cmd ); } + private static function print_history() { + $history_file = self::get_history_path(); + + if ( !is_readable( $history_file ) ) + return; + + $lines = array_filter( explode( "\n", file_get_contents( $history_file ) ) ); + + foreach ( $lines as $line ) { + if ( 'history' == $line ) + continue; + + $line = rtrim( $line, ';' ) . ';'; + + echo "$line\n"; + } + } + private static function get_history_path() { $data = getcwd() . get_current_user(); From 1528767a367c1fc12b4934b779243eec457b3a55 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 4 Apr 2013 01:41:23 +0300 Subject: [PATCH 1463/4858] add man page for `wp shell` --- man-src/shell.txt | 5 +++++ man/shell.1 | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 man-src/shell.txt create mode 100644 man/shell.1 diff --git a/man-src/shell.txt b/man-src/shell.txt new file mode 100644 index 0000000000..ccd56f4937 --- /dev/null +++ b/man-src/shell.txt @@ -0,0 +1,5 @@ +## DESCRIPTION + +`wp shell` allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example. + +If you type `history` and hit Return, WP-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file. diff --git a/man/shell.1 b/man/shell.1 new file mode 100644 index 0000000000..de0e717e1f --- /dev/null +++ b/man/shell.1 @@ -0,0 +1,16 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SHELL" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-shell\fR \- Interactive PHP console\. +. +.SH "SYNOPSIS" +wp shell +. +.SH "DESCRIPTION" +\fBwp shell\fR allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment\. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example\. +. +.P +If you type \fBhistory\fR and hit Return, WP\-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file\. From 274f1e26e1d4b9b62ddf7bec4094ba642d5284a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 4 Apr 2013 01:54:56 +0300 Subject: [PATCH 1464/4858] compute the history file path at the beginning this avoids problems if the user calls chdir() --- php/commands/shell.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 3f0eac005e..fd32cb6ec3 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -10,8 +10,10 @@ class Shell_Command extends \WP_CLI_Command { public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); + $this->set_history_file(); + while ( true ) { - $line = self::prompt(); + $line = $this->prompt(); switch ( $line ) { case '': { @@ -49,11 +51,11 @@ private static function non_expressions() { ) ); } - private static function prompt() { + private function prompt() { static $cmd; if ( !$cmd ) { - $cmd = self::create_prompt_cmd( 'wp> ', self::get_history_path() ); + $cmd = self::create_prompt_cmd( 'wp> ', $this->history_file ); } $fp = popen( $cmd, 'r' ); @@ -87,13 +89,11 @@ private static function create_prompt_cmd( $prompt, $history_path ) { return '/bin/bash -c ' . escapeshellarg( $cmd ); } - private static function print_history() { - $history_file = self::get_history_path(); - - if ( !is_readable( $history_file ) ) + private function print_history() { + if ( !is_readable( $this->history_file ) ) return; - $lines = array_filter( explode( "\n", file_get_contents( $history_file ) ) ); + $lines = array_filter( explode( "\n", file_get_contents( $this->history_file ) ) ); foreach ( $lines as $line ) { if ( 'history' == $line ) @@ -105,10 +105,10 @@ private static function print_history() { } } - private static function get_history_path() { + private function set_history_file() { $data = getcwd() . get_current_user(); - return sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); + $this->history_file = sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); } private static function starts_with( $tokens, $line ) { From 24e45edc6d33385a08ae75349b5050c20d5ef19b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 4 Apr 2013 04:29:14 +0300 Subject: [PATCH 1465/4858] remove --str flag from db subcommands The --str flag assumes that all the information will be passed as CLI arguments, but that's no longer the case since we started using the MYSQL_PWD env variable. And we might want to start using the PDO extension in the future, instead of the `mysql` binary. Also introduce run_mysql_query() utility. --- php/commands/db.php | 104 +++++++++++++++++--------------------------- php/utils.php | 14 ++++++ 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 5f8d531230..ad5be78be1 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -10,12 +10,10 @@ class DB_Command extends WP_CLI_Command { /** * Create the database, as specified in wp-config.php * - * @synopsis [--str] + * @synopsis */ function create( $_, $assoc_args ) { - self::run( $assoc_args, self::create_execute_cmd( - sprintf( 'CREATE DATABASE `%s`', DB_NAME ) - ) ); + self::run_query( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); WP_CLI::success( "Database created." ); } @@ -23,48 +21,37 @@ function create( $_, $assoc_args ) { /** * Delete the database. * - * @synopsis [--yes] [--str] + * @synopsis [--yes] */ function drop( $_, $assoc_args ) { - $command = self::create_execute_cmd( sprintf( 'DROP DATABASE `%s`', DB_NAME ) ); - - if ( !isset( $assoc_args['str'] ) ) { - WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); - WP_CLI::launch( $command ); - WP_CLI::success( "Database dropped." ); - } else { - WP_CLI::line( $command ); - } + WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); + + self::run_query( sprintf( 'DROP DATABASE `%s`', DB_NAME ) ); + + WP_CLI::success( "Database dropped." ); } /** * Remove all tables from the database. * - * @synopsis [--yes] [--str] + * @synopsis [--yes] */ function reset( $_, $assoc_args ) { - $drop_cmd = self::create_execute_cmd( sprintf( 'DROP DATABASE IF EXISTS `%s`', DB_NAME ) ); - - $create_cmd = self::create_execute_cmd( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); - - if ( !isset( $assoc_args['str'] ) ) { - WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); - WP_CLI::launch( $drop_cmd ); - WP_CLI::launch( $create_cmd ); - WP_CLI::success( "Database reset." ); - } else { - WP_CLI::line( $drop_cmd ); - WP_CLI::line( $create_cmd ); - } + WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); + + self::run_query( sprintf( 'DROP DATABASE IF EXISTS `%s`', DB_NAME ) ); + self::run_query( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); + + WP_CLI::success( "Database reset." ); } /** * Optimize the database. * - * @synopsis [--str] + * @synopsis */ - function optimize( $_, $assoc_args ) { - self::run( $assoc_args, \WP_CLI\Utils\create_cmd( + function optimize() { + self::run( \WP_CLI\Utils\create_cmd( 'mysqlcheck --optimize --host=%s --user=%s %s', DB_HOST, DB_USER, DB_NAME ) ); @@ -75,13 +62,12 @@ function optimize( $_, $assoc_args ) { /** * Repair the database. * - * @synopsis [--str] + * @synopsis */ - function repair( $_, $assoc_args ) { - self::run( $assoc_args, \WP_CLI\Utils\create_cmd( + function repair() { + self::run( \WP_CLI\Utils\create_cmd( 'mysqlcheck --repair --host=%s --user=%s %s', - DB_HOST, DB_USER, DB_NAME - ) ); + DB_HOST, DB_USER, DB_NAME ) ); WP_CLI::success( "Database repaired." ); } @@ -91,34 +77,35 @@ function repair( $_, $assoc_args ) { * * @alias cli * - * @synopsis [--str] + * @synopsis */ - function connect( $_, $assoc_args ) { - self::run( $assoc_args, $this->connect_string() ); + function connect() { + self::run( \WP_CLI\Utils\create_cmd( + 'mysql --host=%s --user=%s --database=%s', + DB_HOST, DB_USER, DB_NAME ) ); } /** * Execute a query against the database. * - * @synopsis <sql> [--str] + * @synopsis <sql> */ - function query( $args, $assoc_args ) { + function query( $args ) { list( $query ) = $args; - self::run( $assoc_args, $this->connect_string() . \WP_CLI\Utils\create_cmd( - ' --execute=%s', $query ) ); + self::run_query( $query ); } /** * Exports the database using mysqldump. * * @alias dump - * @synopsis [<file>] [--str] + * @synopsis [<file>] */ function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( $assoc_args, \WP_CLI\Utils\create_cmd( + self::run( \WP_CLI\Utils\create_cmd( 'mysqldump %s --user=%s --host=%s --result-file %s', DB_NAME, DB_USER, DB_HOST, $result_file ) ); @@ -128,23 +115,18 @@ function export( $args, $assoc_args ) { /** * Import database from a file. * - * @synopsis [<file>] [--str] + * @synopsis [<file>] */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( $assoc_args, \WP_CLI\Utils\create_cmd( + self::run( \WP_CLI\Utils\create_cmd( 'mysql %s --user=%s --host=%s < %s', DB_NAME, DB_USER, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } - private function connect_string() { - return \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --database=%s', - DB_HOST, DB_USER, DB_NAME ); - } - private function get_file_name( $args ) { if ( empty( $args ) ) return sprintf( '%s.sql', DB_NAME ); @@ -152,19 +134,15 @@ private function get_file_name( $args ) { return $args[0]; } - private static function create_execute_cmd( $execute_statement ) { - return \WP_CLI\Utils\create_cmd( - 'mysql --host=%s --user=%s --execute=%s', - DB_HOST, DB_USER, $execute_statement - ); + private static function run_query( $query ) { + return \WP_CLI\Utils\run_mysql_query( $query, array( + 'host' => DB_HOST, + 'user' => DB_USER, + 'pass' => DB_PASSWORD, + ) ); } - private static function run( $assoc_args, $cmd ) { - if ( isset( $assoc_args['str'] ) ) { - WP_CLI::line( $cmd ); - exit; - } - + private static function run( $cmd ) { $old_val = getenv( 'MYSQL_PWD' ); putenv( 'MYSQL_PWD=' . DB_PASSWORD ); diff --git a/php/utils.php b/php/utils.php index eeb6f000b1..c54e15e6d1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -362,3 +362,17 @@ function find_subcommand( $args ) { return $command; } +function run_mysql_query( $query, $args, $dry_run = false ) { + // TODO: use PDO? + + $cmd = \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --execute=%s', + $args['host'], $args['user'], $query + ); + + $old_val = getenv( 'MYSQL_PWD' ); + + putenv( 'MYSQL_PWD=' . $args['pass'] ); + \WP_CLI::launch( $cmd ); + putenv( 'MYSQL_PWD=' . $old_val ); +} + From 624510a6c0774a26f659ee0e28d2f300025256ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 4 Apr 2013 04:38:22 +0300 Subject: [PATCH 1466/4858] create tests database if it doesn't exist --- php/commands/core.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 85a4bcf5e5..3e65fccf81 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -308,15 +308,30 @@ function init_tests( $args, $assoc_args ) { else $tests_dir = ABSPATH . 'unit-tests/'; + $assoc_args = wp_parse_args( $assoc_args, array( + 'dbpass' => '', + ) ); + + // Download the test suite WP_CLI::launch( 'svn co https://unit-test.svn.wordpress.org/trunk/ ' . escapeshellarg( $tests_dir ) ); + // Create the database + $query = sprintf( 'CREATE DATABASE IF NOT EXISTS `%s`', $assoc_args['dbname'] ); + + \WP_CLI\Utils\run_mysql_query( $query, array( + 'host' => 'localhost', + 'user' => $assoc_args['dbuser'], + 'pass' => $assoc_args['dbpass'], + ) ); + + // Create the wp-tests-config.php file $config_file = file_get_contents( $tests_dir . 'wp-tests-config-sample.php' ); $replacements = array( "dirname( __FILE__ ) . '/wordpress/'" => "'" . ABSPATH . "'", "yourdbnamehere" => $assoc_args['dbname'], "yourusernamehere" => $assoc_args['dbuser'], - "yourpasswordhere" => isset( $assoc_args['dbpass'] ) ? $assoc_args['dbpass'] : '' + "yourpasswordhere" => $assoc_args['dbpass'], ); $config_file = str_replace( array_keys( $replacements ), array_values( $replacements ), $config_file ); From 8dab261b415f928ac5e631d03e36f7dad646d87e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 4 Apr 2013 05:13:56 +0300 Subject: [PATCH 1467/4858] update db man page --- man-src/db.txt | 4 ---- man/db.1 | 18 +++++++++--------- php/commands/db.php | 9 +-------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/man-src/db.txt b/man-src/db.txt index f160ad01a3..e60509350b 100644 --- a/man-src/db.txt +++ b/man-src/db.txt @@ -1,9 +1,5 @@ ## OPTIONS -* `--str`: - - Show the mysql command, instead of executing it. - * `--yes`: Answer yes to the confirmation message. diff --git a/man/db.1 b/man/db.1 index 319076f6e0..99983e2d34 100644 --- a/man/db.1 +++ b/man/db.1 @@ -7,31 +7,31 @@ \fBwp\-db\fR \- Perform basic database operations\. . .SH "SYNOPSIS" -wp db create [\-\-str] +wp db create . .P -wp db drop [\-\-yes] [\-\-str] +wp db drop [\-\-yes] . .P -wp db reset [\-\-yes] [\-\-str] +wp db reset [\-\-yes] . .P -wp db optimize [\-\-str] +wp db optimize . .P -wp db repair [\-\-str] +wp db repair . .P -wp db connect [\-\-str] +wp db connect . .P -wp db query \fIsql\fR [\-\-str] +wp db query \fIsql\fR . .P -wp db export [\fIfile\fR] [\-\-str] +wp db export [\fIfile\fR] . .P -wp db import [\fIfile\fR] [\-\-str] +wp db import [\fIfile\fR] . .SH "SUBCOMMANDS" . diff --git a/php/commands/db.php b/php/commands/db.php index ad5be78be1..fbcf636aac 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -9,8 +9,6 @@ class DB_Command extends WP_CLI_Command { /** * Create the database, as specified in wp-config.php - * - * @synopsis */ function create( $_, $assoc_args ) { self::run_query( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); @@ -47,8 +45,6 @@ function reset( $_, $assoc_args ) { /** * Optimize the database. - * - * @synopsis */ function optimize() { self::run( \WP_CLI\Utils\create_cmd( @@ -61,8 +57,6 @@ function optimize() { /** * Repair the database. - * - * @synopsis */ function repair() { self::run( \WP_CLI\Utils\create_cmd( @@ -76,8 +70,6 @@ function repair() { * Open a mysql console using the WordPress credentials. * * @alias cli - * - * @synopsis */ function connect() { self::run( \WP_CLI\Utils\create_cmd( @@ -100,6 +92,7 @@ function query( $args ) { * Exports the database using mysqldump. * * @alias dump + * * @synopsis [<file>] */ function export( $args, $assoc_args ) { From 5f6db53478f7e462dd189e349e99a6f4b4d95828 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 4 Apr 2013 23:51:02 +0200 Subject: [PATCH 1468/4858] Added label scaffold behat test --- features/scaffold.feature | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 features/scaffold.feature diff --git a/features/scaffold.feature b/features/scaffold.feature new file mode 100644 index 0000000000..4a041b95cc --- /dev/null +++ b/features/scaffold.feature @@ -0,0 +1,22 @@ +Feature: Wordpress code scaffolding + + @Custom Post Types + Scenario: Scaffold a Custom Post Type with label + Given a WP install + + When I run `wp scaffold post-type zombie --label="Brain eater"` + Then it should run without errors + And STDOUT should contain: + """ + __( 'Brain eaters' + """ + + Scenario: Scaffold a Custom Post Type without the label flag + Given a WP install + + When I run `wp scaffold post-type zombie` + Then it should run without errors + And STDOUT should contain: + """ + __( 'Zombies' + """ \ No newline at end of file From a8ea75807ab01e01a558eedd2e0771f45fc91ecc Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 4 Apr 2013 23:54:12 +0200 Subject: [PATCH 1469/4858] Reorder tests --- features/scaffold.feature | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 4a041b95cc..0ced7c3ea2 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,6 +1,16 @@ Feature: Wordpress code scaffolding @Custom Post Types + Scenario: Scaffold a Custom Post Type + Given a WP install + + When I run `wp scaffold post-type zombie` + Then it should run without errors + And STDOUT should contain: + """ + __( 'Zombies' + """ + Scenario: Scaffold a Custom Post Type with label Given a WP install @@ -9,14 +19,4 @@ Feature: Wordpress code scaffolding And STDOUT should contain: """ __( 'Brain eaters' - """ - - Scenario: Scaffold a Custom Post Type without the label flag - Given a WP install - - When I run `wp scaffold post-type zombie` - Then it should run without errors - And STDOUT should contain: - """ - __( 'Zombies' - """ \ No newline at end of file + """ \ No newline at end of file From b35b4ef5540e86f53c9590dd3fe7e04e3364e60e Mon Sep 17 00:00:00 2001 From: John Lamp <j3lamp@gmail.com> Date: Thu, 4 Apr 2013 22:26:36 -0400 Subject: [PATCH 1470/4858] Added `post get` command. --- features/post.feature | 15 +++++++++++++++ man-src/post-get.txt | 18 ++++++++++++++++++ man/post-get.1 | 38 ++++++++++++++++++++++++++++++++++++++ php/commands/post.php | 23 ++++++++++++++++++++++- 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 man-src/post-get.txt create mode 100644 man/post-get.1 diff --git a/features/post.feature b/features/post.feature index af7999f42a..5fb6dd22dc 100644 --- a/features/post.feature +++ b/features/post.feature @@ -27,3 +27,18 @@ Feature: Manage WordPress posts When I run the previous command again Then the return code should be 1 + + Scenario: Creating/geting posts + Given a WP install + + When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` + Then it should run without errors + And STDOUT should match '%d' + And save STDOUT as {POST_ID} + + When I run `wp post get {POST_ID} -` + Then it should run without errors + And STDOUT should be: + """ + Test content. + """ diff --git a/man-src/post-get.txt b/man-src/post-get.txt new file mode 100644 index 0000000000..0df8d89526 --- /dev/null +++ b/man-src/post-get.txt @@ -0,0 +1,18 @@ +## OPTIONS + +* `<id>`: + + The ID of the post to get. + +* `<filename>`: + + Write post content to <filename>. + + Passing `-` as the filename will cause post content to + be written to STDOUT. + +## EXAMPLES + + wp post get 12 - + + wp post get 12 file.txt diff --git a/man/post-get.1 b/man/post-get.1 new file mode 100644 index 0000000000..0261db57a8 --- /dev/null +++ b/man/post-get.1 @@ -0,0 +1,38 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-POST\-GET" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-post\-get\fR \- Get a post\'s content by ID\. +. +.SH "SYNOPSIS" +wp post get \fIid\fR \fIfilename\fR +. +.SH "OPTIONS" +. +.TP +\fB<id>\fR: +. +.IP +The ID of the post to get\. +. +.TP +\fB<filename>\fR: +. +.IP +Write post content to \fIfilename\fR\. +. +.IP +Passing \fB\-\fR as the filename will cause post content to be written to STDOUT\. +. +.SH "EXAMPLES" +. +.nf + +wp post get 12 \- + +wp post get 12 file\.txt +. +.fi + diff --git a/php/commands/post.php b/php/commands/post.php index 028afbce0b..ff25bce90f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -79,6 +79,28 @@ protected function _edit( $content, $title ) { return \WP_CLI\Utils\launch_editor_for_input( $content, $title ); } + /** + * Get a post's content by ID. + * + * @synopsis <id> <filename> + */ + public function get( $args, $_ ) { + $post_id = $args[0]; + if ( !$post_id || !$post = get_post( $post_id ) ) + \WP_CLI::error( "Failed opening post $post_id to get." ); + + if ( $args[1] !== '-' ) { + $writefile = $args[1]; + if ( ! file_exists( $writefile ) || ! is_file( $writefile ) ) + \WP_CLI::error( "Unable to write content to $writefile." ); + } else + $writefile = 'php://stdout'; + + $r = file_put_contents( $writefile, $post->post_content ); + if ( $r === false ) + \WP_CLI::error( "Failed to write content to $writefile." ); + } + /** * Delete a post by ID. * @@ -241,4 +263,3 @@ private function maybe_reset_depth() { } WP_CLI::add_command( 'post', 'Post_Command' ); - From df325ba4790eff06d727b23510e3ae2ca3af9512 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Fri, 5 Apr 2013 12:27:45 +0200 Subject: [PATCH 1471/4858] Removed feature tag --- features/scaffold.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 0ced7c3ea2..5c966f080d 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,6 +1,5 @@ Feature: Wordpress code scaffolding - @Custom Post Types Scenario: Scaffold a Custom Post Type Given a WP install From 0bcaa756c60e55dc04ff42e09461ad3540325952 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 5 Apr 2013 21:21:20 +0300 Subject: [PATCH 1472/4858] add --defaults-file=/dev/null to mysql commands --- php/commands/db.php | 33 ++++++++++++++++----------------- php/utils.php | 17 +++++++++++------ 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index fbcf636aac..300b82740b 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -1,5 +1,7 @@ <?php +use \WP_CLI\Utils; + /** * Perform basic database operations. * @@ -47,8 +49,8 @@ function reset( $_, $assoc_args ) { * Optimize the database. */ function optimize() { - self::run( \WP_CLI\Utils\create_cmd( - 'mysqlcheck --optimize --host=%s --user=%s %s', + self::run( 'mysqlcheck', Utils\create_cmd( + '--optimize --host=%s --user=%s %s', DB_HOST, DB_USER, DB_NAME ) ); @@ -59,8 +61,8 @@ function optimize() { * Repair the database. */ function repair() { - self::run( \WP_CLI\Utils\create_cmd( - 'mysqlcheck --repair --host=%s --user=%s %s', + self::run( 'mysqlcheck', Utils\create_cmd( + '--repair --host=%s --user=%s %s', DB_HOST, DB_USER, DB_NAME ) ); WP_CLI::success( "Database repaired." ); @@ -72,8 +74,8 @@ function repair() { * @alias cli */ function connect() { - self::run( \WP_CLI\Utils\create_cmd( - 'mysql --host=%s --user=%s --database=%s', + self::run( 'mysql', Utils\create_cmd( + '--host=%s --user=%s --database=%s', DB_HOST, DB_USER, DB_NAME ) ); } @@ -98,8 +100,8 @@ function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( \WP_CLI\Utils\create_cmd( - 'mysqldump %s --user=%s --host=%s --result-file %s', + self::run( 'mysqldump', Utils\create_cmd( + '%s --user=%s --host=%s --result-file %s', DB_NAME, DB_USER, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); @@ -113,8 +115,8 @@ function export( $args, $assoc_args ) { function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( \WP_CLI\Utils\create_cmd( - 'mysql %s --user=%s --host=%s < %s', + self::run( 'mysql', Utils\create_cmd( + '%s --user=%s --host=%s < %s', DB_NAME, DB_USER, DB_HOST, $result_file ) ); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); @@ -128,20 +130,17 @@ private function get_file_name( $args ) { } private static function run_query( $query ) { - return \WP_CLI\Utils\run_mysql_query( $query, array( + Utils\run_mysql_query( $query, array( 'host' => DB_HOST, 'user' => DB_USER, 'pass' => DB_PASSWORD, ) ); } - private static function run( $cmd ) { - $old_val = getenv( 'MYSQL_PWD' ); - - putenv( 'MYSQL_PWD=' . DB_PASSWORD ); - WP_CLI::launch( $cmd ); - putenv( 'MYSQL_PWD=' . $old_val ); + private static function run( $cmd, $args ) { + Utils\run_mysql_command( $cmd, $args, DB_PASSWORD ); } } WP_CLI::add_command( 'db', 'DB_Command' ); + diff --git a/php/utils.php b/php/utils.php index c54e15e6d1..73e89b9efd 100644 --- a/php/utils.php +++ b/php/utils.php @@ -362,17 +362,22 @@ function find_subcommand( $args ) { return $command; } -function run_mysql_query( $query, $args, $dry_run = false ) { +function run_mysql_query( $query, $args ) { // TODO: use PDO? - $cmd = \WP_CLI\Utils\create_cmd( 'mysql --host=%s --user=%s --execute=%s', - $args['host'], $args['user'], $query - ); + $arg_str = create_cmd( '--host=%s --user=%s --execute=%s', + $args['host'], $args['user'], $query ); + + run_mysql_command( 'mysql', $arg_str, $args['pass'] ); +} +function run_mysql_command( $cmd, $arg_str, $pass ) { $old_val = getenv( 'MYSQL_PWD' ); - putenv( 'MYSQL_PWD=' . $args['pass'] ); - \WP_CLI::launch( $cmd ); + $final_cmd = "$cmd --defaults-file=/dev/null $arg_str"; + + putenv( 'MYSQL_PWD=' . $pass ); + \WP_CLI::launch( $final_cmd ); putenv( 'MYSQL_PWD=' . $old_val ); } From 981542f3d8ca0f18fa8431252c7b1976487a13ce Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 5 Apr 2013 22:05:15 +0300 Subject: [PATCH 1473/4858] use run_mysql_query() in functional tests too --- features/bootstrap/FeatureContext.php | 19 +++++++++++-------- php/utils.php | 4 +++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d70fd2be59..07038d3e8e 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -5,6 +5,8 @@ Behat\Behat\Context\BehatContext, Behat\Behat\Event\SuiteEvent; +use \WP_CLI\Utils; + require_once 'PHPUnit/Framework/Assert/Functions.php'; require_once __DIR__ . '/../../php/utils.php'; @@ -92,21 +94,22 @@ public function get_cache_path( $file ) { if ( !$path ) { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - system( \WP_CLI\Utils\create_cmd( 'mkdir -p %s', $path ) ); + system( Utils\create_cmd( 'mkdir -p %s', $path ) ); } return $path . '/' . $file; } public function download_file( $url, $path ) { - system( \WP_CLI\Utils\create_cmd( 'curl -sSL %s > %s', $url, $path ) ); + system( Utils\create_cmd( 'curl -sSL %s > %s', $url, $path ) ); } private static function run_sql( $sql ) { - putenv( 'MYSQL_PWD=' . self::$db_settings['dbpass'] ); - - system( \WP_CLI\Utils\create_cmd( 'mysql -u%s -e %s', - self::$db_settings['dbuser'], $sql ) ); + Utils\run_mysql_query( $sql, array( + 'host' => 'localhost', + 'user' => self::$db_settings['dbuser'], + 'pass' => self::$db_settings['dbpass'], + ) ); } public function create_db() { @@ -121,7 +124,7 @@ public function drop_db() { private function _run( $command, $assoc_args, $subdir = '' ) { if ( !empty( $assoc_args ) ) - $command .= \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); + $command .= Utils\assoc_args_to_str( $assoc_args ); $subdir = $this->get_path( $subdir ); @@ -184,7 +187,7 @@ public function download_wordpress_files( $subdir = '' ) { if ( $subdir ) mkdir( $dest_dir ); - $cmd = \WP_CLI\Utils\create_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ); + $cmd = Utils\create_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ); system( $cmd ); } diff --git a/php/utils.php b/php/utils.php index 73e89b9efd..51f25b541d 100644 --- a/php/utils.php +++ b/php/utils.php @@ -377,7 +377,9 @@ function run_mysql_command( $cmd, $arg_str, $pass ) { $final_cmd = "$cmd --defaults-file=/dev/null $arg_str"; putenv( 'MYSQL_PWD=' . $pass ); - \WP_CLI::launch( $final_cmd ); + $r = proc_close( proc_open( $final_cmd, array( STDIN, STDOUT, STDERR ), $pipes ) ); putenv( 'MYSQL_PWD=' . $old_val ); + + if ( $r ) exit( $r ); } From d92d3bdf653aa2d128d1ce3a639fabda84b248eb Mon Sep 17 00:00:00 2001 From: John Lamp <j3lamp@gmail.com> Date: Fri, 5 Apr 2013 17:23:23 -0400 Subject: [PATCH 1474/4858] Removed the <filename> argument from `post get`. --- features/post.feature | 8 ++++---- man-src/post-get.txt | 11 ++--------- man/post-get.1 | 15 +++------------ php/commands/post.php | 13 ++----------- 4 files changed, 11 insertions(+), 36 deletions(-) diff --git a/features/post.feature b/features/post.feature index 5fb6dd22dc..874609063f 100644 --- a/features/post.feature +++ b/features/post.feature @@ -36,9 +36,9 @@ Feature: Manage WordPress posts And STDOUT should match '%d' And save STDOUT as {POST_ID} - When I run `wp post get {POST_ID} -` + When I run `wp post get {POST_ID}` Then it should run without errors And STDOUT should be: - """ - Test content. - """ + """ + Test content. + """ diff --git a/man-src/post-get.txt b/man-src/post-get.txt index 0df8d89526..38d10df7ce 100644 --- a/man-src/post-get.txt +++ b/man-src/post-get.txt @@ -4,15 +4,8 @@ The ID of the post to get. -* `<filename>`: - - Write post content to <filename>. - - Passing `-` as the filename will cause post content to - be written to STDOUT. - ## EXAMPLES - wp post get 12 - + wp post get 12 - wp post get 12 file.txt + wp post get 12 > file.txt diff --git a/man/post-get.1 b/man/post-get.1 index 0261db57a8..7666551432 100644 --- a/man/post-get.1 +++ b/man/post-get.1 @@ -7,7 +7,7 @@ \fBwp\-post\-get\fR \- Get a post\'s content by ID\. . .SH "SYNOPSIS" -wp post get \fIid\fR \fIfilename\fR +wp post get \fIid\fR . .SH "OPTIONS" . @@ -17,22 +17,13 @@ wp post get \fIid\fR \fIfilename\fR .IP The ID of the post to get\. . -.TP -\fB<filename>\fR: -. -.IP -Write post content to \fIfilename\fR\. -. -.IP -Passing \fB\-\fR as the filename will cause post content to be written to STDOUT\. -. .SH "EXAMPLES" . .nf -wp post get 12 \- +wp post get 12 -wp post get 12 file\.txt +wp post get 12 > file\.txt . .fi diff --git a/php/commands/post.php b/php/commands/post.php index ff25bce90f..e2bd934368 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -82,23 +82,14 @@ protected function _edit( $content, $title ) { /** * Get a post's content by ID. * - * @synopsis <id> <filename> + * @synopsis <id> */ public function get( $args, $_ ) { $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) \WP_CLI::error( "Failed opening post $post_id to get." ); - if ( $args[1] !== '-' ) { - $writefile = $args[1]; - if ( ! file_exists( $writefile ) || ! is_file( $writefile ) ) - \WP_CLI::error( "Unable to write content to $writefile." ); - } else - $writefile = 'php://stdout'; - - $r = file_put_contents( $writefile, $post->post_content ); - if ( $r === false ) - \WP_CLI::error( "Failed to write content to $writefile." ); + echo($post->post_content); } /** From e57c9ea38f243eefc1e17168f113bf960c63b17e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 9 Apr 2013 20:39:44 +0300 Subject: [PATCH 1475/4858] tests: add IF NOT EXISTS to create_db() --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 07038d3e8e..fd2fdf2d9f 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -114,7 +114,7 @@ private static function run_sql( $sql ) { public function create_db() { $dbname = self::$db_settings['dbname']; - self::run_sql( "CREATE DATABASE $dbname" ); + self::run_sql( "CREATE DATABASE IF NOT EXISTS $dbname" ); } public function drop_db() { From fbf53ad262f50f27cc55762d55e2c6bf8d630617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=20Burc=C4=83?= <scribu@gmail.com> Date: Fri, 12 Apr 2013 17:24:02 +0300 Subject: [PATCH 1476/4858] be more explicit about which code is covered by the MIT license --- LICENSE.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index bd624ddd0e..1b2b49c65b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,8 +1,8 @@ -======================================== -WP-CLI is licensed under the MIT License -======================================== +========================================================================================================= +All code in this repository, unless otherwise specified, is hereby licensed under the MIT Public License: +========================================================================================================= -Copyright (C) 2011-2012 WP-CLI Development Group (https://github.com/wp-cli/wp-cli/contributors) +Copyright (C) 2011-2013 WP-CLI Development Group (https://github.com/wp-cli/wp-cli/contributors) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From a134ce6e46561e9f36ee5efeb33e69ad97b97141 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 12 Apr 2013 08:59:13 -0700 Subject: [PATCH 1477/4858] Correct file permissions to 755 --- php/commands/scaffold.php | 0 php/wp-cli.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 php/commands/scaffold.php mode change 100644 => 100755 php/wp-cli.php diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php old mode 100644 new mode 100755 diff --git a/php/wp-cli.php b/php/wp-cli.php old mode 100644 new mode 100755 From ea6b75fa6fb7268e4abc1fa657837abc916c3a59 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 12 Apr 2013 09:47:39 -0700 Subject: [PATCH 1478/4858] Revert a134ce6e46561e9f36ee5efeb33e69ad97b97141 See https://github.com/wp-cli/wp-cli/commit/a134ce6e46561e9f36ee5efeb33e69ad97b97141#commitcomment-3001898 --- php/commands/scaffold.php | 0 php/wp-cli.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 php/commands/scaffold.php mode change 100755 => 100644 php/wp-cli.php diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php old mode 100755 new mode 100644 diff --git a/php/wp-cli.php b/php/wp-cli.php old mode 100755 new mode 100644 From 5aaaa1ab8dd6cf678514e38c8bf8f6234cf0b691 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 12 Apr 2013 10:06:16 -0700 Subject: [PATCH 1479/4858] Support for `--format` when using `wp post list` --- man-src/post-list.txt | 6 ++++++ man/post-list.1 | 10 +++++++++- php/commands/post.php | 26 +++++++++++++++----------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/man-src/post-list.txt b/man-src/post-list.txt index 295f102c0f..ad67863679 100644 --- a/man-src/post-list.txt +++ b/man-src/post-list.txt @@ -8,8 +8,14 @@ Return only the IDs of the found posts, separated by spaces. +* `--format`=<format>: + + Output list as table, CSV or JSON. Defaults to table. + ## EXAMPLES wp post list wp post list --post_type=page --post_status=draft --ids + + wp post list --post_type=post --posts_per_page=5 --format=json diff --git a/man/post-list.1 b/man/post-list.1 index 299c62aaa2..85a82be0e8 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -7,7 +7,7 @@ \fBwp\-post\-list\fR \- Get a list of posts\. . .SH "SYNOPSIS" -wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] +wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -23,6 +23,12 @@ One or more args to pass to WP_Query\. .IP Return only the IDs of the found posts, separated by spaces\. . +.TP +\fB\-\-format\fR=\fIformat\fR: +. +.IP +Output list as table, CSV or JSON\. Defaults to table\. +. .SH "EXAMPLES" . .nf @@ -30,6 +36,8 @@ Return only the IDs of the found posts, separated by spaces\. wp post list wp post list \-\-post_type=page \-\-post_status=draft \-\-ids + +wp post list \-\-post_type=post \-\-posts_per_page=5 \-\-format=json . .fi diff --git a/php/commands/post.php b/php/commands/post.php index 028afbce0b..645df962ef 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -108,13 +108,20 @@ protected function _delete( $post_id, $assoc_args ) { * Get a list of posts. * * @subcommand list - * @synopsis [--<field>=<value>] [--ids] + * @synopsis [--<field>=<value>] [--ids] [--format=<format>] */ public function _list( $_, $assoc_args ) { $query_args = array( 'posts_per_page' => -1 ); + if ( ! empty( $assoc_args['format'] ) ) { + $format = $assoc_args['format']; + unset( $assoc_args['format'] ); + } else { + $format = 'table'; + } + foreach ( $assoc_args as $key => $value ) { if ( true === $value ) continue; @@ -130,24 +137,21 @@ public function _list( $_, $assoc_args ) { if ( isset( $assoc_args['ids'] ) ) { WP_CLI::out( implode( ' ', $query->posts ) ); } else { - $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); - - $table = new \cli\Table(); - $table->setHeaders( $fields ); + $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); + $output_posts = array(); foreach ( $query->posts as $post ) { - $line = array(); + $output_post = new stdClass; foreach ( $fields as $field ) { - $line[] = $post->$field; + $output_post->$field = $post->$field; } - - $table->addRow( $line ); + $output_posts[] = $output_post; } - - $table->display(); + WP_CLI\Utils\format_items( $format, $fields, $output_posts ); } + } /** From b0c0f6f36f36fda11c13f68bfe364e2b5278833d Mon Sep 17 00:00:00 2001 From: Tim Brayshaw <tim@brayshaw.com> Date: Sat, 13 Apr 2013 00:10:15 +0100 Subject: [PATCH 1480/4858] Fix example for 'core is-installed' --- man-src/core-is-installed.txt | 2 +- man/core-is-installed.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/core-is-installed.txt b/man-src/core-is-installed.txt index 6432d0e669..e4901fe31d 100644 --- a/man-src/core-is-installed.txt +++ b/man-src/core-is-installed.txt @@ -1,5 +1,5 @@ ## EXAMPLES -if [ ! $(wp core is-installed) ]; then +if ! $(wp core is-installed); then wp core install fi diff --git a/man/core-is-installed.1 b/man/core-is-installed.1 index ac423ae11a..0aab8f72cc 100644 --- a/man/core-is-installed.1 +++ b/man/core-is-installed.1 @@ -10,7 +10,7 @@ wp core is\-installed . .SH "EXAMPLES" -if [ ! $(wp core is\-installed) ]; then +if ! $(wp core is\-installed); then . .IP "" 4 . From cfae9d7894891947492a4a9c61f8ee933d54c6b4 Mon Sep 17 00:00:00 2001 From: John Lamp <j3lamp@gmail.com> Date: Fri, 12 Apr 2013 21:21:33 -0400 Subject: [PATCH 1481/4858] Added the `--feature` option for `post get`. --- features/post.feature | 34 +++++++++++++++++++ features/steps/basic_steps.php | 60 ++++++++++++++++++++++++++++++++++ man-src/post-get.txt | 13 ++++++++ man/post-get.1 | 20 +++++++++++- php/commands/post.php | 57 ++++++++++++++++++++++++++------ 5 files changed, 173 insertions(+), 11 deletions(-) diff --git a/features/post.feature b/features/post.feature index 874609063f..74f6cd842d 100644 --- a/features/post.feature +++ b/features/post.feature @@ -42,3 +42,37 @@ Feature: Manage WordPress posts """ Test content. """ + + When I run `wp post get --format=content {POST_ID}` + Then it should run without errors + And STDOUT should be: + """ + Test content. + """ + + When I run `wp post get --format=table {POST_ID}` + Then it should run without errors + And STDOUT should be a table containing rows: + """ + Field Value + ID {POST_ID} + post_title Test post + post_content Test content. + """ + + When I run `wp post get --format=csv {POST_ID}` + Then it should run without errors + And STDOUT should be a table containing rows: + """ + Field,Value + ID,{POST_ID} + post_title,"Test post" + post_content,"Test content." + """ + + When I run `wp post get --format=json {POST_ID}` + Then it should run without errors + And STDOUT should be JSON containing: + """ + {"ID":{POST_ID},"post_title":"Test post","post_content":"Test content."} + """ diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 352bdb77a9..d6eb182e05 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -178,6 +178,41 @@ function ( $world, $stream, $format ) { } ); +$steps->Then( '/^STDOUT should be a table containing rows:$/', + function ( $world, PyStringNode $expected ) { + $output = $world->result->STDOUT; + $outputRows = explode( "\n", rtrim( $output, "\n" ) ); + + $expected = $world->replace_variables( (string) $expected ); + $expectedRows = explode( "\n", rtrim( $expected, "\n" ) ); + + // the first row is the header and must be present + if ( $expectedRows[0] != $outputRows[0] ) { + throw new \Exception( $output ); + } + + unset($outputRows[0]); + unset($expectedRows[0]); + $matches = array_intersect( $expectedRows, $outputRows ); + if ( count( $expectedRows ) != count( $matches ) ) { + throw new \Exception( $output ); + } + } +); + +$steps->Then( '/^STDOUT should be JSON containing:$/', + function ( $world, PyStringNode $expected ) { + $output = $world->result->STDOUT; + $outputJson = json_decode( $output ); + + $expected = $world->replace_variables( (string) $expected ); + $expectedJson = json_decode( $expected ); + + if ( !compareJson( $expectedJson, $outputJson ) ) { + throw new \Exception( $output ); + } +}); + $steps->Then( '/^(STDOUT|STDERR) should be empty$/', function ( $world, $stream ) { if ( !empty( $world->result->$stream ) ) { @@ -197,3 +232,28 @@ function ( $world, $path ) { assertFileExists( $world->get_path( $path ) ); } ); + + +function compareJson( $expected, $actual ) { + if ( gettype( $expected ) != gettype( $actual ) ) { + return false; + } + + if ( is_object( $expected ) ) { + foreach ( get_object_vars( $expected ) as $name => $value ) { + if ( !compareJson( $value, $actual->$name ) ) { + return false; + } + } + } else if ( is_array( $expected ) ) { + foreach ( $expected as $key => $value ) { + if ( !compareJson( $value, $actual[$key] ) ) { + return false; + } + } + } else { + return $expected === $actual; + } + + return true; +} diff --git a/man-src/post-get.txt b/man-src/post-get.txt index 38d10df7ce..ff20d1df9a 100644 --- a/man-src/post-get.txt +++ b/man-src/post-get.txt @@ -1,5 +1,18 @@ ## OPTIONS +* `[--format=<format>]`: + + The format to use when printing the post, acceptable values: + + content: outputs only the post's content (default) + + table: output all fields of the post as a table, note that the + post_content field is output last to simplify parsing + + csv: output all fields in Comma Separated Value format + + json: output all fields in JavaScript Object Notation format + * `<id>`: The ID of the post to get. diff --git a/man/post-get.1 b/man/post-get.1 index 7666551432..1a44a8296f 100644 --- a/man/post-get.1 +++ b/man/post-get.1 @@ -7,11 +7,29 @@ \fBwp\-post\-get\fR \- Get a post\'s content by ID\. . .SH "SYNOPSIS" -wp post get \fIid\fR +wp post get [\-\-format=\fIformat\fR] \fIid\fR . .SH "OPTIONS" . .TP +\fB[\-\-format=<format>]\fR: +. +.IP +The format to use when printing the post, acceptable values: +. +.IP +content: outputs only the post\'s content (default) +. +.IP +table: output all fields of the post as a table, note that the post_content field is output last to simplify parsing +. +.IP +csv: output all fields in Comma Separated Value format +. +.IP +json: output all fields in JavaScript Object Notation format +. +.TP \fB<id>\fR: . .IP diff --git a/php/commands/post.php b/php/commands/post.php index e2bd934368..b84d193498 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -65,14 +65,14 @@ protected function _update( $params ) { public function edit( $args, $_ ) { $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) - \WP_CLI::error( "Failed opening post $post_id to edit." ); + \WP_CLI::error( "Failed opening post $post_id to edit." ); $r = $this->_edit( $post->post_content, "WP-CLI post $post_id" ); if ( $r === false ) - \WP_CLI::warning( 'No change made to post content.', 'Aborted' ); + \WP_CLI::warning( 'No change made to post content.', 'Aborted' ); else - parent::update( $args, array( 'post_content' => $r ) ); + parent::update( $args, array( 'post_content' => $r ) ); } protected function _edit( $content, $title ) { @@ -80,16 +80,53 @@ protected function _edit( $content, $title ) { } /** - * Get a post's content by ID. - * - * @synopsis <id> - */ - public function get( $args, $_ ) { + * Get a post's content by ID. + * + * @synopsis [--format=<format>] <id> + */ + public function get( $args, $assoc_args ) { + $assoc_args = wp_parse_args( $assoc_args, array( + 'format' => 'content' + ) ); + $format = $assoc_args['format']; + $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) - \WP_CLI::error( "Failed opening post $post_id to get." ); + \WP_CLI::error( "Failed opening post $post_id to get." ); + + switch ( $assoc_args['format'] ) { + + case 'content': + echo($post->post_content); + break; - echo($post->post_content); + case 'table': + case 'csv': + $items = array(); + foreach ( get_object_vars( $post ) as $field => $value ) { + if ( 'post_content' === $field ) + continue; + + $item = new \stdClass; + $item->Field = $field; + $item->Value = $value; + $items[] = $item; + } + $content = new \stdClass; + $content->Field = 'post_content'; + $content->Value = $post->post_content; + $items[] = $content; + + \WP_CLI\Utils\format_items( $format, array( 'Field', 'Value' ), $items ); + break; + + case 'json': + echo( json_encode( $post ) ); + break; + + default: + \WP_CLI::error( "Invalid value for format: " . $format ); + } } /** From b98df06b1562c3aa7c0f2128661d015c27b524f5 Mon Sep 17 00:00:00 2001 From: John Lamp <j3lamp@gmail.com> Date: Sat, 13 Apr 2013 20:46:32 -0400 Subject: [PATCH 1482/4858] Removed CSV format from `post get`, with JSON format it is redundent, etc. Removed the `post_content` field from the table format output as the table becomes unweildy and the extremely long value of the content or the content itself causes problems with the table processing. Besides, chances are if one wanted the contents and the other fields JSON would be easier anyway. --- features/post.feature | 11 ----------- man-src/post-get.txt | 4 +--- man/post-get.1 | 5 +---- php/commands/post.php | 14 ++++++++------ 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/features/post.feature b/features/post.feature index 74f6cd842d..ee5efed9db 100644 --- a/features/post.feature +++ b/features/post.feature @@ -57,17 +57,6 @@ Feature: Manage WordPress posts Field Value ID {POST_ID} post_title Test post - post_content Test content. - """ - - When I run `wp post get --format=csv {POST_ID}` - Then it should run without errors - And STDOUT should be a table containing rows: - """ - Field,Value - ID,{POST_ID} - post_title,"Test post" - post_content,"Test content." """ When I run `wp post get --format=json {POST_ID}` diff --git a/man-src/post-get.txt b/man-src/post-get.txt index ff20d1df9a..fab4fdeb35 100644 --- a/man-src/post-get.txt +++ b/man-src/post-get.txt @@ -7,9 +7,7 @@ content: outputs only the post's content (default) table: output all fields of the post as a table, note that the - post_content field is output last to simplify parsing - - csv: output all fields in Comma Separated Value format + post_content field is omitted so that the table is readable json: output all fields in JavaScript Object Notation format diff --git a/man/post-get.1 b/man/post-get.1 index 1a44a8296f..67511f0136 100644 --- a/man/post-get.1 +++ b/man/post-get.1 @@ -21,10 +21,7 @@ The format to use when printing the post, acceptable values: content: outputs only the post\'s content (default) . .IP -table: output all fields of the post as a table, note that the post_content field is output last to simplify parsing -. -.IP -csv: output all fields in Comma Separated Value format +table: output all fields of the post as a table, note that the post_content field is omitted so that the table is readable . .IP json: output all fields in JavaScript Object Notation format diff --git a/php/commands/post.php b/php/commands/post.php index b84d193498..d87f903a80 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -20,7 +20,7 @@ public function create( $args, $assoc_args ) { if ( $args[0] !== '-' ) { $readfile = $args[0]; if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) - \WP_CLI::error( "Unable to read content from $readfile." ); + \WP_CLI::error( "Unable to read content from $readfile." ); } else $readfile = 'php://stdin'; @@ -101,31 +101,33 @@ public function get( $args, $assoc_args ) { break; case 'table': - case 'csv': $items = array(); foreach ( get_object_vars( $post ) as $field => $value ) { if ( 'post_content' === $field ) continue; + if ( !is_string($value) ) { + $value = json_encode($value); + } + $item = new \stdClass; $item->Field = $field; $item->Value = $value; $items[] = $item; } - $content = new \stdClass; - $content->Field = 'post_content'; - $content->Value = $post->post_content; - $items[] = $content; \WP_CLI\Utils\format_items( $format, array( 'Field', 'Value' ), $items ); break; case 'json': echo( json_encode( $post ) ); + echo( "\n" ); break; default: \WP_CLI::error( "Invalid value for format: " . $format ); + break; + } } From 0b52bebd0c6c1a3a4bcd4ed3846e4c03e9aed67c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Apr 2013 22:11:05 +0300 Subject: [PATCH 1483/4858] move iterators to separate namespace --- php/WP_CLI/{CSVIterator.php => Iterators/CSV.php} | 4 ++-- php/WP_CLI/Iterators/Exception.php | 6 ++++++ php/WP_CLI/{QueryIterator.php => Iterators/Query.php} | 10 ++++------ php/WP_CLI/{TableIterator.php => Iterators/Table.php} | 8 ++++---- php/commands/role.php | 2 +- php/commands/search-replace.php | 2 +- php/commands/user.php | 2 +- 7 files changed, 19 insertions(+), 15 deletions(-) rename php/WP_CLI/{CSVIterator.php => Iterators/CSV.php} (95%) create mode 100644 php/WP_CLI/Iterators/Exception.php rename php/WP_CLI/{QueryIterator.php => Iterators/Query.php} (86%) rename php/WP_CLI/{TableIterator.php => Iterators/Table.php} (86%) diff --git a/php/WP_CLI/CSVIterator.php b/php/WP_CLI/Iterators/CSV.php similarity index 95% rename from php/WP_CLI/CSVIterator.php rename to php/WP_CLI/Iterators/CSV.php index 46a3bf9c0e..dde3fb51c9 100644 --- a/php/WP_CLI/CSVIterator.php +++ b/php/WP_CLI/Iterators/CSV.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Iterators; -class CSVIterator implements \Iterator { +class CSV implements \Iterator { const ROW_SIZE = 4096; diff --git a/php/WP_CLI/Iterators/Exception.php b/php/WP_CLI/Iterators/Exception.php new file mode 100644 index 0000000000..e7320e0778 --- /dev/null +++ b/php/WP_CLI/Iterators/Exception.php @@ -0,0 +1,6 @@ +<?php + +namespace WP_CLI\Iterators; + +class Exception extends \RuntimeException {} + diff --git a/php/WP_CLI/QueryIterator.php b/php/WP_CLI/Iterators/Query.php similarity index 86% rename from php/WP_CLI/QueryIterator.php rename to php/WP_CLI/Iterators/Query.php index 3962d11088..1954586247 100644 --- a/php/WP_CLI/QueryIterator.php +++ b/php/WP_CLI/Iterators/Query.php @@ -1,13 +1,13 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Iterators; /** * Iterates over results of a query, split into many queries via LIMIT and OFFSET * * @source https://gist.github.com/4060005 */ -class QueryIterator implements \Iterator { +class Query implements \Iterator { private $limit = 500; private $query = ''; @@ -24,7 +24,7 @@ class QueryIterator implements \Iterator { * * This will loop over all users, but will retrieve them 100 by 100: * <code> - * foreach( new QueryIterator( array( 'query' => 'SELECT * FROM users', 'limit' => 100 ) ) as $user ) { + * foreach( new Iterators\Query( array( 'query' => 'SELECT * FROM users', 'limit' => 100 ) ) as $user ) { * tickle( $user ); * } * </code> @@ -49,7 +49,7 @@ function load_items_from_db() { $this->results = $this->db->get_results( $query ); if ( !$this->results ) { if ( $this->db->last_error ) { - throw new QueryIteratorException( 'Database error: '.$this->db->last_error ); + throw new Iterators\Exception( 'Database error: '.$this->db->last_error ); } else { return false; } @@ -96,5 +96,3 @@ function valid() { } } -class QueryIteratorException extends \RuntimeException {} - diff --git a/php/WP_CLI/TableIterator.php b/php/WP_CLI/Iterators/Table.php similarity index 86% rename from php/WP_CLI/TableIterator.php rename to php/WP_CLI/Iterators/Table.php index ef8bf8905c..fb807d0a14 100644 --- a/php/WP_CLI/TableIterator.php +++ b/php/WP_CLI/Iterators/Table.php @@ -1,23 +1,23 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Iterators; /** * @source https://gist.github.com/4060005 */ -class TableIterator extends QueryIterator { +class Table extends Iterators\Query { /** * Creates an iterator over a database table * * <code> - * foreach( new TableIterator( array( 'table' => $wpdb->posts, 'fields' => array( 'ID', 'post_content' ) ) ) as $post ) { + * foreach( new Iterators\Table( array( 'table' => $wpdb->posts, 'fields' => array( 'ID', 'post_content' ) ) ) as $post ) { * count_words_for( $post->ID, $post->post_content ); * } * </code> * * <code> - * foreach( new TableIterator( array( 'table' => $wpdb->posts, 'where' => 'ID = 8 OR post_status = "publish"' ) ) as $post ) { + * foreach( new Iterators\Table( array( 'table' => $wpdb->posts, 'where' => 'ID = 8 OR post_status = "publish"' ) ) as $post ) { * … * } * </code> diff --git a/php/commands/role.php b/php/commands/role.php index 8f2e0765c7..88c43b0de6 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -109,4 +109,4 @@ private static function persistence_check() { } } -WP_CLI::add_command( 'role', 'Role_Command' ); \ No newline at end of file +WP_CLI::add_command( 'role', 'Role_Command' ); diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f46cc27906..607ccd28db 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -62,7 +62,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry 'limit' => 1000 ); - $it = new \WP_CLI\TableIterator( $args ); + $it = new \WP_CLI\Iterators\Table( $args ); $count = 0; diff --git a/php/commands/user.php b/php/commands/user.php index f867204e17..b2fdc7911e 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -300,7 +300,7 @@ public function import_csv( $args, $assoc_args ) { $filename = $args[0]; - foreach ( new \WP_CLI\CSVIterator( $filename ) as $i => $new_user ) { + foreach ( new \WP_CLI\Iterators\CSV( $filename ) as $i => $new_user ) { $defaults = array( 'role' => get_option('default_role'), 'user_pass' => wp_generate_password(), From 72e10a40a2d9f8a33832d08f73a35cd23c468d2e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Apr 2013 22:18:42 +0300 Subject: [PATCH 1484/4858] on OS X, wc -l inexplicably outputs whitespace before the result --- features/user.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/user.feature b/features/user.feature index d1d034a9ea..e725dcedc1 100644 --- a/features/user.feature +++ b/features/user.feature @@ -35,7 +35,7 @@ Feature: Manage WordPress users When I run `wp user generate --count=10` Then it should run without errors - When I run `wp user list | wc -l` + When I run `wp user list | wc -l | tr -d ' '` Then STDOUT should be: """ 11 From a4460e3cfdb313ca8051fb1b00dfb7042ba1ea22 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Apr 2013 23:13:56 +0300 Subject: [PATCH 1485/4858] add smoke test for search-replace --- features/search-replace.feature | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 features/search-replace.feature diff --git a/features/search-replace.feature b/features/search-replace.feature new file mode 100644 index 0000000000..34241c880e --- /dev/null +++ b/features/search-replace.feature @@ -0,0 +1,8 @@ +Feature: Do global search/replace + + Scenario: Basic search/replace + Given a WP install + + When I run `wp search-replace foo bar` + Then it should run without errors + And STDOUT should not be empty From e960694560527f26f801c7bb5a37f9e293fb2aba Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Apr 2013 23:17:07 +0300 Subject: [PATCH 1486/4858] fix class reference in Iterators/Table.php --- php/WP_CLI/Iterators/Table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index fb807d0a14..eade2ca1d2 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -5,7 +5,7 @@ /** * @source https://gist.github.com/4060005 */ -class Table extends Iterators\Query { +class Table extends Query { /** * Creates an iterator over a database table From 6f0870761e644bf4e47ffb7e6a012b974c61d913 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Apr 2013 00:57:16 +0300 Subject: [PATCH 1487/4858] add smoke test for wp user import-csv --- features/user.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/features/user.feature b/features/user.feature index e725dcedc1..316b534d5d 100644 --- a/features/user.feature +++ b/features/user.feature @@ -40,3 +40,23 @@ Feature: Manage WordPress users """ 11 """ + + Scenario: Importing users from a CSV file + Given a WP install + And a users.csv file: + """ + user_login, user_email, display_name, role + bobjones, bobjones@domain.com, Bob Jones, contributor + newuser1, newuser1@domain.com, New User, author + admin, admin@domain.com, Existing User, administrator + """ + + When I run `wp user import-csv users.csv` + Then it should run without errors + + When I run `wp user list | wc -l | tr -d ' '` + Then STDOUT should be: + """ + 4 + """ + From 3ab5140e621dba66defc878a9cbdc1f92cfd57d9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Apr 2013 02:37:32 +0300 Subject: [PATCH 1488/4858] make query string mandatory first parameter in Iterators\Query constructor see #390 --- php/WP_CLI/Iterators/Query.php | 19 +++++++------------ php/WP_CLI/Iterators/Table.php | 9 ++++----- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/Iterators/Query.php b/php/WP_CLI/Iterators/Query.php index 1954586247..523e300d2d 100644 --- a/php/WP_CLI/Iterators/Query.php +++ b/php/WP_CLI/Iterators/Query.php @@ -24,24 +24,19 @@ class Query implements \Iterator { * * This will loop over all users, but will retrieve them 100 by 100: * <code> - * foreach( new Iterators\Query( array( 'query' => 'SELECT * FROM users', 'limit' => 100 ) ) as $user ) { + * foreach( new Iterators\Query( 'SELECT * FROM users', 100 ) as $user ) { * tickle( $user ); * } * </code> * - * - * @param array $args Supported arguments: - * query – the query as a string. It shouldn't include any LIMIT clauses - * limit – (optional) how many rows to retrieve at once, default value is 500 + * @param string $query The query as a string. It shouldn't include any LIMIT clauses + * @param number $limit How many rows to retrieve at once; default value is 500 (optional) */ - function __construct( $args = array() ) { + public function __construct( $query, $limit = 500 ) { + $this->query = $query; + $this->limit = $limit; + $this->db = $GLOBALS['wpdb']; - foreach( $args as $key => $value ) { - $this->$key = $value; - } - if ( !$this->query ) { - throw new InvalidArgumentException( 'Missing query argument.' ); - } } function load_items_from_db() { diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index eade2ca1d2..825bf265e2 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -52,11 +52,10 @@ function __construct( $args = array() ) { $conditions = self::build_where_conditions( $args['where'] ); $where_sql = $conditions? " WHERE $conditions" : ''; $query = "SELECT $fields FROM $table $where_sql"; - $parent_args = compact( 'query' ); - if ( isset( $args['limit'] ) ) { - $parent_args['limit'] = $args['limit']; - } - parent::__construct( $parent_args ); + + $limit = isset( $args['limit'] ) ? $args['limit'] : 500; + + parent::__construct( $query, $limit ); } static function build_fields( $fields ) { From bf9e77f409199d947147bfa880ad6e06cd7eace4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Apr 2013 02:38:23 +0300 Subject: [PATCH 1489/4858] mark some iterator methods as private see #390 --- php/WP_CLI/Iterators/Query.php | 14 ++++++++++---- php/WP_CLI/Iterators/Table.php | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Iterators/Query.php b/php/WP_CLI/Iterators/Query.php index 523e300d2d..1577e99ab8 100644 --- a/php/WP_CLI/Iterators/Query.php +++ b/php/WP_CLI/Iterators/Query.php @@ -39,22 +39,24 @@ public function __construct( $query, $limit = 500 ) { $this->db = $GLOBALS['wpdb']; } - function load_items_from_db() { + private function load_items_from_db() { $query = $this->query . sprintf( ' LIMIT %d OFFSET %d', $this->limit, $this->offset ); $this->results = $this->db->get_results( $query ); + if ( !$this->results ) { if ( $this->db->last_error ) { - throw new Iterators\Exception( 'Database error: '.$this->db->last_error ); + throw new Iterators\Exception( 'Database error: ' . $this->db->last_error ); } else { return false; } } + $this->offset += $this->limit; return true; } function current() { - return $this->results[$this->index_in_results]; + return $this->results[ $this->index_in_results ]; } function key() { @@ -78,15 +80,19 @@ function valid() { if ( $this->depleted ) { return false; } - if ( !isset( $this->results[$this->index_in_results] ) ) { + + if ( !isset( $this->results[ $this->index_in_results ] ) ) { $items_loaded = $this->load_items_from_db(); + if ( !$items_loaded ) { $this->rewind(); $this->depleted = true; return false; } + $this->index_in_results = 0; } + return true; } } diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 825bf265e2..450301ae2f 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -58,11 +58,11 @@ function __construct( $args = array() ) { parent::__construct( $query, $limit ); } - static function build_fields( $fields ) { + private static function build_fields( $fields ) { return implode( ', ', $fields ); } - static function build_where_conditions( $where ) { + private static function build_where_conditions( $where ) { global $wpdb; if ( is_array( $where ) ) { $conditions = array(); From 3aae56760cf6e7e3eb0df0efc2cf6d7234a291a8 Mon Sep 17 00:00:00 2001 From: John Lamp <j3lamp@gmail.com> Date: Sun, 14 Apr 2013 22:29:30 -0400 Subject: [PATCH 1490/4858] Refactored the poorly named `compareJson()` function into the more accurate `checkThatJsonStringContainsJsonString()` function which encapsulates the calls to `json_decode()`. --- features/steps/basic_steps.php | 77 ++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index d6eb182e05..5f03ada13b 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -203,12 +203,11 @@ function ( $world, PyStringNode $expected ) { $steps->Then( '/^STDOUT should be JSON containing:$/', function ( $world, PyStringNode $expected ) { $output = $world->result->STDOUT; - $outputJson = json_decode( $output ); $expected = $world->replace_variables( (string) $expected ); - $expectedJson = json_decode( $expected ); - if ( !compareJson( $expectedJson, $outputJson ) ) { + if ( !checkThatJsonStringContainsJsonString( $output, + $expected ) ) { throw new \Exception( $output ); } }); @@ -234,26 +233,70 @@ function ( $world, $path ) { ); -function compareJson( $expected, $actual ) { - if ( gettype( $expected ) != gettype( $actual ) ) { +/** + * Compare two strings containing JSON to ensure that @a $actualJson contains at + * least what the JSON string @a $expectedJson contains. + * + * @return whether or not @a $actualJson contains @a $expectedJson + * @retval true @a $actualJson contains @a $expectedJson + * @retval false @a $actualJson does not contain @a $expectedJson + * + * @param[in] $actualJson the JSON string to be tested + * @param[in] $expectedJson the expected JSON string + * + * Examples: + * expected: {'a':1,'array':[1,3,5]} + * + * 1) + * actual: {'a':1,'b':2,'c':3,'array':[1,2,3,4,5]} + * return: true + * + * 2) + * actual: {'b':2,'c':3,'array':[1,2,3,4,5]} + * return: false + * element 'a' is missing from the root object + * + * 3) + * actual: {'a':0,'b':2,'c':3,'array':[1,2,3,4,5]} + * return: false + * the value of element 'a' is not 1 + * + * 4) + * actual: {'a':1,'b':2,'c':3,'array':[1,2,4,5]} + * return: false + * the contents of 'array' does not include 3 + */ +function checkThatJsonStringContainsJsonString( $actualJson, $expectedJson ) { + $actualValue = json_decode( $actualJson ); + $expectedValue = json_decode( $expectedJson ); + + if ( !$actualValue ) { return false; } - if ( is_object( $expected ) ) { - foreach ( get_object_vars( $expected ) as $name => $value ) { - if ( !compareJson( $value, $actual->$name ) ) { - return false; - } + function compareContents( $expected, $actual ) { + if ( gettype( $expected ) != gettype( $actual ) ) { + return false; } - } else if ( is_array( $expected ) ) { - foreach ( $expected as $key => $value ) { - if ( !compareJson( $value, $actual[$key] ) ) { - return false; + + if ( is_object( $expected ) ) { + foreach ( get_object_vars( $expected ) as $name => $value ) { + if ( !compareContents( $value, $actual->$name ) ) { + return false; + } } + } else if ( is_array( $expected ) ) { + foreach ( $expected as $key => $value ) { + if ( !compareContents( $value, $actual[$key] ) ) { + return false; + } + } + } else { + return $expected === $actual; } - } else { - return $expected === $actual; + + return true; } - return true; + return compareContents( $expectedValue, $actualValue ); } From 9bf27efa2a2c7fa9000ea88200611f9a2ee61033 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Wed, 17 Apr 2013 01:12:09 +0200 Subject: [PATCH 1491/4858] Fixed query_var using slug instead of boolean TRUE --- templates/taxonomy.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index 20747a722a..5d82234e32 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -3,7 +3,7 @@ 'public' => true, 'show_in_nav_menus' => true, 'show_ui' => true, - 'query_var' => {{slug}}, + 'query_var' => true, 'rewrite' => true, 'capabilities' => array( 'manage_terms' => 'edit_posts', From f917293010981a6240b66ed23049ca07ef696417 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Apr 2013 18:24:58 -0700 Subject: [PATCH 1492/4858] Ignore composer.phar, as it's installed separately from the project --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0e7aef9033..325d475d87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +composer.phar /vendor /phpunit.xml From f739e5388307ff02d7241fc04893e8fa49179950 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Apr 2013 19:03:11 -0700 Subject: [PATCH 1493/4858] Functional test for creating / listing a term --- features/steps/basic_steps.php | 7 +++++++ features/term.feature | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 features/term.feature diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 5f03ada13b..64ab158cbd 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -142,6 +142,13 @@ function ( $world ) { } ); +$steps->Then( '/^it should run with errors$/' , + function ( $world ) { + if ( empty( $world->result->STDERR ) ) + throw new \Exception( "No error produced" ); + } +); + $steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', function ( $world, $stream, $action, PyStringNode $expected ) { $output = $world->result->$stream; diff --git a/features/term.feature b/features/term.feature new file mode 100644 index 0000000000..268fba52a7 --- /dev/null +++ b/features/term.feature @@ -0,0 +1,25 @@ +Feature: Manage WordPress terms + + Scenario: Creating/listing a term + Given a WP install + + When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term'` + Then it should run without errors + And STDOUT should be: + """ + Success: Term created. + """ + + When I run the previous command again + Then it should run with errors + And STDERR should be: + """ + Error: A term with the name provided already exists. + """ + + When I run `wp term list post_tag --format=json` + Then it should run without errors + And STDOUT should be JSON containing: + """ + [{"term_id":"2","term_taxonomy_id":"2","name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] + """ \ No newline at end of file From 4076050a8342e64a197ec24a1dbfe0516b8d6029 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Apr 2013 19:14:15 -0700 Subject: [PATCH 1494/4858] Newline fix for failed test --- features/term.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/term.feature b/features/term.feature index 268fba52a7..9698050bc5 100644 --- a/features/term.feature +++ b/features/term.feature @@ -22,4 +22,4 @@ Feature: Manage WordPress terms And STDOUT should be JSON containing: """ [{"term_id":"2","term_taxonomy_id":"2","name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] - """ \ No newline at end of file + """ From 8f0ce253fb203c0486be185741f438b8716296f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Apr 2013 20:35:29 -0700 Subject: [PATCH 1495/4858] Actually fix failing tests. Functions defined inside of functions cause everything to fatal when the parent function is called twice. --- features/steps/basic_steps.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 64ab158cbd..0414f2a5f5 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -281,6 +281,7 @@ function checkThatJsonStringContainsJsonString( $actualJson, $expectedJson ) { return false; } + if ( ! function_exists( 'compareContents' ) ) : function compareContents( $expected, $actual ) { if ( gettype( $expected ) != gettype( $actual ) ) { return false; @@ -304,6 +305,7 @@ function compareContents( $expected, $actual ) { return true; } + endif; return compareContents( $expectedValue, $actualValue ); } From b908f81bc637027cd166c6b7658e9ddf51832d50 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 13:28:03 -0700 Subject: [PATCH 1496/4858] Move declaration of compareContents() outside of a function, to avoid fatals when the function is declared twice See https://github.com/wp-cli/wp-cli/pull/398/files#r3869537 --- features/steps/basic_steps.php | 42 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 0414f2a5f5..9de39f064f 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -281,31 +281,29 @@ function checkThatJsonStringContainsJsonString( $actualJson, $expectedJson ) { return false; } - if ( ! function_exists( 'compareContents' ) ) : - function compareContents( $expected, $actual ) { - if ( gettype( $expected ) != gettype( $actual ) ) { - return false; - } + return compareContents( $expectedValue, $actualValue ); +} + +function compareContents( $expected, $actual ) { + if ( gettype( $expected ) != gettype( $actual ) ) { + return false; + } - if ( is_object( $expected ) ) { - foreach ( get_object_vars( $expected ) as $name => $value ) { - if ( !compareContents( $value, $actual->$name ) ) { - return false; - } + if ( is_object( $expected ) ) { + foreach ( get_object_vars( $expected ) as $name => $value ) { + if ( !compareContents( $value, $actual->$name ) ) { + return false; } - } else if ( is_array( $expected ) ) { - foreach ( $expected as $key => $value ) { - if ( !compareContents( $value, $actual[$key] ) ) { - return false; - } + } + } else if ( is_array( $expected ) ) { + foreach ( $expected as $key => $value ) { + if ( !compareContents( $value, $actual[$key] ) ) { + return false; } - } else { - return $expected === $actual; } - - return true; + } else { + return $expected === $actual; } - endif; - return compareContents( $expectedValue, $actualValue ); -} + return true; +} \ No newline at end of file From 395a9c8097fbfa4a46ee36b9c7303351538d2e9a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 13:30:55 -0700 Subject: [PATCH 1497/4858] Skip checking these numeric fields, as they might change during the tests See https://github.com/wp-cli/wp-cli/pull/398/files#r3869915 --- features/term.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/term.feature b/features/term.feature index 9698050bc5..8c29b00215 100644 --- a/features/term.feature +++ b/features/term.feature @@ -21,5 +21,5 @@ Feature: Manage WordPress terms Then it should run without errors And STDOUT should be JSON containing: """ - [{"term_id":"2","term_taxonomy_id":"2","name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] + [{"name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] """ From dbd057a968c2d04d0119a1f1a5df9b5e5b934b76 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 13:33:52 -0700 Subject: [PATCH 1498/4858] Simplify expression of the run with errors condition See https://github.com/wp-cli/wp-cli/pull/398/files#r3869578 --- features/steps/basic_steps.php | 7 ------- features/term.feature | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 9de39f064f..4e1d8c2bf7 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -142,13 +142,6 @@ function ( $world ) { } ); -$steps->Then( '/^it should run with errors$/' , - function ( $world ) { - if ( empty( $world->result->STDERR ) ) - throw new \Exception( "No error produced" ); - } -); - $steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', function ( $world, $stream, $action, PyStringNode $expected ) { $output = $world->result->$stream; diff --git a/features/term.feature b/features/term.feature index 8c29b00215..e8be1655b7 100644 --- a/features/term.feature +++ b/features/term.feature @@ -11,11 +11,7 @@ Feature: Manage WordPress terms """ When I run the previous command again - Then it should run with errors - And STDERR should be: - """ - Error: A term with the name provided already exists. - """ + Then STDERR should not be empty When I run `wp term list post_tag --format=json` Then it should run without errors From b62bd52fa7d1706376ed1c8609b0ae43e6d55c14 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 00:10:28 +0300 Subject: [PATCH 1499/4858] rename `scaffold child_theme` to `scaffold child-theme` --- php/commands/scaffold.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index b637201485..4b76b6ce52 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -149,6 +149,8 @@ function _s( $args, $assoc_args ) { /** * Generate empty child theme (twentytwelve by default). * + * @subcommand child-theme + * * @synopsis <slug> [--theme_name=<title>] [--parent_theme=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] */ function child_theme( $args, $assoc_args ) { @@ -166,14 +168,14 @@ function child_theme( $args, $assoc_args ) { $data['theme_description'] = ucfirst($data['parent_theme']) . " child theme. "; - + $theme_dir = $theme_path . "/$theme_slug"; $theme_style_path = "$theme_dir/style.css"; $this->create_file( $theme_style_path, $this->render( 'child_theme.mustache', $data ) ); WP_CLI::success( "Created $theme_dir" ); - + if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); From 1b1be354eee3ad35bbac32d87005479fe7955e3a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 00:14:37 +0300 Subject: [PATCH 1500/4858] make --parent_theme mandatory --- php/commands/scaffold.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 4b76b6ce52..281f97e4df 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -151,7 +151,7 @@ function _s( $args, $assoc_args ) { * * @subcommand child-theme * - * @synopsis <slug> [--theme_name=<title>] [--parent_theme=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] + * @synopsis <slug> --parent_theme=<title> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] */ function child_theme( $args, $assoc_args ) { @@ -160,7 +160,6 @@ function child_theme( $args, $assoc_args ) { $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), - 'parent_theme' => 'twentytwelve', 'author' => "Me", 'author_uri' => "", 'theme_uri' => "" From 8cb137677286fe31b56b51b4f9c24ad805db8695 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 00:19:08 +0300 Subject: [PATCH 1501/4858] style fixes for scaffold child-theme --- php/commands/scaffold.php | 9 ++------- templates/child_theme.mustache | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 281f97e4df..b7a5f9e307 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -154,9 +154,7 @@ function _s( $args, $assoc_args ) { * @synopsis <slug> --parent_theme=<title> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] */ function child_theme( $args, $assoc_args ) { - $theme_slug = $args[0]; - $theme_path = WP_CONTENT_DIR . "/themes"; $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), @@ -165,20 +163,17 @@ function child_theme( $args, $assoc_args ) { 'theme_uri' => "" ) ); - $data['theme_description'] = ucfirst($data['parent_theme']) . " child theme. "; - + $data['description'] = ucfirst( $data['parent_theme'] ) . " child theme."; - $theme_dir = $theme_path . "/$theme_slug"; + $theme_dir = WP_CONTENT_DIR . "themes" . "/$theme_slug"; $theme_style_path = "$theme_dir/style.css"; $this->create_file( $theme_style_path, $this->render( 'child_theme.mustache', $data ) ); WP_CLI::success( "Created $theme_dir" ); - if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } private function get_output_path( $assoc_args, $subdir ) { diff --git a/templates/child_theme.mustache b/templates/child_theme.mustache index a6b182b828..6e96440f11 100644 --- a/templates/child_theme.mustache +++ b/templates/child_theme.mustache @@ -1,11 +1,11 @@ /* Theme Name: {{theme_name}} Theme URI: {{theme_uri}} -Description: {{theme_description}} +Description: {{description}} Author: {{author}} Author URI: {{author_uri}} Template: {{parent_theme}} Version: 0.1.0 */ -@import '../{{parent_theme}}/style.css'; \ No newline at end of file +@import '../{{parent_theme}}/style.css'; From 8443a96168bcea0b13c9dad5db5446752ec3929d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 00:26:38 +0300 Subject: [PATCH 1502/4858] add man page for scaffold child-theme. see #339 --- man-src/scaffold-child-theme.txt | 29 +++++++++++++++++ man/scaffold-child-theme.1 | 55 ++++++++++++++++++++++++++++++++ php/commands/scaffold.php | 4 +-- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 man-src/scaffold-child-theme.txt create mode 100644 man/scaffold-child-theme.1 diff --git a/man-src/scaffold-child-theme.txt b/man-src/scaffold-child-theme.txt new file mode 100644 index 0000000000..2f05ab25f4 --- /dev/null +++ b/man-src/scaffold-child-theme.txt @@ -0,0 +1,29 @@ +## OPTIONS + +* <slug>: + + The slug for the new child theme. + +* `--parent_theme=<slug>`: + + What to put in the 'Template:' header in style.css + +* `--theme_name=<title>`: + + What to put in the 'Theme Name:' header in style.css + +* `--author=<full name>`: + + What to put in the 'Author:' header in style.css + +* `--author_uri=<http url>`: + + What to put in the 'Author URI:' header in style.css + +* `--theme_uri=<http url>`: + + What to put in the 'Theme URI:' header in style.css + +* `--activate`: + + Activate the newly created child theme. diff --git a/man/scaffold-child-theme.1 b/man/scaffold-child-theme.1 new file mode 100644 index 0000000000..67fa5bcd3f --- /dev/null +++ b/man/scaffold-child-theme.1 @@ -0,0 +1,55 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SCAFFOLD\-CHILD\-THEME" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-scaffold\-child\-theme\fR \- Generate empty child theme\. +. +.SH "SYNOPSIS" +wp scaffold child\-theme \fIslug\fR \-\-parent_theme=\fIslug\fR [\-\-theme_name=\fItitle\fR] [\-\-author=\fIfull\-name\fR] [\-\-author_uri=\fIhttp\-url\fR] [\-\-theme_uri=\fIhttp\-url\fR] [\-\-activate] +. +.SH "OPTIONS" +. +.TP +\fIslug\fR: +. +.IP +The slug for the new child theme\. +. +.TP +\fB\-\-parent_theme=<slug>\fR: +. +.IP +What to put in the \'Template:\' header in style\.css +. +.TP +\fB\-\-theme_name=<title>\fR: +. +.IP +What to put in the \'Theme Name:\' header in style\.css +. +.TP +\fB\-\-author=<full name>\fR: +. +.IP +What to put in the \'Author:\' header in style\.css +. +.TP +\fB\-\-author_uri=<http url>\fR: +. +.IP +What to put in the \'Author URI:\' header in style\.css +. +.TP +\fB\-\-theme_uri=<http url>\fR: +. +.IP +What to put in the \'Theme URI:\' header in style\.css +. +.TP +\fB\-\-activate\fR: +. +.IP +Activate the newly created child theme\. + diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 69a72d89a7..b43e87a135 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -148,11 +148,11 @@ function _s( $args, $assoc_args ) { } /** - * Generate empty child theme (twentytwelve by default). + * Generate empty child theme. * * @subcommand child-theme * - * @synopsis <slug> --parent_theme=<title> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] + * @synopsis <slug> --parent_theme=<slug> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] */ function child_theme( $args, $assoc_args ) { $theme_slug = $args[0]; From ae1d943ec09c6ef4bc67c725a7cc4e7e89c663ae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Apr 2013 21:04:17 -0700 Subject: [PATCH 1503/4858] wp term list: Support for `--ids` argument --- man-src/term-list.txt | 4 ++++ man/term-list.1 | 8 +++++++- php/commands/term.php | 29 +++++++++++++++++------------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/man-src/term-list.txt b/man-src/term-list.txt index f991f2558f..32e01215df 100644 --- a/man-src/term-list.txt +++ b/man-src/term-list.txt @@ -4,6 +4,10 @@ List terms of a given taxonomy. +* `--ids`: + + Return only the term ids of the found terms, separated by spaces. + * `--format`=<format>: Output list as table, CSV or JSON. Defaults to table. diff --git a/man/term-list.1 b/man/term-list.1 index 060772fdd5..88d47ab967 100644 --- a/man/term-list.1 +++ b/man/term-list.1 @@ -7,7 +7,7 @@ \fBwp\-term\-list\fR \- List terms in a taxonomy\. . .SH "SYNOPSIS" -wp term list \fItaxonomy\fR [\-\-format=\fIformat\fR] +wp term list \fItaxonomy\fR [\-\-ids] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -18,6 +18,12 @@ wp term list \fItaxonomy\fR [\-\-format=\fIformat\fR] List terms of a given taxonomy\. . .TP +\fB\-\-ids\fR: +. +.IP +Return only the term ids of the found terms, separated by spaces\. +. +.TP \fB\-\-format\fR=\fIformat\fR: . .IP diff --git a/php/commands/term.php b/php/commands/term.php index 9c4e82a1e4..4679a33129 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -10,7 +10,7 @@ class Term_Command extends WP_CLI_Command { * List terms in a taxonomy. * * @subcommand list - * @synopsis <taxonomy> [--format=<format>] + * @synopsis <taxonomy> [--ids] [--format=<format>] */ public function _list( $args, $assoc_args ) { @@ -24,17 +24,22 @@ public function _list( $args, $assoc_args ) { $terms = get_terms( array( $taxonomy ), $assoc_args ); - $fields = array( - 'term_id', - 'term_taxonomy_id', - 'name', - 'slug', - 'description', - 'parent', - 'count', - ); - - WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); + if ( isset( $assoc_args['ids'] ) ) { + WP_CLI::out( implode( ' ', wp_list_pluck( $terms, 'term_id' ) ) ); + } else { + + $fields = array( + 'term_id', + 'term_taxonomy_id', + 'name', + 'slug', + 'description', + 'parent', + 'count', + ); + + WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); + } } /** From ef46664602e1fce1d4e48491901faea7cc75fbf1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 14:08:31 -0700 Subject: [PATCH 1504/4858] Refactor to allow 'ids' be passed to `format_items()` as a formatting argument --- man-src/term-list.txt | 6 +----- man/term-list.1 | 10 ++-------- php/commands/term.php | 28 +++++++++++++--------------- php/utils.php | 3 +++ 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/man-src/term-list.txt b/man-src/term-list.txt index 32e01215df..f782b7e595 100644 --- a/man-src/term-list.txt +++ b/man-src/term-list.txt @@ -4,13 +4,9 @@ List terms of a given taxonomy. -* `--ids`: - - Return only the term ids of the found terms, separated by spaces. - * `--format`=<format>: - Output list as table, CSV or JSON. Defaults to table. + Output list as table, CSV, JSON, or simply IDs. Defaults to table. ## EXAMPLES diff --git a/man/term-list.1 b/man/term-list.1 index 88d47ab967..9990d2ff09 100644 --- a/man/term-list.1 +++ b/man/term-list.1 @@ -7,7 +7,7 @@ \fBwp\-term\-list\fR \- List terms in a taxonomy\. . .SH "SYNOPSIS" -wp term list \fItaxonomy\fR [\-\-ids] [\-\-format=\fIformat\fR] +wp term list \fItaxonomy\fR [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -18,16 +18,10 @@ wp term list \fItaxonomy\fR [\-\-ids] [\-\-format=\fIformat\fR] List terms of a given taxonomy\. . .TP -\fB\-\-ids\fR: -. -.IP -Return only the term ids of the found terms, separated by spaces\. -. -.TP \fB\-\-format\fR=\fIformat\fR: . .IP -Output list as table, CSV or JSON\. Defaults to table\. +Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. . .SH "EXAMPLES" . diff --git a/php/commands/term.php b/php/commands/term.php index 4679a33129..c55b585086 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -10,7 +10,7 @@ class Term_Command extends WP_CLI_Command { * List terms in a taxonomy. * * @subcommand list - * @synopsis <taxonomy> [--ids] [--format=<format>] + * @synopsis <taxonomy> [--format=<format>] */ public function _list( $args, $assoc_args ) { @@ -24,22 +24,20 @@ public function _list( $args, $assoc_args ) { $terms = get_terms( array( $taxonomy ), $assoc_args ); - if ( isset( $assoc_args['ids'] ) ) { - WP_CLI::out( implode( ' ', wp_list_pluck( $terms, 'term_id' ) ) ); - } else { - - $fields = array( - 'term_id', - 'term_taxonomy_id', - 'name', - 'slug', - 'description', - 'parent', - 'count', + if ( 'ids' == $assoc_args['format'] ) + $terms = wp_list_pluck( $terms, 'term_id' ); + + $fields = array( + 'term_id', + 'term_taxonomy_id', + 'name', + 'slug', + 'description', + 'parent', + 'count', ); - WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); - } + WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); } /** diff --git a/php/utils.php b/php/utils.php index 51f25b541d..3489393d7c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -293,6 +293,9 @@ function format_items( $format, $fields, $items ) { else write_csv( STDOUT, $output_items, $fields ); break; + case 'ids': + \WP_CLI::out( implode( ' ', $items ) ); + break; } } From aec54c690ef9bc8184bebe5ce34fa20a1df3ba14 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 14:27:20 -0700 Subject: [PATCH 1505/4858] Convert `wp user list --ids` to `wp user list --format=ids` Also, dropped the formatting of the `$output_items`, as a user is already a WP_User object and the formatting is handled within our `format_items()` util --- man-src/user-list.txt | 6 +----- man/user-list.1 | 10 ++-------- php/commands/user.php | 38 ++++++++++++++++---------------------- 3 files changed, 19 insertions(+), 35 deletions(-) diff --git a/man-src/user-list.txt b/man-src/user-list.txt index 8fc98a0131..f675f25a0a 100644 --- a/man-src/user-list.txt +++ b/man-src/user-list.txt @@ -4,13 +4,9 @@ Only display users with a certain role. -* `--ids`: - - Return only the IDs of the found users, separated by spaces. - * `--format`=<format>: - Output list as table, CSV or JSON. Defaults to table. + Output list as table, CSV, JSON, or simply IDs. Defaults to table. ## EXAMPLES diff --git a/man/user-list.1 b/man/user-list.1 index 251e9f254f..73c72ba33d 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -7,7 +7,7 @@ \fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" -wp user list [\-\-role=\fIrole\fR] [\-\-ids] [\-\-format=\fIformat\fR] +wp user list [\-\-role=\fIrole\fR] [\-\-format=\fIformat\fR] [\-\-ids] . .SH "OPTIONS" . @@ -18,16 +18,10 @@ wp user list [\-\-role=\fIrole\fR] [\-\-ids] [\-\-format=\fIformat\fR] Only display users with a certain role\. . .TP -\fB\-\-ids\fR: -. -.IP -Return only the IDs of the found users, separated by spaces\. -. -.TP \fB\-\-format\fR=\fIformat\fR: . .IP -Output list as table, CSV or JSON\. Defaults to table\. +Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. . .SH "EXAMPLES" . diff --git a/php/commands/user.php b/php/commands/user.php index b2fdc7911e..f59583ffc3 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -13,7 +13,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * List users. * * @subcommand list - * @synopsis [--role=<role>] [--ids] [--format=<format>] + * @synopsis [--role=<role>] [--format=<format>] [--ids] */ public function _list( $args, $assoc_args ) { @@ -28,38 +28,32 @@ public function _list( $args, $assoc_args ) { $params['role'] = $assoc_args['role']; } - $users = get_users( $params ); - - if ( isset( $assoc_args['ids'] ) ) { - WP_CLI::out( implode( ' ', $users ) ); - exit; + // --ids is deprecated + if ( isset( $params['ids'] ) ) { + $params['format'] = 'ids'; + unset( $params['ids'] ); } + if ( 'ids' == $params['format'] ) + $params['fields'] = 'ids'; + + $users = get_users( $params ); + $fields = array( 'ID', 'user_login', 'display_name', 'user_email', - 'user_registered' + 'user_registered', + 'roles' ); - - $output_users = array(); - - foreach ( $users as $user ) { - $output_user = new stdClass; - - foreach ( $fields as $field ) { - $output_user->$field = $user->$field; + if ( 'ids' != $params['format'] ) { + foreach ( $users as $user ) { + $user->roles = implode( ',', $user->roles ); } - - $output_user->roles = implode( ',', $user->roles ); - - $output_users[] = $output_user; } - $fields[] = 'roles'; - - WP_CLI\Utils\format_items( $params['format'], $fields, $output_users ); + WP_CLI\Utils\format_items( $params['format'], $fields, $users ); } /** From fff9d064a6df71e25fc631fd720c2af2546ed4a0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 14:43:17 -0700 Subject: [PATCH 1506/4858] JSON format test for `wp user list` Also, fix the CSV used in the setup of the scenario as it originally caused the test to fail --- features/user.feature | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/features/user.feature b/features/user.feature index 316b534d5d..183986f8da 100644 --- a/features/user.feature +++ b/features/user.feature @@ -45,10 +45,10 @@ Feature: Manage WordPress users Given a WP install And a users.csv file: """ - user_login, user_email, display_name, role - bobjones, bobjones@domain.com, Bob Jones, contributor - newuser1, newuser1@domain.com, New User, author - admin, admin@domain.com, Existing User, administrator + user_login,user_email,display_name,role + bobjones,bobjones@domain.com,Bob Jones,contributor + newuser1,newuser1@domain.com,New User,author + admin,admin@domain.com,Existing User,administrator """ When I run `wp user import-csv users.csv` @@ -60,3 +60,9 @@ Feature: Manage WordPress users 4 """ + When I run `wp user list --format=json` + Then it should run without errors + And STDOUT should be JSON containing: + """ + [{"user_login":"admin","display_name":"Existing User","user_email":"admin@domain.com","roles":"administrator"}] + """ From ee5da67d2188663536b43801354431606a558545 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 15:27:20 -0700 Subject: [PATCH 1507/4858] Convert `wp post list --ids` to `wp post list --format=ids` --- php/commands/post.php | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index bcd2e71ee2..88e5c8517e 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -160,13 +160,19 @@ protected function _delete( $post_id, $assoc_args ) { * Get a list of posts. * * @subcommand list - * @synopsis [--<field>=<value>] [--ids] [--format=<format>] + * @synopsis [--<field>=<value>] [--format=<format>] [--ids] */ public function _list( $_, $assoc_args ) { $query_args = array( 'posts_per_page' => -1 ); + // --ids is deprecated + if ( isset( $assoc_args['ids'] ) ) { + $assoc_args['format'] = 'ids'; + unset( $assoc_args['ids'] ); + } + if ( ! empty( $assoc_args['format'] ) ) { $format = $assoc_args['format']; unset( $assoc_args['format'] ); @@ -181,29 +187,16 @@ public function _list( $_, $assoc_args ) { $query_args[ $key ] = $value; } - if ( isset( $assoc_args['ids'] ) ) + if ( 'ids' == $format ) $query_args['fields'] = 'ids'; $query = new WP_Query( $query_args ); - if ( isset( $assoc_args['ids'] ) ) { - WP_CLI::out( implode( ' ', $query->posts ) ); - } else { - - $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); - - $output_posts = array(); - foreach ( $query->posts as $post ) { + $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); - $output_post = new stdClass; - foreach ( $fields as $field ) { - $output_post->$field = $post->$field; - } - $output_posts[] = $output_post; - } - WP_CLI\Utils\format_items( $format, $fields, $output_posts ); - } + $output_posts = $query->posts; + WP_CLI\Utils\format_items( $format, $fields, $output_posts ); } /** From 2037ae14567f85a115bd6a513e7b8184b2421373 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Apr 2013 15:32:16 -0700 Subject: [PATCH 1508/4858] Update man for `wp post list` --- man-src/post-list.txt | 8 +------- man/post-list.1 | 12 ++---------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/man-src/post-list.txt b/man-src/post-list.txt index ad67863679..400e712cc4 100644 --- a/man-src/post-list.txt +++ b/man-src/post-list.txt @@ -4,18 +4,12 @@ One or more args to pass to WP_Query. -* `--ids`: - - Return only the IDs of the found posts, separated by spaces. - * `--format`=<format>: - Output list as table, CSV or JSON. Defaults to table. + Output list as table, CSV, JSON, or simply IDs. Defaults to table. ## EXAMPLES wp post list - wp post list --post_type=page --post_status=draft --ids - wp post list --post_type=post --posts_per_page=5 --format=json diff --git a/man/post-list.1 b/man/post-list.1 index 85a82be0e8..8da81f7a4c 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -7,7 +7,7 @@ \fBwp\-post\-list\fR \- Get a list of posts\. . .SH "SYNOPSIS" -wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] [\-\-format=\fIformat\fR] +wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-format=\fIformat\fR] [\-\-ids] . .SH "OPTIONS" . @@ -18,16 +18,10 @@ wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-ids] [\-\-format=\fIformat\fR] One or more args to pass to WP_Query\. . .TP -\fB\-\-ids\fR: -. -.IP -Return only the IDs of the found posts, separated by spaces\. -. -.TP \fB\-\-format\fR=\fIformat\fR: . .IP -Output list as table, CSV or JSON\. Defaults to table\. +Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. . .SH "EXAMPLES" . @@ -35,8 +29,6 @@ Output list as table, CSV or JSON\. Defaults to table\. wp post list -wp post list \-\-post_type=page \-\-post_status=draft \-\-ids - wp post list \-\-post_type=post \-\-posts_per_page=5 \-\-format=json . .fi From 17757fea7519464c6772af3a6f1957f608179e8a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 01:57:24 +0300 Subject: [PATCH 1509/4858] transparently convert --ids to --format=ids this keeps the back-compat code separate from the command implementation --- man-src/post-list.txt | 2 +- man-src/user-list.txt | 2 +- man/post-list.1 | 4 ++-- man/user-list.1 | 4 ++-- php/WP_CLI/Runner.php | 9 +++++++++ php/commands/post.php | 8 +------- php/commands/user.php | 9 ++------- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/man-src/post-list.txt b/man-src/post-list.txt index 400e712cc4..47849ced93 100644 --- a/man-src/post-list.txt +++ b/man-src/post-list.txt @@ -10,6 +10,6 @@ ## EXAMPLES - wp post list + wp post list --format=ids wp post list --post_type=post --posts_per_page=5 --format=json diff --git a/man-src/user-list.txt b/man-src/user-list.txt index f675f25a0a..d30757b450 100644 --- a/man-src/user-list.txt +++ b/man-src/user-list.txt @@ -10,6 +10,6 @@ ## EXAMPLES - wp user list + wp user list --format=ids wp user list --role=administrator --format=csv diff --git a/man/post-list.1 b/man/post-list.1 index 8da81f7a4c..b20875028b 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -7,7 +7,7 @@ \fBwp\-post\-list\fR \- Get a list of posts\. . .SH "SYNOPSIS" -wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-format=\fIformat\fR] [\-\-ids] +wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -27,7 +27,7 @@ Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. . .nf -wp post list +wp post list \-\-format=ids wp post list \-\-post_type=post \-\-posts_per_page=5 \-\-format=json . diff --git a/man/user-list.1 b/man/user-list.1 index 73c72ba33d..8d66afa59e 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -7,7 +7,7 @@ \fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" -wp user list [\-\-role=\fIrole\fR] [\-\-format=\fIformat\fR] [\-\-ids] +wp user list [\-\-role=\fIrole\fR] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -27,7 +27,7 @@ Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. . .nf -wp user list +wp user list \-\-format=ids wp user list \-\-role=administrator \-\-format=csv . diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 835aba90da..a41f34b67b 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -226,6 +226,15 @@ public function before_wp_load() { unset( $this->assoc_args['all'] ); } + // {post|user} list --ids -> {post|user} list --format=ids + if ( count( $this->arguments ) > 1 && in_array( $this->arguments[0], array( 'post', 'user' ) ) + && $this->arguments[1] == 'list' + && isset( $this->assoc_args['ids'] ) + ) { + $this->assoc_args['format'] = 'ids'; + unset( $this->assoc_args['ids'] ); + } + $config_spec = Utils\get_config_spec(); // Set the path default to the ABSPATH diff --git a/php/commands/post.php b/php/commands/post.php index 88e5c8517e..7dec705411 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -160,19 +160,13 @@ protected function _delete( $post_id, $assoc_args ) { * Get a list of posts. * * @subcommand list - * @synopsis [--<field>=<value>] [--format=<format>] [--ids] + * @synopsis [--<field>=<value>] [--format=<format>] */ public function _list( $_, $assoc_args ) { $query_args = array( 'posts_per_page' => -1 ); - // --ids is deprecated - if ( isset( $assoc_args['ids'] ) ) { - $assoc_args['format'] = 'ids'; - unset( $assoc_args['ids'] ); - } - if ( ! empty( $assoc_args['format'] ) ) { $format = $assoc_args['format']; unset( $assoc_args['format'] ); diff --git a/php/commands/user.php b/php/commands/user.php index f59583ffc3..e96e398431 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -13,7 +13,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * List users. * * @subcommand list - * @synopsis [--role=<role>] [--format=<format>] [--ids] + * @synopsis [--role=<role>] [--format=<format>] */ public function _list( $args, $assoc_args ) { @@ -28,12 +28,6 @@ public function _list( $args, $assoc_args ) { $params['role'] = $assoc_args['role']; } - // --ids is deprecated - if ( isset( $params['ids'] ) ) { - $params['format'] = 'ids'; - unset( $params['ids'] ); - } - if ( 'ids' == $params['format'] ) $params['fields'] = 'ids'; @@ -47,6 +41,7 @@ public function _list( $args, $assoc_args ) { 'user_registered', 'roles' ); + if ( 'ids' != $params['format'] ) { foreach ( $users as $user ) { $user->roles = implode( ',', $user->roles ); From f22aa8e21293fb53c5bec284b4fddfbbc79d6831 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 02:01:10 +0300 Subject: [PATCH 1510/4858] update `wp post delete` example --- man-src/post-delete.txt | 2 +- man/post-delete.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/post-delete.txt b/man-src/post-delete.txt index 7deed70506..d2a614bd81 100644 --- a/man-src/post-delete.txt +++ b/man-src/post-delete.txt @@ -12,4 +12,4 @@ wp post delete 123 --force - wp post delete $(wp post list --post_type='page' --ids) + wp post delete $(wp post list --post_type='page' --format=ids) diff --git a/man/post-delete.1 b/man/post-delete.1 index e301e77332..f163575f26 100644 --- a/man/post-delete.1 +++ b/man/post-delete.1 @@ -29,7 +29,7 @@ Skip the trash bin\. wp post delete 123 \-\-force -wp post delete $(wp post list \-\-post_type=\'page\' \-\-ids) +wp post delete $(wp post list \-\-post_type=\'page\' \-\-format=ids) . .fi From 8895f824acc0b5ce1e53a781c8cd0295ff0973ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Apr 2013 02:01:41 +0300 Subject: [PATCH 1511/4858] use --format=ids in user.feature --- features/user.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index 183986f8da..627a684a23 100644 --- a/features/user.feature +++ b/features/user.feature @@ -25,10 +25,10 @@ Feature: Manage WordPress users Given a WP install # Delete all users - When I run `wp user list --ids` + When I run `wp user list --format=ids` And save STDOUT as {USER_IDS} And I run `wp user delete {USER_IDS}` - When I run `wp user list --ids` + When I run `wp user list --format=ids` Then it should run without errors And STDOUT should be empty From bed5cb0b47e650000a69232b81e45c01b433dc2b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 21:27:00 -0700 Subject: [PATCH 1512/4858] Improvements to `wp term` output * Add `--porcelain` argument to `wp term create` * `wp term create` should include term ID in success message * `wp term delete` includes the term ID of the deleted term * Updated tests / doc See https://github.com/wp-cli/wp-cli/issues/399#issuecomment-16685216 --- features/term.feature | 25 ++++++++++++++++++++----- man-src/term-create.txt | 4 ++++ man/term-create.1 | 8 +++++++- php/commands/term.php | 20 +++++++++++++++----- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/features/term.feature b/features/term.feature index e8be1655b7..47a4219dc0 100644 --- a/features/term.feature +++ b/features/term.feature @@ -3,12 +3,9 @@ Feature: Manage WordPress terms Scenario: Creating/listing a term Given a WP install - When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term'` + When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term' --porcelain` Then it should run without errors - And STDOUT should be: - """ - Success: Term created. - """ + And STDOUT should match '%d' When I run the previous command again Then STDERR should not be empty @@ -19,3 +16,21 @@ Feature: Manage WordPress terms """ [{"name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] """ + + Scenario: Creating/deleting a term + Given a WP install + + When I run `wp term create 'Test delete term' post_tag --slug=test-delete --description='This is a test term to be deleted' --porcelain` + Then it should run without errors + And STDOUT should match '%d' + And save STDOUT as {TERM_ID} + + When I run `wp term delete {TERM_ID} post_tag` + Then it should run without errors + And STDOUT should contain: + """ + Deleted post_tag {TERM_ID}. + """ + + When I run the previous command again + Then STDERR should not be empty diff --git a/man-src/term-create.txt b/man-src/term-create.txt index e34cd38421..46b85b9f05 100644 --- a/man-src/term-create.txt +++ b/man-src/term-create.txt @@ -20,6 +20,10 @@ A parent for the new term. +* `--porcelain`: + + Output just the new term id. + ## EXAMPLES wp term create Apple category --description="A type of fruit" diff --git a/man/term-create.1 b/man/term-create.1 index a5cf4ad564..366ee1a886 100644 --- a/man/term-create.1 +++ b/man/term-create.1 @@ -7,7 +7,7 @@ \fBwp\-term\-create\fR \- Create a term\. . .SH "SYNOPSIS" -wp term create \fIterm\fR \fItaxonomy\fR [\-\-slug=\fIslug\fR] [\-\-description=\fIdescription\fR] [\-\-parent=\fIterm\-id\fR] +wp term create \fIterm\fR \fItaxonomy\fR [\-\-slug=\fIslug\fR] [\-\-description=\fIdescription\fR] [\-\-parent=\fIterm\-id\fR] [\-\-porcelain] . .SH "OPTIONS" . @@ -41,6 +41,12 @@ A description for the new term\. .IP A parent for the new term\. . +.TP +\fB\-\-porcelain\fR: +. +.IP +Output just the new term id\. +. .SH "EXAMPLES" . .nf diff --git a/php/commands/term.php b/php/commands/term.php index c55b585086..12e56bda55 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -43,7 +43,7 @@ public function _list( $args, $assoc_args ) { /** * Create a term. * - * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<term-id>] + * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<term-id>] [--porcelain] */ public function create( $args, $assoc_args ) { @@ -56,12 +56,22 @@ public function create( $args, $assoc_args ) { ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); + if ( isset( $assoc_args['porcelain'] ) ) { + $porcelain = true; + unset( $assoc_args['porcelain'] ); + } else + $porcelain = false; + $ret = wp_insert_term( $term, $taxonomy, $assoc_args ); if ( is_wp_error( $ret ) ) WP_CLI::error( $ret->get_error_message() ); - else - WP_CLI::success( "Term created." ); + else { + if ( $porcelain ) + WP_CLI::line( $ret['term_id'] ); + else + WP_CLI::success( sprintf( "Created %s %d.", $taxonomy, $ret['term_id'] ) ); + } } /** @@ -108,9 +118,9 @@ public function delete( $args ) { if ( is_wp_error( $ret ) ) WP_CLI::error( $ret->get_error_message() ); else if ( $ret ) - WP_CLI::success( "Term deleted." ); + WP_CLI::success( sprintf( "Deleted %s %d.", $taxonomy, $term_id ) ); else - WP_CLI::error( "Error deleting term." ); + WP_CLI::error( "Term doesn't exist." ); } } From 34522269e92b3a818735c457d8a1d1b05bb84e7e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 21:52:57 -0700 Subject: [PATCH 1513/4858] For ease of use, allow a CSV of fields to be passed into `format_items()` --- php/utils.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 3489393d7c..1aaa9a91d0 100644 --- a/php/utils.php +++ b/php/utils.php @@ -252,12 +252,15 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria /** * Output items in a table, JSON, or CSV * - * @param string $format Format to use: 'table', 'json', 'csv' - * @param array $fields Named fields for each item of data - * @param array $items Data to output + * @param string $format Format to use: 'table', 'json', 'csv' + * @param array|string $fields Named fields for each item of data. Can be array or CSV + * @param array $items Data to output */ function format_items( $format, $fields, $items ) { + if ( ! is_array( $fields ) ) + $fields = explode( ',', $fields ); + switch ( $format ) { case 'table': $table = new \cli\Table(); From 298d84ef800d5d11797bb3579a7403d02ab4bb62 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 22:07:20 -0700 Subject: [PATCH 1514/4858] Refactor `format_items()` such that it prepares output items in advance, and validates `$fields` based on the fields avaialble on the object. --- php/utils.php | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/php/utils.php b/php/utils.php index 1aaa9a91d0..d6a0ff5ba3 100644 --- a/php/utils.php +++ b/php/utils.php @@ -261,35 +261,37 @@ function format_items( $format, $fields, $items ) { if ( ! is_array( $fields ) ) $fields = explode( ',', $fields ); + $output_items = array(); + foreach ( $items as $item ) { + + $output_item = new \stdClass; + foreach ( $fields as $key => $field ) { + + if ( ! isset( $item->$field ) ) { + unset( $fields[$key] ); + continue; + } + + $output_item->$field = $item->$field; + } + + $output_items[] = $output_item; + } + switch ( $format ) { case 'table': $table = new \cli\Table(); $table->setHeaders( $fields ); - foreach ( $items as $item ) { - $line = array(); - - foreach ( $fields as $field ) { - $line[] = $item->$field; - } - - $table->addRow( $line ); + foreach ( $output_items as $item ) { + $table->addRow( array_values( (array)$item ) ); } $table->display(); break; case 'csv': case 'json': - $output_items = array(); - - foreach( $items as $item ) { - $output_item = new \stdClass; - foreach( $fields as $field ) { - $output_item->$field = $item->$field; - } - $output_items[] = $output_item; - } if ( 'json' == $format ) echo json_encode( $output_items ); From 62be7cb17287676e6afd4d75bf122ba7fc2768e1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 22:09:54 -0700 Subject: [PATCH 1515/4858] Add `--fields` support to `wp term list`. Needs updated tests and doc. --- php/commands/term.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c55b585086..2a64f1b447 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -6,37 +6,41 @@ */ class Term_Command extends WP_CLI_Command { + public $fields = array( + 'term_id', + 'term_taxonomy_id', + 'name', + 'slug', + 'description', + 'parent', + 'count', + ); + /** * List terms in a taxonomy. * * @subcommand list - * @synopsis <taxonomy> [--format=<format>] + * @synopsis <taxonomy> [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { list( $taxonomy ) = $args; $defaults = array( + 'fields' => implode( ',', $this->fields ), 'format' => 'table', 'hide_empty' => false, ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); + $fields = $assoc_args['fields']; + unset( $assoc_args['fields'] ); + $terms = get_terms( array( $taxonomy ), $assoc_args ); if ( 'ids' == $assoc_args['format'] ) $terms = wp_list_pluck( $terms, 'term_id' ); - $fields = array( - 'term_id', - 'term_taxonomy_id', - 'name', - 'slug', - 'description', - 'parent', - 'count', - ); - WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); } From 61151e7f2e7ffcc282c511992911a4468ca0309b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 22:23:19 -0700 Subject: [PATCH 1516/4858] `--fields` support for `wp role list` --- php/commands/role.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 88c43b0de6..a397dc6adc 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -7,24 +7,28 @@ */ class Role_Command extends WP_CLI_Command { + public $fields = array( + 'name', + 'role' + ); + /** * List all roles. * * @subcommand list - * @synopsis [--format=<format>] + * @synopsis [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { global $wp_roles; $defaults = array( + 'fields' => implode( ',', $this->fields ), 'format' => 'table', ); $params = array_merge( $defaults, $assoc_args ); - $fields = array( - 'name', - 'role', - ); + $fields = $params['fields']; + unset( $params['fields'] ); $output_roles = array(); foreach ( $wp_roles->roles as $key => $role ) { From 2e38aa503a4a82326111c0f8cc1dac00a07497e1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 22:37:18 -0700 Subject: [PATCH 1517/4858] Implement `--fields` support for `wp post list` --- php/commands/post.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 7dec705411..7d966c3bbe 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -9,6 +9,13 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'post'; + public $fields = array( + 'ID', + 'post_title', + 'post_name', + 'post_date' + ); + /** * Create a post. * @@ -160,7 +167,7 @@ protected function _delete( $post_id, $assoc_args ) { * Get a list of posts. * * @subcommand list - * @synopsis [--<field>=<value>] [--format=<format>] + * @synopsis [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $_, $assoc_args ) { $query_args = array( @@ -174,6 +181,13 @@ public function _list( $_, $assoc_args ) { $format = 'table'; } + if ( isset( $assoc_args['fields'] ) ) { + $fields = $assoc_args['fields']; + unset( $assoc_args['fields'] ); + } else { + $fields = $this->fields; + } + foreach ( $assoc_args as $key => $value ) { if ( true === $value ) continue; @@ -186,8 +200,6 @@ public function _list( $_, $assoc_args ) { $query = new WP_Query( $query_args ); - $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); - $output_posts = $query->posts; WP_CLI\Utils\format_items( $format, $fields, $output_posts ); From 30fa02622992cdf1554df8cb152f72ebcbfb27e4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Apr 2013 22:48:25 -0700 Subject: [PATCH 1518/4858] Implement `--fields` support for `wp user list` --- php/commands/user.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index e96e398431..de3245f99e 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -9,39 +9,44 @@ class User_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'user'; + public $fields = array( + 'ID', + 'user_login', + 'display_name', + 'user_email', + 'user_registered', + 'roles' + ); + /** * List users. * * @subcommand list - * @synopsis [--role=<role>] [--format=<format>] + * @synopsis [--role=<role>] [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { $defaults = array( 'blog_id' => get_current_blog_id(), - 'fields' => isset( $assoc_args['ids'] ) ? 'ids' : 'all_with_meta', + 'fields' => implode( ',', $this->fields ), 'format' => 'table', ); $params = array_merge( $defaults, $assoc_args ); + $fields = $params['fields']; + unset( $params['fields'] ); + if ( array_key_exists( 'role', $assoc_args ) ) { $params['role'] = $assoc_args['role']; } if ( 'ids' == $params['format'] ) $params['fields'] = 'ids'; + else + $params['fields'] = 'all_with_meta'; $users = get_users( $params ); - $fields = array( - 'ID', - 'user_login', - 'display_name', - 'user_email', - 'user_registered', - 'roles' - ); - if ( 'ids' != $params['format'] ) { foreach ( $users as $user ) { $user->roles = implode( ',', $user->roles ); From 210ad2f63f09cc940325078b99a1b2c0992572dc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 21 Apr 2013 07:32:11 -0700 Subject: [PATCH 1519/4858] Balance ze curly braces to meet WP standards https://github.com/wp-cli/wp-cli/pull/407/files#r3886566 --- php/commands/term.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 12e56bda55..8adba26cd2 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -59,14 +59,15 @@ public function create( $args, $assoc_args ) { if ( isset( $assoc_args['porcelain'] ) ) { $porcelain = true; unset( $assoc_args['porcelain'] ); - } else + } else { $porcelain = false; + } $ret = wp_insert_term( $term, $taxonomy, $assoc_args ); - if ( is_wp_error( $ret ) ) + if ( is_wp_error( $ret ) ) { WP_CLI::error( $ret->get_error_message() ); - else { + } else { if ( $porcelain ) WP_CLI::line( $ret['term_id'] ); else From 40f6681065b79bbefd734c03747b83e5ee830d9b Mon Sep 17 00:00:00 2001 From: Michael Williamson <mike@zwobble.org> Date: Sun, 21 Apr 2013 22:36:04 +0100 Subject: [PATCH 1520/4858] Don't create temporary wordpress directory during "wp core download" --- php/commands/core.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 3e65fccf81..8f29005a86 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -35,9 +35,11 @@ public function download( $args, $assoc_args ) { } $silent = WP_CLI::get_config('quiet') ? ' --silent ' : ' '; - - WP_CLI::launch( 'curl -f' . $silent . escapeshellarg( $download_url ) . ' | tar xz' ); - WP_CLI::launch( sprintf( 'cp -r wordpress/* %s && rm -rf wordpress', escapeshellarg( ABSPATH ) ) ); + + WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); + $curl_command = 'curl -f' . $silent . escapeshellarg( $download_url ); + $tar_command = sprintf( 'tar xz --directory=%s --strip-components=1', escapeshellarg( ABSPATH ) ); + WP_CLI::launch( $curl_command . ' | ' . $tar_command ); WP_CLI::success( 'WordPress downloaded.' ); } From fef40acd10fc722257ddc323d7fb19ed422a0ab2 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Sun, 21 Apr 2013 23:53:29 +0000 Subject: [PATCH 1521/4858] Add empty_blog subcommand to core --- php/commands/core.php | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 3e65fccf81..d1df7cb994 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -61,6 +61,84 @@ public function config( $args, $assoc_args ) { if ( WP_CLI::get_config('quiet') ) ob_end_clean(); } + /** + * Empty a blog + * + * @synopsis [--post_type] [--empty_terms] [--empty_comments] [--empty_options] + */ + public function empty_blog( $args, $assoc_args ) { + + $assoc_args = wp_parse_args( $assoc_args, array( + 'post_type' => 'all', + 'empty_terms' => 1, + 'empty_comments' => 1, + 'empty_options' => 1, + ) ); + + WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); + + global $wpdb; + + // Empty posts and post cache + $posts_query = "SELECT ID FROM $wpdb->posts"; + if ( 'all' != $assoc_args['post_type'] ) + $posts_query .= " WHERE post_type='$assoc_args[post_type]'"; + + $taxonomies = get_taxonomies(); + $posts = $wpdb->get_col( $posts_query ); + $max = count( $posts ); + foreach ( $posts as $postid ) { + wp_cache_delete( $postid, 'posts' ); + wp_cache_delete( $postid, 'post_meta' ); + foreach ( $taxonomies as $taxonomy ) + wp_cache_delete( $postid, "{$taxonomy}_relationships" ); + wp_cache_delete( $wpdb->blogid . '-' . $postid, 'global-posts' ); + } + $wpdb->query( "TRUNCATE $wpdb->posts" ); + + if ( 'all' == $assoc_args['post_type'] ) + $wpdb->query( "TRUNCATE $wpdb->postmeta" ); + + + // Empty comments and comment cache + if ( 1 == $assoc_args['empty_comments'] ) { + $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments" ); + foreach ( $comment_ids as $comment_id ) { + wp_cache_delete( $comment_id, 'comment' ); + wp_cache_delete( $comment_id, 'comment_meta' ); + } + $wpdb->query( "TRUNCATE $wpdb->comments" ); + $wpdb->query( "TRUNCATE $wpdb->commentmeta" ); + } + + // Empty taxonomies and terms + if ( 1 == $assoc_args['empty_terms'] ) { + $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); + $ids = array(); + foreach ( (array) $terms as $term ) { + $taxonomies[] = $term->taxonomy; + $ids[] = $term->term_id; + wp_cache_delete( $term->term_id, $term->taxonomy ); + } + + $taxonomies = array_unique( $taxonomies ); + foreach ( $taxonomies as $taxonomy ) { + if ( isset( $cleaned[$taxonomy] ) ) + continue; + $cleaned[$taxonomy] = true; + + wp_cache_delete( 'all_ids', $taxonomy ); + wp_cache_delete( 'get', $taxonomy ); + delete_option( "{$taxonomy}_children" ); + } + $wpdb->query( "TRUNCATE $wpdb->terms" ); + $wpdb->query( "TRUNCATE $wpdb->term_taxonomy" ); + $wpdb->query( "TRUNCATE $wpdb->term_relationships" ); + } + + WP_CLI::success( 'The blog at ' . site_url() . ' was emptied.' ); + } + /** * Determine if the WordPress tables are installed. * From 779bb624355c5639e6bba897b62fd925deb31011 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Mon, 22 Apr 2013 00:00:13 +0000 Subject: [PATCH 1522/4858] Remove some old code [closes #406] --- php/commands/core.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d1df7cb994..f14cee5877 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -86,7 +86,6 @@ public function empty_blog( $args, $assoc_args ) { $taxonomies = get_taxonomies(); $posts = $wpdb->get_col( $posts_query ); - $max = count( $posts ); foreach ( $posts as $postid ) { wp_cache_delete( $postid, 'posts' ); wp_cache_delete( $postid, 'post_meta' ); From d77c50ee2a3496b28119b26d54a66392c6b53769 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Mon, 22 Apr 2013 00:19:58 +0000 Subject: [PATCH 1523/4858] Remove empty_options flag --- php/commands/core.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index f14cee5877..840431b44d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -64,7 +64,7 @@ public function config( $args, $assoc_args ) { /** * Empty a blog * - * @synopsis [--post_type] [--empty_terms] [--empty_comments] [--empty_options] + * @synopsis [--post_type] [--empty_terms] [--empty_comments] */ public function empty_blog( $args, $assoc_args ) { @@ -72,7 +72,6 @@ public function empty_blog( $args, $assoc_args ) { 'post_type' => 'all', 'empty_terms' => 1, 'empty_comments' => 1, - 'empty_options' => 1, ) ); WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); From 4b2bf491bee726bf241625faed1f595e1181647a Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Mon, 22 Apr 2013 13:58:28 +0000 Subject: [PATCH 1524/4858] Use WP_CLI\Iterators\Query instead of ->get_col --- php/commands/core.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 840431b44d..2ce416096b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -84,13 +84,18 @@ public function empty_blog( $args, $assoc_args ) { $posts_query .= " WHERE post_type='$assoc_args[post_type]'"; $taxonomies = get_taxonomies(); - $posts = $wpdb->get_col( $posts_query ); - foreach ( $posts as $postid ) { - wp_cache_delete( $postid, 'posts' ); - wp_cache_delete( $postid, 'post_meta' ); + $posts = new WP_CLI\Iterators\Query( $posts_query, 10000 ); + + while ( $posts->valid() ) { + $post_id = $posts->current()->ID; + + wp_cache_delete( $post_id, 'posts' ); + wp_cache_delete( $post_id, 'post_meta' ); foreach ( $taxonomies as $taxonomy ) - wp_cache_delete( $postid, "{$taxonomy}_relationships" ); - wp_cache_delete( $wpdb->blogid . '-' . $postid, 'global-posts' ); + wp_cache_delete( $post_id, "{$taxonomy}_relationships" ); + wp_cache_delete( $wpdb->blogid . '-' . $post_id, 'global-posts' ); + + $posts->next(); } $wpdb->query( "TRUNCATE $wpdb->posts" ); From 1e2f7a84b3b1732596c639b19202743cead23c3c Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Mon, 22 Apr 2013 13:59:42 +0000 Subject: [PATCH 1525/4858] Fix post type argument in comments --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 2ce416096b..0d1721ef41 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -64,7 +64,7 @@ public function config( $args, $assoc_args ) { /** * Empty a blog * - * @synopsis [--post_type] [--empty_terms] [--empty_comments] + * @synopsis [--post_type=<post-type>] [--empty_terms] [--empty_comments] */ public function empty_blog( $args, $assoc_args ) { From a4e4d4ec5515f9e51bf4c22ad84a8472c6fc7a92 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Mon, 22 Apr 2013 14:04:28 +0000 Subject: [PATCH 1526/4858] Change empty_terms and empty_comments to keep_terms and keep_comments --- php/commands/core.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 0d1721ef41..9feeaa9e38 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -64,14 +64,14 @@ public function config( $args, $assoc_args ) { /** * Empty a blog * - * @synopsis [--post_type=<post-type>] [--empty_terms] [--empty_comments] + * @synopsis [--post_type=<post-type>] [--keep_terms] [--keep_comments] */ public function empty_blog( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( 'post_type' => 'all', - 'empty_terms' => 1, - 'empty_comments' => 1, + 'keep_terms' => 0, + 'keep_comments' => 0, ) ); WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); @@ -104,7 +104,7 @@ public function empty_blog( $args, $assoc_args ) { // Empty comments and comment cache - if ( 1 == $assoc_args['empty_comments'] ) { + if ( 0 == $assoc_args['keep_comments'] ) { $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments" ); foreach ( $comment_ids as $comment_id ) { wp_cache_delete( $comment_id, 'comment' ); @@ -115,7 +115,7 @@ public function empty_blog( $args, $assoc_args ) { } // Empty taxonomies and terms - if ( 1 == $assoc_args['empty_terms'] ) { + if ( 0 == $assoc_args['keep_terms'] ) { $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); $ids = array(); foreach ( (array) $terms as $term ) { From b42005e1c3d4ca505a0e507313a4e9f5443df4f7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Apr 2013 16:42:50 +0300 Subject: [PATCH 1527/4858] Simulate and announce a /wp-admin/ page load Most of the built-in commands need access to code from wp-admin/includes/ so it makes sense to load it upfront. Since we're already doing that, it seems like a good idea to also announce this fact to plugins, by setting WP_ADMIN to true. And since we're setting WP_ADMIN to true, we don't need to set up the global $wp_query instance anymore, because the only admin screen where it's set is the post list screen (wp-admin/edit.php). See #385 --- features/core.feature | 14 ++++++++++++++ php/WP_CLI/Runner.php | 3 --- php/utils-wp.php | 7 ------- php/wp-cli.php | 8 ++++++-- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/features/core.feature b/features/core.feature index 87d06872db..60923299c7 100644 --- a/features/core.feature +++ b/features/core.feature @@ -69,6 +69,20 @@ Feature: Manage WordPress installation When I run `wp core is-installed` Then it should run without errors + When I run `wp eval 'var_export( is_admin() );'` + Then it should run without errors + And STDOUT should be: + """ + true + """ + + When I run `wp eval 'var_export( function_exists( 'media_handle_upload' ) );'` + Then it should run without errors + And STDOUT should be: + """ + true + """ + Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a41f34b67b..4af9554eae 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -347,9 +347,6 @@ public function after_wp_load() { Utils\set_user( $this->config ); - if ( !defined( 'WP_INSTALLING' ) && isset( $this->config['url'] ) ) - Utils\set_wp_query(); - if ( isset( $this->config['require'] ) ) require $this->config['require']; diff --git a/php/utils-wp.php b/php/utils-wp.php index 2153d3feeb..1821f7f8c4 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -65,13 +65,6 @@ function set_user( $assoc_args ) { } } -function set_wp_query() { - if ( isset( $GLOBALS['wp_query'] ) && isset( $GLOBALS['wp'] ) ) { - $GLOBALS['wp']->parse_request(); - $GLOBALS['wp_query']->query($GLOBALS['wp']->query_vars); - } -} - function get_upgrader( $class ) { if ( !class_exists( '\WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; diff --git a/php/wp-cli.php b/php/wp-cli.php index a3bc6cd67d..449a19e9f2 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -17,18 +17,22 @@ WP_CLI::$runner->before_wp_load(); -// Load WordPress, in the global scope +// Load wp-config.php code, in the global scope eval( WP_CLI::$runner->get_wp_config_code() ); WP_CLI::$runner->after_wp_config_load(); +// Load main WordPress code, in the global scope require WP_CLI_ROOT . 'wp-settings-cli.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); -// Load all admin utilities +// Simulate a /wp-admin/ page load +$_SERVER['PHP_SELF'] = '/wp-admin/index.php'; +define( 'WP_ADMIN', true ); require ABSPATH . 'wp-admin/includes/admin.php'; +do_action( 'admin_init' ); WP_CLI::$runner->after_wp_load(); From 65eb98d6e7b192118e69773c7f1775e4b2530949 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Apr 2013 19:39:21 +0300 Subject: [PATCH 1528/4858] Define WP_ADMIN before loading WordPress ... where "loading WordPress" also includes loading plugins and themes. Also, define WP_NETWORK_ADMIN and WP_USER_ADMIN, for completeness. see #385 --- php/wp-cli.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 449a19e9f2..f002341c3e 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -22,15 +22,18 @@ WP_CLI::$runner->after_wp_config_load(); -// Load main WordPress code, in the global scope +// Simulate a /wp-admin/ page load +$_SERVER['PHP_SELF'] = '/wp-admin/index.php'; +define( 'WP_ADMIN', true ); +define( 'WP_NETWORK_ADMIN', false ); +define( 'WP_USER_ADMIN', false ); + +// Load Core, mu-plugins, plugins, themes etc. require WP_CLI_ROOT . 'wp-settings-cli.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); -// Simulate a /wp-admin/ page load -$_SERVER['PHP_SELF'] = '/wp-admin/index.php'; -define( 'WP_ADMIN', true ); require ABSPATH . 'wp-admin/includes/admin.php'; do_action( 'admin_init' ); From 53a823ab4b9fb90ad0db0d762db2c0ed02d21bad Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Wed, 24 Apr 2013 04:46:17 +0000 Subject: [PATCH 1529/4858] Moving empty blog subcommand to blog command --- php/commands/core.php | 81 ------------------------------------------- 1 file changed, 81 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9feeaa9e38..3e65fccf81 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -61,87 +61,6 @@ public function config( $args, $assoc_args ) { if ( WP_CLI::get_config('quiet') ) ob_end_clean(); } - /** - * Empty a blog - * - * @synopsis [--post_type=<post-type>] [--keep_terms] [--keep_comments] - */ - public function empty_blog( $args, $assoc_args ) { - - $assoc_args = wp_parse_args( $assoc_args, array( - 'post_type' => 'all', - 'keep_terms' => 0, - 'keep_comments' => 0, - ) ); - - WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); - - global $wpdb; - - // Empty posts and post cache - $posts_query = "SELECT ID FROM $wpdb->posts"; - if ( 'all' != $assoc_args['post_type'] ) - $posts_query .= " WHERE post_type='$assoc_args[post_type]'"; - - $taxonomies = get_taxonomies(); - $posts = new WP_CLI\Iterators\Query( $posts_query, 10000 ); - - while ( $posts->valid() ) { - $post_id = $posts->current()->ID; - - wp_cache_delete( $post_id, 'posts' ); - wp_cache_delete( $post_id, 'post_meta' ); - foreach ( $taxonomies as $taxonomy ) - wp_cache_delete( $post_id, "{$taxonomy}_relationships" ); - wp_cache_delete( $wpdb->blogid . '-' . $post_id, 'global-posts' ); - - $posts->next(); - } - $wpdb->query( "TRUNCATE $wpdb->posts" ); - - if ( 'all' == $assoc_args['post_type'] ) - $wpdb->query( "TRUNCATE $wpdb->postmeta" ); - - - // Empty comments and comment cache - if ( 0 == $assoc_args['keep_comments'] ) { - $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments" ); - foreach ( $comment_ids as $comment_id ) { - wp_cache_delete( $comment_id, 'comment' ); - wp_cache_delete( $comment_id, 'comment_meta' ); - } - $wpdb->query( "TRUNCATE $wpdb->comments" ); - $wpdb->query( "TRUNCATE $wpdb->commentmeta" ); - } - - // Empty taxonomies and terms - if ( 0 == $assoc_args['keep_terms'] ) { - $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); - $ids = array(); - foreach ( (array) $terms as $term ) { - $taxonomies[] = $term->taxonomy; - $ids[] = $term->term_id; - wp_cache_delete( $term->term_id, $term->taxonomy ); - } - - $taxonomies = array_unique( $taxonomies ); - foreach ( $taxonomies as $taxonomy ) { - if ( isset( $cleaned[$taxonomy] ) ) - continue; - $cleaned[$taxonomy] = true; - - wp_cache_delete( 'all_ids', $taxonomy ); - wp_cache_delete( 'get', $taxonomy ); - delete_option( "{$taxonomy}_children" ); - } - $wpdb->query( "TRUNCATE $wpdb->terms" ); - $wpdb->query( "TRUNCATE $wpdb->term_taxonomy" ); - $wpdb->query( "TRUNCATE $wpdb->term_relationships" ); - } - - WP_CLI::success( 'The blog at ' . site_url() . ' was emptied.' ); - } - /** * Determine if the WordPress tables are installed. * From 5e8ea533730160b883898c734ba67039b499ca90 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Wed, 24 Apr 2013 04:47:15 +0000 Subject: [PATCH 1530/4858] Move empty blog subcommand to blog command; create separate class for multi-site commands so that we can make blog available to single site installations --- php/commands/blog.php | 156 +++++++++++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 33 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index b7af961037..0eef48b7f6 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -1,12 +1,130 @@ <?php /** - * Manage blogs in a multisite install. + * Manage blog(s) * * @package wp-cli */ class Blog_Command extends WP_CLI_Command { + /** + * Empty a blog + * + * @synopsis [--post_type=<post-type>] [--keep_terms] [--keep_comments] + */ + public function truncate( $args, $assoc_args ) { + + $assoc_args = wp_parse_args( $assoc_args, array( + 'post_type' => 'all', + 'keep_terms' => 0, + 'keep_comments' => 0, + ) ); + + WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); + + global $wpdb; + + // Empty posts and post cache + $posts_query = "SELECT ID FROM $wpdb->posts"; + if ( 'all' != $assoc_args['post_type'] ) + $posts_query .= " WHERE post_type='$assoc_args[post_type]'"; + + $taxonomies = get_taxonomies(); + $posts = new WP_CLI\Iterators\Query( $posts_query, 10000 ); + + while ( $posts->valid() ) { + $post_id = $posts->current()->ID; + + wp_cache_delete( $post_id, 'posts' ); + wp_cache_delete( $post_id, 'post_meta' ); + foreach ( $taxonomies as $taxonomy ) + wp_cache_delete( $post_id, "{$taxonomy}_relationships" ); + wp_cache_delete( $wpdb->blogid . '-' . $post_id, 'global-posts' ); + + $posts->next(); + } + $wpdb->query( "TRUNCATE $wpdb->posts" ); + + if ( 'all' == $assoc_args['post_type'] ) + $wpdb->query( "TRUNCATE $wpdb->postmeta" ); + + + // Empty comments and comment cache + if ( 0 == $assoc_args['keep_comments'] ) { + $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments" ); + foreach ( $comment_ids as $comment_id ) { + wp_cache_delete( $comment_id, 'comment' ); + wp_cache_delete( $comment_id, 'comment_meta' ); + } + $wpdb->query( "TRUNCATE $wpdb->comments" ); + $wpdb->query( "TRUNCATE $wpdb->commentmeta" ); + } + + // Empty taxonomies and terms + if ( 0 == $assoc_args['keep_terms'] ) { + $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); + $ids = array(); + foreach ( (array) $terms as $term ) { + $taxonomies[] = $term->taxonomy; + $ids[] = $term->term_id; + wp_cache_delete( $term->term_id, $term->taxonomy ); + } + + $taxonomies = array_unique( $taxonomies ); + foreach ( $taxonomies as $taxonomy ) { + if ( isset( $cleaned[$taxonomy] ) ) + continue; + $cleaned[$taxonomy] = true; + + wp_cache_delete( 'all_ids', $taxonomy ); + wp_cache_delete( 'get', $taxonomy ); + delete_option( "{$taxonomy}_children" ); + } + $wpdb->query( "TRUNCATE $wpdb->terms" ); + $wpdb->query( "TRUNCATE $wpdb->term_taxonomy" ); + $wpdb->query( "TRUNCATE $wpdb->term_relationships" ); + } + + WP_CLI::success( 'The blog at ' . site_url() . ' was emptied.' ); + } +} + +/** + * Manage blogs in a multisite install + */ +class MS_Blog_Command extends Blog_Command { + + public function __construct() { } + + /** + * Delete a blog in a multisite install. + * + * @synopsis [<blog-id>] [--slug=<slug>] [--yes] [--keep-tables] + */ + function delete( $args, $assoc_args ) { + if ( isset( $assoc_args['slug'] ) ) { + $blog = get_blog_details( trim( $assoc_args['slug'], '/' ) ); + } else { + if ( empty( $args ) ) { + WP_CLI::error( "Need to specify a blog id." ); + } + + $blog_id = $args[0]; + + $blog = get_blog_details( $blog_id ); + } + + if ( !$blog ) { + WP_CLI::error( "Blog not found." ); + } + + WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl blog?", $assoc_args ); + + wpmu_delete_blog( $blog->blog_id, !isset( $assoc_args['keep-tables'] ) ); + + WP_CLI::success( "The blog at $blog->siteurl was deleted." ); + } + /** * Get site (network) data for a given id * @@ -123,39 +241,11 @@ public function create( $_, $assoc_args ) { else WP_CLI::success( "Blog $id created: $url" ); } - - /** - * Delete a blog in a multisite install. - * - * @synopsis [<blog-id>] [--slug=<slug>] [--yes] [--keep-tables] - */ - function delete( $args, $assoc_args ) { - if ( isset( $assoc_args['slug'] ) ) { - $blog = get_blog_details( trim( $assoc_args['slug'], '/' ) ); - } else { - if ( empty( $args ) ) { - WP_CLI::error( "Need to specify a blog id." ); - } - - $blog_id = $args[0]; - - $blog = get_blog_details( $blog_id ); - } - - if ( !$blog ) { - WP_CLI::error( "Blog not found." ); - } - - WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl blog?", $assoc_args ); - - wpmu_delete_blog( $blog->blog_id, !isset( $assoc_args['keep-tables'] ) ); - - WP_CLI::success( "The blog at $blog->siteurl was deleted." ); - } } -if ( function_exists( 'is_multisite' ) && !is_multisite() ) - return; +$command_class = 'Blog_Command'; +if ( function_exists( 'is_multisite' ) && is_multisite() ) + $command_class = 'MS_Blog_Command'; -WP_CLI::add_command( 'blog', 'Blog_Command' ); +WP_CLI::add_command( 'blog', $command_class ); From 99b65aa57af98e21113b1f5e382144a1d3543822 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Wed, 24 Apr 2013 13:39:56 +0000 Subject: [PATCH 1531/4858] Rename wp blog truncate to wp blog empty --- php/commands/blog.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index 0eef48b7f6..7b046fb8a3 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -10,9 +10,10 @@ class Blog_Command extends WP_CLI_Command { /** * Empty a blog * + * @subcommand empty * @synopsis [--post_type=<post-type>] [--keep_terms] [--keep_comments] */ - public function truncate( $args, $assoc_args ) { + public function _empty( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( 'post_type' => 'all', From 108b485fb68e1bfc2ccafcafce7750aa54637a11 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Thu, 25 Apr 2013 02:57:17 +0000 Subject: [PATCH 1532/4858] Remove empty subcommands args; move empty terms/taxes, posts, and comments; insert default terms/taxes --- php/commands/blog.php | 133 ++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 49 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index 7b046fb8a3..32229c6848 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -8,30 +8,32 @@ class Blog_Command extends WP_CLI_Command { /** - * Empty a blog - * - * @subcommand empty - * @synopsis [--post_type=<post-type>] [--keep_terms] [--keep_comments] + * Delete comments */ - public function _empty( $args, $assoc_args ) { - - $assoc_args = wp_parse_args( $assoc_args, array( - 'post_type' => 'all', - 'keep_terms' => 0, - 'keep_comments' => 0, - ) ); + private function _empty_comments() { + global $wpdb; - WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); + // Empty comments and comment cache + $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments" ); + foreach ( $comment_ids as $comment_id ) { + wp_cache_delete( $comment_id, 'comment' ); + wp_cache_delete( $comment_id, 'comment_meta' ); + } + $wpdb->query( "TRUNCATE $wpdb->comments" ); + $wpdb->query( "TRUNCATE $wpdb->commentmeta" ); + } + /** + * Delete all posts + */ + private function _empty_posts() { global $wpdb; // Empty posts and post cache $posts_query = "SELECT ID FROM $wpdb->posts"; - if ( 'all' != $assoc_args['post_type'] ) - $posts_query .= " WHERE post_type='$assoc_args[post_type]'"; + $posts = new WP_CLI\Iterators\Query( $posts_query, 10000 ); $taxonomies = get_taxonomies(); - $posts = new WP_CLI\Iterators\Query( $posts_query, 10000 ); while ( $posts->valid() ) { $post_id = $posts->current()->ID; @@ -45,47 +47,80 @@ public function _empty( $args, $assoc_args ) { $posts->next(); } $wpdb->query( "TRUNCATE $wpdb->posts" ); + $wpdb->query( "TRUNCATE $wpdb->postmeta" ); + } - if ( 'all' == $assoc_args['post_type'] ) - $wpdb->query( "TRUNCATE $wpdb->postmeta" ); - + /** + * Delete terms, taxonomies, and tax relationships + */ + private function _empty_taxonomies() { + global $wpdb; - // Empty comments and comment cache - if ( 0 == $assoc_args['keep_comments'] ) { - $comment_ids = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments" ); - foreach ( $comment_ids as $comment_id ) { - wp_cache_delete( $comment_id, 'comment' ); - wp_cache_delete( $comment_id, 'comment_meta' ); - } - $wpdb->query( "TRUNCATE $wpdb->comments" ); - $wpdb->query( "TRUNCATE $wpdb->commentmeta" ); + // Empty taxonomies and terms + $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); + $ids = array(); + foreach ( (array) $terms as $term ) { + $taxonomies[] = $term->taxonomy; + $ids[] = $term->term_id; + wp_cache_delete( $term->term_id, $term->taxonomy ); + } + + $taxonomies = array_unique( $taxonomies ); + foreach ( $taxonomies as $taxonomy ) { + if ( isset( $cleaned[$taxonomy] ) ) + continue; + $cleaned[$taxonomy] = true; + + wp_cache_delete( 'all_ids', $taxonomy ); + wp_cache_delete( 'get', $taxonomy ); + delete_option( "{$taxonomy}_children" ); } + $wpdb->query( "TRUNCATE $wpdb->terms" ); + $wpdb->query( "TRUNCATE $wpdb->term_taxonomy" ); + $wpdb->query( "TRUNCATE $wpdb->term_relationships" ); + } - // Empty taxonomies and terms - if ( 0 == $assoc_args['keep_terms'] ) { - $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); - $ids = array(); - foreach ( (array) $terms as $term ) { - $taxonomies[] = $term->taxonomy; - $ids[] = $term->term_id; - wp_cache_delete( $term->term_id, $term->taxonomy ); - } - - $taxonomies = array_unique( $taxonomies ); - foreach ( $taxonomies as $taxonomy ) { - if ( isset( $cleaned[$taxonomy] ) ) - continue; - $cleaned[$taxonomy] = true; - - wp_cache_delete( 'all_ids', $taxonomy ); - wp_cache_delete( 'get', $taxonomy ); - delete_option( "{$taxonomy}_children" ); + /** + * Insert default terms + */ + private function _insert_default_terms() { + global $wpdb; + + // Default category + $cat_name = __( 'Uncategorized' ); + + /* translators: Default category slug */ + $cat_slug = sanitize_title( _x( 'Uncategorized', 'Default category slug' ) ); + + if ( global_terms_enabled() ) { + $cat_id = $wpdb->get_var( $wpdb->prepare( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = %s", $cat_slug ) ); + if ( $cat_id == null ) { + $wpdb->insert( $wpdb->sitecategories, array('cat_ID' => 0, 'cat_name' => $cat_name, 'category_nicename' => $cat_slug, 'last_updated' => current_time('mysql', true)) ); + $cat_id = $wpdb->insert_id; } - $wpdb->query( "TRUNCATE $wpdb->terms" ); - $wpdb->query( "TRUNCATE $wpdb->term_taxonomy" ); - $wpdb->query( "TRUNCATE $wpdb->term_relationships" ); + update_option('default_category', $cat_id); + } else { + $cat_id = 1; } + $wpdb->insert( $wpdb->terms, array('term_id' => $cat_id, 'name' => $cat_name, 'slug' => $cat_slug, 'term_group' => 0) ); + $wpdb->insert( $wpdb->term_taxonomy, array('term_id' => $cat_id, 'taxonomy' => 'category', 'description' => '', 'parent' => 0, 'count' => 1)); + } + + /** + * Empty a blog + * + * @subcommand empty + */ + public function _empty( $args, $assoc_args ) { + + WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); + + $this->_empty_posts(); + $this->_empty_comments(); + $this->_empty_taxonomies(); + $this->_insert_default_terms(); + WP_CLI::success( 'The blog at ' . site_url() . ' was emptied.' ); } } From 6bccb80d7619f47391a44df3f5d884e5986f68d7 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Wed, 27 Mar 2013 15:03:45 -0700 Subject: [PATCH 1533/4858] Initial implementation of wp media import Introduces `wp media import` command to sideload images and import them as attachments. Needs tests, second opinion, etc. --- man-src/media-import.txt | 20 +++++++++++++++++++ man/media-import.1 | 43 ++++++++++++++++++++++++++++++++++++++++ php/commands/media.php | 39 ++++++++++++++++++++++++++++++++++++ utils/wp-completion.bash | 7 +++++-- 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 man-src/media-import.txt create mode 100644 man/media-import.1 diff --git a/man-src/media-import.txt b/man-src/media-import.txt new file mode 100644 index 0000000000..ed910ff5de --- /dev/null +++ b/man-src/media-import.txt @@ -0,0 +1,20 @@ +## OPTIONS + +* `<file>`: + + Path to file or files to be imported. Supports the glob(3) capabilities of the current shell. + +* `--post-id=<post_id>` + + ID of the post to attach the imported files to. + +* `--desc=<description>` + + "Description" field (post title) of attachment post + + +## EXAMPLES + + wp media import ~/Pictures/**/*.jpg + + wp media import ~/Downloads/image.png --post_id=123 --desc="A downloaded picture" diff --git a/man/media-import.1 b/man/media-import.1 new file mode 100644 index 0000000000..304529c6b8 --- /dev/null +++ b/man/media-import.1 @@ -0,0 +1,43 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-MEDIA\-IMPORT" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-media\-import\fR \- Sideload images from file(s) and import as attachments, optionally attached to a post +. +.SH "SYNOPSIS" +wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-desc=\fIdescription\fR] +. +.SH "OPTIONS" +. +.IP "\(bu" 4 +\fB<file>\fR: +. +.IP +Path to file or files to be imported\. Supports the glob(3) capabilities of the current shell\. +. +.IP "\(bu" 4 +\fB\-\-post\-id=<post_id>\fR +. +.IP +ID of the post to attach the imported files to\. +. +.IP "\(bu" 4 +\fB\-\-desc=<description>\fR +. +.IP +"Description" field (post title) of attachment post +. +.IP "" 0 +. +.SH "EXAMPLES" +. +.nf + +wp media import ~/Pictures/**/*\.jpg + +wp media import ~/Downloads/image\.png \-\-post_id=123 \-\-desc="A downloaded picture" +. +.fi + diff --git a/php/commands/media.php b/php/commands/media.php index 36c37ac917..2ac40ad8b0 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -53,6 +53,45 @@ function regenerate( $args, $assoc_args = array() ) { WP_CLI::success( sprintf( 'Finished regenerating %1$s.', ngettext('the image', 'all images', $count) ) ); } + /** + * Sideload images from file(s) and import as attachments, optionally attached to a post + * + * @synopsis <file>... [--post_id=<post_id>] [--desc=<description>] + */ + function import( $args, $assoc_args = array() ) { + + $assoc_args = wp_parse_args( + $assoc_args, + array( + 'post_id' => 0, + ) + ); + + foreach( $args as $file ) { + $file_array = array( + 'tmp_name' => $file, + 'name' => basename( $file ) + ); + $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['desc'] ); + if ( is_wp_error( $success ) ) + WP_CLI::error( + sprintf( + 'Unable to import file %s. Reason: %s', + $file_array['tmp_name'], implode( ', ', $success->get_error_messages() ) + ) + ); + else + WP_CLI::success( + sprintf( + 'Successfully imported file %s as attachment ID %d.', + $file_array['tmp_name'], $success + ) + ); + } + + } + + private function _process_regeneration( $id ) { $image = get_post( $id ); diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index f3822d3503..d78f1001aa 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -1,7 +1,7 @@ # bash completion for the wp command _wp() { - local cur prev opts + local cur prev opts file_ops cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} @@ -12,7 +12,10 @@ _wp() { opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2- | tr '\n' ' ') fi - if [[ 'create' = $prev ]]; then + # An array of prev keywords that should get file completion + declare -A file_ops=([create]=1 [import]=1) + + if [[ ${file_ops[$prev]} ]]; then COMPREPLY=( $(compgen -f "$cur") ) else COMPREPLY=( $(compgen -W "$opts" -- $cur) ) From dd70a96efc41870cebcd3c54dd24ec4d3805bc54 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Wed, 27 Mar 2013 17:24:51 -0700 Subject: [PATCH 1534/4858] Add capability to download files from URL If a recognizable scheme is passed in the <file> argument, `wp media import` will attempt to download the file to a temp directory before importing it. --- man-src/media-import.txt | 2 ++ man/media-import.1 | 2 +- php/commands/media.php | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/man-src/media-import.txt b/man-src/media-import.txt index ed910ff5de..d619298482 100644 --- a/man-src/media-import.txt +++ b/man-src/media-import.txt @@ -3,6 +3,8 @@ * `<file>`: Path to file or files to be imported. Supports the glob(3) capabilities of the current shell. + If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be + downloaded to a temp file before being sideloaded. * `--post-id=<post_id>` diff --git a/man/media-import.1 b/man/media-import.1 index 304529c6b8..9bce04bc94 100644 --- a/man/media-import.1 +++ b/man/media-import.1 @@ -15,7 +15,7 @@ wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-desc=\fIdescri \fB<file>\fR: . .IP -Path to file or files to be imported\. Supports the glob(3) capabilities of the current shell\. +Path to file or files to be imported\. Supports the glob(3) capabilities of the current shell\. If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be downloaded to a temp file before being sideloaded\. . .IP "\(bu" 4 \fB\-\-post\-id=<post_id>\fR diff --git a/php/commands/media.php b/php/commands/media.php index 2ac40ad8b0..475972e4d0 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -54,7 +54,7 @@ function regenerate( $args, $assoc_args = array() ) { } /** - * Sideload images from file(s) and import as attachments, optionally attached to a post + * Sideload images from local file(s) or URL and import as attachments, optionally attached to a post * * @synopsis <file>... [--post_id=<post_id>] [--desc=<description>] */ @@ -64,10 +64,26 @@ function import( $args, $assoc_args = array() ) { $assoc_args, array( 'post_id' => 0, + 'desc' => null ) ); foreach( $args as $file ) { + + $is_file_remote = parse_url( $file, PHP_URL_SCHEME ); + + if ( !empty( $is_file_remote ) ) { + $extension = pathinfo( $file, PATHINFO_EXTENSION ); + $tempfile = download_url( $file ); + + // Necessary because temp filename will probably have an extension like + // .tmp, which is not in the list of permitted upload extensions + // and won't be recognized with the correct mime type + $tempfile_extension = pathinfo( $tempfile, PATHINFO_EXTENSION ); + $file = preg_replace( "/$tempfile_extension$/", $extension, $tempfile ); + rename( $tempfile, $file ); + } + $file_array = array( 'tmp_name' => $file, 'name' => basename( $file ) From 51be561678556db85d2afbcdeff4eaa945a5188d Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 28 Mar 2013 10:19:28 -0700 Subject: [PATCH 1535/4858] Remove filename completion for wp media import Filtering bash completions breaks bash's default filename globbing, which is a more useful feature here. --- utils/wp-completion.bash | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index d78f1001aa..f3822d3503 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -1,7 +1,7 @@ # bash completion for the wp command _wp() { - local cur prev opts file_ops + local cur prev opts cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} @@ -12,10 +12,7 @@ _wp() { opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2- | tr '\n' ' ') fi - # An array of prev keywords that should get file completion - declare -A file_ops=([create]=1 [import]=1) - - if [[ ${file_ops[$prev]} ]]; then + if [[ 'create' = $prev ]]; then COMPREPLY=( $(compgen -f "$cur") ) else COMPREPLY=( $(compgen -W "$opts" -- $cur) ) From f25992520584fc05f1af589ac608aa04a9f8780f Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 28 Mar 2013 10:21:07 -0700 Subject: [PATCH 1536/4858] Rename arguments to make more logical sense Use the same field labels as are used by the admin media uploader, to avoid confusion: title / caption / alt / description; rather than the variable names used internally, where 'description' is really title and so on. --- man-src/media-import.txt | 24 ++++++++++++++++++++---- man/media-import.1 | 32 ++++++++++++++++++++++++++------ php/commands/media.php | 18 ++++++++++++++++-- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/man-src/media-import.txt b/man-src/media-import.txt index d619298482..e937ada5d4 100644 --- a/man-src/media-import.txt +++ b/man-src/media-import.txt @@ -6,17 +6,33 @@ If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be downloaded to a temp file before being sideloaded. -* `--post-id=<post_id>` +* `--post_id=<post_id>` - ID of the post to attach the imported files to. + ID of the post to attach the imported files to + +* `--title=<title>` + + Attachment title (post title field) + +* `--caption=<caption>` + + Caption for attachent (post excerpt field) + +* `--alt=<alt_text>` + + Alt text for image (saved as post meta) * `--desc=<description>` - "Description" field (post title) of attachment post + "Description" field (post content) of attachment post ## EXAMPLES wp media import ~/Pictures/**/*.jpg - wp media import ~/Downloads/image.png --post_id=123 --desc="A downloaded picture" + wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" + + wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" + + diff --git a/man/media-import.1 b/man/media-import.1 index 9bce04bc94..0af6e249ad 100644 --- a/man/media-import.1 +++ b/man/media-import.1 @@ -4,10 +4,10 @@ .TH "WP\-MEDIA\-IMPORT" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-media\-import\fR \- Sideload images from file(s) and import as attachments, optionally attached to a post +\fBwp\-media\-import\fR \- Sideload images from local file(s) or URL and import as attachments, optionally attached to a post . .SH "SYNOPSIS" -wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-desc=\fIdescription\fR] +wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fIalt_text\fR] [\-\-desc=\fIdescription\fR] . .SH "OPTIONS" . @@ -18,16 +18,34 @@ wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-desc=\fIdescri Path to file or files to be imported\. Supports the glob(3) capabilities of the current shell\. If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be downloaded to a temp file before being sideloaded\. . .IP "\(bu" 4 -\fB\-\-post\-id=<post_id>\fR +\fB\-\-post_id=<post_id>\fR . .IP -ID of the post to attach the imported files to\. +ID of the post to attach the imported files to +. +.IP "\(bu" 4 +\fB\-\-title=<title>\fR +. +.IP +Attachment title (post title field) +. +.IP "\(bu" 4 +\fB\-\-caption=<caption>\fR +. +.IP +Caption for attachent (post excerpt field) +. +.IP "\(bu" 4 +\fB\-\-alt=<alt_text>\fR +. +.IP +Alt text for image (saved as post meta) . .IP "\(bu" 4 \fB\-\-desc=<description>\fR . .IP -"Description" field (post title) of attachment post +"Description" field (post content) of attachment post . .IP "" 0 . @@ -37,7 +55,9 @@ ID of the post to attach the imported files to\. wp media import ~/Pictures/**/*\.jpg -wp media import ~/Downloads/image\.png \-\-post_id=123 \-\-desc="A downloaded picture" +wp media import ~/Downloads/image\.png \-\-post_id=123 \-\-title="A downloaded picture" + +wp media import http://s\.wordpress\.org/style/images/wp\-header\-logo\.png \-\-title=\'The WordPress logo\' \-\-alt="Semantic personal publishing" . .fi diff --git a/php/commands/media.php b/php/commands/media.php index 475972e4d0..be4eebf82b 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -56,7 +56,7 @@ function regenerate( $args, $assoc_args = array() ) { /** * Sideload images from local file(s) or URL and import as attachments, optionally attached to a post * - * @synopsis <file>... [--post_id=<post_id>] [--desc=<description>] + * @synopsis <file>... [--post_id=<post_id>] [--title=<title>] [--caption=<caption>] [--alt=<alt_text>] [--desc=<description>] */ function import( $args, $assoc_args = array() ) { @@ -64,6 +64,9 @@ function import( $args, $assoc_args = array() ) { $assoc_args, array( 'post_id' => 0, + 'title' => null, + 'caption' => null, + 'alt' => null, 'desc' => null ) ); @@ -88,7 +91,18 @@ function import( $args, $assoc_args = array() ) { 'tmp_name' => $file, 'name' => basename( $file ) ); - $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['desc'] ); + + $post_array= array( + 'post_title' => $assoc_args['title'], + 'post_excerpt' => $assoc_args['caption'], + 'post_content' => $assoc_args['desc'] + ); + + $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); + + if ( !is_wp_error( $success ) && $assoc_args['alt'] ) + update_post_meta( $success, '_wp_attachment_image_alt', $assoc_args['alt'] ); + if ( is_wp_error( $success ) ) WP_CLI::error( sprintf( From bc620eb45cf2920a9110f659ed3ad46744aff403 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Wed, 17 Apr 2013 17:01:53 -0700 Subject: [PATCH 1537/4858] Add Behat feature for `wp media import` --- features/media.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/media.feature b/features/media.feature index 6afe09198b..7521376b2b 100644 --- a/features/media.feature +++ b/features/media.feature @@ -9,3 +9,12 @@ Feature: Manage WordPress attachments """ Error: Unable to find the images """ + + Scenario: Import image from remote URL + Given a WP install + + When I run `wp media import 'http://s.wordpress.org/style/images/codeispoetry.png' --post_id=1` + Then STDOUT should contain: + """ + Success: Successfully imported file /tmp/codeispoetry.png + """ From d170024c17febf975b8c3bd5a10e5e45a614e925 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 25 Apr 2013 12:40:29 -0700 Subject: [PATCH 1538/4858] Add `--featured_image` associative arg This flag will set the uploaded image to be the post thumbnail of the post its attached to. Also, fix the success message and the Behat feature, so that tests don't fail on environments that use a different tmp path. --- features/media.feature | 2 +- php/commands/media.php | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/features/media.feature b/features/media.feature index 7521376b2b..c247d68600 100644 --- a/features/media.feature +++ b/features/media.feature @@ -16,5 +16,5 @@ Feature: Manage WordPress attachments When I run `wp media import 'http://s.wordpress.org/style/images/codeispoetry.png' --post_id=1` Then STDOUT should contain: """ - Success: Successfully imported file /tmp/codeispoetry.png + Success: Imported file http://s.wordpress.org/style/images/codeispoetry.png """ diff --git a/php/commands/media.php b/php/commands/media.php index be4eebf82b..1e946f400b 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -56,7 +56,7 @@ function regenerate( $args, $assoc_args = array() ) { /** * Sideload images from local file(s) or URL and import as attachments, optionally attached to a post * - * @synopsis <file>... [--post_id=<post_id>] [--title=<title>] [--caption=<caption>] [--alt=<alt_text>] [--desc=<description>] + * @synopsis <file>... [--post_id=<post_id>] [--title=<title>] [--caption=<caption>] [--alt=<alt_text>] [--desc=<description>] [--featured_image] */ function import( $args, $assoc_args = array() ) { @@ -74,6 +74,7 @@ function import( $args, $assoc_args = array() ) { foreach( $args as $file ) { $is_file_remote = parse_url( $file, PHP_URL_SCHEME ); + $orig_filename = $file; if ( !empty( $is_file_remote ) ) { $extension = pathinfo( $file, PATHINFO_EXTENSION ); @@ -100,21 +101,31 @@ function import( $args, $assoc_args = array() ) { $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); + // Set alt text if ( !is_wp_error( $success ) && $assoc_args['alt'] ) update_post_meta( $success, '_wp_attachment_image_alt', $assoc_args['alt'] ); + // Set as featured image, if --post_id and --featured_image are set + if ( !is_wp_error( $success ) && $assoc_args['post_id'] && $assoc_args['featured_image'] ) + update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); + + $attachment_success_text = ( $assoc_args['post_id'] && get_post( $assoc_args['post_id'] ) ) ? + " and attached to post {$assoc_args['post_id']}" . + ( ( $assoc_args['featured_image'] ) ? ' as featured image' : '' ) + : ''; + if ( is_wp_error( $success ) ) WP_CLI::error( sprintf( 'Unable to import file %s. Reason: %s', - $file_array['tmp_name'], implode( ', ', $success->get_error_messages() ) + $orig_filename, implode( ', ', $success->get_error_messages() ) ) ); else WP_CLI::success( sprintf( - 'Successfully imported file %s as attachment ID %d.', - $file_array['tmp_name'], $success + 'Imported file %s as attachment ID %d%s.', + $orig_filename, $success, $attachment_success_text ) ); } From 661169fd55ee5124cf0003665cede7c37e8e1f6e Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Thu, 25 Apr 2013 13:22:03 -0700 Subject: [PATCH 1539/4858] Update man page for `wp media import` Add option description for `--featured_image`, and briefly explain examples --- man-src/media-import.txt | 9 ++++++++- man/media-import.1 | 13 +++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/man-src/media-import.txt b/man-src/media-import.txt index e937ada5d4..5f7e7d1dce 100644 --- a/man-src/media-import.txt +++ b/man-src/media-import.txt @@ -26,13 +26,20 @@ "Description" field (post content) of attachment post +* `--featured_image` + + If set, set the imported image as the Featured Image of the post its attached to. + ## EXAMPLES + # Import all jpgs in the current user's "Pictures" directory, not attached to any post wp media import ~/Pictures/**/*.jpg - wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" + # Import a local image and set it to be the post thumbnail for a post + wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image + # Import an image from the web wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" diff --git a/man/media-import.1 b/man/media-import.1 index 0af6e249ad..03bb00ae09 100644 --- a/man/media-import.1 +++ b/man/media-import.1 @@ -7,7 +7,7 @@ \fBwp\-media\-import\fR \- Sideload images from local file(s) or URL and import as attachments, optionally attached to a post . .SH "SYNOPSIS" -wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fIalt_text\fR] [\-\-desc=\fIdescription\fR] +wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fIalt_text\fR] [\-\-desc=\fIdescription\fR] [\-\-featured_image] . .SH "OPTIONS" . @@ -47,16 +47,25 @@ Alt text for image (saved as post meta) .IP "Description" field (post content) of attachment post . +.IP "\(bu" 4 +\fB\-\-featured_image\fR +. +.IP +If set, set the imported image as the Featured Image of the post its attached to\. +. .IP "" 0 . .SH "EXAMPLES" . .nf +# Import all jpgs in the current user\'s "Pictures" directory, not attached to any post wp media import ~/Pictures/**/*\.jpg -wp media import ~/Downloads/image\.png \-\-post_id=123 \-\-title="A downloaded picture" +# Import a local image and set it to be the post thumbnail for a post +wp media import ~/Downloads/image\.png \-\-post_id=123 \-\-title="A downloaded picture" \-\-featured_image +# Import an image from the web wp media import http://s\.wordpress\.org/style/images/wp\-header\-logo\.png \-\-title=\'The WordPress logo\' \-\-alt="Semantic personal publishing" . .fi From e3858df53cd0748bbc5fcaa7e956f8b1e9929911 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 26 Apr 2013 20:43:10 +0300 Subject: [PATCH 1540/4858] check for __invoke() method instead of parameter type --- php/class-wp-cli.php | 32 ++++++++++++++++---------------- php/commands/eval-file.php | 2 +- php/commands/eval.php | 2 +- php/commands/export.php | 2 +- php/commands/help.php | 2 +- php/commands/home.php | 3 +-- php/commands/search-replace.php | 2 +- php/commands/shell.php | 2 +- 8 files changed, 23 insertions(+), 24 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1f453e1c7f..3b579bef1a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -31,24 +31,32 @@ static function init() { * Add a command to the wp-cli list of commands * * @param string $name The name of the command that will be used in the cli - * @param string|object $implementation The command implementation + * @param string $class The command implementation */ - static function add_command( $name, $implementation ) { + static function add_command( $name, $class ) { if ( in_array( $name, self::get_config('disabled_commands') ) ) return; - if ( is_string( $implementation ) ) { - $command = self::create_composite_command( $name, $implementation ); + $reflection = new \ReflectionClass( $class ); + + if ( $reflection->hasMethod( '__invoke' ) ) { + $command = self::create_atomic_command( $name, $reflection ); } else { - $command = self::create_atomic_command( $name, $implementation ); + $command = self::create_composite_command( $name, $reflection ); } self::$root->add_subcommand( $name, $command ); } - private static function create_composite_command( $name, $class ) { - $reflection = new \ReflectionClass( $class ); + private static function create_atomic_command( $name, $reflection ) { + $method = $reflection->getMethod( '__invoke' ); + + $docparser = new \WP_CLI\DocParser( $method ); + + return new Dispatcher\Subcommand( self::$root, $name, $reflection->name, $docparser ); + } + private static function create_composite_command( $name, $reflection ) { $docparser = new \WP_CLI\DocParser( $reflection ); $container = new Dispatcher\CompositeCommand( $name, $docparser->get_shortdesc() ); @@ -57,7 +65,7 @@ private static function create_composite_command( $name, $class ) { if ( !self::_is_good_method( $method ) ) continue; - $subcommand = new Dispatcher\MethodSubcommand( $container, $class, $method ); + $subcommand = new Dispatcher\MethodSubcommand( $container, $reflection->name, $method ); $subcommand_name = $subcommand->get_name(); $full_name = self::get_full_name( $subcommand ); @@ -82,14 +90,6 @@ private static function _is_good_method( $method ) { return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); } - private static function create_atomic_command( $name, $implementation ) { - $method = new \ReflectionMethod( $implementation, '__invoke' ); - - $docparser = new \WP_CLI\DocParser( $method ); - - return new Dispatcher\Subcommand( self::$root, $name, $implementation, $docparser ); - } - static function add_man_dir( $dest_dir, $src_dir ) { self::$man_dirs[ $dest_dir ] = $src_dir; } diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 8ee5b6e33d..e1c60b9ef1 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -18,5 +18,5 @@ public function __invoke( $args, $assoc_args ) { } } -WP_CLI::add_command( 'eval-file', new EvalFile_Command ); +WP_CLI::add_command( 'eval-file', 'EvalFile_Command' ); diff --git a/php/commands/eval.php b/php/commands/eval.php index b8cd803cf5..02b97c6a99 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -12,5 +12,5 @@ public function __invoke( $args, $assoc_args ) { } } -WP_CLI::add_command( 'eval', new Eval_Command ); +WP_CLI::add_command( 'eval', 'Eval_Command' ); diff --git a/php/commands/export.php b/php/commands/export.php index 8a08f3bf70..0f85c92c33 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -532,5 +532,5 @@ private function export_wp( $args = array() ) { } } -WP_CLI::add_command( 'export', new Export_Command ); +WP_CLI::add_command( 'export', 'Export_Command' ); diff --git a/php/commands/help.php b/php/commands/help.php index ef1eded1af..55050bb99f 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -22,5 +22,5 @@ function __invoke( $args ) { } } -WP_CLI::add_command( 'help', new Help_Command ); +WP_CLI::add_command( 'help', 'Help_Command' ); diff --git a/php/commands/home.php b/php/commands/home.php index fbb3b2fdcb..eed233f66a 100644 --- a/php/commands/home.php +++ b/php/commands/home.php @@ -25,5 +25,4 @@ function __invoke() { } } -WP_CLI::add_command( 'home', new Home_Command ); - +WP_CLI::add_command( 'home', 'Home_Command' ); diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 607ccd28db..89f76d55c6 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -118,5 +118,5 @@ private static function is_text_col( $type ) { } } -WP_CLI::add_command( 'search-replace', new Search_Replace_Command ); +WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); diff --git a/php/commands/shell.php b/php/commands/shell.php index fd32cb6ec3..0f63833a7f 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -116,5 +116,5 @@ private static function starts_with( $tokens, $line ) { } } -\WP_CLI::add_command( 'shell', new Shell_Command ); +\WP_CLI::add_command( 'shell', 'Shell_Command' ); From 79180d315f130fdb4700b2bfa52808414546b48e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 26 Apr 2013 21:27:09 +0300 Subject: [PATCH 1541/4858] remove unnecessary WP_CLI\Commands namespace --- php/commands/shell.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 0f63833a7f..02daaed999 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -1,7 +1,5 @@ <?php -namespace WP_CLI\Commands; - class Shell_Command extends \WP_CLI_Command { /** From 68d4b4d458f4c8f685f7942087eca5b8fd2a3197 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 26 Apr 2013 21:32:28 +0300 Subject: [PATCH 1542/4858] instantiate MethodSubcommand instead of Subcommand --- php/class-wp-cli.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 3b579bef1a..befc5092ec 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -40,7 +40,7 @@ static function add_command( $name, $class ) { $reflection = new \ReflectionClass( $class ); if ( $reflection->hasMethod( '__invoke' ) ) { - $command = self::create_atomic_command( $name, $reflection ); + $command = new Dispatcher\MethodSubcommand( self::$root, $reflection->name, $reflection->getMethod( '__invoke' ) ); } else { $command = self::create_composite_command( $name, $reflection ); } @@ -48,14 +48,6 @@ static function add_command( $name, $class ) { self::$root->add_subcommand( $name, $command ); } - private static function create_atomic_command( $name, $reflection ) { - $method = $reflection->getMethod( '__invoke' ); - - $docparser = new \WP_CLI\DocParser( $method ); - - return new Dispatcher\Subcommand( self::$root, $name, $reflection->name, $docparser ); - } - private static function create_composite_command( $name, $reflection ) { $docparser = new \WP_CLI\DocParser( $reflection ); From ab598d4ef7f95ad3494e5f04dfa673f21ae55e5d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 26 Apr 2013 21:50:59 +0300 Subject: [PATCH 1543/4858] merge MethodSubcommand into Subcommand --- php/WP_CLI/Dispatcher/MethodSubcommand.php | 23 ---------------------- php/WP_CLI/Dispatcher/Subcommand.php | 23 ++++++++++++++++++---- php/class-wp-cli.php | 5 +++-- php/dispatcher.php | 15 -------------- 4 files changed, 22 insertions(+), 44 deletions(-) delete mode 100644 php/WP_CLI/Dispatcher/MethodSubcommand.php diff --git a/php/WP_CLI/Dispatcher/MethodSubcommand.php b/php/WP_CLI/Dispatcher/MethodSubcommand.php deleted file mode 100644 index f66329bc2a..0000000000 --- a/php/WP_CLI/Dispatcher/MethodSubcommand.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -namespace WP_CLI\Dispatcher; - -class MethodSubcommand extends Subcommand { - - function __construct( CommandContainer $parent, $class, \ReflectionMethod $method ) { - $docparser = new \WP_CLI\DocParser( $method ); - - $name = $docparser->get_tag( 'subcommand' ); - if ( !$name ) - $name = $method->name; - - $callable = new CallableMethod( $class, $method->name ); - - parent::__construct( $parent, $name, $callable, $docparser ); - } - - function get_alias() { - return $this->docparser->get_tag( 'alias' ); - } -} - diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 80d43f620d..8b3bae2451 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -4,15 +4,28 @@ class Subcommand implements Command, AtomicCommand, Documentable { - function __construct( CommandContainer $parent, $name, $callable, $docparser ) { + private $parent, $name, $method, $docparser; + + function __construct( CommandContainer $parent, \ReflectionMethod $method, $name = false ) { + $docparser = new \WP_CLI\DocParser( $method ); + + if ( !$name ) + $name = $docparser->get_tag( 'subcommand' ); + + if ( !$name ) + $name = $method->name; + $this->parent = $parent; $this->name = $name; - $this->callable = $callable; - + $this->method = $method; $this->docparser = $docparser; } + function get_alias() { + return $this->docparser->get_tag( 'alias' ); + } + function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $prefix . $this->get_full_synopsis() ); } @@ -53,7 +66,9 @@ function invoke( $args, $assoc_args ) { array( $this, 'show_usage' ) ); } - call_user_func( $this->callable, $args, $assoc_args ); + $instance = new $this->method->class; + + call_user_func( array( $instance, $this->method->name ), $args, $assoc_args ); } function get_name() { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index befc5092ec..b8abeccef1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -40,7 +40,8 @@ static function add_command( $name, $class ) { $reflection = new \ReflectionClass( $class ); if ( $reflection->hasMethod( '__invoke' ) ) { - $command = new Dispatcher\MethodSubcommand( self::$root, $reflection->name, $reflection->getMethod( '__invoke' ) ); + $command = new Dispatcher\Subcommand( self::$root, + $reflection->getMethod( '__invoke' ), $name ); } else { $command = self::create_composite_command( $name, $reflection ); } @@ -57,7 +58,7 @@ private static function create_composite_command( $name, $reflection ) { if ( !self::_is_good_method( $method ) ) continue; - $subcommand = new Dispatcher\MethodSubcommand( $container, $reflection->name, $method ); + $subcommand = new Dispatcher\Subcommand( $container, $method ); $subcommand_name = $subcommand->get_name(); $full_name = self::get_full_name( $subcommand ); diff --git a/php/dispatcher.php b/php/dispatcher.php index da4e1b0ff4..168ced1eb8 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -52,18 +52,3 @@ function get_shortdesc(); function get_full_synopsis(); } - -class CallableMethod { - - function __construct( $class, $method ) { - $this->class = $class; - $this->method = $method; - } - - function __invoke( $args, $assoc_args ) { - $instance = new $this->class; - - call_user_func( array( $instance, $this->method ), $args, $assoc_args ); - } -} - From f42948036e1ff75d0fa024a31d03b8ac152a2fae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 26 Apr 2013 22:29:00 +0300 Subject: [PATCH 1544/4858] dev-build: check that 'php' is available before doing anything else see #419 --- utils/dev-build | 6 ++++++ utils/find-php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/utils/dev-build b/utils/dev-build index 6583a472ce..2f0a97dade 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -1,5 +1,11 @@ #!/usr/bin/env bash +# check that PHP is available +command -v php > /dev/null || { + echo "can't find PHP binary" >&2 + exit 1 +} + # install Composer command -v composer > /dev/null || { curl -sS https://getcomposer.org/installer | php diff --git a/utils/find-php b/utils/find-php index e1a82c470a..f8d19f4a25 100755 --- a/utils/find-php +++ b/utils/find-php @@ -15,5 +15,5 @@ if [ $? -eq 0 ]; then exit fi -echo "no php binary found" +echo "no PHP binary found" >&2 exit 1 From cd784fd2c51f72a18cc81e53e8b72a79d6debe8d Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 26 Apr 2013 14:39:04 -0700 Subject: [PATCH 1545/4858] For local media imports, copy to tempfile before importing Apparently `wp_handle_sideload` performs a`rename()` operation on the file it's sideloading. In this case thats an unexpected side effect - you don't want the original image to go away when importing it to WordPress. --- php/commands/media.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 1e946f400b..6fdf2b069e 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -76,18 +76,30 @@ function import( $args, $assoc_args = array() ) { $is_file_remote = parse_url( $file, PHP_URL_SCHEME ); $orig_filename = $file; - if ( !empty( $is_file_remote ) ) { - $extension = pathinfo( $file, PATHINFO_EXTENSION ); + if ( empty( $is_file_remote ) ) { + // File appears to be a local file; make a copy first to work with + + $tempfile = wp_tempnam( $file ); + if ( ! $tempfile ) + WP_CLI::error( 'Could not create temporary file.' ); + + copy( $file, $tempfile ); + + } else { + // File appear to be a remote file; download as temp file + $tempfile = download_url( $file ); - // Necessary because temp filename will probably have an extension like - // .tmp, which is not in the list of permitted upload extensions - // and won't be recognized with the correct mime type - $tempfile_extension = pathinfo( $tempfile, PATHINFO_EXTENSION ); - $file = preg_replace( "/$tempfile_extension$/", $extension, $tempfile ); - rename( $tempfile, $file ); } + // Necessary because temp filename will probably have an extension like + // .tmp, which is not in the list of permitted upload extensions + // and won't be recognized with the correct mime type + $extension = pathinfo( $file, PATHINFO_EXTENSION ); + $tempfile_extension = pathinfo( $tempfile, PATHINFO_EXTENSION ); + $file = preg_replace( "/$tempfile_extension$/", $extension, $tempfile ); + rename( $tempfile, $file ); + $file_array = array( 'tmp_name' => $file, 'name' => basename( $file ) From 10f253ebff870015142594d43c33d432645d5b41 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 26 Apr 2013 15:32:50 -0700 Subject: [PATCH 1546/4858] Add behat features to test against local files One test for failure on trying to import non-existant image, and one to make sure that local images are not removed on import --- features/media.feature | 26 +++++++++++++++++++++++++- features/steps/basic_steps.php | 26 +++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/features/media.feature b/features/media.feature index c247d68600..09cf8db323 100644 --- a/features/media.feature +++ b/features/media.feature @@ -13,8 +13,32 @@ Feature: Manage WordPress attachments Scenario: Import image from remote URL Given a WP install - When I run `wp media import 'http://s.wordpress.org/style/images/codeispoetry.png' --post_id=1` + When I run `wp media import 'http://s.wordpress.org/style/images/codeispoetry.png' --post_id=1` Then STDOUT should contain: """ Success: Imported file http://s.wordpress.org/style/images/codeispoetry.png """ + + Scenario: Fail to import missing image + Given a WP install + + When I run `wp media import gobbledygook.png` + Then STDERR should contain: + """ + Error: Unable to import file gobbledygook.png. Reason: File is empty. + """ + + Scenario: Import a file as attachment from a local image + Given a WP install + And a large image file + + When I try to import it + Then STDOUT should contain: + """ + Success: Imported file + """ + And STDOUT should contain: + """ + and attached to post 1 as featured image + """ + And the image should not be deleted diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 4e1d8c2bf7..3e4fd0a0aa 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -93,6 +93,16 @@ function ( $world ) { } ); +$steps->Given( '/^a large image file$/', + function ( $world ) { + $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; + + $world->variables['DOWNLOADED_IMAGE'] = $world->get_cache_path( 'wallpaper.jpg' ); + + $world->download_file( $image_file, $world->variables['DOWNLOADED_IMAGE'] ); + } +); + $steps->When( '/^I run `wp`$/', function ( $world ) { $world->result = $world->run( '' ); @@ -120,6 +130,15 @@ function ( $world ) { } ); +$steps->When( '/^I try to import it$/', + function ( $world ) { + if ( !isset( $world->variables['DOWNLOADED_IMAGE'] ) ) + throw new \Exception( 'Cached image not available.' ); + + $world->result = $world->run( 'media import ' . $world->variables['DOWNLOADED_IMAGE'] . ' --post_id=1 --featured_image' ); + } +); + $steps->Given( '/^save (STDOUT|STDERR) as \{(\w+)\}$/', function ( $world, $stream, $key ) { $world->variables[ $key ] = rtrim( $world->result->$stream, "\n" ); @@ -232,6 +251,11 @@ function ( $world, $path ) { } ); +$steps->Then( '/^the image should not be deleted$/', + function ( $world ) { + assertFileExists( $world->variables['DOWNLOADED_IMAGE'] ); + } +); /** * Compare two strings containing JSON to ensure that @a $actualJson contains at @@ -299,4 +323,4 @@ function compareContents( $expected, $actual ) { } return true; -} \ No newline at end of file +} From 4ae855aa32147cec1db5d6a6bab1cad0550223a6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 27 Apr 2013 01:38:49 +0300 Subject: [PATCH 1547/4858] add functional test for --require flag --- features/flags.feature | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index 223fda99b8..7053443bb5 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -59,6 +59,28 @@ Feature: Global flags Error: Could not get a user_id for this user: 'non-existing-user' """ + Scenario: Using --require + Given a WP install + And a custom-cmd.php file: + """ + <?php + class Test_Command extends WP_CLI_Command { + + function req( $args, $assoc_args ) { + WP_CLI::line( $args[0] ); + } + } + + WP_CLI::add_command( 'test', 'Test_Command' ); + """ + + When I run `wp --require=custom-cmd.php test req 'This is a custom command.'` + Then it should run without errors + And STDOUT should be: + """ + This is a custom command. + """ + Scenario: Enabling/disabling color Given a WP install From 8652b9adbf6b50582076cf3f65dccfb82ed7a111 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 26 Apr 2013 16:55:36 -0700 Subject: [PATCH 1548/4858] Use variables in feature steps for readability Rewrote the feature step so that it displays the actual command being run, and uses variable substitution. * I had to modify the definition of the "file should exist" step to allow variable substitution. All of the existing tests still pass, but I'm not sure if this is best practice. I can write a new step instead, if that makes more sense. --- features/media.feature | 9 ++++++--- features/steps/basic_steps.php | 15 +++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/features/media.feature b/features/media.feature index 09cf8db323..e7a607cf39 100644 --- a/features/media.feature +++ b/features/media.feature @@ -10,6 +10,7 @@ Feature: Manage WordPress attachments Error: Unable to find the images """ + @images Scenario: Import image from remote URL Given a WP install @@ -19,6 +20,7 @@ Feature: Manage WordPress attachments Success: Imported file http://s.wordpress.org/style/images/codeispoetry.png """ + @images Scenario: Fail to import missing image Given a WP install @@ -28,17 +30,18 @@ Feature: Manage WordPress attachments Error: Unable to import file gobbledygook.png. Reason: File is empty. """ + @images Scenario: Import a file as attachment from a local image Given a WP install And a large image file - When I try to import it + When I run `wp media import {DOWNLOADED_IMAGE} --post_id=1 --featured_image` Then STDOUT should contain: """ - Success: Imported file + Success: Imported file """ And STDOUT should contain: """ and attached to post 1 as featured image """ - And the image should not be deleted + And the {DOWNLOADED_IMAGE} file should exist diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 3e4fd0a0aa..04f299ba21 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -247,13 +247,16 @@ function ( $world, $stream ) { $steps->Then( '/^the (.+) file should exist$/', function ( $world, $path ) { - assertFileExists( $world->get_path( $path ) ); - } -); + $path = $world->replace_variables( $path ); -$steps->Then( '/^the image should not be deleted$/', - function ( $world ) { - assertFileExists( $world->variables['DOWNLOADED_IMAGE'] ); + // If $path refers to a complete cache path, use it; + // otherwise, get the real path using $world->get_path() + if ( strpos( $path, $world->get_cache_path('') ) === 0 ) + $realpath = $path; + else + $realpath = $world->get_path( $path ); + + assertFileExists( $realpath ); } ); From 49cceec63db619f89f828d00d8c67f30e9837c99 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 27 Apr 2013 13:32:13 +0300 Subject: [PATCH 1549/4858] Shorten description for `wp media import` see #367 --- man/media-import.1 | 2 +- man/media-regenerate.1 | 2 +- php/commands/media.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/media-import.1 b/man/media-import.1 index 03bb00ae09..8dca82091e 100644 --- a/man/media-import.1 +++ b/man/media-import.1 @@ -4,7 +4,7 @@ .TH "WP\-MEDIA\-IMPORT" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-media\-import\fR \- Sideload images from local file(s) or URL and import as attachments, optionally attached to a post +\fBwp\-media\-import\fR \- Create attachments from local files or from URLs\. . .SH "SYNOPSIS" wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fIalt_text\fR] [\-\-desc=\fIdescription\fR] [\-\-featured_image] diff --git a/man/media-regenerate.1 b/man/media-regenerate.1 index 8591e809a3..c829722ac0 100644 --- a/man/media-regenerate.1 +++ b/man/media-regenerate.1 @@ -4,7 +4,7 @@ .TH "WP\-MEDIA\-REGENERATE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-media\-regenerate\fR \- Regenerate thumbnail(s) +\fBwp\-media\-regenerate\fR \- Regenerate thumbnail(s)\. . .SH "SYNOPSIS" wp media regenerate \fIattachment\-id\fR\.\.\. [\-\-yes] diff --git a/php/commands/media.php b/php/commands/media.php index 6fdf2b069e..0ee75de292 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -8,7 +8,7 @@ class Media_Command extends WP_CLI_Command { /** - * Regenerate thumbnail(s) + * Regenerate thumbnail(s). * * @synopsis <attachment-id>... [--yes] */ @@ -54,7 +54,7 @@ function regenerate( $args, $assoc_args = array() ) { } /** - * Sideload images from local file(s) or URL and import as attachments, optionally attached to a post + * Create attachments from local files or from URLs. * * @synopsis <file>... [--post_id=<post_id>] [--title=<title>] [--caption=<caption>] [--alt=<alt_text>] [--desc=<description>] [--featured_image] */ From c4d4adb0059a68832ad471336a254cd005cb62c3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 27 Apr 2013 13:33:55 +0300 Subject: [PATCH 1550/4858] nested ternary operators are bad, mkay... see #367 --- php/commands/media.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 0ee75de292..e8c668ba90 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -121,10 +121,12 @@ function import( $args, $assoc_args = array() ) { if ( !is_wp_error( $success ) && $assoc_args['post_id'] && $assoc_args['featured_image'] ) update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); - $attachment_success_text = ( $assoc_args['post_id'] && get_post( $assoc_args['post_id'] ) ) ? - " and attached to post {$assoc_args['post_id']}" . - ( ( $assoc_args['featured_image'] ) ? ' as featured image' : '' ) - : ''; + $attachment_success_text = ''; + if ( $assoc_args['post_id'] && get_post( $assoc_args['post_id'] ) ) { + $attachment_success_text = " and attached to post {$assoc_args['post_id']}"; + if ( $assoc_args['featured_image'] ) + $attachment_success_text .= ' as featured image'; + } if ( is_wp_error( $success ) ) WP_CLI::error( From 93aab78fd284e62f395b36a4779f0318d8732fca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 27 Apr 2013 13:38:17 +0300 Subject: [PATCH 1551/4858] validate --post_id only once and issue warning see #367 --- php/commands/media.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index e8c668ba90..64e954018a 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -63,7 +63,7 @@ function import( $args, $assoc_args = array() ) { $assoc_args = wp_parse_args( $assoc_args, array( - 'post_id' => 0, + 'post_id' => false, 'title' => null, 'caption' => null, 'alt' => null, @@ -71,7 +71,12 @@ function import( $args, $assoc_args = array() ) { ) ); - foreach( $args as $file ) { + if ( !get_post( $assoc_args['post_id'] ) ) { + WP_CLI::warning( "Invalid --post_id" ); + $assoc_args['post_id'] = false; + } + + foreach ( $args as $file ) { $is_file_remote = parse_url( $file, PHP_URL_SCHEME ); $orig_filename = $file; @@ -122,7 +127,7 @@ function import( $args, $assoc_args = array() ) { update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); $attachment_success_text = ''; - if ( $assoc_args['post_id'] && get_post( $assoc_args['post_id'] ) ) { + if ( $assoc_args['post_id'] ) { $attachment_success_text = " and attached to post {$assoc_args['post_id']}"; if ( $assoc_args['featured_image'] ) $attachment_success_text .= ' as featured image'; From 15ba7e0618a9d5e762a9159a8c19f90cedb837f7 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Sat, 27 Apr 2013 17:36:50 +0000 Subject: [PATCH 1552/4858] Update man pages --- man-src/blog-empty.txt | 3 +++ man/blog-empty.1 | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 man-src/blog-empty.txt create mode 100644 man/blog-empty.1 diff --git a/man-src/blog-empty.txt b/man-src/blog-empty.txt new file mode 100644 index 0000000000..80db5732c2 --- /dev/null +++ b/man-src/blog-empty.txt @@ -0,0 +1,3 @@ +## EXAMPLES + + wp blog empty \ No newline at end of file diff --git a/man/blog-empty.1 b/man/blog-empty.1 new file mode 100644 index 0000000000..137b9c69c0 --- /dev/null +++ b/man/blog-empty.1 @@ -0,0 +1,19 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-BLOG\-EMPTY" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-blog\-empty\fR \- Empty a blog +. +.SH "SYNOPSIS" +wp blog empty +. +.SH "EXAMPLES" +. +.nf + +wp blog empty +. +.fi + From 670a00d4b35e5b290f8f6fc10ece54a79dc04d81 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 27 Apr 2013 16:57:55 -0700 Subject: [PATCH 1553/4858] Ensure `wp post list` returns posts of all statuses by default, as WP_Query behaves differently in the WP_ADMIN context. See #412 --- php/commands/post.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 7dec705411..d58f90b802 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -164,7 +164,8 @@ protected function _delete( $post_id, $assoc_args ) { */ public function _list( $_, $assoc_args ) { $query_args = array( - 'posts_per_page' => -1 + 'posts_per_page' => -1, + 'post_status' => 'any', ); if ( ! empty( $assoc_args['format'] ) ) { From e07da7ad0de88a8f214914b6e4c49f25f6a7ca14 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 27 Apr 2013 17:17:31 -0700 Subject: [PATCH 1554/4858] Update composer.lock to latest --- composer.lock | 92 ++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/composer.lock b/composer.lock index bdbb23f0b8..9bd1adfaa3 100644 --- a/composer.lock +++ b/composer.lock @@ -1,4 +1,8 @@ { + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + ], "hash": "f2b06fd19e26795775358b054c6fb09d", "packages": [ { @@ -445,16 +449,16 @@ }, { "name": "phpunit/phpunit", - "version": "3.7.15", + "version": "3.7.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.15" + "reference": "3.7.19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.15", - "reference": "3.7.15", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.19", + "reference": "3.7.19", "shasum": "" }, "require": { @@ -468,7 +472,7 @@ "phpunit/php-text-template": ">=1.1.1", "phpunit/php-timer": ">=1.0.2,<1.1.0", "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", - "symfony/yaml": ">=2.2.0" + "symfony/yaml": ">=2.0.0,<2.3.0" }, "require-dev": { "pear-pear/pear": "1.9.4" @@ -515,7 +519,7 @@ "testing", "xunit" ], - "time": "2013-03-01 11:55:06" + "time": "2013-03-25 11:45:06" }, { "name": "phpunit/phpunit-mock-objects", @@ -568,17 +572,17 @@ }, { "name": "symfony/config", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "v2.2.0-RC3" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.0-RC3", - "reference": "v2.2.0-RC3", + "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -611,21 +615,21 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2013-02-17 12:27:42" + "time": "2013-03-01 10:42:10" }, { "name": "symfony/console", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "v2.2.0" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.0", - "reference": "v2.2.0", + "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -658,21 +662,21 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2013-03-01 06:43:14" + "time": "2013-03-19 20:48:08" }, { "name": "symfony/dependency-injection", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "v2.2.0-RC3" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.0-RC3", - "reference": "v2.2.0-RC3", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -713,21 +717,21 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2013-02-11 11:43:49" + "time": "2013-03-23 07:49:54" }, { "name": "symfony/event-dispatcher", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.2.0-RC3" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.0-RC3", - "reference": "v2.2.0-RC3", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -771,17 +775,17 @@ }, { "name": "symfony/finder", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "v2.2.0" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.2.0", - "reference": "v2.2.0", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -814,21 +818,21 @@ ], "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2013-02-28 14:06:36" + "time": "2013-04-01 07:51:50" }, { "name": "symfony/translation", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "v2.2.0-RC3" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.0-RC3", - "reference": "v2.2.0-RC3", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -869,21 +873,21 @@ ], "description": "Symfony Translation Component", "homepage": "http://symfony.com", - "time": "2013-02-08 16:10:57" + "time": "2013-04-01 08:06:05" }, { "name": "symfony/yaml", - "version": "v2.2.0", + "version": "v2.2.1", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.2.0-RC3" + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.0-RC3", - "reference": "v2.2.0-RC3", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { @@ -916,7 +920,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-01-27 16:49:19" + "time": "2013-03-23 07:49:54" } ], "aliases": [ @@ -926,5 +930,11 @@ "stability-flags": { "wp-cli/php-cli-tools": 20, "behat/behat": 0 - } + }, + "platform": { + "php": ">=5.3" + }, + "platform-dev": [ + + ] } From 8e57994640c506071159b263bcb7a0958ca8c71b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 28 Apr 2013 18:07:39 -0700 Subject: [PATCH 1555/4858] Fix typo --- features/post.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/post.feature b/features/post.feature index ee5efed9db..d2677bb68c 100644 --- a/features/post.feature +++ b/features/post.feature @@ -28,7 +28,7 @@ Feature: Manage WordPress posts When I run the previous command again Then the return code should be 1 - Scenario: Creating/geting posts + Scenario: Creating/getting posts Given a WP install When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` From d74921231b6634447cd6c4445674c1c745082dd6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 28 Apr 2013 18:44:39 -0700 Subject: [PATCH 1556/4858] Behat step for checking a CSV contains string --- features/steps/basic_steps.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 04f299ba21..d5821906f0 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -231,6 +231,17 @@ function ( $world, PyStringNode $expected ) { } }); +$steps->Then( '/^STDOUT should be CSV containing:$/', + function( $world, PyStringNode $expected ) { + + $output = $world->result->STDOUT; + $expected = $world->replace_variables( (string) $expected ); + + if ( ! checkThatCsvStringContainsCsvString( $output, $expected ) ) + throw new \Exception( $output ); + } +); + $steps->Then( '/^(STDOUT|STDERR) should be empty$/', function ( $world, $stream ) { if ( !empty( $world->result->$stream ) ) { @@ -327,3 +338,20 @@ function compareContents( $expected, $actual ) { return true; } + +/** + * Compare two strings to confirm $actualCSV contains $expectedCSV + * + * @return bool Whether $actualCSV contacts $expectedCSV + */ +function checkThatCsvStringContainsCsvString( $actualCSV, $expectedCSV ) { + + $actualCSV = array_map( 'str_getcsv', explode( PHP_EOL, $actualCSV ) ); + $expectedCSV = array_map( 'str_getcsv', explode( PHP_EOL, $expectedCSV ) ); + + if ( ! $actualCSV ) { + return false; + } + + return compareContents( $expectedCSV, $actualCSV ); +} From 2dfa40109d828e2ed92cffadd5c2043a00ebd5a9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 28 Apr 2013 19:34:06 -0700 Subject: [PATCH 1557/4858] Refactor checkThatCsvStringContainsCsvString() such that: * expected CSV can be in any row of the actual CSV * actual CSV must contain all expected CSV data rows --- features/steps/basic_steps.php | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index d5821906f0..1d10594dc1 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -322,15 +322,13 @@ function compareContents( $expected, $actual ) { if ( is_object( $expected ) ) { foreach ( get_object_vars( $expected ) as $name => $value ) { - if ( !compareContents( $value, $actual->$name ) ) { + if ( ! compareContents( $value, $actual->$name ) ) return false; - } } } else if ( is_array( $expected ) ) { foreach ( $expected as $key => $value ) { - if ( !compareContents( $value, $actual[$key] ) ) { + if ( ! compareContents( $value, $actual[$key] ) ) return false; - } } } else { return $expected === $actual; @@ -341,6 +339,8 @@ function compareContents( $expected, $actual ) { /** * Compare two strings to confirm $actualCSV contains $expectedCSV + * Both strings are expected to have headers for their CSVs. + * $actualCSV must match all data rows in $expectedCSV * * @return bool Whether $actualCSV contacts $expectedCSV */ @@ -349,9 +349,27 @@ function checkThatCsvStringContainsCsvString( $actualCSV, $expectedCSV ) { $actualCSV = array_map( 'str_getcsv', explode( PHP_EOL, $actualCSV ) ); $expectedCSV = array_map( 'str_getcsv', explode( PHP_EOL, $expectedCSV ) ); - if ( ! $actualCSV ) { + if ( empty( $actualCSV ) ) return false; + + // Each sample must have headers + $actualHeaders = array_values( array_shift( $actualCSV ) ); + $expectedHeaders = array_values( array_shift( $expectedCSV ) ); + + // Each expectedCSV must exist somewhere in actualCSV in the proper column + $expectedResult = 0; + foreach( $expectedCSV as $expected_row ) { + $expected_row = array_combine( $expectedHeaders, $expected_row ); + foreach( $actualCSV as $actual_row ) { + + if ( count( $actualHeaders ) != count( $actual_row ) ) + continue; + + $actual_row = array_intersect_key( array_combine( $actualHeaders, $actual_row ), $expected_row ); + if ( $actual_row == $expected_row ) + $expectedResult++; + } } - return compareContents( $expectedCSV, $actualCSV ); + return $expectedResult >= count( $expectedCSV ); } From ad1b293b279e2c60facdd0693436daae76d3fb9a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 28 Apr 2013 19:38:22 -0700 Subject: [PATCH 1558/4858] Test: `wp post list` should contain both 'draft' and 'publish' posts --- features/post.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/features/post.feature b/features/post.feature index d2677bb68c..3fa02b1d64 100644 --- a/features/post.feature +++ b/features/post.feature @@ -65,3 +65,23 @@ Feature: Manage WordPress posts """ {"ID":{POST_ID},"post_title":"Test post","post_content":"Test content."} """ + + Scenario: Creating/listing posts + Given a WP install + + When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` + Then it should run without errors + And STDOUT should match '%d' + + When I run `wp post create --post_title='Draft post' --post_content='Draft post content' --post_status='draft' --porcelain` + Then it should run without errors + And STDOUT should match '%d' + + When I run `wp post list --post_type='post' --format=csv` + Then it should run without errors + And STDOUT should be CSV containing: + """ + post_title,post_name + "Publish post",publish-post + "Draft post", + """ From 9105cbba89dd3d78b4e5f2c7077e5d8ba06f4db8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 14:45:00 +0300 Subject: [PATCH 1559/4858] add post_status to `wp post list` output --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index d58f90b802..a1b3aa65c6 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -187,7 +187,7 @@ public function _list( $_, $assoc_args ) { $query = new WP_Query( $query_args ); - $fields = array( 'ID', 'post_title', 'post_name', 'post_date' ); + $fields = array( 'ID', 'post_title', 'post_name', 'post_date', 'post_status' ); $output_posts = $query->posts; From 54a65ecd35f227b2969e8401b1648dd512d84666 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 18:16:26 +0300 Subject: [PATCH 1560/4858] Rename `wp db connect` back to `wp db cli` `db connect` is rather ambigous: you connect to the database, and then what?! `db cli` is more explicit: connect to the database and open a MySQL command-line session --- man/db.1 | 10 ++-------- php/commands/db.php | 4 ++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/man/db.1 b/man/db.1 index 99983e2d34..80c7f34ce9 100644 --- a/man/db.1 +++ b/man/db.1 @@ -22,7 +22,7 @@ wp db optimize wp db repair . .P -wp db connect +wp db cli . .P wp db query \fIsql\fR @@ -36,7 +36,7 @@ wp db import [\fIfile\fR] .SH "SUBCOMMANDS" . .TP -\fBconnect\fR: +\fBcli\fR: . .IP Open a mysql console using the WordPress credentials\. @@ -91,12 +91,6 @@ Remove all tables from the database\. . .SH "OPTIONS" -. -.TP -\fB\-\-str\fR: -. -.IP -Show the mysql command, instead of executing it\. . .TP \fB\-\-yes\fR: diff --git a/php/commands/db.php b/php/commands/db.php index 300b82740b..c411413a45 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -71,9 +71,9 @@ function repair() { /** * Open a mysql console using the WordPress credentials. * - * @alias cli + * @alias connect */ - function connect() { + function cli() { self::run( 'mysql', Utils\create_cmd( '--host=%s --user=%s --database=%s', DB_HOST, DB_USER, DB_NAME ) ); From b52917e1ad7f11b61c76951b7fa4f988825f54b7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 18:58:33 +0300 Subject: [PATCH 1561/4858] Use `wp core download` in Travis tests too. --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e470d86ced..48687d040a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,10 +17,7 @@ before_script: # install dependencies - composer install --dev --no-interaction --prefer-source # set up WP install - - WP_CORE_DIR=/tmp/wp-cli-test-core-download-cache/ - - mkdir -p $WP_CORE_DIR - - wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/wordpress-$WP_VERSION.tar.gz - - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + - bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ # set up database - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot From abc3facc04401f03d68f9d496df90ebbd06fb758 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 19:22:31 +0300 Subject: [PATCH 1562/4858] core download: remove duplicate code for creating the directory --- php/commands/core.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8f29005a86..391ba1402b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -18,7 +18,7 @@ public function download( $args, $assoc_args ) { if ( !is_dir( ABSPATH ) ) { WP_CLI::line( sprintf( 'Creating directory %s', ABSPATH ) ); - WP_CLI::launch( 'mkdir -p ' . escapeshellarg( ABSPATH ) ); + WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); } if ( isset( $assoc_args['locale'] ) ) { @@ -35,8 +35,7 @@ public function download( $args, $assoc_args ) { } $silent = WP_CLI::get_config('quiet') ? ' --silent ' : ' '; - - WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); + $curl_command = 'curl -f' . $silent . escapeshellarg( $download_url ); $tar_command = sprintf( 'tar xz --directory=%s --strip-components=1', escapeshellarg( ABSPATH ) ); WP_CLI::launch( $curl_command . ' | ' . $tar_command ); From 86d713c9ceae21c4d4cb77cc3a31201c324162cb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 19:29:55 +0300 Subject: [PATCH 1563/4858] core download: refactor curl + tar into a single command string --- php/commands/core.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 391ba1402b..d3f13b743f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -34,11 +34,10 @@ public function download( $args, $assoc_args ) { WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - $silent = WP_CLI::get_config('quiet') ? ' --silent ' : ' '; + $silent = WP_CLI::get_config('quiet') ? '--silent ' : ''; - $curl_command = 'curl -f' . $silent . escapeshellarg( $download_url ); - $tar_command = sprintf( 'tar xz --directory=%s --strip-components=1', escapeshellarg( ABSPATH ) ); - WP_CLI::launch( $curl_command . ' | ' . $tar_command ); + $cmd = "curl -f $silent %s | tar xz --strip-components=1 --directory=%s"; + WP_CLI::launch( \WP_CLI\Utils\create_cmd( $cmd, $download_url, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); } From 46813ade0679ba8c15cc04f1c127a2e454ec5b58 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 19:31:45 +0300 Subject: [PATCH 1564/4858] core command: "use WP_CLI\Utils;" --- php/commands/core.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index d3f13b743f..e62a2ea69c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1,5 +1,7 @@ <?php +use \WP_CLI\Utils; + /** * Download, install, update and otherwise manage WordPress proper. * @@ -37,7 +39,7 @@ public function download( $args, $assoc_args ) { $silent = WP_CLI::get_config('quiet') ? '--silent ' : ''; $cmd = "curl -f $silent %s | tar xz --strip-components=1 --directory=%s"; - WP_CLI::launch( \WP_CLI\Utils\create_cmd( $cmd, $download_url, ABSPATH ) ); + WP_CLI::launch( Utils\create_cmd( $cmd, $download_url, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); } @@ -161,7 +163,7 @@ public function install_network( $args, $assoc_args ) { } private static function modify_wp_config( $content ) { - $wp_config_path = WP_CLI\Utils\locate_wp_config(); + $wp_config_path = Utils\locate_wp_config(); $token = "/* That's all, stop editing!"; @@ -270,7 +272,7 @@ function update( $args, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - $result = WP_CLI\Utils\get_upgrader( $upgrader )->upgrade( $update ); + $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); @@ -318,7 +320,7 @@ function init_tests( $args, $assoc_args ) { // Create the database $query = sprintf( 'CREATE DATABASE IF NOT EXISTS `%s`', $assoc_args['dbname'] ); - \WP_CLI\Utils\run_mysql_query( $query, array( + Utils\run_mysql_query( $query, array( 'host' => 'localhost', 'user' => $assoc_args['dbuser'], 'pass' => $assoc_args['dbpass'], From 62b97c9b048d450e1066cecec67dfe51d9febc7c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 19:38:51 +0300 Subject: [PATCH 1565/4858] rename create_cmd() to esc_cmd() Matches WP escaping functions: esc_sql(), esc_html() etc. --- features/bootstrap/FeatureContext.php | 6 +++--- php/commands/core.php | 2 +- php/commands/db.php | 10 +++++----- php/utils.php | 7 +++++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index fd2fdf2d9f..19b7025c23 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -94,14 +94,14 @@ public function get_cache_path( $file ) { if ( !$path ) { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - system( Utils\create_cmd( 'mkdir -p %s', $path ) ); + system( Utils\esc_cmd( 'mkdir -p %s', $path ) ); } return $path . '/' . $file; } public function download_file( $url, $path ) { - system( Utils\create_cmd( 'curl -sSL %s > %s', $url, $path ) ); + system( Utils\esc_cmd( 'curl -sSL %s > %s', $url, $path ) ); } private static function run_sql( $sql ) { @@ -187,7 +187,7 @@ public function download_wordpress_files( $subdir = '' ) { if ( $subdir ) mkdir( $dest_dir ); - $cmd = Utils\create_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ); + $cmd = Utils\esc_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ); system( $cmd ); } diff --git a/php/commands/core.php b/php/commands/core.php index e62a2ea69c..3c3724abb1 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -39,7 +39,7 @@ public function download( $args, $assoc_args ) { $silent = WP_CLI::get_config('quiet') ? '--silent ' : ''; $cmd = "curl -f $silent %s | tar xz --strip-components=1 --directory=%s"; - WP_CLI::launch( Utils\create_cmd( $cmd, $download_url, ABSPATH ) ); + WP_CLI::launch( Utils\esc_cmd( $cmd, $download_url, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); } diff --git a/php/commands/db.php b/php/commands/db.php index c411413a45..a14c286f12 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -49,7 +49,7 @@ function reset( $_, $assoc_args ) { * Optimize the database. */ function optimize() { - self::run( 'mysqlcheck', Utils\create_cmd( + self::run( 'mysqlcheck', Utils\esc_cmd( '--optimize --host=%s --user=%s %s', DB_HOST, DB_USER, DB_NAME ) ); @@ -61,7 +61,7 @@ function optimize() { * Repair the database. */ function repair() { - self::run( 'mysqlcheck', Utils\create_cmd( + self::run( 'mysqlcheck', Utils\esc_cmd( '--repair --host=%s --user=%s %s', DB_HOST, DB_USER, DB_NAME ) ); @@ -74,7 +74,7 @@ function repair() { * @alias connect */ function cli() { - self::run( 'mysql', Utils\create_cmd( + self::run( 'mysql', Utils\esc_cmd( '--host=%s --user=%s --database=%s', DB_HOST, DB_USER, DB_NAME ) ); } @@ -100,7 +100,7 @@ function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( 'mysqldump', Utils\create_cmd( + self::run( 'mysqldump', Utils\esc_cmd( '%s --user=%s --host=%s --result-file %s', DB_NAME, DB_USER, DB_HOST, $result_file ) ); @@ -115,7 +115,7 @@ function export( $args, $assoc_args ) { function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( 'mysql', Utils\create_cmd( + self::run( 'mysql', Utils\esc_cmd( '%s --user=%s --host=%s < %s', DB_NAME, DB_USER, DB_HOST, $result_file ) ); diff --git a/php/utils.php b/php/utils.php index 3489393d7c..3521a2a624 100644 --- a/php/utils.php +++ b/php/utils.php @@ -138,7 +138,10 @@ function assoc_args_to_str( $assoc_args ) { * Given a template string and an arbitrary number of arguments, * returns the final command, with the parameters escaped. */ -function create_cmd( $cmd ) { +function esc_cmd( $cmd ) { + if ( func_num_args() < 2 ) + trigger_error( 'esc_cmd() requires at least two arguments.', E_USER_WARNING ); + $args = func_get_args(); $cmd = array_shift( $args ); @@ -368,7 +371,7 @@ function find_subcommand( $args ) { function run_mysql_query( $query, $args ) { // TODO: use PDO? - $arg_str = create_cmd( '--host=%s --user=%s --execute=%s', + $arg_str = esc_cmd( '--host=%s --user=%s --execute=%s', $args['host'], $args['user'], $query ); run_mysql_command( 'mysql', $arg_str, $args['pass'] ); From 6fea8a4e49497b5c2642dd979b1594dc6d4390fb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 20:41:03 +0300 Subject: [PATCH 1566/4858] since it's called dev-build, install the development dependencies --- utils/dev-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/dev-build b/utils/dev-build index 2f0a97dade..2994603608 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -13,7 +13,7 @@ command -v composer > /dev/null || { } # install dependencies -composer install +composer install --dev # add symlink to wp binary for dir in /usr/bin /usr/local/bin; do From d966e0bda697e358ebd5641dc572d8b6e0be1fa6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 18:36:25 +0300 Subject: [PATCH 1567/4858] make `wp db query` optionally read from STDIN --- php/commands/db.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index a14c286f12..e19cc14289 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -82,10 +82,14 @@ function cli() { /** * Execute a query against the database. * - * @synopsis <sql> + * @synopsis [<sql>] */ function query( $args ) { - list( $query ) = $args; + if ( empty( $args ) ) { + $query = file_get_contents( 'php://stdin' ); + } else { + list( $query ) = $args; + } self::run_query( $query ); } From bf8d5bb929f3de1baa66798b0b012da9ab42afff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 20:46:52 +0300 Subject: [PATCH 1568/4858] test that database is selected --- features/db.feature | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/features/db.feature b/features/db.feature index 1d440234e9..30630fa6c1 100644 --- a/features/db.feature +++ b/features/db.feature @@ -24,9 +24,6 @@ Feature: Perform database operations Then it should run without errors And STDOUT should not be empty - When I run `wp db query 'SELECT 42 FROM dual'` + When I run `wp db query 'SELECT COUNT(*) FROM wp_posts'` Then it should run without errors - And STDOUT should contain: - """ - 42 - """ + And STDOUT should match '%d' From 67b2c3d4890e5865ad9100a0b320bbc8f1017249 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 21:08:34 +0300 Subject: [PATCH 1569/4858] db query: select database Also, let WP_CLI::launch() proxy STDIN, instead of reading it explicitly. --- features/db.feature | 22 ++++++++++++++++++++-- php/commands/db.php | 11 ++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/features/db.feature b/features/db.feature index 30630fa6c1..ca32411118 100644 --- a/features/db.feature +++ b/features/db.feature @@ -24,6 +24,24 @@ Feature: Perform database operations Then it should run without errors And STDOUT should not be empty - When I run `wp db query 'SELECT COUNT(*) FROM wp_posts'` + Scenario: DB Query + Given a WP install + + When I run `wp db query 'SELECT COUNT(*) as total FROM wp_posts'` + Then it should run without errors + And STDOUT should contain: + """ + total + """ + + Given a debug.sql file: + """ + SELECT COUNT(*) as total FROM wp_posts + """ + + When I run `wp db query < debug.sql` Then it should run without errors - And STDOUT should match '%d' + And STDOUT should contain: + """ + total + """ diff --git a/php/commands/db.php b/php/commands/db.php index e19cc14289..662306d5f9 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -85,13 +85,14 @@ function cli() { * @synopsis [<sql>] */ function query( $args ) { - if ( empty( $args ) ) { - $query = file_get_contents( 'php://stdin' ); - } else { - list( $query ) = $args; + $cmd = '--host=%s --user=%s --database=%s'; + $cmd = Utils\esc_cmd( $cmd, DB_HOST, DB_USER, DB_NAME ); + + if ( !empty( $args ) ) { + $cmd .= Utils\esc_cmd( ' --execute=%s', $args[0] ); } - self::run_query( $query ); + self::run( 'mysql', $cmd ); } /** From 172ff6d65c0ed4ef586550c38cd311a5136eb5ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 29 Apr 2013 21:13:37 +0300 Subject: [PATCH 1570/4858] man: add `wp db query` example --- man-src/db.txt | 4 ++++ man/db.1 | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/man-src/db.txt b/man-src/db.txt index e60509350b..a9fb12bfd1 100644 --- a/man-src/db.txt +++ b/man-src/db.txt @@ -11,3 +11,7 @@ * `<SQL>`: A SQL query. + +## EXAMPLES + +wp db query < debug.sql diff --git a/man/db.1 b/man/db.1 index 80c7f34ce9..98c8a6b8ef 100644 --- a/man/db.1 +++ b/man/db.1 @@ -25,7 +25,7 @@ wp db repair wp db cli . .P -wp db query \fIsql\fR +wp db query [\fIsql\fR] . .P wp db export [\fIfile\fR] @@ -109,4 +109,6 @@ The name of the export file\. If omitted, it will be \'{dbname}\.sql\' . .IP A SQL query\. - +. +.SH "EXAMPLES" +wp db query < debug\.sql From 37fc45c7c706f42d6574b3ff5436b57f5fadf5d2 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Mon, 29 Apr 2013 23:12:32 +0200 Subject: [PATCH 1571/4858] Fixed issue #428. Ability to display version for plugin status --- man-src/plugin-status.txt | 4 ++++ man/plugin-status.1 | 8 +++++++- php/WP_CLI/CommandWithUpgrade.php | 20 ++++++++++++++++---- php/commands/plugin.php | 7 ++++--- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/man-src/plugin-status.txt b/man-src/plugin-status.txt index daf14a99e1..33135209b4 100644 --- a/man-src/plugin-status.txt +++ b/man-src/plugin-status.txt @@ -3,3 +3,7 @@ * `<plugin>`: A particular plugin to show the status for. + +* `--with-version`: + + If set, the plugin version will also be shown. \ No newline at end of file diff --git a/man/plugin-status.1 b/man/plugin-status.1 index 797ffa320e..126cac0726 100644 --- a/man/plugin-status.1 +++ b/man/plugin-status.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-status\fR \- See the status of one or all plugins\. . .SH "SYNOPSIS" -wp plugin status [\fIplugin\fR] +wp plugin status [\fIplugin\fR] [\-\-with\-version] . .SH "OPTIONS" . @@ -16,4 +16,10 @@ wp plugin status [\fIplugin\fR] . .IP A particular plugin to show the status for\. +. +.TP +\fB\-\-with\-version\fR: +. +.IP +If set, the plugin version will also be shown\. diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 08b87ccfb0..f7ba9e55f3 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -20,18 +20,23 @@ abstract protected function status_single( $args ); abstract protected function install_from_repo( $slug, $assoc_args ); - function status( $args ) { + function status( $args, $assoc_args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); if ( empty( $args ) ) { - $this->status_all(); + $with_version = false; + if( in_array( 'with-version', $assoc_args ) ) { + $with_version = true; + } + + $this->status_all( $with_version ); } else { $this->status_single( $args ); } } - private function status_all() { + private function status_all( $with_version = false ) { $items = $this->get_all_items(); $n = count( $items ); @@ -47,7 +52,10 @@ private function status_all() { } $line .= $this->format_status( $details['status'], 'short' ); - $line .= " " . $details['name'] . "%n"; + $line .= " " . $details['name']; + if ( $with_version ) { + $line .= " " . $this->format_version( $details['version'] ) . "%n"; + } \WP_CLI::line( $line ); } @@ -183,6 +191,10 @@ protected function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } + protected function format_version( $version ) { + return '%c' . $version; + } + private function get_color( $status ) { static $colors = array( 'inactive' => '', diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ea01f2a9a5..4c01e3d597 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -22,10 +22,10 @@ function __construct() { /** * See the status of one or all plugins. * - * @synopsis [<plugin>] + * @synopsis [<plugin>] [--with-version] */ - function status( $args ) { - parent::status( $args ); + function status( $args, $assoc_args ) { + parent::status( $args, $assoc_args ); } protected function status_single( $args ) { @@ -240,6 +240,7 @@ protected function get_item_list() { 'name' => $this->get_name( $file ), 'status' => $this->get_status( $file ), 'update' => $this->has_update( $file ), + 'version' => $details['Version'], 'update_id' => $file, ); } From c5f438b1657ff3fbbb0a2b55174ea887b6dc5a7d Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Tue, 30 Apr 2013 01:05:19 +0200 Subject: [PATCH 1572/4858] show version default, remove color from version and align left --- man-src/plugin-status.txt | 6 +----- man/plugin-status.1 | 8 +------ php/WP_CLI/CommandWithUpgrade.php | 36 +++++++++++++++++++------------ php/commands/plugin.php | 6 +++--- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/man-src/plugin-status.txt b/man-src/plugin-status.txt index 33135209b4..6902ac2709 100644 --- a/man-src/plugin-status.txt +++ b/man-src/plugin-status.txt @@ -2,8 +2,4 @@ * `<plugin>`: - A particular plugin to show the status for. - -* `--with-version`: - - If set, the plugin version will also be shown. \ No newline at end of file + A particular plugin to show the status for. \ No newline at end of file diff --git a/man/plugin-status.1 b/man/plugin-status.1 index 126cac0726..797ffa320e 100644 --- a/man/plugin-status.1 +++ b/man/plugin-status.1 @@ -7,7 +7,7 @@ \fBwp\-plugin\-status\fR \- See the status of one or all plugins\. . .SH "SYNOPSIS" -wp plugin status [\fIplugin\fR] [\-\-with\-version] +wp plugin status [\fIplugin\fR] . .SH "OPTIONS" . @@ -16,10 +16,4 @@ wp plugin status [\fIplugin\fR] [\-\-with\-version] . .IP A particular plugin to show the status for\. -. -.TP -\fB\-\-with\-version\fR: -. -.IP -If set, the plugin version will also be shown\. diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index f7ba9e55f3..a994eb22d9 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -20,23 +20,18 @@ abstract protected function status_single( $args ); abstract protected function install_from_repo( $slug, $assoc_args ); - function status( $args, $assoc_args ) { + function status( $args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); if ( empty( $args ) ) { - $with_version = false; - if( in_array( 'with-version', $assoc_args ) ) { - $with_version = true; - } - - $this->status_all( $with_version ); + $this->status_all(); } else { $this->status_single( $args ); } } - private function status_all( $with_version = false ) { + private function status_all() { $items = $this->get_all_items(); $n = count( $items ); @@ -44,18 +39,17 @@ private function status_all( $with_version = false ) { // Not interested in the translation, just the number logic \WP_CLI::line( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); + $padding = $this->get_padding($items); + foreach ( $items as $file => $details ) { if ( $details['update'] ) { $line = ' %yU%n'; } else { $line = ' '; } - $line .= $this->format_status( $details['status'], 'short' ); - $line .= " " . $details['name']; - if ( $with_version ) { - $line .= " " . $this->format_version( $details['version'] ) . "%n"; - } + $line .= " " . str_pad( $details['name'], $padding ); + $line .= "%n " . $this->format_version( $details['version'] ) . "%n"; \WP_CLI::line( $line ); } @@ -65,6 +59,20 @@ private function status_all( $with_version = false ) { $this->show_legend( $items ); } + private function get_padding( $items ) { + $max_len = 0; + + foreach ( $items as $details ) { + $len = strlen( $details['name'] ); + + if ( $len > $max_len ) { + $max_len = $len; + } + } + + return $max_len; + } + private function show_legend( $items ) { $statuses = array_unique( wp_list_pluck( $items, 'status' ) ); @@ -192,7 +200,7 @@ protected function format_status( $status, $format ) { } protected function format_version( $version ) { - return '%c' . $version; + return '' . $version; } private function get_color( $status ) { diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 4c01e3d597..f761afb192 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -22,10 +22,10 @@ function __construct() { /** * See the status of one or all plugins. * - * @synopsis [<plugin>] [--with-version] + * @synopsis [<plugin>] */ - function status( $args, $assoc_args ) { - parent::status( $args, $assoc_args ); + function status( $args ) { + parent::status( $args ); } protected function status_single( $args ) { From 0021a7363bce5dae043c8f0512b7f1c467126930 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Tue, 30 Apr 2013 11:39:58 +0200 Subject: [PATCH 1573/4858] Check empty version for mu-plugins, remove unnecessary formatting --- php/WP_CLI/CommandWithUpgrade.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index a994eb22d9..01d1c06a30 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -48,8 +48,10 @@ private function status_all() { $line = ' '; } $line .= $this->format_status( $details['status'], 'short' ); - $line .= " " . str_pad( $details['name'], $padding ); - $line .= "%n " . $this->format_version( $details['version'] ) . "%n"; + $line .= " " . str_pad( $details['name'], $padding ). "%n"; + if ( !empty( $details['version'] ) ) { + $line .= " " . $details['version']; + } \WP_CLI::line( $line ); } @@ -199,10 +201,6 @@ protected function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } - protected function format_version( $version ) { - return '' . $version; - } - private function get_color( $status ) { static $colors = array( 'inactive' => '', From af75f064de177106040541897a23ee8bc1702c2d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 16:55:01 +0300 Subject: [PATCH 1574/4858] add basic shell smoke test --- features/shell.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 features/shell.feature diff --git a/features/shell.feature b/features/shell.feature new file mode 100644 index 0000000000..924f84fa07 --- /dev/null +++ b/features/shell.feature @@ -0,0 +1,11 @@ +Feature: WordPress REPL + + Scenario: Blank session + Given a WP install + + When I run `wp shell < /dev/null` + Then it should run without errors + And STDOUT should be: + """ + Type "exit" to close session. + """ From 55f887dc50c66626f9cb187132d36f886904bdb1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 17:21:48 +0300 Subject: [PATCH 1575/4858] shell: use WP_CLI::print_value(), since we don't want to colorize the output --- php/commands/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 02daaed999..d379d93a61 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -36,7 +36,7 @@ public function __invoke() { eval( $line ); - \WP_CLI::line( var_export( $_, false ) ); + \WP_CLI::print_value( var_export( $_, false ) ); } } } From 938d2ba47491ea86a965f125f224ba3536ee9ce9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 17:26:51 +0300 Subject: [PATCH 1576/4858] behat: add newline to generated files `wp shell` expects it --- features/shell.feature | 20 ++++++++++++++++++++ features/steps/basic_steps.php | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/features/shell.feature b/features/shell.feature index 924f84fa07..2131772042 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -9,3 +9,23 @@ Feature: WordPress REPL """ Type "exit" to close session. """ + + Scenario: Basic session + Given a WP install + And a session file: + """ + WP_ADMIN + $_ + get_current_user_id() + $_ + """ + + When I run `wp shell --quiet < session` + Then it should run without errors + And STDOUT should be: + """ + true + true + 0 + 0 + """ diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 1d10594dc1..0002a6c54b 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -12,7 +12,8 @@ function ( $world ) { $steps->Given( '/^a ([^\s]+) file:$/', function ( $world, $path, PyStringNode $content ) { - file_put_contents( $world->get_path( $path ), (string) $content ); + $content = (string) $content . "\n"; + file_put_contents( $world->get_path( $path ), $content ); } ); From b5b6abcc10b4ee6196d0abbd48d7639d1c2f3b1c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 18:02:02 +0300 Subject: [PATCH 1577/4858] travis: don't send email notifications on success Branches always go through pull requests, which give plenty of feedback about the build status. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 48687d040a..f6bfe635b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,3 +23,7 @@ before_script: - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot script: vendor/bin/phpunit && vendor/bin/behat + +notifications: + email: + on_success: never From e7dd57240e6f958f6357985b2a35629a69fa6028 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 18:17:22 +0300 Subject: [PATCH 1578/4858] test declaring functions and variables in a shell session --- features/shell.feature | 19 ++++++++++++++++++- php/commands/shell.php | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index 2131772042..8c29ca78dd 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -10,7 +10,7 @@ Feature: WordPress REPL Type "exit" to close session. """ - Scenario: Basic session + Scenario: $_ special variable Given a WP install And a session file: """ @@ -29,3 +29,20 @@ Feature: WordPress REPL 0 0 """ + + Scenario: Persistent environment + Given a WP install + And a session file: + """ + function is_empty_string( $str ) { return strlen( $str ) == 0; } + 1; $a = get_option('home') + is_empty_string( $a ) + """ + + When I run `wp shell --quiet < session` + Then it should run without errors + And STDOUT should be: + """ + 1 + false + """ diff --git a/php/commands/shell.php b/php/commands/shell.php index d379d93a61..32e0808a23 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -43,7 +43,7 @@ public function __invoke() { private static function non_expressions() { return implode( '|', array( - 'echo', 'global', 'unset', + 'echo', 'global', 'unset', 'function', 'while', 'for', 'foreach', 'if', 'switch', 'include', 'include\_once', 'require', 'require\_once' ) ); From 5ca08111848514241bb2cdb1d0d956660fd0dbda Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 18:26:28 +0300 Subject: [PATCH 1579/4858] add test for 'history' builtin; see #373 --- features/shell.feature | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/features/shell.feature b/features/shell.feature index 8c29ca78dd..9015f678db 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -46,3 +46,22 @@ Feature: WordPress REPL 1 false """ + + Scenario: History builtin + Given a WP install + And a session file: + """ + defined('WP_CLI') + function foo() {} + history + """ + + When I run `wp shell --quiet < session` + Then it should run without errors + And STDOUT should be: + """ + true + defined('WP_CLI'); + function foo() {}; + """ + From 8fa99e9b589dc80a69bff2bcf19f0f7aff7a1b9b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 19:37:47 +0300 Subject: [PATCH 1580/4858] Add multiline support to `wp shell` via backslash We could remove the -r flag from the `read` builtin, but that would have several drawbacks: * couldn't dynamically change the prompt * would add another layer of escaping, on top of PHP's eval() --- features/shell.feature | 18 ++++++++++++++++++ php/commands/shell.php | 34 +++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index 9015f678db..2cc9c47f83 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -65,3 +65,21 @@ Feature: WordPress REPL function foo() {}; """ + Scenario: Multiline support + Given a WP install + And a session file: + """ + function is_empty_string( $str ) { \ + return strlen( $str ) == 0; \ + } + + function_exists( 'is_empty_string' ) + """ + + When I run `wp shell --quiet < session` + Then it should run without errors + And STDOUT should be: + """ + true + """ + diff --git a/php/commands/shell.php b/php/commands/shell.php index 32e0808a23..0c586ccc43 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -50,21 +50,37 @@ private static function non_expressions() { } private function prompt() { - static $cmd; + $full_line = false; - if ( !$cmd ) { - $cmd = self::create_prompt_cmd( 'wp> ', $this->history_file ); - } + $done = false; + do { + $prompt = ( !$done && $full_line !== false ) ? '--> ' : 'wp> '; + + $fp = popen( self::create_prompt_cmd( $prompt, $this->history_file ), 'r' ); + + $line = fgets( $fp ); + + if ( !$line ) { + break; + } + + $line = rtrim( $line, "\n" ); + + if ( $line && '\\' == $line[ strlen( $line ) - 1 ] ) { + $line = substr( $line, 0, -1 ); + } else { + $done = true; + } - $fp = popen( $cmd, 'r' ); + $full_line .= $line; - $line = fgets( $fp ); + } while ( !$done ); - if ( !$line ) { - $line = 'exit'; + if ( $full_line === false ) { + return 'exit'; } - return trim( $line ); + return $full_line; } private static function create_prompt_cmd( $prompt, $history_path ) { From c7739f0822ea64c71fe15f673d9932680ec07940 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Apr 2013 19:53:22 +0300 Subject: [PATCH 1581/4858] update shell man page [ci skip] --- man-src/shell.txt | 4 ++++ man/shell.1 | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/man-src/shell.txt b/man-src/shell.txt index ccd56f4937..1759cffb53 100644 --- a/man-src/shell.txt +++ b/man-src/shell.txt @@ -2,4 +2,8 @@ `wp shell` allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example. +`$_` is a special variable that contains the result from the last evaluated statement. + +You can split a statement over multiple lines by adding a `\` (backslash) before hitting Return. + If you type `history` and hit Return, WP-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file. diff --git a/man/shell.1 b/man/shell.1 index de0e717e1f..d145d4a612 100644 --- a/man/shell.1 +++ b/man/shell.1 @@ -13,4 +13,10 @@ wp shell \fBwp shell\fR allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment\. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example\. . .P +\fB$_\fR is a special variable that contains the result from the last evaluated statement\. +. +.P +You can split a statement over multiple lines by adding a \fB\e\fR (backslash) before hitting Return\. +. +.P If you type \fBhistory\fR and hit Return, WP\-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file\. From a6265228f7695b265877022f0c9acc6b35ed432a Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Wed, 1 May 2013 09:17:23 +0200 Subject: [PATCH 1582/4858] Show version on wp theme status by default --- php/commands/theme.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 9e8ad5aff0..f7670c8cb1 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -133,6 +133,7 @@ protected function get_item_list() { 'name' => $key, 'status' => $this->get_status( $theme ), 'update' => $this->has_update( $theme->get_stylesheet() ), + 'version' => $theme->get('Version'), 'update_id' => $theme->get_stylesheet(), ); } From 2065b139b5a17ca73e7d15f5a217d2eaf6fc3adb Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Wed, 1 May 2013 17:07:09 +0000 Subject: [PATCH 1583/4858] Rename multisite.feature to blog.feature; add feature tests for wp blog empty --- features/{multisite.feature => blog.feature} | 25 +++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) rename features/{multisite.feature => blog.feature} (56%) diff --git a/features/multisite.feature b/features/blog.feature similarity index 56% rename from features/multisite.feature rename to features/blog.feature index 536fed7f51..264dd66d40 100644 --- a/features/multisite.feature +++ b/features/blog.feature @@ -1,4 +1,4 @@ -Feature: Manage a WordPress multisite installation +Feature: Manage a WordPress installation Scenario: Install multisite Given a WP install @@ -37,3 +37,26 @@ Feature: Manage a WordPress multisite installation When I run the previous command again Then the return code should be 1 + + Scenario: Empty a blog + Given a WP install + + When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term'` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp blog empty --yes` + Then it should run without errors + And STDOUT should not be empty + + When I run `wp post list --format=ids` + Then it should run without errors + And STDOUT should be empty + + When I run `wp term list post_tag --format=ids` + Then it should run without errors + And STDOUT should be empty \ No newline at end of file From 5b203f5594b8a095518a37af7cf5e43a80a7506c Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Wed, 1 May 2013 17:14:06 +0000 Subject: [PATCH 1584/4858] Add docblock mention for --yes flag --- php/commands/blog.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/blog.php b/php/commands/blog.php index 32229c6848..15686aa80b 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -111,6 +111,7 @@ private function _insert_default_terms() { * Empty a blog * * @subcommand empty + * @synopsis [--yes] */ public function _empty( $args, $assoc_args ) { From c7b4d0691a5f14799e9bbc531c70a1ef49c4351b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 3 May 2013 18:50:51 +0300 Subject: [PATCH 1585/4858] remove empty constructor from MS_Blog_Command see #416 and #410 --- php/commands/blog.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index 15686aa80b..ae91486aed 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -131,8 +131,6 @@ public function _empty( $args, $assoc_args ) { */ class MS_Blog_Command extends Blog_Command { - public function __construct() { } - /** * Delete a blog in a multisite install. * From eb7584f30ec4872703fce07c5260b371c245bc6c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 3 May 2013 19:55:38 +0300 Subject: [PATCH 1586/4858] add missing dots to blog subcommand descriptions see #410 --- man/blog-empty.1 | 4 ++-- php/commands/blog.php | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/man/blog-empty.1 b/man/blog-empty.1 index 137b9c69c0..34cf749fca 100644 --- a/man/blog-empty.1 +++ b/man/blog-empty.1 @@ -4,10 +4,10 @@ .TH "WP\-BLOG\-EMPTY" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-blog\-empty\fR \- Empty a blog +\fBwp\-blog\-empty\fR \- Empty a blog of its content\. . .SH "SYNOPSIS" -wp blog empty +wp blog empty [\-\-yes] . .SH "EXAMPLES" . diff --git a/php/commands/blog.php b/php/commands/blog.php index ae91486aed..3c38438d39 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -1,14 +1,14 @@ <?php /** - * Manage blog(s) + * Manage blog. * * @package wp-cli */ class Blog_Command extends WP_CLI_Command { /** - * Delete comments + * Delete comments. */ private function _empty_comments() { global $wpdb; @@ -24,7 +24,7 @@ private function _empty_comments() { } /** - * Delete all posts + * Delete all posts. */ private function _empty_posts() { global $wpdb; @@ -51,7 +51,7 @@ private function _empty_posts() { } /** - * Delete terms, taxonomies, and tax relationships + * Delete terms, taxonomies, and tax relationships. */ private function _empty_taxonomies() { global $wpdb; @@ -64,13 +64,13 @@ private function _empty_taxonomies() { $ids[] = $term->term_id; wp_cache_delete( $term->term_id, $term->taxonomy ); } - + $taxonomies = array_unique( $taxonomies ); foreach ( $taxonomies as $taxonomy ) { if ( isset( $cleaned[$taxonomy] ) ) continue; $cleaned[$taxonomy] = true; - + wp_cache_delete( 'all_ids', $taxonomy ); wp_cache_delete( 'get', $taxonomy ); delete_option( "{$taxonomy}_children" ); @@ -81,7 +81,7 @@ private function _empty_taxonomies() { } /** - * Insert default terms + * Insert default terms. */ private function _insert_default_terms() { global $wpdb; @@ -108,7 +108,7 @@ private function _insert_default_terms() { } /** - * Empty a blog + * Empty a blog of its content. * * @subcommand empty * @synopsis [--yes] @@ -127,7 +127,7 @@ public function _empty( $args, $assoc_args ) { } /** - * Manage blogs in a multisite install + * Manage blogs in a multisite install. */ class MS_Blog_Command extends Blog_Command { @@ -161,7 +161,7 @@ function delete( $args, $assoc_args ) { } /** - * Get site (network) data for a given id + * Get site (network) data for a given id. * * @param int $site_id * @return bool|array False if no network found with given id, array otherwise From 57d66645ee7f313dc9fe73674a1d7642ea1ee4b9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 3 May 2013 21:02:53 +0300 Subject: [PATCH 1587/4858] behat: merge _run() and run() methods --- features/bootstrap/FeatureContext.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 19b7025c23..040401788d 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -122,7 +122,12 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - private function _run( $command, $assoc_args, $subdir = '' ) { + public function run( $command, $assoc_args = array(), $subdir = '' ) { + if ( isset( self::$additional_args[ $command ] ) ) { + $assoc_args = array_merge( self::$additional_args[ $command ], + $assoc_args ); + } + if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); @@ -155,15 +160,6 @@ private function _run( $command, $assoc_args, $subdir = '' ) { return $r; } - public function run( $command, $assoc_args = array(), $subdir = '' ) { - if ( isset( self::$additional_args[ $command ] ) ) { - $assoc_args = array_merge( self::$additional_args[ $command ], - $assoc_args ); - } - - return $this->_run( $command, $assoc_args, $subdir ); - } - public function move_files( $src, $dest ) { rename( $this->get_path( $src ), $this->get_path( $dest ) ); } @@ -179,7 +175,7 @@ public function download_wordpress_files( $subdir = '' ) { // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - $r = $this->_run( 'core download', array( + $r = $this->run( 'core download', array( 'path' => $cache_dir ) ); From ac5b70ce6199cccfa631f48a1d6ba285918ec88f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 3 May 2013 21:45:09 +0300 Subject: [PATCH 1588/4858] behat: introduce Process class The run_check() method is a shortcut for implicitly checking that a command runs succesfully. --- features/bootstrap/FeatureContext.php | 46 +++++---------------- features/bootstrap/Process.php | 58 +++++++++++++++++++++++++++ features/steps/basic_steps.php | 22 +++++----- 3 files changed, 78 insertions(+), 48 deletions(-) create mode 100644 features/bootstrap/Process.php diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 040401788d..ab61ffe598 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -94,14 +94,14 @@ public function get_cache_path( $file ) { if ( !$path ) { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - system( Utils\esc_cmd( 'mkdir -p %s', $path ) ); + Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); } return $path . '/' . $file; } public function download_file( $url, $path ) { - system( Utils\esc_cmd( 'curl -sSL %s > %s', $url, $path ) ); + Process::create( Utils\esc_cmd( 'curl -sSL %s > %s', $url, $path ) )->run_check(); } private static function run_sql( $sql ) { @@ -122,7 +122,7 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - public function run( $command, $assoc_args = array(), $subdir = '' ) { + public function proc( $command, $assoc_args = array() ) { if ( isset( self::$additional_args[ $command ] ) ) { $assoc_args = array_merge( self::$additional_args[ $command ], $assoc_args ); @@ -131,33 +131,7 @@ public function run( $command, $assoc_args = array(), $subdir = '' ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - $subdir = $this->get_path( $subdir ); - - $cmd = __DIR__ . "/../../bin/wp $command"; - - $descriptors = array( - 0 => STDIN, - 1 => array( 'pipe', 'w' ), - 2 => array( 'pipe', 'w' ), - ); - - $proc = proc_open( $cmd, $descriptors, $pipes, $subdir ); - - $STDOUT = stream_get_contents( $pipes[1] ); - fclose( $pipes[1] ); - - $STDERR = stream_get_contents( $pipes[2] ); - fclose( $pipes[2] ); - - $r = (object) array( - 'command' => $command, - 'STDOUT' => $STDOUT, - 'STDERR' => $STDERR, - 'return_code' => proc_close( $proc ), - 'cwd' => $this->install_dir - ); - - return $r; + return Process::create( __DIR__ . "/../../bin/wp $command", $this->install_dir ); } public function move_files( $src, $dest ) { @@ -175,25 +149,23 @@ public function download_wordpress_files( $subdir = '' ) { // Ideally, we'd cache at the HTTP layer for more reliable tests $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - $r = $this->run( 'core download', array( + $r = $this->proc( 'core download', array( 'path' => $cache_dir - ) ); + ) )->run(); $dest_dir = $this->get_path( $subdir ); if ( $subdir ) mkdir( $dest_dir ); - $cmd = Utils\esc_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ); - - system( $cmd ); + Process::create( Utils\esc_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ) )->run_check(); } public function wp_install( $subdir = '' ) { $this->create_db(); $this->create_empty_dir(); $this->download_wordpress_files( $subdir ); - $this->run( 'core config', array(), $subdir ); - $this->run( 'core install', array(), $subdir ); + $this->proc( 'core config' )->run_check( $subdir ); + $this->proc( 'core install' )->run_check( $subdir ); } } diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php new file mode 100644 index 0000000000..0776a28653 --- /dev/null +++ b/features/bootstrap/Process.php @@ -0,0 +1,58 @@ +<?php + +class Process { + + public static function create( $command, $cwd = null ) { + $proc = new self; + + $proc->command = $command; + $proc->cwd = $cwd; + + return $proc; + } + + private $command, $cwd; + + private function __construct() {} + + public function run( $subdir = '' ) { + $cwd = $this->cwd; + if ( $subdir ) { + $cwd .= '/' . $subdir; + } + + $descriptors = array( + 0 => STDIN, + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ); + + $proc = proc_open( $this->command, $descriptors, $pipes, $cwd ); + + $STDOUT = stream_get_contents( $pipes[1] ); + fclose( $pipes[1] ); + + $STDERR = stream_get_contents( $pipes[2] ); + fclose( $pipes[2] ); + + return (object) array( + 'STDOUT' => $STDOUT, + 'STDERR' => $STDERR, + 'return_code' => proc_close( $proc ), + 'command' => $this->command, + 'cwd' => $cwd + ); + } + + public function run_check( $subdir = '' ) { + $r = $this->run( $subdir ); + + if ( $r->return_code ) { + throw new \RuntimeException( sprintf( "%s: %s\ncwd: %s", + $r->command, $r->STDERR, $r->cwd ) ); + } + + return $r; + } +} + diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 0002a6c54b..3b6905e100 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -25,7 +25,7 @@ function ( $world ) { $steps->Given( '/^wp-config\.php$/', function ( $world ) { - $world->run( 'core config' ); + $world->proc( 'core config' )->run_check(); } ); @@ -50,7 +50,7 @@ function ( $world, $subdir ) { $steps->Given( '/^a WP multisite install$/', function ( $world ) { $world->wp_install(); - $world->run( 'core install-network' ); + $world->proc( 'core install-network' )->run_check(); } ); @@ -96,29 +96,29 @@ function ( $world ) { $steps->Given( '/^a large image file$/', function ( $world ) { - $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; + $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; - $world->variables['DOWNLOADED_IMAGE'] = $world->get_cache_path( 'wallpaper.jpg' ); + $world->variables['DOWNLOADED_IMAGE'] = $world->get_cache_path( 'wallpaper.jpg' ); - $world->download_file( $image_file, $world->variables['DOWNLOADED_IMAGE'] ); + $world->download_file( $image_file, $world->variables['DOWNLOADED_IMAGE'] ); } ); $steps->When( '/^I run `wp`$/', function ( $world ) { - $world->result = $world->run( '' ); + $world->result = $world->proc( '' )->run(); } ); $steps->When( '/^I run `wp (.+)`$/', function ( $world, $cmd ) { - $world->result = $world->run( $world->replace_variables( $cmd ) ); + $world->result = $world->proc( $world->replace_variables( $cmd ) )->run(); } ); $steps->When( "/^I run `wp (.+)` from '([^\s]+)'$/", function ( $world, $cmd, $subdir ) { - $world->result = $world->run( $world->replace_variables( $cmd ), array(), $subdir ); + $world->result = $world->proc( $world->replace_variables( $cmd ) )->run( $subdir ); } ); @@ -127,7 +127,7 @@ function ( $world ) { if ( !isset( $world->result ) ) throw new \Exception( 'No previous command.' ); - $world->result = $world->run( $world->result->command ); + $world->result = Process::create( $world->result->command, $world->result->cwd )->run(); } ); @@ -136,7 +136,7 @@ function ( $world ) { if ( !isset( $world->variables['DOWNLOADED_IMAGE'] ) ) throw new \Exception( 'Cached image not available.' ); - $world->result = $world->run( 'media import ' . $world->variables['DOWNLOADED_IMAGE'] . ' --post_id=1 --featured_image' ); + $world->result = $world->proc( 'media import ' . $world->variables['DOWNLOADED_IMAGE'] . ' --post_id=1 --featured_image' )->run(); } ); @@ -234,7 +234,7 @@ function ( $world, PyStringNode $expected ) { $steps->Then( '/^STDOUT should be CSV containing:$/', function( $world, PyStringNode $expected ) { - + $output = $world->result->STDOUT; $expected = $world->replace_variables( (string) $expected ); From 40deddeba9d8a572b4e51673e605674933860852 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 3 May 2013 23:57:40 +0300 Subject: [PATCH 1589/4858] behat: set different db prefix for subdir install --- features/bootstrap/FeatureContext.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index ab61ffe598..1245620f2a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -164,7 +164,9 @@ public function wp_install( $subdir = '' ) { $this->create_db(); $this->create_empty_dir(); $this->download_wordpress_files( $subdir ); - $this->proc( 'core config' )->run_check( $subdir ); + + $this->proc( 'core config', array( 'dbprefix' => $subdir ? $subdir : 'wp_' ) )->run_check( $subdir ); + $this->proc( 'core install' )->run_check( $subdir ); } } From 4f4ba1a1c6b37622c791be3041f6df0b06f106c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 4 May 2013 01:00:07 +0300 Subject: [PATCH 1590/4858] behat: be more verbose when a command fails --- features/steps/basic_steps.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 3b6905e100..f0591acfe7 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -154,8 +154,11 @@ function ( $world, $return_code ) { $steps->Then( '/^it should run without errors$/', function ( $world ) { - if ( !empty( $world->result->STDERR ) ) - throw new \Exception( $world->result->STDERR ); + if ( !empty( $world->result->STDERR ) ) { + $r = $world->result; + throw new \Exception( sprintf( "%s: %s\ncwd: %s", + $r->command, $r->STDERR, $r->cwd ) ); + } if ( 0 != $world->result->return_code ) throw new \Exception( "Return code was $world->result->return_code" ); From e66e78bb8bc486287e8dd8792d37d73ec2c4f285 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 4 May 2013 01:01:32 +0300 Subject: [PATCH 1591/4858] generate test plugin on the fly, instead of downloading one from github --- features/help.feature | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/features/help.feature b/features/help.feature index af077c730a..5a410db416 100644 --- a/features/help.feature +++ b/features/help.feature @@ -29,15 +29,23 @@ Feature: Get help about WP-CLI commands Scenario: Getting help for a third-party command Given a WP install - And a google-sitemap-generator-cli plugin zip - And I run `wp plugin install --activate {PLUGIN_ZIP}` - And it should run without errors - And I run `wp plugin install --activate google-sitemap-generator` + And a wp-content/plugins/test-cli-help.php file: + """ + <?php + // Plugin Name: Test CLI Help + + class Test_Help extends WP_CLI_Command { + function __invoke() {} + } + + WP_CLI::add_command( 'test-help', 'Test_Help' ); + """ + And I run `wp plugin activate test-cli-help` And it should run without errors - When I run `wp help google-sitemap` + When I run `wp help test-help` Then it should run without errors And STDOUT should contain: """ - usage: wp google-sitemap + usage: wp test-help """ From f7bc7c39554b195a96ec37c3624a395dfe6756ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 4 May 2013 01:14:50 +0300 Subject: [PATCH 1592/4858] behat: remove unused step definition. see #434 --- features/steps/basic_steps.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index f0591acfe7..89368ceb7c 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -84,16 +84,6 @@ function ( $world ) { } ); -$steps->Given( '/^a google-sitemap-generator-cli plugin zip$/', - function ( $world ) { - $zip_url = 'https://github.com/wp-cli/google-sitemap-generator-cli/archive/master.zip'; - - $world->variables['PLUGIN_ZIP'] = $world->get_cache_path( 'google-sitemap-generator-cli.zip' ); - - $world->download_file( $zip_url, $world->variables['PLUGIN_ZIP'] ); - } -); - $steps->Given( '/^a large image file$/', function ( $world ) { $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; From c5126c4f15dc2f8cea49561c9a61d6355328ffca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 4 May 2013 01:30:14 +0300 Subject: [PATCH 1593/4858] outut a single error message, instead of multiple warnings fixes #114 --- php/WP_CLI/SynopsisParser.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index b488c71957..0cc8a49a7b 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -60,11 +60,12 @@ private function check_assoc( $assoc_args, $callback ) { } if ( !empty( $errors ) ) { + $out = ''; foreach ( $errors as $error ) { - \WP_CLI::warning( $error ); + $out .= "\n " . $error; } - call_user_func( $callback ); - exit(1); + + \WP_CLI::error( $out, "Parameter errors" ); } } From 2f84fe816ebf1b2d2efda20fb44b79a493e599aa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 6 May 2013 22:26:17 +0300 Subject: [PATCH 1594/4858] argument validation: separate logic from presentation also, show warning when an optional assoc param doesn't have a value see #436 --- php/WP_CLI/Dispatcher/Subcommand.php | 47 ++++++++++++++----- php/WP_CLI/SynopsisParser.php | 67 +++++++++------------------- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 8b3bae2451..23afd66ffe 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -26,6 +26,14 @@ function get_alias() { return $this->docparser->get_tag( 'alias' ); } + function get_name() { + return $this->name; + } + + function get_parent() { + return $this->parent; + } + function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $prefix . $this->get_full_synopsis() ); } @@ -58,25 +66,42 @@ function get_synopsis() { return $this->docparser->get_synopsis(); } - function invoke( $args, $assoc_args ) { + private function validate_args( $args, $assoc_args ) { $synopsis = $this->get_synopsis(); - if ( $synopsis ) { - \WP_CLI\SynopsisParser::validate_args( $synopsis, $args, $assoc_args, - array( $this, 'show_usage' ) ); + if ( !$synopsis ) + return; + + $parser = new \WP_CLI\SynopsisParser( $synopsis ); + if ( !$parser->enough_positionals( $args ) ) { + $this->show_usage(); + exit(1); } - $instance = new $this->method->class; + $errors = $parser->validate_assoc( $assoc_args ); - call_user_func( array( $instance, $this->method->name ), $args, $assoc_args ); - } + if ( !empty( $errors['fatal'] ) ) { + $out = ''; + foreach ( $errors['fatal'] as $error ) { + $out .= "\n " . $error; + } - function get_name() { - return $this->name; + \WP_CLI::error( $out, "Parameter errors" ); + } + + array_map( '\\WP_CLI::warning', $errors['warnings'] ); + + foreach ( $parser->unknown_assoc( $assoc_args ) as $key ) { + \WP_CLI::warning( "unknown --$key parameter" ); + } } - function get_parent() { - return $this->parent; + function invoke( $args, $assoc_args ) { + $this->validate_args( $args, $assoc_args ); + + $instance = new $this->method->class; + + call_user_func( array( $instance, $this->method->name ), $args, $assoc_args ); } } diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 0cc8a49a7b..c0eba6f555 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -8,68 +8,47 @@ class SynopsisParser { private $params = array(); - /** - * @param string Synopsis - * @param array Positional args - * @param array Associative args - * @param callback What to do on a critical failure - */ - static function validate_args( $synopsis, $args, $assoc_args, $callback ) { - $instance = new self( $synopsis ); - - $instance->check_positional( $args, $callback ); - - $instance->check_assoc( $assoc_args, $callback ); - - $instance->check_unknown_assoc( $assoc_args ); - } - - private function __construct( $synopsis ) { + public function __construct( $synopsis ) { $this->params = $this->parse( $synopsis ); } - private function check_positional( $args, $callback ) { + public function enough_positionals( $args ) { $positional = $this->query_params( array( 'type' => 'positional', 'flavour' => 'mandatory' ) ); - if ( count( $args ) < count( $positional ) ) { - call_user_func( $callback ); - exit(1); - } + return count( $args ) >= count( $positional ); } - private function check_assoc( $assoc_args, $callback ) { + public function validate_assoc( $assoc_args ) { $assoc_args += \WP_CLI::get_config(); - $errors = array(); - - $mandatory_assoc = $this->query_params( array( + $assoc = $this->query_params( array( 'type' => 'assoc', - 'flavour' => 'mandatory' ) ); - foreach ( $mandatory_assoc as $param ) { - $key = $param['name']; + $errors = array(); - if ( !isset( $assoc_args[ $key ] ) ) - $errors[] = "missing --$key parameter"; - elseif ( true === $assoc_args[ $key ] ) - $errors[] = "--$key parameter needs a value"; - } + foreach ( $assoc as $param ) { + $key = $param['name']; - if ( !empty( $errors ) ) { - $out = ''; - foreach ( $errors as $error ) { - $out .= "\n " . $error; + if ( !isset( $assoc_args[ $key ] ) ) { + if ( 'mandatory' == $param['flavour'] ) { + $errors['fatal'][] = "missing --$key parameter"; + } + } else { + if ( true === $assoc_args[ $key ] ) { + $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning'; + $errors[ $error_type ][] = "--$key parameter needs a value"; + } } - - \WP_CLI::error( $out, "Parameter errors" ); } + + return $errors; } - private function check_unknown_assoc( $assoc_args ) { + public function unknown_assoc( $assoc_args ) { $generic = $this->query_params( array( 'type' => 'generic', ) ); @@ -84,11 +63,7 @@ private function check_unknown_assoc( $assoc_args ) { $known_assoc[] = $param['name']; } - $unknown_assoc = array_diff( array_keys( $assoc_args ), $known_assoc ); - - foreach ( $unknown_assoc as $key ) { - \WP_CLI::warning( "unknown --$key parameter" ); - } + return array_diff( array_keys( $assoc_args ), $known_assoc ); } /** From 2f621fc9ee0dbb9feb0e2b37972dff92bd950738 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 6 May 2013 22:53:26 +0300 Subject: [PATCH 1595/4858] add empty arrays, to avoid notices --- php/WP_CLI/SynopsisParser.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index c0eba6f555..06b1e4950c 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -28,7 +28,10 @@ public function validate_assoc( $assoc_args ) { 'type' => 'assoc', ) ); - $errors = array(); + $errors = array( + 'fatal' => array(), + 'warnings' => array() + ); foreach ( $assoc as $param ) { $key = $param['name']; @@ -54,7 +57,7 @@ public function unknown_assoc( $assoc_args ) { ) ); if ( count( $generic ) ) - return; + return array(); $known_assoc = array(); From 81f0c26472a8f8983c675a8a7772d0567e9bec0b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 6 May 2013 23:14:04 +0300 Subject: [PATCH 1596/4858] add some unit tests for argument validation methods --- php/WP_CLI/Dispatcher/Subcommand.php | 4 +-- php/WP_CLI/SynopsisParser.php | 4 +-- tests/test-arg-validation.php | 50 ++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 tests/test-arg-validation.php diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 23afd66ffe..8845b2a412 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -78,7 +78,7 @@ private function validate_args( $args, $assoc_args ) { exit(1); } - $errors = $parser->validate_assoc( $assoc_args ); + $errors = $parser->validate_assoc( array_merge( WP_CLI::get_config(), $assoc_args ) ); if ( !empty( $errors['fatal'] ) ) { $out = ''; @@ -89,7 +89,7 @@ private function validate_args( $args, $assoc_args ) { \WP_CLI::error( $out, "Parameter errors" ); } - array_map( '\\WP_CLI::warning', $errors['warnings'] ); + array_map( '\\WP_CLI::warning', $errors['warning'] ); foreach ( $parser->unknown_assoc( $assoc_args ) as $key ) { \WP_CLI::warning( "unknown --$key parameter" ); diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 06b1e4950c..e0b316c22c 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -22,15 +22,13 @@ public function enough_positionals( $args ) { } public function validate_assoc( $assoc_args ) { - $assoc_args += \WP_CLI::get_config(); - $assoc = $this->query_params( array( 'type' => 'assoc', ) ); $errors = array( 'fatal' => array(), - 'warnings' => array() + 'warning' => array() ); foreach ( $assoc as $param ) { diff --git a/tests/test-arg-validation.php b/tests/test-arg-validation.php new file mode 100644 index 0000000000..8875891196 --- /dev/null +++ b/tests/test-arg-validation.php @@ -0,0 +1,50 @@ +<?php + +use WP_CLI\SynopsisParser; + +class ArgValidationTests extends PHPUnit_Framework_TestCase { + + function testMissingPositional() { + $parser = new SynopsisParser( '<foo> <bar> [<baz>]' ); + + $this->assertFalse( $parser->enough_positionals( array() ) ); + $this->assertTrue( $parser->enough_positionals( array( 1, 2 ) ) ); + $this->assertTrue( $parser->enough_positionals( array( 1, 2, 3, 4 ) ) ); + } + + function testRepeatingPositional() { + $parser = new SynopsisParser( '<foo> [<bar>...]' ); + + $this->assertFalse( $parser->enough_positionals( array() ) ); + $this->assertTrue( $parser->enough_positionals( array( 1 ) ) ); + $this->assertTrue( $parser->enough_positionals( array( 1, 2, 3 ) ) ); + } + + function testUnknownAssocEmpty() { + $parser = new SynopsisParser( '' ); + + $assoc_args = array( 'foo' => true, 'bar' => false ); + $this->assertEquals( array_keys( $assoc_args ), $parser->unknown_assoc( $assoc_args ) ); + } + + function testUnknownAssoc() { + $parser = new SynopsisParser( '--type=<type> [--brand=<brand>] [--flag]' ); + + $assoc_args = array( 'type' => 'analog', 'brand' => true, 'flag' => true ); + $this->assertEmpty( $parser->unknown_assoc( $assoc_args ) ); + + $assoc_args['another'] = true; + $this->assertContains( 'another', $parser->unknown_assoc( $assoc_args ) ); + } + + function testMissingAssoc() { + $parser = new SynopsisParser( '--type=<type> [--brand=<brand>] [--flag]' ); + + $assoc_args = array( 'brand' => true, 'flag' => true ); + $errors = $parser->validate_assoc( $assoc_args ); + + $this->assertCount( 1, $errors['fatal'] ); + $this->assertCount( 1, $errors['warning'] ); + } +} + From 33b48341977f7eee71041f0e8e5c382a0f2be0f9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 6 May 2013 23:28:26 +0300 Subject: [PATCH 1597/4858] fix SynopsisParser::validate_args() not finding the WP_CLI class --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 8845b2a412..4ac02a7df0 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -78,7 +78,7 @@ private function validate_args( $args, $assoc_args ) { exit(1); } - $errors = $parser->validate_assoc( array_merge( WP_CLI::get_config(), $assoc_args ) ); + $errors = $parser->validate_assoc( array_merge( \WP_CLI::get_config(), $assoc_args ) ); if ( !empty( $errors['fatal'] ) ) { $out = ''; From 6f0789b4e62c9baee02f7d8c0b80e6d78da9c571 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 6 May 2013 23:52:38 +0300 Subject: [PATCH 1598/4858] remove invalid assoc args before. fixes #436 --- php/WP_CLI/Dispatcher/Subcommand.php | 4 ++-- php/WP_CLI/SynopsisParser.php | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 4ac02a7df0..8c6191419d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -66,7 +66,7 @@ function get_synopsis() { return $this->docparser->get_synopsis(); } - private function validate_args( $args, $assoc_args ) { + private function validate_args( $args, &$assoc_args ) { $synopsis = $this->get_synopsis(); if ( !$synopsis ) @@ -78,7 +78,7 @@ private function validate_args( $args, $assoc_args ) { exit(1); } - $errors = $parser->validate_assoc( array_merge( \WP_CLI::get_config(), $assoc_args ) ); + $errors = $parser->validate_assoc( $assoc_args, array_keys( \WP_CLI::get_config() ) ); if ( !empty( $errors['fatal'] ) ) { $out = ''; diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index e0b316c22c..2021c486c8 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -21,7 +21,7 @@ public function enough_positionals( $args ) { return count( $args ) >= count( $positional ); } - public function validate_assoc( $assoc_args ) { + public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { $assoc = $this->query_params( array( 'type' => 'assoc', ) ); @@ -34,6 +34,9 @@ public function validate_assoc( $assoc_args ) { foreach ( $assoc as $param ) { $key = $param['name']; + if ( in_array( $key, $ignored_keys ) ) + continue; + if ( !isset( $assoc_args[ $key ] ) ) { if ( 'mandatory' == $param['flavour'] ) { $errors['fatal'][] = "missing --$key parameter"; @@ -42,6 +45,8 @@ public function validate_assoc( $assoc_args ) { if ( true === $assoc_args[ $key ] ) { $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning'; $errors[ $error_type ][] = "--$key parameter needs a value"; + + unset( $assoc_args[ $key ] ); } } } From 3500a184e5ca652370fdaa7e2c2217290fadf69c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 7 May 2013 00:27:29 +0300 Subject: [PATCH 1599/4858] make $items the first parameter in format_items() The idea is that $items is in fact the most important value, guaranteed to be mandatory, whereas $format and $fields could be optional. --- php/commands/post.php | 6 ++---- php/commands/role.php | 2 +- php/commands/term.php | 2 +- php/commands/user.php | 2 +- php/utils.php | 11 +++++------ 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 7d966c3bbe..7228e4a1a1 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -123,7 +123,7 @@ public function get( $args, $assoc_args ) { $items[] = $item; } - \WP_CLI\Utils\format_items( $format, array( 'Field', 'Value' ), $items ); + \WP_CLI\Utils\format_items( $items, $format, array( 'Field', 'Value' ) ); break; case 'json': @@ -200,9 +200,7 @@ public function _list( $_, $assoc_args ) { $query = new WP_Query( $query_args ); - $output_posts = $query->posts; - - WP_CLI\Utils\format_items( $format, $fields, $output_posts ); + WP_CLI\Utils\format_items( $query->posts, $format, $fields ); } /** diff --git a/php/commands/role.php b/php/commands/role.php index a397dc6adc..cadfb96587 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -40,7 +40,7 @@ public function _list( $args, $assoc_args ) { $output_roles[] = $output_role; } - WP_CLI\Utils\format_items( $params['format'], $fields, $output_roles ); + WP_CLI\Utils\format_items( $output_roles, $params['format'], $fields ); } /** diff --git a/php/commands/term.php b/php/commands/term.php index 2a64f1b447..e72b209e48 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -41,7 +41,7 @@ public function _list( $args, $assoc_args ) { if ( 'ids' == $assoc_args['format'] ) $terms = wp_list_pluck( $terms, 'term_id' ); - WP_CLI\Utils\format_items( $assoc_args['format'], $fields, $terms ); + WP_CLI\Utils\format_items( $terms, $assoc_args['format'], $fields, $terms ); } /** diff --git a/php/commands/user.php b/php/commands/user.php index de3245f99e..09de1e64cc 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -53,7 +53,7 @@ public function _list( $args, $assoc_args ) { } } - WP_CLI\Utils\format_items( $params['format'], $fields, $users ); + WP_CLI\Utils\format_items( $users, $params['format'], $fields ); } /** diff --git a/php/utils.php b/php/utils.php index d6a0ff5ba3..99272dc7f6 100644 --- a/php/utils.php +++ b/php/utils.php @@ -252,11 +252,13 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria /** * Output items in a table, JSON, or CSV * - * @param string $format Format to use: 'table', 'json', 'csv' - * @param array|string $fields Named fields for each item of data. Can be array or CSV * @param array $items Data to output + * @param string $format Format to use: 'table', 'json', 'csv' + * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ -function format_items( $format, $fields, $items ) { +function format_items( $items, $format, $fields ) { + if ( 'ids' == $format ) + \WP_CLI::out( implode( ' ', $items ) ); if ( ! is_array( $fields ) ) $fields = explode( ',', $fields ); @@ -298,9 +300,6 @@ function format_items( $format, $fields, $items ) { else write_csv( STDOUT, $output_items, $fields ); break; - case 'ids': - \WP_CLI::out( implode( ' ', $items ) ); - break; } } From e94b5c2057ddeaade5fa33451188c1eb6b3bbfdd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 7 May 2013 00:38:07 +0300 Subject: [PATCH 1600/4858] refactor Post_Command::_list() --- php/commands/post.php | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 7228e4a1a1..47ed019bc7 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -174,19 +174,18 @@ public function _list( $_, $assoc_args ) { 'posts_per_page' => -1 ); - if ( ! empty( $assoc_args['format'] ) ) { - $format = $assoc_args['format']; - unset( $assoc_args['format'] ); - } else { - $format = 'table'; - } + $values = array( + 'format' => 'table', + 'fields' => $this->fields + ); - if ( isset( $assoc_args['fields'] ) ) { - $fields = $assoc_args['fields']; - unset( $assoc_args['fields'] ); - } else { - $fields = $this->fields; + foreach ( $values as $key => &$value ) { + if ( isset( $assoc_args[ $key ] ) ) { + $value = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } } + unset( $value ); foreach ( $assoc_args as $key => $value ) { if ( true === $value ) @@ -195,12 +194,12 @@ public function _list( $_, $assoc_args ) { $query_args[ $key ] = $value; } - if ( 'ids' == $format ) + if ( 'ids' == $values['format'] ) $query_args['fields'] = 'ids'; $query = new WP_Query( $query_args ); - WP_CLI\Utils\format_items( $query->posts, $format, $fields ); + WP_CLI\Utils\format_items( $query->posts, $values['format'], $values['fields'] ); } /** From f6e50633c89afd534691bd79694ca7c2723c07a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 7 May 2013 00:41:33 +0300 Subject: [PATCH 1601/4858] make the $fields property private there really isn't any use for it outside of its own class --- php/commands/post.php | 2 +- php/commands/role.php | 8 ++++---- php/commands/term.php | 18 +++++++++--------- php/commands/user.php | 16 ++++++++-------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 47ed019bc7..e9a7aa7bb8 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -9,7 +9,7 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'post'; - public $fields = array( + private $fields = array( 'ID', 'post_title', 'post_name', diff --git a/php/commands/role.php b/php/commands/role.php index cadfb96587..2f88e4d02d 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -7,10 +7,10 @@ */ class Role_Command extends WP_CLI_Command { - public $fields = array( - 'name', - 'role' - ); + private $fields = array( + 'name', + 'role' + ); /** * List all roles. diff --git a/php/commands/term.php b/php/commands/term.php index e72b209e48..c891e9e4c6 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -6,15 +6,15 @@ */ class Term_Command extends WP_CLI_Command { - public $fields = array( - 'term_id', - 'term_taxonomy_id', - 'name', - 'slug', - 'description', - 'parent', - 'count', - ); + private $fields = array( + 'term_id', + 'term_taxonomy_id', + 'name', + 'slug', + 'description', + 'parent', + 'count', + ); /** * List terms in a taxonomy. diff --git a/php/commands/user.php b/php/commands/user.php index 09de1e64cc..1880a2960b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -9,14 +9,14 @@ class User_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'user'; - public $fields = array( - 'ID', - 'user_login', - 'display_name', - 'user_email', - 'user_registered', - 'roles' - ); + private $fields = array( + 'ID', + 'user_login', + 'display_name', + 'user_email', + 'user_registered', + 'roles' + ); /** * List users. From 7580187615790e68ea443e41f0ec7f86c8e1abbd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 14:09:55 +0300 Subject: [PATCH 1602/4858] move REPL implementation to separate class --- php/WP_CLI/REPL.php | 135 +++++++++++++++++++++++++++++++++++++++++ php/commands/shell.php | 121 +----------------------------------- 2 files changed, 137 insertions(+), 119 deletions(-) create mode 100644 php/WP_CLI/REPL.php diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php new file mode 100644 index 0000000000..93e43774bf --- /dev/null +++ b/php/WP_CLI/REPL.php @@ -0,0 +1,135 @@ +<?php + +namespace WP_CLI; + +class REPL { + + private $promt; + + public function __construct( $prompt ) { + $this->prompt = $prompt; + + $this->set_history_file(); + } + + public function start() { + while ( true ) { + $line = $this->prompt(); + + switch ( $line ) { + case '': { + continue 2; + } + + case 'history': { + self::print_history(); + continue 2; + } + } + + $line = rtrim( $line, ';' ) . ';'; + + if ( self::starts_with( self::non_expressions(), $line ) ) { + eval( $line ); + } else { + if ( self::starts_with( 'return', $line ) ) + $line = substr( $line, strlen( 'return' ) ); + + $line = '$_ = ' . $line; + + eval( $line ); + + \WP_CLI::print_value( var_export( $_, false ) ); + } + } + } + + private static function non_expressions() { + return implode( '|', array( + 'echo', 'global', 'unset', 'function', + 'while', 'for', 'foreach', 'if', 'switch', + 'include', 'include\_once', 'require', 'require\_once' + ) ); + } + + private function prompt() { + $full_line = false; + + $done = false; + do { + $prompt = ( !$done && $full_line !== false ) ? '--> ' : $this->prompt; + + $fp = popen( self::create_prompt_cmd( $prompt, $this->history_file ), 'r' ); + + $line = fgets( $fp ); + + if ( !$line ) { + break; + } + + $line = rtrim( $line, "\n" ); + + if ( $line && '\\' == $line[ strlen( $line ) - 1 ] ) { + $line = substr( $line, 0, -1 ); + } else { + $done = true; + } + + $full_line .= $line; + + } while ( !$done ); + + if ( $full_line === false ) { + return 'exit'; + } + + return $full_line; + } + + private static function create_prompt_cmd( $prompt, $history_path ) { + $prompt = escapeshellarg( $prompt ); + $history_path = escapeshellarg( $history_path ); + + $cmd = <<<BASH +set -f +history -r $history_path +LINE="" +read -re -p $prompt LINE +[ $? -eq 0 ] || exit +history -s "\$LINE" +history -w $history_path +echo \$LINE +BASH; + + $cmd = str_replace( "\n", '; ', $cmd ); + + return '/bin/bash -c ' . escapeshellarg( $cmd ); + } + + private function print_history() { + if ( !is_readable( $this->history_file ) ) + return; + + $lines = array_filter( explode( "\n", file_get_contents( $this->history_file ) ) ); + + foreach ( $lines as $line ) { + if ( 'history' == $line ) + continue; + + $line = rtrim( $line, ';' ) . ';'; + + echo "$line\n"; + } + } + + private function set_history_file() { + $data = getcwd() . get_current_user(); + + $this->history_file = sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); + } + + private static function starts_with( $tokens, $line ) { + return preg_match( "/^($tokens)[\(\s]+/", $line ); + } +} + diff --git a/php/commands/shell.php b/php/commands/shell.php index 0c586ccc43..2bc41fd218 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -8,125 +8,8 @@ class Shell_Command extends \WP_CLI_Command { public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); - $this->set_history_file(); - - while ( true ) { - $line = $this->prompt(); - - switch ( $line ) { - case '': { - continue 2; - } - - case 'history': { - self::print_history(); - continue 2; - } - } - - $line = rtrim( $line, ';' ) . ';'; - - if ( self::starts_with( self::non_expressions(), $line ) ) { - eval( $line ); - } else { - if ( self::starts_with( 'return', $line ) ) - $line = substr( $line, strlen( 'return' ) ); - - $line = '$_ = ' . $line; - - eval( $line ); - - \WP_CLI::print_value( var_export( $_, false ) ); - } - } - } - - private static function non_expressions() { - return implode( '|', array( - 'echo', 'global', 'unset', 'function', - 'while', 'for', 'foreach', 'if', 'switch', - 'include', 'include\_once', 'require', 'require\_once' - ) ); - } - - private function prompt() { - $full_line = false; - - $done = false; - do { - $prompt = ( !$done && $full_line !== false ) ? '--> ' : 'wp> '; - - $fp = popen( self::create_prompt_cmd( $prompt, $this->history_file ), 'r' ); - - $line = fgets( $fp ); - - if ( !$line ) { - break; - } - - $line = rtrim( $line, "\n" ); - - if ( $line && '\\' == $line[ strlen( $line ) - 1 ] ) { - $line = substr( $line, 0, -1 ); - } else { - $done = true; - } - - $full_line .= $line; - - } while ( !$done ); - - if ( $full_line === false ) { - return 'exit'; - } - - return $full_line; - } - - private static function create_prompt_cmd( $prompt, $history_path ) { - $prompt = escapeshellarg( $prompt ); - $history_path = escapeshellarg( $history_path ); - - $cmd = <<<BASH -set -f -history -r $history_path -LINE="" -read -re -p $prompt LINE -[ $? -eq 0 ] || exit -history -s "\$LINE" -history -w $history_path -echo \$LINE -BASH; - - $cmd = str_replace( "\n", '; ', $cmd ); - - return '/bin/bash -c ' . escapeshellarg( $cmd ); - } - - private function print_history() { - if ( !is_readable( $this->history_file ) ) - return; - - $lines = array_filter( explode( "\n", file_get_contents( $this->history_file ) ) ); - - foreach ( $lines as $line ) { - if ( 'history' == $line ) - continue; - - $line = rtrim( $line, ';' ) . ';'; - - echo "$line\n"; - } - } - - private function set_history_file() { - $data = getcwd() . get_current_user(); - - $this->history_file = sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); - } - - private static function starts_with( $tokens, $line ) { - return preg_match( "/^($tokens)[\(\s]+/", $line ); + $repl = new \WP_CLI\REPL( 'wp> ' ); + $repl->start(); } } From 61939d5677dc02556daf45de7982fc3b22fde1f1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 14:17:39 +0300 Subject: [PATCH 1603/4858] add Boris as a dependency and use it instead of homegrown REPL --- composer.json | 3 ++- composer.lock | 35 ++++++++++++++++++++++++++++++++++- php/commands/shell.php | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 46ed157254..5817208cb7 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "require": { "php": ">=5.3", "wp-cli/php-cli-tools": "dev-master", - "mustache/mustache": "2.0.x" + "mustache/mustache": "2.0.x", + "d11wtq/boris": "dev-master" }, "require-dev": { "phpunit/phpunit": "3.7.x", diff --git a/composer.lock b/composer.lock index 9bd1adfaa3..e804126ba8 100644 --- a/composer.lock +++ b/composer.lock @@ -3,8 +3,40 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "f2b06fd19e26795775358b054c6fb09d", + "hash": "1d1cf2cc2d559d96f2e3397353a4be3e", "packages": [ + { + "name": "d11wtq/boris", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/d11wtq/boris.git", + "reference": "09c211ab3a79154f39efce542f737ad08596e63f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/d11wtq/boris/zipball/09c211ab3a79154f39efce542f737ad08596e63f", + "reference": "09c211ab3a79154f39efce542f737ad08596e63f", + "shasum": "" + }, + "require": { + "ext-pcntl": "*", + "ext-posix": "*", + "ext-readline": "*", + "php": ">=5.3.0" + }, + "bin": [ + "bin/boris" + ], + "type": "library", + "autoload": { + "psr-0": { + "Boris": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "time": "2013-04-23 13:31:51" + }, { "name": "mustache/mustache", "version": "v2.0.2", @@ -929,6 +961,7 @@ "minimum-stability": "stable", "stability-flags": { "wp-cli/php-cli-tools": 20, + "d11wtq/boris": 20, "behat/behat": 0 }, "platform": { diff --git a/php/commands/shell.php b/php/commands/shell.php index 2bc41fd218..077e22ef38 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -8,7 +8,7 @@ class Shell_Command extends \WP_CLI_Command { public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); - $repl = new \WP_CLI\REPL( 'wp> ' ); + $repl = new \Boris\Boris( 'wp> ' ); $repl->start(); } } From cf2753e12fffe89fd762147bdc580a69125a71de Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 14:48:02 +0300 Subject: [PATCH 1604/4858] fall back to old REPL implementation if Boris is not available --- php/commands/shell.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 077e22ef38..8ab60c0138 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -8,8 +8,18 @@ class Shell_Command extends \WP_CLI_Command { public function __invoke() { \WP_CLI::line( 'Type "exit" to close session.' ); - $repl = new \Boris\Boris( 'wp> ' ); - $repl->start(); + $implementations = array( + '\\Boris\\Boris', + '\\WP_CLI\\REPL', + ); + + foreach ( $implementations as $class ) { + if ( class_exists( $class ) ) { + $repl = new $class( 'wp> ' ); + $repl->start(); + break; + } + } } } From 883411c7d1d84ec8392aded2ae345ab080aa7d0f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 15:06:46 +0300 Subject: [PATCH 1605/4858] add --basic flag to `wp shell` command --- man-src/shell.txt | 6 ++++++ php/commands/shell.php | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/man-src/shell.txt b/man-src/shell.txt index 1759cffb53..da5393cf2c 100644 --- a/man-src/shell.txt +++ b/man-src/shell.txt @@ -7,3 +7,9 @@ You can split a statement over multiple lines by adding a `\` (backslash) before hitting Return. If you type `history` and hit Return, WP-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file. + +## OPTIONS + +* `--basic`: + + Start in fail-safe mode, even if Boris is available. diff --git a/php/commands/shell.php b/php/commands/shell.php index 8ab60c0138..4ff4215ab2 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -4,8 +4,10 @@ class Shell_Command extends \WP_CLI_Command { /** * Interactive PHP console. + * + * @synopsis [--basic] */ - public function __invoke() { + public function __invoke( $_, $assoc_args ) { \WP_CLI::line( 'Type "exit" to close session.' ); $implementations = array( @@ -13,6 +15,10 @@ public function __invoke() { '\\WP_CLI\\REPL', ); + if ( isset( $assoc_args['basic'] ) ) { + unset( $implementations[0] ); + } + foreach ( $implementations as $class ) { if ( class_exists( $class ) ) { $repl = new $class( 'wp> ' ); From 1ead253ab0731414ac14dead11ee58d84eb33da3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 15:10:12 +0300 Subject: [PATCH 1606/4858] remove support for $_ special variable, since Boris doesn't support it. --- features/shell.feature | 20 -------------------- man-src/shell.txt | 2 -- php/WP_CLI/REPL.php | 10 +++------- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index 2cc9c47f83..a880b91a60 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -10,26 +10,6 @@ Feature: WordPress REPL Type "exit" to close session. """ - Scenario: $_ special variable - Given a WP install - And a session file: - """ - WP_ADMIN - $_ - get_current_user_id() - $_ - """ - - When I run `wp shell --quiet < session` - Then it should run without errors - And STDOUT should be: - """ - true - true - 0 - 0 - """ - Scenario: Persistent environment Given a WP install And a session file: diff --git a/man-src/shell.txt b/man-src/shell.txt index da5393cf2c..02f84c9770 100644 --- a/man-src/shell.txt +++ b/man-src/shell.txt @@ -2,8 +2,6 @@ `wp shell` allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example. -`$_` is a special variable that contains the result from the last evaluated statement. - You can split a statement over multiple lines by adding a `\` (backslash) before hitting Return. If you type `history` and hit Return, WP-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file. diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index 93e43774bf..830404d0ab 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -32,14 +32,10 @@ public function start() { if ( self::starts_with( self::non_expressions(), $line ) ) { eval( $line ); } else { - if ( self::starts_with( 'return', $line ) ) - $line = substr( $line, strlen( 'return' ) ); + if ( !self::starts_with( 'return', $line ) ) + $line = 'return ' . $line; - $line = '$_ = ' . $line; - - eval( $line ); - - \WP_CLI::print_value( var_export( $_, false ) ); + \WP_CLI::print_value( var_export( eval( $line ), false ) ); } } } From d7e43e5cf2af2413c9b3831911ff708901d79bea Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 15:49:33 +0300 Subject: [PATCH 1607/4858] fix shell tests --- features/shell.feature | 43 ++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index a880b91a60..8cb9f59e75 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -5,25 +5,25 @@ Feature: WordPress REPL When I run `wp shell < /dev/null` Then it should run without errors - And STDOUT should be: - """ - Type "exit" to close session. - """ + And STDOUT should not be empty + + When I run `wp shell --basic < /dev/null` + Then it should run without errors + And STDOUT should not be empty Scenario: Persistent environment Given a WP install And a session file: """ function is_empty_string( $str ) { return strlen( $str ) == 0; } - 1; $a = get_option('home') - is_empty_string( $a ) + $a = get_option('home'); + is_empty_string( $a ); """ - When I run `wp shell --quiet < session` + When I run `wp shell --basic --quiet < session` Then it should run without errors - And STDOUT should be: + And STDOUT should contain: """ - 1 false """ @@ -36,7 +36,7 @@ Feature: WordPress REPL history """ - When I run `wp shell --quiet < session` + When I run `wp shell --basic --quiet < session` Then it should run without errors And STDOUT should be: """ @@ -46,6 +46,25 @@ Feature: WordPress REPL """ Scenario: Multiline support + Given a WP install + And a session file: + """ + function is_empty_string( $str ) { + return strlen( $str ) == 0; + } + + function_exists( 'is_empty_string' ); + """ + + When I run `wp shell --quiet < session` + Then it should run without errors + And STDOUT should be: + """ + → NULL + → bool(true) + """ + + Scenario: Multiline support (basic) Given a WP install And a session file: """ @@ -53,10 +72,10 @@ Feature: WordPress REPL return strlen( $str ) == 0; \ } - function_exists( 'is_empty_string' ) + function_exists( 'is_empty_string' ); """ - When I run `wp shell --quiet < session` + When I run `wp shell --basic --quiet < session` Then it should run without errors And STDOUT should be: """ From 4a7f30a36482d4ef2b034ab14bc4eda61b905974 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 15:57:13 +0300 Subject: [PATCH 1608/4858] shell: use var_dump(), to better match Boris output --- features/shell.feature | 6 +++--- php/WP_CLI/REPL.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index 8cb9f59e75..fd774963b9 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -24,7 +24,7 @@ Feature: WordPress REPL Then it should run without errors And STDOUT should contain: """ - false + bool(false) """ Scenario: History builtin @@ -40,7 +40,7 @@ Feature: WordPress REPL Then it should run without errors And STDOUT should be: """ - true + bool(true) defined('WP_CLI'); function foo() {}; """ @@ -79,6 +79,6 @@ Feature: WordPress REPL Then it should run without errors And STDOUT should be: """ - true + bool(true) """ diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index 830404d0ab..73232b7474 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -35,7 +35,7 @@ public function start() { if ( !self::starts_with( 'return', $line ) ) $line = 'return ' . $line; - \WP_CLI::print_value( var_export( eval( $line ), false ) ); + var_dump( eval( $line ) ); } } } From a9dd5dcc36a744b163a7f94bde5ab93bde7977f9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 16:03:04 +0300 Subject: [PATCH 1609/4858] shell: remove support for 'history' builtin 1. The syntax felt kind of inconsistent. 2. Boris doesn't support it. 3. It didn't ship with a stable release, so not many people know about it. see #373 --- features/shell.feature | 18 ------------------ man-src/shell.txt | 2 -- php/WP_CLI/REPL.php | 27 +-------------------------- 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index fd774963b9..ed1bd3503c 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -27,24 +27,6 @@ Feature: WordPress REPL bool(false) """ - Scenario: History builtin - Given a WP install - And a session file: - """ - defined('WP_CLI') - function foo() {} - history - """ - - When I run `wp shell --basic --quiet < session` - Then it should run without errors - And STDOUT should be: - """ - bool(true) - defined('WP_CLI'); - function foo() {}; - """ - Scenario: Multiline support Given a WP install And a session file: diff --git a/man-src/shell.txt b/man-src/shell.txt index 02f84c9770..a895f32c43 100644 --- a/man-src/shell.txt +++ b/man-src/shell.txt @@ -4,8 +4,6 @@ You can split a statement over multiple lines by adding a `\` (backslash) before hitting Return. -If you type `history` and hit Return, WP-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file. - ## OPTIONS * `--basic`: diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index 73232b7474..c065091a29 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -16,16 +16,7 @@ public function start() { while ( true ) { $line = $this->prompt(); - switch ( $line ) { - case '': { - continue 2; - } - - case 'history': { - self::print_history(); - continue 2; - } - } + if ( '' === $line ) continue; $line = rtrim( $line, ';' ) . ';'; @@ -102,22 +93,6 @@ private static function create_prompt_cmd( $prompt, $history_path ) { return '/bin/bash -c ' . escapeshellarg( $cmd ); } - private function print_history() { - if ( !is_readable( $this->history_file ) ) - return; - - $lines = array_filter( explode( "\n", file_get_contents( $this->history_file ) ) ); - - foreach ( $lines as $line ) { - if ( 'history' == $line ) - continue; - - $line = rtrim( $line, ';' ) . ';'; - - echo "$line\n"; - } - } - private function set_history_file() { $data = getcwd() . get_current_user(); From abf1240e2cb11ea56ff29c16cf3fcbf958c6037f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 16:06:39 +0300 Subject: [PATCH 1610/4858] shell man: remove note about backslashes Backslashes are needed only in basic mode. --- man-src/shell.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/man-src/shell.txt b/man-src/shell.txt index a895f32c43..7dd583a28f 100644 --- a/man-src/shell.txt +++ b/man-src/shell.txt @@ -2,8 +2,6 @@ `wp shell` allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example. -You can split a statement over multiple lines by adding a `\` (backslash) before hitting Return. - ## OPTIONS * `--basic`: From 86493d25e89562a78c9e8caf2d6f1b38951331b3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 16:17:42 +0300 Subject: [PATCH 1611/4858] shell: remove Boris tests they belong in the Boris repo --- features/shell.feature | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index ed1bd3503c..e328ac1716 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -27,25 +27,6 @@ Feature: WordPress REPL bool(false) """ - Scenario: Multiline support - Given a WP install - And a session file: - """ - function is_empty_string( $str ) { - return strlen( $str ) == 0; - } - - function_exists( 'is_empty_string' ); - """ - - When I run `wp shell --quiet < session` - Then it should run without errors - And STDOUT should be: - """ - → NULL - → bool(true) - """ - Scenario: Multiline support (basic) Given a WP install And a session file: From 29e1b0547f1bbb22249b3e0cdd2a4d9fd96c9b4c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 16:45:12 +0300 Subject: [PATCH 1612/4858] make Boris a suggested package --- composer.json | 6 ++++-- composer.lock | 35 +---------------------------------- utils/dev-build | 3 +++ 3 files changed, 8 insertions(+), 36 deletions(-) diff --git a/composer.json b/composer.json index 5817208cb7..64773ce14e 100644 --- a/composer.json +++ b/composer.json @@ -10,8 +10,10 @@ "require": { "php": ">=5.3", "wp-cli/php-cli-tools": "dev-master", - "mustache/mustache": "2.0.x", - "d11wtq/boris": "dev-master" + "mustache/mustache": "2.0.x" + }, + "suggest": { + "d11wtq/boris": "Enhanced `wp shell` functionality" }, "require-dev": { "phpunit/phpunit": "3.7.x", diff --git a/composer.lock b/composer.lock index e804126ba8..26c0f6bdf0 100644 --- a/composer.lock +++ b/composer.lock @@ -3,40 +3,8 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "1d1cf2cc2d559d96f2e3397353a4be3e", + "hash": "b0b7111ec0133fedf911454fef153d87", "packages": [ - { - "name": "d11wtq/boris", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/d11wtq/boris.git", - "reference": "09c211ab3a79154f39efce542f737ad08596e63f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/d11wtq/boris/zipball/09c211ab3a79154f39efce542f737ad08596e63f", - "reference": "09c211ab3a79154f39efce542f737ad08596e63f", - "shasum": "" - }, - "require": { - "ext-pcntl": "*", - "ext-posix": "*", - "ext-readline": "*", - "php": ">=5.3.0" - }, - "bin": [ - "bin/boris" - ], - "type": "library", - "autoload": { - "psr-0": { - "Boris": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "time": "2013-04-23 13:31:51" - }, { "name": "mustache/mustache", "version": "v2.0.2", @@ -961,7 +929,6 @@ "minimum-stability": "stable", "stability-flags": { "wp-cli/php-cli-tools": 20, - "d11wtq/boris": 20, "behat/behat": 0 }, "platform": { diff --git a/utils/dev-build b/utils/dev-build index 2994603608..c97b95fa87 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -15,6 +15,9 @@ command -v composer > /dev/null || { # install dependencies composer install --dev +# try installing Boris +composer require d11wtq/boris=dev-master + # add symlink to wp binary for dir in /usr/bin /usr/local/bin; do if [ -d $dir ]; then From e9ef2cb186147ff953b42e040b3acb8dcf0a9868 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 21:08:36 +0300 Subject: [PATCH 1613/4858] shell: remove superfluous exit instructions --- features/shell.feature | 6 ++---- php/commands/shell.php | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index e328ac1716..0ca5aa9a9d 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -5,11 +5,9 @@ Feature: WordPress REPL When I run `wp shell < /dev/null` Then it should run without errors - And STDOUT should not be empty When I run `wp shell --basic < /dev/null` Then it should run without errors - And STDOUT should not be empty Scenario: Persistent environment Given a WP install @@ -20,7 +18,7 @@ Feature: WordPress REPL is_empty_string( $a ); """ - When I run `wp shell --basic --quiet < session` + When I run `wp shell --basic < session` Then it should run without errors And STDOUT should contain: """ @@ -38,7 +36,7 @@ Feature: WordPress REPL function_exists( 'is_empty_string' ); """ - When I run `wp shell --basic --quiet < session` + When I run `wp shell --basic < session` Then it should run without errors And STDOUT should be: """ diff --git a/php/commands/shell.php b/php/commands/shell.php index 4ff4215ab2..4fbf4bbcce 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -8,8 +8,6 @@ class Shell_Command extends \WP_CLI_Command { * @synopsis [--basic] */ public function __invoke( $_, $assoc_args ) { - \WP_CLI::line( 'Type "exit" to close session.' ); - $implementations = array( '\\Boris\\Boris', '\\WP_CLI\\REPL', From 4190db66edb86dc6a498aa49b3ea4770b3a24e2c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 21:12:56 +0300 Subject: [PATCH 1614/4858] travis: force-install Boris, for smoke testing --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f6bfe635b4..7225c6eaab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ matrix: before_script: # install dependencies - composer install --dev --no-interaction --prefer-source + - composer require d11wtq/boris=dev-master --no-interaction --prefer-source # set up WP install - bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ # set up database From 3c2fd0be6ece9976073066ea3d90c97263083c67 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 23:03:18 +0300 Subject: [PATCH 1615/4858] shell: re-generate man page [ci skip] --- man/shell.1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/man/shell.1 b/man/shell.1 index d145d4a612..6aa5f9e1f1 100644 --- a/man/shell.1 +++ b/man/shell.1 @@ -7,16 +7,16 @@ \fBwp\-shell\fR \- Interactive PHP console\. . .SH "SYNOPSIS" -wp shell +wp shell [\-\-basic] . .SH "DESCRIPTION" \fBwp shell\fR allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment\. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example\. . -.P -\fB$_\fR is a special variable that contains the result from the last evaluated statement\. +.SH "OPTIONS" . -.P -You can split a statement over multiple lines by adding a \fB\e\fR (backslash) before hitting Return\. +.TP +\fB\-\-basic\fR: . -.P -If you type \fBhistory\fR and hit Return, WP\-CLI will print the list of previously evaluated statements, which you can copy+paste into a PHP file\. +.IP +Start in fail\-safe mode, even if Boris is available\. + From 096a4944004c533435ce0ef498e840bb6b6e4c68 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 23:05:26 +0300 Subject: [PATCH 1616/4858] don't install Boris in dev-build, since it alters the git repo --- utils/dev-build | 3 --- 1 file changed, 3 deletions(-) diff --git a/utils/dev-build b/utils/dev-build index c97b95fa87..2994603608 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -15,9 +15,6 @@ command -v composer > /dev/null || { # install dependencies composer install --dev -# try installing Boris -composer require d11wtq/boris=dev-master - # add symlink to wp binary for dir in /usr/bin /usr/local/bin; do if [ -d $dir ]; then From 4c73c449255fb209d612510810948ffd85badb84 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 23:43:09 +0300 Subject: [PATCH 1617/4858] Bump required PHP version to 5.3.2 We depend on Composer and Composer doesn't work wit anything below that. This also allows us to move back to the upstream php-cli-tools package. --- composer.json | 4 +-- composer.lock | 69 +++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/composer.json b/composer.json index 64773ce14e..dc3cc5aaa4 100644 --- a/composer.json +++ b/composer.json @@ -8,8 +8,8 @@ "bin/wp" ], "require": { - "php": ">=5.3", - "wp-cli/php-cli-tools": "dev-master", + "php": ">=5.3.2", + "jlogsdon/cli": "~0.9.1", "mustache/mustache": "2.0.x" }, "suggest": { diff --git a/composer.lock b/composer.lock index 26c0f6bdf0..726e2b26b5 100644 --- a/composer.lock +++ b/composer.lock @@ -3,29 +3,29 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "b0b7111ec0133fedf911454fef153d87", + "hash": "2f907ef4729a8057cba8d5310e72ed9f", "packages": [ { - "name": "mustache/mustache", - "version": "v2.0.2", + "name": "jlogsdon/cli", + "version": "v0.9.1", "source": { "type": "git", - "url": "https://github.com/bobthecow/mustache.php", - "reference": "v2.0.2" + "url": "git://github.com/jlogsdon/php-cli-tools.git", + "reference": "v0.9.1" }, "dist": { "type": "zip", - "url": "https://github.com/bobthecow/mustache.php/zipball/v2.0.2", - "reference": "v2.0.2", + "url": "https://github.com/jlogsdon/php-cli-tools/zipball/v0.9.1", + "reference": "v0.9.1", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">= 5.3.0" }, "type": "library", "autoload": { "psr-0": { - "Mustache": "src/" + "cli": "lib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -34,40 +34,40 @@ ], "authors": [ { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "name": "James Logsdon", + "email": "jlogsdon@php.net", + "role": "Developer" } ], - "description": "A Mustache implementation in PHP.", - "homepage": "https://github.com/bobthecow/mustache.php", + "description": "Console utilities for PHP", + "homepage": "http://github.com/jlogsdon/php-cli-tools", "keywords": [ - "mustache", - "templating" + "cli", + "console" ], - "time": "2012-09-12 09:13:06" + "time": "2012-09-15 14:09:00" }, { - "name": "wp-cli/php-cli-tools", - "version": "dev-master", + "name": "mustache/mustache", + "version": "v2.0.2", "source": { "type": "git", - "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "f3def25b862bb0c5330a6347c6c04d62a99eb217" + "url": "https://github.com/bobthecow/mustache.php", + "reference": "v2.0.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/f3def25b862bb0c5330a6347c6c04d62a99eb217", - "reference": "f3def25b862bb0c5330a6347c6c04d62a99eb217", + "url": "https://github.com/bobthecow/mustache.php/zipball/v2.0.2", + "reference": "v2.0.2", "shasum": "" }, "require": { - "php": ">= 5.3.0" + "php": ">=5.2.4" }, "type": "library", "autoload": { "psr-0": { - "cli": "lib/" + "Mustache": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -76,18 +76,18 @@ ], "authors": [ { - "name": "James Logsdon", - "email": "jlogsdon@php.net", - "role": "Developer" + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" } ], - "description": "Console utilities for PHP", - "homepage": "http://github.com/jlogsdon/php-cli-tools", + "description": "A Mustache implementation in PHP.", + "homepage": "https://github.com/bobthecow/mustache.php", "keywords": [ - "cli", - "console" + "mustache", + "templating" ], - "time": "2012-12-13 22:18:34" + "time": "2012-09-12 09:13:06" } ], "packages-dev": [ @@ -928,11 +928,10 @@ ], "minimum-stability": "stable", "stability-flags": { - "wp-cli/php-cli-tools": 20, "behat/behat": 0 }, "platform": { - "php": ">=5.3" + "php": ">=5.3.2" }, "platform-dev": [ From a524e2ff71b06d76c2f2ceda9e2af055b12d959d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 23:52:02 +0300 Subject: [PATCH 1618/4858] fix path to cli-tools package --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 3521a2a624..a0a6fb188a 100644 --- a/php/utils.php +++ b/php/utils.php @@ -17,7 +17,7 @@ function load_dependencies() { foreach ( $vendor_paths as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; - include $vendor_path . '/wp-cli/php-cli-tools/lib/cli/cli.php'; + include $vendor_path . '/jlogsdon/cli/lib/cli/cli.php'; $has_autoload = true; break; } From bae50f56e0da11b228edca69772475bc6dcaa307 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 8 May 2013 23:55:34 +0300 Subject: [PATCH 1619/4858] change exit code when Composer packages aren't installed 2 is a reserved exit code: http://tldp.org/LDP/abs/html/exitcodes.html --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index a0a6fb188a..12e8595caa 100644 --- a/php/utils.php +++ b/php/utils.php @@ -25,7 +25,7 @@ function load_dependencies() { if ( !$has_autoload ) { fputs( STDERR, "Internal error: Can't find Composer autoloader.\n" ); - exit(2); + exit(3); } include WP_CLI_ROOT . 'Spyc.php'; From 7ce4dec8ed2c606199bf50c185b1e90856ae8237 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 8 May 2013 16:01:19 -0700 Subject: [PATCH 1620/4858] Revert parts of 3500a184e5ca652370fdaa7e2c2217290fadf69c. Changing the order in which arguments are passed will break community use of this helper function. See https://github.com/wp-cli/wp-cli/commit/3500a184e5ca652370fdaa7e2c2217290fadf69c#commitcomment-3174323 --- php/commands/post.php | 4 ++-- php/commands/role.php | 2 +- php/commands/term.php | 2 +- php/commands/user.php | 2 +- php/utils.php | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index d9d182fd3b..7952a8b734 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -123,7 +123,7 @@ public function get( $args, $assoc_args ) { $items[] = $item; } - \WP_CLI\Utils\format_items( $items, $format, array( 'Field', 'Value' ) ); + \WP_CLI\Utils\format_items( $format, $items, array( 'Field', 'Value' ) ); break; case 'json': @@ -200,7 +200,7 @@ public function _list( $_, $assoc_args ) { $query = new WP_Query( $query_args ); - WP_CLI\Utils\format_items( $query->posts, $values['format'], $values['fields'] ); + WP_CLI\Utils\format_items( $values['format'], $query->posts, $values['fields'] ); } /** diff --git a/php/commands/role.php b/php/commands/role.php index 2f88e4d02d..bfd974b632 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -40,7 +40,7 @@ public function _list( $args, $assoc_args ) { $output_roles[] = $output_role; } - WP_CLI\Utils\format_items( $output_roles, $params['format'], $fields ); + WP_CLI\Utils\format_items( $params['format'], $output_roles, $fields ); } /** diff --git a/php/commands/term.php b/php/commands/term.php index 5c9c72468a..5cbaf0a5a6 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -41,7 +41,7 @@ public function _list( $args, $assoc_args ) { if ( 'ids' == $assoc_args['format'] ) $terms = wp_list_pluck( $terms, 'term_id' ); - WP_CLI\Utils\format_items( $terms, $assoc_args['format'], $fields, $terms ); + WP_CLI\Utils\format_items( $assoc_args['format'], $terms, $fields ); } /** diff --git a/php/commands/user.php b/php/commands/user.php index 1880a2960b..23b68f3733 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -53,7 +53,7 @@ public function _list( $args, $assoc_args ) { } } - WP_CLI\Utils\format_items( $users, $params['format'], $fields ); + WP_CLI\Utils\format_items( $params['format'], $users, $fields ); } /** diff --git a/php/utils.php b/php/utils.php index acb259d5f9..39ff8e7ad3 100644 --- a/php/utils.php +++ b/php/utils.php @@ -255,11 +255,11 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria /** * Output items in a table, JSON, or CSV * + * @param string $format Format to use: 'table', 'json', 'csv', 'ids' * @param array $items Data to output - * @param string $format Format to use: 'table', 'json', 'csv' * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ -function format_items( $items, $format, $fields ) { +function format_items( $format, $items, $fields ) { if ( 'ids' == $format ) \WP_CLI::out( implode( ' ', $items ) ); From c2594aa16e1199296d2f7c4b4eed284d958eab4e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 8 May 2013 16:06:19 -0700 Subject: [PATCH 1621/4858] Update post.feature to test new `--fields` argument --- features/post.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/post.feature b/features/post.feature index 3fa02b1d64..731184f933 100644 --- a/features/post.feature +++ b/features/post.feature @@ -77,11 +77,11 @@ Feature: Manage WordPress posts Then it should run without errors And STDOUT should match '%d' - When I run `wp post list --post_type='post' --format=csv` + When I run `wp post list --post_type='post' --fields=post_title,post_name,post_status --format=csv` Then it should run without errors And STDOUT should be CSV containing: """ - post_title,post_name - "Publish post",publish-post - "Draft post", + post_title,post_name,post_status + "Publish post",publish-post,publish + "Draft post",,draft """ From 78a461720ec98134a6bb300698b6590cee1aed96 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 8 May 2013 16:23:08 -0700 Subject: [PATCH 1622/4858] Update term.feature to make use of `--fields` argument --- features/term.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/term.feature b/features/term.feature index 47a4219dc0..0c6af7e536 100644 --- a/features/term.feature +++ b/features/term.feature @@ -17,6 +17,14 @@ Feature: Manage WordPress terms [{"name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] """ + When I run `wp term list post_tag --fields=name,slug --format=csv` + Then it should run without errors + And STDOUT should be CSV containing: + """ + name,slug + "Test term",test + """ + Scenario: Creating/deleting a term Given a WP install From 3a54547a13c9853858f2c2b58c7151c9a26d4825 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 8 May 2013 16:42:37 -0700 Subject: [PATCH 1623/4858] Update man docs to mention `--fields` --- man-src/post-list.txt | 6 ++++++ man-src/role-list.txt | 6 +++++- man-src/term-list.txt | 8 +++++++- man-src/user-list.txt | 6 ++++++ man/post-list.1 | 10 +++++++++- man/role-list.1 | 10 ++++++++-- man/term-list.1 | 10 +++++++++- man/user-list.1 | 10 +++++++++- 8 files changed, 59 insertions(+), 7 deletions(-) diff --git a/man-src/post-list.txt b/man-src/post-list.txt index 47849ced93..67637487ab 100644 --- a/man-src/post-list.txt +++ b/man-src/post-list.txt @@ -4,6 +4,10 @@ One or more args to pass to WP_Query. +* `--fields`=<fields>: + + Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date. + * `--format`=<format>: Output list as table, CSV, JSON, or simply IDs. Defaults to table. @@ -13,3 +17,5 @@ wp post list --format=ids wp post list --post_type=post --posts_per_page=5 --format=json + + wp post list --post_type=page --fields=post_title,post_status diff --git a/man-src/role-list.txt b/man-src/role-list.txt index a2dcd0cc02..2b79401613 100644 --- a/man-src/role-list.txt +++ b/man-src/role-list.txt @@ -1,9 +1,13 @@ ## OPTIONS +* `--fields`=<fields>: + + Limit the output to specific object fields. Defaults to name,role. + * `--format`=<format>: Output list as table, CSV or JSON. Defaults to table. ## EXAMPLES - wp role list + wp role list --fields=role --format=csv diff --git a/man-src/term-list.txt b/man-src/term-list.txt index f782b7e595..18cd0a4ed1 100644 --- a/man-src/term-list.txt +++ b/man-src/term-list.txt @@ -4,10 +4,16 @@ List terms of a given taxonomy. +* `--fields`=<fields>: + + Limit the output to specific object fields. Defaults to all of the term object fields. + * `--format`=<format>: Output list as table, CSV, JSON, or simply IDs. Defaults to table. ## EXAMPLES - wp term list category --format=csv \ No newline at end of file + wp term list category --format=csv + + wp term list post_tag --fields=name,slug diff --git a/man-src/user-list.txt b/man-src/user-list.txt index d30757b450..0aa7951da6 100644 --- a/man-src/user-list.txt +++ b/man-src/user-list.txt @@ -4,6 +4,10 @@ Only display users with a certain role. +* `--fields`=<fields>: + + Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles + * `--format`=<format>: Output list as table, CSV, JSON, or simply IDs. Defaults to table. @@ -13,3 +17,5 @@ wp user list --format=ids wp user list --role=administrator --format=csv + + wp user list --fields=display_name,user_email diff --git a/man/post-list.1 b/man/post-list.1 index b20875028b..83d3c3991e 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -7,7 +7,7 @@ \fBwp\-post\-list\fR \- Get a list of posts\. . .SH "SYNOPSIS" -wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-format=\fIformat\fR] +wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -18,6 +18,12 @@ wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-format=\fIformat\fR] One or more args to pass to WP_Query\. . .TP +\fB\-\-fields\fR=\fIfields\fR: +. +.IP +Limit the output to specific object fields\. Defaults to ID,post_title,post_name,post_date\. +. +.TP \fB\-\-format\fR=\fIformat\fR: . .IP @@ -30,6 +36,8 @@ Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. wp post list \-\-format=ids wp post list \-\-post_type=post \-\-posts_per_page=5 \-\-format=json + +wp post list \-\-post_type=page \-\-fields=post_title,post_status . .fi diff --git a/man/role-list.1 b/man/role-list.1 index a962ccae40..14d58a8b85 100644 --- a/man/role-list.1 +++ b/man/role-list.1 @@ -7,11 +7,17 @@ \fBwp\-role\-list\fR \- List all roles\. . .SH "SYNOPSIS" -wp role list [\-\-format=\fIformat\fR] +wp role list [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . .TP +\fB\-\-fields\fR=\fIfields\fR: +. +.IP +Limit the output to specific object fields\. Defaults to name,role\. +. +.TP \fB\-\-format\fR=\fIformat\fR: . .IP @@ -21,7 +27,7 @@ Output list as table, CSV or JSON\. Defaults to table\. . .nf -wp role list +wp role list \-\-fields=role \-\-format=csv . .fi diff --git a/man/term-list.1 b/man/term-list.1 index 9990d2ff09..ef15301912 100644 --- a/man/term-list.1 +++ b/man/term-list.1 @@ -7,7 +7,7 @@ \fBwp\-term\-list\fR \- List terms in a taxonomy\. . .SH "SYNOPSIS" -wp term list \fItaxonomy\fR [\-\-format=\fIformat\fR] +wp term list \fItaxonomy\fR [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -18,6 +18,12 @@ wp term list \fItaxonomy\fR [\-\-format=\fIformat\fR] List terms of a given taxonomy\. . .TP +\fB\-\-fields\fR=\fIfields\fR: +. +.IP +Limit the output to specific object fields\. Defaults to all of the term object fields\. +. +.TP \fB\-\-format\fR=\fIformat\fR: . .IP @@ -28,6 +34,8 @@ Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. .nf wp term list category \-\-format=csv + +wp term list post_tag \-\-fields=name,slug . .fi diff --git a/man/user-list.1 b/man/user-list.1 index 8d66afa59e..f5dac94ed1 100644 --- a/man/user-list.1 +++ b/man/user-list.1 @@ -7,7 +7,7 @@ \fBwp\-user\-list\fR \- List users\. . .SH "SYNOPSIS" -wp user list [\-\-role=\fIrole\fR] [\-\-format=\fIformat\fR] +wp user list [\-\-role=\fIrole\fR] [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] . .SH "OPTIONS" . @@ -18,6 +18,12 @@ wp user list [\-\-role=\fIrole\fR] [\-\-format=\fIformat\fR] Only display users with a certain role\. . .TP +\fB\-\-fields\fR=\fIfields\fR: +. +.IP +Limit the output to specific object fields\. Defaults to ID,user_login,display_name,user_email,user_registered,roles +. +.TP \fB\-\-format\fR=\fIformat\fR: . .IP @@ -30,6 +36,8 @@ Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. wp user list \-\-format=ids wp user list \-\-role=administrator \-\-format=csv + +wp user list \-\-fields=display_name,user_email . .fi From e46e6ec9d7af558580f77091316079f4c534c74a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 13:04:02 +0300 Subject: [PATCH 1624/4858] don't load cli/cli.php utilities (unused) --- php/utils.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 39ff8e7ad3..7ef9154311 100644 --- a/php/utils.php +++ b/php/utils.php @@ -17,7 +17,6 @@ function load_dependencies() { foreach ( $vendor_paths as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; - include $vendor_path . '/jlogsdon/cli/lib/cli/cli.php'; $has_autoload = true; break; } From d7cf3340f8988eefe16ee371b61938ef772f7850 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 13:11:55 +0300 Subject: [PATCH 1625/4858] Revert "don't load cli/cli.php utilities (unused)" It's used internally by cli\Table. This reverts commit e46e6ec9d7af558580f77091316079f4c534c74a. --- php/utils.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/utils.php b/php/utils.php index 7ef9154311..39ff8e7ad3 100644 --- a/php/utils.php +++ b/php/utils.php @@ -17,6 +17,7 @@ function load_dependencies() { foreach ( $vendor_paths as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; + include $vendor_path . '/jlogsdon/cli/lib/cli/cli.php'; $has_autoload = true; break; } From 2612b40ea2dcbc1c2633e2f28088eabddb833882 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Thu, 9 May 2013 13:32:16 +0200 Subject: [PATCH 1626/4858] Implemented 'list' command for theme and plugin command, issue #440 --- php/WP_CLI/CommandWithUpgrade.php | 44 +++++++++++++++++++++++++++++++ php/commands/plugin.php | 17 ++++++++++++ php/commands/theme.php | 17 ++++++++++++ 3 files changed, 78 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 01d1c06a30..88687f2b33 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -169,6 +169,26 @@ function update_all( $args, $assoc_args ) { } } + protected function _list( $format ) { + $values = array( + 'format' => 'table', + 'fields' => $this->fields + ); + + foreach ( $values as $key => &$value ) { + if ( isset( $format[ $key ] ) ) { + $value = $format[ $key ]; + unset( $format[ $key ] ); + } + } + unset( $value ); + + $all_items = $this->get_all_items(); + $items = $this->create_objects( $all_items ); + + \WP_CLI\Utils\format_items( $values['format'], $items, $values['fields'] ); + } + /** * Check whether an item has an update available or not. * @@ -197,6 +217,30 @@ protected function has_update( $slug ) { ) ); + private function create_objects( $items ) { + if ( !is_array( $items ) && !empty( $items ) ) + \WP_CLI::error( sprintf( "No '$this->item_type's found." ) ); + + $objects = array(); + + foreach ( $items as $item ) { + $object = new \stdClass; + + foreach ( $item as $field => $value ) { + if ( $value === true ) { + $value = "available"; + } else if ( $value === false) { + $value = "none"; + } + + $object->{$field} = $value; + } + $objects[] = $object; + } + + return $objects; + } + protected function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index f761afb192..162b2539d7 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -12,6 +12,13 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade { protected $upgrade_refresh = 'wp_update_plugins'; protected $upgrade_transient = 'update_plugins'; + protected $fields = array( + 'name', + 'status', + 'update', + 'version' + ); + function __construct() { require_once ABSPATH.'wp-admin/includes/plugin.php'; require_once ABSPATH.'wp-admin/includes/plugin-install.php'; @@ -292,6 +299,16 @@ function delete( $args, $assoc_args = array(), $exit_on_error = true ) { return WP_CLI::launch( $command, $exit_on_error ); } + /** + * Get a list of plugins. + * + * @subcommand list + * @synopsis [--format=<format>] + */ + function _list( $_, $assoc_args ) { + parent::_list( $_, $assoc_args ); + } + /* PRIVATES */ private function check_active( $file, $network_wide ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index f7670c8cb1..2970eb65fc 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -12,6 +12,13 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { protected $upgrade_refresh = 'wp_update_themes'; protected $upgrade_transient = 'update_themes'; + protected $fields = array( + 'name', + 'status', + 'update', + 'version' + ); + /** * See the status of one or all themes. * @@ -190,6 +197,16 @@ function delete( $args ) { } } + /** + * Get a list of themes. + * + * @subcommand list + * @synopsis [--format=<format>] + */ + function _list( $_, $assoc_args ) { + parent::_list( $assoc_args ); + } + protected function parse_name( $args ) { if ( empty( $args ) ) { WP_CLI::line( "usage: wp theme $subcommand <theme-name>" ); From a1a28bb9ff4bdaebb5a6d84a55ee42b20467c945 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Thu, 9 May 2013 16:26:24 +0200 Subject: [PATCH 1627/4858] Match arguments of parent function --- php/WP_CLI/CommandWithUpgrade.php | 2 +- php/commands/theme.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 88687f2b33..f8b349a1f8 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -169,7 +169,7 @@ function update_all( $args, $assoc_args ) { } } - protected function _list( $format ) { + protected function _list( $_, $format ) { $values = array( 'format' => 'table', 'fields' => $this->fields diff --git a/php/commands/theme.php b/php/commands/theme.php index 2970eb65fc..441b2a3a29 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -204,7 +204,7 @@ function delete( $args ) { * @synopsis [--format=<format>] */ function _list( $_, $assoc_args ) { - parent::_list( $assoc_args ); + parent::_list( $_, $assoc_args ); } protected function parse_name( $args ) { From 77c971350d8cf14098f85ca23a6da2ffed4b32e8 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Thu, 9 May 2013 16:30:28 +0200 Subject: [PATCH 1628/4858] Generated man pages for the list commands --- man-src/plugin-list.txt | 9 +++++++++ man-src/theme-list.txt | 9 +++++++++ man/plugin-list.1 | 21 +++++++++++++++++++++ man/theme-list.1 | 21 +++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 man-src/plugin-list.txt create mode 100644 man-src/theme-list.txt create mode 100644 man/plugin-list.1 create mode 100644 man/theme-list.1 diff --git a/man-src/plugin-list.txt b/man-src/plugin-list.txt new file mode 100644 index 0000000000..8d2344d887 --- /dev/null +++ b/man-src/plugin-list.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `--format`=<format>: + + Output list as table, CSV or JSON. Defaults to table. + +## EXAMPLES + + wp plugin list --format=json diff --git a/man-src/theme-list.txt b/man-src/theme-list.txt new file mode 100644 index 0000000000..b875caeed5 --- /dev/null +++ b/man-src/theme-list.txt @@ -0,0 +1,9 @@ +## OPTIONS + +* `--format`=<format>: + + Output list as table, CSV or JSON. Defaults to table. + +## EXAMPLES + + wp theme list --format=csv diff --git a/man/plugin-list.1 b/man/plugin-list.1 new file mode 100644 index 0000000000..fd23e19af9 --- /dev/null +++ b/man/plugin-list.1 @@ -0,0 +1,21 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-PLUGIN\-LIST" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-plugin\-list\fR \- Get a list of plugins\. +. +.SH "SYNOPSIS" +wp plugin list [\-\-format=\fIformat\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-format\fR=\fIformat\fR: +. +.IP +Output list as table, CSV or JSON\. Defaults to table\. +. +.SH "EXAMPLES" +wp plugin list \-\-format=json diff --git a/man/theme-list.1 b/man/theme-list.1 new file mode 100644 index 0000000000..96436899fe --- /dev/null +++ b/man/theme-list.1 @@ -0,0 +1,21 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-THEME\-LIST" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-theme\-list\fR \- Get a list of themes\. +. +.SH "SYNOPSIS" +wp theme list [\-\-format=\fIformat\fR] +. +.SH "OPTIONS" +. +.TP +\fB\-\-format\fR=\fIformat\fR: +. +.IP +Output list as table, CSV or JSON\. Defaults to table\. +. +.SH "EXAMPLES" +wp theme list \-\-format=csv From 4fb95a3e4f994677b1b23fbaefd5a0841ec23c93 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Thu, 9 May 2013 16:41:08 +0200 Subject: [PATCH 1629/4858] Added functional tests for the plugin and theme list command --- features/plugin.feature | 4 ++++ features/theme.feature | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 88dbf0548a..66bdb0530e 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -21,3 +21,7 @@ Feature: Manage WordPress plugins """ Error: The plugin 'non-existent-plugin' could not be found. """ + + When I run `wp plugin list --format=json` + Then it should run without errors + And STDOUT should not be empty diff --git a/features/theme.feature b/features/theme.feature index a6a57c252a..4424b44042 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -49,6 +49,10 @@ Feature: Manage WordPress themes Error: The theme 'p2' could not be found. """ + When I run `wp theme list` + Then it should run without errors + And STDOUT should not be empty + Scenario: Upgrading a theme Given a WP install And a P2 theme zip From 32402827d8e738c7c4e6025b7b3bbc6d7a1a45d2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 20:53:47 +0300 Subject: [PATCH 1630/4858] first pass at --verbose flag for `wp export` --- php/commands/export.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index 0f85c92c33..2983053d36 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -11,7 +11,7 @@ class Export_Command extends WP_CLI_Command { /** * Export content to a WXR file. * - * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] + * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] [--verbose] */ public function __invoke( $_, $assoc_args ) { $defaults = array( @@ -25,6 +25,7 @@ public function __invoke( $_, $assoc_args ) { 'post__in' => NULL, 'skip_comments' => NULL, 'file_item_count' => 1000, + 'verbose' => false, ); $args = wp_parse_args( $assoc_args, $defaults ); @@ -51,6 +52,12 @@ public function __invoke( $_, $assoc_args ) { $this->export_wp( $this->export_args ); } + private function check_verbose( $verbose ) { + $this->verbose = $verbose; + + return true; + } + private function check_dir( $path ) { if ( empty( $path ) ) { $this->export_args['dir'] = getcwd(); @@ -376,7 +383,8 @@ private function export_wp( $args = array() ) { WP_CLI::line( 'Writing to file ' . $full_path ); } - $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); + if ( !$this->verbose ) + $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); $this->start_export(); echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . "\" ?>\n"; @@ -447,7 +455,11 @@ private function export_wp( $args = array() ) { // Begin Loop foreach ( $posts as $post ) { - $progress->tick(); + if ( !$this->verbose ) { + $progress->tick(); + } else { + WP_CLI::line( "Exporting post $post->ID" ); + } setup_postdata( $post ); $is_sticky = is_sticky( $post->ID ) ? 1 : 0; @@ -525,7 +537,11 @@ private function export_wp( $args = array() ) { $this->flush_export( $full_path ); $this->end_export(); $this->stop_the_insanity(); - $progress->finish(); + + if ( !$this->verbose ) { + $progress->finish(); + } + $file_count++; } WP_CLI::success( "All done with export" ); From 067c9ed741efad4ddd38d9b1fefd284d50d7d501 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 21:02:00 +0300 Subject: [PATCH 1631/4858] export: minor whitespace fixes --- php/commands/export.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index 2983053d36..e28d778e03 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -15,16 +15,16 @@ class Export_Command extends WP_CLI_Command { */ public function __invoke( $_, $assoc_args ) { $defaults = array( - 'dir' => NULL, - 'start_date' => NULL, - 'end_date' => NULL, - 'post_type' => NULL, - 'author' => NULL, - 'category' => NULL, - 'post_status' => NULL, - 'post__in' => NULL, - 'skip_comments' => NULL, - 'file_item_count' => 1000, + 'dir' => NULL, + 'start_date' => NULL, + 'end_date' => NULL, + 'post_type' => NULL, + 'author' => NULL, + 'category' => NULL, + 'post_status' => NULL, + 'post__in' => NULL, + 'skip_comments' => NULL, + 'file_item_count' => 1000, 'verbose' => false, ); @@ -386,8 +386,8 @@ private function export_wp( $args = array() ) { if ( !$this->verbose ) $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); - $this->start_export(); - echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . "\" ?>\n"; + $this->start_export(); + echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . "\" ?>\n"; ?> <!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. --> From a8180e70bcf4a30909f7c06e8cc39ddf3d66f058 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 23:54:58 +0300 Subject: [PATCH 1632/4858] behat: set up WP file cache only once, before suite Also, use run_check() to catch download errors. see #441 --- features/bootstrap/FeatureContext.php | 32 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 1245620f2a..699f6c56b2 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -16,6 +16,8 @@ */ class FeatureContext extends BehatContext implements ClosuredContextInterface { + private static $cache_dir; + private static $db_settings = array( 'dbname' => 'wp_cli_test', 'dbuser' => 'wp_cli_test', @@ -28,10 +30,28 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { public $variables = array(); + private static function wp_cli( $command ) { + return __DIR__ . "/../../bin/wp $command"; + } + + // We cache the results of `wp core download` to improve test performance + // Ideally, we'd cache at the HTTP layer for more reliable tests + private static function cache_wp_files() { + self::$cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + + if ( is_readable( self::$cache_dir . '/wp-config-sample.php' ) ) + return; + + $cmd = Utils\esc_cmd( 'core download --force --path=%s', self::$cache_dir ); + Process::create( self::wp_cli( $cmd ) )->run_check(); + } + /** * @BeforeSuite */ public static function prepare( SuiteEvent $event ) { + self::cache_wp_files(); + self::$additional_args = array( 'core config' => self::$db_settings, @@ -131,7 +151,7 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - return Process::create( __DIR__ . "/../../bin/wp $command", $this->install_dir ); + return Process::create( self::wp_cli( $command ), $this->install_dir ); } public function move_files( $src, $dest ) { @@ -145,19 +165,11 @@ public function add_line_to_wp_config( &$wp_config_code, $line ) { } public function download_wordpress_files( $subdir = '' ) { - // We cache the results of "wp core download" to improve test performance - // Ideally, we'd cache at the HTTP layer for more reliable tests - $cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; - - $r = $this->proc( 'core download', array( - 'path' => $cache_dir - ) )->run(); - $dest_dir = $this->get_path( $subdir ); if ( $subdir ) mkdir( $dest_dir ); - Process::create( Utils\esc_cmd( "cp -r %s/* %s", $cache_dir, $dest_dir ) )->run_check(); + Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ) )->run_check(); } public function wp_install( $subdir = '' ) { From 8e03de3d4f968d73daa7f3419adac937620e52bc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 23:23:58 +0300 Subject: [PATCH 1633/4858] define WP_DEBUG in Utils\wp_debug_mode() --- php/WP_CLI/Runner.php | 7 ------- php/utils-wp.php | 3 +++ php/wp-cli.php | 2 -- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4af9554eae..fba607aecc 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -335,13 +335,6 @@ public function before_wp_load() { } } - public function after_wp_config_load() { - if ( $this->config['debug'] ) { - if ( !defined( 'WP_DEBUG' ) ) - define( 'WP_DEBUG', true ); - } - } - public function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); diff --git a/php/utils-wp.php b/php/utils-wp.php index 1821f7f8c4..a50be47135 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -14,6 +14,9 @@ function wp_not_installed() { 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 ); ini_set( 'display_errors', true ); } else { diff --git a/php/wp-cli.php b/php/wp-cli.php index f002341c3e..74db4137d1 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -20,8 +20,6 @@ // Load wp-config.php code, in the global scope eval( WP_CLI::$runner->get_wp_config_code() ); -WP_CLI::$runner->after_wp_config_load(); - // Simulate a /wp-admin/ page load $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; define( 'WP_ADMIN', true ); From 6aa4fa36f8701e3148ba44e7a0ee33b7fc71a54a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 10 May 2013 00:39:15 +0300 Subject: [PATCH 1634/4858] never display PHP errors on STDOUT --- features/flags.feature | 8 ++++++-- php/utils-wp.php | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 7053443bb5..39592c33a4 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -30,9 +30,13 @@ Feature: Global flags When I run `wp eval 'echo CONST_WITHOUT_QUOTES;' --debug` Then the return code should be 0 - And STDOUT should contain: + And STDOUT should be: + """ + CONST_WITHOUT_QUOTES + """ + And STDERR should contain: """ - Notice: Use of undefined constant CONST_WITHOUT_QUOTES + PHP Notice: Use of undefined constant CONST_WITHOUT_QUOTES """ Scenario: Setting the WP user diff --git a/php/utils-wp.php b/php/utils-wp.php index a50be47135..f5c2afe85b 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -18,10 +18,12 @@ function wp_debug_mode() { define( 'WP_DEBUG', true ); error_reporting( E_ALL & ~E_DEPRECATED & ~E_STRICT ); - ini_set( 'display_errors', true ); } else { \wp_debug_mode(); } + + // Never show errors on STDOUT; only on STDERR + ini_set( 'display_errors', false ); } function replace_wp_die_handler() { From d3e4016a84d1173f5587937d1734c1e137413db5 Mon Sep 17 00:00:00 2001 From: tolgap <tolga@hoppinger.com> Date: Fri, 10 May 2013 15:16:31 +0200 Subject: [PATCH 1635/4858] Force the version field if not exist so it shows up in the table --- php/WP_CLI/CommandWithUpgrade.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index f8b349a1f8..4ffe023860 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -226,6 +226,9 @@ private function create_objects( $items ) { foreach ( $items as $item ) { $object = new \stdClass; + if ( empty( $item['version'] ) ) + $item['version'] = ""; + foreach ( $item as $field => $value ) { if ( $value === true ) { $value = "available"; From 5ad115079538d63bb17c9d6f248821265df61bd9 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 23 Apr 2013 00:50:10 +0200 Subject: [PATCH 1636/4858] Added CPT and TAX --flags test and TAX --theme test --- features/scaffold.feature | 65 ++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 5c966f080d..616ebfad48 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,15 +1,64 @@ Feature: Wordpress code scaffolding - - Scenario: Scaffold a Custom Post Type - Given a WP install - When I run `wp scaffold post-type zombie` - Then it should run without errors - And STDOUT should contain: + Scenario: Scaffold a Custom Taxonomy and write it to active theme + Given a WP install + + When I run `wp scaffold taxonomy zombie-speed --theme` + Then it should run without errors + + When I run `wp option get stylesheet` + Then it should run without errors + And save STDOUT as {ACTIVE_THEME} + + #And the wp-content/{ACTIVE_THEME}/taxonomy/zombie-speed.php file should exist + And the wp-content/themes/twentytwelve/taxonomies/zombie-speed.php file should exist + + # Test for all flags but --label, --theme, --plugin and --raw + Scenario: Scaffold a Custom Taxonomy and attach it to a CPT zombie that is prefixed and has a text domain + Given a WP install + + When I run `wp scaffold taxonomy zombie-speed --post_types="prefix-zombie" --textdomain=zombieland` + Then it should run without errors + And STDOUT should contain: + """ + __( 'Zombie speeds' + """ + And STDOUT should contain: + """ + array( 'prefix-zombie' ) + """ + And STDOUT should contain: + """ + __( 'Zombie speeds', 'zombieland' + """ + + Scenario: Scaffold a Custom Taxonomy with label "Speed" + Given a WP install + + When I run `wp scaffold taxonomy zombie-speed --label="Speed"` + Then it should run without errors + And STDOUT should contain: """ - __( 'Zombies' + __( 'Speed' """ - + + + + # Test for all flags but --label, --theme, --plugin and --raw + Scenario: Scaffold a Custom Post Type + Given a WP install + + When I run `wp scaffold post-type zombie --textdomain=zombieland` + Then it should run without errors + And STDOUT should contain: + """ + __( 'Zombies' + """ + And STDOUT should contain: + """ + __( 'Zombies', 'zombieland' + """ + Scenario: Scaffold a Custom Post Type with label Given a WP install From 61dd38e0d9b35681d953d9460966b56d90a7f728 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 9 May 2013 02:39:02 +0200 Subject: [PATCH 1637/4858] Using stylesheetpath because it gets them path and active theme at once --- features/scaffold.feature | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 616ebfad48..423d373c51 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -6,12 +6,10 @@ Feature: Wordpress code scaffolding When I run `wp scaffold taxonomy zombie-speed --theme` Then it should run without errors - When I run `wp option get stylesheet` + When I run `wp eval 'echo STYLESHEETPATH;'` Then it should run without errors - And save STDOUT as {ACTIVE_THEME} - - #And the wp-content/{ACTIVE_THEME}/taxonomy/zombie-speed.php file should exist - And the wp-content/themes/twentytwelve/taxonomies/zombie-speed.php file should exist + And save STDOUT as {STYLESHEETPATH} + And the {STYLESHEETPATH}/taxonomies/zombie-speed.php file should exist # Test for all flags but --label, --theme, --plugin and --raw Scenario: Scaffold a Custom Taxonomy and attach it to a CPT zombie that is prefixed and has a text domain From d55d5599861bcb69e318927be2c86dca98abc4d5 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 9 May 2013 18:20:27 +0200 Subject: [PATCH 1638/4858] Added CPT creation --- features/scaffold.feature | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 423d373c51..7f018db3d3 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -11,6 +11,17 @@ Feature: Wordpress code scaffolding And save STDOUT as {STYLESHEETPATH} And the {STYLESHEETPATH}/taxonomies/zombie-speed.php file should exist + Scenario: Scaffold a Custom Post Type and write it to active theme + Given a WP install + + When I run `wp scaffold post-type zombie --theme` + Then it should run without errors + + When I run `wp eval 'echo STYLESHEETPATH;'` + Then it should run without errors + And save STDOUT as {STYLESHEETPATH} + And the {STYLESHEETPATH}/post-types/zombie.php file should exist + # Test for all flags but --label, --theme, --plugin and --raw Scenario: Scaffold a Custom Taxonomy and attach it to a CPT zombie that is prefixed and has a text domain Given a WP install @@ -40,8 +51,6 @@ Feature: Wordpress code scaffolding __( 'Speed' """ - - # Test for all flags but --label, --theme, --plugin and --raw Scenario: Scaffold a Custom Post Type Given a WP install From 0d1771575235eb4cfa26729dc4ebb19283f20b1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 May 2013 01:03:35 +0300 Subject: [PATCH 1639/4858] simplify 'file should exist' step definition --- features/steps/basic_steps.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 89368ceb7c..59cf646b79 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -252,16 +252,13 @@ function ( $world, $stream ) { $steps->Then( '/^the (.+) file should exist$/', function ( $world, $path ) { - $path = $world->replace_variables( $path ); + $path = $world->replace_variables( $path ); - // If $path refers to a complete cache path, use it; - // otherwise, get the real path using $world->get_path() - if ( strpos( $path, $world->get_cache_path('') ) === 0 ) - $realpath = $path; - else - $realpath = $world->get_path( $path ); + // If it's a relative path, make it relative to the current test dir + if ( '/' !== $path[0] ) + $path = $world->get_path( $path ); - assertFileExists( $realpath ); + assertFileExists( $path ); } ); From 2d2fc66c30af12e24b3609a950393cd24aeae41e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 May 2013 23:27:19 +0300 Subject: [PATCH 1640/4858] switch back to our fork of php-cli-tools --- composer.json | 2 +- composer.lock | 72 +++++++++++++++++++++++++++------------------------ php/utils.php | 1 - 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/composer.json b/composer.json index dc3cc5aaa4..ff0d20c9de 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "jlogsdon/cli": "~0.9.1", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "2.0.x" }, "suggest": { diff --git a/composer.lock b/composer.lock index 726e2b26b5..a16ee74ea4 100644 --- a/composer.lock +++ b/composer.lock @@ -3,29 +3,29 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "2f907ef4729a8057cba8d5310e72ed9f", + "hash": "e83d4615b33cb717939303cba9848c94", "packages": [ { - "name": "jlogsdon/cli", - "version": "v0.9.1", + "name": "mustache/mustache", + "version": "v2.0.2", "source": { "type": "git", - "url": "git://github.com/jlogsdon/php-cli-tools.git", - "reference": "v0.9.1" + "url": "https://github.com/bobthecow/mustache.php", + "reference": "v2.0.2" }, "dist": { "type": "zip", - "url": "https://github.com/jlogsdon/php-cli-tools/zipball/v0.9.1", - "reference": "v0.9.1", + "url": "https://github.com/bobthecow/mustache.php/zipball/v2.0.2", + "reference": "v2.0.2", "shasum": "" }, "require": { - "php": ">= 5.3.0" + "php": ">=5.2.4" }, "type": "library", "autoload": { "psr-0": { - "cli": "lib/" + "Mustache": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -34,41 +34,44 @@ ], "authors": [ { - "name": "James Logsdon", - "email": "jlogsdon@php.net", - "role": "Developer" + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" } ], - "description": "Console utilities for PHP", - "homepage": "http://github.com/jlogsdon/php-cli-tools", + "description": "A Mustache implementation in PHP.", + "homepage": "https://github.com/bobthecow/mustache.php", "keywords": [ - "cli", - "console" + "mustache", + "templating" ], - "time": "2012-09-15 14:09:00" + "time": "2012-09-12 09:13:06" }, { - "name": "mustache/mustache", - "version": "v2.0.2", + "name": "wp-cli/php-cli-tools", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/bobthecow/mustache.php", - "reference": "v2.0.2" + "url": "https://github.com/wp-cli/php-cli-tools.git", + "reference": "d44e1a9bd32d564a1c77dda0e96b66a199993e5c" }, "dist": { "type": "zip", - "url": "https://github.com/bobthecow/mustache.php/zipball/v2.0.2", - "reference": "v2.0.2", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/d44e1a9bd32d564a1c77dda0e96b66a199993e5c", + "reference": "d44e1a9bd32d564a1c77dda0e96b66a199993e5c", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">= 5.3.0" }, "type": "library", "autoload": { "psr-0": { - "Mustache": "src/" - } + "cli": "lib/" + }, + "files": [ + "lib/cli/cli.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -76,18 +79,18 @@ ], "authors": [ { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "name": "James Logsdon", + "email": "jlogsdon@php.net", + "role": "Developer" } ], - "description": "A Mustache implementation in PHP.", - "homepage": "https://github.com/bobthecow/mustache.php", + "description": "Console utilities for PHP", + "homepage": "http://github.com/jlogsdon/php-cli-tools", "keywords": [ - "mustache", - "templating" + "cli", + "console" ], - "time": "2012-09-12 09:13:06" + "time": "2013-05-11 20:20:03" } ], "packages-dev": [ @@ -928,6 +931,7 @@ ], "minimum-stability": "stable", "stability-flags": { + "wp-cli/php-cli-tools": 20, "behat/behat": 0 }, "platform": { diff --git a/php/utils.php b/php/utils.php index 39ff8e7ad3..7ef9154311 100644 --- a/php/utils.php +++ b/php/utils.php @@ -17,7 +17,6 @@ function load_dependencies() { foreach ( $vendor_paths as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; - include $vendor_path . '/jlogsdon/cli/lib/cli/cli.php'; $has_autoload = true; break; } From 4365b16811300622ef17c079e010c776bf9eb793 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 May 2013 23:28:24 +0300 Subject: [PATCH 1641/4858] autoload from local vendor dir, then from global This allows running `composer update` on the spot and without switching the wp-cli repo back to the master branch. This also allows using suggested packages from a super-project (most common being ~/.composer). --- php/utils.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index 7ef9154311..07aa0a083f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -8,8 +8,8 @@ function load_dependencies() { $vendor_paths = array( - WP_CLI_ROOT . '../../../../vendor', // part of a larger project WP_CLI_ROOT . '../vendor', // top-level project + WP_CLI_ROOT . '../../../../vendor', // part of a larger project ); $has_autoload = false; @@ -18,7 +18,6 @@ function load_dependencies() { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; $has_autoload = true; - break; } } From d233ebbdc56320497e07357ed7eb966ae4bd4e64 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 00:11:04 +0300 Subject: [PATCH 1642/4858] stop after finding the first Composer autoloader. Otherwise, could get fatal errors, such as "Cannot redeclare cli\register_autoload()". Unfortunately, this also means that suggested packages will be ignored, if there's a local vendor dir present. --- php/utils.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/utils.php b/php/utils.php index 07aa0a083f..880136c861 100644 --- a/php/utils.php +++ b/php/utils.php @@ -18,6 +18,7 @@ function load_dependencies() { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; $has_autoload = true; + break; } } From 0c047f6f2fc65b1b677e7dd8a61e60abb444f7eb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 16:22:29 +0300 Subject: [PATCH 1643/4858] add deprecation message for WP_CLI::addCommand() closes #448 --- php/class-wp-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index b8abeccef1..e3855a7ce8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -270,6 +270,8 @@ public static function run_command( $args, $assoc_args = array() ) { // back-compat static function addCommand( $name, $class ) { + trigger_error( sprintf( 'wp %s: %s is deprecated. use WP_CLI::add_command() instead.', + $name, __FUNCTION__ ), E_USER_WARNING ); self::add_command( $name, $class ); } } From c8a5b120904579f3e3e7debbd63e8788ad37a12a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 16:37:13 +0300 Subject: [PATCH 1644/4858] make is_absolute_path() work on Windows paths fixes #447 --- php/WP_CLI/Runner.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index fba607aecc..981716dc14 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -110,6 +110,10 @@ private static function set_wp_root( $config ) { } private static function is_absolute_path( $path ) { + // Windows + if ( ':' === $path[1] ) + return true; + return $path[0] === '/'; } From 9fe97c833a367d0d42e8c691b1dcb9f7a21de5a3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 19:25:31 +0300 Subject: [PATCH 1645/4858] export: more indentation fixes --- php/commands/export.php | 44 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index e28d778e03..9b6b1d6d53 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -329,31 +329,31 @@ private function export_wp( $args = array() ) { $cats = array( $cat->term_id => $cat ); unset( $term, $cat ); } else if ( 'all' == $args['post_type'] ) { - $categories = (array) get_categories( array( 'get' => 'all' ) ); - $tags = (array) get_tags( array( 'get' => 'all' ) ); - - $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); - $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); - - // put categories in order with no child going before its parent - while ( $cat = array_shift( $categories ) ) { - if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) ) - $cats[$cat->term_id] = $cat; - else - $categories[] = $cat; - } - - // put terms in order with no child going before its parent - while ( $t = array_shift( $custom_terms ) ) { - if ( $t->parent == 0 || isset( $terms[$t->parent] ) ) - $terms[$t->term_id] = $t; - else - $custom_terms[] = $t; - } + $categories = (array) get_categories( array( 'get' => 'all' ) ); + $tags = (array) get_tags( array( 'get' => 'all' ) ); + + $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); + $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); + + // put categories in order with no child going before its parent + while ( $cat = array_shift( $categories ) ) { + if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) ) + $cats[$cat->term_id] = $cat; + else + $categories[] = $cat; + } - unset( $categories, $custom_taxonomies, $custom_terms ); + // put terms in order with no child going before its parent + while ( $t = array_shift( $custom_terms ) ) { + if ( $t->parent == 0 || isset( $terms[$t->parent] ) ) + $terms[$t->term_id] = $t; + else + $custom_terms[] = $t; } + unset( $categories, $custom_taxonomies, $custom_terms ); + } + // Load the functions available in wp-admin/includes/export.php ob_start(); export_wp( array( 'content' => 'page', 'start_date' => '1971-01-01', 'end_date' => '1971-01-02' ) ); From e057464acc250f16330da40c6f80941de7adc249 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 19:26:55 +0300 Subject: [PATCH 1646/4858] export: show parameters sent to export_wp() only if --verbose is set --- php/commands/export.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 9b6b1d6d53..3bde8c3148 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -256,7 +256,9 @@ private function export_wp( $args = array() ) { ); $args = wp_parse_args( $args, $defaults ); - WP_CLI::line( "Exporting with export_wp with arguments: " . var_export( $args, true ) ); + if ( $this->verbose ) { + WP_CLI::line( "Exporting with export_wp with arguments: " . var_export( $args, true ) ); + } do_action( 'export_wp' ); From 0781be0fd832627fef85ef3e8d783654fc012a12 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 19:29:34 +0300 Subject: [PATCH 1647/4858] export: document --verbose parameter [ci skip] --- man-src/export.txt | 4 ++++ man/export.1 | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/man-src/export.txt b/man-src/export.txt index 94e5cab4bd..dcb8ea478c 100644 --- a/man-src/export.txt +++ b/man-src/export.txt @@ -13,6 +13,10 @@ to current working directory. Break export into files with N posts. +* `--verbose`: + + Show more information about the process on STDOUT. + ## FILTERS * `--start_date`=<date>: diff --git a/man/export.1 b/man/export.1 index a11fc78cbd..e4aaf633b0 100644 --- a/man/export.1 +++ b/man/export.1 @@ -7,7 +7,7 @@ \fBwp\-export\fR \- Export content to a WXR file\. . .SH "SYNOPSIS" -wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post__in=\fIpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] +wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post__in=\fIpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] [\-\-verbose] . .SH "OPTIONS" . @@ -29,6 +29,12 @@ Don\'t export comments\. .IP Break export into files with N posts\. . +.TP +\fB\-\-verbose\fR: +. +.IP +Show more information about the process on STDOUT\. +. .SH "FILTERS" . .TP From 7066757ee12a27c17a629507fbeda0d799cbb08a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 19:37:31 +0300 Subject: [PATCH 1648/4858] export: add smoke test --- features/export.feature | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 features/export.feature diff --git a/features/export.feature b/features/export.feature new file mode 100644 index 0000000000..096429833f --- /dev/null +++ b/features/export.feature @@ -0,0 +1,8 @@ +Feature: Export content. + + Scenario: Basic export + Given a WP install + + When I run `wp export` + Then it should run without errors + And STDOUT should not be empty From e3fbb0525f241e3a3e9d3a4e244a53cb26fa0a81 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 12 May 2013 23:02:20 +0200 Subject: [PATCH 1649/4858] Merged CPT and Tax test --- features/scaffold.feature | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 7f018db3d3..acd875f5f4 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,6 +1,6 @@ Feature: Wordpress code scaffolding - Scenario: Scaffold a Custom Taxonomy and write it to active theme + Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install When I run `wp scaffold taxonomy zombie-speed --theme` @@ -11,15 +11,8 @@ Feature: Wordpress code scaffolding And save STDOUT as {STYLESHEETPATH} And the {STYLESHEETPATH}/taxonomies/zombie-speed.php file should exist - Scenario: Scaffold a Custom Post Type and write it to active theme - Given a WP install - When I run `wp scaffold post-type zombie --theme` Then it should run without errors - - When I run `wp eval 'echo STYLESHEETPATH;'` - Then it should run without errors - And save STDOUT as {STYLESHEETPATH} And the {STYLESHEETPATH}/post-types/zombie.php file should exist # Test for all flags but --label, --theme, --plugin and --raw From 0d4e5357ca7b6c0638185e3fe09d10b6391665c1 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 12 May 2013 23:05:21 +0200 Subject: [PATCH 1650/4858] Added trailing slash to WP_CONTENT_DIR Fixes #446 --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index b43e87a135..1cdcac3968 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -166,7 +166,7 @@ function child_theme( $args, $assoc_args ) { $data['description'] = ucfirst( $data['parent_theme'] ) . " child theme."; - $theme_dir = WP_CONTENT_DIR . "themes" . "/$theme_slug"; + $theme_dir = WP_CONTENT_DIR . "/themes" . "/$theme_slug"; $theme_style_path = "$theme_dir/style.css"; $this->create_file( $theme_style_path, $this->render( 'child_theme.mustache', $data ) ); From 29ee3d3227437b4c3f4d287ea1e878ff4a0c5200 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 13 May 2013 00:29:45 +0200 Subject: [PATCH 1651/4858] Added child-theme behat test --- features/scaffold.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index acd875f5f4..10b8763243 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,5 +1,18 @@ Feature: Wordpress code scaffolding + @theme + Scenario: Scaffold a child theme + Given a WP install + + When I run `wp scaffold child-theme zombieland --parent_theme=umbrella` + Then it should run without errors + + When I run `wp theme path` + Then it should run without errors + And save STDOUT as {THEME_PATH} + And the {THEME_PATH}/zombieland/style.css file should exist + + Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install From b07830876addfa08b5804f32925ed3e4f1fbcf02 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 13 May 2013 00:52:13 +0200 Subject: [PATCH 1652/4858] Added tags --- features/scaffold.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 10b8763243..4fa80f7438 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -12,7 +12,7 @@ Feature: Wordpress code scaffolding And save STDOUT as {THEME_PATH} And the {THEME_PATH}/zombieland/style.css file should exist - + @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install @@ -29,6 +29,7 @@ Feature: Wordpress code scaffolding And the {STYLESHEETPATH}/post-types/zombie.php file should exist # Test for all flags but --label, --theme, --plugin and --raw + @tax Scenario: Scaffold a Custom Taxonomy and attach it to a CPT zombie that is prefixed and has a text domain Given a WP install @@ -47,6 +48,7 @@ Feature: Wordpress code scaffolding __( 'Zombie speeds', 'zombieland' """ + @tax Scenario: Scaffold a Custom Taxonomy with label "Speed" Given a WP install @@ -58,6 +60,7 @@ Feature: Wordpress code scaffolding """ # Test for all flags but --label, --theme, --plugin and --raw + @cpt Scenario: Scaffold a Custom Post Type Given a WP install @@ -72,6 +75,7 @@ Feature: Wordpress code scaffolding __( 'Zombies', 'zombieland' """ + @cpt Scenario: Scaffold a Custom Post Type with label Given a WP install From b56b58f778913cb2c63fbd7eecc9077c6e354e4a Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 13 May 2013 00:58:12 +0200 Subject: [PATCH 1653/4858] Added behat test for plugin scaffolding --- features/scaffold.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 4fa80f7438..1285ddb05f 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -11,6 +11,18 @@ Feature: Wordpress code scaffolding Then it should run without errors And save STDOUT as {THEME_PATH} And the {THEME_PATH}/zombieland/style.css file should exist + + @plugin + Scenario: Scaffold a plugin + Given a WP install + + When I run `wp scaffold plugin zombieland` + Then it should run without errors + + When I run `wp path path` + Then it should run without errors + And save STDOUT as {PLUGIN_PATH} + And the {PLUGIN_PATH}/zombieland/zombieland.php file should exist @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme From 37b3d8bfac6793862d0a0fe6497ed7a597fe23be Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 13 May 2013 01:11:11 +0200 Subject: [PATCH 1654/4858] Added scaffold plugin activation test --- features/scaffold.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 1285ddb05f..ba516bfb26 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -4,7 +4,7 @@ Feature: Wordpress code scaffolding Scenario: Scaffold a child theme Given a WP install - When I run `wp scaffold child-theme zombieland --parent_theme=umbrella` + When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --activate` Then it should run without errors When I run `wp theme path` @@ -16,7 +16,7 @@ Feature: Wordpress code scaffolding Scenario: Scaffold a plugin Given a WP install - When I run `wp scaffold plugin zombieland` + When I run `wp scaffold plugin zombieland --activate` Then it should run without errors When I run `wp path path` From 5a985b4bfc72fe70bcbb93884442511f5adeff86 Mon Sep 17 00:00:00 2001 From: Jaime Martinez <jmslbam@gmail.com> Date: Mon, 13 May 2013 09:26:51 +0200 Subject: [PATCH 1655/4858] Plugin scaffold typo fix for Behat test --- features/scaffold.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index ba516bfb26..2d27a889b3 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -19,7 +19,7 @@ Feature: Wordpress code scaffolding When I run `wp scaffold plugin zombieland --activate` Then it should run without errors - When I run `wp path path` + When I run `wp plugin path` Then it should run without errors And save STDOUT as {PLUGIN_PATH} And the {PLUGIN_PATH}/zombieland/zombieland.php file should exist @@ -96,4 +96,4 @@ Feature: Wordpress code scaffolding And STDOUT should contain: """ __( 'Brain eaters' - """ \ No newline at end of file + """ From a00f6056b5f5d995d254be7e5ac83e8448243418 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 13 May 2013 22:45:36 +0200 Subject: [PATCH 1656/4858] Split up plugin activation --- features/scaffold.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 2d27a889b3..02bf15727a 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -12,17 +12,21 @@ Feature: Wordpress code scaffolding And save STDOUT as {THEME_PATH} And the {THEME_PATH}/zombieland/style.css file should exist + # Adding --activate to the test crashes the tests @plugin Scenario: Scaffold a plugin Given a WP install - When I run `wp scaffold plugin zombieland --activate` + When I run `wp scaffold plugin zombieland` Then it should run without errors When I run `wp plugin path` Then it should run without errors And save STDOUT as {PLUGIN_PATH} And the {PLUGIN_PATH}/zombieland/zombieland.php file should exist + + When I run `wp plugin activate zombieland` + Then it should run without errors @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme From ac2272bc83379d5f8a7d3b79fc2f947933b2d576 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 13 May 2013 22:54:23 +0200 Subject: [PATCH 1657/4858] Added plugin_name arg --- features/scaffold.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 02bf15727a..6a1e96d176 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -17,7 +17,7 @@ Feature: Wordpress code scaffolding Scenario: Scaffold a plugin Given a WP install - When I run `wp scaffold plugin zombieland` + When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland"` Then it should run without errors When I run `wp plugin path` From c813d88c11cb89d8a5ecc684403e54e0bf6f83a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 14:08:41 +0300 Subject: [PATCH 1658/4858] behat: reorganize common cpt and tax setup --- features/scaffold.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 6a1e96d176..ed94dc4eca 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -32,12 +32,12 @@ Feature: Wordpress code scaffolding Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install - When I run `wp scaffold taxonomy zombie-speed --theme` - Then it should run without errors - When I run `wp eval 'echo STYLESHEETPATH;'` Then it should run without errors And save STDOUT as {STYLESHEETPATH} + + When I run `wp scaffold taxonomy zombie-speed --theme` + Then it should run without errors And the {STYLESHEETPATH}/taxonomies/zombie-speed.php file should exist When I run `wp scaffold post-type zombie --theme` From 7d80a1237413cdacb51b65c17e84d8df4f931eac Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 16:14:22 +0300 Subject: [PATCH 1659/4858] behat: remove "it should run without errors" step introduce "try `cmd`" steps. --- features/blog.feature | 35 +++++++++-------------- features/config.feature | 25 ++++++----------- features/core.feature | 35 ++++++++++------------- features/db.feature | 21 +++++--------- features/export.feature | 3 +- features/flags.feature | 26 +++++++---------- features/help.feature | 14 ++++----- features/media.feature | 4 +-- features/plugin.feature | 9 ++---- features/post.feature | 37 +++++++++--------------- features/scaffold.feature | 33 ++++++++-------------- features/search-replace.feature | 3 +- features/shell.feature | 7 ++--- features/steps/basic_steps.php | 50 ++++++++++++++++----------------- features/term.feature | 19 +++++-------- features/theme.feature | 36 +++++++++--------------- features/user.feature | 18 ++++-------- 17 files changed, 143 insertions(+), 232 deletions(-) diff --git a/features/blog.feature b/features/blog.feature index 264dd66d40..14712c4449 100644 --- a/features/blog.feature +++ b/features/blog.feature @@ -4,59 +4,50 @@ Feature: Manage a WordPress installation Given a WP install When I run `wp core install-network` - Then it should run without errors + Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 Scenario: Delete a blog by id Given a WP multisite install When I run `wp blog create --slug=first --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' And save STDOUT as {BLOG_ID} When I run `wp blog delete {BLOG_ID} --yes` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 Scenario: Delete a blog by slug Given a WP multisite install When I run `wp blog create --slug=first` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp blog delete --slug=first --yes` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 Scenario: Empty a blog Given a WP install When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term'` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp blog empty --yes` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp post list --format=ids` - Then it should run without errors - And STDOUT should be empty + Then STDOUT should be empty When I run `wp term list post_tag --format=ids` - Then it should run without errors - And STDOUT should be empty \ No newline at end of file + Then STDOUT should be empty diff --git a/features/config.feature b/features/config.feature index 9bb174d7d2..339319c953 100644 --- a/features/config.feature +++ b/features/config.feature @@ -4,15 +4,13 @@ Feature: Have a config file Given a WP install When I run `wp --info` - Then it should run without errors - And STDOUT should not contain: + Then STDOUT should not contain: """ wp-cli.yml """ When I run `wp core is-installed` from 'wp-content' - Then it should run without errors - And STDOUT should be empty + Then STDOUT should be empty Scenario: Config file in WP Root Given a WP install @@ -21,15 +19,13 @@ Feature: Have a config file """ When I run `wp --info` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ wp-cli.yml """ When I run `wp core is-installed` - Then it should run without errors - And STDOUT should be empty + Then STDOUT should be empty Scenario: WP in a subdirectory Given a WP install in 'core' @@ -39,19 +35,16 @@ Feature: Have a config file """ When I run `wp --info` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ wp-cli.yml """ When I run `wp core is-installed` - Then it should run without errors - And STDOUT should be empty + Then STDOUT should be empty When I run `wp core is-installed` from 'core/wp-content' - Then it should run without errors - And STDOUT should be empty + Then STDOUT should be empty Scenario: Nested installs Given a WP install @@ -60,8 +53,8 @@ Feature: Have a config file """ """ - When I run `wp info` from 'subsite' - And STDOUT should not contain: + When I run `wp --info` from 'subsite' + Then STDOUT should not contain: """ wp-cli.yml """ diff --git a/features/core.feature b/features/core.feature index 60923299c7..7de94acec1 100644 --- a/features/core.feature +++ b/features/core.feature @@ -2,21 +2,22 @@ Feature: Manage WordPress installation Scenario: Empty dir Given an empty directory - When I run `wp core is-installed` + + When I try `wp core is-installed` Then the return code should be 1 When I run `wp core download --quiet` - Then it should run without errors - And the wp-settings.php file should exist + Then the wp-settings.php file should exist Scenario: No wp-config.php Given an empty directory And WP files - When I run `wp core is-installed` + When I try `wp core is-installed` Then the return code should be 1 - When I run `wp core install` + When I try `wp core install` + Then the return code should be 1 Then STDERR should be: """ Error: wp-config.php not found. @@ -24,20 +25,19 @@ Feature: Manage WordPress installation """ When I run `wp core config` - Then it should run without errors - And the wp-config.php file should exist + Then the wp-config.php file should exist Scenario: Database doesn't exist Given an empty directory And WP files And wp-config.php - When I run `wp` + When I try `wp` Then the return code should be 1 And STDERR should not be empty When I run `wp db create` - Then it should run without errors + Then STDOUT should not be empty Scenario: Database tables not installed Given an empty directory @@ -45,10 +45,10 @@ Feature: Manage WordPress installation And wp-config.php And a database - When I run `wp core is-installed` + When I try `wp core is-installed` Then the return code should be 1 - When I run `wp` + When I try `wp` Then the return code should be 1 And STDERR should be: """ @@ -57,28 +57,24 @@ Feature: Manage WordPress installation """ When I run `wp core install` - Then the return code should be 0 + Then STDOUT should not be empty When I run `wp core version` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty Scenario: Full install Given a WP install When I run `wp core is-installed` - Then it should run without errors When I run `wp eval 'var_export( is_admin() );'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ true """ When I run `wp eval 'var_export( function_exists( 'media_handle_upload' ) );'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ true """ @@ -88,4 +84,3 @@ Feature: Manage WordPress installation And a custom wp-content directory When I run `wp plugin status hello` - Then it should run without errors diff --git a/features/db.feature b/features/db.feature index ca32411118..6bef95986a 100644 --- a/features/db.feature +++ b/features/db.feature @@ -6,30 +6,25 @@ Feature: Perform database operations And wp-config.php When I run `wp db create` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 When I run `wp db reset --yes` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp db optimize` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp db repair` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty Scenario: DB Query Given a WP install When I run `wp db query 'SELECT COUNT(*) as total FROM wp_posts'` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ total """ @@ -38,10 +33,8 @@ Feature: Perform database operations """ SELECT COUNT(*) as total FROM wp_posts """ - When I run `wp db query < debug.sql` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ total """ diff --git a/features/export.feature b/features/export.feature index 096429833f..1194696f92 100644 --- a/features/export.feature +++ b/features/export.feature @@ -4,5 +4,4 @@ Feature: Export content. Given a WP install When I run `wp export` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty diff --git a/features/flags.feature b/features/flags.feature index 39592c33a4..95a201a732 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -4,14 +4,12 @@ Feature: Global flags Given a WP install When I run `wp` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp --quiet` - Then it should run without errors - And STDOUT should be empty + Then STDOUT should be empty - When I run `wp non-existing-command --quiet` + When I try `wp non-existing-command --quiet` Then the return code should be 1 And STDERR should be: """ @@ -22,8 +20,7 @@ Feature: Global flags Given a WP install When I run `wp eval 'echo CONST_WITHOUT_QUOTES;'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ CONST_WITHOUT_QUOTES """ @@ -43,20 +40,18 @@ Feature: Global flags Given a WP install When I run `wp eval 'echo (int) is_user_logged_in();'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ 0 """ When I run `wp --user=admin eval 'echo wp_get_current_user()->user_login;'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ admin """ - When I run `wp --user=non-existing-user` + When I try `wp --user=non-existing-user` Then the return code should be 1 And STDERR should be: """ @@ -79,8 +74,7 @@ Feature: Global flags """ When I run `wp --require=custom-cmd.php test req 'This is a custom command.'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ This is a custom command. """ @@ -88,13 +82,13 @@ Feature: Global flags Scenario: Enabling/disabling color Given a WP install - When I run `wp --no-color non-existent-command` + When I try `wp --no-color non-existent-command` Then STDERR should be: """ Error: 'non-existent-command' is not a registered wp command. See 'wp help'. """ - When I run `wp --color non-existent-command` + When I try `wp --color non-existent-command` Then STDERR should contain: """ [31;1mError: diff --git a/features/help.feature b/features/help.feature index 5a410db416..81599f5899 100644 --- a/features/help.feature +++ b/features/help.feature @@ -4,28 +4,26 @@ Feature: Get help about WP-CLI commands Given an empty directory When I run `wp help` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ Available commands: """ When I run `wp help core` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ usage: wp core """ When I run `wp help core download` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ WP-CORE-DOWNLOAD(1) """ - When I run `wp help non-existent-command` + When I try `wp help non-existent-command` Then the return code should be 1 + And STDERR should not be empty Scenario: Getting help for a third-party command Given a WP install @@ -41,10 +39,8 @@ Feature: Get help about WP-CLI commands WP_CLI::add_command( 'test-help', 'Test_Help' ); """ And I run `wp plugin activate test-cli-help` - And it should run without errors When I run `wp help test-help` - Then it should run without errors And STDOUT should contain: """ usage: wp test-help diff --git a/features/media.feature b/features/media.feature index e7a607cf39..ddb721c48d 100644 --- a/features/media.feature +++ b/features/media.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress attachments Scenario: Regenerate all images while none exists Given a WP install - When I run `wp media regenerate --yes` + When I try `wp media regenerate --yes` Then STDERR should contain: """ Error: Unable to find the images @@ -24,7 +24,7 @@ Feature: Manage WordPress attachments Scenario: Fail to import missing image Given a WP install - When I run `wp media import gobbledygook.png` + When I try `wp media import gobbledygook.png` Then STDERR should contain: """ Error: Unable to import file gobbledygook.png. Reason: File is empty. diff --git a/features/plugin.feature b/features/plugin.feature index 66bdb0530e..ad9a885206 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -4,18 +4,16 @@ Feature: Manage WordPress plugins Given a WP install When I run `wp plugin status` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp plugin status hello` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ Plugin hello details: Name: Hello Dolly """ - When I run `wp plugin status non-existent-plugin` + When I try `wp plugin status non-existent-plugin` Then the return code should be 1 And STDERR should contain: """ @@ -23,5 +21,4 @@ Feature: Manage WordPress plugins """ When I run `wp plugin list --format=json` - Then it should run without errors And STDOUT should not be empty diff --git a/features/post.feature b/features/post.feature index 731184f933..c9e93d630e 100644 --- a/features/post.feature +++ b/features/post.feature @@ -4,55 +4,48 @@ Feature: Manage WordPress posts Given a WP install When I run `wp post create --post_title='Test post' --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' And save STDOUT as {POST_ID} When I run `wp post update {POST_ID} --post_title='Updated post'` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ Success: Updated post {POST_ID}. """ When I run `wp post delete {POST_ID}` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ Success: Trashed post {POST_ID}. """ When I run the previous command again - Then it should run without errors + Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 Scenario: Creating/getting posts Given a WP install When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' And save STDOUT as {POST_ID} When I run `wp post get {POST_ID}` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ Test content. """ When I run `wp post get --format=content {POST_ID}` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ Test content. """ When I run `wp post get --format=table {POST_ID}` - Then it should run without errors - And STDOUT should be a table containing rows: + Then STDOUT should be a table containing rows: """ Field Value ID {POST_ID} @@ -60,8 +53,7 @@ Feature: Manage WordPress posts """ When I run `wp post get --format=json {POST_ID}` - Then it should run without errors - And STDOUT should be JSON containing: + Then STDOUT should be JSON containing: """ {"ID":{POST_ID},"post_title":"Test post","post_content":"Test content."} """ @@ -70,16 +62,13 @@ Feature: Manage WordPress posts Given a WP install When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' When I run `wp post create --post_title='Draft post' --post_content='Draft post content' --post_status='draft' --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' When I run `wp post list --post_type='post' --fields=post_title,post_name,post_status --format=csv` - Then it should run without errors - And STDOUT should be CSV containing: + Then STDOUT should be CSV containing: """ post_title,post_name,post_status "Publish post",publish-post,publish diff --git a/features/scaffold.feature b/features/scaffold.feature index ed94dc4eca..c12a3cfee7 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -5,11 +5,9 @@ Feature: Wordpress code scaffolding Given a WP install When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --activate` - Then it should run without errors When I run `wp theme path` - Then it should run without errors - And save STDOUT as {THEME_PATH} + Then save STDOUT as {THEME_PATH} And the {THEME_PATH}/zombieland/style.css file should exist # Adding --activate to the test crashes the tests @@ -18,31 +16,26 @@ Feature: Wordpress code scaffolding Given a WP install When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland"` - Then it should run without errors + Then STDOUT should not be empty When I run `wp plugin path` - Then it should run without errors And save STDOUT as {PLUGIN_PATH} - And the {PLUGIN_PATH}/zombieland/zombieland.php file should exist + Then the {PLUGIN_PATH}/zombieland/zombieland.php file should exist When I run `wp plugin activate zombieland` - Then it should run without errors + Then STDOUT should not be empty @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install - - When I run `wp eval 'echo STYLESHEETPATH;'` - Then it should run without errors + And I run `wp eval 'echo STYLESHEETPATH;'` And save STDOUT as {STYLESHEETPATH} When I run `wp scaffold taxonomy zombie-speed --theme` - Then it should run without errors - And the {STYLESHEETPATH}/taxonomies/zombie-speed.php file should exist + Then the {STYLESHEETPATH}/taxonomies/zombie-speed.php file should exist When I run `wp scaffold post-type zombie --theme` - Then it should run without errors - And the {STYLESHEETPATH}/post-types/zombie.php file should exist + Then the {STYLESHEETPATH}/post-types/zombie.php file should exist # Test for all flags but --label, --theme, --plugin and --raw @tax @@ -50,8 +43,7 @@ Feature: Wordpress code scaffolding Given a WP install When I run `wp scaffold taxonomy zombie-speed --post_types="prefix-zombie" --textdomain=zombieland` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ __( 'Zombie speeds' """ @@ -69,8 +61,7 @@ Feature: Wordpress code scaffolding Given a WP install When I run `wp scaffold taxonomy zombie-speed --label="Speed"` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ __( 'Speed' """ @@ -81,8 +72,7 @@ Feature: Wordpress code scaffolding Given a WP install When I run `wp scaffold post-type zombie --textdomain=zombieland` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ __( 'Zombies' """ @@ -96,8 +86,7 @@ Feature: Wordpress code scaffolding Given a WP install When I run `wp scaffold post-type zombie --label="Brain eater"` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ __( 'Brain eaters' """ diff --git a/features/search-replace.feature b/features/search-replace.feature index 34241c880e..30d9ecb784 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -4,5 +4,4 @@ Feature: Do global search/replace Given a WP install When I run `wp search-replace foo bar` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty diff --git a/features/shell.feature b/features/shell.feature index 0ca5aa9a9d..ad0f5c52c3 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -4,10 +4,9 @@ Feature: WordPress REPL Given a WP install When I run `wp shell < /dev/null` - Then it should run without errors When I run `wp shell --basic < /dev/null` - Then it should run without errors + Then STDOUT should be empty Scenario: Persistent environment Given a WP install @@ -19,8 +18,7 @@ Feature: WordPress REPL """ When I run `wp shell --basic < session` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ bool(false) """ @@ -37,7 +35,6 @@ Feature: WordPress REPL """ When I run `wp shell --basic < session` - Then it should run without errors And STDOUT should be: """ bool(true) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 59cf646b79..c4d373aa35 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -4,6 +4,16 @@ Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; +function invoke_proc( $proc, $mode, $subdir = null ) { + $map = array( + 'run' => 'run_check', + 'try' => 'run' + ); + $method = $map[ $mode ]; + + return $proc->$method( $subdir ); +} + $steps->Given( '/^an empty directory$/', function ( $world ) { $world->create_empty_dir(); @@ -94,30 +104,33 @@ function ( $world ) { } ); -$steps->When( '/^I run `wp`$/', - function ( $world ) { - $world->result = $world->proc( '' )->run(); +$steps->When( '/^I (run|try) `wp`$/', + function ( $world, $mode ) { + $world->result = invoke_proc( $world->proc( '' ), $mode ); } ); -$steps->When( '/^I run `wp (.+)`$/', - function ( $world, $cmd ) { - $world->result = $world->proc( $world->replace_variables( $cmd ) )->run(); +$steps->When( '/^I (run|try) `wp (.+)`$/', + function ( $world, $mode, $cmd ) { + $cmd = $world->replace_variables( $cmd ); + $world->result = invoke_proc( $world->proc( $cmd ), $mode ); } ); -$steps->When( "/^I run `wp (.+)` from '([^\s]+)'$/", - function ( $world, $cmd, $subdir ) { - $world->result = $world->proc( $world->replace_variables( $cmd ) )->run( $subdir ); +$steps->When( "/^I (run|try) `wp (.+)` from '([^\s]+)'$/", + function ( $world, $mode, $cmd, $subdir ) { + $cmd = $world->replace_variables( $cmd ); + $world->result = invoke_proc( $world->proc( $cmd ), $mode, $subdir ); } ); -$steps->When( '/^I run the previous command again$/', - function ( $world ) { +$steps->When( '/^I (run|try) the previous command again$/', + function ( $world, $mode ) { if ( !isset( $world->result ) ) throw new \Exception( 'No previous command.' ); - $world->result = Process::create( $world->result->command, $world->result->cwd )->run(); + $proc = Process::create( $world->result->command, $world->result->cwd ); + $world->result = invoke_proc( $proc, $mode ); } ); @@ -142,19 +155,6 @@ function ( $world, $return_code ) { } ); -$steps->Then( '/^it should run without errors$/', - function ( $world ) { - if ( !empty( $world->result->STDERR ) ) { - $r = $world->result; - throw new \Exception( sprintf( "%s: %s\ncwd: %s", - $r->command, $r->STDERR, $r->cwd ) ); - } - - if ( 0 != $world->result->return_code ) - throw new \Exception( "Return code was $world->result->return_code" ); - } -); - $steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', function ( $world, $stream, $action, PyStringNode $expected ) { $output = $world->result->$stream; diff --git a/features/term.feature b/features/term.feature index 0c6af7e536..7a6442d453 100644 --- a/features/term.feature +++ b/features/term.feature @@ -4,22 +4,19 @@ Feature: Manage WordPress terms Given a WP install When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term' --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' - When I run the previous command again + When I try the previous command again Then STDERR should not be empty When I run `wp term list post_tag --format=json` - Then it should run without errors - And STDOUT should be JSON containing: + Then STDOUT should be JSON containing: """ [{"name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] """ When I run `wp term list post_tag --fields=name,slug --format=csv` - Then it should run without errors - And STDOUT should be CSV containing: + Then STDOUT should be CSV containing: """ name,slug "Test term",test @@ -29,16 +26,14 @@ Feature: Manage WordPress terms Given a WP install When I run `wp term create 'Test delete term' post_tag --slug=test-delete --description='This is a test term to be deleted' --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' And save STDOUT as {TERM_ID} When I run `wp term delete {TERM_ID} post_tag` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ Deleted post_tag {TERM_ID}. """ - When I run the previous command again + When I try the previous command again Then STDERR should not be empty diff --git a/features/theme.feature b/features/theme.feature index 4424b44042..2991173f8c 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -4,43 +4,38 @@ Feature: Manage WordPress themes Given a WP install When I run `wp theme install p2` - Then it should run without errors + Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 When I run `wp theme status p2` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ Theme p2 details: Name: P2 """ When I run `wp theme path p2` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ /themes/p2/style.css """ When I run `wp option get stylesheet` - Then it should run without errors - And save STDOUT as {PREVIOUS_THEME} + Then save STDOUT as {PREVIOUS_THEME} When I run `wp theme activate p2` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ Success: Switched to 'P2' theme. """ When I run `wp theme activate {PREVIOUS_THEME}` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty When I run `wp theme delete p2` - Then it should run without errors + Then STDOUT should not be empty When I run the previous command again Then the return code should be 1 @@ -50,36 +45,31 @@ Feature: Manage WordPress themes """ When I run `wp theme list` - Then it should run without errors - And STDOUT should not be empty + Then STDOUT should not be empty Scenario: Upgrading a theme Given a WP install And a P2 theme zip When I run `wp theme install {THEME_ZIP}` - Then it should run without errors + Then STDOUT should not be empty When I run `wp theme status` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ U = Update Available """ When I run `wp theme status p2` - Then it should run without errors - And STDOUT should contain: + Then STDOUT should contain: """ Version: 1.0.1 (Update available) """ When I run `wp theme update p2` - Then it should run without errors When I run `wp theme status p2` - Then it should run without errors - And STDOUT should not contain: + Then STDOUT should not contain: """ (Update available) """ diff --git a/features/user.feature b/features/user.feature index 627a684a23..5370006d9f 100644 --- a/features/user.feature +++ b/features/user.feature @@ -4,22 +4,19 @@ Feature: Manage WordPress users Given a WP install When I run `wp user create testuser testuser@example.com --porcelain` - Then it should run without errors - And STDOUT should match '%d' + Then STDOUT should match '%d' And save STDOUT as {USER_ID} - When I run the previous command again + When I try the previous command again Then the return code should be 1 When I run `wp user update {USER_ID} --displayname=Foo` - Then it should run without errors - And STDOUT should be: + Then STDOUT should be: """ Success: Updated user {USER_ID}. """ When I run `wp user delete {USER_ID}` - Then it should run without errors Scenario: Generating users Given a WP install @@ -28,12 +25,10 @@ Feature: Manage WordPress users When I run `wp user list --format=ids` And save STDOUT as {USER_IDS} And I run `wp user delete {USER_IDS}` - When I run `wp user list --format=ids` - Then it should run without errors - And STDOUT should be empty + And I run `wp user list --format=ids` + Then STDOUT should be empty When I run `wp user generate --count=10` - Then it should run without errors When I run `wp user list | wc -l | tr -d ' '` Then STDOUT should be: @@ -52,7 +47,7 @@ Feature: Manage WordPress users """ When I run `wp user import-csv users.csv` - Then it should run without errors + Then STDOUT should not be empty When I run `wp user list | wc -l | tr -d ' '` Then STDOUT should be: @@ -61,7 +56,6 @@ Feature: Manage WordPress users """ When I run `wp user list --format=json` - Then it should run without errors And STDOUT should be JSON containing: """ [{"user_login":"admin","display_name":"Existing User","user_email":"admin@domain.com","roles":"administrator"}] From 54753392104e6114a2f3d9babbfe34b0de00d480 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 16:28:41 +0300 Subject: [PATCH 1660/4858] add success message for `wp theme delete` --- php/commands/theme.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 441b2a3a29..3b0a5c6f7b 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -195,6 +195,8 @@ function delete( $args ) { if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); } + + WP_CLI::success( "$theme->name theme deleted." ); } /** @@ -204,7 +206,7 @@ function delete( $args ) { * @synopsis [--format=<format>] */ function _list( $_, $assoc_args ) { - parent::_list( $_, $assoc_args ); + parent::_list( $_, $assoc_args ); } protected function parse_name( $args ) { From 1611e1885f38ff7715f86fa664268b5acfa5e743 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 21:55:03 +0300 Subject: [PATCH 1661/4858] don't create a new test dir if one already exists this allows having nested WP installs --- features/bootstrap/FeatureContext.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 699f6c56b2..b48d8f7ff7 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -101,8 +101,10 @@ private function _replace_var( $matches ) { } public function create_empty_dir() { - $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); - mkdir( $this->install_dir ); + if ( !$this->install_dir ) { + $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + mkdir( $this->install_dir ); + } } public function get_path( $file ) { From 93afe56e211958f70e52712e3c09840b4f145814 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 22:14:42 +0300 Subject: [PATCH 1662/4858] behat: fix theme test --- features/theme.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/theme.feature b/features/theme.feature index 2991173f8c..3870379d15 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -37,7 +37,7 @@ Feature: Manage WordPress themes When I run `wp theme delete p2` Then STDOUT should not be empty - When I run the previous command again + When I try the previous command again Then the return code should be 1 And STDERR should contain: """ From 687f52b7dddf9dcab0c52f25100ace46bea99736 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 23:35:46 +0300 Subject: [PATCH 1663/4858] behat: misc fixes --- features/help.feature | 2 +- features/shell.feature | 2 +- features/theme.feature | 1 + features/user.feature | 4 +++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/features/help.feature b/features/help.feature index 81599f5899..f82b0c7cf9 100644 --- a/features/help.feature +++ b/features/help.feature @@ -41,7 +41,7 @@ Feature: Get help about WP-CLI commands And I run `wp plugin activate test-cli-help` When I run `wp help test-help` - And STDOUT should contain: + Then STDOUT should contain: """ usage: wp test-help """ diff --git a/features/shell.feature b/features/shell.feature index ad0f5c52c3..1e855ae7f2 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -35,7 +35,7 @@ Feature: WordPress REPL """ When I run `wp shell --basic < session` - And STDOUT should be: + Then STDOUT should be: """ bool(true) """ diff --git a/features/theme.feature b/features/theme.feature index 3870379d15..db3804ebb6 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -67,6 +67,7 @@ Feature: Manage WordPress themes """ When I run `wp theme update p2` + Then STDOUT should not be empty When I run `wp theme status p2` Then STDOUT should not contain: diff --git a/features/user.feature b/features/user.feature index 5370006d9f..1e8131e583 100644 --- a/features/user.feature +++ b/features/user.feature @@ -17,6 +17,7 @@ Feature: Manage WordPress users """ When I run `wp user delete {USER_ID}` + Then STDOUT should not be empty Scenario: Generating users Given a WP install @@ -29,6 +30,7 @@ Feature: Manage WordPress users Then STDOUT should be empty When I run `wp user generate --count=10` + Then STDOUT should not be empty When I run `wp user list | wc -l | tr -d ' '` Then STDOUT should be: @@ -56,7 +58,7 @@ Feature: Manage WordPress users """ When I run `wp user list --format=json` - And STDOUT should be JSON containing: + Then STDOUT should be JSON containing: """ [{"user_login":"admin","display_name":"Existing User","user_email":"admin@domain.com","roles":"administrator"}] """ From 7253f7fcb3e7540f754125e225e5129aacabde91 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 23:44:07 +0300 Subject: [PATCH 1664/4858] behat: move theme dir acquiring to the 'Given' block --- features/scaffold.feature | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index c12a3cfee7..6b51ae80a4 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -3,12 +3,12 @@ Feature: Wordpress code scaffolding @theme Scenario: Scaffold a child theme Given a WP install + And I run `wp theme path` + And save STDOUT as {THEME_DIR} - When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --activate` - - When I run `wp theme path` - Then save STDOUT as {THEME_PATH} - And the {THEME_PATH}/zombieland/style.css file should exist + When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --activate` + Then STDOUT should not be empty + And the {THEME_DIR}/zombieland/style.css file should exist # Adding --activate to the test crashes the tests @plugin @@ -17,14 +17,14 @@ Feature: Wordpress code scaffolding When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland"` Then STDOUT should not be empty - + When I run `wp plugin path` And save STDOUT as {PLUGIN_PATH} Then the {PLUGIN_PATH}/zombieland/zombieland.php file should exist When I run `wp plugin activate zombieland` Then STDOUT should not be empty - + @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install From 00e0bd2034fdce799899509a6dd83097fd38c5ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 23:46:09 +0300 Subject: [PATCH 1665/4858] behat: more misc fixes --- features/core.feature | 1 + features/plugin.feature | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 7de94acec1..4accc60b39 100644 --- a/features/core.feature +++ b/features/core.feature @@ -84,3 +84,4 @@ Feature: Manage WordPress installation And a custom wp-content directory When I run `wp plugin status hello` + Then STDOUT should not be empty diff --git a/features/plugin.feature b/features/plugin.feature index ad9a885206..b1093e2f89 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -21,4 +21,4 @@ Feature: Manage WordPress plugins """ When I run `wp plugin list --format=json` - And STDOUT should not be empty + Then STDOUT should not be empty From 147d5b37b23ded49020694ffc5004368166e7291 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 May 2013 23:59:55 +0300 Subject: [PATCH 1666/4858] behat: move plugin dir acquiring to the 'Given' block --- features/scaffold.feature | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 6b51ae80a4..e2cc2b4e88 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -14,13 +14,12 @@ Feature: Wordpress code scaffolding @plugin Scenario: Scaffold a plugin Given a WP install + And I run `wp plugin path` + And save STDOUT as {PLUGIN_DIR} When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland"` Then STDOUT should not be empty - - When I run `wp plugin path` - And save STDOUT as {PLUGIN_PATH} - Then the {PLUGIN_PATH}/zombieland/zombieland.php file should exist + And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist When I run `wp plugin activate zombieland` Then STDOUT should not be empty From 4e436222a11efc1b492fa0c56791aa55e687f4c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 15 May 2013 00:11:50 +0300 Subject: [PATCH 1667/4858] try the --activate flag for `wp scaffold plugin` one more time --- features/scaffold.feature | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index e2cc2b4e88..c638f6c149 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -10,14 +10,13 @@ Feature: Wordpress code scaffolding Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist - # Adding --activate to the test crashes the tests @plugin Scenario: Scaffold a plugin Given a WP install And I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} - When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland"` + When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland" --activate` Then STDOUT should not be empty And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist From e74d250da7412669a2c4dcf6b9837ab3229cbdd9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 16:38:13 +0300 Subject: [PATCH 1668/4858] travis: make Behat output less verbose --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7225c6eaab..622e25b65c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_script: - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot -script: vendor/bin/phpunit && vendor/bin/behat +script: vendor/bin/phpunit && vendor/bin/behat --format progress notifications: email: From 3c10db3147990c4ea9e81446693481799040a7ef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 16:31:23 +0300 Subject: [PATCH 1669/4858] test wp core download --locale --- features/core.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/core.feature b/features/core.feature index 4accc60b39..b9497e37e0 100644 --- a/features/core.feature +++ b/features/core.feature @@ -1,5 +1,6 @@ Feature: Manage WordPress installation + @download Scenario: Empty dir Given an empty directory @@ -9,6 +10,12 @@ Feature: Manage WordPress installation When I run `wp core download --quiet` Then the wp-settings.php file should exist + @download + Scenario: Localized install + Given an empty directory + When I run `wp core download --locale=de_DE` + Then the wp-settings.php file should exist + Scenario: No wp-config.php Given an empty directory And WP files From 3fbef8ba71eb62a8e37b8b5d874e1cc351c57c6f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 17:13:40 +0300 Subject: [PATCH 1670/4858] core download: update to /version-check/1.6/ --- php/commands/core.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 3c3724abb1..24ce49d446 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -24,10 +24,10 @@ public function download( $args, $assoc_args ) { } if ( isset( $assoc_args['locale'] ) ) { - exec( 'curl -s ' . escapeshellarg( 'https://api.wordpress.org/core/version-check/1.5/?locale=' . $assoc_args['locale'] ), $lines, $r ); - if ($r) exit($r); - $download_url = str_replace( '.zip', '.tar.gz', $lines[2] ); - WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $lines[3], $lines[4] ) ); + $offer = $this->get_download_offer( $assoc_args['locale'] ); + $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); + WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', + $offer['current'], $offer['locale'] ) ); } elseif ( isset( $assoc_args['version'] ) ) { $download_url = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); @@ -44,6 +44,14 @@ public function download( $args, $assoc_args ) { WP_CLI::success( 'WordPress downloaded.' ); } + private function get_download_offer( $locale ) { + $out = exec( 'curl -s ' . escapeshellarg( 'https://api.wordpress.org/core/version-check/1.6/?locale=' . $locale ), $lines, $r ); + if ($r) exit($r); + + $out = unserialize( $out ); + return $out['offers'][0]; + } + /** * Set up a wp-config.php file. * From 670d641fd0cbdf92f97b13d7ac62abafb377912b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 18:28:56 +0300 Subject: [PATCH 1671/4858] post get: default to table format. see #399 --- features/post.feature | 6 ------ php/commands/post.php | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/features/post.feature b/features/post.feature index c9e93d630e..499224754a 100644 --- a/features/post.feature +++ b/features/post.feature @@ -32,12 +32,6 @@ Feature: Manage WordPress posts Then STDOUT should match '%d' And save STDOUT as {POST_ID} - When I run `wp post get {POST_ID}` - Then STDOUT should be: - """ - Test content. - """ - When I run `wp post get --format=content {POST_ID}` Then STDOUT should be: """ diff --git a/php/commands/post.php b/php/commands/post.php index 7952a8b734..b2b5199a2a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -93,7 +93,7 @@ protected function _edit( $content, $title ) { */ public function get( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( - 'format' => 'content' + 'format' => 'table' ) ); $format = $assoc_args['format']; From e79a132eed734a4d63adbd807ed910c291a8183b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 18:35:43 +0300 Subject: [PATCH 1672/4858] transparently convert from --json to --format=json --- man-src/option.txt | 4 ++-- man-src/post-meta.txt | 2 +- man-src/rewrite-dump.txt | 2 +- man-src/user-meta.txt | 2 +- php/WP_CLI/Runner.php | 21 ++++++++++++++++----- php/class-wp-cli.php | 4 ++-- php/commands/post.php | 5 ++--- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/man-src/option.txt b/man-src/option.txt index 423e816694..99c8aab055 100644 --- a/man-src/option.txt +++ b/man-src/option.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `--json`: +* `--format=json`: Encode/decode values as JSON. @@ -10,6 +10,6 @@ wp option add my_option foobar - wp option update my_option '{"foo": "bar"}' --json + wp option update my_option '{"foo": "bar"}' --format=json wp option delete my_option diff --git a/man-src/post-meta.txt b/man-src/post-meta.txt index 974a2bd7b6..eeadc606ff 100644 --- a/man-src/post-meta.txt +++ b/man-src/post-meta.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `--json`: +* `--format=json`: Encode/decode values as JSON. diff --git a/man-src/rewrite-dump.txt b/man-src/rewrite-dump.txt index 26498dbcaf..f15473d02c 100644 --- a/man-src/rewrite-dump.txt +++ b/man-src/rewrite-dump.txt @@ -1,5 +1,5 @@ ## OPTIONS -* `--json`: +* `--format=json`: Output rules in JSON format. diff --git a/man-src/user-meta.txt b/man-src/user-meta.txt index 9db91bbf1a..94d507cc5b 100644 --- a/man-src/user-meta.txt +++ b/man-src/user-meta.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `--json`: +* `--format=json`: Encode/decode values as JSON. diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 981716dc14..4c5cabe3ba 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -210,11 +210,8 @@ private static function show_help_early( $args ) { return false; } - public function before_wp_load() { - $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); - - list( $this->arguments, $this->assoc_args ) = $r; - + // Transparently convert old syntaxes + private function back_compat_conversions() { // foo --help -> help foo if ( isset( $this->assoc_args['help'] ) ) { array_unshift( $this->arguments, 'help' ); @@ -239,6 +236,20 @@ public function before_wp_load() { unset( $this->assoc_args['ids'] ); } + // --json -> --format=json + if ( isset( $this->assoc_args['json'] ) ) { + $this->assoc_args['format'] = 'json'; + unset( $this->assoc_args['ids'] ); + } + } + + public function before_wp_load() { + $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); + + list( $this->arguments, $this->assoc_args ) = $r; + + $this->back_compat_conversions(); + $config_spec = Utils\get_config_spec(); // Set the path default to the ABSPATH diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e3855a7ce8..320cb5031f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -169,7 +169,7 @@ static function confirm( $question, $assoc_args ) { * @param array $assoc_args */ static function read_value( $value, $assoc_args = array() ) { - if ( isset( $assoc_args['json'] ) ) { + if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { $value = json_decode( $value, true ); } @@ -183,7 +183,7 @@ static function read_value( $value, $assoc_args = array() ) { * @param array $assoc_args */ static function print_value( $value, $assoc_args = array() ) { - if ( isset( $assoc_args['json'] ) ) { + if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { $value = json_encode( $value ); } elseif ( is_array( $value ) || is_object( $value ) ) { $value = var_export( $value ); diff --git a/php/commands/post.php b/php/commands/post.php index b2b5199a2a..b895a78d9c 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -104,7 +104,7 @@ public function get( $args, $assoc_args ) { switch ( $assoc_args['format'] ) { case 'content': - echo($post->post_content); + WP_CLI::print_value( $post->post_content ); break; case 'table': @@ -127,8 +127,7 @@ public function get( $args, $assoc_args ) { break; case 'json': - echo( json_encode( $post ) ); - echo( "\n" ); + WP_CLI::print_value( $post, $assoc_args ); break; default: From 51186ddd9c75347b452e2be176866bbbaf80263d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 19:04:42 +0300 Subject: [PATCH 1673/4858] option: add tests --- features/option.feature | 28 ++++++++++++++++++++++++++++ php/commands/option.php | 6 +++--- 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 features/option.feature diff --git a/features/option.feature b/features/option.feature new file mode 100644 index 0000000000..0ab33e8158 --- /dev/null +++ b/features/option.feature @@ -0,0 +1,28 @@ +Feature: Manage WordPress options + + Scenario: Option CRUD + Given a WP install + + When I run `wp option add foo 'bar'` + Then STDOUT should be empty + + When I run `wp option get foo` + Then STDOUT should be: + """ + bar + """ + + When I run `wp option set foo '[ 1, 2 ]' --format=json` + Then STDOUT should be empty + + When I run `wp option get foo --format=json` + Then STDOUT should be: + """ + [1,2] + """ + + When I run `wp option delete foo` + Then STDOUT should be empty + + When I try `wp option get foo` + Then the return code should be 1 diff --git a/php/commands/option.php b/php/commands/option.php index 525a89a36e..361a1f73ba 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -10,7 +10,7 @@ class Option_Command extends WP_CLI_Command { /** * Get an option. * - * @synopsis <key> [--json] + * @synopsis <key> [--format=<format>] */ public function get( $args, $assoc_args ) { list( $key ) = $args; @@ -26,7 +26,7 @@ public function get( $args, $assoc_args ) { /** * Add an option. * - * @synopsis <key> <value> [--json] + * @synopsis <key> [--format=<format>] */ public function add( $args, $assoc_args ) { $key = $args[0]; @@ -42,7 +42,7 @@ public function add( $args, $assoc_args ) { * Update an option. * * @alias set - * @synopsis <key> <value> [--json] + * @synopsis <key> [--format=<format>] */ public function update( $args, $assoc_args ) { $key = $args[0]; From 49997f835585e04d44282961bb273cd9cfed6539 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 May 2013 19:16:57 +0300 Subject: [PATCH 1674/4858] post-meta: add tests --- features/post-meta.feature | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 features/post-meta.feature diff --git a/features/post-meta.feature b/features/post-meta.feature new file mode 100644 index 0000000000..0b7ac02d59 --- /dev/null +++ b/features/post-meta.feature @@ -0,0 +1,28 @@ +Feature: Manage post custom fields + + Scenario: Postmeta CRUD + Given a WP install + + When I run `wp post-meta add 1 foo 'bar'` + Then STDOUT should be empty + + When I run `wp post-meta get 1 foo` + Then STDOUT should be: + """ + bar + """ + + When I run `wp post-meta set 1 foo '[ 1, 2 ]' --format=json` + Then STDOUT should be empty + + When I run `wp post-meta get 1 foo --format=json` + Then STDOUT should be: + """ + [1,2] + """ + + When I run `wp post-meta delete 1 foo` + Then STDOUT should be empty + + When I try `wp post-meta get 1 foo` + Then the return code should be 1 From 60822fedc670e70337f33825009a90d0fc418250 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 19:40:31 +0300 Subject: [PATCH 1675/4858] add --format parameter to meta get and update --- php/WP_CLI/CommandWithMeta.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 3ec480e14f..6695d1e51c 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -14,7 +14,7 @@ abstract class CommandWithMeta extends \WP_CLI_Command { /** * Get meta field value. * - * @synopsis <id> <key> [--json] + * @synopsis <id> <key> [--format=<format>] */ public function get( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; @@ -47,10 +47,12 @@ public function delete( $args, $assoc_args ) { /** * Add a meta field. * - * @synopsis <id> <key> <value> + * @synopsis <id> <key> <value> [--format=<format>] */ public function add( $args, $assoc_args ) { - list( $object_id, $meta_key, $meta_value ) = $args; + list( $object_id, $meta_key ) = $args; + + $meta_value = \WP_CLI::read_value( $args[2], $assoc_args ); $success = \add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); @@ -65,10 +67,12 @@ public function add( $args, $assoc_args ) { * Update a meta field. * * @alias set - * @synopsis <id> <key> <value> + * @synopsis <id> <key> <value> [--format=<format>] */ public function update( $args, $assoc_args ) { - list( $object_id, $meta_key, $meta_value ) = $args; + list( $object_id, $meta_key ) = $args; + + $meta_value = \WP_CLI::read_value( $args[2], $assoc_args ); $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); From dea3de8c207b82f831e2a97724323e0f15122ecb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 19:52:23 +0300 Subject: [PATCH 1676/4858] save parent class in Subcommand ReflectionMethod only stores the name of the original class, which might be abstract. --- php/WP_CLI/Dispatcher/Subcommand.php | 7 ++++--- php/class-wp-cli.php | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 8c6191419d..91dfcbf548 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -4,9 +4,10 @@ class Subcommand implements Command, AtomicCommand, Documentable { - private $parent, $name, $method, $docparser; + private $parent, $name, $class, $method, $docparser; - function __construct( CommandContainer $parent, \ReflectionMethod $method, $name = false ) { + function __construct( CommandContainer $parent, $class, \ReflectionMethod $method, $name = false ) { + $this->class = $class; $docparser = new \WP_CLI\DocParser( $method ); if ( !$name ) @@ -99,7 +100,7 @@ private function validate_args( $args, &$assoc_args ) { function invoke( $args, $assoc_args ) { $this->validate_args( $args, $assoc_args ); - $instance = new $this->method->class; + $instance = new $this->class; call_user_func( array( $instance, $this->method->name ), $args, $assoc_args ); } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 320cb5031f..a711d4d0a8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -40,7 +40,7 @@ static function add_command( $name, $class ) { $reflection = new \ReflectionClass( $class ); if ( $reflection->hasMethod( '__invoke' ) ) { - $command = new Dispatcher\Subcommand( self::$root, + $command = new Dispatcher\Subcommand( self::$root, $reflection->name, $reflection->getMethod( '__invoke' ), $name ); } else { $command = self::create_composite_command( $name, $reflection ); @@ -58,7 +58,7 @@ private static function create_composite_command( $name, $reflection ) { if ( !self::_is_good_method( $method ) ) continue; - $subcommand = new Dispatcher\Subcommand( $container, $method ); + $subcommand = new Dispatcher\Subcommand( $container, $reflection->name, $method ); $subcommand_name = $subcommand->get_name(); $full_name = self::get_full_name( $subcommand ); From c92524ffc5300ddc92b7cea9aca2ca933be743bf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 19:57:52 +0300 Subject: [PATCH 1677/4858] unlike `wp option`, `wp post-meta` outputs confirmation messages --- features/post-meta.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/post-meta.feature b/features/post-meta.feature index 0b7ac02d59..664417b4f7 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -4,7 +4,7 @@ Feature: Manage post custom fields Given a WP install When I run `wp post-meta add 1 foo 'bar'` - Then STDOUT should be empty + Then STDOUT should not be empty When I run `wp post-meta get 1 foo` Then STDOUT should be: @@ -13,7 +13,7 @@ Feature: Manage post custom fields """ When I run `wp post-meta set 1 foo '[ 1, 2 ]' --format=json` - Then STDOUT should be empty + Then STDOUT should not be empty When I run `wp post-meta get 1 foo --format=json` Then STDOUT should be: @@ -22,7 +22,7 @@ Feature: Manage post custom fields """ When I run `wp post-meta delete 1 foo` - Then STDOUT should be empty + Then STDOUT should not be empty When I try `wp post-meta get 1 foo` Then the return code should be 1 From 8e176d75358f9f2907390ae136d49708adfacab8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 21:06:55 +0300 Subject: [PATCH 1678/4858] behat: work around bug in WP 3.4.2 related to serializing custom fields --- features/post-meta.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/post-meta.feature b/features/post-meta.feature index 664417b4f7..5c3ecd1167 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -12,13 +12,13 @@ Feature: Manage post custom fields bar """ - When I run `wp post-meta set 1 foo '[ 1, 2 ]' --format=json` + When I run `wp post-meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty When I run `wp post-meta get 1 foo --format=json` Then STDOUT should be: """ - [1,2] + ["1","2"] """ When I run `wp post-meta delete 1 foo` From 7046dcc76a1135eb79e01cf1b430362337a993c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 21:07:11 +0300 Subject: [PATCH 1679/4858] behat: formatting fixes --- features/steps/basic_steps.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index c4d373aa35..d5432db90f 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -215,21 +215,18 @@ function ( $world, PyStringNode $expected ) { $steps->Then( '/^STDOUT should be JSON containing:$/', function ( $world, PyStringNode $expected ) { - $output = $world->result->STDOUT; - - $expected = $world->replace_variables( (string) $expected ); + $output = $world->result->STDOUT; + $expected = $world->replace_variables( (string) $expected ); - if ( !checkThatJsonStringContainsJsonString( $output, - $expected ) ) { + if ( !checkThatJsonStringContainsJsonString( $output, $expected ) ) { throw new \Exception( $output ); } }); $steps->Then( '/^STDOUT should be CSV containing:$/', function( $world, PyStringNode $expected ) { - - $output = $world->result->STDOUT; - $expected = $world->replace_variables( (string) $expected ); + $output = $world->result->STDOUT; + $expected = $world->replace_variables( (string) $expected ); if ( ! checkThatCsvStringContainsCsvString( $output, $expected ) ) throw new \Exception( $output ); From b8f624737690f0ea97b25867c10903a49747b846 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 21:08:39 +0300 Subject: [PATCH 1680/4858] user-meta: add tests --- features/user-meta.feature | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 features/user-meta.feature diff --git a/features/user-meta.feature b/features/user-meta.feature new file mode 100644 index 0000000000..9452371538 --- /dev/null +++ b/features/user-meta.feature @@ -0,0 +1,28 @@ +Feature: Manage user custom fields + + Scenario: Usermeta CRUD + Given a WP install + + When I run `wp user-meta add 1 foo 'bar'` + Then STDOUT should not be empty + + When I run `wp user-meta get 1 foo` + Then STDOUT should be: + """ + bar + """ + + When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` + Then STDOUT should not be empty + + When I run `wp user-meta get 1 foo --format=json` + Then STDOUT should be: + """ + ["1","2"] + """ + + When I run `wp user-meta delete 1 foo` + Then STDOUT should not be empty + + When I try `wp user-meta get 1 foo` + Then the return code should be 1 From a38cf376dc4fa1912e3146d27dc91903dd143f81 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 21:21:09 +0300 Subject: [PATCH 1681/4858] re-generate man pages [ci skip] --- man/option.1 | 10 +++++----- man/post-meta.1 | 8 ++++---- man/rewrite-dump.1 | 2 +- man/scaffold-post-type.1 | 2 +- man/scaffold-taxonomy.1 | 2 +- man/user-meta.1 | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/man/option.1 b/man/option.1 index 531d1c2c80..bfb8105b8e 100644 --- a/man/option.1 +++ b/man/option.1 @@ -7,13 +7,13 @@ \fBwp\-option\fR \- Manage WordPress options\. . .SH "SYNOPSIS" -wp option get \fIkey\fR [\-\-json] +wp option get \fIkey\fR [\-\-format=\fIformat\fR] . .P -wp option add \fIkey\fR \fIvalue\fR [\-\-json] +wp option add \fIkey\fR [\-\-format=\fIformat\fR] . .P -wp option update \fIkey\fR \fIvalue\fR [\-\-json] +wp option update \fIkey\fR [\-\-format=\fIformat\fR] . .P wp option delete \fIkey\fR @@ -48,7 +48,7 @@ Update an option\. . .TP -\fB\-\-json\fR: +\fB\-\-format=json\fR: . .IP Encode/decode values as JSON\. @@ -61,7 +61,7 @@ wp option get siteurl wp option add my_option foobar -wp option update my_option \'{"foo": "bar"}\' \-\-json +wp option update my_option \'{"foo": "bar"}\' \-\-format=json wp option delete my_option . diff --git a/man/post-meta.1 b/man/post-meta.1 index 3a2cd20404..b806b334d5 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -7,16 +7,16 @@ \fBwp\-post\-meta\fR \- Manage post custom fields\. . .SH "SYNOPSIS" -wp post\-meta get \fIid\fR \fIkey\fR [\-\-json] +wp post\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] . .P wp post\-meta delete \fIid\fR \fIkey\fR . .P -wp post\-meta add \fIid\fR \fIkey\fR \fIvalue\fR +wp post\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .P -wp post\-meta update \fIid\fR \fIkey\fR \fIvalue\fR +wp post\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .SH "SUBCOMMANDS" . @@ -48,7 +48,7 @@ Update a meta field\. . .TP -\fB\-\-json\fR: +\fB\-\-format=json\fR: . .IP Encode/decode values as JSON\. diff --git a/man/rewrite-dump.1 b/man/rewrite-dump.1 index 932d8691a1..a5e9c33d3a 100644 --- a/man/rewrite-dump.1 +++ b/man/rewrite-dump.1 @@ -12,7 +12,7 @@ wp rewrite dump [\-\-json] .SH "OPTIONS" . .TP -\fB\-\-json\fR: +\fB\-\-format=json\fR: . .IP Output rules in JSON format\. diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 index 1fc921d042..5d07b487b6 100644 --- a/man/scaffold-post-type.1 +++ b/man/scaffold-post-type.1 @@ -7,7 +7,7 @@ \fBwp\-scaffold\-post\-type\fR \- Generate PHP code for registering a custom post type\. . .SH "SYNOPSIS" -wp scaffold post\-type \fIslug\fR [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-label=\fIlabel\fR] [\-\-raw] +wp scaffold post\-type \fIslug\fR [\-\-label=\fIlabel\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] . .SH "OPTIONS" . diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index 10f5b5e64c..a61470a2d7 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -7,7 +7,7 @@ \fBwp\-scaffold\-taxonomy\fR \- Generate PHP code for registering a custom taxonomy\. . .SH "SYNOPSIS" -wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-label=\fIlabel\fR] [\-\-raw] +wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-label=\fIlabel\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] . .SH "OPTIONS" . diff --git a/man/user-meta.1 b/man/user-meta.1 index b88a027f4f..883b2923b5 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -7,16 +7,16 @@ \fBwp\-user\-meta\fR \- Manage user custom fields\. . .SH "SYNOPSIS" -wp user\-meta get \fIid\fR \fIkey\fR [\-\-json] +wp user\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] . .P wp user\-meta delete \fIid\fR \fIkey\fR . .P -wp user\-meta add \fIid\fR \fIkey\fR \fIvalue\fR +wp user\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .P -wp user\-meta update \fIid\fR \fIkey\fR \fIvalue\fR +wp user\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .SH "SUBCOMMANDS" . @@ -48,7 +48,7 @@ Update a meta field\. . .TP -\fB\-\-json\fR: +\fB\-\-format=json\fR: . .IP Encode/decode values as JSON\. From 6b3b6ca8bbe9961915f6b5e56405fdab5d864d9e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 21:23:25 +0300 Subject: [PATCH 1682/4858] unset 'json' key, not 'ids' --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4c5cabe3ba..2de3bb6f6c 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -239,7 +239,7 @@ private function back_compat_conversions() { // --json -> --format=json if ( isset( $this->assoc_args['json'] ) ) { $this->assoc_args['format'] = 'json'; - unset( $this->assoc_args['ids'] ); + unset( $this->assoc_args['json'] ); } } From 8448a661073f8091888b99a4e429bdfdd2960f8e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 22:06:20 +0300 Subject: [PATCH 1683/4858] behat: remove temp files for scenarios that don't have failing steps --- features/bootstrap/FeatureContext.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index b48d8f7ff7..76d2343dbb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -68,6 +68,18 @@ public static function prepare( SuiteEvent $event ) { ); } + /** + * @AfterScenario + */ + public function afterScenario( $event ) { + if ( !$this->install_dir ) + return; + + if ( $event->getResult() < 4 ) { + Process::create( Utils\esc_cmd( 'rm -r %s', $this->install_dir ) )->run(); + } + } + /** * Initializes context. * Every scenario gets it's own context object. From 097c6383095a253122dd696d0cfe9532ec3b1d71 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 22:22:10 +0300 Subject: [PATCH 1684/4858] rename InternalAssoc to InternalFlags 'flags' is more descriptive than 'assoc' --- .../{InternalAssoc.php => InternalFlags.php} | 2 +- php/WP_CLI/Runner.php | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) rename php/WP_CLI/{InternalAssoc.php => InternalFlags.php} (98%) diff --git a/php/WP_CLI/InternalAssoc.php b/php/WP_CLI/InternalFlags.php similarity index 98% rename from php/WP_CLI/InternalAssoc.php rename to php/WP_CLI/InternalFlags.php index 661d282f45..87cabf3725 100644 --- a/php/WP_CLI/InternalAssoc.php +++ b/php/WP_CLI/InternalFlags.php @@ -6,7 +6,7 @@ /** * Class that handles special assoc parameters */ -class InternalAssoc { +class InternalFlags { static function version() { WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 2de3bb6f6c..ff428c38df 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -273,25 +273,25 @@ public function before_wp_load() { // Handle --version parameter if ( isset( $this->assoc_args['version'] ) && empty( $this->arguments ) ) { - \WP_CLI\InternalAssoc::version(); + \WP_CLI\InternalFlags::version(); exit; } // Handle --info parameter if ( isset( $this->assoc_args['info'] ) && empty( $this->arguments ) ) { - \WP_CLI\InternalAssoc::info(); + \WP_CLI\InternalFlags::info(); exit; } // Handle --param-dump parameter if ( isset( $this->assoc_args['param-dump'] ) ) { - \WP_CLI\InternalAssoc::param_dump(); + \WP_CLI\InternalFlags::param_dump(); exit; } // Handle --cmd-dump parameter if ( isset( $this->assoc_args['cmd-dump'] ) ) { - \WP_CLI\InternalAssoc::cmd_dump(); + \WP_CLI\InternalFlags::cmd_dump(); exit; } @@ -304,7 +304,7 @@ public function before_wp_load() { } } - // Handle --path + // Handle --path parameter self::set_wp_root( $this->config ); // Handle --url and --blog parameters @@ -358,13 +358,15 @@ public function after_wp_load() { if ( isset( $this->config['require'] ) ) require $this->config['require']; + // Handle --man parameter if ( isset( $this->assoc_args['man'] ) ) { - \WP_CLI\InternalAssoc::man( $this->arguments ); + \WP_CLI\InternalFlags::man( $this->arguments ); exit; } + // Handle --completions parameter if ( isset( $this->assoc_args['completions'] ) ) { - \WP_CLI\InternalAssoc::completions(); + \WP_CLI\InternalFlags::completions(); exit; } From f266205b63a4378fedc0af65a8a54dffd4987486 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 22:29:07 +0300 Subject: [PATCH 1685/4858] move --man handling to _run_command() so that `wp db --man` works --- php/WP_CLI/Runner.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ff428c38df..3ae1b5ed3b 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -163,6 +163,12 @@ private function cmd_starts_with( $prefix ) { } private function _run_command() { + // Handle --man parameter + if ( isset( $this->assoc_args['man'] ) ) { + \WP_CLI\InternalFlags::man( $this->arguments ); + exit; + } + WP_CLI::run_command( $this->arguments, $this->assoc_args ); } @@ -358,12 +364,6 @@ public function after_wp_load() { if ( isset( $this->config['require'] ) ) require $this->config['require']; - // Handle --man parameter - if ( isset( $this->assoc_args['man'] ) ) { - \WP_CLI\InternalFlags::man( $this->arguments ); - exit; - } - // Handle --completions parameter if ( isset( $this->assoc_args['completions'] ) ) { \WP_CLI\InternalFlags::completions(); From a07b8e17cfc2e89f55f1d06d5e93b47228155754 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 22:51:30 +0300 Subject: [PATCH 1686/4858] reduce code duplication by merging show_help_early() into Help_Command --- php/WP_CLI/Runner.php | 18 +----------------- php/commands/help.php | 14 ++++++++++---- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3ae1b5ed3b..106fc6479a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -202,20 +202,6 @@ public function get_wp_config_code() { return preg_replace( '|^\s*\<\?php\s*|', '', implode( "\n", $lines_to_run ) ); } - private static function show_help_early( $args ) { - if ( \WP_CLI\Man\maybe_show_manpage( $args ) ) - return true; - - $command = WP_CLI\Utils\find_subcommand( $args ); - - if ( $command ) { - $command->show_usage(); - return true; - } - - return false; - } - // Transparently convert old syntaxes private function back_compat_conversions() { // foo --help -> help foo @@ -305,9 +291,7 @@ public function before_wp_load() { // First try at showing man page if ( $this->cmd_starts_with( array( 'help' ) ) ) { - if ( self::show_help_early( array_slice( $this->arguments, 1 ) ) ) { - exit; - } + $this->_run_command(); } // Handle --path parameter diff --git a/php/commands/help.php b/php/commands/help.php index 55050bb99f..0afaea7423 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -10,15 +10,21 @@ class Help_Command extends WP_CLI_Command { * @synopsis [<command>] */ function __invoke( $args ) { - \WP_CLI\Man\maybe_show_manpage( $args ); + if ( \WP_CLI\Man\maybe_show_manpage( $args ) ) { + exit; + } $command = WP_CLI\Utils\find_subcommand( $args ); - if ( !$command ) { - \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); + if ( $command ) { + $command->show_usage(); + exit; } - $command->show_usage(); + // WordPress is already loaded, so there's no chance we'll find the command + if ( function_exists( 'add_filter' ) ) { + \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); + } } } From 13f90966a7c2e3ca7c533267fe31286cf5852c7b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 22:59:07 +0300 Subject: [PATCH 1687/4858] create empty help.txt file, so that `wp help --man` works --- man-src/help.txt | 0 man/help.1 | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 man-src/help.txt diff --git a/man-src/help.txt b/man-src/help.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/man/help.1 b/man/help.1 index ec0050cb1c..707ebcc97e 100644 --- a/man/help.1 +++ b/man/help.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-HELP" "1" "October 2012" "" "WP-CLI" +.TH "WP\-HELP" "1" "" "WP-CLI" . .SH "NAME" \fBwp\-help\fR \- Get help on a certain topic\. . .SH "SYNOPSIS" -\fBwp help\fR [\fIcommand\fR] +wp help [\fIcommand\fR] From 6ce07e6c875a438644b376a6fa7f21c5102d222d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 23:03:13 +0300 Subject: [PATCH 1688/4858] create empty home.txt file, so that `wp home --man` works --- man-src/home.txt | 0 man/home.1 | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 man-src/home.txt diff --git a/man-src/home.txt b/man-src/home.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/man/home.1 b/man/home.1 index 235d563cb5..184b182908 100644 --- a/man/home.1 +++ b/man/home.1 @@ -1,10 +1,10 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-HOME" "1" "October 2012" "" "WP-CLI" +.TH "WP\-HOME" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-home\fR \- Opens the wp\-cli homepage in your browser\. +\fBwp\-home\fR \- Open the wp\-cli homepage in your browser\. . .SH "SYNOPSIS" -\fBwp home\fR +wp home From 53ecf149fc7cd136b980f820e293dd006979b810 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 23:04:46 +0300 Subject: [PATCH 1689/4858] remove old db man pages --- man/db-cli.1 | 10 ---------- man/db-connect.1 | 10 ---------- man/db-create.1 | 10 ---------- man/db-drop.1 | 19 ------------------- man/db-export.1 | 19 ------------------- man/db-import.1 | 19 ------------------- man/db-optimize.1 | 10 ---------- man/db-query.1 | 19 ------------------- man/db-repair.1 | 10 ---------- man/db-reset.1 | 19 ------------------- 10 files changed, 145 deletions(-) delete mode 100644 man/db-cli.1 delete mode 100644 man/db-connect.1 delete mode 100644 man/db-create.1 delete mode 100644 man/db-drop.1 delete mode 100644 man/db-export.1 delete mode 100644 man/db-import.1 delete mode 100644 man/db-optimize.1 delete mode 100644 man/db-query.1 delete mode 100644 man/db-repair.1 delete mode 100644 man/db-reset.1 diff --git a/man/db-cli.1 b/man/db-cli.1 deleted file mode 100644 index f5d2b88da9..0000000000 --- a/man/db-cli.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-CLI" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-cli\fR \- Open a mysql console using the WordPress credentials\. -. -.SH "SYNOPSIS" -\fBwp db cli\fR diff --git a/man/db-connect.1 b/man/db-connect.1 deleted file mode 100644 index 9fea5148e5..0000000000 --- a/man/db-connect.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-CONNECT" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-connect\fR \- Print a string for connecting to the DB\. -. -.SH "SYNOPSIS" -\fBwp db connect\fR diff --git a/man/db-create.1 b/man/db-create.1 deleted file mode 100644 index 4c94095c8f..0000000000 --- a/man/db-create.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-CREATE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-create\fR \- Create the database, as specified in wp\-config\.php -. -.SH "SYNOPSIS" -\fBwp db create\fR diff --git a/man/db-drop.1 b/man/db-drop.1 deleted file mode 100644 index 2f28197ff4..0000000000 --- a/man/db-drop.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-DROP" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-drop\fR \- Delete the database\. -. -.SH "SYNOPSIS" -wp db drop [\-\-yes] -. -.SH "OPTIONS" -. -.TP -\fB\-\-yes\fR: -. -.IP -Answer yes to the confirmation message\. - diff --git a/man/db-export.1 b/man/db-export.1 deleted file mode 100644 index 2f0a811fca..0000000000 --- a/man/db-export.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-EXPORT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-export\fR \- Exports the database using mysqldump\. -. -.SH "SYNOPSIS" -wp db export [\fIfile\fR] -. -.SH "OPTIONS" -. -.TP -\fB<file>\fR: -. -.IP -The name of the export file\. If omitted, it will be \'{dbname}\.sql\' - diff --git a/man/db-import.1 b/man/db-import.1 deleted file mode 100644 index eaa90697ee..0000000000 --- a/man/db-import.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-IMPORT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-import\fR \- Import database from a file\. -. -.SH "SYNOPSIS" -wp db import [\fIfile\fR] -. -.SH "OPTIONS" -. -.TP -\fB<file>\fR: -. -.IP -The name of the import file\. If omitted, it will be \'{dbname}\.sql\' - diff --git a/man/db-optimize.1 b/man/db-optimize.1 deleted file mode 100644 index 50fad9af38..0000000000 --- a/man/db-optimize.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-OPTIMIZE" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-optimize\fR \- Optimize the database\. -. -.SH "SYNOPSIS" -\fBwp db optimize\fR diff --git a/man/db-query.1 b/man/db-query.1 deleted file mode 100644 index 0e0abdaf90..0000000000 --- a/man/db-query.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-QUERY" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-query\fR \- Execute a query against the database\. -. -.SH "SYNOPSIS" -wp db query \fIsql\fR -. -.SH "OPTIONS" -. -.TP -\fB<SQL>\fR: -. -.IP -A SQL query\. - diff --git a/man/db-repair.1 b/man/db-repair.1 deleted file mode 100644 index 3e6539c8dc..0000000000 --- a/man/db-repair.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-REPAIR" "1" "October 2012" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-repair\fR \- Repair the database\. -. -.SH "SYNOPSIS" -\fBwp db repair\fR diff --git a/man/db-reset.1 b/man/db-reset.1 deleted file mode 100644 index b27e41cfc0..0000000000 --- a/man/db-reset.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB\-RESET" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\-reset\fR \- Remove all tables from the database\. -. -.SH "SYNOPSIS" -wp db reset [\-\-yes] -. -.SH "OPTIONS" -. -.TP -\fB\-\-yes\fR: -. -.IP -Answer yes to the confirmation message\. - From 7e93170380b98ed51a41bc876905172f7a838767 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 May 2013 23:12:01 +0300 Subject: [PATCH 1690/4858] help: add test for --help --- features/help.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/help.feature b/features/help.feature index f82b0c7cf9..84207355da 100644 --- a/features/help.feature +++ b/features/help.feature @@ -21,6 +21,12 @@ Feature: Get help about WP-CLI commands WP-CORE-DOWNLOAD(1) """ + When I run `wp help --help` + Then STDOUT should contain: + """ + WP-HELP(1) + """ + When I try `wp help non-existent-command` Then the return code should be 1 And STDERR should not be empty From 262781e7215717be05dcd42cd313d38e4aafe0a4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 00:09:59 +0300 Subject: [PATCH 1691/4858] post list: show post status by default Yes, we have --fields, but useful defaults matter. The post status helps to remind users that they might want to filter the list further. see #422 --- php/commands/post.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index b895a78d9c..e1e2da842f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -13,7 +13,8 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { 'ID', 'post_title', 'post_name', - 'post_date' + 'post_date', + 'post_status' ); /** From ca9c9715429d94c911d48cb1be73495df49f9ddc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 00:20:48 +0300 Subject: [PATCH 1692/4858] post list: update man page --- man-src/post-list.txt | 2 +- man/post-list.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/post-list.txt b/man-src/post-list.txt index 67637487ab..098d41c743 100644 --- a/man-src/post-list.txt +++ b/man-src/post-list.txt @@ -6,7 +6,7 @@ * `--fields`=<fields>: - Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date. + Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. * `--format`=<format>: diff --git a/man/post-list.1 b/man/post-list.1 index 83d3c3991e..9212454234 100644 --- a/man/post-list.1 +++ b/man/post-list.1 @@ -21,7 +21,7 @@ One or more args to pass to WP_Query\. \fB\-\-fields\fR=\fIfields\fR: . .IP -Limit the output to specific object fields\. Defaults to ID,post_title,post_name,post_date\. +Limit the output to specific object fields\. Defaults to ID,post_title,post_name,post_date,post_status\. . .TP \fB\-\-format\fR=\fIformat\fR: From 9b983ff044fc02843662287fbac7299d906f6213 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 00:34:04 +0300 Subject: [PATCH 1693/4858] post create: include --post_date in example closes #282 --- man-src/post-create.txt | 4 ++-- man/post-create.1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man-src/post-create.txt b/man-src/post-create.txt index 0a2bb1e06d..770713c9c4 100644 --- a/man-src/post-create.txt +++ b/man-src/post-create.txt @@ -26,6 +26,6 @@ ## EXAMPLES - wp post create --post_type=page --post_status=publish --post_title='A new page' + wp post create --post_type=page --post_status=publish --post_title='A future post' --post-status=future --post_date='2020-12-01 07:00:00' - wp post create file.txt --post_type=post --post_title='Post from file' + wp post create page.txt --post_type=page --post_title='Page from file' diff --git a/man/post-create.1 b/man/post-create.1 index 12e7be4085..7dbc248443 100644 --- a/man/post-create.1 +++ b/man/post-create.1 @@ -45,9 +45,9 @@ Output just the new post id\. . .nf -wp post create \-\-post_type=page \-\-post_status=publish \-\-post_title=\'A new page\' +wp post create \-\-post_type=page \-\-post_status=publish \-\-post_title=\'A future post\' \-\-post\-status=future \-\-post_date=\'2020\-12\-01 07:00:00\' -wp post create file\.txt \-\-post_type=post \-\-post_title=\'Post from file\' +wp post create page\.txt \-\-post_type=page \-\-post_title=\'Page from file\' . .fi From c74fa93214b28b3d5577219ca84630737c4cf716 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 12 May 2013 00:01:10 +0300 Subject: [PATCH 1694/4858] don't attempt to export $COLUMNS First of all, it's not used by wp-cli (php-cli-tools calls tput directly). Second of all, $COLUMNS is a shell variable, so it wouldn't be available via PHP's getenv() normally. In other words, calling tput directly is the correct solution. --- bin/wp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/bin/wp b/bin/wp index 0ae1dabd59..0120a18dea 100755 --- a/bin/wp +++ b/bin/wp @@ -30,19 +30,6 @@ case $(uname -a) in SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; esac -# If not exported, try to determine and export the number of columns. -# We do not want to run $(tput cols) if $TERM is empty or "dumb", because -# if we do, tput will output an undesirable error message to stderr. If -# we redirect stderr in any way, e.g. $(tput cols 2>/dev/null), then the -# error message is suppressed, but tput cols becomes confused about the -# terminal and prints out the default value (80). -if [ -z $COLUMNS ] && [ -n "$TERM" ] && [ "$TERM" != dumb ] ; then - # Note to cygwin users: install the ncurses package to get tput command. - if COLUMNS=$(tput cols); then - export COLUMNS - fi -fi - if [ ! -z "$WP_CLI_PHP" ] ; then # Use the WP_CLI_PHP environment variable if it is available. php="$WP_CLI_PHP" From c12b24d6201cc09dd4e9c22a04dbed904b6e3225 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 15:20:07 +0300 Subject: [PATCH 1695/4858] convert `wp --man` to `wp help --gen` --- php/WP_CLI/Dispatcher/RootCommand.php | 5 ---- php/WP_CLI/InternalFlags.php | 22 ----------------- php/WP_CLI/Runner.php | 6 ----- php/commands/help.php | 34 +++++++++++++++++++++++---- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 0da342d74c..4c74f82cb2 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -73,11 +73,6 @@ private static function generate_synopsis() { } function pre_invoke( &$args ) { - if ( array( 'help' ) == $args ) { - $this->show_usage(); - exit; - } - $cmd_name = $args[0]; $command = $this->find_subcommand( $args ); diff --git a/php/WP_CLI/InternalFlags.php b/php/WP_CLI/InternalFlags.php index 87cabf3725..1f5bf70893 100644 --- a/php/WP_CLI/InternalFlags.php +++ b/php/WP_CLI/InternalFlags.php @@ -55,27 +55,5 @@ static function completions() { WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); } } - - static function man( $args ) { - if ( '' === exec( 'which ronn' ) ) { - WP_CLI::error( '`ronn` executable not found.' ); - } - - $arg_copy = $args; - - $command = WP_CLI::$root; - - while ( !empty( $args ) && $command && $command instanceof Dispatcher\CommandContainer ) { - $command = $command->find_subcommand( $args ); - } - - if ( !$command ) - WP_CLI::error( sprintf( "'%s' command not found.", - implode( ' ', $arg_copy ) ) ); - - foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { - WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); - } - } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 106fc6479a..1079637166 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -163,12 +163,6 @@ private function cmd_starts_with( $prefix ) { } private function _run_command() { - // Handle --man parameter - if ( isset( $this->assoc_args['man'] ) ) { - \WP_CLI\InternalFlags::man( $this->arguments ); - exit; - } - WP_CLI::run_command( $this->arguments, $this->assoc_args ); } diff --git a/php/commands/help.php b/php/commands/help.php index 0afaea7423..c66e4a99b3 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -1,15 +1,20 @@ <?php -use \WP_CLI\Dispatcher\CommandContainer; - class Help_Command extends WP_CLI_Command { /** * Get help on a certain topic. * - * @synopsis [<command>] + * @synopsis [<command>] [--gen] */ - function __invoke( $args ) { + function __invoke( $args, $assoc_args ) { + if ( isset( $assoc_args['gen'] ) ) + $this->generate( $args ); + else + $this->show( $args ); + } + + private function show( $args ) { if ( \WP_CLI\Man\maybe_show_manpage( $args ) ) { exit; } @@ -26,6 +31,27 @@ function __invoke( $args ) { \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); } } + + private function generate( $args ) { + if ( '' === exec( 'which ronn' ) ) { + WP_CLI::error( '`ronn` executable not found.' ); + } + + $arg_copy = $args; + + $command = WP_CLI\Utils\find_subcommand( $args ); + + if ( !$command ) { + WP_CLI::error( sprintf( "'%s' command not found.", + implode( ' ', $arg_copy ) ) ); + } + + foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { + WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + } + + exit; + } } WP_CLI::add_command( 'help', 'Help_Command' ); From d8b2af174b36308a10e7448ce43c5aa88f6cdc15 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 15:20:49 +0300 Subject: [PATCH 1696/4858] wp help: update man page --- CONTRIBUTING.md | 6 +----- man-src/help.txt | 10 ++++++++++ man/help.1 | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c90ed7c397..7389047efd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,11 +16,7 @@ The compiled man page is placed in the `man` directory. To (re)generate one or more man pages, you first need to have the [ronn](https://rubygems.org/gems/ronn) ruby gem installed. -Then, you can run one of the following: - -* `wp --man` - regenerates all man pages -* `wp core --man` - regenerates man pages for the `core` command -* `wp core download --man` - regenerates man page only for the `core download` subcommand +Then, you can use the `wp help --gen` command. Running the tests ----------------- diff --git a/man-src/help.txt b/man-src/help.txt index e69de29bb2..69ac8e6993 100644 --- a/man-src/help.txt +++ b/man-src/help.txt @@ -0,0 +1,10 @@ +## EXAMPLES + + # (re)generates all man pages + wp help --gen + + # (re)generate man pages for the `core` command + wp help --gen core + + # (re)generate man page only for the `core download` subcommand + wp help --gen core download diff --git a/man/help.1 b/man/help.1 index 707ebcc97e..9b707455e8 100644 --- a/man/help.1 +++ b/man/help.1 @@ -7,4 +7,20 @@ \fBwp\-help\fR \- Get help on a certain topic\. . .SH "SYNOPSIS" -wp help [\fIcommand\fR] +wp help [\fIcommand\fR] [\-\-gen] +. +.SH "EXAMPLES" +. +.nf + +# (re)generates all man pages +wp help \-\-gen + +# (re)generate man pages for the `core` command +wp help \-\-gen core + +# (re)generate man page only for the `core download` subcommand +wp help \-\-gen core download +. +.fi + From ad73dea652a38f826aaa45173afd4ab00a4b3125 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 15:56:44 +0300 Subject: [PATCH 1697/4858] help --gen: add test for multisite-only subcommands --- features/help.feature | 8 ++++++++ php/commands/blog.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index 84207355da..205cd8b36e 100644 --- a/features/help.feature +++ b/features/help.feature @@ -51,3 +51,11 @@ Feature: Get help about WP-CLI commands """ usage: wp test-help """ + + Scenario: Generating help + Given an empty directory + When I run `wp help --gen blog create` + Then STDOUT should be: + """ + generated blog-create.1 + """ diff --git a/php/commands/blog.php b/php/commands/blog.php index 3c38438d39..548981e5e4 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -279,7 +279,7 @@ public function create( $_, $assoc_args ) { } $command_class = 'Blog_Command'; -if ( function_exists( 'is_multisite' ) && is_multisite() ) +if ( !function_exists( 'is_multisite' ) || is_multisite() ) $command_class = 'MS_Blog_Command'; WP_CLI::add_command( 'blog', $command_class ); From 64d4085f60f8ff0d3b61fb3f8bbf373e28b42992 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 16:53:44 +0300 Subject: [PATCH 1698/4858] help --gen: add test for third-party commands --- .travis.yml | 1 + features/help.feature | 26 +++++++++++++++++++++++--- features/steps/basic_steps.php | 4 +++- php/class-wp-cli.php | 4 ++-- php/commands/help.php | 15 ++++++++------- php/man.php | 6 +++--- 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 622e25b65c..d0a9cebc49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ before_script: # install dependencies - composer install --dev --no-interaction --prefer-source - composer require d11wtq/boris=dev-master --no-interaction --prefer-source + - gem install ronn # set up WP install - bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ # set up database diff --git a/features/help.feature b/features/help.feature index 205cd8b36e..7ee24d6a44 100644 --- a/features/help.feature +++ b/features/help.feature @@ -33,7 +33,13 @@ Feature: Get help about WP-CLI commands Scenario: Getting help for a third-party command Given a WP install - And a wp-content/plugins/test-cli-help.php file: + And a wp-content/plugins/test-cli/test-help.txt file: + """ + ## EXAMPLES + + wp test-help + """ + And a wp-content/plugins/test-cli/command.php file: """ <?php // Plugin Name: Test CLI Help @@ -43,8 +49,10 @@ Feature: Get help about WP-CLI commands } WP_CLI::add_command( 'test-help', 'Test_Help' ); + + WP_CLI::add_man_dir( __DIR__, __DIR__ ); """ - And I run `wp plugin activate test-cli-help` + And I run `wp plugin activate test-cli` When I run `wp help test-help` Then STDOUT should contain: @@ -52,7 +60,19 @@ Feature: Get help about WP-CLI commands usage: wp test-help """ - Scenario: Generating help + When I run `wp help --gen test-help` + Then STDOUT should contain: + """ + generated test-help.1 + """ + + When I run `wp help test-help` + Then STDOUT should contain: + """ + WP-TEST-HELP(1) + """ + + Scenario: Generating help for multisite-only subcommands Given an empty directory When I run `wp help --gen blog create` Then STDOUT should be: diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index d5432db90f..f838df65c0 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -23,7 +23,9 @@ function ( $world ) { $steps->Given( '/^a ([^\s]+) file:$/', function ( $world, $path, PyStringNode $content ) { $content = (string) $content . "\n"; - file_put_contents( $world->get_path( $path ), $content ); + $full_path = $world->get_path( $path ); + Process::create( \WP_CLI\utils\esc_cmd( 'mkdir -p %s', dirname( $full_path ) ) )->run_check(); + file_put_contents( $full_path, $content ); } ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index a711d4d0a8..1a47614f1d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -19,8 +19,8 @@ class WP_CLI { */ static function init() { self::add_man_dir( - WP_CLI_ROOT . "../man/", - WP_CLI_ROOT . "../man-src/" + WP_CLI_ROOT . "../man", + WP_CLI_ROOT . "../man-src" ); self::$root = new Dispatcher\RootCommand; diff --git a/php/commands/help.php b/php/commands/help.php index c66e4a99b3..9043a7e84d 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -41,16 +41,17 @@ private function generate( $args ) { $command = WP_CLI\Utils\find_subcommand( $args ); - if ( !$command ) { - WP_CLI::error( sprintf( "'%s' command not found.", - implode( ' ', $arg_copy ) ) ); + if ( $command ) { + foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { + WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + } + exit; } - foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { - WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + // WordPress is already loaded, so there's no chance we'll find the command + if ( function_exists( 'add_filter' ) ) { + WP_CLI::error( sprintf( "'%s' command not found.", implode( ' ', $arg_copy ) ) ); } - - exit; } } diff --git a/php/man.php b/php/man.php index 0d42cbfd07..38abf2d905 100644 --- a/php/man.php +++ b/php/man.php @@ -16,8 +16,8 @@ function generate( $src_dir, $dest_dir, $command ) { $cmd_path = Dispatcher\get_path( $command ); array_shift( $cmd_path ); // discard 'wp' - $src_path = $src_dir . get_src_file_name( $cmd_path ); - $dest_path = $dest_dir . get_file_name( $cmd_path ); + $src_path = "$src_dir/" . get_src_file_name( $cmd_path ); + $dest_path = "$dest_dir/" . get_file_name( $cmd_path ); call_ronn( get_markdown( $src_path, $command ), $dest_path ); @@ -134,7 +134,7 @@ function maybe_show_manpage( $args ) { $man_file = get_file_name( $args ); foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { - $man_path = $dest_dir . $man_file; + $man_path = "$dest_dir/" . $man_file; if ( is_readable( $man_path ) ) { show_manpage( $man_path ); From 780c5f4fc2571b92a2f141fa483b203be6366bc9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 17:21:17 +0300 Subject: [PATCH 1699/4858] merge man.php into commands/help.php --- php/commands/help.php | 147 +++++++++++++++++++++++++++++++++++++++++- php/man.php | 147 ------------------------------------------ php/wp-cli.php | 1 - 3 files changed, 145 insertions(+), 150 deletions(-) delete mode 100644 php/man.php diff --git a/php/commands/help.php b/php/commands/help.php index 9043a7e84d..3fa8de9c02 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -1,5 +1,7 @@ <?php +use \WP_CLI\Dispatcher; + class Help_Command extends WP_CLI_Command { /** @@ -15,7 +17,7 @@ function __invoke( $args, $assoc_args ) { } private function show( $args ) { - if ( \WP_CLI\Man\maybe_show_manpage( $args ) ) { + if ( self::maybe_show_manpage( $args ) ) { exit; } @@ -43,7 +45,7 @@ private function generate( $args ) { if ( $command ) { foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { - WP_CLI\Man\generate( $src_dir, $dest_dir, $command ); + self::_generate( $src_dir, $dest_dir, $command ); } exit; } @@ -53,6 +55,147 @@ private function generate( $args ) { WP_CLI::error( sprintf( "'%s' command not found.", implode( ' ', $arg_copy ) ) ); } } + + private static function maybe_show_manpage( $args ) { + $man_file = self::get_file_name( $args ); + + foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { + $man_path = "$dest_dir/" . $man_file; + + if ( is_readable( $man_path ) ) { + self::show_manpage( $man_path ); + return true; + } + } + + return false; + } + + private static function show_manpage( $path ) { + // man can't read phar://, so need to copy to a temporary file + $tmp_path = tempnam( sys_get_temp_dir(), 'wp-cli-man-' ); + + copy( $path, $tmp_path ); + + \WP_CLI::launch( "man $tmp_path" ); + + unlink( $tmp_path ); + } + + private static function _generate( $src_dir, $dest_dir, $command ) { + $cmd_path = Dispatcher\get_path( $command ); + array_shift( $cmd_path ); // discard 'wp' + + $src_path = "$src_dir/" . self::get_src_file_name( $cmd_path ); + $dest_path = "$dest_dir/" . self::get_file_name( $cmd_path ); + + self::call_ronn( self::get_markdown( $src_path, $command ), $dest_path ); + + if ( $command instanceof Dispatcher\CommandContainer ) { + foreach ( $command->get_subcommands() as $subcommand ) { + self::_generate( $src_dir, $dest_dir, $subcommand ); + } + } + } + + // returns a file descriptor or false + private static function get_markdown( $doc_path, $command ) { + if ( !file_exists( $doc_path ) ) + return false; + + $fd = fopen( "php://temp", "rw" ); + + if ( $command instanceof Dispatcher\Documentable ) + self::add_initial_markdown( $fd, $command ); + + fwrite( $fd, file_get_contents( $doc_path ) ); + + if ( 0 === ftell( $fd ) ) + return false; + + fseek( $fd, 0 ); + + return $fd; + } + + private static function add_initial_markdown( $fd, $command ) { + $path = Dispatcher\get_path( $command ); + + $shortdesc = $command->get_shortdesc(); + $synopsis = $command->get_full_synopsis(); + + $synopsis = str_replace( '_', '\_', $synopsis ); + $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); + + $name_m = implode( '-', $path ); + $name_s = implode( ' ', $path ); + + if ( !$shortdesc ) { + \WP_CLI::warning( "No shortdesc for $name_s" ); + } + + fwrite( $fd, <<<DOC +$name_m(1) -- $shortdesc +==== + +## SYNOPSIS + +$synopsis + +DOC + ); + + if ( $command instanceof Dispatcher\CommandContainer ) { + + fwrite( $fd, <<<DOC +## SUBCOMMANDS + +DOC + ); + + foreach ( $command->get_subcommands() as $subcommand ) { + $name = $subcommand->get_name(); + $desc = $subcommand->get_shortdesc(); + + fwrite( $fd, <<<DOC +* `$name`: + + $desc + +DOC + ); + } + } + } + + private static function call_ronn( $markdown, $dest ) { + if ( !$markdown ) + return; + + $descriptorspec = array( + 0 => $markdown, + 1 => array( 'file', $dest, 'w' ), + 2 => STDERR + ); + + $cmd = "ronn --date=2012-01-01 --roff --manual='WP-CLI'"; + + $r = proc_close( proc_open( $cmd, $descriptorspec, $pipes ) ); + + $roff = file_get_contents( $dest ); + $roff = str_replace( ' "January 2012"', '', $roff ); + file_put_contents( $dest, $roff ); + + \WP_CLI::line( "generated " . basename( $dest ) ); + } + + private static function get_file_name( $args ) { + return implode( '-', $args ) . '.1'; + } + + private static function get_src_file_name( $args ) { + return implode( '-', $args ) . '.txt'; + } } WP_CLI::add_command( 'help', 'Help_Command' ); diff --git a/php/man.php b/php/man.php deleted file mode 100644 index 38abf2d905..0000000000 --- a/php/man.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -namespace WP_CLI\Man; - -use \WP_CLI\Dispatcher; - -function get_file_name( $args ) { - return implode( '-', $args ) . '.1'; -} - -function get_src_file_name( $args ) { - return implode( '-', $args ) . '.txt'; -} - -function generate( $src_dir, $dest_dir, $command ) { - $cmd_path = Dispatcher\get_path( $command ); - array_shift( $cmd_path ); // discard 'wp' - - $src_path = "$src_dir/" . get_src_file_name( $cmd_path ); - $dest_path = "$dest_dir/" . get_file_name( $cmd_path ); - - call_ronn( get_markdown( $src_path, $command ), $dest_path ); - - if ( $command instanceof Dispatcher\CommandContainer ) { - foreach ( $command->get_subcommands() as $subcommand ) { - generate( $src_dir, $dest_dir, $subcommand ); - } - } -} - -// returns a file descriptor or false -function get_markdown( $doc_path, $command ) { - if ( !file_exists( $doc_path ) ) - return false; - - $fd = fopen( "php://temp", "rw" ); - - if ( $command instanceof Dispatcher\Documentable ) - add_initial_markdown( $fd, $command ); - - fwrite( $fd, file_get_contents( $doc_path ) ); - - if ( 0 === ftell( $fd ) ) - return false; - - fseek( $fd, 0 ); - - return $fd; -} - -function add_initial_markdown( $fd, $command ) { - $path = Dispatcher\get_path( $command ); - - $shortdesc = $command->get_shortdesc(); - $synopsis = $command->get_full_synopsis(); - - $synopsis = str_replace( '_', '\_', $synopsis ); - $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); - - $name_m = implode( '-', $path ); - $name_s = implode( ' ', $path ); - - if ( !$shortdesc ) { - \WP_CLI::warning( "No shortdesc for $name_s" ); - } - - fwrite( $fd, <<<DOC -$name_m(1) -- $shortdesc -==== - -## SYNOPSIS - -$synopsis - -DOC - ); - - if ( $command instanceof Dispatcher\CommandContainer ) { - - fwrite( $fd, <<<DOC -## SUBCOMMANDS - -DOC - ); - - foreach ( $command->get_subcommands() as $subcommand ) { - $name = $subcommand->get_name(); - $desc = $subcommand->get_shortdesc(); - - fwrite( $fd, <<<DOC -* `$name`: - - $desc - -DOC - ); - } - } -} - -function call_ronn( $markdown, $dest ) { - if ( !$markdown ) - return; - - $descriptorspec = array( - 0 => $markdown, - 1 => array( 'file', $dest, 'w' ), - 2 => STDERR - ); - - $cmd = "ronn --date=2012-01-01 --roff --manual='WP-CLI'"; - - $r = proc_close( proc_open( $cmd, $descriptorspec, $pipes ) ); - - $roff = file_get_contents( $dest ); - $roff = str_replace( ' "January 2012"', '', $roff ); - file_put_contents( $dest, $roff ); - - \WP_CLI::line( "generated " . basename( $dest ) ); -} - -function show_manpage( $path ) { - // man can't read phar://, so need to copy to a temporary file - $tmp_path = tempnam( sys_get_temp_dir(), 'wp-cli-man-' ); - - copy( $path, $tmp_path ); - - \WP_CLI::launch( "man $tmp_path" ); - - unlink( $tmp_path ); -} - -function maybe_show_manpage( $args ) { - $man_file = get_file_name( $args ); - - foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { - $man_path = "$dest_dir/" . $man_file; - - if ( is_readable( $man_path ) ) { - show_manpage( $man_path ); - return true; - } - } - - return false; -} - diff --git a/php/wp-cli.php b/php/wp-cli.php index 74db4137d1..8ca2bcf13c 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -9,7 +9,6 @@ include WP_CLI_ROOT . 'dispatcher.php'; include WP_CLI_ROOT . 'class-wp-cli.php'; include WP_CLI_ROOT . 'class-wp-cli-command.php'; -include WP_CLI_ROOT . 'man.php'; \WP_CLI\Utils\load_dependencies(); From 77cb9de295aef1c1f625b335f2ce2c227639553e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 17:31:42 +0300 Subject: [PATCH 1700/4858] convert Scaffold_Command->render() to Utils\mustache_render() --- php/commands/scaffold.php | 26 ++++++++------------------ php/utils.php | 8 ++++++++ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 1cdcac3968..9ba3d923d4 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -1,5 +1,7 @@ <?php +use WP_CLI\Utils; + /** * Generate code for post types, taxonomies, etc. * @@ -80,7 +82,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) list( $raw_template, $extended_template ) = $templates; - $raw_output = $this->render( $raw_template, $vars ); + $raw_output = Utils\mustache_render( $raw_template, $vars ); if ( ! $control_args['raw'] ) { $vars = array_merge( $vars, array( @@ -88,7 +90,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) 'output' => $raw_output ) ); - $final_output = $this->render( $extended_template, $vars ); + $final_output = Utils\mustache_render( $extended_template, $vars ); } else { $final_output = $raw_output; } @@ -169,7 +171,7 @@ function child_theme( $args, $assoc_args ) { $theme_dir = WP_CONTENT_DIR . "/themes" . "/$theme_slug"; $theme_style_path = "$theme_dir/style.css"; - $this->create_file( $theme_style_path, $this->render( 'child_theme.mustache', $data ) ); + $this->create_file( $theme_style_path, Utils\mustache_render( 'child_theme.mustache', $data ) ); WP_CLI::success( "Created $theme_dir" ); @@ -213,7 +215,7 @@ function plugin( $args, $assoc_args ) { $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; $plugin_path = "$plugin_dir/$plugin_slug.php"; - $this->create_file( $plugin_path, $this->render( 'plugin.mustache', $data ) ); + $this->create_file( $plugin_path, Utils\mustache_render( 'plugin.mustache', $data ) ); WP_CLI::success( "Created $plugin_dir" ); @@ -242,7 +244,7 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->mkdir( $tests_dir ); $this->create_file( "$tests_dir/bootstrap.php", - $this->render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ); + Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ); $to_copy = array( 'phpunit.xml' => $plugin_dir, @@ -251,7 +253,7 @@ function plugin_tests( $args, $assoc_args ) { ); foreach ( $to_copy as $file => $dir ) { - $wp_filesystem->copy( $this->get_template_path( $file ), "$dir/$file", true ); + $wp_filesystem->copy( WP_CLI_ROOT . "../templates/$file", "$dir/$file", true ); } WP_CLI::success( "Created test files in $plugin_dir" ); @@ -350,18 +352,6 @@ protected function extract_args( $assoc_args, $defaults ) { return $out; } - - private function render( $template, $data ) { - $template = file_get_contents( $this->get_template_path( $template ) ); - - $m = new Mustache_Engine; - - return $m->render( $template, $data ); - } - - private function get_template_path( $template ) { - return WP_CLI_ROOT . "../templates/$template"; - } } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); diff --git a/php/utils.php b/php/utils.php index 880136c861..65614d3271 100644 --- a/php/utils.php +++ b/php/utils.php @@ -392,3 +392,11 @@ function run_mysql_command( $cmd, $arg_str, $pass ) { if ( $r ) exit( $r ); } +function mustache_render( $template_name, $data ) { + $template = file_get_contents( WP_CLI_ROOT . "../templates/$template_name" ); + + $m = new \Mustache_Engine; + + return $m->render( $template, $data ); +} + From d21f33adb4513b1d006f23b71ab8639f143e6757 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 17:47:40 +0300 Subject: [PATCH 1701/4858] help --gen: add test for combined man pages --- features/help.feature | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/features/help.feature b/features/help.feature index 7ee24d6a44..39ca944d8e 100644 --- a/features/help.feature +++ b/features/help.feature @@ -1,6 +1,6 @@ Feature: Get help about WP-CLI commands - Scenario: Empty dir + Scenario: Help for internal commands Given an empty directory When I run `wp help` @@ -31,7 +31,23 @@ Feature: Get help about WP-CLI commands Then the return code should be 1 And STDERR should not be empty - Scenario: Getting help for a third-party command + Scenario: Generating help for subcommands + Given an empty directory + When I run `wp help --gen option` + Then STDOUT should be: + """ + generated option.1 + """ + + Scenario: Generating help for multisite-only subcommands + Given an empty directory + When I run `wp help --gen blog create` + Then STDOUT should be: + """ + generated blog-create.1 + """ + + Scenario: Help for third-party commands Given a WP install And a wp-content/plugins/test-cli/test-help.txt file: """ @@ -71,11 +87,3 @@ Feature: Get help about WP-CLI commands """ WP-TEST-HELP(1) """ - - Scenario: Generating help for multisite-only subcommands - Given an empty directory - When I run `wp help --gen blog create` - Then STDOUT should be: - """ - generated blog-create.1 - """ From 770f53c3a38723ffa3f16f1e1f165b5b4ff65d03 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 17:59:38 +0300 Subject: [PATCH 1702/4858] introduce man.mustache --- php/commands/help.php | 45 +++++++++++++----------------------------- templates/man.mustache | 17 ++++++++++++++++ 2 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 templates/man.mustache diff --git a/php/commands/help.php b/php/commands/help.php index 3fa8de9c02..12a31397d0 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -1,5 +1,6 @@ <?php +use \WP_CLI\Utils; use \WP_CLI\Dispatcher; class Help_Command extends WP_CLI_Command { @@ -121,51 +122,33 @@ private static function get_markdown( $doc_path, $command ) { private static function add_initial_markdown( $fd, $command ) { $path = Dispatcher\get_path( $command ); - $shortdesc = $command->get_shortdesc(); + $binding = array( + 'name_m' => implode( '-', $path ), + 'shortdesc' => $command->get_shortdesc(), + ); + $synopsis = $command->get_full_synopsis(); $synopsis = str_replace( '_', '\_', $synopsis ); $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); - $name_m = implode( '-', $path ); - $name_s = implode( ' ', $path ); + $binding['synopsis'] = $synopsis; - if ( !$shortdesc ) { + if ( !$binding['shortdesc'] ) { + $name_s = implode( ' ', $path ); \WP_CLI::warning( "No shortdesc for $name_s" ); } - fwrite( $fd, <<<DOC -$name_m(1) -- $shortdesc -==== - -## SYNOPSIS - -$synopsis - -DOC - ); - if ( $command instanceof Dispatcher\CommandContainer ) { - - fwrite( $fd, <<<DOC -## SUBCOMMANDS - -DOC - ); - foreach ( $command->get_subcommands() as $subcommand ) { - $name = $subcommand->get_name(); - $desc = $subcommand->get_shortdesc(); - - fwrite( $fd, <<<DOC -* `$name`: - - $desc - -DOC + $binding['has-subcommands']['subcommands'][] = array( + 'name' => $subcommand->get_name(), + 'desc' => $subcommand->get_shortdesc(), ); } } + + fwrite( $fd, Utils\mustache_render( 'man.mustache', $binding ) ); } private static function call_ronn( $markdown, $dest ) { diff --git a/templates/man.mustache b/templates/man.mustache new file mode 100644 index 0000000000..61a99bcfcb --- /dev/null +++ b/templates/man.mustache @@ -0,0 +1,17 @@ +{{name_m}}(1) -- {{shortdesc}} +==== + +## SYNOPSIS + +{{synopsis}} + +{{#has-subcommands}} +## SUBCOMMANDS + +{{#subcommands}} +* `{{name}}`: + + {{desc}} + +{{/subcommands}} +{{/has-subcommands}} From d7d3939e889309292a8a6457182935a1289fd0cc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 18:13:31 +0300 Subject: [PATCH 1703/4858] re-generate man pages --- man/cache.1 | 3 --- man/cap.1 | 17 ++++++----------- man/db.1 | 1 - man/option.1 | 1 - man/post-meta.1 | 1 - man/transient.1 | 5 +---- man/user-meta.1 | 1 - 7 files changed, 7 insertions(+), 22 deletions(-) diff --git a/man/cache.1 b/man/cache.1 index 19d4886d6c..82f66dc5b9 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -90,9 +90,6 @@ Set a value to the object cache\. Attempts to determine which object cache is being used\. . .SH "EXAMPLES" - -. -.P wp cache set my_key my_value my_group 300 . .P diff --git a/man/cap.1 b/man/cap.1 index 5e8c620f85..fdee7e6b6c 100644 --- a/man/cap.1 +++ b/man/cap.1 @@ -37,21 +37,16 @@ Remove capabilities from a given role\. . .SH "EXAMPLES" . -.IP +.nf + # Add \'spectate\' capability to \'author\' role -. -.br wp cap add \'author\' \'spectate\' -. -.IP + # Add all caps from \'editor\' role to \'author\' role -. -.br wp cap list \'editor\' | xargs wp cap add \'author\' -. -.IP + # Remove all caps from \'editor\' role that also appear in \'author\' role -. -.br wp cap list \'author\' | xargs wp cap remove \'editor\' +. +.fi diff --git a/man/db.1 b/man/db.1 index 98c8a6b8ef..5dd4689952 100644 --- a/man/db.1 +++ b/man/db.1 @@ -90,7 +90,6 @@ Repair the database\. Remove all tables from the database\. . .SH "OPTIONS" - . .TP \fB\-\-yes\fR: diff --git a/man/option.1 b/man/option.1 index bfb8105b8e..904b88a2ab 100644 --- a/man/option.1 +++ b/man/option.1 @@ -45,7 +45,6 @@ Get an option\. Update an option\. . .SH "OPTIONS" - . .TP \fB\-\-format=json\fR: diff --git a/man/post-meta.1 b/man/post-meta.1 index b806b334d5..ac1203efe2 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -45,7 +45,6 @@ Get meta field value\. Update a meta field\. . .SH "OPTIONS" - . .TP \fB\-\-format=json\fR: diff --git a/man/transient.1 b/man/transient.1 index 6c267b4391..1edd72a003 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -36,7 +36,7 @@ Get a transient value\. \fBset\fR: . .IP -Set a transient value\. \fIexpiration\fR is the time until expiration, in seconds\. +Set a transient value\. <expiration> is the time until expiration, in seconds\. . .TP \fBtype\fR: @@ -45,7 +45,4 @@ Set a transient value\. \fIexpiration\fR is the time until expiration, in second See wether the transients API is using an object cache or the options table\. . .SH "EXAMPLES" - -. -.P wp transient set my_key my_value 300 diff --git a/man/user-meta.1 b/man/user-meta.1 index 883b2923b5..b09bb8db9c 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -45,7 +45,6 @@ Get meta field value\. Update a meta field\. . .SH "OPTIONS" - . .TP \fB\-\-format=json\fR: From 1ba4c6c9676f3c93f71bba397b3aa9449e6aa2af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 18:49:40 +0300 Subject: [PATCH 1704/4858] CommandWithUpgrade: remove unnecessary args check; indentation fixes --- php/WP_CLI/CommandWithUpgrade.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 4ffe023860..d2b8529c0a 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -47,6 +47,7 @@ private function status_all() { } else { $line = ' '; } + $line .= $this->format_status( $details['status'], 'short' ); $line .= " " . str_pad( $details['name'], $padding ). "%n"; if ( !empty( $details['version'] ) ) { @@ -65,11 +66,11 @@ private function get_padding( $items ) { $max_len = 0; foreach ( $items as $details ) { - $len = strlen( $details['name'] ); + $len = strlen( $details['name'] ); - if ( $len > $max_len ) { - $max_len = $len; - } + if ( $len > $max_len ) { + $max_len = $len; + } } return $max_len; @@ -95,11 +96,6 @@ private function show_legend( $items ) { } function install( $args, $assoc_args ) { - if ( empty( $args ) ) { - \WP_CLI::line( "usage: wp $this->item_type install <slug>" ); - exit; - } - // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); @@ -235,7 +231,7 @@ private function create_objects( $items ) { } else if ( $value === false) { $value = "none"; } - + $object->{$field} = $value; } $objects[] = $object; From 3a70d152dceec529e21a70629106ff068015d9c9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 18:52:51 +0300 Subject: [PATCH 1705/4858] behat: replace 'a P2 theme zip' step with 'wp theme install' call --- features/steps/basic_steps.php | 12 ------------ features/theme.feature | 5 +---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index f838df65c0..dfec88c931 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -84,18 +84,6 @@ function ( $world ) { } ); -$steps->Given( '/^a P2 theme zip$/', - function ( $world ) { - $zip_name = 'p2.1.0.1.zip'; - - $world->variables['THEME_ZIP'] = $world->get_cache_path( $zip_name ); - - $zip_url = 'http://wordpress.org/extend/themes/download/' . $zip_name; - - $world->download_file( $zip_url, $world->variables['THEME_ZIP'] ); - } -); - $steps->Given( '/^a large image file$/', function ( $world ) { $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; diff --git a/features/theme.feature b/features/theme.feature index db3804ebb6..fd65ec6653 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -49,10 +49,7 @@ Feature: Manage WordPress themes Scenario: Upgrading a theme Given a WP install - And a P2 theme zip - - When I run `wp theme install {THEME_ZIP}` - Then STDOUT should not be empty + And I run `wp theme install p2 --version=1.0.1` When I run `wp theme status` Then STDOUT should contain: From 09d12e552cefba13cc8bd66574a1c60b73dd6538 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 20 May 2013 18:59:06 +0300 Subject: [PATCH 1706/4858] blog: explain logic behind multisite condition The `function_exists( 'add_filter' )` part tests that WordPress is loaded. --- php/commands/blog.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index 548981e5e4..d92e3ac393 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -278,9 +278,11 @@ public function create( $_, $assoc_args ) { } } -$command_class = 'Blog_Command'; -if ( !function_exists( 'is_multisite' ) || is_multisite() ) +// We want multisite subcommands to be available when doing `wp help --gen blog` +if ( !function_exists( 'add_filter' ) || is_multisite() ) $command_class = 'MS_Blog_Command'; +else + $command_class = 'Blog_Command'; WP_CLI::add_command( 'blog', $command_class ); From 4a72e73d34c6574734d6b385722f50cea9e75d16 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Mon, 20 May 2013 16:29:22 -0700 Subject: [PATCH 1707/4858] Add a search-replace option to skip guids. --- man-src/search-replace.txt | 4 ++++ man/search-replace.1 | 8 +++++++- php/commands/search-replace.php | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index 2db4c96cf7..f4ed828d55 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -10,6 +10,10 @@ It will correctly handle serialized values. Show report, but don't perform the changes. +* `--skip-guids`: + + Do not perform the replacement in columns named 'guid'. Use to preserve existing GUID values when changing domain names. + ## EXAMPLES wp search-replace 'http://example.dev' 'http://example.com' --dry-run diff --git a/man/search-replace.1 b/man/search-replace.1 index 0a5e342365..edd227a8db 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -7,7 +7,7 @@ \fBwp\-search\-replace\fR \- Search/replace strings in the database\. . .SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] +wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] [\-\-skip\-guids] . .SH "DESCRIPTION" This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. @@ -23,6 +23,12 @@ It will correctly handle serialized values\. .IP Show report, but don\'t perform the changes\. . +.TP +\fB\-\-skip\-guids\fR: +. +.IP +Do not perform the replacement in columns named \'guid\'\. Use to preserve existing GUID values when changing domain names\. +. .SH "EXAMPLES" . .nf diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 89f76d55c6..752b2d50d2 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,7 +10,7 @@ class Search_Replace_Command extends WP_CLI_Command { /** * Search/replace strings in the database. * - * @synopsis <old> <new> [<table>...] [--dry-run] + * @synopsis <old> <new> [<table>...] [--dry-run] [--skip-guids] */ public function __invoke( $args, $assoc_args ) { global $wpdb; @@ -30,10 +30,15 @@ public function __invoke( $args, $assoc_args ) { $dry_run = isset( $assoc_args['dry-run'] ); + $skip_guids = isset( $assoc_args['skip-guids'] ); + foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); foreach ( $columns as $col ) { + if ( $skip_guids && 'guid' === $col ) + continue; + $count = self::handle_col( $col, $primary_key, $table, $old, $new, $dry_run ); From d261d7011e30f67870eb96aa06f1908223f88b49 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Mon, 20 May 2013 20:57:40 -0700 Subject: [PATCH 1708/4858] Specify any columns to be skipped. --- man-src/search-replace.txt | 8 ++++---- man/search-replace.1 | 10 +++++----- php/commands/search-replace.php | 9 ++++++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index f4ed828d55..0168065d32 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -2,7 +2,7 @@ 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. +It will correctly handle serialized values, and will not change primary key values. ## OPTIONS @@ -10,12 +10,12 @@ It will correctly handle serialized values. Show report, but don't perform the changes. -* `--skip-guids`: +* `--skip-columns=<columns>`: - Do not perform the replacement in columns named 'guid'. Use to preserve existing GUID values when changing domain names. + Do not perform the replacement in the comma-separated columns. Useful to preserve existing guid column values when changing domain names. ## EXAMPLES - wp search-replace 'http://example.dev' 'http://example.com' --dry-run + wp search-replace 'http://example.dev' 'http://example.com' --dry-run --skip-columns=guid wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms diff --git a/man/search-replace.1 b/man/search-replace.1 index edd227a8db..c532ce291a 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -7,13 +7,13 @@ \fBwp\-search\-replace\fR \- Search/replace strings in the database\. . .SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] [\-\-skip\-guids] +wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] [\-\-skip\-columns=\fIcolumns\fR] . .SH "DESCRIPTION" This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. . .P -It will correctly handle serialized values\. +It will correctly handle serialized values, and will not change primary key values\. . .SH "OPTIONS" . @@ -24,16 +24,16 @@ It will correctly handle serialized values\. Show report, but don\'t perform the changes\. . .TP -\fB\-\-skip\-guids\fR: +\fB\-\-skip\-columns=<columns>\fR: . .IP -Do not perform the replacement in columns named \'guid\'\. Use to preserve existing GUID values when changing domain names\. +Do not perform the replacement in the comma\-separated columns\. Useful to preserve existing guid column values when changing domain names\. . .SH "EXAMPLES" . .nf -wp search\-replace \'http://example\.dev\' \'http://example\.com\' \-\-dry\-run +wp search\-replace \'http://example\.dev\' \'http://example\.com\' \-\-dry\-run \-\-skip\-columns=guid wp search\-replace \'foo\' \'bar\' wp_posts wp_postmeta wp_terms . diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 752b2d50d2..c5ffbe95d7 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,7 +10,7 @@ class Search_Replace_Command extends WP_CLI_Command { /** * Search/replace strings in the database. * - * @synopsis <old> <new> [<table>...] [--dry-run] [--skip-guids] + * @synopsis <old> <new> [<table>...] [--dry-run] [--skip-columns=<columns>] */ public function __invoke( $args, $assoc_args ) { global $wpdb; @@ -30,13 +30,16 @@ public function __invoke( $args, $assoc_args ) { $dry_run = isset( $assoc_args['dry-run'] ); - $skip_guids = isset( $assoc_args['skip-guids'] ); + if ( isset( $assoc_args['skip-columns'] ) ) + $skip_columns = explode( ',', $assoc_args['skip-columns'] ); + else + $skip_columns = array(); foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); foreach ( $columns as $col ) { - if ( $skip_guids && 'guid' === $col ) + if ( in_array( $col, $skip_columns ) ) continue; $count = self::handle_col( $col, $primary_key, $table, $old, $new, From a0f456c4a707fbf16c4fa8cdee69592b3804bbc6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 22 May 2013 15:59:50 +0300 Subject: [PATCH 1709/4858] search-replace: the --dry-run flag should be last --- man-src/search-replace.txt | 12 ++++++------ man/search-replace.1 | 14 +++++++------- php/commands/search-replace.php | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index 0168065d32..f6ead0c895 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -6,16 +6,16 @@ It will correctly handle serialized values, and will not change primary key valu ## OPTIONS -* `--dry-run`: +* `--skip-columns=<columns>`: - Show report, but don't perform the changes. + Do not perform the replacement in the comma-separated columns. -* `--skip-columns=<columns>`: +* `--dry-run`: - Do not perform the replacement in the comma-separated columns. Useful to preserve existing guid column values when changing domain names. + Show report, but don't perform the changes. ## EXAMPLES - wp search-replace 'http://example.dev' 'http://example.com' --dry-run --skip-columns=guid + wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid - wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms + wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run diff --git a/man/search-replace.1 b/man/search-replace.1 index c532ce291a..7ee007f607 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -7,7 +7,7 @@ \fBwp\-search\-replace\fR \- Search/replace strings in the database\. . .SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-dry\-run] [\-\-skip\-columns=\fIcolumns\fR] +wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-skip\-columns=\fIcolumns\fR] [\-\-dry\-run] . .SH "DESCRIPTION" This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. @@ -18,24 +18,24 @@ It will correctly handle serialized values, and will not change primary key valu .SH "OPTIONS" . .TP -\fB\-\-dry\-run\fR: +\fB\-\-skip\-columns=<columns>\fR: . .IP -Show report, but don\'t perform the changes\. +Do not perform the replacement in the comma\-separated columns\. . .TP -\fB\-\-skip\-columns=<columns>\fR: +\fB\-\-dry\-run\fR: . .IP -Do not perform the replacement in the comma\-separated columns\. Useful to preserve existing guid column values when changing domain names\. +Show report, but don\'t perform the changes\. . .SH "EXAMPLES" . .nf -wp search\-replace \'http://example\.dev\' \'http://example\.com\' \-\-dry\-run \-\-skip\-columns=guid +wp search\-replace \'http://example\.dev\' \'http://example\.com\' \-\-skip\-columns=guid -wp search\-replace \'foo\' \'bar\' wp_posts wp_postmeta wp_terms +wp search\-replace \'foo\' \'bar\' wp_posts wp_postmeta wp_terms \-\-dry\-run . .fi diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c5ffbe95d7..a08af875c1 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,7 +10,7 @@ class Search_Replace_Command extends WP_CLI_Command { /** * Search/replace strings in the database. * - * @synopsis <old> <new> [<table>...] [--dry-run] [--skip-columns=<columns>] + * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] */ public function __invoke( $args, $assoc_args ) { global $wpdb; From 1cf29c4fdd30d68105e10985b06cf3f69c70f504 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 22 May 2013 16:04:19 +0300 Subject: [PATCH 1710/4858] search-replace: add test for --skip-columns see #464 --- features/search-replace.feature | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 30d9ecb784..d5bf8ff4a1 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -4,4 +4,13 @@ Feature: Do global search/replace Given a WP install When I run `wp search-replace foo bar` - Then STDOUT should not be empty + Then STDOUT should contain: + """ + guid + """ + + When I run `wp search-replace foo bar --skip-columns=guid` + Then STDOUT should not contain: + """ + guid + """ From fd465cea7ff0695d28f8dd30bd5605a0968c9921 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Thu, 23 May 2013 10:19:30 -0700 Subject: [PATCH 1711/4858] Correct taxonomy scaffold code for multiple post types. --- features/scaffold.feature | 11 +++++++++++ man-src/scaffold-taxonomy.txt | 4 ++++ man/core-update.1 | 37 ----------------------------------- man/scaffold-taxonomy.1 | 6 ++++++ php/commands/scaffold.php | 6 ++++++ templates/taxonomy.mustache | 2 +- 6 files changed, 28 insertions(+), 38 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index c638f6c149..e4d4fe3a8a 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -53,6 +53,17 @@ Feature: Wordpress code scaffolding """ __( 'Zombie speeds', 'zombieland' """ + + # Test for multiple post types + @tax + Scenario: Scaffold a Custom Taxonomy and attach it to multiple post types + Given a WP install + + When I run `wp scaffold taxonomy perambulation-speed --post_types="zombie,wraith" --textdomain=zombieland` + Then STDOUT should contain: + """ + array( 'zombie', 'wraith' ) + """ @tax Scenario: Scaffold a Custom Taxonomy with label "Speed" diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt index 41c7ab375c..f3e9a892b7 100644 --- a/man-src/scaffold-taxonomy.txt +++ b/man-src/scaffold-taxonomy.txt @@ -1,5 +1,9 @@ ## OPTIONS +* `--post_types=<post_types>`: + + Post types to register for use with the taxonomy. + * `--label=<label>`: The text used to translate the update messages diff --git a/man/core-update.1 b/man/core-update.1 index cb5848fb20..e69de29bb2 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -1,37 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-update\fR \- Update WordPress\. -. -.SH "SYNOPSIS" -wp core update [\fIzip\fR] [\-\-version=\fIversion\fR] [\-\-force] -. -.SH "OPTIONS" -. -.TP -\fB\-\-version=\fR\fInew_version\fR [package/zip]: -. -.IP -When passed, updates to new_version, optionally using package/zip as input\. -. -.TP -\fB\-\-force\fR: -. -.IP -Will update even when current WP version < passed version\. Use with caution\. -. -.SH "EXAMPLES" -. -.nf - -wp core update - -wp core update \-\-version=3\.4 \.\./latest\.zip - -wp core update \-\-version=3\.1 \-\-force -. -.fi - diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index a61470a2d7..ec4586af27 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -12,6 +12,12 @@ wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-label=\f .SH "OPTIONS" . .TP +\fB\-\-post_types=<post_types>\fR: +. +.IP +Post types to register for use with the taxonomy\. +. +.TP \fB\-\-label=<label>\fR: . .IP diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 9ba3d923d4..6b3b1bf050 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -68,6 +68,8 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $vars['slug'] = $slug; + $vars['post_types'] = $this->quote_comma_list_elements( $vars['post_types'] ); + $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); $vars['label'] = $control_args['label']; @@ -352,6 +354,10 @@ protected function extract_args( $assoc_args, $defaults ) { return $out; } + + protected function quote_comma_list_elements( $comma_list ) { + return "'" . implode( "', '", explode( ',', $comma_list ) ) . "'"; + } } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index 5d82234e32..96e18b5862 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -1,4 +1,4 @@ - register_taxonomy( '{{slug}}', array( '{{post_types}}' ), array( + register_taxonomy( '{{slug}}', array( {{post_types}} ), array( 'hierarchical' => false, 'public' => true, 'show_in_nav_menus' => true, From fcf449dd9b4c0c740843f5a7a7b711cec52f179e Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Thu, 23 May 2013 10:49:18 -0700 Subject: [PATCH 1712/4858] Restore accidentally deleted man page. --- man/core-update.1 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/man/core-update.1 b/man/core-update.1 index e69de29bb2..cb5848fb20 100644 --- a/man/core-update.1 +++ b/man/core-update.1 @@ -0,0 +1,37 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-CORE\-UPDATE" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-core\-update\fR \- Update WordPress\. +. +.SH "SYNOPSIS" +wp core update [\fIzip\fR] [\-\-version=\fIversion\fR] [\-\-force] +. +.SH "OPTIONS" +. +.TP +\fB\-\-version=\fR\fInew_version\fR [package/zip]: +. +.IP +When passed, updates to new_version, optionally using package/zip as input\. +. +.TP +\fB\-\-force\fR: +. +.IP +Will update even when current WP version < passed version\. Use with caution\. +. +.SH "EXAMPLES" +. +.nf + +wp core update + +wp core update \-\-version=3\.4 \.\./latest\.zip + +wp core update \-\-version=3\.1 \-\-force +. +.fi + From fbdb6c5792b363bada7d57b4fe3c26bb23c833d8 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Thu, 23 May 2013 10:49:43 -0700 Subject: [PATCH 1713/4858] Remove unnecessary comment. --- features/scaffold.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index e4d4fe3a8a..cebd1ff7d5 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -54,7 +54,6 @@ Feature: Wordpress code scaffolding __( 'Zombie speeds', 'zombieland' """ - # Test for multiple post types @tax Scenario: Scaffold a Custom Taxonomy and attach it to multiple post types Given a WP install From 12b9be1b0a31dba18db5f8400f080710718e8b27 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 24 May 2013 15:43:11 +0300 Subject: [PATCH 1714/4858] introduce WP_CLI\Loggers namespace --- php/WP_CLI/Loggers/Quiet.php | 30 +++++++++++++++++++++++++++++ php/WP_CLI/Loggers/Regular.php | 31 ++++++++++++++++++++++++++++++ php/WP_CLI/Runner.php | 25 ++++++++++++++++++------ php/class-wp-cli.php | 35 ++++++++++++++++------------------ php/utils.php | 2 +- 5 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 php/WP_CLI/Loggers/Quiet.php create mode 100644 php/WP_CLI/Loggers/Regular.php diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php new file mode 100644 index 0000000000..d080815c5b --- /dev/null +++ b/php/WP_CLI/Loggers/Quiet.php @@ -0,0 +1,30 @@ +<?php + +namespace WP_CLI\Loggers; + +class Quiet { + + private $colorize; + + function __construct( $colorize ) { + $this->colorize = $colorize; + } + + function line( $message ) { + // nothing + } + + function success( $message, $label ) { + // nothing + } + + function warning( $message, $label ) { + // nothing + } + + function error( $message, $label ) { + $msg = '%R' . $label . ': %n' . \WP_CLI::error_to_string( $message ); + fwrite( STDERR, \cli\Colors::colorize( $msg . "\n", $this->colorize ) ); + } +} + diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php new file mode 100644 index 0000000000..bca7f10e74 --- /dev/null +++ b/php/WP_CLI/Loggers/Regular.php @@ -0,0 +1,31 @@ +<?php + +namespace WP_CLI\Loggers; + +class Regular { + + private $colorize; + + function __construct( $colorize ) { + $this->colorize = $colorize; + } + + function line( $message, $handle = STDOUT ) { + fwrite( $handle, \cli\Colors::colorize( $message . "\n", $this->colorize ) ); + } + + function success( $message, $label ) { + $this->line( '%G' . $label . ': %n' . $message ); + } + + function warning( $message, $label ) { + $msg = '%C' . $label . ': %n' . \WP_CLI::error_to_string( $message ); + $this->line( $msg, STDERR ); + } + + function error( $message, $label ) { + $msg = '%R' . $label . ': %n' . \WP_CLI::error_to_string( $message ); + $this->line( $msg, STDERR ); + } +} + diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 1079637166..e312e14d2e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -229,6 +229,24 @@ private function back_compat_conversions() { } } + private function init_logger() { + if ( isset( $this->assoc_args['no-color'] ) ) { + $color = false; + unset( $this->assoc_args['no-color'] ); + } elseif ( 'auto' === $this->config['color'] ) { + $color = ! \cli\Shell::isPiped(); + } else { + $color = $this->config['color']; + } + + if ( $this->config['quiet'] ) + $logger = new \WP_CLI\Loggers\Quiet( $color ); + else + $logger = new \WP_CLI\Loggers\Regular( $color ); + + WP_CLI::set_logger( $logger ); + } + public function before_wp_load() { $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -250,12 +268,7 @@ public function before_wp_load() { self::split_special( $this->assoc_args, $this->config, $config_spec ); - if ( isset( $this->assoc_args['no-color'] ) ) { - $this->config['color'] = false; - unset( $this->assoc_args['no-color'] ); - } elseif ( 'auto' === $this->config['color'] ) { - $this->config['color'] = ! \cli\Shell::isPiped(); - } + $this->init_logger(); // Handle --version parameter if ( isset( $this->assoc_args['version'] ) && empty( $this->arguments ) ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1a47614f1d..0cc024c889 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -12,6 +12,8 @@ class WP_CLI { public static $runner; + private static $logger; + private static $man_dirs = array(); /** @@ -27,6 +29,15 @@ static function init() { self::$runner = new WP_CLI\Runner; } + /** + * Set the logger instance. + * + * @param object $logger + */ + static function set_logger( $logger ) { + self::$logger = $logger; + } + /** * Add a command to the wp-cli list of commands * @@ -91,25 +102,13 @@ static function get_man_dirs() { return self::$man_dirs; } - /** - * Display a message in the cli - * - * @param string $message - */ - static function out( $message, $handle = STDOUT ) { - if ( self::get_config('quiet') ) - return; - - fwrite( $handle, \cli\Colors::colorize( $message, self::get_config('color') ) ); - } - /** * Display a message in the CLI and end with a newline * * @param string $message */ static function line( $message = '' ) { - self::out( $message . "\n" ); + self::$logger->line( $message ); } /** @@ -120,8 +119,7 @@ static function line( $message = '' ) { */ static function error( $message, $label = 'Error' ) { if ( ! isset( self::$runner->assoc_args[ 'completions' ] ) ) { - $msg = '%R' . $label . ': %n' . self::error_to_string( $message ) . "\n"; - fwrite( STDERR, \cli\Colors::colorize( $msg, self::get_config('color') ) ); + self::$logger->error( $message, $label ); } exit(1); @@ -134,7 +132,7 @@ static function error( $message, $label = 'Error' ) { * @param string $label */ static function success( $message, $label = 'Success' ) { - self::line( '%G' . $label . ': %n' . $message ); + self::$logger->success( $message, $label ); } /** @@ -144,8 +142,7 @@ static function success( $message, $label = 'Success' ) { * @param string $label */ static function warning( $message, $label = 'Warning' ) { - $msg = '%C' . $label . ': %n' . self::error_to_string( $message ); - self::out( $msg . "\n", STDERR ); + self::$logger->warning( $message, $label ); } /** @@ -153,7 +150,7 @@ static function warning( $message, $label = 'Warning' ) { */ static function confirm( $question, $assoc_args ) { if ( !isset( $assoc_args['yes'] ) ) { - self::out( $question . " [y/n] " ); + echo $question . " [y/n] "; $answer = trim( fgets( STDIN ) ); diff --git a/php/utils.php b/php/utils.php index 65614d3271..e9cad0bd73 100644 --- a/php/utils.php +++ b/php/utils.php @@ -260,7 +260,7 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria */ function format_items( $format, $items, $fields ) { if ( 'ids' == $format ) - \WP_CLI::out( implode( ' ', $items ) ); + echo implode( ' ', $items ); if ( ! is_array( $fields ) ) $fields = explode( ',', $fields ); From e085ceb25a0d621ec80f14e64c2f4dc3b268927a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 24 May 2013 16:29:23 +0300 Subject: [PATCH 1715/4858] add back WP_CLI::out(), just to prevent fatal errors --- php/class-wp-cli.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0cc024c889..d30f56ae33 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -265,6 +265,11 @@ public static function run_command( $args, $assoc_args = array() ) { } } + // back-compat + static function out( $str ) { + echo $str; + } + // back-compat static function addCommand( $name, $class ) { trigger_error( sprintf( 'wp %s: %s is deprecated. use WP_CLI::add_command() instead.', From 77e4a4ed91dfdc772474d8be590034e2803ddbde Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Fri, 24 May 2013 08:46:13 -0700 Subject: [PATCH 1716/4858] add an EXAMPLES section that features the --post_types parameter --- man-src/scaffold-taxonomy.txt | 4 ++++ man/scaffold-taxonomy.1 | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt index f3e9a892b7..f739fb1f64 100644 --- a/man-src/scaffold-taxonomy.txt +++ b/man-src/scaffold-taxonomy.txt @@ -25,3 +25,7 @@ STDOUT. * `--raw`: Just generate the `register_taxonomy()` call and nothing else. + +## EXAMPLES + + wp scaffold taxonomy venue --post_types=event,presentation diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index ec4586af27..84a1a79002 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -46,4 +46,12 @@ Create a file in the given plugin\'s directory, instead of sending to STDOUT\. . .IP Just generate the \fBregister_taxonomy()\fR call and nothing else\. +. +.SH "EXAMPLES" +. +.nf + +wp scaffold taxonomy venue \-\-post_types=event,presentation +. +.fi From 443ef23fed256098f7719524e8a47755e5307eb9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 25 May 2013 01:36:07 +0300 Subject: [PATCH 1717/4858] Loggers\Regular: don't expose $handle parameter --- php/WP_CLI/Loggers/Regular.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index bca7f10e74..aa18dd0829 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -10,22 +10,26 @@ function __construct( $colorize ) { $this->colorize = $colorize; } - function line( $message, $handle = STDOUT ) { + private function _line( $message, $handle = STDOUT ) { fwrite( $handle, \cli\Colors::colorize( $message . "\n", $this->colorize ) ); } + function line( $message ) { + $this->_line( $message ); + } + function success( $message, $label ) { $this->line( '%G' . $label . ': %n' . $message ); } function warning( $message, $label ) { $msg = '%C' . $label . ': %n' . \WP_CLI::error_to_string( $message ); - $this->line( $msg, STDERR ); + $this->_line( $msg, STDERR ); } function error( $message, $label ) { $msg = '%R' . $label . ': %n' . \WP_CLI::error_to_string( $message ); - $this->line( $msg, STDERR ); + $this->_line( $msg, STDERR ); } } From 71d60af8c7603f84038049e7fa400921903f5de9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 25 May 2013 01:42:56 +0300 Subject: [PATCH 1718/4858] keep error_to_string() calls inside WP_CLI They assume WP is loaded, by calling is_wp_error(). --- php/WP_CLI/Loggers/Quiet.php | 2 +- php/WP_CLI/Loggers/Regular.php | 4 ++-- php/class-wp-cli.php | 26 +++++++++++++------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index d080815c5b..06a404bb50 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -23,7 +23,7 @@ function warning( $message, $label ) { } function error( $message, $label ) { - $msg = '%R' . $label . ': %n' . \WP_CLI::error_to_string( $message ); + $msg = '%R' . $label . ': %n' . $message; fwrite( STDERR, \cli\Colors::colorize( $msg . "\n", $this->colorize ) ); } } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index aa18dd0829..65104db231 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -23,12 +23,12 @@ function success( $message, $label ) { } function warning( $message, $label ) { - $msg = '%C' . $label . ': %n' . \WP_CLI::error_to_string( $message ); + $msg = '%C' . $label . ': %n' . $message; $this->_line( $msg, STDERR ); } function error( $message, $label ) { - $msg = '%R' . $label . ': %n' . \WP_CLI::error_to_string( $message ); + $msg = '%R' . $label . ': %n' . $message; $this->_line( $msg, STDERR ); } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d30f56ae33..c07c602f8f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -112,37 +112,37 @@ static function line( $message = '' ) { } /** - * Display an error in the CLI and end with a newline + * Display a success in the CLI and end with a newline * * @param string $message * @param string $label */ - static function error( $message, $label = 'Error' ) { - if ( ! isset( self::$runner->assoc_args[ 'completions' ] ) ) { - self::$logger->error( $message, $label ); - } - - exit(1); + static function success( $message, $label = 'Success' ) { + self::$logger->success( $message, $label ); } /** - * Display a success in the CLI and end with a newline + * Display a warning in the CLI and end with a newline * * @param string $message * @param string $label */ - static function success( $message, $label = 'Success' ) { - self::$logger->success( $message, $label ); + static function warning( $message, $label = 'Warning' ) { + self::$logger->warning( self::error_to_string( $message ), $label ); } /** - * Display a warning in the CLI and end with a newline + * Display an error in the CLI and end with a newline * * @param string $message * @param string $label */ - static function warning( $message, $label = 'Warning' ) { - self::$logger->warning( $message, $label ); + static function error( $message, $label = 'Error' ) { + if ( ! isset( self::$runner->assoc_args[ 'completions' ] ) ) { + self::$logger->error( self::error_to_string( $message ), $label ); + } + + exit(1); } /** From 4b15043008fa053ea33e68ff1e1c70ba7733cc98 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 25 May 2013 02:11:12 +0300 Subject: [PATCH 1719/4858] don't use is_wp_error() in error_to_string() We want to be able to use it without WP being installed. --- php/class-wp-cli.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index c07c602f8f..69199003d2 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -196,11 +196,13 @@ static function print_value( $value, $assoc_args = array() ) { * @return string */ static function error_to_string( $errors ) { - if( is_string( $errors ) ) { + if ( is_string( $errors ) ) { return $errors; - } elseif( is_wp_error( $errors ) && $errors->get_error_code() ) { - foreach( $errors->get_error_messages() as $message ) { - if( $errors->get_error_data() ) + } + + if ( is_object( $errors ) && is_a( $errors, 'WP_Error' ) ) { + foreach ( $errors->get_error_messages() as $message ) { + if ( $errors->get_error_data() ) return $message . ' ' . $errors->get_error_data(); else return $message; From 5cacbcfd2c3bf580a00612111945c6b870e59d38 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Fri, 24 May 2013 18:22:52 -0700 Subject: [PATCH 1720/4858] combine similar custom taxonomy tests --- features/scaffold.feature | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index cebd1ff7d5..8449990c1d 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -37,33 +37,23 @@ Feature: Wordpress code scaffolding # Test for all flags but --label, --theme, --plugin and --raw @tax - Scenario: Scaffold a Custom Taxonomy and attach it to a CPT zombie that is prefixed and has a text domain + Scenario: Scaffold a Custom Taxonomy and attach it to CPTs including one that is prefixed and has a text domain Given a WP install - When I run `wp scaffold taxonomy zombie-speed --post_types="prefix-zombie" --textdomain=zombieland` + When I run `wp scaffold taxonomy zombie-speed --post_types="prefix-zombie,wraith" --textdomain=zombieland` Then STDOUT should contain: """ __( 'Zombie speeds' """ And STDOUT should contain: """ - array( 'prefix-zombie' ) + array( 'prefix-zombie', 'wraith' ) """ And STDOUT should contain: """ __( 'Zombie speeds', 'zombieland' """ - @tax - Scenario: Scaffold a Custom Taxonomy and attach it to multiple post types - Given a WP install - - When I run `wp scaffold taxonomy perambulation-speed --post_types="zombie,wraith" --textdomain=zombieland` - Then STDOUT should contain: - """ - array( 'zombie', 'wraith' ) - """ - @tax Scenario: Scaffold a Custom Taxonomy with label "Speed" Given a WP install From daff963bddae0d2e485790f9882e975a95eb18f7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 26 May 2013 19:57:09 +0300 Subject: [PATCH 1721/4858] clarify that only the bash code was copied from drush --- bin/wp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/wp b/bin/wp index 0120a18dea..f53faf4137 100755 --- a/bin/wp +++ b/bin/wp @@ -1,6 +1,6 @@ #!/usr/bin/env sh # -# This script has been adapted from the drush wrapper script +# This wrapper script has been adapted from the equivalent drush wrapper # and 99.9% of all credit should go to the authors of that project: # http://drupal.org/project/drush # And 0.09% to the author of this project: From 85d4d0c8362997ebe6f552408f82f108921c91f8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 27 May 2013 23:37:22 +0300 Subject: [PATCH 1722/4858] TableIterator: rename 'limit' parameter to 'chunk_size', so that it's not confused with SQL LIMIT see https://github.com/wp-cli/wp-cli/commit/b1bd56dd5e2bdc106603c1034affc6a953b5e6b1#commitcomment-3296894 --- php/WP_CLI/Iterators/Query.php | 12 ++++++------ php/WP_CLI/Iterators/Table.php | 5 ++--- php/commands/search-replace.php | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Iterators/Query.php b/php/WP_CLI/Iterators/Query.php index 1577e99ab8..016961a0a1 100644 --- a/php/WP_CLI/Iterators/Query.php +++ b/php/WP_CLI/Iterators/Query.php @@ -9,7 +9,7 @@ */ class Query implements \Iterator { - private $limit = 500; + private $chunk_size; private $query = ''; private $global_index = 0; @@ -30,17 +30,17 @@ class Query implements \Iterator { * </code> * * @param string $query The query as a string. It shouldn't include any LIMIT clauses - * @param number $limit How many rows to retrieve at once; default value is 500 (optional) + * @param number $chunk_size How many rows to retrieve at once; default value is 500 (optional) */ - public function __construct( $query, $limit = 500 ) { + public function __construct( $query, $chunk_size = 500 ) { $this->query = $query; - $this->limit = $limit; + $this->chunk_size = $chunk_size; $this->db = $GLOBALS['wpdb']; } private function load_items_from_db() { - $query = $this->query . sprintf( ' LIMIT %d OFFSET %d', $this->limit, $this->offset ); + $query = $this->query . sprintf( ' LIMIT %d OFFSET %d', $this->chunk_size, $this->offset ); $this->results = $this->db->get_results( $query ); if ( !$this->results ) { @@ -51,7 +51,7 @@ private function load_items_from_db() { } } - $this->offset += $this->limit; + $this->offset += $this->chunk_size; return true; } diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 450301ae2f..6e05cf9ed9 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -44,6 +44,7 @@ function __construct( $args = array() ) { 'fields' => array( '*' ), 'where' => array(), 'table' => null, + 'chunk_size' => 500 ); $table = $args['table']; $args = array_merge( $defaults, $args ); @@ -53,9 +54,7 @@ function __construct( $args = array() ) { $where_sql = $conditions? " WHERE $conditions" : ''; $query = "SELECT $fields FROM $table $where_sql"; - $limit = isset( $args['limit'] ) ? $args['limit'] : 500; - - parent::__construct( $query, $limit ); + parent::__construct( $query, $args['chunk_size'] ); } private static function build_fields( $fields ) { diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index a08af875c1..e6bcd5f940 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -67,7 +67,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry 'table' => $table, 'fields' => array( $primary_key, $col ), 'where' => $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', - 'limit' => 1000 + 'chunk_size' => 1000 ); $it = new \WP_CLI\Iterators\Table( $args ); From d3515347c2ed7d96746b151196761084117d8e46 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Mon, 27 May 2013 15:18:21 -0700 Subject: [PATCH 1723/4858] Add a test for large search/replace failure. --- features/search-replace.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index d5bf8ff4a1..f18dd3635f 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -14,3 +14,15 @@ Feature: Do global search/replace """ guid """ + + Scenario: Large search/replace + Given a WP install + + And I run `wp post generate --count=1200` + + And I run `wp search-replace $( wp option get siteurl ) testreplacement` + Then STDOUT should be a table containing rows: + """ + Table Column Replacements + wp_posts guid 1202 + """ From 27697bc455cf95472d9b456aaf5706cda8fb908e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 28 May 2013 01:40:57 +0300 Subject: [PATCH 1724/4858] make back_compat_conversion() method static --- php/WP_CLI/Runner.php | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e312e14d2e..cd60aefba0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -197,36 +197,39 @@ public function get_wp_config_code() { } // Transparently convert old syntaxes - private function back_compat_conversions() { + private static function back_compat_conversions( $r ) { + list( $args, $assoc_args ) = $r; + // foo --help -> help foo - if ( isset( $this->assoc_args['help'] ) ) { - array_unshift( $this->arguments, 'help' ); - unset( $this->assoc_args['help'] ); + if ( isset( $assoc_args['help'] ) ) { + array_unshift( $args, 'help' ); + unset( $assoc_args['help'] ); } // {plugin|theme} update --all -> {plugin|theme} update-all - if ( count( $this->arguments ) > 1 && in_array( $this->arguments[0], array( 'plugin', 'theme' ) ) - && $this->arguments[1] == 'update' - && isset( $this->assoc_args['all'] ) + if ( count( $args ) > 1 && in_array( $args[0], array( 'plugin', 'theme' ) ) + && $args[1] == 'update' && isset( $assoc_args['all'] ) ) { - $this->arguments[1] = 'update-all'; - unset( $this->assoc_args['all'] ); + $args[1] = 'update-all'; + unset( $assoc_args['all'] ); } // {post|user} list --ids -> {post|user} list --format=ids - if ( count( $this->arguments ) > 1 && in_array( $this->arguments[0], array( 'post', 'user' ) ) - && $this->arguments[1] == 'list' - && isset( $this->assoc_args['ids'] ) + if ( count( $args ) > 1 && in_array( $args[0], array( 'post', 'user' ) ) + && $args[1] == 'list' + && isset( $assoc_args['ids'] ) ) { - $this->assoc_args['format'] = 'ids'; - unset( $this->assoc_args['ids'] ); + $assoc_args['format'] = 'ids'; + unset( $assoc_args['ids'] ); } // --json -> --format=json - if ( isset( $this->assoc_args['json'] ) ) { - $this->assoc_args['format'] = 'json'; - unset( $this->assoc_args['json'] ); + if ( isset( $assoc_args['json'] ) ) { + $assoc_args['format'] = 'json'; + unset( $assoc_args['json'] ); } + + return array( $args, $assoc_args ); } private function init_logger() { @@ -248,11 +251,8 @@ private function init_logger() { } public function before_wp_load() { - $r = Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ); - - list( $this->arguments, $this->assoc_args ) = $r; - - $this->back_compat_conversions(); + list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( + Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ) ); $config_spec = Utils\get_config_spec(); From 41f8ffe5cdbd1f9e44fb09391a1a89e5eacc04ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 28 May 2013 02:03:55 +0300 Subject: [PATCH 1725/4858] alias `wp plugin scaffold` to `wp scaffold plugin` --- features/scaffold.feature | 2 +- php/WP_CLI/Runner.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 8449990c1d..6143dd8deb 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -16,7 +16,7 @@ Feature: Wordpress code scaffolding And I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} - When I run `wp scaffold plugin zombieland --plugin_name="Welcome to Zombieland" --activate` + When I run `wp plugin scaffold zombieland --plugin_name="Welcome to Zombieland" --activate` Then STDOUT should not be empty And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index cd60aefba0..245711cb78 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -214,6 +214,11 @@ private static function back_compat_conversions( $r ) { unset( $assoc_args['all'] ); } + // plugin scaffold -> scaffold plugin + if ( array( 'plugin', 'scaffold' ) == array_slice( $args, 0, 2 ) ) { + list( $args[0], $args[1] ) = array( $args[1], $args[0] ); + } + // {post|user} list --ids -> {post|user} list --format=ids if ( count( $args ) > 1 && in_array( $args[0], array( 'post', 'user' ) ) && $args[1] == 'list' From fba2f4ee98b2f635ec630430c33bb797fdff64e0 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Mon, 27 May 2013 18:56:14 -0700 Subject: [PATCH 1726/4858] Use the STDOUT saving technique so tests can pass. The wp aliases in my PATH made me oblivious before... --- features/search-replace.feature | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index f18dd3635f..fa11307e74 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,12 +15,31 @@ Feature: Do global search/replace guid """ - Scenario: Large search/replace + Scenario: Small guid search/replace Given a WP install + When I run `wp option get siteurl` + + And save STDOUT as {SITEURL} + + And I run `wp post generate --count=100` + + And I run `wp search-replace {SITEURL} testreplacement` + Then STDOUT should be a table containing rows: + """ + Table Column Replacements + wp_posts guid 102 + """ + Scenario: Large guid search/replace + Given a WP install + + When I run `wp option get siteurl` + + And save STDOUT as {SITEURL} + And I run `wp post generate --count=1200` - And I run `wp search-replace $( wp option get siteurl ) testreplacement` + And I run `wp search-replace {SITEURL} testreplacement` Then STDOUT should be a table containing rows: """ Table Column Replacements From 132bf3799569db79a2f6ffb5d78cbec8345eaf7c Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Mon, 27 May 2013 20:17:02 -0700 Subject: [PATCH 1727/4858] Add a test for the case when the replacement contains the search string. In this case the current code works, but alternatives I was considering might not. Also removed the small test - that case is already covered. --- features/search-replace.feature | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index fa11307e74..2d946ae211 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,22 +15,22 @@ Feature: Do global search/replace guid """ - Scenario: Small guid search/replace + Scenario: Large guid search/replace where replacement contains search Given a WP install When I run `wp option get siteurl` And save STDOUT as {SITEURL} - And I run `wp post generate --count=100` + And I run `wp post generate --count=1200` - And I run `wp search-replace {SITEURL} testreplacement` + And I run `wp search-replace {SITEURL} {SITEURL}/subdir` Then STDOUT should be a table containing rows: """ Table Column Replacements - wp_posts guid 102 + wp_posts guid 1202 """ - Scenario: Large guid search/replace + Scenario: Large guid search/replace where replacement does not contain search Given a WP install When I run `wp option get siteurl` @@ -39,7 +39,7 @@ Feature: Do global search/replace And I run `wp post generate --count=1200` - And I run `wp search-replace {SITEURL} testreplacement` + And I run `wp search-replace {SITEURL} http://newdomain.com` Then STDOUT should be a table containing rows: """ Table Column Replacements From 45770c2d2fef4da9021ef458e4ef55504a7b5872 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Mon, 27 May 2013 20:41:44 -0700 Subject: [PATCH 1728/4858] Adjust chunking based on whether the replacement contains the search string. --- php/commands/search-replace.php | 48 ++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e6bcd5f940..b32b9798a6 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -63,31 +63,41 @@ public function __invoke( $args, $assoc_args ) { private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { global $wpdb; - $args = array( - 'table' => $table, - 'fields' => array( $primary_key, $col ), - 'where' => $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', - 'chunk_size' => 1000 - ); + if ( strpos( $new, $old ) !== false ) + $new_contains_old = true; + else + $new_contains_old = false; - $it = new \WP_CLI\Iterators\Table( $args ); + $fields = $primary_key . ', ' . $col; + $conditions = $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"'; + $chunk_size = 1000; + $offset = 0; + + $chunk_query = "SELECT $fields FROM $table WHERE $conditions LIMIT $chunk_size OFFSET $offset"; $count = 0; - foreach ( $it as $row ) { - if ( '' === $row->$col ) - continue; + while ( $chunk = $wpdb->get_results( $chunk_query ) ) { + foreach ( $chunk as $row ) { + if ( '' === $row->$col ) + continue; - $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); + $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); + + if ( $dry_run ) { + if ( $value != $row->$col ) + $count++; + } else { + $count += $wpdb->update( $table, + array( $col => $value ), + array( $primary_key => $row->$primary_key ) + ); + } + } - if ( $dry_run ) { - if ( $value != $row->$col ) - $count++; - } else { - $count += $wpdb->update( $table, - array( $col => $value ), - array( $primary_key => $row->$primary_key ) - ); + if ( $new_contains_old ) { + $offset += $chunk_size; + $chunk_query = "SELECT $fields FROM $table WHERE $conditions LIMIT $chunk_size OFFSET $offset"; } } From ac13794f742ede999054a6a74ae15b5f48b15967 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 28 May 2013 03:03:41 +0300 Subject: [PATCH 1729/4858] behat: use bash function to allow inner calls to `wp` (bash aliases seem to be available only in interactive mode) --- features/bootstrap/FeatureContext.php | 2 +- features/bootstrap/Process.php | 8 +++++++- features/user.feature | 4 +--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 76d2343dbb..e0478d2102 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -31,7 +31,7 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { public $variables = array(); private static function wp_cli( $command ) { - return __DIR__ . "/../../bin/wp $command"; + return "wp $command"; } // We cache the results of `wp core download` to improve test performance diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 0776a28653..4dddf4225b 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -27,7 +27,13 @@ public function run( $subdir = '' ) { 2 => array( 'pipe', 'w' ), ); - $proc = proc_open( $this->command, $descriptors, $pipes, $cwd ); + // Ensure we're using the expected `wp` binary + $env = sprintf( 'function wp() { %s "$@"; }; %s', + realpath( __DIR__ . "/../../bin/wp" ), $this->command ); + + $wrapper = sprintf( 'bash -c %s', escapeshellarg( $env ) ); + + $proc = proc_open( $wrapper, $descriptors, $pipes, $cwd ); $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); diff --git a/features/user.feature b/features/user.feature index 1e8131e583..8743d12730 100644 --- a/features/user.feature +++ b/features/user.feature @@ -23,9 +23,7 @@ Feature: Manage WordPress users Given a WP install # Delete all users - When I run `wp user list --format=ids` - And save STDOUT as {USER_IDS} - And I run `wp user delete {USER_IDS}` + When I run `wp user delete $(wp user list --format=ids)` And I run `wp user list --format=ids` Then STDOUT should be empty From 72f6a58cfaf415abef6b601ee05fc8a155697a1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 28 May 2013 03:38:41 +0300 Subject: [PATCH 1730/4858] behat: don't hardcode `wp ` in the step definitions --- features/bootstrap/FeatureContext.php | 20 ++++++++------------ features/steps/basic_steps.php | 16 +++++----------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index e0478d2102..20114ddefb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -30,10 +30,6 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { public $variables = array(); - private static function wp_cli( $command ) { - return "wp $command"; - } - // We cache the results of `wp core download` to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests private static function cache_wp_files() { @@ -42,8 +38,8 @@ private static function cache_wp_files() { if ( is_readable( self::$cache_dir . '/wp-config-sample.php' ) ) return; - $cmd = Utils\esc_cmd( 'core download --force --path=%s', self::$cache_dir ); - Process::create( self::wp_cli( $cmd ) )->run_check(); + $cmd = Utils\esc_cmd( 'wp core download --force --path=%s', self::$cache_dir ); + Process::create( $cmd )->run_check(); } /** @@ -53,16 +49,16 @@ public static function prepare( SuiteEvent $event ) { self::cache_wp_files(); self::$additional_args = array( - 'core config' => self::$db_settings, + 'wp core config' => self::$db_settings, - 'core install' => array( + 'wp core install' => array( 'url' => 'http://example.com', 'title' => 'WP CLI Site', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' ), - 'core install-network' => array( + 'wp core install-network' => array( 'title' => 'WP CLI Network' ) ); @@ -165,7 +161,7 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - return Process::create( self::wp_cli( $command ), $this->install_dir ); + return Process::create( $command, $this->install_dir ); } public function move_files( $src, $dest ) { @@ -191,9 +187,9 @@ public function wp_install( $subdir = '' ) { $this->create_empty_dir(); $this->download_wordpress_files( $subdir ); - $this->proc( 'core config', array( 'dbprefix' => $subdir ? $subdir : 'wp_' ) )->run_check( $subdir ); + $this->proc( 'wp core config', array( 'dbprefix' => $subdir ? $subdir : 'wp_' ) )->run_check( $subdir ); - $this->proc( 'core install' )->run_check( $subdir ); + $this->proc( 'wp core install' )->run_check( $subdir ); } } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index f838df65c0..b2cab9d3bf 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -37,7 +37,7 @@ function ( $world ) { $steps->Given( '/^wp-config\.php$/', function ( $world ) { - $world->proc( 'core config' )->run_check(); + $world->proc( 'wp core config' )->run_check(); } ); @@ -62,7 +62,7 @@ function ( $world, $subdir ) { $steps->Given( '/^a WP multisite install$/', function ( $world ) { $world->wp_install(); - $world->proc( 'core install-network' )->run_check(); + $world->proc( 'wp core install-network' )->run_check(); } ); @@ -106,20 +106,14 @@ function ( $world ) { } ); -$steps->When( '/^I (run|try) `wp`$/', - function ( $world, $mode ) { - $world->result = invoke_proc( $world->proc( '' ), $mode ); - } -); - -$steps->When( '/^I (run|try) `wp (.+)`$/', +$steps->When( '/^I (run|try) `([^`]+)`$/', function ( $world, $mode, $cmd ) { $cmd = $world->replace_variables( $cmd ); $world->result = invoke_proc( $world->proc( $cmd ), $mode ); } ); -$steps->When( "/^I (run|try) `wp (.+)` from '([^\s]+)'$/", +$steps->When( "/^I (run|try) `([^`]+)` from '([^\s]+)'$/", function ( $world, $mode, $cmd, $subdir ) { $cmd = $world->replace_variables( $cmd ); $world->result = invoke_proc( $world->proc( $cmd ), $mode, $subdir ); @@ -141,7 +135,7 @@ function ( $world ) { if ( !isset( $world->variables['DOWNLOADED_IMAGE'] ) ) throw new \Exception( 'Cached image not available.' ); - $world->result = $world->proc( 'media import ' . $world->variables['DOWNLOADED_IMAGE'] . ' --post_id=1 --featured_image' )->run(); + $world->result = $world->proc( 'wp media import ' . $world->variables['DOWNLOADED_IMAGE'] . ' --post_id=1 --featured_image' )->run(); } ); From 611afd7e6fe46d7fe507278e73b411681ac5afae Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Tue, 28 May 2013 06:56:53 -0700 Subject: [PATCH 1731/4858] Generate only as many posts as needed to test chunking. --- features/search-replace.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 2d946ae211..3c3b2ce7cd 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -22,13 +22,13 @@ Feature: Do global search/replace And save STDOUT as {SITEURL} - And I run `wp post generate --count=1200` + And I run `wp post generate --count=1000` And I run `wp search-replace {SITEURL} {SITEURL}/subdir` Then STDOUT should be a table containing rows: """ Table Column Replacements - wp_posts guid 1202 + wp_posts guid 1002 """ Scenario: Large guid search/replace where replacement does not contain search Given a WP install @@ -37,11 +37,11 @@ Feature: Do global search/replace And save STDOUT as {SITEURL} - And I run `wp post generate --count=1200` + And I run `wp post generate --count=1000` And I run `wp search-replace {SITEURL} http://newdomain.com` Then STDOUT should be a table containing rows: """ Table Column Replacements - wp_posts guid 1202 + wp_posts guid 1002 """ From 05a89293a491ac9a476863b6b972d28a03b93735 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Tue, 28 May 2013 21:09:44 -0700 Subject: [PATCH 1732/4858] Revert "Adjust chunking based on whether the replacement contains the search string." This reverts commit 45770c2d2fef4da9021ef458e4ef55504a7b5872. --- php/commands/search-replace.php | 48 +++++++++++++-------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b32b9798a6..e6bcd5f940 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -63,41 +63,31 @@ public function __invoke( $args, $assoc_args ) { private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { global $wpdb; - if ( strpos( $new, $old ) !== false ) - $new_contains_old = true; - else - $new_contains_old = false; + $args = array( + 'table' => $table, + 'fields' => array( $primary_key, $col ), + 'where' => $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', + 'chunk_size' => 1000 + ); - $fields = $primary_key . ', ' . $col; - $conditions = $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"'; - $chunk_size = 1000; - $offset = 0; - - $chunk_query = "SELECT $fields FROM $table WHERE $conditions LIMIT $chunk_size OFFSET $offset"; + $it = new \WP_CLI\Iterators\Table( $args ); $count = 0; - while ( $chunk = $wpdb->get_results( $chunk_query ) ) { - foreach ( $chunk as $row ) { - if ( '' === $row->$col ) - continue; + foreach ( $it as $row ) { + if ( '' === $row->$col ) + continue; - $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); - - if ( $dry_run ) { - if ( $value != $row->$col ) - $count++; - } else { - $count += $wpdb->update( $table, - array( $col => $value ), - array( $primary_key => $row->$primary_key ) - ); - } - } + $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); - if ( $new_contains_old ) { - $offset += $chunk_size; - $chunk_query = "SELECT $fields FROM $table WHERE $conditions LIMIT $chunk_size OFFSET $offset"; + if ( $dry_run ) { + if ( $value != $row->$col ) + $count++; + } else { + $count += $wpdb->update( $table, + array( $col => $value ), + array( $primary_key => $row->$primary_key ) + ); } } From 6196545ff8bd58f5b722f189acabbfe7c8820ceb Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Tue, 28 May 2013 21:46:44 -0700 Subject: [PATCH 1733/4858] Add a dry run test to make sure the iterator doesn't depend on updates. --- features/search-replace.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index 3c3b2ce7cd..3cf524dbdf 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -45,3 +45,19 @@ Feature: Do global search/replace Table Column Replacements wp_posts guid 1002 """ + + Scenario: Large guid search/replace dry run where replacement does not contain search + Given a WP install + + When I run `wp option get siteurl` + + And save STDOUT as {SITEURL} + + And I run `wp post generate --count=1000` + + And I run `wp search-replace --dry-run {SITEURL} http://newdomain.com` + Then STDOUT should be a table containing rows: + """ + Table Column Replacements + wp_posts guid 1002 + """ From b58290cde490548479e46bb41ad84c4d969dd673 Mon Sep 17 00:00:00 2001 From: Dylan Kuhn <dylan.k.kuhn@gmail.com> Date: Tue, 28 May 2013 21:47:55 -0700 Subject: [PATCH 1734/4858] Reduce chunk offset to account for updated rows. --- php/WP_CLI/Iterators/Query.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/php/WP_CLI/Iterators/Query.php b/php/WP_CLI/Iterators/Query.php index 016961a0a1..4fea0301ee 100644 --- a/php/WP_CLI/Iterators/Query.php +++ b/php/WP_CLI/Iterators/Query.php @@ -11,10 +11,12 @@ class Query implements \Iterator { private $chunk_size; private $query = ''; + private $count_query = ''; private $global_index = 0; private $index_in_results = 0; private $results = array(); + private $row_count = 0; private $offset = 0; private $db = null; private $depleted = false; @@ -34,12 +36,38 @@ class Query implements \Iterator { */ public function __construct( $query, $chunk_size = 500 ) { $this->query = $query; + + $this->count_query = preg_replace( '/^.*? FROM /', 'SELECT COUNT(*) FROM ', $query, 1, $replacements ); + if ( $replacements != 1 ) + $this->count_query = ''; + $this->chunk_size = $chunk_size; $this->db = $GLOBALS['wpdb']; } + /** + * Reduces the offset when the query row count shrinks + * + * In cases where the iterated rows are being updated such that they will no + * longer be returned by the original query, the offset must be reduced to + * iterate over all remaining rows. + */ + private function adjust_offset_for_shrinking_result_set() { + if ( empty( $this->count_query ) ) + return; + + $row_count = $this->db->get_var( $this->count_query ); + + if ( $row_count < $this->row_count ) + $this->offset -= $this->row_count - $row_count; + + $this->row_count = $row_count; + } + private function load_items_from_db() { + $this->adjust_offset_for_shrinking_result_set(); + $query = $this->query . sprintf( ' LIMIT %d OFFSET %d', $this->chunk_size, $this->offset ); $this->results = $this->db->get_results( $query ); From f2c94a4e329c3bd25892597fd8783850225aedeb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 29 May 2013 19:41:29 +0300 Subject: [PATCH 1735/4858] behat: change subprocess PATH, instead of creating a function see #475 --- features/bootstrap/Process.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 4dddf4225b..36ad7bcfd0 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -28,12 +28,9 @@ public function run( $subdir = '' ) { ); // Ensure we're using the expected `wp` binary - $env = sprintf( 'function wp() { %s "$@"; }; %s', - realpath( __DIR__ . "/../../bin/wp" ), $this->command ); - - $wrapper = sprintf( 'bash -c %s', escapeshellarg( $env ) ); - - $proc = proc_open( $wrapper, $descriptors, $pipes, $cwd ); + $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, array( + 'PATH' => realpath( __DIR__ . "/../../bin" ) . ':' . getenv( 'PATH' ) + ) ); $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); From f121dfac28e9268f55a03f911e8c2f366441ec46 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 29 May 2013 20:00:24 +0300 Subject: [PATCH 1736/4858] travis: move init script to separate file --- .travis.yml | 11 +---------- bin/ci/install_dependencies.sh | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) create mode 100755 bin/ci/install_dependencies.sh diff --git a/.travis.yml b/.travis.yml index d0a9cebc49..a2fc11f22c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,16 +13,7 @@ matrix: - php: 5.4 env: WP_VERSION=3.4.2 -before_script: - # install dependencies - - composer install --dev --no-interaction --prefer-source - - composer require d11wtq/boris=dev-master --no-interaction --prefer-source - - gem install ronn - # set up WP install - - bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ - # set up database - - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot - - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot +before_script: ./bin/ci/install_dependencies.sh script: vendor/bin/phpunit && vendor/bin/behat --format progress diff --git a/bin/ci/install_dependencies.sh b/bin/ci/install_dependencies.sh new file mode 100755 index 0000000000..38049100da --- /dev/null +++ b/bin/ci/install_dependencies.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# called by Travis CI + +set -ex + +# install dependencies +composer install --dev --no-interaction --prefer-source +composer require d11wtq/boris=dev-master --no-interaction --prefer-source +gem install ronn + +# set up WP install +./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ + +# set up database +mysql -e 'CREATE DATABASE wp_cli_test;' -uroot +mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot From a675de3f72d107bc1c4d5304fa295b30df14ecc8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 29 May 2013 20:12:54 +0300 Subject: [PATCH 1737/4858] travis: move main script to separate file --- .travis.yml | 4 ++-- bin/ci/run_build.sh | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100755 bin/ci/run_build.sh diff --git a/.travis.yml b/.travis.yml index a2fc11f22c..81e74cf684 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,8 @@ matrix: before_script: ./bin/ci/install_dependencies.sh -script: vendor/bin/phpunit && vendor/bin/behat --format progress - +script: ./bin/ci/run_build.sh + notifications: email: on_success: never diff --git a/bin/ci/run_build.sh b/bin/ci/run_build.sh new file mode 100755 index 0000000000..3ed2e35cdb --- /dev/null +++ b/bin/ci/run_build.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -ex + +vendor/bin/phpunit + +vendor/bin/behat --format progress From 7f7a9faab825bdeb2f8295e44b9c0cd0c8492894 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 29 May 2013 20:20:08 +0300 Subject: [PATCH 1738/4858] travis: set WITH_RONN env variable Also, tag behat tests that depend on the ronn gem. We don't care too much about which WP version is installed, so run the ronn tests only once. --- .travis.yml | 6 +++--- bin/ci/install_dependencies.sh | 5 ++++- bin/ci/run_build.sh | 6 +++++- features/help.feature | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 81e74cf684..138b44b662 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,13 @@ php: - 5.4 env: - - WP_VERSION=latest - - WP_VERSION=3.4.2 + - WP_VERSION=latest + - WP_VERSION=3.4.2 WITH_RONN=1 matrix: exclude: - php: 5.4 - env: WP_VERSION=3.4.2 + env: WP_VERSION=3.4.2 WITH_RONN=1 before_script: ./bin/ci/install_dependencies.sh diff --git a/bin/ci/install_dependencies.sh b/bin/ci/install_dependencies.sh index 38049100da..02b33c11b9 100755 --- a/bin/ci/install_dependencies.sh +++ b/bin/ci/install_dependencies.sh @@ -7,7 +7,10 @@ set -ex # install dependencies composer install --dev --no-interaction --prefer-source composer require d11wtq/boris=dev-master --no-interaction --prefer-source -gem install ronn + +if [ -n "$WITH_RONN" ]; then + gem install ronn +fi # set up WP install ./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ diff --git a/bin/ci/run_build.sh b/bin/ci/run_build.sh index 3ed2e35cdb..aed4ad0bf3 100755 --- a/bin/ci/run_build.sh +++ b/bin/ci/run_build.sh @@ -4,4 +4,8 @@ set -ex vendor/bin/phpunit -vendor/bin/behat --format progress +if [ -z "$WITH_RONN" ]; then + BEHAT_OPTS="--tags ~@ronn" +fi + +vendor/bin/behat --format progress $BEHAT_OPTS diff --git a/features/help.feature b/features/help.feature index 39ca944d8e..b23b898da3 100644 --- a/features/help.feature +++ b/features/help.feature @@ -31,6 +31,7 @@ Feature: Get help about WP-CLI commands Then the return code should be 1 And STDERR should not be empty + @ronn Scenario: Generating help for subcommands Given an empty directory When I run `wp help --gen option` @@ -39,6 +40,7 @@ Feature: Get help about WP-CLI commands generated option.1 """ + @ronn Scenario: Generating help for multisite-only subcommands Given an empty directory When I run `wp help --gen blog create` @@ -47,6 +49,7 @@ Feature: Get help about WP-CLI commands generated blog-create.1 """ + @ronn Scenario: Help for third-party commands Given a WP install And a wp-content/plugins/test-cli/test-help.txt file: From e594b0aadf3a5418e22c786d1b52ffab095ff20a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 29 May 2013 22:42:03 +0300 Subject: [PATCH 1739/4858] contributing: clarify workflow --- CONTRIBUTING.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7389047efd..e4b8ec7e95 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,19 @@ Contribute ========== -So you've got an awesome idea to throw into WP-CLI. Great! Please keep the following in mind: +So you've got an awesome idea to throw into WP-CLI. Great! Here's the process, in a nutshell: -* The best way to get feedback is by opening an issue or a pull request; if you think the code shouldn't be merged yet, just say so. -* If you're adding a new command or subcommand, please consider adding a functional test for it in the `features` directory. Also, please create the appropriate `.txt` file in the `man-src` directory. -* Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). +1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. +2. Make the code changes in your fork. +3. Open a pull request. + +It doesn't matter if the code isn't perfect. The idea is to get feedback early and iterate. + +If you're adding a new feature, please add one or more functional tests for it in the `features` directory. See below. + +Also, please create or update the appropriate `.txt` file in the `man-src` directory. See below. + +Lastly, please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). Generating man pages -------------------- From fbd1a9f35c06017999118f5056c2a4ad8080b701 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 01:20:35 +0300 Subject: [PATCH 1740/4858] behat: move utility functions to separate file --- features/bootstrap/support.php | 106 +++++++++++++++++++++++++++++++++ features/steps/basic_steps.php | 102 ------------------------------- 2 files changed, 106 insertions(+), 102 deletions(-) create mode 100644 features/bootstrap/support.php diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php new file mode 100644 index 0000000000..64a52bcad1 --- /dev/null +++ b/features/bootstrap/support.php @@ -0,0 +1,106 @@ +<?php + +// Utility functions used by Behat steps + +function compareContents( $expected, $actual ) { + if ( gettype( $expected ) != gettype( $actual ) ) { + return false; + } + + if ( is_object( $expected ) ) { + foreach ( get_object_vars( $expected ) as $name => $value ) { + if ( ! compareContents( $value, $actual->$name ) ) + return false; + } + } else if ( is_array( $expected ) ) { + foreach ( $expected as $key => $value ) { + if ( ! compareContents( $value, $actual[$key] ) ) + return false; + } + } else { + return $expected === $actual; + } + + return true; +} + +/** + * Compare two strings containing JSON to ensure that @a $actualJson contains at + * least what the JSON string @a $expectedJson contains. + * + * @return whether or not @a $actualJson contains @a $expectedJson + * @retval true @a $actualJson contains @a $expectedJson + * @retval false @a $actualJson does not contain @a $expectedJson + * + * @param[in] $actualJson the JSON string to be tested + * @param[in] $expectedJson the expected JSON string + * + * Examples: + * expected: {'a':1,'array':[1,3,5]} + * + * 1 ) + * actual: {'a':1,'b':2,'c':3,'array':[1,2,3,4,5]} + * return: true + * + * 2 ) + * actual: {'b':2,'c':3,'array':[1,2,3,4,5]} + * return: false + * element 'a' is missing from the root object + * + * 3 ) + * actual: {'a':0,'b':2,'c':3,'array':[1,2,3,4,5]} + * return: false + * the value of element 'a' is not 1 + * + * 4 ) + * actual: {'a':1,'b':2,'c':3,'array':[1,2,4,5]} + * return: false + * the contents of 'array' does not include 3 + */ +function checkThatJsonStringContainsJsonString( $actualJson, $expectedJson ) { + $actualValue = json_decode( $actualJson ); + $expectedValue = json_decode( $expectedJson ); + + if ( !$actualValue ) { + return false; + } + + return compareContents( $expectedValue, $actualValue ); +} + +/** + * Compare two strings to confirm $actualCSV contains $expectedCSV + * Both strings are expected to have headers for their CSVs. + * $actualCSV must match all data rows in $expectedCSV + * + * @return bool Whether $actualCSV contacts $expectedCSV + */ +function checkThatCsvStringContainsCsvString( $actualCSV, $expectedCSV ) { + $actualCSV = array_map( 'str_getcsv', explode( PHP_EOL, $actualCSV ) ); + $expectedCSV = array_map( 'str_getcsv', explode( PHP_EOL, $expectedCSV ) ); + + if ( empty( $actualCSV ) ) + return false; + + // Each sample must have headers + $actualHeaders = array_values( array_shift( $actualCSV ) ); + $expectedHeaders = array_values( array_shift( $expectedCSV ) ); + + // Each expectedCSV must exist somewhere in actualCSV in the proper column + $expectedResult = 0; + foreach ( $expectedCSV as $expected_row ) { + $expected_row = array_combine( $expectedHeaders, $expected_row ); + foreach ( $actualCSV as $actual_row ) { + + if ( count( $actualHeaders ) != count( $actual_row ) ) + continue; + + $actual_row = array_intersect_key( array_combine( $actualHeaders, $actual_row ), $expected_row ); + if ( $actual_row == $expected_row ) + $expectedResult++; + } + } + + return $expectedResult >= count( $expectedCSV ); +} + diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index b2cab9d3bf..c020b4873e 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -255,105 +255,3 @@ function ( $world, $path ) { } ); -/** - * Compare two strings containing JSON to ensure that @a $actualJson contains at - * least what the JSON string @a $expectedJson contains. - * - * @return whether or not @a $actualJson contains @a $expectedJson - * @retval true @a $actualJson contains @a $expectedJson - * @retval false @a $actualJson does not contain @a $expectedJson - * - * @param[in] $actualJson the JSON string to be tested - * @param[in] $expectedJson the expected JSON string - * - * Examples: - * expected: {'a':1,'array':[1,3,5]} - * - * 1) - * actual: {'a':1,'b':2,'c':3,'array':[1,2,3,4,5]} - * return: true - * - * 2) - * actual: {'b':2,'c':3,'array':[1,2,3,4,5]} - * return: false - * element 'a' is missing from the root object - * - * 3) - * actual: {'a':0,'b':2,'c':3,'array':[1,2,3,4,5]} - * return: false - * the value of element 'a' is not 1 - * - * 4) - * actual: {'a':1,'b':2,'c':3,'array':[1,2,4,5]} - * return: false - * the contents of 'array' does not include 3 - */ -function checkThatJsonStringContainsJsonString( $actualJson, $expectedJson ) { - $actualValue = json_decode( $actualJson ); - $expectedValue = json_decode( $expectedJson ); - - if ( !$actualValue ) { - return false; - } - - return compareContents( $expectedValue, $actualValue ); -} - -function compareContents( $expected, $actual ) { - if ( gettype( $expected ) != gettype( $actual ) ) { - return false; - } - - if ( is_object( $expected ) ) { - foreach ( get_object_vars( $expected ) as $name => $value ) { - if ( ! compareContents( $value, $actual->$name ) ) - return false; - } - } else if ( is_array( $expected ) ) { - foreach ( $expected as $key => $value ) { - if ( ! compareContents( $value, $actual[$key] ) ) - return false; - } - } else { - return $expected === $actual; - } - - return true; -} - -/** - * Compare two strings to confirm $actualCSV contains $expectedCSV - * Both strings are expected to have headers for their CSVs. - * $actualCSV must match all data rows in $expectedCSV - * - * @return bool Whether $actualCSV contacts $expectedCSV - */ -function checkThatCsvStringContainsCsvString( $actualCSV, $expectedCSV ) { - - $actualCSV = array_map( 'str_getcsv', explode( PHP_EOL, $actualCSV ) ); - $expectedCSV = array_map( 'str_getcsv', explode( PHP_EOL, $expectedCSV ) ); - - if ( empty( $actualCSV ) ) - return false; - - // Each sample must have headers - $actualHeaders = array_values( array_shift( $actualCSV ) ); - $expectedHeaders = array_values( array_shift( $expectedCSV ) ); - - // Each expectedCSV must exist somewhere in actualCSV in the proper column - $expectedResult = 0; - foreach( $expectedCSV as $expected_row ) { - $expected_row = array_combine( $expectedHeaders, $expected_row ); - foreach( $actualCSV as $actual_row ) { - - if ( count( $actualHeaders ) != count( $actual_row ) ) - continue; - - $actual_row = array_intersect_key( array_combine( $actualHeaders, $actual_row ), $expected_row ); - if ( $actual_row == $expected_row ) - $expectedResult++; - } - } - - return $expectedResult >= count( $expectedCSV ); -} From 2a10fb74af51e7c8449c0b52f5831a4f6a7c5205 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 02:04:50 +0300 Subject: [PATCH 1741/4858] behat: add aditional args if command merely starts with a given string --- features/bootstrap/FeatureContext.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 20114ddefb..66b3bfb3e5 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -153,9 +153,11 @@ public function drop_db() { } public function proc( $command, $assoc_args = array() ) { - if ( isset( self::$additional_args[ $command ] ) ) { - $assoc_args = array_merge( self::$additional_args[ $command ], - $assoc_args ); + foreach ( self::$additional_args as $start => $additional_args ) { + if ( 0 === strpos( $command, $start ) ) { + $assoc_args = array_merge( $additional_args, $assoc_args ); + break; + } } if ( !empty( $assoc_args ) ) From e27c5d6c66003a8f1ec8a7337eed8d1e03cb8c7d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 02:12:14 +0300 Subject: [PATCH 1742/4858] behat: extend 'the file should' step --- features/bootstrap/support.php | 24 ++++++++++++++++++++++ features/steps/basic_steps.php | 37 +++++++++------------------------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index 64a52bcad1..178df3ad24 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -2,6 +2,30 @@ // Utility functions used by Behat steps +function checkString( $output, $expected, $action ) { + switch ( $action ) { + + case 'be': + $r = $expected === rtrim( $output, "\n" ); + break; + + case 'contain': + $r = false !== strpos( $output, $expected ); + break; + + case 'not contain': + $r = false === strpos( $output, $expected ); + break; + + default: + throw new Behat\Behat\Exception\PendingException(); + } + + if ( !$r ) { + throw new Exception( $output ); + } +} + function compareContents( $expected, $actual ) { if ( gettype( $expected ) != gettype( $actual ) ) { return false; diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index c020b4873e..3367484f94 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -1,7 +1,6 @@ <?php -use Behat\Behat\Exception\PendingException, - Behat\Gherkin\Node\PyStringNode, +use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; function invoke_proc( $proc, $mode, $subdir = null ) { @@ -153,31 +152,9 @@ function ( $world, $return_code ) { $steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', function ( $world, $stream, $action, PyStringNode $expected ) { - $output = $world->result->$stream; - $expected = $world->replace_variables( (string) $expected ); - switch ( $action ) { - - case 'be': - $r = $expected === rtrim( $output, "\n" ); - break; - - case 'contain': - $r = false !== strpos( $output, $expected ); - break; - - case 'not contain': - $r = false === strpos( $output, $expected ); - break; - - default: - throw new PendingException(); - } - - if ( !$r ) { - throw new \Exception( $output ); - } + checkString( $world->result->$stream, $expected, $action ); } ); @@ -243,8 +220,8 @@ function ( $world, $stream ) { } ); -$steps->Then( '/^the (.+) file should exist$/', - function ( $world, $path ) { +$steps->Then( '/^the (.+) file should (exist|be:|contain:|not contain:)$/', + function ( $world, $path, $action, $expected = null ) { $path = $world->replace_variables( $path ); // If it's a relative path, make it relative to the current test dir @@ -252,6 +229,12 @@ function ( $world, $path ) { $path = $world->get_path( $path ); assertFileExists( $path ); + + if ( 'exist' !== $action ) { + $action = substr( $action, 0, -1 ); + $expected = $world->replace_variables( (string) $expected ); + checkString( file_get_contents( $path ), $expected, $action ); + } } ); From 4057bd0b251c0b8efa655d0cc911890c2cc067e2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 03:34:24 +0300 Subject: [PATCH 1743/4858] behat: pass BEHAT_RUN env variable see #473 --- features/bootstrap/Process.php | 3 ++- php/commands/search-replace.php | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 36ad7bcfd0..792277d9cf 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -29,7 +29,8 @@ public function run( $subdir = '' ) { // Ensure we're using the expected `wp` binary $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, array( - 'PATH' => realpath( __DIR__ . "/../../bin" ) . ':' . getenv( 'PATH' ) + 'PATH' => realpath( __DIR__ . "/../../bin" ) . ':' . getenv( 'PATH' ), + 'BEHAT_RUN' => 1 ) ); $STDOUT = stream_get_contents( $pipes[1] ); diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e6bcd5f940..3a2af08895 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -63,11 +63,14 @@ public function __invoke( $args, $assoc_args ) { private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { global $wpdb; + // We don't want to have to generate thousands of rows when running the test suite + $chunk_size = getenv( 'BEHAT_RUN' ) ? 10 : 1000; + $args = array( 'table' => $table, 'fields' => array( $primary_key, $col ), 'where' => $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', - 'chunk_size' => 1000 + 'chunk_size' => $chunk_size ); $it = new \WP_CLI\Iterators\Table( $args ); From 8e6c8c4e5d1a32f45c0d5d06bf42cef3052ff077 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 02:46:58 +0300 Subject: [PATCH 1744/4858] behat: use table in 'should be a table containing rows' step --- features/post.feature | 8 +++----- features/search-replace.feature | 19 +++++++------------ features/steps/basic_steps.php | 8 +++++--- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/features/post.feature b/features/post.feature index 499224754a..0e0c3c1666 100644 --- a/features/post.feature +++ b/features/post.feature @@ -40,11 +40,9 @@ Feature: Manage WordPress posts When I run `wp post get --format=table {POST_ID}` Then STDOUT should be a table containing rows: - """ - Field Value - ID {POST_ID} - post_title Test post - """ + | Field | Value | + | ID | {POST_ID} | + | post_title | Test post | When I run `wp post get --format=json {POST_ID}` Then STDOUT should be JSON containing: diff --git a/features/search-replace.feature b/features/search-replace.feature index 3cf524dbdf..1dd40fcba5 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -26,10 +26,9 @@ Feature: Do global search/replace And I run `wp search-replace {SITEURL} {SITEURL}/subdir` Then STDOUT should be a table containing rows: - """ - Table Column Replacements - wp_posts guid 1002 - """ + | Table | Column | Replacements | + | wp_posts | guid | 1002 | + Scenario: Large guid search/replace where replacement does not contain search Given a WP install @@ -41,10 +40,8 @@ Feature: Do global search/replace And I run `wp search-replace {SITEURL} http://newdomain.com` Then STDOUT should be a table containing rows: - """ - Table Column Replacements - wp_posts guid 1002 - """ + | Table | Column | Replacements | + | wp_posts | guid | 1002 | Scenario: Large guid search/replace dry run where replacement does not contain search Given a WP install @@ -57,7 +54,5 @@ Feature: Do global search/replace And I run `wp search-replace --dry-run {SITEURL} http://newdomain.com` Then STDOUT should be a table containing rows: - """ - Table Column Replacements - wp_posts guid 1002 - """ + | Table | Column | Replacements | + | wp_posts | guid | 1002 | diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 3367484f94..747de64724 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -165,12 +165,14 @@ function ( $world, $stream, $format ) { ); $steps->Then( '/^STDOUT should be a table containing rows:$/', - function ( $world, PyStringNode $expected ) { + function ( $world, TableNode $expected ) { $output = $world->result->STDOUT; $outputRows = explode( "\n", rtrim( $output, "\n" ) ); - $expected = $world->replace_variables( (string) $expected ); - $expectedRows = explode( "\n", rtrim( $expected, "\n" ) ); + $expectedRows = array(); + foreach ( $expected->getRows() as $row ) { + $expectedRows[] = $world->replace_variables( implode( "\t", $row ) ); + } // the first row is the header and must be present if ( $expectedRows[0] != $outputRows[0] ) { From 8192d51d6741001ac4bd1f6662d9455117ba052d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 03:36:47 +0300 Subject: [PATCH 1745/4858] behat: refactor search-replace tests by using a scenario outline --- features/search-replace.feature | 45 ++++++++------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 1dd40fcba5..978959bab9 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,44 +15,19 @@ Feature: Do global search/replace guid """ - Scenario: Large guid search/replace where replacement contains search + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install - - When I run `wp option get siteurl` - + And I run `wp option get siteurl` And save STDOUT as {SITEURL} + And I run `wp post generate --count=20` - And I run `wp post generate --count=1000` - - And I run `wp search-replace {SITEURL} {SITEURL}/subdir` + When I run `wp search-replace <flags> {SITEURL} <replacement>` Then STDOUT should be a table containing rows: | Table | Column | Replacements | - | wp_posts | guid | 1002 | - - Scenario: Large guid search/replace where replacement does not contain search - Given a WP install - - When I run `wp option get siteurl` + | wp_posts | guid | 22 | - And save STDOUT as {SITEURL} - - And I run `wp post generate --count=1000` - - And I run `wp search-replace {SITEURL} http://newdomain.com` - Then STDOUT should be a table containing rows: - | Table | Column | Replacements | - | wp_posts | guid | 1002 | - - Scenario: Large guid search/replace dry run where replacement does not contain search - Given a WP install - - When I run `wp option get siteurl` - - And save STDOUT as {SITEURL} - - And I run `wp post generate --count=1000` - - And I run `wp search-replace --dry-run {SITEURL} http://newdomain.com` - Then STDOUT should be a table containing rows: - | Table | Column | Replacements | - | wp_posts | guid | 1002 | + Examples: + | replacement | flags | + | {SITEURL}/subdir | | + | http://newdomain.com | | + | http://newdomain.com | --dry-run | From 0de17883f863c26a0d4b00dde171ce920a8dbe7e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 03:56:16 +0300 Subject: [PATCH 1746/4858] behat: use table in 'should be CSV containing' step --- features/bootstrap/support.php | 7 ++++--- features/post.feature | 8 +++----- features/steps/basic_steps.php | 12 +++++++++--- features/term.feature | 6 ++---- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index 178df3ad24..d213ea3def 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -97,11 +97,12 @@ function checkThatJsonStringContainsJsonString( $actualJson, $expectedJson ) { * Both strings are expected to have headers for their CSVs. * $actualCSV must match all data rows in $expectedCSV * - * @return bool Whether $actualCSV contacts $expectedCSV + * @param string A CSV string + * @param array A nested array of values + * @return bool Whether $actualCSV contains $expectedCSV */ -function checkThatCsvStringContainsCsvString( $actualCSV, $expectedCSV ) { +function checkThatCsvStringContainsValues( $actualCSV, $expectedCSV ) { $actualCSV = array_map( 'str_getcsv', explode( PHP_EOL, $actualCSV ) ); - $expectedCSV = array_map( 'str_getcsv', explode( PHP_EOL, $expectedCSV ) ); if ( empty( $actualCSV ) ) return false; diff --git a/features/post.feature b/features/post.feature index 0e0c3c1666..035be2982c 100644 --- a/features/post.feature +++ b/features/post.feature @@ -61,8 +61,6 @@ Feature: Manage WordPress posts When I run `wp post list --post_type='post' --fields=post_title,post_name,post_status --format=csv` Then STDOUT should be CSV containing: - """ - post_title,post_name,post_status - "Publish post",publish-post,publish - "Draft post",,draft - """ + | post_title | post_name | post_status | + | Publish post | publish-post | publish | + | Draft post | | draft | diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 747de64724..ec5a0fe8f9 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -199,11 +199,17 @@ function ( $world, PyStringNode $expected ) { }); $steps->Then( '/^STDOUT should be CSV containing:$/', - function( $world, PyStringNode $expected ) { + function( $world, TableNode $expected ) { $output = $world->result->STDOUT; - $expected = $world->replace_variables( (string) $expected ); - if ( ! checkThatCsvStringContainsCsvString( $output, $expected ) ) + $expectedRows = $expected->getRows(); + foreach ( $expected as &$row ) { + foreach ( $row as &$value ) { + $value = $world->replace_variables( $value ); + } + } + + if ( ! checkThatCsvStringContainsValues( $output, $expectedRows ) ) throw new \Exception( $output ); } ); diff --git a/features/term.feature b/features/term.feature index 7a6442d453..df7dea76c9 100644 --- a/features/term.feature +++ b/features/term.feature @@ -17,10 +17,8 @@ Feature: Manage WordPress terms When I run `wp term list post_tag --fields=name,slug --format=csv` Then STDOUT should be CSV containing: - """ - name,slug - "Test term",test - """ + | name | slug | + | Test term | test | Scenario: Creating/deleting a term Given a WP install From 9f561881756524df46b3366c4b0d65f760120358 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 03:02:09 +0300 Subject: [PATCH 1747/4858] first pass at ditching wp-admin/setup-config.php --- features/core.feature | 17 +++++++-- man-src/core-config.txt | 15 ++++++++ php/commands/core.php | 44 ++++++++++++++++------- templates/wp-config.mustache | 68 ++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 16 deletions(-) create mode 100644 templates/wp-config.mustache diff --git a/features/core.feature b/features/core.feature index b9497e37e0..a61b01b705 100644 --- a/features/core.feature +++ b/features/core.feature @@ -25,14 +25,25 @@ Feature: Manage WordPress installation When I try `wp core install` Then the return code should be 1 - Then STDERR should be: + And STDERR should be: """ Error: wp-config.php not found. Either create one manually or use `wp core config`. """ - When I run `wp core config` - Then the wp-config.php file should exist + Given a wp-config-extra.php file: + """ + define( 'WP_DEBUG_LOG', true ); + """ + When I run `wp core config --extra-php < wp-config-extra.php` + Then the wp-config.php file should contain: + """ + define('AUTH_SALT', + """ + And the wp-config.php file should contain: + """ + define( 'WP_DEBUG_LOG', true ); + """ Scenario: Database doesn't exist Given an empty directory diff --git a/man-src/core-config.txt b/man-src/core-config.txt index 5b3345010f..203927aad6 100644 --- a/man-src/core-config.txt +++ b/man-src/core-config.txt @@ -19,3 +19,18 @@ * `--dbprefix`=<dbprefix>: Set the database table prefix. Default: 'wp_' + +* `--extra-php`: + + If set, the command reads additional PHP code from STDIN. + +## EXAMPLES + +# Standard wp-config.php file: +wp core config --dbname=testing --dbuser=wp --dbpass=securepswd + +# Enable WP_DEBUG and WP_DEBUG_LOG +wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP +define( 'WP_DEBUG', true ); +define( 'WP_DEBUG_LOG', true ); +PHP diff --git a/php/commands/core.php b/php/commands/core.php index 24ce49d446..2e0de6aee4 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -44,31 +44,49 @@ public function download( $args, $assoc_args ) { WP_CLI::success( 'WordPress downloaded.' ); } + private static function _download( $url ) { + exec( 'curl -s ' . escapeshellarg( $url ), $lines, $r ); + if ( $r ) exit( $r ); + return implode( "\n", $lines ); + } + private function get_download_offer( $locale ) { - $out = exec( 'curl -s ' . escapeshellarg( 'https://api.wordpress.org/core/version-check/1.6/?locale=' . $locale ), $lines, $r ); - if ($r) exit($r); + $out = unserialize( self::_download( + 'https://api.wordpress.org/core/version-check/1.6/?locale=' . $locale ) ); - $out = unserialize( $out ); return $out['offers'][0]; } /** * Set up a wp-config.php file. * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--extra-php] */ public function config( $args, $assoc_args ) { - $_POST['dbname'] = $assoc_args['dbname']; - $_POST['uname'] = $assoc_args['dbuser']; - $_POST['pwd'] = isset( $assoc_args['dbpass'] ) ? $assoc_args['dbpass'] : ''; - $_POST['dbhost'] = isset( $assoc_args['dbhost'] ) ? $assoc_args['dbhost'] : 'localhost'; - $_POST['prefix'] = isset( $assoc_args['dbprefix'] ) ? $assoc_args['dbprefix'] : 'wp_'; + // TODO: check if wp-config.php already exists + + if ( isset( $assoc_args['extra-php'] ) ) { + $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); + } + + if ( isset( $assoc_args['dbprefix'] ) ) { + if ( preg_match( '|[^a-z0-9_]|i', $assoc_args['dbprefix'] ) ) + WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); + } else { + $assoc_args['dbprefix'] = 'wp_'; + } + + // TODO: check db connection + + // TODO: adapt more resilient code from wp-admin/setup-config.php + $assoc_args['keys-and-salts'] = self::_download( + 'https://api.wordpress.org/secret-key/1.1/salt/' ); + + $out = Utils\mustache_render( 'wp-config.mustache', $assoc_args ); - $_GET['step'] = 2; + file_put_contents( ABSPATH . 'wp-config.php', $out ); - if ( WP_CLI::get_config('quiet') ) ob_start(); - require ABSPATH . '/wp-admin/setup-config.php'; - if ( WP_CLI::get_config('quiet') ) ob_end_clean(); + WP_CLI::success( 'Generated wp-config.php file.' ); } /** diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache new file mode 100644 index 0000000000..9c1442a03a --- /dev/null +++ b/templates/wp-config.mustache @@ -0,0 +1,68 @@ +<?php +/** + * The base configurations of the WordPress. + * + * This file has the following configurations: MySQL settings, Table Prefix, + * Secret Keys, WordPress Language, and ABSPATH. You can find more information + * by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing + * wp-config.php} Codex page. You can get the MySQL settings from your web host. + * @package WordPress + */ + +// ** MySQL settings - You can get this info from your web host ** // +/** The name of the database for WordPress */ +define('DB_NAME', '{{dbname}}'); + +/** MySQL database username */ +define('DB_USER', '{{dbuser}}'); + +/** MySQL database password */ +define('DB_PASSWORD', '{{dbpass}}'); + +/** MySQL hostname */ +define('DB_HOST', '{{dbhost}}'); + +/** Database Charset to use in creating database tables. */ +define('DB_CHARSET', 'utf8'); + +/** The Database Collate type. Don't change this if in doubt. */ +define('DB_COLLATE', ''); + +/**#@+ + * Authentication Unique Keys and Salts. + * + * Change these to different unique phrases! + * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} + * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again. + */ +{{{keys-and-salts}}} +/**#@-*/ + +/** + * WordPress Database Table prefix. + * + * You can have multiple installations in one database if you give each a unique + * prefix. Only numbers, letters, and underscores please! + */ +$table_prefix = '{{dbprefix}}'; + +/** + * WordPress Localized Language, defaults to English. + * + * Change this to localize WordPress. A corresponding MO file for the chosen + * language must be installed to wp-content/languages. For example, install + * de_DE.mo to wp-content/languages and set WPLANG to 'de_DE' to enable German + * language support. + */ +define('WPLANG', ''); + +{{{extra-php}}} + +/* That's all, stop editing! Happy blogging. */ + +/** Absolute path to the WordPress directory. */ +if ( !defined('ABSPATH') ) + define('ABSPATH', dirname(__FILE__) . '/'); + +/** Sets up WordPress vars and included files. */ +require_once(ABSPATH . 'wp-settings.php'); From e13bc3c0c241aa32764fa15fe9894f4db1dd089b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 15:17:21 +0300 Subject: [PATCH 1748/4858] core config: abort if wp-config.php already exists --- features/core.feature | 4 ++++ php/commands/core.php | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index a61b01b705..eb9d7339d9 100644 --- a/features/core.feature +++ b/features/core.feature @@ -45,6 +45,10 @@ Feature: Manage WordPress installation define( 'WP_DEBUG_LOG', true ); """ + When I try the previous command again + Then the return code should be 1 + And STDERR should not be empty + Scenario: Database doesn't exist Given an empty directory And WP files diff --git a/php/commands/core.php b/php/commands/core.php index 2e0de6aee4..824c2fad0f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -63,7 +63,9 @@ private function get_download_offer( $locale ) { * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--extra-php] */ public function config( $args, $assoc_args ) { - // TODO: check if wp-config.php already exists + if ( Utils\locate_wp_config() ) { + WP_CLI::error( "The 'wp-config.php' file already exists." ); + } if ( isset( $assoc_args['extra-php'] ) ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); From f5b5f04ab49dd64c133141e6a36008868356fb0e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 15:32:00 +0300 Subject: [PATCH 1749/4858] core config: check DB credentials --- php/commands/core.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 824c2fad0f..37d6a6d206 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -62,24 +62,31 @@ private function get_download_offer( $locale ) { * * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--extra-php] */ - public function config( $args, $assoc_args ) { + public function config( $_, $assoc_args ) { if ( Utils\locate_wp_config() ) { WP_CLI::error( "The 'wp-config.php' file already exists." ); } + $defaults = array( + 'dbhost' => 'localhost', + 'dbprefix' => 'wp_' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + if ( preg_match( '|[^a-z0-9_]|i', $assoc_args['dbprefix'] ) ) + WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); + + // Check DB connection + Utils\run_mysql_query( ';', array( + 'host' => $assoc_args['dbhost'], + 'user' => $assoc_args['dbuser'], + 'pass' => $assoc_args['dbpass'], + ) ); + if ( isset( $assoc_args['extra-php'] ) ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); } - if ( isset( $assoc_args['dbprefix'] ) ) { - if ( preg_match( '|[^a-z0-9_]|i', $assoc_args['dbprefix'] ) ) - WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); - } else { - $assoc_args['dbprefix'] = 'wp_'; - } - - // TODO: check db connection - // TODO: adapt more resilient code from wp-admin/setup-config.php $assoc_args['keys-and-salts'] = self::_download( 'https://api.wordpress.org/secret-key/1.1/salt/' ); From 7bd54f449685f1f4e270b01b1b6edd59ee756597 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 15:50:57 +0300 Subject: [PATCH 1750/4858] core config: update man page [ci skip] --- man-src/core-config.txt | 16 ++++++++-------- man/core-config.1 | 23 ++++++++++++++++++++++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/man-src/core-config.txt b/man-src/core-config.txt index 203927aad6..2f5920998c 100644 --- a/man-src/core-config.txt +++ b/man-src/core-config.txt @@ -26,11 +26,11 @@ ## EXAMPLES -# Standard wp-config.php file: -wp core config --dbname=testing --dbuser=wp --dbpass=securepswd - -# Enable WP_DEBUG and WP_DEBUG_LOG -wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP -define( 'WP_DEBUG', true ); -define( 'WP_DEBUG_LOG', true ); -PHP + # Standard wp-config.php file + wp core config --dbname=testing --dbuser=wp --dbpass=securepswd + + # Enable WP_DEBUG and WP_DEBUG_LOG + wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP + define( 'WP_DEBUG', true ); + define( 'WP_DEBUG_LOG', true ); + PHP diff --git a/man/core-config.1 b/man/core-config.1 index 47e893b7b7..4a8d6e8d91 100644 --- a/man/core-config.1 +++ b/man/core-config.1 @@ -7,7 +7,7 @@ \fBwp\-core\-config\fR \- Set up a wp\-config\.php file\. . .SH "SYNOPSIS" -wp core config \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\-\-dbpass=\fIpassword\fR] [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] +wp core config \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\-\-dbpass=\fIpassword\fR] [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] [\-\-extra\-php] . .SH "OPTIONS" . @@ -40,4 +40,25 @@ Set the database host\. Default: \'localhost\' . .IP Set the database table prefix\. Default: \'wp_\' +. +.TP +\fB\-\-extra\-php\fR: +. +.IP +If set, the command reads additional PHP code from STDIN\. +. +.SH "EXAMPLES" +. +.nf + +# Standard wp\-config\.php file +wp core config \-\-dbname=testing \-\-dbuser=wp \-\-dbpass=securepswd + +# Enable WP_DEBUG and WP_DEBUG_LOG +wp core config \-\-dbname=testing \-\-dbuser=wp \-\-dbpass=securepswd \-\-extra\-php <<PHP +define( \'WP_DEBUG\', true ); +define( \'WP_DEBUG_LOG\', true ); +PHP +. +.fi From a834ef1e5fae0da5319731a561653d08efea19d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 May 2013 21:28:11 +0300 Subject: [PATCH 1751/4858] move Utils\set_user() to Runner::set_user() it's not a general-purpose utility and it shouldn't be public --- php/WP_CLI/Runner.php | 20 +++++++++++++++++++- php/utils-wp.php | 18 ------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 245711cb78..b0f9b9c912 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -109,6 +109,23 @@ private static function set_wp_root( $config ) { define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); } + private static function set_user( $assoc_args ) { + if ( !isset( $assoc_args['user'] ) ) + return; + + $user = $assoc_args['user']; + + if ( is_numeric( $user ) ) { + $user_id = (int) $user; + } else { + $user_id = (int) username_exists( $user ); + } + + if ( !$user_id || !wp_set_current_user( $user_id ) ) { + \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); + } + } + private static function is_absolute_path( $path ) { // Windows if ( ':' === $path[1] ) @@ -355,7 +372,8 @@ public function before_wp_load() { public function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - Utils\set_user( $this->config ); + // Handle --user parameter + self::set_user( $this->config ); if ( isset( $this->config['require'] ) ) require $this->config['require']; diff --git a/php/utils-wp.php b/php/utils-wp.php index f5c2afe85b..5d42c52c88 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -52,24 +52,6 @@ function maybe_require( $since, $path ) { require $path; } -// Handle --user parameter -function set_user( $assoc_args ) { - if ( !isset( $assoc_args['user'] ) ) - return; - - $user = $assoc_args['user']; - - if ( is_numeric( $user ) ) { - $user_id = (int) $user; - } else { - $user_id = (int) username_exists( $user ); - } - - if ( !$user_id || !wp_set_current_user( $user_id ) ) { - \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); - } -} - function get_upgrader( $class ) { if ( !class_exists( '\WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; From ca7b4f1319f48f34a51a8bce4c4c1d5598d1f252 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 26 May 2013 05:28:53 +0300 Subject: [PATCH 1752/4858] extract find_command_to_run() method --- php/class-wp-cli.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 69199003d2..1daf81559d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -243,14 +243,8 @@ static function get_config( $key = null ) { return self::$runner->config[ $key ]; } - /** - * Run a given command. - * - * @param array - * @param array - */ - public static function run_command( $args, $assoc_args = array() ) { - $command = self::$root; + private static function find_command_to_run( $args ) { + $command = \WP_CLI::$root; while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { $subcommand = $command->pre_invoke( $args ); @@ -260,10 +254,22 @@ public static function run_command( $args, $assoc_args = array() ) { $command = $subcommand; } + return array( $command, $args ); + } + + /** + * Run a given command. + * + * @param array + * @param array + */ + public static function run_command( $args, $assoc_args = array() ) { + list( $command, $final_args ) = self::find_command_to_run( $args ); + if ( $command instanceof Dispatcher\CommandContainer ) { $command->show_usage(); } else { - $command->invoke( $args, $assoc_args ); + $command->invoke( $final_args, $assoc_args ); } } From 3d046d1a1ec22000c521f507adf4a75d983be59e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 26 May 2013 05:22:23 +0300 Subject: [PATCH 1753/4858] make load_command() and load_all_commands() standalone utilities --- php/WP_CLI/Dispatcher/RootCommand.php | 49 +++++---------------------- php/utils.php | 21 ++++++++++++ 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 4c74f82cb2..e47721aefc 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -2,6 +2,8 @@ namespace WP_CLI\Dispatcher; +use \WP_CLI\Utils; + class RootCommand extends AbstractCommandContainer implements Documentable { function get_name() { @@ -93,54 +95,19 @@ function find_subcommand( &$args ) { if ( isset( $aliases[ $command ] ) ) $command = $aliases[ $command ]; - return $this->load_command( $command ); - } - - function get_subcommands() { - $this->load_all_commands(); - - return parent::get_subcommands(); - } - - protected function load_all_commands() { - $cmd_dir = WP_CLI_ROOT . "commands"; + Utils\load_command( $command ); - $iterator = new \DirectoryIterator( $cmd_dir ); - - foreach ( $iterator as $filename ) { - if ( '.php' != substr( $filename, -4 ) ) - continue; - - $command = substr( $filename, 0, -4 ); - - if ( isset( $this->subcommands[ $command ] ) ) - continue; - - include "$cmd_dir/$filename"; - } - } - - protected static function get_command_file( $command ) { - $path = WP_CLI_ROOT . "/commands/$command.php"; - - if ( !is_readable( $path ) ) { + if ( !isset( $this->subcommands[ $command ] ) ) { return false; } - return $path; + return $this->subcommands[ $command ]; } - protected function load_command( $command ) { - if ( !isset( $this->subcommands[ $command ] ) ) { - if ( $path = self::get_command_file( $command ) ) - include $path; - } - - if ( !isset( $this->subcommands[ $command ] ) ) { - return false; - } + function get_subcommands() { + Utils\load_all_commands(); - return $this->subcommands[ $command ]; + return parent::get_subcommands(); } } diff --git a/php/utils.php b/php/utils.php index e9cad0bd73..5c4da77524 100644 --- a/php/utils.php +++ b/php/utils.php @@ -30,6 +30,27 @@ function load_dependencies() { include WP_CLI_ROOT . 'Spyc.php'; } +function load_command( $name ) { + $path = WP_CLI_ROOT . "/commands/$name.php"; + + if ( is_readable( $path ) ) { + include_once $path; + } +} + +function load_all_commands() { + $cmd_dir = WP_CLI_ROOT . "commands"; + + $iterator = new \DirectoryIterator( $cmd_dir ); + + foreach ( $iterator as $filename ) { + if ( '.php' != substr( $filename, -4 ) ) + continue; + + include_once "$cmd_dir/$filename"; + } +} + function get_config_spec() { $spec = include __DIR__ . '/config-spec.php'; From a4fb83f3952751e7eef1074e0e48d5205954d424 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 31 May 2013 22:07:53 +0000 Subject: [PATCH 1754/4858] `$group` is optional for the function, so let it be optional for the command too --- php/commands/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cache.php b/php/commands/cache.php index 00b93b254e..4516e7e16d 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -51,7 +51,7 @@ public function decr( $args, $assoc_args ) { /** * Remove a value from the object cache. * - * @synopsis <key> <group> + * @synopsis <key> [<group>] */ public function delete( $args, $assoc_args ) { $key = $args[0]; From a8c9d64508bc4228ee1af9111dfbcc71d79604d5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 1 Jun 2013 00:21:56 +0000 Subject: [PATCH 1755/4858] Regenerate cache man --- man/cache.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/cache.1 b/man/cache.1 index 82f66dc5b9..2f724253c9 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -13,7 +13,7 @@ wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] wp cache decr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] . .P -wp cache delete \fIkey\fR \fIgroup\fR +wp cache delete \fIkey\fR [\fIgroup\fR] . .P wp cache flush From 9fb3dc1ba38a15d1c7b5919427d5c15f6ec753f0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 1 Jun 2013 20:10:46 +0000 Subject: [PATCH 1756/4858] Use `get_stylesheet_directory()` instead of `TEMPLATEPATH` when determining where to place a scaffold. In parent-child theme relationships, `TEMPLATEPATH` will always be the parent theme. We'd like to instead place our CPT/taxonomy in the child theme, as child themes are where the customizations occur. --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 6b3b1bf050..a9354de18a 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -185,7 +185,7 @@ private function get_output_path( $assoc_args, $subdir ) { extract( $assoc_args, EXTR_SKIP ); if ( $theme ) { - $path = TEMPLATEPATH; + $path = get_stylesheet_directory(); } elseif ( ! empty( $plugin ) ) { $path = WP_PLUGIN_DIR . '/' . $plugin; if ( !is_dir( $path ) ) { From c4d503b01b4bce364dc67e1bc6f42fd7ceddb1e4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Jun 2013 13:47:15 +0300 Subject: [PATCH 1757/4858] scaffold: clarify --theme description in docs --- man-src/scaffold-post-type.txt | 2 +- man-src/scaffold-taxonomy.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/scaffold-post-type.txt b/man-src/scaffold-post-type.txt index e45952d06c..9e50ebaf5b 100644 --- a/man-src/scaffold-post-type.txt +++ b/man-src/scaffold-post-type.txt @@ -10,7 +10,7 @@ * `--theme`: - Create a file in the current theme directory, instead of sending to + Create a file in the current theme's directory, instead of sending to STDOUT. * `--plugin=<plugin>`: diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt index f739fb1f64..4156dfd650 100644 --- a/man-src/scaffold-taxonomy.txt +++ b/man-src/scaffold-taxonomy.txt @@ -14,7 +14,7 @@ * `--theme`: - Create a file in the current theme directory, instead of sending to + Create a file in the current theme's directory, instead of sending to STDOUT. * `--plugin=<plugin>`: From 59f7dc5be40e6b490beff2fbd3456bd780624fb5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Jun 2013 17:32:13 +0300 Subject: [PATCH 1758/4858] core config: fix notice when not passing --dbpass --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 37d6a6d206..b088af51e6 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -69,7 +69,8 @@ public function config( $_, $assoc_args ) { $defaults = array( 'dbhost' => 'localhost', - 'dbprefix' => 'wp_' + 'dbpass' => '', + 'dbprefix' => 'wp_', ); $assoc_args = array_merge( $defaults, $assoc_args ); From 1df18344b8852ed8a5663b30c0a9c5b47eeb36fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Jun 2013 17:41:41 +0300 Subject: [PATCH 1759/4858] core config: set WPLANG based on downloaded locale fixes #488 --- php/commands/core.php | 10 ++++++++++ templates/wp-config.mustache | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index b088af51e6..3009dde8fe 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -57,6 +57,15 @@ private function get_download_offer( $locale ) { return $out['offers'][0]; } + private static function get_initial_locale() { + include ABSPATH . '/wp-includes/version.php'; + + if ( isset( $wp_local_package ) ) + return $wp_local_package; + + return ''; + } + /** * Set up a wp-config.php file. * @@ -71,6 +80,7 @@ public function config( $_, $assoc_args ) { 'dbhost' => 'localhost', 'dbpass' => '', 'dbprefix' => 'wp_', + 'locale' => self::get_initial_locale() ); $assoc_args = array_merge( $defaults, $assoc_args ); diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index 9c1442a03a..78cca74884 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -54,7 +54,7 @@ $table_prefix = '{{dbprefix}}'; * de_DE.mo to wp-content/languages and set WPLANG to 'de_DE' to enable German * language support. */ -define('WPLANG', ''); +define('WPLANG', '{{locale}}'); {{{extra-php}}} From c01406fbf03565ae46daa6de98e2d993a292bfcb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 2 Jun 2013 08:44:32 -0700 Subject: [PATCH 1760/4858] Update post type and taxonomy scaffold to support a named theme target --- php/commands/scaffold.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index a9354de18a..65f0e96880 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -185,7 +185,10 @@ private function get_output_path( $assoc_args, $subdir ) { extract( $assoc_args, EXTR_SKIP ); if ( $theme ) { - $path = get_stylesheet_directory(); + if ( is_string( $theme ) ) + $path = get_theme_root( $theme ) . '/' . $theme; + else + $path = get_stylesheet_directory(); } elseif ( ! empty( $plugin ) ) { $path = WP_PLUGIN_DIR . '/' . $plugin; if ( !is_dir( $path ) ) { From 08fbddac696473977e0140c781e05b2f8ccf13d0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 2 Jun 2013 08:47:13 -0700 Subject: [PATCH 1761/4858] Update man docs --- man-src/scaffold-post-type.txt | 4 ++-- man-src/scaffold-taxonomy.txt | 4 ++-- man/scaffold-post-type.1 | 2 +- man/scaffold-taxonomy.1 | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/man-src/scaffold-post-type.txt b/man-src/scaffold-post-type.txt index 9e50ebaf5b..e164c1f3bc 100644 --- a/man-src/scaffold-post-type.txt +++ b/man-src/scaffold-post-type.txt @@ -10,8 +10,8 @@ * `--theme`: - Create a file in the current theme's directory, instead of sending to -STDOUT. + Create a file in the active theme directory, instead of sending to +STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. * `--plugin=<plugin>`: diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt index 4156dfd650..1015bf54c0 100644 --- a/man-src/scaffold-taxonomy.txt +++ b/man-src/scaffold-taxonomy.txt @@ -14,8 +14,8 @@ * `--theme`: - Create a file in the current theme's directory, instead of sending to -STDOUT. + Create a file in the active theme directory, instead of sending to +STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. * `--plugin=<plugin>`: diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 index 5d07b487b6..6db8bf44c2 100644 --- a/man/scaffold-post-type.1 +++ b/man/scaffold-post-type.1 @@ -27,7 +27,7 @@ The textdomain to use for the labels\. \fB\-\-theme\fR: . .IP -Create a file in the current theme directory, instead of sending to STDOUT\. +Create a file in the active theme directory, instead of sending to STDOUT\. Specify a theme with \fB\-\-theme=<theme>\fR to have the file placed in that theme\. . .TP \fB\-\-plugin=<plugin>\fR: diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 index 84a1a79002..3d7986f2e1 100644 --- a/man/scaffold-taxonomy.1 +++ b/man/scaffold-taxonomy.1 @@ -33,7 +33,7 @@ The textdomain to use for the labels\. \fB\-\-theme\fR: . .IP -Create a file in the current theme directory, instead of sending to STDOUT\. +Create a file in the active theme directory, instead of sending to STDOUT\. Specify a theme with \fB\-\-theme=<theme>\fR to have the file placed in that theme\. . .TP \fB\-\-plugin=<plugin>\fR: From c5d8f7073caff031e3d5988d654551fa85f0b583 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Jun 2013 22:10:18 +0300 Subject: [PATCH 1762/4858] bump version to 0.10.0-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 8ca2bcf13c..1b40a05d3f 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.0-alpha' ); +define( 'WP_CLI_VERSION', '0.10.0-beta' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 4fb859972901bef44a03c491316fa721b65b624e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 30 May 2013 17:26:45 +0300 Subject: [PATCH 1763/4858] run_mysql_command: use --no-defaults instead of --defaults-file --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 5c4da77524..7d3fe7afca 100644 --- a/php/utils.php +++ b/php/utils.php @@ -404,7 +404,7 @@ function run_mysql_query( $query, $args ) { function run_mysql_command( $cmd, $arg_str, $pass ) { $old_val = getenv( 'MYSQL_PWD' ); - $final_cmd = "$cmd --defaults-file=/dev/null $arg_str"; + $final_cmd = "$cmd --no-defaults $arg_str"; putenv( 'MYSQL_PWD=' . $pass ); $r = proc_close( proc_open( $final_cmd, array( STDIN, STDOUT, STDERR ), $pipes ) ); From dae17e1496f6994824ec3345de449dd3ef8dac90 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 May 2013 22:00:00 +0300 Subject: [PATCH 1764/4858] standardize special flags handling --- php/WP_CLI/Runner.php | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b0f9b9c912..22e1a60a00 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -292,28 +292,15 @@ public function before_wp_load() { $this->init_logger(); - // Handle --version parameter - if ( isset( $this->assoc_args['version'] ) && empty( $this->arguments ) ) { - \WP_CLI\InternalFlags::version(); - exit; - } - - // Handle --info parameter - if ( isset( $this->assoc_args['info'] ) && empty( $this->arguments ) ) { - \WP_CLI\InternalFlags::info(); - exit; - } - - // Handle --param-dump parameter - if ( isset( $this->assoc_args['param-dump'] ) ) { - \WP_CLI\InternalFlags::param_dump(); - exit; - } - - // Handle --cmd-dump parameter - if ( isset( $this->assoc_args['cmd-dump'] ) ) { - \WP_CLI\InternalFlags::cmd_dump(); - exit; + // Handle a bunch of special-purpose flags + if ( empty( $this->arguments ) ) { + foreach ( array( 'version', 'info', 'param-dump', 'cmd-dump' ) as $key ) { + if ( isset( $this->assoc_args[ $key ] ) ) { + call_user_func( array( '\\WP_CLI\\InternalFlags', + str_replace( '-', '_', $key ) ) ); + exit; + } + } } $_SERVER['DOCUMENT_ROOT'] = realpath( $this->config['path'] ); From 4cea180531a2e2318ff5b4e03673a161938a481e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Jun 2013 23:08:50 +0300 Subject: [PATCH 1765/4858] convert InternalFlags class to Sys_Command --- php/WP_CLI/Dispatcher/RootCommand.php | 3 + php/WP_CLI/Runner.php | 32 +++++---- .../InternalFlags.php => commands/_sys.php} | 67 +++++++++---------- 3 files changed, 55 insertions(+), 47 deletions(-) rename php/{WP_CLI/InternalFlags.php => commands/_sys.php} (65%) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index e47721aefc..9fc159aee1 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -26,6 +26,9 @@ function show_usage() { \WP_CLI::line( 'Available commands:' ); foreach ( $this->get_subcommands() as $command ) { + if ( '_sys' == $command->get_name() ) + continue; + \WP_CLI::line( sprintf( " %s %s", implode( ' ', get_path( $command ) ), implode( '|', array_keys( get_subcommands( $command ) ) ) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 22e1a60a00..dcfe5fffe3 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -251,6 +251,16 @@ private static function back_compat_conversions( $r ) { unset( $assoc_args['json'] ); } + // --{version|info} -> _sys {version|info} + if ( empty( $args ) ) { + foreach ( array( 'version', 'info' ) as $key ) { + if ( isset( $assoc_args[ $key ] ) ) { + $args = array( '_sys', $key ); + break; + } + } + } + return array( $args, $assoc_args ); } @@ -292,19 +302,13 @@ public function before_wp_load() { $this->init_logger(); - // Handle a bunch of special-purpose flags - if ( empty( $this->arguments ) ) { - foreach ( array( 'version', 'info', 'param-dump', 'cmd-dump' ) as $key ) { - if ( isset( $this->assoc_args[ $key ] ) ) { - call_user_func( array( '\\WP_CLI\\InternalFlags', - str_replace( '-', '_', $key ) ) ); - exit; - } - } - } - $_SERVER['DOCUMENT_ROOT'] = realpath( $this->config['path'] ); + if ( $this->cmd_starts_with( array( '_sys' ) ) ) { + $this->_run_command(); + exit; + } + // First try at showing man page if ( $this->cmd_starts_with( array( 'help' ) ) ) { $this->_run_command(); @@ -367,7 +371,11 @@ public function after_wp_load() { // Handle --completions parameter if ( isset( $this->assoc_args['completions'] ) ) { - \WP_CLI\InternalFlags::completions(); + foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { + $subcommands = Dispatcher\get_subcommands( $command ); + + WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); + } exit; } diff --git a/php/WP_CLI/InternalFlags.php b/php/commands/_sys.php similarity index 65% rename from php/WP_CLI/InternalFlags.php rename to php/commands/_sys.php index 1f5bf70893..af2b1b714f 100644 --- a/php/WP_CLI/InternalFlags.php +++ b/php/commands/_sys.php @@ -1,37 +1,11 @@ <?php -namespace WP_CLI; -use \WP_CLI; +use \WP_CLI\Dispatcher, + \WP_CLI\Utils; -/** - * Class that handles special assoc parameters - */ -class InternalFlags { +class Sys_Command extends WP_CLI_Command { - static function version() { - WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); - } - - static function info() { - $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); - - WP_CLI::line( "PHP binary:\t" . $php_bin ); - WP_CLI::line( "PHP version:\t" . PHP_VERSION ); - WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); - WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); - WP_CLI::line( "wp-cli config:\t" . WP_CLI::get_config_path() ); - WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); - } - - static function param_dump() { - echo json_encode( Utils\get_config_spec() ); - } - - static function cmd_dump() { - echo json_encode( self::command_to_array( WP_CLI::$root ) ); - } - - private static function command_to_array( $command ) { + private function command_to_array( $command ) { $dump = array( 'name' => $command->get_name(), 'description' => $command->get_shortdesc(), @@ -48,12 +22,35 @@ private static function command_to_array( $command ) { return $dump; } - static function completions() { - foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { - $subcommands = Dispatcher\get_subcommands( $command ); + function version() { + WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); + } - WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); - } + function info() { + $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + + WP_CLI::line( "PHP binary:\t" . $php_bin ); + WP_CLI::line( "PHP version:\t" . PHP_VERSION ); + WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); + WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); + WP_CLI::line( "wp-cli config:\t" . WP_CLI::get_config_path() ); + WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); + } + + /** + * @subcommand param-dump + */ + function param_dump() { + echo json_encode( Utils\get_config_spec() ); + } + + /** + * @subcommand cmd-dump + */ + function cmd_dump() { + echo json_encode( self::command_to_array( WP_CLI::$root ) ); } } +WP_CLI::add_command( '_sys', 'Sys_Command' ); + From 3f08d5f7eefeb678fb36e380205d343bebd2dfe1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 3 Jun 2013 10:34:22 -0700 Subject: [PATCH 1766/4858] Create `get_api_for_version()`, which will give us the proper download link for a given version --- php/WP_CLI/CommandWithUpgrade.php | 26 ++++++++++++++++++++++++++ php/commands/theme.php | 3 +++ 2 files changed, 29 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index d2b8529c0a..bed5291ffa 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -119,6 +119,32 @@ function install( $args, $assoc_args ) { } } + protected function get_api_for_version( $api, $version ) { + + list( $link ) = explode( $api->slug, $api->download_link ); + + if ( stripos( $api->download_link, 'theme' ) ) + $download_type = 'theme'; + else + $download_type = 'plugin'; + + + if ( 'dev' == $version ) { + $api->download_link = $link . $api->slug . '.zip'; + $api->version = 'Development Version'; + } else { + $api->download_link = $link . $api->slug . '.' . $version .'.zip'; + $api->version = $version; + + // check if the requested version exists + $response = wp_remote_head( $api->download_link ); + if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { + \WP_CLI::error( sprintf( "Can't find the requested %s's version %s in the WordPress.org %s repository.", $download_type, $version, $download_type ) ); + } + } + return $api; + } + protected function _update( $item ) { call_user_func( $this->upgrade_refresh ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 3b0a5c6f7b..4c5414737d 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -107,6 +107,9 @@ protected function install_from_repo( $slug, $assoc_args ) { WP_CLI::error( $api ); } + if ( ! empty( $assoc_args['version'] ) ) + $api = $this->get_api_for_version( $api, $assoc_args['version'] ); + // Check to see if we should update, rather than install. if ( $this->has_update( $slug ) ) { WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); From f8f5742962b498e7c97cf0c8f9b6870250058d22 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Jun 2013 22:12:28 +0300 Subject: [PATCH 1767/4858] rename get_api_for_version() to alter_api_response() and use in plugin command --- features/theme.feature | 24 ------------------------ features/upgradables.feature | 31 +++++++++++++++++++++++++++++++ php/WP_CLI/CommandWithUpgrade.php | 31 ++++++++++++++++++------------- php/commands/plugin.php | 16 +--------------- php/commands/theme.php | 5 +++-- 5 files changed, 53 insertions(+), 54 deletions(-) create mode 100644 features/upgradables.feature diff --git a/features/theme.feature b/features/theme.feature index fd65ec6653..f7a57b5b98 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -47,27 +47,3 @@ Feature: Manage WordPress themes When I run `wp theme list` Then STDOUT should not be empty - Scenario: Upgrading a theme - Given a WP install - And I run `wp theme install p2 --version=1.0.1` - - When I run `wp theme status` - Then STDOUT should contain: - """ - U = Update Available - """ - - When I run `wp theme status p2` - Then STDOUT should contain: - """ - Version: 1.0.1 (Update available) - """ - - When I run `wp theme update p2` - Then STDOUT should not be empty - - When I run `wp theme status p2` - Then STDOUT should not contain: - """ - (Update available) - """ diff --git a/features/upgradables.feature b/features/upgradables.feature new file mode 100644 index 0000000000..0dd81ef2d5 --- /dev/null +++ b/features/upgradables.feature @@ -0,0 +1,31 @@ +Feature: Manage WordPress themes and plugins + + Scenario Outline: Upgrading a theme or plugin + Given a WP install + And I run `wp <type> install <item> --version=<version>` + + When I run `wp <type> status` + Then STDOUT should contain: + """ + U = Update Available + """ + + When I run `wp <type> status <item>` + Then STDOUT should contain: + """ + Version: <version> (Update available) + """ + + When I run `wp <type> update <item>` + Then STDOUT should not be empty + + When I run `wp <type> status <item>` + Then STDOUT should not contain: + """ + (Update available) + """ + + Examples: + | type | item | version | + | theme | p2 | 1.0.1 | + | plugin | category-checklist-tree | 1.2 | diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index bed5291ffa..50c4bc1c5f 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -119,30 +119,35 @@ function install( $args, $assoc_args ) { } } - protected function get_api_for_version( $api, $version ) { - - list( $link ) = explode( $api->slug, $api->download_link ); + /** + * Prepare an API response for downloading a particular version of an item. + * + * @param object $response wordpress.org API response + * @param string $version The desired version of the package + */ + protected static function alter_api_response( $response, $version ) { + list( $link ) = explode( $response->slug, $response->download_link ); - if ( stripos( $api->download_link, 'theme' ) ) + if ( false !== strpos( $response->download_link, 'theme' ) ) $download_type = 'theme'; else $download_type = 'plugin'; - if ( 'dev' == $version ) { - $api->download_link = $link . $api->slug . '.zip'; - $api->version = 'Development Version'; + $response->download_link = $link . $response->slug . '.zip'; + $response->version = 'Development Version'; } else { - $api->download_link = $link . $api->slug . '.' . $version .'.zip'; - $api->version = $version; + $response->download_link = $link . $response->slug . '.' . $version .'.zip'; + $response->version = $version; // check if the requested version exists - $response = wp_remote_head( $api->download_link ); + $response = wp_remote_head( $response->download_link ); if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { - \WP_CLI::error( sprintf( "Can't find the requested %s's version %s in the WordPress.org %s repository.", $download_type, $version, $download_type ) ); - } + \WP_CLI::error( sprintf( + "Can't find the requested %s's version %s in the WordPress.org %s repository.", + $download_type, $version, $download_type ) ); + } } - return $api; } protected function _update( $item ) { diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 162b2539d7..6d6f1200ee 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -158,21 +158,7 @@ protected function install_from_repo( $slug, $assoc_args ) { } if ( isset( $assoc_args['version'] ) ) { - list( $link ) = explode( $slug, $api->download_link ); - - if ( 'dev' == $assoc_args['version'] ) { - $api->download_link = $link . $slug . '.zip'; - $api->version = 'Development Version'; - } else { - $api->download_link = $link . $slug . '.' . $assoc_args['version'] .'.zip'; - $api->version = $assoc_args['version']; - - // check if the requested version exists - $response = wp_remote_head( $api->download_link ); - if ( !$response || $response['headers']['content-type'] != 'application/octet-stream' ) { - WP_CLI::error( "Can't find the requested plugin's version " . $assoc_args['version'] . " in the WordPress.org plugins repository." ); - } - } + self::alter_api_response( $api, $assoc_args['version'] ); } $status = install_plugin_install_status( $api ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 4c5414737d..4aceba9259 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -107,8 +107,9 @@ protected function install_from_repo( $slug, $assoc_args ) { WP_CLI::error( $api ); } - if ( ! empty( $assoc_args['version'] ) ) - $api = $this->get_api_for_version( $api, $assoc_args['version'] ); + if ( isset( $assoc_args['version'] ) ) { + self::alter_api_response( $api, $assoc_args['version'] ); + } // Check to see if we should update, rather than install. if ( $this->has_update( $slug ) ) { From 42d3ab15fbf10fbf1380a9ac64573f886d8b1c43 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Jun 2013 16:35:15 +0300 Subject: [PATCH 1768/4858] contributing: use `behat --expand` Without --expand, it's hard to debug failures in scenarion outlines. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e4b8ec7e95..52ce37fda4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,7 +47,7 @@ Running the following as root in MySQL should do the trick: Finally, to run the tests: vendor/bin/phpunit - vendor/bin/behat + vendor/bin/behat --expand Finally... ---------- From f4169830d213245488c464c2c4fe4d6afdba3153 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Jun 2013 16:11:59 +0300 Subject: [PATCH 1769/4858] behat: generate new plugin instead of relying on Hello Dolly This allows us to check more things, since all the plugin data is frozen. --- features/plugin.feature | 43 +++++++++++++++++++++++++++------- features/scaffold.feature | 13 ---------- features/steps/basic_steps.php | 14 +++++++---- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index b1093e2f89..5ab78736dc 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -1,24 +1,49 @@ Feature: Manage WordPress plugins - Scenario: Checking the plugin status + Scenario: Create, activate and check plugin status Given a WP install + And I run `wp plugin path` + And save STDOUT as {PLUGIN_DIR} - When I run `wp plugin status` + When I run `wp plugin scaffold zombieland --plugin_name="Zombieland"` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist + + When I run `wp plugin status zombieland` + Then STDOUT should contain: + """ + Plugin zombieland details: + Name: Zombieland + Status: Inactive + Version: 0.1-alpha + Author: YOUR NAME HERE + Description: PLUGIN DESCRIPTION HERE + """ + + When I run `wp plugin activate zombieland` Then STDOUT should not be empty - When I run `wp plugin status hello` + When I run `wp plugin status zombieland` Then STDOUT should contain: """ - Plugin hello details: - Name: Hello Dolly + Status: Active """ - When I try `wp plugin status non-existent-plugin` + When I run `wp plugin status` + Then STDOUT should not be empty + + When I run `wp plugin list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | zombieland | active | none | 0.1-alpha | + + When I run `wp plugin delete zombieland` + Then the {PLUGIN_DIR}/zombieland file should not exist + + When I try `wp plugin status zombieland` Then the return code should be 1 And STDERR should contain: """ - Error: The plugin 'non-existent-plugin' could not be found. + Error: The plugin 'zombieland' could not be found. """ - When I run `wp plugin list --format=json` - Then STDOUT should not be empty diff --git a/features/scaffold.feature b/features/scaffold.feature index 6143dd8deb..5e26019647 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -10,19 +10,6 @@ Feature: Wordpress code scaffolding Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist - @plugin - Scenario: Scaffold a plugin - Given a WP install - And I run `wp plugin path` - And save STDOUT as {PLUGIN_DIR} - - When I run `wp plugin scaffold zombieland --plugin_name="Welcome to Zombieland" --activate` - Then STDOUT should not be empty - And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist - - When I run `wp plugin activate zombieland` - Then STDOUT should not be empty - @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 700cf47361..c90c4a736b 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -216,7 +216,7 @@ function ( $world, $stream ) { } ); -$steps->Then( '/^the (.+) file should (exist|be:|contain:|not contain:)$/', +$steps->Then( '/^the (.+) file should (exist|not exist|be:|contain:|not contain:)$/', function ( $world, $path, $action, $expected = null ) { $path = $world->replace_variables( $path ); @@ -224,9 +224,15 @@ function ( $world, $path, $action, $expected = null ) { if ( '/' !== $path[0] ) $path = $world->get_path( $path ); - assertFileExists( $path ); - - if ( 'exist' !== $action ) { + switch ( $action ) { + case 'exist': + assertFileExists( $path ); + break; + case 'not exist': + assertFileNotExists( $path ); + break; + default: + assertFileExists( $path ); $action = substr( $action, 0, -1 ); $expected = $world->replace_variables( (string) $expected ); checkString( file_get_contents( $path ), $expected, $action ); From f2df95dad28ef7fc0540ad528f534ee9c5487360 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Jun 2013 17:26:33 +0300 Subject: [PATCH 1770/4858] Ensure `wp plugin delete` and `wp theme delete` output consistent messages. --- features/plugin.feature | 23 ++++++++++++++++++----- features/upgradables.feature | 15 +++++++++++++-- php/commands/plugin.php | 36 +++++++++++++++++++++++------------- php/commands/theme.php | 5 +++-- 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 5ab78736dc..174ab4abe7 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -37,13 +37,26 @@ Feature: Manage WordPress plugins | name | status | update | version | | zombieland | active | none | 0.1-alpha | - When I run `wp plugin delete zombieland` - Then the {PLUGIN_DIR}/zombieland file should not exist - - When I try `wp plugin status zombieland` + When I try `wp plugin uninstall zombieland` Then the return code should be 1 And STDERR should contain: """ - Error: The plugin 'zombieland' could not be found. + The plugin is active. """ + When I run `wp plugin deactivate zombieland` + Then STDOUT should not be empty + + When I run `wp plugin uninstall zombieland` + Then STDOUT should contain: + """ + Success: Uninstalled 'zombieland' plugin. + """ + And the {PLUGIN_DIR}/zombieland file should not exist + + When I try the previous command again + Then the return code should be 1 + And STDERR should contain: + """ + The plugin 'zombieland' could not be found. + """ diff --git a/features/upgradables.feature b/features/upgradables.feature index 0dd81ef2d5..e444286176 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -1,6 +1,6 @@ Feature: Manage WordPress themes and plugins - Scenario Outline: Upgrading a theme or plugin + Scenario Outline: Installing, upgrading and deleting a theme or plugin Given a WP install And I run `wp <type> install <item> --version=<version>` @@ -13,7 +13,8 @@ Feature: Manage WordPress themes and plugins When I run `wp <type> status <item>` Then STDOUT should contain: """ - Version: <version> (Update available) + Status: Inactive + Version: <version> (Update available) """ When I run `wp <type> update <item>` @@ -25,6 +26,16 @@ Feature: Manage WordPress themes and plugins (Update available) """ + When I run `wp <type> delete <item>` + Then STDOUT should contain: + """ + Success: Deleted '<item>' <type>. + """ + + When I try `wp <type> status <item>` + Then the return code should be 1 + And STDERR should not be empty + Examples: | type | item | version | | theme | p2 | 1.0.1 | diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 6d6f1200ee..4b860a0818 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -192,12 +192,12 @@ protected function install_from_repo( $slug, $assoc_args ) { * @synopsis <plugin> [--version=<version>] */ function update( $args, $assoc_args ) { + list( $basename ) = $this->parse_name( $args ); + if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { - $this->delete( $args, array(), false ); + $this->_delete( $basename, false ); $this->install( $args, $assoc_args ); } else { - list( $basename ) = $this->parse_name( $args ); - $was_active = is_plugin_active( $basename ); $was_network_active = is_plugin_active_for_network( $basename ); @@ -264,8 +264,12 @@ function uninstall( $args, $assoc_args = array() ) { uninstall_plugin( $file ); - if ( !isset( $assoc_args['no-delete'] ) ) - $this->delete( $args ); + if ( isset( $assoc_args['no-delete'] ) ) + return; + + if ( $this->_delete( $file ) ) { + WP_CLI::success( sprintf( "Uninstalled '%s' plugin.", $name ) ); + } } /** @@ -273,16 +277,12 @@ function uninstall( $args, $assoc_args = array() ) { * * @synopsis <plugin> */ - function delete( $args, $assoc_args = array(), $exit_on_error = true ) { + function delete( $args, $assoc_args = array() ) { list( $file, $name ) = $this->parse_name( $args ); - $plugin_dir = dirname( $file ); - if ( '.' == $plugin_dir ) - $plugin_dir = $file; - - $command = 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ); - - return WP_CLI::launch( $command, $exit_on_error ); + if ( $this->_delete( $file ) ) { + WP_CLI::success( sprintf( "Deleted '%s' plugin.", $name ) ); + } } /** @@ -362,6 +362,16 @@ private function get_name( $file ) { return $name; } + + private function _delete( $file ) { + $plugin_dir = dirname( $file ); + if ( '.' == $plugin_dir ) + $plugin_dir = $file; + + $command = 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ); + + return ! WP_CLI::launch( $command ); + } } WP_CLI::add_command( 'plugin', 'Plugin_Command' ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 4aceba9259..50245e7143 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -189,18 +189,19 @@ function update_all( $args, $assoc_args ) { */ function delete( $args ) { $theme = $this->parse_name( $args ); + $theme_slug = $theme->get_stylesheet(); if ( $this->is_active_theme( $theme ) ) { WP_CLI::error( "Can't delete the currently active theme." ); } - $r = delete_theme( $theme->get_stylesheet() ); + $r = delete_theme( $theme_slug ); if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); } - WP_CLI::success( "$theme->name theme deleted." ); + WP_CLI::success( sprintf( "Deleted '%s' theme.", $theme_slug ) ); } /** From 15bf1fe4259c291562410e169ac675f7dbe8b41d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 4 Jun 2013 18:04:18 +0300 Subject: [PATCH 1771/4858] option: add success messages see #472 --- features/option.feature | 6 +++--- php/commands/option.php | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/features/option.feature b/features/option.feature index 0ab33e8158..707c4fe82e 100644 --- a/features/option.feature +++ b/features/option.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress options Given a WP install When I run `wp option add foo 'bar'` - Then STDOUT should be empty + Then STDOUT should not be empty When I run `wp option get foo` Then STDOUT should be: @@ -13,7 +13,7 @@ Feature: Manage WordPress options """ When I run `wp option set foo '[ 1, 2 ]' --format=json` - Then STDOUT should be empty + Then STDOUT should not be empty When I run `wp option get foo --format=json` Then STDOUT should be: @@ -22,7 +22,7 @@ Feature: Manage WordPress options """ When I run `wp option delete foo` - Then STDOUT should be empty + Then STDOUT should not be empty When I try `wp option get foo` Then the return code should be 1 diff --git a/php/commands/option.php b/php/commands/option.php index 361a1f73ba..fb39ce7b59 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -35,6 +35,8 @@ public function add( $args, $assoc_args ) { if ( !add_option( $key, $value ) ) { WP_CLI::error( "Could not add option '$key'. Does it already exist?" ); + } else { + WP_CLI::success( "Added '$key' option." ); } } @@ -54,6 +56,8 @@ public function update( $args, $assoc_args ) { if ( !update_option( $key, $value ) ) { WP_CLI::error( "Could not update option '$key'." ); + } else { + WP_CLI::success( "Updated '$key' option." ); } } @@ -67,6 +71,8 @@ public function delete( $args ) { if ( !delete_option( $key ) ) { WP_CLI::error( "Could not delete '$key' option. Does it exist?" ); + } else { + WP_CLI::success( "Deleted '$key' option." ); } } } From 682b0d51afc68f776fa907e0f308c3b03c5b2346 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Apr 2013 21:50:34 +0300 Subject: [PATCH 1772/4858] core is-installed: let the bootstrap process show the error message. --- features/core.feature | 4 ++++ php/WP_CLI/Runner.php | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index eb9d7339d9..29478558d6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -6,6 +6,7 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 + And STDERR should not be empty When I run `wp core download --quiet` Then the wp-settings.php file should exist @@ -22,6 +23,7 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 + And STDERR should not be empty When I try `wp core install` Then the return code should be 1 @@ -69,6 +71,7 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 + And STDERR should not be empty When I try `wp` Then the return code should be 1 @@ -88,6 +91,7 @@ Feature: Manage WordPress installation Given a WP install When I run `wp core is-installed` + Then STDOUT should be empty When I run `wp eval 'var_export( is_admin() );'` Then STDOUT should be: diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b0f9b9c912..6a02c39d01 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -358,8 +358,7 @@ public function before_wp_load() { } if ( - $this->cmd_starts_with( array( 'core', 'install' ) ) || - $this->cmd_starts_with( array( 'core', 'is-installed' ) ) + $this->cmd_starts_with( array( 'core', 'install' ) ) ) { define( 'WP_INSTALLING', true ); From 7ed975a42fe06f9adc0f20700dc764ad7dcdeb7d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Jun 2013 04:04:07 +0300 Subject: [PATCH 1773/4858] composer: update mustache to 2.3.x; update composer.lock --- composer.json | 2 +- composer.lock | 107 ++++++++++++++++++++++++++------------------------ 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/composer.json b/composer.json index ff0d20c9de..895c4e2f90 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "require": { "php": ">=5.3.2", "wp-cli/php-cli-tools": "dev-master", - "mustache/mustache": "2.0.x" + "mustache/mustache": "2.3.x" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" diff --git a/composer.lock b/composer.lock index a16ee74ea4..6e824d1cfe 100644 --- a/composer.lock +++ b/composer.lock @@ -3,20 +3,20 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "e83d4615b33cb717939303cba9848c94", + "hash": "9cb0bdfbcfa8b3b505b9241ca38f19f7", "packages": [ { "name": "mustache/mustache", - "version": "v2.0.2", + "version": "v2.3.1", "source": { "type": "git", - "url": "https://github.com/bobthecow/mustache.php", - "reference": "v2.0.2" + "url": "https://github.com/bobthecow/mustache.php.git", + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://github.com/bobthecow/mustache.php/zipball/v2.0.2", - "reference": "v2.0.2", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { @@ -45,7 +45,7 @@ "mustache", "templating" ], - "time": "2012-09-12 09:13:06" + "time": "2013-04-25 15:23:30" }, { "name": "wp-cli/php-cli-tools", @@ -221,16 +221,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "1.2.9", + "version": "1.2.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "1.2.9" + "reference": "1.2.11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.9", - "reference": "1.2.9", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.11", + "reference": "1.2.11", "shasum": "" }, "require": { @@ -239,6 +239,9 @@ "phpunit/php-text-template": ">=1.1.1@stable", "phpunit/php-token-stream": ">=1.1.3@stable" }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, "suggest": { "ext-dom": "*", "ext-xdebug": ">=2.0.5" @@ -270,7 +273,7 @@ "testing", "xunit" ], - "time": "2013-02-26 18:55:56" + "time": "2013-05-23 18:23:24" }, { "name": "phpunit/php-file-iterator", @@ -452,16 +455,16 @@ }, { "name": "phpunit/phpunit", - "version": "3.7.19", + "version": "3.7.21", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.19" + "reference": "3.7.21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.19", - "reference": "3.7.19", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.21", + "reference": "3.7.21", "shasum": "" }, "require": { @@ -475,7 +478,7 @@ "phpunit/php-text-template": ">=1.1.1", "phpunit/php-timer": ">=1.0.2,<1.1.0", "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", - "symfony/yaml": ">=2.0.0,<2.3.0" + "symfony/yaml": ">=2.0,<3.0" }, "require-dev": { "pear-pear/pear": "1.9.4" @@ -522,7 +525,7 @@ "testing", "xunit" ], - "time": "2013-03-25 11:45:06" + "time": "2013-05-23 18:54:29" }, { "name": "phpunit/phpunit-mock-objects", @@ -575,17 +578,17 @@ }, { "name": "symfony/config", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -618,21 +621,21 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2013-03-01 10:42:10" + "time": "2013-05-10 18:08:31" }, { "name": "symfony/console", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -665,21 +668,21 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2013-03-19 20:48:08" + "time": "2013-05-27 14:47:40" }, { "name": "symfony/dependency-injection", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -720,21 +723,21 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2013-03-23 07:49:54" + "time": "2013-05-06 08:37:50" }, { "name": "symfony/event-dispatcher", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -778,17 +781,17 @@ }, { "name": "symfony/finder", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -821,21 +824,21 @@ ], "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2013-04-01 07:51:50" + "time": "2013-05-27 20:26:32" }, { "name": "symfony/translation", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -876,21 +879,21 @@ ], "description": "Symfony Translation Component", "homepage": "http://symfony.com", - "time": "2013-04-01 08:06:05" + "time": "2013-05-10 16:49:00" }, { "name": "symfony/yaml", - "version": "v2.2.1", + "version": "v2.2.2", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.2.1" + "reference": "v2.2.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.1", - "reference": "v2.2.1", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.2", + "reference": "v2.2.2", "shasum": "" }, "require": { @@ -923,7 +926,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-03-23 07:49:54" + "time": "2013-05-10 18:08:31" } ], "aliases": [ From 03fb31d13fc2359b0347bd39a81087126a6d007a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 5 Jun 2013 04:14:58 +0300 Subject: [PATCH 1774/4858] bump version to 0.10.0-beta2 [ci skip] --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 1b40a05d3f..cae0c4c287 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.0-beta' ); +define( 'WP_CLI_VERSION', '0.10.0-beta2' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 8491cfbcb4d7c2e6fa093e2fd9c47632eb1648bc Mon Sep 17 00:00:00 2001 From: James Collins <james@jamesc.id.au> Date: Wed, 5 Jun 2013 22:42:10 +1000 Subject: [PATCH 1775/4858] Only use maintenance mode if a plugin or theme needs updating When updating plugins (wp plugin update-all) or themes (wp theme update-all) on a WordPress multisite installation, maintenance activated and deactivated even if there are no updates to install. The Plugin_Upgrader::bulk_upgrade() and Theme_Upgrader::bulk_upgrade() WordPress functions currently don't check that the array passed to it isn't empty, causing maintenance mode to be enabled even if no updates are required. This bug doesn't affect non multisite installs, because for non multisite installs the code in Plugin_Upgrader::bulk_upgrade() and Theme_Upgrader::bulk_upgrade() only uses maintenance mode if the plugin/theme being updated is activated. Fixes #491 --- php/WP_CLI/CommandWithUpgrade.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 50c4bc1c5f..f02f3c6f5d 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -179,7 +179,8 @@ function update_all( $args, $assoc_args ) { } $upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); - $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); + + $result = count($items_to_update) ? $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ) : array(); // Let the user know the results. $num_to_update = count( $items_to_update ); From 186b0480e3b9940afdad73921abfe56842803642 Mon Sep 17 00:00:00 2001 From: James Collins <james@jamesc.id.au> Date: Wed, 5 Jun 2013 22:59:11 +1000 Subject: [PATCH 1776/4858] Change ternary operator to simple if statement --- php/WP_CLI/CommandWithUpgrade.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index f02f3c6f5d..ad18dbe83c 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -180,7 +180,11 @@ function update_all( $args, $assoc_args ) { $upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); - $result = count($items_to_update) ? $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ) : array(); + $result = array(); + + // Only attempt to update if there is something to update + if ( count($items_to_update) > 0 ) + $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); // Let the user know the results. $num_to_update = count( $items_to_update ); From 2e220527ac4ad325a357c1d7ccedcc8d8b96c66c Mon Sep 17 00:00:00 2001 From: James Collins <james@jamesc.id.au> Date: Wed, 5 Jun 2013 23:41:29 +1000 Subject: [PATCH 1777/4858] Use empty() check instead of count() Requested in https://github.com/wp-cli/wp-cli/pull/492#discussion_r4545088. --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index ad18dbe83c..cf771d6f58 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -183,7 +183,7 @@ function update_all( $args, $assoc_args ) { $result = array(); // Only attempt to update if there is something to update - if ( count($items_to_update) > 0 ) + if ( !empty( $items_to_update ) ) $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); // Let the user know the results. From 485dd3f64d8f973f012ca5d232eb9f3175fe6142 Mon Sep 17 00:00:00 2001 From: Ramon de la Fuente <ramon@future500.nl> Date: Thu, 6 Jun 2013 16:16:21 +0200 Subject: [PATCH 1778/4858] Allow capital letters in <value> tokens in @synopsis Values in @synopsis tags are not matched if they contain capital letters. This allows for capital letters i.e. --name=<myPropertyValue> fixes #493 --- php/WP_CLI/SynopsisParser.php | 2 +- tests/test-synopsis.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 2021c486c8..eb5dc8e0e8 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -108,7 +108,7 @@ static function parse( $synopsis ) { private static function init_patterns() { $p_name = '(?P<name>[a-z-_]+)'; - $p_value = '(?P<value>[a-z-|]+)'; + $p_value = '(?P<value>[a-zA-Z-|]+)'; self::gen_patterns( 'positional', "<$p_value>", array( 'mandatory', 'optional', 'repeating' ) ); self::gen_patterns( 'generic', "--<field>=<value>", array( 'mandatory', 'optional', 'repeating' ) ); diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index d54f9df2a9..9262b593eb 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -85,5 +85,23 @@ function testCombined() { $this->assertEquals( 'generic', $r[2]['type'] ); $this->assertEquals( 'flag', $r[3]['type'] ); } + + function testAllowedValueCharacters() { + $r = SynopsisParser::parse( '--capitals=<VALUE> --hyphen=<val-ue> --combined=<VAL-ue> --disallowed=<wrong:char>' ); + + $this->assertCount( 4, $r ); + + $this->assertEquals( 'assoc', $r[0]['type'] ); + $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + + $this->assertEquals( 'assoc', $r[1]['type'] ); + $this->assertEquals( 'mandatory', $r[1]['flavour'] ); + + $this->assertEquals( 'assoc', $r[2]['type'] ); + $this->assertEquals( 'mandatory', $r[2]['flavour'] ); + + $this->assertEquals( 'unknown', $r[3]['type'] ); + } + } From 1e1561d69f6a4bfe343d593a85851b0eceaf30ae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Jun 2013 17:37:08 +0300 Subject: [PATCH 1779/4858] remove `wp home` command --- man-src/home.txt | 0 man/home.1 | 10 ---------- php/commands/home.php | 28 ---------------------------- 3 files changed, 38 deletions(-) delete mode 100644 man-src/home.txt delete mode 100644 man/home.1 delete mode 100644 php/commands/home.php diff --git a/man-src/home.txt b/man-src/home.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/man/home.1 b/man/home.1 deleted file mode 100644 index 184b182908..0000000000 --- a/man/home.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-HOME" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-home\fR \- Open the wp\-cli homepage in your browser\. -. -.SH "SYNOPSIS" -wp home diff --git a/php/commands/home.php b/php/commands/home.php deleted file mode 100644 index eed233f66a..0000000000 --- a/php/commands/home.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -class Home_Command extends WP_CLI_Command { - - /** - * Open the wp-cli homepage in your browser. - */ - function __invoke() { - // The url for the wp-cli repository - $repository_url = 'https://github.com/wp-cli/wp-cli'; - - // Open the wp-cli page in the browser - if ( exec( 'which x-www-browser' ) ) { - system( 'x-www-browser '.$repository_url ); - } - elseif ( exec( 'which open' ) ) { - system( 'open '.$repository_url ); - } - else { - WP_CLI::error( 'No command found to open the homepage in the browser. Please open it manually: '.$repository_url ); - return; - } - - WP_CLI::success( 'The wp-cli homepage should be opening in your browser.' ); - } -} - -WP_CLI::add_command( 'home', 'Home_Command' ); From 3c3f624c4cc413fbbdbe7d26ce112a5160dde0db Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 12:55:22 +0300 Subject: [PATCH 1780/4858] bump version to 0.10.0-RC --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index cae0c4c287..63ea796689 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.0-beta2' ); +define( 'WP_CLI_VERSION', '0.10.0-RC' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From c06ba098837720f18f0aa1caa45bf2789fab415d Mon Sep 17 00:00:00 2001 From: daithi-coombes <webeire@gmail.com> Date: Sat, 8 Jun 2013 13:54:39 +0100 Subject: [PATCH 1781/4858] search-replace function modified to perform a search and replace through multisite specific tables --- features/search-replace.feature | 9 ++++++ php/commands/search-replace.php | 51 ++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 978959bab9..df3884df31 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,6 +15,15 @@ Feature: Do global search/replace guid """ + Scenario: Multisite search/replace + Given a WP multisite install + And I run `wp blog create --slug="foo" --title="foo" --email="foo@example.com"` + And I run `wp search-replace foo bar --multisite` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | + | wp_2_posts | guid | 2 | + | wp_blogs | path | 1 | + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install And I run `wp option get siteurl` diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 3a2af08895..478f296839 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,25 +10,54 @@ class Search_Replace_Command extends WP_CLI_Command { /** * Search/replace strings in the database. * - * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] + * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--multisite] */ public function __invoke( $args, $assoc_args ) { - global $wpdb; + //vars + global $wpdb; $old = array_shift( $args ); $new = array_shift( $args ); + $total = 0; + $report = array(); + $dry_run = isset( $assoc_args['dry-run'] ); + $multisite = isset( $assoc_args['multisite'] ); + /** + * build list of tables to find/replace + */ if ( !empty( $args ) ) { $tables = $args; } else { - $tables = $wpdb->tables( 'blog' ); - } - - $total = 0; - $report = array(); + $tables = $wpdb->tables( 'blog' ); - $dry_run = isset( $assoc_args['dry-run'] ); + if( $multisite ) { + $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}blogs ORDER BY blog_id" ) ); + $mu_tables = $wpdb->tables( 'global' ); + + if( ! $wpdb->query("SHOW TABLES LIKE '{$mu_tables['sitecategories']}' " ) ) + unset( $mu_tables['sitecategories'] ); //table $prefix_sitecategories not found + + foreach( $blogs as $blog ){ + if( $blog->blog_id == 1 ) + continue; + + foreach( $tables as $table_ref => $table ){ + $tbl = "{$wpdb->prefix}{$blog->blog_id}_{$table_ref}"; + $mu_tables[$tbl] = $tbl; + } + } + + //set multisite vars + $tables = array_merge( $mu_tables, $tables ); + if ( isset( $assoc_args['skip-columns'] ) ) + $assoc_args['skip-columns'] .= ",user_pass"; + else + $assoc_args['skip-columns'] .= "user_pass"; + } + } + //end build list of tables to find/replace if ( isset( $assoc_args['skip-columns'] ) ) $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -37,7 +66,6 @@ public function __invoke( $args, $assoc_args ) { foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); - foreach ( $columns as $col ) { if ( in_array( $col, $skip_columns ) ) continue; @@ -73,6 +101,9 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry 'chunk_size' => $chunk_size ); + if($primary_key===null) + return "skipped"; + $it = new \WP_CLI\Iterators\Table( $args ); $count = 0; @@ -93,7 +124,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry ); } } - + return $count; } From 415695ee5e56efb2e17512147dfdbc7fccd39912 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 16:08:10 +0300 Subject: [PATCH 1782/4858] search-replace: whitespace fixes --- php/commands/search-replace.php | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 478f296839..77c47a9094 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -13,8 +13,6 @@ class Search_Replace_Command extends WP_CLI_Command { * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--multisite] */ public function __invoke( $args, $assoc_args ) { - - //vars global $wpdb; $old = array_shift( $args ); $new = array_shift( $args ); @@ -23,33 +21,29 @@ public function __invoke( $args, $assoc_args ) { $dry_run = isset( $assoc_args['dry-run'] ); $multisite = isset( $assoc_args['multisite'] ); - /** - * build list of tables to find/replace - */ + // build list of tables to find/replace if ( !empty( $args ) ) { $tables = $args; } else { - $tables = $wpdb->tables( 'blog' ); - if( $multisite ) { + if ( $multisite ) { $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}blogs ORDER BY blog_id" ) ); $mu_tables = $wpdb->tables( 'global' ); - - if( ! $wpdb->query("SHOW TABLES LIKE '{$mu_tables['sitecategories']}' " ) ) + + if ( ! $wpdb->query( "SHOW TABLES LIKE '{$mu_tables['sitecategories']}' " ) ) unset( $mu_tables['sitecategories'] ); //table $prefix_sitecategories not found - - foreach( $blogs as $blog ){ - if( $blog->blog_id == 1 ) + + foreach ( $blogs as $blog ) { + if ( $blog->blog_id == 1 ) continue; - foreach( $tables as $table_ref => $table ){ + foreach ( $tables as $table_ref => $table ) { $tbl = "{$wpdb->prefix}{$blog->blog_id}_{$table_ref}"; $mu_tables[$tbl] = $tbl; } } - //set multisite vars $tables = array_merge( $mu_tables, $tables ); if ( isset( $assoc_args['skip-columns'] ) ) $assoc_args['skip-columns'] .= ",user_pass"; @@ -57,7 +51,7 @@ public function __invoke( $args, $assoc_args ) { $assoc_args['skip-columns'] .= "user_pass"; } } - //end build list of tables to find/replace + // end build list of tables to find/replace if ( isset( $assoc_args['skip-columns'] ) ) $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -101,9 +95,9 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry 'chunk_size' => $chunk_size ); - if($primary_key===null) + if ( $primary_key===null ) return "skipped"; - + $it = new \WP_CLI\Iterators\Table( $args ); $count = 0; @@ -124,7 +118,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry ); } } - + return $count; } From 91fa8f55eb4a6820755142c22e2bc0bd2e0c2833 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 16:09:37 +0300 Subject: [PATCH 1783/4858] search-replace: blacklist user_pass column later --- php/commands/search-replace.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 77c47a9094..2d20e251a5 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -45,10 +45,6 @@ public function __invoke( $args, $assoc_args ) { } $tables = array_merge( $mu_tables, $tables ); - if ( isset( $assoc_args['skip-columns'] ) ) - $assoc_args['skip-columns'] .= ",user_pass"; - else - $assoc_args['skip-columns'] .= "user_pass"; } } // end build list of tables to find/replace @@ -58,6 +54,9 @@ public function __invoke( $args, $assoc_args ) { else $skip_columns = array(); + // never mess with hashed passwords + $skip_columns[] = 'user_pass'; + foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); foreach ( $columns as $col ) { From 8352de2bafaf2f07f2c6e6520c3ad46a70b93f61 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 16:17:32 +0300 Subject: [PATCH 1784/4858] search-replace: extract get_table_list() method --- php/commands/search-replace.php | 63 +++++++++++++++++---------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 2d20e251a5..600302cc15 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -13,41 +13,11 @@ class Search_Replace_Command extends WP_CLI_Command { * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--multisite] */ 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'] ); - $multisite = isset( $assoc_args['multisite'] ); - - // build list of tables to find/replace - if ( !empty( $args ) ) { - $tables = $args; - } else { - $tables = $wpdb->tables( 'blog' ); - - if ( $multisite ) { - $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}blogs ORDER BY blog_id" ) ); - $mu_tables = $wpdb->tables( 'global' ); - - if ( ! $wpdb->query( "SHOW TABLES LIKE '{$mu_tables['sitecategories']}' " ) ) - unset( $mu_tables['sitecategories'] ); //table $prefix_sitecategories not found - - foreach ( $blogs as $blog ) { - if ( $blog->blog_id == 1 ) - continue; - - foreach ( $tables as $table_ref => $table ) { - $tbl = "{$wpdb->prefix}{$blog->blog_id}_{$table_ref}"; - $mu_tables[$tbl] = $tbl; - } - } - - $tables = array_merge( $mu_tables, $tables ); - } - } - // end build list of tables to find/replace if ( isset( $assoc_args['skip-columns'] ) ) $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -57,6 +27,8 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; + $tables = self::get_table_list( $args, isset( $assoc_args['multisite'] ) ); + foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); foreach ( $columns as $col ) { @@ -81,6 +53,37 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::success( "Made $total replacements." ); } + private static function get_table_list( $args, $multisite ) { + global $wpdb; + + if ( !empty( $args ) ) + return $args; + + $tables = $wpdb->tables( 'blog' ); + + if ( $multisite ) { + $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}blogs ORDER BY blog_id" ) ); + $mu_tables = $wpdb->tables( 'global' ); + + if ( ! $wpdb->query( "SHOW TABLES LIKE '{$mu_tables['sitecategories']}' " ) ) + unset( $mu_tables['sitecategories'] ); //table $prefix_sitecategories not found + + foreach ( $blogs as $blog ) { + if ( $blog->blog_id == 1 ) + continue; + + foreach ( $tables as $table_ref => $table ) { + $tbl = "{$wpdb->prefix}{$blog->blog_id}_{$table_ref}"; + $mu_tables[$tbl] = $tbl; + } + } + + $tables = array_merge( $mu_tables, $tables ); + } + + return $tables; + } + private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { global $wpdb; From 5eb3aff846f3e7af054590b360c497dec2c6fa3f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 16:22:21 +0300 Subject: [PATCH 1785/4858] search-replace: fix warning from using wpdb->prepare() with only 1 parameter --- php/commands/search-replace.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 600302cc15..998cacb265 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -62,11 +62,15 @@ private static function get_table_list( $args, $multisite ) { $tables = $wpdb->tables( 'blog' ); if ( $multisite ) { - $blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}blogs ORDER BY blog_id" ) ); $mu_tables = $wpdb->tables( 'global' ); - if ( ! $wpdb->query( "SHOW TABLES LIKE '{$mu_tables['sitecategories']}' " ) ) - unset( $mu_tables['sitecategories'] ); //table $prefix_sitecategories not found + // The $prefix_sitecategories table isn't always present + if ( ! $wpdb->query( $wpdb->prepare( "SHOW TABLES LIKE %s", + $mu_tables['sitecategories'] ) ) ) { + unset( $mu_tables['sitecategories'] ); + } + + $blogs = $wpdb->get_results( "SELECT * FROM $wpdb->blogs ORDER BY blog_id" ); foreach ( $blogs as $blog ) { if ( $blog->blog_id == 1 ) From 7ccbc9d77766d5ffa98ab22ab73629794b6bca70 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 16:36:18 +0300 Subject: [PATCH 1786/4858] search-replace: use a single SHOW TABLES query to get list of multisite tables Besides simplicity, it avoids warnings for non-existant tables. For example, the Posts 2 Posts plugin creates 2 custom, per-blog tables. But it might not be activated on all blogs. --- php/commands/search-replace.php | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 998cacb265..56e740f6b6 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -59,30 +59,10 @@ private static function get_table_list( $args, $multisite ) { if ( !empty( $args ) ) return $args; - $tables = $wpdb->tables( 'blog' ); - - if ( $multisite ) { - $mu_tables = $wpdb->tables( 'global' ); - - // The $prefix_sitecategories table isn't always present - if ( ! $wpdb->query( $wpdb->prepare( "SHOW TABLES LIKE %s", - $mu_tables['sitecategories'] ) ) ) { - unset( $mu_tables['sitecategories'] ); - } - - $blogs = $wpdb->get_results( "SELECT * FROM $wpdb->blogs ORDER BY blog_id" ); - - foreach ( $blogs as $blog ) { - if ( $blog->blog_id == 1 ) - continue; - - foreach ( $tables as $table_ref => $table ) { - $tbl = "{$wpdb->prefix}{$blog->blog_id}_{$table_ref}"; - $mu_tables[$tbl] = $tbl; - } - } - - $tables = array_merge( $mu_tables, $tables ); + if ( !$multisite ) { + $tables = $wpdb->tables( 'blog' ); + } else { + $tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->base_prefix}%'" ); } return $tables; From 9234c0804d97e596c2b0168282d55cdf955f0618 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 16:49:38 +0300 Subject: [PATCH 1787/4858] search-replace: move primary key check --- php/commands/search-replace.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 56e740f6b6..e7d3faede0 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -31,6 +31,14 @@ public function __invoke( $args, $assoc_args ) { 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; @@ -81,9 +89,6 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry 'chunk_size' => $chunk_size ); - if ( $primary_key===null ) - return "skipped"; - $it = new \WP_CLI\Iterators\Table( $args ); $count = 0; From bad9f6d0f2cbaed4819096050a85eefe3a7229ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 8 Jun 2013 17:01:01 +0300 Subject: [PATCH 1788/4858] search-replace: update man page --- man-src/search-replace.txt | 4 ++++ man/search-replace.1 | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index f6ead0c895..de5fdca915 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -6,6 +6,10 @@ It will correctly handle serialized values, and will not change primary key valu ## OPTIONS +* `--multisite`: + + Search/replace through all the tables in a multisite install. + * `--skip-columns=<columns>`: Do not perform the replacement in the comma-separated columns. diff --git a/man/search-replace.1 b/man/search-replace.1 index 7ee007f607..963900f394 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -7,7 +7,7 @@ \fBwp\-search\-replace\fR \- Search/replace strings in the database\. . .SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-skip\-columns=\fIcolumns\fR] [\-\-dry\-run] +wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-skip\-columns=\fIcolumns\fR] [\-\-dry\-run] [\-\-multisite] . .SH "DESCRIPTION" This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. From ea497952deb1dc6f04fa9b96763bf92436adaf0c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 00:06:59 +0300 Subject: [PATCH 1789/4858] bump version to 0.10.0 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 63ea796689..b4c7d52217 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.0-RC' ); +define( 'WP_CLI_VERSION', '0.10.0' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 348e6125caf26f9bdcba918a33476d0a15d2f21a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 00:36:50 +0300 Subject: [PATCH 1790/4858] contrib-list: validate github URLs --- utils/contrib-list | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/utils/contrib-list b/utils/contrib-list index 76f5a1531b..43d8f1542d 100755 --- a/utils/contrib-list +++ b/utils/contrib-list @@ -8,9 +8,22 @@ fi prev_version=$1 linked=$2 +githubify() { + local url="https://github.com/$name" + local response_code=$(curl -o /dev/null --silent --head --write-out '%{http_code}\n' $url) + + if [ "200" != "$response_code" ]; then + echo "$response_code: $url" 1>&2; + fi + + while read name; do + echo " [$name]($url)" + done +} + if [ '-l' == "$linked" ] then - git log --format="%aN" $prev_version -- | sort | uniq | sed 's#\(.*\)# [\1](http://github.com/\1)#' | tr '\n' ',' + git log --format="%aN" $prev_version -- | sort | uniq | githubify | tr '\n' ',' else git log --format="%aN <%aE>" $prev_version -- | sort | uniq fi From 4f6dbb8d53ec5904dd722dfdcdd23b7003fe4812 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 00:51:09 +0300 Subject: [PATCH 1791/4858] mailmap: add new contributors from 0.10 release --- .mailmap | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.mailmap b/.mailmap index cb5c30bb23..682554bd43 100644 --- a/.mailmap +++ b/.mailmap @@ -2,13 +2,17 @@ andreascreten <andreas@madewithlove.be> bendoh <ben@thinkoomph.com> builtbylane <lanegoldberg@gmail.com> conatus <alex@recordsonribs.com> +cyberhobo <dylan.k.kuhn@gmail.com> danielbachhuber <d@danielbachhuber.com> drrobotnik <B@Brandons-Mac-Pro-4.local> dwightjack <marco.solazzi@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> +future500 <ramon@future500.nl> getsource <mike.schroder@dreamhost.com> +glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> +j3lamp <j3lamp@gmail.com> jghazally <jeff@bigfish.co.uk> jghazally <jghazally@gmail.com> jmslbam <jmslbam@gmail.com> @@ -28,6 +32,7 @@ nacin <andrewnacin@gmail.com> navitronic <adrian@navitronic.co.uk> nb <nb@nikolay.bg> ocean90 <dominikschilling+git@gmail.com> +om4james <james@jamesc.id.au> roelven <roel@soundcloud.com> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> @@ -36,7 +41,11 @@ spuriousdata <spuriousdata@gmail.com> svaj <chris@chrisbot.(none)> taupecat <tracy@taupecat.com> tddewey <td@tddewey.com> +tlovett1 <admin@taylorlovett.com> tollmanz <zack@zackdev.com> toszcze <toszcze@gmail.com> tott <tott@automattic.com> +twisty <tim@brayshaw.com> +westonruter <weston@x-team.com> +westonruter <westonruter@gmail.com> wopr42 <john@zippykid.com> From 61dc7086e497eda0bf5209033601a7c41077af8f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 01:33:58 +0300 Subject: [PATCH 1792/4858] search-replace: rename --multisite flag to --network it's more consistent with other commands fixes #504; see #501 --- features/search-replace.feature | 2 +- man-src/search-replace.txt | 2 +- man/search-replace.1 | 8 +++++++- php/commands/search-replace.php | 8 ++++---- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index df3884df31..07fa919f16 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -18,7 +18,7 @@ Feature: Do global search/replace Scenario: Multisite search/replace Given a WP multisite install And I run `wp blog create --slug="foo" --title="foo" --email="foo@example.com"` - And I run `wp search-replace foo bar --multisite` + And I run `wp search-replace foo bar --network` Then STDOUT should be a table containing rows: | Table | Column | Replacements | | wp_2_posts | guid | 2 | diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt index de5fdca915..812dfcc97d 100644 --- a/man-src/search-replace.txt +++ b/man-src/search-replace.txt @@ -6,7 +6,7 @@ It will correctly handle serialized values, and will not change primary key valu ## OPTIONS -* `--multisite`: +* `--network`: Search/replace through all the tables in a multisite install. diff --git a/man/search-replace.1 b/man/search-replace.1 index 963900f394..6af388a6eb 100644 --- a/man/search-replace.1 +++ b/man/search-replace.1 @@ -7,7 +7,7 @@ \fBwp\-search\-replace\fR \- Search/replace strings in the database\. . .SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-skip\-columns=\fIcolumns\fR] [\-\-dry\-run] [\-\-multisite] +wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-skip\-columns=\fIcolumns\fR] [\-\-dry\-run] [\-\-network] . .SH "DESCRIPTION" This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. @@ -18,6 +18,12 @@ It will correctly handle serialized values, and will not change primary key valu .SH "OPTIONS" . .TP +\fB\-\-network\fR: +. +.IP +Search/replace through all the tables in a multisite install\. +. +.TP \fB\-\-skip\-columns=<columns>\fR: . .IP diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e7d3faede0..2a0f3309e9 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,7 +10,7 @@ class Search_Replace_Command extends WP_CLI_Command { /** * Search/replace strings in the database. * - * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--multisite] + * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--network] */ public function __invoke( $args, $assoc_args ) { $old = array_shift( $args ); @@ -27,7 +27,7 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; - $tables = self::get_table_list( $args, isset( $assoc_args['multisite'] ) ); + $tables = self::get_table_list( $args, isset( $assoc_args['network'] ) ); foreach ( $tables as $table ) { list( $primary_key, $columns ) = self::get_columns( $table ); @@ -61,13 +61,13 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::success( "Made $total replacements." ); } - private static function get_table_list( $args, $multisite ) { + private static function get_table_list( $args, $network ) { global $wpdb; if ( !empty( $args ) ) return $args; - if ( !$multisite ) { + if ( !$network ) { $tables = $wpdb->tables( 'blog' ); } else { $tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->base_prefix}%'" ); From 0066dac71fc85acc4f9da2a56824cafdb99fcd1c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 13:57:54 +0300 Subject: [PATCH 1793/4858] link to contributor guide from readme --- CONTRIBUTING.md | 1 + README.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 52ce37fda4..a2053192d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,7 @@ Contribute So you've got an awesome idea to throw into WP-CLI. Great! Here's the process, in a nutshell: 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. +2. Clone the repo and run `./utils/dev-build`. 2. Make the code changes in your fork. 3. Open a pull request. diff --git a/README.md b/README.md index 2c49bc83db..51151a18ab 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,7 @@ Need even more info? Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. + +Contributing +------------ +See [CONTRIBUTING.md](CONTRIBUTING.md). From 6ebf0b4f6a3ac81659530f1764fca32b049458f9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 15:02:15 +0300 Subject: [PATCH 1794/4858] bump version to 0.11.0-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index b4c7d52217..59cee2480e 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.0' ); +define( 'WP_CLI_VERSION', '0.11.0-alpha' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 653c6c7f9d014d6136945faa78e23908a18e382c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 15:37:23 +0300 Subject: [PATCH 1795/4858] contributing: remove confusing ./utils/dev-build step --- CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a2053192d4..52ce37fda4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,6 @@ Contribute So you've got an awesome idea to throw into WP-CLI. Great! Here's the process, in a nutshell: 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. -2. Clone the repo and run `./utils/dev-build`. 2. Make the code changes in your fork. 3. Open a pull request. From e5d5c09c0ad444831b8297f554ffa56673c4624f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 15:23:53 +0300 Subject: [PATCH 1796/4858] blog: don't hide multisite-only subcommands; just throw an error This is good for `wp help --gen`, which doesn't have a WP install. It's also good for users, since they have a clear indication of why the subcommand doesn't work. --- php/commands/blog.php | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/php/commands/blog.php b/php/commands/blog.php index d92e3ac393..dfc91e1db5 100644 --- a/php/commands/blog.php +++ b/php/commands/blog.php @@ -1,7 +1,7 @@ <?php /** - * Manage blog. + * Perform blog-wide operations. * * @package wp-cli */ @@ -124,12 +124,6 @@ public function _empty( $args, $assoc_args ) { WP_CLI::success( 'The blog at ' . site_url() . ' was emptied.' ); } -} - -/** - * Manage blogs in a multisite install. - */ -class MS_Blog_Command extends Blog_Command { /** * Delete a blog in a multisite install. @@ -137,6 +131,10 @@ class MS_Blog_Command extends Blog_Command { * @synopsis [<blog-id>] [--slug=<slug>] [--yes] [--keep-tables] */ function delete( $args, $assoc_args ) { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + if ( isset( $assoc_args['slug'] ) ) { $blog = get_blog_details( trim( $assoc_args['slug'], '/' ) ); } else { @@ -184,6 +182,10 @@ private function _get_site( $site_id ) { * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--site_id=<site-id>] [--private] [--porcelain] */ public function create( $_, $assoc_args ) { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + global $wpdb; $base = $assoc_args['slug']; @@ -278,11 +280,5 @@ public function create( $_, $assoc_args ) { } } -// We want multisite subcommands to be available when doing `wp help --gen blog` -if ( !function_exists( 'add_filter' ) || is_multisite() ) - $command_class = 'MS_Blog_Command'; -else - $command_class = 'Blog_Command'; - -WP_CLI::add_command( 'blog', $command_class ); +WP_CLI::add_command( 'blog', 'Blog_Command' ); From c88cfc815e65ff16519118426eb5419ed4e5a8a9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 16:40:22 +0300 Subject: [PATCH 1797/4858] move 'sql' aliasing to Runner --- php/WP_CLI/Dispatcher/RootCommand.php | 7 ------- php/WP_CLI/Runner.php | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 9fc159aee1..fb9b05de49 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -91,13 +91,6 @@ function pre_invoke( &$args ) { function find_subcommand( &$args ) { $command = array_shift( $args ); - $aliases = array( - 'sql' => 'db' - ); - - if ( isset( $aliases[ $command ] ) ) - $command = $aliases[ $command ]; - Utils\load_command( $command ); if ( !isset( $this->subcommands[ $command ] ) ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 621097b0de..6b17b49c81 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -223,6 +223,11 @@ private static function back_compat_conversions( $r ) { unset( $assoc_args['help'] ); } + // sql -> db + if ( count( $args ) > 0 && 'sql' == $args[0] ) { + $args[0] = 'db'; + } + // {plugin|theme} update --all -> {plugin|theme} update-all if ( count( $args ) > 1 && in_array( $args[0], array( 'plugin', 'theme' ) ) && $args[1] == 'update' && isset( $assoc_args['all'] ) From a8132f2db549185c732b04a38e1867d7b46e8c8d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 21:41:20 +0300 Subject: [PATCH 1798/4858] branding: the project name is 'WP-CLI', not 'wp-cli' It's an abbreviation for 'WordPress Command-Line Interface' --- README.md | 2 +- php/boot-fs.php | 2 +- php/class-wp-cli.php | 2 +- php/commands/_sys.php | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 51151a18ab..a85012c680 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ WP-CLI [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) -wp-cli is a set of command-line tools for managing WordPress installations. +WP-CLI is a set of command-line tools for managing WordPress installations. Where can I get more info? -------------------------- diff --git a/php/boot-fs.php b/php/boot-fs.php index a3311c887d..a227bfedec 100644 --- a/php/boot-fs.php +++ b/php/boot-fs.php @@ -8,7 +8,7 @@ } if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) { - printf( "Error: wp-cli requires PHP %s or newer. You are running version %s.\n", '5.3.0', PHP_VERSION ); + printf( "Error: WP-CLI requires PHP %s or newer. You are running version %s.\n", '5.3.0', PHP_VERSION ); die(-1); } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1daf81559d..71d87d80ba 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -39,7 +39,7 @@ static function set_logger( $logger ) { } /** - * Add a command to the wp-cli list of commands + * Add a command to the WP-CLI list of commands * * @param string $name The name of the command that will be used in the cli * @param string $class The command implementation diff --git a/php/commands/_sys.php b/php/commands/_sys.php index af2b1b714f..95aabdde28 100644 --- a/php/commands/_sys.php +++ b/php/commands/_sys.php @@ -23,7 +23,7 @@ private function command_to_array( $command ) { } function version() { - WP_CLI::line( 'wp-cli ' . WP_CLI_VERSION ); + WP_CLI::line( 'WP-CLI ' . WP_CLI_VERSION ); } function info() { @@ -32,9 +32,9 @@ function info() { WP_CLI::line( "PHP binary:\t" . $php_bin ); WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); - WP_CLI::line( "wp-cli root:\t" . WP_CLI_ROOT ); - WP_CLI::line( "wp-cli config:\t" . WP_CLI::get_config_path() ); - WP_CLI::line( "wp-cli version:\t" . WP_CLI_VERSION ); + WP_CLI::line( "WP-CLI root:\t" . WP_CLI_ROOT ); + WP_CLI::line( "WP-CLI config:\t" . WP_CLI::get_config_path() ); + WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); } /** From 268515f2ecb9da6ff2c1c54433ff3a441a805964 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 22:19:19 +0300 Subject: [PATCH 1799/4858] get rid of AtomicCommand interface --- .../Dispatcher/AbstractCommandContainer.php | 8 ++++++++ php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/WP_CLI/Dispatcher/Subcommand.php | 6 +++++- php/WP_CLI/Runner.php | 2 +- php/commands/_sys.php | 10 +++++----- php/dispatcher.php | 17 +++-------------- 6 files changed, 23 insertions(+), 22 deletions(-) diff --git a/php/WP_CLI/Dispatcher/AbstractCommandContainer.php b/php/WP_CLI/Dispatcher/AbstractCommandContainer.php index 29136f9206..7724a9b480 100644 --- a/php/WP_CLI/Dispatcher/AbstractCommandContainer.php +++ b/php/WP_CLI/Dispatcher/AbstractCommandContainer.php @@ -6,6 +6,14 @@ abstract class AbstractCommandContainer implements Command, CommandContainer { protected $subcommands = array(); + function get_synopsis() { + return ''; + } + + function invoke( $args, $assoc_args ) { + $this->show_usage(); + } + function add_subcommand( $name, Command $command ) { $this->subcommands[ $name ] = $command; } diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index fb9b05de49..99f4c25348 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -31,7 +31,7 @@ function show_usage() { \WP_CLI::line( sprintf( " %s %s", implode( ' ', get_path( $command ) ), - implode( '|', array_keys( get_subcommands( $command ) ) ) + implode( '|', array_keys( $command->get_subcommands() ) ) ) ); } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 91dfcbf548..c775ece897 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class Subcommand implements Command, AtomicCommand, Documentable { +class Subcommand implements Command, Documentable { private $parent, $name, $class, $method, $docparser; @@ -35,6 +35,10 @@ function get_parent() { return $this->parent; } + function get_subcommands() { + return array(); + } + function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $prefix . $this->get_full_synopsis() ); } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6b17b49c81..5332f75167 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -376,7 +376,7 @@ public function after_wp_load() { // Handle --completions parameter if ( isset( $this->assoc_args['completions'] ) ) { foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { - $subcommands = Dispatcher\get_subcommands( $command ); + $subcommands = $command->get_subcommands(); WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); } diff --git a/php/commands/_sys.php b/php/commands/_sys.php index 95aabdde28..963d48af6b 100644 --- a/php/commands/_sys.php +++ b/php/commands/_sys.php @@ -11,12 +11,12 @@ private function command_to_array( $command ) { 'description' => $command->get_shortdesc(), ); - if ( $command instanceof Dispatcher\AtomicCommand ) { + foreach ( $command->get_subcommands() as $subcommand ) { + $dump['subcommands'][] = self::command_to_array( $subcommand ); + } + + if ( empty( $dump['subcommands'] ) ) { $dump['synopsis'] = (string) $command->get_synopsis(); - } else { - foreach ( Dispatcher\get_subcommands( $command ) as $subcommand ) { - $dump['subcommands'][] = self::command_to_array( $subcommand ); - } } return $dump; diff --git a/php/dispatcher.php b/php/dispatcher.php index 168ced1eb8..b9921cb534 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -2,13 +2,6 @@ namespace WP_CLI\Dispatcher; -function get_subcommands( $command ) { - if ( $command instanceof CommandContainer ) - return $command->get_subcommands(); - - return array(); -} - function get_path( Command $command ) { $path = array(); @@ -24,22 +17,18 @@ interface Command { function get_name(); function get_parent(); + function get_synopsis(); - function show_usage(); -} - - -interface AtomicCommand { + function get_subcommands(); - function get_synopsis(); function invoke( $args, $assoc_args ); + function show_usage(); } interface CommandContainer { function add_subcommand( $name, Command $command ); - function get_subcommands(); function find_subcommand( &$args ); function pre_invoke( &$args ); From cd092fd19732e640cd171f57406af3bf2870302d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 22:23:00 +0300 Subject: [PATCH 1800/4858] everything is documentable, so get rid of the Documentable interface --- php/WP_CLI/Dispatcher/CompositeCommand.php | 2 +- php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/commands/help.php | 3 +-- php/dispatcher.php | 10 +++------- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 897992bbe7..f39b9b826d 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class CompositeCommand extends AbstractCommandContainer implements Documentable { +class CompositeCommand extends AbstractCommandContainer { protected $name; protected $shortdesc; diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 99f4c25348..88da4a363d 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -4,7 +4,7 @@ use \WP_CLI\Utils; -class RootCommand extends AbstractCommandContainer implements Documentable { +class RootCommand extends AbstractCommandContainer { function get_name() { return 'wp'; diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index c775ece897..1e0fcd3413 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -class Subcommand implements Command, Documentable { +class Subcommand implements Command { private $parent, $name, $class, $method, $docparser; diff --git a/php/commands/help.php b/php/commands/help.php index 12a31397d0..d23675de05 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -106,8 +106,7 @@ private static function get_markdown( $doc_path, $command ) { $fd = fopen( "php://temp", "rw" ); - if ( $command instanceof Dispatcher\Documentable ) - self::add_initial_markdown( $fd, $command ); + self::add_initial_markdown( $fd, $command ); fwrite( $fd, file_get_contents( $doc_path ) ); diff --git a/php/dispatcher.php b/php/dispatcher.php index b9921cb534..25d7ee3274 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -17,7 +17,10 @@ interface Command { function get_name(); function get_parent(); + function get_synopsis(); + function get_shortdesc(); + function get_full_synopsis(); function get_subcommands(); @@ -34,10 +37,3 @@ function find_subcommand( &$args ); function pre_invoke( &$args ); } - -interface Documentable { - - function get_shortdesc(); - function get_full_synopsis(); -} - From b34ede5128979309744048fcb7e979f1c63efd45 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 22:48:13 +0300 Subject: [PATCH 1801/4858] convert get_full_synopsis() method to a standalone function --- php/WP_CLI/Dispatcher/CompositeCommand.php | 10 -------- php/WP_CLI/Dispatcher/RootCommand.php | 4 --- php/WP_CLI/Dispatcher/Subcommand.php | 22 +--------------- php/commands/help.php | 2 +- php/dispatcher.php | 29 +++++++++++++++++++++- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index f39b9b826d..4febf465ea 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -73,15 +73,5 @@ private static function get_aliases( $subcommands ) { public function get_shortdesc() { return $this->shortdesc; } - - public function get_full_synopsis() { - $str = array(); - - foreach ( $this->subcommands as $subcommand ) { - $str[] = $subcommand->get_full_synopsis( true ); - } - - return implode( "\n\n", $str ); - } } diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 88da4a363d..f502134873 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -18,10 +18,6 @@ function get_shortdesc() { return ''; } - function get_full_synopsis() { - return ''; - } - function show_usage() { \WP_CLI::line( 'Available commands:' ); diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 1e0fcd3413..5af76a1ef6 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -40,33 +40,13 @@ function get_subcommands() { } function show_usage( $prefix = 'usage: ' ) { - \WP_CLI::line( $prefix . $this->get_full_synopsis() ); + \WP_CLI::line( $prefix . get_full_synopsis( $this ) ); } function get_shortdesc() { return $this->docparser->get_shortdesc(); } - function get_full_synopsis( $validate = false ) { - $full_name = implode( ' ', get_path( $this ) ); - $synopsis = $this->get_synopsis(); - - if ( $validate ) { - $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); - - foreach ( $tokens as $token ) { - if ( 'unknown' == $token['type'] ) { - \WP_CLI::warning( sprintf( - "Invalid token '%s' in synopsis for '%s'", - $token['token'], $full_name - ) ); - } - } - } - - return "$full_name $synopsis"; - } - function get_synopsis() { return $this->docparser->get_synopsis(); } diff --git a/php/commands/help.php b/php/commands/help.php index d23675de05..b56281a634 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -126,7 +126,7 @@ private static function add_initial_markdown( $fd, $command ) { 'shortdesc' => $command->get_shortdesc(), ); - $synopsis = $command->get_full_synopsis(); + $synopsis = Dispatcher\get_full_synopsis( $command, true ); $synopsis = str_replace( '_', '\_', $synopsis ); $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); diff --git a/php/dispatcher.php b/php/dispatcher.php index 25d7ee3274..689acba45d 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -12,6 +12,34 @@ function get_path( Command $command ) { return $path; } +function get_full_synopsis( $command, $validate = false ) { + $subcommands = $command->get_subcommands(); + + if ( empty( $subcommands ) ) { + $synopsis = $command->get_synopsis(); + + if ( $validate ) { + $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); + + foreach ( $tokens as $token ) { + if ( 'unknown' == $token['type'] ) { + \WP_CLI::warning( sprintf( + "Invalid token '%s' in synopsis for '%s'", + $token['token'], $full_name + ) ); + } + } + } + + $full_name = implode( ' ', get_path( $command ) ); + + return "$full_name $synopsis"; + } else { + return implode( "\n\n", array_map( __FUNCTION__, + $subcommands ) ); + } +} + interface Command { @@ -20,7 +48,6 @@ function get_parent(); function get_synopsis(); function get_shortdesc(); - function get_full_synopsis(); function get_subcommands(); From 7bc411cbea62a85caa7bcfb61945a5dc79379890 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 22:52:56 +0300 Subject: [PATCH 1802/4858] Simplify dispatch class hierarchy: * merge AbstractCommandContainer into CompositeCommand * make RootCommand inherit from CompositeCommand * get rid of redundant Command and CommandContainer interfaces --- .../Dispatcher/AbstractCommandContainer.php | 27 ------------------- php/WP_CLI/Dispatcher/CompositeCommand.php | 24 ++++++++++++++++- php/WP_CLI/Dispatcher/RootCommand.php | 13 +++++---- php/WP_CLI/Dispatcher/Subcommand.php | 7 +++-- php/class-wp-cli.php | 6 ++--- php/commands/help.php | 4 +-- php/dispatcher.php | 26 +----------------- php/utils.php | 2 +- 8 files changed, 41 insertions(+), 68 deletions(-) delete mode 100644 php/WP_CLI/Dispatcher/AbstractCommandContainer.php diff --git a/php/WP_CLI/Dispatcher/AbstractCommandContainer.php b/php/WP_CLI/Dispatcher/AbstractCommandContainer.php deleted file mode 100644 index 7724a9b480..0000000000 --- a/php/WP_CLI/Dispatcher/AbstractCommandContainer.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -namespace WP_CLI\Dispatcher; - -abstract class AbstractCommandContainer implements Command, CommandContainer { - - protected $subcommands = array(); - - function get_synopsis() { - return ''; - } - - function invoke( $args, $assoc_args ) { - $this->show_usage(); - } - - function add_subcommand( $name, Command $command ) { - $this->subcommands[ $name ] = $command; - } - - function get_subcommands() { - ksort( $this->subcommands ); - - return $this->subcommands; - } -} - diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 4febf465ea..159fcfb738 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -2,16 +2,30 @@ namespace WP_CLI\Dispatcher; -class CompositeCommand extends AbstractCommandContainer { +/** + * A non-leaf node in the command tree. + */ +class CompositeCommand { protected $name; protected $shortdesc; + protected $subcommands = array(); public function __construct( $name, $shortdesc ) { $this->name = $name; $this->shortdesc = $shortdesc; } + function add_subcommand( $name, $command ) { + $this->subcommands[ $name ] = $command; + } + + function get_subcommands() { + ksort( $this->subcommands ); + + return $this->subcommands; + } + function get_name() { return $this->name; } @@ -20,6 +34,14 @@ function get_parent() { return \WP_CLI::$root; } + function get_synopsis() { + return ''; + } + + function invoke( $args, $assoc_args ) { + $this->show_usage(); + } + function show_usage() { $methods = $this->get_subcommands(); diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index f502134873..98be09d495 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -4,20 +4,19 @@ use \WP_CLI\Utils; -class RootCommand extends AbstractCommandContainer { +/** + * The root node in the command tree. + */ +class RootCommand extends CompositeCommand { - function get_name() { - return 'wp'; + function __construct() { + parent::__construct( 'wp', '' ); } function get_parent() { return false; } - function get_shortdesc() { - return ''; - } - function show_usage() { \WP_CLI::line( 'Available commands:' ); diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 5af76a1ef6..1742f1c381 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -2,11 +2,14 @@ namespace WP_CLI\Dispatcher; -class Subcommand implements Command { +/** + * A leaf node in the command tree. + */ +class Subcommand { private $parent, $name, $class, $method, $docparser; - function __construct( CommandContainer $parent, $class, \ReflectionMethod $method, $name = false ) { + function __construct( CompositeCommand $parent, $class, \ReflectionMethod $method, $name = false ) { $this->class = $class; $docparser = new \WP_CLI\DocParser( $method ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 71d87d80ba..3b1e7c2309 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -83,7 +83,7 @@ private static function create_composite_command( $name, $reflection ) { return $container; } - private static function get_full_name( Dispatcher\Command $command ) { + private static function get_full_name( $command ) { $path = Dispatcher\get_path( $command ); array_shift( $path ); @@ -246,7 +246,7 @@ static function get_config( $key = null ) { private static function find_command_to_run( $args ) { $command = \WP_CLI::$root; - while ( !empty( $args ) && $command instanceof Dispatcher\CommandContainer ) { + while ( !empty( $args ) && $command instanceof Dispatcher\CompositeCommand ) { $subcommand = $command->pre_invoke( $args ); if ( !$subcommand ) break; @@ -266,7 +266,7 @@ private static function find_command_to_run( $args ) { public static function run_command( $args, $assoc_args = array() ) { list( $command, $final_args ) = self::find_command_to_run( $args ); - if ( $command instanceof Dispatcher\CommandContainer ) { + if ( $command instanceof Dispatcher\CompositeCommand ) { $command->show_usage(); } else { $command->invoke( $final_args, $assoc_args ); diff --git a/php/commands/help.php b/php/commands/help.php index b56281a634..934de6929d 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -92,7 +92,7 @@ private static function _generate( $src_dir, $dest_dir, $command ) { self::call_ronn( self::get_markdown( $src_path, $command ), $dest_path ); - if ( $command instanceof Dispatcher\CommandContainer ) { + if ( $command instanceof Dispatcher\CompositeCommand ) { foreach ( $command->get_subcommands() as $subcommand ) { self::_generate( $src_dir, $dest_dir, $subcommand ); } @@ -138,7 +138,7 @@ private static function add_initial_markdown( $fd, $command ) { \WP_CLI::warning( "No shortdesc for $name_s" ); } - if ( $command instanceof Dispatcher\CommandContainer ) { + if ( $command instanceof Dispatcher\CompositeCommand ) { foreach ( $command->get_subcommands() as $subcommand ) { $binding['has-subcommands']['subcommands'][] = array( 'name' => $subcommand->get_name(), diff --git a/php/dispatcher.php b/php/dispatcher.php index 689acba45d..45903834f3 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -2,7 +2,7 @@ namespace WP_CLI\Dispatcher; -function get_path( Command $command ) { +function get_path( $command ) { $path = array(); do { @@ -40,27 +40,3 @@ function get_full_synopsis( $command, $validate = false ) { } } - -interface Command { - - function get_name(); - function get_parent(); - - function get_synopsis(); - function get_shortdesc(); - - function get_subcommands(); - - function invoke( $args, $assoc_args ); - function show_usage(); -} - - -interface CommandContainer { - - function add_subcommand( $name, Command $command ); - - function find_subcommand( &$args ); - function pre_invoke( &$args ); -} - diff --git a/php/utils.php b/php/utils.php index 7d3fe7afca..49a87f6094 100644 --- a/php/utils.php +++ b/php/utils.php @@ -385,7 +385,7 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { function find_subcommand( $args ) { $command = \WP_CLI::$root; - while ( !empty( $args ) && $command && $command instanceof Dispatcher\CommandContainer ) { + while ( !empty( $args ) && $command && $command instanceof Dispatcher\CompositeCommand ) { $command = $command->find_subcommand( $args ); } From 8526f9e4a0dbcde27f3f99e6b7cc1baa25ac7f54 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 23:38:12 +0300 Subject: [PATCH 1803/4858] make Subcommand inherit from CompositeCommand --- php/WP_CLI/Dispatcher/CompositeCommand.php | 29 ++++++++++------- php/WP_CLI/Dispatcher/RootCommand.php | 11 ++++--- php/WP_CLI/Dispatcher/Subcommand.php | 37 ++++++---------------- php/class-wp-cli.php | 11 +++---- php/commands/help.php | 4 +-- php/utils.php | 2 +- 6 files changed, 40 insertions(+), 54 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 159fcfb738..446bfbac35 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -7,19 +7,30 @@ */ class CompositeCommand { - protected $name; - protected $shortdesc; - protected $subcommands = array(); + protected $name, $shortdesc, $synopsis; + + protected $parent, $subcommands = array(); + + public function __construct( $parent, $name, $shortdesc, $synopsis = '' ) { + $this->parent = $parent; - public function __construct( $name, $shortdesc ) { $this->name = $name; $this->shortdesc = $shortdesc; + $this->synopsis = $synopsis; + } + + function get_parent() { + return $this->parent; } function add_subcommand( $name, $command ) { $this->subcommands[ $name ] = $command; } + function has_subcommands() { + return !empty( $this->subcommands ); + } + function get_subcommands() { ksort( $this->subcommands ); @@ -30,12 +41,12 @@ function get_name() { return $this->name; } - function get_parent() { - return \WP_CLI::$root; + function get_shortdesc() { + return $this->shortdesc; } function get_synopsis() { - return ''; + return $this->synopsis; } function invoke( $args, $assoc_args ) { @@ -91,9 +102,5 @@ private static function get_aliases( $subcommands ) { return $aliases; } - - public function get_shortdesc() { - return $this->shortdesc; - } } diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 98be09d495..800ff89aa6 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -10,11 +10,7 @@ class RootCommand extends CompositeCommand { function __construct() { - parent::__construct( 'wp', '' ); - } - - function get_parent() { - return false; + parent::__construct( false, 'wp', '' ); } function show_usage() { @@ -100,5 +96,10 @@ function get_subcommands() { return parent::get_subcommands(); } + + function has_subcommands() { + // Commands are lazy-loaded, so we need to assume there will be some + return true; + } } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 1742f1c381..69249d97a3 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -5,55 +5,36 @@ /** * A leaf node in the command tree. */ -class Subcommand { +class Subcommand extends CompositeCommand { - private $parent, $name, $class, $method, $docparser; + private $class, $method; function __construct( CompositeCommand $parent, $class, \ReflectionMethod $method, $name = false ) { $this->class = $class; + $this->method = $method; + $docparser = new \WP_CLI\DocParser( $method ); + $this->alias = $docparser->get_tag( 'alias' ); + if ( !$name ) $name = $docparser->get_tag( 'subcommand' ); if ( !$name ) $name = $method->name; - $this->parent = $parent; - $this->name = $name; - - $this->method = $method; - $this->docparser = $docparser; + parent::__construct( $parent, $name, + $docparser->get_shortdesc(), $docparser->get_synopsis() ); } function get_alias() { - return $this->docparser->get_tag( 'alias' ); - } - - function get_name() { - return $this->name; - } - - function get_parent() { - return $this->parent; - } - - function get_subcommands() { - return array(); + return $this->alias; } function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $prefix . get_full_synopsis( $this ) ); } - function get_shortdesc() { - return $this->docparser->get_shortdesc(); - } - - function get_synopsis() { - return $this->docparser->get_synopsis(); - } - private function validate_args( $args, &$assoc_args ) { $synopsis = $this->get_synopsis(); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 3b1e7c2309..cbf7f1f22f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -63,7 +63,8 @@ static function add_command( $name, $class ) { private static function create_composite_command( $name, $reflection ) { $docparser = new \WP_CLI\DocParser( $reflection ); - $container = new Dispatcher\CompositeCommand( $name, $docparser->get_shortdesc() ); + $container = new Dispatcher\CompositeCommand( self::$root, $name, + $docparser->get_shortdesc() ); foreach ( $reflection->getMethods() as $method ) { if ( !self::_is_good_method( $method ) ) @@ -246,7 +247,7 @@ static function get_config( $key = null ) { private static function find_command_to_run( $args ) { $command = \WP_CLI::$root; - while ( !empty( $args ) && $command instanceof Dispatcher\CompositeCommand ) { + while ( !empty( $args ) && $command->has_subcommands() ) { $subcommand = $command->pre_invoke( $args ); if ( !$subcommand ) break; @@ -266,11 +267,7 @@ private static function find_command_to_run( $args ) { public static function run_command( $args, $assoc_args = array() ) { list( $command, $final_args ) = self::find_command_to_run( $args ); - if ( $command instanceof Dispatcher\CompositeCommand ) { - $command->show_usage(); - } else { - $command->invoke( $final_args, $assoc_args ); - } + $command->invoke( $final_args, $assoc_args ); } // back-compat diff --git a/php/commands/help.php b/php/commands/help.php index 934de6929d..39e5da307f 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -92,7 +92,7 @@ private static function _generate( $src_dir, $dest_dir, $command ) { self::call_ronn( self::get_markdown( $src_path, $command ), $dest_path ); - if ( $command instanceof Dispatcher\CompositeCommand ) { + if ( $command->has_subcommands() ) { foreach ( $command->get_subcommands() as $subcommand ) { self::_generate( $src_dir, $dest_dir, $subcommand ); } @@ -138,7 +138,7 @@ private static function add_initial_markdown( $fd, $command ) { \WP_CLI::warning( "No shortdesc for $name_s" ); } - if ( $command instanceof Dispatcher\CompositeCommand ) { + if ( $command->has_subcommands() ) { foreach ( $command->get_subcommands() as $subcommand ) { $binding['has-subcommands']['subcommands'][] = array( 'name' => $subcommand->get_name(), diff --git a/php/utils.php b/php/utils.php index 49a87f6094..93ffad35f7 100644 --- a/php/utils.php +++ b/php/utils.php @@ -385,7 +385,7 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { function find_subcommand( $args ) { $command = \WP_CLI::$root; - while ( !empty( $args ) && $command && $command instanceof Dispatcher\CompositeCommand ) { + while ( !empty( $args ) && $command && $command->has_subcommands() ) { $command = $command->find_subcommand( $args ); } From 810689dff7e870d79decf744d0830caef0ff825d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 00:30:10 +0300 Subject: [PATCH 1804/4858] get rid of pre_invoke() method --- php/WP_CLI/Dispatcher/CompositeCommand.php | 4 ---- php/WP_CLI/Dispatcher/RootCommand.php | 11 ----------- php/class-wp-cli.php | 13 ++++++++++--- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 446bfbac35..42adc96356 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -68,10 +68,6 @@ function show_usage() { \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); } - function pre_invoke( &$args ) { - return $this->find_subcommand( $args ); - } - function find_subcommand( &$args ) { $name = array_shift( $args ); diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 800ff89aa6..0f8654ef0b 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -68,17 +68,6 @@ private static function generate_synopsis() { } } - function pre_invoke( &$args ) { - $cmd_name = $args[0]; - - $command = $this->find_subcommand( $args ); - - if ( !$command ) - \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $cmd_name ) ); - - return $command; - } - function find_subcommand( &$args ) { $command = array_shift( $args ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index cbf7f1f22f..06708d0ea1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -247,10 +247,17 @@ static function get_config( $key = null ) { private static function find_command_to_run( $args ) { $command = \WP_CLI::$root; + $cmd_path = array(); + while ( !empty( $args ) && $command->has_subcommands() ) { - $subcommand = $command->pre_invoke( $args ); - if ( !$subcommand ) - break; + $cmd_path[] = $args[0]; + + $subcommand = $command->find_subcommand( $args ); + + if ( !$subcommand ) { + \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", + implode( ' ', $cmd_path ) ) ); + } $command = $subcommand; } From 89058ba5296b9e2c0af619dcca431691fd996cd5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 00:35:48 +0300 Subject: [PATCH 1805/4858] move find_command() utility to Help_Command class it's not used anywhere else, nor should it be --- php/commands/help.php | 14 ++++++++++++-- php/utils.php | 10 ---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 39e5da307f..d2b8691e3f 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -17,12 +17,22 @@ function __invoke( $args, $assoc_args ) { $this->show( $args ); } + private static function find_subcommand( $args ) { + $command = \WP_CLI::$root; + + while ( !empty( $args ) && $command && $command->has_subcommands() ) { + $command = $command->find_subcommand( $args ); + } + + return $command; + } + private function show( $args ) { if ( self::maybe_show_manpage( $args ) ) { exit; } - $command = WP_CLI\Utils\find_subcommand( $args ); + $command = self::find_subcommand( $args ); if ( $command ) { $command->show_usage(); @@ -42,7 +52,7 @@ private function generate( $args ) { $arg_copy = $args; - $command = WP_CLI\Utils\find_subcommand( $args ); + $command = self::find_subcommand( $args ); if ( $command ) { foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { diff --git a/php/utils.php b/php/utils.php index 93ffad35f7..bd5cada514 100644 --- a/php/utils.php +++ b/php/utils.php @@ -382,16 +382,6 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { return $output; } -function find_subcommand( $args ) { - $command = \WP_CLI::$root; - - while ( !empty( $args ) && $command && $command->has_subcommands() ) { - $command = $command->find_subcommand( $args ); - } - - return $command; -} - function run_mysql_query( $query, $args ) { // TODO: use PDO? From 65e4d75d3423f3d89b60a34038a51a50798423f1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 02:30:38 +0300 Subject: [PATCH 1806/4858] extract create_subcommand() method --- php/WP_CLI/Dispatcher/Subcommand.php | 15 ++++----------- php/class-wp-cli.php | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 69249d97a3..00152d1d81 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -7,24 +7,17 @@ */ class Subcommand extends CompositeCommand { + private $alias; + private $class, $method; - function __construct( CompositeCommand $parent, $class, \ReflectionMethod $method, $name = false ) { + function __construct( $parent, $name, $class, \ReflectionMethod $method, $docparser ) { $this->class = $class; $this->method = $method; - $docparser = new \WP_CLI\DocParser( $method ); - $this->alias = $docparser->get_tag( 'alias' ); - if ( !$name ) - $name = $docparser->get_tag( 'subcommand' ); - - if ( !$name ) - $name = $method->name; - - parent::__construct( $parent, $name, - $docparser->get_shortdesc(), $docparser->get_synopsis() ); + parent::__construct( $parent, $name, $docparser->get_shortdesc(), $docparser->get_synopsis() ); } function get_alias() { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 06708d0ea1..1a036d49cc 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -51,8 +51,8 @@ static function add_command( $name, $class ) { $reflection = new \ReflectionClass( $class ); if ( $reflection->hasMethod( '__invoke' ) ) { - $command = new Dispatcher\Subcommand( self::$root, $reflection->name, - $reflection->getMethod( '__invoke' ), $name ); + $command = self::create_subcommand( self::$root, $name, $reflection->name, + $reflection->getMethod( '__invoke' ) ); } else { $command = self::create_composite_command( $name, $reflection ); } @@ -60,6 +60,18 @@ static function add_command( $name, $class ) { self::$root->add_subcommand( $name, $command ); } + private static function create_subcommand( $parent, $name, $class_name, $method ) { + $docparser = new \WP_CLI\DocParser( $method ); + + if ( !$name ) + $name = $docparser->get_tag( 'subcommand' ); + + if ( !$name ) + $name = $method->name; + + return new Dispatcher\Subcommand( $parent, $name, $class_name, $method, $docparser ); + } + private static function create_composite_command( $name, $reflection ) { $docparser = new \WP_CLI\DocParser( $reflection ); @@ -70,7 +82,7 @@ private static function create_composite_command( $name, $reflection ) { if ( !self::_is_good_method( $method ) ) continue; - $subcommand = new Dispatcher\Subcommand( $container, $reflection->name, $method ); + $subcommand = self::create_subcommand( $container, false, $reflection->name, $method ); $subcommand_name = $subcommand->get_name(); $full_name = self::get_full_name( $subcommand ); From 00b154962caf3dc2336376fe4cc3c9a2f5379ad4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 02:50:01 +0300 Subject: [PATCH 1807/4858] make the Subcommand constructor accept a callback the idea is to have fewer parameters, with a clearer purpose --- php/WP_CLI/Dispatcher/Subcommand.php | 11 ++++------- php/class-wp-cli.php | 8 +++++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 00152d1d81..c86b096e6b 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -9,11 +9,10 @@ class Subcommand extends CompositeCommand { private $alias; - private $class, $method; + private $when_invoked; - function __construct( $parent, $name, $class, \ReflectionMethod $method, $docparser ) { - $this->class = $class; - $this->method = $method; + function __construct( $parent, $name, $when_invoked, $docparser ) { + $this->when_invoked = $when_invoked; $this->alias = $docparser->get_tag( 'alias' ); @@ -61,9 +60,7 @@ private function validate_args( $args, &$assoc_args ) { function invoke( $args, $assoc_args ) { $this->validate_args( $args, $assoc_args ); - $instance = new $this->class; - - call_user_func( array( $instance, $this->method->name ), $args, $assoc_args ); + call_user_func( $this->when_invoked, $args, $assoc_args ); } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1a036d49cc..cb9a0a9e04 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -69,7 +69,13 @@ private static function create_subcommand( $parent, $name, $class_name, $method if ( !$name ) $name = $method->name; - return new Dispatcher\Subcommand( $parent, $name, $class_name, $method, $docparser ); + $method_name = $method->name; + + $when_invoked = function ( $args, $assoc_args ) use ( $class_name, $method_name ) { + call_user_func( array( new $class_name, $method_name ), $args, $assoc_args ); + }; + + return new Dispatcher\Subcommand( $parent, $name, $when_invoked, $docparser ); } private static function create_composite_command( $name, $reflection ) { From 7b4546fa021f0a9544d83f4b85635cb93329f4e2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 03:15:47 +0300 Subject: [PATCH 1808/4858] pass docparser directly to CompositeCommand constructor --- php/WP_CLI/Dispatcher/CompositeCommand.php | 7 ++++--- php/WP_CLI/Dispatcher/RootCommand.php | 7 ++++++- php/WP_CLI/Dispatcher/Subcommand.php | 4 ++-- php/class-wp-cli.php | 5 ++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 42adc96356..4b4ad4e0ba 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -11,12 +11,13 @@ class CompositeCommand { protected $parent, $subcommands = array(); - public function __construct( $parent, $name, $shortdesc, $synopsis = '' ) { + public function __construct( $parent, $name, $docparser ) { $this->parent = $parent; $this->name = $name; - $this->shortdesc = $shortdesc; - $this->synopsis = $synopsis; + + $this->shortdesc = $docparser->get_shortdesc(); + $this->synopsis = $docparser->get_synopsis(); } function get_parent() { diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 0f8654ef0b..25ddc558a1 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -10,7 +10,12 @@ class RootCommand extends CompositeCommand { function __construct() { - parent::__construct( false, 'wp', '' ); + $this->parent = false; + + $this->name = 'wp'; + + $this->shortdesc = ''; + $this->synopsis = ''; } function show_usage() { diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index c86b096e6b..7a71e282df 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -11,12 +11,12 @@ class Subcommand extends CompositeCommand { private $when_invoked; - function __construct( $parent, $name, $when_invoked, $docparser ) { + function __construct( $parent, $name, $docparser, $when_invoked ) { $this->when_invoked = $when_invoked; $this->alias = $docparser->get_tag( 'alias' ); - parent::__construct( $parent, $name, $docparser->get_shortdesc(), $docparser->get_synopsis() ); + parent::__construct( $parent, $name, $docparser ); } function get_alias() { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index cb9a0a9e04..564965df20 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -75,14 +75,13 @@ private static function create_subcommand( $parent, $name, $class_name, $method call_user_func( array( new $class_name, $method_name ), $args, $assoc_args ); }; - return new Dispatcher\Subcommand( $parent, $name, $when_invoked, $docparser ); + return new Dispatcher\Subcommand( $parent, $name, $docparser, $when_invoked ); } private static function create_composite_command( $name, $reflection ) { $docparser = new \WP_CLI\DocParser( $reflection ); - $container = new Dispatcher\CompositeCommand( self::$root, $name, - $docparser->get_shortdesc() ); + $container = new Dispatcher\CompositeCommand( self::$root, $name, $docparser ); foreach ( $reflection->getMethods() as $method ) { if ( !self::_is_good_method( $method ) ) From eb48065e296adaabd2d57e2f38a7019d7d56e015 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 15:28:15 +0300 Subject: [PATCH 1809/4858] post get: update man page fixes #509 --- man-src/post-get.txt | 10 +++++----- man/post-get.1 | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/man-src/post-get.txt b/man-src/post-get.txt index fab4fdeb35..9b79b9ce97 100644 --- a/man-src/post-get.txt +++ b/man-src/post-get.txt @@ -4,12 +4,12 @@ The format to use when printing the post, acceptable values: - content: outputs only the post's content (default) + **content**: Outputs only the post's content. - table: output all fields of the post as a table, note that the - post_content field is omitted so that the table is readable + **table**: Outputs all fields of the post as a table. Note that the + post_content field is omitted so that the table is readable. - json: output all fields in JavaScript Object Notation format + **json**: Outputs all fields in JSON format. * `<id>`: @@ -17,6 +17,6 @@ ## EXAMPLES - wp post get 12 + wp post get 12 --format=content wp post get 12 > file.txt diff --git a/man/post-get.1 b/man/post-get.1 index 67511f0136..94df8e63b5 100644 --- a/man/post-get.1 +++ b/man/post-get.1 @@ -18,13 +18,13 @@ wp post get [\-\-format=\fIformat\fR] \fIid\fR The format to use when printing the post, acceptable values: . .IP -content: outputs only the post\'s content (default) +\fBcontent\fR: Outputs only the post\'s content\. . .IP -table: output all fields of the post as a table, note that the post_content field is omitted so that the table is readable +\fBtable\fR: Outputs all fields of the post as a table\. Note that the post_content field is omitted so that the table is readable\. . .IP -json: output all fields in JavaScript Object Notation format +\fBjson\fR: Outputs all fields in JSON format\. . .TP \fB<id>\fR: @@ -36,7 +36,7 @@ The ID of the post to get\. . .nf -wp post get 12 +wp post get 12 \-\-format=content wp post get 12 > file\.txt . From d44992ee47537085701cba12a2f9f1ff22bc1cb2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 19:08:59 +0300 Subject: [PATCH 1810/4858] mention `wp --info` in README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2c49bc83db..3d4a0eb0ac 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ I'm running into troubles, what can I do? ----------------------------------------- To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). +If you're reporting a bug, please also post the output from `wp --info`. + Who's behind this thing? ------------------------ We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). From 32aa314db1037128b21e14368e5ebd53ef0735c6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 19:59:41 +0300 Subject: [PATCH 1811/4858] don't alter API response if the returned version happens to be the one we want see #511 --- php/WP_CLI/CommandWithUpgrade.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index cf771d6f58..28bc23731f 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -126,6 +126,9 @@ function install( $args, $assoc_args ) { * @param string $version The desired version of the package */ protected static function alter_api_response( $response, $version ) { + if ( $response->version == $version ) + return; + list( $link ) = explode( $response->slug, $response->download_link ); if ( false !== strpos( $response->download_link, 'theme' ) ) From 6ca5bae8d2879468021a5feea20f2bcc0e9fe2c8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Jun 2013 20:10:55 +0300 Subject: [PATCH 1812/4858] bump version to 0.10.1-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index b4c7d52217..7fa1276aa4 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.0' ); +define( 'WP_CLI_VERSION', '0.10.1-alpha' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 89cc55159d94431c2c268d2b388c242fecbd1551 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Jun 2013 15:49:38 +0300 Subject: [PATCH 1813/4858] remove executable bit from mustache templates --- templates/post_type_extended.mustache | 0 templates/taxonomy_extended.mustache | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 templates/post_type_extended.mustache mode change 100755 => 100644 templates/taxonomy_extended.mustache diff --git a/templates/post_type_extended.mustache b/templates/post_type_extended.mustache old mode 100755 new mode 100644 diff --git a/templates/taxonomy_extended.mustache b/templates/taxonomy_extended.mustache old mode 100755 new mode 100644 From 42366d044de5b5cb9c164576d4473692ff46cd4e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Jun 2013 15:59:31 +0300 Subject: [PATCH 1814/4858] scaffold plugin-tests: create install-wp-tests.sh script This makes it easier to run unit tests locally. --- php/commands/scaffold.php | 8 +++++--- templates/.travis.yml | 20 +------------------- templates/install-wp-tests.sh | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 22 deletions(-) create mode 100644 templates/install-wp-tests.sh diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 6b3b1bf050..ef0eb2b28f 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -240,17 +240,19 @@ function plugin_tests( $args, $assoc_args ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - $tests_dir = "$plugin_dir/tests"; + $bin_dir = "$plugin_dir/bin"; $wp_filesystem->mkdir( $tests_dir ); + $wp_filesystem->mkdir( $bin_dir ); $this->create_file( "$tests_dir/bootstrap.php", Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ); $to_copy = array( - 'phpunit.xml' => $plugin_dir, + 'install-wp-tests.sh' => $bin_dir, '.travis.yml' => $plugin_dir, + 'phpunit.xml' => $plugin_dir, 'test-sample.php' => $tests_dir, ); @@ -258,7 +260,7 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->copy( WP_CLI_ROOT . "../templates/$file", "$dir/$file", true ); } - WP_CLI::success( "Created test files in $plugin_dir" ); + WP_CLI::success( "Created test files." ); } private function create_file( $filename, $contents ) { diff --git a/templates/.travis.yml b/templates/.travis.yml index a2020ad18f..a91b121be7 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -10,26 +10,8 @@ env: - WP_VERSION=3.5.1 WP_MULTISITE=0 - WP_VERSION=3.5.1 WP_MULTISITE=1 -before_install: - - git submodule update --init --recursive - before_script: - # set up WP install - - WP_CORE_DIR=/tmp/wordpress/ - - mkdir -p $WP_CORE_DIR - - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION - - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - # set up testing suite - export WP_TESTS_DIR=/tmp/wordpress-tests/ - - svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR - - cd $WP_TESTS_DIR - - cp wp-tests-config-sample.php wp-tests-config.php - - sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php - - sed -i "s/yourdbnamehere/wordpress_test/" wp-tests-config.php - - sed -i "s/yourusernamehere/root/" wp-tests-config.php - - sed -i "s/yourpasswordhere//" wp-tests-config.php - - cd - - # set up database - - mysql -e 'CREATE DATABASE wordpress_test;' -uroot + - bash bin/install-wp-tests.sh wordpress_test root '' $WP_VERSION script: phpunit diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh new file mode 100644 index 0000000000..a93a900d62 --- /dev/null +++ b/templates/install-wp-tests.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +if [ $# -lt 3 ]; then + echo "usage: $0 <db-name> <db-user> <db-pass> [wp-version]" + exit 1 +fi + +DB_NAME=$1 +DB_USER=$2 +DB_PASS=$3 +WP_VERSION=${4-master} + +set -ex + +# set up a WP install +WP_CORE_DIR=/tmp/wordpress/ +mkdir -p $WP_CORE_DIR +wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION +tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + +# set up testing suite +svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR + +cd $WP_TESTS_DIR +cp wp-tests-config-sample.php wp-tests-config.php +sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php +sed -i "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php +sed -i "s/yourusernamehere/$DB_USER/" wp-tests-config.php +sed -i "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php + +# create database +mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS" From 03f9539f83d50478b4eca0c245b5561821df9dcd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 04:12:11 +0300 Subject: [PATCH 1815/4858] move all config logic to a new class --- php/WP_CLI/Configurator.php | 100 ++++++++++++++++++++++++++ php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/WP_CLI/Runner.php | 70 ++---------------- php/class-wp-cli.php | 3 +- php/commands/_sys.php | 2 +- php/utils.php | 25 +++---- 6 files changed, 116 insertions(+), 86 deletions(-) create mode 100644 php/WP_CLI/Configurator.php diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php new file mode 100644 index 0000000000..fc3c5caefd --- /dev/null +++ b/php/WP_CLI/Configurator.php @@ -0,0 +1,100 @@ +<?php + +namespace WP_CLI; + +class Configurator { + + private $spec; + + function __construct( $path ) { + $this->spec = include $path; + + $defaults = array( + 'runtime' => false, + 'file' => false, + 'synopsis' => '', + 'default' => null, + ); + + foreach ( $this->spec as &$option ) { + $option = array_merge( $defaults, $option ); + } + } + + /** + * Get configuration specification, i.e. list of accepted keys. + * + * @return array + */ + function get_spec() { + return $this->spec; + } + + /** + * Set default value for a particular configuration key. + */ + function set_default( $key, $value ) { + $this->spec[ $key ]['default'] = $value; + } + + /** + * Load values from a YML file and sanitize them according to the spec. + * + * @return array + */ + function load_config( $path ) { + if ( $path ) + $config = spyc_load_file( $path ); + else + $config = array(); + + $sanitized_config = array(); + + foreach ( $this->spec as $key => $details ) { + if ( $details['file'] && isset( $config[ $key ] ) ) + $sanitized_config[ $key ] = $config[ $key ]; + else + $sanitized_config[ $key ] = $details['default']; + } + + // When invoking from a subdirectory in the project, + // make sure a config-relative 'path' is made absolute + if ( ! empty( $sanitized_config['path'] ) && ! \WP_CLI\Utils\is_absolute_path( $sanitized_config['path'] ) ) { + $sanitized_config['path'] = dirname( $path ) . DIRECTORY_SEPARATOR . $sanitized_config['path']; + } + + return $sanitized_config; + } + + /** + * Extract values from an associative array, according to the spec. + */ + function split_special( &$assoc_args, &$config ) { + foreach ( $this->spec as $key => $details ) { + if ( true === $details['runtime'] ) { + self::handle_boolean_param( $assoc_args, $config, $key ); + } elseif ( false !== $details['runtime'] ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } + } + } + } + + private static function handle_boolean_param( &$assoc_args, &$config, $param ) { + $subkeys = array( + "$param" => true, + "no-$param" => false + ); + + foreach ( $subkeys as $key => $value ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $param ] = $value; + } + + unset( $assoc_args[ $key ] ); + } + } +} + diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 25ddc558a1..ffebadb15f 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -47,7 +47,7 @@ private static function generate_synopsis() { $lines = array(); - foreach ( \WP_CLI\Utils\get_config_spec() as $key => $details ) { + foreach ( \WP_CLI::$configurator->get_spec() as $key => $details ) { if ( false === $details['runtime'] ) continue; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 5332f75167..fd33cd0c82 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -44,63 +44,11 @@ private static function get_config_path( &$assoc_args ) { return false; } - private static function load_config( $path, $spec ) { - if ( $path ) - $config = spyc_load_file( $path ); - else - $config = array(); - - $sanitized_config = array(); - - foreach ( $spec as $key => $details ) { - if ( $details['file'] && isset( $config[ $key ] ) ) - $sanitized_config[ $key ] = $config[ $key ]; - else - $sanitized_config[ $key ] = $details['default']; - } - - // When invoking from a subdirectory in the project, - // make sure a config-relative 'path' is made absolute - if ( ! empty( $sanitized_config['path'] ) && ! self::is_absolute_path( $sanitized_config['path'] ) ) { - $sanitized_config['path'] = dirname( $path ) . DIRECTORY_SEPARATOR . $sanitized_config['path']; - } - - return $sanitized_config; - } - - private static function handle_boolean_param( &$assoc_args, &$config, $param ) { - $subkeys = array( - "$param" => true, - "no-$param" => false - ); - - foreach ( $subkeys as $key => $value ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $param ] = $value; - } - - unset( $assoc_args[ $key ] ); - } - } - - private static function split_special( &$assoc_args, &$config, $spec ) { - foreach ( $spec as $key => $details ) { - if ( true === $details['runtime'] ) { - self::handle_boolean_param( $assoc_args, $config, $key ); - } elseif ( false !== $details['runtime'] ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $key ] = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); - } - } - } - } - private static function set_wp_root( $config ) { $path = getcwd(); if ( !empty( $config['path'] ) ) { - if ( self::is_absolute_path( $config['path'] ) ) + if ( Utils\is_absolute_path( $config['path'] ) ) $path = $config['path']; else $path .= '/' . $config['path']; @@ -126,14 +74,6 @@ private static function set_user( $assoc_args ) { } } - private static function is_absolute_path( $path ) { - // Windows - if ( ':' === $path[1] ) - return true; - - return $path[0] === '/'; - } - private static function set_url( $assoc_args ) { if ( isset( $assoc_args['url'] ) ) { $url = $assoc_args['url']; @@ -291,19 +231,17 @@ public function before_wp_load() { list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ) ); - $config_spec = Utils\get_config_spec(); - // Set the path default to the ABSPATH $wp_abspath = dirname( Utils\find_file_upward( 'wp-load.php' ) ); if ( ! empty( $wp_abspath ) ) { - $config_spec['path']['default'] = $wp_abspath; + \WP_CLI::$configurator->set_default( 'path', $wp_abspath ); } $this->config_path = self::get_config_path( $this->assoc_args ); - $this->config = self::load_config( $this->config_path, $config_spec ); + $this->config = \WP_CLI::$configurator->load_config( $this->config_path ); - self::split_special( $this->assoc_args, $this->config, $config_spec ); + \WP_CLI::$configurator->split_special( $this->assoc_args, $this->config ); $this->init_logger(); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 564965df20..bdee64d149 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -8,8 +8,8 @@ */ class WP_CLI { + public static $configurator; public static $root; - public static $runner; private static $logger; @@ -25,6 +25,7 @@ static function init() { WP_CLI_ROOT . "../man-src" ); + self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/config-spec.php' ); self::$root = new Dispatcher\RootCommand; self::$runner = new WP_CLI\Runner; } diff --git a/php/commands/_sys.php b/php/commands/_sys.php index 963d48af6b..82a7107aa8 100644 --- a/php/commands/_sys.php +++ b/php/commands/_sys.php @@ -41,7 +41,7 @@ function info() { * @subcommand param-dump */ function param_dump() { - echo json_encode( Utils\get_config_spec() ); + echo json_encode( \WP_CLI::$configurator->get_spec() ); } /** diff --git a/php/utils.php b/php/utils.php index bd5cada514..e0cef0c1f4 100644 --- a/php/utils.php +++ b/php/utils.php @@ -51,23 +51,6 @@ function load_all_commands() { } } -function get_config_spec() { - $spec = include __DIR__ . '/config-spec.php'; - - $defaults = array( - 'runtime' => false, - 'file' => false, - 'synopsis' => '', - 'default' => null, - ); - - foreach ( $spec as &$option ) { - $option = array_merge( $defaults, $option ); - } - - return $spec; -} - /** * Search for file by walking up the directory tree until the first file is found or until $stop_check($dir) returns true * @param string|array The files (or file) to search for @@ -102,6 +85,14 @@ function find_file_upward( $files, $dir = null, $stop_check = null ) { return null; } +function is_absolute_path( $path ) { + // Windows + if ( ':' === $path[1] ) + return true; + + return $path[0] === '/'; +} + /** * Splits $argv into positional and associative arguments. * From 02fdfacec78e92c6613f59ba05f9f2a6b086b45d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 05:26:32 +0300 Subject: [PATCH 1816/4858] rename is_absolute_path() to is_path_absolute() it emphasises the assumption that the parameter is a path and not some random string --- php/WP_CLI/Configurator.php | 2 +- php/WP_CLI/Runner.php | 2 +- php/utils.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index fc3c5caefd..a677d1f3ea 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -59,7 +59,7 @@ function load_config( $path ) { // When invoking from a subdirectory in the project, // make sure a config-relative 'path' is made absolute - if ( ! empty( $sanitized_config['path'] ) && ! \WP_CLI\Utils\is_absolute_path( $sanitized_config['path'] ) ) { + if ( ! empty( $sanitized_config['path'] ) && ! \WP_CLI\Utils\is_path_absolute( $sanitized_config['path'] ) ) { $sanitized_config['path'] = dirname( $path ) . DIRECTORY_SEPARATOR . $sanitized_config['path']; } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index fd33cd0c82..5003f70a6e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -48,7 +48,7 @@ private static function set_wp_root( $config ) { $path = getcwd(); if ( !empty( $config['path'] ) ) { - if ( Utils\is_absolute_path( $config['path'] ) ) + if ( Utils\is_path_absolute( $config['path'] ) ) $path = $config['path']; else $path .= '/' . $config['path']; diff --git a/php/utils.php b/php/utils.php index e0cef0c1f4..240bce8e64 100644 --- a/php/utils.php +++ b/php/utils.php @@ -85,7 +85,7 @@ function find_file_upward( $files, $dir = null, $stop_check = null ) { return null; } -function is_absolute_path( $path ) { +function is_path_absolute( $path ) { // Windows if ( ':' === $path[1] ) return true; From 4129614a80e647ebf0e431a699e69beb743c4a95 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 05:32:37 +0300 Subject: [PATCH 1817/4858] move parse_args() to Configurator and set WP path only if it's not explicitly set --- php/WP_CLI/Configurator.php | 22 +++++++++++++++++++--- php/WP_CLI/Runner.php | 12 +++++------- php/utils.php | 23 ----------------------- 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index a677d1f3ea..a7078c5d99 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -31,10 +31,26 @@ function get_spec() { } /** - * Set default value for a particular configuration key. + * Splits a list of arguments into positional and associative. + * + * @param string + * @return array */ - function set_default( $key, $value ) { - $this->spec[ $key ]['default'] = $value; + function parse_args( $arguments ) { + $regular_args = array(); + $assoc_args = array(); + + foreach ( $arguments as $arg ) { + if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = true; + } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = $matches[2]; + } else { + $regular_args[] = $arg; + } + } + + return array( $regular_args, $assoc_args ); } /** diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 5003f70a6e..93510c915f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -229,13 +229,7 @@ private function init_logger() { public function before_wp_load() { list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( - Utils\parse_args( array_slice( $GLOBALS['argv'], 1 ) ) ); - - // Set the path default to the ABSPATH - $wp_abspath = dirname( Utils\find_file_upward( 'wp-load.php' ) ); - if ( ! empty( $wp_abspath ) ) { - \WP_CLI::$configurator->set_default( 'path', $wp_abspath ); - } + \WP_CLI::$configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ) ); $this->config_path = self::get_config_path( $this->assoc_args ); @@ -243,6 +237,10 @@ public function before_wp_load() { \WP_CLI::$configurator->split_special( $this->assoc_args, $this->config ); + if ( !isset( $this->config['path'] ) ) { + $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); + } + $this->init_logger(); $_SERVER['DOCUMENT_ROOT'] = realpath( $this->config['path'] ); diff --git a/php/utils.php b/php/utils.php index 240bce8e64..a5a2bad76b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -93,29 +93,6 @@ function is_path_absolute( $path ) { return $path[0] === '/'; } -/** - * Splits $argv into positional and associative arguments. - * - * @param string - * @return array - */ -function parse_args( $arguments ) { - $regular_args = array(); - $assoc_args = array(); - - foreach ( $arguments as $arg ) { - if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { - $assoc_args[ $matches[1] ] = true; - } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { - $assoc_args[ $matches[1] ] = $matches[2]; - } else { - $regular_args[] = $arg; - } - } - - return array( $regular_args, $assoc_args ); -} - /** * Composes positional arguments into a command string. * From 82b5d8520f3392e0a459d78589fb83b00731ec44 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 05:50:43 +0300 Subject: [PATCH 1818/4858] merge split_special() into parse_args() this gives us two clear variables to work with: $runtime_config and $local_config --- php/WP_CLI/Configurator.php | 63 ++++++++++++++++++------------------- php/WP_CLI/Runner.php | 33 +++++++++---------- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index a7078c5d99..47e919f69f 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -31,7 +31,7 @@ function get_spec() { } /** - * Splits a list of arguments into positional and associative. + * Splits a list of arguments into positional, associative and config. * * @param string * @return array @@ -50,7 +50,35 @@ function parse_args( $arguments ) { } } - return array( $regular_args, $assoc_args ); + $runtime_config = array(); + + foreach ( $this->spec as $key => $details ) { + if ( true === $details['runtime'] ) { + self::handle_boolean_param( $assoc_args, $runtime_config, $key ); + } elseif ( false !== $details['runtime'] ) { + if ( isset( $assoc_args[ $key ] ) ) { + $runtime_config[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } + } + } + + return array( $regular_args, $assoc_args, $runtime_config ); + } + + private static function handle_boolean_param( &$assoc_args, &$config, $param ) { + $subkeys = array( + "$param" => true, + "no-$param" => false + ); + + foreach ( $subkeys as $key => $value ) { + if ( isset( $assoc_args[ $key ] ) ) { + $config[ $param ] = $value; + } + + unset( $assoc_args[ $key ] ); + } } /** @@ -81,36 +109,5 @@ function load_config( $path ) { return $sanitized_config; } - - /** - * Extract values from an associative array, according to the spec. - */ - function split_special( &$assoc_args, &$config ) { - foreach ( $this->spec as $key => $details ) { - if ( true === $details['runtime'] ) { - self::handle_boolean_param( $assoc_args, $config, $key ); - } elseif ( false !== $details['runtime'] ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $key ] = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); - } - } - } - } - - private static function handle_boolean_param( &$assoc_args, &$config, $param ) { - $subkeys = array( - "$param" => true, - "no-$param" => false - ); - - foreach ( $subkeys as $key => $value ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $param ] = $value; - } - - unset( $assoc_args[ $key ] ); - } - } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 93510c915f..c33edc7290 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -16,27 +16,27 @@ public function __get( $key ) { return $this->$key; } - private static function get_config_path( &$assoc_args ) { - if ( isset( $assoc_args['config'] ) && file_exists( $assoc_args['config'] ) ) { - $path = $assoc_args['config']; - unset( $assoc_args['config'] ); - return $path; + private static function get_config_path( $runtime_config ) { + if ( isset( $runtime_config['config'] ) && file_exists( $runtime_config['config'] ) ) { + return $runtime_config['config']; } $config_files = array( 'wp-cli.local.yml', 'wp-cli.yml' ); - // Stop looking upward when we find we have emerged from a subdirectory install into a parent install - $stop_check = function ( $dir ) { + + // Stop looking upward when we find we have emerged from a subdirectory + // install into a parent install + $path = Utils\find_file_upward( $config_files, getcwd(), function ( $dir ) { static $wp_load_count = 0; $wp_load_path = $dir . DIRECTORY_SEPARATOR . 'wp-load.php'; if ( file_exists( $wp_load_path ) ) { $wp_load_count += 1; } return $wp_load_count > 1; - }; - $path = Utils\find_file_upward( $config_files, getcwd(), $stop_check ); + } ); + if ( $path ) { return $path; } @@ -154,9 +154,7 @@ public function get_wp_config_code() { } // Transparently convert old syntaxes - private static function back_compat_conversions( $r ) { - list( $args, $assoc_args ) = $r; - + private static function back_compat_conversions( $args, $assoc_args ) { // foo --help -> help foo if ( isset( $assoc_args['help'] ) ) { array_unshift( $args, 'help' ); @@ -228,14 +226,17 @@ private function init_logger() { } public function before_wp_load() { + list( $args, $assoc_args, $runtime_config ) = \WP_CLI::$configurator->parse_args( + array_slice( $GLOBALS['argv'], 1 ) ); + list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( - \WP_CLI::$configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ) ); + $args, $assoc_args ); - $this->config_path = self::get_config_path( $this->assoc_args ); + $this->config_path = self::get_config_path( $runtime_config ); - $this->config = \WP_CLI::$configurator->load_config( $this->config_path ); + $local_config = \WP_CLI::$configurator->load_config( $this->config_path ); - \WP_CLI::$configurator->split_special( $this->assoc_args, $this->config ); + $this->config = array_merge( $local_config, $runtime_config ); if ( !isset( $this->config['path'] ) ) { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); From b56969e7d3755b1e651b327958fedc5bc59c7474 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 06:51:18 +0300 Subject: [PATCH 1819/4858] behat: add -run- to temporary directory names this makes it easy to delete them, without deleting wp-cli-test-download-cache --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 66b3bfb3e5..eb699c29b2 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -110,7 +110,7 @@ private function _replace_var( $matches ) { public function create_empty_dir() { if ( !$this->install_dir ) { - $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-", TRUE ); + $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-run-", TRUE ); mkdir( $this->install_dir ); } } From a1c78df3df41d6a01e6598b4e8e09a05c677c7ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 06:39:01 +0300 Subject: [PATCH 1820/4858] support passing --require multiple times --- features/flags.feature | 52 +++++++++++++++++++++++++++++-------- php/WP_CLI/Configurator.php | 49 +++++++++++++++++++--------------- php/WP_CLI/Runner.php | 23 +++++++++++++--- php/config-spec.php | 2 ++ 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 95a201a732..e99f95996d 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -61,23 +61,53 @@ Feature: Global flags Scenario: Using --require Given a WP install And a custom-cmd.php file: - """ - <?php - class Test_Command extends WP_CLI_Command { + """ + <?php + class Test_Command extends WP_CLI_Command { - function req( $args, $assoc_args ) { - WP_CLI::line( $args[0] ); + function req( $args, $assoc_args ) { + WP_CLI::line( $args[0] ); + } } - } - WP_CLI::add_command( 'test', 'Test_Command' ); - """ + WP_CLI::add_command( 'test', 'Test_Command' ); + """ + + And a foo.php file: + """ + <?php echo basename(__FILE__) . "\n"; + """ + + And a bar.php file: + """ + <?php echo basename(__FILE__) . "\n"; + """ + + And a wp-cli.yml file: + """ + require: + - foo.php + - bar.php + """ + + And a wp-cli2.yml file: + """ + require: custom-cmd.php + """ When I run `wp --require=custom-cmd.php test req 'This is a custom command.'` Then STDOUT should be: - """ - This is a custom command. - """ + """ + foo.php + bar.php + This is a custom command. + """ + + When I run `wp --config=wp-cli2.yml test req 'This is a custom command.'` + Then STDOUT should contain: + """ + This is a custom command. + """ Scenario: Enabling/disabling color Given a WP install diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 47e919f69f..fba6f75023 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -14,6 +14,7 @@ function __construct( $path ) { 'file' => false, 'synopsis' => '', 'default' => null, + 'multiple' => false, ); foreach ( $this->spec as &$option ) { @@ -37,28 +38,34 @@ function get_spec() { * @return array */ function parse_args( $arguments ) { - $regular_args = array(); - $assoc_args = array(); + $regular_args = $mixed_args = array(); foreach ( $arguments as $arg ) { if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { - $assoc_args[ $matches[1] ] = true; + $mixed_args[] = array( $matches[1], true ); } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { - $assoc_args[ $matches[1] ] = $matches[2]; + $mixed_args[] = array( $matches[1], $matches[2] ); } else { $regular_args[] = $arg; } } - $runtime_config = array(); + $assoc_args = $runtime_config = array(); - foreach ( $this->spec as $key => $details ) { - if ( true === $details['runtime'] ) { - self::handle_boolean_param( $assoc_args, $runtime_config, $key ); - } elseif ( false !== $details['runtime'] ) { - if ( isset( $assoc_args[ $key ] ) ) { - $runtime_config[ $key ] = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); + foreach ( $mixed_args as $tmp ) { + list( $key, $value ) = $tmp; + + $enabled = isset( $this->spec[ $key ] ) ? $this->spec[ $key ]['runtime'] : false; + + if ( false === $enabled ) { + $assoc_args[ $key ] = $value; + } elseif ( true === $enabled ) { + self::handle_boolean_param( $mixed_args, $runtime_config, $key ); + } else { + if ( $this->spec[ $key ]['multiple'] ) { + $runtime_config[ $key ][] = $value; + } else { + $runtime_config[ $key ] = $value; } } } @@ -95,16 +102,16 @@ function load_config( $path ) { $sanitized_config = array(); foreach ( $this->spec as $key => $details ) { - if ( $details['file'] && isset( $config[ $key ] ) ) - $sanitized_config[ $key ] = $config[ $key ]; - else - $sanitized_config[ $key ] = $details['default']; - } + if ( $details['file'] && isset( $config[ $key ] ) ) { + $value = $config[ $key ]; + if ( $details['multiple'] && !is_array( $value ) ) { + $value = array( $value ); + } + } else { + $value = $details['default']; + } - // When invoking from a subdirectory in the project, - // make sure a config-relative 'path' is made absolute - if ( ! empty( $sanitized_config['path'] ) && ! \WP_CLI\Utils\is_path_absolute( $sanitized_config['path'] ) ) { - $sanitized_config['path'] = dirname( $path ) . DIRECTORY_SEPARATOR . $sanitized_config['path']; + $sanitized_config[ $key ] = $value; } return $sanitized_config; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c33edc7290..13def081cb 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -236,7 +236,21 @@ public function before_wp_load() { $local_config = \WP_CLI::$configurator->load_config( $this->config_path ); - $this->config = array_merge( $local_config, $runtime_config ); + // When invoking from a subdirectory in the project, + // make sure a config-relative 'path' is made absolute + if ( !empty( $local_config['path'] ) && !\WP_CLI\Utils\is_path_absolute( $local_config['path'] ) ) { + $local_config['path'] = dirname( $this->config_path ) . DIRECTORY_SEPARATOR . $local_config['path']; + } + + $this->config = $local_config; + + foreach ( $runtime_config as $key => $value ) { + if ( isset( $this->config[ $key ] ) && is_array( $this->config[ $key ] ) ) { + $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); + } else { + $this->config[ $key ] = $value; + } + } if ( !isset( $this->config['path'] ) ) { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); @@ -307,8 +321,11 @@ public function after_wp_load() { // Handle --user parameter self::set_user( $this->config ); - if ( isset( $this->config['require'] ) ) - require $this->config['require']; + if ( isset( $this->config['require'] ) ) { + foreach ( $this->config['require'] as $path ) { + require $path; + } + } // Handle --completions parameter if ( isset( $this->assoc_args['completions'] ) ) { diff --git a/php/config-spec.php b/php/config-spec.php index 41332d9a3f..a711db49b9 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -33,6 +33,8 @@ 'runtime' => '=<path>', 'file' => '<path>', 'desc' => 'Load given PHP file before running the command', + 'multiple' => true, + 'default' => array(), ), 'disabled_commands' => array( From 034f1e634cbf47f3d458bd5346fb260e4ef562af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 18:09:28 +0300 Subject: [PATCH 1821/4858] fix boolean flag handling --- php/WP_CLI/Configurator.php | 21 +++------------------ php/WP_CLI/Runner.php | 5 +---- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index fba6f75023..70b72522b6 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -41,7 +41,9 @@ function parse_args( $arguments ) { $regular_args = $mixed_args = array(); foreach ( $arguments as $arg ) { - if ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { + if ( preg_match( '|^--no-([^=]+)$|', $arg, $matches ) ) { + $mixed_args[] = array( $matches[1], false ); + } elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { $mixed_args[] = array( $matches[1], true ); } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { $mixed_args[] = array( $matches[1], $matches[2] ); @@ -59,8 +61,6 @@ function parse_args( $arguments ) { if ( false === $enabled ) { $assoc_args[ $key ] = $value; - } elseif ( true === $enabled ) { - self::handle_boolean_param( $mixed_args, $runtime_config, $key ); } else { if ( $this->spec[ $key ]['multiple'] ) { $runtime_config[ $key ][] = $value; @@ -73,21 +73,6 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args, $runtime_config ); } - private static function handle_boolean_param( &$assoc_args, &$config, $param ) { - $subkeys = array( - "$param" => true, - "no-$param" => false - ); - - foreach ( $subkeys as $key => $value ) { - if ( isset( $assoc_args[ $key ] ) ) { - $config[ $param ] = $value; - } - - unset( $assoc_args[ $key ] ); - } - } - /** * Load values from a YML file and sanitize them according to the spec. * diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 13def081cb..6e735b0479 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -208,10 +208,7 @@ private static function back_compat_conversions( $args, $assoc_args ) { } private function init_logger() { - if ( isset( $this->assoc_args['no-color'] ) ) { - $color = false; - unset( $this->assoc_args['no-color'] ); - } elseif ( 'auto' === $this->config['color'] ) { + if ( 'auto' === $this->config['color'] ) { $color = ! \cli\Shell::isPiped(); } else { $color = $this->config['color']; From e91a480df19e806598cedaed5ff06df4f3dc974f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 18:41:55 +0300 Subject: [PATCH 1822/4858] mention that --require can be used more than once --- php/WP_CLI/Dispatcher/RootCommand.php | 4 ++-- php/config-spec.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index ffebadb15f..c9e9abddca 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -25,7 +25,7 @@ function show_usage() { if ( '_sys' == $command->get_name() ) continue; - \WP_CLI::line( sprintf( " %s %s", + \WP_CLI::line( sprintf( ' %s %s', implode( ' ', get_path( $command ) ), implode( '|', array_keys( $command->get_subcommands() ) ) ) ); @@ -69,7 +69,7 @@ private static function generate_synopsis() { foreach ( $lines as $line ) { list( $synopsis, $desc ) = $line; - \WP_CLI::line( ' ' . str_pad( $synopsis, $max_len ) . ' ' . $desc ); + \WP_CLI::line( sprintf( ' %s %s', str_pad( $synopsis, $max_len ), $desc ) ); } } diff --git a/php/config-spec.php b/php/config-spec.php index a711db49b9..61aaf46ba3 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -32,7 +32,7 @@ 'require' => array( 'runtime' => '=<path>', 'file' => '<path>', - 'desc' => 'Load given PHP file before running the command', + 'desc' => 'Load PHP file before running the command (may be used more than once)', 'multiple' => true, 'default' => array(), ), From 5d9ce1fbd8668b8e04ded941aae83b893e056d51 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 23 May 2013 14:25:45 +0300 Subject: [PATCH 1823/4858] load path from --require before WP is loaded --- php/WP_CLI/Runner.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6e735b0479..a8474e4b83 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -255,6 +255,12 @@ public function before_wp_load() { $this->init_logger(); + if ( isset( $this->config['require'] ) ) { + foreach ( $this->config['require'] as $path ) { + require $path; + } + } + $_SERVER['DOCUMENT_ROOT'] = realpath( $this->config['path'] ); if ( $this->cmd_starts_with( array( '_sys' ) ) ) { @@ -318,12 +324,6 @@ public function after_wp_load() { // Handle --user parameter self::set_user( $this->config ); - if ( isset( $this->config['require'] ) ) { - foreach ( $this->config['require'] as $path ) { - require $path; - } - } - // Handle --completions parameter if ( isset( $this->assoc_args['completions'] ) ) { foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { From 782a6b71f2382ebb29614bfb8f441bd8e0f3ff5a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 16:44:51 +0300 Subject: [PATCH 1824/4858] attempt to load built-in command early --- php/WP_CLI/Runner.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a8474e4b83..93613ad9af 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -255,6 +255,9 @@ public function before_wp_load() { $this->init_logger(); + if ( !empty( $this->arguments ) ) + Utils\load_command( $this->arguments[0] ); + if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { require $path; From 10c987faf2b6b08edd32987b4334b82ad92af35e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 17:09:26 +0300 Subject: [PATCH 1825/4858] behat: test that --require works without a WP install --- features/flags.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index e99f95996d..20a2e436fd 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -58,6 +58,27 @@ Feature: Global flags Error: Could not get a user_id for this user: 'non-existing-user' """ + Scenario: Using a custom logger + Given an empty directory + And a custom-logger.php file: + """ + <?php + class Dummy_Logger { + + function __call( $method, $args ) { + echo "log: called '$method' method"; + } + } + + WP_CLI::set_logger( new Dummy_Logger ); + """ + + When I try `wp --require=custom-logger.php` + Then STDOUT should be: + """ + log: called 'error' method + """ + Scenario: Using --require Given a WP install And a custom-cmd.php file: From 56476488709e462e5c738ac6f1129f3ffa44bbd5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Jun 2013 19:41:48 +0300 Subject: [PATCH 1826/4858] update Composer dependencies make version requirements less strict --- composer.json | 6 +- composer.lock | 193 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 128 insertions(+), 71 deletions(-) diff --git a/composer.json b/composer.json index 895c4e2f90..c9a8e7b551 100644 --- a/composer.json +++ b/composer.json @@ -10,14 +10,14 @@ "require": { "php": ">=5.3.2", "wp-cli/php-cli-tools": "dev-master", - "mustache/mustache": "2.3.x" + "mustache/mustache": "~2.3" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" }, "require-dev": { - "phpunit/phpunit": "3.7.x", - "behat/behat": "2.4.*@stable" + "phpunit/phpunit": "~3.7", + "behat/behat": "~2.4" }, "autoload": { "psr-0": { "WP_CLI": "php" } diff --git a/composer.lock b/composer.lock index 6e824d1cfe..8764fbff5c 100644 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "9cb0bdfbcfa8b3b505b9241ca38f19f7", + "hash": "6cae44632851e1e1cee580631b2d784a", "packages": [ { "name": "mustache/mustache", @@ -96,28 +96,31 @@ "packages-dev": [ { "name": "behat/behat", - "version": "v2.4.5", + "version": "v2.4.6", "source": { "type": "git", - "url": "git://github.com/Behat/Behat.git", - "reference": "v2.4.5" + "url": "https://github.com/Behat/Behat.git", + "reference": "v2.4.6" }, "dist": { "type": "zip", - "url": "https://github.com/Behat/Behat/archive/v2.4.5.zip", - "reference": "v2.4.5", + "url": "https://api.github.com/repos/Behat/Behat/zipball/v2.4.6", + "reference": "v2.4.6", "shasum": "" }, "require": { - "behat/gherkin": ">=2.2.4,<2.3-dev", + "behat/gherkin": ">=2.2.9,<2.3", "php": ">=5.3.1", - "symfony/config": ">=2.0,<2.3-dev", - "symfony/console": ">=2.0,<2.3-dev", - "symfony/dependency-injection": ">=2.0,<2.3-dev", - "symfony/event-dispatcher": ">=2.0,<2.3-dev", - "symfony/finder": ">=2.0,<2.3-dev", - "symfony/translation": ">=2.0,<2.3-dev", - "symfony/yaml": ">=2.0,<2.3-dev" + "symfony/config": ">=2.0,<3.0", + "symfony/console": ">=2.0,<3.0", + "symfony/dependency-injection": ">=2.0,<3.0", + "symfony/event-dispatcher": ">=2.0,<3.0", + "symfony/finder": ">=2.0,<3.0", + "symfony/translation": ">=2.0,<3.0", + "symfony/yaml": ">=2.0,<3.0" + }, + "require-dev": { + "phpunit/phpunit": ">=3.7.19.0,<3.8" }, "suggest": { "behat/mink-extension": "for integration with Mink testing framework", @@ -156,7 +159,7 @@ "Behat", "Symfony2" ], - "time": "2013-01-27 14:45:41" + "time": "2013-06-06 10:46:48" }, { "name": "behat/gherkin", @@ -578,26 +581,27 @@ }, { "name": "symfony/config", - "version": "v2.2.2", + "version": "v2.3.1", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "v2.2.2" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/Config/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "symfony/filesystem": ">=2.3,<3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -621,30 +625,36 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2013-05-10 18:08:31" + "time": "2013-06-03 00:18:25" }, { "name": "symfony/console", - "version": "v2.2.2", + "version": "v2.3.1", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "v2.2.2" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/Console/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/event-dispatcher": ">=2.1,<3.0" + }, + "suggest": { + "symfony/event-dispatcher": "" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -668,38 +678,39 @@ ], "description": "Symfony Console Component", "homepage": "http://symfony.com", - "time": "2013-05-27 14:47:40" + "time": "2013-06-11 07:15:14" }, { "name": "symfony/dependency-injection", - "version": "v2.2.2", + "version": "v2.3.1", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "v2.2.2" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "symfony/config": ">=2.2,<2.3-dev", + "symfony/config": ">=2.2,<3.0", "symfony/yaml": ">=2.0,<3.0" }, "suggest": { - "symfony/config": "2.2.*", - "symfony/yaml": "2.2.*" + "symfony/config": "", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -723,21 +734,21 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2013-05-06 08:37:50" + "time": "2013-06-05 09:51:05" }, { "name": "symfony/event-dispatcher", - "version": "v2.2.2", + "version": "v2.3.0", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.2.2" + "reference": "v2.3.0-RC1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.0-RC1", + "reference": "v2.3.0-RC1", "shasum": "" }, "require": { @@ -747,13 +758,13 @@ "symfony/dependency-injection": ">=2.0,<3.0" }, "suggest": { - "symfony/dependency-injection": "2.2.*", - "symfony/http-kernel": "2.2.*" + "symfony/dependency-injection": "", + "symfony/http-kernel": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -777,21 +788,68 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2013-02-11 11:26:43" + "time": "2013-05-13 14:36:40" + }, + { + "name": "symfony/filesystem", + "version": "v2.3.1", + "target-dir": "Symfony/Component/Filesystem", + "source": { + "type": "git", + "url": "https://github.com/symfony/Filesystem.git", + "reference": "v2.3.1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.1", + "reference": "v2.3.1", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Filesystem\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "http://symfony.com", + "time": "2013-06-04 15:02:05" }, { "name": "symfony/finder", - "version": "v2.2.2", + "version": "v2.3.1", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "v2.2.2" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { @@ -800,7 +858,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -824,38 +882,38 @@ ], "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2013-05-27 20:26:32" + "time": "2013-06-02 12:05:51" }, { "name": "symfony/translation", - "version": "v2.2.2", + "version": "v2.3.0", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "v2.2.2" + "reference": "v2.3.0-RC1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.0-RC1", + "reference": "v2.3.0-RC1", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "symfony/config": ">=2.0,<2.3-dev", + "symfony/config": ">=2.0,<3.0", "symfony/yaml": ">=2.2,<3.0" }, "suggest": { - "symfony/config": "2.2.*", - "symfony/yaml": "2.2.*" + "symfony/config": "", + "symfony/yaml": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -879,21 +937,21 @@ ], "description": "Symfony Translation Component", "homepage": "http://symfony.com", - "time": "2013-05-10 16:49:00" + "time": "2013-05-13 14:36:40" }, { "name": "symfony/yaml", - "version": "v2.2.2", + "version": "v2.3.0", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.2.2" + "reference": "v2.3.0-RC1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.2", - "reference": "v2.2.2", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.0-RC1", + "reference": "v2.3.0-RC1", "shasum": "" }, "require": { @@ -902,7 +960,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -926,7 +984,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-05-10 18:08:31" + "time": "2013-05-10 18:12:13" } ], "aliases": [ @@ -934,8 +992,7 @@ ], "minimum-stability": "stable", "stability-flags": { - "wp-cli/php-cli-tools": 20, - "behat/behat": 0 + "wp-cli/php-cli-tools": 20 }, "platform": { "php": ">=5.3.2" From c8d5e0d567db81fee1f6f89ef8429eb07ba292eb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Jun 2013 05:22:55 +0300 Subject: [PATCH 1827/4858] introduce WP_CLI::colorize() utility --- php/WP_CLI/Loggers/Quiet.php | 8 +------- php/WP_CLI/Loggers/Regular.php | 8 +------- php/WP_CLI/Runner.php | 17 ++++++++++++----- php/class-wp-cli.php | 4 ++++ 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 06a404bb50..e2fd0c6b55 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -4,12 +4,6 @@ class Quiet { - private $colorize; - - function __construct( $colorize ) { - $this->colorize = $colorize; - } - function line( $message ) { // nothing } @@ -24,7 +18,7 @@ function warning( $message, $label ) { function error( $message, $label ) { $msg = '%R' . $label . ': %n' . $message; - fwrite( STDERR, \cli\Colors::colorize( $msg . "\n", $this->colorize ) ); + fwrite( STDERR, \WP_CLI::colorize( $msg . "\n" ) ); } } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index 65104db231..cb2809ffde 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -4,14 +4,8 @@ class Regular { - private $colorize; - - function __construct( $colorize ) { - $this->colorize = $colorize; - } - private function _line( $message, $handle = STDOUT ) { - fwrite( $handle, \cli\Colors::colorize( $message . "\n", $this->colorize ) ); + fwrite( $handle, \WP_CLI::colorize( $message . "\n" ) ); } function line( $message ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 93613ad9af..f1100d4d27 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -207,17 +207,23 @@ private static function back_compat_conversions( $args, $assoc_args ) { return array( $args, $assoc_args ); } - private function init_logger() { + public function in_color() { + return $this->colorize; + } + + private function init_colorization() { if ( 'auto' === $this->config['color'] ) { - $color = ! \cli\Shell::isPiped(); + $this->colorize = !\cli\Shell::isPiped(); } else { - $color = $this->config['color']; + $this->colorize = $this->config['color']; } + } + private function init_logger() { if ( $this->config['quiet'] ) - $logger = new \WP_CLI\Loggers\Quiet( $color ); + $logger = new \WP_CLI\Loggers\Quiet; else - $logger = new \WP_CLI\Loggers\Regular( $color ); + $logger = new \WP_CLI\Loggers\Regular; WP_CLI::set_logger( $logger ); } @@ -253,6 +259,7 @@ public function before_wp_load() { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); } + $this->init_colorization(); $this->init_logger(); if ( !empty( $this->arguments ) ) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index bdee64d149..ea33cd04aa 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -39,6 +39,10 @@ static function set_logger( $logger ) { self::$logger = $logger; } + static function colorize( $string ) { + return \cli\Colors::colorize( $string, self::$runner->in_color() ); + } + /** * Add a command to the WP-CLI list of commands * From 71d81899acfa7d1ccce2674b9669b30250494f34 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Jun 2013 05:30:44 +0300 Subject: [PATCH 1828/4858] use Mustache templates to display plugin/theme details --- php/commands/plugin.php | 18 ++++++++---------- php/commands/theme.php | 12 +++++++----- templates/plugin-status.mustache | 6 ++++++ templates/theme-status.mustache | 5 +++++ 4 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 templates/plugin-status.mustache create mode 100644 templates/theme-status.mustache diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 4b860a0818..1aee7a29c3 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -47,16 +47,14 @@ protected function status_single( $args ) { if ( $this->has_update( $file ) ) $version .= ' (%gUpdate available%n)'; - $this->_status_single( $details, $name, $version, $status ); - } - - protected function _status_single( $details, $name, $version, $status ) { - WP_CLI::line( 'Plugin %9' . $name . '%n details:' ); - WP_CLI::line( ' Name: ' . $details[ 'Name' ] ); - WP_CLI::line( ' Status: ' . $status .'%n' ); - WP_CLI::line( ' Version: ' . $version ); - WP_CLI::line( ' Author: ' . $details[ 'Author' ] ); - WP_CLI::line( ' Description: ' . $details[ 'Description' ] ); + echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'plugin-status.mustache', array( + 'slug' => $name, + 'status' => $status, + 'version' => $version, + 'name' => $details['Name'], + 'author' => $details['Author'], + 'description' => $details['Description'] + ) ) ); } protected function get_all_items() { diff --git a/php/commands/theme.php b/php/commands/theme.php index 50245e7143..0a9602b824 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -37,11 +37,13 @@ protected function status_single( $args ) { if ( $this->has_update( $theme->get_stylesheet() ) ) $version .= ' (%gUpdate available%n)'; - WP_CLI::line( 'Theme %9' . $theme->get_stylesheet() . '%n details:' ); - WP_CLI::line( ' Name: ' . $theme->get('Name') ); - WP_CLI::line( ' Status: ' . $status .'%n' ); - WP_CLI::line( ' Version: ' . $version ); - WP_CLI::line( ' Author: ' . $theme->get('Author') ); + echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'theme-status.mustache', array( + 'slug' => $theme->get_stylesheet(), + 'status' => $status, + 'version' => $version, + 'name' => $theme->get('Name'), + 'author' => $theme->get('Author'), + ) ) ); } protected function get_all_items() { diff --git a/templates/plugin-status.mustache b/templates/plugin-status.mustache new file mode 100644 index 0000000000..3758626902 --- /dev/null +++ b/templates/plugin-status.mustache @@ -0,0 +1,6 @@ +Plugin %9{{slug}}%n details: + Name: {{name}} + Status: {{status}}%n + Version: {{version}} + Author: {{author}} + Description: {{description}} diff --git a/templates/theme-status.mustache b/templates/theme-status.mustache new file mode 100644 index 0000000000..c53be6338f --- /dev/null +++ b/templates/theme-status.mustache @@ -0,0 +1,5 @@ +Theme %9{{slug}}%n details: + Name: {{name}} + Status: {{status}}%n + Version: {{version}} + Author: {{author}} From 7066d87f7b383836f4c64f4adad9158a86570fad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Jun 2013 05:50:08 +0300 Subject: [PATCH 1829/4858] refresh `core version` output * remove manifest version (absent from recent WP releases) * remove redundant stability label for core versions * use Mustache template and replace tabs with spaces --- php/commands/core.php | 38 ++++++++++++------------------------- templates/versions.mustache | 3 +++ 2 files changed, 15 insertions(+), 26 deletions(-) create mode 100644 templates/versions.mustache diff --git a/php/commands/core.php b/php/commands/core.php index 3009dde8fe..99c52fec15 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -231,36 +231,22 @@ private static function get_clean_basedomain() { * @synopsis [--extra] */ public function version( $args = array(), $assoc_args = array() ) { - global $wp_version, $wp_db_version, $tinymce_version, $manifest_version; - - $color = '%G'; - $version_text = $wp_version; - $version_types = array( - '-RC' => array( 'release candidate', '%y' ), - '-beta' => array( 'beta', '%B' ), - '-' => array( 'in development', '%R' ), - ); - - foreach( $version_types as $needle => $type ) { - if ( stristr( $wp_version, $needle ) ) { - list( $version_text, $color ) = $type; - $version_text = "$color$wp_version%n (stability: $version_text)"; - break; - } - } + global $wp_version, $wp_db_version, $tinymce_version; if ( isset( $assoc_args['extra'] ) ) { - WP_CLI::line( "WordPress version:\t$version_text" ); - - WP_CLI::line( "Database revision:\t$wp_db_version" ); - preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); - $human_readable_tiny_mce = $match? $match[1] . '.' . $match[2] : ''; - WP_CLI::line( "TinyMCE version:\t" . ( $human_readable_tiny_mce? "$human_readable_tiny_mce ($tinymce_version)" : $tinymce_version ) ); - - WP_CLI::line( "Manifest revision:\t$manifest_version" ); + $human_readable_tiny_mce = $match ? $match[1] . '.' . $match[2] : ''; + + echo \WP_CLI\Utils\mustache_render( 'versions.mustache', array( + 'wp-version' => $wp_version, + 'db-version' => $wp_db_version, + 'mce-version' => ( $human_readable_tiny_mce ? + "$human_readable_tiny_mce ($tinymce_version)" + : $tinymce_version + ) + ) ); } else { - WP_CLI::line( $version_text ); + WP_CLI::line( $wp_version ); } } diff --git a/templates/versions.mustache b/templates/versions.mustache new file mode 100644 index 0000000000..06c0e8ea95 --- /dev/null +++ b/templates/versions.mustache @@ -0,0 +1,3 @@ +WordPress version: {{wp-version}} +Database revision: {{db-version}} +TinyMCE version: {{mce-version}} From b9ae3fdb1f0eee329f019227df67a44af18e76a5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Jun 2013 06:03:02 +0300 Subject: [PATCH 1830/4858] use WP_CLI::colorize() in CommandWithUpgrade --- php/WP_CLI/CommandWithUpgrade.php | 2 +- php/WP_CLI/Loggers/Regular.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index cf771d6f58..8f99841aa5 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -54,7 +54,7 @@ private function status_all() { $line .= " " . $details['version']; } - \WP_CLI::line( $line ); + \WP_CLI::line( \WP_CLI::colorize( $line ) ); } \WP_CLI::line(); diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index cb2809ffde..08d0670df0 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -9,7 +9,7 @@ private function _line( $message, $handle = STDOUT ) { } function line( $message ) { - $this->_line( $message ); + echo $message . "\n"; } function success( $message, $label ) { From 174ef01d9ec5e9ca6dd4546fbfec441e76a7ee78 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Jun 2013 06:13:35 +0300 Subject: [PATCH 1831/4858] move line() method from loggers back to the WP_CLI class --- php/WP_CLI/Loggers/Quiet.php | 7 +------ php/WP_CLI/Loggers/Regular.php | 9 ++------- php/class-wp-cli.php | 2 +- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index e2fd0c6b55..14b929566c 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -4,10 +4,6 @@ class Quiet { - function line( $message ) { - // nothing - } - function success( $message, $label ) { // nothing } @@ -17,8 +13,7 @@ function warning( $message, $label ) { } function error( $message, $label ) { - $msg = '%R' . $label . ': %n' . $message; - fwrite( STDERR, \WP_CLI::colorize( $msg . "\n" ) ); + fwrite( STDERR, \WP_CLI::colorize( "%R$label:%n $message\n" ) ); } } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index 08d0670df0..6cd2db0ba1 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -8,17 +8,12 @@ private function _line( $message, $handle = STDOUT ) { fwrite( $handle, \WP_CLI::colorize( $message . "\n" ) ); } - function line( $message ) { - echo $message . "\n"; - } - function success( $message, $label ) { - $this->line( '%G' . $label . ': %n' . $message ); + $this->_line( "%G$label:%n $message" ); } function warning( $message, $label ) { - $msg = '%C' . $label . ': %n' . $message; - $this->_line( $msg, STDERR ); + $this->_line( "%C$label:%n $message", STDERR ); } function error( $message, $label ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ea33cd04aa..cfcf3ac4af 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -131,7 +131,7 @@ static function get_man_dirs() { * @param string $message */ static function line( $message = '' ) { - self::$logger->line( $message ); + echo $message . "\n"; } /** From 14a0d4f83a121e7ea0fef62802f275a4aa1f09ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Jun 2013 06:30:37 +0300 Subject: [PATCH 1832/4858] behat: partially delete quiet run test output from WP_CLI::line() is no longer suppressed, since we can't be sure it's not the essential output (think `wp core version`) --- features/flags.feature | 6 ------ 1 file changed, 6 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 20a2e436fd..dc73efbf4d 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -3,12 +3,6 @@ Feature: Global flags Scenario: Quiet run Given a WP install - When I run `wp` - Then STDOUT should not be empty - - When I run `wp --quiet` - Then STDOUT should be empty - When I try `wp non-existing-command --quiet` Then the return code should be 1 And STDERR should be: From 37829cb231523dd2aefb3d9ce5bb512afa594226 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Jun 2013 21:55:02 +0300 Subject: [PATCH 1833/4858] add URL redirect warning --- php/utils-wp.php | 10 ++++++++++ php/wp-settings-cli.php | 2 ++ 2 files changed, 12 insertions(+) diff --git a/php/utils-wp.php b/php/utils-wp.php index 5d42c52c88..4a307e7538 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -45,6 +45,16 @@ function wp_die_handler( $message ) { \WP_CLI::error( $message ); } +function wp_redirect_handler( $url ) { + \WP_CLI::warning( 'Some code is trying to do a URL redirect. Backtrace:' ); + + ob_start(); + debug_print_backtrace(); + fwrite( STDERR, ob_get_clean() ); + + return $url; +} + function maybe_require( $since, $path ) { global $wp_version; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 12321c11ad..f892f57eb1 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -56,7 +56,9 @@ require( ABSPATH . WPINC . '/plugin.php' ); require( ABSPATH . WPINC . '/pomo/mo.php' ); +// WP_CLI: Early hooks Utils\replace_wp_die_handler(); +add_filter( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); From 4ccd65904c363cc4b67ca15aa07e8ec7e5d0578e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Jun 2013 21:55:02 +0300 Subject: [PATCH 1834/4858] add URL redirect warning (for 0.10.1 branch) see #521 --- php/utils-wp.php | 10 ++++++++++ php/wp-settings-cli.php | 2 ++ 2 files changed, 12 insertions(+) diff --git a/php/utils-wp.php b/php/utils-wp.php index 5d42c52c88..4a307e7538 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -45,6 +45,16 @@ function wp_die_handler( $message ) { \WP_CLI::error( $message ); } +function wp_redirect_handler( $url ) { + \WP_CLI::warning( 'Some code is trying to do a URL redirect. Backtrace:' ); + + ob_start(); + debug_print_backtrace(); + fwrite( STDERR, ob_get_clean() ); + + return $url; +} + function maybe_require( $since, $path ) { global $wp_version; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 12321c11ad..f892f57eb1 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -56,7 +56,9 @@ require( ABSPATH . WPINC . '/plugin.php' ); require( ABSPATH . WPINC . '/pomo/mo.php' ); +// WP_CLI: Early hooks Utils\replace_wp_die_handler(); +add_filter( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); From 65a2dabc95193c5026f3dd8707fff4eb21846400 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 11:46:01 +0300 Subject: [PATCH 1835/4858] set version to 0.10.1 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 7fa1276aa4..c54a7a4ac2 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.10.1-alpha' ); +define( 'WP_CLI_VERSION', '0.10.1' ); include WP_CLI_ROOT . 'utils.php'; include WP_CLI_ROOT . 'dispatcher.php'; From 973a5ec67bb088ac56c06b75b8c39ff89ab13e4d Mon Sep 17 00:00:00 2001 From: Tomasz Ratajczak <tomasz.ratajczak@espeo.pl> Date: Fri, 7 Jun 2013 16:26:54 +0200 Subject: [PATCH 1836/4858] add site meta commands --- php/commands/site-meta.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 php/commands/site-meta.php diff --git a/php/commands/site-meta.php b/php/commands/site-meta.php new file mode 100644 index 0000000000..3642167dec --- /dev/null +++ b/php/commands/site-meta.php @@ -0,0 +1,13 @@ +<?php + +/** + * Manage site custom fields. + * + * @package wp-cli + */ +class Site_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'site'; +} + +WP_CLI::add_command( 'site-meta', 'Site_Meta_Command' ); + From 6ae19150fe3263b5b19e1237c58b92f73d9eab15 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 May 2013 17:35:38 +0300 Subject: [PATCH 1837/4858] introduce 'before_invoke:{cmd}' hook and use it for site-meta command --- features/site-meta.feature | 17 +++++++++++++++++ php/WP_CLI/Dispatcher/Subcommand.php | 2 ++ php/class-wp-cli.php | 26 +++++++++++++++++++++++++- php/commands/site-meta.php | 6 ++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 features/site-meta.feature diff --git a/features/site-meta.feature b/features/site-meta.feature new file mode 100644 index 0000000000..8b1fa20351 --- /dev/null +++ b/features/site-meta.feature @@ -0,0 +1,17 @@ +Feature: Manage WordPress installation + + Scenario: Non-multisite + Given a WP install + + When I try `wp site-meta` + Then STDOUT should contain: + """ + usage: wp site-meta + """ + + When I try `wp site-meta get 1 site_admins` + Then STDOUT should be empty + And STDERR should contain: + """ + This is not a multisite install. + """ diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 7a71e282df..5ce7058c80 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -60,6 +60,8 @@ private function validate_args( $args, &$assoc_args ) { function invoke( $args, $assoc_args ) { $this->validate_args( $args, $assoc_args ); + \WP_CLI::do_hook( 'before_invoke:' . $this->get_parent()->get_name() ); + call_user_func( $this->when_invoked, $args, $assoc_args ); } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index cfcf3ac4af..4bccc21014 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -14,6 +14,8 @@ class WP_CLI { private static $logger; + private static $hooks = array(), $hooks_passed = array(); + private static $man_dirs = array(); /** @@ -44,7 +46,29 @@ static function colorize( $string ) { } /** - * Add a command to the WP-CLI list of commands + * Schedule a callback to be executed at a certain point (before WP is loaded). + */ + static function add_hook( $when, $callback ) { + if ( in_array( $when, self::$hooks_passed ) ) + call_user_func( $callback ); + + self::$hooks[ $when ][] = $callback; + } + + /** + * Execute registered callbacks. + */ + static function do_hook( $when ) { + self::$hooks_passed[] = $when; + + if ( !isset( self::$hooks[ $when ] ) ) + return; + + array_map( 'call_user_func', self::$hooks[ $when ] ); + } + + /** + * Add a command to the wp-cli list of commands * * @param string $name The name of the command that will be used in the cli * @param string $class The command implementation diff --git a/php/commands/site-meta.php b/php/commands/site-meta.php index 3642167dec..9ca5c61bb2 100644 --- a/php/commands/site-meta.php +++ b/php/commands/site-meta.php @@ -11,3 +11,9 @@ class Site_Meta_Command extends \WP_CLI\CommandWithMeta { WP_CLI::add_command( 'site-meta', 'Site_Meta_Command' ); +WP_CLI::add_hook( 'before_invoke:site-meta', function () { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } +} ); + From 567f7f57efac5a0abd45934c2b6e7f8a1590e007 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 12:52:41 +0300 Subject: [PATCH 1838/4858] add man page for site-meta [ci skip] --- man-src/site-meta.txt | 14 ++++++++ man/site-meta.1 | 69 ++++++++++++++++++++++++++++++++++++++ php/commands/site-meta.php | 2 +- 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 man-src/site-meta.txt create mode 100644 man/site-meta.1 diff --git a/man-src/site-meta.txt b/man-src/site-meta.txt new file mode 100644 index 0000000000..e921abce76 --- /dev/null +++ b/man-src/site-meta.txt @@ -0,0 +1,14 @@ +## OPTIONS + +* `<id>`: + + The network id (usually 1). + +* `--format=json`: + + Encode/decode values as JSON. + +## EXAMPLES + + # get a list of super-admins + wp site-meta get 1 site_admins diff --git a/man/site-meta.1 b/man/site-meta.1 new file mode 100644 index 0000000000..eaa72b0de0 --- /dev/null +++ b/man/site-meta.1 @@ -0,0 +1,69 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "WP\-SITE\-META" "1" "" "WP-CLI" +. +.SH "NAME" +\fBwp\-site\-meta\fR \- Manage network custom fields\. +. +.SH "SYNOPSIS" +wp site\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] +. +.P +wp site\-meta delete \fIid\fR \fIkey\fR +. +.P +wp site\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] +. +.P +wp site\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] +. +.SH "SUBCOMMANDS" +. +.TP +\fBadd\fR: +. +.IP +Add a meta field\. +. +.TP +\fBdelete\fR: +. +.IP +Delete a meta field\. +. +.TP +\fBget\fR: +. +.IP +Get meta field value\. +. +.TP +\fBupdate\fR: +. +.IP +Update a meta field\. +. +.SH "OPTIONS" +. +.TP +\fB<id>\fR: +. +.IP +The network id (usually 1)\. +. +.TP +\fB\-\-format=json\fR: +. +.IP +Encode/decode values as JSON\. +. +.SH "EXAMPLES" +. +.nf + +# get a list of super\-admins +wp site\-meta get 1 site_admins +. +.fi + diff --git a/php/commands/site-meta.php b/php/commands/site-meta.php index 9ca5c61bb2..b31ba358b6 100644 --- a/php/commands/site-meta.php +++ b/php/commands/site-meta.php @@ -1,7 +1,7 @@ <?php /** - * Manage site custom fields. + * Manage network custom fields. * * @package wp-cli */ From b672bc767c8439790910957a67bfdb95f6921437 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 13:02:50 +0300 Subject: [PATCH 1839/4858] rename `wp site-meta` to `wp network-meta` --- features/{site-meta.feature => network-meta.feature} | 8 ++++---- man-src/{site-meta.txt => network-meta.txt} | 0 man/{site-meta.1 => network-meta.1} | 12 ++++++------ php/commands/{site-meta.php => network-meta.php} | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) rename features/{site-meta.feature => network-meta.feature} (59%) rename man-src/{site-meta.txt => network-meta.txt} (100%) rename man/{site-meta.1 => network-meta.1} (61%) rename php/commands/{site-meta.php => network-meta.php} (51%) diff --git a/features/site-meta.feature b/features/network-meta.feature similarity index 59% rename from features/site-meta.feature rename to features/network-meta.feature index 8b1fa20351..dd6bf9c886 100644 --- a/features/site-meta.feature +++ b/features/network-meta.feature @@ -1,15 +1,15 @@ -Feature: Manage WordPress installation +Feature: Manage network-wide custom fields. Scenario: Non-multisite Given a WP install - When I try `wp site-meta` + When I try `wp network-meta` Then STDOUT should contain: """ - usage: wp site-meta + usage: wp network-meta """ - When I try `wp site-meta get 1 site_admins` + When I try `wp network-meta get 1 site_admins` Then STDOUT should be empty And STDERR should contain: """ diff --git a/man-src/site-meta.txt b/man-src/network-meta.txt similarity index 100% rename from man-src/site-meta.txt rename to man-src/network-meta.txt diff --git a/man/site-meta.1 b/man/network-meta.1 similarity index 61% rename from man/site-meta.1 rename to man/network-meta.1 index eaa72b0de0..fad87547db 100644 --- a/man/site-meta.1 +++ b/man/network-meta.1 @@ -1,22 +1,22 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-SITE\-META" "1" "" "WP-CLI" +.TH "WP\-NETWORK\-META" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-site\-meta\fR \- Manage network custom fields\. +\fBwp\-network\-meta\fR \- Manage network custom fields\. . .SH "SYNOPSIS" -wp site\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] +wp network\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .P -wp site\-meta delete \fIid\fR \fIkey\fR +wp network\-meta delete \fIid\fR \fIkey\fR . .P -wp site\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] +wp network\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] . .P -wp site\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] +wp network\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .SH "SUBCOMMANDS" . diff --git a/php/commands/site-meta.php b/php/commands/network-meta.php similarity index 51% rename from php/commands/site-meta.php rename to php/commands/network-meta.php index b31ba358b6..1d39a6e0c7 100644 --- a/php/commands/site-meta.php +++ b/php/commands/network-meta.php @@ -5,13 +5,13 @@ * * @package wp-cli */ -class Site_Meta_Command extends \WP_CLI\CommandWithMeta { +class Network_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'site'; } -WP_CLI::add_command( 'site-meta', 'Site_Meta_Command' ); +WP_CLI::add_command( 'network-meta', 'Network_Meta_Command' ); -WP_CLI::add_hook( 'before_invoke:site-meta', function () { +WP_CLI::add_hook( 'before_invoke:network-meta', function () { if ( !is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); } From 9fc38aa32737987e59e0eca1757ab0ab3d7c798a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 13:11:14 +0300 Subject: [PATCH 1840/4858] rename `wp blog` to `wp site` --- features/search-replace.feature | 2 +- features/{blog.feature => site.feature} | 29 +++++++------------- man-src/{blog-create.txt => site-create.txt} | 0 man-src/{blog-delete.txt => site-delete.txt} | 0 man-src/{blog-empty.txt => site-empty.txt} | 0 man/{blog-create.1 => site-create.1} | 6 ++-- man/{blog-delete.1 => site-delete.1} | 6 ++-- man/{blog-empty.1 => site-empty.1} | 6 ++-- php/commands/{blog.php => site.php} | 24 ++++++++-------- 9 files changed, 32 insertions(+), 41 deletions(-) rename features/{blog.feature => site.feature} (58%) rename man-src/{blog-create.txt => site-create.txt} (100%) rename man-src/{blog-delete.txt => site-delete.txt} (100%) rename man-src/{blog-empty.txt => site-empty.txt} (100%) rename man/{blog-create.1 => site-create.1} (84%) rename man/{blog-delete.1 => site-delete.1} (77%) rename man/{blog-empty.1 => site-empty.1} (56%) rename php/commands/{blog.php => site.php} (93%) diff --git a/features/search-replace.feature b/features/search-replace.feature index 07fa919f16..2031ceb142 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -17,7 +17,7 @@ Feature: Do global search/replace Scenario: Multisite search/replace Given a WP multisite install - And I run `wp blog create --slug="foo" --title="foo" --email="foo@example.com"` + And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` And I run `wp search-replace foo bar --network` Then STDOUT should be a table containing rows: | Table | Column | Replacements | diff --git a/features/blog.feature b/features/site.feature similarity index 58% rename from features/blog.feature rename to features/site.feature index 14712c4449..80a6c94ff7 100644 --- a/features/blog.feature +++ b/features/site.feature @@ -1,40 +1,31 @@ -Feature: Manage a WordPress installation +Feature: Manage sites in a multisite installation - Scenario: Install multisite - Given a WP install - - When I run `wp core install-network` - Then STDOUT should not be empty - - When I try the previous command again - Then the return code should be 1 - - Scenario: Delete a blog by id + Scenario: Delete a site by id Given a WP multisite install - When I run `wp blog create --slug=first --porcelain` + When I run `wp site create --slug=first --porcelain` Then STDOUT should match '%d' - And save STDOUT as {BLOG_ID} + And save STDOUT as {SITE_ID} - When I run `wp blog delete {BLOG_ID} --yes` + When I run `wp site delete {SITE_ID} --yes` Then STDOUT should not be empty When I try the previous command again Then the return code should be 1 - Scenario: Delete a blog by slug + Scenario: Delete a site by slug Given a WP multisite install - When I run `wp blog create --slug=first` + When I run `wp site create --slug=first` Then STDOUT should not be empty - When I run `wp blog delete --slug=first --yes` + When I run `wp site delete --slug=first --yes` Then STDOUT should not be empty When I try the previous command again Then the return code should be 1 - Scenario: Empty a blog + Scenario: Empty a site Given a WP install When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` @@ -43,7 +34,7 @@ Feature: Manage a WordPress installation When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term'` Then STDOUT should not be empty - When I run `wp blog empty --yes` + When I run `wp site empty --yes` Then STDOUT should not be empty When I run `wp post list --format=ids` diff --git a/man-src/blog-create.txt b/man-src/site-create.txt similarity index 100% rename from man-src/blog-create.txt rename to man-src/site-create.txt diff --git a/man-src/blog-delete.txt b/man-src/site-delete.txt similarity index 100% rename from man-src/blog-delete.txt rename to man-src/site-delete.txt diff --git a/man-src/blog-empty.txt b/man-src/site-empty.txt similarity index 100% rename from man-src/blog-empty.txt rename to man-src/site-empty.txt diff --git a/man/blog-create.1 b/man/site-create.1 similarity index 84% rename from man/blog-create.1 rename to man/site-create.1 index 022c1c88a1..a306643964 100644 --- a/man/blog-create.1 +++ b/man/site-create.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-CREATE" "1" "" "WP-CLI" +.TH "WP\-SITE\-CREATE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-blog\-create\fR \- Create a blog in a multisite install\. +\fBwp\-site\-create\fR \- Create a site in a multisite install\. . .SH "SYNOPSIS" -wp blog create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] [\-\-porcelain] +wp site create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] [\-\-porcelain] . .SH "OPTIONS" . diff --git a/man/blog-delete.1 b/man/site-delete.1 similarity index 77% rename from man/blog-delete.1 rename to man/site-delete.1 index d90ec3e166..d8f7f3bc3d 100644 --- a/man/blog-delete.1 +++ b/man/site-delete.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-DELETE" "1" "" "WP-CLI" +.TH "WP\-SITE\-DELETE" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-blog\-delete\fR \- Delete a blog in a multisite install\. +\fBwp\-site\-delete\fR \- Delete a site in a multisite install\. . .SH "SYNOPSIS" -wp blog delete [\fIblog\-id\fR] [\-\-slug=\fIslug\fR] [\-\-yes] [\-\-keep\-tables] +wp site delete [\fIsite\-id\fR] [\-\-slug=\fIslug\fR] [\-\-yes] [\-\-keep\-tables] . .SH "OPTIONS" . diff --git a/man/blog-empty.1 b/man/site-empty.1 similarity index 56% rename from man/blog-empty.1 rename to man/site-empty.1 index 34cf749fca..144391fba1 100644 --- a/man/blog-empty.1 +++ b/man/site-empty.1 @@ -1,13 +1,13 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "WP\-BLOG\-EMPTY" "1" "" "WP-CLI" +.TH "WP\-SITE\-EMPTY" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-blog\-empty\fR \- Empty a blog of its content\. +\fBwp\-site\-empty\fR \- Empty a site of its content\. . .SH "SYNOPSIS" -wp blog empty [\-\-yes] +wp site empty [\-\-yes] . .SH "EXAMPLES" . diff --git a/php/commands/blog.php b/php/commands/site.php similarity index 93% rename from php/commands/blog.php rename to php/commands/site.php index dfc91e1db5..fbe438c011 100644 --- a/php/commands/blog.php +++ b/php/commands/site.php @@ -5,7 +5,7 @@ * * @package wp-cli */ -class Blog_Command extends WP_CLI_Command { +class Site_Command extends WP_CLI_Command { /** * Delete comments. @@ -108,27 +108,27 @@ private function _insert_default_terms() { } /** - * Empty a blog of its content. + * Empty a site of its content. * * @subcommand empty * @synopsis [--yes] */ public function _empty( $args, $assoc_args ) { - WP_CLI::confirm( 'Are you sure you want to empty the blog at ' . site_url() . '?', $assoc_args ); + WP_CLI::confirm( 'Are you sure you want to empty the site at ' . site_url() . '?', $assoc_args ); $this->_empty_posts(); $this->_empty_comments(); $this->_empty_taxonomies(); $this->_insert_default_terms(); - WP_CLI::success( 'The blog at ' . site_url() . ' was emptied.' ); + WP_CLI::success( 'The site at ' . site_url() . ' was emptied.' ); } /** - * Delete a blog in a multisite install. + * Delete a site in a multisite install. * - * @synopsis [<blog-id>] [--slug=<slug>] [--yes] [--keep-tables] + * @synopsis [<site-id>] [--slug=<slug>] [--yes] [--keep-tables] */ function delete( $args, $assoc_args ) { if ( !is_multisite() ) { @@ -148,14 +148,14 @@ function delete( $args, $assoc_args ) { } if ( !$blog ) { - WP_CLI::error( "Blog not found." ); + WP_CLI::error( "Site not found." ); } - WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl blog?", $assoc_args ); + WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl site?", $assoc_args ); wpmu_delete_blog( $blog->blog_id, !isset( $assoc_args['keep-tables'] ) ); - WP_CLI::success( "The blog at $blog->siteurl was deleted." ); + WP_CLI::success( "The site at $blog->siteurl was deleted." ); } /** @@ -177,7 +177,7 @@ private function _get_site( $site_id ) { } /** - * Create a blog in a multisite install. + * Create a site in a multisite install. * * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--site_id=<site-id>] [--private] [--porcelain] */ @@ -276,9 +276,9 @@ public function create( $_, $assoc_args ) { if ( isset( $assoc_args['porcelain'] ) ) WP_CLI::line( $id ); else - WP_CLI::success( "Blog $id created: $url" ); + WP_CLI::success( "Site $id created: $url" ); } } -WP_CLI::add_command( 'blog', 'Blog_Command' ); +WP_CLI::add_command( 'site', 'Site_Command' ); From 8791bbef53fc83d05cf4e0038824939f1cdf3087 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 13:28:49 +0300 Subject: [PATCH 1841/4858] alias `wp blog` to `wp site` --- php/WP_CLI/Runner.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index f1100d4d27..76eef20624 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -155,15 +155,17 @@ public function get_wp_config_code() { // Transparently convert old syntaxes private static function back_compat_conversions( $args, $assoc_args ) { - // foo --help -> help foo - if ( isset( $assoc_args['help'] ) ) { - array_unshift( $args, 'help' ); - unset( $assoc_args['help'] ); - } - - // sql -> db - if ( count( $args ) > 0 && 'sql' == $args[0] ) { - $args[0] = 'db'; + $top_level_aliases = array( + 'sql' => 'db', + 'blog' => 'site' + ); + if ( count( $args ) > 0 ) { + foreach ( $top_level_aliases as $old => $new ) { + if ( $old == $args[0] ) { + $args[0] = $new; + break; + } + } } // {plugin|theme} update --all -> {plugin|theme} update-all @@ -179,6 +181,12 @@ private static function back_compat_conversions( $args, $assoc_args ) { list( $args[0], $args[1] ) = array( $args[1], $args[0] ); } + // foo --help -> help foo + if ( isset( $assoc_args['help'] ) ) { + array_unshift( $args, 'help' ); + unset( $assoc_args['help'] ); + } + // {post|user} list --ids -> {post|user} list --format=ids if ( count( $args ) > 1 && in_array( $args[0], array( 'post', 'user' ) ) && $args[1] == 'list' From 8a631204a88c6dfe2b88b9b62641fa78d622e4f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 13:47:15 +0300 Subject: [PATCH 1842/4858] behat: fix help --gen test --- features/help.feature | 4 ++-- man/option.1 | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/help.feature b/features/help.feature index b23b898da3..5b8b421fe1 100644 --- a/features/help.feature +++ b/features/help.feature @@ -43,10 +43,10 @@ Feature: Get help about WP-CLI commands @ronn Scenario: Generating help for multisite-only subcommands Given an empty directory - When I run `wp help --gen blog create` + When I run `wp help --gen site create` Then STDOUT should be: """ - generated blog-create.1 + generated site-create.1 """ @ronn diff --git a/man/option.1 b/man/option.1 index 904b88a2ab..69a8fb23b6 100644 --- a/man/option.1 +++ b/man/option.1 @@ -7,16 +7,16 @@ \fBwp\-option\fR \- Manage WordPress options\. . .SH "SYNOPSIS" -wp option get \fIkey\fR [\-\-format=\fIformat\fR] +wp option add \fIkey\fR [\-\-format=\fIformat\fR] . .P -wp option add \fIkey\fR [\-\-format=\fIformat\fR] +wp option delete \fIkey\fR . .P -wp option update \fIkey\fR [\-\-format=\fIformat\fR] +wp option get \fIkey\fR [\-\-format=\fIformat\fR] . .P -wp option delete \fIkey\fR +wp option update \fIkey\fR [\-\-format=\fIformat\fR] . .SH "SUBCOMMANDS" . From 093e6aeb6a864a9744519059d0a9511c540fa529 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 14:11:43 +0300 Subject: [PATCH 1843/4858] site create: rename --site_id= to --network_id= --- man-src/site-create.txt | 12 ++++++------ man/site-create.1 | 14 +++++++------- php/commands/site.php | 9 +++++---- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/man-src/site-create.txt b/man-src/site-create.txt index 1c7e6aea59..84c3df9856 100644 --- a/man-src/site-create.txt +++ b/man-src/site-create.txt @@ -2,24 +2,24 @@ * `--slug`=<slug>: - Path for the new blog. Subdomain on subdomain installs, directory on subdirectory installs. + Path for the new site. Subdomain on subdomain installs, directory on subdirectory installs. * `--title`=<title>: - Title of the new blog. Default: prettified slug. + Title of the new site. Default: prettified slug. * `--email`=<email>: Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included. -* `--site_id`=<site-id>: +* `--network_id`=<network-id>: - Site (network) to associate new blog with. Defaults to current site (typically 1). + Network to associate new site with. Defaults to current network (typically 1). * `--private`: - If set, the new blog will be non-public (not indexed) + If set, the new site will be non-public (not indexed) * `--porcelain`: - If set, only the blog id will be output on success. + If set, only the site id will be output on success. diff --git a/man/site-create.1 b/man/site-create.1 index a306643964..20675a3e6a 100644 --- a/man/site-create.1 +++ b/man/site-create.1 @@ -7,7 +7,7 @@ \fBwp\-site\-create\fR \- Create a site in a multisite install\. . .SH "SYNOPSIS" -wp site create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-site_id=\fIsite\-id\fR] [\-\-private] [\-\-porcelain] +wp site create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-network_id=\fInetwork\-id\fR] [\-\-private] [\-\-porcelain] . .SH "OPTIONS" . @@ -15,13 +15,13 @@ wp site create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\f \fB\-\-slug\fR=\fIslug\fR: . .IP -Path for the new blog\. Subdomain on subdomain installs, directory on subdirectory installs\. +Path for the new site\. Subdomain on subdomain installs, directory on subdirectory installs\. . .TP \fB\-\-title\fR=<title>: . .IP -Title of the new blog\. Default: prettified slug\. +Title of the new site\. Default: prettified slug\. . .TP \fB\-\-email\fR=\fIemail\fR: @@ -30,20 +30,20 @@ Title of the new blog\. Default: prettified slug\. Email for Admin user\. User will be created if none exists\. Assignement to Super Admin if not included\. . .TP -\fB\-\-site_id\fR=\fIsite\-id\fR: +\fB\-\-network_id\fR=\fInetwork\-id\fR: . .IP -Site (network) to associate new blog with\. Defaults to current site (typically 1)\. +Network to associate new site with\. Defaults to current network (typically 1)\. . .TP \fB\-\-private\fR: . .IP -If set, the new blog will be non\-public (not indexed) +If set, the new site will be non\-public (not indexed) . .TP \fB\-\-porcelain\fR: . .IP -If set, only the blog id will be output on success\. +If set, only the site id will be output on success\. diff --git a/php/commands/site.php b/php/commands/site.php index fbe438c011..5f548284c6 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -179,7 +179,7 @@ private function _get_site( $site_id ) { /** * Create a site in a multisite install. * - * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--site_id=<site-id>] [--private] [--porcelain] + * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--network_id=<network-id>] [--private] [--porcelain] */ public function create( $_, $assoc_args ) { if ( !is_multisite() ) { @@ -192,11 +192,12 @@ public function create( $_, $assoc_args ) { $title = isset( $assoc_args['title'] ) ? $assoc_args['title'] : ucfirst( $base ); $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; + // Site - if ( !empty( $assoc_args['site_id'] ) ) { - $site = $this->_get_site( $assoc_args['site_id'] ); + if ( !empty( $assoc_args['network_id'] ) ) { + $site = $this->_get_site( $assoc_args['network_id'] ); if ( $site === false ) { - WP_CLI::error( 'Site with id '.$assoc_args['site_id'].' does not exist' ); + WP_CLI::error( sprintf( 'Network with id %d does not exist.', $assoc_args['network_id'] ) ); } } else { From 639d9d97f488d85598e216d7b882a9e7b8e11560 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 14:24:06 +0300 Subject: [PATCH 1844/4858] site create: alias --site_id= to --network_id= --- php/WP_CLI/Runner.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 76eef20624..b72f47706e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -168,6 +168,12 @@ private static function back_compat_conversions( $args, $assoc_args ) { } } + // site --site_id= -> site --network_id= + if ( count( $args ) > 0 && 'site' == $args[0] && isset( $assoc_args['site_id'] ) ) { + $assoc_args['network_id'] = $assoc_args['site_id']; + unset( $assoc_args['site_id'] ); + } + // {plugin|theme} update --all -> {plugin|theme} update-all if ( count( $args ) > 1 && in_array( $args[0], array( 'plugin', 'theme' ) ) && $args[1] == 'update' && isset( $assoc_args['all'] ) From fd3bdfd4ee23c866779aa4f4a4cd24851acc97b0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 8 Jun 2013 15:19:13 -0700 Subject: [PATCH 1845/4858] A basic test for converting an install to multisite. --- features/core.feature | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/features/core.feature b/features/core.feature index 29478558d6..0390c7db01 100644 --- a/features/core.feature +++ b/features/core.feature @@ -100,6 +100,24 @@ Feature: Manage WordPress installation """ When I run `wp eval 'var_export( function_exists( 'media_handle_upload' ) );'` + Then STDOUT should be: + """ + true + """ + + Scenario: Convert install to multisite + Given a WP install + + When I run `wp eval 'var_export( is_multisite() );'` + Then STDOUT should be: + """ + false + """ + + When I run `wp core install-network --title='test network'` + Then STDOUT should not be empty + + When I run `wp eval 'var_export( is_multisite() );'` Then STDOUT should be: """ true From 757b9eea6d395c482bc4eb772f7a6654a0aec296 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Jun 2013 18:36:15 +0300 Subject: [PATCH 1846/4858] behat: try running the install-network command again --- features/core.feature | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/core.feature b/features/core.feature index 0390c7db01..592ba49153 100644 --- a/features/core.feature +++ b/features/core.feature @@ -123,6 +123,9 @@ Feature: Manage WordPress installation true """ + When I try `wp core install-network --title='test network'` + Then the return code should be 1 + Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory From 421766b557eda056f7d243f47ba6df7308d5524f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 18:26:09 +0300 Subject: [PATCH 1847/4858] rename _hook() to _action() --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/class-wp-cli.php | 4 ++-- php/commands/network-meta.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 5ce7058c80..55d27f925e 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -60,7 +60,7 @@ private function validate_args( $args, &$assoc_args ) { function invoke( $args, $assoc_args ) { $this->validate_args( $args, $assoc_args ); - \WP_CLI::do_hook( 'before_invoke:' . $this->get_parent()->get_name() ); + \WP_CLI::do_action( 'before_invoke:' . $this->get_parent()->get_name() ); call_user_func( $this->when_invoked, $args, $assoc_args ); } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 4bccc21014..8c73a401b4 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -48,7 +48,7 @@ static function colorize( $string ) { /** * Schedule a callback to be executed at a certain point (before WP is loaded). */ - static function add_hook( $when, $callback ) { + static function add_action( $when, $callback ) { if ( in_array( $when, self::$hooks_passed ) ) call_user_func( $callback ); @@ -58,7 +58,7 @@ static function add_hook( $when, $callback ) { /** * Execute registered callbacks. */ - static function do_hook( $when ) { + static function do_action( $when ) { self::$hooks_passed[] = $when; if ( !isset( self::$hooks[ $when ] ) ) diff --git a/php/commands/network-meta.php b/php/commands/network-meta.php index 1d39a6e0c7..88b43759ac 100644 --- a/php/commands/network-meta.php +++ b/php/commands/network-meta.php @@ -11,7 +11,7 @@ class Network_Meta_Command extends \WP_CLI\CommandWithMeta { WP_CLI::add_command( 'network-meta', 'Network_Meta_Command' ); -WP_CLI::add_hook( 'before_invoke:network-meta', function () { +WP_CLI::add_action( 'before_invoke:network-meta', function () { if ( !is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); } From 6c73830c0b21a35ae3c154484338a27bdda8c4e7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 15 Jun 2013 18:50:14 +0300 Subject: [PATCH 1848/4858] help: move duplicated function_exists() check to __invoke() --- php/commands/help.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index d2b8691e3f..b85f070235 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -15,6 +15,11 @@ function __invoke( $args, $assoc_args ) { $this->generate( $args ); else $this->show( $args ); + + // WordPress is already loaded, so there's no chance we'll find the command + if ( function_exists( 'add_filter' ) ) { + \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); + } } private static function find_subcommand( $args ) { @@ -38,11 +43,6 @@ private function show( $args ) { $command->show_usage(); exit; } - - // WordPress is already loaded, so there's no chance we'll find the command - if ( function_exists( 'add_filter' ) ) { - \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); - } } private function generate( $args ) { @@ -50,8 +50,6 @@ private function generate( $args ) { WP_CLI::error( '`ronn` executable not found.' ); } - $arg_copy = $args; - $command = self::find_subcommand( $args ); if ( $command ) { @@ -60,11 +58,6 @@ private function generate( $args ) { } exit; } - - // WordPress is already loaded, so there's no chance we'll find the command - if ( function_exists( 'add_filter' ) ) { - WP_CLI::error( sprintf( "'%s' command not found.", implode( ' ', $arg_copy ) ) ); - } } private static function maybe_show_manpage( $args ) { From 4bfb75fd8adb864b2a329fff024987b98631e3dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 19:54:42 +0300 Subject: [PATCH 1849/4858] introduce WP_CLI::log() WP_CLI::line() is for spitting something to STDOUT. WP_CLI::log() is for sending a message to the logger, which could do various things with it. closes #465 --- php/WP_CLI/Loggers/Quiet.php | 4 ++++ php/WP_CLI/Loggers/Regular.php | 4 ++++ php/class-wp-cli.php | 9 +++++++++ 3 files changed, 17 insertions(+) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 14b929566c..926986c5e3 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -4,6 +4,10 @@ class Quiet { + function info( $message ) { + // nothing + } + function success( $message, $label ) { // nothing } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index 6cd2db0ba1..b33a7f84b9 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -8,6 +8,10 @@ private function _line( $message, $handle = STDOUT ) { fwrite( $handle, \WP_CLI::colorize( $message . "\n" ) ); } + function info( $message ) { + fwrite( STDOUT, $message . "\n" ); + } + function success( $message, $label ) { $this->_line( "%G$label:%n $message" ); } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 8c73a401b4..e78de8c14c 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -158,6 +158,15 @@ static function line( $message = '' ) { echo $message . "\n"; } + /** + * Log an informational message. + * + * @param string $message + */ + static function log( $message ) { + self::$logger->info( $message ); + } + /** * Display a success in the CLI and end with a newline * From 52943dfa68d7661505fbe9207f6b83ca9bb8ad4e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 20:22:00 +0300 Subject: [PATCH 1850/4858] convert from WP_CLI::line() to WP_CLI::log() where appropriate --- php/WP_CLI/CommandWithUpgrade.php | 4 ++-- php/commands/core.php | 10 +++++----- php/commands/help.php | 2 +- php/commands/media.php | 6 +++--- php/commands/plugin.php | 4 ++-- php/commands/theme.php | 6 +++--- php/commands/user.php | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 52c261cd46..c8da9c3a4e 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -37,7 +37,7 @@ private function status_all() { $n = count( $items ); // Not interested in the translation, just the number logic - \WP_CLI::line( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); + \WP_CLI::log( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); $padding = $this->get_padding($items); @@ -108,7 +108,7 @@ function install( $args, $assoc_args ) { $slug = $file_upgrader->result['destination_name']; if ( isset( $assoc_args['activate'] ) ) { - \WP_CLI::line( "Activating '$slug'..." ); + \WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } } else { diff --git a/php/commands/core.php b/php/commands/core.php index 99c52fec15..125e3db2ef 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -19,21 +19,21 @@ public function download( $args, $assoc_args ) { WP_CLI::error( 'WordPress files seem to already be present here.' ); if ( !is_dir( ABSPATH ) ) { - WP_CLI::line( sprintf( 'Creating directory %s', ABSPATH ) ); + WP_CLI::log( sprintf( 'Creating directory %s', ABSPATH ) ); WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); } if ( isset( $assoc_args['locale'] ) ) { $offer = $this->get_download_offer( $assoc_args['locale'] ); $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); - WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $offer['current'], $offer['locale'] ) ); } elseif ( isset( $assoc_args['version'] ) ) { $download_url = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; - WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { $download_url = 'https://wordpress.org/latest.tar.gz'; - WP_CLI::line( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); + WP_CLI::log( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } $silent = WP_CLI::get_config('quiet') ? '--silent ' : ''; @@ -279,7 +279,7 @@ function update( $args, $assoc_args ) { if ( empty( $args[0] ) ) { $new_package = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; - WP_CLI::line( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { $new_package = $args[0]; $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; diff --git a/php/commands/help.php b/php/commands/help.php index b85f070235..ef8b24bef8 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -171,7 +171,7 @@ private static function call_ronn( $markdown, $dest ) { $roff = str_replace( ' "January 2012"', '', $roff ); file_put_contents( $dest, $roff ); - \WP_CLI::line( "generated " . basename( $dest ) ); + \WP_CLI::log( "generated " . basename( $dest ) ); } private static function get_file_name( $args ) { diff --git a/php/commands/media.php b/php/commands/media.php index 64e954018a..b35db1ef88 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -39,7 +39,7 @@ function regenerate( $args, $assoc_args = array() ) { } $count = $images->post_count; - WP_CLI::line( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); + WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); $not_found = array_diff( $args, $images->posts ); if( !empty($not_found) ) { @@ -162,7 +162,7 @@ private function _process_regeneration( $id ) { return; } - WP_CLI::line( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); + WP_CLI::log( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); $this->remove_old_images( $image->ID ); @@ -198,7 +198,7 @@ private function remove_old_images( $att_id ) { continue; if ( unlink( $intermediate_path ) ) { - WP_CLI::line( sprintf( "Thumbnail %s x %s was deleted.", + WP_CLI::log( sprintf( "Thumbnail %s x %s was deleted.", $size_info['width'], $size_info['height'] ) ); } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 1aee7a29c3..c96d85465c 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -161,7 +161,7 @@ protected function install_from_repo( $slug, $assoc_args ) { $status = install_plugin_install_status( $api ); - WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); switch ( $status['status'] ) { case 'update_available': @@ -170,7 +170,7 @@ protected function install_from_repo( $slug, $assoc_args ) { $result = $upgrader->install( $api->download_link ); if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::line( "Activating '$slug'..." ); + WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index 0a9602b824..c2047cd998 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -115,7 +115,7 @@ protected function install_from_repo( $slug, $assoc_args ) { // Check to see if we should update, rather than install. if ( $this->has_update( $slug ) ) { - WP_CLI::line( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); + WP_CLI::log( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $slug ); /** @@ -123,7 +123,7 @@ protected function install_from_repo( $slug, $assoc_args ) { * or it's newer than what we've got. */ } else if ( !wp_get_theme( $slug )->exists() ) { - WP_CLI::line( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); } else { WP_CLI::error( 'Theme already installed and up to date.' ); @@ -131,7 +131,7 @@ protected function install_from_repo( $slug, $assoc_args ) { // Finally, activate theme if requested. if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::line( "Activating '$slug'..." ); + WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } } diff --git a/php/commands/user.php b/php/commands/user.php index 23b68f3733..4c1a85795b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -324,7 +324,7 @@ public function import_csv( $args, $assoc_args ) { if ( !in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) && $new_user['role'] ) { add_user_to_blog( get_current_blog_id(), $existing_user->ID, $new_user['role'] ); - WP_CLI::line( "{$existing_user->user_login} added to blog as {$new_user['role']}" ); + WP_CLI::log( "{$existing_user->user_login} added to blog as {$new_user['role']}" ); } // Create the user From 614da25404ce45a77e12c4d8897239fc25c69556 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 20:28:29 +0300 Subject: [PATCH 1851/4858] remove redundant arg check in Theme_Command::parse_name() it's already handled by the synopsis parser --- php/commands/theme.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index c2047cd998..681d273bef 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -217,11 +217,6 @@ function _list( $_, $assoc_args ) { } protected function parse_name( $args ) { - if ( empty( $args ) ) { - WP_CLI::line( "usage: wp theme $subcommand <theme-name>" ); - exit; - } - $name = $args[0]; $theme = wp_get_theme( $name ); From 21fb2961e224f56a83689e674a0a96ca24d01c7c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 17 Jun 2013 03:17:02 +0300 Subject: [PATCH 1852/4858] move command instance creation to a separate class Keep the disabled_commands logic inside the WP_CLI class; show an explicit error, instead of pretending the command doesn't exist. --- features/config.feature | 13 ++++ php/WP_CLI/Dispatcher/CommandFactory.php | 64 +++++++++++++++++++ php/class-wp-cli.php | 80 +++++------------------- 3 files changed, 92 insertions(+), 65 deletions(-) create mode 100644 php/WP_CLI/Dispatcher/CommandFactory.php diff --git a/features/config.feature b/features/config.feature index 339319c953..83813588b4 100644 --- a/features/config.feature +++ b/features/config.feature @@ -59,3 +59,16 @@ Feature: Have a config file wp-cli.yml """ + Scenario: Disabled subcommands + Given a WP install + And a wp-cli.yml file: + """ + disabled_commands: + - db drop + """ + + When I try `wp db drop --yes` + Then STDERR should contain: + """ + command has been disabled + """ diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php new file mode 100644 index 0000000000..72eb104f34 --- /dev/null +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -0,0 +1,64 @@ +<?php + +namespace WP_CLI\Dispatcher; + +/** + * Creates CompositeCommand or Subcommand instances. + */ +class CommandFactory { + + public static function create( $name, $class, $parent ) { + $reflection = new \ReflectionClass( $class ); + + if ( $reflection->hasMethod( '__invoke' ) ) { + $command = self::create_subcommand( $parent, $name, $reflection->name, + $reflection->getMethod( '__invoke' ) ); + } else { + $command = self::create_composite_command( $parent, $name, $reflection ); + } + + return $command; + } + + private static function create_subcommand( $parent, $name, $class_name, $method ) { + $docparser = new \WP_CLI\DocParser( $method ); + + if ( !$name ) + $name = $docparser->get_tag( 'subcommand' ); + + if ( !$name ) + $name = $method->name; + + $method_name = $method->name; + + $when_invoked = function ( $args, $assoc_args ) use ( $class_name, $method_name ) { + call_user_func( array( new $class_name, $method_name ), $args, $assoc_args ); + }; + + return new Subcommand( $parent, $name, $docparser, $when_invoked ); + } + + private static function create_composite_command( $parent, $name, $reflection ) { + $docparser = new \WP_CLI\DocParser( $reflection ); + + $container = new CompositeCommand( $parent, $name, $docparser ); + + foreach ( $reflection->getMethods() as $method ) { + if ( !self::is_good_method( $method ) ) + continue; + + $subcommand = self::create_subcommand( $container, false, $reflection->name, $method ); + + $subcommand_name = $subcommand->get_name(); + + $container->add_subcommand( $subcommand_name, $subcommand ); + } + + return $container; + } + + private static function is_good_method( $method ) { + return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); + } +} + diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e78de8c14c..47d5db6bfd 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -74,73 +74,11 @@ static function do_action( $when ) { * @param string $class The command implementation */ static function add_command( $name, $class ) { - if ( in_array( $name, self::get_config('disabled_commands') ) ) - return; - - $reflection = new \ReflectionClass( $class ); - - if ( $reflection->hasMethod( '__invoke' ) ) { - $command = self::create_subcommand( self::$root, $name, $reflection->name, - $reflection->getMethod( '__invoke' ) ); - } else { - $command = self::create_composite_command( $name, $reflection ); - } + $command = Dispatcher\CommandFactory::create( $name, $class, self::$root ); self::$root->add_subcommand( $name, $command ); } - private static function create_subcommand( $parent, $name, $class_name, $method ) { - $docparser = new \WP_CLI\DocParser( $method ); - - if ( !$name ) - $name = $docparser->get_tag( 'subcommand' ); - - if ( !$name ) - $name = $method->name; - - $method_name = $method->name; - - $when_invoked = function ( $args, $assoc_args ) use ( $class_name, $method_name ) { - call_user_func( array( new $class_name, $method_name ), $args, $assoc_args ); - }; - - return new Dispatcher\Subcommand( $parent, $name, $docparser, $when_invoked ); - } - - private static function create_composite_command( $name, $reflection ) { - $docparser = new \WP_CLI\DocParser( $reflection ); - - $container = new Dispatcher\CompositeCommand( self::$root, $name, $docparser ); - - foreach ( $reflection->getMethods() as $method ) { - if ( !self::_is_good_method( $method ) ) - continue; - - $subcommand = self::create_subcommand( $container, false, $reflection->name, $method ); - - $subcommand_name = $subcommand->get_name(); - $full_name = self::get_full_name( $subcommand ); - - if ( in_array( $full_name, self::get_config('disabled_commands') ) ) - continue; - - $container->add_subcommand( $subcommand_name, $subcommand ); - } - - return $container; - } - - private static function get_full_name( $command ) { - $path = Dispatcher\get_path( $command ); - array_shift( $path ); - - return implode( ' ', $path ); - } - - private static function _is_good_method( $method ) { - return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); - } - static function add_man_dir( $dest_dir, $src_dir ) { self::$man_dirs[ $dest_dir ] = $src_dir; } @@ -304,14 +242,26 @@ private static function find_command_to_run( $args ) { $cmd_path = array(); + $disabled_commands = self::get_config('disabled_commands'); + while ( !empty( $args ) && $command->has_subcommands() ) { $cmd_path[] = $args[0]; + $full_name = implode( ' ', $cmd_path ); $subcommand = $command->find_subcommand( $args ); if ( !$subcommand ) { - \WP_CLI::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", - implode( ' ', $cmd_path ) ) ); + \WP_CLI::error( sprintf( + "'%s' is not a registered wp command. See 'wp help'.", + $full_name + ) ); + } + + if ( in_array( $full_name, $disabled_commands ) ) { + \WP_CLI::error( sprintf( + "The '%s' command has been disabled from the config file.", + $full_name + ) ); } $command = $subcommand; From 3f9c545e40367ee7d5afb3a86ff4171547b1fb37 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 17 Jun 2013 04:37:53 +0300 Subject: [PATCH 1853/4858] move setting $_SERVER['DOCUMENT_ROOT'] to set_wp_root() method It was first defined in 390e7dbbabee7398527c3a1552e849f5c87053aa and then sort of drifted away from where paths are handled. --- php/WP_CLI/Runner.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b72f47706e..596176f241 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -55,6 +55,8 @@ private static function set_wp_root( $config ) { } define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); + + $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); } private static function set_user( $assoc_args ) { @@ -285,8 +287,6 @@ public function before_wp_load() { } } - $_SERVER['DOCUMENT_ROOT'] = realpath( $this->config['path'] ); - if ( $this->cmd_starts_with( array( '_sys' ) ) ) { $this->_run_command(); exit; From a88bf1c8ea6100d6c02f23f9d1769747455b7ce0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 17 Jun 2013 04:21:58 +0300 Subject: [PATCH 1854/4858] implement '@when' docblock tag Works on both commands and subcommands. --- php/WP_CLI/Dispatcher/CompositeCommand.php | 5 ++++ php/WP_CLI/DocParser.php | 2 +- php/WP_CLI/Runner.php | 32 ++++++++++++++++------ php/commands/_sys.php | 3 ++ php/commands/core.php | 2 ++ 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 4b4ad4e0ba..14179199cd 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -18,6 +18,11 @@ public function __construct( $parent, $name, $docparser ) { $this->shortdesc = $docparser->get_shortdesc(); $this->synopsis = $docparser->get_synopsis(); + + $when_to_invoke = $docparser->get_tag( 'when' ); + if ( $when_to_invoke ) { + \WP_CLI::$runner->register_early_invoke( $when_to_invoke, $this ); + } } function get_parent() { diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index cb891d19d5..4d597a6313 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -18,7 +18,7 @@ function get_shortdesc() { } function get_tag( $name ) { - if ( preg_match( '/@' . $name . '\s+([a-z-]+)/', $this->docComment, $matches ) ) + if ( preg_match( '/@' . $name . '\s+([a-z-_]+)/', $this->docComment, $matches ) ) return $matches[1]; return false; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 596176f241..f4dc78b2f4 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -12,10 +12,32 @@ class Runner { private $arguments, $assoc_args; + private $_early_invoke = array(); + public function __get( $key ) { + if ( '_' === $key[0] ) + return null; + return $this->$key; } + public function register_early_invoke( $when, $command ) { + $this->_early_invoke[ $when ][] = $command; + } + + private function do_early_invoke( $when ) { + if ( !isset( $this->_early_invoke[ $when ] ) ) + return; + + foreach ( $this->_early_invoke[ $when ] as $command ) { + $path = array_slice( Dispatcher\get_path( $command ), 1 ); + if ( $this->cmd_starts_with( $path ) ) { + $this->_run_command(); + exit; + } + } + } + private static function get_config_path( $runtime_config ) { if ( isset( $runtime_config['config'] ) && file_exists( $runtime_config['config'] ) ) { return $runtime_config['config']; @@ -287,11 +309,6 @@ public function before_wp_load() { } } - if ( $this->cmd_starts_with( array( '_sys' ) ) ) { - $this->_run_command(); - exit; - } - // First try at showing man page if ( $this->cmd_starts_with( array( 'help' ) ) ) { $this->_run_command(); @@ -303,10 +320,7 @@ public function before_wp_load() { // Handle --url and --blog parameters self::set_url( $this->config ); - if ( array( 'core', 'download' ) == $this->arguments ) { - $this->_run_command(); - exit; - } + $this->do_early_invoke( 'before_wp_load' ); if ( !is_readable( ABSPATH . 'wp-load.php' ) ) { WP_CLI::error( diff --git a/php/commands/_sys.php b/php/commands/_sys.php index 82a7107aa8..fefbc22316 100644 --- a/php/commands/_sys.php +++ b/php/commands/_sys.php @@ -3,6 +3,9 @@ use \WP_CLI\Dispatcher, \WP_CLI\Utils; +/** + * @when before_wp_load + */ class Sys_Command extends WP_CLI_Command { private function command_to_array( $command ) { diff --git a/php/commands/core.php b/php/commands/core.php index 125e3db2ef..6feb6bc5c3 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -13,6 +13,8 @@ class Core_Command extends WP_CLI_Command { * Download core WordPress files. * * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] [--force] + * + * @when before_wp_load */ public function download( $args, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && is_readable( ABSPATH . 'wp-load.php' ) ) From 73374561c1e09750690a2e22f771cfd7f6badd8b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 17 Jun 2013 05:04:38 +0300 Subject: [PATCH 1855/4858] calculate path for early commands only once --- php/WP_CLI/Runner.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index f4dc78b2f4..d484558651 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -22,15 +22,14 @@ public function __get( $key ) { } public function register_early_invoke( $when, $command ) { - $this->_early_invoke[ $when ][] = $command; + $this->_early_invoke[ $when ][] = array_slice( Dispatcher\get_path( $command ), 1 ); } private function do_early_invoke( $when ) { if ( !isset( $this->_early_invoke[ $when ] ) ) return; - foreach ( $this->_early_invoke[ $when ] as $command ) { - $path = array_slice( Dispatcher\get_path( $command ), 1 ); + foreach ( $this->_early_invoke[ $when ] as $path ) { if ( $this->cmd_starts_with( $path ) ) { $this->_run_command(); exit; From 16fd5dd8a739eba58a54b6ac8d13ea24b64a44de Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 18 Jun 2013 01:28:56 +0300 Subject: [PATCH 1856/4858] fix network-meta man page. see #529 --- man-src/network-meta.txt | 2 +- man/network-meta.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/network-meta.txt b/man-src/network-meta.txt index e921abce76..c1899f2d47 100644 --- a/man-src/network-meta.txt +++ b/man-src/network-meta.txt @@ -11,4 +11,4 @@ ## EXAMPLES # get a list of super-admins - wp site-meta get 1 site_admins + wp network-meta get 1 site_admins diff --git a/man/network-meta.1 b/man/network-meta.1 index fad87547db..0beb7eb4a8 100644 --- a/man/network-meta.1 +++ b/man/network-meta.1 @@ -63,7 +63,7 @@ Encode/decode values as JSON\. .nf # get a list of super\-admins -wp site\-meta get 1 site_admins +wp network\-meta get 1 site_admins . .fi From 56bc7ce75e335ac63fb1da484cccd6a35a4e8189 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 19 Jun 2013 20:47:33 +0300 Subject: [PATCH 1857/4858] show error on invalid json. closes #531 --- php/class-wp-cli.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 47d5db6bfd..3cb5133c46 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -159,9 +159,14 @@ static function confirm( $question, $assoc_args ) { * @param mixed $value * @param array $assoc_args */ - static function read_value( $value, $assoc_args = array() ) { + static function read_value( $raw_value, $assoc_args = array() ) { if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { - $value = json_decode( $value, true ); + $value = json_decode( $raw_value, true ); + if ( null === $value ) { + WP_CLI::error( sprintf( 'Invalid JSON: %s', $raw_value ) ); + } + } else { + $value = $raw_value; } return $value; From 6f3b77c7938044fc491d318608e17ad431fc3056 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 20 Jun 2013 04:27:56 +0300 Subject: [PATCH 1858/4858] add optional 'before_invoke' parameter to WP_CLI::add_command() this avoids repeating the command name and makes it clearer when the callback is fired --- php/class-wp-cli.php | 8 +++++++- php/commands/network-meta.php | 12 ++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 3cb5133c46..bac6d34680 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -72,10 +72,16 @@ static function do_action( $when ) { * * @param string $name The name of the command that will be used in the cli * @param string $class The command implementation + * @param array $args An associative array with additional parameters: + * 'before_invoke' => callback to execute before invoking the command */ - static function add_command( $name, $class ) { + static function add_command( $name, $class, $args = array() ) { $command = Dispatcher\CommandFactory::create( $name, $class, self::$root ); + if ( isset( $args['before_invoke'] ) ) { + self::add_action( "before_invoke:$name", $args['before_invoke'] ); + } + self::$root->add_subcommand( $name, $command ); } diff --git a/php/commands/network-meta.php b/php/commands/network-meta.php index 88b43759ac..c7a603a903 100644 --- a/php/commands/network-meta.php +++ b/php/commands/network-meta.php @@ -9,11 +9,11 @@ class Network_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'site'; } -WP_CLI::add_command( 'network-meta', 'Network_Meta_Command' ); - -WP_CLI::add_action( 'before_invoke:network-meta', function () { - if ( !is_multisite() ) { - WP_CLI::error( 'This is not a multisite install.' ); +WP_CLI::add_command( 'network-meta', 'Network_Meta_Command', array( + 'before_invoke' => function () { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } } -} ); +) ); From 195ad148e753ce2e856ed1b4aeae2c601a1405a9 Mon Sep 17 00:00:00 2001 From: Mitesh Shah <Mitesh.Shah@rtCamp.com> Date: Thu, 20 Jun 2013 15:05:30 +0530 Subject: [PATCH 1859/4858] Support Subdomains --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 6feb6bc5c3..ea82af3baf 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -158,7 +158,7 @@ public function install( $args, $assoc_args ) { * Transform a single-site install into a multi-site install. * * @subcommand install-network - * @synopsis --title=<network-title> [--base=<url-path>] + * @synopsis --title=<network-title> [--base=<url-path>] [--subdomains=<TRUE>] */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) From ec59bac9036b2182c5a2f7e05c98da9843dbc40b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 20 Jun 2013 12:44:28 +0300 Subject: [PATCH 1860/4858] core install-network: flags don't need a value; update man page see #532 --- man-src/core-install-network.txt | 4 ++++ man/core-install-network.1 | 8 +++++++- php/commands/core.php | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/man-src/core-install-network.txt b/man-src/core-install-network.txt index 26e2c2a955..24494f1170 100644 --- a/man-src/core-install-network.txt +++ b/man-src/core-install-network.txt @@ -8,3 +8,7 @@ Base path after the domain name that each site url will start with. Default: '/' + +* `--subdomains`: + + If passed, the network will use subdomains, instead of subdirectories. diff --git a/man/core-install-network.1 b/man/core-install-network.1 index f7f4f84a8c..60fdbfc0e7 100644 --- a/man/core-install-network.1 +++ b/man/core-install-network.1 @@ -7,7 +7,7 @@ \fBwp\-core\-install\-network\fR \- Transform a single\-site install into a multi\-site install\. . .SH "SYNOPSIS" -wp core install\-network \-\-title=\fInetwork\-title\fR [\-\-base=\fIurl\-path\fR] +wp core install\-network \-\-title=\fInetwork\-title\fR [\-\-base=\fIurl\-path\fR] [\-\-subdomains] . .SH "OPTIONS" . @@ -22,4 +22,10 @@ The title of the new network\. . .IP Base path after the domain name that each site url will start with\. Default: \'/\' +. +.TP +\fB\-\-subdomains\fR: +. +.IP +If passed, the network will use subdomains, instead of subdirectories\. diff --git a/php/commands/core.php b/php/commands/core.php index ea82af3baf..9f450ce5bb 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -158,7 +158,7 @@ public function install( $args, $assoc_args ) { * Transform a single-site install into a multi-site install. * * @subcommand install-network - * @synopsis --title=<network-title> [--base=<url-path>] [--subdomains=<TRUE>] + * @synopsis --title=<network-title> [--base=<url-path>] [--subdomains] */ public function install_network( $args, $assoc_args ) { if ( is_multisite() ) From 404a035fb0cb834337bc08f691afd530cf6cf0a5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 20 Jun 2013 19:04:20 +0300 Subject: [PATCH 1861/4858] search-replace: always do a SHOW TABLES query --- php/commands/search-replace.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 2a0f3309e9..1eee976567 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -67,13 +67,9 @@ private static function get_table_list( $args, $network ) { if ( !empty( $args ) ) return $args; - if ( !$network ) { - $tables = $wpdb->tables( 'blog' ); - } else { - $tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->base_prefix}%'" ); - } + $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; - return $tables; + return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { From 3931aea9fc6ff3c5189c629c9e085555a7a38b98 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 20 Jun 2013 21:30:07 +0300 Subject: [PATCH 1862/4858] option update: show success message even if the value has not changed see #531 --- features/option.feature | 3 +++ php/commands/option.php | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/features/option.feature b/features/option.feature index 707c4fe82e..66c8d78e2e 100644 --- a/features/option.feature +++ b/features/option.feature @@ -15,6 +15,9 @@ Feature: Manage WordPress options When I run `wp option set foo '[ 1, 2 ]' --format=json` Then STDOUT should not be empty + When I run the previous command again + Then STDOUT should not be empty + When I run `wp option get foo --format=json` Then STDOUT should be: """ diff --git a/php/commands/option.php b/php/commands/option.php index fb39ce7b59..f3f83404c3 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -51,10 +51,10 @@ public function update( $args, $assoc_args ) { $value = WP_CLI::read_value( $args[1], $assoc_args ); - if ( $value === get_option( $key ) ) - return; + $result = update_option( $key, $value ); - if ( !update_option( $key, $value ) ) { + // update_option() returns false if the value is the same + if ( !$result && $value !== get_option( $key ) ) { WP_CLI::error( "Could not update option '$key'." ); } else { WP_CLI::success( "Updated '$key' option." ); From 80cc692d2ab8576233e675ed1e049f39f3c0a871 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 20 Jun 2013 22:38:06 +0300 Subject: [PATCH 1863/4858] post create: balance brackets --- php/commands/post.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index e1e2da842f..438f86ac1a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -24,13 +24,14 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { - if ( $args[0] !== '-' ) { $readfile = $args[0]; - if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) + if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) { \WP_CLI::error( "Unable to read content from $readfile." ); - } else + } + } else { $readfile = 'php://stdin'; + } $assoc_args['post_content'] = file_get_contents( $readfile ); } From b28a4a47ee94813f3a8816ee866f285cbad17604 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 20 Jun 2013 22:44:34 +0300 Subject: [PATCH 1864/4858] behat: add test for `post create` reading content from STDIN --- features/post.feature | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/features/post.feature b/features/post.feature index 035be2982c..f8de28f0ce 100644 --- a/features/post.feature +++ b/features/post.feature @@ -27,15 +27,23 @@ Feature: Manage WordPress posts Scenario: Creating/getting posts Given a WP install + And a content.html file: + """ + This is some content. + + It will be inserted in a post. + """ - When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` + When I run `wp post create --post_title='Test post' --porcelain - < content.html` Then STDOUT should match '%d' And save STDOUT as {POST_ID} When I run `wp post get --format=content {POST_ID}` Then STDOUT should be: """ - Test content. + This is some content. + + It will be inserted in a post. """ When I run `wp post get --format=table {POST_ID}` @@ -47,7 +55,7 @@ Feature: Manage WordPress posts When I run `wp post get --format=json {POST_ID}` Then STDOUT should be JSON containing: """ - {"ID":{POST_ID},"post_title":"Test post","post_content":"Test content."} + {"ID":{POST_ID},"post_title":"Test post"} """ Scenario: Creating/listing posts From 3ca6c14ab22042ce3a1be78a5ac057ec0c735358 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Jun 2013 00:22:49 +0300 Subject: [PATCH 1865/4858] --info: make WP-CLI root be the root folder, not php/ --- php/commands/_sys.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/_sys.php b/php/commands/_sys.php index fefbc22316..e5510c563a 100644 --- a/php/commands/_sys.php +++ b/php/commands/_sys.php @@ -35,7 +35,7 @@ function info() { WP_CLI::line( "PHP binary:\t" . $php_bin ); WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); - WP_CLI::line( "WP-CLI root:\t" . WP_CLI_ROOT ); + WP_CLI::line( "WP-CLI root:\t" . dirname( WP_CLI_ROOT ) ); WP_CLI::line( "WP-CLI config:\t" . WP_CLI::get_config_path() ); WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); } From 8483fb709b2285a033515f59b4ad818468a0372a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 9 May 2013 00:08:37 +0300 Subject: [PATCH 1866/4858] remove support for Phar archive --- php/boot-phar.php | 6 --- php/commands/help.php | 13 +----- utils/make-phar.php | 88 ---------------------------------------- utils/test-phar-download | 6 --- utils/update-phar | 46 --------------------- 5 files changed, 1 insertion(+), 158 deletions(-) delete mode 100644 php/boot-phar.php delete mode 100644 utils/make-phar.php delete mode 100755 utils/test-phar-download delete mode 100755 utils/update-phar diff --git a/php/boot-phar.php b/php/boot-phar.php deleted file mode 100644 index be8cfdcb20..0000000000 --- a/php/boot-phar.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php - -define( 'WP_CLI_ROOT', 'phar://wp-cli.phar/php/' ); - -include WP_CLI_ROOT . 'wp-cli.php'; - diff --git a/php/commands/help.php b/php/commands/help.php index ef8b24bef8..a15ecc2234 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -67,7 +67,7 @@ private static function maybe_show_manpage( $args ) { $man_path = "$dest_dir/" . $man_file; if ( is_readable( $man_path ) ) { - self::show_manpage( $man_path ); + \WP_CLI::launch( "man $man_path" ); return true; } } @@ -75,17 +75,6 @@ private static function maybe_show_manpage( $args ) { return false; } - private static function show_manpage( $path ) { - // man can't read phar://, so need to copy to a temporary file - $tmp_path = tempnam( sys_get_temp_dir(), 'wp-cli-man-' ); - - copy( $path, $tmp_path ); - - \WP_CLI::launch( "man $tmp_path" ); - - unlink( $tmp_path ); - } - private static function _generate( $src_dir, $dest_dir, $command ) { $cmd_path = Dispatcher\get_path( $command ); array_shift( $cmd_path ); // discard 'wp' diff --git a/utils/make-phar.php b/utils/make-phar.php deleted file mode 100644 index 1911b8f36a..0000000000 --- a/utils/make-phar.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php - -if ( !isset( $argv[1] ) ) { - echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet]\n"; - exit(1); -} - -define( 'DEST_PATH', $argv[1] ); - -define( 'BE_QUIET', in_array( '--quiet', $argv ) ); - -function get_iterator( $dir ) { - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ) - ); -} - -function add_file( $phar, $path ) { - $key = str_replace( './', '', $path ); - - if ( !BE_QUIET ) - echo "$key - $path\n"; - - $phar[ $key ] = file_get_contents( $path ); -} - -$phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' ); - -$phar->startBuffering(); - -// php files -foreach ( get_iterator( './php' ) as $path ) { - if ( !preg_match( '/\.php$/', $path ) ) - continue; - - add_file( $phar, $path ); -} - -// non-php files -$additional_dirs = array( - './templates', - './man' -); - -foreach ( $additional_dirs as $dir ) { - foreach ( get_iterator( $dir ) as $path ) { - add_file( $phar, $path ); - } -} - -// dependencies -$ignored_paths = array( - '/.git', -); - -$vendor_dirs = array( - './vendor/mustache', - './vendor/wp-cli', - './vendor/composer', -); - -foreach ( $vendor_dirs as $vendor_dir ) { - foreach ( get_iterator( $vendor_dir ) as $path ) { - foreach ( $ignored_paths as $ignore ) { - if ( strpos( $path, $ignore ) ) - continue 2; - } - - add_file( $phar, $path ); - } -} - -add_file( $phar, './vendor/autoload.php' ); - -$phar->setStub( <<<EOB -#!/usr/bin/env php -<?php -Phar::mapPhar(); -include 'phar://wp-cli.phar/php/boot-phar.php'; -__HALT_COMPILER(); -?> -EOB -); - -$phar->stopBuffering(); - -echo "Generated " . DEST_PATH . "\n"; - diff --git a/utils/test-phar-download b/utils/test-phar-download deleted file mode 100755 index f1a47e5190..0000000000 --- a/utils/test-phar-download +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -actual_checksum=$(curl http://wp-cli.org/packages/phar/wp-cli.phar | md5sum | cut -d ' ' -f 1) - -echo "expected:" $(curl -s http://wp-cli.org/packages/phar/wp-cli.phar.md5) -echo "actual: " $actual_checksum diff --git a/utils/update-phar b/utils/update-phar deleted file mode 100755 index ea79bf1129..0000000000 --- a/utils/update-phar +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -current_rev=$(git rev-parse HEAD) -current_rev=${current_rev:0:10} - -packages_repo=../wp-cli-packages - -fname="phar/wp-cli.phar" - -# generate archive -php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet - -cd $packages_repo - -# smoke test -php $fname --version - -# check which wp-cli commit the previous Phar archive was based on -# can't use the md5 hash, since it will be different each time the -# archive is generated -new_commit_subj="update wp-cli.phar to wp-cli/wp-cli@$current_rev" - -current_commit_subj=$(git show -s --pretty=format:%s HEAD) - -if [ "$new_commit_subj" = "$current_commit_subj" ]; then - echo "already at latest revision" - exit 1 -fi - -# generate md5 checksum -if [ command -v md5sum > /dev/null ] -then - md5hash=$(md5sum $fname) -else - md5hash=$(md5 -r $fname) -fi - -echo $md5hash | cut -d ' ' -f 1 > $fname.md5 - -git add $fname $fname.md5 - -git commit -m "$new_commit_subj" - -git push From ec88e63f36841cbac5b6fb88eefbc181c6b1c06c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Jun 2013 12:34:38 +0300 Subject: [PATCH 1867/4858] define WP_CLI_ROOT to be the root directory, with no trailing slash --- php/boot-fs.php | 4 ++-- php/class-wp-cli.php | 6 +++--- php/commands/_sys.php | 2 +- php/commands/scaffold.php | 2 +- php/utils.php | 12 ++++++------ php/wp-cli.php | 10 +++++----- php/wp-settings-cli.php | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/php/boot-fs.php b/php/boot-fs.php index a227bfedec..7a13744db4 100644 --- a/php/boot-fs.php +++ b/php/boot-fs.php @@ -12,7 +12,7 @@ die(-1); } -define( 'WP_CLI_ROOT', __DIR__ . '/' ); +define( 'WP_CLI_ROOT', dirname( __DIR__ ) ); -include dirname(__FILE__) . '/wp-cli.php'; +include WP_CLI_ROOT . '/php/wp-cli.php'; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 3cb5133c46..9f928a481f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -23,11 +23,11 @@ class WP_CLI { */ static function init() { self::add_man_dir( - WP_CLI_ROOT . "../man", - WP_CLI_ROOT . "../man-src" + WP_CLI_ROOT . "/man", + WP_CLI_ROOT . "/man-src" ); - self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/config-spec.php' ); + self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); self::$root = new Dispatcher\RootCommand; self::$runner = new WP_CLI\Runner; } diff --git a/php/commands/_sys.php b/php/commands/_sys.php index e5510c563a..fefbc22316 100644 --- a/php/commands/_sys.php +++ b/php/commands/_sys.php @@ -35,7 +35,7 @@ function info() { WP_CLI::line( "PHP binary:\t" . $php_bin ); WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); - WP_CLI::line( "WP-CLI root:\t" . dirname( WP_CLI_ROOT ) ); + WP_CLI::line( "WP-CLI root:\t" . WP_CLI_ROOT ); WP_CLI::line( "WP-CLI config:\t" . WP_CLI::get_config_path() ); WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); } diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 7997e23da9..2428339731 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -260,7 +260,7 @@ function plugin_tests( $args, $assoc_args ) { ); foreach ( $to_copy as $file => $dir ) { - $wp_filesystem->copy( WP_CLI_ROOT . "../templates/$file", "$dir/$file", true ); + $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); } WP_CLI::success( "Created test files." ); diff --git a/php/utils.php b/php/utils.php index a5a2bad76b..dab686c871 100644 --- a/php/utils.php +++ b/php/utils.php @@ -8,8 +8,8 @@ function load_dependencies() { $vendor_paths = array( - WP_CLI_ROOT . '../vendor', // top-level project - WP_CLI_ROOT . '../../../../vendor', // part of a larger project + WP_CLI_ROOT . '/vendor', // top-level project + WP_CLI_ROOT . '/../../../vendor', // part of a larger project ); $has_autoload = false; @@ -27,11 +27,11 @@ function load_dependencies() { exit(3); } - include WP_CLI_ROOT . 'Spyc.php'; + include WP_CLI_ROOT . '/php/Spyc.php'; } function load_command( $name ) { - $path = WP_CLI_ROOT . "/commands/$name.php"; + $path = WP_CLI_ROOT . "/php/commands/$name.php"; if ( is_readable( $path ) ) { include_once $path; @@ -39,7 +39,7 @@ function load_command( $name ) { } function load_all_commands() { - $cmd_dir = WP_CLI_ROOT . "commands"; + $cmd_dir = WP_CLI_ROOT . "/php/commands"; $iterator = new \DirectoryIterator( $cmd_dir ); @@ -372,7 +372,7 @@ function run_mysql_command( $cmd, $arg_str, $pass ) { } function mustache_render( $template_name, $data ) { - $template = file_get_contents( WP_CLI_ROOT . "../templates/$template_name" ); + $template = file_get_contents( WP_CLI_ROOT . "/templates/$template_name" ); $m = new \Mustache_Engine; diff --git a/php/wp-cli.php b/php/wp-cli.php index 59cee2480e..5970c361f3 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -5,10 +5,10 @@ define( 'WP_CLI_VERSION', '0.11.0-alpha' ); -include WP_CLI_ROOT . 'utils.php'; -include WP_CLI_ROOT . 'dispatcher.php'; -include WP_CLI_ROOT . 'class-wp-cli.php'; -include WP_CLI_ROOT . 'class-wp-cli-command.php'; +include WP_CLI_ROOT . '/php/utils.php'; +include WP_CLI_ROOT . '/php/dispatcher.php'; +include WP_CLI_ROOT . '/php/class-wp-cli.php'; +include WP_CLI_ROOT . '/php/class-wp-cli-command.php'; \WP_CLI\Utils\load_dependencies(); @@ -26,7 +26,7 @@ define( 'WP_USER_ADMIN', false ); // Load Core, mu-plugins, plugins, themes etc. -require WP_CLI_ROOT . 'wp-settings-cli.php'; +require WP_CLI_ROOT . '/php/wp-settings-cli.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index f892f57eb1..34cba9323f 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -40,7 +40,7 @@ timer_start(); // Load WP-CLI utilities -require WP_CLI_ROOT . 'utils-wp.php'; +require WP_CLI_ROOT . '/php/utils-wp.php'; // Check if we're in WP_DEBUG mode. Utils\wp_debug_mode(); From 34b370439109a9d28c6339071e4f4cc947a5839a Mon Sep 17 00:00:00 2001 From: Andrey Savchenko <contact@rarst.net> Date: Sat, 22 Jun 2013 01:42:33 +0300 Subject: [PATCH 1868/4858] Added basic wp.bat launcher for Windows environment. --- bin/wp.bat | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 bin/wp.bat diff --git a/bin/wp.bat b/bin/wp.bat new file mode 100644 index 0000000000..59f953440b --- /dev/null +++ b/bin/wp.bat @@ -0,0 +1,2 @@ +@ECHO OFF +php "%~dp0../php/boot-fs.php" %* \ No newline at end of file From 4b5786bc16905cf0c3f2cc95a4afd9d51390f2d4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Jun 2013 02:24:31 +0300 Subject: [PATCH 1869/4858] colorize plugin/theme status legend. see #517 --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index c8da9c3a4e..65ede4f568 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -92,7 +92,7 @@ private function show_legend( $items ) { if ( in_array( true, wp_list_pluck( $items, 'update' ) ) ) $legend_line[] = '%yU = Update Available%n'; - \WP_CLI::line( 'Legend: ' . implode( ', ', $legend_line ) ); + \WP_CLI::line( 'Legend: ' . implode( ', ', \WP_CLI::colorize( $legend_line ) ) ); } function install( $args, $assoc_args ) { From 9304d773ab2f993bc820fc41e7b0e218f4724c07 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Jun 2013 21:08:28 +0300 Subject: [PATCH 1870/4858] fix man page for `wp core is-installed` --- man-src/core-is-installed.txt | 6 +++--- man/core-is-installed.1 | 13 ++++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/man-src/core-is-installed.txt b/man-src/core-is-installed.txt index e4901fe31d..afccd6c95b 100644 --- a/man-src/core-is-installed.txt +++ b/man-src/core-is-installed.txt @@ -1,5 +1,5 @@ ## EXAMPLES -if ! $(wp core is-installed); then - wp core install -fi + if ! $(wp core is-installed); then + wp core install + fi diff --git a/man/core-is-installed.1 b/man/core-is-installed.1 index 0aab8f72cc..56f61768b5 100644 --- a/man/core-is-installed.1 +++ b/man/core-is-installed.1 @@ -10,17 +10,12 @@ wp core is\-installed . .SH "EXAMPLES" -if ! $(wp core is\-installed); then -. -.IP "" 4 . .nf -wp core install +if ! $(wp core is\-installed); then + wp core install +fi . .fi -. -.IP "" 0 -. -.P -fi + From 625081abb79fd9ce7ce0427c72619821244c7e4a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Jun 2013 21:52:52 +0300 Subject: [PATCH 1871/4858] fix synopsis for `wp media import` --- man/media-import.1 | 2 +- php/commands/media.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man/media-import.1 b/man/media-import.1 index 8dca82091e..8ef92207d1 100644 --- a/man/media-import.1 +++ b/man/media-import.1 @@ -7,7 +7,7 @@ \fBwp\-media\-import\fR \- Create attachments from local files or from URLs\. . .SH "SYNOPSIS" -wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIpost_id\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fIalt_text\fR] [\-\-desc=\fIdescription\fR] [\-\-featured_image] +wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIid\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fItext\fR] [\-\-desc=\fIdescription\fR] [\-\-featured_image] . .SH "OPTIONS" . diff --git a/php/commands/media.php b/php/commands/media.php index b35db1ef88..0b73113fd6 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -56,7 +56,7 @@ function regenerate( $args, $assoc_args = array() ) { /** * Create attachments from local files or from URLs. * - * @synopsis <file>... [--post_id=<post_id>] [--title=<title>] [--caption=<caption>] [--alt=<alt_text>] [--desc=<description>] [--featured_image] + * @synopsis <file>... [--post_id=<id>] [--title=<title>] [--caption=<caption>] [--alt=<text>] [--desc=<description>] [--featured_image] */ function import( $args, $assoc_args = array() ) { From 31a30e5015fb098811c1f5b0ce6225abd7d1b7dd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Jun 2013 21:53:13 +0300 Subject: [PATCH 1872/4858] various man page updates --- man/cap.1 | 4 ++-- man/db.1 | 16 ++++++++-------- man/post-meta.1 | 4 ++-- man/transient.1 | 6 +++--- man/user-meta.1 | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/man/cap.1 b/man/cap.1 index fdee7e6b6c..fd4b8f669a 100644 --- a/man/cap.1 +++ b/man/cap.1 @@ -7,10 +7,10 @@ \fBwp\-cap\fR \- Manage user capabilities\. . .SH "SYNOPSIS" -wp cap list \fIrole\fR +wp cap add \fIrole\fR \fIcap\fR\.\.\. . .P -wp cap add \fIrole\fR \fIcap\fR\.\.\. +wp cap list \fIrole\fR . .P wp cap remove \fIrole\fR \fIcap\fR\.\.\. diff --git a/man/db.1 b/man/db.1 index 5dd4689952..eaca52f2cf 100644 --- a/man/db.1 +++ b/man/db.1 @@ -7,31 +7,31 @@ \fBwp\-db\fR \- Perform basic database operations\. . .SH "SYNOPSIS" -wp db create +wp db cli . .P -wp db drop [\-\-yes] +wp db create . .P -wp db reset [\-\-yes] +wp db drop [\-\-yes] . .P -wp db optimize +wp db export [\fIfile\fR] . .P -wp db repair +wp db import [\fIfile\fR] . .P -wp db cli +wp db optimize . .P wp db query [\fIsql\fR] . .P -wp db export [\fIfile\fR] +wp db repair . .P -wp db import [\fIfile\fR] +wp db reset [\-\-yes] . .SH "SUBCOMMANDS" . diff --git a/man/post-meta.1 b/man/post-meta.1 index ac1203efe2..90398260aa 100644 --- a/man/post-meta.1 +++ b/man/post-meta.1 @@ -7,13 +7,13 @@ \fBwp\-post\-meta\fR \- Manage post custom fields\. . .SH "SYNOPSIS" -wp post\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] +wp post\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .P wp post\-meta delete \fIid\fR \fIkey\fR . .P -wp post\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] +wp post\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] . .P wp post\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] diff --git a/man/transient.1 b/man/transient.1 index 1edd72a003..695644fc72 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -7,13 +7,13 @@ \fBwp\-transient\fR \- Manage WordPress transients\. . .SH "SYNOPSIS" -wp transient get \fIkey\fR [\-\-json] +wp transient delete \fIkey\fR . .P -wp transient set \fIkey\fR \fIvalue\fR [\fIexpiration\fR] +wp transient get \fIkey\fR [\-\-json] . .P -wp transient delete \fIkey\fR +wp transient set \fIkey\fR \fIvalue\fR [\fIexpiration\fR] . .P wp transient type diff --git a/man/user-meta.1 b/man/user-meta.1 index b09bb8db9c..817491f42e 100644 --- a/man/user-meta.1 +++ b/man/user-meta.1 @@ -7,13 +7,13 @@ \fBwp\-user\-meta\fR \- Manage user custom fields\. . .SH "SYNOPSIS" -wp user\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] +wp user\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] . .P wp user\-meta delete \fIid\fR \fIkey\fR . .P -wp user\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] +wp user\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] . .P wp user\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] From 22dadc77575cae1b15e08bac93a86f299b270aa4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Jun 2013 22:28:49 +0300 Subject: [PATCH 1873/4858] misc man fixes [ci skip] --- man-src/cache.txt | 4 ++-- man-src/core-download.txt | 2 +- man-src/core-init-tests.txt | 2 +- man-src/db.txt | 3 ++- man-src/scaffold-plugin-tests.txt | 2 +- man-src/theme-delete.txt | 2 +- man-src/theme-install.txt | 2 +- man-src/theme-update.txt | 2 +- man-src/transient.txt | 2 +- man/cache.1 | 9 +++++++-- man/core-download.1 | 2 +- man/core-init-tests.1 | 6 ++++++ man/db.1 | 7 +++++++ man/scaffold-plugin-tests.1 | 6 ++++++ man/theme-delete.1 | 2 +- man/theme-install.1 | 2 +- man/theme-update.1 | 2 +- man/transient.1 | 6 ++++++ 18 files changed, 47 insertions(+), 16 deletions(-) diff --git a/man-src/cache.txt b/man-src/cache.txt index 7b25aa6d75..70856ff26f 100644 --- a/man-src/cache.txt +++ b/man-src/cache.txt @@ -1,5 +1,5 @@ ## EXAMPLES -wp cache set my_key my_value my_group 300 + wp cache set my_key my_value my_group 300 -wp cache get my_key my_group + wp cache get my_key my_group diff --git a/man-src/core-download.txt b/man-src/core-download.txt index 74448c9860..a72ecc610e 100644 --- a/man-src/core-download.txt +++ b/man-src/core-download.txt @@ -15,4 +15,4 @@ ignored in this case. ## EXAMPLES - Download version 3.3: wp core download --version=3.3 + wp core download --version=3.3 diff --git a/man-src/core-init-tests.txt b/man-src/core-init-tests.txt index 9f55ec5cc4..55d72eafc4 100644 --- a/man-src/core-init-tests.txt +++ b/man-src/core-init-tests.txt @@ -19,4 +19,4 @@ you run the tests. ## EXAMPLE -wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test + wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test diff --git a/man-src/db.txt b/man-src/db.txt index a9fb12bfd1..d7ccfb703d 100644 --- a/man-src/db.txt +++ b/man-src/db.txt @@ -14,4 +14,5 @@ ## EXAMPLES -wp db query < debug.sql + # execute a query stored in a file + wp db query < debug.sql diff --git a/man-src/scaffold-plugin-tests.txt b/man-src/scaffold-plugin-tests.txt index 927c7fea48..7224977bdf 100644 --- a/man-src/scaffold-plugin-tests.txt +++ b/man-src/scaffold-plugin-tests.txt @@ -14,4 +14,4 @@ variable. ## EXAMPLE -wp scaffold plugin-tests hello + wp scaffold plugin-tests hello diff --git a/man-src/theme-delete.txt b/man-src/theme-delete.txt index 22506747b4..030f781e4c 100644 --- a/man-src/theme-delete.txt +++ b/man-src/theme-delete.txt @@ -1,6 +1,6 @@ ## OPTIONS -* <theme>: +* `<theme>`: The theme to delete. diff --git a/man-src/theme-install.txt b/man-src/theme-install.txt index 28e26a342c..a7377e6282 100644 --- a/man-src/theme-install.txt +++ b/man-src/theme-install.txt @@ -1,6 +1,6 @@ ## OPTIONS -* <theme>: +* `<theme>`: A theme slug or the path to a zip file. diff --git a/man-src/theme-update.txt b/man-src/theme-update.txt index d3439e48a8..b7e6109406 100644 --- a/man-src/theme-update.txt +++ b/man-src/theme-update.txt @@ -1,6 +1,6 @@ ## OPTIONS -* <theme>: +* `<theme>`: The theme to update. diff --git a/man-src/transient.txt b/man-src/transient.txt index 175ca9c8d3..64dcebe0f1 100644 --- a/man-src/transient.txt +++ b/man-src/transient.txt @@ -1,3 +1,3 @@ ## EXAMPLES -wp transient set my_key my_value 300 + wp transient set my_key my_value 300 diff --git a/man/cache.1 b/man/cache.1 index 2f724253c9..7587a2a941 100644 --- a/man/cache.1 +++ b/man/cache.1 @@ -90,7 +90,12 @@ Set a value to the object cache\. Attempts to determine which object cache is being used\. . .SH "EXAMPLES" -wp cache set my_key my_value my_group 300 . -.P +.nf + +wp cache set my_key my_value my_group 300 + wp cache get my_key my_group +. +.fi + diff --git a/man/core-download.1 b/man/core-download.1 index 7f2725d56f..7f607ca286 100644 --- a/man/core-download.1 +++ b/man/core-download.1 @@ -33,7 +33,7 @@ Overwrites existing files, if present\. . .nf -Download version 3\.3: wp core download \-\-version=3\.3 +wp core download \-\-version=3\.3 . .fi diff --git a/man/core-init-tests.1 b/man/core-init-tests.1 index 7e5c481958..e5001c3311 100644 --- a/man/core-init-tests.1 +++ b/man/core-init-tests.1 @@ -36,4 +36,10 @@ Set the database user\. Set the database user password\. . .SH "EXAMPLE" +. +.nf + wp core init\-tests ~/svn/wp\-tests \-\-dbname=wp_test \-\-dbuser=wp_test +. +.fi + diff --git a/man/db.1 b/man/db.1 index eaca52f2cf..7524abedd3 100644 --- a/man/db.1 +++ b/man/db.1 @@ -110,4 +110,11 @@ The name of the export file\. If omitted, it will be \'{dbname}\.sql\' A SQL query\. . .SH "EXAMPLES" +. +.nf + +# execute a query stored in a file wp db query < debug\.sql +. +.fi + diff --git a/man/scaffold-plugin-tests.1 b/man/scaffold-plugin-tests.1 index 1e1e7cd26c..5c0a07ee5e 100644 --- a/man/scaffold-plugin-tests.1 +++ b/man/scaffold-plugin-tests.1 @@ -30,4 +30,10 @@ These are the files that are generated: The \fBtests/bootstrap\.php\fR file looks for the WP_TESTS_DIR environment variable\. . .SH "EXAMPLE" +. +.nf + wp scaffold plugin\-tests hello +. +.fi + diff --git a/man/theme-delete.1 b/man/theme-delete.1 index 0066624757..3bfae3759f 100644 --- a/man/theme-delete.1 +++ b/man/theme-delete.1 @@ -12,7 +12,7 @@ wp theme delete \fItheme\fR .SH "OPTIONS" . .TP -\fItheme\fR: +\fB<theme>\fR: . .IP The theme to delete\. diff --git a/man/theme-install.1 b/man/theme-install.1 index df8a8ef701..5e74e7c305 100644 --- a/man/theme-install.1 +++ b/man/theme-install.1 @@ -12,7 +12,7 @@ wp theme install \fItheme|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] .SH "OPTIONS" . .TP -\fItheme\fR: +\fB<theme>\fR: . .IP A theme slug or the path to a zip file\. diff --git a/man/theme-update.1 b/man/theme-update.1 index 86fd820bd6..7e877c8172 100644 --- a/man/theme-update.1 +++ b/man/theme-update.1 @@ -12,7 +12,7 @@ wp theme update \fItheme\fR [\-\-version=\fIversion\fR] .SH "OPTIONS" . .TP -\fItheme\fR: +\fB<theme>\fR: . .IP The theme to update\. diff --git a/man/transient.1 b/man/transient.1 index 695644fc72..e3fd1ddd1e 100644 --- a/man/transient.1 +++ b/man/transient.1 @@ -45,4 +45,10 @@ Set a transient value\. <expiration> is the time until expiration, in seconds\. See wether the transients API is using an object cache or the options table\. . .SH "EXAMPLES" +. +.nf + wp transient set my_key my_value 300 +. +.fi + From 7fe10d4c70387e093351270aea6c3e982548bc02 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Jun 2013 12:46:34 +0300 Subject: [PATCH 1874/4858] remove empty line --- php/WP_CLI/Dispatcher/RootCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index c9e9abddca..03bc8196d0 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -39,10 +39,10 @@ function show_usage() { EOB ); - \WP_CLI::line( self::generate_synopsis() ); + self::show_synopsis(); } - private static function generate_synopsis() { + private static function show_synopsis() { $max_len = 0; $lines = array(); From e2dc746ac6dd025f3422bbbb6d46978427f44021 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Jun 2013 14:44:11 +0300 Subject: [PATCH 1875/4858] update Composer dependencies --- composer.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/composer.lock b/composer.lock index 8764fbff5c..4eb19204e4 100644 --- a/composer.lock +++ b/composer.lock @@ -53,12 +53,12 @@ "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "d44e1a9bd32d564a1c77dda0e96b66a199993e5c" + "reference": "9c34cb24ddbdec5ae0a56297561acda708890b5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/d44e1a9bd32d564a1c77dda0e96b66a199993e5c", - "reference": "d44e1a9bd32d564a1c77dda0e96b66a199993e5c", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/9c34cb24ddbdec5ae0a56297561acda708890b5c", + "reference": "9c34cb24ddbdec5ae0a56297561acda708890b5c", "shasum": "" }, "require": { @@ -90,7 +90,7 @@ "cli", "console" ], - "time": "2013-05-11 20:20:03" + "time": "2013-06-23 11:32:36" } ], "packages-dev": [ @@ -738,17 +738,17 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.3.0", + "version": "v2.3.1", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.3.0-RC1" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { @@ -886,17 +886,17 @@ }, { "name": "symfony/translation", - "version": "v2.3.0", + "version": "v2.3.1", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "v2.3.0-RC1" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { @@ -941,17 +941,17 @@ }, { "name": "symfony/yaml", - "version": "v2.3.0", + "version": "v2.3.1", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.3.0-RC1" + "reference": "v2.3.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.1", + "reference": "v2.3.1", "shasum": "" }, "require": { From 7cc4c8669674ee1a7485efe7e1ef4f1d02876187 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Jun 2013 14:45:44 +0300 Subject: [PATCH 1876/4858] ignore composer.lock Facts: 1. When WP-CLI isn't installed as the root package, composer.lock is ignored. 2. The wp-cli.org installer doesn't install WP-CLI as the root package, but as a dependency. 1. + 2. => Having composer.lock under version control gives a false sense of security. Instead, we should take more care with how we define dependencies in composer.json --- .gitignore | 1 + composer.lock | 1003 ------------------------------------------------- 2 files changed, 1 insertion(+), 1003 deletions(-) delete mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 325d475d87..03f9ead5d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +composer.lock composer.phar /vendor /phpunit.xml diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 4eb19204e4..0000000000 --- a/composer.lock +++ /dev/null @@ -1,1003 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" - ], - "hash": "6cae44632851e1e1cee580631b2d784a", - "packages": [ - { - "name": "mustache/mustache", - "version": "v2.3.1", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "type": "library", - "autoload": { - "psr-0": { - "Mustache": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" - } - ], - "description": "A Mustache implementation in PHP.", - "homepage": "https://github.com/bobthecow/mustache.php", - "keywords": [ - "mustache", - "templating" - ], - "time": "2013-04-25 15:23:30" - }, - { - "name": "wp-cli/php-cli-tools", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "9c34cb24ddbdec5ae0a56297561acda708890b5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/9c34cb24ddbdec5ae0a56297561acda708890b5c", - "reference": "9c34cb24ddbdec5ae0a56297561acda708890b5c", - "shasum": "" - }, - "require": { - "php": ">= 5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "cli": "lib/" - }, - "files": [ - "lib/cli/cli.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "James Logsdon", - "email": "jlogsdon@php.net", - "role": "Developer" - } - ], - "description": "Console utilities for PHP", - "homepage": "http://github.com/jlogsdon/php-cli-tools", - "keywords": [ - "cli", - "console" - ], - "time": "2013-06-23 11:32:36" - } - ], - "packages-dev": [ - { - "name": "behat/behat", - "version": "v2.4.6", - "source": { - "type": "git", - "url": "https://github.com/Behat/Behat.git", - "reference": "v2.4.6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/v2.4.6", - "reference": "v2.4.6", - "shasum": "" - }, - "require": { - "behat/gherkin": ">=2.2.9,<2.3", - "php": ">=5.3.1", - "symfony/config": ">=2.0,<3.0", - "symfony/console": ">=2.0,<3.0", - "symfony/dependency-injection": ">=2.0,<3.0", - "symfony/event-dispatcher": ">=2.0,<3.0", - "symfony/finder": ">=2.0,<3.0", - "symfony/translation": ">=2.0,<3.0", - "symfony/yaml": ">=2.0,<3.0" - }, - "require-dev": { - "phpunit/phpunit": ">=3.7.19.0,<3.8" - }, - "suggest": { - "behat/mink-extension": "for integration with Mink testing framework", - "behat/symfony2-extension": "for integration with Symfony2 web framework", - "behat/yii-extension": "for integration with Yii web framework" - }, - "bin": [ - "bin/behat" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "2.4-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Behat": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Scenario-oriented BDD framework for PHP 5.3", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "Symfony2" - ], - "time": "2013-06-06 10:46:48" - }, - { - "name": "behat/gherkin", - "version": "v2.2.9", - "source": { - "type": "git", - "url": "https://github.com/Behat/Gherkin.git", - "reference": "v2.2.9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/v2.2.9", - "reference": "v2.2.9", - "shasum": "" - }, - "require": { - "php": ">=5.3.1", - "symfony/finder": ">=2.0,<2.4-dev" - }, - "require-dev": { - "symfony/config": ">=2.0,<2.4-dev", - "symfony/translation": ">=2.0,<2.4-dev", - "symfony/yaml": ">=2.0,<2.4-dev" - }, - "suggest": { - "symfony/config": "If you want to use Config component to manage resources", - "symfony/translation": "If you want to use Symfony2 translations adapter", - "symfony/yaml": "If you want to parse features, represented in YAML files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "2.2-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Gherkin": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Gherkin DSL parser for PHP 5.3", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "DSL", - "Symfony2", - "parser" - ], - "time": "2013-03-02 10:38:40" - }, - { - "name": "phpunit/php-code-coverage", - "version": "1.2.11", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "1.2.11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.11", - "reference": "1.2.11", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-text-template": ">=1.1.1@stable", - "phpunit/php-token-stream": ">=1.1.3@stable" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.0.5" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2013-05-23 18:23:24" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.3", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "1.3.3" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", - "reference": "1.3.3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2012-10-11 04:44:38" - }, - { - "name": "phpunit/php-text-template", - "version": "1.1.4", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-text-template.git", - "reference": "1.1.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", - "reference": "1.1.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2012-10-31 11:15:28" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.4", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-timer.git", - "reference": "1.0.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", - "reference": "1.0.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "timer" - ], - "time": "2012-10-11 04:45:58" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.1.5", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1.1.5" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", - "reference": "1.1.5", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "tokenizer" - ], - "time": "2012-10-11 04:47:14" - }, - { - "name": "phpunit/phpunit", - "version": "3.7.21", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.21" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.21", - "reference": "3.7.21", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": ">=1.2.1,<1.3.0", - "phpunit/php-file-iterator": ">=1.3.1", - "phpunit/php-text-template": ">=1.1.1", - "phpunit/php-timer": ">=1.0.2,<1.1.0", - "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", - "symfony/yaml": ">=2.0,<3.0" - }, - "require-dev": { - "pear-pear/pear": "1.9.4" - }, - "suggest": { - "ext-json": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "phpunit/php-invoker": ">=1.1.0,<1.2.0" - }, - "bin": [ - "composer/bin/phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2013-05-23 18:54:29" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "1.2.3", - "source": { - "type": "git", - "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "1.2.3" - }, - "dist": { - "type": "zip", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip", - "reference": "1.2.3", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2013-01-13 10:24:48" - }, - { - "name": "symfony/config", - "version": "v2.3.1", - "target-dir": "Symfony/Component/Config", - "source": { - "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/filesystem": ">=2.3,<3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "http://symfony.com", - "time": "2013-06-03 00:18:25" - }, - { - "name": "symfony/console", - "version": "v2.3.1", - "target-dir": "Symfony/Component/Console", - "source": { - "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/event-dispatcher": ">=2.1,<3.0" - }, - "suggest": { - "symfony/event-dispatcher": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Console\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "http://symfony.com", - "time": "2013-06-11 07:15:14" - }, - { - "name": "symfony/dependency-injection", - "version": "v2.3.1", - "target-dir": "Symfony/Component/DependencyInjection", - "source": { - "type": "git", - "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": ">=2.2,<3.0", - "symfony/yaml": ">=2.0,<3.0" - }, - "suggest": { - "symfony/config": "", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\DependencyInjection\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com", - "time": "2013-06-05 09:51:05" - }, - { - "name": "symfony/event-dispatcher", - "version": "v2.3.1", - "target-dir": "Symfony/Component/EventDispatcher", - "source": { - "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/dependency-injection": ">=2.0,<3.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com", - "time": "2013-05-13 14:36:40" - }, - { - "name": "symfony/filesystem", - "version": "v2.3.1", - "target-dir": "Symfony/Component/Filesystem", - "source": { - "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Filesystem\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "http://symfony.com", - "time": "2013-06-04 15:02:05" - }, - { - "name": "symfony/finder", - "version": "v2.3.1", - "target-dir": "Symfony/Component/Finder", - "source": { - "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Finder\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "http://symfony.com", - "time": "2013-06-02 12:05:51" - }, - { - "name": "symfony/translation", - "version": "v2.3.1", - "target-dir": "Symfony/Component/Translation", - "source": { - "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": ">=2.0,<3.0", - "symfony/yaml": ">=2.2,<3.0" - }, - "suggest": { - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Translation\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Translation Component", - "homepage": "http://symfony.com", - "time": "2013-05-13 14:36:40" - }, - { - "name": "symfony/yaml", - "version": "v2.3.1", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.3.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.1", - "reference": "v2.3.1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2013-05-10 18:12:13" - } - ], - "aliases": [ - - ], - "minimum-stability": "stable", - "stability-flags": { - "wp-cli/php-cli-tools": 20 - }, - "platform": { - "php": ">=5.3.2" - }, - "platform-dev": [ - - ] -} From 7742a7003428aa22a764feb957a9e2cb22c59418 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Jun 2013 23:31:14 +0300 Subject: [PATCH 1877/4858] output help markdown directly, instead of going through man --- .travis.yml | 4 +- CONTRIBUTING.md | 11 -- bin/ci/install_dependencies.sh | 4 - bin/ci/run_build.sh | 6 +- features/help.feature | 55 +------- man-src/help.txt | 11 +- php/WP_CLI/Dispatcher/CompositeCommand.php | 3 +- php/WP_CLI/Dispatcher/Subcommand.php | 11 +- php/commands/help.php | 145 ++++----------------- php/dispatcher.php | 28 ---- templates/man.mustache | 15 ++- 11 files changed, 58 insertions(+), 235 deletions(-) diff --git a/.travis.yml b/.travis.yml index 138b44b662..cff1fea328 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,12 +6,12 @@ php: env: - WP_VERSION=latest - - WP_VERSION=3.4.2 WITH_RONN=1 + - WP_VERSION=3.4.2 matrix: exclude: - php: 5.4 - env: WP_VERSION=3.4.2 WITH_RONN=1 + env: WP_VERSION=3.4.2 before_script: ./bin/ci/install_dependencies.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 52ce37fda4..3580119b93 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,17 +15,6 @@ Also, please create or update the appropriate `.txt` file in the `man-src` direc Lastly, please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). -Generating man pages --------------------- - -To generate a man page, WP-CLI looks for `.txt` files in the `man-src` directory. It also gathers information from the inline comments and the `@synopsis` annotations. - -The compiled man page is placed in the `man` directory. - -To (re)generate one or more man pages, you first need to have the [ronn](https://rubygems.org/gems/ronn) ruby gem installed. - -Then, you can use the `wp help --gen` command. - Running the tests ----------------- diff --git a/bin/ci/install_dependencies.sh b/bin/ci/install_dependencies.sh index 02b33c11b9..c756510987 100755 --- a/bin/ci/install_dependencies.sh +++ b/bin/ci/install_dependencies.sh @@ -8,10 +8,6 @@ set -ex composer install --dev --no-interaction --prefer-source composer require d11wtq/boris=dev-master --no-interaction --prefer-source -if [ -n "$WITH_RONN" ]; then - gem install ronn -fi - # set up WP install ./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ diff --git a/bin/ci/run_build.sh b/bin/ci/run_build.sh index aed4ad0bf3..3ed2e35cdb 100755 --- a/bin/ci/run_build.sh +++ b/bin/ci/run_build.sh @@ -4,8 +4,4 @@ set -ex vendor/bin/phpunit -if [ -z "$WITH_RONN" ]; then - BEHAT_OPTS="--tags ~@ronn" -fi - -vendor/bin/behat --format progress $BEHAT_OPTS +vendor/bin/behat --format progress diff --git a/features/help.feature b/features/help.feature index 5b8b421fe1..2f2193548c 100644 --- a/features/help.feature +++ b/features/help.feature @@ -4,52 +4,21 @@ Feature: Get help about WP-CLI commands Given an empty directory When I run `wp help` - Then STDOUT should contain: - """ - Available commands: - """ + Then STDOUT should not be empty When I run `wp help core` - Then STDOUT should contain: - """ - usage: wp core - """ + Then STDOUT should not be empty When I run `wp help core download` - Then STDOUT should contain: - """ - WP-CORE-DOWNLOAD(1) - """ + Then STDOUT should not be empty - When I run `wp help --help` - Then STDOUT should contain: - """ - WP-HELP(1) - """ + When I run `wp help help` + Then STDOUT should not be empty When I try `wp help non-existent-command` Then the return code should be 1 And STDERR should not be empty - @ronn - Scenario: Generating help for subcommands - Given an empty directory - When I run `wp help --gen option` - Then STDOUT should be: - """ - generated option.1 - """ - - @ronn - Scenario: Generating help for multisite-only subcommands - Given an empty directory - When I run `wp help --gen site create` - Then STDOUT should be: - """ - generated site-create.1 - """ - - @ronn Scenario: Help for third-party commands Given a WP install And a wp-content/plugins/test-cli/test-help.txt file: @@ -76,17 +45,5 @@ Feature: Get help about WP-CLI commands When I run `wp help test-help` Then STDOUT should contain: """ - usage: wp test-help - """ - - When I run `wp help --gen test-help` - Then STDOUT should contain: - """ - generated test-help.1 - """ - - When I run `wp help test-help` - Then STDOUT should contain: - """ - WP-TEST-HELP(1) + wp test-help """ diff --git a/man-src/help.txt b/man-src/help.txt index 69ac8e6993..19e660f7c4 100644 --- a/man-src/help.txt +++ b/man-src/help.txt @@ -1,10 +1,7 @@ ## EXAMPLES - # (re)generates all man pages - wp help --gen + # get help for `core` command + wp help core - # (re)generate man pages for the `core` command - wp help --gen core - - # (re)generate man page only for the `core download` subcommand - wp help --gen core download + # get help for `core download` subcommand + wp help core download diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 14179199cd..8a527fa09f 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -17,7 +17,6 @@ public function __construct( $parent, $name, $docparser ) { $this->name = $name; $this->shortdesc = $docparser->get_shortdesc(); - $this->synopsis = $docparser->get_synopsis(); $when_to_invoke = $docparser->get_tag( 'when' ); if ( $when_to_invoke ) { @@ -52,7 +51,7 @@ function get_shortdesc() { } function get_synopsis() { - return $this->synopsis; + return '<subcommand>'; } function invoke( $args, $assoc_args ) { diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 55d27f925e..3203ef9d42 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -14,17 +14,26 @@ class Subcommand extends CompositeCommand { function __construct( $parent, $name, $docparser, $when_invoked ) { $this->when_invoked = $when_invoked; + $this->synopsis = $docparser->get_synopsis(); $this->alias = $docparser->get_tag( 'alias' ); parent::__construct( $parent, $name, $docparser ); } + function get_synopsis() { + return $this->synopsis; + } + function get_alias() { return $this->alias; } function show_usage( $prefix = 'usage: ' ) { - \WP_CLI::line( $prefix . get_full_synopsis( $this ) ); + \WP_CLI::line( sprintf( "%s%s %s", + $prefix, + implode( ' ', get_path( $this ) ), + $this->get_synopsis() + ) ); } private function validate_args( $args, &$assoc_args ) { diff --git a/php/commands/help.php b/php/commands/help.php index a15ecc2234..03ac39082d 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -8,13 +8,21 @@ class Help_Command extends WP_CLI_Command { /** * Get help on a certain topic. * - * @synopsis [<command>] [--gen] + * @synopsis [<command>] */ function __invoke( $args, $assoc_args ) { - if ( isset( $assoc_args['gen'] ) ) - $this->generate( $args ); - else - $this->show( $args ); + $command = self::find_subcommand( $args ); + + if ( $command ) { + self::add_initial_markdown( $command ); + + $extra_markdown_path = self::find_extra_markdown( $command ); + if ( $extra_markdown_path ) { + echo file_get_contents( $extra_markdown_path ); + } + + exit; + } // WordPress is already loaded, so there's no chance we'll find the command if ( function_exists( 'add_filter' ) ) { @@ -32,103 +40,29 @@ private static function find_subcommand( $args ) { return $command; } - private function show( $args ) { - if ( self::maybe_show_manpage( $args ) ) { - exit; - } - - $command = self::find_subcommand( $args ); - - if ( $command ) { - $command->show_usage(); - exit; - } - } - - private function generate( $args ) { - if ( '' === exec( 'which ronn' ) ) { - WP_CLI::error( '`ronn` executable not found.' ); - } - - $command = self::find_subcommand( $args ); - - if ( $command ) { - foreach ( WP_CLI::get_man_dirs() as $dest_dir => $src_dir ) { - self::_generate( $src_dir, $dest_dir, $command ); - } - exit; - } - } - - private static function maybe_show_manpage( $args ) { - $man_file = self::get_file_name( $args ); - - foreach ( \WP_CLI::get_man_dirs() as $dest_dir => $_ ) { - $man_path = "$dest_dir/" . $man_file; - - if ( is_readable( $man_path ) ) { - \WP_CLI::launch( "man $man_path" ); - return true; - } - } - - return false; - } - - private static function _generate( $src_dir, $dest_dir, $command ) { + private static function find_extra_markdown( $command ) { $cmd_path = Dispatcher\get_path( $command ); array_shift( $cmd_path ); // discard 'wp' + $cmd_path = implode( '-', $cmd_path ); - $src_path = "$src_dir/" . self::get_src_file_name( $cmd_path ); - $dest_path = "$dest_dir/" . self::get_file_name( $cmd_path ); - - self::call_ronn( self::get_markdown( $src_path, $command ), $dest_path ); - - if ( $command->has_subcommands() ) { - foreach ( $command->get_subcommands() as $subcommand ) { - self::_generate( $src_dir, $dest_dir, $subcommand ); - } + foreach ( WP_CLI::get_man_dirs() as $src_dir ) { + $src_path = "$src_dir/$cmd_path.txt"; + if ( is_readable( $src_path ) ) + return $src_path; } - } - - // returns a file descriptor or false - private static function get_markdown( $doc_path, $command ) { - if ( !file_exists( $doc_path ) ) - return false; - - $fd = fopen( "php://temp", "rw" ); - - self::add_initial_markdown( $fd, $command ); - fwrite( $fd, file_get_contents( $doc_path ) ); - - if ( 0 === ftell( $fd ) ) - return false; - - fseek( $fd, 0 ); - - return $fd; + return false; } - private static function add_initial_markdown( $fd, $command ) { - $path = Dispatcher\get_path( $command ); + private static function add_initial_markdown( $command ) { + $name = implode( ' ', Dispatcher\get_path( $command ) ); $binding = array( - 'name_m' => implode( '-', $path ), + 'name' => $name, 'shortdesc' => $command->get_shortdesc(), ); - $synopsis = Dispatcher\get_full_synopsis( $command, true ); - - $synopsis = str_replace( '_', '\_', $synopsis ); - $synopsis = str_replace( array( '<', '>' ), '_', $synopsis ); - - $binding['synopsis'] = $synopsis; - - if ( !$binding['shortdesc'] ) { - $name_s = implode( ' ', $path ); - \WP_CLI::warning( "No shortdesc for $name_s" ); - } + $binding['synopsis'] = "$name " . $command->get_synopsis(); if ( $command->has_subcommands() ) { foreach ( $command->get_subcommands() as $subcommand ) { @@ -139,36 +73,7 @@ private static function add_initial_markdown( $fd, $command ) { } } - fwrite( $fd, Utils\mustache_render( 'man.mustache', $binding ) ); - } - - private static function call_ronn( $markdown, $dest ) { - if ( !$markdown ) - return; - - $descriptorspec = array( - 0 => $markdown, - 1 => array( 'file', $dest, 'w' ), - 2 => STDERR - ); - - $cmd = "ronn --date=2012-01-01 --roff --manual='WP-CLI'"; - - $r = proc_close( proc_open( $cmd, $descriptorspec, $pipes ) ); - - $roff = file_get_contents( $dest ); - $roff = str_replace( ' "January 2012"', '', $roff ); - file_put_contents( $dest, $roff ); - - \WP_CLI::log( "generated " . basename( $dest ) ); - } - - private static function get_file_name( $args ) { - return implode( '-', $args ) . '.1'; - } - - private static function get_src_file_name( $args ) { - return implode( '-', $args ) . '.txt'; + echo Utils\mustache_render( 'man.mustache', $binding ); } } diff --git a/php/dispatcher.php b/php/dispatcher.php index 45903834f3..8157d21b6b 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -12,31 +12,3 @@ function get_path( $command ) { return $path; } -function get_full_synopsis( $command, $validate = false ) { - $subcommands = $command->get_subcommands(); - - if ( empty( $subcommands ) ) { - $synopsis = $command->get_synopsis(); - - if ( $validate ) { - $tokens = \WP_CLI\SynopsisParser::parse( $synopsis ); - - foreach ( $tokens as $token ) { - if ( 'unknown' == $token['type'] ) { - \WP_CLI::warning( sprintf( - "Invalid token '%s' in synopsis for '%s'", - $token['token'], $full_name - ) ); - } - } - } - - $full_name = implode( ' ', get_path( $command ) ); - - return "$full_name $synopsis"; - } else { - return implode( "\n\n", array_map( __FUNCTION__, - $subcommands ) ); - } -} - diff --git a/templates/man.mustache b/templates/man.mustache index 61a99bcfcb..0c9aafb1e4 100644 --- a/templates/man.mustache +++ b/templates/man.mustache @@ -1,17 +1,20 @@ -{{name_m}}(1) -- {{shortdesc}} -==== +## NAME + + {{{name}}} + +## DESCRIPTION + + {{{shortdesc}}} ## SYNOPSIS -{{synopsis}} + {{{synopsis}}} {{#has-subcommands}} ## SUBCOMMANDS {{#subcommands}} -* `{{name}}`: - - {{desc}} + * `{{name}}`: {{desc}} {{/subcommands}} {{/has-subcommands}} From d7a46f010ba954c11be3373c27808fc7c853abeb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Jun 2013 13:53:53 +0300 Subject: [PATCH 1878/4858] make help headings bright --- php/commands/help.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 03ac39082d..00881a0fbc 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -14,13 +14,7 @@ function __invoke( $args, $assoc_args ) { $command = self::find_subcommand( $args ); if ( $command ) { - self::add_initial_markdown( $command ); - - $extra_markdown_path = self::find_extra_markdown( $command ); - if ( $extra_markdown_path ) { - echo file_get_contents( $extra_markdown_path ); - } - + self::show_help( $command ); exit; } @@ -40,6 +34,20 @@ private static function find_subcommand( $args ) { return $command; } + private static function show_help( $command ) { + $out = self::get_initial_markdown( $command ); + + $extra_markdown_path = self::find_extra_markdown( $command ); + if ( $extra_markdown_path ) { + $out .= file_get_contents( $extra_markdown_path ); + } + + $out = str_replace( "\t", ' ', $out ); + $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); + + echo WP_CLI::colorize( $out ); + } + private static function find_extra_markdown( $command ) { $cmd_path = Dispatcher\get_path( $command ); array_shift( $cmd_path ); // discard 'wp' @@ -54,7 +62,7 @@ private static function find_extra_markdown( $command ) { return false; } - private static function add_initial_markdown( $command ) { + private static function get_initial_markdown( $command ) { $name = implode( ' ', Dispatcher\get_path( $command ) ); $binding = array( @@ -73,7 +81,7 @@ private static function add_initial_markdown( $command ) { } } - echo Utils\mustache_render( 'man.mustache', $binding ); + return Utils\mustache_render( 'man.mustache', $binding ); } } From b57796b31115895f5711bf1a2e554cb2ee056ff3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Jun 2013 14:10:25 +0300 Subject: [PATCH 1879/4858] prettify subcommand listing --- php/commands/help.php | 34 ++++++++++++++++++++++++++++------ templates/man.mustache | 4 ++-- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 00881a0fbc..af9941c293 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -73,16 +73,38 @@ private static function get_initial_markdown( $command ) { $binding['synopsis'] = "$name " . $command->get_synopsis(); if ( $command->has_subcommands() ) { - foreach ( $command->get_subcommands() as $subcommand ) { - $binding['has-subcommands']['subcommands'][] = array( - 'name' => $subcommand->get_name(), - 'desc' => $subcommand->get_shortdesc(), - ); - } + $binding['has-subcommands']['subcommands'] = self::render_subcommands( $command ); } return Utils\mustache_render( 'man.mustache', $binding ); } + + private static function render_subcommands( $command ) { + $subcommands = array(); + foreach ( $command->get_subcommands() as $subcommand ) { + $subcommands[ $subcommand->get_name() ] = $subcommand->get_shortdesc(); + } + + $max_len = self::get_max_len( array_keys( $subcommands ) ); + + $lines = array(); + foreach ( $subcommands as $name => $desc ) { + $lines[] = str_pad( $name, $max_len ) . "\t\t\t" . $desc; + } + + return $lines; + } + + private static function get_max_len( $strings ) { + $max_len = 0; + foreach ( $strings as $str ) { + $len = strlen( $str ); + if ( $len > $max_len ) + $max_len = $len; + } + + return $max_len; + } } WP_CLI::add_command( 'help', 'Help_Command' ); diff --git a/templates/man.mustache b/templates/man.mustache index 0c9aafb1e4..6767c83d87 100644 --- a/templates/man.mustache +++ b/templates/man.mustache @@ -14,7 +14,7 @@ ## SUBCOMMANDS {{#subcommands}} - * `{{name}}`: {{desc}} - + {{{.}}} {{/subcommands}} + {{/has-subcommands}} From 7ca41b2f12b8c83f3f826ad394062a84f935e5c6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 23 Jun 2013 14:39:51 +0300 Subject: [PATCH 1880/4858] partial cleanup of option listing --- php/commands/help.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index af9941c293..c1cf96b2aa 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -42,8 +42,9 @@ private static function show_help( $command ) { $out .= file_get_contents( $extra_markdown_path ); } + $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); // section headers + $out = preg_replace( '/^\* `([^`]+)`/m', '\1', $out ); // options $out = str_replace( "\t", ' ', $out ); - $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); echo WP_CLI::colorize( $out ); } From 3b4efe3a967bc2f1f6f2d63b01c128736d583b50 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <danielbachhuber@gmail.com> Date: Mon, 24 Jun 2013 11:02:49 +0000 Subject: [PATCH 1881/4858] Clarity the `site empty` command doesn't do anything to the options table or users. --- man/site-empty.1 | 2 +- php/commands/site.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man/site-empty.1 b/man/site-empty.1 index 144391fba1..1c0b067d09 100644 --- a/man/site-empty.1 +++ b/man/site-empty.1 @@ -4,7 +4,7 @@ .TH "WP\-SITE\-EMPTY" "1" "" "WP-CLI" . .SH "NAME" -\fBwp\-site\-empty\fR \- Empty a site of its content\. +\fBwp\-site\-empty\fR \- Empty a site of its content (posts, comments, and terms)\. . .SH "SYNOPSIS" wp site empty [\-\-yes] diff --git a/php/commands/site.php b/php/commands/site.php index 5f548284c6..c027cf4958 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -108,14 +108,14 @@ private function _insert_default_terms() { } /** - * Empty a site of its content. + * Empty a site of its content (posts, comments, and terms). * * @subcommand empty * @synopsis [--yes] */ public function _empty( $args, $assoc_args ) { - WP_CLI::confirm( 'Are you sure you want to empty the site at ' . site_url() . '?', $assoc_args ); + WP_CLI::confirm( 'Are you sure you want to empty the site at ' . site_url() . ' of all posts, comments, and terms?', $assoc_args ); $this->_empty_posts(); $this->_empty_comments(); From 2d6344c1ab0095d6cfbe00a2cee5debd481a6fa0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <danielbachhuber@gmail.com> Date: Mon, 24 Jun 2013 11:06:09 +0000 Subject: [PATCH 1882/4858] Manual for the `--yes` prompt --- man-src/site-empty.txt | 8 +++++++- man/site-empty.1 | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/man-src/site-empty.txt b/man-src/site-empty.txt index 80db5732c2..b97477a0fd 100644 --- a/man-src/site-empty.txt +++ b/man-src/site-empty.txt @@ -1,3 +1,9 @@ ## EXAMPLES - wp blog empty \ No newline at end of file + wp blog empty + +## OPTIONS + +* `--yes`: + + Proceed to empty the site without a confirmation prompt. \ No newline at end of file diff --git a/man/site-empty.1 b/man/site-empty.1 index 1c0b067d09..f1de33d864 100644 --- a/man/site-empty.1 +++ b/man/site-empty.1 @@ -16,4 +16,12 @@ wp site empty [\-\-yes] wp blog empty . .fi +. +.SH "OPTIONS" +. +.TP +\fB\-\-yes\fR: +. +.IP +Proceed to empty the site without a confirmation prompt\. From 8c649489ad68f889068e471bbe961b0703a62424 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <danielbachhuber@gmail.com> Date: Mon, 24 Jun 2013 11:07:04 +0000 Subject: [PATCH 1883/4858] Fix reference to command --- man-src/site-empty.txt | 2 +- man/site-empty.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/man-src/site-empty.txt b/man-src/site-empty.txt index b97477a0fd..0d95815310 100644 --- a/man-src/site-empty.txt +++ b/man-src/site-empty.txt @@ -1,6 +1,6 @@ ## EXAMPLES - wp blog empty + wp site empty ## OPTIONS diff --git a/man/site-empty.1 b/man/site-empty.1 index f1de33d864..6ce47ca00e 100644 --- a/man/site-empty.1 +++ b/man/site-empty.1 @@ -13,7 +13,7 @@ wp site empty [\-\-yes] . .nf -wp blog empty +wp site empty . .fi . From 2ab4b4fae31a7874d62f5dd418467760e6f7f574 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <danielbachhuber@gmail.com> Date: Mon, 24 Jun 2013 11:16:58 +0000 Subject: [PATCH 1884/4858] Drop the example entirely. Basic usage is covered in the synopsis --- man-src/site-empty.txt | 4 ---- man/site-empty.1 | 8 -------- 2 files changed, 12 deletions(-) diff --git a/man-src/site-empty.txt b/man-src/site-empty.txt index 0d95815310..bbb41c593f 100644 --- a/man-src/site-empty.txt +++ b/man-src/site-empty.txt @@ -1,7 +1,3 @@ -## EXAMPLES - - wp site empty - ## OPTIONS * `--yes`: diff --git a/man/site-empty.1 b/man/site-empty.1 index 6ce47ca00e..0a15512db7 100644 --- a/man/site-empty.1 +++ b/man/site-empty.1 @@ -9,14 +9,6 @@ .SH "SYNOPSIS" wp site empty [\-\-yes] . -.SH "EXAMPLES" -. -.nf - -wp site empty -. -.fi -. .SH "OPTIONS" . .TP From 1a486b2412705e30195bdf3da3e1a190638c327b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 15:00:25 +0300 Subject: [PATCH 1885/4858] more cleanup of option listing --- php/commands/help.php | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index c1cf96b2aa..5e0b1b6690 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -37,19 +37,28 @@ private static function find_subcommand( $args ) { private static function show_help( $command ) { $out = self::get_initial_markdown( $command ); - $extra_markdown_path = self::find_extra_markdown( $command ); - if ( $extra_markdown_path ) { - $out .= file_get_contents( $extra_markdown_path ); - } + $out .= self::get_extra_markdown( $command ); + + // section headers + $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); + + // old-style options + $out = preg_replace( '/\* `(.+)`([^\n]*):\n\n/', "\\1\\2\n\t", $out ); - $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); // section headers - $out = preg_replace( '/^\* `([^`]+)`/m', '\1', $out ); // options $out = str_replace( "\t", ' ', $out ); echo WP_CLI::colorize( $out ); } - private static function find_extra_markdown( $command ) { + private static function get_extra_markdown( $command ) { + $md_file = self::find_extra_markdown_file( $command ); + if ( !$md_file ) + return ''; + + return file_get_contents( $md_file ); + } + + private static function find_extra_markdown_file( $command ) { $cmd_path = Dispatcher\get_path( $command ); array_shift( $cmd_path ); // discard 'wp' $cmd_path = implode( '-', $cmd_path ); From 2c6be8fc7e99af415061e37108d6b0a7f8bdffed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 15:23:42 +0300 Subject: [PATCH 1886/4858] fix indentation for options --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 5e0b1b6690..af94415cad 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -43,7 +43,7 @@ private static function show_help( $command ) { $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); // old-style options - $out = preg_replace( '/\* `(.+)`([^\n]*):\n\n/', "\\1\\2\n\t", $out ); + $out = preg_replace( '/\n\* `(.+)`([^\n]*):\n\n/', "\n\t\\1\\2\n\t\t", $out ); $out = str_replace( "\t", ' ', $out ); From ac7a6df4bfe25cdec3cdc55a7c8c5a73786f0488 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 16:20:34 +0300 Subject: [PATCH 1887/4858] Make `wp` show the same output as `wp help`. --- php/WP_CLI/Dispatcher/CompositeCommand.php | 22 +++++++++ php/WP_CLI/Dispatcher/RootCommand.php | 56 +++++----------------- php/WP_CLI/Runner.php | 6 ++- php/commands/help.php | 26 +--------- templates/man-params.mustache | 8 ++++ 5 files changed, 48 insertions(+), 70 deletions(-) create mode 100644 templates/man-params.mustache diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 8a527fa09f..90dc7fe1b8 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -73,6 +73,28 @@ function show_usage() { \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); } + function get_extra_markdown() { + $md_file = self::find_extra_markdown_file( $this ); + if ( !$md_file ) + return ''; + + return file_get_contents( $md_file ); + } + + private static function find_extra_markdown_file( $command ) { + $cmd_path = get_path( $command ); + array_shift( $cmd_path ); // discard 'wp' + $cmd_path = implode( '-', $cmd_path ); + + foreach ( \WP_CLI::get_man_dirs() as $src_dir ) { + $src_path = "$src_dir/$cmd_path.txt"; + if ( is_readable( $src_path ) ) + return $src_path; + } + + return false; + } + function find_subcommand( &$args ) { $name = array_shift( $args ); diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 03bc8196d0..afae682215 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -14,38 +14,11 @@ function __construct() { $this->name = 'wp'; - $this->shortdesc = ''; - $this->synopsis = ''; + $this->shortdesc = 'Manage WordPress installations through the command-line.'; } - function show_usage() { - \WP_CLI::line( 'Available commands:' ); - - foreach ( $this->get_subcommands() as $command ) { - if ( '_sys' == $command->get_name() ) - continue; - - \WP_CLI::line( sprintf( ' %s %s', - implode( ' ', get_path( $command ) ), - implode( '|', array_keys( $command->get_subcommands() ) ) - ) ); - } - - \WP_CLI::line(<<<EOB - -See 'wp help <command>' for more information on a specific command. - -Global parameters: -EOB - ); - - self::show_synopsis(); - } - - private static function show_synopsis() { - $max_len = 0; - - $lines = array(); + function get_extra_markdown() { + $binding = array(); foreach ( \WP_CLI::$configurator->get_spec() as $key => $details ) { if ( false === $details['runtime'] ) @@ -54,23 +27,18 @@ private static function show_synopsis() { if ( isset( $details['deprecated'] ) ) continue; - $synopsis = ( true === $details['runtime'] ) - ? "--[no-]$key" - : "--$key" . $details['runtime']; - - $cur_len = strlen( $synopsis ); + if ( true === $details['runtime'] ) + $synopsis = "--[no-]$key"; + else + $synopsis = "--$key" . $details['runtime']; - if ( $max_len < $cur_len ) - $max_len = $cur_len; - - $lines[] = array( $synopsis, $details['desc'] ); + $binding['parameters'][] = array( + 'synopsis' => $synopsis, + 'desc' => $details['desc'] + ); } - foreach ( $lines as $line ) { - list( $synopsis, $desc ) = $line; - - \WP_CLI::line( sprintf( ' %s %s', str_pad( $synopsis, $max_len ), $desc ) ); - } + return Utils\mustache_render( 'man-params.mustache', $binding ); } function find_subcommand( &$args ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index d484558651..17426a0353 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -299,8 +299,10 @@ public function before_wp_load() { $this->init_colorization(); $this->init_logger(); - if ( !empty( $this->arguments ) ) - Utils\load_command( $this->arguments[0] ); + if ( empty( $this->arguments ) ) + $this->arguments[] = 'help'; + + Utils\load_command( $this->arguments[0] ); if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { diff --git a/php/commands/help.php b/php/commands/help.php index af94415cad..d1b2cc9456 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -37,10 +37,10 @@ private static function find_subcommand( $args ) { private static function show_help( $command ) { $out = self::get_initial_markdown( $command ); - $out .= self::get_extra_markdown( $command ); + $out .= $command->get_extra_markdown(); // section headers - $out = preg_replace( '/^## ([A-Z]+)/m', '%9\1%n', $out ); + $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); // old-style options $out = preg_replace( '/\n\* `(.+)`([^\n]*):\n\n/', "\n\t\\1\\2\n\t\t", $out ); @@ -50,28 +50,6 @@ private static function show_help( $command ) { echo WP_CLI::colorize( $out ); } - private static function get_extra_markdown( $command ) { - $md_file = self::find_extra_markdown_file( $command ); - if ( !$md_file ) - return ''; - - return file_get_contents( $md_file ); - } - - private static function find_extra_markdown_file( $command ) { - $cmd_path = Dispatcher\get_path( $command ); - array_shift( $cmd_path ); // discard 'wp' - $cmd_path = implode( '-', $cmd_path ); - - foreach ( WP_CLI::get_man_dirs() as $src_dir ) { - $src_path = "$src_dir/$cmd_path.txt"; - if ( is_readable( $src_path ) ) - return $src_path; - } - - return false; - } - private static function get_initial_markdown( $command ) { $name = implode( ' ', Dispatcher\get_path( $command ) ); diff --git a/templates/man-params.mustache b/templates/man-params.mustache new file mode 100644 index 0000000000..2d3383f57f --- /dev/null +++ b/templates/man-params.mustache @@ -0,0 +1,8 @@ +## GLOBAL PARAMETERS + +{{#parameters}} + {{{synopsis}}} + {{desc}} + +{{/parameters}} +Run 'wp help <subcommand>' to get more information on a specific command. From 1c08d00c41b4ca3952079566d764fb0d78c1445c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 16:40:27 +0300 Subject: [PATCH 1888/4858] rename '_sys' to 'cli' --- php/WP_CLI/Runner.php | 4 ++-- php/commands/{_sys.php => cli.php} | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) rename php/commands/{_sys.php => cli.php} (90%) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 17426a0353..87fee00127 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -231,11 +231,11 @@ private static function back_compat_conversions( $args, $assoc_args ) { unset( $assoc_args['json'] ); } - // --{version|info} -> _sys {version|info} + // --{version|info} -> cli {version|info} if ( empty( $args ) ) { foreach ( array( 'version', 'info' ) as $key ) { if ( isset( $assoc_args[ $key ] ) ) { - $args = array( '_sys', $key ); + $args = array( 'cli', $key ); break; } } diff --git a/php/commands/_sys.php b/php/commands/cli.php similarity index 90% rename from php/commands/_sys.php rename to php/commands/cli.php index fefbc22316..b371c23147 100644 --- a/php/commands/_sys.php +++ b/php/commands/cli.php @@ -4,9 +4,11 @@ \WP_CLI\Utils; /** + * Get information about WP-CLI itself. + * * @when before_wp_load */ -class Sys_Command extends WP_CLI_Command { +class CLI_Command extends WP_CLI_Command { private function command_to_array( $command ) { $dump = array( @@ -55,5 +57,5 @@ function cmd_dump() { } } -WP_CLI::add_command( '_sys', 'Sys_Command' ); +WP_CLI::add_command( 'cli', 'CLI_Command' ); From 02a5a2db84488adbf177e9faf9b15396b8de5b53 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 16:50:54 +0300 Subject: [PATCH 1889/4858] ignore first parameter to WP_CLI::add_man_dir() --- php/class-wp-cli.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9f928a481f..1c94a5872a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -22,10 +22,7 @@ class WP_CLI { * Initialize WP_CLI static variables. */ static function init() { - self::add_man_dir( - WP_CLI_ROOT . "/man", - WP_CLI_ROOT . "/man-src" - ); + self::add_man_dir( null, WP_CLI_ROOT . "/man-src" ); self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); self::$root = new Dispatcher\RootCommand; @@ -79,8 +76,8 @@ static function add_command( $name, $class ) { self::$root->add_subcommand( $name, $command ); } - static function add_man_dir( $dest_dir, $src_dir ) { - self::$man_dirs[ $dest_dir ] = $src_dir; + static function add_man_dir( $deprecated = null, $src_dir ) { + self::$man_dirs[] = $src_dir; } static function get_man_dirs() { From d5c3d652e8b3b6f608c6c61af872f0906381495a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 17:12:55 +0300 Subject: [PATCH 1890/4858] remove man/ dir --- man/cache.1 | 101 ------------------------------ man/cap.1 | 52 ---------------- man/comment-approve.1 | 27 -------- man/comment-count.1 | 28 --------- man/comment-create.1 | 35 ----------- man/comment-delete.1 | 33 ---------- man/comment-last.1 | 33 ---------- man/comment-spam.1 | 27 -------- man/comment-status.1 | 27 -------- man/comment-trash.1 | 27 -------- man/comment-unapprove.1 | 27 -------- man/comment-unspam.1 | 27 -------- man/comment-untrash.1 | 27 -------- man/core-config.1 | 64 ------------------- man/core-download.1 | 39 ------------ man/core-init-tests.1 | 45 -------------- man/core-install-network.1 | 31 ---------- man/core-install.1 | 43 ------------- man/core-is-installed.1 | 21 ------- man/core-update-db.1 | 10 --- man/core-update.1 | 37 ----------- man/core-version.1 | 19 ------ man/db.1 | 120 ------------------------------------ man/eval-file.1 | 19 ------ man/eval.1 | 19 ------ man/export.1 | 91 --------------------------- man/help.1 | 26 -------- man/media-import.1 | 72 ---------------------- man/media-regenerate.1 | 35 ----------- man/network-meta.1 | 69 --------------------- man/option.1 | 68 -------------------- man/plugin-activate.1 | 25 -------- man/plugin-deactivate.1 | 25 -------- man/plugin-delete.1 | 27 -------- man/plugin-install.1 | 43 ------------- man/plugin-list.1 | 21 ------- man/plugin-path.1 | 33 ---------- man/plugin-status.1 | 19 ------ man/plugin-toggle.1 | 25 -------- man/plugin-uninstall.1 | 33 ---------- man/plugin-update-all.1 | 27 -------- man/plugin-update.1 | 33 ---------- man/post-create.1 | 53 ---------------- man/post-delete.1 | 35 ----------- man/post-edit.1 | 27 -------- man/post-generate.1 | 57 ----------------- man/post-get.1 | 44 ------------- man/post-list.1 | 43 ------------- man/post-meta.1 | 62 ------------------- man/post-update.1 | 33 ---------- man/rewrite-dump.1 | 19 ------ man/rewrite-flush.1 | 19 ------ man/rewrite-structure.1 | 31 ---------- man/role-create.1 | 35 ----------- man/role-delete.1 | 29 --------- man/role-exists.1 | 30 --------- man/role-list.1 | 33 ---------- man/scaffold-_s.1 | 43 ------------- man/scaffold-child-theme.1 | 55 ----------------- man/scaffold-plugin-tests.1 | 39 ------------ man/scaffold-plugin.1 | 25 -------- man/scaffold-post-type.1 | 43 ------------- man/scaffold-taxonomy.1 | 57 ----------------- man/search-replace.1 | 47 -------------- man/shell.1 | 22 ------- man/site-create.1 | 49 --------------- man/site-delete.1 | 37 ----------- man/site-empty.1 | 19 ------ man/term-create.1 | 57 ----------------- man/term-delete.1 | 33 ---------- man/term-list.1 | 41 ------------ man/term-update.1 | 57 ----------------- man/theme-activate.1 | 19 ------ man/theme-delete.1 | 27 -------- man/theme-install.1 | 35 ----------- man/theme-list.1 | 21 ------- man/theme-path.1 | 33 ---------- man/theme-status.1 | 19 ------ man/theme-update-all.1 | 27 -------- man/theme-update.1 | 33 ---------- man/transient.1 | 54 ---------------- man/user-create.1 | 63 ------------------- man/user-delete.1 | 33 ---------- man/user-generate.1 | 25 -------- man/user-import-csv.1 | 34 ---------- man/user-list.1 | 43 ------------- man/user-meta.1 | 62 ------------------- man/user-remove-role.1 | 28 --------- man/user-set-role.1 | 34 ---------- man/user-update.1 | 33 ---------- 90 files changed, 3407 deletions(-) delete mode 100644 man/cache.1 delete mode 100644 man/cap.1 delete mode 100644 man/comment-approve.1 delete mode 100644 man/comment-count.1 delete mode 100644 man/comment-create.1 delete mode 100644 man/comment-delete.1 delete mode 100644 man/comment-last.1 delete mode 100644 man/comment-spam.1 delete mode 100644 man/comment-status.1 delete mode 100644 man/comment-trash.1 delete mode 100644 man/comment-unapprove.1 delete mode 100644 man/comment-unspam.1 delete mode 100644 man/comment-untrash.1 delete mode 100644 man/core-config.1 delete mode 100644 man/core-download.1 delete mode 100644 man/core-init-tests.1 delete mode 100644 man/core-install-network.1 delete mode 100644 man/core-install.1 delete mode 100644 man/core-is-installed.1 delete mode 100644 man/core-update-db.1 delete mode 100644 man/core-update.1 delete mode 100644 man/core-version.1 delete mode 100644 man/db.1 delete mode 100644 man/eval-file.1 delete mode 100644 man/eval.1 delete mode 100644 man/export.1 delete mode 100644 man/help.1 delete mode 100644 man/media-import.1 delete mode 100644 man/media-regenerate.1 delete mode 100644 man/network-meta.1 delete mode 100644 man/option.1 delete mode 100644 man/plugin-activate.1 delete mode 100644 man/plugin-deactivate.1 delete mode 100644 man/plugin-delete.1 delete mode 100644 man/plugin-install.1 delete mode 100644 man/plugin-list.1 delete mode 100644 man/plugin-path.1 delete mode 100644 man/plugin-status.1 delete mode 100644 man/plugin-toggle.1 delete mode 100644 man/plugin-uninstall.1 delete mode 100644 man/plugin-update-all.1 delete mode 100644 man/plugin-update.1 delete mode 100644 man/post-create.1 delete mode 100644 man/post-delete.1 delete mode 100644 man/post-edit.1 delete mode 100644 man/post-generate.1 delete mode 100644 man/post-get.1 delete mode 100644 man/post-list.1 delete mode 100644 man/post-meta.1 delete mode 100644 man/post-update.1 delete mode 100644 man/rewrite-dump.1 delete mode 100644 man/rewrite-flush.1 delete mode 100644 man/rewrite-structure.1 delete mode 100644 man/role-create.1 delete mode 100644 man/role-delete.1 delete mode 100644 man/role-exists.1 delete mode 100644 man/role-list.1 delete mode 100644 man/scaffold-_s.1 delete mode 100644 man/scaffold-child-theme.1 delete mode 100644 man/scaffold-plugin-tests.1 delete mode 100644 man/scaffold-plugin.1 delete mode 100644 man/scaffold-post-type.1 delete mode 100644 man/scaffold-taxonomy.1 delete mode 100644 man/search-replace.1 delete mode 100644 man/shell.1 delete mode 100644 man/site-create.1 delete mode 100644 man/site-delete.1 delete mode 100644 man/site-empty.1 delete mode 100644 man/term-create.1 delete mode 100644 man/term-delete.1 delete mode 100644 man/term-list.1 delete mode 100644 man/term-update.1 delete mode 100644 man/theme-activate.1 delete mode 100644 man/theme-delete.1 delete mode 100644 man/theme-install.1 delete mode 100644 man/theme-list.1 delete mode 100644 man/theme-path.1 delete mode 100644 man/theme-status.1 delete mode 100644 man/theme-update-all.1 delete mode 100644 man/theme-update.1 delete mode 100644 man/transient.1 delete mode 100644 man/user-create.1 delete mode 100644 man/user-delete.1 delete mode 100644 man/user-generate.1 delete mode 100644 man/user-import-csv.1 delete mode 100644 man/user-list.1 delete mode 100644 man/user-meta.1 delete mode 100644 man/user-remove-role.1 delete mode 100644 man/user-set-role.1 delete mode 100644 man/user-update.1 diff --git a/man/cache.1 b/man/cache.1 deleted file mode 100644 index 7587a2a941..0000000000 --- a/man/cache.1 +++ /dev/null @@ -1,101 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CACHE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cache\fR \- Manage the object cache\. -. -.SH "SYNOPSIS" -wp cache add \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] -. -.P -wp cache decr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] -. -.P -wp cache delete \fIkey\fR [\fIgroup\fR] -. -.P -wp cache flush -. -.P -wp cache get \fIkey\fR [\fIgroup\fR] -. -.P -wp cache incr \fIkey\fR [\fIoffset\fR] [\fIgroup\fR] -. -.P -wp cache replace \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] -. -.P -wp cache set \fIkey\fR \fIvalue\fR [\fIgroup\fR] [\fIexpiration\fR] -. -.P -wp cache type -. -.SH "SUBCOMMANDS" -. -.TP -\fBadd\fR: -. -.IP -Add a value to the object cache\. -. -.TP -\fBdecr\fR: -. -.IP -Decrement a value in the object cache\. -. -.TP -\fBdelete\fR: -. -.IP -Remove a value from the object cache\. -. -.TP -\fBflush\fR: -. -.IP -Flush the object cache\. -. -.TP -\fBget\fR: -. -.IP -Get a value from the object cache\. -. -.TP -\fBincr\fR: -. -.IP -Increment a value in the object cache\. -. -.TP -\fBreplace\fR: -. -.IP -Replace an existing value in the object cache\. -. -.TP -\fBset\fR: -. -.IP -Set a value to the object cache\. -. -.TP -\fBtype\fR: -. -.IP -Attempts to determine which object cache is being used\. -. -.SH "EXAMPLES" -. -.nf - -wp cache set my_key my_value my_group 300 - -wp cache get my_key my_group -. -.fi - diff --git a/man/cap.1 b/man/cap.1 deleted file mode 100644 index fd4b8f669a..0000000000 --- a/man/cap.1 +++ /dev/null @@ -1,52 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CAP" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-cap\fR \- Manage user capabilities\. -. -.SH "SYNOPSIS" -wp cap add \fIrole\fR \fIcap\fR\.\.\. -. -.P -wp cap list \fIrole\fR -. -.P -wp cap remove \fIrole\fR \fIcap\fR\.\.\. -. -.SH "SUBCOMMANDS" -. -.TP -\fBadd\fR: -. -.IP -Add capabilities to a given role\. -. -.TP -\fBlist\fR: -. -.IP -List capabilities for a given role\. -. -.TP -\fBremove\fR: -. -.IP -Remove capabilities from a given role\. -. -.SH "EXAMPLES" -. -.nf - -# Add \'spectate\' capability to \'author\' role -wp cap add \'author\' \'spectate\' - -# Add all caps from \'editor\' role to \'author\' role -wp cap list \'editor\' | xargs wp cap add \'author\' - -# Remove all caps from \'editor\' role that also appear in \'author\' role -wp cap list \'author\' | xargs wp cap remove \'editor\' -. -.fi - diff --git a/man/comment-approve.1 b/man/comment-approve.1 deleted file mode 100644 index 759498b75c..0000000000 --- a/man/comment-approve.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-APPROVE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-approve\fR \- Approve a comment\. -. -.SH "SYNOPSIS" -wp comment approve \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to approve\. -. -.SH "EXAMPLES" -. -.nf - -wp comment approve 1337 -. -.fi - diff --git a/man/comment-count.1 b/man/comment-count.1 deleted file mode 100644 index 4cb5c913b5..0000000000 --- a/man/comment-count.1 +++ /dev/null @@ -1,28 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-COUNT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-count\fR \- Count comments, on whole blog or on a given post\. -. -.SH "SYNOPSIS" -wp comment count [\fIpost\-id\fR] -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the post to count comments in -. -.SH "EXAMPLES" -. -.nf - -wp comment count -wp comment count 42 -. -.fi - diff --git a/man/comment-create.1 b/man/comment-create.1 deleted file mode 100644 index 8ca70f0cec..0000000000 --- a/man/comment-create.1 +++ /dev/null @@ -1,35 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-create\fR \- Insert a comment\. -. -.SH "SYNOPSIS" -wp comment create \-\-\fIfield\fR=\fIvalue\fR [\-\-porcelain] -. -.SH "OPTIONS" -. -.TP -\fB\-\-<field>\fR=\fIvalue\fR: -. -.IP -Field values for the new comment\. See wp_insert_comment()\. -. -.TP -\fB\-\-porcelain\fR: -. -.IP -Output just the new comment id\. -. -.SH "EXAMPLES" -. -.nf - -wp comment create \-\-comment_post_ID=15 \-\-comment_content="hello blog" -. -.fi -. -.P -\-\-comment_author="wp\-cli" diff --git a/man/comment-delete.1 b/man/comment-delete.1 deleted file mode 100644 index fe9567b793..0000000000 --- a/man/comment-delete.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-delete\fR \- Delete a comment\. -. -.SH "SYNOPSIS" -wp comment delete \fIid\fR [\-\-force] -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to delete\. -. -.TP -\fB\-\-force\fR: -. -.IP -Skip the trash bin\. -. -.SH "EXAMPLES" -. -.nf - -wp comment delete 1337 \-\-force -. -.fi - diff --git a/man/comment-last.1 b/man/comment-last.1 deleted file mode 100644 index 47b760f839..0000000000 --- a/man/comment-last.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-LAST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-last\fR \- Get last approved comment\. -. -.SH "SYNOPSIS" -wp comment last [\-\-id] [\-\-full] -. -.SH "OPTIONS" -. -.TP -\fB\-\-id\fR: -. -.IP -Output just the last comment id\. -. -.TP -\fB\-\-full\fR: -. -.IP -Output complete comment information\. -. -.SH "EXAMPLES" -. -.nf - -wp comment last \-\-full -. -.fi - diff --git a/man/comment-spam.1 b/man/comment-spam.1 deleted file mode 100644 index 1f07321783..0000000000 --- a/man/comment-spam.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-SPAM" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-spam\fR \- Spam a comment\. -. -.SH "SYNOPSIS" -wp comment spam \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to mark as spam\. -. -.SH "EXAMPLES" -. -.nf - -wp comment spam 1337 -. -.fi - diff --git a/man/comment-status.1 b/man/comment-status.1 deleted file mode 100644 index 70c4ddd4ef..0000000000 --- a/man/comment-status.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-STATUS" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-status\fR \- Get status of a comment\. -. -.SH "SYNOPSIS" -wp comment status \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to check -. -.SH "EXAMPLES" -. -.nf - -wp comment status 1337 -. -.fi - diff --git a/man/comment-trash.1 b/man/comment-trash.1 deleted file mode 100644 index 2deba83bae..0000000000 --- a/man/comment-trash.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-TRASH" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-trash\fR \- Trash a comment\. -. -.SH "SYNOPSIS" -wp comment trash \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to trash\. -. -.SH "EXAMPLES" -. -.nf - -wp comment trash 1337 -. -.fi - diff --git a/man/comment-unapprove.1 b/man/comment-unapprove.1 deleted file mode 100644 index e6d18d043f..0000000000 --- a/man/comment-unapprove.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-UNAPPROVE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-unapprove\fR \- Unapprove a comment\. -. -.SH "SYNOPSIS" -wp comment unapprove \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to unapprove\. -. -.SH "EXAMPLES" -. -.nf - -wp comment unapprove 1337 -. -.fi - diff --git a/man/comment-unspam.1 b/man/comment-unspam.1 deleted file mode 100644 index 41d7dd87f0..0000000000 --- a/man/comment-unspam.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-UNSPAM" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-unspam\fR \- Unspam a comment\. -. -.SH "SYNOPSIS" -wp comment unspam \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to unmark as spam\. -. -.SH "EXAMPLES" -. -.nf - -wp comment unspam 1337 -. -.fi - diff --git a/man/comment-untrash.1 b/man/comment-untrash.1 deleted file mode 100644 index ca2caa724c..0000000000 --- a/man/comment-untrash.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-COMMENT\-UNTRASH" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-comment\-untrash\fR \- Untrash a comment\. -. -.SH "SYNOPSIS" -wp comment untrash \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the comment to untrash\. -. -.SH "EXAMPLES" -. -.nf - -wp comment untrash 1337 -. -.fi - diff --git a/man/core-config.1 b/man/core-config.1 deleted file mode 100644 index 4a8d6e8d91..0000000000 --- a/man/core-config.1 +++ /dev/null @@ -1,64 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-CONFIG" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-config\fR \- Set up a wp\-config\.php file\. -. -.SH "SYNOPSIS" -wp core config \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\-\-dbpass=\fIpassword\fR] [\-\-dbhost=\fIhost\fR] [\-\-dbprefix=\fIprefix\fR] [\-\-extra\-php] -. -.SH "OPTIONS" -. -.TP -\fB\-\-dbname\fR=\fIdbname\fR: -. -.IP -Set the database name\. -. -.TP -\fB\-\-dbuser\fR=\fIdbuser\fR: -. -.IP -Set the database user\. -. -.TP -\fB\-\-dbpass\fR=\fIdbpass\fR: -. -.IP -Set the database user password\. -. -.TP -\fB\-\-dbhost\fR=\fIdbhost\fR: -. -.IP -Set the database host\. Default: \'localhost\' -. -.TP -\fB\-\-dbprefix\fR=\fIdbprefix\fR: -. -.IP -Set the database table prefix\. Default: \'wp_\' -. -.TP -\fB\-\-extra\-php\fR: -. -.IP -If set, the command reads additional PHP code from STDIN\. -. -.SH "EXAMPLES" -. -.nf - -# Standard wp\-config\.php file -wp core config \-\-dbname=testing \-\-dbuser=wp \-\-dbpass=securepswd - -# Enable WP_DEBUG and WP_DEBUG_LOG -wp core config \-\-dbname=testing \-\-dbuser=wp \-\-dbpass=securepswd \-\-extra\-php <<PHP -define( \'WP_DEBUG\', true ); -define( \'WP_DEBUG_LOG\', true ); -PHP -. -.fi - diff --git a/man/core-download.1 b/man/core-download.1 deleted file mode 100644 index 7f607ca286..0000000000 --- a/man/core-download.1 +++ /dev/null @@ -1,39 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-DOWNLOAD" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-download\fR \- Download core WordPress files\. -. -.SH "SYNOPSIS" -wp core download [\-\-locale=\fIlocale\fR] [\-\-version=\fIversion\fR] [\-\-path=\fIpath\fR] [\-\-force] -. -.SH "OPTIONS" -. -.TP -\fB\-\-locale\fR=\fIlocale\fR: -. -.IP -Select which language you want to download\. The \-\-version parameter is ignored in this case\. -. -.TP -\fB\-\-version\fR=\fIversion\fR: -. -.IP -Select which version you want to download\. -. -.TP -\fB\-\-force\fR: -. -.IP -Overwrites existing files, if present\. -. -.SH "EXAMPLES" -. -.nf - -wp core download \-\-version=3\.3 -. -.fi - diff --git a/man/core-init-tests.1 b/man/core-init-tests.1 deleted file mode 100644 index e5001c3311..0000000000 --- a/man/core-init-tests.1 +++ /dev/null @@ -1,45 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-INIT\-TESTS" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-init\-tests\fR \- Set up the official test suite using the current WordPress instance\. -. -.SH "SYNOPSIS" -wp core init\-tests [\fIpath\fR] \-\-dbname=\fIname\fR \-\-dbuser=\fIuser\fR [\-\-dbpass=\fIpassword\fR] -. -.SH "OPTIONS" -. -.TP -\fB<path>\fR: -. -.IP -The directory in which to download the testing suite files\. (Optional) -. -.TP -\fB\-\-dbname\fR=\fIdbname\fR: -. -.IP -Set the database name\. \fBWARNING\fR: The database will be whipped every time you run the tests\. -. -.TP -\fB\-\-dbuser\fR=\fIdbuser\fR: -. -.IP -Set the database user\. -. -.TP -\fB\-\-dbpass\fR=\fIdbpass\fR: -. -.IP -Set the database user password\. -. -.SH "EXAMPLE" -. -.nf - -wp core init\-tests ~/svn/wp\-tests \-\-dbname=wp_test \-\-dbuser=wp_test -. -.fi - diff --git a/man/core-install-network.1 b/man/core-install-network.1 deleted file mode 100644 index 60fdbfc0e7..0000000000 --- a/man/core-install-network.1 +++ /dev/null @@ -1,31 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-INSTALL\-NETWORK" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-install\-network\fR \- Transform a single\-site install into a multi\-site install\. -. -.SH "SYNOPSIS" -wp core install\-network \-\-title=\fInetwork\-title\fR [\-\-base=\fIurl\-path\fR] [\-\-subdomains] -. -.SH "OPTIONS" -. -.TP -\fB\-\-title\fR=\fIsite\-title\fR: -. -.IP -The title of the new network\. -. -.TP -\fB\-\-base\fR=\fIurl\-path\fR: -. -.IP -Base path after the domain name that each site url will start with\. Default: \'/\' -. -.TP -\fB\-\-subdomains\fR: -. -.IP -If passed, the network will use subdomains, instead of subdirectories\. - diff --git a/man/core-install.1 b/man/core-install.1 deleted file mode 100644 index 8667886296..0000000000 --- a/man/core-install.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-INSTALL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-install\fR \- Create the WordPress tables in the database\. -. -.SH "SYNOPSIS" -wp core install \-\-url=\fIurl\fR \-\-title=\fIsite\-title\fR [\-\-admin_name=\fIusername\fR] \-\-admin_email=\fIemail\fR \-\-admin_password=\fIpassword\fR -. -.SH "OPTIONS" -. -.TP -\fB\-\-url\fR=\fIurl\fR: -. -.IP -The address of the new site\. -. -.TP -\fB\-\-title\fR=\fIsite\-title\fR: -. -.IP -The title of the new site\. -. -.TP -\fB\-\-admin_name\fR=\fIusername\fR: -. -.IP -The name of the admin user\. Default: \'admin\' -. -.TP -\fB\-\-admin_password\fR=\fIpassword\fR: -. -.IP -The password for the admin user\. -. -.TP -\fB\-\-admin_email\fR=\fIemail\fR: -. -.IP -The email address for the admin user\. - diff --git a/man/core-is-installed.1 b/man/core-is-installed.1 deleted file mode 100644 index 56f61768b5..0000000000 --- a/man/core-is-installed.1 +++ /dev/null @@ -1,21 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-IS\-INSTALLED" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-is\-installed\fR \- Determine if the WordPress tables are installed\. -. -.SH "SYNOPSIS" -wp core is\-installed -. -.SH "EXAMPLES" -. -.nf - -if ! $(wp core is\-installed); then - wp core install -fi -. -.fi - diff --git a/man/core-update-db.1 b/man/core-update-db.1 deleted file mode 100644 index 1dd86294fd..0000000000 --- a/man/core-update-db.1 +++ /dev/null @@ -1,10 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-UPDATE\-DB" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-update\-db\fR \- Update the WordPress database\. -. -.SH "SYNOPSIS" -wp core update\-db diff --git a/man/core-update.1 b/man/core-update.1 deleted file mode 100644 index cb5848fb20..0000000000 --- a/man/core-update.1 +++ /dev/null @@ -1,37 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-update\fR \- Update WordPress\. -. -.SH "SYNOPSIS" -wp core update [\fIzip\fR] [\-\-version=\fIversion\fR] [\-\-force] -. -.SH "OPTIONS" -. -.TP -\fB\-\-version=\fR\fInew_version\fR [package/zip]: -. -.IP -When passed, updates to new_version, optionally using package/zip as input\. -. -.TP -\fB\-\-force\fR: -. -.IP -Will update even when current WP version < passed version\. Use with caution\. -. -.SH "EXAMPLES" -. -.nf - -wp core update - -wp core update \-\-version=3\.4 \.\./latest\.zip - -wp core update \-\-version=3\.1 \-\-force -. -.fi - diff --git a/man/core-version.1 b/man/core-version.1 deleted file mode 100644 index c3a37f1c15..0000000000 --- a/man/core-version.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-CORE\-VERSION" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-core\-version\fR \- Display the WordPress version\. -. -.SH "SYNOPSIS" -wp core version [\-\-extra] -. -.SH "OPTIONS" -. -.TP -\fB\-\-extra\fR: -. -.IP -Show extended version information\. - diff --git a/man/db.1 b/man/db.1 deleted file mode 100644 index 7524abedd3..0000000000 --- a/man/db.1 +++ /dev/null @@ -1,120 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-DB" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-db\fR \- Perform basic database operations\. -. -.SH "SYNOPSIS" -wp db cli -. -.P -wp db create -. -.P -wp db drop [\-\-yes] -. -.P -wp db export [\fIfile\fR] -. -.P -wp db import [\fIfile\fR] -. -.P -wp db optimize -. -.P -wp db query [\fIsql\fR] -. -.P -wp db repair -. -.P -wp db reset [\-\-yes] -. -.SH "SUBCOMMANDS" -. -.TP -\fBcli\fR: -. -.IP -Open a mysql console using the WordPress credentials\. -. -.TP -\fBcreate\fR: -. -.IP -Create the database, as specified in wp\-config\.php -. -.TP -\fBdrop\fR: -. -.IP -Delete the database\. -. -.TP -\fBexport\fR: -. -.IP -Exports the database using mysqldump\. -. -.TP -\fBimport\fR: -. -.IP -Import database from a file\. -. -.TP -\fBoptimize\fR: -. -.IP -Optimize the database\. -. -.TP -\fBquery\fR: -. -.IP -Execute a query against the database\. -. -.TP -\fBrepair\fR: -. -.IP -Repair the database\. -. -.TP -\fBreset\fR: -. -.IP -Remove all tables from the database\. -. -.SH "OPTIONS" -. -.TP -\fB\-\-yes\fR: -. -.IP -Answer yes to the confirmation message\. -. -.TP -\fB<file>\fR: -. -.IP -The name of the export file\. If omitted, it will be \'{dbname}\.sql\' -. -.TP -\fB<SQL>\fR: -. -.IP -A SQL query\. -. -.SH "EXAMPLES" -. -.nf - -# execute a query stored in a file -wp db query < debug\.sql -. -.fi - diff --git a/man/eval-file.1 b/man/eval-file.1 deleted file mode 100644 index fc8fb2cafd..0000000000 --- a/man/eval-file.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-EVAL\-FILE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-eval\-file\fR \- Load and execute a PHP file after loading WordPress\. -. -.SH "SYNOPSIS" -wp eval\-file \fIpath\fR -. -.SH "EXAMPLES" -. -.nf - -wp eval\-file my\-code\.php -. -.fi - diff --git a/man/eval.1 b/man/eval.1 deleted file mode 100644 index 644451e322..0000000000 --- a/man/eval.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-EVAL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-eval\fR \- Execute arbitrary PHP code after loading WordPress\. -. -.SH "SYNOPSIS" -wp eval \fIphp\-code\fR -. -.SH "EXAMPLES" -. -.nf - -wp eval \'echo WP_CONTENT_DIR;\' -. -.fi - diff --git a/man/export.1 b/man/export.1 deleted file mode 100644 index e4aaf633b0..0000000000 --- a/man/export.1 +++ /dev/null @@ -1,91 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-EXPORT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-export\fR \- Export content to a WXR file\. -. -.SH "SYNOPSIS" -wp export [\-\-dir=\fIdir\fR] [\-\-start_date=\fIdate\fR] [\-\-end_date=\fIdate\fR] [\-\-post_type=\fIptype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post__in=\fIpids\fR] [\-\-author=\fIlogin\fR] [\-\-category=\fIcat\fR] [\-\-skip_comments] [\-\-file_item_count=\fIcount\fR] [\-\-verbose] -. -.SH "OPTIONS" -. -.TP -\fB\-\-dir\fR=\fIdirname\fR: -. -.IP -Full path to directory where WXR export files should be stored\. Defaults to current working directory\. -. -.TP -\fB\-\-skip_comments\fR: -. -.IP -Don\'t export comments\. -. -.TP -\fB\-\-file_item_count\fR=\fIcount\fR: -. -.IP -Break export into files with N posts\. -. -.TP -\fB\-\-verbose\fR: -. -.IP -Show more information about the process on STDOUT\. -. -.SH "FILTERS" -. -.TP -\fB\-\-start_date\fR=\fIdate\fR: -. -.IP -Export only posts newer than this date, in format YYYY\-MM\-DD\. -. -.TP -\fB\-\-end_date\fR=\fIdate\fR: -. -.IP -Export only posts older than this date, in format YYYY\-MM\-DD\. -. -.TP -\fB\-\-post_type\fR=\fIpost_type\fR: -. -.IP -Export only posts with this post_type\. -. -.TP -\fB\-\-post__in\fR=\fIpid\fR: -. -.IP -Export all posts specified as a comma\-separated list of IDs\. -. -.TP -\fB\-\-author\fR=<login/id>: -. -.IP -Export only posts by this author\. -. -.TP -\fB\-\-category\fR=\fIcategory\-id\fR: -. -.IP -Export only posts in this category\. -. -.TP -\fB\-\-post_status\fR=\fIstatus\fR: -. -.IP -Export only posts with this status\. -. -.SH "EXAMPLES" -. -.nf - -wp export \-\-dir=/tmp/ \-\-user=admin \-\-post_type=post \-\-start_date=2011\-01\-01 \-\-end_date=2011\-12\-31 - -wp export \-\-dir=/tmp/ \-\-post__in=123,124,125 -. -.fi - diff --git a/man/help.1 b/man/help.1 deleted file mode 100644 index 9b707455e8..0000000000 --- a/man/help.1 +++ /dev/null @@ -1,26 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-HELP" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-help\fR \- Get help on a certain topic\. -. -.SH "SYNOPSIS" -wp help [\fIcommand\fR] [\-\-gen] -. -.SH "EXAMPLES" -. -.nf - -# (re)generates all man pages -wp help \-\-gen - -# (re)generate man pages for the `core` command -wp help \-\-gen core - -# (re)generate man page only for the `core download` subcommand -wp help \-\-gen core download -. -.fi - diff --git a/man/media-import.1 b/man/media-import.1 deleted file mode 100644 index 8ef92207d1..0000000000 --- a/man/media-import.1 +++ /dev/null @@ -1,72 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-MEDIA\-IMPORT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-media\-import\fR \- Create attachments from local files or from URLs\. -. -.SH "SYNOPSIS" -wp media import \fIfile\fR\.\.\. [\-\-post_id=\fIid\fR] [\-\-title=\fItitle\fR] [\-\-caption=\fIcaption\fR] [\-\-alt=\fItext\fR] [\-\-desc=\fIdescription\fR] [\-\-featured_image] -. -.SH "OPTIONS" -. -.IP "\(bu" 4 -\fB<file>\fR: -. -.IP -Path to file or files to be imported\. Supports the glob(3) capabilities of the current shell\. If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be downloaded to a temp file before being sideloaded\. -. -.IP "\(bu" 4 -\fB\-\-post_id=<post_id>\fR -. -.IP -ID of the post to attach the imported files to -. -.IP "\(bu" 4 -\fB\-\-title=<title>\fR -. -.IP -Attachment title (post title field) -. -.IP "\(bu" 4 -\fB\-\-caption=<caption>\fR -. -.IP -Caption for attachent (post excerpt field) -. -.IP "\(bu" 4 -\fB\-\-alt=<alt_text>\fR -. -.IP -Alt text for image (saved as post meta) -. -.IP "\(bu" 4 -\fB\-\-desc=<description>\fR -. -.IP -"Description" field (post content) of attachment post -. -.IP "\(bu" 4 -\fB\-\-featured_image\fR -. -.IP -If set, set the imported image as the Featured Image of the post its attached to\. -. -.IP "" 0 -. -.SH "EXAMPLES" -. -.nf - -# Import all jpgs in the current user\'s "Pictures" directory, not attached to any post -wp media import ~/Pictures/**/*\.jpg - -# Import a local image and set it to be the post thumbnail for a post -wp media import ~/Downloads/image\.png \-\-post_id=123 \-\-title="A downloaded picture" \-\-featured_image - -# Import an image from the web -wp media import http://s\.wordpress\.org/style/images/wp\-header\-logo\.png \-\-title=\'The WordPress logo\' \-\-alt="Semantic personal publishing" -. -.fi - diff --git a/man/media-regenerate.1 b/man/media-regenerate.1 deleted file mode 100644 index c829722ac0..0000000000 --- a/man/media-regenerate.1 +++ /dev/null @@ -1,35 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-MEDIA\-REGENERATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-media\-regenerate\fR \- Regenerate thumbnail(s)\. -. -.SH "SYNOPSIS" -wp media regenerate \fIattachment\-id\fR\.\.\. [\-\-yes] -. -.SH "OPTIONS" -. -.TP -\fB\-\-yes\fR: -. -.IP -Answer yes to the confirmation message\. -. -.TP -\fB<attachment\-id>\fR: -. -.IP -One or more IDs of the attachments to regenerate\. -. -.SH "EXAMPLES" -. -.nf - -wp media regenerate 123 1337 - -wp media regenerate \-\-yes -. -.fi - diff --git a/man/network-meta.1 b/man/network-meta.1 deleted file mode 100644 index 0beb7eb4a8..0000000000 --- a/man/network-meta.1 +++ /dev/null @@ -1,69 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-NETWORK\-META" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-network\-meta\fR \- Manage network custom fields\. -. -.SH "SYNOPSIS" -wp network\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] -. -.P -wp network\-meta delete \fIid\fR \fIkey\fR -. -.P -wp network\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] -. -.P -wp network\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] -. -.SH "SUBCOMMANDS" -. -.TP -\fBadd\fR: -. -.IP -Add a meta field\. -. -.TP -\fBdelete\fR: -. -.IP -Delete a meta field\. -. -.TP -\fBget\fR: -. -.IP -Get meta field value\. -. -.TP -\fBupdate\fR: -. -.IP -Update a meta field\. -. -.SH "OPTIONS" -. -.TP -\fB<id>\fR: -. -.IP -The network id (usually 1)\. -. -.TP -\fB\-\-format=json\fR: -. -.IP -Encode/decode values as JSON\. -. -.SH "EXAMPLES" -. -.nf - -# get a list of super\-admins -wp network\-meta get 1 site_admins -. -.fi - diff --git a/man/option.1 b/man/option.1 deleted file mode 100644 index 69a8fb23b6..0000000000 --- a/man/option.1 +++ /dev/null @@ -1,68 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-OPTION" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-option\fR \- Manage WordPress options\. -. -.SH "SYNOPSIS" -wp option add \fIkey\fR [\-\-format=\fIformat\fR] -. -.P -wp option delete \fIkey\fR -. -.P -wp option get \fIkey\fR [\-\-format=\fIformat\fR] -. -.P -wp option update \fIkey\fR [\-\-format=\fIformat\fR] -. -.SH "SUBCOMMANDS" -. -.TP -\fBadd\fR: -. -.IP -Add an option\. -. -.TP -\fBdelete\fR: -. -.IP -Delete an option\. -. -.TP -\fBget\fR: -. -.IP -Get an option\. -. -.TP -\fBupdate\fR: -. -.IP -Update an option\. -. -.SH "OPTIONS" -. -.TP -\fB\-\-format=json\fR: -. -.IP -Encode/decode values as JSON\. -. -.SH "EXAMPLES" -. -.nf - -wp option get siteurl - -wp option add my_option foobar - -wp option update my_option \'{"foo": "bar"}\' \-\-format=json - -wp option delete my_option -. -.fi - diff --git a/man/plugin-activate.1 b/man/plugin-activate.1 deleted file mode 100644 index a5355ada74..0000000000 --- a/man/plugin-activate.1 +++ /dev/null @@ -1,25 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-ACTIVATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-activate\fR \- Activate a plugin\. -. -.SH "SYNOPSIS" -wp plugin activate \fIplugin\fR [\-\-network] -. -.SH "OPTIONS" -. -.TP -\fB<plugin>\fR: -. -.IP -The plugin to activate\. -. -.TP -\fB\-\-network\fR: -. -.IP -If set, the plugin will be activated for the entire multisite network\. - diff --git a/man/plugin-deactivate.1 b/man/plugin-deactivate.1 deleted file mode 100644 index 332b91a115..0000000000 --- a/man/plugin-deactivate.1 +++ /dev/null @@ -1,25 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-DEACTIVATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-deactivate\fR \- Deactivate a plugin\. -. -.SH "SYNOPSIS" -wp plugin deactivate \fIplugin\fR [\-\-network] -. -.SH "OPTIONS" -. -.TP -\fB<plugin>\fR: -. -.IP -The plugin to deactivate\. -. -.TP -\fB\-\-network\fR: -. -.IP -If set, the plugin will be deactivated for the entire multisite network\. - diff --git a/man/plugin-delete.1 b/man/plugin-delete.1 deleted file mode 100644 index 41b1927e0b..0000000000 --- a/man/plugin-delete.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-delete\fR \- Delete plugin files\. -. -.SH "SYNOPSIS" -wp plugin delete \fIplugin\fR -. -.SH "OPTIONS" -. -.TP -\fIplugin\fR: -. -.IP -The plugin to delete\. -. -.SH "EXAMPLES" -. -.nf - -wp plugin delete hello -. -.fi - diff --git a/man/plugin-install.1 b/man/plugin-install.1 deleted file mode 100644 index 557ec7db76..0000000000 --- a/man/plugin-install.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-INSTALL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-install\fR \- Install a plugin\. -. -.SH "SYNOPSIS" -wp plugin install \fIplugin|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] -. -.SH "OPTIONS" -. -.TP -\fIplugin\fR: -. -.IP -A plugin slug or the path to a zip file\. -. -.TP -\fB\-\-version\fR=\fIversion\fR: -. -.IP -If set, get that particular version from wordpress\.org, instead of the stable version\. -. -.TP -\fB\-\-activate\fR: -. -.IP -If set, the plugin will be activated immediately after install\. -. -.SH "EXAMPLES" -. -.nf - -wp plugin install bbpress \-\-version=2\.1 \-\-activate - -wp plugin install bbpress \-\-version=dev - -wp plugin install \.\./my\-plugin\.zip -. -.fi - diff --git a/man/plugin-list.1 b/man/plugin-list.1 deleted file mode 100644 index fd23e19af9..0000000000 --- a/man/plugin-list.1 +++ /dev/null @@ -1,21 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-list\fR \- Get a list of plugins\. -. -.SH "SYNOPSIS" -wp plugin list [\-\-format=\fIformat\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-format\fR=\fIformat\fR: -. -.IP -Output list as table, CSV or JSON\. Defaults to table\. -. -.SH "EXAMPLES" -wp plugin list \-\-format=json diff --git a/man/plugin-path.1 b/man/plugin-path.1 deleted file mode 100644 index 7b4b33bb07..0000000000 --- a/man/plugin-path.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-PATH" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-path\fR \- Get the path to a plugin or to the plugin directory\. -. -.SH "SYNOPSIS" -wp plugin path [\fIplugin\fR] [\-\-dir] -. -.SH "OPTIONS" -. -.TP -\fB<plugin>\fR: -. -.IP -The plugin to get the path to\. If not set, will return the path to the plugins directory\. -. -.TP -\fB\-\-dir\fR: -. -.IP -If set, get the path to the closest parent directory, instead of the plugin file\. -. -.SH "EXAMPLES" -. -.nf - -cd $(wp theme path) -. -.fi - diff --git a/man/plugin-status.1 b/man/plugin-status.1 deleted file mode 100644 index 797ffa320e..0000000000 --- a/man/plugin-status.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-STATUS" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-status\fR \- See the status of one or all plugins\. -. -.SH "SYNOPSIS" -wp plugin status [\fIplugin\fR] -. -.SH "OPTIONS" -. -.TP -\fB<plugin>\fR: -. -.IP -A particular plugin to show the status for\. - diff --git a/man/plugin-toggle.1 b/man/plugin-toggle.1 deleted file mode 100644 index 3c8e567c15..0000000000 --- a/man/plugin-toggle.1 +++ /dev/null @@ -1,25 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-TOGGLE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-toggle\fR \- Toggle a plugin\'s activation state\. -. -.SH "SYNOPSIS" -wp plugin toggle \fIplugin\fR [\-\-network] -. -.SH "OPTIONS" -. -.TP -\fB<plugin>\fR: -. -.IP -The plugin to toggle\. -. -.TP -\fB\-\-network\fR: -. -.IP -If set, the plugin will be toggled for the entire multisite network\. - diff --git a/man/plugin-uninstall.1 b/man/plugin-uninstall.1 deleted file mode 100644 index fa2fff4953..0000000000 --- a/man/plugin-uninstall.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-UNINSTALL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-uninstall\fR \- Uninstall a plugin\. -. -.SH "SYNOPSIS" -wp plugin uninstall \fIplugin\fR [\-\-no\-delete] -. -.SH "OPTIONS" -. -.TP -\fIplugin\fR: -. -.IP -The plugin to uninstall\. -. -.TP -\fB\-\-no\-delete\fR: -. -.IP -If set, the plugin files will not be deleted\. Only the uninstall procedure will be run\. -. -.SH "EXAMPLES" -. -.nf - -wp plugin uninstall hello -. -.fi - diff --git a/man/plugin-update-all.1 b/man/plugin-update-all.1 deleted file mode 100644 index ae85d459a2..0000000000 --- a/man/plugin-update-all.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-UPDATE\-ALL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-update\-all\fR \- Update all plugins\. -. -.SH "SYNOPSIS" -wp plugin update\-all [\-\-dry\-run] -. -.SH "OPTIONS" -. -.TP -\fB\-\-dry\-run\fR: -. -.IP -Pretend to do the updates, to see what would happen\. -. -.SH "EXAMPLES" -. -.nf - -wp plugin update\-all -. -.fi - diff --git a/man/plugin-update.1 b/man/plugin-update.1 deleted file mode 100644 index cd26ed8e9c..0000000000 --- a/man/plugin-update.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-PLUGIN\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-plugin\-update\fR \- Update a plugin\. -. -.SH "SYNOPSIS" -wp plugin update \fIplugin\fR [\-\-version=\fIversion\fR] -. -.SH "OPTIONS" -. -.TP -\fIplugin\fR: -. -.IP -The plugin to update\. -. -.TP -\fB\-\-version=dev\fR: -. -.IP -If set, the plugin will be updated to the latest development version, regardless of what version is currently installed\. -. -.SH "EXAMPLES" -. -.nf - -wp plugin update bbpress \-\-version=dev -. -.fi - diff --git a/man/post-create.1 b/man/post-create.1 deleted file mode 100644 index 7dbc248443..0000000000 --- a/man/post-create.1 +++ /dev/null @@ -1,53 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-create\fR \- Create a post\. -. -.SH "SYNOPSIS" -wp post create [\fIfilename\fR] \-\-\fIfield\fR=\fIvalue\fR [\-\-edit] [\-\-porcelain] -. -.SH "OPTIONS" -. -.TP -\fB<filename>\fR: -. -.IP -Read post content from \fIfilename\fR\. If this value is present, the \fB\-\-post_content\fR argument will be ignored\. -. -.IP -Passing \fB\-\fR as the filename will cause post content to be read from STDIN\. -. -.TP -\fB\-\-<field>\fR=\fIvalue\fR: -. -.IP -Field values for the new post\. See wp_insert_post()\. -. -.TP -\fB\-\-edit\fR: -. -.IP -Immediately open system\'s editor to write or edit post content\. -. -.IP -(If content is read from a file, from STDIN, or from the \fB\-\-post_content\fR argument, that text will be loaded into the editor; otherwise, an empty file will be opened\.) -. -.TP -\fB\-\-porcelain\fR: -. -.IP -Output just the new post id\. -. -.SH "EXAMPLES" -. -.nf - -wp post create \-\-post_type=page \-\-post_status=publish \-\-post_title=\'A future post\' \-\-post\-status=future \-\-post_date=\'2020\-12\-01 07:00:00\' - -wp post create page\.txt \-\-post_type=page \-\-post_title=\'Page from file\' -. -.fi - diff --git a/man/post-delete.1 b/man/post-delete.1 deleted file mode 100644 index f163575f26..0000000000 --- a/man/post-delete.1 +++ /dev/null @@ -1,35 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-delete\fR \- Delete a post by ID\. -. -.SH "SYNOPSIS" -wp post delete \fIid\fR\.\.\. [\-\-force] -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the post to delete\. -. -.TP -\fB\-\-force\fR: -. -.IP -Skip the trash bin\. -. -.SH "EXAMPLES" -. -.nf - -wp post delete 123 \-\-force - -wp post delete $(wp post list \-\-post_type=\'page\' \-\-format=ids) -. -.fi - diff --git a/man/post-edit.1 b/man/post-edit.1 deleted file mode 100644 index 9ce9629024..0000000000 --- a/man/post-edit.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-EDIT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-edit\fR \- Launch system editor to edit post content\. -. -.SH "SYNOPSIS" -wp post edit \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB<id>\fR: -. -.IP -The ID of the post to edit\. -. -.SH "EXAMPLES" -. -.nf - -wp post edit 123 -. -.fi - diff --git a/man/post-generate.1 b/man/post-generate.1 deleted file mode 100644 index d89efebe9d..0000000000 --- a/man/post-generate.1 +++ /dev/null @@ -1,57 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-GENERATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-generate\fR \- Generate some posts\. -. -.SH "SYNOPSIS" -wp post generate [\-\-count=\fInumber\fR] [\-\-post_type=\fItype\fR] [\-\-post_status=\fIstatus\fR] [\-\-post_author=\fIlogin\fR] [\-\-post_date=\fIyyyy\-mm\-dd\fR] [\-\-max_depth=\fInumber\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-count\fR=\fInumber\fR: -. -.IP -How many posts to generate\. Default: 100 -. -.TP -\fB\-\-post_type\fR=\fItype\fR: -. -.IP -The type of the generated posts\. Default: \'post\' -. -.TP -\fB\-\-post_status\fR=\fIstatus\fR: -. -.IP -The status of the generated posts\. Default: \'publish\' -. -.TP -\fB\-\-post_author\fR=\fIlogin\fR: -. -.IP -The author of the generated posts\. Default: none -. -.TP -\fB\-\-post_date\fR=\fIyyyy\-mm\-dd\fR: -. -.IP -The date of the generated posts\. Default: current date -. -.TP -\fB\-\-max_depth\fR=\fInumber\fR: -. -.IP -For hierarchical post types, generate child posts down to a certain depth\. Default: 1 -. -.SH "EXAMPLES" -. -.nf - -wp post generate \-\-count=10 \-\-post_type=page \-\-post_date=1999\-01\-04 -. -.fi - diff --git a/man/post-get.1 b/man/post-get.1 deleted file mode 100644 index 94df8e63b5..0000000000 --- a/man/post-get.1 +++ /dev/null @@ -1,44 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-GET" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-get\fR \- Get a post\'s content by ID\. -. -.SH "SYNOPSIS" -wp post get [\-\-format=\fIformat\fR] \fIid\fR -. -.SH "OPTIONS" -. -.TP -\fB[\-\-format=<format>]\fR: -. -.IP -The format to use when printing the post, acceptable values: -. -.IP -\fBcontent\fR: Outputs only the post\'s content\. -. -.IP -\fBtable\fR: Outputs all fields of the post as a table\. Note that the post_content field is omitted so that the table is readable\. -. -.IP -\fBjson\fR: Outputs all fields in JSON format\. -. -.TP -\fB<id>\fR: -. -.IP -The ID of the post to get\. -. -.SH "EXAMPLES" -. -.nf - -wp post get 12 \-\-format=content - -wp post get 12 > file\.txt -. -.fi - diff --git a/man/post-list.1 b/man/post-list.1 deleted file mode 100644 index 9212454234..0000000000 --- a/man/post-list.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-list\fR \- Get a list of posts\. -. -.SH "SYNOPSIS" -wp post list [\-\-\fIfield\fR=\fIvalue\fR] [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-<field>\fR=\fIvalue\fR: -. -.IP -One or more args to pass to WP_Query\. -. -.TP -\fB\-\-fields\fR=\fIfields\fR: -. -.IP -Limit the output to specific object fields\. Defaults to ID,post_title,post_name,post_date,post_status\. -. -.TP -\fB\-\-format\fR=\fIformat\fR: -. -.IP -Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. -. -.SH "EXAMPLES" -. -.nf - -wp post list \-\-format=ids - -wp post list \-\-post_type=post \-\-posts_per_page=5 \-\-format=json - -wp post list \-\-post_type=page \-\-fields=post_title,post_status -. -.fi - diff --git a/man/post-meta.1 b/man/post-meta.1 deleted file mode 100644 index 90398260aa..0000000000 --- a/man/post-meta.1 +++ /dev/null @@ -1,62 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-META" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-meta\fR \- Manage post custom fields\. -. -.SH "SYNOPSIS" -wp post\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] -. -.P -wp post\-meta delete \fIid\fR \fIkey\fR -. -.P -wp post\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] -. -.P -wp post\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] -. -.SH "SUBCOMMANDS" -. -.TP -\fBadd\fR: -. -.IP -Add a meta field\. -. -.TP -\fBdelete\fR: -. -.IP -Delete a meta field\. -. -.TP -\fBget\fR: -. -.IP -Get meta field value\. -. -.TP -\fBupdate\fR: -. -.IP -Update a meta field\. -. -.SH "OPTIONS" -. -.TP -\fB\-\-format=json\fR: -. -.IP -Encode/decode values as JSON\. -. -.SH "EXAMPLES" -. -.nf - -wp post\-meta set 123 _wp_page_template about\.php -. -.fi - diff --git a/man/post-update.1 b/man/post-update.1 deleted file mode 100644 index 91b69b6b52..0000000000 --- a/man/post-update.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-POST\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-post\-update\fR \- Update one or more posts\. -. -.SH "SYNOPSIS" -wp post update \fIid\fR\.\.\. \-\-\fIfield\fR=\fIvalue\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the post to update\. -. -.TP -\fB\-\-<field>\fR=\fIvalue\fR: -. -.IP -One or more fields to update\. See wp_update_post()\. -. -.SH "EXAMPLES" -. -.nf - -wp post update 123 \-\-post_name=something \-\-post_status=draft -. -.fi - diff --git a/man/rewrite-dump.1 b/man/rewrite-dump.1 deleted file mode 100644 index a5e9c33d3a..0000000000 --- a/man/rewrite-dump.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-REWRITE\-DUMP" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-rewrite\-dump\fR \- Print current rewrite rules\. -. -.SH "SYNOPSIS" -wp rewrite dump [\-\-json] -. -.SH "OPTIONS" -. -.TP -\fB\-\-format=json\fR: -. -.IP -Output rules in JSON format\. - diff --git a/man/rewrite-flush.1 b/man/rewrite-flush.1 deleted file mode 100644 index 622e11e126..0000000000 --- a/man/rewrite-flush.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-REWRITE\-FLUSH" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-rewrite\-flush\fR \- Flush rewrite rules\. -. -.SH "SYNOPSIS" -wp rewrite flush [\-\-soft] -. -.SH "OPTIONS" -. -.TP -\fB\-\-soft\fR: -. -.IP -Perform a soft flush \- do not overwrite \fB\.htaccess\fR\. The default is to update \fB\.htaccess\fR rules as well as rewrite rules in database\. - diff --git a/man/rewrite-structure.1 b/man/rewrite-structure.1 deleted file mode 100644 index 50272811d0..0000000000 --- a/man/rewrite-structure.1 +++ /dev/null @@ -1,31 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-REWRITE\-STRUCTURE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-rewrite\-structure\fR \- Update the permalink structure\. -. -.SH "SYNOPSIS" -wp rewrite structure \fIpermastruct\fR [\-\-category\-base=\fIbase\fR] [\-\-tag\-base=\fIbase\fR] -. -.SH "OPTIONS" -. -.TP -\fIpermastruct\fR: -. -.IP -The new permalink structure to apply; like "/%year%/%monthnum%/%postname%"\. -. -.TP -\fB\-\-category\-base\fR=\fIcategorybase\fR: -. -.IP -Set the base for category permalinks, ie \'/category/\'\. -. -.TP -\fB\-\-tag\-base\fR=\fItagbase\fR: -. -.IP -Set the base for tag permalinks, ie \'/tag/\'\. - diff --git a/man/role-create.1 b/man/role-create.1 deleted file mode 100644 index 4737ed2b0c..0000000000 --- a/man/role-create.1 +++ /dev/null @@ -1,35 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLE\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-role\-create\fR \- Create a new role\. -. -.SH "SYNOPSIS" -wp role create \fIrole\-key\fR \fIrole\-name\fR -. -.SH "OPTIONS" -. -.TP -\fIrole\-key\fR: -. -.IP -The internal name of the role, e\.g\. editor -. -.TP -\fIrole\-name\fR: -. -.IP -The publically visible name of the role, e\.g\. Editor -. -.SH "EXAMPLES" -. -.nf - -wp role create approver Approver - -wp role create productadmin "Product Administrator" -. -.fi - diff --git a/man/role-delete.1 b/man/role-delete.1 deleted file mode 100644 index 02375d3693..0000000000 --- a/man/role-delete.1 +++ /dev/null @@ -1,29 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLE\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-role\-delete\fR \- Delete an existing role\. -. -.SH "SYNOPSIS" -wp role delete \fIrole\-key\fR -. -.SH "OPTIONS" -. -.TP -\fIrole\-key\fR: -. -.IP -The internal name of the role, e\.g\. editor -. -.SH "EXAMPLES" -. -.nf - -wp role delete approver - -wp role delete productadmin -. -.fi - diff --git a/man/role-exists.1 b/man/role-exists.1 deleted file mode 100644 index 7db3baa31f..0000000000 --- a/man/role-exists.1 +++ /dev/null @@ -1,30 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLE\-EXISTS" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-role\-exists\fR \- Check if a role exists\. -. -.SH "SYNOPSIS" -wp role exists \fIrole\-key\fR -. -.SH "OPTIONS" -. -.TP -\fIrole\-key\fR: -. -.IP -The internal name of the role, e\.g\. editor -. -.SH "DESCRIPTION" -Will exit with status 0 if the role exists, 1 if it does not\. -. -.SH "EXAMPLES" -. -.nf - -wp role exists editor -. -.fi - diff --git a/man/role-list.1 b/man/role-list.1 deleted file mode 100644 index 14d58a8b85..0000000000 --- a/man/role-list.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-ROLE\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-role\-list\fR \- List all roles\. -. -.SH "SYNOPSIS" -wp role list [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-fields\fR=\fIfields\fR: -. -.IP -Limit the output to specific object fields\. Defaults to name,role\. -. -.TP -\fB\-\-format\fR=\fIformat\fR: -. -.IP -Output list as table, CSV or JSON\. Defaults to table\. -. -.SH "EXAMPLES" -. -.nf - -wp role list \-\-fields=role \-\-format=csv -. -.fi - diff --git a/man/scaffold-_s.1 b/man/scaffold-_s.1 deleted file mode 100644 index d6ee0407ce..0000000000 --- a/man/scaffold-_s.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SCAFFOLD\-_S" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-scaffold\-_s\fR \- Generate starter code for a theme\. -. -.SH "SYNOPSIS" -wp scaffold _s \fIslug\fR [\-\-theme_name=\fItitle\fR] [\-\-author=\fIfull\-name\fR] [\-\-author_uri=\fIhttp\-url\fR] [\-\-activate] -. -.SH "OPTIONS" -. -.TP -\fIslug\fR: -. -.IP -The slug for the new theme, used for prefixing functions\. -. -.TP -\fB\-\-activate\fR: -. -.IP -Activate the newly downloaded theme\. -. -.TP -\fB\-\-theme_name=<title>\fR: -. -.IP -What to put in the \'Theme Name:\' header in style\.css -. -.TP -\fB\-\-author=<full name>\fR: -. -.IP -What to put in the \'Author:\' header in style\.css -. -.TP -\fB\-\-author_uri=<http url>\fR: -. -.IP -What to put in the \'Author URI:\' header in style\.css - diff --git a/man/scaffold-child-theme.1 b/man/scaffold-child-theme.1 deleted file mode 100644 index 67fa5bcd3f..0000000000 --- a/man/scaffold-child-theme.1 +++ /dev/null @@ -1,55 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SCAFFOLD\-CHILD\-THEME" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-scaffold\-child\-theme\fR \- Generate empty child theme\. -. -.SH "SYNOPSIS" -wp scaffold child\-theme \fIslug\fR \-\-parent_theme=\fIslug\fR [\-\-theme_name=\fItitle\fR] [\-\-author=\fIfull\-name\fR] [\-\-author_uri=\fIhttp\-url\fR] [\-\-theme_uri=\fIhttp\-url\fR] [\-\-activate] -. -.SH "OPTIONS" -. -.TP -\fIslug\fR: -. -.IP -The slug for the new child theme\. -. -.TP -\fB\-\-parent_theme=<slug>\fR: -. -.IP -What to put in the \'Template:\' header in style\.css -. -.TP -\fB\-\-theme_name=<title>\fR: -. -.IP -What to put in the \'Theme Name:\' header in style\.css -. -.TP -\fB\-\-author=<full name>\fR: -. -.IP -What to put in the \'Author:\' header in style\.css -. -.TP -\fB\-\-author_uri=<http url>\fR: -. -.IP -What to put in the \'Author URI:\' header in style\.css -. -.TP -\fB\-\-theme_uri=<http url>\fR: -. -.IP -What to put in the \'Theme URI:\' header in style\.css -. -.TP -\fB\-\-activate\fR: -. -.IP -Activate the newly created child theme\. - diff --git a/man/scaffold-plugin-tests.1 b/man/scaffold-plugin-tests.1 deleted file mode 100644 index 5c0a07ee5e..0000000000 --- a/man/scaffold-plugin-tests.1 +++ /dev/null @@ -1,39 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SCAFFOLD\-PLUGIN\-TESTS" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-scaffold\-plugin\-tests\fR \- Generate files needed for running PHPUnit tests\. -. -.SH "SYNOPSIS" -wp scaffold plugin\-tests \fIplugin\fR -. -.SH "DESCRIPTION" -These are the files that are generated: -. -.IP "\(bu" 4 -\fBphpunit\.xml\fR is the configuration file for PHPUnit -. -.IP "\(bu" 4 -\fB\.travis\.yml\fR is the configuration file for Travis CI -. -.IP "\(bu" 4 -\fBtests/bootstrap\.php\fR is the file that makes the current plugin active when running the test suite -. -.IP "\(bu" 4 -\fBtests/test\-sample\.php\fR is a sample file containing the actual tests -. -.IP "" 0 -. -.SH "ENVIRONMENT" -The \fBtests/bootstrap\.php\fR file looks for the WP_TESTS_DIR environment variable\. -. -.SH "EXAMPLE" -. -.nf - -wp scaffold plugin\-tests hello -. -.fi - diff --git a/man/scaffold-plugin.1 b/man/scaffold-plugin.1 deleted file mode 100644 index f91ec221e5..0000000000 --- a/man/scaffold-plugin.1 +++ /dev/null @@ -1,25 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SCAFFOLD\-PLUGIN" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-scaffold\-plugin\fR \- Generate starter code for a plugin\. -. -.SH "SYNOPSIS" -wp scaffold plugin \fIslug\fR [\-\-plugin_name=\fItitle\fR] [\-\-activate] -. -.SH "OPTIONS" -. -.TP -\fB\-\-activate\fR: -. -.IP -Activate the newly generated plugin\. -. -.TP -\fB\-\-plugin_name=<title>\fR: -. -.IP -What to put in the \'Plugin Name:\' header - diff --git a/man/scaffold-post-type.1 b/man/scaffold-post-type.1 deleted file mode 100644 index 6db8bf44c2..0000000000 --- a/man/scaffold-post-type.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SCAFFOLD\-POST\-TYPE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-scaffold\-post\-type\fR \- Generate PHP code for registering a custom post type\. -. -.SH "SYNOPSIS" -wp scaffold post\-type \fIslug\fR [\-\-label=\fIlabel\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] -. -.SH "OPTIONS" -. -.TP -\fB\-\-label=<label>\fR: -. -.IP -The text used to translate the update messages -. -.TP -\fB\-\-textdomain=<textdomain>\fR: -. -.IP -The textdomain to use for the labels\. -. -.TP -\fB\-\-theme\fR: -. -.IP -Create a file in the active theme directory, instead of sending to STDOUT\. Specify a theme with \fB\-\-theme=<theme>\fR to have the file placed in that theme\. -. -.TP -\fB\-\-plugin=<plugin>\fR: -. -.IP -Create a file in the given plugin\'s directory, instead of sending to STDOUT\. -. -.TP -\fB\-\-raw\fR: -. -.IP -Just generate the \fBregister_post_type()\fR call and nothing else\. - diff --git a/man/scaffold-taxonomy.1 b/man/scaffold-taxonomy.1 deleted file mode 100644 index 3d7986f2e1..0000000000 --- a/man/scaffold-taxonomy.1 +++ /dev/null @@ -1,57 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SCAFFOLD\-TAXONOMY" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-scaffold\-taxonomy\fR \- Generate PHP code for registering a custom taxonomy\. -. -.SH "SYNOPSIS" -wp scaffold taxonomy \fIslug\fR [\-\-post_types=\fIpost\-types\fR] [\-\-label=\fIlabel\fR] [\-\-textdomain=\fItextdomain\fR] [\-\-theme] [\-\-plugin=\fIplugin\fR] [\-\-raw] -. -.SH "OPTIONS" -. -.TP -\fB\-\-post_types=<post_types>\fR: -. -.IP -Post types to register for use with the taxonomy\. -. -.TP -\fB\-\-label=<label>\fR: -. -.IP -The text used to translate the update messages -. -.TP -\fB\-\-textdomain=<textdomain>\fR: -. -.IP -The textdomain to use for the labels\. -. -.TP -\fB\-\-theme\fR: -. -.IP -Create a file in the active theme directory, instead of sending to STDOUT\. Specify a theme with \fB\-\-theme=<theme>\fR to have the file placed in that theme\. -. -.TP -\fB\-\-plugin=<plugin>\fR: -. -.IP -Create a file in the given plugin\'s directory, instead of sending to STDOUT\. -. -.TP -\fB\-\-raw\fR: -. -.IP -Just generate the \fBregister_taxonomy()\fR call and nothing else\. -. -.SH "EXAMPLES" -. -.nf - -wp scaffold taxonomy venue \-\-post_types=event,presentation -. -.fi - diff --git a/man/search-replace.1 b/man/search-replace.1 deleted file mode 100644 index 6af388a6eb..0000000000 --- a/man/search-replace.1 +++ /dev/null @@ -1,47 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SEARCH\-REPLACE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-search\-replace\fR \- Search/replace strings in the database\. -. -.SH "SYNOPSIS" -wp search\-replace \fIold\fR \fInew\fR [\fItable\fR\.\.\.] [\-\-skip\-columns=\fIcolumns\fR] [\-\-dry\-run] [\-\-network] -. -.SH "DESCRIPTION" -This command will go through all rows in all tables and will replace all appearances of the old string with the new one\. -. -.P -It will correctly handle serialized values, and will not change primary key values\. -. -.SH "OPTIONS" -. -.TP -\fB\-\-network\fR: -. -.IP -Search/replace through all the tables in a multisite install\. -. -.TP -\fB\-\-skip\-columns=<columns>\fR: -. -.IP -Do not perform the replacement in the comma\-separated columns\. -. -.TP -\fB\-\-dry\-run\fR: -. -.IP -Show report, but don\'t perform the changes\. -. -.SH "EXAMPLES" -. -.nf - -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 -. -.fi - diff --git a/man/shell.1 b/man/shell.1 deleted file mode 100644 index 6aa5f9e1f1..0000000000 --- a/man/shell.1 +++ /dev/null @@ -1,22 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SHELL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-shell\fR \- Interactive PHP console\. -. -.SH "SYNOPSIS" -wp shell [\-\-basic] -. -.SH "DESCRIPTION" -\fBwp shell\fR allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment\. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example\. -. -.SH "OPTIONS" -. -.TP -\fB\-\-basic\fR: -. -.IP -Start in fail\-safe mode, even if Boris is available\. - diff --git a/man/site-create.1 b/man/site-create.1 deleted file mode 100644 index 20675a3e6a..0000000000 --- a/man/site-create.1 +++ /dev/null @@ -1,49 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SITE\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-site\-create\fR \- Create a site in a multisite install\. -. -.SH "SYNOPSIS" -wp site create \-\-slug=\fIslug\fR [\-\-title=\fItitle\fR] [\-\-email=\fIemail\fR] [\-\-network_id=\fInetwork\-id\fR] [\-\-private] [\-\-porcelain] -. -.SH "OPTIONS" -. -.TP -\fB\-\-slug\fR=\fIslug\fR: -. -.IP -Path for the new site\. Subdomain on subdomain installs, directory on subdirectory installs\. -. -.TP -\fB\-\-title\fR=<title>: -. -.IP -Title of the new site\. Default: prettified slug\. -. -.TP -\fB\-\-email\fR=\fIemail\fR: -. -.IP -Email for Admin user\. User will be created if none exists\. Assignement to Super Admin if not included\. -. -.TP -\fB\-\-network_id\fR=\fInetwork\-id\fR: -. -.IP -Network to associate new site with\. Defaults to current network (typically 1)\. -. -.TP -\fB\-\-private\fR: -. -.IP -If set, the new site will be non\-public (not indexed) -. -.TP -\fB\-\-porcelain\fR: -. -.IP -If set, only the site id will be output on success\. - diff --git a/man/site-delete.1 b/man/site-delete.1 deleted file mode 100644 index d8f7f3bc3d..0000000000 --- a/man/site-delete.1 +++ /dev/null @@ -1,37 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SITE\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-site\-delete\fR \- Delete a site in a multisite install\. -. -.SH "SYNOPSIS" -wp site delete [\fIsite\-id\fR] [\-\-slug=\fIslug\fR] [\-\-yes] [\-\-keep\-tables] -. -.SH "OPTIONS" -. -.TP -\fB<blog\-id>\fR: -. -.IP -The id of the blog to delete\. If not provided, you must set the \-\-slug parameter\. -. -.TP -\fB\-\-slug\fR=\fIslug\fR: -. -.IP -Path of the blog to be deleted\. Subdomain on subdomain installs, directory on subdirectory installs\. -. -.TP -\fB\-\-yes\fR: -. -.IP -Answer yes to the confirmation message\. -. -.TP -\fB\-\-keep\-tables\fR: -. -.IP -Delete the blog from the list, but don\'t drop it\'s tables\. - diff --git a/man/site-empty.1 b/man/site-empty.1 deleted file mode 100644 index 144391fba1..0000000000 --- a/man/site-empty.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-SITE\-EMPTY" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-site\-empty\fR \- Empty a site of its content\. -. -.SH "SYNOPSIS" -wp site empty [\-\-yes] -. -.SH "EXAMPLES" -. -.nf - -wp blog empty -. -.fi - diff --git a/man/term-create.1 b/man/term-create.1 deleted file mode 100644 index 366ee1a886..0000000000 --- a/man/term-create.1 +++ /dev/null @@ -1,57 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TERM\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-term\-create\fR \- Create a term\. -. -.SH "SYNOPSIS" -wp term create \fIterm\fR \fItaxonomy\fR [\-\-slug=\fIslug\fR] [\-\-description=\fIdescription\fR] [\-\-parent=\fIterm\-id\fR] [\-\-porcelain] -. -.SH "OPTIONS" -. -.TP -\fB<term>\fR: -. -.IP -A name for the new term\. -. -.TP -\fB<taxonomy>\fR: -. -.IP -Taxonomy for the new term\. -. -.TP -\fB\-\-slug\fR=\fIslug\fR: -. -.IP -A unique slug for the new term\. Defaults to sanitized version of name\. -. -.TP -\fB\-\-description\fR=\fIdescription\fR: -. -.IP -A description for the new term\. -. -.TP -\fB\-\-parent\fR=\fIterm\-id\fR: -. -.IP -A parent for the new term\. -. -.TP -\fB\-\-porcelain\fR: -. -.IP -Output just the new term id\. -. -.SH "EXAMPLES" -. -.nf - -wp term create Apple category \-\-description="A type of fruit" -. -.fi - diff --git a/man/term-delete.1 b/man/term-delete.1 deleted file mode 100644 index 1a9700510f..0000000000 --- a/man/term-delete.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TERM\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-term\-delete\fR \- Delete a term\. -. -.SH "SYNOPSIS" -wp term delete \fIterm\-id\fR \fItaxonomy\fR -. -.SH "OPTIONS" -. -.TP -\fB<term\-id>\fR: -. -.IP -ID for the term to delete\. -. -.TP -\fB<taxonomy>\fR: -. -.IP -Taxonomy of the term to delete\. -. -.SH "EXAMPLES" -. -.nf - -wp term delete 15 category -. -.fi - diff --git a/man/term-list.1 b/man/term-list.1 deleted file mode 100644 index ef15301912..0000000000 --- a/man/term-list.1 +++ /dev/null @@ -1,41 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TERM\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-term\-list\fR \- List terms in a taxonomy\. -. -.SH "SYNOPSIS" -wp term list \fItaxonomy\fR [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] -. -.SH "OPTIONS" -. -.TP -\fB<taxonomy>\fR: -. -.IP -List terms of a given taxonomy\. -. -.TP -\fB\-\-fields\fR=\fIfields\fR: -. -.IP -Limit the output to specific object fields\. Defaults to all of the term object fields\. -. -.TP -\fB\-\-format\fR=\fIformat\fR: -. -.IP -Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. -. -.SH "EXAMPLES" -. -.nf - -wp term list category \-\-format=csv - -wp term list post_tag \-\-fields=name,slug -. -.fi - diff --git a/man/term-update.1 b/man/term-update.1 deleted file mode 100644 index 34bf099def..0000000000 --- a/man/term-update.1 +++ /dev/null @@ -1,57 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TERM\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-term\-update\fR \- Update a term\. -. -.SH "SYNOPSIS" -wp term update \fIterm\-id\fR \fItaxonomy\fR [\-\-name=\fIname\fR] [\-\-slug=\fIslug\fR] [\-\-description=\fIdescription\fR] [\-\-parent=\fIterm\-id\fR] -. -.SH "OPTIONS" -. -.TP -\fB<term\-id>\fR: -. -.IP -ID for the term to update\. -. -.TP -\fB<taxonomy>\fR: -. -.IP -Taxonomy of the term to update\. -. -.TP -\fB\-\-name\fR=\fIname\fR: -. -.IP -A new name for the term\. -. -.TP -\fB\-\-slug\fR=\fIslug\fR: -. -.IP -A new slug for the term\. -. -.TP -\fB\-\-description\fR=\fIdescription\fR: -. -.IP -A new description for the term\. -. -.TP -\fB\-\-parent\fR=\fIterm\-id\fR: -. -.IP -A new parent for the term\. -. -.SH "EXAMPLES" -. -.nf - -wp term update 15 category \-\-name=Apple -. -.fi - diff --git a/man/theme-activate.1 b/man/theme-activate.1 deleted file mode 100644 index 52f33f8b4d..0000000000 --- a/man/theme-activate.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-ACTIVATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-activate\fR \- Activate a theme\. -. -.SH "SYNOPSIS" -wp theme activate \fItheme\fR -. -.SH "OPTIONS" -. -.TP -\fB<theme>\fR: -. -.IP -The theme to activate\. - diff --git a/man/theme-delete.1 b/man/theme-delete.1 deleted file mode 100644 index 3bfae3759f..0000000000 --- a/man/theme-delete.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-delete\fR \- Delete a theme\. -. -.SH "SYNOPSIS" -wp theme delete \fItheme\fR -. -.SH "OPTIONS" -. -.TP -\fB<theme>\fR: -. -.IP -The theme to delete\. -. -.SH "EXAMPLES" -. -.nf - -wp theme delete twentyeleven -. -.fi - diff --git a/man/theme-install.1 b/man/theme-install.1 deleted file mode 100644 index 5e74e7c305..0000000000 --- a/man/theme-install.1 +++ /dev/null @@ -1,35 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-INSTALL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-install\fR \- Install a theme\. -. -.SH "SYNOPSIS" -wp theme install \fItheme|zip\fR [\-\-version=\fIversion\fR] [\-\-activate] -. -.SH "OPTIONS" -. -.TP -\fB<theme>\fR: -. -.IP -A theme slug or the path to a zip file\. -. -.TP -\fB\-\-activate\fR: -. -.IP -If set, the theme will be activated immediately after install\. -. -.SH "EXAMPLES" -. -.nf - -wp theme install twentytwelve \-\-activate - -wp theme install \.\./my\-theme\.zip -. -.fi - diff --git a/man/theme-list.1 b/man/theme-list.1 deleted file mode 100644 index 96436899fe..0000000000 --- a/man/theme-list.1 +++ /dev/null @@ -1,21 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-list\fR \- Get a list of themes\. -. -.SH "SYNOPSIS" -wp theme list [\-\-format=\fIformat\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-format\fR=\fIformat\fR: -. -.IP -Output list as table, CSV or JSON\. Defaults to table\. -. -.SH "EXAMPLES" -wp theme list \-\-format=csv diff --git a/man/theme-path.1 b/man/theme-path.1 deleted file mode 100644 index b657808c8d..0000000000 --- a/man/theme-path.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-PATH" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-path\fR \- Get the path to a theme or to the theme directory\. -. -.SH "SYNOPSIS" -wp theme path [\fItheme\fR] [\-\-dir] -. -.SH "OPTIONS" -. -.TP -\fB<theme>\fR: -. -.IP -The theme to get the path to\. If not set, will return the path to the themes directory\. -. -.TP -\fB\-\-dir\fR: -. -.IP -If set, get the path to the closest parent directory, instead of the theme file\. -. -.SH "EXAMPLES" -. -.nf - -cd $(wp theme path) -. -.fi - diff --git a/man/theme-status.1 b/man/theme-status.1 deleted file mode 100644 index 89fb262e69..0000000000 --- a/man/theme-status.1 +++ /dev/null @@ -1,19 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-STATUS" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-status\fR \- See the status of one or all themes\. -. -.SH "SYNOPSIS" -wp theme status [\fItheme\fR] -. -.SH "OPTIONS" -. -.TP -\fB<theme>\fR: -. -.IP -A particular theme to show the status for\. - diff --git a/man/theme-update-all.1 b/man/theme-update-all.1 deleted file mode 100644 index 82f580ff9f..0000000000 --- a/man/theme-update-all.1 +++ /dev/null @@ -1,27 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-UPDATE\-ALL" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-update\-all\fR \- Update all themes\. -. -.SH "SYNOPSIS" -wp theme update\-all [\-\-dry\-run] -. -.SH "OPTIONS" -. -.TP -\fB\-\-dry\-run\fR: -. -.IP -Pretend to do the updates, to see what would happen\. -. -.SH "EXAMPLES" -. -.nf - -wp theme update\-all -. -.fi - diff --git a/man/theme-update.1 b/man/theme-update.1 deleted file mode 100644 index 7e877c8172..0000000000 --- a/man/theme-update.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-THEME\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-theme\-update\fR \- Update a theme\. -. -.SH "SYNOPSIS" -wp theme update \fItheme\fR [\-\-version=\fIversion\fR] -. -.SH "OPTIONS" -. -.TP -\fB<theme>\fR: -. -.IP -The theme to update\. -. -.TP -\fB\-\-version=dev\fR: -. -.IP -If set, the theme will be updated to the latest development version, regardless of what version is currently installed\. -. -.SH "EXAMPLES" -. -.nf - -wp theme update twentytwelve -. -.fi - diff --git a/man/transient.1 b/man/transient.1 deleted file mode 100644 index e3fd1ddd1e..0000000000 --- a/man/transient.1 +++ /dev/null @@ -1,54 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-TRANSIENT" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-transient\fR \- Manage WordPress transients\. -. -.SH "SYNOPSIS" -wp transient delete \fIkey\fR -. -.P -wp transient get \fIkey\fR [\-\-json] -. -.P -wp transient set \fIkey\fR \fIvalue\fR [\fIexpiration\fR] -. -.P -wp transient type -. -.SH "SUBCOMMANDS" -. -.TP -\fBdelete\fR: -. -.IP -Delete a transient value\. -. -.TP -\fBget\fR: -. -.IP -Get a transient value\. -. -.TP -\fBset\fR: -. -.IP -Set a transient value\. <expiration> is the time until expiration, in seconds\. -. -.TP -\fBtype\fR: -. -.IP -See wether the transients API is using an object cache or the options table\. -. -.SH "EXAMPLES" -. -.nf - -wp transient set my_key my_value 300 -. -.fi - diff --git a/man/user-create.1 b/man/user-create.1 deleted file mode 100644 index 6eadf9ec9c..0000000000 --- a/man/user-create.1 +++ /dev/null @@ -1,63 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-CREATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-create\fR \- Create a user\. -. -.SH "SYNOPSIS" -wp user create \fIuser\-login\fR \fIuser\-email\fR [\-\-role=\fIrole\fR] [\-\-user_pass=\fIpassword\fR] [\-\-user_registered=\fIyyyy\-mm\-dd\fR] [\-\-display_name=\fIname\fR] [\-\-porcelain] -. -.SH "OPTIONS" -. -.TP -\fB<user\-login>\fR: -. -.IP -The login of the user to create\. -. -.TP -\fB<user\-email>\fR: -. -.IP -The email address of the user to create\. -. -.TP -\fB\-\-role\fR=\fIrole\fR: -. -.IP -The role of the user to create\. Default: default role -. -.TP -\fB\-\-user_pass\fR=\fIpassword\fR: -. -.IP -The user password\. Default: randomly generated -. -.TP -\fB\-\-user_registered\fR=\fIyyyy\-mm\-dd\fR: -. -.IP -The date the user registered\. Default: current date -. -.TP -\fB\-\-display_name\fR=\fIname\fR: -. -.IP -The display name\. -. -.TP -\fB\-\-porcelain\fR: -. -.IP -Output just the new user id\. -. -.SH "EXAMPLES" -. -.nf - -wp user create bob bob@example\.com \-\-role=author -. -.fi - diff --git a/man/user-delete.1 b/man/user-delete.1 deleted file mode 100644 index d498eb4153..0000000000 --- a/man/user-delete.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-DELETE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-delete\fR \- Delete one or more users\. -. -.SH "SYNOPSIS" -wp user delete \fIid\fR\.\.\. [\-\-reassign=\fIid\fR] -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the user to delete\. -. -.TP -\fB\-\-reassign\fR=\fIID\fR: -. -.IP -User to reassign the posts to\. -. -.SH "EXAMPLES" -. -.nf - -wp user delete 123 \-\-reassign=567 -. -.fi - diff --git a/man/user-generate.1 b/man/user-generate.1 deleted file mode 100644 index 3c87b5c76b..0000000000 --- a/man/user-generate.1 +++ /dev/null @@ -1,25 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-GENERATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-generate\fR \- Generate users\. -. -.SH "SYNOPSIS" -wp user generate [\-\-count=\fInumber\fR] [\-\-role=\fIrole\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-count\fR=\fInumber\fR: -. -.IP -How many users to generate\. Default: 100 -. -.TP -\fB\-\-role\fR=\fIrole\fR: -. -.IP -The role of the generated users\. Default: default role from WP - diff --git a/man/user-import-csv.1 b/man/user-import-csv.1 deleted file mode 100644 index 0c3d07c7a1..0000000000 --- a/man/user-import-csv.1 +++ /dev/null @@ -1,34 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-IMPORT\-CSV" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-import\-csv\fR \- Import users from a CSV file\. -. -.SH "SYNOPSIS" -wp user import\-csv \fIfile\fR -. -.SH "OPTIONS" -. -.TP -\fB<file>\fR: -. -.IP -The CSV file of users to import\. -. -.SH "EXAMPLES" -. -.nf - -wp user import\-csv /path/to/users\.csv - -Sample users\.csv file: - -user_login,user_email,display_name,role -bobjones,bobjones@domain\.com,Bob Jones,contributor -newuser1,newuser1@domain\.com,New User,author -existinguser,existinguser@domain\.com,Existing User,administrator -. -.fi - diff --git a/man/user-list.1 b/man/user-list.1 deleted file mode 100644 index f5dac94ed1..0000000000 --- a/man/user-list.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-LIST" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-list\fR \- List users\. -. -.SH "SYNOPSIS" -wp user list [\-\-role=\fIrole\fR] [\-\-fields=\fIfields\fR] [\-\-format=\fIformat\fR] -. -.SH "OPTIONS" -. -.TP -\fB\-\-role\fR=\fIrole\fR: -. -.IP -Only display users with a certain role\. -. -.TP -\fB\-\-fields\fR=\fIfields\fR: -. -.IP -Limit the output to specific object fields\. Defaults to ID,user_login,display_name,user_email,user_registered,roles -. -.TP -\fB\-\-format\fR=\fIformat\fR: -. -.IP -Output list as table, CSV, JSON, or simply IDs\. Defaults to table\. -. -.SH "EXAMPLES" -. -.nf - -wp user list \-\-format=ids - -wp user list \-\-role=administrator \-\-format=csv - -wp user list \-\-fields=display_name,user_email -. -.fi - diff --git a/man/user-meta.1 b/man/user-meta.1 deleted file mode 100644 index 817491f42e..0000000000 --- a/man/user-meta.1 +++ /dev/null @@ -1,62 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-META" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-meta\fR \- Manage user custom fields\. -. -.SH "SYNOPSIS" -wp user\-meta add \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] -. -.P -wp user\-meta delete \fIid\fR \fIkey\fR -. -.P -wp user\-meta get \fIid\fR \fIkey\fR [\-\-format=\fIformat\fR] -. -.P -wp user\-meta update \fIid\fR \fIkey\fR \fIvalue\fR [\-\-format=\fIformat\fR] -. -.SH "SUBCOMMANDS" -. -.TP -\fBadd\fR: -. -.IP -Add a meta field\. -. -.TP -\fBdelete\fR: -. -.IP -Delete a meta field\. -. -.TP -\fBget\fR: -. -.IP -Get meta field value\. -. -.TP -\fBupdate\fR: -. -.IP -Update a meta field\. -. -.SH "OPTIONS" -. -.TP -\fB\-\-format=json\fR: -. -.IP -Encode/decode values as JSON\. -. -.SH "EXAMPLES" -. -.nf - -wp user\-meta set 123 description "Mary is a WordPress developer\." -. -.fi - diff --git a/man/user-remove-role.1 b/man/user-remove-role.1 deleted file mode 100644 index e6e0360a9c..0000000000 --- a/man/user-remove-role.1 +++ /dev/null @@ -1,28 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-REMOVE\-ROLE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-remove\-role\fR \- Remove a user\'s role\. -. -.SH "SYNOPSIS" -wp user remove\-role \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] -. -.SH "OPTIONS" -. -.TP -\fB<user\-login>\fR: -. -.IP -User ID or user login\. -. -.SH "EXAMPLES" -. -.nf - -wp user remove\-role bob -wp user remove\-role 12 -. -.fi - diff --git a/man/user-set-role.1 b/man/user-set-role.1 deleted file mode 100644 index edd5ea550a..0000000000 --- a/man/user-set-role.1 +++ /dev/null @@ -1,34 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-SET\-ROLE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-set\-role\fR \- Set the user role (for a particular blog)\. -. -.SH "SYNOPSIS" -wp user set\-role \fIuser\-login\fR [\fIrole\fR] [\-\-blog=\fIblog\fR] -. -.SH "OPTIONS" -. -.TP -\fB<user\-login>\fR: -. -.IP -User ID or user login\. -. -.TP -\fB[<role>]\fR: -. -.IP -Add the user with the specified role\. Defaults to blog default\. -. -.SH "EXAMPLES" -. -.nf - -wp user set\-role bob author -wp user set\-role 12 author -. -.fi - diff --git a/man/user-update.1 b/man/user-update.1 deleted file mode 100644 index 965501ff58..0000000000 --- a/man/user-update.1 +++ /dev/null @@ -1,33 +0,0 @@ -.\" generated with Ronn/v0.7.3 -.\" http://github.com/rtomayko/ronn/tree/0.7.3 -. -.TH "WP\-USER\-UPDATE" "1" "" "WP-CLI" -. -.SH "NAME" -\fBwp\-user\-update\fR \- Update a user\. -. -.SH "SYNOPSIS" -wp user update \fIid\fR\.\.\. \-\-\fIfield\fR=\fIvalue\fR -. -.SH "OPTIONS" -. -.TP -\fB<ID>\fR: -. -.IP -The ID of the user to update\. -. -.TP -\fB\-\-<field>\fR=\fIvalue\fR: -. -.IP -One or more fields to update\. For accepted fields, see wp_update_user()\. -. -.SH "EXAMPLES" -. -.nf - -wp user update 123 \-\-user_login=mary \-\-display_name=Mary -. -.fi - From d1cb39fa5c2fb82f2753777f4b73666a8c073f7c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 18:08:11 +0300 Subject: [PATCH 1891/4858] attempt to pass doc through a pager --- php/commands/help.php | 49 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index d1b2cc9456..bd681c31a1 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -47,7 +47,54 @@ private static function show_help( $command ) { $out = str_replace( "\t", ' ', $out ); - echo WP_CLI::colorize( $out ); + self::pass_through_pager( WP_CLI::colorize( $out ) ); + } + + private static function launch_pager( $pager, $fd ) { + // launch pager + $descriptorspec = array( + 0 => $fd, + 1 => STDOUT, + 2 => array( 'pipe', 'w' ) + ); + + $r = proc_close( proc_open( $pager, $descriptorspec, $pipes ) ); + + if ( 127 == $r ) { + return false; + } + + if ( $r ) { + fwrite( STDERR, stream_get_contents( $pipes[1] ) ); + exit( $r ); + } + + return true; + } + + private static function pass_through_pager( $out ) { + // convert string to file handle + $fd = fopen( "php://temp", "r+" ); + fputs( $fd, $out ); + rewind( $fd ); + + $pagers = array( 'less -r', 'more -r' ); + foreach ( $pagers as $pager ) { + if ( self::launch_pager( $pager, $fd ) ) + return; + } + + // no pager found + echo $out; + } + + private static function find( $candidates, $callback ) { + foreach ( $candidates as $candidate ) { + if ( call_user_func( $callback, $candidate ) ) + return $candidate; + } + + return false; } private static function get_initial_markdown( $command ) { From c60ed18bd0fecfdf5c12cae74a02f8a2d5c9f26f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 19:40:22 +0300 Subject: [PATCH 1892/4858] behat: use `@when` flag for testing --require see #453 --- features/flags.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/flags.feature b/features/flags.feature index dc73efbf4d..0033116729 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -74,10 +74,13 @@ Feature: Global flags """ Scenario: Using --require - Given a WP install + Given an empty directory And a custom-cmd.php file: """ <?php + /** + * @when before_wp_load + */ class Test_Command extends WP_CLI_Command { function req( $args, $assoc_args ) { From 1b80fdffc015f9624e431d073a3377b68481b3fc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Jun 2013 19:54:46 -0700 Subject: [PATCH 1893/4858] When specifying a `--version` for a plugin, always install that version. Previous behavior was to quit if the plugin was already installed. --- php/commands/plugin.php | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index c96d85465c..54639bc3fc 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -164,23 +164,29 @@ protected function install_from_repo( $slug, $assoc_args ) { WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); switch ( $status['status'] ) { - case 'update_available': - case 'install': - $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); - $result = $upgrader->install( $api->download_link ); - - if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } - break; - case 'newer_installed': - WP_CLI::error( sprintf( 'Newer version (%s) installed.', $status['version'] ) ); - break; - case 'latest_installed': - WP_CLI::error( 'Latest version already installed.' ); - break; + case 'latest_installed': + WP_CLI::error( 'Latest version already installed.' ); + break; + + // Newer installed plugin, but we might want the older version + case 'newer_installed': + case 'update_available': + if ( isset( $assoc_args['version'] ) + && version_compare( $status['version'], $assoc_args['version'], '>=' ) ) { + list( $file, $name ) = $this->parse_name( array( $api->slug ) ); + $this->_delete( $file ); + } + + case 'install': + $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); + $result = $upgrader->install( $api->download_link ); + + if ( $result && isset( $assoc_args['activate'] ) ) { + WP_CLI::log( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); + } + break; } } From 608fd04d8ab5a2acbde5c7cf7741e6c8365fb6e7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 11:20:20 +0300 Subject: [PATCH 1894/4858] behat: always invoke `wp` with a command --- features/core.feature | 9 ++++++--- features/flags.feature | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index 592ba49153..fef65dca1d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -56,9 +56,12 @@ Feature: Manage WordPress installation And WP files And wp-config.php - When I try `wp` + When I try `wp core is-installed` Then the return code should be 1 - And STDERR should not be empty + And STDERR should contain: + """ + Can’t select database + """ When I run `wp db create` Then STDOUT should not be empty @@ -73,7 +76,7 @@ Feature: Manage WordPress installation Then the return code should be 1 And STDERR should not be empty - When I try `wp` + When I try `wp core is-installed` Then the return code should be 1 And STDERR should be: """ diff --git a/features/flags.feature b/features/flags.feature index 0033116729..3c59cd2365 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -45,7 +45,7 @@ Feature: Global flags admin """ - When I try `wp --user=non-existing-user` + When I try `wp --user=non-existing-user eval 'echo wp_get_current_user()->user_login;'` Then the return code should be 1 And STDERR should be: """ @@ -67,7 +67,7 @@ Feature: Global flags WP_CLI::set_logger( new Dummy_Logger ); """ - When I try `wp --require=custom-logger.php` + When I try `wp --require=custom-logger.php is-installed` Then STDOUT should be: """ log: called 'error' method From 6f432fa1e8a39ea1b3c8a3a3777777c4085d1d79 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 11:30:01 +0300 Subject: [PATCH 1895/4858] behat: don't check DB error message, since it's sometimes encoded and sometimes not. --- features/core.feature | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index fef65dca1d..d0004d5716 100644 --- a/features/core.feature +++ b/features/core.feature @@ -58,10 +58,7 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 - And STDERR should contain: - """ - Can’t select database - """ + And STDERR should not be empty When I run `wp db create` Then STDOUT should not be empty From e838b0beef8f28a8d12b0897325a1b463ec6864e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 14:24:03 +0300 Subject: [PATCH 1896/4858] s/blog-wide/site-wide/g --- php/commands/site.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index c027cf4958..f1208a1298 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -1,7 +1,7 @@ <?php /** - * Perform blog-wide operations. + * Perform site-wide operations. * * @package wp-cli */ From 8d1311c70d2a9feea181ee6c6f856b974fde415b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 14:25:22 +0300 Subject: [PATCH 1897/4858] don't mention deprecated --blog option in synopsis --- php/commands/user.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 4c1a85795b..3533ec800d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -212,7 +212,7 @@ public function generate( $args, $assoc_args ) { * Set the user role (for a particular blog). * * @subcommand set-role - * @synopsis <user-login> [<role>] [--blog=<blog>] + * @synopsis <user-login> [<role>] */ public function set_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); @@ -232,7 +232,7 @@ public function set_role( $args, $assoc_args ) { * Add a role for a user. * * @subcommand add-role - * @synopsis <user-login> <role> [--blog=<blog>] + * @synopsis <user-login> <role> */ public function add_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); @@ -248,7 +248,7 @@ public function add_role( $args, $assoc_args ) { * Remove a user's role. * * @subcommand remove-role - * @synopsis <user-login> [<role>] [--blog=<blog>] + * @synopsis <user-login> [<role>] */ public function remove_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); @@ -277,7 +277,7 @@ private static function get_user_from_first_arg( $id_or_login ) { $user = get_user_by( 'login', $id_or_login ); if ( ! $user ) - WP_CLI::error( "Please specify a valid user ID or user login to remove from this blog" ); + WP_CLI::error( "Invalid user ID or login: $id_or_login" ); return $user; } @@ -324,7 +324,7 @@ public function import_csv( $args, $assoc_args ) { if ( !in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) && $new_user['role'] ) { add_user_to_blog( get_current_blog_id(), $existing_user->ID, $new_user['role'] ); - WP_CLI::log( "{$existing_user->user_login} added to blog as {$new_user['role']}" ); + WP_CLI::log( "{$existing_user->user_login} added as {$new_user['role']}." ); } // Create the user From 6e664d8bfc779921acbbe4c06f092cbc3e92006a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Jun 2013 14:26:38 +0300 Subject: [PATCH 1898/4858] show warning if --url doesn't receive a value --- php/WP_CLI/Runner.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 87fee00127..b383cd5f35 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -98,14 +98,16 @@ private static function set_user( $assoc_args ) { } private static function set_url( $assoc_args ) { - if ( isset( $assoc_args['url'] ) ) { - $url = $assoc_args['url']; - } elseif ( isset( $assoc_args['blog'] ) ) { + if ( isset( $assoc_args['blog'] ) ) { + $assoc_args['url'] = $assoc_args['blog']; + unset( $assoc_args['blog'] ); WP_CLI::warning( 'The --blog parameter is deprecated. Use --url instead.' ); + } - $url = $assoc_args['blog']; + if ( isset( $assoc_args['url'] ) ) { + $url = $assoc_args['url']; if ( true === $url ) { - WP_CLI::line( 'usage: wp --blog=example.com' ); + WP_CLI::warning( 'The --url parameter expects a value.' ); } } elseif ( is_readable( ABSPATH . 'wp-cli-blog' ) ) { WP_CLI::warning( 'The wp-cli-blog file is deprecated. Use wp-cli.yml instead.' ); From f08a43a02624a447d8728db0f5ddd558cd849812 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 13:20:44 +0300 Subject: [PATCH 1899/4858] behat: add test for relative 'require:' path in wp-cli.yml --- features/config.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/config.feature b/features/config.feature index 83813588b4..a51d366c06 100644 --- a/features/config.feature +++ b/features/config.feature @@ -14,8 +14,13 @@ Feature: Have a config file Scenario: Config file in WP Root Given a WP install + And a sample.php file: + """ + <?php + """ And a wp-cli.yml file: """ + require: sample.php """ When I run `wp --info` @@ -27,6 +32,9 @@ Feature: Have a config file When I run `wp core is-installed` Then STDOUT should be empty + When I run `wp` from 'wp-content' + Then STDOUT should not be empty + Scenario: WP in a subdirectory Given a WP install in 'core' And a wp-cli.yml file: From d8aac013918d2e161772fffe9b9daccb3123a7c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 13:21:28 +0300 Subject: [PATCH 1900/4858] move 'path:' absolutization logic to Configurator --- php/WP_CLI/Configurator.php | 15 ++++++++++++--- php/WP_CLI/Runner.php | 6 ------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 70b72522b6..0bbcca8044 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -78,9 +78,9 @@ function parse_args( $arguments ) { * * @return array */ - function load_config( $path ) { - if ( $path ) - $config = spyc_load_file( $path ); + function load_config( $yml_file ) { + if ( $yml_file ) + $config = spyc_load_file( $yml_file ); else $config = array(); @@ -99,7 +99,16 @@ function load_config( $path ) { $sanitized_config[ $key ] = $value; } + // Make sure a config-relative 'path' is made absolute + self::absolutize( $sanitized_config['path'], dirname( $yml_file ) ); + return $sanitized_config; } + + private static function absolutize( &$path, $base ) { + if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { + $path = $base . DIRECTORY_SEPARATOR . $path; + } + } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b383cd5f35..0ce51fb0cb 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -278,12 +278,6 @@ public function before_wp_load() { $local_config = \WP_CLI::$configurator->load_config( $this->config_path ); - // When invoking from a subdirectory in the project, - // make sure a config-relative 'path' is made absolute - if ( !empty( $local_config['path'] ) && !\WP_CLI\Utils\is_path_absolute( $local_config['path'] ) ) { - $local_config['path'] = dirname( $this->config_path ) . DIRECTORY_SEPARATOR . $local_config['path']; - } - $this->config = $local_config; foreach ( $runtime_config as $key => $value ) { From 723e0f2004e4215a302d1d41359e8d8f53f40e28 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 13:38:54 +0300 Subject: [PATCH 1901/4858] absolutize 'require:' --- php/WP_CLI/Configurator.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 0bbcca8044..e28c90f1fb 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -99,8 +99,17 @@ function load_config( $yml_file ) { $sanitized_config[ $key ] = $value; } - // Make sure a config-relative 'path' is made absolute - self::absolutize( $sanitized_config['path'], dirname( $yml_file ) ); + // Make sure config-file-relative paths are made absolute. + $yml_file_dir = dirname( $yml_file ); + + if ( isset( $sanitized_config['path'] ) ) + self::absolutize( $sanitized_config['path'], $yml_file_dir ); + + if ( isset( $sanitized_config['require'] ) ) { + foreach ( $sanitized_config['require'] as &$path ) { + self::absolutize( $path, $yml_file_dir ); + } + } return $sanitized_config; } From 3673a7d2762809f8a0a6ed96ad5cd3b204fbc67f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 15:34:18 +0300 Subject: [PATCH 1902/4858] harmonize command descriptions --- php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/commands/help.php | 2 +- php/commands/media.php | 2 +- php/commands/option.php | 2 +- php/commands/transient.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index afae682215..67282fd6ab 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -14,7 +14,7 @@ function __construct() { $this->name = 'wp'; - $this->shortdesc = 'Manage WordPress installations through the command-line.'; + $this->shortdesc = 'Manage WordPress through the command-line.'; } function get_extra_markdown() { diff --git a/php/commands/help.php b/php/commands/help.php index d1b2cc9456..c339c6fbf1 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -6,7 +6,7 @@ class Help_Command extends WP_CLI_Command { /** - * Get help on a certain topic. + * Get help on a certain command. * * @synopsis [<command>] */ diff --git a/php/commands/media.php b/php/commands/media.php index 0b73113fd6..3657d31912 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -1,7 +1,7 @@ <?php /** - * Control the media library and its attachments. + * Manage attachments. * * @package wp-cli */ diff --git a/php/commands/option.php b/php/commands/option.php index f3f83404c3..da3f3ceaf2 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -1,7 +1,7 @@ <?php /** - * Manage WordPress options. + * Manage options. * * @package wp-cli */ diff --git a/php/commands/transient.php b/php/commands/transient.php index c7dae59610..6294a79763 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -1,7 +1,7 @@ <?php /** - * Manage WordPress transients. + * Manage transients. * * @package wp-cli */ From 16c7dd9c79bc6225fe962f887e9875842e479297 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 21:51:28 +0300 Subject: [PATCH 1903/4858] behat: add test for --url global parameter --- features/flags.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index 3c59cd2365..f33e928640 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -1,5 +1,14 @@ Feature: Global flags + Scenario: Setting the URL + Given a WP install + + When I run `wp --url=localhost:8001 eval 'echo $_SERVER["SERVER_PORT"];'` + Then STDOUT should be: + """ + 8001 + """ + Scenario: Quiet run Given a WP install From f32919f56fac18c5cde937d07f455dd1130a3c45 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 21:52:39 +0300 Subject: [PATCH 1904/4858] set $_SERVER['SERVER_PORT'] --- php/utils.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/utils.php b/php/utils.php index dab686c871..de0f66bf55 100644 --- a/php/utils.php +++ b/php/utils.php @@ -156,6 +156,7 @@ function set_url_params( $url ) { $_SERVER['HTTP_HOST'] = $f('host'); $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); $_SERVER['REQUEST_URL'] = $f('path'); + $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; $_SERVER['QUERY_STRING'] = $f('query'); $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 649df2db99b25813f211e7af2f1ecc1da0fc7bd6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 22:10:13 +0300 Subject: [PATCH 1905/4858] behat: remove duplicate check in core.feature --- features/core.feature | 4 ---- 1 file changed, 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index d0004d5716..27d87889f7 100644 --- a/features/core.feature +++ b/features/core.feature @@ -69,10 +69,6 @@ Feature: Manage WordPress installation And wp-config.php And a database - When I try `wp core is-installed` - Then the return code should be 1 - And STDERR should not be empty - When I try `wp core is-installed` Then the return code should be 1 And STDERR should be: From e1136931194e065f014ef3369fb7ceb822e41b4b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 22:55:22 +0300 Subject: [PATCH 1906/4858] behat: install WP with custom URL --- features/bootstrap/FeatureContext.php | 2 +- features/core.feature | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index eb699c29b2..40928fc35a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -52,7 +52,7 @@ public static function prepare( SuiteEvent $event ) { 'wp core config' => self::$db_settings, 'wp core install' => array( - 'url' => 'http://example.com', + 'url' => 'http://localhost:8001', 'title' => 'WP CLI Site', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' diff --git a/features/core.feature b/features/core.feature index d0004d5716..cbbf65701a 100644 --- a/features/core.feature +++ b/features/core.feature @@ -84,8 +84,11 @@ Feature: Manage WordPress installation When I run `wp core install` Then STDOUT should not be empty - When I run `wp core version` - Then STDOUT should not be empty + When I run `wp eval 'echo home_url();'` + Then STDOUT should be: + """ + http://localhost:8001 + """ Scenario: Full install Given a WP install From b01bbc3cc28bd042d2bc8afb8712758d2ae7d9a8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 22:55:53 +0300 Subject: [PATCH 1907/4858] append port to $_SERVER['HTTP_HOST'] --- php/utils.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index de0f66bf55..9f3f5abb90 100644 --- a/php/utils.php +++ b/php/utils.php @@ -153,12 +153,19 @@ function set_url_params( $url ) { return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; }; - $_SERVER['HTTP_HOST'] = $f('host'); + if ( isset( $url_parts['host'] ) ) { + $_SERVER['HTTP_HOST'] = $url_parts['host']; + if ( isset( $url_parts['port'] ) ) { + $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; + } + + $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); + } + $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); $_SERVER['REQUEST_URL'] = $f('path'); $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; $_SERVER['QUERY_STRING'] = $f('query'); - $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; $_SERVER['HTTP_USER_AGENT'] = ''; $_SERVER['REQUEST_METHOD'] = 'GET'; From fadef7811bc3c97ed9cf1833764df03a7779cc8b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 22:56:16 +0300 Subject: [PATCH 1908/4858] don't set $_SERVER['REQUEST_URL'] not used by WordPress and probably bogus --- php/utils.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 9f3f5abb90..72ab484459 100644 --- a/php/utils.php +++ b/php/utils.php @@ -163,7 +163,6 @@ function set_url_params( $url ) { } $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); - $_SERVER['REQUEST_URL'] = $f('path'); $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; $_SERVER['QUERY_STRING'] = $f('query'); $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 8962f408c1388b5c95582c8451a0358e7b0d797c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 23:18:28 +0300 Subject: [PATCH 1909/4858] behat: set custom port only in that specific test, since multisite installs don't like it --- features/bootstrap/FeatureContext.php | 16 ++++++++-------- features/core.feature | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 40928fc35a..25836cc02c 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -51,13 +51,6 @@ public static function prepare( SuiteEvent $event ) { self::$additional_args = array( 'wp core config' => self::$db_settings, - 'wp core install' => array( - 'url' => 'http://localhost:8001', - 'title' => 'WP CLI Site', - 'admin_email' => 'admin@example.com', - 'admin_password' => 'password1' - ), - 'wp core install-network' => array( 'title' => 'WP CLI Network' ) @@ -191,7 +184,14 @@ public function wp_install( $subdir = '' ) { $this->proc( 'wp core config', array( 'dbprefix' => $subdir ? $subdir : 'wp_' ) )->run_check( $subdir ); - $this->proc( 'wp core install' )->run_check( $subdir ); + $install_args = array( + 'url' => 'http://example.com', + 'title' => 'WP CLI Site', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1' + ); + + $this->proc( 'wp core install', $install_args )->run_check( $subdir ); } } diff --git a/features/core.feature b/features/core.feature index cbbf65701a..c0477048a1 100644 --- a/features/core.feature +++ b/features/core.feature @@ -81,7 +81,7 @@ Feature: Manage WordPress installation Run `wp core install`. """ - When I run `wp core install` + When I run `wp core install --url='localhost:8001' --title='Test' --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty When I run `wp eval 'echo home_url();'` From 33fedb7ada301508d5059b112b3672f88e53c912 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 23:45:05 +0300 Subject: [PATCH 1910/4858] add test for --completions flag --- features/flags.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index f33e928640..8cb7107fca 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -150,3 +150,11 @@ Feature: Global flags """ [31;1mError: """ + + Scenario: Generate completions + Given an empty directory + When I run `wp --completions` + Then STDOUT should contain: + """ + transient delete get set type + """ From e35483b4656913415dbe2dc88deea4ae11936c2d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Jun 2013 23:45:52 +0300 Subject: [PATCH 1911/4858] move completions flag to 'cli' command --- php/WP_CLI/Runner.php | 15 +++------------ php/commands/cli.php | 8 ++++++++ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 0ce51fb0cb..5740b0de4a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -233,9 +233,10 @@ private static function back_compat_conversions( $args, $assoc_args ) { unset( $assoc_args['json'] ); } - // --{version|info} -> cli {version|info} + // --{version|info|completions} -> cli {version|info|completions} if ( empty( $args ) ) { - foreach ( array( 'version', 'info' ) as $key ) { + $special_flags = array( 'version', 'info', 'completions' ); + foreach ( $special_flags as $key ) { if ( isset( $assoc_args[ $key ] ) ) { $args = array( 'cli', $key ); break; @@ -359,16 +360,6 @@ public function after_wp_load() { // Handle --user parameter self::set_user( $this->config ); - // Handle --completions parameter - if ( isset( $this->assoc_args['completions'] ) ) { - foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { - $subcommands = $command->get_subcommands(); - - WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); - } - exit; - } - $this->_run_command(); } } diff --git a/php/commands/cli.php b/php/commands/cli.php index b371c23147..b537b10280 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -55,6 +55,14 @@ function param_dump() { function cmd_dump() { echo json_encode( self::command_to_array( WP_CLI::$root ) ); } + + function completions() { + foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { + $subcommands = $command->get_subcommands(); + + WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); + } + } } WP_CLI::add_command( 'cli', 'CLI_Command' ); From a568f674640b534481d4bab5e5a2b7c62a880129 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 12 Feb 2013 14:07:21 +1300 Subject: [PATCH 1912/4858] A wee bit of work on an import command --- php/WP_CLI/Runner.php | 4 ++++ php/commands/import.php | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 php/commands/import.php diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 0ce51fb0cb..7a469c788d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -351,6 +351,10 @@ public function before_wp_load() { Utils\set_url_params( 'http://example.com' ); } } + + if ( $this->cmd_starts_with( array( 'import') ) ) + define( 'WP_LOAD_IMPORTERS', true ); + } public function after_wp_load() { diff --git a/php/commands/import.php b/php/commands/import.php new file mode 100644 index 0000000000..92bcfe1f4c --- /dev/null +++ b/php/commands/import.php @@ -0,0 +1,43 @@ +<?php + +class Import_Command extends WP_CLI_Command { + + /** + * Import content from a WXR file + * + * @synopsis <file> [--author_mapping=<file>] [--skip_attachments=<bool>] + */ + public function __invoke( $args, $assoc_args ) { + + list( $file ) = $args; + + $defaults = array( + 'skip_attachments' => false, + 'author_mapping' => null, + ); + $assoc_args = wp_parse_args( $assoc_args, $defaults ); + + $wp_import = new WP_Import; + $wp_import->fetch_attachments = ( $assoc_args['skip_attachments'] ) ? false : true; + + $_GET = array( 'import' => 'wordpress', 'step' => 2 ); + $author_in = $user_select = array(); + // @todo properly handle mapping + foreach( array() as $in => $out ) { + $author_in[] = sanitize_user( $in, true ); + $user_select[] = $out; + } + $_POST = array( + 'imported_authors' => $author_in, + 'user_map' => $user_select, + 'fetch_attachments' => $wp_import->fetch_attachments, + ); + $wp_import->import( $file ); + + WP_CLI::success( "Import complete." ); + } + + +} + +WP_CLI::add_command( 'import', new Import_Command ); \ No newline at end of file From ffa3037f63b528439966dc2b5b8601353a80a21a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 21 Apr 2013 08:19:16 -0700 Subject: [PATCH 1913/4858] Also define `WP_IMPORTING`, as this constant can be used to determine whether a number of supplemental actions are run (or not) --- php/WP_CLI/Runner.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7a469c788d..65baffdecd 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -352,8 +352,10 @@ public function before_wp_load() { } } - if ( $this->cmd_starts_with( array( 'import') ) ) + if ( $this->cmd_starts_with( array( 'import') ) ) { define( 'WP_LOAD_IMPORTERS', true ); + define( 'WP_IMPORTING', true ); + } } From 6b131265c6d332d5234bfe1ae2dcb2e4ee32cbb2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 21 Apr 2013 09:04:52 -0700 Subject: [PATCH 1914/4858] First pass at a refactor to make `wp import` more abstracted, and potentially support multiple importers. --- php/commands/import.php | 95 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index 92bcfe1f4c..cf766875cf 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -3,23 +3,67 @@ class Import_Command extends WP_CLI_Command { /** - * Import content from a WXR file + * Import content. * - * @synopsis <file> [--author_mapping=<file>] [--skip_attachments=<bool>] + * @synopsis <file> [--authors=<authors>] [--skip=<data-type>] */ public function __invoke( $args, $assoc_args ) { list( $file ) = $args; + if ( ! file_exists( $file ) ) + WP_CLI::error( "File to import doesn't exist." ); + $defaults = array( - 'skip_attachments' => false, - 'author_mapping' => null, + 'type' => 'wxr', + 'authors' => null, + 'skip' => array(), ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); + $assoc_args['file'] = $file; + + if ( ! empty( $assoc_args['skip'] ) ) + $assoc_args['skip'] = explode( ',', $assoc_args['skip'] ); + + $importer = $this->is_importer_available( $assoc_args['type'] ); + if ( is_wp_error( $importer ) ) + WP_CLI::error( $importer->get_error_message() ); + + $ret = $this->import( $assoc_args ); + + if ( is_wp_error( $ret ) ) + WP_CLI::error( $ret->get_error_message() ); + else + WP_CLI::success( "Import complete." ); + } + + /** + * Import a file into WordPress. + */ + private function import( $args ) { + + switch( $args['type'] ) { + case 'wxr': + case 'wordpress': + $ret = $this->import_wxr( $args ); + break; + default: + $ret = new WP_Error( 'missing-import-type', "Import type doesn't exist." ); + break; + } + return $ret; + } + + /** + * Import a WXR file + */ + private function import_wxr( $args ) { + $wp_import = new WP_Import; - $wp_import->fetch_attachments = ( $assoc_args['skip_attachments'] ) ? false : true; + $wp_import->fetch_attachments = ( in_array( 'attachment', $args['skip'] ) ) ? false : true; + $_GET = array( 'import' => 'wordpress', 'step' => 2 ); $author_in = $user_select = array(); // @todo properly handle mapping @@ -28,13 +72,42 @@ public function __invoke( $args, $assoc_args ) { $user_select[] = $out; } $_POST = array( - 'imported_authors' => $author_in, - 'user_map' => $user_select, - 'fetch_attachments' => $wp_import->fetch_attachments, - ); - $wp_import->import( $file ); + 'imported_authors' => $author_in, + 'user_map' => $user_select, + 'fetch_attachments' => $wp_import->fetch_attachments, + ); + $wp_import->import( $args['file'] ); + + return true; + } + + /** + * Is the requested importer available? + */ + private function is_importer_available( $importer ) { + + require_once ABSPATH . 'wp-admin/includes/plugin.php'; - WP_CLI::success( "Import complete." ); + switch ( $importer ) { + case 'wxr': + case 'wordpress': + if ( class_exists( 'WP_Import' ) ) { + $ret = true; + } else { + $plugins = get_plugins(); + $wordpress_importer = 'wordpress-importer/wordpress-importer.php'; + if ( array_key_exists( $wordpress_importer, $plugins ) ) + $error_msg = "WordPress Importer needs to be activated. Try 'wp plugin activate wordpress-importer'."; + else + $error_msg = "WordPress Importer needs to be installed. Try 'wp plugin install wordpress-importer --activate'."; + $ret = new WP_Error( 'importer-missing', $error_msg ); + } + break; + default: + $ret = new WP_Error( 'missing-import-type', "Import type doesn't exist." ); + break; + } + return $ret; } From 630086271cc0151de45e6b7078ee96036ff36bd0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 21 Apr 2013 11:20:02 -0700 Subject: [PATCH 1915/4858] Incorporate author mapping support into the WordPress importer. * If a .csv filename is specified, it will look for an author mapping file. * If the .csv author mapping file doesn't exist, it will create one for you and wait for you to edit. * `--authors=create` will create any missing users, and expect that either user_email or user_logins map up directly. * `--authors=skip` will ignore any byline mapping. --- php/commands/import.php | 119 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 112 insertions(+), 7 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index cf766875cf..40e1c510c1 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -61,16 +61,80 @@ private function import( $args ) { private function import_wxr( $args ) { $wp_import = new WP_Import; + $import_data = $wp_import->parse( $args['file'] ); + if ( is_wp_error( $import_data ) ) + return $import_data; - $wp_import->fetch_attachments = ( in_array( 'attachment', $args['skip'] ) ) ? false : true; - - $_GET = array( 'import' => 'wordpress', 'step' => 2 ); $author_in = $user_select = array(); - // @todo properly handle mapping - foreach( array() as $in => $out ) { - $author_in[] = sanitize_user( $in, true ); - $user_select[] = $out; + if ( file_exists( $args['authors'] ) ) { + foreach ( new \WP_CLI\Iterators\CSV( $args['authors'] ) as $i => $author ) { + if ( ! array_key_exists( 'old_user_login', $author ) || ! array_key_exists( 'new_user_login', $author ) ) + return new WP_Error( 'invalid-author-mapping', "Author mapping file isn't properly formatted." ); + + $author_in[] = $author['old_user_login']; + $user_select[] = $author['new_user_login']; + } + } else if ( false !== stripos( $args['authors'], '.csv' ) ) { + if ( touch( $args['authors'] ) ) { + $author_mapping = array(); + foreach( $import_data['authors'] as $wxr_author ) { + $author_mapping[] = array( + 'old_user_login' => $wxr_author['author_login'], + 'new_user_login' => $this->suggest_user( $wxr_author['author_login'], $wxr_author['author_email'] ), + ); + } + $file = fopen( $args['authors'], 'w' ); + \WP_CLI\utils\write_csv( $file, $author_mapping, array( 'old_user_login', 'new_user_login' ) ); + WP_CLI::success( sprintf( "Please update author mapping file before continuing: %s", $args['authors'] ) ); + exit; + } else { + return new WP_Error( 'author-mapping-error', "Couldn't create author mapping file." ); + } + } else { + switch( $args['authors'] ) { + // Create authors if they don't yet exist; maybe match on email or user_login + case 'create': + foreach( $import_data['authors'] as $author ) { + + if ( $user = get_user_by( 'email', $author['author_email'] ) ) { + $author_in[] = $author['author_login']; + $user_select[] = $user->user_login; + continue; + } + + if ( $user = get_user_by( 'login', $author['author_login'] ) ) { + $author_in[] = $author['author_login']; + $user_select[] = $user->user_login; + continue; + } + + $user = array( + 'user_login' => $author['author_login'], + 'user_email' => $author['author_email'], + 'display_name' => $author['author_display_name'], + 'first_name' => $author['author_first_name'], + 'last_name' => $author['author_last_name'], + 'user_pass' => wp_generate_password(), + ); + $user_id = wp_insert_user( $user ); + if ( is_wp_error( $user_id ) ) + return $user_id; + + $user = get_user_by( 'id', $user_id ); + $author_in[] = $author['author_login']; + $user_select[] = $user->user_login; + } + break; + // Skip any sort of author mapping + case 'skip': + break; + default: + return new WP_Error( 'invalid-argument', "'authors' argument is invalid." ); + } } + + $wp_import->fetch_attachments = ( in_array( 'attachment', $args['skip'] ) ) ? false : true; + $_GET = array( 'import' => 'wordpress', 'step' => 2 ); $_POST = array( 'imported_authors' => $author_in, 'user_map' => $user_select, @@ -110,6 +174,47 @@ private function is_importer_available( $importer ) { return $ret; } + /** + * Suggest a blog user based on the levenshtein distance + */ + private function suggest_user( $author_user_login, $author_user_email = '' ) { + + if ( ! isset( $this->blog_users ) ) + $this->blog_users = get_users(); + + $shortest = -1; + $shortestavg = array(); + + $threshold = floor( ( strlen( $author_user_login ) / 100 ) * 10 ); // 10 % of the strlen are valid + $closest = ''; + foreach ( $this->blog_users as $user ) { + // Before we resort to an algorithm, let's try for an exact match + if ( $author_user_email && $user->user_email == $author_user_email ) + return $user->user_login; + + $levs[] = levenshtein( $author_user_login, $user->display_name ); + $levs[] = levenshtein( $author_user_login, $user->user_login ); + $levs[] = levenshtein( $author_user_login, $user->user_email ); + $levs[] = levenshtein( $author_user_login, array_shift( explode( "@", $user->user_email ) ) ); + arsort( $levs ); + $lev = array_pop( $levs ); + if ( 0 == $lev ) { + $closest = $user->user_login; + $shortest = 0; + break; + } + + if ( ( $lev <= $shortest || $shortest < 0 ) && $lev <= $threshold ) { + $closest = $user->user_login; + $shortest = $lev; + } + $shortestavg[] = $lev; + } + // in case all usernames have a common pattern + if ( $shortest > ( array_sum( $shortestavg ) / count( $shortestavg ) ) ) + return ''; + return $closest; + } } From dcec61f962e00fb8d502fbf0bd263aa2c5be2aeb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 21 Apr 2013 12:29:45 -0700 Subject: [PATCH 1916/4858] Refactor author mapping code so it can be used with other importers --- php/commands/import.php | 220 ++++++++++++++++++++++++++++------------ 1 file changed, 154 insertions(+), 66 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index 40e1c510c1..954567dd13 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -65,74 +65,47 @@ private function import_wxr( $args ) { if ( is_wp_error( $import_data ) ) return $import_data; - $author_in = $user_select = array(); - if ( file_exists( $args['authors'] ) ) { - foreach ( new \WP_CLI\Iterators\CSV( $args['authors'] ) as $i => $author ) { - if ( ! array_key_exists( 'old_user_login', $author ) || ! array_key_exists( 'new_user_login', $author ) ) - return new WP_Error( 'invalid-author-mapping', "Author mapping file isn't properly formatted." ); - - $author_in[] = $author['old_user_login']; - $user_select[] = $author['new_user_login']; - } - } else if ( false !== stripos( $args['authors'], '.csv' ) ) { - if ( touch( $args['authors'] ) ) { - $author_mapping = array(); - foreach( $import_data['authors'] as $wxr_author ) { - $author_mapping[] = array( - 'old_user_login' => $wxr_author['author_login'], - 'new_user_login' => $this->suggest_user( $wxr_author['author_login'], $wxr_author['author_email'] ), - ); - } - $file = fopen( $args['authors'], 'w' ); - \WP_CLI\utils\write_csv( $file, $author_mapping, array( 'old_user_login', 'new_user_login' ) ); - WP_CLI::success( sprintf( "Please update author mapping file before continuing: %s", $args['authors'] ) ); - exit; - } else { - return new WP_Error( 'author-mapping-error', "Couldn't create author mapping file." ); - } - } else { - switch( $args['authors'] ) { - // Create authors if they don't yet exist; maybe match on email or user_login - case 'create': - foreach( $import_data['authors'] as $author ) { - - if ( $user = get_user_by( 'email', $author['author_email'] ) ) { - $author_in[] = $author['author_login']; - $user_select[] = $user->user_login; - continue; - } - - if ( $user = get_user_by( 'login', $author['author_login'] ) ) { - $author_in[] = $author['author_login']; - $user_select[] = $user->user_login; - continue; - } - - $user = array( - 'user_login' => $author['author_login'], - 'user_email' => $author['author_email'], - 'display_name' => $author['author_display_name'], - 'first_name' => $author['author_first_name'], - 'last_name' => $author['author_last_name'], - 'user_pass' => wp_generate_password(), - ); - $user_id = wp_insert_user( $user ); - if ( is_wp_error( $user_id ) ) - return $user_id; - - $user = get_user_by( 'id', $user_id ); - $author_in[] = $author['author_login']; - $user_select[] = $user->user_login; - } - break; - // Skip any sort of author mapping - case 'skip': - break; - default: - return new WP_Error( 'invalid-argument', "'authors' argument is invalid." ); - } + // Prepare the data to be used in process_author_mapping(); + $wp_import->get_authors_from_import( $import_data ); + $author_data = array(); + foreach( $wp_import->authors as $wxr_author ) { + $author = new \stdClass; + // Always in the WXR + $author->user_login = $wxr_author['author_login']; + $author->user_email = $wxr_author['author_email']; + + // Should be in the WXR; no guarantees + if ( isset( $wxr_author['author_display_name'] ) ) + $author->display_name = $wxr_author['author_display_name']; + if ( isset( $wxr_author['author_first_name'] ) ) + $author->first_name = $wxr_author['author_first_name']; + if ( isset( $wxr_author['author_last_name'] ) ) + $author->last_name = $wxr_author['author_last_name']; + + $author_data[] = $author; } + // Build the author mapping + $author_mapping = $this->process_author_mapping( $args['authors'], $author_data ); + if ( is_wp_error( $author_mapping ) ) + return $author_mapping; + + $author_in = wp_list_pluck( $author_mapping, 'old_user_login' ); + $author_out = wp_list_pluck( $author_mapping, 'new_user_login' ); + // $user_select needs to be an array of user IDs + $user_select = array(); + $invalid_user_select = array(); + foreach( $author_out as $author_login ) { + $user = get_user_by( 'login', $author_login ); + if ( $user ) + $user_select[] = $user->ID; + else + $invalid_user_select[] = $author_login; + } + if ( ! empty( $invalid_user_select ) ) + return new WP_Error( 'invalid-author-mapping', sprintf( "These user_logins are invalid: %s", implode( ',', $invalid_user_select ) ) ); + + // Drive the import $wp_import->fetch_attachments = ( in_array( 'attachment', $args['skip'] ) ) ? false : true; $_GET = array( 'import' => 'wordpress', 'step' => 2 ); $_POST = array( @@ -174,6 +147,121 @@ private function is_importer_available( $importer ) { return $ret; } + /** + * Process how the authors should be mapped + * + * @param string $authors_arg The `--author` argument originally passed to command + * @param array $author_data An array of WP_User-esque author objects + * @return array|WP_Error $author_mapping Author mapping array if successful, WP_Error if something bad happened + */ + private function process_author_mapping( $authors_arg, $author_data ) { + + // Provided an author mapping file (method checks validity) + if ( file_exists( $authors_arg ) ) + return $this->read_author_mapping_file( $authors_arg ); + + // Provided a file reference, but the file doesn't yet exist + if ( false !== stripos( $authors_arg, '.csv' ) ) + return $this->create_author_mapping_file( $authors_arg, $author_data ); + + switch( $authors_arg ) { + // Create authors if they don't yet exist; maybe match on email or user_login + case 'create': + return $this->create_authors_for_mapping( $author_data ); + break; + // Skip any sort of author mapping + case 'skip': + return array(); + break; + default: + return new WP_Error( 'invalid-argument', "'authors' argument is invalid." ); + } + } + + /** + * Read an author mapping file + */ + private function read_author_mapping_file( $file ) { + + $author_mapping = array(); + foreach ( new \WP_CLI\Iterators\CSV( $file ) as $i => $author ) { + if ( ! array_key_exists( 'old_user_login', $author ) || ! array_key_exists( 'new_user_login', $author ) ) + return new WP_Error( 'invalid-author-mapping', "Author mapping file isn't properly formatted." ); + + $author_mapping[] = $author; + } + return $author_mapping; + } + + /** + * Create an author mapping file, based on provided author data + * + * @return WP_Error The file was just now created, so some action needs to be taken + */ + private function create_author_mapping_file( $file, $author_data ) { + + if ( touch( $file ) ) { + $author_mapping = array(); + foreach( $author_data as $author ) { + $author_mapping[] = array( + 'old_user_login' => $author->user_login, + 'new_user_login' => $this->suggest_user( $author->user_login, $author->user_email ), + ); + } + $file_resource = fopen( $file, 'w' ); + \WP_CLI\utils\write_csv( $file_resource, $author_mapping, array( 'old_user_login', 'new_user_login' ) ); + return new WP_Error( 'author-mapping-error', sprintf( "Please update author mapping file before continuing: %s", $file ) ); + } else { + return new WP_Error( 'author-mapping-error', "Couldn't create author mapping file." ); + } + } + + /** + * Create users if they don't exist, and build an author mapping file + */ + private function create_authors_for_mapping( $author_data ) { + + $author_mapping = array(); + foreach( $author_data as $author ) { + + if ( isset( $author->user_email ) ) { + if ( $user = get_user_by( 'email', $author->user_email ) ) { + $author_mapping[] = array( + 'old_user_login' => $author->user_login, + 'new_user_login' => $user->user_login, + ); + continue; + } + } + + if ( $user = get_user_by( 'login', $author->user_login ) ) { + $author_mapping[] = array( + 'old_user_login' => $author->user_login, + 'new_user_login' => $user->user_login, + ); + continue; + } + + $user = array( + 'user_login' => '', + 'user_email' => '', + 'user_pass' => wp_generate_password(), + ); + $user = array_merge( $user, (array)$author ); + $user_id = wp_insert_user( $user ); + if ( is_wp_error( $user_id ) ) + return $user_id; + + $user = get_user_by( 'id', $user_id ); + $author_mapping[] = array( + 'old_user_login' => $author->user_login, + 'new_user_login' => $user->user_login, + ); + } + return $author_mapping; + + } + /** * Suggest a blog user based on the levenshtein distance */ From 19d06afd92ac4ae9cf13633f42efe06a79bf655b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <danielbachhuber@gmail.com> Date: Thu, 25 Apr 2013 17:29:34 +0000 Subject: [PATCH 1917/4858] Make the `--authors` argument required. It's a very necessary step, even if just to have the user confirm they're skipping mappings. --- php/commands/import.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index 954567dd13..f682287cdc 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -5,7 +5,7 @@ class Import_Command extends WP_CLI_Command { /** * Import content. * - * @synopsis <file> [--authors=<authors>] [--skip=<data-type>] + * @synopsis <file> --authors=<authors> [--skip=<data-type>] */ public function __invoke( $args, $assoc_args ) { From 52da29f162ea314bead853554d1ba92c99531a78 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <danielbachhuber@gmail.com> Date: Mon, 24 Jun 2013 12:41:30 +0000 Subject: [PATCH 1918/4858] Incorporate @mjangda's helpful verbosity filters --- php/commands/import.php | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/php/commands/import.php b/php/commands/import.php index f682287cdc..80240fac5d 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -46,6 +46,7 @@ private function import( $args ) { switch( $args['type'] ) { case 'wxr': case 'wordpress': + $this->add_wxr_filters(); $ret = $this->import_wxr( $args ); break; default: @@ -118,6 +119,65 @@ private function import_wxr( $args ) { return true; } + /** + * Useful verbosity filters for the WXR importer + */ + private function add_wxr_filters() { + + add_filter( 'wp_import_posts', function( $posts ) { + global $wpcli_import_counts; + $wpcli_import_counts['current_post'] = 0; + $wpcli_import_counts['total_posts'] = count( $posts ); + return $posts; + }, 10 ); + + add_filter( 'wp_import_post_comments', function( $comments, $post_id, $post ) { + global $wpcli_import_counts; + $wpcli_import_counts['current_comment'] = 0; + $wpcli_import_counts['total_comments'] = count( $comments ); + return $comments; + }, 10, 3 ); + + add_filter( 'wp_import_post_data_raw', function( $post ) { + global $wpcli_import_counts; + + $wpcli_import_counts['current_post']++; + WP_CLI::line(); + WP_CLI::line(); + WP_CLI::line( sprintf( 'Processing post #%d ("%s") (post_type: %s)', $post['post_id'], $post['post_title'], $post['post_type'] ) ); + WP_CLI::line( sprintf( '-- %s of %s', number_format( $wpcli_import_counts['current_post'] ), number_format( $wpcli_import_counts['total_posts'] ) ) ); + WP_CLI::line( '-- ' . date( 'r' ) ); + + return $post; + } ); + + add_action( 'wp_import_insert_post', function( $post_id, $original_post_ID, $post, $postdata ) { + if ( is_wp_error( $post_id ) ) + WP_CLI::warning( "-- Error importing post: " . $post_id->get_error_code() ); + else + WP_CLI::line( "-- Imported post as post_id #{$post_id}" ); + }, 10, 4 ); + + add_action( 'wp_import_insert_term', function( $t, $import_term, $post_id, $post ) { + WP_CLI::line( "-- Created term \"{$import_term['name']}\"" ); + }, 10, 4 ); + + add_action( 'wp_import_set_post_terms', function( $tt_ids, $term_ids, $taxonomy, $post_id, $post ) { + WP_CLI::line( "-- Added terms (" . implode( ',', $term_ids ) .") for taxonomy \"{$taxonomy}\"" ); + }, 10, 5 ); + + add_action( 'wp_import_insert_comment', function( $comment_id, $comment, $comment_post_ID, $post ) { + global $wpcli_import_counts; + $wpcli_import_counts['current_comment']++; + WP_CLI::line( sprintf( '-- Added comment #%d (%s of %s)', $comment_id, number_format( $wpcli_import_counts['current_comment'] ), number_format( $wpcli_import_counts['total_comments'] ) ) ); + }, 10, 4 ); + + add_action( 'import_post_meta', function( $post_id, $key, $value ) { + WP_CLI::line( "-- Added post_meta $key" ); + }, 10, 3 ); + + } + /** * Is the requested importer available? */ From b48cf5d059364ab2ae383731b3e0eb8dba1bf0fe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Jun 2013 10:48:58 -0700 Subject: [PATCH 1919/4858] Allow a subset of STDOUT and STDERR to be used with a syntax like: `'Writing to file %s'` --- features/steps/basic_steps.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index c90c4a736b..8198bf7b71 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -126,9 +126,19 @@ function ( $world ) { } ); -$steps->Given( '/^save (STDOUT|STDERR) as \{(\w+)\}$/', - function ( $world, $stream, $key ) { - $world->variables[ $key ] = rtrim( $world->result->$stream, "\n" ); +$steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', + function ( $world, $stream, $output_filter, $key ) { + + if ( $output_filter ) { + $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; + if ( false !== preg_match( $output_filter, $world->result->$stream, $matches ) ) + $output = array_pop( $matches ); + else + $output = ''; + } else { + $output = $world->result->$stream; + } + $world->variables[ $key ] = trim( $output, "\n" ); } ); From 9b757f990326f36a95b80285cba0606668bedd00 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Jun 2013 10:50:47 -0700 Subject: [PATCH 1920/4858] Basic feature test for import command --- features/import.feature | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 features/import.feature diff --git a/features/import.feature b/features/import.feature new file mode 100644 index 0000000000..ffab45b5e1 --- /dev/null +++ b/features/import.feature @@ -0,0 +1,44 @@ +Feature: Import content. + +Scenario: Basic export then import + Given a WP install + + When I run `wp post generate --post_type=post --count=3` + Then STDOUT should not be empty + + When I run `wp post generate --post_type=page --count=2` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=csv | wc -l` + Then STDOUT should be: + """ + 8 + """ + + When I run `wp export` + Then STDOUT should contain: + """ + All done with export + """ + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=csv | wc -l` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should not be empty + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=csv | wc -l` + Then STDOUT should be: + """ + 8 + """ \ No newline at end of file From 11f18c8ec3cfa891f22439a7f04ab67a7d9da738 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Jun 2013 11:04:31 -0700 Subject: [PATCH 1921/4858] Update docs --- man-src/import.txt | 13 +++++++++++++ php/commands/import.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 man-src/import.txt diff --git a/man-src/import.txt b/man-src/import.txt new file mode 100644 index 0000000000..8a26f302e2 --- /dev/null +++ b/man-src/import.txt @@ -0,0 +1,13 @@ +## OPTIONS + +* `<file>`: + + Path to a valid WXR file for importing. + +* `--authors=<authors>`: + + How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. + +* `--skip=<data-type>`: + + Skip importing specific data. Supported option is 'attachment'. \ No newline at end of file diff --git a/php/commands/import.php b/php/commands/import.php index 80240fac5d..b9f41b8af1 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -3,7 +3,7 @@ class Import_Command extends WP_CLI_Command { /** - * Import content. + * Import content from a WXR file. * * @synopsis <file> --authors=<authors> [--skip=<data-type>] */ From c5e1f4212b99610386deb5d97b198aad7959a8ae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Jun 2013 14:10:49 -0700 Subject: [PATCH 1922/4858] For most `wp user` subcommands, the first argument can be user ID or login --- php/commands/user.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 3533ec800d..d4b23b3f9e 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -59,13 +59,14 @@ public function _list( $args, $assoc_args ) { /** * Delete one or more users. * - * @synopsis <id>... [--reassign=<id>] + * @synopsis <user>... [--reassign=<id>] */ public function delete( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( 'reassign' => null ) ); + $args[0] = self::get_user_from_first_arg( $args[0] )->ID; parent::delete( $args, $assoc_args ); } @@ -145,9 +146,11 @@ protected function _create( $params ) { /** * Update a user. * - * @synopsis <id>... --<field>=<value> + * @synopsis <user>... --<field>=<value> */ public function update( $args, $assoc_args ) { + + $args[0] = self::get_user_from_first_arg( $args[0] )->ID; parent::update( $args, $assoc_args, 'user' ); } @@ -212,7 +215,7 @@ public function generate( $args, $assoc_args ) { * Set the user role (for a particular blog). * * @subcommand set-role - * @synopsis <user-login> [<role>] + * @synopsis <user> [<role>] */ public function set_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); @@ -232,7 +235,7 @@ public function set_role( $args, $assoc_args ) { * Add a role for a user. * * @subcommand add-role - * @synopsis <user-login> <role> + * @synopsis <user> <role> */ public function add_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); @@ -248,7 +251,7 @@ public function add_role( $args, $assoc_args ) { * Remove a user's role. * * @subcommand remove-role - * @synopsis <user-login> [<role>] + * @synopsis <user> [<role>] */ public function remove_role( $args, $assoc_args ) { $user = self::get_user_from_first_arg( $args[0] ); From 2e144908c25126c26f43c27c2b0c6393da177947 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Jun 2013 14:14:18 -0700 Subject: [PATCH 1923/4858] Update documentation --- man-src/user-delete.txt | 4 ++-- man-src/user-remove-role.txt | 2 +- man-src/user-set-role.txt | 2 +- man-src/user-update.txt | 6 ++++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/man-src/user-delete.txt b/man-src/user-delete.txt index 920282f7e6..88d8966a16 100644 --- a/man-src/user-delete.txt +++ b/man-src/user-delete.txt @@ -1,8 +1,8 @@ ## OPTIONS -* `<ID>`: +* `<user>`: - The ID of the user to delete. + The user login or ID of the user to delete. * `--reassign`=<ID>: diff --git a/man-src/user-remove-role.txt b/man-src/user-remove-role.txt index c85990bd4e..b4a77e47d9 100644 --- a/man-src/user-remove-role.txt +++ b/man-src/user-remove-role.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `<user-login>`: +* `<user>`: User ID or user login. diff --git a/man-src/user-set-role.txt b/man-src/user-set-role.txt index 3c5050f0e6..84190293b6 100644 --- a/man-src/user-set-role.txt +++ b/man-src/user-set-role.txt @@ -1,6 +1,6 @@ ## OPTIONS -* `<user-login>`: +* `<user>`: User ID or user login. diff --git a/man-src/user-update.txt b/man-src/user-update.txt index 9a93a9f81a..092ab8b594 100644 --- a/man-src/user-update.txt +++ b/man-src/user-update.txt @@ -1,8 +1,8 @@ ## OPTIONS -* `<ID>`: +* `<user>`: - The ID of the user to update. + The user login or ID of the user to update. * `--<field>`=<value>: @@ -11,3 +11,5 @@ ## EXAMPLES wp user update 123 --user_login=mary --display_name=Mary + + wp user update mary --user_pass=marypass From f7c0354a8f9bf8e93811824000631aa435bb7cf3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Jun 2013 14:25:20 -0700 Subject: [PATCH 1924/4858] Have the success message appear on its own line https://github.com/wp-cli/wp-cli/pull/299#issuecomment-20008252 --- php/commands/import.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index b9f41b8af1..c904e53c02 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -32,10 +32,12 @@ public function __invoke( $args, $assoc_args ) { $ret = $this->import( $assoc_args ); - if ( is_wp_error( $ret ) ) + if ( is_wp_error( $ret ) ) { WP_CLI::error( $ret->get_error_message() ); - else + } else { + WP_CLI::line(); // WXR import ends with HTML, so make sure message is on next line WP_CLI::success( "Import complete." ); + } } /** From 8329d4b0e4f2217a48c96c12a81584fa70a70854 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 15:39:31 +0300 Subject: [PATCH 1925/4858] copy files from wp-includes/export verbatim --- php/export/class-wp-export-oxymel.php | 27 ++ php/export/class-wp-export-query.php | 311 +++++++++++++++++++ php/export/class-wp-export-wxr-formatter.php | 262 ++++++++++++++++ php/export/functions.export.php | 30 ++ php/export/writers.php | 145 +++++++++ 5 files changed, 775 insertions(+) create mode 100644 php/export/class-wp-export-oxymel.php create mode 100644 php/export/class-wp-export-query.php create mode 100644 php/export/class-wp-export-wxr-formatter.php create mode 100644 php/export/functions.export.php create mode 100644 php/export/writers.php diff --git a/php/export/class-wp-export-oxymel.php b/php/export/class-wp-export-oxymel.php new file mode 100644 index 0000000000..6c2bc96742 --- /dev/null +++ b/php/export/class-wp-export-oxymel.php @@ -0,0 +1,27 @@ +<?php + +require_once ABSPATH . WPINC . '/Oxymel.php'; + +class WP_Export_Oxymel extends Oxymel { + public function optional( $tag_name, $contents ) { + if ( $contents ) { + $this->$tag_name( $contents ); + } + return $this; + } + + public function optional_cdata( $tag_name, $contents ) { + if ( $contents ) { + $this->$tag_name->contains->cdata( $contents )->end; + } + return $this; + } + + public function cdata( $text ) { + if ( !seems_utf8( $text ) ) { + $text = utf8_encode( $text ); + } + return parent::cdata( $text ); + } +} + diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php new file mode 100644 index 0000000000..5522cc06a8 --- /dev/null +++ b/php/export/class-wp-export-query.php @@ -0,0 +1,311 @@ +<?php +/** + * Represents a set of posts and other site data to be exported. + * + * An immutable object, which gathers all data needed for the export. + */ +class WP_Export_Query { + const QUERY_CHUNK = 100; + + private static $defaults = array( + 'post_ids' => null, + 'post_type' => null, + 'status' => null, + 'author' => null, + 'start_date' => null, + 'end_date' => null, + 'category' => null, + ); + + private $post_ids; + private $filters; + private $xml_gen; + + private $wheres = array(); + private $joins = array(); + + private $author; + private $category; + + public function __construct( $filters = array() ) { + $this->filters = wp_parse_args( $filters, self::$defaults ); + $this->post_ids = $this->calculate_post_ids(); + } + + public function post_ids() { + return $this->post_ids; + } + + public function charset() { + return get_bloginfo( 'charset' ); + } + + public function site_metadata() { + $metadata = array( + 'name' => $this->bloginfo_rss( 'name' ), + 'url' => $this->bloginfo_rss( 'url' ), + 'language' => $this->bloginfo_rss( 'language' ), + 'description' => $this->bloginfo_rss( 'description' ), + 'pubDate' => date( 'D, d M Y H:i:s +0000' ), + 'site_url' => is_multisite()? network_home_url() : $this->bloginfo_rss( 'url' ), + 'blog_url' => $this->bloginfo_rss( 'url' ), + ); + return $metadata; + } + + public function wp_generator_tag() { + return apply_filters( 'the_generator', get_the_generator( 'export' ), 'export' ); + } + + public function authors() { + global $wpdb; + $authors = array(); + $author_ids = $wpdb->get_col( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft'" ); + foreach ( (array) $author_ids as $author_id ) { + $authors[] = get_userdata( $author_id ); + } + $authors = array_filter( $authors ); + return $authors; + } + + public function categories() { + if ( $this->category ) { + return array( $this->category ); + } + if ( $this->filters['post_type'] ) { + return array(); + } + $categories = (array) get_categories( array( 'get' => 'all' ) ); + $categories = self::topologically_sort_terms( $categories ); + return $categories; + } + + public function tags() { + if ( $this->filters['post_type'] ) { + return array(); + } + $tags = (array) get_tags( array( 'get' => 'all' ) ); + return $tags; + } + + public function custom_taxonomies_terms() { + if ( $this->filters['post_type'] ) { + return array(); + } + $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); + $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); + $custom_terms = self::topologically_sort_terms( $custom_terms ); + return $custom_terms; + } + + public function nav_menu_terms() { + $nav_menus = wp_get_nav_menus(); + foreach( $nav_menus as &$term ) { + $term->description = ''; + } + return $nav_menus; + } + + public function exportify_post( $post ) { + $GLOBALS['wp_query']->in_the_loop = true; + $previous_global_post = isset( $GLOBALS['post'] )? $GLOBALS['post'] : null; + $GLOBALS['post'] = $post; + setup_postdata( $post ); + $post->post_content = apply_filters( 'the_content_export', $post->post_content ); + $post->post_excerpt = apply_filters( 'the_excerpt_export', $post->post_excerpt ); + $post->is_sticky = is_sticky( $post->ID ) ? 1 : 0; + $post->terms = self::get_terms_for_post( $post ); + $post->meta = self::get_meta_for_post( $post ); + $post->comments = self::get_comments_for_post( $post ); + $GLOBALS['post'] = $previous_global_post; + return $post; + } + + public function posts() { + $posts_iterator = new WP_Post_IDs_Iterator( $this->post_ids, self::QUERY_CHUNK ); + return new WP_Map_Iterator( $posts_iterator, array( $this, 'exportify_post' ) ); + } + + private function calculate_post_ids() { + global $wpdb; + if ( is_array( $this->filters['post_ids'] ) ) { + return $this->filters['post_ids']; + } + $this->post_type_where(); + $this->status_where(); + $this->author_where(); + $this->start_date_where(); + $this->end_date_where(); + $this->category_where(); + + $where = implode( ' AND ', array_filter( $this->wheres ) ); + if ( $where ) $where = "WHERE $where"; + $join = implode( ' ', array_filter( $this->joins ) ); + + $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} AS p $join $where" ); + $post_ids = array_merge( $post_ids, $this->attachments_for_specific_post_types( $post_ids ) ); + return $post_ids; + } + + private function post_type_where() { + global $wpdb; + $post_types_filters = array( 'can_export' => true ); + if ( $this->filters['post_type'] ) { + $post_types_filters = array_merge( $post_types_filters, array( 'name' => $this->filters['post_type'] ) ); + } + $post_types = get_post_types( $post_types_filters ); + if ( !$post_types ) { + $this->wheres[] = 'p.post_type IS NULL'; + return; + } + $this->wheres[] = $wpdb->build_IN_condition( 'p.post_type', $post_types ); + } + + private function status_where() { + global $wpdb; + if ( !$this->filters['status'] ) { + $this->wheres[] = "p.post_status != 'auto-draft'"; + return; + } + $this->wheres[] = $wpdb->prepare( 'p.post_status = %s', $this->filters['status'] ); + } + + private function author_where() { + global $wpdb; + $user = $this->find_user_from_any_object( $this->filters['author'] ); + if ( !$user || is_wp_error( $user ) ) { + return; + } + $this->author = $user; + $this->wheres[] = $wpdb->prepare( 'p.post_author = %d', $user->ID ); + } + + private function start_date_where() { + global $wpdb; + $timestamp = strtotime( $this->filters['start_date'] ); + if ( !$timestamp ) { + return; + } + $this->wheres[] = $wpdb->prepare( 'p.post_date >= %s', date( 'Y-m-d 00:00:00', $timestamp ) ); + } + + private function end_date_where() { + global $wpdb; + if ( preg_match( '/^\d{4}-\d{2}$/', $this->filters['end_date'] ) ) { + $timestamp = $this->get_timestamp_for_the_last_day_of_a_month( $this->filters['end_date'] ); + } else { + $timestamp = strtotime( $this->filters['end_date'] ); + } + if ( !$timestamp ) { + return; + } + $this->wheres[] = $wpdb->prepare( 'p.post_date <= %s', date( 'Y-m-d 23:59:59', $timestamp ) ); + } + + private function get_timestamp_for_the_last_day_of_a_month( $yyyy_mm ) { + return strtotime( "$yyyy_mm +1month -1day" ); + } + + private function category_where() { + global $wpdb; + if ( 'post' != $this->filters['post_type'] ) { + return; + } + $category = $this->find_category_from_any_object( $this->filters['category'] ); + if ( !$category ) { + return; + } + $this->category = $category; + $this->joins[] = "INNER JOIN {$wpdb->term_relationships} AS tr ON (p.ID = tr.object_id)"; + $this->wheres[] = $wpdb->prepare( 'tr.term_taxonomy_id = %d', $category->term_taxonomy_id ); + } + + private function attachments_for_specific_post_types( $post_ids ) { + global $wpdb; + if ( !$this->filters['post_type'] ) { + return array(); + } + $attachment_ids = array(); + while ( $batch_of_post_ids = array_splice( $post_ids, 0, self::QUERY_CHUNK ) ) { + $post_parent_condition = $wpdb->build_IN_condition( 'post_parent', $batch_of_post_ids ); + $attachment_ids = array_merge( $attachment_ids, (array)$wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND $post_parent_condition" ) ); + } + return array_map( 'intval', $attachment_ids ); + } + + private function bloginfo_rss( $section ) { + return apply_filters( 'bloginfo_rss', get_bloginfo_rss( $section ), $section ); + } + + private function find_user_from_any_object( $user ) { + if ( is_numeric( $user ) ) { + return get_user_by( 'id', $user ); + } elseif ( is_string( $user ) ) { + return get_user_by( 'login', $user ); + } elseif ( isset( $user->ID ) ) { + return get_user_by( 'id', $user->ID ); + } + return false; + } + + private function find_category_from_any_object( $category ) { + if ( is_numeric( $category ) ) { + return get_term( $category, 'category' ); + } elseif ( is_string( $category ) ) { + $term = term_exists( $category, 'category' ); + return isset( $term['term_id'] )? get_term( $term['term_id'], 'category' ) : false; + } elseif ( isset( $category->term_id ) ) { + return get_term( $category->term_id, 'category' ); + } + return false; + } + + private static function topologically_sort_terms( $terms ) { + $sorted = array(); + while ( $term = array_shift( $terms ) ) { + if ( $term->parent == 0 || isset( $sorted[$term->parent] ) ) + $sorted[$term->term_id] = $term; + else + $terms[] = $term; + } + return $sorted; + } + + private static function get_terms_for_post( $post ) { + $taxonomies = get_object_taxonomies( $post->post_type ); + if ( empty( $taxonomies ) ) + return array(); + $terms = wp_get_object_terms( $post->ID, $taxonomies ); + $terms = $terms? $terms : array(); + return $terms; + } + + private static function get_meta_for_post( $post ) { + global $wpdb; + $meta_for_export = array(); + $meta_from_db = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) ); + foreach ( $meta_from_db as $meta ) { + if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) ) + continue; + if ( in_array( $meta->meta_key, array( '_edit_lock', '_wp_attachment_metadata', '_wp_attached_file' ) ) ) { + continue; + } + $meta_for_export[] = $meta; + } + return $meta_for_export; + } + + private static function get_comments_for_post( $post ) { + global $wpdb; + $comments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); + foreach( $comments as $comment ) { + $meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $comment->comment_ID ) ); + $meta = $meta? $meta : array(); + $comment->meta = $meta; + } + return $comments; + } +} + +class WP_Export_Exception extends RuntimeException { +} diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php new file mode 100644 index 0000000000..f4850ac325 --- /dev/null +++ b/php/export/class-wp-export-wxr-formatter.php @@ -0,0 +1,262 @@ +<?php +/** + * Version number for the export format. + * + * Bump this when something changes that might affect compatibility. + * + * @since 2.5.0 + */ +define( 'WXR_VERSION', '1.2' ); + +require_once ABSPATH . WPINC . '/export/class-wp-export-oxymel.php'; + +/** + * Responsible for formatting the data in WP_Export_Query to WXR + */ +class WP_Export_WXR_Formatter { + public function __construct( $export ) { + $this->export = $export; + $this->wxr_version = WXR_VERSION; + } + + public function before_posts() { + $before_posts_xml = ''; + $before_posts_xml .= $this->header(); + $before_posts_xml .= $this->site_metadata(); + $before_posts_xml .= $this->authors(); + $before_posts_xml .= $this->categories(); + $before_posts_xml .= $this->tags(); + $before_posts_xml .= $this->nav_menu_terms(); + $before_posts_xml .= $this->custom_taxonomies_terms(); + $before_posts_xml .= $this->rss2_head_action(); + return $before_posts_xml; + } + + public function posts() { + return new WP_Map_Iterator( $this->export->posts(), array( $this, 'post' ) ); + } + + public function after_posts() { + return $this->footer(); + } + + public function header() { + $oxymel = new Oxymel; + $charset = $this->export->charset(); + $wp_generator_tag = $this->export->wp_generator_tag(); + $comment = <<<COMMENT + + This is a WordPress eXtended RSS file generated by WordPress as an export of your site. + It contains information about your site's posts, pages, comments, categories, and other content. + You may use this file to transfer that content from one site to another. + This file is not intended to serve as a complete backup of your site. + + To import this information into a WordPress site follow these steps: + 1. Log in to that site as an administrator. + 2. Go to Tools: Import in the WordPress admin panel. + 3. Install the "WordPress" importer from the list. + 4. Activate & Run Importer. + 5. Upload this file using the form provided on that page. + 6. You will first be asked to map the authors in this export file to users + on the site. For each author, you may choose to map to an + existing user on the site or to create a new user. + 7. WordPress will then import each of the posts, pages, comments, categories, etc. + contained in this file into your site. + +COMMENT; + return $oxymel + ->xml + ->comment( $comment ) + ->raw( $wp_generator_tag ) + ->open_rss( array( + 'version' => '2.0', + 'xmlns:excerpt' => "http://wordpress.org/export/{$this->wxr_version}/excerpt/", + 'xmlns:content' => "http://purl.org/rss/1.0/modules/content/", + 'xmlns:wfw' => "http://wellformedweb.org/CommentAPI/", + 'xmlns:dc' => "http://purl.org/dc/elements/1.1/", + 'xmlns:wp' => "http://wordpress.org/export/{$this->wxr_version}/", + ) ) + ->open_channel + ->to_string(); + + } + + public function site_metadata() { + $oxymel = new Oxymel; + $metadata = $this->export->site_metadata(); + return $oxymel + ->title( $metadata['name'] ) + ->link( $metadata['url'] ) + ->description( $metadata['description'] ) + ->pubDate( $metadata['pubDate'] ) + ->language( $metadata['language'] ) + ->tag( 'wp:wxr_version', $this->wxr_version ) + ->tag( 'wp:base_site_url', $metadata['site_url'] ) + ->tag( 'wp:base_blog_url', $metadata['blog_url'] ) + ->to_string(); + } + + public function authors() { + $oxymel = new Oxymel; + $authors = $this->export->authors(); + foreach ( $authors as $author ) { + $oxymel + ->tag( 'wp:wp_author' )->contains + ->tag( 'wp:author_login', $author->user_login ) + ->tag( 'wp:author_email', $author->user_email ) + ->tag( 'wp:author_display_name' )->contains->cdata( $author->display_name )->end + ->tag( 'wp:author_first_name' )->contains->cdata( $author->user_first_name )->end + ->tag( 'wp:author_last_name' )->contains->cdata( $author->user_last_name )->end + ->end; + } + return $oxymel->to_string(); + } + + public function categories() { + $oxymel = new WP_Export_Oxymel; + $categories = $this->export->categories(); + foreach( $categories as $term_id => $category ) { + $category->parent_slug = $category->parent? $categories[$category->parent]->slug : ''; + $oxymel->tag( 'wp:category' )->contains + ->tag( 'wp:term_id', $category->term_id ) + ->tag( 'wp:category_nicename', $category->slug ) + ->tag( 'wp:category_parent', $category->parent_slug ) + ->optional_cdata( 'wp:cat_name', $category->name ) + ->optional_cdata( 'wp:category_description', $category->description ) + ->end; + } + return $oxymel->to_string(); + } + + public function tags() { + $oxymel = new WP_Export_Oxymel; + $tags = $this->export->tags(); + foreach( $tags as $tag ) { + $oxymel->tag( 'wp:tag' )->contains + ->tag( 'wp:term_id', $tag->term_id ) + ->tag( 'wp:tag_slug', $tag->slug ) + ->optional_cdata( 'wp:tag_name', $tag->name ) + ->optional_cdata( 'wp:tag_description', $tag->description ) + ->end; + } + return $oxymel->to_string(); + } + + public function nav_menu_terms() { + return $this->terms( $this->export->nav_menu_terms() ); + } + + public function custom_taxonomies_terms() { + return $this->terms( $this->export->custom_taxonomies_terms() ); + } + + public function rss2_head_action() { + ob_start(); + do_action( 'rss2_head' ); + $action_output = ob_get_clean(); + return $action_output; + } + + public function post( $post ) { + $oxymel = new WP_Export_Oxymel; + $GLOBALS['wp_query']->in_the_loop = true; + $GLOBALS['post'] = $post; + setup_postdata( $post ); + + $oxymel->item->contains + ->title( apply_filters( 'the_title_rss', $post->post_title ) ) + ->link( esc_url( apply_filters('the_permalink_rss', get_permalink() ) ) ) + ->pubDate( mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ) ) + ->tag( 'dc:creator', get_the_author_meta( 'login' ) ) + ->guid( get_the_guid(), array( 'isPermaLink' => 'false' ) ) + ->description( '' ) + ->tag( 'content:encoded' )->contains->cdata( $post->post_content )->end + ->tag( 'excerpt:encoded' )->contains->cdata( $post->post_excerpt )->end + ->tag( 'wp:post_id', $post->ID ) + ->tag( 'wp:post_date', $post->post_date ) + ->tag( 'wp:post_date_gmt', $post->post_date_gmt ) + ->tag( 'wp:comment_status', $post->comment_status ) + ->tag( 'wp:ping_status', $post->ping_status ) + ->tag( 'wp:post_name', $post->post_name ) + ->tag( 'wp:status', $post->post_status ) + ->tag( 'wp:post_parent', $post->post_parent ) + ->tag( 'wp:menu_order', $post->menu_order ) + ->tag( 'wp:post_type', $post->post_type ) + ->tag( 'wp:post_password', $post->post_password ) + ->tag( 'wp:is_sticky', $post->is_sticky ) + ->optional( 'wp:attachment_url', wp_get_attachment_url( $post->ID ) ); + foreach( $post->terms as $term ) { + $oxymel + ->category( array( 'domain' => $term->taxonomy, 'nicename' => $term->slug ) )->contains->cdata( $term->name )->end; + } + foreach( $post->meta as $meta ) { + $oxymel + ->tag( 'wp:postmeta' )->contains + ->tag( 'wp:meta_key', $meta->meta_key ) + ->tag( 'wp:meta_value' )->contains->cdata( $meta->meta_value )->end + ->end; + } + foreach( $post->comments as $comment ) { + $oxymel + ->tag( 'wp:comment' )->contains + ->tag( 'wp:comment_id', $comment->comment_ID ) + ->tag( 'wp:comment_author' )->contains->cdata( $comment->comment_author )->end + ->tag( 'wp:comment_author_email', $comment->comment_author_email ) + ->tag( 'wp:comment_author_url', esc_url( $comment->comment_author_url ) ) + ->tag( 'wp:comment_author_IP', $comment->comment_author_IP ) + ->tag( 'wp:comment_date', $comment->comment_date ) + ->tag( 'wp:comment_date_gmt', $comment->comment_date_gmt ) + ->tag( 'wp:comment_content' )->contains->cdata( $comment->comment_content )->end + ->tag( 'wp:comment_approved', $comment->comment_approved ) + ->tag( 'wp:comment_type', $comment->comment_type ) + ->tag( 'wp:comment_parent', $comment->comment_parent ) + ->tag( 'wp:comment_user_id', $comment->user_id ) + ->oxymel( $this->comment_meta( $comment ) ) + ->end; + } + $oxymel + ->end; + return $oxymel->to_string(); + } + + public function footer() { + $oxymel = new Oxymel; + return $oxymel->close_channel->close_rss->to_string(); + } + + protected function terms( $terms ) { + $oxymel = new WP_Export_Oxymel; + foreach( $terms as $term ) { + $term->parent_slug = $term->parent? $terms[$term->parent]->slug : ''; + $oxymel->tag( 'wp:term' )->contains + ->tag( 'wp:term_id', $term->term_id ) + ->tag( 'wp:term_taxonomy', $term->taxonomy ) + ->tag( 'wp:term_slug', $term->slug ); + if ( 'nav_menu' != $term->taxonomy ) { + $oxymel + ->tag( 'wp:term_parent', $term->parent_slug ); + } + $oxymel + ->optional_cdata( 'wp:term_name', $term->name ) + ->optional_cdata( 'wp:term_description', $term->description ) + ->end; + } + return $oxymel->to_string(); + } + + protected function comment_meta( $comment ) { + global $wpdb; + $metas = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $comment->comment_ID ) ); + if ( !$metas ) { + return new Oxymel; + } + $oxymel = new WP_Export_Oxymel; + foreach( $metas as $meta ) { + $oxymel->tag( 'wp:commentmeta' )->contains + ->tag( 'wp:meta_key', $meta->meta_key ) + ->tag( 'wp:meta_value', $meta->meta_value ) + ->end; + } + return $oxymel; + } +} diff --git a/php/export/functions.export.php b/php/export/functions.export.php new file mode 100644 index 0000000000..441736ef87 --- /dev/null +++ b/php/export/functions.export.php @@ -0,0 +1,30 @@ +<?php + +function wp_export( $args = array() ) { + $defaults = array( + 'filters' => array(), + 'format' => 'WP_Export_WXR_Formatter', + 'writer' => 'WP_Export_Returner', + 'writer_args' => null, + ); + $args = wp_parse_args( $args, $defaults ); + $export_query = new WP_Export_Query( $args['filters'] ); + $formatter = new $args['format']( $export_query ); + $writer = new $args['writer']( $formatter, $args['writer_args'] ); + try { + return $writer->export(); + } catch ( WP_Export_Exception $e ) { + return new WP_Error( 'wp-export-error', $e->getMessage() ); + } +} + +function wp_export_new_style_args_from_old_style_args( $args ) { + if ( isset( $args['content'] ) ) { + if ( 'all' == $args['content'] ) { + unset( $args['content'] ); + } else { + $args['post_type'] = $args['content']; + } + } + return $args; +} diff --git a/php/export/writers.php b/php/export/writers.php new file mode 100644 index 0000000000..52a68d7025 --- /dev/null +++ b/php/export/writers.php @@ -0,0 +1,145 @@ +<?php +abstract class WP_Export_Base_Writer { + protected $formatter; + + function __construct( $formatter ) { + $this->formatter = $formatter; + } + + public function export() { + $this->write( $this->formatter->before_posts() ); + foreach( $this->formatter->posts() as $post_in_wxr ) { + $this->write( $post_in_wxr ); + } + $this->write( $this->formatter->after_posts() ); + } + + abstract protected function write( $xml ); +} + +class WP_Export_XML_Over_HTTP extends WP_Export_Base_Writer { + private $file_name; + + function __construct( $formatter, $file_name ) { + parent::__construct( $formatter ); + $this->file_name = $file_name; + } + + public function export() { + header( 'Content-Description: File Transfer' ); + header( 'Content-Disposition: attachment; filename=' . $this->file_name ); + header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true ); + parent::export(); + } + + protected function write( $xml ) { + echo $xml; + } +} + +class WP_Export_Returner extends WP_Export_Base_Writer { + private $result = ''; + + public function export() { + $this->private = ''; + parent::export(); + return $this->result; + } + protected function write( $xml ) { + $this->result .= $xml; + } +} + +class WP_Export_File_Writer extends WP_Export_Base_Writer { + private $f; + private $file_name; + + public function __construct( $formatter, $file_name ) { + parent::__construct( $formatter ); + $this->file_name = $file_name; + } + + public function export() { + $this->f = fopen( $this->file_name, 'w' ); + if ( !$this->f ) { + throw new WP_Export_Exception( sprintf( __( 'WP Export: error opening %s for writing.' ), $this->file_name ) ); + } + parent::export(); + fclose( $this->f ); + } + + protected function write( $xml ) { + $res = fwrite( $this->f, $xml); + if ( false === $res ) { + throw new WP_Export_Exception( __( 'WP Export: error writing to export file.' ) ); + } + } +} + +class WP_Export_Split_Files_Writer extends WP_Export_Base_Writer { + private $result = ''; + private $f; + private $next_file_number = 0; + private $current_file_size = 0; + + function __construct( $formatter, $writer_args = array() ) { + parent::__construct( $formatter ); + //TODO: check if args are not missing + $this->max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $writer_args['max_file_size']; + $this->destination_directory = $writer_args['destination_directory']; + $this->filename_template = $writer_args['filename_template']; + $this->before_posts_xml = $this->formatter->before_posts(); + $this->after_posts_xml = $this->formatter->after_posts(); + } + + public function export() { + $this->start_new_file(); + foreach( $this->formatter->posts() as $post_xml ) { + if ( ( $this->current_file_size + strlen( $post_xml ) ) > $this->max_file_size ) { + $this->start_new_file(); + } + $this->write( $post_xml ); + } + $this->close_current_file(); + } + + protected function write( $xml ) { + $res = fwrite( $this->f, $xml); + if ( false === $res ) { + throw new WP_Export_Exception( __( 'WP Export: error writing to export file.' ) ); + } + $this->current_file_size += strlen( $xml ); + } + + private function start_new_file() { + if ( $this->f ) { + $this->close_current_file(); + } + $file_path = $this->next_file_path(); + $this->f = fopen( $file_path, 'w' ); + if ( !$this->f ) { + throw new WP_Export_Exception( sprintf( __( 'WP Export: error opening %s for writing.' ), $file_path ) ); + } + $this->current_file_size = 0; + $this->write( $this->before_posts_xml ); + } + + private function close_current_file() { + if ( !$this->f ) { + return; + } + $this->write( $this->after_posts_xml ); + fclose( $this->f ); + } + + private function next_file_name() { + $next_file_name = sprintf( $this->filename_template, $this->next_file_number ); + $this->next_file_number++; + return $next_file_name; + } + + private function next_file_path() { + return untrailingslashit( $this->destination_directory ) . DIRECTORY_SEPARATOR . $this->next_file_name(); + } + +} From c3480588ffe4b1676be9e0d675cf0f20cde100d3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 17:04:13 +0300 Subject: [PATCH 1926/4858] copy wp-includes/iterators.php to export/iterators.php --- php/export/iterators.php | 80 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 php/export/iterators.php diff --git a/php/export/iterators.php b/php/export/iterators.php new file mode 100644 index 0000000000..6a4613cbbc --- /dev/null +++ b/php/export/iterators.php @@ -0,0 +1,80 @@ +<?php +class WP_Map_Iterator extends IteratorIterator { + function __construct( $iterator, $callback ) { + $this->callback = $callback; + parent::__construct( $iterator ); + } + + function current() { + $original_current = parent::current(); + return call_user_func( $this->callback, $original_current ); + } +} + +class WP_Post_IDs_Iterator implements Iterator { + private $limit = 100; + private $post_ids; + private $ids_left; + private $results = array(); + + public function __construct( $post_ids, $limit = null ) { + $this->db = $GLOBALS['wpdb']; + $this->post_ids = $post_ids; + $this->ids_left = $post_ids; + if ( !is_null( $limit ) ) { + $this->limit = $limit; + } + } + + public function current() { + return $this->results[$this->index_in_results]; + } + + public function key() { + return $this->global_index; + } + + public function next() { + $this->index_in_results++; + $this->global_index++; + } + + public function rewind() { + $this->results = array(); + $this->global_index = 0; + $this->index_in_results = 0; + $this->ids_left = $this->post_ids; + } + + public function valid() { + if ( isset( $this->results[$this->index_in_results] ) ) { + return true; + } + if ( empty( $this->ids_left ) ) { + return false; + } + $has_posts = $this->load_next_posts_from_db(); + if ( !$has_posts ) { + return false; + } + $this->index_in_results = 0; + return true; + } + + private function load_next_posts_from_db() { + $next_batch_post_ids = array_splice( $this->ids_left, 0, $this->limit ); + $in_post_ids_sql = $this->db->build_IN_condition( 'ID', $next_batch_post_ids ); + $this->results = $this->db->get_results( "SELECT * FROM {$this->db->posts} WHERE $in_post_ids_sql" ); + if ( !$this->results ) { + if ( $this->db->last_error ) { + throw new WP_Iterator_Exception( 'Database error: ' . $this->db->last_error ); + } else { + return false; + } + } + return true; + } +} + +class WP_Iterator_Exception extends Exception { +} From adfdc881a5a9ac4885a336954ef22ea81c869587 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 15:07:06 +0300 Subject: [PATCH 1927/4858] load Oxymel via Composer --- composer.json | 3 ++- php/export/class-wp-export-oxymel.php | 2 -- php/export/class-wp-export-wxr-formatter.php | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index c9a8e7b551..19183596d5 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "require": { "php": ">=5.3.2", "wp-cli/php-cli-tools": "dev-master", - "mustache/mustache": "~2.3" + "mustache/mustache": "~2.3", + "nb/oxymel": "dev-master" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" diff --git a/php/export/class-wp-export-oxymel.php b/php/export/class-wp-export-oxymel.php index 6c2bc96742..74c1a7cf1a 100644 --- a/php/export/class-wp-export-oxymel.php +++ b/php/export/class-wp-export-oxymel.php @@ -1,7 +1,5 @@ <?php -require_once ABSPATH . WPINC . '/Oxymel.php'; - class WP_Export_Oxymel extends Oxymel { public function optional( $tag_name, $contents ) { if ( $contents ) { diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php index f4850ac325..c169029feb 100644 --- a/php/export/class-wp-export-wxr-formatter.php +++ b/php/export/class-wp-export-wxr-formatter.php @@ -8,8 +8,6 @@ */ define( 'WXR_VERSION', '1.2' ); -require_once ABSPATH . WPINC . '/export/class-wp-export-oxymel.php'; - /** * Responsible for formatting the data in WP_Export_Query to WXR */ From 9ae66fa07c312531004bf4640b86fbc795bcec39 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 18:33:24 +0300 Subject: [PATCH 1928/4858] load export classes via Composer --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 19183596d5..4a9d9cb3f6 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "behat/behat": "~2.4" }, "autoload": { - "psr-0": { "WP_CLI": "php" } + "psr-0": { "WP_CLI": "php" }, + "classmap": [ "php/export" ] } } From 1e50229f93d348454fd69f4d671f6099db7cc49f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 16 Jun 2013 18:54:03 +0300 Subject: [PATCH 1929/4858] first pass at loading and using the export API * replace --file_item_count with --max_file_size * --verbose is ignored, for now --- man-src/export.txt | 4 +- php/commands/export.php | 420 ++++++---------------------------------- 2 files changed, 58 insertions(+), 366 deletions(-) diff --git a/man-src/export.txt b/man-src/export.txt index dcb8ea478c..d58e6de7c3 100644 --- a/man-src/export.txt +++ b/man-src/export.txt @@ -9,9 +9,9 @@ to current working directory. Don't export comments. -* `--file_item_count`=<count>: +* `--max_file_size`=<MB>: - Break export into files with N posts. + Set maximum size (in MB) each export file should have. Default: 15. * `--verbose`: diff --git a/php/commands/export.php b/php/commands/export.php index 3bde8c3148..ee2ca87dbe 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -11,7 +11,7 @@ class Export_Command extends WP_CLI_Command { /** * Export content to a WXR file. * - * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] [--verbose] + * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--max_file_size=<MB>] [--verbose] */ public function __invoke( $_, $assoc_args ) { $defaults = array( @@ -24,12 +24,55 @@ public function __invoke( $_, $assoc_args ) { 'post_status' => NULL, 'post__in' => NULL, 'skip_comments' => NULL, - 'file_item_count' => 1000, + 'max_file_size' => 15, 'verbose' => false, ); - $args = wp_parse_args( $assoc_args, $defaults ); + $this->validate_args( wp_parse_args( $assoc_args, $defaults ) ); + if ( !function_exists( 'wp_export' ) ) { + self::load_export_api(); + } + + WP_CLI::line( 'Starting export process...' ); + + wp_export( array( + 'filters' => $this->export_args, + 'writer' => 'WP_Export_Split_Files_Writer', + 'writer_args' => array( + 'max_file_size' => $this->max_file_size * MB_IN_BYTES, + 'destination_directory' => $this->wxr_path, + 'filename_template' => self::get_filename_template() + ) + ) ); + + WP_CLI::success( 'All done with export.' ); + } + + private static function get_filename_template() { + $sitename = sanitize_key( get_bloginfo( 'name' ) ); + if ( ! empty($sitename) ) $sitename .= '.'; + return $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.%d.xml'; + } + + private static function load_export_api() { + if ( !defined( 'KB_IN_BYTES' ) ) { + // Constants for expressing human-readable data sizes + // in their respective number of bytes. + define( 'KB_IN_BYTES', 1024 ); + define( 'MB_IN_BYTES', 1024 * KB_IN_BYTES ); + define( 'GB_IN_BYTES', 1024 * MB_IN_BYTES ); + define( 'TB_IN_BYTES', 1024 * GB_IN_BYTES ); + define( 'PB_IN_BYTES', 1024 * TB_IN_BYTES ); + define( 'EB_IN_BYTES', 1024 * PB_IN_BYTES ); + define( 'ZB_IN_BYTES', 1024 * EB_IN_BYTES ); + define( 'YB_IN_BYTES', 1024 * ZB_IN_BYTES ); + } + + require WP_CLI_ROOT . '/export/functions.export.php'; + } + + private function validate_args( $args ) { $has_errors = false; foreach ( $args as $key => $value ) { @@ -43,13 +86,6 @@ public function __invoke( $_, $assoc_args ) { if ( $has_errors ) { exit(1); } - - $this->wxr_path = trailingslashit( $this->export_args['dir'] ); - unset( $this->export_args['dir'] ); - - WP_CLI::line( 'Starting export process...' ); - WP_CLI::line(); - $this->export_wp( $this->export_args ); } private function check_verbose( $verbose ) { @@ -60,15 +96,14 @@ private function check_verbose( $verbose ) { private function check_dir( $path ) { if ( empty( $path ) ) { - $this->export_args['dir'] = getcwd(); - return true; - } - - if ( !is_dir( $path ) ) { + $path = getcwd(); + } elseif ( !is_dir( $path ) ) { WP_CLI::error( sprintf( "The directory %s does not exist", $path ) ); + return false; } - $this->export_args['dir'] = $path; + $this->wxr_path = trailingslashit( $path ); + return true; } @@ -195,358 +230,15 @@ private function check_skip_comments( $skip ) { return true; } - private function check_file_item_count( $file_item_count ) { - - if ( ! is_numeric( $file_item_count ) ) { - WP_CLI::warning( 'File item count needs to be numeric' ); + private function check_max_file_size( $size ) { + if ( !is_numeric( $size ) ) { + WP_CLI::warning( sprintf( "max_file_size should be numeric", $size ) ); return false; } - $this->export_args['file_item_count'] = $file_item_count; - return true; - } - - - /** - * Workaround to prevent memory leaks from growing variables - */ - - private function stop_the_insanity() { - global $wpdb, $wp_object_cache; - $wpdb->queries = array(); // or define( 'WP_IMPORTING', true ); - if ( !is_object( $wp_object_cache ) ) - return; - $wp_object_cache->group_ops = array(); - $wp_object_cache->stats = array(); - $wp_object_cache->memcache_debug = array(); - $wp_object_cache->cache = array(); - if ( method_exists( $wp_object_cache, '__remoteset' ) ) - $wp_object_cache->__remoteset(); - } - - private function start_export() { - ob_start(); - } - - private function end_export() { - ob_end_clean(); - } - - private function flush_export( $file_path, $append = true ) { - $result = ob_get_clean(); - if ( $append ) - $append = FILE_APPEND; - file_put_contents( $file_path, $result, $append ); - $this->start_export(); - } - - /** - * Export function as it is defined in the original code of export_wp defined in wp-admin/includes/export.php - */ - - private function export_wp( $args = array() ) { - require_once ABSPATH . 'wp-admin/includes/export.php'; - - global $wpdb; - - /** - * This is mostly the original code of export_wp defined in wp-admin/includes/export.php - */ - $defaults = array( 'post_type' => 'all', 'post__in' => false, 'author' => false, 'category' => false, - 'start_date' => false, 'end_date' => false, 'status' => false, 'skip_comments' => false, 'file_item_count' => 1000, - ); - $args = wp_parse_args( $args, $defaults ); - - if ( $this->verbose ) { - WP_CLI::line( "Exporting with export_wp with arguments: " . var_export( $args, true ) ); - } - - do_action( 'export_wp' ); - - $sitename = sanitize_key( get_bloginfo( 'name' ) ); - if ( ! empty( $sitename ) ) - $sitename .= '.'; - - $append = array( date( 'Y-m-d' ) ); - foreach( array_keys( $args ) as $arg_key ) { - if ( $defaults[$arg_key] <> $args[$arg_key] && 'post__in' != $arg_key ) - $append[]= "$arg_key-" . (string) $args[$arg_key]; - } - $file_name_base = sanitize_file_name( $sitename . 'wordpress.' . implode( ".", $append ) ); - - if ( 'all' != $args['post_type'] && post_type_exists( $args['post_type'] ) ) { - $ptype = get_post_type_object( $args['post_type'] ); - if ( ! $ptype->can_export ) - $args['post_type'] = 'post'; - - $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['post_type'] ); - } else { - $post_types = get_post_types( array( 'can_export' => true ) ); - $esses = array_fill( 0, count( $post_types ), '%s' ); - $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (" . implode( ',', $esses ) . ')', $post_types ); - } - - if ( $args['status'] && ( 'post' == $args['post_type'] || 'page' == $args['post_type'] ) ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] ); - else - $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'"; - - $join = ''; - if ( $args['category'] && 'post' == $args['post_type'] ) { - if ( $term = term_exists( $args['category'], 'category' ) ) { - $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)"; - $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] ); - } - } - - - if ( $args['author'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] ); - - if ( $args['start_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d 00:00:00', strtotime( $args['start_date'] ) ) ); - - if ( $args['end_date'] ) - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date <= %s", date( 'Y-m-d 23:59:59', strtotime( $args['end_date'] ) ) ); - // grab a snapshot of post IDs, just in case it changes during the export - if ( empty( $args['post__in'] ) ) - $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where ORDER BY post_date ASC, post_parent ASC" ); - else - $all_the_post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE ID IN ({$args['post__in']}) ORDER BY post_date ASC, post_parent ASC" ); - - // Make sure we're getting all of the attachments for these posts too - if ( 'all' != $args['post_type'] || ! empty( $args['post__in'] ) ) { - $all_post_ids_with_attachments = array(); - while ( $post_ids = array_splice( $all_the_post_ids, 0, 100 ) ) { - $attachment_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent IN (". implode( ",", array_map( 'intval', $post_ids ) ) .")" ); - $all_post_ids_with_attachments = array_merge( $all_post_ids_with_attachments, $post_ids, (array)$attachment_ids ); - } - $all_the_post_ids = $all_post_ids_with_attachments; - } - - // get the requested terms ready, empty unless posts filtered by category or all content - $cats = $tags = $terms = array(); - if ( isset( $term ) && $term ) { - $cat = get_term( $term['term_id'], 'category' ); - $cats = array( $cat->term_id => $cat ); - unset( $term, $cat ); - } else if ( 'all' == $args['post_type'] ) { - $categories = (array) get_categories( array( 'get' => 'all' ) ); - $tags = (array) get_tags( array( 'get' => 'all' ) ); - - $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); - $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); - - // put categories in order with no child going before its parent - while ( $cat = array_shift( $categories ) ) { - if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) ) - $cats[$cat->term_id] = $cat; - else - $categories[] = $cat; - } + $this->max_file_size = $size; - // put terms in order with no child going before its parent - while ( $t = array_shift( $custom_terms ) ) { - if ( $t->parent == 0 || isset( $terms[$t->parent] ) ) - $terms[$t->term_id] = $t; - else - $custom_terms[] = $t; - } - - unset( $categories, $custom_taxonomies, $custom_terms ); - } - - // Load the functions available in wp-admin/includes/export.php - ob_start(); - export_wp( array( 'content' => 'page', 'start_date' => '1971-01-01', 'end_date' => '1971-01-02' ) ); - ob_end_clean(); - - WP_CLI::line( 'Exporting ' . count( $all_the_post_ids ) . ' items to be broken into ' . ceil( count( $all_the_post_ids ) / $args['file_item_count'] ) . ' files' ); - WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); - WP_CLI::line( 'Exporting ' . count( $tags ) . ' tags' ); - WP_CLI::line( 'Exporting ' . count( $terms ) . ' terms' ); - WP_CLI::line(); - - $file_count = 1; - - while ( $post_ids = array_splice( $all_the_post_ids, 0, $args['file_item_count'] ) ) { - - $full_path = $this->wxr_path . $file_name_base . '.' . str_pad( $file_count, 3, '0', STR_PAD_LEFT ) . '.xml'; - - // Create the file if it doesn't exist - if ( ! file_exists( $full_path ) ) { - touch( $full_path ); - } - - if ( ! file_exists( $full_path ) ) { - WP_CLI::error( "Failed to create file " . $full_path ); - exit; - } else { - WP_CLI::line( 'Writing to file ' . $full_path ); - } - - if ( !$this->verbose ) - $progress = new \cli\progress\Bar( 'Exporting', count( $post_ids ) ); - - $this->start_export(); - echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . "\" ?>\n"; - -?> -<!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. --> -<!-- It contains information about your site's posts, pages, comments, categories, and other content. --> -<!-- You may use this file to transfer that content from one site to another. --> -<!-- This file is not intended to serve as a complete backup of your site. --> - -<!-- To import this information into a WordPress site follow these steps: --> -<!-- 1. Log in to that site as an administrator. --> -<!-- 2. Go to Tools: Import in the WordPress admin panel. --> -<!-- 3. Install the "WordPress" importer from the list. --> -<!-- 4. Activate & Run Importer. --> -<!-- 5. Upload this file using the form provided on that page. --> -<!-- 6. You will first be asked to map the authors in this export file to users --> -<!-- on the site. For each author, you may choose to map to an --> -<!-- existing user on the site or to create a new user. --> -<!-- 7. WordPress will then import each of the posts, pages, comments, categories, etc. --> -<!-- contained in this file into your site. --> - -<?php the_generator( 'export' ); ?> -<rss version="2.0" - xmlns:excerpt="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/excerpt/" - xmlns:content="http://purl.org/rss/1.0/modules/content/" - xmlns:wfw="http://wellformedweb.org/CommentAPI/" - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:wp="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/" -> - -<channel> - <title><?php bloginfo_rss( 'name' ); ?> - - - - - - - - - - - - term_id ?>slug; ?>parent ? $cats[$c->parent]->slug : ''; ?> - - - term_id ?>slug; ?> - - - term_id ?>taxonomy; ?>slug; ?>parent ? $terms[$t->parent]->slug : ''; ?> - - - - - flush_export( $full_path, false ); ?> - -in_the_loop = true; // Fake being in the loop. - - // fetch 20 posts at a time rather than loading the entire table into memory - while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) { - - $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')'; - $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" ); - - // Begin Loop - foreach ( $posts as $post ) { - - if ( !$this->verbose ) { - $progress->tick(); - } else { - WP_CLI::line( "Exporting post $post->ID" ); - } - - setup_postdata( $post ); - $is_sticky = is_sticky( $post->ID ) ? 1 : 0; -?> - - <?php echo apply_filters( 'the_title_rss', $post->post_title ); ?> - - - - - - post_content ) ); ?> - post_excerpt ) ); ?> - ID; ?> - post_date; ?> - post_date_gmt; ?> - comment_status; ?> - ping_status; ?> - post_name; ?> - post_status; ?> - post_parent; ?> - menu_order; ?> - post_type; ?> - post_password; ?> - -post_type == 'attachment' ) : ?> - ID ); ?> - - -get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) ); - foreach ( $postmeta as $meta ) : - if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) ) - continue; - ?> - - meta_key; ?> - meta_value ); ?> - - - -get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); - foreach ( $comments as $c ) : ?> - - comment_ID; ?> - comment_author ); ?> - comment_author_email; ?> - comment_author_url ); ?> - comment_author_IP; ?> - comment_date; ?> - comment_date_gmt; ?> - comment_content ) ?> - comment_approved; ?> - comment_type; ?> - comment_parent; ?> - user_id; ?> -get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $c->comment_ID ) ); - foreach ( $c_meta as $meta ) : ?> - - meta_key; ?> - meta_value ); ?> - - - - - - -flush_export( $full_path ); - } - } - } ?> - - -flush_export( $full_path ); - $this->end_export(); - $this->stop_the_insanity(); - - if ( !$this->verbose ) { - $progress->finish(); - } - - $file_count++; - } - WP_CLI::success( "All done with export" ); + return true; } } From 128b9c0674dcecb5f24a1c370c0a4ed16f5e25ea Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 16 Jun 2013 19:09:52 +0300 Subject: [PATCH 1930/4858] add _wp_export_build_IN_condition() helper --- php/export/class-wp-export-query.php | 4 ++-- php/export/functions.export.php | 11 +++++++++++ php/export/iterators.php | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 5522cc06a8..b99636e040 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -158,7 +158,7 @@ private function post_type_where() { $this->wheres[] = 'p.post_type IS NULL'; return; } - $this->wheres[] = $wpdb->build_IN_condition( 'p.post_type', $post_types ); + $this->wheres[] = _wp_export_build_IN_condition( 'p.post_type', $post_types ); } private function status_where() { @@ -227,7 +227,7 @@ private function attachments_for_specific_post_types( $post_ids ) { } $attachment_ids = array(); while ( $batch_of_post_ids = array_splice( $post_ids, 0, self::QUERY_CHUNK ) ) { - $post_parent_condition = $wpdb->build_IN_condition( 'post_parent', $batch_of_post_ids ); + $post_parent_condition = _wp_export_build_IN_condition( 'post_parent', $batch_of_post_ids ); $attachment_ids = array_merge( $attachment_ids, (array)$wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND $post_parent_condition" ) ); } return array_map( 'intval', $attachment_ids ); diff --git a/php/export/functions.export.php b/php/export/functions.export.php index 441736ef87..492e97e9bd 100644 --- a/php/export/functions.export.php +++ b/php/export/functions.export.php @@ -28,3 +28,14 @@ function wp_export_new_style_args_from_old_style_args( $args ) { } return $args; } + +// TEMPORARY +function _wp_export_build_IN_condition( $column_name, $values, $format = '%s' ) { + global $wpdb; + + if ( !is_array( $values ) || empty( $values ) ) { + return ''; + } + $formats = implode( ', ', array_fill( 0, count( $values ), $format ) ); + return $wpdb->prepare( "$column_name IN ($formats)", $values ); +} diff --git a/php/export/iterators.php b/php/export/iterators.php index 6a4613cbbc..86572f56c6 100644 --- a/php/export/iterators.php +++ b/php/export/iterators.php @@ -63,7 +63,7 @@ public function valid() { private function load_next_posts_from_db() { $next_batch_post_ids = array_splice( $this->ids_left, 0, $this->limit ); - $in_post_ids_sql = $this->db->build_IN_condition( 'ID', $next_batch_post_ids ); + $in_post_ids_sql = _wp_export_build_IN_condition( 'ID', $next_batch_post_ids ); $this->results = $this->db->get_results( "SELECT * FROM {$this->db->posts} WHERE $in_post_ids_sql" ); if ( !$this->results ) { if ( $this->db->last_error ) { From 4bfc6be67d22983b2566e9c8a336c4922156f906 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 16 Jun 2013 20:15:53 +0300 Subject: [PATCH 1931/4858] log each exported file path had to copy over the whole WP_Export_Split_Files_Writer class. --- php/WP_CLI/VerboseExportWriter.php | 73 ++++++++++++++++++++++++++++++ php/commands/export.php | 2 +- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 php/WP_CLI/VerboseExportWriter.php diff --git a/php/WP_CLI/VerboseExportWriter.php b/php/WP_CLI/VerboseExportWriter.php new file mode 100644 index 0000000000..5facc3f90f --- /dev/null +++ b/php/WP_CLI/VerboseExportWriter.php @@ -0,0 +1,73 @@ +max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $writer_args['max_file_size']; + $this->destination_directory = $writer_args['destination_directory']; + $this->filename_template = $writer_args['filename_template']; + $this->before_posts_xml = $this->formatter->before_posts(); + $this->after_posts_xml = $this->formatter->after_posts(); + } + + public function export() { + $this->start_new_file(); + foreach( $this->formatter->posts() as $post_xml ) { + if ( ( $this->current_file_size + strlen( $post_xml ) ) > $this->max_file_size ) { + $this->start_new_file(); + } + $this->write( $post_xml ); + } + $this->close_current_file(); + } + + protected function write( $xml ) { + $res = fwrite( $this->f, $xml); + if ( false === $res ) { + throw new WP_Export_Exception( __( 'WP Export: error writing to export file.' ) ); + } + $this->current_file_size += strlen( $xml ); + } + + private function start_new_file() { + if ( $this->f ) { + $this->close_current_file(); + } + $file_path = $this->next_file_path(); + $this->f = fopen( $file_path, 'w' ); + if ( !$this->f ) { + throw new WP_Export_Exception( sprintf( __( 'WP Export: error opening %s for writing.' ), $file_path ) ); + } + \WP_CLI::log( sprintf( "Started writing to %s", $file_path ) ); + $this->current_file_size = 0; + $this->write( $this->before_posts_xml ); + } + + private function close_current_file() { + if ( !$this->f ) { + return; + } + $this->write( $this->after_posts_xml ); + fclose( $this->f ); + } + + private function next_file_name() { + $next_file_name = sprintf( $this->filename_template, $this->next_file_number ); + $this->next_file_number++; + return $next_file_name; + } + + private function next_file_path() { + return untrailingslashit( $this->destination_directory ) . DIRECTORY_SEPARATOR . $this->next_file_name(); + } +} + diff --git a/php/commands/export.php b/php/commands/export.php index ee2ca87dbe..c777f5464b 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -38,7 +38,7 @@ public function __invoke( $_, $assoc_args ) { wp_export( array( 'filters' => $this->export_args, - 'writer' => 'WP_Export_Split_Files_Writer', + 'writer' => '\\WP_CLI\\VerboseExportWriter', 'writer_args' => array( 'max_file_size' => $this->max_file_size * MB_IN_BYTES, 'destination_directory' => $this->wxr_path, From aa542585aeeef589b1ce1e18edf3d4aa30a06786 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 16 Jun 2013 20:16:28 +0300 Subject: [PATCH 1932/4858] remove --verbose parameter The idea is to be reasonably verbose by default and completely silent when --quiet is passed. --- man-src/export.txt | 4 ---- php/commands/export.php | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/man-src/export.txt b/man-src/export.txt index d58e6de7c3..58326c5f67 100644 --- a/man-src/export.txt +++ b/man-src/export.txt @@ -13,10 +13,6 @@ to current working directory. Set maximum size (in MB) each export file should have. Default: 15. -* `--verbose`: - - Show more information about the process on STDOUT. - ## FILTERS * `--start_date`=: diff --git a/php/commands/export.php b/php/commands/export.php index c777f5464b..d7fc59da49 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -11,7 +11,7 @@ class Export_Command extends WP_CLI_Command { /** * Export content to a WXR file. * - * @synopsis [--dir=] [--start_date=] [--end_date=] [--post_type=] [--post_status=] [--post__in=] [--author=] [--category=] [--skip_comments] [--max_file_size=] [--verbose] + * @synopsis [--dir=] [--start_date=] [--end_date=] [--post_type=] [--post_status=] [--post__in=] [--author=] [--category=] [--skip_comments] [--max_file_size=] */ public function __invoke( $_, $assoc_args ) { $defaults = array( @@ -25,7 +25,6 @@ public function __invoke( $_, $assoc_args ) { 'post__in' => NULL, 'skip_comments' => NULL, 'max_file_size' => 15, - 'verbose' => false, ); $this->validate_args( wp_parse_args( $assoc_args, $defaults ) ); @@ -34,7 +33,7 @@ public function __invoke( $_, $assoc_args ) { self::load_export_api(); } - WP_CLI::line( 'Starting export process...' ); + WP_CLI::log( 'Starting export process...' ); wp_export( array( 'filters' => $this->export_args, From fb5da0ab2b1f1034c7f4f12796d22af534f9e255 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Tue, 25 Jun 2013 14:32:18 -0700 Subject: [PATCH 1933/4858] Restore af65fe41c8d3b9df3c1fb1461fddf92ac165fde5, which I accidentally overwrote :( --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index d7fc59da49..97a319b9fb 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -68,7 +68,7 @@ private static function load_export_api() { define( 'YB_IN_BYTES', 1024 * ZB_IN_BYTES ); } - require WP_CLI_ROOT . '/export/functions.export.php'; + require WP_CLI_ROOT . '/php/export/functions.export.php'; } private function validate_args( $args ) { From 4923fefdb4d2cb512c9f35fa0e1316312b35647a Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Jun 2013 01:16:44 +0300 Subject: [PATCH 1934/4858] minor whitespace fixes --- php/commands/import.php | 53 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index c904e53c02..1f2dc08928 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -15,10 +15,10 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( "File to import doesn't exist." ); $defaults = array( - 'type' => 'wxr', - 'authors' => null, - 'skip' => array(), - ); + 'type' => 'wxr', + 'authors' => null, + 'skip' => array(), + ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); $assoc_args['file'] = $file; @@ -71,7 +71,7 @@ private function import_wxr( $args ) { // Prepare the data to be used in process_author_mapping(); $wp_import->get_authors_from_import( $import_data ); $author_data = array(); - foreach( $wp_import->authors as $wxr_author ) { + foreach ( $wp_import->authors as $wxr_author ) { $author = new \stdClass; // Always in the WXR $author->user_login = $wxr_author['author_login']; @@ -98,7 +98,7 @@ private function import_wxr( $args ) { // $user_select needs to be an array of user IDs $user_select = array(); $invalid_user_select = array(); - foreach( $author_out as $author_login ) { + foreach ( $author_out as $author_login ) { $user = get_user_by( 'login', $author_login ); if ( $user ) $user_select[] = $user->ID; @@ -109,7 +109,7 @@ private function import_wxr( $args ) { return new WP_Error( 'invalid-author-mapping', sprintf( "These user_logins are invalid: %s", implode( ',', $invalid_user_select ) ) ); // Drive the import - $wp_import->fetch_attachments = ( in_array( 'attachment', $args['skip'] ) ) ? false : true; + $wp_import->fetch_attachments = !in_array( 'attachment', $args['skip'] ); $_GET = array( 'import' => 'wordpress', 'step' => 2 ); $_POST = array( 'imported_authors' => $author_in, @@ -264,11 +264,11 @@ private function create_author_mapping_file( $file, $author_data ) { if ( touch( $file ) ) { $author_mapping = array(); - foreach( $author_data as $author ) { + foreach ( $author_data as $author ) { $author_mapping[] = array( - 'old_user_login' => $author->user_login, - 'new_user_login' => $this->suggest_user( $author->user_login, $author->user_email ), - ); + 'old_user_login' => $author->user_login, + 'new_user_login' => $this->suggest_user( $author->user_login, $author->user_email ), + ); } $file_resource = fopen( $file, 'w' ); \WP_CLI\utils\write_csv( $file_resource, $author_mapping, array( 'old_user_login', 'new_user_login' ) ); @@ -284,14 +284,14 @@ private function create_author_mapping_file( $file, $author_data ) { private function create_authors_for_mapping( $author_data ) { $author_mapping = array(); - foreach( $author_data as $author ) { + foreach ( $author_data as $author ) { if ( isset( $author->user_email ) ) { if ( $user = get_user_by( 'email', $author->user_email ) ) { $author_mapping[] = array( - 'old_user_login' => $author->user_login, - 'new_user_login' => $user->user_login, - ); + 'old_user_login' => $author->user_login, + 'new_user_login' => $user->user_login, + ); continue; } } @@ -305,10 +305,10 @@ private function create_authors_for_mapping( $author_data ) { } $user = array( - 'user_login' => '', - 'user_email' => '', - 'user_pass' => wp_generate_password(), - ); + 'user_login' => '', + 'user_email' => '', + 'user_pass' => wp_generate_password(), + ); $user = array_merge( $user, (array)$author ); $user_id = wp_insert_user( $user ); if ( is_wp_error( $user_id ) ) @@ -316,9 +316,9 @@ private function create_authors_for_mapping( $author_data ) { $user = get_user_by( 'id', $user_id ); $author_mapping[] = array( - 'old_user_login' => $author->user_login, - 'new_user_login' => $user->user_login, - ); + 'old_user_login' => $author->user_login, + 'new_user_login' => $user->user_login, + ); } return $author_mapping; @@ -334,7 +334,7 @@ private function suggest_user( $author_user_login, $author_user_email = '' ) { $shortest = -1; $shortestavg = array(); - + $threshold = floor( ( strlen( $author_user_login ) / 100 ) * 10 ); // 10 % of the strlen are valid $closest = ''; foreach ( $this->blog_users as $user ) { @@ -353,13 +353,13 @@ private function suggest_user( $author_user_login, $author_user_email = '' ) { $shortest = 0; break; } - + if ( ( $lev <= $shortest || $shortest < 0 ) && $lev <= $threshold ) { $closest = $user->user_login; $shortest = $lev; } $shortestavg[] = $lev; - } + } // in case all usernames have a common pattern if ( $shortest > ( array_sum( $shortestavg ) / count( $shortestavg ) ) ) return ''; @@ -368,4 +368,5 @@ private function suggest_user( $author_user_login, $author_user_email = '' ) { } -WP_CLI::add_command( 'import', new Import_Command ); \ No newline at end of file +WP_CLI::add_command( 'import', new Import_Command ); + From e50c87f52bd89558d4dd367ca1be266d14a00b40 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Jun 2013 01:24:26 +0300 Subject: [PATCH 1935/4858] add newline at end of man-src/import.txt [ci skip] --- man-src/import.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man-src/import.txt b/man-src/import.txt index 8a26f302e2..5f4e3dedf4 100644 --- a/man-src/import.txt +++ b/man-src/import.txt @@ -10,4 +10,4 @@ * `--skip=`: - Skip importing specific data. Supported option is 'attachment'. \ No newline at end of file + Skip importing specific data. Supported option is 'attachment'. From 6e42fae31f03f4af200e0a3373b1011047565aeb Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Jun 2013 01:26:13 +0300 Subject: [PATCH 1936/4858] fix indentation in import.feature [ci skip] --- features/import.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/import.feature b/features/import.feature index ffab45b5e1..dc9f201a17 100644 --- a/features/import.feature +++ b/features/import.feature @@ -1,6 +1,6 @@ Feature: Import content. -Scenario: Basic export then import + Scenario: Basic export then import Given a WP install When I run `wp post generate --post_type=post --count=3` @@ -25,7 +25,7 @@ Scenario: Basic export then import When I run `wp site empty --yes` Then STDOUT should not be empty - When I run `wp post list --post_type=any --format=csv | wc -l` + When I run `wp post list --post_type=any --format=csv | wc -l` Then STDOUT should be: """ 1 @@ -41,4 +41,4 @@ Scenario: Basic export then import Then STDOUT should be: """ 8 - """ \ No newline at end of file + """ From 3ca418c83ea26b92c5670a11348d547ad0230558 Mon Sep 17 00:00:00 2001 From: Andrey Savchenko Date: Wed, 26 Jun 2013 02:52:56 +0300 Subject: [PATCH 1937/4858] Added wp.bat to bin section of composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c9a8e7b551..318de31b6c 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "homepage": "http://wp-cli.org", "license": "MIT", "bin": [ - "bin/wp" + "bin/wp.bat", "bin/wp" ], "require": { "php": ">=5.3.2", From dbd220902cb6370a9089f38d1feed6280c09c344 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 26 Jun 2013 11:52:51 +1000 Subject: [PATCH 1938/4858] support for port and socket configurations with wp core config --- php/utils.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index dab686c871..f755257106 100644 --- a/php/utils.php +++ b/php/utils.php @@ -353,8 +353,25 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { function run_mysql_query( $query, $args ) { // TODO: use PDO? + $host_parts = explode( ':', $args['host'] ); + if ( count( $host_parts ) == 2 ) { + list( $host, $extra ) = $host_parts; + } else { + $host = $args['host']; + } + $arg_str = esc_cmd( '--host=%s --user=%s --execute=%s', - $args['host'], $args['user'], $query ); + $host, $args['user'], $query ); + + if ( isset( $extra ) ) { + if ( is_numeric($extra) ) { + $arg_str .= esc_cmd( ' --port=%s --protocol=%s', intval( $extra ), 'tcp' ); + } else if ( trim($extra) !== '' ) { + $arg_str .= esc_cmd( ' --socket=%s', trim( $extra ) ); + } + } + + echo $arg_str . "\n"; run_mysql_command( 'mysql', $arg_str, $args['pass'] ); } From 91d4521d62723bccac68901bdc7968b5429ed25f Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 26 Jun 2013 16:37:16 +1000 Subject: [PATCH 1939/4858] Make wp rewrite (flush|structure) generate .htaccess files properly for apache. --- php/commands/rewrite.php | 28 ++++++++++++++++++++++++---- php/config-spec.php | 7 +++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 7f464ae0ac..3453496e19 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -10,16 +10,18 @@ class Rewrite_Command extends WP_CLI_Command { /** * Flush rewrite rules. * - * @synopsis [--soft] + * @synopsis [--hard] */ public function flush( $args, $assoc_args ) { - flush_rewrite_rules( isset( $assoc_args['soft'] ) ); + // make sure we detect mod_rewrite if configured in apache_modules in config + self::apache_modules(); + flush_rewrite_rules( isset( $assoc_args['hard'] ) ); } /** * Update the permalink structure. * - * @synopsis [--category-base=] [--tag-base=] + * @synopsis [--category-base=] [--tag-base=] [--hard] */ public function structure( $args, $assoc_args ) { global $wp_rewrite; @@ -62,7 +64,9 @@ public function structure( $args, $assoc_args ) { $wp_rewrite->set_tag_base( $tag_base ); } - flush_rewrite_rules( $hard ); + // make sure we detect mod_rewrite if configured in apache_modules in config + self::apache_modules(); + flush_rewrite_rules( isset( $assoc_args['hard'] ) ); } /** @@ -86,6 +90,22 @@ public function dump( $args, $assoc_args ) { } } + + /** + * Expose apache modules if present in config + */ + public static function apache_modules() { + $mods = WP_CLI::get_config('apache_modules'); + if ( count($mods) > 0 && !function_exists( 'apache_get_modules') ) { + global $is_apache; + $is_apache = true; + + function apache_get_modules() { + return WP_CLI::get_config('apache_modules'); + } + } + } + } WP_CLI:: add_command( 'rewrite', 'Rewrite_Command' ); diff --git a/php/config-spec.php b/php/config-spec.php index 61aaf46ba3..1ec7556f82 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -63,5 +63,12 @@ 'default' => false, 'desc' => 'Suppress informational messages', ), + + 'apache_modules' => array( + 'file' => '', + 'desc' => 'List of Apache Modules that are to be reported as loaded', + 'multiple' => true, + 'default' => array(), + ), ); From e97184ef6856a1ae4db8a7803c36f1a6985e19f7 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Jun 2013 12:27:09 +0300 Subject: [PATCH 1940/4858] lock php-cli-tools version to 0.9.3 fixes #560; see #561 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c9a8e7b551..832b311da7 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "0.9.3", "mustache/mustache": "~2.3" }, "suggest": { From f2300d56d231aa6bddfb8a9e2fa692c1e3b30eba Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Jun 2013 17:52:37 +0300 Subject: [PATCH 1941/4858] set Oxymel to version 0.1.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4a9d9cb3f6..fd5211d416 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "php": ">=5.3.2", "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.3", - "nb/oxymel": "dev-master" + "nb/oxymel": "0.1.0" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" From 949b40770010f90579d93db797ec1da40879bac8 Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 26 Jun 2013 18:53:20 +0300 Subject: [PATCH 1942/4858] ensure CRLF are always normalized to LF in the git database --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..0fdf7ac9b9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform EOL normalization +* text=auto From 198e8a3afbd96151633e197055f159aab58a7cd3 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 28 Jun 2013 20:42:04 +0300 Subject: [PATCH 1943/4858] check wp-includes/version.php before loading WP --- php/WP_CLI/Runner.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b3de186ff7..4c57380d1a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -268,6 +268,26 @@ private function init_logger() { WP_CLI::set_logger( $logger ); } + private function check_wp_version() { + if ( !is_readable( ABSPATH . 'wp-includes/version.php' ) ) { + WP_CLI::error( + "This does not seem to be a WordPress install.\n" . + "Pass --path=`path/to/wordpress` or run `wp core download`." ); + } + + include ABSPATH . 'wp-includes/version.php'; + + $minimum_version = '3.4'; + + if ( version_compare( $wp_version, $minimum_version, '<' ) ) { + WP_CLI::error( + "WP-CLI needs WordPress $minimum_version or later to work properly. " . + "The version currently installed is $wp_version.\n" . + "Try running `wp core download --force`." + ); + } + } + public function before_wp_load() { list( $args, $assoc_args, $runtime_config ) = \WP_CLI::$configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -320,11 +340,7 @@ public function before_wp_load() { $this->do_early_invoke( 'before_wp_load' ); - if ( !is_readable( ABSPATH . 'wp-load.php' ) ) { - WP_CLI::error( - "This does not seem to be a WordPress install.\n" . - "Pass --path=`path/to/wordpress` or run `wp core download`." ); - } + $this->check_wp_version(); if ( array( 'core', 'config' ) == $this->arguments ) { $this->_run_command(); From 1c304a996b466c6d17aaf48d2fbc8bf0fbeb91a5 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 22:53:41 +0200 Subject: [PATCH 1944/4858] make WP_CLI::add_command() work when called from a Composer package's autoloaded file --- php/class-wp-cli.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9a7ac59f76..f8d1f3631a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -15,6 +15,7 @@ class WP_CLI { private static $logger; private static $hooks = array(), $hooks_passed = array(); + private static $commands_in_packages = array(); private static $man_dirs = array(); @@ -27,6 +28,10 @@ static function init() { self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); self::$root = new Dispatcher\RootCommand; self::$runner = new WP_CLI\Runner; + + foreach ( self::$commands_in_packages as $args ) { + call_user_func_array( array( __CLASS__, 'add_command' ), $args ); + } } /** @@ -73,6 +78,14 @@ static function do_action( $when ) { * 'before_invoke' => callback to execute before invoking the command */ static function add_command( $name, $class, $args = array() ) { + if ( !self::$root ) { // Still loading Composer autoloader + self::$commands_in_packages[] = func_get_args(); + } else { + self::_add_command( $name, $class, $args ); + } + } + + private static function _add_command( $name, $class, $args ) { $command = Dispatcher\CommandFactory::create( $name, $class, self::$root ); if ( isset( $args['before_invoke'] ) ) { From 5c4fcc3cf083d4dd67a31c4a231e7ac3ec0f88f9 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 23:14:33 +0200 Subject: [PATCH 1945/4858] instantiate WP_CLI::$root on-demand --- php/class-wp-cli.php | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f8d1f3631a..347a3d4d00 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -15,7 +15,6 @@ class WP_CLI { private static $logger; private static $hooks = array(), $hooks_passed = array(); - private static $commands_in_packages = array(); private static $man_dirs = array(); @@ -26,12 +25,7 @@ static function init() { self::add_man_dir( null, WP_CLI_ROOT . "/man-src" ); self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); - self::$root = new Dispatcher\RootCommand; self::$runner = new WP_CLI\Runner; - - foreach ( self::$commands_in_packages as $args ) { - call_user_func_array( array( __CLASS__, 'add_command' ), $args ); - } } /** @@ -78,20 +72,16 @@ static function do_action( $when ) { * 'before_invoke' => callback to execute before invoking the command */ static function add_command( $name, $class, $args = array() ) { - if ( !self::$root ) { // Still loading Composer autoloader - self::$commands_in_packages[] = func_get_args(); - } else { - self::_add_command( $name, $class, $args ); - } - } - - private static function _add_command( $name, $class, $args ) { $command = Dispatcher\CommandFactory::create( $name, $class, self::$root ); if ( isset( $args['before_invoke'] ) ) { self::add_action( "before_invoke:$name", $args['before_invoke'] ); } + if ( !self::$root ) { + self::$root = new Dispatcher\RootCommand; + } + self::$root->add_subcommand( $name, $command ); } From 75504265afd5e36f654e9bf1ac3d469c9739a64e Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 23:19:55 +0200 Subject: [PATCH 1946/4858] introduce get_root_command() getter --- php/class-wp-cli.php | 12 ++++++++---- php/commands/cli.php | 4 ++-- php/commands/help.php | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 347a3d4d00..068acd31aa 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -9,9 +9,9 @@ class WP_CLI { public static $configurator; - public static $root; public static $runner; + private static $root; private static $logger; private static $hooks = array(), $hooks_passed = array(); @@ -72,17 +72,21 @@ static function do_action( $when ) { * 'before_invoke' => callback to execute before invoking the command */ static function add_command( $name, $class, $args = array() ) { - $command = Dispatcher\CommandFactory::create( $name, $class, self::$root ); + $command = Dispatcher\CommandFactory::create( $name, $class, self::get_root_command() ); if ( isset( $args['before_invoke'] ) ) { self::add_action( "before_invoke:$name", $args['before_invoke'] ); } + self::get_root_command()->add_subcommand( $name, $command ); + } + + static function get_root_command() { if ( !self::$root ) { self::$root = new Dispatcher\RootCommand; } - self::$root->add_subcommand( $name, $command ); + return self::$root; } static function add_man_dir( $deprecated = null, $src_dir ) { @@ -249,7 +253,7 @@ static function get_config( $key = null ) { } private static function find_command_to_run( $args ) { - $command = \WP_CLI::$root; + $command = \WP_CLI::get_root_command(); $cmd_path = array(); diff --git a/php/commands/cli.php b/php/commands/cli.php index b537b10280..110fcb0981 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -53,11 +53,11 @@ function param_dump() { * @subcommand cmd-dump */ function cmd_dump() { - echo json_encode( self::command_to_array( WP_CLI::$root ) ); + echo json_encode( self::command_to_array( WP_CLI::get_root_command() ) ); } function completions() { - foreach ( WP_CLI::$root->get_subcommands() as $name => $command ) { + foreach ( WP_CLI::get_root_command()->get_subcommands() as $name => $command ) { $subcommands = $command->get_subcommands(); WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); diff --git a/php/commands/help.php b/php/commands/help.php index c339c6fbf1..7b6599dc71 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -25,7 +25,7 @@ function __invoke( $args, $assoc_args ) { } private static function find_subcommand( $args ) { - $command = \WP_CLI::$root; + $command = \WP_CLI::get_root_command(); while ( !empty( $args ) && $command && $command->has_subcommands() ) { $command = $command->find_subcommand( $args ); From 8148411fa9fbc171fa562ddaa1f026255cdc9e63 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 23:24:07 +0200 Subject: [PATCH 1947/4858] convert $root from class static to method static This avoids accidental direct access from other class methods. --- php/class-wp-cli.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 068acd31aa..964533a200 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -11,7 +11,6 @@ class WP_CLI { public static $configurator; public static $runner; - private static $root; private static $logger; private static $hooks = array(), $hooks_passed = array(); @@ -82,11 +81,13 @@ static function add_command( $name, $class, $args = array() ) { } static function get_root_command() { - if ( !self::$root ) { - self::$root = new Dispatcher\RootCommand; + static $root; + + if ( !$root ) { + $root = new Dispatcher\RootCommand; } - return self::$root; + return $root; } static function add_man_dir( $deprecated = null, $src_dir ) { From 4709fa695e8eece3177a826ba09d81898dcbd82d Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 23:37:08 +0200 Subject: [PATCH 1948/4858] convert from WP_CLI:: to self:: --- php/class-wp-cli.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 964533a200..2df1376a96 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -254,7 +254,7 @@ static function get_config( $key = null ) { } private static function find_command_to_run( $args ) { - $command = \WP_CLI::get_root_command(); + $command = self::get_root_command(); $cmd_path = array(); @@ -267,14 +267,14 @@ private static function find_command_to_run( $args ) { $subcommand = $command->find_subcommand( $args ); if ( !$subcommand ) { - \WP_CLI::error( sprintf( + self::error( sprintf( "'%s' is not a registered wp command. See 'wp help'.", $full_name ) ); } if ( in_array( $full_name, $disabled_commands ) ) { - \WP_CLI::error( sprintf( + self::error( sprintf( "The '%s' command has been disabled from the config file.", $full_name ) ); From ac041c617a386a39cd627f19fee70737ef564ec6 Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 23:41:33 +0200 Subject: [PATCH 1949/4858] introduce get_configurator() getter We don't want to allow people to change the configurator instance just yet. --- php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/WP_CLI/Runner.php | 4 ++-- php/class-wp-cli.php | 6 +++++- php/commands/cli.php | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 67282fd6ab..311d295bbb 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -20,7 +20,7 @@ function __construct() { function get_extra_markdown() { $binding = array(); - foreach ( \WP_CLI::$configurator->get_spec() as $key => $details ) { + foreach ( \WP_CLI::get_configurator()->get_spec() as $key => $details ) { if ( false === $details['runtime'] ) continue; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b3de186ff7..dacbd30284 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -269,7 +269,7 @@ private function init_logger() { } public function before_wp_load() { - list( $args, $assoc_args, $runtime_config ) = \WP_CLI::$configurator->parse_args( + list( $args, $assoc_args, $runtime_config ) = \WP_CLI::get_configurator()->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( @@ -277,7 +277,7 @@ public function before_wp_load() { $this->config_path = self::get_config_path( $runtime_config ); - $local_config = \WP_CLI::$configurator->load_config( $this->config_path ); + $local_config = \WP_CLI::get_configurator()->load_config( $this->config_path ); $this->config = $local_config; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 2df1376a96..dc3462f215 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -8,7 +8,7 @@ */ class WP_CLI { - public static $configurator; + private static $configurator; public static $runner; private static $logger; @@ -36,6 +36,10 @@ static function set_logger( $logger ) { self::$logger = $logger; } + static function get_configurator() { + return self::$configurator; + } + static function colorize( $string ) { return \cli\Colors::colorize( $string, self::$runner->in_color() ); } diff --git a/php/commands/cli.php b/php/commands/cli.php index 110fcb0981..a31493b879 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -46,7 +46,7 @@ function info() { * @subcommand param-dump */ function param_dump() { - echo json_encode( \WP_CLI::$configurator->get_spec() ); + echo json_encode( \WP_CLI::get_configurator()->get_spec() ); } /** From 20ee2ae3817354285970cc107d2700cbc8f77e1b Mon Sep 17 00:00:00 2001 From: scribu Date: Sun, 30 Jun 2013 23:44:49 +0200 Subject: [PATCH 1950/4858] introduce WP_CLI::get_runner() getter We don't want to allow people to change the runner instance either. --- php/WP_CLI/Dispatcher/CompositeCommand.php | 2 +- php/class-wp-cli.php | 4 ++++ php/wp-cli.php | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 90dc7fe1b8..1aa21b5d3e 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -20,7 +20,7 @@ public function __construct( $parent, $name, $docparser ) { $when_to_invoke = $docparser->get_tag( 'when' ); if ( $when_to_invoke ) { - \WP_CLI::$runner->register_early_invoke( $when_to_invoke, $this ); + \WP_CLI::get_runner()->register_early_invoke( $when_to_invoke, $this ); } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index dc3462f215..9b91d35fce 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -40,6 +40,10 @@ static function get_configurator() { return self::$configurator; } + static function get_runner() { + return self::$runner; + } + static function colorize( $string ) { return \cli\Colors::colorize( $string, self::$runner->in_color() ); } diff --git a/php/wp-cli.php b/php/wp-cli.php index 5970c361f3..1064b77e61 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -14,10 +14,10 @@ WP_CLI::init(); -WP_CLI::$runner->before_wp_load(); +WP_CLI::get_runner()->before_wp_load(); // Load wp-config.php code, in the global scope -eval( WP_CLI::$runner->get_wp_config_code() ); +eval( WP_CLI::get_runner()->get_wp_config_code() ); // Simulate a /wp-admin/ page load $_SERVER['PHP_SELF'] = '/wp-admin/index.php'; @@ -34,5 +34,5 @@ require ABSPATH . 'wp-admin/includes/admin.php'; do_action( 'admin_init' ); -WP_CLI::$runner->after_wp_load(); +WP_CLI::get_runner()->after_wp_load(); From 36aac2e3f69d16bc431b58ad840b2d13fa40436f Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 1 Jul 2013 01:52:19 +0200 Subject: [PATCH 1951/4858] travis: test against PHP 5.5 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cff1fea328..7ed5e423f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: php php: - 5.3 - - 5.4 + - 5.5 env: - WP_VERSION=latest @@ -10,7 +10,7 @@ env: matrix: exclude: - - php: 5.4 + - php: 5.5 env: WP_VERSION=3.4.2 before_script: ./bin/ci/install_dependencies.sh From 5cfe3c1d83df156887b1db740d1a617c5d67d299 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Tue, 2 Jul 2013 12:26:09 +1000 Subject: [PATCH 1952/4858] bool -> list --- php/config-spec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/config-spec.php b/php/config-spec.php index 1ec7556f82..a2f174769b 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -65,7 +65,7 @@ ), 'apache_modules' => array( - 'file' => '', + 'file' => '', 'desc' => 'List of Apache Modules that are to be reported as loaded', 'multiple' => true, 'default' => array(), From d48fee13b22bdbf9fdd5bd285ef80e1c483247da Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Tue, 2 Jul 2013 12:28:01 +1000 Subject: [PATCH 1953/4858] remove debug line --- php/utils.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index f755257106..e2523f296c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -371,8 +371,6 @@ function run_mysql_query( $query, $args ) { } } - echo $arg_str . "\n"; - run_mysql_command( 'mysql', $arg_str, $args['pass'] ); } From a7c9fd9ca8dd5e4214b0674eeeedc59aa27d4d13 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 20:18:54 -0700 Subject: [PATCH 1954/4858] Improve `theme install` logic to support force-installing a specific version. Previous `theme install` logic: * Updates the theme if there's an update available. * Installs if the theme isn't installed. * Otherwise, assume the theme is installed. New `theme install` logic: * Don't do anything if theme is already installed and no `--version` specified. * If `--version` is set and is different than what's installed, force install. * Install if the theme isn't installed. --- php/commands/theme.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 681d273bef..e6824309fc 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -113,20 +113,20 @@ protected function install_from_repo( $slug, $assoc_args ) { self::alter_api_response( $api, $assoc_args['version'] ); } - // Check to see if we should update, rather than install. - if ( $this->has_update( $slug ) ) { - WP_CLI::log( sprintf( 'Updating %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $slug ); - - /** - * Else, if there's no update, it's either not installed, - * or it's newer than what we've got. - */ - } else if ( !wp_get_theme( $slug )->exists() ) { + $theme_obj = wp_get_theme( $slug ); + if ( $theme_obj->exists() + && empty( $assoc_args['version'] ) ) { + // Theme is already installed to the correct version. + WP_CLI::error( 'Theme already installed.' ); + } else if ( $theme_obj->exists() + && version_compare( $assoc_args['version'], $theme_obj->version, '!=' ) ) { + // Theme is installed, but we want a different version + WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + delete_theme( $theme_obj->stylesheet ); + $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); + } else if ( ! $theme_obj->exists() ) { WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); - } else { - WP_CLI::error( 'Theme already installed and up to date.' ); } // Finally, activate theme if requested. From 8565c6fb9212dd850019a9ab0ed8bbe7cf5365e2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 20:30:56 -0700 Subject: [PATCH 1955/4858] A Behat test for force-installing a plugin --- features/plugin.feature | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 174ab4abe7..349559f51d 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -60,3 +60,25 @@ Feature: Manage WordPress plugins """ The plugin 'zombieland' could not be found. """ + + Scenario: Install a plugin, activate, then force install an older version of the plugin + Given a WP install + + When I run `wp plugin install akismet --version=2.5.7` + Then STDOUT should not be empty + + When I run `wp plugin list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | akismet | inactive | available | 2.5.7 | + + When I run `wp plugin activate akismet` + Then STDOUT should not be empty + + When I run `wp plugin install akismet --version=2.5.6` + Then STDOUT should not be empty + + When I run `wp plugin list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | akismet | active | available | 2.5.6 | From 7979a5bd1866cb3438d679a16fcc2f7cfdc1ae12 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 20:35:24 -0700 Subject: [PATCH 1956/4858] Behat test for force-installing a specific version of a theme. --- features/theme.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index f7a57b5b98..b599957bdd 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -47,3 +47,24 @@ Feature: Manage WordPress themes When I run `wp theme list` Then STDOUT should not be empty + Scenario: Install a theme, activate, then force install an older version of the theme + Given a WP install + + When I run `wp theme install p2 --version=1.4.2` + Then STDOUT should not be empty + + When I run `wp theme list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | p2 | inactive | available | 1.4.2 | + + When I run `wp theme activate p2` + Then STDOUT should not be empty + + When I run `wp theme install p2 --version=1.4.1` + Then STDOUT should not be empty + + When I run `wp theme list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | p2 | active | available | 1.4.1 | From da576a63037aeb77fd5e4288f9e8feabeddace48 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 20:58:29 -0700 Subject: [PATCH 1957/4858] Support for `count` as a format type; update PHPdoc --- php/utils.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 72ab484459..810f3fb1e1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -248,15 +248,21 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria } /** - * Output items in a table, JSON, or CSV + * Output items in a table, JSON, CSV, ids, or the total count * - * @param string $format Format to use: 'table', 'json', 'csv', 'ids' + * @param string $format Format to use: 'table', 'json', 'csv', 'ids', 'count' * @param array $items Data to output * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ function format_items( $format, $items, $fields ) { - if ( 'ids' == $format ) + + if ( 'ids' == $format ) { echo implode( ' ', $items ); + return; + } else if ( 'count' == $format ) { + echo count( $items ); + return; + } if ( ! is_array( $fields ) ) $fields = explode( ',', $fields ); From fbc4792d159adbe3c4e593b1ad7c3d84a11b0820 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 20:59:04 -0700 Subject: [PATCH 1958/4858] Fix maths error --- features/import.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/import.feature b/features/import.feature index dc9f201a17..feca82c72d 100644 --- a/features/import.feature +++ b/features/import.feature @@ -12,7 +12,7 @@ Feature: Import content. When I run `wp post list --post_type=any --format=csv | wc -l` Then STDOUT should be: """ - 8 + 7 """ When I run `wp export` From c4ee20dac02564643f27b06fb8354860ddc2c50c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 21:00:32 -0700 Subject: [PATCH 1959/4858] Scratch, fbc4792 was because I dropped the CSV heading. Update the rest of the scenarios --- features/import.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/import.feature b/features/import.feature index feca82c72d..a10af31846 100644 --- a/features/import.feature +++ b/features/import.feature @@ -9,7 +9,7 @@ Feature: Import content. When I run `wp post generate --post_type=page --count=2` Then STDOUT should not be empty - When I run `wp post list --post_type=any --format=csv | wc -l` + When I run `wp post list --post_type=any --format=count` Then STDOUT should be: """ 7 @@ -25,10 +25,10 @@ Feature: Import content. When I run `wp site empty --yes` Then STDOUT should not be empty - When I run `wp post list --post_type=any --format=csv | wc -l` + When I run `wp post list --post_type=any --format=count` Then STDOUT should be: """ - 1 + 0 """ When I run `wp plugin install wordpress-importer --activate` @@ -37,8 +37,8 @@ Feature: Import content. When I run `wp import {EXPORT_FILE} --authors=skip` Then STDOUT should not be empty - When I run `wp post list --post_type=any --format=csv | wc -l` + When I run `wp post list --post_type=any --format=count` Then STDOUT should be: """ - 8 + 7 """ From 97d266b23478c5efb164c679891f73d75316b832 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 1 Jul 2013 21:01:59 -0700 Subject: [PATCH 1960/4858] Update user behat tests to use `--format=count` --- features/user.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/user.feature b/features/user.feature index 8743d12730..137ee89366 100644 --- a/features/user.feature +++ b/features/user.feature @@ -30,10 +30,10 @@ Feature: Manage WordPress users When I run `wp user generate --count=10` Then STDOUT should not be empty - When I run `wp user list | wc -l | tr -d ' '` + When I run `wp user list --format=count` Then STDOUT should be: """ - 11 + 10 """ Scenario: Importing users from a CSV file @@ -49,10 +49,10 @@ Feature: Manage WordPress users When I run `wp user import-csv users.csv` Then STDOUT should not be empty - When I run `wp user list | wc -l | tr -d ' '` + When I run `wp user list --format=count` Then STDOUT should be: """ - 4 + 3 """ When I run `wp user list --format=json` From 50010c4c30ed2a270c3d776626c520e083873798 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Tue, 2 Jul 2013 06:39:46 -0700 Subject: [PATCH 1961/4858] Mention why there's no break See https://github.com/wp-cli/wp-cli/pull/476/files#r4981709 [ci-skip] --- php/commands/plugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 54639bc3fc..8ebb2ed7ae 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -177,6 +177,7 @@ protected function install_from_repo( $slug, $assoc_args ) { list( $file, $name ) = $this->parse_name( array( $api->slug ) ); $this->_delete( $file ); } + // fallthrough - need to install the plugin nows case 'install': $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); From eaac711c6f3e204c5a59da09ab97e60497c99204 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 2 Jul 2013 17:22:41 +0200 Subject: [PATCH 1962/4858] instantiate WP_CLI\Runner on demand; see #571 This allows early commands to be defined in third-party packages. --- php/class-wp-cli.php | 45 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9b91d35fce..784a296223 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -9,7 +9,6 @@ class WP_CLI { private static $configurator; - public static $runner; private static $logger; @@ -24,7 +23,6 @@ static function init() { self::add_man_dir( null, WP_CLI_ROOT . "/man-src" ); self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); - self::$runner = new WP_CLI\Runner; } /** @@ -40,12 +38,28 @@ static function get_configurator() { return self::$configurator; } + static function get_root_command() { + static $root; + + if ( !$root ) { + $root = new Dispatcher\RootCommand; + } + + return $root; + } + static function get_runner() { - return self::$runner; + static $runner; + + if ( !$runner ) { + $runner = new WP_CLI\Runner; + } + + return $runner; } static function colorize( $string ) { - return \cli\Colors::colorize( $string, self::$runner->in_color() ); + return \cli\Colors::colorize( $string, self::get_runner()->in_color() ); } /** @@ -88,16 +102,6 @@ static function add_command( $name, $class, $args = array() ) { self::get_root_command()->add_subcommand( $name, $command ); } - static function get_root_command() { - static $root; - - if ( !$root ) { - $root = new Dispatcher\RootCommand; - } - - return $root; - } - static function add_man_dir( $deprecated = null, $src_dir ) { self::$man_dirs[] = $src_dir; } @@ -151,7 +155,7 @@ static function warning( $message, $label = 'Warning' ) { * @param string $label */ static function error( $message, $label = 'Error' ) { - if ( ! isset( self::$runner->assoc_args[ 'completions' ] ) ) { + if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) ) { self::$logger->error( self::error_to_string( $message ), $label ); } @@ -246,19 +250,20 @@ static function launch( $command, $exit_on_error = true ) { } static function get_config_path() { - return self::$runner->config_path; + return self::get_runner()->config_path; } static function get_config( $key = null ) { - if ( null === $key ) - return self::$runner->config; + if ( null === $key ) { + return self::get_runner()->config; + } - if ( !isset( self::$runner->config[ $key ] ) ) { + if ( !isset( self::get_runner()->config[ $key ] ) ) { self::warning( "Unknown config option '$key'." ); return null; } - return self::$runner->config[ $key ]; + return self::get_runner()->config[ $key ]; } private static function find_command_to_run( $args ) { From 7efff3015a7d615169a01764799fd7a316694812 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 09:44:11 +1000 Subject: [PATCH 1963/4858] add comment explaining need for apache_modules() function --- php/commands/rewrite.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 3453496e19..297caba79d 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -93,6 +93,26 @@ public function dump( $args, $assoc_args ) { /** * Expose apache modules if present in config + * + * Implementation Notes: This function exposes a global function + * apache_get_modules and also sets the $is_apache global variable. + * + * This is so that flush_rewrite_rules will actually write out the + * .htaccess file for apache wordpress installations. There is a check + * to see: + * + * 1. if the $is_apache variable is set. + * 2. if the mod_rewrite module is returned from the apche_get_modules + * function. + * + * To get this to work with wp-cli you'll need to add the mod_rewrite module + * to your config.yml. For example + * + * apache_modules: + * - mod_rewrite + * + * If this isn't done then the .htaccess rewrite rules won't be flushed out + * to disk. */ public static function apache_modules() { $mods = WP_CLI::get_config('apache_modules'); From 070ad89cbba10dce8cbdbe379bdc5caaf239335b Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 11:42:37 +1000 Subject: [PATCH 1964/4858] don\'t hard code localhost --- php/commands/core.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9f450ce5bb..c14344c4be 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -336,7 +336,7 @@ function update_db() { * * @subcommand init-tests * - * @synopsis [] --dbname= --dbuser= [--dbpass=] + * @synopsis [] --dbname= --dbuser= [--dbpass=] [--dbhost=] */ function init_tests( $args, $assoc_args ) { if ( isset( $args[0] ) ) @@ -346,6 +346,7 @@ function init_tests( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( 'dbpass' => '', + 'dbhost' => 'localhost' ) ); // Download the test suite @@ -355,7 +356,7 @@ function init_tests( $args, $assoc_args ) { $query = sprintf( 'CREATE DATABASE IF NOT EXISTS `%s`', $assoc_args['dbname'] ); Utils\run_mysql_query( $query, array( - 'host' => 'localhost', + 'host' => $assoc_args['dbhost'], 'user' => $assoc_args['dbuser'], 'pass' => $assoc_args['dbpass'], ) ); From f75d5a1f41ecc3af14ca721a9a0ea931a6327b38 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 12:26:57 +1000 Subject: [PATCH 1965/4858] replace host in config file --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index c14344c4be..59964c0822 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -369,6 +369,7 @@ function init_tests( $args, $assoc_args ) { "yourdbnamehere" => $assoc_args['dbname'], "yourusernamehere" => $assoc_args['dbuser'], "yourpasswordhere" => $assoc_args['dbpass'], + "localhost" => $assoc_args['dbhost'], ); $config_file = str_replace( array_keys( $replacements ), array_values( $replacements ), $config_file ); From e3f0c5b59cafb81165ea356c6491e6120b1b0542 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 15:46:38 +1000 Subject: [PATCH 1966/4858] inline sed replace that is portable across GNU linux and Mac OSX --- templates/install-wp-tests.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index a93a900d62..616bfb99b5 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -21,12 +21,16 @@ tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR # set up testing suite svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR +# portable in-place argument for both GNU sed and Mac OSX sed +[[ $(uname -s) == 'Darwin' ]] && ioption=(-i "") || ioption=(-i) + +# generate testing config file cd $WP_TESTS_DIR cp wp-tests-config-sample.php wp-tests-config.php -sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php -sed -i "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php -sed -i "s/yourusernamehere/$DB_USER/" wp-tests-config.php -sed -i "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php +sed "${ioption[@]}" "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php +sed "${ioption[@]}" "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php +sed "${ioption[@]}" "s/yourusernamehere/$DB_USER/" wp-tests-config.php +sed "${ioption[@]}" "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php # create database mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS" From 0004bbc4689249b96dbd4438f685c692e24a41f7 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 15:48:16 +1000 Subject: [PATCH 1967/4858] enable passing through a db hostname with port, socket, etc --- templates/install-wp-tests.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 616bfb99b5..7d2572214c 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -1,14 +1,15 @@ #!/usr/bin/env bash if [ $# -lt 3 ]; then - echo "usage: $0 [wp-version]" + echo "usage: $0 [db-host] [wp-version]" exit 1 fi DB_NAME=$1 DB_USER=$2 DB_PASS=$3 -WP_VERSION=${4-master} +DB_HOST=$4 +WP_VERSION=${5-master} set -ex @@ -31,6 +32,23 @@ sed "${ioption[@]}" "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-t sed "${ioption[@]}" "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php sed "${ioption[@]}" "s/yourusernamehere/$DB_USER/" wp-tests-config.php sed "${ioption[@]}" "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php +sed "${ioption[@]}" "s/localhost/${DB_HOST//\//\\/}/" wp-tests-config.php + +# parse DB_HOST for port or socket references +PARTS=(${DB_HOST//\:/ }) +DB_HOSTNAME=${PARTS[0]}; +DB_SOCK_OR_PORT=${PARTS[1]}; +EXTRA="" + +if ! [ -z $DB_HOSTNAME ] ; then + if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi +fi # create database -mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS" +mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA From 047fdc7f67d8ecc02cd7f48cfc18d79ec86c7078 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 16:42:59 +1000 Subject: [PATCH 1968/4858] default host to localhost --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 7d2572214c..2357d1a828 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -8,7 +8,7 @@ fi DB_NAME=$1 DB_USER=$2 DB_PASS=$3 -DB_HOST=$4 +DB_HOST=${4:-localhost} WP_VERSION=${5-master} set -ex From 97da95413727b3c0b3affa68c5038b246d90bd56 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 21:46:59 +1000 Subject: [PATCH 1969/4858] use | as sed separator --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 2357d1a828..151c10b3dc 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -32,7 +32,7 @@ sed "${ioption[@]}" "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-t sed "${ioption[@]}" "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php sed "${ioption[@]}" "s/yourusernamehere/$DB_USER/" wp-tests-config.php sed "${ioption[@]}" "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php -sed "${ioption[@]}" "s/localhost/${DB_HOST//\//\\/}/" wp-tests-config.php +sed "${ioption[@]}" "s|localhost|${DB_HOST}|" wp-tests-config.php # parse DB_HOST for port or socket references PARTS=(${DB_HOST//\:/ }) From 9a148445ce4b8f081034ca0aff1161bbdb418445 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Wed, 3 Jul 2013 21:51:37 +1000 Subject: [PATCH 1970/4858] fix whitespace and count -> empty --- php/commands/rewrite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 297caba79d..71538d25b2 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -116,12 +116,12 @@ public function dump( $args, $assoc_args ) { */ public static function apache_modules() { $mods = WP_CLI::get_config('apache_modules'); - if ( count($mods) > 0 && !function_exists( 'apache_get_modules') ) { + if ( !empty( $mods ) && !function_exists( 'apache_get_modules' ) ) { global $is_apache; $is_apache = true; function apache_get_modules() { - return WP_CLI::get_config('apache_modules'); + return WP_CLI::get_config( 'apache_modules' ); } } } From a12965c749c8e10f76246990de799c1c8608cdea Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 5 Jul 2013 14:16:45 +1000 Subject: [PATCH 1971/4858] Bug fix: allow plugins and themes to be installed from zip file URLs that contain GET parameters Without this bug fix, doing something like: wp plugin install http://downloads.wordpress.org/plugin/buddypress.1.7.2.zip?test would fail, because wp-cli wouldn't recognise that the URL contains a zip file. This is because the wp-cli code assumes that ".zip" are the last 4 characters in the URL. With this bug fix, the .zip file detection in URLs has been improved, so the above command works as expected. This allows (for example), plugins/themes to be installed directly from private Amazon S3 URLs (which have GET parameters in the URLs). For example: wp plugin install 'http://s3.amazonaws.com/bucketname/plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef' Note: for complex URLs that contain ampersands, it is usually necessary to enclose the URL in single quotes. --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 65ede4f568..efc6b316f2 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -101,7 +101,7 @@ function install( $args, $assoc_args ) { $slug = stripslashes( $args[0] ); - if ( '.zip' == substr( $slug, -4 ) ) { + if ( '.zip' == substr( $slug, strrpos($slug, '.'), 4 ) ) { $file_upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); if ( $file_upgrader->install( $slug ) ) { From 743092d08e4ef2c8b754ece8e2f17e9474b8b515 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 5 Jul 2013 19:52:12 +0200 Subject: [PATCH 1972/4858] replace VerboseExportWriter class with 'wp_export_new_file' hook --- php/WP_CLI/VerboseExportWriter.php | 73 ------------------------------ php/commands/export.php | 6 ++- php/export/writers.php | 1 + 3 files changed, 6 insertions(+), 74 deletions(-) delete mode 100644 php/WP_CLI/VerboseExportWriter.php diff --git a/php/WP_CLI/VerboseExportWriter.php b/php/WP_CLI/VerboseExportWriter.php deleted file mode 100644 index 5facc3f90f..0000000000 --- a/php/WP_CLI/VerboseExportWriter.php +++ /dev/null @@ -1,73 +0,0 @@ -max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $writer_args['max_file_size']; - $this->destination_directory = $writer_args['destination_directory']; - $this->filename_template = $writer_args['filename_template']; - $this->before_posts_xml = $this->formatter->before_posts(); - $this->after_posts_xml = $this->formatter->after_posts(); - } - - public function export() { - $this->start_new_file(); - foreach( $this->formatter->posts() as $post_xml ) { - if ( ( $this->current_file_size + strlen( $post_xml ) ) > $this->max_file_size ) { - $this->start_new_file(); - } - $this->write( $post_xml ); - } - $this->close_current_file(); - } - - protected function write( $xml ) { - $res = fwrite( $this->f, $xml); - if ( false === $res ) { - throw new WP_Export_Exception( __( 'WP Export: error writing to export file.' ) ); - } - $this->current_file_size += strlen( $xml ); - } - - private function start_new_file() { - if ( $this->f ) { - $this->close_current_file(); - } - $file_path = $this->next_file_path(); - $this->f = fopen( $file_path, 'w' ); - if ( !$this->f ) { - throw new WP_Export_Exception( sprintf( __( 'WP Export: error opening %s for writing.' ), $file_path ) ); - } - \WP_CLI::log( sprintf( "Started writing to %s", $file_path ) ); - $this->current_file_size = 0; - $this->write( $this->before_posts_xml ); - } - - private function close_current_file() { - if ( !$this->f ) { - return; - } - $this->write( $this->after_posts_xml ); - fclose( $this->f ); - } - - private function next_file_name() { - $next_file_name = sprintf( $this->filename_template, $this->next_file_number ); - $this->next_file_number++; - return $next_file_name; - } - - private function next_file_path() { - return untrailingslashit( $this->destination_directory ) . DIRECTORY_SEPARATOR . $this->next_file_name(); - } -} - diff --git a/php/commands/export.php b/php/commands/export.php index 97a319b9fb..3d4130b5c3 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -35,9 +35,13 @@ public function __invoke( $_, $assoc_args ) { WP_CLI::log( 'Starting export process...' ); + add_action( 'wp_export_new_file', function( $file_path ) { + WP_CLI::log( sprintf( "Started writing to %s", $file_path ) ); + } ); + wp_export( array( 'filters' => $this->export_args, - 'writer' => '\\WP_CLI\\VerboseExportWriter', + 'writer' => 'WP_Export_Split_Files_Writer', 'writer_args' => array( 'max_file_size' => $this->max_file_size * MB_IN_BYTES, 'destination_directory' => $this->wxr_path, diff --git a/php/export/writers.php b/php/export/writers.php index 52a68d7025..751d356a10 100644 --- a/php/export/writers.php +++ b/php/export/writers.php @@ -120,6 +120,7 @@ private function start_new_file() { if ( !$this->f ) { throw new WP_Export_Exception( sprintf( __( 'WP Export: error opening %s for writing.' ), $file_path ) ); } + do_action( 'wp_export_new_file', $file_path ); $this->current_file_size = 0; $this->write( $this->before_posts_xml ); } From 0f58857c7e7bc2b019e982e545250d5edbec99f1 Mon Sep 17 00:00:00 2001 From: scribu Date: Fri, 5 Jul 2013 20:03:20 +0200 Subject: [PATCH 1973/4858] behat: fix import by making the export message match the expected format again --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 3d4130b5c3..f7d7228075 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -36,7 +36,7 @@ public function __invoke( $_, $assoc_args ) { WP_CLI::log( 'Starting export process...' ); add_action( 'wp_export_new_file', function( $file_path ) { - WP_CLI::log( sprintf( "Started writing to %s", $file_path ) ); + WP_CLI::log( sprintf( "Writing to file %s", $file_path ) ); } ); wp_export( array( From e749f71cb00d2f905bf794677250818e05df58a5 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sat, 6 Jul 2013 11:34:07 +1000 Subject: [PATCH 1974/4858] behat: Tests to demonstraten the plugin/theme install bug in #581 * Install plugins from WordPress.org repository, a local zip file, and remote zip files. * Install themes from WordPress.org repository, a local zip file, and remote zip files. --- features/plugin.feature | 81 ++++++++++++++++++++++++++++++++++ features/steps/basic_steps.php | 20 +++++++++ features/theme.feature | 74 +++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 174ab4abe7..ad517cad34 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -60,3 +60,84 @@ Feature: Manage WordPress plugins """ The plugin 'zombieland' could not be found. """ + + Scenario: Install plugins from WordPress.org repository, a local zip file, and remote zip files + Given a WP install + And I run `wp plugin path` + And save STDOUT as {PLUGIN_DIR} + And a local mp6 plugin zip file + + When I run `wp plugin delete akismet` + Then STDOUT should contain: + """ + Success: Deleted 'akismet' plugin. + """ + And the {PLUGIN_DIR}/akismet file should not exist + + # Install plugin from WordPress.org repository + When I run `wp plugin install akismet` + Then STDOUT should contain: + """ + Plugin installed successfully. + """ + And the {PLUGIN_DIR}/akismet/akismet.php file should exist + + When I try the previous command again + Then the return code should be 1 + And STDERR should contain: + """ + Error: Latest version already installed. + """ + + When I run `wp plugin delete akismet` + Then STDOUT should contain: + """ + Success: Deleted 'akismet' plugin. + """ + And the {PLUGIN_DIR}/akismet file should not exist + + # Install plugin from a local zip file + When I run `wp plugin install {DOWNLOADED_PLUGIN_FILE}` + Then STDOUT should contain: + """ + Plugin installed successfully. + """ + And the {PLUGIN_DIR}/mp6/mp6.php file should exist + And the {DOWNLOADED_PLUGIN_FILE} file should exist + + When I run `wp plugin delete mp6` + Then STDOUT should contain: + """ + Success: Deleted 'mp6' plugin. + """ + And the {PLUGIN_DIR}/mp6 file should not exist + + # Install plugin from remote ZIP file (standard URL with no GET parameters) + When I run `wp plugin install http://downloads.wordpress.org/plugin/akismet.zip` + Then STDOUT should contain: + """ + Plugin installed successfully. + """ + And the {PLUGIN_DIR}/akismet/akismet.php file should exist + + When I run `wp plugin delete akismet` + Then STDOUT should contain: + """ + Success: Deleted 'akismet' plugin. + """ + And the {PLUGIN_DIR}/akismet file should not exist + + # Install plugin from remote ZIP file (complex URL with GET parameters) + When I run `wp plugin install 'http://downloads.wordpress.org/plugin/akismet.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` + Then STDOUT should contain: + """ + Plugin installed successfully. + """ + And the {PLUGIN_DIR}/akismet/akismet.php file should exist + + When I run `wp plugin delete akismet` + Then STDOUT should contain: + """ + Success: Deleted 'akismet' plugin. + """ + And the {PLUGIN_DIR}/akismet file should not exist \ No newline at end of file diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 8198bf7b71..f8400046da 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -93,6 +93,26 @@ function ( $world ) { } ); +$steps->Given( '/^a local mp6 plugin zip file/', + function ( $world ) { + $image_file = 'http://downloads.wordpress.org/plugin/mp6.zip'; + + $world->variables['DOWNLOADED_PLUGIN_FILE'] = $world->get_cache_path( 'mp6.zip' ); + + $world->download_file( $image_file, $world->variables['DOWNLOADED_PLUGIN_FILE'] ); + } +); + +$steps->Given( '/^a local classic theme zip file/', + function ( $world ) { + $image_file = 'http://wordpress.org/themes/download/classic.1.6.zip'; + + $world->variables['DOWNLOADED_THEME_FILE'] = $world->get_cache_path( 'classic.zip' ); + + $world->download_file( $image_file, $world->variables['DOWNLOADED_THEME_FILE'] ); + } +); + $steps->When( '/^I (run|try) `([^`]+)`$/', function ( $world, $mode, $cmd ) { $cmd = $world->replace_variables( $cmd ); diff --git a/features/theme.feature b/features/theme.feature index f7a57b5b98..17195ef792 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -47,3 +47,77 @@ Feature: Manage WordPress themes When I run `wp theme list` Then STDOUT should not be empty + + Scenario: Install themes from WordPress.org repository, a local zip file, and remote zip files + Given a WP install + And I run `wp theme path` + And save STDOUT as {THEME_DIR} + And a local classic theme zip file + + # Install theme from WordPress.org repository + When I run `wp theme install classic` + Then STDOUT should contain: + """ + Theme installed successfully. + """ + And the {THEME_DIR}/classic/style.css file should exist + + When I try the previous command again + Then the return code should be 1 + And STDERR should contain: + """ + Error: Theme already installed and up to date. + """ + + When I run `wp theme delete classic` + Then STDOUT should contain: + """ + Success: Deleted 'classic' theme. + """ + And the {THEME_DIR}/classic file should not exist + + # Install Theme from a local zip file + When I run `wp theme install {DOWNLOADED_THEME_FILE}` + Then STDOUT should contain: + """ + Theme installed successfully. + """ + And the {THEME_DIR}/classic/style.css file should exist + And the {DOWNLOADED_THEME_FILE} file should exist + + When I run `wp theme delete classic` + Then STDOUT should contain: + """ + Success: Deleted 'classic' theme. + """ + And the {THEME_DIR}/classic file should not exist + + # Install Theme from remote ZIP file (standard URL with no GET parameters) + When I run `wp theme install http://wordpress.org/themes/download/classic.1.6.zip` + Then STDOUT should contain: + """ + Theme installed successfully. + """ + And the {THEME_DIR}/classic/style.css file should exist + + When I run `wp theme delete classic` + Then STDOUT should contain: + """ + Success: Deleted 'classic' theme. + """ + And the {THEME_DIR}/classic file should not exist + + # Install Theme from remote ZIP file (complex URL with GET parameters) + When I run `wp theme install 'http://wordpress.org/themes/download/classic.1.6.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` + Then STDOUT should contain: + """ + Theme installed successfully. + """ + And the {THEME_DIR}/classic/style.css file should exist + + When I run `wp theme delete classic` + Then STDOUT should contain: + """ + Success: Deleted 'classic' theme. + """ + And the {THEME_DIR}/classic file should not exist \ No newline at end of file From b26cade8e5c0131762f65abe2135f3a36f2a71a9 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sat, 6 Jul 2013 11:39:59 +1000 Subject: [PATCH 1975/4858] Bug Fix for #581: allow plugins/themes to be installed from complex zip file URLs This should be more reliable than the attempted fix in a12965c. --- php/WP_CLI/CommandWithUpgrade.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index efc6b316f2..1b3434842c 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -101,10 +101,25 @@ function install( $args, $assoc_args ) { $slug = stripslashes( $args[0] ); - if ( '.zip' == substr( $slug, strrpos($slug, '.'), 4 ) ) { + $local_or_remote_zip_file = ''; + + // Check if a URL to a remote zip file has been specified + $url_path = parse_url( $slug, PHP_URL_PATH ); + if ( ! empty( $url_path ) && '.zip' === substr( $url_path, - 4 ) ) { + $local_or_remote_zip_file = $slug; + } else { + // Check if a local zip file has been specified + if ( 'zip' === pathinfo( $slug, PATHINFO_EXTENSION ) && file_exists( $slug ) ) { + $local_or_remote_zip_file = $slug; + } + } + + if ( ! empty( $local_or_remote_zip_file ) ) { + + // Install from local or remote zip file $file_upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); - if ( $file_upgrader->install( $slug ) ) { + if ( $file_upgrader->install( $local_or_remote_zip_file ) ) { $slug = $file_upgrader->result['destination_name']; if ( isset( $assoc_args['activate'] ) ) { @@ -114,7 +129,9 @@ function install( $args, $assoc_args ) { } else { exit(1); } + } else { + // Assume a plugin/theme slug from the WordPress.org repository has been specified $this->install_from_repo( $slug, $assoc_args ); } } From be69d7669d061fb8844492ad8838dd64d0de1490 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 6 Jul 2013 22:34:41 +0200 Subject: [PATCH 1976/4858] behat: replace 'a large image file' step with a more generic and explicit 'download' step --- features/bootstrap/FeatureContext.php | 18 +++++------------- features/media.feature | 8 +++++--- features/steps/basic_steps.php | 19 ++++++++++++------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 25836cc02c..a4e6b45e5b 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -77,6 +77,7 @@ public function afterScenario( $event ) { */ public function __construct( array $parameters ) { $this->drop_db(); + $this->set_cache_dir(); } public function getStepDefinitionResources() { @@ -112,19 +113,10 @@ public function get_path( $file ) { return $this->install_dir . '/' . $file; } - public function get_cache_path( $file ) { - static $path; - - if ( !$path ) { - $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); - } - - return $path . '/' . $file; - } - - public function download_file( $url, $path ) { - Process::create( Utils\esc_cmd( 'curl -sSL %s > %s', $url, $path ) )->run_check(); + private function set_cache_dir() { + $path = sys_get_temp_dir() . '/wp-cli-test-cache'; + Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); + $this->variables['CACHE_DIR'] = $path; } private static function run_sql( $sql ) { diff --git a/features/media.feature b/features/media.feature index ddb721c48d..e09e2b1735 100644 --- a/features/media.feature +++ b/features/media.feature @@ -33,9 +33,11 @@ Feature: Manage WordPress attachments @images Scenario: Import a file as attachment from a local image Given a WP install - And a large image file + And download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg | - When I run `wp media import {DOWNLOADED_IMAGE} --post_id=1 --featured_image` + When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1 --featured_image` Then STDOUT should contain: """ Success: Imported file @@ -44,4 +46,4 @@ Feature: Manage WordPress attachments """ and attached to post 1 as featured image """ - And the {DOWNLOADED_IMAGE} file should exist + And the {CACHE_DIR}/large-image.jpg file should exist diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 8198bf7b71..874c342096 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -83,13 +83,18 @@ function ( $world ) { } ); -$steps->Given( '/^a large image file$/', - function ( $world ) { - $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; - - $world->variables['DOWNLOADED_IMAGE'] = $world->get_cache_path( 'wallpaper.jpg' ); +$steps->Given( '/^download:$/', + function ( $world, TableNode $table ) { + foreach ( $table->getHash() as $row ) { + $path = $world->replace_variables( $row['path'] ); + if ( file_exists( $path ) ) { + var_dump($path); + // assume it's the same file and skip re-download + continue; + } - $world->download_file( $image_file, $world->variables['DOWNLOADED_IMAGE'] ); + \Process::create( \WP_CLI\Utils\esc_cmd( 'curl -sSL %s > %s', $row['url'], $path ) )->run_check(); + } } ); @@ -128,7 +133,7 @@ function ( $world ) { $steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', function ( $world, $stream, $output_filter, $key ) { - + if ( $output_filter ) { $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; if ( false !== preg_match( $output_filter, $world->result->$stream, $matches ) ) From a2798f96a29cde367f88b1d7093d0866501ef6f5 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 6 Jul 2013 22:45:14 +0200 Subject: [PATCH 1977/4858] behat: convert install_dir private property to RUN_DIR variable --- features/bootstrap/FeatureContext.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index a4e6b45e5b..83f8b2ccba 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -26,8 +26,6 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { private static $additional_args; - private $install_dir; - public $variables = array(); // We cache the results of `wp core download` to improve test performance @@ -61,11 +59,12 @@ public static function prepare( SuiteEvent $event ) { * @AfterScenario */ public function afterScenario( $event ) { - if ( !$this->install_dir ) + if ( !isset( $this->variables['RUN_DIR'] ) ) return; + // remove altered WP install, unless there's an error if ( $event->getResult() < 4 ) { - Process::create( Utils\esc_cmd( 'rm -r %s', $this->install_dir ) )->run(); + Process::create( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ) )->run(); } } @@ -103,14 +102,14 @@ private function _replace_var( $matches ) { } public function create_empty_dir() { - if ( !$this->install_dir ) { - $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-run-", TRUE ); - mkdir( $this->install_dir ); + if ( !isset( $this->variables['RUN_DIR'] ) ) { + $this->variables['RUN_DIR'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-run-", TRUE ); + mkdir( $this->variables['RUN_DIR'] ); } } public function get_path( $file ) { - return $this->install_dir . '/' . $file; + return $this->variables['RUN_DIR'] . '/' . $file; } private function set_cache_dir() { @@ -148,7 +147,7 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - return Process::create( $command, $this->install_dir ); + return Process::create( $command, $this->variables['RUN_DIR'] ); } public function move_files( $src, $dest ) { From 59369baf41a2c33b9b069af97998f63e6c24645d Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 6 Jul 2013 22:56:10 +0200 Subject: [PATCH 1978/4858] behat: remove get_path() helper method --- features/bootstrap/FeatureContext.php | 8 ++------ features/steps/basic_steps.php | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 83f8b2ccba..31e10fd1b6 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -108,10 +108,6 @@ public function create_empty_dir() { } } - public function get_path( $file ) { - return $this->variables['RUN_DIR'] . '/' . $file; - } - private function set_cache_dir() { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); @@ -151,7 +147,7 @@ public function proc( $command, $assoc_args = array() ) { } public function move_files( $src, $dest ) { - rename( $this->get_path( $src ), $this->get_path( $dest ) ); + rename( $this->variables['RUN_DIR'] . "/$src", $this->variables['RUN_DIR'] . "/$dest" ); } public function add_line_to_wp_config( &$wp_config_code, $line ) { @@ -161,7 +157,7 @@ public function add_line_to_wp_config( &$wp_config_code, $line ) { } public function download_wordpress_files( $subdir = '' ) { - $dest_dir = $this->get_path( $subdir ); + $dest_dir = $this->variables['RUN_DIR'] . "/$subdir"; if ( $subdir ) mkdir( $dest_dir ); diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 874c342096..481b4cc345 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -22,7 +22,7 @@ function ( $world ) { $steps->Given( '/^a ([^\s]+) file:$/', function ( $world, $path, PyStringNode $content ) { $content = (string) $content . "\n"; - $full_path = $world->get_path( $path ); + $full_path = $world->variables['RUN_DIR'] . "/$path"; Process::create( \WP_CLI\utils\esc_cmd( 'mkdir -p %s', dirname( $full_path ) ) )->run_check(); file_put_contents( $full_path, $content ); } @@ -67,7 +67,7 @@ function ( $world ) { $steps->Given( '/^a custom wp-content directory$/', function ( $world ) { - $wp_config_path = $world->get_path( 'wp-config.php' ); + $wp_config_path = $world->variables['RUN_DIR'] . "/wp-config.php"; $wp_config_code = file_get_contents( $wp_config_path ); @@ -237,7 +237,7 @@ function ( $world, $path, $action, $expected = null ) { // If it's a relative path, make it relative to the current test dir if ( '/' !== $path[0] ) - $path = $world->get_path( $path ); + $path = $world->variables['RUN_DIR'] . "/$path"; switch ( $action ) { case 'exist': From 6671b38302248631b6c78d091c6193ddba650285 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 6 Jul 2013 22:58:07 +0200 Subject: [PATCH 1979/4858] behat: rename some helper methods --- features/bootstrap/FeatureContext.php | 13 +++++++------ features/steps/basic_steps.php | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 31e10fd1b6..8c4dc9fadb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -101,7 +101,7 @@ private function _replace_var( $matches ) { return $cmd; } - public function create_empty_dir() { + public function create_run_dir() { if ( !isset( $this->variables['RUN_DIR'] ) ) { $this->variables['RUN_DIR'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-run-", TRUE ); mkdir( $this->variables['RUN_DIR'] ); @@ -156,7 +156,7 @@ public function add_line_to_wp_config( &$wp_config_code, $line ) { $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); } - public function download_wordpress_files( $subdir = '' ) { + public function download_wp( $subdir = '' ) { $dest_dir = $this->variables['RUN_DIR'] . "/$subdir"; if ( $subdir ) mkdir( $dest_dir ); @@ -164,12 +164,13 @@ public function download_wordpress_files( $subdir = '' ) { Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ) )->run_check(); } - public function wp_install( $subdir = '' ) { + public function install_wp( $subdir = '' ) { $this->create_db(); - $this->create_empty_dir(); - $this->download_wordpress_files( $subdir ); + $this->create_run_dir(); + $this->download_wp( $subdir ); - $this->proc( 'wp core config', array( 'dbprefix' => $subdir ? $subdir : 'wp_' ) )->run_check( $subdir ); + $dbprefix = $subdir ?: 'wp_'; + $this->proc( 'wp core config', compact( 'dbprefix' ) )->run_check( $subdir ); $install_args = array( 'url' => 'http://example.com', diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 481b4cc345..ce1d956a6f 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -15,7 +15,7 @@ function invoke_proc( $proc, $mode, $subdir = null ) { $steps->Given( '/^an empty directory$/', function ( $world ) { - $world->create_empty_dir(); + $world->create_run_dir(); } ); @@ -30,7 +30,7 @@ function ( $world, $path, PyStringNode $content ) { $steps->Given( '/^WP files$/', function ( $world ) { - $world->download_wordpress_files(); + $world->download_wp(); } ); @@ -48,19 +48,19 @@ function ( $world ) { $steps->Given( '/^a WP install$/', function ( $world ) { - $world->wp_install(); + $world->install_wp(); } ); $steps->Given( "/^a WP install in '([^\s]+)'$/", function ( $world, $subdir ) { - $world->wp_install( $subdir ); + $world->install_wp( $subdir ); } ); $steps->Given( '/^a WP multisite install$/', function ( $world ) { - $world->wp_install(); + $world->install_wp(); $world->proc( 'wp core install-network' )->run_check(); } ); From 498fb6a001e2a9dbb6ccc8220356a8485f1fd533 Mon Sep 17 00:00:00 2001 From: scribu Date: Sat, 6 Jul 2013 23:10:58 +0200 Subject: [PATCH 1980/4858] behat: remove var_dump() --- features/steps/basic_steps.php | 1 - 1 file changed, 1 deletion(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index ce1d956a6f..6d84fdc604 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -88,7 +88,6 @@ function ( $world, TableNode $table ) { foreach ( $table->getHash() as $row ) { $path = $world->replace_variables( $row['path'] ); if ( file_exists( $path ) ) { - var_dump($path); // assume it's the same file and skip re-download continue; } From b07154ed976b937aa9875cf55573722e38308ef6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Sun, 7 Jul 2013 18:58:02 +0100 Subject: [PATCH 1981/4858] If a plugin or theme is already installed and the `--version` parameter is used, prompt the user to confirm they'd like it installed. See https://github.com/wp-cli/wp-cli/pull/476#issuecomment-20354895 --- php/commands/plugin.php | 7 +++++-- php/commands/theme.php | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 8ebb2ed7ae..73e11eace5 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -173,7 +173,10 @@ protected function install_from_repo( $slug, $assoc_args ) { case 'newer_installed': case 'update_available': if ( isset( $assoc_args['version'] ) - && version_compare( $status['version'], $assoc_args['version'], '>=' ) ) { + && version_compare( $status['version'], $assoc_args['version'], '!=' ) ) { + + WP_CLI::confirm( "A different version is installed. Overwrite it?", $assoc_args ); + list( $file, $name ) = $this->parse_name( array( $api->slug ) ); $this->_delete( $file ); } @@ -249,7 +252,7 @@ protected function get_item_list() { /** * Install a plugin. * - * @synopsis [--version=] [--activate] + * @synopsis [--version=] [--activate] [--yes] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); diff --git a/php/commands/theme.php b/php/commands/theme.php index e6824309fc..df2da7f67e 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -121,6 +121,8 @@ protected function install_from_repo( $slug, $assoc_args ) { } else if ( $theme_obj->exists() && version_compare( $assoc_args['version'], $theme_obj->version, '!=' ) ) { // Theme is installed, but we want a different version + WP_CLI::confirm( "A different version is installed. Overwrite it?", $assoc_args ); + WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); delete_theme( $theme_obj->stylesheet ); $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); @@ -157,7 +159,7 @@ protected function get_item_list() { /** * Install a theme. * - * @synopsis [--version=] [--activate] + * @synopsis [--version=] [--activate] [--yes] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); From 396adfcc339b3e3dc9cde4dcaebb962b2bb61265 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Sun, 7 Jul 2013 20:08:12 +0100 Subject: [PATCH 1982/4858] Update stories to support b07154e. Behat isn't working properly on my local machine bcause of my shoddy connection, so let's see if this passes in Travis --- features/plugin.feature | 2 +- features/theme.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 349559f51d..5c3e9fb265 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -75,7 +75,7 @@ Feature: Manage WordPress plugins When I run `wp plugin activate akismet` Then STDOUT should not be empty - When I run `wp plugin install akismet --version=2.5.6` + When I run `wp plugin install akismet --version=2.5.6 --yes` Then STDOUT should not be empty When I run `wp plugin list` diff --git a/features/theme.feature b/features/theme.feature index b599957bdd..afc96a97de 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -61,7 +61,7 @@ Feature: Manage WordPress themes When I run `wp theme activate p2` Then STDOUT should not be empty - When I run `wp theme install p2 --version=1.4.1` + When I run `wp theme install p2 --version=1.4.1 --yes` Then STDOUT should not be empty When I run `wp theme list` From fb760886206e76681746ce6322796380ee5aa6ff Mon Sep 17 00:00:00 2001 From: James Collins Date: Mon, 8 Jul 2013 09:10:08 +1000 Subject: [PATCH 1983/4858] Merge remote-tracking branch 'upstream/master' into zipfiles Changes: https://github.com/wp-cli/wp-cli/compare/fbaab715...498fb6 behat: replace 'a large image file' step with a more generic and explicit 'download' step --- features/bootstrap/FeatureContext.php | 54 +++++++++++---------------- features/media.feature | 8 ++-- features/steps/basic_steps.php | 34 +++++++++-------- 3 files changed, 45 insertions(+), 51 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 25836cc02c..8c4dc9fadb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -26,8 +26,6 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { private static $additional_args; - private $install_dir; - public $variables = array(); // We cache the results of `wp core download` to improve test performance @@ -61,11 +59,12 @@ public static function prepare( SuiteEvent $event ) { * @AfterScenario */ public function afterScenario( $event ) { - if ( !$this->install_dir ) + if ( !isset( $this->variables['RUN_DIR'] ) ) return; + // remove altered WP install, unless there's an error if ( $event->getResult() < 4 ) { - Process::create( Utils\esc_cmd( 'rm -r %s', $this->install_dir ) )->run(); + Process::create( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ) )->run(); } } @@ -77,6 +76,7 @@ public function afterScenario( $event ) { */ public function __construct( array $parameters ) { $this->drop_db(); + $this->set_cache_dir(); } public function getStepDefinitionResources() { @@ -101,30 +101,17 @@ private function _replace_var( $matches ) { return $cmd; } - public function create_empty_dir() { - if ( !$this->install_dir ) { - $this->install_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-run-", TRUE ); - mkdir( $this->install_dir ); - } - } - - public function get_path( $file ) { - return $this->install_dir . '/' . $file; - } - - public function get_cache_path( $file ) { - static $path; - - if ( !$path ) { - $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); + public function create_run_dir() { + if ( !isset( $this->variables['RUN_DIR'] ) ) { + $this->variables['RUN_DIR'] = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-run-", TRUE ); + mkdir( $this->variables['RUN_DIR'] ); } - - return $path . '/' . $file; } - public function download_file( $url, $path ) { - Process::create( Utils\esc_cmd( 'curl -sSL %s > %s', $url, $path ) )->run_check(); + private function set_cache_dir() { + $path = sys_get_temp_dir() . '/wp-cli-test-cache'; + Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); + $this->variables['CACHE_DIR'] = $path; } private static function run_sql( $sql ) { @@ -156,11 +143,11 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - return Process::create( $command, $this->install_dir ); + return Process::create( $command, $this->variables['RUN_DIR'] ); } public function move_files( $src, $dest ) { - rename( $this->get_path( $src ), $this->get_path( $dest ) ); + rename( $this->variables['RUN_DIR'] . "/$src", $this->variables['RUN_DIR'] . "/$dest" ); } public function add_line_to_wp_config( &$wp_config_code, $line ) { @@ -169,20 +156,21 @@ public function add_line_to_wp_config( &$wp_config_code, $line ) { $wp_config_code = str_replace( $token, "$line\n\n$token", $wp_config_code ); } - public function download_wordpress_files( $subdir = '' ) { - $dest_dir = $this->get_path( $subdir ); + public function download_wp( $subdir = '' ) { + $dest_dir = $this->variables['RUN_DIR'] . "/$subdir"; if ( $subdir ) mkdir( $dest_dir ); Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ) )->run_check(); } - public function wp_install( $subdir = '' ) { + public function install_wp( $subdir = '' ) { $this->create_db(); - $this->create_empty_dir(); - $this->download_wordpress_files( $subdir ); + $this->create_run_dir(); + $this->download_wp( $subdir ); - $this->proc( 'wp core config', array( 'dbprefix' => $subdir ? $subdir : 'wp_' ) )->run_check( $subdir ); + $dbprefix = $subdir ?: 'wp_'; + $this->proc( 'wp core config', compact( 'dbprefix' ) )->run_check( $subdir ); $install_args = array( 'url' => 'http://example.com', diff --git a/features/media.feature b/features/media.feature index ddb721c48d..e09e2b1735 100644 --- a/features/media.feature +++ b/features/media.feature @@ -33,9 +33,11 @@ Feature: Manage WordPress attachments @images Scenario: Import a file as attachment from a local image Given a WP install - And a large image file + And download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg | - When I run `wp media import {DOWNLOADED_IMAGE} --post_id=1 --featured_image` + When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1 --featured_image` Then STDOUT should contain: """ Success: Imported file @@ -44,4 +46,4 @@ Feature: Manage WordPress attachments """ and attached to post 1 as featured image """ - And the {DOWNLOADED_IMAGE} file should exist + And the {CACHE_DIR}/large-image.jpg file should exist diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index f8400046da..8fe4d431e1 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -15,14 +15,14 @@ function invoke_proc( $proc, $mode, $subdir = null ) { $steps->Given( '/^an empty directory$/', function ( $world ) { - $world->create_empty_dir(); + $world->create_run_dir(); } ); $steps->Given( '/^a ([^\s]+) file:$/', function ( $world, $path, PyStringNode $content ) { $content = (string) $content . "\n"; - $full_path = $world->get_path( $path ); + $full_path = $world->variables['RUN_DIR'] . "/$path"; Process::create( \WP_CLI\utils\esc_cmd( 'mkdir -p %s', dirname( $full_path ) ) )->run_check(); file_put_contents( $full_path, $content ); } @@ -30,7 +30,7 @@ function ( $world, $path, PyStringNode $content ) { $steps->Given( '/^WP files$/', function ( $world ) { - $world->download_wordpress_files(); + $world->download_wp(); } ); @@ -48,26 +48,26 @@ function ( $world ) { $steps->Given( '/^a WP install$/', function ( $world ) { - $world->wp_install(); + $world->install_wp(); } ); $steps->Given( "/^a WP install in '([^\s]+)'$/", function ( $world, $subdir ) { - $world->wp_install( $subdir ); + $world->install_wp( $subdir ); } ); $steps->Given( '/^a WP multisite install$/', function ( $world ) { - $world->wp_install(); + $world->install_wp(); $world->proc( 'wp core install-network' )->run_check(); } ); $steps->Given( '/^a custom wp-content directory$/', function ( $world ) { - $wp_config_path = $world->get_path( 'wp-config.php' ); + $wp_config_path = $world->variables['RUN_DIR'] . "/wp-config.php"; $wp_config_code = file_get_contents( $wp_config_path ); @@ -83,13 +83,17 @@ function ( $world ) { } ); -$steps->Given( '/^a large image file$/', - function ( $world ) { - $image_file = 'http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg'; - - $world->variables['DOWNLOADED_IMAGE'] = $world->get_cache_path( 'wallpaper.jpg' ); +$steps->Given( '/^download:$/', + function ( $world, TableNode $table ) { + foreach ( $table->getHash() as $row ) { + $path = $world->replace_variables( $row['path'] ); + if ( file_exists( $path ) ) { + // assume it's the same file and skip re-download + continue; + } - $world->download_file( $image_file, $world->variables['DOWNLOADED_IMAGE'] ); + \Process::create( \WP_CLI\Utils\esc_cmd( 'curl -sSL %s > %s', $row['url'], $path ) )->run_check(); + } } ); @@ -148,7 +152,7 @@ function ( $world ) { $steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', function ( $world, $stream, $output_filter, $key ) { - + if ( $output_filter ) { $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; if ( false !== preg_match( $output_filter, $world->result->$stream, $matches ) ) @@ -252,7 +256,7 @@ function ( $world, $path, $action, $expected = null ) { // If it's a relative path, make it relative to the current test dir if ( '/' !== $path[0] ) - $path = $world->get_path( $path ); + $path = $world->variables['RUN_DIR'] . "/$path"; switch ( $action ) { case 'exist': From 05f6beed91ad2a5339c274dec060dc241a477f4d Mon Sep 17 00:00:00 2001 From: James Collins Date: Mon, 8 Jul 2013 09:54:53 +1000 Subject: [PATCH 1984/4858] behat: Convert duplicate plugin/theme tests to scenario outlines Converts the plugin/theme tests added in e749f71 to Behat's scenario outlines (http://docs.behat.org/guides/1.gherkin.html#scenario-outlines), which removes test duplication. vendor/bin/behat features/upgradables.feature --expand --- features/plugin.feature | 81 ------------------------------------ features/theme.feature | 75 --------------------------------- features/upgradables.feature | 66 +++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 160 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index ad517cad34..174ab4abe7 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -60,84 +60,3 @@ Feature: Manage WordPress plugins """ The plugin 'zombieland' could not be found. """ - - Scenario: Install plugins from WordPress.org repository, a local zip file, and remote zip files - Given a WP install - And I run `wp plugin path` - And save STDOUT as {PLUGIN_DIR} - And a local mp6 plugin zip file - - When I run `wp plugin delete akismet` - Then STDOUT should contain: - """ - Success: Deleted 'akismet' plugin. - """ - And the {PLUGIN_DIR}/akismet file should not exist - - # Install plugin from WordPress.org repository - When I run `wp plugin install akismet` - Then STDOUT should contain: - """ - Plugin installed successfully. - """ - And the {PLUGIN_DIR}/akismet/akismet.php file should exist - - When I try the previous command again - Then the return code should be 1 - And STDERR should contain: - """ - Error: Latest version already installed. - """ - - When I run `wp plugin delete akismet` - Then STDOUT should contain: - """ - Success: Deleted 'akismet' plugin. - """ - And the {PLUGIN_DIR}/akismet file should not exist - - # Install plugin from a local zip file - When I run `wp plugin install {DOWNLOADED_PLUGIN_FILE}` - Then STDOUT should contain: - """ - Plugin installed successfully. - """ - And the {PLUGIN_DIR}/mp6/mp6.php file should exist - And the {DOWNLOADED_PLUGIN_FILE} file should exist - - When I run `wp plugin delete mp6` - Then STDOUT should contain: - """ - Success: Deleted 'mp6' plugin. - """ - And the {PLUGIN_DIR}/mp6 file should not exist - - # Install plugin from remote ZIP file (standard URL with no GET parameters) - When I run `wp plugin install http://downloads.wordpress.org/plugin/akismet.zip` - Then STDOUT should contain: - """ - Plugin installed successfully. - """ - And the {PLUGIN_DIR}/akismet/akismet.php file should exist - - When I run `wp plugin delete akismet` - Then STDOUT should contain: - """ - Success: Deleted 'akismet' plugin. - """ - And the {PLUGIN_DIR}/akismet file should not exist - - # Install plugin from remote ZIP file (complex URL with GET parameters) - When I run `wp plugin install 'http://downloads.wordpress.org/plugin/akismet.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` - Then STDOUT should contain: - """ - Plugin installed successfully. - """ - And the {PLUGIN_DIR}/akismet/akismet.php file should exist - - When I run `wp plugin delete akismet` - Then STDOUT should contain: - """ - Success: Deleted 'akismet' plugin. - """ - And the {PLUGIN_DIR}/akismet file should not exist \ No newline at end of file diff --git a/features/theme.feature b/features/theme.feature index 17195ef792..d4a073c52b 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -46,78 +46,3 @@ Feature: Manage WordPress themes When I run `wp theme list` Then STDOUT should not be empty - - - Scenario: Install themes from WordPress.org repository, a local zip file, and remote zip files - Given a WP install - And I run `wp theme path` - And save STDOUT as {THEME_DIR} - And a local classic theme zip file - - # Install theme from WordPress.org repository - When I run `wp theme install classic` - Then STDOUT should contain: - """ - Theme installed successfully. - """ - And the {THEME_DIR}/classic/style.css file should exist - - When I try the previous command again - Then the return code should be 1 - And STDERR should contain: - """ - Error: Theme already installed and up to date. - """ - - When I run `wp theme delete classic` - Then STDOUT should contain: - """ - Success: Deleted 'classic' theme. - """ - And the {THEME_DIR}/classic file should not exist - - # Install Theme from a local zip file - When I run `wp theme install {DOWNLOADED_THEME_FILE}` - Then STDOUT should contain: - """ - Theme installed successfully. - """ - And the {THEME_DIR}/classic/style.css file should exist - And the {DOWNLOADED_THEME_FILE} file should exist - - When I run `wp theme delete classic` - Then STDOUT should contain: - """ - Success: Deleted 'classic' theme. - """ - And the {THEME_DIR}/classic file should not exist - - # Install Theme from remote ZIP file (standard URL with no GET parameters) - When I run `wp theme install http://wordpress.org/themes/download/classic.1.6.zip` - Then STDOUT should contain: - """ - Theme installed successfully. - """ - And the {THEME_DIR}/classic/style.css file should exist - - When I run `wp theme delete classic` - Then STDOUT should contain: - """ - Success: Deleted 'classic' theme. - """ - And the {THEME_DIR}/classic file should not exist - - # Install Theme from remote ZIP file (complex URL with GET parameters) - When I run `wp theme install 'http://wordpress.org/themes/download/classic.1.6.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` - Then STDOUT should contain: - """ - Theme installed successfully. - """ - And the {THEME_DIR}/classic/style.css file should exist - - When I run `wp theme delete classic` - Then STDOUT should contain: - """ - Success: Deleted 'classic' theme. - """ - And the {THEME_DIR}/classic file should not exist \ No newline at end of file diff --git a/features/upgradables.feature b/features/upgradables.feature index e444286176..fbda07e2dc 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -2,7 +2,18 @@ Feature: Manage WordPress themes and plugins Scenario Outline: Installing, upgrading and deleting a theme or plugin Given a WP install - And I run `wp install --version=` + And download: + | path | url | + | {CACHE_DIR}/.zip | | + And I run `wp path` + And save STDOUT as {CONTENT_DIR} + + # Install an out of date from WordPress.org repository + When I run `wp install --version=` + Then STDOUT should contain: + """ + installed successfully + """ When I run `wp status` Then STDOUT should contain: @@ -36,7 +47,54 @@ Feature: Manage WordPress themes and plugins Then the return code should be 1 And STDERR should not be empty + + # Install from local zip file + When I run `wp install {CACHE_DIR}/.zip` + Then STDOUT should contain: + """ + installed successfully. + """ + And the file should exist + + When I run `wp delete ` + Then STDOUT should contain: + """ + Success: Deleted '' . + """ + And the file should not exist + + # Install plugin from remote ZIP file (standard URL with no GET parameters) + When I run `wp install ` + Then STDOUT should contain: + """ + installed successfully. + """ + And the file should exist + + When I run `wp delete ` + Then STDOUT should contain: + """ + Success: Deleted '' . + """ + And the file should not exist + + # Install from remote ZIP file (complex URL with GET parameters) + When I run `wp install '?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` + Then STDOUT should contain: + """ + installed successfully. + """ + And the file should exist + + When I run `wp delete ` + Then STDOUT should contain: + """ + Success: Deleted '' . + """ + And the file should not exist + + Examples: - | type | item | version | - | theme | p2 | 1.0.1 | - | plugin | category-checklist-tree | 1.2 | + | type | type_name | item | version | zip_file | file_to_check | + | theme | Theme | p2 | 1.0.1 | http://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css | + | plugin | Plugin | category-checklist-tree | 1.2 | http://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | From 01fd2847b18b762c7a993fbd6de1d3f701d3bea7 Mon Sep 17 00:00:00 2001 From: James Collins Date: Mon, 8 Jul 2013 17:32:01 +1000 Subject: [PATCH 1985/4858] behat: upgradables comment updates --- features/upgradables.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index fbda07e2dc..7ca5b06ae2 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -48,7 +48,7 @@ Feature: Manage WordPress themes and plugins And STDERR should not be empty - # Install from local zip file + # Install from a local zip file When I run `wp install {CACHE_DIR}/.zip` Then STDOUT should contain: """ @@ -63,7 +63,7 @@ Feature: Manage WordPress themes and plugins """ And the file should not exist - # Install plugin from remote ZIP file (standard URL with no GET parameters) + # Install from a remote zip file (standard URL with no GET parameters) When I run `wp install ` Then STDOUT should contain: """ @@ -78,7 +78,7 @@ Feature: Manage WordPress themes and plugins """ And the file should not exist - # Install from remote ZIP file (complex URL with GET parameters) + # Install from a remote zip file (complex URL with GET parameters) When I run `wp install '?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` Then STDOUT should contain: """ From 0281324c80a7326f53565cfdcca8e8a9b75299af Mon Sep 17 00:00:00 2001 From: James Collins Date: Mon, 8 Jul 2013 17:55:25 +1000 Subject: [PATCH 1986/4858] man-src updates for #581 --- man-src/plugin-install.txt | 6 +++++- man-src/theme-install.txt | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/man-src/plugin-install.txt b/man-src/plugin-install.txt index 90f951721c..f8887421cb 100644 --- a/man-src/plugin-install.txt +++ b/man-src/plugin-install.txt @@ -2,7 +2,7 @@ * : - A plugin slug or the path to a zip file. + A plugin slug, the path to a local zip file, or URL to a remote zip file. * `--version`=: @@ -20,3 +20,7 @@ stable version. wp plugin install bbpress --version=dev wp plugin install ../my-plugin.zip + + wp plugin install http://mydomain.com/my-plugin.zip + + wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef diff --git a/man-src/theme-install.txt b/man-src/theme-install.txt index a7377e6282..3ea74e081d 100644 --- a/man-src/theme-install.txt +++ b/man-src/theme-install.txt @@ -2,7 +2,7 @@ * ``: - A theme slug or the path to a zip file. + A theme slug, the path to a local zip file, or URL to a remote zip file. * `--activate`: @@ -13,3 +13,7 @@ wp theme install twentytwelve --activate wp theme install ../my-theme.zip + + wp theme install http://mydomain.com/my-theme.zip + + wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef \ No newline at end of file From b85e04c8dc7e0564b10df126ef57e84da6da7f07 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 8 Jul 2013 11:06:30 +0300 Subject: [PATCH 1987/4858] add comments to examples for plugin/theme install see #581 --- man-src/plugin-install.txt | 10 ++++++---- man-src/theme-install.txt | 9 +++++---- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/man-src/plugin-install.txt b/man-src/plugin-install.txt index f8887421cb..9561c92ce6 100644 --- a/man-src/plugin-install.txt +++ b/man-src/plugin-install.txt @@ -1,6 +1,6 @@ ## OPTIONS -* : +* : A plugin slug, the path to a local zip file, or URL to a remote zip file. @@ -15,12 +15,14 @@ stable version. ## EXAMPLES - wp plugin install bbpress --version=2.1 --activate + # Install the latest version from wordpress.org and activate + wp plugin install bbpress --activate + # Install the development version from wordpress.org wp plugin install bbpress --version=dev + # Install from a local zip file wp plugin install ../my-plugin.zip - wp plugin install http://mydomain.com/my-plugin.zip - + # Install from a remote zip file wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef diff --git a/man-src/theme-install.txt b/man-src/theme-install.txt index 3ea74e081d..0cf7271e11 100644 --- a/man-src/theme-install.txt +++ b/man-src/theme-install.txt @@ -1,6 +1,6 @@ ## OPTIONS -* ``: +* ``: A theme slug, the path to a local zip file, or URL to a remote zip file. @@ -10,10 +10,11 @@ ## EXAMPLES + # Install the latest version from wordpress.org and activate wp theme install twentytwelve --activate + # Install from a local zip file wp theme install ../my-theme.zip - wp theme install http://mydomain.com/my-theme.zip - - wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef \ No newline at end of file + # Install from a remote zip file + wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef diff --git a/php/commands/plugin.php b/php/commands/plugin.php index c96d85465c..17989e7f1e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -242,7 +242,7 @@ protected function get_item_list() { /** * Install a plugin. * - * @synopsis [--version=] [--activate] + * @synopsis [--version=] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 681d273bef..b5639d25a4 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -157,7 +157,7 @@ protected function get_item_list() { /** * Install a theme. * - * @synopsis [--version=] [--activate] + * @synopsis [--version=] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); From 25a02192559a31c2b461b3c62f9bb1b88365fcd5 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Mon, 8 Jul 2013 18:11:38 +1000 Subject: [PATCH 1988/4858] ternary -> if else --- templates/install-wp-tests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 151c10b3dc..e1f08050c2 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -23,7 +23,11 @@ tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR # portable in-place argument for both GNU sed and Mac OSX sed -[[ $(uname -s) == 'Darwin' ]] && ioption=(-i "") || ioption=(-i) +if [[ $(uname -s) == 'Darwin' ]]; then + ioption=(-i "") +else + ioption=(-i) +fi # generate testing config file cd $WP_TESTS_DIR From 7f546af3c35dd34484b9734b258ccd4b04f549b9 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Mon, 8 Jul 2013 18:15:03 +1000 Subject: [PATCH 1989/4858] remove : --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index e1f08050c2..3f4001ec40 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -8,7 +8,7 @@ fi DB_NAME=$1 DB_USER=$2 DB_PASS=$3 -DB_HOST=${4:-localhost} +DB_HOST=${4-localhost} WP_VERSION=${5-master} set -ex From 359a7084f223e279b7e99fc3b12f61f294be60b9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Mon, 8 Jul 2013 10:44:47 +0100 Subject: [PATCH 1990/4858] Force install Akismet, as it comes with a default WordPress install. --- features/plugin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 5c3e9fb265..49bcc55c7a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -64,7 +64,7 @@ Feature: Manage WordPress plugins Scenario: Install a plugin, activate, then force install an older version of the plugin Given a WP install - When I run `wp plugin install akismet --version=2.5.7` + When I run `wp plugin install akismet --version=2.5.7 --yes` Then STDOUT should not be empty When I run `wp plugin list` From fd265ff5bd3ca5b87ab46bbe4d258d1e519ee8f4 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Mon, 8 Jul 2013 19:48:16 +1000 Subject: [PATCH 1991/4858] ioption fixes --- templates/install-wp-tests.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 3f4001ec40..82cd598ed8 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -24,19 +24,19 @@ svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP # portable in-place argument for both GNU sed and Mac OSX sed if [[ $(uname -s) == 'Darwin' ]]; then - ioption=(-i "") + ioption='-i ""' else - ioption=(-i) + ioption='-i' fi # generate testing config file cd $WP_TESTS_DIR cp wp-tests-config-sample.php wp-tests-config.php -sed "${ioption[@]}" "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php -sed "${ioption[@]}" "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php -sed "${ioption[@]}" "s/yourusernamehere/$DB_USER/" wp-tests-config.php -sed "${ioption[@]}" "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php -sed "${ioption[@]}" "s|localhost|${DB_HOST}|" wp-tests-config.php +sed $ioption "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php +sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php +sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php +sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php +sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php # parse DB_HOST for port or socket references PARTS=(${DB_HOST//\:/ }) From 473c1c8c448ca21324ff6ce4ba5577276ea177e1 Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Mon, 8 Jul 2013 20:32:57 +1000 Subject: [PATCH 1992/4858] fix travis.yml --- templates/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index a91b121be7..de2d819e56 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -12,6 +12,6 @@ env: before_script: - export WP_TESTS_DIR=/tmp/wordpress-tests/ - - bash bin/install-wp-tests.sh wordpress_test root '' $WP_VERSION + - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION script: phpunit From 515a1375f493c8ef489b18dd9fb7debdf7833ebd Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 8 Jul 2013 18:51:58 +0300 Subject: [PATCH 1993/4858] replace --yes with --force --- features/plugin.feature | 4 ++-- features/theme.feature | 2 +- php/class-wp-cli.php | 2 +- php/commands/plugin.php | 5 +++-- php/commands/theme.php | 5 +++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 49bcc55c7a..f48979760a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -64,7 +64,7 @@ Feature: Manage WordPress plugins Scenario: Install a plugin, activate, then force install an older version of the plugin Given a WP install - When I run `wp plugin install akismet --version=2.5.7 --yes` + When I run `wp plugin install akismet --version=2.5.7 --force` Then STDOUT should not be empty When I run `wp plugin list` @@ -75,7 +75,7 @@ Feature: Manage WordPress plugins When I run `wp plugin activate akismet` Then STDOUT should not be empty - When I run `wp plugin install akismet --version=2.5.6 --yes` + When I run `wp plugin install akismet --version=2.5.6 --force` Then STDOUT should not be empty When I run `wp plugin list` diff --git a/features/theme.feature b/features/theme.feature index afc96a97de..a42199f48c 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -61,7 +61,7 @@ Feature: Manage WordPress themes When I run `wp theme activate p2` Then STDOUT should not be empty - When I run `wp theme install p2 --version=1.4.1 --yes` + When I run `wp theme install p2 --version=1.4.1 --force` Then STDOUT should not be empty When I run `wp theme list` diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 784a296223..7d2c9dff4a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -165,7 +165,7 @@ static function error( $message, $label = 'Error' ) { /** * Ask for confirmation before running a destructive operation. */ - static function confirm( $question, $assoc_args ) { + static function confirm( $question, $assoc_args = array() ) { if ( !isset( $assoc_args['yes'] ) ) { echo $question . " [y/n] "; diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 725a0fd9cb..19259de28e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -175,7 +175,8 @@ protected function install_from_repo( $slug, $assoc_args ) { if ( isset( $assoc_args['version'] ) && version_compare( $status['version'], $assoc_args['version'], '!=' ) ) { - WP_CLI::confirm( "A different version is installed. Overwrite it?", $assoc_args ); + if ( !isset( $assoc_args['force'] ) ) + WP_CLI::confirm( "A different version is installed. Overwrite it?" ); list( $file, $name ) = $this->parse_name( array( $api->slug ) ); $this->_delete( $file ); @@ -252,7 +253,7 @@ protected function get_item_list() { /** * Install a plugin. * - * @synopsis [--version=] [--activate] [--yes] + * @synopsis [--version=] [--force] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); diff --git a/php/commands/theme.php b/php/commands/theme.php index d6e82df7b0..de17fb0f48 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -121,7 +121,8 @@ protected function install_from_repo( $slug, $assoc_args ) { } else if ( $theme_obj->exists() && version_compare( $assoc_args['version'], $theme_obj->version, '!=' ) ) { // Theme is installed, but we want a different version - WP_CLI::confirm( "A different version is installed. Overwrite it?", $assoc_args ); + if ( !isset( $assoc_args['force'] ) ) + WP_CLI::confirm( "A different version is installed. Overwrite it?" ); WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); delete_theme( $theme_obj->stylesheet ); @@ -159,7 +160,7 @@ protected function get_item_list() { /** * Install a theme. * - * @synopsis [--version=] [--activate] [--yes] + * @synopsis [--version=] [--force] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); From 223ab887f3ff923fc76320d8daf96a0bd0d0c17c Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 8 Jul 2013 18:56:14 +0300 Subject: [PATCH 1994/4858] document --force flag --- man-src/plugin-install.txt | 5 +++++ man-src/theme-install.txt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/man-src/plugin-install.txt b/man-src/plugin-install.txt index 9561c92ce6..e896cca2fe 100644 --- a/man-src/plugin-install.txt +++ b/man-src/plugin-install.txt @@ -9,6 +9,11 @@ If set, get that particular version from wordpress.org, instead of the stable version. +* `--force`: + + If set, the command will overwrite any installed version of the plugin, without prompting +for confirmation. + * `--activate`: If set, the plugin will be activated immediately after install. diff --git a/man-src/theme-install.txt b/man-src/theme-install.txt index 0cf7271e11..b8eced70c7 100644 --- a/man-src/theme-install.txt +++ b/man-src/theme-install.txt @@ -4,6 +4,11 @@ A theme slug, the path to a local zip file, or URL to a remote zip file. +* `--force`: + + If set, the command will overwrite any installed version of the theme, without prompting +for confirmation. + * `--activate`: If set, the theme will be activated immediately after install. From aa7537846abcdcf46a44bb28f3b8e8a54db6cf43 Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 8 Jul 2013 20:36:13 +0300 Subject: [PATCH 1995/4858] make parse_name a private function, since it's not used in CommandWithUpgrade also, each implementation returns different things --- php/WP_CLI/CommandWithUpgrade.php | 2 -- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 1b3434842c..74413303d0 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -9,8 +9,6 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $upgrade_refresh; protected $upgrade_transient; - abstract protected function parse_name( $args ); - abstract protected function get_item_list(); abstract protected function get_all_items(); diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 17989e7f1e..e432b46995 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -330,7 +330,7 @@ protected function get_details( $file ) { * @param array $args * @return array */ - protected function parse_name( $args ) { + private function parse_name( $args ) { $name = $args[0]; $plugins = get_plugins( '/' . $name ); diff --git a/php/commands/theme.php b/php/commands/theme.php index b5639d25a4..cabca9de0f 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -216,7 +216,7 @@ function _list( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); } - protected function parse_name( $args ) { + private function parse_name( $args ) { $name = $args[0]; $theme = wp_get_theme( $name ); From c54acb14e04379bb2d40a10904d2db8a9bc958eb Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 8 Jul 2013 21:07:10 +0300 Subject: [PATCH 1996/4858] plugin: parse_name() only needs the first arg and only needs to return the filename. It accepted the whole arguments initially because it used to check if the slug was missing. This is handled by the synopsis validator now, beforehand. --- php/commands/plugin.php | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e432b46995..8c5895fac1 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -36,7 +36,8 @@ function status( $args ) { } protected function status_single( $args ) { - list( $file, $name ) = $this->parse_name( $args ); + $name = $args[0]; + $file = $this->parse_name( $name ); $details = $this->get_details( $file ); @@ -77,7 +78,8 @@ protected function get_all_items() { * @synopsis [--network] */ function activate( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args ); + $name = $args[0]; + $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -96,7 +98,8 @@ function activate( $args, $assoc_args = array() ) { * @synopsis [--network] */ function deactivate( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args ); + $name = $args[0]; + $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -115,7 +118,8 @@ function deactivate( $args, $assoc_args = array() ) { * @synopsis [--network] */ function toggle( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args ); + $name = $args[0]; + $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -135,7 +139,7 @@ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); if ( !empty( $args ) ) { - list( $file, $name ) = $this->parse_name( $args ); + $file = $this->parse_name( $args[0] ); $path .= '/' . $file; if ( isset( $assoc_args['dir'] ) ) @@ -190,7 +194,8 @@ protected function install_from_repo( $slug, $assoc_args ) { * @synopsis [--version=] */ function update( $args, $assoc_args ) { - list( $basename ) = $this->parse_name( $args ); + $name = $args[0]; + $basename = $this->parse_name( $name ); if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { $this->_delete( $basename, false ); @@ -254,7 +259,8 @@ function install( $args, $assoc_args ) { * @synopsis [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args ); + $name = $args[0]; + $file = $this->parse_name( $name ); if ( is_plugin_active( $file ) ) { WP_CLI::error( 'The plugin is active.' ); @@ -276,7 +282,8 @@ function uninstall( $args, $assoc_args = array() ) { * @synopsis */ function delete( $args, $assoc_args = array() ) { - list( $file, $name ) = $this->parse_name( $args ); + $name = $args[0]; + $file = $this->parse_name( $name ); if ( $this->_delete( $file ) ) { WP_CLI::success( sprintf( "Deleted '%s' plugin.", $name ) ); @@ -325,14 +332,12 @@ protected function get_details( $file ) { } /** - * Parse the name of a plugin to a filename, check if it exists + * Parse the name of a plugin to a filename; check if it exists. * - * @param array $args - * @return array + * @param string name + * @return string */ - private function parse_name( $args ) { - $name = $args[0]; - + private function parse_name( $name ) { $plugins = get_plugins( '/' . $name ); if ( !empty( $plugins ) ) { @@ -349,9 +354,12 @@ private function parse_name( $args ) { } } - return array( $file, $name ); + return $file; } + /** + * Converts a plugin basename back into a friendly slug. + */ private function get_name( $file ) { if ( false === strpos( $file, '/' ) ) $name = basename( $file, '.php' ); From c83739c8c24e3eb7fd668540e18b3b0f1f2b56db Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 8 Jul 2013 21:23:35 +0300 Subject: [PATCH 1997/4858] theme: parse_name() only needs the first argument --- php/commands/theme.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index cabca9de0f..3ac4a59a57 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -29,7 +29,7 @@ function status( $args ) { } protected function status_single( $args ) { - $theme = $this->parse_name( $args ); + $theme = $this->parse_name( $args[0] ); $status = $this->format_status( $this->get_status( $theme ), 'long' ); @@ -60,7 +60,7 @@ protected function get_status( $theme ) { * @synopsis */ public function activate( $args = array() ) { - $theme = $this->parse_name( $args ); + $theme = $this->parse_name( $args[0] ); switch_theme( $theme->get_template(), $theme->get_stylesheet() ); @@ -86,7 +86,7 @@ function path( $args, $assoc_args ) { if ( empty( $args ) ) { $path = WP_CONTENT_DIR . '/themes'; } else { - $theme = $this->parse_name( $args ); + $theme = $this->parse_name( $args[0] ); $path = $theme->get_stylesheet_directory(); @@ -169,7 +169,7 @@ function install( $args, $assoc_args ) { * @synopsis [--version=] */ function update( $args, $assoc_args ) { - $theme = $this->parse_name( $args ); + $theme = $this->parse_name( $args[0] ); parent::_update( $theme->get_stylesheet() ); } @@ -190,7 +190,7 @@ function update_all( $args, $assoc_args ) { * @synopsis */ function delete( $args ) { - $theme = $this->parse_name( $args ); + $theme = $this->parse_name( $args[0] ); $theme_slug = $theme->get_stylesheet(); if ( $this->is_active_theme( $theme ) ) { @@ -216,9 +216,13 @@ function _list( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); } - private function parse_name( $args ) { - $name = $args[0]; - + /** + * Parse the name of a plugin to a filename; check if it exists. + * + * @param string name + * @return object + */ + private function parse_name( $name ) { $theme = wp_get_theme( $name ); if ( !$theme->exists() ) { From f30d795bb4c69cbdaac16e89618b4a407c9a23b2 Mon Sep 17 00:00:00 2001 From: scribu Date: Tue, 9 Jul 2013 01:19:52 +0300 Subject: [PATCH 1998/4858] leverage 'clear_destination' parameter from WP_Upgrader --- php/WP_CLI/CommandWithUpgrade.php | 18 +++++++++--------- php/WP_CLI/DestructivePluginUpgrader.php | 18 ++++++++++++++++++ php/WP_CLI/DestructiveThemeUpgrader.php | 18 ++++++++++++++++++ php/commands/plugin.php | 18 +++++++++++------- php/commands/theme.php | 23 +++++++++++++---------- 5 files changed, 69 insertions(+), 26 deletions(-) create mode 100644 php/WP_CLI/DestructivePluginUpgrader.php create mode 100644 php/WP_CLI/DestructiveThemeUpgrader.php diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 74413303d0..aaac62ed9a 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -5,10 +5,11 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $item_type; - protected $upgrader; protected $upgrade_refresh; protected $upgrade_transient; + abstract protected function get_upgrader_class( $force ); + abstract protected function get_item_list(); abstract protected function get_all_items(); @@ -115,7 +116,7 @@ function install( $args, $assoc_args ) { if ( ! empty( $local_or_remote_zip_file ) ) { // Install from local or remote zip file - $file_upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); + $file_upgrader = $this->get_upgrader( $assoc_args ); if ( $file_upgrader->install( $local_or_remote_zip_file ) ) { $slug = $file_upgrader->result['destination_name']; @@ -168,10 +169,9 @@ protected static function alter_api_response( $response, $version ) { } } - protected function _update( $item ) { - call_user_func( $this->upgrade_refresh ); - - \WP_CLI\Utils\get_upgrader( $this->upgrader )->upgrade( $item ); + protected function get_upgrader( $assoc_args ) { + $upgrader_class = $this->get_upgrader_class( isset( $assoc_args['force'] ) ); + return \WP_CLI\Utils\get_upgrader( $upgrader_class ); } function update_all( $args, $assoc_args ) { @@ -196,13 +196,13 @@ function update_all( $args, $assoc_args ) { return; } - $upgrader = \WP_CLI\Utils\get_upgrader( $this->upgrader ); - $result = array(); // Only attempt to update if there is something to update - if ( !empty( $items_to_update ) ) + if ( !empty( $items_to_update ) ) { + $upgrader = $this->get_upgrader( $assoc_args ); $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); + } // Let the user know the results. $num_to_update = count( $items_to_update ); diff --git a/php/WP_CLI/DestructivePluginUpgrader.php b/php/WP_CLI/DestructivePluginUpgrader.php new file mode 100644 index 0000000000..7fc0d16dbd --- /dev/null +++ b/php/WP_CLI/DestructivePluginUpgrader.php @@ -0,0 +1,18 @@ +_delete( $this->parse_name( $api->slug ) ); + $assoc_args['force'] = true; + } } // fallthrough - need to install the plugin nows case 'install': - $upgrader = WP_CLI\Utils\get_upgrader( $this->upgrader ); - $result = $upgrader->install( $api->download_link ); + $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); if ( $result && isset( $assoc_args['activate'] ) ) { WP_CLI::log( "Activating '$slug'..." ); @@ -214,7 +216,9 @@ function update( $args, $assoc_args ) { $was_active = is_plugin_active( $basename ); $was_network_active = is_plugin_active_for_network( $basename ); - parent::_update( $basename ); + call_user_func( $this->upgrade_refresh ); + + $this->get_upgrader( $assoc_args )->upgrade( $basename ); if ( $was_active ) { $new_args = array( $args[0] ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 5fb85eda1c..b419b35ad9 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -8,7 +8,6 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { protected $item_type = 'theme'; - protected $upgrader = 'Theme_Upgrader'; protected $upgrade_refresh = 'wp_update_themes'; protected $upgrade_transient = 'update_themes'; @@ -19,6 +18,10 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { 'version' ); + protected function get_upgrader_class( $force ) { + return $force ? '\\WP_CLI\\DestructiveThemeUpgrader' : 'Theme_Upgrader'; + } + /** * See the status of one or all themes. * @@ -121,17 +124,15 @@ protected function install_from_repo( $slug, $assoc_args ) { } else if ( $theme_obj->exists() && version_compare( $assoc_args['version'], $theme_obj->version, '!=' ) ) { // Theme is installed, but we want a different version - if ( !isset( $assoc_args['force'] ) ) + if ( !isset( $assoc_args['force'] ) ) { WP_CLI::confirm( "A different version is installed. Overwrite it?" ); - - WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - delete_theme( $theme_obj->stylesheet ); - $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); - } else if ( ! $theme_obj->exists() ) { - WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - $result = WP_CLI\Utils\get_upgrader( $this->upgrader )->install( $api->download_link ); + $assoc_args['force'] = true; + } } + WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); + // Finally, activate theme if requested. if ( $result && isset( $assoc_args['activate'] ) ) { WP_CLI::log( "Activating '$slug'..." ); @@ -174,7 +175,9 @@ function install( $args, $assoc_args ) { function update( $args, $assoc_args ) { $theme = $this->parse_name( $args[0] ); - parent::_update( $theme->get_stylesheet() ); + call_user_func( $this->upgrade_refresh ); + + $this->get_upgrader( $assoc_args )->upgrade( $theme->get_stylesheet() ); } /** From 54a92091ff573c6cf51d7760d8f11bf2efee8a3b Mon Sep 17 00:00:00 2001 From: scribu Date: Wed, 10 Jul 2013 14:15:29 +0300 Subject: [PATCH 1999/4858] simplify logic for theme and plugin installs --- php/commands/plugin.php | 36 +++++++++--------------------------- php/commands/theme.php | 13 ++----------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index a17fa70cc4..630dbee3ef 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -168,35 +168,17 @@ protected function install_from_repo( $slug, $assoc_args ) { $status = install_plugin_install_status( $api ); + if ( !isset( $assoc_args['force'] ) && 'install' != $status['status'] ) { + // We know this will fail, so avoid a needless download of the package. + WP_CLI::error( 'Plugin already installed.' ); + } + WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); - switch ( $status['status'] ) { - - case 'latest_installed': - WP_CLI::error( 'Latest version already installed.' ); - break; - - // Newer installed plugin, but we might want the older version - case 'newer_installed': - case 'update_available': - if ( isset( $assoc_args['version'] ) - && version_compare( $status['version'], $assoc_args['version'], '!=' ) ) { - - if ( !isset( $assoc_args['force'] ) ) { - WP_CLI::confirm( "A different version is installed. Overwrite it?" ); - $assoc_args['force'] = true; - } - } - // fallthrough - need to install the plugin nows - - case 'install': - $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); - - if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } - break; + if ( $result && isset( $assoc_args['activate'] ) ) { + WP_CLI::log( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); } } diff --git a/php/commands/theme.php b/php/commands/theme.php index b419b35ad9..843bf8d73f 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -116,18 +116,9 @@ protected function install_from_repo( $slug, $assoc_args ) { self::alter_api_response( $api, $assoc_args['version'] ); } - $theme_obj = wp_get_theme( $slug ); - if ( $theme_obj->exists() - && empty( $assoc_args['version'] ) ) { - // Theme is already installed to the correct version. + if ( !isset( $assoc_args['force'] ) && wp_get_theme( $slug )->exists() ) { + // We know this will fail, so avoid a needless download of the package. WP_CLI::error( 'Theme already installed.' ); - } else if ( $theme_obj->exists() - && version_compare( $assoc_args['version'], $theme_obj->version, '!=' ) ) { - // Theme is installed, but we want a different version - if ( !isset( $assoc_args['force'] ) ) { - WP_CLI::confirm( "A different version is installed. Overwrite it?" ); - $assoc_args['force'] = true; - } } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); From 83b03bfd3cd1f6200889246809cc95eed05bb25f Mon Sep 17 00:00:00 2001 From: jmslbam Date: Thu, 11 Jul 2013 20:54:56 +0200 Subject: [PATCH 2000/4858] Fix notices no index featured_image --- php/commands/media.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 3657d31912..0f6db05b38 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -123,13 +123,13 @@ function import( $args, $assoc_args = array() ) { update_post_meta( $success, '_wp_attachment_image_alt', $assoc_args['alt'] ); // Set as featured image, if --post_id and --featured_image are set - if ( !is_wp_error( $success ) && $assoc_args['post_id'] && $assoc_args['featured_image'] ) + if ( !is_wp_error( $success ) && $assoc_args['post_id'] && isset($assoc_args['featured_image']) ) update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); $attachment_success_text = ''; if ( $assoc_args['post_id'] ) { $attachment_success_text = " and attached to post {$assoc_args['post_id']}"; - if ( $assoc_args['featured_image'] ) + if ( isset($assoc_args['featured_image']) ) $attachment_success_text .= ' as featured image'; } From 935a4bdca3f88c234f63c186daf5beff01757c41 Mon Sep 17 00:00:00 2001 From: scribu Date: Thu, 11 Jul 2013 23:26:53 +0300 Subject: [PATCH 2001/4858] code formatting fixes in media.php --- php/commands/media.php | 57 ++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 0f6db05b38..4ffda25798 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -50,7 +50,10 @@ function regenerate( $args, $assoc_args = array() ) { $this->_process_regeneration( $id ); } - WP_CLI::success( sprintf( 'Finished regenerating %1$s.', ngettext('the image', 'all images', $count) ) ); + WP_CLI::success( sprintf( + 'Finished regenerating %1$s.', + ngettext('the image', 'all images', $count) + ) ); } /** @@ -59,17 +62,13 @@ function regenerate( $args, $assoc_args = array() ) { * @synopsis ... [--post_id=] [--title=] [--caption=<caption>] [--alt=<text>] [--desc=<description>] [--featured_image] */ function import( $args, $assoc_args = array() ) { - - $assoc_args = wp_parse_args( - $assoc_args, - array( - 'post_id' => false, - 'title' => null, - 'caption' => null, - 'alt' => null, - 'desc' => null - ) - ); + $assoc_args = wp_parse_args( $assoc_args, array( + 'post_id' => false, + 'title' => null, + 'caption' => null, + 'alt' => null, + 'desc' => null + ) ); if ( !get_post( $assoc_args['post_id'] ) ) { WP_CLI::warning( "Invalid --post_id" ); @@ -77,13 +76,11 @@ function import( $args, $assoc_args = array() ) { } foreach ( $args as $file ) { - $is_file_remote = parse_url( $file, PHP_URL_SCHEME ); $orig_filename = $file; if ( empty( $is_file_remote ) ) { - // File appears to be a local file; make a copy first to work with - + // File appears to be local; make a working copy $tempfile = wp_tempnam( $file ); if ( ! $tempfile ) WP_CLI::error( 'Could not create temporary file.' ); @@ -91,10 +88,8 @@ function import( $args, $assoc_args = array() ) { copy( $file, $tempfile ); } else { - // File appear to be a remote file; download as temp file - + // File appears to be remote; download as temp file $tempfile = download_url( $file ); - } // Necessary because temp filename will probably have an extension like @@ -133,22 +128,18 @@ function import( $args, $assoc_args = array() ) { $attachment_success_text .= ' as featured image'; } - if ( is_wp_error( $success ) ) - WP_CLI::error( - sprintf( - 'Unable to import file %s. Reason: %s', - $orig_filename, implode( ', ', $success->get_error_messages() ) - ) - ); - else - WP_CLI::success( - sprintf( - 'Imported file %s as attachment ID %d%s.', - $orig_filename, $success, $attachment_success_text - ) - ); + if ( is_wp_error( $success ) ) { + WP_CLI::error( sprintf( + 'Unable to import file %s. Reason: %s', + $orig_filename, implode( ', ', $success->get_error_messages() ) + ) ); + } else { + WP_CLI::success( sprintf( + 'Imported file %s as attachment ID %d%s.', + $orig_filename, $success, $attachment_success_text + ) ); + } } - } From 44f246e4fd636616ce0aa25d6e87eb0613bf2366 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Jul 2013 00:04:47 +0300 Subject: [PATCH 2002/4858] media: don't call get_post() if --post_id isn't even passed --- php/commands/media.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 4ffda25798..0726f6a8ff 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -63,15 +63,18 @@ function regenerate( $args, $assoc_args = array() ) { */ function import( $args, $assoc_args = array() ) { $assoc_args = wp_parse_args( $assoc_args, array( - 'post_id' => false, 'title' => null, 'caption' => null, 'alt' => null, 'desc' => null ) ); - if ( !get_post( $assoc_args['post_id'] ) ) { - WP_CLI::warning( "Invalid --post_id" ); + if ( isset( $assoc_args['post_id'] ) ) { + if ( !get_post( $assoc_args['post_id'] ) ) { + WP_CLI::warning( "Invalid --post_id" ); + $assoc_args['post_id'] = false; + } + } else { $assoc_args['post_id'] = false; } From ca6e32c8ddfebb44392da996adee02620660c320 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 11 Jul 2013 23:51:12 +0300 Subject: [PATCH 2003/4858] media: make the temp file have the proper extension from the start --- features/media.feature | 2 +- php/commands/media.php | 39 +++++++++++++++++++++------------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/features/media.feature b/features/media.feature index e09e2b1735..74752d2771 100644 --- a/features/media.feature +++ b/features/media.feature @@ -27,7 +27,7 @@ Feature: Manage WordPress attachments When I try `wp media import gobbledygook.png` Then STDERR should contain: """ - Error: Unable to import file gobbledygook.png. Reason: File is empty. + Unable to import file gobbledygook.png. Reason: File doesn't exist. """ @images diff --git a/php/commands/media.php b/php/commands/media.php index 0726f6a8ff..22cae68c9f 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -83,28 +83,17 @@ function import( $args, $assoc_args = array() ) { $orig_filename = $file; if ( empty( $is_file_remote ) ) { - // File appears to be local; make a working copy - $tempfile = wp_tempnam( $file ); - if ( ! $tempfile ) - WP_CLI::error( 'Could not create temporary file.' ); - - copy( $file, $tempfile ); - + if ( !file_exists( $file ) ) { + WP_CLI::warning( "Unable to import file $file. Reason: File doesn't exist." ); + break; + } + $tempfile = $this->_make_copy( $file ); } else { - // File appears to be remote; download as temp file $tempfile = download_url( $file ); } - // Necessary because temp filename will probably have an extension like - // .tmp, which is not in the list of permitted upload extensions - // and won't be recognized with the correct mime type - $extension = pathinfo( $file, PATHINFO_EXTENSION ); - $tempfile_extension = pathinfo( $tempfile, PATHINFO_EXTENSION ); - $file = preg_replace( "/$tempfile_extension$/", $extension, $tempfile ); - rename( $tempfile, $file ); - $file_array = array( - 'tmp_name' => $file, + 'tmp_name' => $tempfile, 'name' => basename( $file ) ); @@ -114,6 +103,7 @@ function import( $args, $assoc_args = array() ) { 'post_content' => $assoc_args['desc'] ); + // Deletes the temporary file. $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); // Set alt text @@ -132,7 +122,7 @@ function import( $args, $assoc_args = array() ) { } if ( is_wp_error( $success ) ) { - WP_CLI::error( sprintf( + WP_CLI::warning( sprintf( 'Unable to import file %s. Reason: %s', $orig_filename, implode( ', ', $success->get_error_messages() ) ) ); @@ -145,6 +135,19 @@ function import( $args, $assoc_args = array() ) { } } + // wp_tempnam() inexplicably forces a .tmp extension, which spoils MIME type detection + private function _make_copy( $path ) { + $dir = get_temp_dir(); + $filename = basename( $path ); + if ( empty( $filename ) ) + $filename = time(); + + $filename = $dir . wp_unique_filename( $dir, $filename ); + if ( !copy( $path, $filename ) ) + WP_CLI::error( "Could not create temporary file for $path" ); + + return $filename; + } private function _process_regeneration( $id ) { $image = get_post( $id ); From bbf481ad77886b24ebcc6f77ee8c6989172eb657 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Jul 2013 01:19:38 +0300 Subject: [PATCH 2004/4858] rename _download() to _read() to make it clearer that it doesn't deal with binary data --- php/commands/core.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 59964c0822..42419f649f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -46,14 +46,14 @@ public function download( $args, $assoc_args ) { WP_CLI::success( 'WordPress downloaded.' ); } - private static function _download( $url ) { + private static function _read( $url ) { exec( 'curl -s ' . escapeshellarg( $url ), $lines, $r ); if ( $r ) exit( $r ); return implode( "\n", $lines ); } private function get_download_offer( $locale ) { - $out = unserialize( self::_download( + $out = unserialize( self::_read( 'https://api.wordpress.org/core/version-check/1.6/?locale=' . $locale ) ); return $out['offers'][0]; @@ -101,7 +101,7 @@ public function config( $_, $assoc_args ) { } // TODO: adapt more resilient code from wp-admin/setup-config.php - $assoc_args['keys-and-salts'] = self::_download( + $assoc_args['keys-and-salts'] = self::_read( 'https://api.wordpress.org/secret-key/1.1/salt/' ); $out = Utils\mustache_render( 'wp-config.mustache', $assoc_args ); From 1d0ca4b0f09ee7196771e797e9ab77c5e6ca590b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Jun 2013 14:19:38 +0300 Subject: [PATCH 2005/4858] behat: make run_check() check STDERR --- features/bootstrap/Process.php | 2 +- features/flags.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 792277d9cf..992428a0cf 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -51,7 +51,7 @@ public function run( $subdir = '' ) { public function run_check( $subdir = '' ) { $r = $this->run( $subdir ); - if ( $r->return_code ) { + if ( $r->return_code || !empty( $r->STDERR ) ) { throw new \RuntimeException( sprintf( "%s: %s\ncwd: %s", $r->command, $r->STDERR, $r->cwd ) ); } diff --git a/features/flags.feature b/features/flags.feature index 8cb7107fca..ee07a67c70 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -28,7 +28,7 @@ Feature: Global flags CONST_WITHOUT_QUOTES """ - When I run `wp eval 'echo CONST_WITHOUT_QUOTES;' --debug` + When I try `wp eval 'echo CONST_WITHOUT_QUOTES;' --debug` Then the return code should be 0 And STDOUT should be: """ From 15910b0e738f820e71c1ab5f5076a05cba9eaf91 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Jul 2013 02:56:53 +0300 Subject: [PATCH 2006/4858] behat: no-op wp_mail() --- features/bootstrap/FeatureContext.php | 4 ++++ features/extra/no-mail.php | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 features/extra/no-mail.php diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 8c4dc9fadb..b60c007b1a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -162,6 +162,10 @@ public function download_wp( $subdir = '' ) { if ( $subdir ) mkdir( $dest_dir ); Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ) )->run_check(); + + // disable emailing + mkdir( $dest_dir . '/wp-content/mu-plugins' ); + copy( __DIR__ . '/../extra/no-mail.php', $dest_dir . '/wp-content/mu-plugins/no-mail.php' ); } public function install_wp( $subdir = '' ) { diff --git a/features/extra/no-mail.php b/features/extra/no-mail.php new file mode 100644 index 0000000000..ba222ad595 --- /dev/null +++ b/features/extra/no-mail.php @@ -0,0 +1,6 @@ +<?php + +function wp_mail() { + // do nothing +} + From 6804cf8a0fdefbd463238dca0dbc2eafd133e3b3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Jun 2013 16:36:39 +0300 Subject: [PATCH 2007/4858] behat: fix `user generate` test --- features/user.feature | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/features/user.feature b/features/user.feature index 137ee89366..f8f3b61362 100644 --- a/features/user.feature +++ b/features/user.feature @@ -28,9 +28,7 @@ Feature: Manage WordPress users Then STDOUT should be empty When I run `wp user generate --count=10` - Then STDOUT should not be empty - - When I run `wp user list --format=count` + And I run `wp user list --format=count` Then STDOUT should be: """ 10 From 88af0ed99071606c79257973512cd9e4e2563104 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 21 Jun 2013 16:02:24 +0300 Subject: [PATCH 2008/4858] don't show progress bar if not in a TTY this fixes 'tput: No value for $TERM and no -T specified' error --- features/import.feature | 9 ++------- php/WP_CLI/NoOp.php | 15 +++++++++++++++ php/commands/post.php | 2 +- php/commands/user.php | 2 +- php/utils.php | 7 +++++++ 5 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 php/WP_CLI/NoOp.php diff --git a/features/import.feature b/features/import.feature index a10af31846..e90d4c57b7 100644 --- a/features/import.feature +++ b/features/import.feature @@ -2,13 +2,8 @@ Feature: Import content. Scenario: Basic export then import Given a WP install - - When I run `wp post generate --post_type=post --count=3` - Then STDOUT should not be empty - - When I run `wp post generate --post_type=page --count=2` - Then STDOUT should not be empty - + And I run `wp post generate --post_type=post --count=3` + And I run `wp post generate --post_type=page --count=2` When I run `wp post list --post_type=any --format=count` Then STDOUT should be: """ diff --git a/php/WP_CLI/NoOp.php b/php/WP_CLI/NoOp.php new file mode 100644 index 0000000000..9334aff22e --- /dev/null +++ b/php/WP_CLI/NoOp.php @@ -0,0 +1,15 @@ +<?php + +namespace WP_CLI; + +final class NoOp { + + function __set( $key, $value ) { + // do nothing + } + + function __call( $method, $args ) { + // do nothing + } +} + diff --git a/php/commands/post.php b/php/commands/post.php index 438f86ac1a..d378366036 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -243,7 +243,7 @@ public function generate( $args, $assoc_args ) { $limit = $count + $total; - $notify = new \cli\progress\Bar( 'Generating posts', $count ); + $notify = \WP_CLI\Utils\make_progress_bar( 'Generating posts', $count ); $current_depth = 1; $current_parent = 0; diff --git a/php/commands/user.php b/php/commands/user.php index 3533ec800d..59dccb4efe 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -183,7 +183,7 @@ public function generate( $args, $assoc_args ) { $limit = $count + $total; - $notify = new \cli\progress\Bar( 'Generating users', $count ); + $notify = \WP_CLI\Utils\make_progress_bar( 'Generating users', $count ); for ( $i = $total; $i < $limit; $i++ ) { $login = sprintf( 'user_%d_%d', $blog_id, $i ); diff --git a/php/utils.php b/php/utils.php index 278cf4cf7b..8b8c463fc7 100644 --- a/php/utils.php +++ b/php/utils.php @@ -407,3 +407,10 @@ function mustache_render( $template_name, $data ) { return $m->render( $template, $data ); } +function make_progress_bar( $message, $count ) { + if ( \cli\Shell::isPiped() ) + return new \WP_CLI\NoOp; + + return new \cli\progress\Bar( $message, $count ); +} + From d1c0f1fe88cdf44b878652351c316d70f02473d8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Jul 2013 01:24:32 +0300 Subject: [PATCH 2009/4858] suppress curl download meter if not running interactively --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 42419f649f..1efda9f088 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -38,7 +38,8 @@ public function download( $args, $assoc_args ) { WP_CLI::log( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - $silent = WP_CLI::get_config('quiet') ? '--silent ' : ''; + $silent = WP_CLI::get_config('quiet') || \cli\Shell::isPiped() ? + '--silent ' : ''; $cmd = "curl -f $silent %s | tar xz --strip-components=1 --directory=%s"; WP_CLI::launch( Utils\esc_cmd( $cmd, $download_url, ABSPATH ) ); From 9e45d824866a547d7d629cb9af6c57cf2b207b05 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Jul 2013 03:50:59 +0300 Subject: [PATCH 2010/4858] behat: hide export warnings --- features/export.feature | 8 ++++++-- features/import.feature | 7 ++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/features/export.feature b/features/export.feature index 1194696f92..31ea124037 100644 --- a/features/export.feature +++ b/features/export.feature @@ -3,5 +3,9 @@ Feature: Export content. Scenario: Basic export Given a WP install - When I run `wp export` - Then STDOUT should not be empty + When I try `wp export` + Then the return code should be 0 + And STDOUT should contain: + """ + All done with export + """ diff --git a/features/import.feature b/features/import.feature index e90d4c57b7..5a4c940cab 100644 --- a/features/import.feature +++ b/features/import.feature @@ -10,11 +10,8 @@ Feature: Import content. 7 """ - When I run `wp export` - Then STDOUT should contain: - """ - All done with export - """ + When I try `wp export` + Then the return code should be 0 And save STDOUT 'Writing to file %s' as {EXPORT_FILE} When I run `wp site empty --yes` From 864da43168f9834bc2f2ba8ad09e7e40303a66e3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 12 Jul 2013 18:42:21 +0300 Subject: [PATCH 2011/4858] behat: check STDERR when running `wp export` --- features/export.feature | 5 ++--- features/import.feature | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/features/export.feature b/features/export.feature index 31ea124037..f0bcfa85c0 100644 --- a/features/export.feature +++ b/features/export.feature @@ -3,9 +3,8 @@ Feature: Export content. Scenario: Basic export Given a WP install - When I try `wp export` - Then the return code should be 0 - And STDOUT should contain: + When I run `wp export` + Then STDOUT should contain: """ All done with export """ diff --git a/features/import.feature b/features/import.feature index 5a4c940cab..b9faed2641 100644 --- a/features/import.feature +++ b/features/import.feature @@ -10,8 +10,7 @@ Feature: Import content. 7 """ - When I try `wp export` - Then the return code should be 0 + When I run `wp export` And save STDOUT 'Writing to file %s' as {EXPORT_FILE} When I run `wp site empty --yes` From 4aa1b85cf80c6a3e443fc0aca013129dcb94920c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 13 Jul 2013 18:54:56 +0300 Subject: [PATCH 2012/4858] add missing docs for `user add-role`; improve docs for `user set-role` --- man-src/user-add-role.txt | 14 ++++++++++++++ man-src/user-set-role.txt | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 man-src/user-add-role.txt diff --git a/man-src/user-add-role.txt b/man-src/user-add-role.txt new file mode 100644 index 0000000000..b6e5ab4826 --- /dev/null +++ b/man-src/user-add-role.txt @@ -0,0 +1,14 @@ +## OPTIONS + +* `<user>`: + + User ID or user login. + +* `<role>`: + + Add the specified role to the user. + +## EXAMPLES + + wp user set-role bob author + wp user set-role 12 author diff --git a/man-src/user-set-role.txt b/man-src/user-set-role.txt index 84190293b6..4817f740d0 100644 --- a/man-src/user-set-role.txt +++ b/man-src/user-set-role.txt @@ -6,7 +6,8 @@ * `[<role>]`: - Add the user with the specified role. Defaults to blog default. + Make the user have the specified role. If not passed, the default role is +used. ## EXAMPLES From de5814f005f5e69c41a8fac09cb02c1a7a94ca7e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 13 Jul 2013 19:12:00 -0700 Subject: [PATCH 2013/4858] Update to accommodate scenario when multiple users are passed See https://github.com/wp-cli/wp-cli/pull/555#discussion_r5179695 --- php/commands/user.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index d4b23b3f9e..102e179997 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -66,7 +66,9 @@ public function delete( $args, $assoc_args ) { 'reassign' => null ) ); - $args[0] = self::get_user_from_first_arg( $args[0] )->ID; + foreach( $args as $key => $arg ) { + $args[$key] = self::get_user_from_first_arg( $arg )->ID; + } parent::delete( $args, $assoc_args ); } @@ -150,7 +152,9 @@ protected function _create( $params ) { */ public function update( $args, $assoc_args ) { - $args[0] = self::get_user_from_first_arg( $args[0] )->ID; + foreach( $args as $key => $arg ) { + $args[$key] = self::get_user_from_first_arg( $arg )->ID; + } parent::update( $args, $assoc_args, 'user' ); } From 8d9c95f6662a22abe13bb95f550b21f389745d83 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 13 Jul 2013 19:15:37 -0700 Subject: [PATCH 2014/4858] Update "Generating Users" scenario to accommodate deleting multiple users in one go. --- features/user.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/user.feature b/features/user.feature index 137ee89366..c2d4a51d2e 100644 --- a/features/user.feature +++ b/features/user.feature @@ -19,7 +19,7 @@ Feature: Manage WordPress users When I run `wp user delete {USER_ID}` Then STDOUT should not be empty - Scenario: Generating users + Scenario: Generating and deleting users Given a WP install # Delete all users @@ -36,6 +36,10 @@ Feature: Manage WordPress users 10 """ + When I run `wp user delete $(wp user list --format=ids)` + And I run `wp user list --format=ids` + Then STDOUT should be empty + Scenario: Importing users from a CSV file Given a WP install And a users.csv file: From ed03bb4c5c100bd2a015782136b214fb82db7c33 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 13:50:33 +0300 Subject: [PATCH 2015/4858] rename get_user_from_first_arg() to get_user() --- php/commands/user.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 102e179997..880565a446 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -67,7 +67,7 @@ public function delete( $args, $assoc_args ) { ) ); foreach( $args as $key => $arg ) { - $args[$key] = self::get_user_from_first_arg( $arg )->ID; + $args[$key] = self::get_user( $arg )->ID; } parent::delete( $args, $assoc_args ); } @@ -153,7 +153,7 @@ protected function _create( $params ) { public function update( $args, $assoc_args ) { foreach( $args as $key => $arg ) { - $args[$key] = self::get_user_from_first_arg( $arg )->ID; + $args[$key] = self::get_user( $arg )->ID; } parent::update( $args, $assoc_args, 'user' ); } @@ -222,7 +222,7 @@ public function generate( $args, $assoc_args ) { * @synopsis <user> [<role>] */ public function set_role( $args, $assoc_args ) { - $user = self::get_user_from_first_arg( $args[0] ); + $user = self::get_user( $args[0] ); $role = isset( $args[1] ) ? $args[1] : get_option( 'default_role' ); @@ -242,7 +242,7 @@ public function set_role( $args, $assoc_args ) { * @synopsis <user> <role> */ public function add_role( $args, $assoc_args ) { - $user = self::get_user_from_first_arg( $args[0] ); + $user = self::get_user( $args[0] ); $role = $args[1]; @@ -258,7 +258,7 @@ public function add_role( $args, $assoc_args ) { * @synopsis <user> [<role>] */ public function remove_role( $args, $assoc_args ) { - $user = self::get_user_from_first_arg( $args[0] ); + $user = self::get_user( $args[0] ); if ( isset( $args[1] ) ) { $role = $args[1]; @@ -277,7 +277,7 @@ public function remove_role( $args, $assoc_args ) { } } - private static function get_user_from_first_arg( $id_or_login ) { + private static function get_user( $id_or_login ) { if ( is_numeric( $id_or_login ) ) $user = get_user_by( 'id', $id_or_login ); else From 3d23368e101b936f9a2ec9cf308ddb4c7024633e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 14:00:15 +0300 Subject: [PATCH 2016/4858] don't abort if a user isn't found --- features/user.feature | 9 ++++++--- php/commands/user.php | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/features/user.feature b/features/user.feature index c2d4a51d2e..437c548cbd 100644 --- a/features/user.feature +++ b/features/user.feature @@ -36,9 +36,12 @@ Feature: Manage WordPress users 10 """ - When I run `wp user delete $(wp user list --format=ids)` - And I run `wp user list --format=ids` - Then STDOUT should be empty + When I try `wp user delete invalid-user $(wp user list --format=ids)` + And I run `wp user list --format=count` + Then STDOUT should be: + """ + 0 + """ Scenario: Importing users from a CSV file Given a WP install diff --git a/php/commands/user.php b/php/commands/user.php index 880565a446..6998a18516 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -283,8 +283,9 @@ private static function get_user( $id_or_login ) { else $user = get_user_by( 'login', $id_or_login ); - if ( ! $user ) - WP_CLI::error( "Invalid user ID or login: $id_or_login" ); + if ( ! $user ) { + WP_CLI::warning( "Invalid user ID or login: $id_or_login" ); + } return $user; } From 85deb2d241d6cb1a5c86c623fbdbc5fa23e96911 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 14:51:54 +0300 Subject: [PATCH 2017/4858] simplify user test --- features/user.feature | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/features/user.feature b/features/user.feature index a5c8477045..f61d3a1c20 100644 --- a/features/user.feature +++ b/features/user.feature @@ -22,12 +22,7 @@ Feature: Manage WordPress users Scenario: Generating and deleting users Given a WP install - # Delete all users - When I run `wp user delete $(wp user list --format=ids)` - And I run `wp user list --format=ids` - Then STDOUT should be empty - - When I run `wp user generate --count=10` + When I run `wp user generate --count=9` And I run `wp user list --format=count` Then STDOUT should be: """ From 7973a4ae5fa6e2b629110d529e233aec706b0e13 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 15:56:46 +0300 Subject: [PATCH 2018/4858] extract assoc_array_to_table() utility. Also: - unset the 'format_content' field; it can be just as long as 'post_content'. - unset the 'filter' field; it's a runtime value, not persistent data --- php/WP_CLI/CommandWithDBObject.php | 18 ++++++++++++++++++ php/commands/post.php | 19 +++---------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index fa735be9e7..083b068758 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -68,6 +68,23 @@ protected function success_or_failure( $r ) { return $status; } + protected function assoc_array_to_table( $fields ) { + $rows = array(); + + foreach ( $fields as $field => $value ) { + if ( !is_string($value) ) { + $value = json_encode( $value ); + } + + $rows[] = (object) array( + 'Field' => $field, + 'Value' => $value + ); + } + + \WP_CLI\Utils\format_items( 'table', $rows, array( 'Field', 'Value' ) ); + } + public function delete( $args, $assoc_args ) { $status = 0; @@ -78,5 +95,6 @@ public function delete( $args, $assoc_args ) { exit( $status ); } + } diff --git a/php/commands/post.php b/php/commands/post.php index d378366036..8ef3c727e4 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -110,22 +110,9 @@ public function get( $args, $assoc_args ) { break; case 'table': - $items = array(); - foreach ( get_object_vars( $post ) as $field => $value ) { - if ( 'post_content' === $field ) - continue; - - if ( !is_string($value) ) { - $value = json_encode($value); - } - - $item = new \stdClass; - $item->Field = $field; - $item->Value = $value; - $items[] = $item; - } - - \WP_CLI\Utils\format_items( $format, $items, array( 'Field', 'Value' ) ); + $fields = get_object_vars( $post ); + unset( $fields['filter'], $fields['post_content'], $fields['format_content'] ); + $this->assoc_array_to_table( $fields ); break; case 'json': From 8514eee1105fe573b135ec66c79a8ace7b914bc9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 16:12:37 +0300 Subject: [PATCH 2019/4858] implement `wp user get` --- features/user.feature | 13 +++++++------ man-src/user-get.txt | 19 +++++++++++++++++++ php/commands/user.php | 29 +++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 man-src/user-get.txt diff --git a/features/user.feature b/features/user.feature index f61d3a1c20..ee18ec43c3 100644 --- a/features/user.feature +++ b/features/user.feature @@ -1,6 +1,6 @@ Feature: Manage WordPress users - Scenario: Creating/updating/deleting users + Scenario: User CRUD operations Given a WP install When I run `wp user create testuser testuser@example.com --porcelain` @@ -10,11 +10,12 @@ Feature: Manage WordPress users When I try the previous command again Then the return code should be 1 - When I run `wp user update {USER_ID} --displayname=Foo` - Then STDOUT should be: - """ - Success: Updated user {USER_ID}. - """ + When I run `wp user update {USER_ID} --display_name=Foo` + And I run `wp user get {USER_ID}` + Then STDOUT should be a table containing rows: + | Field | Value | + | ID | {USER_ID} | + | display_name | Foo | When I run `wp user delete {USER_ID}` Then STDOUT should not be empty diff --git a/man-src/user-get.txt b/man-src/user-get.txt new file mode 100644 index 0000000000..9493599eff --- /dev/null +++ b/man-src/user-get.txt @@ -0,0 +1,19 @@ +## OPTIONS + +* `[--format=<format>]`: + + The format to use when printing the user; acceptable values: + + **table**: Outputs all fields of the user as a table. + + **json**: Outputs all fields in JSON format. + +* `<user>`: + + User ID or user login. + +## EXAMPLES + + wp user get 12 + + wp user get bob --format=json > bob.json diff --git a/php/commands/user.php b/php/commands/user.php index eb03e03ef1..b7cbc815fa 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -56,6 +56,35 @@ public function _list( $args, $assoc_args ) { WP_CLI\Utils\format_items( $params['format'], $users, $fields ); } + /** + * Get a single user. + * + * @synopsis [--format=<format>] <user> + */ + public function get( $args, $assoc_args ) { + $assoc_args = wp_parse_args( $assoc_args, array( + 'format' => 'table' + ) ); + + $user = self::get_user( $args[0] )->to_array(); + + switch ( $assoc_args['format'] ) { + + case 'table': + $this->assoc_array_to_table( $user ); + break; + + case 'json': + WP_CLI::print_value( $user, $assoc_args ); + break; + + default: + \WP_CLI::error( "Invalid value for format: " . $format ); + break; + + } + } + /** * Delete one or more users. * From 34fffe816ae704a1a38ff8bae3afc07c3def6699 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 16:22:53 +0300 Subject: [PATCH 2020/4858] behat: align table bars --- features/user.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index ee18ec43c3..cb70e36fb4 100644 --- a/features/user.feature +++ b/features/user.feature @@ -13,9 +13,9 @@ Feature: Manage WordPress users When I run `wp user update {USER_ID} --display_name=Foo` And I run `wp user get {USER_ID}` Then STDOUT should be a table containing rows: - | Field | Value | + | Field | Value | | ID | {USER_ID} | - | display_name | Foo | + | display_name | Foo | When I run `wp user delete {USER_ID}` Then STDOUT should not be empty From ed808c47e215a458eaa53632744624615682290b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 14 Jul 2013 16:38:17 +0300 Subject: [PATCH 2021/4858] WP_User->to_array() doesn't exist in WP 3.4 --- php/commands/user.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index b7cbc815fa..d53cdd87da 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -66,16 +66,23 @@ public function get( $args, $assoc_args ) { 'format' => 'table' ) ); - $user = self::get_user( $args[0] )->to_array(); + $user = self::get_user( $args[0] ); + + if ( method_exists( $user, 'to_array' ) ) { + $user_data = $user->to_array(); + } else { + // WP 3.4 compat + $user_data = $user->data; + } switch ( $assoc_args['format'] ) { case 'table': - $this->assoc_array_to_table( $user ); + $this->assoc_array_to_table( $user_data ); break; case 'json': - WP_CLI::print_value( $user, $assoc_args ); + WP_CLI::print_value( $user_data, $assoc_args ); break; default: From 7397a2507b23f7bfed26e90b505a5882f3792993 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 15 Jul 2013 16:25:28 +0300 Subject: [PATCH 2022/4858] bump version to 0.11.0-alpha2 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 1064b77e61..f721cde077 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.11.0-alpha' ); +define( 'WP_CLI_VERSION', '0.11.0-alpha2' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 1f981c86a1dd43f220c69384b1287e8eceb467c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 16 Jul 2013 23:20:28 +0300 Subject: [PATCH 2023/4858] introduce `wp core multisite-install` (doesn't work yet) --- features/core.feature | 13 ++++++++++ php/WP_CLI/Runner.php | 4 ++- php/commands/core.php | 58 +++++++++++++++++++++++++++++++------------ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/features/core.feature b/features/core.feature index eda3c15b80..cc48e7ef9e 100644 --- a/features/core.feature +++ b/features/core.feature @@ -125,6 +125,19 @@ Feature: Manage WordPress installation When I try `wp core install-network --title='test network'` Then the return code should be 1 + Scenario: Install multisite from scrath + Given a WP multisite install + And I run `wp db reset --yes` + + When I run `wp core multisite-install --title=Test --admin_email=admin@example.com --admin_password=1` + Then STDOUT should not be empty + + When I run `wp eval 'var_export( is_multisite() );'` + Then STDOUT should be: + """ + true + """ + Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index abce20467f..85a0563d6d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -360,7 +360,9 @@ public function before_wp_load() { } if ( - $this->cmd_starts_with( array( 'core', 'install' ) ) + count( $this->arguments ) >= 2 && + $this->arguments[0] == 'core' && + in_array( $this->arguments[1], array( 'install', 'multisite-install' ) ) ) { define( 'WP_INSTALLING', true ); diff --git a/php/commands/core.php b/php/commands/core.php index 1efda9f088..0f9f2d5785 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -131,6 +131,37 @@ public function is_installed() { * @synopsis --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { + $this->_install( $assoc_args ); + WP_CLI::success( 'WordPress installed successfully.' ); + } + + /** + * Transform a single-site install into a multi-site install. + * + * @subcommand multisite-convert + * @alias install-network + * @synopsis --title=<network-title> [--base=<url-path>] + */ + public function multisite_convert( $args, $assoc_args ) { + if ( is_multisite() ) + WP_CLI::error( 'This already is a multisite install.' ); + + $this->_multisite_convert( $assoc_args ); + } + + /** + * Install multisite from scratch. + * + * @subcommand multisite-install + * @synopsis --url=<url> [--base=<url-path>] --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> + */ + public function multisite_install( $args, $assoc_args ) { + $this->_install( $assoc_args ); + WP_CLI::log( 'Created single site database tables.' ); + $this->_multisite_convert( $assoc_args ); + } + + private function _install( $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); if ( is_blog_installed() ) { @@ -150,21 +181,10 @@ public function install( $args, $assoc_args ) { if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::error_to_string($result) . ').' ); - } else { - WP_CLI::success( 'WordPress installed successfully.' ); } } - /** - * Transform a single-site install into a multi-site install. - * - * @subcommand install-network - * @synopsis --title=<network-title> [--base=<url-path>] [--subdomains] - */ - public function install_network( $args, $assoc_args ) { - if ( is_multisite() ) - WP_CLI::error( 'This already is a multisite install.' ); - + private function _multisite_convert( $assoc_args ) { global $wpdb; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); @@ -181,17 +201,21 @@ public function install_network( $args, $assoc_args ) { $subdomain_install = isset( $assoc_args['subdomains'] ); install_network(); + WP_CLI::log( 'Created multisite database tables.' ); $result = populate_network( 1, $hostname, get_option( 'admin_email' ), $assoc_args['title'], $base, $subdomain_install ); - if ( is_wp_error( $result ) ) { + if ( true === $result ) { + WP_CLI::log( 'Populated multisite options.' ); + } else if ( is_wp_error( $result ) ) { if ( $result->get_error_codes() === array( 'no_wildcard_dns' ) ) WP_CLI::warning( __( 'Wildcard DNS may not be configured correctly.' ) ); else WP_CLI::error( $result ); } - ob_start(); + if ( !defined( 'MULTISITE' ) ) { + ob_start(); ?> define('MULTISITE', true); define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>); @@ -202,9 +226,11 @@ public function install_network( $args, $assoc_args ) { define('BLOG_ID_CURRENT_SITE', 1); <?php - $ms_config = ob_get_clean(); + $ms_config = ob_get_clean(); - self::modify_wp_config( $ms_config ); + self::modify_wp_config( $ms_config ); + WP_CLI::log( 'Added multisite constants to wp-config.php.' ); + } wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); From b0db8685fb52293cda1928e6e61f82c126b10c68 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 00:40:25 +0300 Subject: [PATCH 2024/4858] skip ms_site_check() when installing --- php/wp-settings-cli.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 34cba9323f..b40e1479c9 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -304,7 +304,8 @@ do_action( 'init' ); // Check site status -if ( is_multisite() ) { +# if ( is_multisite() ) { // WP-CLI +if ( is_multisite() && !defined('WP_INSTALLING') ) { if ( true !== ( $file = ms_site_check() ) ) { require( $file ); die(); From f428094cf1de9e56cd201dd87ac0732abae8faaf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 03:18:54 +0300 Subject: [PATCH 2025/4858] test both with and without multisite constants scenarios --- features/core.feature | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index cc48e7ef9e..1360d62712 100644 --- a/features/core.feature +++ b/features/core.feature @@ -125,17 +125,32 @@ Feature: Manage WordPress installation When I try `wp core install-network --title='test network'` Then the return code should be 1 - Scenario: Install multisite from scrath + Scenario: Install multisite from scratch + Given an empty directory + And WP files + And wp-config.php + And a database + + When I run `wp core multisite-install --url=foobar.org --title=Test --admin_email=admin@example.com --admin_password=1` + Then STDOUT should not be empty + + When I run `wp eval 'echo $GLOBALS["current_site"]->domain;'` + Then STDOUT should be: + """ + foobar.org + """ + + Scenario: Install multisite from scratch, with MULTISITE already set in wp-config.php Given a WP multisite install And I run `wp db reset --yes` - When I run `wp core multisite-install --title=Test --admin_email=admin@example.com --admin_password=1` + When I run `wp core multisite-install --url=foobar.org --title=Test --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty - When I run `wp eval 'var_export( is_multisite() );'` + When I run `wp eval 'echo $GLOBALS["current_site"]->domain;'` Then STDOUT should be: """ - true + foobar.org """ Scenario: Custom wp-content directory From 02ce185f7d3e92b30e60adbcdc68e9649d72db54 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 02:34:18 +0300 Subject: [PATCH 2026/4858] copy the missing steps from populate_network() --- php/commands/core.php | 63 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 0f9f2d5785..293fdf47b8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -147,6 +147,7 @@ public function multisite_convert( $args, $assoc_args ) { WP_CLI::error( 'This already is a multisite install.' ); $this->_multisite_convert( $assoc_args ); + WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); } /** @@ -158,7 +159,20 @@ public function multisite_convert( $args, $assoc_args ) { public function multisite_install( $args, $assoc_args ) { $this->_install( $assoc_args ); WP_CLI::log( 'Created single site database tables.' ); + $this->_multisite_convert( $assoc_args ); + + // do the steps that were skipped by populate_network(), which checks is_multisite() + if ( defined( 'MULTISITE' ) ) { + $site_user = get_user_by( 'email', $assoc_args['admin_email'] ); + self::add_site_admins( $site_user ); + $domain = self::get_clean_basedomain(); + $path = isset( $assoc_args['base'] ) ? $assoc_args['base'] : '/'; + $subdomain_install = isset( $assoc_args['subdomains'] ); + self::create_initial_blog( 1, 1, $domain, $path, $subdomain_install, $site_user ); + } + + WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); } private function _install( $assoc_args ) { @@ -197,13 +211,13 @@ private function _multisite_convert( $assoc_args ) { 'base' => '/', ) ) ); - $hostname = self::get_clean_basedomain(); $subdomain_install = isset( $assoc_args['subdomains'] ); install_network(); WP_CLI::log( 'Created multisite database tables.' ); - $result = populate_network( 1, $hostname, get_option( 'admin_email' ), $assoc_args['title'], $base, $subdomain_install ); + $domain = self::get_clean_basedomain(); + $result = populate_network( 1, $domain, get_option( 'admin_email' ), $assoc_args['title'], $base, $subdomain_install ); if ( true === $result ) { WP_CLI::log( 'Populated multisite options.' ); @@ -214,13 +228,13 @@ private function _multisite_convert( $assoc_args ) { WP_CLI::error( $result ); } - if ( !defined( 'MULTISITE' ) ) { + if ( !is_multisite() ) { ob_start(); ?> define('MULTISITE', true); define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>); $base = '<?php echo $base; ?>'; -define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>'); +define('DOMAIN_CURRENT_SITE', '<?php echo $domain; ?>'); define('PATH_CURRENT_SITE', '<?php echo $base; ?>'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); @@ -233,8 +247,47 @@ private function _multisite_convert( $assoc_args ) { } wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); + } - WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); + // copied from populate_network() + private static function create_initial_blog( $network_id, $blog_id, $domain, $path, + $subdomain_install, $site_user ) { + global $wpdb, $current_site, $wp_rewrite; + + $current_site = new stdClass; + $current_site->domain = $domain; + $current_site->path = $path; + $current_site->site_name = ucfirst( $domain ); + $wpdb->insert( $wpdb->blogs, array( + 'site_id' => $network_id, + 'domain' => $domain, + 'path' => $path, + 'registered' => current_time( 'mysql' ) + ) ); + $current_site->blog_id = $blog_id = $wpdb->insert_id; + update_user_meta( $site_user->ID, 'source_domain', $domain ); + update_user_meta( $site_user->ID, 'primary_blog', $blog_id ); + + if ( $subdomain_install ) + $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' ); + else + $wp_rewrite->set_permalink_structure( '/blog/%year%/%monthnum%/%day%/%postname%/' ); + + flush_rewrite_rules(); + } + + // copied from populate_network() + private static function add_site_admins( $site_user ) { + $site_admins = array( $site_user->user_login ); + $users = get_users( array( 'fields' => array( 'ID', 'user_login' ) ) ); + if ( $users ) { + foreach ( $users as $user ) { + if ( is_super_admin( $user->ID ) && !in_array( $user->user_login, $site_admins ) ) + $site_admins[] = $user->user_login; + } + } + + update_site_option( 'site_admins', $site_admins ); } private static function modify_wp_config( $content ) { From d3e49e0465f37e6fb45adf5563ce705ef4374d55 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 03:19:22 +0300 Subject: [PATCH 2027/4858] fake $current_site and $current_blog globals --- php/WP_CLI/Runner.php | 60 ++++++++++++++++++++++++++++++++++++++++--- php/utils.php | 12 +++------ 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 85a0563d6d..917f8431f4 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -97,7 +97,7 @@ private static function set_user( $assoc_args ) { } } - private static function set_url( $assoc_args ) { + private static function guess_url( $assoc_args ) { if ( isset( $assoc_args['blog'] ) ) { $assoc_args['url'] = $assoc_args['blog']; unset( $assoc_args['blog'] ); @@ -136,8 +136,10 @@ private static function set_url( $assoc_args ) { } if ( isset( $url ) ) { - Utils\set_url_params( $url ); + return $url; } + + return false; } private function cmd_starts_with( $prefix ) { @@ -336,7 +338,11 @@ public function before_wp_load() { self::set_wp_root( $this->config ); // Handle --url and --blog parameters - self::set_url( $this->config ); + $url = self::guess_url( $this->config ); + if ( $url ) { + $url_parts = self::parse_url( $url ); + Utils\set_url_params( $url_parts ); + } $this->do_early_invoke( 'before_wp_load' ); @@ -366,8 +372,15 @@ public function before_wp_load() { ) { define( 'WP_INSTALLING', true ); + // We really need a URL here if ( !isset( $_SERVER['HTTP_HOST'] ) ) { - Utils\set_url_params( 'http://example.com' ); + $url_parts = self::parse_url( 'http://example.com' ); + Utils\set_url_params( $url_parts ); + } + + if ( 'multisite-install' == $this->arguments[1] ) { + // need to fake some globals to skip the checks in wp-inclues/ms-settings.php + self::fake_current_site_blog( $url_parts ); } } @@ -375,7 +388,46 @@ public function before_wp_load() { define( 'WP_LOAD_IMPORTERS', true ); define( 'WP_IMPORTING', true ); } + } + + private static function parse_url( $url ) { + $url_parts = parse_url( $url ); + + if ( !isset( $url_parts['scheme'] ) ) { + $url_parts = parse_url( 'http://' . $url ); + } + return $url_parts; + } + + private static function fake_current_site_blog( $url_parts ) { + global $current_site, $current_blog; + + if ( !isset( $url_parts['path'] ) ) { + $url_parts['path'] = '/'; + } + + $current_site = (object) array( + 'id' => 1, + 'blog_id' => 1, + 'domain' => $url_parts['host'], + 'path' => $url_parts['path'], + 'cookie_domain' => $url_parts['host'], + 'site_name' => 'Fake Site', + ); + + $current_blog = (object) array( + 'blog_id' => 1, + 'site_id' => 1, + 'domain' => $url_parts['host'], + 'path' => $url_parts['path'], + 'public' => '1', + 'archived' => '0', + 'mature' => '0', + 'spam' => '0', + 'deleted' => '0', + 'lang_id' => '0', + ); } public function after_wp_load() { diff --git a/php/utils.php b/php/utils.php index 8b8c463fc7..cb21c7ac73 100644 --- a/php/utils.php +++ b/php/utils.php @@ -140,15 +140,9 @@ function esc_cmd( $cmd ) { /** * Sets the appropriate $_SERVER keys based on a given string * - * @param string $url The URL + * @param array $url_parts The URL, as represented by parse_url() */ -function set_url_params( $url ) { - $url_parts = parse_url( $url ); - - if ( !isset( $url_parts['scheme'] ) ) { - $url_parts = parse_url( 'http://' . $url ); - } - +function set_url_params( $url_parts ) { $f = function( $key ) use ( $url_parts ) { return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; }; @@ -255,7 +249,7 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ function format_items( $format, $items, $fields ) { - + if ( 'ids' == $format ) { echo implode( ' ', $items ); return; From 03db22492e065aff081129e6e4a10de6d1e26207 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 03:29:13 +0300 Subject: [PATCH 2028/4858] fix edge case in guess_url() --- php/WP_CLI/Runner.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 917f8431f4..497208b4ed 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -129,10 +129,11 @@ private static function guess_url( $assoc_args ) { } } - if ( !empty( $hit ) && isset( $hit['domain'] ) ) + if ( !empty( $hit ) && isset( $hit['domain'] ) ) { $url = $hit['domain']; - if ( !empty( $hit ) && isset( $hit['path'] ) ) - $url .= $hit['path']; + if ( isset( $hit['path'] ) ) + $url .= $hit['path']; + } } if ( isset( $url ) ) { From e68eab4127fe98b75c1ab9e33f2df9e88208f92a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 03:36:23 +0300 Subject: [PATCH 2029/4858] move set_url_params() to WP_CLI\Runner It wasn't really meant to be a public utility. We just didn't have a runner class back then. --- php/WP_CLI/Runner.php | 26 ++++++++++++++++++++++++-- php/utils.php | 27 --------------------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 497208b4ed..dc18ebf47f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -143,6 +143,28 @@ private static function guess_url( $assoc_args ) { return false; } + private static function set_url_params( $url_parts ) { + $f = function( $key ) use ( $url_parts ) { + return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; + }; + + if ( isset( $url_parts['host'] ) ) { + $_SERVER['HTTP_HOST'] = $url_parts['host']; + if ( isset( $url_parts['port'] ) ) { + $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; + } + + $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); + } + + $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); + $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; + $_SERVER['QUERY_STRING'] = $f('query'); + $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; + $_SERVER['HTTP_USER_AGENT'] = ''; + $_SERVER['REQUEST_METHOD'] = 'GET'; + } + private function cmd_starts_with( $prefix ) { return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); } @@ -342,7 +364,7 @@ public function before_wp_load() { $url = self::guess_url( $this->config ); if ( $url ) { $url_parts = self::parse_url( $url ); - Utils\set_url_params( $url_parts ); + self::set_url_params( $url_parts ); } $this->do_early_invoke( 'before_wp_load' ); @@ -376,7 +398,7 @@ public function before_wp_load() { // We really need a URL here if ( !isset( $_SERVER['HTTP_HOST'] ) ) { $url_parts = self::parse_url( 'http://example.com' ); - Utils\set_url_params( $url_parts ); + self::set_url_params( $url_parts ); } if ( 'multisite-install' == $this->arguments[1] ) { diff --git a/php/utils.php b/php/utils.php index cb21c7ac73..9c0396359c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -137,33 +137,6 @@ function esc_cmd( $cmd ) { return vsprintf( $cmd, array_map( 'escapeshellarg', $args ) ); } -/** - * Sets the appropriate $_SERVER keys based on a given string - * - * @param array $url_parts The URL, as represented by parse_url() - */ -function set_url_params( $url_parts ) { - $f = function( $key ) use ( $url_parts ) { - return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; - }; - - if ( isset( $url_parts['host'] ) ) { - $_SERVER['HTTP_HOST'] = $url_parts['host']; - if ( isset( $url_parts['port'] ) ) { - $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; - } - - $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); - } - - $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); - $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; - $_SERVER['QUERY_STRING'] = $f('query'); - $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; - $_SERVER['HTTP_USER_AGENT'] = ''; - $_SERVER['REQUEST_METHOD'] = 'GET'; -} - function locate_wp_config() { static $path; From c05ba4c1ba5b7f8d58b580541c89eab9f37949f0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 03:41:36 +0300 Subject: [PATCH 2030/4858] move docs for multisite-convert --- man-src/{core-install-network.txt => core-multisite-convert.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename man-src/{core-install-network.txt => core-multisite-convert.txt} (100%) diff --git a/man-src/core-install-network.txt b/man-src/core-multisite-convert.txt similarity index 100% rename from man-src/core-install-network.txt rename to man-src/core-multisite-convert.txt From 18b1b224e83a0f92cab5139b0a65dabbbeb8a4e6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 04:02:37 +0300 Subject: [PATCH 2031/4858] get rid of some DB warnings --- php/wp-settings-cli.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index b40e1479c9..50687b3de0 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -59,6 +59,22 @@ // WP_CLI: Early hooks Utils\replace_wp_die_handler(); add_filter( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); +if ( defined( 'WP_INSTALLING' ) && is_multisite() ) { + $values = array( + 'ms_files_rewriting' => null, + 'active_sitewide_plugins' => array(), + '_site_transient_update_core' => null, + '_site_transient_update_themes' => null, + '_site_transient_update_plugins' => null, + 'WPLANG' => '', + ); + foreach ( $values as $key => $value ) { + add_filter( "pre_site_option_$key", function () use ( $values, $key ) { + return $values[ $key ]; + } ); + } + unset( $values, $key, $value ); +} // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); From e986f4ee626e8d315fef8ad210e837152b700c12 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 04:08:06 +0300 Subject: [PATCH 2032/4858] define COOKIEHASH to get rid of DB warning That's because wp_cookie_constants() goes looking for siteurl in the not-yet-existing wp_sitemeta table. --- php/WP_CLI/Runner.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index dc18ebf47f..47832b519d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -404,6 +404,10 @@ public function before_wp_load() { if ( 'multisite-install' == $this->arguments[1] ) { // need to fake some globals to skip the checks in wp-inclues/ms-settings.php self::fake_current_site_blog( $url_parts ); + + if ( !defined( 'COOKIEHASH' ) ) { + define( 'COOKIEHASH', md5( $url_parts['host'] ) ); + } } } From 34ed6ce4a8d98a28bcb56a647001798f5f0ff3eb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 04:29:27 +0300 Subject: [PATCH 2033/4858] behat: remove mismatched URL --- features/core.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index 1360d62712..5da719ccc6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -144,14 +144,14 @@ Feature: Manage WordPress installation Given a WP multisite install And I run `wp db reset --yes` - When I run `wp core multisite-install --url=foobar.org --title=Test --admin_email=admin@example.com --admin_password=1` + When I run `wp core multisite-install --title=Test --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty When I run `wp eval 'echo $GLOBALS["current_site"]->domain;'` Then STDOUT should be: """ - foobar.org - """ + example.com + """ Scenario: Custom wp-content directory Given a WP install From 874a0442ae9771324b8c572b0d61b6d0a0d086bd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 17 Jul 2013 22:12:51 +0300 Subject: [PATCH 2034/4858] account for already defined multisite constants --- php/commands/core.php | 70 ++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 293fdf47b8..fff84d7070 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -140,12 +140,14 @@ public function install( $args, $assoc_args ) { * * @subcommand multisite-convert * @alias install-network - * @synopsis --title=<network-title> [--base=<url-path>] + * @synopsis --title=<network-title> [--base=<url-path>] [--subdomains] */ public function multisite_convert( $args, $assoc_args ) { if ( is_multisite() ) WP_CLI::error( 'This already is a multisite install.' ); + $assoc_args = self::_set_multisite_defaults( $assoc_args ); + $this->_multisite_convert( $assoc_args ); WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); } @@ -154,27 +156,60 @@ public function multisite_convert( $args, $assoc_args ) { * Install multisite from scratch. * * @subcommand multisite-install - * @synopsis --url=<url> [--base=<url-path>] --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> + * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ public function multisite_install( $args, $assoc_args ) { $this->_install( $assoc_args ); WP_CLI::log( 'Created single site database tables.' ); + $assoc_args = self::_set_multisite_defaults( $assoc_args ); + + // Overwrite runtime args, to avoid mismatches. + $consts_to_args = array( + 'SUBDOMAIN_INSTALL' => 'subdomains', + 'PATH_CURRENT_SITE' => 'base', + 'SITE_ID_CURRENT_SITE' => 'site_id', + 'BLOG_ID_CURRENT_SITE' => 'blog_id', + ); + + foreach ( $consts_to_args as $const => $arg ) { + if ( defined( $const ) ) { + $assoc_args[ $arg ] = constant( $const ); + } + } + $this->_multisite_convert( $assoc_args ); - // do the steps that were skipped by populate_network(), which checks is_multisite() - if ( defined( 'MULTISITE' ) ) { + // Do the steps that were skipped by populate_network(), + // which checks is_multisite(). + if ( is_multisite() ) { $site_user = get_user_by( 'email', $assoc_args['admin_email'] ); self::add_site_admins( $site_user ); $domain = self::get_clean_basedomain(); - $path = isset( $assoc_args['base'] ) ? $assoc_args['base'] : '/'; - $subdomain_install = isset( $assoc_args['subdomains'] ); - self::create_initial_blog( 1, 1, $domain, $path, $subdomain_install, $site_user ); + self::create_initial_blog( + $assoc_args['site_id'], + $assoc_args['blog_id'], + $domain, + $assoc_args['base'], + $assoc_args['subdomains'], + $site_user + ); } WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); } + private static function _set_multisite_defaults( $assoc_args ) { + $defaults = array( + 'subdomains' => false, + 'base' => '/', + 'site_id' => 1, + 'blog_id' => 1, + ); + + return array_merge( $defaults, $assoc_args ); + } + private function _install( $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); @@ -207,17 +242,18 @@ private function _multisite_convert( $assoc_args ) { foreach ( $wpdb->tables( 'ms_global' ) as $table => $prefixed_table ) $wpdb->$table = $prefixed_table; - extract( wp_parse_args( $assoc_args, array( - 'base' => '/', - ) ) ); - - $subdomain_install = isset( $assoc_args['subdomains'] ); - install_network(); WP_CLI::log( 'Created multisite database tables.' ); $domain = self::get_clean_basedomain(); - $result = populate_network( 1, $domain, get_option( 'admin_email' ), $assoc_args['title'], $base, $subdomain_install ); + $result = populate_network( + $assoc_args['site_id'], + $domain, + get_option( 'admin_email' ), + $assoc_args['title'], + $assoc_args['base'], + $assoc_args['subdomains'] + ); if ( true === $result ) { WP_CLI::log( 'Populated multisite options.' ); @@ -232,10 +268,10 @@ private function _multisite_convert( $assoc_args ) { ob_start(); ?> define('MULTISITE', true); -define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>); -$base = '<?php echo $base; ?>'; +define('SUBDOMAIN_INSTALL', <?php var_export( $assoc_args['subdomains'] ); ?>); +$base = '<?php echo $assoc_args['base']; ?>'; define('DOMAIN_CURRENT_SITE', '<?php echo $domain; ?>'); -define('PATH_CURRENT_SITE', '<?php echo $base; ?>'); +define('PATH_CURRENT_SITE', '<?php echo $assoc_args['base']; ?>'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); From 1b7cb612e91c85aed99e778aaafbf6becd720790 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 18 Jul 2013 23:53:30 +0300 Subject: [PATCH 2035/4858] add docs for 'core multisite-install' --- man-src/core-multisite-install.txt | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 man-src/core-multisite-install.txt diff --git a/man-src/core-multisite-install.txt b/man-src/core-multisite-install.txt new file mode 100644 index 0000000000..eb9d7bd4d6 --- /dev/null +++ b/man-src/core-multisite-install.txt @@ -0,0 +1,30 @@ +## OPTIONS + +* `--url`=<url>: + + The address of the new site. + +* `--base`=<url-path>: + + Base path after the domain name that each site url in the network will start with. +Default: '/' + +* `--subdomains`: + + If passed, the network will use subdomains, instead of subdirectories. + +* `--title`=<site-title>: + + The title of the new site. + +* `--admin_name`=<username>: + + The name of the admin user. Default: 'admin' + +* `--admin_password`=<password>: + + The password for the admin user. + +* `--admin_email`=<email>: + + The email address for the admin user. From b57a0539ff32ea09817a64ba2aa1c155a9280b79 Mon Sep 17 00:00:00 2001 From: Veered <lucashansne@gmail.com> Date: Thu, 18 Jul 2013 15:36:46 -0700 Subject: [PATCH 2036/4858] Allow paths with spaces. --- bin/wp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/wp b/bin/wp index f53faf4137..706f6c9fd7 100755 --- a/bin/wp +++ b/bin/wp @@ -63,4 +63,4 @@ export WP_CLI_PHP_USED=$php # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands -exec $php "$SCRIPT_PATH" "$@" +exec "$php" "$SCRIPT_PATH" "$@" From ffc80dcba0018504e545a8a50a53d8055ca88a93 Mon Sep 17 00:00:00 2001 From: Veered <lucashansne@gmail.com> Date: Thu, 18 Jul 2013 16:42:38 -0700 Subject: [PATCH 2037/4858] The Windows version of tar doesn't play nicely with pipes. This way is more cross-platform. --- php/commands/core.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 1efda9f088..fa31422913 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -40,8 +40,9 @@ public function download( $args, $assoc_args ) { $silent = WP_CLI::get_config('quiet') || \cli\Shell::isPiped() ? '--silent ' : ''; - - $cmd = "curl -f $silent %s | tar xz --strip-components=1 --directory=%s"; + + $temp = tempnam(sys_get_temp_dir(), "wp_"); + $cmd = "curl -f $silent %s > $temp && tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; WP_CLI::launch( Utils\esc_cmd( $cmd, $download_url, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); From 67c074c5e4765a9756706fd723139194bdf2d214 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 19 Jul 2013 03:19:22 +0300 Subject: [PATCH 2038/4858] add comment about cURL + tar. see #604 --- php/commands/core.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index fa31422913..1458a8886d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -40,8 +40,10 @@ public function download( $args, $assoc_args ) { $silent = WP_CLI::get_config('quiet') || \cli\Shell::isPiped() ? '--silent ' : ''; - - $temp = tempnam(sys_get_temp_dir(), "wp_"); + + // We need to use a temporary file because piping from cURL to tar is flaky + // on MinGW (and probably in other environments too). + $temp = tempnam( sys_get_temp_dir(), "wp_" ); $cmd = "curl -f $silent %s > $temp && tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; WP_CLI::launch( Utils\esc_cmd( $cmd, $download_url, ABSPATH ) ); From 819b2b742ffe97b8779b97722b606220a4520728 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 20 Jul 2013 00:35:09 +0300 Subject: [PATCH 2039/4858] make --title optional for multisite-convert use the same logic from /wp-admin/network.php --- php/commands/core.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index fff84d7070..0867d8750e 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -140,13 +140,16 @@ public function install( $args, $assoc_args ) { * * @subcommand multisite-convert * @alias install-network - * @synopsis --title=<network-title> [--base=<url-path>] [--subdomains] + * @synopsis [--title=<network-title>] [--base=<url-path>] [--subdomains] */ public function multisite_convert( $args, $assoc_args ) { if ( is_multisite() ) WP_CLI::error( 'This already is a multisite install.' ); $assoc_args = self::_set_multisite_defaults( $assoc_args ); + if ( !isset( $assoc_args['title'] ) ) { + $assoc_args['title'] = sprintf( _x('%s Sites', 'Default network name' ), get_option( 'blogname' ) ); + } $this->_multisite_convert( $assoc_args ); WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); @@ -163,6 +166,7 @@ public function multisite_install( $args, $assoc_args ) { WP_CLI::log( 'Created single site database tables.' ); $assoc_args = self::_set_multisite_defaults( $assoc_args ); + $assoc_args['title'] = sprintf( _x('%s Sites', 'Default network name' ), $assoc_args['title'] ); // Overwrite runtime args, to avoid mismatches. $consts_to_args = array( @@ -243,7 +247,6 @@ private function _multisite_convert( $assoc_args ) { $wpdb->$table = $prefixed_table; install_network(); - WP_CLI::log( 'Created multisite database tables.' ); $domain = self::get_clean_basedomain(); $result = populate_network( @@ -256,7 +259,7 @@ private function _multisite_convert( $assoc_args ) { ); if ( true === $result ) { - WP_CLI::log( 'Populated multisite options.' ); + WP_CLI::log( 'Set up multisite database tables.' ); } else if ( is_wp_error( $result ) ) { if ( $result->get_error_codes() === array( 'no_wildcard_dns' ) ) WP_CLI::warning( __( 'Wildcard DNS may not be configured correctly.' ) ); From ec4d54403a1a1712c8e40e6b50041446573dc8e7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Jul 2013 03:23:58 +0300 Subject: [PATCH 2040/4858] add --locale parameter to 'wp core config'. fixes #607 --- man-src/core-config.txt | 6 +++++- php/commands/core.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/man-src/core-config.txt b/man-src/core-config.txt index 2f5920998c..9945a05c38 100644 --- a/man-src/core-config.txt +++ b/man-src/core-config.txt @@ -20,6 +20,10 @@ Set the database table prefix. Default: 'wp_' +* `--locale`=<locale>: + + Set the WPLANG constant. Defaults to $wp_local_package variable. + * `--extra-php`: If set, the command reads additional PHP code from STDIN. @@ -27,7 +31,7 @@ ## EXAMPLES # Standard wp-config.php file - wp core config --dbname=testing --dbuser=wp --dbpass=securepswd + wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --locale=ro_RO # Enable WP_DEBUG and WP_DEBUG_LOG wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP diff --git a/php/commands/core.php b/php/commands/core.php index 1458a8886d..cc4eaf8af5 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -75,7 +75,7 @@ private static function get_initial_locale() { /** * Set up a wp-config.php file. * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--extra-php] + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] */ public function config( $_, $assoc_args ) { if ( Utils\locate_wp_config() ) { From 398bc1ff7577cd492cac331a73d4bfd222228d43 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Jul 2013 18:59:08 +0300 Subject: [PATCH 2041/4858] don't fail if the site is already installed --- features/core.feature | 8 ++++++++ php/commands/core.php | 46 ++++++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/features/core.feature b/features/core.feature index 5da719ccc6..27818a62aa 100644 --- a/features/core.feature +++ b/features/core.feature @@ -104,6 +104,10 @@ Feature: Manage WordPress installation true """ + # Can complain that it's already installed, but don't exit with an error code + When I try `wp core install --url='localhost:8001' --title='Test' --admin_email=admin@example.com --admin_password=1` + Then the return code should be 0 + Scenario: Convert install to multisite Given a WP install @@ -140,6 +144,10 @@ Feature: Manage WordPress installation foobar.org """ + # Can complain that it's already installed, but don't exit with an error code + When I try `wp core multisite-install --url=foobar.org --title=Test --admin_email=admin@example.com --admin_password=1` + Then the return code should be 0 + Scenario: Install multisite from scratch, with MULTISITE already set in wp-config.php Given a WP multisite install And I run `wp db reset --yes` diff --git a/php/commands/core.php b/php/commands/core.php index 0867d8750e..3781181a66 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -131,8 +131,11 @@ public function is_installed() { * @synopsis --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { - $this->_install( $assoc_args ); - WP_CLI::success( 'WordPress installed successfully.' ); + if ( $this->_install( $assoc_args ) ) { + WP_CLI::success( 'WordPress installed successfully.' ); + } else { + WP_CLI::log( 'WordPress is already installed.' ); + } } /** @@ -151,8 +154,9 @@ public function multisite_convert( $args, $assoc_args ) { $assoc_args['title'] = sprintf( _x('%s Sites', 'Default network name' ), get_option( 'blogname' ) ); } - $this->_multisite_convert( $assoc_args ); - WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); + if ( $this->_multisite_convert( $assoc_args ) ) { + WP_CLI::success( "Network installed. Don't forget to set up rewrite rules." ); + } } /** @@ -162,8 +166,11 @@ public function multisite_convert( $args, $assoc_args ) { * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ public function multisite_install( $args, $assoc_args ) { - $this->_install( $assoc_args ); - WP_CLI::log( 'Created single site database tables.' ); + if ( $this->_install( $assoc_args ) ) { + WP_CLI::log( 'Created single site database tables.' ); + } else { + WP_CLI::log( 'Single site database tables already present.' ); + } $assoc_args = self::_set_multisite_defaults( $assoc_args ); $assoc_args['title'] = sprintf( _x('%s Sites', 'Default network name' ), $assoc_args['title'] ); @@ -182,7 +189,9 @@ public function multisite_install( $args, $assoc_args ) { } } - $this->_multisite_convert( $assoc_args ); + if ( !$this->_multisite_convert( $assoc_args ) ) { + return; + } // Do the steps that were skipped by populate_network(), // which checks is_multisite(). @@ -215,12 +224,12 @@ private static function _set_multisite_defaults( $assoc_args ) { } private function _install( $assoc_args ) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - if ( is_blog_installed() ) { - WP_CLI::error( 'WordPress is already installed.' ); + return false; } + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + extract( wp_parse_args( $assoc_args, array( 'title' => '', 'admin_name' => 'admin', @@ -235,6 +244,8 @@ private function _install( $assoc_args ) { if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::error_to_string($result) . ').' ); } + + return true; } private function _multisite_convert( $assoc_args ) { @@ -261,10 +272,19 @@ private function _multisite_convert( $assoc_args ) { if ( true === $result ) { WP_CLI::log( 'Set up multisite database tables.' ); } else if ( is_wp_error( $result ) ) { - if ( $result->get_error_codes() === array( 'no_wildcard_dns' ) ) + switch ( $result->get_error_code() ) { + + case 'siteid_exists': + WP_CLI::log( $result->get_error_message() ); + return false; + + case 'no_wildcard_dns': WP_CLI::warning( __( 'Wildcard DNS may not be configured correctly.' ) ); - else + break; + + default: WP_CLI::error( $result ); + } } if ( !is_multisite() ) { @@ -286,6 +306,8 @@ private function _multisite_convert( $assoc_args ) { } wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); + + return true; } // copied from populate_network() From ef051f9dcfddf3384b98a977a6588a74e468fe9f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Jul 2013 22:03:53 +0300 Subject: [PATCH 2042/4858] clone object instead of calling constructor; fixes #592 --- php/utils.php | 8 ++------ tests/test-unserialize-replace.php | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 tests/test-unserialize-replace.php diff --git a/php/utils.php b/php/utils.php index 8b8c463fc7..0bb98f1d7b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -217,19 +217,15 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria } $data = $_tmp; - unset( $_tmp ); } - // Submitted by Tina Matter elseif ( is_object( $data ) ) { - $dataClass = get_class( $data ); - $_tmp = new $dataClass( ); + $_tmp = clone( $data ); foreach ( $data as $key => $value ) { $_tmp->$key = recursive_unserialize_replace( $from, $to, $value, false ); } $data = $_tmp; - unset( $_tmp ); } else { @@ -255,7 +251,7 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ function format_items( $format, $items, $fields ) { - + if ( 'ids' == $format ) { echo implode( ' ', $items ); return; diff --git a/tests/test-unserialize-replace.php b/tests/test-unserialize-replace.php new file mode 100644 index 0000000000..3389336f38 --- /dev/null +++ b/tests/test-unserialize-replace.php @@ -0,0 +1,24 @@ +<?php + +class UnserializeReplaceTest extends PHPUnit_Framework_TestCase { + + function testPrivateConstructor() { + $old_obj = ClassWithPrivateConstructor::get_instance(); + + $new_obj = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_obj ); + $this->assertEquals( 'bar', $new_obj->prop ); + } +} + + +class ClassWithPrivateConstructor { + + public $prop = 'foo'; + + private function __construct() {} + + public static function get_instance() { + return new self; + } +} + From 2a21e33c38611c5b09cf7bc97e24fa153f0c07b5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Jul 2013 23:18:30 +0300 Subject: [PATCH 2043/4858] add comment above apparently unnecessary load_command() call --- php/WP_CLI/Runner.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index abce20467f..9a08694013 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -319,6 +319,8 @@ public function before_wp_load() { if ( empty( $this->arguments ) ) $this->arguments[] = 'help'; + // Load bundled commands early, so that they're forced to use the same + // APIs as non-bundled commands. Utils\load_command( $this->arguments[0] ); if ( isset( $this->config['require'] ) ) { From 5c1c36520b3706b40479e75dbb938c22a8741809 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 23 Jul 2013 22:57:52 +0300 Subject: [PATCH 2044/4858] move find_command_to_run() method to WP_CLI\Runner the WP_CLI class should be a simple facade, with only public methods --- php/WP_CLI/Runner.php | 41 ++++++++++++++++++++++++++++++++++++++++- php/class-wp-cli.php | 39 ++------------------------------------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9a08694013..8af6b2a0ce 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -144,8 +144,47 @@ private function cmd_starts_with( $prefix ) { return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); } + private function find_command_to_run( $args ) { + $command = \WP_CLI::get_root_command(); + + $cmd_path = array(); + + $disabled_commands = $this->config['disabled_commands']; + + while ( !empty( $args ) && $command->has_subcommands() ) { + $cmd_path[] = $args[0]; + $full_name = implode( ' ', $cmd_path ); + + $subcommand = $command->find_subcommand( $args ); + + if ( !$subcommand ) { + \WP_CLI::error( sprintf( + "'%s' is not a registered wp command. See 'wp help'.", + $full_name + ) ); + } + + if ( in_array( $full_name, $disabled_commands ) ) { + \WP_CLI::error( sprintf( + "The '%s' command has been disabled from the config file.", + $full_name + ) ); + } + + $command = $subcommand; + } + + return array( $command, $args ); + } + + public function run_command( $args, $assoc_args = array() ) { + list( $command, $final_args ) = $this->find_command_to_run( $args ); + + $command->invoke( $final_args, $assoc_args ); + } + private function _run_command() { - WP_CLI::run_command( $this->arguments, $this->assoc_args ); + $this->run_command( $this->arguments, $this->assoc_args ); } /** diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7d2c9dff4a..1408f97288 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -266,49 +266,14 @@ static function get_config( $key = null ) { return self::get_runner()->config[ $key ]; } - private static function find_command_to_run( $args ) { - $command = self::get_root_command(); - - $cmd_path = array(); - - $disabled_commands = self::get_config('disabled_commands'); - - while ( !empty( $args ) && $command->has_subcommands() ) { - $cmd_path[] = $args[0]; - $full_name = implode( ' ', $cmd_path ); - - $subcommand = $command->find_subcommand( $args ); - - if ( !$subcommand ) { - self::error( sprintf( - "'%s' is not a registered wp command. See 'wp help'.", - $full_name - ) ); - } - - if ( in_array( $full_name, $disabled_commands ) ) { - self::error( sprintf( - "The '%s' command has been disabled from the config file.", - $full_name - ) ); - } - - $command = $subcommand; - } - - return array( $command, $args ); - } - /** * Run a given command. * * @param array * @param array */ - public static function run_command( $args, $assoc_args = array() ) { - list( $command, $final_args ) = self::find_command_to_run( $args ); - - $command->invoke( $final_args, $assoc_args ); + static function run_command( $args, $assoc_args = array() ) { + self::get_runner()->run_command( $args, $assoc_args ); } // back-compat From 09b5b2577a6e0af0b1c338410a20661d842e5de5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Jul 2013 00:02:35 +0300 Subject: [PATCH 2045/4858] show synopsis for incomplete commands, even without a WP install --- features/help.feature | 9 +++++++++ php/WP_CLI/Runner.php | 26 +++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/features/help.feature b/features/help.feature index 2f2193548c..3aef3dbcb5 100644 --- a/features/help.feature +++ b/features/help.feature @@ -47,3 +47,12 @@ Feature: Get help about WP-CLI commands """ wp test-help """ + + Scenario: Help for incomplete commands + Given an empty directory + + When I run `wp core` + Then STDOUT should contain: + """ + usage: wp core + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8af6b2a0ce..515f75dca0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -158,17 +158,17 @@ private function find_command_to_run( $args ) { $subcommand = $command->find_subcommand( $args ); if ( !$subcommand ) { - \WP_CLI::error( sprintf( + return sprintf( "'%s' is not a registered wp command. See 'wp help'.", $full_name - ) ); + ); } if ( in_array( $full_name, $disabled_commands ) ) { - \WP_CLI::error( sprintf( + return sprintf( "The '%s' command has been disabled from the config file.", $full_name - ) ); + ); } $command = $subcommand; @@ -178,7 +178,12 @@ private function find_command_to_run( $args ) { } public function run_command( $args, $assoc_args = array() ) { - list( $command, $final_args ) = $this->find_command_to_run( $args ); + $r = $this->find_command_to_run( $args ); + if ( is_string( $r ) ) { + WP_CLI::error( $r ); + } + + list( $command, $final_args ) = $r; $command->invoke( $final_args, $assoc_args ); } @@ -368,6 +373,17 @@ public function before_wp_load() { } } + // Show synopsis if it's a composite command. + $r = $this->find_command_to_run( $args ); + if ( is_array( $r ) ) { + list( $command ) = $r; + + if ( $command->has_subcommands() ) { + $command->show_usage(); + exit; + } + } + // First try at showing man page if ( $this->cmd_starts_with( array( 'help' ) ) ) { $this->_run_command(); From 230c741467e8baf92506e67ee0c0f7bfad26bcc3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Jul 2013 00:23:45 +0300 Subject: [PATCH 2046/4858] extract init_config() helper method --- php/WP_CLI/Runner.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 515f75dca0..8f5af66344 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -332,7 +332,7 @@ private function check_wp_version() { } } - public function before_wp_load() { + private function init_config() { list( $args, $assoc_args, $runtime_config ) = \WP_CLI::get_configurator()->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -341,9 +341,7 @@ public function before_wp_load() { $this->config_path = self::get_config_path( $runtime_config ); - $local_config = \WP_CLI::get_configurator()->load_config( $this->config_path ); - - $this->config = $local_config; + $this->config = \WP_CLI::get_configurator()->load_config( $this->config_path ); foreach ( $runtime_config as $key => $value ) { if ( isset( $this->config[ $key ] ) && is_array( $this->config[ $key ] ) ) { @@ -356,7 +354,10 @@ public function before_wp_load() { if ( !isset( $this->config['path'] ) ) { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); } + } + public function before_wp_load() { + $this->init_config(); $this->init_colorization(); $this->init_logger(); @@ -374,7 +375,7 @@ public function before_wp_load() { } // Show synopsis if it's a composite command. - $r = $this->find_command_to_run( $args ); + $r = $this->find_command_to_run( $this->arguments ); if ( is_array( $r ) ) { list( $command ) = $r; @@ -430,7 +431,6 @@ public function before_wp_load() { define( 'WP_LOAD_IMPORTERS', true ); define( 'WP_IMPORTING', true ); } - } public function after_wp_load() { @@ -442,3 +442,4 @@ public function after_wp_load() { $this->_run_command(); } } + From 9d7940b1cb5be79a9bb1ab635f602912098f0af3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 24 Jul 2013 14:43:48 +0300 Subject: [PATCH 2047/4858] fix indentation in .travis.yml --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7ed5e423f5..7a642a4544 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,12 @@ language: php php: - - 5.3 - - 5.5 + - 5.3 + - 5.5 env: - - WP_VERSION=latest - - WP_VERSION=3.4.2 + - WP_VERSION=latest + - WP_VERSION=3.4.2 matrix: exclude: @@ -16,7 +16,7 @@ matrix: before_script: ./bin/ci/install_dependencies.sh script: ./bin/ci/run_build.sh - + notifications: - email: - on_success: never + email: + on_success: never From 0562f785855abc0fec13d7ac265f7478ac9d9af7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Jul 2013 19:17:14 +0300 Subject: [PATCH 2048/4858] allow WP_CLI::error() to do its thing (it prints both the error message and any additional data) --- php/commands/plugin.php | 5 +---- php/commands/theme.php | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 630dbee3ef..e95c568452 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -156,10 +156,7 @@ protected function install_from_repo( $slug, $assoc_args ) { $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { - if ( null === maybe_unserialize( $api->get_error_data() ) ) - WP_CLI::error( "Can't find the plugin in the WordPress.org repository." ); - else - WP_CLI::error( $api ); + WP_CLI::error( $api ); } if ( isset( $assoc_args['version'] ) ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 843bf8d73f..8db618bd43 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -106,10 +106,7 @@ protected function install_from_repo( $slug, $assoc_args ) { $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { - if ( null === maybe_unserialize( $api->get_error_data() ) ) - WP_CLI::error( "Can't find the theme in the WordPress.org repository." ); - else - WP_CLI::error( $api ); + WP_CLI::error( $api ); } if ( isset( $assoc_args['version'] ) ) { From 7cd6d9d69894db971283e2c8ab19addb961feead Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Jul 2013 01:05:01 +0300 Subject: [PATCH 2049/4858] make `wp user get` show roles fixes #616 --- php/commands/user.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index d53cdd87da..f80b56c339 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -72,8 +72,9 @@ public function get( $args, $assoc_args ) { $user_data = $user->to_array(); } else { // WP 3.4 compat - $user_data = $user->data; + $user_data = (array) $user->data; } + $user_data['roles'] = implode( ', ', $user->roles ); switch ( $assoc_args['format'] ) { From 5de309a3057d2731affc62c1615e48757ef1e0a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 28 Jul 2013 19:42:13 +0300 Subject: [PATCH 2050/4858] add some Behat tests for `wp user *-role` see #594 --- features/user.feature | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/features/user.feature b/features/user.feature index cb70e36fb4..ced0e41920 100644 --- a/features/user.feature +++ b/features/user.feature @@ -61,3 +61,34 @@ Feature: Manage WordPress users """ [{"user_login":"admin","display_name":"Existing User","user_email":"admin@domain.com","roles":"administrator"}] """ + + Scenario: Managing user roles + Given a WP install + + When I run `wp user add-role 1 editor` + Then STDOUT should not be empty + And I run `wp user get 1` + Then STDOUT should be a table containing rows: + | Field | Value | + | roles | administrator, editor | + + When I run `wp user set-role 1 author` + Then STDOUT should not be empty + And I run `wp user get 1` + Then STDOUT should be a table containing rows: + | Field | Value | + | roles | author | + + When I run `wp user remove-role 1 editor` + Then STDOUT should not be empty + And I run `wp user get 1` + Then STDOUT should be a table containing rows: + | Field | Value | + | roles | author | + + When I run `wp user remove-role 1` + Then STDOUT should not be empty + And I run `wp user get 1` + Then STDOUT should be a table containing rows: + | Field | Value | + | roles | | From 73ae6b0a1f00303a46f8f692ecd7c21dd6035704 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 29 Jul 2013 18:16:00 +0000 Subject: [PATCH 2051/4858] Per Codex instructions, use gettext context for `singlular_name` --- templates/taxonomy.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index 96e18b5862..f4431bf488 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -13,7 +13,7 @@ ), 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), - 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), + 'singular_name' => _x( '{{label_ucfirst}}', 'taxonomy general name', '{{textdomain}}' ), 'search_items' => __( 'Search {{label_plural}}', '{{textdomain}}' ), 'popular_items' => __( 'Popular {{label_plural}}', '{{textdomain}}' ), 'all_items' => __( 'All {{label_plural}}', '{{textdomain}}' ), From 8bfdf451c411afd9c4552f61bcdd4bca403cafe6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Jul 2013 03:55:57 +0300 Subject: [PATCH 2052/4858] introduce SynopsisValidator class --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/WP_CLI/SynopsisParser.php | 95 ------------------------ php/WP_CLI/SynopsisValidator.php | 105 +++++++++++++++++++++++++++ tests/test-arg-validation.php | 12 +-- 4 files changed, 112 insertions(+), 102 deletions(-) create mode 100644 php/WP_CLI/SynopsisValidator.php diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 3203ef9d42..16d101e3f0 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -42,7 +42,7 @@ private function validate_args( $args, &$assoc_args ) { if ( !$synopsis ) return; - $parser = new \WP_CLI\SynopsisParser( $synopsis ); + $parser = new \WP_CLI\SynopsisValidator( $synopsis ); if ( !$parser->enough_positionals( $args ) ) { $this->show_usage(); exit(1); diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index eb5dc8e0e8..3daf70d3a2 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -6,72 +6,6 @@ class SynopsisParser { private static $patterns = array(); - private $params = array(); - - public function __construct( $synopsis ) { - $this->params = $this->parse( $synopsis ); - } - - public function enough_positionals( $args ) { - $positional = $this->query_params( array( - 'type' => 'positional', - 'flavour' => 'mandatory' - ) ); - - return count( $args ) >= count( $positional ); - } - - public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { - $assoc = $this->query_params( array( - 'type' => 'assoc', - ) ); - - $errors = array( - 'fatal' => array(), - 'warning' => array() - ); - - foreach ( $assoc as $param ) { - $key = $param['name']; - - if ( in_array( $key, $ignored_keys ) ) - continue; - - if ( !isset( $assoc_args[ $key ] ) ) { - if ( 'mandatory' == $param['flavour'] ) { - $errors['fatal'][] = "missing --$key parameter"; - } - } else { - if ( true === $assoc_args[ $key ] ) { - $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning'; - $errors[ $error_type ][] = "--$key parameter needs a value"; - - unset( $assoc_args[ $key ] ); - } - } - } - - return $errors; - } - - public function unknown_assoc( $assoc_args ) { - $generic = $this->query_params( array( - 'type' => 'generic', - ) ); - - if ( count( $generic ) ) - return array(); - - $known_assoc = array(); - - foreach ( $this->params as $param ) { - if ( in_array( $param['type'], array( 'assoc', 'flag' ) ) ) - $known_assoc[] = $param['name']; - } - - return array_diff( array_keys( $assoc_args ), $known_assoc ); - } - /** * @param string * @return array List of parameters @@ -134,34 +68,5 @@ private static function gen_patterns( $type, $pattern, $flavour_types ) { } } } - - /** - * Filters a list of associatve arrays, based on a set of key => value arguments. - * - * @param array $args An array of key => value arguments to match against - * @param string $operator - * @return array - */ - private function query_params( $args, $operator = 'AND' ) { - $operator = strtoupper( $operator ); - $count = count( $args ); - $filtered = array(); - - foreach ( $this->params as $key => $to_match ) { - $matched = 0; - foreach ( $args as $m_key => $m_value ) { - if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) - $matched++; - } - - if ( ( 'AND' == $operator && $matched == $count ) - || ( 'OR' == $operator && $matched > 0 ) - || ( 'NOT' == $operator && 0 == $matched ) ) { - $filtered[$key] = $to_match; - } - } - - return $filtered; - } } diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php new file mode 100644 index 0000000000..597d89b523 --- /dev/null +++ b/php/WP_CLI/SynopsisValidator.php @@ -0,0 +1,105 @@ +<?php + +namespace WP_CLI; + +/** + * Checks if the list of parameters matches the specification defined in the synopsis. + */ +class SynopsisValidator { + + private $spec = array(); + + public function __construct( $synopsis ) { + $this->spec = SynopsisParser::parse( $synopsis ); + } + + public function enough_positionals( $args ) { + $positional = $this->query_spec( array( + 'type' => 'positional', + 'flavour' => 'mandatory' + ) ); + + return count( $args ) >= count( $positional ); + } + + public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { + $assoc = $this->query_spec( array( + 'type' => 'assoc', + ) ); + + $errors = array( + 'fatal' => array(), + 'warning' => array() + ); + + foreach ( $assoc as $param ) { + $key = $param['name']; + + if ( in_array( $key, $ignored_keys ) ) + continue; + + if ( !isset( $assoc_args[ $key ] ) ) { + if ( 'mandatory' == $param['flavour'] ) { + $errors['fatal'][] = "missing --$key parameter"; + } + } else { + if ( true === $assoc_args[ $key ] ) { + $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning'; + $errors[ $error_type ][] = "--$key parameter needs a value"; + + unset( $assoc_args[ $key ] ); + } + } + } + + return $errors; + } + + public function unknown_assoc( $assoc_args ) { + $generic = $this->query_spec( array( + 'type' => 'generic', + ) ); + + if ( count( $generic ) ) + return array(); + + $known_assoc = array(); + + foreach ( $this->spec as $param ) { + if ( in_array( $param['type'], array( 'assoc', 'flag' ) ) ) + $known_assoc[] = $param['name']; + } + + return array_diff( array_keys( $assoc_args ), $known_assoc ); + } + + /** + * Filters a list of associatve arrays, based on a set of key => value arguments. + * + * @param array $args An array of key => value arguments to match against + * @param string $operator + * @return array + */ + private function query_spec( $args, $operator = 'AND' ) { + $operator = strtoupper( $operator ); + $count = count( $args ); + $filtered = array(); + + foreach ( $this->spec as $key => $to_match ) { + $matched = 0; + foreach ( $args as $m_key => $m_value ) { + if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) + $matched++; + } + + if ( ( 'AND' == $operator && $matched == $count ) + || ( 'OR' == $operator && $matched > 0 ) + || ( 'NOT' == $operator && 0 == $matched ) ) { + $filtered[$key] = $to_match; + } + } + + return $filtered; + } +} + diff --git a/tests/test-arg-validation.php b/tests/test-arg-validation.php index 8875891196..f579823c58 100644 --- a/tests/test-arg-validation.php +++ b/tests/test-arg-validation.php @@ -1,11 +1,11 @@ <?php -use WP_CLI\SynopsisParser; +use WP_CLI\SynopsisValidator; class ArgValidationTests extends PHPUnit_Framework_TestCase { function testMissingPositional() { - $parser = new SynopsisParser( '<foo> <bar> [<baz>]' ); + $parser = new SynopsisValidator( '<foo> <bar> [<baz>]' ); $this->assertFalse( $parser->enough_positionals( array() ) ); $this->assertTrue( $parser->enough_positionals( array( 1, 2 ) ) ); @@ -13,7 +13,7 @@ function testMissingPositional() { } function testRepeatingPositional() { - $parser = new SynopsisParser( '<foo> [<bar>...]' ); + $parser = new SynopsisValidator( '<foo> [<bar>...]' ); $this->assertFalse( $parser->enough_positionals( array() ) ); $this->assertTrue( $parser->enough_positionals( array( 1 ) ) ); @@ -21,14 +21,14 @@ function testRepeatingPositional() { } function testUnknownAssocEmpty() { - $parser = new SynopsisParser( '' ); + $parser = new SynopsisValidator( '' ); $assoc_args = array( 'foo' => true, 'bar' => false ); $this->assertEquals( array_keys( $assoc_args ), $parser->unknown_assoc( $assoc_args ) ); } function testUnknownAssoc() { - $parser = new SynopsisParser( '--type=<type> [--brand=<brand>] [--flag]' ); + $parser = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); $assoc_args = array( 'type' => 'analog', 'brand' => true, 'flag' => true ); $this->assertEmpty( $parser->unknown_assoc( $assoc_args ) ); @@ -38,7 +38,7 @@ function testUnknownAssoc() { } function testMissingAssoc() { - $parser = new SynopsisParser( '--type=<type> [--brand=<brand>] [--flag]' ); + $parser = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); $assoc_args = array( 'brand' => true, 'flag' => true ); $errors = $parser->validate_assoc( $assoc_args ); From caf035f7302ed4d8c0a587c912f8d2f0eb448ea2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Jul 2013 04:10:08 +0300 Subject: [PATCH 2053/4858] Rewrite SynopsisParser to support optional values for assoc parameters. Props @jmslbam for initial implementation and tests. see #570 --- php/WP_CLI/SynopsisParser.php | 108 +++++++++++++++++++------------ php/WP_CLI/SynopsisValidator.php | 6 +- tests/test-synopsis.php | 108 ++++++++++++++++++++----------- 3 files changed, 138 insertions(+), 84 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 3daf70d3a2..d7e4c1ba1a 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -4,68 +4,90 @@ class SynopsisParser { - private static $patterns = array(); - /** - * @param string + * @param string A synopsis * @return array List of parameters */ static function parse( $synopsis ) { - if ( empty( self::$patterns ) ) - self::init_patterns(); - $tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) ); $params = array(); - foreach ( $tokens as $token ) { - $type = false; - - foreach ( self::$patterns as $regex => $desc ) { - if ( preg_match( $regex, $token, $matches ) ) { - $type = $desc['type']; - $params[] = array_merge( $matches, $desc ); - break; + $param = self::classify_token( $token ); + + // Some types of parameters shouldn't be mandatory + if ( isset( $param['optional'] ) && !$param['optional'] ) { + if ( 'flag' === $param['type'] || + ( 'assoc' === $param['type'] && $param['value']['optional'] ) + ) { + $param['type'] = 'unknown'; } } - if ( !$type ) { - $params[] = array( - 'type' => 'unknown', - 'token' => $token - ); - } + $param['token'] = $token; + $params[] = $param; } return $params; } - private static function init_patterns() { - $p_name = '(?P<name>[a-z-_]+)'; - $p_value = '(?P<value>[a-zA-Z-|]+)'; + private static function classify_token( $token ) { + $param = array(); - self::gen_patterns( 'positional', "<$p_value>", array( 'mandatory', 'optional', 'repeating' ) ); - self::gen_patterns( 'generic', "--<field>=<value>", array( 'mandatory', 'optional', 'repeating' ) ); - self::gen_patterns( 'assoc', "--$p_name=<$p_value>", array( 'mandatory', 'optional' ) ); - self::gen_patterns( 'flag', "--$p_name", array( 'optional' ) ); - } + list( $param['optional'], $token ) = self::is_optional( $token ); + list( $param['repeating'], $token ) = self::is_repeating( $token ); - private static function gen_patterns( $type, $pattern, $flavour_types ) { - static $flavours = array( - 'mandatory' => ':pattern:', - 'optional' => '\[:pattern:\]', - 'repeating' => array( ':pattern:...', '\[:pattern:...\]' ) - ); - - foreach ( $flavour_types as $flavour_type ) { - foreach ( (array) $flavours[ $flavour_type ] as $flavour ) { - $final_pattern = str_replace( ':pattern:', $pattern, $flavour ); - - self::$patterns[ '/^' . $final_pattern . '$/' ] = array( - 'type' => $type, - 'flavour' => $flavour_type - ); + $p_name = '([a-z-_]+)'; + $p_value = '([a-zA-Z-|]+)'; + + if ( '--<field>=<value>' === $token ) { + $param['type'] = 'generic'; + } elseif ( preg_match( "/^<$p_name>$/", $token, $matches ) ) { + $param['type'] = 'positional'; + } elseif ( preg_match( "/^--$p_name/", $token, $matches ) ) { + $param['name'] = $matches[1]; + + $value = substr( $token, strlen( $matches[0] ) ); + + if ( false === $value ) { + $param['type'] = 'flag'; + } else { + $param['type'] = 'assoc'; + + list( $param['value']['optional'], $value ) = self::is_optional( $value ); + + if ( preg_match( "/^=<$p_value>$/", $value, $matches ) ) { + $param['value']['name'] = $matches[1]; + } else { + $param = array( 'type' => 'unknown' ); + } } + } else { + $param['type'] = 'unknown'; + } + + return $param; + } + + /** + * An optional parameter is surrounded by square brackets. + */ + private static function is_optional( $token ) { + if ( '[' == substr( $token, 0, 1 ) && ']' == substr( $token, -1 ) ) { + return array( true, substr( $token, 1, -1 ) ); + } else { + return array( false, $token ); + } + } + + /** + * A repeating parameter is followed by an ellipsis. + */ + private static function is_repeating( $token ) { + if ( '...' === substr( $token, -3 ) ) { + return array( true, substr( $token, 0, -3 ) ); + } else { + return array( false, $token ); } } } diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index 597d89b523..902b537d04 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -16,7 +16,7 @@ public function __construct( $synopsis ) { public function enough_positionals( $args ) { $positional = $this->query_spec( array( 'type' => 'positional', - 'flavour' => 'mandatory' + 'optional' => false ) ); return count( $args ) >= count( $positional ); @@ -39,12 +39,12 @@ public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { continue; if ( !isset( $assoc_args[ $key ] ) ) { - if ( 'mandatory' == $param['flavour'] ) { + if ( !$param['optional'] ) { $errors['fatal'][] = "missing --$key parameter"; } } else { if ( true === $assoc_args[ $key ] ) { - $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning'; + $error_type = ( !$param['optional'] ) ? 'fatal' : 'warning'; $errors[ $error_type ][] = "--$key parameter needs a value"; unset( $assoc_args[ $key ] ); diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 9262b593eb..22e7cb907c 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -15,54 +15,80 @@ function testPositional() { $this->assertCount( 2, $r ); - $this->assertEquals( 'positional', $r[0]['type'] ); - $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + $param = $r[0]; + $this->assertEquals( 'positional', $param['type'] ); + $this->assertFalse( $param['optional'] ); - $this->assertEquals( 'positional', $r[1]['type'] ); - $this->assertEquals( 'optional', $r[1]['flavour'] ); + $param = $r[1]; + $this->assertEquals( 'positional', $param['type'] ); + $this->assertTrue( $param['optional'] ); } function testFlag() { $r = SynopsisParser::parse( '[--foo]' ); $this->assertCount( 1, $r ); - $this->assertEquals( 'flag', $r[0]['type'] ); - $this->assertEquals( 'optional', $r[0]['flavour'] ); + + $param = $r[0]; + $this->assertEquals( 'flag', $param['type'] ); + $this->assertTrue( $param['optional'] ); // flags can't be mandatory $r = SynopsisParser::parse( '--foo' ); $this->assertCount( 1, $r ); - $this->assertEquals( 'unknown', $r[0]['type'] ); + + $param = $r[0]; + $this->assertEquals( 'unknown', $param['type'] ); } function testGeneric() { - $r = SynopsisParser::parse( '--<field>=<value> [--<field>=<value>]' ); + $r = SynopsisParser::parse( '--<field>=<value> [--<field>=<value>] --<field>[=<value>] [--<field>[=<value>]]' ); - $this->assertCount( 2, $r ); + $this->assertCount( 4, $r ); - $this->assertEquals( 'generic', $r[0]['type'] ); - $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + $param = $r[0]; + $this->assertEquals( 'generic', $param['type'] ); + $this->assertFalse( $param['optional'] ); - $this->assertEquals( 'generic', $r[1]['type'] ); - $this->assertEquals( 'optional', $r[1]['flavour'] ); + $param = $r[1]; + $this->assertEquals( 'generic', $param['type'] ); + $this->assertTrue( $param['optional'] ); + + $param = $r[2]; + $this->assertEquals( 'unknown', $param['type'] ); + + $param = $r[3]; + $this->assertEquals( 'unknown', $param['type'] ); } function testAssoc() { - $r = SynopsisParser::parse( '--foo=<value> [--bar=<value>]' ); + $r = SynopsisParser::parse( '--foo=<value> [--bar=<value>] [--bar[=<value>]]' ); - $this->assertCount( 2, $r ); + $this->assertCount( 3, $r ); - $this->assertEquals( 'assoc', $r[0]['type'] ); - $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + $param = $r[0]; + $this->assertEquals( 'assoc', $param['type'] ); + $this->assertFalse( $param['optional'] ); - $this->assertEquals( 'assoc', $r[1]['type'] ); - $this->assertEquals( 'optional', $r[1]['flavour'] ); + $param = $r[1]; + $this->assertEquals( 'assoc', $param['type'] ); + $this->assertTrue( $param['optional'] ); + + $param = $r[2]; + $this->assertEquals( 'assoc', $param['type'] ); + $this->assertTrue( $param['optional'] ); + $this->assertTrue( $param['value']['optional'] ); + } + + function testInvalidAssoc() { + $r = SynopsisParser::parse( '--bar[=<value>] --bar=[<value>] --count=100' ); + + $this->assertCount( 3, $r ); - // shouldn't pass defaults to assoc parameters - $r = SynopsisParser::parse( '--count=100' ); - $this->assertCount( 1, $r ); $this->assertEquals( 'unknown', $r[0]['type'] ); + $this->assertEquals( 'unknown', $r[1]['type'] ); + $this->assertEquals( 'unknown', $r[2]['type'] ); } function testRepeating() { @@ -70,38 +96,44 @@ function testRepeating() { $this->assertCount( 2, $r ); - $this->assertEquals( 'positional', $r[0]['type'] ); - $this->assertEquals( 'repeating', $r[0]['flavour'] ); + $param = $r[0]; + $this->assertEquals( 'positional', $param['type'] ); + $this->assertTrue( $param['repeating'] ); - $this->assertEquals( 'generic', $r[1]['type'] ); - $this->assertEquals( 'repeating', $r[1]['flavour'] ); + $param = $r[1]; + $this->assertEquals( 'generic', $param['type'] ); + $this->assertTrue( $param['repeating'] ); } function testCombined() { $r = SynopsisParser::parse( '<positional> --assoc=<someval> --<field>=<value> [--flag]' ); + $this->assertCount( 4, $r ); + $this->assertEquals( 'positional', $r[0]['type'] ); $this->assertEquals( 'assoc', $r[1]['type'] ); $this->assertEquals( 'generic', $r[2]['type'] ); $this->assertEquals( 'flag', $r[3]['type'] ); } - function testAllowedValueCharacters() { - $r = SynopsisParser::parse( '--capitals=<VALUE> --hyphen=<val-ue> --combined=<VAL-ue> --disallowed=<wrong:char>' ); + function testAllowedValueCharacters() { + $r = SynopsisParser::parse( '--capitals=<VALUE> --hyphen=<val-ue> --combined=<VAL-ue> --disallowed=<wrong:char>' ); - $this->assertCount( 4, $r ); + $this->assertCount( 4, $r ); - $this->assertEquals( 'assoc', $r[0]['type'] ); - $this->assertEquals( 'mandatory', $r[0]['flavour'] ); + $param = $r[0]; + $this->assertEquals( 'assoc', $param['type'] ); + $this->assertFalse( $param['optional'] ); - $this->assertEquals( 'assoc', $r[1]['type'] ); - $this->assertEquals( 'mandatory', $r[1]['flavour'] ); + $param = $r[1]; + $this->assertEquals( 'assoc', $param['type'] ); + $this->assertFalse( $param['optional'] ); - $this->assertEquals( 'assoc', $r[2]['type'] ); - $this->assertEquals( 'mandatory', $r[2]['flavour'] ); - - $this->assertEquals( 'unknown', $r[3]['type'] ); - } + $param = $r[2]; + $this->assertEquals( 'assoc', $param['type'] ); + $this->assertFalse( $param['optional'] ); + $this->assertEquals( 'unknown', $r[3]['type'] ); + } } From 82473c155a125a850f45cc34a6d1cb17380c9fbf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Jul 2013 04:59:06 +0300 Subject: [PATCH 2054/4858] ignore repeating parameters in enough_positionals() This isn't necessarily the best approach, but it matches previous behaviour. (see parent commit) --- php/WP_CLI/SynopsisValidator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index 902b537d04..4b62a364ea 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -16,7 +16,8 @@ public function __construct( $synopsis ) { public function enough_positionals( $args ) { $positional = $this->query_spec( array( 'type' => 'positional', - 'optional' => false + 'optional' => false, + 'repeating' => false ) ); return count( $args ) >= count( $positional ); From e8ea7f5b62baeb860cdc329a029d2cbc854f2d5c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Jul 2013 04:54:32 +0300 Subject: [PATCH 2055/4858] remove redundant array_filter() around preg_split() --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index d7e4c1ba1a..c28173e6a2 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -9,7 +9,7 @@ class SynopsisParser { * @return array List of parameters */ static function parse( $synopsis ) { - $tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) ); + $tokens = preg_split( '/[\s\t]+/', $synopsis ); $params = array(); foreach ( $tokens as $token ) { From b9325dbe15c87fa5955b8bcfaf59a8fb5ae8acfe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 30 Jul 2013 05:05:19 +0300 Subject: [PATCH 2056/4858] Revert "remove redundant array_filter() around preg_split()" This reverts commit e8ea7f5b62baeb860cdc329a029d2cbc854f2d5c. It's not redundant when the synopsis has leading or trailing whitespace or when it's an empty string. --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index c28173e6a2..d7e4c1ba1a 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -9,7 +9,7 @@ class SynopsisParser { * @return array List of parameters */ static function parse( $synopsis ) { - $tokens = preg_split( '/[\s\t]+/', $synopsis ); + $tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) ); $params = array(); foreach ( $tokens as $token ) { From 0b80c51041717e0bc66bcd20dcc68cf04775d0ee Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Jul 2013 19:54:12 +0300 Subject: [PATCH 2057/4858] remove 'Need even more info' section --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8579249964..bad038e581 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Where can I get more info? -------------------------- For documentation, usage, and examples, check out [wp-cli.org](http://wp-cli.org/). +Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). + I'm running into troubles, what can I do? ----------------------------------------- To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). @@ -21,12 +23,8 @@ We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](ht A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). -Need even more info? --------------------- -Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). - -If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. - Contributing ------------ See [CONTRIBUTING.md](CONTRIBUTING.md). + +If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. From 5f4a5ae59123cbcd6e91339dcd83d64dfaefff89 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 31 Jul 2013 19:59:02 +0300 Subject: [PATCH 2058/4858] giving credit where credit is due --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index bad038e581..83a5f567d3 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,19 @@ To suggest a feature, report a bug, or general discussion, visit the [issues sec If you're reporting a bug, please also post the output from `wp --info`. +Credits +------- + +Besides the libraries defined in [composer.json](composer.json), we have used code or ideas from the following projects: + +* [Drush](http://drush.ws/) for... a lot of things +* [wpshell](http://code.trac.wordpress.org/browser/wpshell) for `wp shell` +* [Regenerate Thumbnails](http://wordpress.org/plugins/regenerate-thumbnails/) for `wp media regenerate` +* [Search-Replace-DB](https://github.com/interconnectit/Search-Replace-DB) for `wp search-replace` +* [WordPress-CLI-Exporter](https://github.com/Automattic/WordPress-CLI-Exporter) for `wp export` +* [WordPress-CLI-Importer](https://github.com/Automattic/WordPress-CLI-Importer) for `wp import` +* [wordpress-plugin-tests](https://github.com/benbalter/wordpress-plugin-tests/) for `wp scaffold plugin-tests` + Who's behind this thing? ------------------------ We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). From 8bde3c0f9f471c765a010f9fa958dce9736b3ff9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 03:43:46 +0300 Subject: [PATCH 2059/4858] don't return 'filter' object in `wp post get --format=json` it's a transient value, not actual data --- php/commands/post.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 8ef3c727e4..f368f7bab2 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -37,7 +37,7 @@ public function create( $args, $assoc_args ) { } if ( isset( $assoc_args['edit'] ) ) { - $input = ( isset( $assoc_args['post_content'] ) ) ? + $input = isset( $assoc_args['post_content'] ) ? $assoc_args['post_content'] : ''; if ( $output = $this->_edit( $input, 'WP-CLI: New Post' ) ) @@ -116,7 +116,9 @@ public function get( $args, $assoc_args ) { break; case 'json': - WP_CLI::print_value( $post, $assoc_args ); + $fields = get_object_vars( $post ); + unset( $fields['filter'] ); + WP_CLI::print_value( $fields, $assoc_args ); break; default: From fa8c9253f7aedf49a92f5165c043b689d98c582f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 03:49:25 +0300 Subject: [PATCH 2060/4858] remove unnecessary temporary variable --- php/commands/post.php | 3 +-- php/commands/user.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index f368f7bab2..1792830998 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -97,7 +97,6 @@ public function get( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( 'format' => 'table' ) ); - $format = $assoc_args['format']; $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) @@ -122,7 +121,7 @@ public function get( $args, $assoc_args ) { break; default: - \WP_CLI::error( "Invalid value for format: " . $format ); + \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); break; } diff --git a/php/commands/user.php b/php/commands/user.php index f80b56c339..7a874a07c1 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -87,7 +87,7 @@ public function get( $args, $assoc_args ) { break; default: - \WP_CLI::error( "Invalid value for format: " . $format ); + \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); break; } From 3f5d5c2f07d05ec608533ba463d5773587b7c254 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 16:46:56 +0300 Subject: [PATCH 2061/4858] introduce utils/convert-docs.php script --- utils/convert-docs.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 utils/convert-docs.php diff --git a/utils/convert-docs.php b/utils/convert-docs.php new file mode 100644 index 0000000000..a2dbf1c86a --- /dev/null +++ b/utils/convert-docs.php @@ -0,0 +1,26 @@ +<?php + +# usage: php utils/convert-docs.php man-src/*.txt + +function convert_file( $path ) { + $out = file_get_contents( $path ); + + // options to definition lists + $out = preg_replace_callback( '/\n\* (.+?):?\n\n\t/', function( $matches ) { + $arg = str_replace( '`', '', $matches[1] ); + + return "\n$arg\n: "; + }, $out ); + + // convert tabs to spaces + $out = preg_replace( '/^\t/m', " ", $out ); + + // prepend docblock notation + $out = preg_replace( '/^(.*)/m', "\t* \\1", $out ); + + file_put_contents( $path, $out ); +} + +foreach ( array_slice( $argv, 1 ) as $arg ) { + convert_file( $arg ); +} From 23c99f47b7ab2411f23fc061b046433b412a11de Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 17:42:40 +0300 Subject: [PATCH 2062/4858] make `wp help` read intermediary format --- php/commands/help.php | 4 ++-- utils/convert-docs.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 7b6599dc71..9b86c08584 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -42,8 +42,8 @@ private static function show_help( $command ) { // section headers $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); - // old-style options - $out = preg_replace( '/\n\* `(.+)`([^\n]*):\n\n/', "\n\t\\1\\2\n\t\t", $out ); + // definition lists + $out = preg_replace( '/\n([^\n]+)\n: (.+?)\n/s', "\n\t\\1\n\t\t\\2\n", $out ); $out = str_replace( "\t", ' ', $out ); diff --git a/utils/convert-docs.php b/utils/convert-docs.php index a2dbf1c86a..59c573347c 100644 --- a/utils/convert-docs.php +++ b/utils/convert-docs.php @@ -16,7 +16,7 @@ function convert_file( $path ) { $out = preg_replace( '/^\t/m', " ", $out ); // prepend docblock notation - $out = preg_replace( '/^(.*)/m', "\t* \\1", $out ); + # $out = preg_replace( '/^(.*)/m', "\t* \\1", $out ); file_put_contents( $path, $out ); } From f7cc325d74074311d2df0f194eeefee569e824cb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 22:40:34 +0300 Subject: [PATCH 2063/4858] pass string to DocParser (makes it easier to unit test) --- php/WP_CLI/Dispatcher/CommandFactory.php | 4 ++-- php/WP_CLI/DocParser.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index 72eb104f34..4e7a0aae14 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -21,7 +21,7 @@ public static function create( $name, $class, $parent ) { } private static function create_subcommand( $parent, $name, $class_name, $method ) { - $docparser = new \WP_CLI\DocParser( $method ); + $docparser = new \WP_CLI\DocParser( $method->getDocComment() ); if ( !$name ) $name = $docparser->get_tag( 'subcommand' ); @@ -39,7 +39,7 @@ private static function create_subcommand( $parent, $name, $class_name, $method } private static function create_composite_command( $parent, $name, $reflection ) { - $docparser = new \WP_CLI\DocParser( $reflection ); + $docparser = new \WP_CLI\DocParser( $reflection->getDocComment() ); $container = new CompositeCommand( $parent, $name, $docparser ); diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index 4d597a6313..c5bfb16480 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -6,8 +6,8 @@ class DocParser { protected $docComment; - function __construct( $reflection ) { - $this->docComment = $reflection->getDocComment(); + function __construct( $docComment ) { + $this->docComment = $docComment; } function get_shortdesc() { From fd37d17336bc433f2976eba6e48bdf66eb7d84b3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 23:08:40 +0300 Subject: [PATCH 2064/4858] add a few unit tests for DocParser --- php/WP_CLI/DocParser.php | 4 +++ tests/test-doc-parser.php | 75 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/test-doc-parser.php diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index c5bfb16480..f830285e31 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -17,6 +17,10 @@ function get_shortdesc() { return $matches[1]; } + function get_longdesc() { + return false; + } + function get_tag( $name ) { if ( preg_match( '/@' . $name . '\s+([a-z-_]+)/', $this->docComment, $matches ) ) return $matches[1]; diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php new file mode 100644 index 0000000000..2026b3af6f --- /dev/null +++ b/tests/test-doc-parser.php @@ -0,0 +1,75 @@ +<?php + +use WP_CLI\DocParser; + +class DocParserTests extends PHPUnit_Framework_TestCase { + + function test_only_tags() { + $doc = new DocParser( <<<EOB +/** + * @alias rock-on + */ +EOB + ); + + $this->assertFalse( $doc->get_shortdesc() ); + $this->assertFalse( $doc->get_longdesc() ); + $this->assertFalse( $doc->get_synopsis() ); + $this->assertFalse( $doc->get_tag('foo') ); + $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); + } + + function test_no_longdesc() { + $doc = new DocParser( <<<EOB +/** + * Rock and roll! + * @alias rock-on + */ +EOB + ); + + $this->assertEquals( 'Rock and roll!', $doc->get_shortdesc() ); + $this->assertFalse( $doc->get_longdesc() ); + $this->assertFalse( $doc->get_synopsis() ); + $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); + } + + function test_complete() { + $doc = new DocParser( <<<EOB +/** + * Rock and roll! + * + * ## OPTIONS + * + * --volume=<number> + * : Sets the volume. + * + * ## EXAMPLES + * + * wp rock-on --volume=11 + * + * @synopsis [--volume=<number>] + * @alias rock-on + */ +EOB + ); + + $this->assertEquals( 'Rock and roll!', $doc->get_shortdesc() ); + $this->assertEquals( '[--volume=<number>]', $doc->get_synopsis() ); + $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); + + $longdesc = <<<EOB +## OPTIONS + +--volume=<number> +: Sets the volume. + +## EXAMPLES + +wp rock-on --volume=11 +EOB + ; + $this->assertEquals( $longdesc, $doc->get_longdesc() ); + } +} + From 8868ee7da7e520a789666823bd7f088e0402967f Mon Sep 17 00:00:00 2001 From: Dan Gardner <dan@web.nearest.to> Date: Thu, 1 Aug 2013 21:09:16 +0100 Subject: [PATCH 2065/4858] Support multi-line argument values (#624) --- php/WP_CLI/Configurator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index e28c90f1fb..239e95f23e 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -45,7 +45,7 @@ function parse_args( $arguments ) { $mixed_args[] = array( $matches[1], false ); } elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { $mixed_args[] = array( $matches[1], true ); - } elseif ( preg_match( '|^--([^=]+)=(.+)|', $arg, $matches ) ) { + } elseif ( preg_match( '|^--([^=]+)=(.+)|s', $arg, $matches ) ) { $mixed_args[] = array( $matches[1], $matches[2] ); } else { $regular_args[] = $arg; From 4efa6555190d2050455115bfb8da9f67119252c9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 23:18:57 +0300 Subject: [PATCH 2066/4858] DocParser: remove decorations before processing --- php/WP_CLI/DocParser.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index f830285e31..ebd9a52967 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -7,11 +7,19 @@ class DocParser { protected $docComment; function __construct( $docComment ) { - $this->docComment = $docComment; + $this->docComment = self::remove_decorations( $docComment ); + } + + private static function remove_decorations( $comment ) { + $comment = preg_replace( '|^/\*\*\n|', '', $comment ); + $comment = preg_replace( '|\n[\t ]*\*/$|', '', $comment ); + $comment = preg_replace( '|^[\t ]*\* ?|m', '', $comment ); + + return $comment; } function get_shortdesc() { - if ( !preg_match( '/\* (\w.+)\n*/', $this->docComment, $matches ) ) + if ( !preg_match( '|^([^@][^\n]+)\n*|', $this->docComment, $matches ) ) return false; return $matches[1]; @@ -22,14 +30,14 @@ function get_longdesc() { } function get_tag( $name ) { - if ( preg_match( '/@' . $name . '\s+([a-z-_]+)/', $this->docComment, $matches ) ) + if ( preg_match( '|^@' . $name . '\s+([a-z-_]+)|m', $this->docComment, $matches ) ) return $matches[1]; return false; } function get_synopsis() { - if ( !preg_match( '/@synopsis\s+([^\n]+)/', $this->docComment, $matches ) ) + if ( !preg_match( '|^@synopsis\s+(.+)|m', $this->docComment, $matches ) ) return false; return $matches[1]; From 7d5106c837821ed884c063a74dd10f35b7f39fe0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 23:45:01 +0300 Subject: [PATCH 2067/4858] DocParser: return empty string instead of false --- php/WP_CLI/DocParser.php | 6 +++--- tests/test-doc-parser.php | 21 +++++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index ebd9a52967..e146833ad1 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -20,7 +20,7 @@ private static function remove_decorations( $comment ) { function get_shortdesc() { if ( !preg_match( '|^([^@][^\n]+)\n*|', $this->docComment, $matches ) ) - return false; + return ''; return $matches[1]; } @@ -33,12 +33,12 @@ function get_tag( $name ) { if ( preg_match( '|^@' . $name . '\s+([a-z-_]+)|m', $this->docComment, $matches ) ) return $matches[1]; - return false; + return ''; } function get_synopsis() { if ( !preg_match( '|^@synopsis\s+(.+)|m', $this->docComment, $matches ) ) - return false; + return ''; return $matches[1]; } diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index 2026b3af6f..4138481910 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -4,6 +4,15 @@ class DocParserTests extends PHPUnit_Framework_TestCase { + function test_empty() { + $doc = new DocParser( '' ); + + $this->assertEquals( '', $doc->get_shortdesc() ); + $this->assertEquals( '', $doc->get_longdesc() ); + $this->assertEquals( '', $doc->get_synopsis() ); + $this->assertEquals( '', $doc->get_tag('alias') ); + } + function test_only_tags() { $doc = new DocParser( <<<EOB /** @@ -12,10 +21,10 @@ function test_only_tags() { EOB ); - $this->assertFalse( $doc->get_shortdesc() ); - $this->assertFalse( $doc->get_longdesc() ); - $this->assertFalse( $doc->get_synopsis() ); - $this->assertFalse( $doc->get_tag('foo') ); + $this->assertEquals( '', $doc->get_shortdesc() ); + $this->assertEquals( '', $doc->get_longdesc() ); + $this->assertEquals( '', $doc->get_synopsis() ); + $this->assertEquals( '', $doc->get_tag('foo') ); $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); } @@ -29,8 +38,8 @@ function test_no_longdesc() { ); $this->assertEquals( 'Rock and roll!', $doc->get_shortdesc() ); - $this->assertFalse( $doc->get_longdesc() ); - $this->assertFalse( $doc->get_synopsis() ); + $this->assertEquals( '', $doc->get_longdesc() ); + $this->assertEquals( '', $doc->get_synopsis() ); $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); } From eada5446c3f328b0a24d3e8190cbe1dbcc1b3fdf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 1 Aug 2013 23:48:38 +0300 Subject: [PATCH 2068/4858] DocParser: implement get_longdesc() --- php/WP_CLI/DocParser.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index e146833ad1..a999a9e1ea 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -26,7 +26,22 @@ function get_shortdesc() { } function get_longdesc() { - return false; + $shortdesc = $this->get_shortdesc(); + if ( !$shortdesc ) + return ''; + + $longdesc = substr( $this->docComment, strlen( $shortdesc ) ); + + $lines = array(); + foreach ( explode( "\n", $longdesc ) as $line ) { + if ( 0 === strpos( $line, '@' ) ) + break; + + $lines[] = $line; + } + $longdesc = trim( implode( $lines, "\n" ) ); + + return $longdesc; } function get_tag( $name ) { From 127f409d29df737904e06a2c864fc8fd2d608059 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 2 Aug 2013 00:57:32 +0300 Subject: [PATCH 2069/4858] replace get_extra_markdown() with get_longdesc() --- php/WP_CLI/Dispatcher/CompositeCommand.php | 27 ++++------------------ php/WP_CLI/Dispatcher/RootCommand.php | 2 +- php/commands/cli.php | 1 + php/commands/help.php | 2 +- 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 1aa21b5d3e..98cbbe734f 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -17,6 +17,7 @@ public function __construct( $parent, $name, $docparser ) { $this->name = $name; $this->shortdesc = $docparser->get_shortdesc(); + $this->longdesc = $docparser->get_longdesc(); $when_to_invoke = $docparser->get_tag( 'when' ); if ( $when_to_invoke ) { @@ -50,6 +51,10 @@ function get_shortdesc() { return $this->shortdesc; } + function get_longdesc() { + return $this->longdesc; + } + function get_synopsis() { return '<subcommand>'; } @@ -73,28 +78,6 @@ function show_usage() { \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); } - function get_extra_markdown() { - $md_file = self::find_extra_markdown_file( $this ); - if ( !$md_file ) - return ''; - - return file_get_contents( $md_file ); - } - - private static function find_extra_markdown_file( $command ) { - $cmd_path = get_path( $command ); - array_shift( $cmd_path ); // discard 'wp' - $cmd_path = implode( '-', $cmd_path ); - - foreach ( \WP_CLI::get_man_dirs() as $src_dir ) { - $src_path = "$src_dir/$cmd_path.txt"; - if ( is_readable( $src_path ) ) - return $src_path; - } - - return false; - } - function find_subcommand( &$args ) { $name = array_shift( $args ); diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 311d295bbb..d65c79fd4b 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -17,7 +17,7 @@ function __construct() { $this->shortdesc = 'Manage WordPress through the command-line.'; } - function get_extra_markdown() { + function get_longdesc() { $binding = array(); foreach ( \WP_CLI::get_configurator()->get_spec() as $key => $details ) { diff --git a/php/commands/cli.php b/php/commands/cli.php index a31493b879..2f550c8856 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -14,6 +14,7 @@ private function command_to_array( $command ) { $dump = array( 'name' => $command->get_name(), 'description' => $command->get_shortdesc(), + 'longdesc' => $command->get_longdesc(), ); foreach ( $command->get_subcommands() as $subcommand ) { diff --git a/php/commands/help.php b/php/commands/help.php index 9b86c08584..fb42b8a400 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -37,7 +37,7 @@ private static function find_subcommand( $args ) { private static function show_help( $command ) { $out = self::get_initial_markdown( $command ); - $out .= $command->get_extra_markdown(); + $out .= $command->get_longdesc(); // section headers $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); From 27a2ff1e94ccb924d24a978c78fb3b1a9520ee25 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 2 Aug 2013 01:38:57 +0300 Subject: [PATCH 2070/4858] add test for multiline excerpt. see #624 --- features/post.feature | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/features/post.feature b/features/post.feature index f8de28f0ce..38dfb3a935 100644 --- a/features/post.feature +++ b/features/post.feature @@ -33,11 +33,23 @@ Feature: Manage WordPress posts It will be inserted in a post. """ + And a command.sh file: + """ + cat content.html | wp post create --post_title='Test post' --post_excerpt="A multiline + excerpt" --porcelain - + """ - When I run `wp post create --post_title='Test post' --porcelain - < content.html` + When I run `bash command.sh` Then STDOUT should match '%d' And save STDOUT as {POST_ID} + When I run `wp eval '$post_id = {POST_ID}; echo get_post( $post_id )->post_excerpt;'` + Then STDOUT should be: + """ + A multiline + excerpt + """ + When I run `wp post get --format=content {POST_ID}` Then STDOUT should be: """ From 8b21c3f17cd2eab2e6856aa96bf2772c031c3875 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 16:17:25 +0300 Subject: [PATCH 2071/4858] convert tabs to spaces only when displaying in the CLI --- php/commands/help.php | 3 +++ utils/convert-docs.php | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index fb42b8a400..e4686e155c 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -45,6 +45,9 @@ private static function show_help( $command ) { // definition lists $out = preg_replace( '/\n([^\n]+)\n: (.+?)\n/s', "\n\t\\1\n\t\t\\2\n", $out ); + // convert tabs to spaces + $out = preg_replace( '/^\t/m', " ", $out ); + $out = str_replace( "\t", ' ', $out ); echo WP_CLI::colorize( $out ); diff --git a/utils/convert-docs.php b/utils/convert-docs.php index 59c573347c..e898b0e629 100644 --- a/utils/convert-docs.php +++ b/utils/convert-docs.php @@ -12,9 +12,6 @@ function convert_file( $path ) { return "\n$arg\n: "; }, $out ); - // convert tabs to spaces - $out = preg_replace( '/^\t/m', " ", $out ); - // prepend docblock notation # $out = preg_replace( '/^(.*)/m', "\t* \\1", $out ); From 95ada7e37be56eac52115136760ff00467fc3779 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Sun, 4 Aug 2013 16:11:14 +0100 Subject: [PATCH 2072/4858] Clearer confirmation message when network-activating plugins --- php/commands/plugin.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e95c568452..c6f442835e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -89,7 +89,10 @@ function activate( $args, $assoc_args = array() ) { activate_plugin( $file, '', $network_wide ); if ( $this->check_active( $file, $network_wide ) ) { - WP_CLI::success( "Plugin '$name' activated." ); + if ( $network_wide ) + WP_CLI::success( "Plugin '$name' network activated." ); + else + WP_CLI::success( "Plugin '$name' activated." ); } else { WP_CLI::error( 'Could not activate plugin: ' . $name ); } @@ -109,7 +112,10 @@ function deactivate( $args, $assoc_args = array() ) { deactivate_plugins( $file, false, $network_wide ); if ( ! $this->check_active( $file, $network_wide ) ) { - WP_CLI::success( "Plugin '$name' deactivated." ); + if ( $network_wide ) + WP_CLI::success( "Plugin '$name' network deactivated." ); + else + WP_CLI::success( "Plugin '$name' deactivated." ); } else { WP_CLI::error( 'Could not deactivate plugin: ' . $name ); } From 95a445613c5e876cf71e21a36e97b4b0986f6e7e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 16:27:56 +0300 Subject: [PATCH 2073/4858] deprecate WP_CLI::add_man_dir() --- features/help.feature | 29 ----------------------------- php/class-wp-cli.php | 20 ++++++++------------ 2 files changed, 8 insertions(+), 41 deletions(-) diff --git a/features/help.feature b/features/help.feature index 3aef3dbcb5..10626d66a1 100644 --- a/features/help.feature +++ b/features/help.feature @@ -19,35 +19,6 @@ Feature: Get help about WP-CLI commands Then the return code should be 1 And STDERR should not be empty - Scenario: Help for third-party commands - Given a WP install - And a wp-content/plugins/test-cli/test-help.txt file: - """ - ## EXAMPLES - - wp test-help - """ - And a wp-content/plugins/test-cli/command.php file: - """ - <?php - // Plugin Name: Test CLI Help - - class Test_Help extends WP_CLI_Command { - function __invoke() {} - } - - WP_CLI::add_command( 'test-help', 'Test_Help' ); - - WP_CLI::add_man_dir( __DIR__, __DIR__ ); - """ - And I run `wp plugin activate test-cli` - - When I run `wp help test-help` - Then STDOUT should contain: - """ - wp test-help - """ - Scenario: Help for incomplete commands Given an empty directory diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1408f97288..da3a32be62 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -14,14 +14,10 @@ class WP_CLI { private static $hooks = array(), $hooks_passed = array(); - private static $man_dirs = array(); - /** * Initialize WP_CLI static variables. */ static function init() { - self::add_man_dir( null, WP_CLI_ROOT . "/man-src" ); - self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); } @@ -102,14 +98,6 @@ static function add_command( $name, $class, $args = array() ) { self::get_root_command()->add_subcommand( $name, $command ); } - static function add_man_dir( $deprecated = null, $src_dir ) { - self::$man_dirs[] = $src_dir; - } - - static function get_man_dirs() { - return self::$man_dirs; - } - /** * Display a message in the CLI and end with a newline * @@ -276,6 +264,14 @@ static function run_command( $args, $assoc_args = array() ) { self::get_runner()->run_command( $args, $assoc_args ); } + + + // DEPRECATED STUFF + + static function add_man_dir() { + trigger_error( 'WP_CLI::add_man_dir() is deprecated. Add docs inline.', E_USER_WARNING ); + } + // back-compat static function out( $str ) { echo $str; From 003239d8586931246d54b88e85af366a18d56ec1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 16:39:07 +0300 Subject: [PATCH 2074/4858] add extra newline if longdesc exists --- php/commands/help.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index e4686e155c..25048e6d1c 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -37,7 +37,10 @@ private static function find_subcommand( $args ) { private static function show_help( $command ) { $out = self::get_initial_markdown( $command ); - $out .= $command->get_longdesc(); + $longdesc = $command->get_longdesc(); + if ( $longdesc ) { + $out .= $longdesc . "\n"; + } // section headers $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); From 94cb592712bfe8ed053d1795a9c75934a3838027 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 16:45:28 +0300 Subject: [PATCH 2075/4858] convert-docs.php: indentation fixes --- php/commands/help.php | 3 --- utils/convert-docs.php | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 25048e6d1c..0e074f0877 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -48,9 +48,6 @@ private static function show_help( $command ) { // definition lists $out = preg_replace( '/\n([^\n]+)\n: (.+?)\n/s', "\n\t\\1\n\t\t\\2\n", $out ); - // convert tabs to spaces - $out = preg_replace( '/^\t/m', " ", $out ); - $out = str_replace( "\t", ' ', $out ); echo WP_CLI::colorize( $out ); diff --git a/utils/convert-docs.php b/utils/convert-docs.php index e898b0e629..b3b9668c8f 100644 --- a/utils/convert-docs.php +++ b/utils/convert-docs.php @@ -12,8 +12,12 @@ function convert_file( $path ) { return "\n$arg\n: "; }, $out ); + // fix indentation + $out = preg_replace( '/^ ([^ ]+)/m', "\t\\1", $out ); + $out = str_replace( "\t", ' ', $out ); + // prepend docblock notation - # $out = preg_replace( '/^(.*)/m', "\t* \\1", $out ); + $out = preg_replace( '/^/m', "\t * ", $out ); file_put_contents( $path, $out ); } From 1a62c552573909b643e97348ac4214ae2bf2c83f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 17:12:08 +0300 Subject: [PATCH 2076/4858] move docs from man-src/ into PHPDoc comments --- man-src/cache.txt | 5 - man-src/cap.txt | 10 -- man-src/comment-approve.txt | 9 -- man-src/comment-count.txt | 10 -- man-src/comment-create.txt | 14 --- man-src/comment-delete.txt | 13 --- man-src/comment-last.txt | 13 --- man-src/comment-spam.txt | 9 -- man-src/comment-status.txt | 9 -- man-src/comment-trash.txt | 9 -- man-src/comment-unapprove.txt | 9 -- man-src/comment-unspam.txt | 9 -- man-src/comment-untrash.txt | 9 -- man-src/core-config.txt | 40 -------- man-src/core-download.txt | 18 ---- man-src/core-init-tests.txt | 22 ----- man-src/core-install.txt | 21 ---- man-src/core-is-installed.txt | 5 - man-src/core-multisite-convert.txt | 14 --- man-src/core-multisite-install.txt | 30 ------ man-src/core-update-db.txt | 0 man-src/core-update.txt | 19 ---- man-src/core-version.txt | 5 - man-src/db.txt | 18 ---- man-src/eval-file.txt | 3 - man-src/eval.txt | 3 - man-src/export.txt | 54 ----------- man-src/help.txt | 7 -- man-src/import.txt | 13 --- man-src/media-import.txt | 45 --------- man-src/media-regenerate.txt | 15 --- man-src/network-meta.txt | 14 --- man-src/option.txt | 15 --- man-src/plugin-activate.txt | 9 -- man-src/plugin-deactivate.txt | 9 -- man-src/plugin-delete.txt | 9 -- man-src/plugin-install.txt | 33 ------- man-src/plugin-list.txt | 9 -- man-src/plugin-path.txt | 15 --- man-src/plugin-status.txt | 5 - man-src/plugin-toggle.txt | 9 -- man-src/plugin-uninstall.txt | 14 --- man-src/plugin-update-all.txt | 9 -- man-src/plugin-update.txt | 14 --- man-src/post-create.txt | 31 ------ man-src/post-delete.txt | 15 --- man-src/post-edit.txt | 9 -- man-src/post-generate.txt | 29 ------ man-src/post-get.txt | 22 ----- man-src/post-list.txt | 21 ---- man-src/post-meta.txt | 9 -- man-src/post-update.txt | 13 --- man-src/rewrite-dump.txt | 5 - man-src/rewrite-flush.txt | 7 -- man-src/rewrite-structure.txt | 14 --- man-src/role-create.txt | 15 --- man-src/role-delete.txt | 12 --- man-src/role-exists.txt | 16 --- man-src/role-list.txt | 13 --- man-src/scaffold-_s.txt | 21 ---- man-src/scaffold-child-theme.txt | 29 ------ man-src/scaffold-plugin-tests.txt | 17 ---- man-src/scaffold-plugin.txt | 9 -- man-src/scaffold-post-type.txt | 23 ----- man-src/scaffold-taxonomy.txt | 31 ------ man-src/search-replace.txt | 25 ----- man-src/shell.txt | 9 -- man-src/site-create.txt | 25 ----- man-src/site-delete.txt | 17 ---- man-src/site-empty.txt | 5 - man-src/term-create.txt | 29 ------ man-src/term-delete.txt | 13 --- man-src/term-list.txt | 19 ---- man-src/term-update.txt | 29 ------ man-src/theme-activate.txt | 5 - man-src/theme-delete.txt | 9 -- man-src/theme-install.txt | 25 ----- man-src/theme-list.txt | 9 -- man-src/theme-path.txt | 15 --- man-src/theme-status.txt | 5 - man-src/theme-update-all.txt | 9 -- man-src/theme-update.txt | 14 --- man-src/transient.txt | 3 - man-src/user-add-role.txt | 14 --- man-src/user-create.txt | 33 ------- man-src/user-delete.txt | 13 --- man-src/user-generate.txt | 9 -- man-src/user-get.txt | 19 ---- man-src/user-import-csv.txt | 16 --- man-src/user-list.txt | 21 ---- man-src/user-meta.txt | 9 -- man-src/user-remove-role.txt | 10 -- man-src/user-set-role.txt | 15 --- man-src/user-update.txt | 15 --- php/commands/cache.php | 6 +- php/commands/cap.php | 11 ++- php/commands/comment.php | 108 +++++++++++++++++++++ php/commands/core.php | 151 +++++++++++++++++++++++++++++ php/commands/db.php | 16 ++- php/commands/eval-file.php | 4 + php/commands/eval.php | 4 + php/commands/export.php | 44 +++++++++ php/commands/help.php | 8 ++ php/commands/import.php | 11 +++ php/commands/media.php | 53 ++++++++++ php/commands/network-meta.php | 13 ++- php/commands/option.php | 15 ++- php/commands/plugin.php | 127 ++++++++++++++++++++++++ php/commands/post-meta.php | 9 +- php/commands/post.php | 128 +++++++++++++++++++++++- php/commands/rewrite.php | 30 +++++- php/commands/role.php | 56 ++++++++++- php/commands/scaffold.php | 111 +++++++++++++++++++++ php/commands/search-replace.php | 23 +++++ php/commands/shell.php | 9 ++ php/commands/site.php | 39 ++++++++ php/commands/term.php | 77 +++++++++++++++ php/commands/theme.php | 88 +++++++++++++++++ php/commands/transient.php | 4 +- php/commands/user-meta.php | 9 +- php/commands/user.php | 151 +++++++++++++++++++++++++++++ 121 files changed, 1290 insertions(+), 1439 deletions(-) delete mode 100644 man-src/cache.txt delete mode 100644 man-src/cap.txt delete mode 100644 man-src/comment-approve.txt delete mode 100644 man-src/comment-count.txt delete mode 100644 man-src/comment-create.txt delete mode 100644 man-src/comment-delete.txt delete mode 100644 man-src/comment-last.txt delete mode 100644 man-src/comment-spam.txt delete mode 100644 man-src/comment-status.txt delete mode 100644 man-src/comment-trash.txt delete mode 100644 man-src/comment-unapprove.txt delete mode 100644 man-src/comment-unspam.txt delete mode 100644 man-src/comment-untrash.txt delete mode 100644 man-src/core-config.txt delete mode 100644 man-src/core-download.txt delete mode 100644 man-src/core-init-tests.txt delete mode 100644 man-src/core-install.txt delete mode 100644 man-src/core-is-installed.txt delete mode 100644 man-src/core-multisite-convert.txt delete mode 100644 man-src/core-multisite-install.txt delete mode 100644 man-src/core-update-db.txt delete mode 100644 man-src/core-update.txt delete mode 100644 man-src/core-version.txt delete mode 100644 man-src/db.txt delete mode 100644 man-src/eval-file.txt delete mode 100644 man-src/eval.txt delete mode 100644 man-src/export.txt delete mode 100644 man-src/help.txt delete mode 100644 man-src/import.txt delete mode 100644 man-src/media-import.txt delete mode 100644 man-src/media-regenerate.txt delete mode 100644 man-src/network-meta.txt delete mode 100644 man-src/option.txt delete mode 100644 man-src/plugin-activate.txt delete mode 100644 man-src/plugin-deactivate.txt delete mode 100644 man-src/plugin-delete.txt delete mode 100644 man-src/plugin-install.txt delete mode 100644 man-src/plugin-list.txt delete mode 100644 man-src/plugin-path.txt delete mode 100644 man-src/plugin-status.txt delete mode 100644 man-src/plugin-toggle.txt delete mode 100644 man-src/plugin-uninstall.txt delete mode 100644 man-src/plugin-update-all.txt delete mode 100644 man-src/plugin-update.txt delete mode 100644 man-src/post-create.txt delete mode 100644 man-src/post-delete.txt delete mode 100644 man-src/post-edit.txt delete mode 100644 man-src/post-generate.txt delete mode 100644 man-src/post-get.txt delete mode 100644 man-src/post-list.txt delete mode 100644 man-src/post-meta.txt delete mode 100644 man-src/post-update.txt delete mode 100644 man-src/rewrite-dump.txt delete mode 100644 man-src/rewrite-flush.txt delete mode 100644 man-src/rewrite-structure.txt delete mode 100644 man-src/role-create.txt delete mode 100644 man-src/role-delete.txt delete mode 100644 man-src/role-exists.txt delete mode 100644 man-src/role-list.txt delete mode 100644 man-src/scaffold-_s.txt delete mode 100644 man-src/scaffold-child-theme.txt delete mode 100644 man-src/scaffold-plugin-tests.txt delete mode 100644 man-src/scaffold-plugin.txt delete mode 100644 man-src/scaffold-post-type.txt delete mode 100644 man-src/scaffold-taxonomy.txt delete mode 100644 man-src/search-replace.txt delete mode 100644 man-src/shell.txt delete mode 100644 man-src/site-create.txt delete mode 100644 man-src/site-delete.txt delete mode 100644 man-src/site-empty.txt delete mode 100644 man-src/term-create.txt delete mode 100644 man-src/term-delete.txt delete mode 100644 man-src/term-list.txt delete mode 100644 man-src/term-update.txt delete mode 100644 man-src/theme-activate.txt delete mode 100644 man-src/theme-delete.txt delete mode 100644 man-src/theme-install.txt delete mode 100644 man-src/theme-list.txt delete mode 100644 man-src/theme-path.txt delete mode 100644 man-src/theme-status.txt delete mode 100644 man-src/theme-update-all.txt delete mode 100644 man-src/theme-update.txt delete mode 100644 man-src/transient.txt delete mode 100644 man-src/user-add-role.txt delete mode 100644 man-src/user-create.txt delete mode 100644 man-src/user-delete.txt delete mode 100644 man-src/user-generate.txt delete mode 100644 man-src/user-get.txt delete mode 100644 man-src/user-import-csv.txt delete mode 100644 man-src/user-list.txt delete mode 100644 man-src/user-meta.txt delete mode 100644 man-src/user-remove-role.txt delete mode 100644 man-src/user-set-role.txt delete mode 100644 man-src/user-update.txt diff --git a/man-src/cache.txt b/man-src/cache.txt deleted file mode 100644 index 70856ff26f..0000000000 --- a/man-src/cache.txt +++ /dev/null @@ -1,5 +0,0 @@ -## EXAMPLES - - wp cache set my_key my_value my_group 300 - - wp cache get my_key my_group diff --git a/man-src/cap.txt b/man-src/cap.txt deleted file mode 100644 index 73b0921b18..0000000000 --- a/man-src/cap.txt +++ /dev/null @@ -1,10 +0,0 @@ -## EXAMPLES - - # Add 'spectate' capability to 'author' role - wp cap add 'author' 'spectate' - - # Add all caps from 'editor' role to 'author' role - wp cap list 'editor' | xargs wp cap add 'author' - - # Remove all caps from 'editor' role that also appear in 'author' role - wp cap list 'author' | xargs wp cap remove 'editor' diff --git a/man-src/comment-approve.txt b/man-src/comment-approve.txt deleted file mode 100644 index f703cd04b2..0000000000 --- a/man-src/comment-approve.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to approve. - -## EXAMPLES - - wp comment approve 1337 diff --git a/man-src/comment-count.txt b/man-src/comment-count.txt deleted file mode 100644 index 0c595e3701..0000000000 --- a/man-src/comment-count.txt +++ /dev/null @@ -1,10 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the post to count comments in - -## EXAMPLES - - wp comment count - wp comment count 42 diff --git a/man-src/comment-create.txt b/man-src/comment-create.txt deleted file mode 100644 index 0b093d2f08..0000000000 --- a/man-src/comment-create.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* `--<field>`=<value>: - - Field values for the new comment. See wp_insert_comment(). - -* `--porcelain`: - - Output just the new comment id. - -## EXAMPLES - - wp comment create --comment_post_ID=15 --comment_content="hello blog" ---comment_author="wp-cli" diff --git a/man-src/comment-delete.txt b/man-src/comment-delete.txt deleted file mode 100644 index bd39300f79..0000000000 --- a/man-src/comment-delete.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to delete. - -* `--force`: - - Skip the trash bin. - -## EXAMPLES - - wp comment delete 1337 --force diff --git a/man-src/comment-last.txt b/man-src/comment-last.txt deleted file mode 100644 index 34504ec539..0000000000 --- a/man-src/comment-last.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `--id`: - - Output just the last comment id. - -* `--full`: - - Output complete comment information. - -## EXAMPLES - - wp comment last --full diff --git a/man-src/comment-spam.txt b/man-src/comment-spam.txt deleted file mode 100644 index b1a446cf19..0000000000 --- a/man-src/comment-spam.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to mark as spam. - -## EXAMPLES - - wp comment spam 1337 diff --git a/man-src/comment-status.txt b/man-src/comment-status.txt deleted file mode 100644 index a53c32765b..0000000000 --- a/man-src/comment-status.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to check - -## EXAMPLES - - wp comment status 1337 diff --git a/man-src/comment-trash.txt b/man-src/comment-trash.txt deleted file mode 100644 index 3d1388178a..0000000000 --- a/man-src/comment-trash.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to trash. - -## EXAMPLES - - wp comment trash 1337 diff --git a/man-src/comment-unapprove.txt b/man-src/comment-unapprove.txt deleted file mode 100644 index 5569199c4c..0000000000 --- a/man-src/comment-unapprove.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to unapprove. - -## EXAMPLES - - wp comment unapprove 1337 diff --git a/man-src/comment-unspam.txt b/man-src/comment-unspam.txt deleted file mode 100644 index 1a055d2ced..0000000000 --- a/man-src/comment-unspam.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to unmark as spam. - -## EXAMPLES - - wp comment unspam 1337 diff --git a/man-src/comment-untrash.txt b/man-src/comment-untrash.txt deleted file mode 100644 index 54fe15eb21..0000000000 --- a/man-src/comment-untrash.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the comment to untrash. - -## EXAMPLES - - wp comment untrash 1337 diff --git a/man-src/core-config.txt b/man-src/core-config.txt deleted file mode 100644 index 9945a05c38..0000000000 --- a/man-src/core-config.txt +++ /dev/null @@ -1,40 +0,0 @@ -## OPTIONS - -* `--dbname`=<dbname>: - - Set the database name. - -* `--dbuser`=<dbuser>: - - Set the database user. - -* `--dbpass`=<dbpass>: - - Set the database user password. - -* `--dbhost`=<dbhost>: - - Set the database host. Default: 'localhost' - -* `--dbprefix`=<dbprefix>: - - Set the database table prefix. Default: 'wp_' - -* `--locale`=<locale>: - - Set the WPLANG constant. Defaults to $wp_local_package variable. - -* `--extra-php`: - - If set, the command reads additional PHP code from STDIN. - -## EXAMPLES - - # Standard wp-config.php file - wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --locale=ro_RO - - # Enable WP_DEBUG and WP_DEBUG_LOG - wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP - define( 'WP_DEBUG', true ); - define( 'WP_DEBUG_LOG', true ); - PHP diff --git a/man-src/core-download.txt b/man-src/core-download.txt deleted file mode 100644 index a72ecc610e..0000000000 --- a/man-src/core-download.txt +++ /dev/null @@ -1,18 +0,0 @@ -## OPTIONS - -* `--locale`=<locale>: - - Select which language you want to download. The --version parameter is -ignored in this case. - -* `--version`=<version>: - - Select which version you want to download. - -* `--force`: - - Overwrites existing files, if present. - -## EXAMPLES - - wp core download --version=3.3 diff --git a/man-src/core-init-tests.txt b/man-src/core-init-tests.txt deleted file mode 100644 index 55d72eafc4..0000000000 --- a/man-src/core-init-tests.txt +++ /dev/null @@ -1,22 +0,0 @@ -## OPTIONS - -* `<path>`: - - The directory in which to download the testing suite files. (Optional) - -* `--dbname`=<dbname>: - - Set the database name. **WARNING**: The database will be whipped every time -you run the tests. - -* `--dbuser`=<dbuser>: - - Set the database user. - -* `--dbpass`=<dbpass>: - - Set the database user password. - -## EXAMPLE - - wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test diff --git a/man-src/core-install.txt b/man-src/core-install.txt deleted file mode 100644 index 711410e55a..0000000000 --- a/man-src/core-install.txt +++ /dev/null @@ -1,21 +0,0 @@ -## OPTIONS - -* `--url`=<url>: - - The address of the new site. - -* `--title`=<site-title>: - - The title of the new site. - -* `--admin_name`=<username>: - - The name of the admin user. Default: 'admin' - -* `--admin_password`=<password>: - - The password for the admin user. - -* `--admin_email`=<email>: - - The email address for the admin user. diff --git a/man-src/core-is-installed.txt b/man-src/core-is-installed.txt deleted file mode 100644 index afccd6c95b..0000000000 --- a/man-src/core-is-installed.txt +++ /dev/null @@ -1,5 +0,0 @@ -## EXAMPLES - - if ! $(wp core is-installed); then - wp core install - fi diff --git a/man-src/core-multisite-convert.txt b/man-src/core-multisite-convert.txt deleted file mode 100644 index 24494f1170..0000000000 --- a/man-src/core-multisite-convert.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* `--title`=<site-title>: - - The title of the new network. - -* `--base`=<url-path>: - - Base path after the domain name that each site url will start with. -Default: '/' - -* `--subdomains`: - - If passed, the network will use subdomains, instead of subdirectories. diff --git a/man-src/core-multisite-install.txt b/man-src/core-multisite-install.txt deleted file mode 100644 index eb9d7bd4d6..0000000000 --- a/man-src/core-multisite-install.txt +++ /dev/null @@ -1,30 +0,0 @@ -## OPTIONS - -* `--url`=<url>: - - The address of the new site. - -* `--base`=<url-path>: - - Base path after the domain name that each site url in the network will start with. -Default: '/' - -* `--subdomains`: - - If passed, the network will use subdomains, instead of subdirectories. - -* `--title`=<site-title>: - - The title of the new site. - -* `--admin_name`=<username>: - - The name of the admin user. Default: 'admin' - -* `--admin_password`=<password>: - - The password for the admin user. - -* `--admin_email`=<email>: - - The email address for the admin user. diff --git a/man-src/core-update-db.txt b/man-src/core-update-db.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/man-src/core-update.txt b/man-src/core-update.txt deleted file mode 100644 index 50caa5f2eb..0000000000 --- a/man-src/core-update.txt +++ /dev/null @@ -1,19 +0,0 @@ -## OPTIONS - -* `--version=`<new_version> [package/zip]: - - When passed, updates to new_version, optionally using package/zip as -input. - -* `--force`: - - Will update even when current WP version < passed version. Use with -caution. - -## EXAMPLES - - wp core update - - wp core update --version=3.4 ../latest.zip - - wp core update --version=3.1 --force diff --git a/man-src/core-version.txt b/man-src/core-version.txt deleted file mode 100644 index d1c5d6a6d9..0000000000 --- a/man-src/core-version.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `--extra`: - - Show extended version information. diff --git a/man-src/db.txt b/man-src/db.txt deleted file mode 100644 index d7ccfb703d..0000000000 --- a/man-src/db.txt +++ /dev/null @@ -1,18 +0,0 @@ -## OPTIONS - -* `--yes`: - - Answer yes to the confirmation message. - -* `<file>`: - - The name of the export file. If omitted, it will be '{dbname}.sql' - -* `<SQL>`: - - A SQL query. - -## EXAMPLES - - # execute a query stored in a file - wp db query < debug.sql diff --git a/man-src/eval-file.txt b/man-src/eval-file.txt deleted file mode 100644 index 57a808c109..0000000000 --- a/man-src/eval-file.txt +++ /dev/null @@ -1,3 +0,0 @@ -## EXAMPLES - - wp eval-file my-code.php diff --git a/man-src/eval.txt b/man-src/eval.txt deleted file mode 100644 index 699b93f2ee..0000000000 --- a/man-src/eval.txt +++ /dev/null @@ -1,3 +0,0 @@ -## EXAMPLES - - wp eval 'echo WP_CONTENT_DIR;' diff --git a/man-src/export.txt b/man-src/export.txt deleted file mode 100644 index dcb8ea478c..0000000000 --- a/man-src/export.txt +++ /dev/null @@ -1,54 +0,0 @@ -## OPTIONS - -* `--dir`=<dirname>: - - Full path to directory where WXR export files should be stored. Defaults -to current working directory. - -* `--skip_comments`: - - Don't export comments. - -* `--file_item_count`=<count>: - - Break export into files with N posts. - -* `--verbose`: - - Show more information about the process on STDOUT. - -## FILTERS - -* `--start_date`=<date>: - - Export only posts newer than this date, in format YYYY-MM-DD. - -* `--end_date`=<date>: - - Export only posts older than this date, in format YYYY-MM-DD. - -* `--post_type`=<post_type>: - - Export only posts with this post_type. - -* `--post__in`=<pid>: - - Export all posts specified as a comma-separated list of IDs. - -* `--author`=<login/id>: - - Export only posts by this author. - -* `--category`=<category-id>: - - Export only posts in this category. - -* `--post_status`=<status>: - - Export only posts with this status. - -## EXAMPLES - - wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 - - wp export --dir=/tmp/ --post__in=123,124,125 diff --git a/man-src/help.txt b/man-src/help.txt deleted file mode 100644 index 19e660f7c4..0000000000 --- a/man-src/help.txt +++ /dev/null @@ -1,7 +0,0 @@ -## EXAMPLES - - # get help for `core` command - wp help core - - # get help for `core download` subcommand - wp help core download diff --git a/man-src/import.txt b/man-src/import.txt deleted file mode 100644 index 5f4e3dedf4..0000000000 --- a/man-src/import.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `<file>`: - - Path to a valid WXR file for importing. - -* `--authors=<authors>`: - - How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. - -* `--skip=<data-type>`: - - Skip importing specific data. Supported option is 'attachment'. diff --git a/man-src/media-import.txt b/man-src/media-import.txt deleted file mode 100644 index 5f7e7d1dce..0000000000 --- a/man-src/media-import.txt +++ /dev/null @@ -1,45 +0,0 @@ -## OPTIONS - -* `<file>`: - - Path to file or files to be imported. Supports the glob(3) capabilities of the current shell. - If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be - downloaded to a temp file before being sideloaded. - -* `--post_id=<post_id>` - - ID of the post to attach the imported files to - -* `--title=<title>` - - Attachment title (post title field) - -* `--caption=<caption>` - - Caption for attachent (post excerpt field) - -* `--alt=<alt_text>` - - Alt text for image (saved as post meta) - -* `--desc=<description>` - - "Description" field (post content) of attachment post - -* `--featured_image` - - If set, set the imported image as the Featured Image of the post its attached to. - - -## EXAMPLES - - # Import all jpgs in the current user's "Pictures" directory, not attached to any post - wp media import ~/Pictures/**/*.jpg - - # Import a local image and set it to be the post thumbnail for a post - wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image - - # Import an image from the web - wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" - - diff --git a/man-src/media-regenerate.txt b/man-src/media-regenerate.txt deleted file mode 100644 index f873f53494..0000000000 --- a/man-src/media-regenerate.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `--yes`: - - Answer yes to the confirmation message. - -* `<attachment-id>`: - - One or more IDs of the attachments to regenerate. - -## EXAMPLES - - wp media regenerate 123 1337 - - wp media regenerate --yes \ No newline at end of file diff --git a/man-src/network-meta.txt b/man-src/network-meta.txt deleted file mode 100644 index c1899f2d47..0000000000 --- a/man-src/network-meta.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* `<id>`: - - The network id (usually 1). - -* `--format=json`: - - Encode/decode values as JSON. - -## EXAMPLES - - # get a list of super-admins - wp network-meta get 1 site_admins diff --git a/man-src/option.txt b/man-src/option.txt deleted file mode 100644 index 99c8aab055..0000000000 --- a/man-src/option.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `--format=json`: - - Encode/decode values as JSON. - -## EXAMPLES - - wp option get siteurl - - wp option add my_option foobar - - wp option update my_option '{"foo": "bar"}' --format=json - - wp option delete my_option diff --git a/man-src/plugin-activate.txt b/man-src/plugin-activate.txt deleted file mode 100644 index 5558338912..0000000000 --- a/man-src/plugin-activate.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<plugin>`: - - The plugin to activate. - -* `--network`: - - If set, the plugin will be activated for the entire multisite network. diff --git a/man-src/plugin-deactivate.txt b/man-src/plugin-deactivate.txt deleted file mode 100644 index 12be8084cb..0000000000 --- a/man-src/plugin-deactivate.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<plugin>`: - - The plugin to deactivate. - -* `--network`: - - If set, the plugin will be deactivated for the entire multisite network. diff --git a/man-src/plugin-delete.txt b/man-src/plugin-delete.txt deleted file mode 100644 index 111865f594..0000000000 --- a/man-src/plugin-delete.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* <plugin>: - - The plugin to delete. - -## EXAMPLES - - wp plugin delete hello diff --git a/man-src/plugin-install.txt b/man-src/plugin-install.txt deleted file mode 100644 index e896cca2fe..0000000000 --- a/man-src/plugin-install.txt +++ /dev/null @@ -1,33 +0,0 @@ -## OPTIONS - -* <plugin|zip|url>: - - A plugin slug, the path to a local zip file, or URL to a remote zip file. - -* `--version`=<version>: - - If set, get that particular version from wordpress.org, instead of the -stable version. - -* `--force`: - - If set, the command will overwrite any installed version of the plugin, without prompting -for confirmation. - -* `--activate`: - - If set, the plugin will be activated immediately after install. - -## EXAMPLES - - # Install the latest version from wordpress.org and activate - wp plugin install bbpress --activate - - # Install the development version from wordpress.org - wp plugin install bbpress --version=dev - - # Install from a local zip file - wp plugin install ../my-plugin.zip - - # Install from a remote zip file - wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef diff --git a/man-src/plugin-list.txt b/man-src/plugin-list.txt deleted file mode 100644 index 8d2344d887..0000000000 --- a/man-src/plugin-list.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--format`=<format>: - - Output list as table, CSV or JSON. Defaults to table. - -## EXAMPLES - - wp plugin list --format=json diff --git a/man-src/plugin-path.txt b/man-src/plugin-path.txt deleted file mode 100644 index a190a77023..0000000000 --- a/man-src/plugin-path.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `<plugin>`: - - The plugin to get the path to. If not set, will return the path to the -plugins directory. - -* `--dir`: - - If set, get the path to the closest parent directory, instead of the -plugin file. - -## EXAMPLES - - cd $(wp theme path) diff --git a/man-src/plugin-status.txt b/man-src/plugin-status.txt deleted file mode 100644 index 6902ac2709..0000000000 --- a/man-src/plugin-status.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `<plugin>`: - - A particular plugin to show the status for. \ No newline at end of file diff --git a/man-src/plugin-toggle.txt b/man-src/plugin-toggle.txt deleted file mode 100644 index 97e284aed0..0000000000 --- a/man-src/plugin-toggle.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<plugin>`: - - The plugin to toggle. - -* `--network`: - - If set, the plugin will be toggled for the entire multisite network. diff --git a/man-src/plugin-uninstall.txt b/man-src/plugin-uninstall.txt deleted file mode 100644 index ea41bcbf1a..0000000000 --- a/man-src/plugin-uninstall.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* <plugin>: - - The plugin to uninstall. - -* `--no-delete`: - - If set, the plugin files will not be deleted. Only the uninstall procedure -will be run. - -## EXAMPLES - - wp plugin uninstall hello diff --git a/man-src/plugin-update-all.txt b/man-src/plugin-update-all.txt deleted file mode 100644 index 8ba4aaa513..0000000000 --- a/man-src/plugin-update-all.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--dry-run`: - - Pretend to do the updates, to see what would happen. - -## EXAMPLES - - wp plugin update-all diff --git a/man-src/plugin-update.txt b/man-src/plugin-update.txt deleted file mode 100644 index 563c303735..0000000000 --- a/man-src/plugin-update.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* <plugin>: - - The plugin to update. - -* `--version=dev`: - - If set, the plugin will be updated to the latest development version, -regardless of what version is currently installed. - -## EXAMPLES - - wp plugin update bbpress --version=dev diff --git a/man-src/post-create.txt b/man-src/post-create.txt deleted file mode 100644 index 770713c9c4..0000000000 --- a/man-src/post-create.txt +++ /dev/null @@ -1,31 +0,0 @@ -## OPTIONS - -* `<filename>`: - - Read post content from <filename>. If this value is present, the - `--post_content` argument will be ignored. - - Passing `-` as the filename will cause post content to - be read from STDIN. - -* `--<field>`=<value>: - - Field values for the new post. See wp_insert_post(). - -* `--edit`: - - Immediately open system's editor to write or edit post content. - - (If content is read from a file, from STDIN, or from the `--post_content` - argument, that text will be loaded into the editor; otherwise, an empty - file will be opened.) - -* `--porcelain`: - - Output just the new post id. - -## EXAMPLES - - wp post create --post_type=page --post_status=publish --post_title='A future post' --post-status=future --post_date='2020-12-01 07:00:00' - - wp post create page.txt --post_type=page --post_title='Page from file' diff --git a/man-src/post-delete.txt b/man-src/post-delete.txt deleted file mode 100644 index d2a614bd81..0000000000 --- a/man-src/post-delete.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the post to delete. - -* `--force`: - - Skip the trash bin. - -## EXAMPLES - - wp post delete 123 --force - - wp post delete $(wp post list --post_type='page' --format=ids) diff --git a/man-src/post-edit.txt b/man-src/post-edit.txt deleted file mode 100644 index 6e3607984e..0000000000 --- a/man-src/post-edit.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<id>`: - - The ID of the post to edit. - -## EXAMPLES - - wp post edit 123 diff --git a/man-src/post-generate.txt b/man-src/post-generate.txt deleted file mode 100644 index 7dba04a6f6..0000000000 --- a/man-src/post-generate.txt +++ /dev/null @@ -1,29 +0,0 @@ -## 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 - -* `--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 diff --git a/man-src/post-get.txt b/man-src/post-get.txt deleted file mode 100644 index 9b79b9ce97..0000000000 --- a/man-src/post-get.txt +++ /dev/null @@ -1,22 +0,0 @@ -## OPTIONS - -* `[--format=<format>]`: - - The format to use when printing the post, acceptable values: - - **content**: Outputs only the post's content. - - **table**: Outputs all fields of the post as a table. Note that the - post_content field is omitted so that the table is readable. - - **json**: Outputs all fields in JSON format. - -* `<id>`: - - The ID of the post to get. - -## EXAMPLES - - wp post get 12 --format=content - - wp post get 12 > file.txt diff --git a/man-src/post-list.txt b/man-src/post-list.txt deleted file mode 100644 index 098d41c743..0000000000 --- a/man-src/post-list.txt +++ /dev/null @@ -1,21 +0,0 @@ -## OPTIONS - -* `--<field>`=<value>: - - One or more args to pass to WP_Query. - -* `--fields`=<fields>: - - Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. - -* `--format`=<format>: - - Output list as table, CSV, JSON, or simply IDs. Defaults to table. - -## EXAMPLES - - wp post list --format=ids - - wp post list --post_type=post --posts_per_page=5 --format=json - - wp post list --post_type=page --fields=post_title,post_status diff --git a/man-src/post-meta.txt b/man-src/post-meta.txt deleted file mode 100644 index eeadc606ff..0000000000 --- a/man-src/post-meta.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--format=json`: - - Encode/decode values as JSON. - -## EXAMPLES - - wp post-meta set 123 _wp_page_template about.php diff --git a/man-src/post-update.txt b/man-src/post-update.txt deleted file mode 100644 index 0fd825e24b..0000000000 --- a/man-src/post-update.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `<ID>`: - - The ID of the post to update. - -* `--<field>`=<value>: - - One or more fields to update. See wp_update_post(). - -## EXAMPLES - - wp post update 123 --post_name=something --post_status=draft diff --git a/man-src/rewrite-dump.txt b/man-src/rewrite-dump.txt deleted file mode 100644 index f15473d02c..0000000000 --- a/man-src/rewrite-dump.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `--format=json`: - - Output rules in JSON format. diff --git a/man-src/rewrite-flush.txt b/man-src/rewrite-flush.txt deleted file mode 100644 index 60ae94af8c..0000000000 --- a/man-src/rewrite-flush.txt +++ /dev/null @@ -1,7 +0,0 @@ -## OPTIONS - -* `--soft`: - - Perform a soft flush - do not overwrite `.htaccess`. The default is to update - `.htaccess` rules as well as rewrite rules in database. - diff --git a/man-src/rewrite-structure.txt b/man-src/rewrite-structure.txt deleted file mode 100644 index 9dec9d860e..0000000000 --- a/man-src/rewrite-structure.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* <permastruct>: - - The new permalink structure to apply; like "/%year%/%monthnum%/%postname%". - -* `--category-base`=<categorybase>: - - Set the base for category permalinks, ie '/category/'. - -* `--tag-base`=<tagbase>: - - Set the base for tag permalinks, ie '/tag/'. - diff --git a/man-src/role-create.txt b/man-src/role-create.txt deleted file mode 100644 index dde7db553f..0000000000 --- a/man-src/role-create.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* <role-key>: - - The internal name of the role, e.g. editor - -* <role-name>: - - The publically visible name of the role, e.g. Editor - -## EXAMPLES - - wp role create approver Approver - - wp role create productadmin "Product Administrator" diff --git a/man-src/role-delete.txt b/man-src/role-delete.txt deleted file mode 100644 index f8519240d2..0000000000 --- a/man-src/role-delete.txt +++ /dev/null @@ -1,12 +0,0 @@ -## OPTIONS - -* <role-key>: - - The internal name of the role, e.g. editor - -## EXAMPLES - - wp role delete approver - - wp role delete productadmin - diff --git a/man-src/role-exists.txt b/man-src/role-exists.txt deleted file mode 100644 index 28a8ee0a50..0000000000 --- a/man-src/role-exists.txt +++ /dev/null @@ -1,16 +0,0 @@ -## OPTIONS - -* <role-key>: - - The internal name of the role, e.g. editor - - -##DESCRIPTION - -Will exit with status 0 if the role exists, 1 if it does not. - - -## EXAMPLES - - wp role exists editor - diff --git a/man-src/role-list.txt b/man-src/role-list.txt deleted file mode 100644 index 2b79401613..0000000000 --- a/man-src/role-list.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `--fields`=<fields>: - - Limit the output to specific object fields. Defaults to name,role. - -* `--format`=<format>: - - Output list as table, CSV or JSON. Defaults to table. - -## EXAMPLES - - wp role list --fields=role --format=csv diff --git a/man-src/scaffold-_s.txt b/man-src/scaffold-_s.txt deleted file mode 100644 index 82c57a8abb..0000000000 --- a/man-src/scaffold-_s.txt +++ /dev/null @@ -1,21 +0,0 @@ -## OPTIONS - -* <slug>: - - The slug for the new theme, used for prefixing functions. - -* `--activate`: - - Activate the newly downloaded theme. - -* `--theme_name=<title>`: - - What to put in the 'Theme Name:' header in style.css - -* `--author=<full name>`: - - What to put in the 'Author:' header in style.css - -* `--author_uri=<http url>`: - - What to put in the 'Author URI:' header in style.css \ No newline at end of file diff --git a/man-src/scaffold-child-theme.txt b/man-src/scaffold-child-theme.txt deleted file mode 100644 index 2f05ab25f4..0000000000 --- a/man-src/scaffold-child-theme.txt +++ /dev/null @@ -1,29 +0,0 @@ -## OPTIONS - -* <slug>: - - The slug for the new child theme. - -* `--parent_theme=<slug>`: - - What to put in the 'Template:' header in style.css - -* `--theme_name=<title>`: - - What to put in the 'Theme Name:' header in style.css - -* `--author=<full name>`: - - What to put in the 'Author:' header in style.css - -* `--author_uri=<http url>`: - - What to put in the 'Author URI:' header in style.css - -* `--theme_uri=<http url>`: - - What to put in the 'Theme URI:' header in style.css - -* `--activate`: - - Activate the newly created child theme. diff --git a/man-src/scaffold-plugin-tests.txt b/man-src/scaffold-plugin-tests.txt deleted file mode 100644 index 7224977bdf..0000000000 --- a/man-src/scaffold-plugin-tests.txt +++ /dev/null @@ -1,17 +0,0 @@ -## DESCRIPTION - -These are the files that are generated: - -* `phpunit.xml` is the configuration file for PHPUnit -* `.travis.yml` is the configuration file for Travis CI -* `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite -* `tests/test-sample.php` is a sample file containing the actual tests - -## ENVIRONMENT - -The `tests/bootstrap.php` file looks for the WP_TESTS_DIR environment -variable. - -## EXAMPLE - - wp scaffold plugin-tests hello diff --git a/man-src/scaffold-plugin.txt b/man-src/scaffold-plugin.txt deleted file mode 100644 index bea18ef97e..0000000000 --- a/man-src/scaffold-plugin.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--activate`: - - Activate the newly generated plugin. - -* `--plugin_name=<title>`: - - What to put in the 'Plugin Name:' header diff --git a/man-src/scaffold-post-type.txt b/man-src/scaffold-post-type.txt deleted file mode 100644 index e164c1f3bc..0000000000 --- a/man-src/scaffold-post-type.txt +++ /dev/null @@ -1,23 +0,0 @@ -## OPTIONS - -* `--label=<label>`: - - The text used to translate the update messages - -* `--textdomain=<textdomain>`: - - The textdomain to use for the labels. - -* `--theme`: - - Create a file in the active theme directory, instead of sending to -STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. - -* `--plugin=<plugin>`: - - Create a file in the given plugin's directory, instead of sending to -STDOUT. - -* `--raw`: - - Just generate the `register_post_type()` call and nothing else. diff --git a/man-src/scaffold-taxonomy.txt b/man-src/scaffold-taxonomy.txt deleted file mode 100644 index 1015bf54c0..0000000000 --- a/man-src/scaffold-taxonomy.txt +++ /dev/null @@ -1,31 +0,0 @@ -## OPTIONS - -* `--post_types=<post_types>`: - - Post types to register for use with the taxonomy. - -* `--label=<label>`: - - The text used to translate the update messages - -* `--textdomain=<textdomain>`: - - The textdomain to use for the labels. - -* `--theme`: - - Create a file in the active theme directory, instead of sending to -STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. - -* `--plugin=<plugin>`: - - Create a file in the given plugin's directory, instead of sending to -STDOUT. - -* `--raw`: - - Just generate the `register_taxonomy()` call and nothing else. - -## EXAMPLES - - wp scaffold taxonomy venue --post_types=event,presentation diff --git a/man-src/search-replace.txt b/man-src/search-replace.txt deleted file mode 100644 index 812dfcc97d..0000000000 --- a/man-src/search-replace.txt +++ /dev/null @@ -1,25 +0,0 @@ -## 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 - -* `--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. - -## 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 diff --git a/man-src/shell.txt b/man-src/shell.txt deleted file mode 100644 index 7dd583a28f..0000000000 --- a/man-src/shell.txt +++ /dev/null @@ -1,9 +0,0 @@ -## DESCRIPTION - -`wp shell` allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example. - -## OPTIONS - -* `--basic`: - - Start in fail-safe mode, even if Boris is available. diff --git a/man-src/site-create.txt b/man-src/site-create.txt deleted file mode 100644 index 84c3df9856..0000000000 --- a/man-src/site-create.txt +++ /dev/null @@ -1,25 +0,0 @@ -## OPTIONS - -* `--slug`=<slug>: - - Path for the new site. Subdomain on subdomain installs, directory on subdirectory installs. - -* `--title`=<title>: - - Title of the new site. Default: prettified slug. - -* `--email`=<email>: - - Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included. - -* `--network_id`=<network-id>: - - Network to associate new site with. Defaults to current network (typically 1). - -* `--private`: - - If set, the new site will be non-public (not indexed) - -* `--porcelain`: - - If set, only the site id will be output on success. diff --git a/man-src/site-delete.txt b/man-src/site-delete.txt deleted file mode 100644 index f119826b96..0000000000 --- a/man-src/site-delete.txt +++ /dev/null @@ -1,17 +0,0 @@ -## OPTIONS - -* `<blog-id>`: - - The id of the blog to delete. If not provided, you must set the --slug parameter. - -* `--slug`=<slug>: - - Path of the blog to be deleted. Subdomain on subdomain installs, directory on subdirectory installs. - -* `--yes`: - - Answer yes to the confirmation message. - -* `--keep-tables`: - - Delete the blog from the list, but don't drop it's tables. diff --git a/man-src/site-empty.txt b/man-src/site-empty.txt deleted file mode 100644 index bbb41c593f..0000000000 --- a/man-src/site-empty.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `--yes`: - - Proceed to empty the site without a confirmation prompt. \ No newline at end of file diff --git a/man-src/term-create.txt b/man-src/term-create.txt deleted file mode 100644 index 46b85b9f05..0000000000 --- a/man-src/term-create.txt +++ /dev/null @@ -1,29 +0,0 @@ -## OPTIONS - -* `<term>`: - - A name for the new term. - -* `<taxonomy>`: - - Taxonomy for the new term. - -* `--slug`=<slug>: - - A unique slug for the new term. Defaults to sanitized version of name. - -* `--description`=<description>: - - A description for the new term. - -* `--parent`=<term-id>: - - A parent for the new term. - -* `--porcelain`: - - Output just the new term id. - -## EXAMPLES - - wp term create Apple category --description="A type of fruit" diff --git a/man-src/term-delete.txt b/man-src/term-delete.txt deleted file mode 100644 index 03f23097d2..0000000000 --- a/man-src/term-delete.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `<term-id>`: - - ID for the term to delete. - -* `<taxonomy>`: - - Taxonomy of the term to delete. - -## EXAMPLES - - wp term delete 15 category \ No newline at end of file diff --git a/man-src/term-list.txt b/man-src/term-list.txt deleted file mode 100644 index 18cd0a4ed1..0000000000 --- a/man-src/term-list.txt +++ /dev/null @@ -1,19 +0,0 @@ -## OPTIONS - -* `<taxonomy>`: - - List terms of a given taxonomy. - -* `--fields`=<fields>: - - Limit the output to specific object fields. Defaults to all of the term object fields. - -* `--format`=<format>: - - Output list as table, CSV, JSON, or simply IDs. Defaults to table. - -## EXAMPLES - - wp term list category --format=csv - - wp term list post_tag --fields=name,slug diff --git a/man-src/term-update.txt b/man-src/term-update.txt deleted file mode 100644 index cc6bc6cf91..0000000000 --- a/man-src/term-update.txt +++ /dev/null @@ -1,29 +0,0 @@ -## OPTIONS - -* `<term-id>`: - - ID for the term to update. - -* `<taxonomy>`: - - Taxonomy of the term to update. - -* `--name`=<name>: - - A new name for the term. - -* `--slug`=<slug>: - - A new slug for the term. - -* `--description`=<description>: - - A new description for the term. - -* `--parent`=<term-id>: - - A new parent for the term. - -## EXAMPLES - - wp term update 15 category --name=Apple diff --git a/man-src/theme-activate.txt b/man-src/theme-activate.txt deleted file mode 100644 index c740472400..0000000000 --- a/man-src/theme-activate.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `<theme>`: - - The theme to activate. diff --git a/man-src/theme-delete.txt b/man-src/theme-delete.txt deleted file mode 100644 index 030f781e4c..0000000000 --- a/man-src/theme-delete.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `<theme>`: - - The theme to delete. - -## EXAMPLES - - wp theme delete twentyeleven diff --git a/man-src/theme-install.txt b/man-src/theme-install.txt deleted file mode 100644 index b8eced70c7..0000000000 --- a/man-src/theme-install.txt +++ /dev/null @@ -1,25 +0,0 @@ -## OPTIONS - -* `<theme|zip|url>`: - - A theme slug, the path to a local zip file, or URL to a remote zip file. - -* `--force`: - - If set, the command will overwrite any installed version of the theme, without prompting -for confirmation. - -* `--activate`: - - If set, the theme will be activated immediately after install. - -## EXAMPLES - - # Install the latest version from wordpress.org and activate - wp theme install twentytwelve --activate - - # Install from a local zip file - wp theme install ../my-theme.zip - - # Install from a remote zip file - wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef diff --git a/man-src/theme-list.txt b/man-src/theme-list.txt deleted file mode 100644 index b875caeed5..0000000000 --- a/man-src/theme-list.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--format`=<format>: - - Output list as table, CSV or JSON. Defaults to table. - -## EXAMPLES - - wp theme list --format=csv diff --git a/man-src/theme-path.txt b/man-src/theme-path.txt deleted file mode 100644 index d54cec5b15..0000000000 --- a/man-src/theme-path.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `<theme>`: - - The theme to get the path to. If not set, will return the path to the -themes directory. - -* `--dir`: - - If set, get the path to the closest parent directory, instead of the -theme file. - -## EXAMPLES - - cd $(wp theme path) diff --git a/man-src/theme-status.txt b/man-src/theme-status.txt deleted file mode 100644 index f4aa713355..0000000000 --- a/man-src/theme-status.txt +++ /dev/null @@ -1,5 +0,0 @@ -## OPTIONS - -* `<theme>`: - - A particular theme to show the status for. diff --git a/man-src/theme-update-all.txt b/man-src/theme-update-all.txt deleted file mode 100644 index 5d24e29a5a..0000000000 --- a/man-src/theme-update-all.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--dry-run`: - - Pretend to do the updates, to see what would happen. - -## EXAMPLES - - wp theme update-all diff --git a/man-src/theme-update.txt b/man-src/theme-update.txt deleted file mode 100644 index b7e6109406..0000000000 --- a/man-src/theme-update.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* `<theme>`: - - The theme to update. - -* `--version=dev`: - - If set, the theme will be updated to the latest development version, -regardless of what version is currently installed. - -## EXAMPLES - - wp theme update twentytwelve diff --git a/man-src/transient.txt b/man-src/transient.txt deleted file mode 100644 index 64dcebe0f1..0000000000 --- a/man-src/transient.txt +++ /dev/null @@ -1,3 +0,0 @@ -## EXAMPLES - - wp transient set my_key my_value 300 diff --git a/man-src/user-add-role.txt b/man-src/user-add-role.txt deleted file mode 100644 index b6e5ab4826..0000000000 --- a/man-src/user-add-role.txt +++ /dev/null @@ -1,14 +0,0 @@ -## OPTIONS - -* `<user>`: - - User ID or user login. - -* `<role>`: - - Add the specified role to the user. - -## EXAMPLES - - wp user set-role bob author - wp user set-role 12 author diff --git a/man-src/user-create.txt b/man-src/user-create.txt deleted file mode 100644 index 8b860096b5..0000000000 --- a/man-src/user-create.txt +++ /dev/null @@ -1,33 +0,0 @@ -## OPTIONS - -* `<user-login>`: - - The login of the user to create. - -* `<user-email>`: - - The email address of the user to create. - -* `--role`=<role>: - - The role of the user to create. Default: default role - -* `--user_pass`=<password>: - - The user password. Default: randomly generated - -* `--user_registered`=<yyyy-mm-dd>: - - The date the user registered. Default: current date - -* `--display_name`=<name>: - - The display name. - -* `--porcelain`: - - Output just the new user id. - -## EXAMPLES - - wp user create bob bob@example.com --role=author diff --git a/man-src/user-delete.txt b/man-src/user-delete.txt deleted file mode 100644 index 88d8966a16..0000000000 --- a/man-src/user-delete.txt +++ /dev/null @@ -1,13 +0,0 @@ -## OPTIONS - -* `<user>`: - - The user login or ID of the user to delete. - -* `--reassign`=<ID>: - - User to reassign the posts to. - -## EXAMPLES - - wp user delete 123 --reassign=567 diff --git a/man-src/user-generate.txt b/man-src/user-generate.txt deleted file mode 100644 index a2467abf0c..0000000000 --- a/man-src/user-generate.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--count`=<number>: - - How many users to generate. Default: 100 - -* `--role`=<role>: - - The role of the generated users. Default: default role from WP diff --git a/man-src/user-get.txt b/man-src/user-get.txt deleted file mode 100644 index 9493599eff..0000000000 --- a/man-src/user-get.txt +++ /dev/null @@ -1,19 +0,0 @@ -## OPTIONS - -* `[--format=<format>]`: - - The format to use when printing the user; acceptable values: - - **table**: Outputs all fields of the user as a table. - - **json**: Outputs all fields in JSON format. - -* `<user>`: - - User ID or user login. - -## EXAMPLES - - wp user get 12 - - wp user get bob --format=json > bob.json diff --git a/man-src/user-import-csv.txt b/man-src/user-import-csv.txt deleted file mode 100644 index e8963372a1..0000000000 --- a/man-src/user-import-csv.txt +++ /dev/null @@ -1,16 +0,0 @@ -## OPTIONS - -* `<file>`: - - The CSV file of users to import. - -## EXAMPLES - - wp user import-csv /path/to/users.csv - - Sample users.csv file: - - user_login,user_email,display_name,role - bobjones,bobjones@domain.com,Bob Jones,contributor - newuser1,newuser1@domain.com,New User,author - existinguser,existinguser@domain.com,Existing User,administrator diff --git a/man-src/user-list.txt b/man-src/user-list.txt deleted file mode 100644 index 0aa7951da6..0000000000 --- a/man-src/user-list.txt +++ /dev/null @@ -1,21 +0,0 @@ -## OPTIONS - -* `--role`=<role>: - - Only display users with a certain role. - -* `--fields`=<fields>: - - Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles - -* `--format`=<format>: - - Output list as table, CSV, JSON, or simply IDs. Defaults to table. - -## EXAMPLES - - wp user list --format=ids - - wp user list --role=administrator --format=csv - - wp user list --fields=display_name,user_email diff --git a/man-src/user-meta.txt b/man-src/user-meta.txt deleted file mode 100644 index 94d507cc5b..0000000000 --- a/man-src/user-meta.txt +++ /dev/null @@ -1,9 +0,0 @@ -## OPTIONS - -* `--format=json`: - - Encode/decode values as JSON. - -## EXAMPLES - - wp user-meta set 123 description "Mary is a WordPress developer." diff --git a/man-src/user-remove-role.txt b/man-src/user-remove-role.txt deleted file mode 100644 index b4a77e47d9..0000000000 --- a/man-src/user-remove-role.txt +++ /dev/null @@ -1,10 +0,0 @@ -## OPTIONS - -* `<user>`: - - User ID or user login. - -## EXAMPLES - - wp user remove-role bob - wp user remove-role 12 diff --git a/man-src/user-set-role.txt b/man-src/user-set-role.txt deleted file mode 100644 index 4817f740d0..0000000000 --- a/man-src/user-set-role.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `<user>`: - - User ID or user login. - -* `[<role>]`: - - Make the user have the specified role. If not passed, the default role is -used. - -## EXAMPLES - - wp user set-role bob author - wp user set-role 12 author diff --git a/man-src/user-update.txt b/man-src/user-update.txt deleted file mode 100644 index 092ab8b594..0000000000 --- a/man-src/user-update.txt +++ /dev/null @@ -1,15 +0,0 @@ -## OPTIONS - -* `<user>`: - - The user login or ID of the user to update. - -* `--<field>`=<value>: - - One or more fields to update. For accepted fields, see wp_update_user(). - -## EXAMPLES - - wp user update 123 --user_login=mary --display_name=Mary - - wp user update mary --user_pass=marypass diff --git a/php/commands/cache.php b/php/commands/cache.php index 4516e7e16d..e522c4be51 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -3,7 +3,11 @@ /** * Manage the object cache. * - * @package wp-cli + * ## EXAMPLES + * + * wp cache set my_key my_value my_group 300 + * + * wp cache get my_key my_group */ class Cache_Command extends WP_CLI_Command { diff --git a/php/commands/cap.php b/php/commands/cap.php index 31004285ca..97d84113c7 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -3,7 +3,16 @@ /** * Manage user capabilities. * - * @package wp-cli + * ## EXAMPLES + * + * # Add 'spectate' capability to 'author' role + * wp cap add 'author' 'spectate' + * + * # Add all caps from 'editor' role to 'author' role + * wp cap list 'editor' | xargs wp cap add 'author' + * + * # Remove all caps from 'editor' role that also appear in 'author' role + * wp cap list 'author' | xargs wp cap remove 'editor' */ class Capabilities_Command extends WP_CLI_Command { diff --git a/php/commands/comment.php b/php/commands/comment.php index dd5442cda8..179b08a6d6 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -10,6 +10,18 @@ class Comment_Command extends WP_CLI_Command { /** * Insert a comment. * + * ## OPTIONS + * + * --<field>=<value> + * : Field values for the new comment. See wp_insert_comment(). + * + * --porcelain + * : Output just the new comment id. + * + * ## EXAMPLES + * + * wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" + * * @synopsis --<field>=<value> [--porcelain] */ public function create( $args, $assoc_args ) { @@ -34,6 +46,18 @@ public function create( $args, $assoc_args ) { /** * Delete a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to delete. + * + * --force + * : Skip the trash bin. + * + * ## EXAMPLES + * + * wp comment delete 1337 --force + * * @synopsis <id> [--force] */ public function delete( $args, $assoc_args ) { @@ -73,6 +97,15 @@ private function set_status( $args, $status, $success ) { /** * Trash a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to trash. + * + * ## EXAMPLES + * + * wp comment trash 1337 + * * @synopsis <id> */ public function trash( $args, $assoc_args ) { @@ -82,6 +115,15 @@ public function trash( $args, $assoc_args ) { /** * Untrash a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to untrash. + * + * ## EXAMPLES + * + * wp comment untrash 1337 + * * @synopsis <id> */ public function untrash( $args, $assoc_args ) { @@ -91,6 +133,15 @@ public function untrash( $args, $assoc_args ) { /** * Spam a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to mark as spam. + * + * ## EXAMPLES + * + * wp comment spam 1337 + * * @synopsis <id> */ public function spam( $args, $assoc_args ) { @@ -100,6 +151,14 @@ public function spam( $args, $assoc_args ) { /** * Unspam a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to unmark as spam. + * + * ## EXAMPLES + * + * wp comment unspam 1337 * @synopsis <id> */ public function unspam( $args, $assoc_args ) { @@ -109,6 +168,15 @@ public function unspam( $args, $assoc_args ) { /** * Approve a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to approve. + * + * ## EXAMPLES + * + * wp comment approve 1337 + * * @synopsis <id> */ public function approve( $args, $assoc_args ) { @@ -118,6 +186,15 @@ public function approve( $args, $assoc_args ) { /** * Unapprove a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to unapprove. + * + * ## EXAMPLES + * + * wp comment unapprove 1337 + * * @synopsis <id> */ public function unapprove( $args, $assoc_args ) { @@ -127,6 +204,16 @@ public function unapprove( $args, $assoc_args ) { /** * Count comments, on whole blog or on a given post. * + * ## OPTIONS + * + * <ID> + * : The ID of the post to count comments in + * + * ## EXAMPLES + * + * wp comment count + * wp comment count 42 + * * @synopsis [<post-id>] */ public function count( $args, $assoc_args ) { @@ -147,6 +234,15 @@ public function count( $args, $assoc_args ) { /** * Get status of a comment. * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to check + * + * ## EXAMPLES + * + * wp comment status 1337 + * * @synopsis <id> */ public function status( $args, $assoc_args ) { @@ -164,6 +260,18 @@ public function status( $args, $assoc_args ) { /** * Get last approved comment. * + * ## OPTIONS + * + * --id + * : Output just the last comment id. + * + * --full + * : Output complete comment information. + * + * ## EXAMPLES + * + * wp comment last --full + * * @synopsis [--id] [--full] */ function last( $args = array(), $assoc_args = array() ) { diff --git a/php/commands/core.php b/php/commands/core.php index eaa2901303..5d21f820de 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -12,6 +12,22 @@ class Core_Command extends WP_CLI_Command { /** * Download core WordPress files. * + * ## OPTIONS + * + * --locale=<locale> + * : Select which language you want to download. The --version parameter is + * ignored in this case. + * + * --version=<version> + * : Select which version you want to download. + * + * --force + * : Overwrites existing files, if present. + * + * ## EXAMPLES + * + * wp core download --version=3.3 + * * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] [--force] * * @when before_wp_load @@ -75,6 +91,40 @@ private static function get_initial_locale() { /** * Set up a wp-config.php file. * + * ## OPTIONS + * + * --dbname=<dbname> + * : Set the database name. + * + * --dbuser=<dbuser> + * : Set the database user. + * + * --dbpass=<dbpass> + * : Set the database user password. + * + * --dbhost=<dbhost> + * : Set the database host. Default: 'localhost' + * + * --dbprefix=<dbprefix> + * : Set the database table prefix. Default: 'wp_' + * + * --locale=<locale> + * : Set the WPLANG constant. Defaults to $wp_local_package variable. + * + * --extra-php + * : If set, the command reads additional PHP code from STDIN. + * + * ## EXAMPLES + * + * # Standard wp-config.php file + * wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --locale=ro_RO + * + * # Enable WP_DEBUG and WP_DEBUG_LOG + * wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP + * define( 'WP_DEBUG', true ); + * define( 'WP_DEBUG_LOG', true ); + * PHP + * * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] */ public function config( $_, $assoc_args ) { @@ -118,6 +168,12 @@ public function config( $_, $assoc_args ) { /** * Determine if the WordPress tables are installed. * + * ## EXAMPLES + * + * if ! $(wp core is-installed); then + * wp core install + * fi + * * @subcommand is-installed */ public function is_installed() { @@ -131,6 +187,23 @@ public function is_installed() { /** * Create the WordPress tables in the database. * + * ## OPTIONS + * + * --url=<url> + * : The address of the new site. + * + * --title=<site-title> + * : The title of the new site. + * + * --admin_name=<username> + * : The name of the admin user. Default: 'admin' + * + * --admin_password=<password> + * : The password for the admin user. + * + * --admin_email=<email> + * : The email address for the admin user. + * * @synopsis --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { @@ -144,6 +217,18 @@ public function install( $args, $assoc_args ) { /** * Transform a single-site install into a multi-site install. * + * ## OPTIONS + * + * --title=<site-title> + * : The title of the new network. + * + * --base=<url-path> + * : Base path after the domain name that each site url will start with. + * Default: '/' + * + * --subdomains + * : If passed, the network will use subdomains, instead of subdirectories. + * * @subcommand multisite-convert * @alias install-network * @synopsis [--title=<network-title>] [--base=<url-path>] [--subdomains] @@ -165,6 +250,30 @@ public function multisite_convert( $args, $assoc_args ) { /** * Install multisite from scratch. * + * ## OPTIONS + * + * --url=<url> + * : The address of the new site. + * + * --base=<url-path> + * : Base path after the domain name that each site url in the network will start with. + * Default: '/' + * + * --subdomains + * : If passed, the network will use subdomains, instead of subdirectories. + * + * --title=<site-title> + * : The title of the new site. + * + * --admin_name=<username> + * : The name of the admin user. Default: 'admin' + * + * --admin_password=<password> + * : The password for the admin user. + * + * --admin_email=<email> + * : The email address for the admin user. + * * @subcommand multisite-install * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] [--admin_name=<username>] --admin_email=<email> --admin_password=<password> */ @@ -374,6 +483,11 @@ private static function get_clean_basedomain() { /** * Display the WordPress version. * + * ## OPTIONS + * + * --extra + * : Show extended version information. + * * @synopsis [--extra] */ public function version( $args = array(), $assoc_args = array() ) { @@ -399,6 +513,24 @@ public function version( $args = array(), $assoc_args = array() ) { /** * Update WordPress. * + * ## OPTIONS + * + * --version=<new_version> [package/zip] + * : When passed, updates to new_version, optionally using package/zip as + * input. + * + * --force + * : Will update even when current WP version < passed version. Use with + * caution. + * + * ## EXAMPLES + * + * wp core update + * + * wp core update --version=3.4 ../latest.zip + * + * wp core update --version=3.1 --force + * * @alias upgrade * * @synopsis [<zip>] [--version=<version>] [--force] @@ -480,6 +612,25 @@ function update_db() { * * @subcommand init-tests * + * ## OPTIONS + * + * <path> + * : The directory in which to download the testing suite files. (Optional) + * + * --dbname=<dbname> + * : Set the database name. **WARNING**: The database will be whipped every time + * you run the tests. + * + * --dbuser=<dbuser> + * : Set the database user. + * + * --dbpass=<dbpass> + * : Set the database user password. + * + * ## EXAMPLE + * + * wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test + * * @synopsis [<path>] --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] */ function init_tests( $args, $assoc_args ) { diff --git a/php/commands/db.php b/php/commands/db.php index 662306d5f9..66ed93d506 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -5,7 +5,21 @@ /** * Perform basic database operations. * - * @package wp-cli + * ## OPTIONS + * + * --yes + * : Answer yes to the confirmation message. + * + * <file> + * : The name of the export file. If omitted, it will be '{dbname}.sql' + * + * <SQL> + * : A SQL query. + * + * ## EXAMPLES + * + * # execute a query stored in a file + * wp db query < debug.sql */ class DB_Command extends WP_CLI_Command { diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index e1c60b9ef1..330c384dd1 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -5,6 +5,10 @@ class EvalFile_Command extends WP_CLI_Command { /** * Load and execute a PHP file after loading WordPress. * + * ## EXAMPLES + * + * wp eval-file my-code.php + * * @synopsis <path> */ public function __invoke( $args, $assoc_args ) { diff --git a/php/commands/eval.php b/php/commands/eval.php index 02b97c6a99..782752b76e 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -5,6 +5,10 @@ class Eval_Command extends WP_CLI_Command { /** * Execute arbitrary PHP code after loading WordPress. * + * ## EXAMPLES + * + * wp eval 'echo WP_CONTENT_DIR;' + * * @synopsis <php-code> */ public function __invoke( $args, $assoc_args ) { diff --git a/php/commands/export.php b/php/commands/export.php index 3bde8c3148..173ad2d136 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -11,6 +11,50 @@ class Export_Command extends WP_CLI_Command { /** * Export content to a WXR file. * + * ## OPTIONS + * + * --dir=<dirname> + * : Full path to directory where WXR export files should be stored. Defaults + * to current working directory. + * + * --skip_comments + * : Don't export comments. + * + * --file_item_count=<count> + * : Break export into files with N posts. + * + * --verbose + * : Show more information about the process on STDOUT. + * + * ## FILTERS + * + * --start_date=<date> + * : Export only posts newer than this date, in format YYYY-MM-DD. + * + * --end_date=<date> + * : Export only posts older than this date, in format YYYY-MM-DD. + * + * --post_type=<post_type> + * : Export only posts with this post_type. + * + * --post__in=<pid> + * : Export all posts specified as a comma-separated list of IDs. + * + * --author=<login/id> + * : Export only posts by this author. + * + * --category=<category-id> + * : Export only posts in this category. + * + * --post_status=<status> + * : Export only posts with this status. + * + * ## EXAMPLES + * + * wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + * + * wp export --dir=/tmp/ --post__in=123,124,125 + * * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] [--verbose] */ public function __invoke( $_, $assoc_args ) { diff --git a/php/commands/help.php b/php/commands/help.php index 0e074f0877..93fc6ab5a2 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -8,6 +8,14 @@ class Help_Command extends WP_CLI_Command { /** * Get help on a certain command. * + * ## EXAMPLES + * + * # get help for `core` command + * wp help core + * + * # get help for `core download` subcommand + * wp help core download + * * @synopsis [<command>] */ function __invoke( $args, $assoc_args ) { diff --git a/php/commands/import.php b/php/commands/import.php index 1f2dc08928..d114d4f9df 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -5,6 +5,17 @@ class Import_Command extends WP_CLI_Command { /** * Import content from a WXR file. * + * ## OPTIONS + * + * <file> + * : Path to a valid WXR file for importing. + * + * --authors=<authors> + * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. + * + * --skip=<data-type> + * : Skip importing specific data. Supported option is 'attachment'. + * * @synopsis <file> --authors=<authors> [--skip=<data-type>] */ public function __invoke( $args, $assoc_args ) { diff --git a/php/commands/media.php b/php/commands/media.php index 22cae68c9f..dfb188dce3 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -10,6 +10,20 @@ class Media_Command extends WP_CLI_Command { /** * Regenerate thumbnail(s). * + * ## OPTIONS + * + * --yes + * : Answer yes to the confirmation message. + * + * <attachment-id> + * : One or more IDs of the attachments to regenerate. + * + * ## EXAMPLES + * + * wp media regenerate 123 1337 + * + * wp media regenerate --yes + * * @synopsis <attachment-id>... [--yes] */ function regenerate( $args, $assoc_args = array() ) { @@ -59,6 +73,45 @@ function regenerate( $args, $assoc_args = array() ) { /** * Create attachments from local files or from URLs. * + * ## OPTIONS + * + * <file> + * : Path to file or files to be imported. Supports the glob(3) capabilities of the current shell. + * If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be + * downloaded to a temp file before being sideloaded. + * + * --post_id=<post_id> + * : ID of the post to attach the imported files to + * + * --title=<title> + * : Attachment title (post title field) + * + * --caption=<caption> + * : Caption for attachent (post excerpt field) + * + * --alt=<alt_text> + * : Alt text for image (saved as post meta) + * + * --desc=<description> + * : "Description" field (post content) of attachment post + * + * --featured_image + * : If set, set the imported image as the Featured Image of the post its attached to. + * + * + * ## EXAMPLES + * + * # Import all jpgs in the current user's "Pictures" directory, not attached to any post + * wp media import ~/Pictures/**/*.jpg + * + * # Import a local image and set it to be the post thumbnail for a post + * wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image + * + * # Import an image from the web + * wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" + * + * + * * @synopsis <file>... [--post_id=<id>] [--title=<title>] [--caption=<caption>] [--alt=<text>] [--desc=<description>] [--featured_image] */ function import( $args, $assoc_args = array() ) { diff --git a/php/commands/network-meta.php b/php/commands/network-meta.php index c7a603a903..181d22949e 100644 --- a/php/commands/network-meta.php +++ b/php/commands/network-meta.php @@ -3,7 +3,18 @@ /** * Manage network custom fields. * - * @package wp-cli + * ## OPTIONS + * + * <id> + * : The network id (usually 1). + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * # get a list of super-admins + * wp network-meta get 1 site_admins */ class Network_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'site'; diff --git a/php/commands/option.php b/php/commands/option.php index da3f3ceaf2..ccefe5bf48 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -3,7 +3,20 @@ /** * Manage options. * - * @package wp-cli + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp option get siteurl + * + * wp option add my_option foobar + * + * wp option update my_option '{"foo": "bar"}' --format=json + * + * wp option delete my_option */ class Option_Command extends WP_CLI_Command { diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e95c568452..8f01209470 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -32,6 +32,11 @@ protected function get_upgrader_class( $force ) { /** * See the status of one or all plugins. * + * ## OPTIONS + * + * <plugin> + * : A particular plugin to show the status for. + * * @synopsis [<plugin>] */ function status( $args ) { @@ -78,6 +83,14 @@ protected function get_all_items() { /** * Activate a plugin. * + * ## OPTIONS + * + * <plugin> + * : The plugin to activate. + * + * --network + * : If set, the plugin will be activated for the entire multisite network. + * * @synopsis <plugin> [--network] */ function activate( $args, $assoc_args = array() ) { @@ -98,6 +111,14 @@ function activate( $args, $assoc_args = array() ) { /** * Deactivate a plugin. * + * ## OPTIONS + * + * <plugin> + * : The plugin to deactivate. + * + * --network + * : If set, the plugin will be deactivated for the entire multisite network. + * * @synopsis <plugin> [--network] */ function deactivate( $args, $assoc_args = array() ) { @@ -118,6 +139,14 @@ function deactivate( $args, $assoc_args = array() ) { /** * Toggle a plugin's activation state. * + * ## OPTIONS + * + * <plugin> + * : The plugin to toggle. + * + * --network + * : If set, the plugin will be toggled for the entire multisite network. + * * @synopsis <plugin> [--network] */ function toggle( $args, $assoc_args = array() ) { @@ -136,6 +165,20 @@ function toggle( $args, $assoc_args = array() ) { /** * Get the path to a plugin or to the plugin directory. * + * ## OPTIONS + * + * <plugin> + * : The plugin to get the path to. If not set, will return the path to the + * plugins directory. + * + * --dir + * : If set, get the path to the closest parent directory, instead of the + * plugin file. + * + * ## EXAMPLES + * + * cd $(wp theme path) + * * @synopsis [<plugin>] [--dir] */ function path( $args, $assoc_args ) { @@ -182,6 +225,19 @@ protected function install_from_repo( $slug, $assoc_args ) { /** * Update a plugin. * + * ## OPTIONS + * + * <plugin> + * : The plugin to update. + * + * --version=dev + * : If set, the plugin will be updated to the latest development version, + * regardless of what version is currently installed. + * + * ## EXAMPLES + * + * wp plugin update bbpress --version=dev + * * @synopsis <plugin> [--version=<version>] */ function update( $args, $assoc_args ) { @@ -214,6 +270,15 @@ function update( $args, $assoc_args ) { /** * Update all plugins. * + * ## OPTIONS + * + * --dry-run + * : Pretend to do the updates, to see what would happen. + * + * ## EXAMPLES + * + * wp plugin update-all + * * @subcommand update-all * @synopsis [--dry-run] */ @@ -240,6 +305,36 @@ protected function get_item_list() { /** * Install a plugin. * + * ## OPTIONS + * + * <plugin|zip|url> + * : A plugin slug, the path to a local zip file, or URL to a remote zip file. + * + * --version=<version> + * : If set, get that particular version from wordpress.org, instead of the + * stable version. + * + * --force + * : If set, the command will overwrite any installed version of the plugin, without prompting + * for confirmation. + * + * --activate + * : If set, the plugin will be activated immediately after install. + * + * ## EXAMPLES + * + * # Install the latest version from wordpress.org and activate + * wp plugin install bbpress --activate + * + * # Install the development version from wordpress.org + * wp plugin install bbpress --version=dev + * + * # Install from a local zip file + * wp plugin install ../my-plugin.zip + * + * # Install from a remote zip file + * wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef + * * @synopsis <plugin|zip|url> [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { @@ -249,6 +344,19 @@ function install( $args, $assoc_args ) { /** * Uninstall a plugin. * + * ## OPTIONS + * + * <plugin> + * : The plugin to uninstall. + * + * --no-delete + * : If set, the plugin files will not be deleted. Only the uninstall procedure + * will be run. + * + * ## EXAMPLES + * + * wp plugin uninstall hello + * * @synopsis <plugin> [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { @@ -272,6 +380,15 @@ function uninstall( $args, $assoc_args = array() ) { /** * Delete plugin files. * + * ## OPTIONS + * + * <plugin> + * : The plugin to delete. + * + * ## EXAMPLES + * + * wp plugin delete hello + * * @synopsis <plugin> */ function delete( $args, $assoc_args = array() ) { @@ -286,6 +403,16 @@ function delete( $args, $assoc_args = array() ) { /** * Get a list of plugins. * + * ## OPTIONS + * + * * `--format`=<format>: + * + * Output list as table, CSV or JSON. Defaults to table. + * + * ## EXAMPLES + * + * wp plugin list --format=json + * * @subcommand list * @synopsis [--format=<format>] */ diff --git a/php/commands/post-meta.php b/php/commands/post-meta.php index 08a1052f0d..31cf7572c3 100644 --- a/php/commands/post-meta.php +++ b/php/commands/post-meta.php @@ -3,7 +3,14 @@ /** * Manage post custom fields. * - * @package wp-cli + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp post-meta set 123 _wp_page_template about.php */ class Post_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'post'; diff --git a/php/commands/post.php b/php/commands/post.php index 1792830998..f8f7a9b59f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -20,6 +20,33 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { /** * Create a post. * + * ## OPTIONS + * + * <filename> + * : Read post content from <filename>. If this value is present, the + * `--post_content` argument will be ignored. + * + * Passing `-` as the filename will cause post content to + * be read from STDIN. + * + * --<field>=<value> + * : Field values for the new post. See wp_insert_post(). + * + * --edit + * : Immediately open system's editor to write or edit post content. + * + * If content is read from a file, from STDIN, or from the `--post_content` + * argument, that text will be loaded into the editor. + * + * --porcelain + * : Output just the new post id. + * + * ## EXAMPLES + * + * wp post create --post_type=page --post_status=publish --post_title='A future post' --post-status=future --post_date='2020-12-01 07:00:00' + * + * wp post create page.txt --post_type=page --post_title='Page from file' + * * @synopsis [<filename>] --<field>=<value> [--edit] [--porcelain] */ public function create( $args, $assoc_args ) { @@ -56,6 +83,18 @@ protected function _create( $params ) { /** * Update one or more posts. * + * ## OPTIONS + * + * <ID> + * : The ID of the post to update. + * + * --<field>=<value> + * : One or more fields to update. See wp_update_post(). + * + * ## EXAMPLES + * + * wp post update 123 --post_name=something --post_status=draft + * * @synopsis <id>... --<field>=<value> */ public function update( $args, $assoc_args ) { @@ -69,6 +108,15 @@ protected function _update( $params ) { /** * Launch system editor to edit post content. * + * ## OPTIONS + * + * <id> + * : The ID of the post to edit. + * + * ## EXAMPLES + * + * wp post edit 123 + * * @synopsis <id> */ public function edit( $args, $_ ) { @@ -91,7 +139,28 @@ protected function _edit( $content, $title ) { /** * Get a post's content by ID. * - * @synopsis [--format=<format>] <id> + * ## OPTIONS + * + * <ID> + * : The ID of the post to get. + * + * --format=<format> + * : The format to use when printing the post, acceptable values: + * + * - **content**: Outputs only the post's content. + * + * - **table**: Outputs all fields of the post as a table. Note that the + * post_content field is omitted so that the table is readable. + * + * - **json**: Outputs all fields in JSON format. + * + * ## EXAMPLES + * + * wp post get 12 --format=content + * + * wp post get 12 > file.txt + * + * @synopsis [--format=<format>] <ID> */ public function get( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( @@ -130,6 +199,20 @@ public function get( $args, $assoc_args ) { /** * Delete a post by ID. * + * ## OPTIONS + * + * <ID> + * : The ID of the post to delete. + * + * --force + * : Skip the trash bin. + * + * ## EXAMPLES + * + * wp post delete 123 --force + * + * wp post delete $(wp post list --post_type='page' --format=ids) + * * @synopsis <id>... [--force] */ public function delete( $args, $assoc_args ) { @@ -155,6 +238,25 @@ protected function _delete( $post_id, $assoc_args ) { /** * Get a list of posts. * + * ## OPTIONS + * + * --<field>=<value> + * : One or more args to pass to WP_Query. + * + * --fields=<fields> + * : Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. + * + * --format=<format> + * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * + * ## EXAMPLES + * + * wp post list --format=ids + * + * wp post list --post_type=post --posts_per_page=5 --format=json + * + * wp post list --post_type=page --fields=post_title,post_status + * * @subcommand list * @synopsis [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ @@ -195,6 +297,30 @@ public function _list( $_, $assoc_args ) { /** * 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 + * + * --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 + * * @synopsis [--count=<number>] [--post_type=<type>] [--post_status=<status>] [--post_author=<login>] [--post_date=<yyyy-mm-dd>] [--max_depth=<number>] */ public function generate( $args, $assoc_args ) { diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 71538d25b2..b1c5a51047 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -10,6 +10,11 @@ class Rewrite_Command extends WP_CLI_Command { /** * Flush rewrite rules. * + * ## OPTIONS + * + * --hard + * : Perform a hard flush - do not overwrite `.htaccess`. The default is to update `.htaccess` rules as well as rewrite rules in database. + * * @synopsis [--hard] */ public function flush( $args, $assoc_args ) { @@ -21,6 +26,21 @@ public function flush( $args, $assoc_args ) { /** * Update the permalink structure. * + * ## OPTIONS + * + * <permastruct> + * : The new permalink structure to apply. + * + * --category-base=<categorybase> + * : Set the base for category permalinks, i.e. '/category/'. + * + * --tag-base=<tagbase> + * : Set the base for tag permalinks, i.e. '/tag/'. + * + * ## EXAMPLES + * + * wp rewrite structure '/%year%/%monthnum%/%postname%' + * * @synopsis <permastruct> [--category-base=<base>] [--tag-base=<base>] [--hard] */ public function structure( $args, $assoc_args ) { @@ -72,10 +92,14 @@ public function structure( $args, $assoc_args ) { /** * Print current rewrite rules. * - * @synopsis [--json] + * ## OPTIONS + * + * --format=json + * : Output rules in JSON format. + * + * @synopsis [--format=<format>] */ public function dump( $args, $assoc_args ) { - $rules = get_option( 'rewrite_rules' ); if ( ! $rules ) { $rules = array(); @@ -88,7 +112,6 @@ public function dump( $args, $assoc_args ) { foreach ( $rules as $route => $rule ) WP_CLI::line( $route . "\t" . $rule ); } - } /** @@ -125,7 +148,6 @@ function apache_get_modules() { } } } - } WP_CLI:: add_command( 'rewrite', 'Rewrite_Command' ); diff --git a/php/commands/role.php b/php/commands/role.php index bfd974b632..3c032e8c16 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -15,6 +15,18 @@ class Role_Command extends WP_CLI_Command { /** * List all roles. * + * ## OPTIONS + * + * --fields=<fields> + * : Limit the output to specific object fields. Defaults to name,role. + * + * --format=<format> + * : Output list as table, CSV or JSON. Defaults to table. + * + * ## EXAMPLES + * + * wp role list --fields=role --format=csv + * * @subcommand list * @synopsis [--fields=<fields>] [--format=<format>] */ @@ -45,7 +57,20 @@ public function _list( $args, $assoc_args ) { /** * Check if a role exists. - * Will return 0 if the role exists, 1 if it does not. + * + * ##DESCRIPTION + * + * Will exit with status 0 if the role exists, 1 if it does not. + * + * ## OPTIONS + * + * * <role-key>: + * + * The internal name of the role, e.g. editor + * + * ## EXAMPLES + * + * wp role exists editor * * @synopsis <role-key> */ @@ -60,6 +85,22 @@ public function exists( $args ) { /** * Create a new role. * + * ## OPTIONS + * + * * <role-key>: + * + * The internal name of the role, e.g. editor + * + * * <role-name>: + * + * The publically visible name of the role, e.g. Editor + * + * ## EXAMPLES + * + * wp role create approver Approver + * + * wp role create productadmin "Product Administrator" + * * @synopsis <role-key> <role-name> */ public function create( $args ) { @@ -75,12 +116,23 @@ public function create( $args ) { WP_CLI::error( "Role couldn't be created." ); else WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); - } /** * Delete an existing role. * + * ## OPTIONS + * + * * <role-key>: + * + * The internal name of the role, e.g. editor + * + * ## EXAMPLES + * + * wp role delete approver + * + * wp role delete productadmin + * * @synopsis <role-key> */ public function delete( $args ) { diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 2428339731..bdf3435d12 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -16,6 +16,25 @@ function __construct() { /** * Generate PHP code for registering a custom post type. * + * ## OPTIONS + * + * --label=<label> + * : The text used to translate the update messages + * + * --textdomain=<textdomain> + * : The textdomain to use for the labels. + * + * --theme + * : Create a file in the active theme directory, instead of sending to + * STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. + * + * --plugin=<plugin> + * : Create a file in the given plugin's directory, instead of sending to + * STDOUT. + * + * --raw + * : Just generate the `register_post_type()` call and nothing else. + * * @subcommand post-type * * @alias cpt @@ -36,6 +55,32 @@ function post_type( $args, $assoc_args ) { /** * Generate PHP code for registering a custom taxonomy. * + * ## OPTIONS + * + * --post_types=<post_types> + * : Post types to register for use with the taxonomy. + * + * --label=<label> + * : The text used to translate the update messages + * + * --textdomain=<textdomain> + * : The textdomain to use for the labels. + * + * --theme + * : Create a file in the active theme directory, instead of sending to + * STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. + * + * --plugin=<plugin> + * : Create a file in the given plugin's directory, instead of sending to + * STDOUT. + * + * --raw + * : Just generate the `register_taxonomy()` call and nothing else. + * + * ## EXAMPLES + * + * wp scaffold taxonomy venue --post_types=event,presentation + * * @subcommand taxonomy * * @alias tax @@ -112,6 +157,23 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) /** * Generate starter code for a theme. * + * ## OPTIONS + * + * <slug> + * : The slug for the new theme, used for prefixing functions. + * + * --activate + * : Activate the newly downloaded theme. + * + * --theme_name=<title> + * : What to put in the 'Theme Name:' header in style.css + * + * --author=<full name> + * : What to put in the 'Author:' header in style.css + * + * --author_uri=<http url> + * : What to put in the 'Author URI:' header in style.css + * * @synopsis <slug> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--activate] */ function _s( $args, $assoc_args ) { @@ -154,6 +216,29 @@ function _s( $args, $assoc_args ) { /** * Generate empty child theme. * + * ## OPTIONS + * + * <slug> + * : The slug for the new child theme. + * + * --parent_theme=<slug> + * : What to put in the 'Template:' header in style.css + * + * --theme_name=<title> + * : What to put in the 'Theme Name:' header in style.css + * + * --author=<full name> + * : What to put in the 'Author:' header in style.css + * + * --author_uri=<http url> + * : What to put in the 'Author URI:' header in style.css + * + * --theme_uri=<http url> + * : What to put in the 'Theme URI:' header in style.css + * + * --activate + * : Activate the newly created child theme. + * * @subcommand child-theme * * @synopsis <slug> --parent_theme=<slug> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] @@ -206,6 +291,14 @@ private function get_output_path( $assoc_args, $subdir ) { /** * Generate starter code for a plugin. * + * ## OPTIONS + * + * --activate + * : Activate the newly generated plugin. + * + * --plugin_name=<title> + * : What to put in the 'Plugin Name:' header + * * @synopsis <slug> [--plugin_name=<title>] [--activate] */ function plugin( $args, $assoc_args ) { @@ -233,6 +326,24 @@ function plugin( $args, $assoc_args ) { /** * Generate files needed for running PHPUnit tests. * + * ## DESCRIPTION + * + * These are the files that are generated: + * + * * `phpunit.xml` is the configuration file for PHPUnit + * * `.travis.yml` is the configuration file for Travis CI + * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite + * * `tests/test-sample.php` is a sample file containing the actual tests + * + * ## ENVIRONMENT + * + * The `tests/bootstrap.php` file looks for the WP_TESTS_DIR environment + * variable. + * + * ## EXAMPLE + * + * wp scaffold plugin-tests hello + * * @subcommand plugin-tests * * @synopsis <plugin> diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 1eee976567..4185598109 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -10,6 +10,29 @@ class Search_Replace_Command extends WP_CLI_Command { /** * 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 + * + * --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. + * + * ## 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 + * * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--network] */ public function __invoke( $args, $assoc_args ) { diff --git a/php/commands/shell.php b/php/commands/shell.php index 4fbf4bbcce..ef0869e853 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -5,6 +5,15 @@ class Shell_Command extends \WP_CLI_Command { /** * Interactive PHP console. * + * ## DESCRIPTION + * + * `wp shell` allows you to evaluate PHP statements and expressions interactively, from within a WordPress environment. This means that you have access to all the functions, classes and globals that you would have access to from inside a WordPress plugin, for example. + * + * ## OPTIONS + * + * --basic + * : Start in fail-safe mode, even if Boris is available. + * * @synopsis [--basic] */ public function __invoke( $_, $assoc_args ) { diff --git a/php/commands/site.php b/php/commands/site.php index f1208a1298..1fd1ffa4b0 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -110,6 +110,11 @@ private function _insert_default_terms() { /** * Empty a site of its content (posts, comments, and terms). * + * ## OPTIONS + * + * --yes + * : Proceed to empty the site without a confirmation prompt. + * * @subcommand empty * @synopsis [--yes] */ @@ -128,6 +133,20 @@ public function _empty( $args, $assoc_args ) { /** * Delete a site in a multisite install. * + * ## OPTIONS + * + * <blog-id> + * : The id of the blog to delete. If not provided, you must set the --slug parameter. + * + * --slug=<slug> + * : Path of the blog to be deleted. Subdomain on subdomain installs, directory on subdirectory installs. + * + * --yes + * : Answer yes to the confirmation message. + * + * --keep-tables + * : Delete the blog from the list, but don't drop it's tables. + * * @synopsis [<site-id>] [--slug=<slug>] [--yes] [--keep-tables] */ function delete( $args, $assoc_args ) { @@ -179,6 +198,26 @@ private function _get_site( $site_id ) { /** * Create a site in a multisite install. * + * ## OPTIONS + * + * --slug=<slug> + * : Path for the new site. Subdomain on subdomain installs, directory on subdirectory installs. + * + * --title=<title> + * : Title of the new site. Default: prettified slug. + * + * --email=<email> + * : Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included. + * + * --network_id=<network-id> + * : Network to associate new site with. Defaults to current network (typically 1). + * + * --private + * : If set, the new site will be non-public (not indexed) + * + * --porcelain + * : If set, only the site id will be output on success. + * * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--network_id=<network-id>] [--private] [--porcelain] */ public function create( $_, $assoc_args ) { diff --git a/php/commands/term.php b/php/commands/term.php index 5cbaf0a5a6..2b400c84e8 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -19,6 +19,23 @@ class Term_Command extends WP_CLI_Command { /** * List terms in a taxonomy. * + * ## OPTIONS + * + * <taxonomy> + * : List terms of a given taxonomy. + * + * --fields=<fields> + * : Limit the output to specific object fields. Defaults to all of the term object fields. + * + * --format=<format> + * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * + * ## EXAMPLES + * + * wp term list category --format=csv + * + * wp term list post_tag --fields=name,slug + * * @subcommand list * @synopsis <taxonomy> [--fields=<fields>] [--format=<format>] */ @@ -47,6 +64,30 @@ public function _list( $args, $assoc_args ) { /** * Create a term. * + * ## OPTIONS + * + * <term> + * : A name for the new term. + * + * <taxonomy> + * : Taxonomy for the new term. + * + * --slug=<slug> + * : A unique slug for the new term. Defaults to sanitized version of name. + * + * --description=<description> + * : A description for the new term. + * + * --parent=<term-id> + * : A parent for the new term. + * + * --porcelain + * : Output just the new term id. + * + * ## EXAMPLES + * + * wp term create Apple category --description="A type of fruit" + * * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<term-id>] [--porcelain] */ public function create( $args, $assoc_args ) { @@ -82,6 +123,30 @@ public function create( $args, $assoc_args ) { /** * Update a term. * + * ## OPTIONS + * + * <term-id> + * : ID for the term to update. + * + * <taxonomy> + * : Taxonomy of the term to update. + * + * --name=<name> + * : A new name for the term. + * + * --slug=<slug> + * : A new slug for the term. + * + * --description=<description> + * : A new description for the term. + * + * --parent=<term-id> + * : A new parent for the term. + * + * ## EXAMPLES + * + * wp term update 15 category --name=Apple + * * @synopsis <term-id> <taxonomy> [--name=<name>] [--slug=<slug>] [--description=<description>] [--parent=<term-id>] */ public function update( $args, $assoc_args ) { @@ -112,6 +177,18 @@ public function update( $args, $assoc_args ) { /** * Delete a term. * + * ## OPTIONS + * + * <term-id> + * : ID for the term to delete. + * + * <taxonomy> + * : Taxonomy of the term to delete. + * + * ## EXAMPLES + * + * wp term delete 15 category + * * @synopsis <term-id> <taxonomy> */ public function delete( $args ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 8db618bd43..33d80413f5 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -25,6 +25,11 @@ protected function get_upgrader_class( $force ) { /** * See the status of one or all themes. * + * ## OPTIONS + * + * <theme> + * : A particular theme to show the status for. + * * @synopsis [<theme>] */ function status( $args ) { @@ -60,6 +65,11 @@ protected function get_status( $theme ) { /** * Activate a theme. * + * ## OPTIONS + * + * <theme> + * : The theme to activate. + * * @synopsis <theme> */ public function activate( $args = array() ) { @@ -83,6 +93,20 @@ private function is_active_theme( $theme ) { /** * Get the path to a theme or to the theme directory. * + * ## OPTIONS + * + * <theme> + * : The theme to get the path to. If not set, will return the path to the + * themes directory. + * + * --dir + * : If set, get the path to the closest parent directory, instead of the + * theme file. + * + * ## EXAMPLES + * + * cd $(wp theme path) + * * @synopsis [<theme>] [--dir] */ function path( $args, $assoc_args ) { @@ -149,6 +173,29 @@ protected function get_item_list() { /** * Install a theme. * + * ## OPTIONS + * + * <theme|zip|url> + * : A theme slug, the path to a local zip file, or URL to a remote zip file. + * + * --force + * : If set, the command will overwrite any installed version of the theme, without prompting + * for confirmation. + * + * --activate + * : If set, the theme will be activated immediately after install. + * + * ## EXAMPLES + * + * # Install the latest version from wordpress.org and activate + * wp theme install twentytwelve --activate + * + * # Install from a local zip file + * wp theme install ../my-theme.zip + * + * # Install from a remote zip file + * wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef + * * @synopsis <theme|zip|url> [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { @@ -158,6 +205,19 @@ function install( $args, $assoc_args ) { /** * Update a theme. * + * ## OPTIONS + * + * <theme> + * : The theme to update. + * + * --version=dev + * : If set, the theme will be updated to the latest development version, + * regardless of what version is currently installed. + * + * ## EXAMPLES + * + * wp theme update twentytwelve + * * @synopsis <theme> [--version=<version>] */ function update( $args, $assoc_args ) { @@ -171,6 +231,15 @@ function update( $args, $assoc_args ) { /** * Update all themes. * + * ## OPTIONS + * + * --dry-run + * : Pretend to do the updates, to see what would happen. + * + * ## EXAMPLES + * + * wp theme update-all + * * @subcommand update-all * @synopsis [--dry-run] */ @@ -181,6 +250,15 @@ function update_all( $args, $assoc_args ) { /** * Delete a theme. * + * ## OPTIONS + * + * <theme> + * : The theme to delete. + * + * ## EXAMPLES + * + * wp theme delete twentyeleven + * * @synopsis <theme> */ function delete( $args ) { @@ -203,6 +281,16 @@ function delete( $args ) { /** * Get a list of themes. * + * ## OPTIONS + * + * * `--format`=<format>: + * + * Output list as table, CSV or JSON. Defaults to table. + * + * ## EXAMPLES + * + * wp theme list --format=csv + * * @subcommand list * @synopsis [--format=<format>] */ diff --git a/php/commands/transient.php b/php/commands/transient.php index 6294a79763..0691b5f056 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -3,7 +3,9 @@ /** * Manage transients. * - * @package wp-cli + * ## EXAMPLES + * + * wp transient set my_key my_value 300 */ class Transient_Command extends WP_CLI_Command { diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php index 59b4b739f6..1e2dda0385 100644 --- a/php/commands/user-meta.php +++ b/php/commands/user-meta.php @@ -3,7 +3,14 @@ /** * Manage user custom fields. * - * @package wp-cli + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp user-meta set 123 description "Mary is a WordPress developer." */ class User_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'user'; diff --git a/php/commands/user.php b/php/commands/user.php index 7a874a07c1..8f1a6335b9 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -21,6 +21,25 @@ class User_Command extends \WP_CLI\CommandWithDBObject { /** * List users. * + * ## OPTIONS + * + * --role=<role> + * : Only display users with a certain role. + * + * --fields=<fields> + * : Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles + * + * --format=<format> + * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * + * ## EXAMPLES + * + * wp user list --format=ids + * + * wp user list --role=administrator --format=csv + * + * wp user list --fields=display_name,user_email + * * @subcommand list * @synopsis [--role=<role>] [--fields=<fields>] [--format=<format>] */ @@ -59,6 +78,24 @@ public function _list( $args, $assoc_args ) { /** * Get a single user. * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * --format=<format> + * : The format to use when printing the user; acceptable values: + * + * **table**: Outputs all fields of the user as a table. + * + * **json**: Outputs all fields in JSON format. + * + * ## EXAMPLES + * + * wp user get 12 + * + * wp user get bob --format=json > bob.json + * * @synopsis [--format=<format>] <user> */ public function get( $args, $assoc_args ) { @@ -96,6 +133,18 @@ public function get( $args, $assoc_args ) { /** * Delete one or more users. * + * ## OPTIONS + * + * <user> + * : The user login or ID of the user to delete. + * + * --reassign=<ID> + * : User to reassign the posts to. + * + * ## EXAMPLES + * + * wp user delete 123 --reassign=567 + * * @synopsis <user>... [--reassign=<id>] */ public function delete( $args, $assoc_args ) { @@ -126,6 +175,33 @@ protected function _delete( $user_id, $assoc_args ) { /** * Create a user. * + * ## OPTIONS + * + * <user-login> + * : The login of the user to create. + * + * <user-email> + * : The email address of the user to create. + * + * --role=<role> + * : The role of the user to create. Default: default role + * + * --user_pass=<password> + * : The user password. Default: randomly generated + * + * --user_registered=<yyyy-mm-dd> + * : The date the user registered. Default: current date + * + * --display_name=<name> + * : The display name. + * + * --porcelain + * : Output just the new user id. + * + * ## EXAMPLES + * + * wp user create bob bob@example.com --role=author + * * @synopsis <user-login> <user-email> [--role=<role>] [--user_pass=<password>] [--user_registered=<yyyy-mm-dd>] [--display_name=<name>] [--porcelain] */ public function create( $args, $assoc_args ) { @@ -185,6 +261,20 @@ protected function _create( $params ) { /** * Update a user. * + * ## OPTIONS + * + * <user> + * : The user login or ID of the user to update. + * + * --<field>=<value> + * : One or more fields to update. For accepted fields, see wp_update_user(). + * + * ## EXAMPLES + * + * wp user update 123 --user_login=mary --display_name=Mary + * + * wp user update mary --user_pass=marypass + * * @synopsis <user>... --<field>=<value> */ public function update( $args, $assoc_args ) { @@ -202,6 +292,14 @@ protected function _update( $params ) { /** * 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 + * * @synopsis [--count=<number>] [--role=<role>] */ public function generate( $args, $assoc_args ) { @@ -255,6 +353,20 @@ public function generate( $args, $assoc_args ) { /** * Set the user role (for a particular blog). * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * [<role>] + * : Make the user have the specified role. If not passed, the default role is + * used. + * + * ## EXAMPLES + * + * wp user set-role bob author + * wp user set-role 12 author + * * @subcommand set-role * @synopsis <user> [<role>] */ @@ -275,6 +387,19 @@ public function set_role( $args, $assoc_args ) { /** * Add a role for a user. * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * <role> + * : Add the specified role to the user. + * + * ## EXAMPLES + * + * wp user set-role bob author + * wp user set-role 12 author + * * @subcommand add-role * @synopsis <user> <role> */ @@ -291,6 +416,16 @@ public function add_role( $args, $assoc_args ) { /** * Remove a user's role. * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * ## EXAMPLES + * + * wp user remove-role bob + * wp user remove-role 12 + * * @subcommand remove-role * @synopsis <user> [<role>] */ @@ -330,6 +465,22 @@ private static function get_user( $id_or_login ) { /** * Import users from a CSV file. * + * ## OPTIONS + * + * <file> + * : The CSV file of users to import. + * + * ## EXAMPLES + * + * wp user import-csv /path/to/users.csv + * + * Sample users.csv file: + * + * user_login,user_email,display_name,role + * bobjones,bobjones@domain.com,Bob Jones,contributor + * newuser1,newuser1@domain.com,New User,author + * existinguser,existinguser@domain.com,Existing User,administrator + * * @subcommand import-csv * @synopsis <file> */ From 0212ebe4b3288bb456929e203d7db637c8fe42d6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 18:16:14 +0300 Subject: [PATCH 2077/4858] escape "*/" sequence in media.php --- php/commands/media.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index dfb188dce3..3c3bbafcf6 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -98,11 +98,10 @@ function regenerate( $args, $assoc_args = array() ) { * --featured_image * : If set, set the imported image as the Featured Image of the post its attached to. * - * * ## EXAMPLES * * # Import all jpgs in the current user's "Pictures" directory, not attached to any post - * wp media import ~/Pictures/**/*.jpg + * wp media import ~/Pictures/**\/*.jpg * * # Import a local image and set it to be the post thumbnail for a post * wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image @@ -110,8 +109,6 @@ function regenerate( $args, $assoc_args = array() ) { * # Import an image from the web * wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" * - * - * * @synopsis <file>... [--post_id=<id>] [--title=<title>] [--caption=<caption>] [--alt=<text>] [--desc=<description>] [--featured_image] */ function import( $args, $assoc_args = array() ) { From e3d50372fb740c7a6cab8780aaf13f0a23a3aed2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 21:40:23 +0300 Subject: [PATCH 2078/4858] remove buggy code that tries to use `more` for paging `wp help` * Windows throws an unexpected exit status when trying to use `less` * more doesn't have an '-r' flag --- php/commands/help.php | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index bd681c31a1..c7df1475ff 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -47,29 +47,12 @@ private static function show_help( $command ) { $out = str_replace( "\t", ' ', $out ); - self::pass_through_pager( WP_CLI::colorize( $out ) ); - } - - private static function launch_pager( $pager, $fd ) { - // launch pager - $descriptorspec = array( - 0 => $fd, - 1 => STDOUT, - 2 => array( 'pipe', 'w' ) - ); - - $r = proc_close( proc_open( $pager, $descriptorspec, $pipes ) ); - - if ( 127 == $r ) { - return false; + if ( strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ) { + // no paging for Windows cmd.exe; sorry + echo $out; + } else { + self::pass_through_pager( WP_CLI::colorize( $out ) ); } - - if ( $r ) { - fwrite( STDERR, stream_get_contents( $pipes[1] ) ); - exit( $r ); - } - - return true; } private static function pass_through_pager( $out ) { @@ -78,14 +61,13 @@ private static function pass_through_pager( $out ) { fputs( $fd, $out ); rewind( $fd ); - $pagers = array( 'less -r', 'more -r' ); - foreach ( $pagers as $pager ) { - if ( self::launch_pager( $pager, $fd ) ) - return; - } + $descriptorspec = array( + 0 => $fd, + 1 => STDOUT, + 2 => STDERR + ); - // no pager found - echo $out; + return proc_close( proc_open( 'less -r', $descriptorspec, $pipes ) ); } private static function find( $candidates, $callback ) { From 453eff2f35a6e90365312fe7ddf45431321cf853 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 21:53:35 +0300 Subject: [PATCH 2079/4858] always pass docs through WP_CLI::colorize() --- php/commands/help.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 72bd6c477f..e2c28ae156 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -58,15 +58,16 @@ private static function show_help( $command ) { $out = str_replace( "\t", ' ', $out ); + self::pass_through_pager( WP_CLI::colorize( $out ) ); + } + + private static function pass_through_pager( $out ) { if ( strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ) { // no paging for Windows cmd.exe; sorry echo $out; - } else { - self::pass_through_pager( WP_CLI::colorize( $out ) ); + return 0; } - } - private static function pass_through_pager( $out ) { // convert string to file handle $fd = fopen( "php://temp", "r+" ); fputs( $fd, $out ); From 2dd66e0d1d983434e53a8d613a4e50469679b383 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 21:55:12 +0300 Subject: [PATCH 2080/4858] help: remove unused find() utility --- php/commands/help.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index e2c28ae156..6e90600b25 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -82,15 +82,6 @@ private static function pass_through_pager( $out ) { return proc_close( proc_open( 'less -r', $descriptorspec, $pipes ) ); } - private static function find( $candidates, $callback ) { - foreach ( $candidates as $candidate ) { - if ( call_user_func( $callback, $candidate ) ) - return $candidate; - } - - return false; - } - private static function get_initial_markdown( $command ) { $name = implode( ' ', Dispatcher\get_path( $command ) ); From 11993ae96f189f84ff1ebdd451cd2964f2978479 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 22:14:15 +0300 Subject: [PATCH 2081/4858] bump version to 0.11.0-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index f721cde077..b220b0d969 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.11.0-alpha2' ); +define( 'WP_CLI_VERSION', '0.11.0-beta' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From d823b0c273132ab5238f9e33f460ac15fce15b11 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 22:37:12 +0300 Subject: [PATCH 2082/4858] update to Mustache 2.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 832b311da7..886935c216 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "require": { "php": ">=5.3.2", "wp-cli/php-cli-tools": "0.9.3", - "mustache/mustache": "~2.3" + "mustache/mustache": "~2.4" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" From 07e037d05206821a70dbbefc34f72d1ae80b6af7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 23:31:46 +0300 Subject: [PATCH 2083/4858] add shortdesc for 'wp cli' subcommands --- php/commands/cli.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index 2f550c8856..d0046d4d13 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -28,10 +28,16 @@ private function command_to_array( $command ) { return $dump; } + /** + * Print WP-CLI version. + */ function version() { WP_CLI::line( 'WP-CLI ' . WP_CLI_VERSION ); } + /** + * Print various data about the CLI environment. + */ function info() { $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); @@ -44,6 +50,8 @@ function info() { } /** + * Dump the list of global parameters, as JSON. + * * @subcommand param-dump */ function param_dump() { @@ -51,12 +59,17 @@ function param_dump() { } /** + * Dump the list of installed commands, as JSON. + * * @subcommand cmd-dump */ function cmd_dump() { echo json_encode( self::command_to_array( WP_CLI::get_root_command() ) ); } + /** + * Generate tab completion strings. + */ function completions() { foreach ( WP_CLI::get_root_command()->get_subcommands() as $name => $command ) { $subcommands = $command->get_subcommands(); From 336bcd96b71fc521c95546375537dfd5eb564040 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 4 Aug 2013 23:55:18 +0300 Subject: [PATCH 2084/4858] add new contributors since 0.10 --- .mailmap | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.mailmap b/.mailmap index 682554bd43..310cb19b87 100644 --- a/.mailmap +++ b/.mailmap @@ -3,11 +3,14 @@ bendoh <ben@thinkoomph.com> builtbylane <lanegoldberg@gmail.com> conatus <alex@recordsonribs.com> cyberhobo <dylan.k.kuhn@gmail.com> +dangardner <dan@web.nearest.to> danielbachhuber <d@danielbachhuber.com> +danielbachhuber <danielbachhuber@gmail.com> drrobotnik <B@Brandons-Mac-Pro-4.local> dwightjack <marco.solazzi@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> +eugeneware <eugene@noblesamurai.com> future500 <ramon@future500.nl> getsource <mike.schroder@dreamhost.com> glebis <glebis@gmail.com> @@ -16,6 +19,7 @@ j3lamp <j3lamp@gmail.com> jghazally <jeff@bigfish.co.uk> jghazally <jghazally@gmail.com> jmslbam <jmslbam@gmail.com> +johnbillion <johnbillion@gmail.com> johnpbloch <jbloch@John-Blochs-iMac.local> johnpbloch <johnpbloch@gmail.com> kidfiction <ejdanderson@gmail.com> @@ -26,6 +30,7 @@ matiskay <matiskay@gmail.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> milesj <mileswjohnson@gmail.com> +MiteshShah <Mitesh.Shah@rtCamp.com> mwilliamson <michael.williamson@red-gate.com> mwilliamson <mike@zwobble.org> nacin <andrewnacin@gmail.com> @@ -33,6 +38,7 @@ navitronic <adrian@navitronic.co.uk> nb <nb@nikolay.bg> ocean90 <dominikschilling+git@gmail.com> om4james <james@jamesc.id.au> +om4james <james@om4.com.au> roelven <roel@soundcloud.com> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> @@ -46,6 +52,7 @@ tollmanz <zack@zackdev.com> toszcze <toszcze@gmail.com> tott <tott@automattic.com> twisty <tim@brayshaw.com> +twratajczak <tomasz.ratajczak@espeo.pl> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> wopr42 <john@zippykid.com> From 573f35f646b236356f6ee6347c4a115176b8e0da Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 17:04:28 -0400 Subject: [PATCH 2085/4858] Add wordpress api plugin search method. fixes #615 --- php/commands/plugin.php | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 667e5dc666..b3b66fb491 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -43,6 +43,67 @@ function status( $args ) { parent::status( $args ); } + /** + * Search wordpress.org plugin repo + * + * ## OPTIONS + * + * <plugin> + * : A particular plugin to search for. + * + * --per_page + * : Optional number of results to display. Defaults to 10. + * + * --fields + * : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. acceptable values: + * + * **name**: Plugin Name + * **slug**: Plugin Slug + * **version**: Current Version Number + * **author**: Plugin Author + * **author_profile**: Plugin Author Profile + * **contributors**: Plugin Contributors + * **requires**: Plugin Minimum Requirements + * **tested**: Plugin Tested Up To + * **compatibility**: Plugin Compatible With + * **rating**: Plugin Rating + * **num_ratings**: Number of Plugin Ratings + * **homepage**: Plugin Author's Homepage + * **description**: Plugin's Description + * **short_description**: Plugin's Short Description + * + * ## EXAMPLES + * + * wp plugin search dsgnwrks --per_page=20 + * + * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings + * + * @synopsis <plugin> + */ + function search( $args, $assoc_args = array() ) { + $term = $args[0]; + $per_page = isset( $assoc_args['per_page'] ) ? (int) $assoc_args['per_page'] : 10; + $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author_profile', 'rating' ); + + if ( $term ) { + $api = plugins_api( 'query_plugins', array( + 'per_page' => $per_page, + 'search' => $term, + ) ); + + if ( is_wp_error( $api ) ) + WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); + + if ( ! isset( $api->plugins ) ) + WP_CLI::error( $api->get_error_message() . __( 'API error. Try Again.' ) ); + + WP_CLI\Utils\format_items( 'table', $api->plugins, $fields ); + + WP_CLI::success( count( $api->plugins ). ' Plugins Found. Use slug for other plugin methods.' ); + } + + } + protected function status_single( $args ) { $name = $args[0]; $file = $this->parse_name( $name ); From d9a97ac3b8fe31974849615432633b3c97f459c5 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 17:15:00 -0400 Subject: [PATCH 2086/4858] Update per @danielbachhuber review. --- php/commands/plugin.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index b3b66fb491..f3d60592f9 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -78,9 +78,9 @@ function status( $args ) { * * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings * - * @synopsis <plugin> + * @synopsis <plugin> [--per_page=<per_page>] [--fields=<fields>] */ - function search( $args, $assoc_args = array() ) { + public function search( $args, $assoc_args = array() ) { $term = $args[0]; $per_page = isset( $assoc_args['per_page'] ) ? (int) $assoc_args['per_page'] : 10; $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author_profile', 'rating' ); @@ -97,9 +97,9 @@ function search( $args, $assoc_args = array() ) { if ( ! isset( $api->plugins ) ) WP_CLI::error( $api->get_error_message() . __( 'API error. Try Again.' ) ); - WP_CLI\Utils\format_items( 'table', $api->plugins, $fields ); - WP_CLI::success( count( $api->plugins ). ' Plugins Found. Use slug for other plugin methods.' ); + + WP_CLI\Utils\format_items( 'table', $api->plugins, $fields ); } } From aeb3e2f81f89d93241127b6583a5dc87681d0ebc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Aug 2013 00:47:00 +0300 Subject: [PATCH 2087/4858] make Rewrite_Command::apache_modules() private other code has no business calling it --- php/commands/rewrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index b1c5a51047..1e04593fdd 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -137,7 +137,7 @@ public function dump( $args, $assoc_args ) { * If this isn't done then the .htaccess rewrite rules won't be flushed out * to disk. */ - public static function apache_modules() { + private static function apache_modules() { $mods = WP_CLI::get_config('apache_modules'); if ( !empty( $mods ) && !function_exists( 'apache_get_modules' ) ) { global $is_apache; From a5ed142fc58b8531caada5bff2a5feef3b90da00 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Aug 2013 02:54:31 +0300 Subject: [PATCH 2088/4858] 0.11.0 final --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index b220b0d969..d435efe167 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.11.0-beta' ); +define( 'WP_CLI_VERSION', '0.11.0' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 3f933876fd6b2f2062b6d3041999cffab4958e5b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Aug 2013 02:59:46 +0300 Subject: [PATCH 2089/4858] contrib-list: fix githubify function --- utils/contrib-list | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/utils/contrib-list b/utils/contrib-list index 43d8f1542d..fbce28190e 100755 --- a/utils/contrib-list +++ b/utils/contrib-list @@ -9,14 +9,14 @@ prev_version=$1 linked=$2 githubify() { - local url="https://github.com/$name" - local response_code=$(curl -o /dev/null --silent --head --write-out '%{http_code}\n' $url) + while read name; do + local url="https://github.com/$name" + local response_code=$(curl -o /dev/null --silent --head --write-out '%{http_code}\n' $url) - if [ "200" != "$response_code" ]; then - echo "$response_code: $url" 1>&2; - fi + if [ "200" != "$response_code" ]; then + echo "$response_code: $url" 1>&2; + fi - while read name; do echo " [$name]($url)" done } From 11e37f7c7cdaf19b467388a1d99fb24fd047ecb5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Aug 2013 03:02:13 +0300 Subject: [PATCH 2090/4858] contrib-list: don't show names starting with upper-case before others --- utils/contrib-list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/contrib-list b/utils/contrib-list index fbce28190e..b47f016973 100755 --- a/utils/contrib-list +++ b/utils/contrib-list @@ -23,7 +23,7 @@ githubify() { if [ '-l' == "$linked" ] then - git log --format="%aN" $prev_version -- | sort | uniq | githubify | tr '\n' ',' + git log --format="%aN" $prev_version -- | sort -f | uniq | githubify | tr '\n' ',' else - git log --format="%aN <%aE>" $prev_version -- | sort | uniq + git log --format="%aN <%aE>" $prev_version -- | sort -f | uniq fi From 953c51ba0ad564ee86f0f0bdc868063e9727d7de Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 22:53:10 -0400 Subject: [PATCH 2091/4858] 1) Move search method to CommandWithUpgrade parent class. 2) Add search method for themes. 3) add search=key replacement for plugin and theme methods that take a slug. --- php/WP_CLI/CommandWithUpgrade.php | 56 +++++++++++++++++++++++++++++ php/commands/plugin.php | 45 +++++++++++------------ php/commands/theme.php | 60 ++++++++++++++++++++++++++++++- 3 files changed, 138 insertions(+), 23 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index aaac62ed9a..0a6e9011ba 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -308,4 +308,60 @@ private function get_color( $status ) { return $colors[ $status ]; } + + /** + * Search wordpress.org plugin repo + * + * @param object $api data from WP plugin/theme API + * @param array $fields Data fields to display in table. + * @param string $data_type Plugin or Theme api endpoint + */ + public function search( $api, $fields, $data_type = 'plugin' ) { + + // Sanitize to 1 of 2 types + $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; + $plural = $data_type . 's'; + $data = $api->$plural; + $count = isset( $api->info['results'] ) ? $api->info['results'] : count( $data ); + + if ( is_wp_error( $api ) ) + \WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); + + if ( ! isset( $data ) ) + \WP_CLI::error( __( 'API error. Try Again.' ) ); + + \WP_CLI::success( $count .' '. $plural .' Found. \'search=$key\' in place of slug available for '. $data_type .' commands.' ); + + foreach ( $data as $key => $item ) { + $item->key = $key; + $data[$key] = $item; + } + + $set = set_site_transient( 'wpcli-$data_type-search-data', $data, 60*60 ); + + \WP_CLI\Utils\format_items( 'table', $data, array_merge( array( 'key' ), $fields ) ); + + } + + /** + * Parse the name of a plugin to check if 'search=' exists, and check search transient for the key + * + * @param string name + * @return string + */ + public function parse_search_key( $name, $data_type = 'plugin' ) { + + // Sanitize to 1 of 2 types + $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; + + if ( false !== strpos( $name, 'search=' ) ) { + $search_key = (int) str_replace( 'search=', '', $name ); + if ( ( $trans = get_site_transient( 'wpcli-$data_type-search-data' ) ) && isset( $trans[$search_key] ) ) + $name = $trans[$search_key]->slug; + else + \WP_CLI::error( 'There is no recent search with that key.' ); + } + return $name; + } + } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index f3d60592f9..6e58e676f5 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -85,27 +85,17 @@ public function search( $args, $assoc_args = array() ) { $per_page = isset( $assoc_args['per_page'] ) ? (int) $assoc_args['per_page'] : 10; $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author_profile', 'rating' ); - if ( $term ) { - $api = plugins_api( 'query_plugins', array( - 'per_page' => $per_page, - 'search' => $term, - ) ); + $api = plugins_api( 'query_plugins', array( + 'per_page' => $per_page, + 'search' => $term, + ) ); - if ( is_wp_error( $api ) ) - WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); - - if ( ! isset( $api->plugins ) ) - WP_CLI::error( $api->get_error_message() . __( 'API error. Try Again.' ) ); - - WP_CLI::success( count( $api->plugins ). ' Plugins Found. Use slug for other plugin methods.' ); - - WP_CLI\Utils\format_items( 'table', $api->plugins, $fields ); - } + parent::search( $api, $fields, 'plugin' ); } protected function status_single( $args ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $file = $this->parse_name( $name ); $details = $this->get_details( $file ); @@ -155,7 +145,7 @@ protected function get_all_items() { * @synopsis <plugin> [--network] */ function activate( $args, $assoc_args = array() ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -186,7 +176,7 @@ function activate( $args, $assoc_args = array() ) { * @synopsis <plugin> [--network] */ function deactivate( $args, $assoc_args = array() ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -217,7 +207,7 @@ function deactivate( $args, $assoc_args = array() ) { * @synopsis <plugin> [--network] */ function toggle( $args, $assoc_args = array() ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -308,7 +298,7 @@ protected function install_from_repo( $slug, $assoc_args ) { * @synopsis <plugin> [--version=<version>] */ function update( $args, $assoc_args ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $basename = $this->parse_name( $name ); if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { @@ -405,6 +395,7 @@ protected function get_item_list() { * @synopsis <plugin|zip|url> [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { + $args[0] = $this->parse_search_key( $args[0] ); parent::install( $args, $assoc_args ); } @@ -427,7 +418,7 @@ function install( $args, $assoc_args ) { * @synopsis <plugin> [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $file = $this->parse_name( $name ); if ( is_plugin_active( $file ) ) { @@ -459,7 +450,7 @@ function uninstall( $args, $assoc_args = array() ) { * @synopsis <plugin> */ function delete( $args, $assoc_args = array() ) { - $name = $args[0]; + $name = $this->parse_search_key( $args[0] ); $file = $this->parse_name( $name ); if ( $this->_delete( $file ) ) { @@ -544,6 +535,16 @@ private function parse_name( $name ) { return $file; } + /** + * Parse the name of a plugin to check if 'search=' exists, and check search transient for the key + * + * @param string name + * @return string + */ + public function parse_search_key( $name ) { + return parent::parse_search_key( $name, 'plugin' ); + } + /** * Converts a plugin basename back into a friendly slug. */ diff --git a/php/commands/theme.php b/php/commands/theme.php index 33d80413f5..b5852c4486 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -36,6 +36,53 @@ function status( $args ) { parent::status( $args ); } + /** + * Search wordpress.org theme repo + * + * ## OPTIONS + * + * <theme> + * : A particular theme to search for. + * + * --per_page + * : Optional number of results to display. Defaults to 10. + * + * --fields + * : Ask for specific fields from the API. Defaults to name,slug,author,rating. acceptable values: + * + * **name**: Theme Name + * **slug**: Theme Slug + * **version**: Current Version Number + * **author**: Theme Author + * **preview_url**: Theme Preview URL + * **screenshot_url**: Theme Screenshot URL + * **rating**: Theme Rating + * **num_ratings**: Number of Theme Ratings + * **homepage**: Theme Author's Homepage + * **description**: Theme Description + * + * ## EXAMPLES + * + * wp theme search automattic --per_page=20 + * + * wp theme search automattic --fields=name,version,slug,rating,num_ratings,description + * + * @synopsis <theme> [--per_page=<per_page>] [--fields=<fields>] + */ + public function search( $args, $assoc_args = array() ) { + $term = $args[0]; + $per_page = isset( $assoc_args['per_page'] ) ? (int) $assoc_args['per_page'] : 10; + $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author', 'rating' ); + + $api = themes_api( 'query_themes', array( + 'per_page' => $per_page, + 'search' => $term, + ) ); + + parent::search( $api, $fields, 'theme' ); + + } + protected function status_single( $args ) { $theme = $this->parse_name( $args[0] ); @@ -199,6 +246,7 @@ protected function get_item_list() { * @synopsis <theme|zip|url> [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { + $args[0] = $this->parse_search_key( $args[0] ); parent::install( $args, $assoc_args ); } @@ -305,7 +353,7 @@ function _list( $_, $assoc_args ) { * @return object */ private function parse_name( $name ) { - $theme = wp_get_theme( $name ); + $theme = wp_get_theme( $this->parse_search_key( $name ) ); if ( !$theme->exists() ) { WP_CLI::error( "The theme '$name' could not be found." ); @@ -314,6 +362,16 @@ private function parse_name( $name ) { return $theme; } + + /** + * Parse the name of a theme to check if 'search=' exists, and check search transient for the key + * + * @param string name + * @return string + */ + public function parse_search_key( $name ) { + return parent::parse_search_key( $name, 'theme' ); + } } WP_CLI::add_command( 'theme', 'Theme_Command' ); From 9c2407c4ee4cbb60920743d63d381c84b6de7577 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 23:03:22 -0400 Subject: [PATCH 2092/4858] Comply with PHP Strict Standards --- php/WP_CLI/CommandWithUpgrade.php | 2 +- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 0a6e9011ba..2e7bd69b01 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -316,7 +316,7 @@ private function get_color( $status ) { * @param array $fields Data fields to display in table. * @param string $data_type Plugin or Theme api endpoint */ - public function search( $api, $fields, $data_type = 'plugin' ) { + public function _search( $api, $fields, $data_type = 'plugin' ) { // Sanitize to 1 of 2 types $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 6e58e676f5..83f58f3d14 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -90,7 +90,7 @@ public function search( $args, $assoc_args = array() ) { 'search' => $term, ) ); - parent::search( $api, $fields, 'plugin' ); + parent::_search( $api, $fields, 'plugin' ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index b5852c4486..0cec541082 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -79,7 +79,7 @@ public function search( $args, $assoc_args = array() ) { 'search' => $term, ) ); - parent::search( $api, $fields, 'theme' ); + parent::_search( $api, $fields, 'theme' ); } From 7214f815e5fd14538057644d033efbb28fb515d9 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 23:12:39 -0400 Subject: [PATCH 2093/4858] Comply with PHP Strict Standards --- php/WP_CLI/CommandWithUpgrade.php | 2 +- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 2e7bd69b01..edac698ebc 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -349,7 +349,7 @@ public function _search( $api, $fields, $data_type = 'plugin' ) { * @param string name * @return string */ - public function parse_search_key( $name, $data_type = 'plugin' ) { + public function _parse_search_key( $name, $data_type = 'plugin' ) { // Sanitize to 1 of 2 types $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 83f58f3d14..f9d0dd517b 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -542,7 +542,7 @@ private function parse_name( $name ) { * @return string */ public function parse_search_key( $name ) { - return parent::parse_search_key( $name, 'plugin' ); + return parent::_parse_search_key( $name, 'plugin' ); } /** diff --git a/php/commands/theme.php b/php/commands/theme.php index 0cec541082..4ac4a1af71 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -370,7 +370,7 @@ private function parse_name( $name ) { * @return string */ public function parse_search_key( $name ) { - return parent::parse_search_key( $name, 'theme' ); + return parent::_parse_search_key( $name, 'theme' ); } } From 533beebcd0e56bfcd9c3da07e22792f1c5872d5c Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 23:33:27 -0400 Subject: [PATCH 2094/4858] classify_token method doesn't like underscores and throws a "Warning: unknown --per_page parameter" error. --- php/commands/plugin.php | 8 ++++---- php/commands/theme.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index f9d0dd517b..be9b61e1d2 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -51,7 +51,7 @@ function status( $args ) { * <plugin> * : A particular plugin to search for. * - * --per_page + * --per-page * : Optional number of results to display. Defaults to 10. * * --fields @@ -74,15 +74,15 @@ function status( $args ) { * * ## EXAMPLES * - * wp plugin search dsgnwrks --per_page=20 + * wp plugin search dsgnwrks --per-page=20 * * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings * - * @synopsis <plugin> [--per_page=<per_page>] [--fields=<fields>] + * @synopsis <plugin> [--per-page=<per-page>] [--fields=<fields>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; - $per_page = isset( $assoc_args['per_page'] ) ? (int) $assoc_args['per_page'] : 10; + $per_page = isset( $assoc_args['per-page'] ) ? (int) $assoc_args['per-page'] : 10; $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author_profile', 'rating' ); $api = plugins_api( 'query_plugins', array( diff --git a/php/commands/theme.php b/php/commands/theme.php index 4ac4a1af71..7894afb427 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -44,7 +44,7 @@ function status( $args ) { * <theme> * : A particular theme to search for. * - * --per_page + * --per-page * : Optional number of results to display. Defaults to 10. * * --fields @@ -63,15 +63,15 @@ function status( $args ) { * * ## EXAMPLES * - * wp theme search automattic --per_page=20 + * wp theme search automattic --per-page=20 * * wp theme search automattic --fields=name,version,slug,rating,num_ratings,description * - * @synopsis <theme> [--per_page=<per_page>] [--fields=<fields>] + * @synopsis <theme> [--per-page=<per-page>] [--fields=<fields>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; - $per_page = isset( $assoc_args['per_page'] ) ? (int) $assoc_args['per_page'] : 10; + $per_page = isset( $assoc_args['per-page'] ) ? (int) $assoc_args['per-page'] : 10; $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author', 'rating' ); $api = themes_api( 'query_themes', array( From 7ddaf5a2e89c82e9fda5129c7e898a130310a5c9 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Sun, 4 Aug 2013 23:34:53 -0400 Subject: [PATCH 2095/4858] update search items found message. Now "Showing $count of $total '$plural." --- php/WP_CLI/CommandWithUpgrade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index edac698ebc..7b0b9c168e 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -322,7 +322,7 @@ public function _search( $api, $fields, $data_type = 'plugin' ) { $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; $plural = $data_type . 's'; $data = $api->$plural; - $count = isset( $api->info['results'] ) ? $api->info['results'] : count( $data ); + $count = isset( $api->info['results'] ) ? $api->info['results'] : 'unknown'; if ( is_wp_error( $api ) ) \WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); @@ -330,7 +330,7 @@ public function _search( $api, $fields, $data_type = 'plugin' ) { if ( ! isset( $data ) ) \WP_CLI::error( __( 'API error. Try Again.' ) ); - \WP_CLI::success( $count .' '. $plural .' Found. \'search=$key\' in place of slug available for '. $data_type .' commands.' ); + \WP_CLI::success( 'Showing '. count( $data ) .' of '. $count .' '. $plural .'. \'search=$key\' in place of slug available for '. $data_type .' commands.' ); foreach ( $data as $key => $item ) { $item->key = $key; From 985cf0e57b7ae4818d50b25d1b97efe1dbe783a4 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Mon, 5 Aug 2013 09:31:48 -0400 Subject: [PATCH 2096/4858] Less is more. All that info won't display well on smaller terminal windows. --- php/commands/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index be9b61e1d2..b7e269a356 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -83,7 +83,7 @@ function status( $args ) { public function search( $args, $assoc_args = array() ) { $term = $args[0]; $per_page = isset( $assoc_args['per-page'] ) ? (int) $assoc_args['per-page'] : 10; - $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author_profile', 'rating' ); + $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'rating' ); $api = plugins_api( 'query_plugins', array( 'per_page' => $per_page, From 844612afc73a1afa37599a28f8df3d32b6c4f80f Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 5 Aug 2013 15:50:29 +0200 Subject: [PATCH 2097/4858] Fix notices undefined index post_types when scaffolding CPT Added post_type default value and use $control_args because it it won't be available in $vars --- php/commands/scaffold.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index bdf3435d12..13541038d9 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -107,13 +107,14 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) 'theme' => false, 'plugin' => false, 'raw' => false, + 'post_types' => false, ) ); $vars = $this->extract_args( $assoc_args, $defaults ); $vars['slug'] = $slug; - $vars['post_types'] = $this->quote_comma_list_elements( $vars['post_types'] ); + $vars['post_types'] = $this->quote_comma_list_elements( $control_args['post_types'] ); $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); From a95b73cb8e69fa9b96d1f8cd02c7f6c2c634b84f Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Mon, 5 Aug 2013 11:49:46 -0400 Subject: [PATCH 2098/4858] Allow formatting for search results. --- php/WP_CLI/CommandWithUpgrade.php | 13 ++++++++----- php/commands/plugin.php | 10 ++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 7b0b9c168e..fb0867c237 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -312,11 +312,12 @@ private function get_color( $status ) { /** * Search wordpress.org plugin repo * - * @param object $api data from WP plugin/theme API - * @param array $fields Data fields to display in table. - * @param string $data_type Plugin or Theme api endpoint + * @param object $api Data from WP plugin/theme API + * @param array $fields Data fields to display in table. + * @param array $assoc_args Data passed in from command. + * @param string $data_type Plugin or Theme api endpoint */ - public function _search( $api, $fields, $data_type = 'plugin' ) { + public function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { // Sanitize to 1 of 2 types $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; @@ -339,7 +340,9 @@ public function _search( $api, $fields, $data_type = 'plugin' ) { $set = set_site_transient( 'wpcli-$data_type-search-data', $data, 60*60 ); - \WP_CLI\Utils\format_items( 'table', $data, array_merge( array( 'key' ), $fields ) ); + $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; + + \WP_CLI\Utils\format_items( $format, $data, array_merge( array( 'key' ), $fields ) ); } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index b7e269a356..018e6ab9f4 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -54,6 +54,9 @@ function status( $args ) { * --per-page * : Optional number of results to display. Defaults to 10. * + * --format + * : Output list as table, CSV or JSON. Defaults to table. + * * --fields * : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. acceptable values: * @@ -74,11 +77,11 @@ function status( $args ) { * * ## EXAMPLES * - * wp plugin search dsgnwrks --per-page=20 + * wp plugin search dsgnwrks --per-page=20 --format=json * * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings * - * @synopsis <plugin> [--per-page=<per-page>] [--fields=<fields>] + * @synopsis <plugin> [--per-page=<per-page>] [--fields=<fields>] [--format=<format>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; @@ -90,8 +93,7 @@ public function search( $args, $assoc_args = array() ) { 'search' => $term, ) ); - parent::_search( $api, $fields, 'plugin' ); - + parent::_search( $api, $fields, $assoc_args, 'plugin' ); } protected function status_single( $args ) { From 5c2bc1ec3755d937c90884382105f785f6582edb Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Mon, 5 Aug 2013 11:57:10 -0400 Subject: [PATCH 2099/4858] Remove search=$key slug replacement method. :( --- php/WP_CLI/CommandWithUpgrade.php | 21 --------------------- php/commands/plugin.php | 25 +++++++------------------ php/commands/theme.php | 12 +----------- 3 files changed, 8 insertions(+), 50 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index fb0867c237..e0d5a29c92 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -346,25 +346,4 @@ public function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { } - /** - * Parse the name of a plugin to check if 'search=' exists, and check search transient for the key - * - * @param string name - * @return string - */ - public function _parse_search_key( $name, $data_type = 'plugin' ) { - - // Sanitize to 1 of 2 types - $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; - - if ( false !== strpos( $name, 'search=' ) ) { - $search_key = (int) str_replace( 'search=', '', $name ); - if ( ( $trans = get_site_transient( 'wpcli-$data_type-search-data' ) ) && isset( $trans[$search_key] ) ) - $name = $trans[$search_key]->slug; - else - \WP_CLI::error( 'There is no recent search with that key.' ); - } - return $name; - } - } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 018e6ab9f4..ebb8d8a01e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -97,7 +97,7 @@ public function search( $args, $assoc_args = array() ) { } protected function status_single( $args ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $file = $this->parse_name( $name ); $details = $this->get_details( $file ); @@ -147,7 +147,7 @@ protected function get_all_items() { * @synopsis <plugin> [--network] */ function activate( $args, $assoc_args = array() ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -178,7 +178,7 @@ function activate( $args, $assoc_args = array() ) { * @synopsis <plugin> [--network] */ function deactivate( $args, $assoc_args = array() ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -209,7 +209,7 @@ function deactivate( $args, $assoc_args = array() ) { * @synopsis <plugin> [--network] */ function toggle( $args, $assoc_args = array() ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $file = $this->parse_name( $name ); $network_wide = isset( $assoc_args['network'] ); @@ -300,7 +300,7 @@ protected function install_from_repo( $slug, $assoc_args ) { * @synopsis <plugin> [--version=<version>] */ function update( $args, $assoc_args ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $basename = $this->parse_name( $name ); if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { @@ -397,7 +397,6 @@ protected function get_item_list() { * @synopsis <plugin|zip|url> [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { - $args[0] = $this->parse_search_key( $args[0] ); parent::install( $args, $assoc_args ); } @@ -420,7 +419,7 @@ function install( $args, $assoc_args ) { * @synopsis <plugin> [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $file = $this->parse_name( $name ); if ( is_plugin_active( $file ) ) { @@ -452,7 +451,7 @@ function uninstall( $args, $assoc_args = array() ) { * @synopsis <plugin> */ function delete( $args, $assoc_args = array() ) { - $name = $this->parse_search_key( $args[0] ); + $name = $args[0]; $file = $this->parse_name( $name ); if ( $this->_delete( $file ) ) { @@ -537,16 +536,6 @@ private function parse_name( $name ) { return $file; } - /** - * Parse the name of a plugin to check if 'search=' exists, and check search transient for the key - * - * @param string name - * @return string - */ - public function parse_search_key( $name ) { - return parent::_parse_search_key( $name, 'plugin' ); - } - /** * Converts a plugin basename back into a friendly slug. */ diff --git a/php/commands/theme.php b/php/commands/theme.php index 7894afb427..8637b6b9fa 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -246,7 +246,6 @@ protected function get_item_list() { * @synopsis <theme|zip|url> [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { - $args[0] = $this->parse_search_key( $args[0] ); parent::install( $args, $assoc_args ); } @@ -353,7 +352,7 @@ function _list( $_, $assoc_args ) { * @return object */ private function parse_name( $name ) { - $theme = wp_get_theme( $this->parse_search_key( $name ) ); + $theme = wp_get_theme( $name ); if ( !$theme->exists() ) { WP_CLI::error( "The theme '$name' could not be found." ); @@ -363,15 +362,6 @@ private function parse_name( $name ) { return $theme; } - /** - * Parse the name of a theme to check if 'search=' exists, and check search transient for the key - * - * @param string name - * @return string - */ - public function parse_search_key( $name ) { - return parent::_parse_search_key( $name, 'theme' ); - } } WP_CLI::add_command( 'theme', 'Theme_Command' ); From c6ef951089269640fb133ff99f7a2ccd4f2f688b Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Mon, 5 Aug 2013 12:58:18 -0400 Subject: [PATCH 2100/4858] =?UTF-8?q?THe=20stars=20have=20aligned=E2=80=A6?= =?UTF-8?q?=20https://github.com/wp-cli/wp-cli/pull/630/files#r5583311?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/commands/plugin.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ebb8d8a01e..49bdfcde19 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -61,19 +61,19 @@ function status( $args ) { * : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. acceptable values: * * **name**: Plugin Name - * **slug**: Plugin Slug - * **version**: Current Version Number - * **author**: Plugin Author - * **author_profile**: Plugin Author Profile - * **contributors**: Plugin Contributors - * **requires**: Plugin Minimum Requirements - * **tested**: Plugin Tested Up To - * **compatibility**: Plugin Compatible With - * **rating**: Plugin Rating - * **num_ratings**: Number of Plugin Ratings - * **homepage**: Plugin Author's Homepage - * **description**: Plugin's Description - * **short_description**: Plugin's Short Description + * **slug**: Plugin Slug + * **version**: Current Version Number + * **author**: Plugin Author + * **author_profile**: Plugin Author Profile + * **contributors**: Plugin Contributors + * **requires**: Plugin Minimum Requirements + * **tested**: Plugin Tested Up To + * **compatibility**: Plugin Compatible With + * **rating**: Plugin Rating + * **num_ratings**: Number of Plugin Ratings + * **homepage**: Plugin Author's Homepage + * **description**: Plugin's Description + * **short_description**: Plugin's Short Description * * ## EXAMPLES * From 03fa3278076b09865cdd12885b12f6424c88e6d3 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Mon, 5 Aug 2013 12:59:23 -0400 Subject: [PATCH 2101/4858] Make _search() a protected method and wrap 'key' field addition in a conditional for 'interactive' (add a @TODO inline comment) https://github.com/wp-cli/wp-cli/pull/630/files#r5583311 --- php/WP_CLI/CommandWithUpgrade.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e0d5a29c92..32f99da43c 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -317,7 +317,7 @@ private function get_color( $status ) { * @param array $assoc_args Data passed in from command. * @param string $data_type Plugin or Theme api endpoint */ - public function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { + protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { // Sanitize to 1 of 2 types $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; @@ -333,16 +333,22 @@ public function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { \WP_CLI::success( 'Showing '. count( $data ) .' of '. $count .' '. $plural .'. \'search=$key\' in place of slug available for '. $data_type .' commands.' ); - foreach ( $data as $key => $item ) { - $item->key = $key; - $data[$key] = $item; - } + $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; - $set = set_site_transient( 'wpcli-$data_type-search-data', $data, 60*60 ); + // @TODO https://github.com/wp-cli/wp-cli/issues/635 + if ( isset( $assoc_args['interactive'] ) ) { + // Add key as a field + $fields = array_merge( array( 'key' ), $fields ) : $fields; + // & infuse object with $key + foreach ( $data as $key => $item ) { + $item->key = $key; + $data[$key] = $item; + } + } - $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; + $fields = isset( $assoc_args['interactive'] ) ? array_merge( array( 'key' ), $fields ) : $fields; - \WP_CLI\Utils\format_items( $format, $data, array_merge( array( 'key' ), $fields ) ); + \WP_CLI\Utils\format_items( $format, $data, $fields ); } From d6287f7622ec71653ec0d5b4e52a8b4992183e0c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Aug 2013 22:59:21 +0300 Subject: [PATCH 2102/4858] add regression test --- features/help.feature | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index 10626d66a1..f8ee09c2bf 100644 --- a/features/help.feature +++ b/features/help.feature @@ -20,10 +20,17 @@ Feature: Get help about WP-CLI commands And STDERR should not be empty Scenario: Help for incomplete commands - Given an empty directory + Given a WP install When I run `wp core` Then STDOUT should contain: """ usage: wp core """ + + # See https://github.com/wp-cli/wp-cli/issues/633 + When I run `wp plugin install` + Then STDOUT should contain: + """ + usage: wp plugin install + """ From 10904b79b21652ebbb381b3a5c3ee4389845232b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 5 Aug 2013 23:09:15 +0300 Subject: [PATCH 2103/4858] add unit test for #633 It's better to test for the specific bug, when possible. This reverts commit d6287f7622ec71653ec0d5b4e52a8b4992183e0c. --- features/help.feature | 9 +-------- tests/test-synopsis.php | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/features/help.feature b/features/help.feature index f8ee09c2bf..10626d66a1 100644 --- a/features/help.feature +++ b/features/help.feature @@ -20,17 +20,10 @@ Feature: Get help about WP-CLI commands And STDERR should not be empty Scenario: Help for incomplete commands - Given a WP install + Given an empty directory When I run `wp core` Then STDOUT should contain: """ usage: wp core """ - - # See https://github.com/wp-cli/wp-cli/issues/633 - When I run `wp plugin install` - Then STDOUT should contain: - """ - usage: wp plugin install - """ diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 22e7cb907c..427e2ab9b3 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -11,7 +11,7 @@ function testEmpty() { } function testPositional() { - $r = SynopsisParser::parse( '<foo> [<bar>]' ); + $r = SynopsisParser::parse( '<plugin|zip> [<bar>]' ); $this->assertCount( 2, $r ); From e84d1e22ccb613528f8d863e0d8380db37d82bbb Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Mon, 5 Aug 2013 23:54:35 +0200 Subject: [PATCH 2104/4858] Move `--post_types` to taxonomy function Because a CPT doesn't need this arg. --- php/commands/scaffold.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 13541038d9..af10af5fbb 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -90,9 +90,13 @@ function post_type( $args, $assoc_args ) { function taxonomy( $args, $assoc_args ) { $defaults = array( 'textdomain' => '', - 'post_types' => 'post' + 'post_types' => "'post'" ); + if( isset($assoc_args['post_types']) ) { + $assoc_args['post_types'] = $this->quote_comma_list_elements( $assoc_args['post_types'] ); + } + $this->_scaffold( $args[0], $assoc_args, $defaults, '/taxonomies/', array( 'taxonomy.mustache', 'taxonomy_extended.mustache' @@ -107,15 +111,12 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) 'theme' => false, 'plugin' => false, 'raw' => false, - 'post_types' => false, ) ); $vars = $this->extract_args( $assoc_args, $defaults ); $vars['slug'] = $slug; - $vars['post_types'] = $this->quote_comma_list_elements( $control_args['post_types'] ); - $vars['textdomain'] = $this->get_textdomain( $vars['textdomain'], $control_args ); $vars['label'] = $control_args['label']; From 1512802316f68d44968c70c9765cbd6ec333e93d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Aug 2013 01:18:32 +0300 Subject: [PATCH 2105/4858] use $p_value instead of $p_name for positional parameters --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index d7e4c1ba1a..1da1504ef5 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -42,7 +42,7 @@ private static function classify_token( $token ) { if ( '--<field>=<value>' === $token ) { $param['type'] = 'generic'; - } elseif ( preg_match( "/^<$p_name>$/", $token, $matches ) ) { + } elseif ( preg_match( "/^<$p_value>$/", $token, $matches ) ) { $param['type'] = 'positional'; } elseif ( preg_match( "/^--$p_name/", $token, $matches ) ) { $param['name'] = $matches[1]; From aa915668f0b6d7a5a7934a4b9326871a1f984975 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Tue, 6 Aug 2013 01:19:56 +0300 Subject: [PATCH 2106/4858] Add/Remove capabilities for users --- php/commands/user.php | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index 8f1a6335b9..5f7d010eba 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -448,6 +448,62 @@ public function remove_role( $args, $assoc_args ) { WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); } } + + /** + * Add a capability for a user. + * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * <cap> + * : Add the specified capability for the user. + * + * ## EXAMPLES + * + * wp user add-cap john create_premium_item + * wp user add-cap 15 edit_product + * + * @subcommand add-cap + * @synopsis <user> <cap> + */ + public function add_cap( $args, $assoc_args ) { + $user = self::get_user( $args[0] ); + $cap = $args[1]; + + $user->add_cap( $cap ); + + WP_CLI::success( sprintf( "Added '%s' capability for %s (%d).", $cap, $user->user_login, $user->ID ) ); + } + + /** + * Remove a user's capability. + * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * <cap> + * : Capability to be removed. + * + * ## EXAMPLES + * + * wp user remove-cap bob edit_themes + * wp user remove-cap 11 publish_newsletters + * + * @subcommand remove-cap + * @synopsis <user> <cap> + */ + public function remove_cap( $args, $assoc_args ) { + $user = self::get_user( $args[0] ); + $cap = $args[1]; + + $user->remove_cap( $cap ); + + WP_CLI::success( sprintf( "Removed '%s' cap for %s (%d).", $cap, $user->user_login, $user->ID ) ); + } private static function get_user( $id_or_login ) { if ( is_numeric( $id_or_login ) ) From de37f20f4d1c230abcc2669680bf16f830083eab Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Aug 2013 01:58:33 +0300 Subject: [PATCH 2107/4858] add array_column() polyfill for PHP<5.5 --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 886935c216..a617277779 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "require": { "php": ">=5.3.2", "wp-cli/php-cli-tools": "0.9.3", - "mustache/mustache": "~2.4" + "mustache/mustache": "~2.4", + "rhumsaa/array_column": "~1.1" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" From 9078761a789880789eadfc0b6e613e0c15217d8b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Aug 2013 02:04:13 +0300 Subject: [PATCH 2108/4858] show warning for invalid synopsis parts --- php/WP_CLI/Dispatcher/Subcommand.php | 9 +++++++++ php/WP_CLI/SynopsisValidator.php | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 16d101e3f0..45be83bd01 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -43,6 +43,15 @@ private function validate_args( $args, &$assoc_args ) { return; $parser = new \WP_CLI\SynopsisValidator( $synopsis ); + + $cmd_path = implode( ' ', get_path( $this ) ); + foreach ( $parser->get_unknown() as $token ) { + \WP_CLI::warning( sprintf( + "The `%s` command has an invalid synopsis part: %s", + $cmd_path, $token + ) ); + } + if ( !$parser->enough_positionals( $args ) ) { $this->show_usage(); exit(1); diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index 4b62a364ea..90a7cb8773 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -13,6 +13,12 @@ public function __construct( $synopsis ) { $this->spec = SynopsisParser::parse( $synopsis ); } + public function get_unknown() { + return array_column( $this->query_spec( array( + 'type' => 'unknown', + ) ), 'token' ); + } + public function enough_positionals( $args ) { $positional = $this->query_spec( array( 'type' => 'positional', From 0423c4bdea8d9c00c8a5c22ede5b332357687b27 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Tue, 6 Aug 2013 02:08:18 +0300 Subject: [PATCH 2109/4858] Add capabilities list function for users --- php/commands/user.php | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index 5f7d010eba..e1aca7ac61 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -504,6 +504,44 @@ public function remove_cap( $args, $assoc_args ) { WP_CLI::success( sprintf( "Removed '%s' cap for %s (%d).", $cap, $user->user_login, $user->ID ) ); } + + /** + * List all user's capabilities. + * + * ## OPTIONS + * + * <user> + * : User ID or user login. + * + * ## EXAMPLES + * + * wp user list-caps admin + * wp user list-caps 21 + * + * @subcommand list-caps + * @synopsis <user> + */ + public function list_caps( $args, $assoc_args ) { + $user = self::get_user( $args[0] ); + $user->get_role_caps(); + + $user_caps_list = $user->allcaps; + $cap_table_titles = array( 'capability', 'status' ); + + // Get all active caps (marked as true) + $active_user_caps = array(); + + foreach( $user_caps_list as $cap => $active ) { + if( $active ) { + $active_user_caps[] = $cap; + } + } + + // Omit formatting from the Utils class due to the assoc array format + $user_caps = implode( ', ', $active_user_caps ); + + WP_CLI::success( sprintf( "User caps (role and individual) are: %s.", $user_caps ) ); + } private static function get_user( $id_or_login ) { if ( is_numeric( $id_or_login ) ) From e35799b1fa726793ec341a6ec30cf38ecb8664b4 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Tue, 6 Aug 2013 02:22:10 +0300 Subject: [PATCH 2110/4858] Listing each cap on a separate line --- php/commands/user.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index e1aca7ac61..8fcb031bcd 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -527,20 +527,14 @@ public function list_caps( $args, $assoc_args ) { $user_caps_list = $user->allcaps; $cap_table_titles = array( 'capability', 'status' ); - - // Get all active caps (marked as true) - $active_user_caps = array(); + + WP_CLI::success( "User caps (role and individual) are: " ); foreach( $user_caps_list as $cap => $active ) { if( $active ) { - $active_user_caps[] = $cap; + \cli\line( $cap ); } } - - // Omit formatting from the Utils class due to the assoc array format - $user_caps = implode( ', ', $active_user_caps ); - - WP_CLI::success( sprintf( "User caps (role and individual) are: %s.", $user_caps ) ); } private static function get_user( $id_or_login ) { From 1fe10ae4e5efd83ef8f74b552bd5e0c1cc4ec3db Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Aug 2013 03:06:02 +0300 Subject: [PATCH 2111/4858] colorize update candidates. fixes #638 --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index aaac62ed9a..8e3e6c8c78 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -192,7 +192,7 @@ function update_all( $args, $assoc_args ) { } } - \WP_CLI::line( $item_list ); + \WP_CLI::line( \WP_CLI::colorize( $item_list ) ); return; } From d8448f5a7e894a8a7e0509dd379bb10a541d48e1 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Tue, 6 Aug 2013 04:03:37 +0300 Subject: [PATCH 2112/4858] First test cases in Behat for capability management --- features/user.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/features/user.feature b/features/user.feature index ced0e41920..43bfe2ae47 100644 --- a/features/user.feature +++ b/features/user.feature @@ -92,3 +92,24 @@ Feature: Manage WordPress users Then STDOUT should be a table containing rows: | Field | Value | | roles | | + + Scenario: Managing user capabilities + Given a WP install + + When I run `wp user add-cap 1 edit_vip_product` + Then STDOUT should be: + """ + Success: Added 'edit_vip_product' capability for admin (1). + """ + + And I run `wp user list-caps 1 | tail -n 1` + Then STDOUT should be: + """ + edit_vip_product + """ + + And I run `wp user remove-cap 1 edit_vip_product` + Then STDOUT should be: + """ + Success: Removed 'edit_vip_product' cap for admin (1). + """ From 2c08a390f81da650a4fcddaee567a6751611b607 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 6 Aug 2013 13:38:35 +0300 Subject: [PATCH 2113/4858] introduce WP_CLI_PHP_ARGS environment variable also, remove old Drush code for looking up php.ini files fixes #631 --- bin/wp | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/bin/wp b/bin/wp index 706f6c9fd7..762d6f5d91 100755 --- a/bin/wp +++ b/bin/wp @@ -39,28 +39,8 @@ else php=`which php` fi -# Check to see if the user has provided a php.ini file or wp-cli.ini file in any conf dir -# Last found wins, so search in reverse priority order -for conf_dir in $(dirname "$SELF_PATH") /etc/wp-cli $HOME/.wp-cli ; do - if [ -f $conf_dir/php.ini ] ; then - wp_cli_php_ini=$conf_dir/php.ini - fi - if [ -f $conf_dir/wp-cli.ini ] ; then - wp_cli_php_override=$conf_dir/wp-cli.ini - fi -done - -# Add in the php file location and/or the php override variables as appropriate -if [ "x$wp_cli_php_ini" != "x" ] ; then - php="$php --php-ini $wp_cli_php_ini" -fi -if [ "x$wp_cli_php_override" != "x" ] ; then - wp_cli_override_vars=`grep '^[a-z_A-Z0-9]\+ *=' $wp_cli_php_override | sed -e 's|\([^ =]*\) *= *\(.*\)|\1="\2"|' -e 's| ||g' -e 's|^|-d |' | tr '\n\r' ' '` - php="$php $wp_cli_override_vars" -fi - -export WP_CLI_PHP_USED=$php - # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands -exec "$php" "$SCRIPT_PATH" "$@" +export WP_CLI_PHP_USED=$php + +exec "$php" $WP_CLI_PHP_ARGS "$SCRIPT_PATH" "$@" From 527e9d02c9802d7e7f8fa9c5fd35871946f1a51f Mon Sep 17 00:00:00 2001 From: Alex Ciobica <alex.ciobica@gmail.com> Date: Tue, 6 Aug 2013 14:33:04 +0300 Subject: [PATCH 2114/4858] Fix search replace reserved column name issues. --- php/commands/search-replace.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 4185598109..c1e4b00700 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -101,10 +101,12 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry // We don't want to have to generate thousands of rows when running the test suite $chunk_size = getenv( 'BEHAT_RUN' ) ? 10 : 1000; + $fields = array( $primary_key, $col ); + $fields = array_map( function ($v) { return "`$v`"; }, $fields ); $args = array( 'table' => $table, - 'fields' => array( $primary_key, $col ), - 'where' => $col . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', + 'fields' => $fields, + 'where' => "`$col`" . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', 'chunk_size' => $chunk_size ); From 8a10e302b8376febec4ed7d5db3671a87708dd13 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Tue, 6 Aug 2013 18:38:26 +0100 Subject: [PATCH 2115/4858] Use `wp_parse_args()` where we can --- php/WP_CLI/CommandWithUpgrade.php | 11 ++--------- php/commands/post.php | 9 +-------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index aaac62ed9a..6331de3380 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -219,19 +219,12 @@ function update_all( $args, $assoc_args ) { } } - protected function _list( $_, $format ) { + protected function _list( $_, $assoc_args ) { $values = array( 'format' => 'table', 'fields' => $this->fields ); - - foreach ( $values as $key => &$value ) { - if ( isset( $format[ $key ] ) ) { - $value = $format[ $key ]; - unset( $format[ $key ] ); - } - } - unset( $value ); + $values = wp_parse_args( $assoc_args, $values ); $all_items = $this->get_all_items(); $items = $this->create_objects( $all_items ); diff --git a/php/commands/post.php b/php/commands/post.php index 1792830998..7465cc51dc 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -168,14 +168,7 @@ public function _list( $_, $assoc_args ) { 'format' => 'table', 'fields' => $this->fields ); - - foreach ( $values as $key => &$value ) { - if ( isset( $assoc_args[ $key ] ) ) { - $value = $assoc_args[ $key ]; - unset( $assoc_args[ $key ] ); - } - } - unset( $value ); + $values = wp_parse_args( $assoc_args, $values ); foreach ( $assoc_args as $key => $value ) { if ( true === $value ) From 0be7a0cf0d895fecba182b360aee25c73d88a015 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 7 Aug 2013 00:47:19 +0300 Subject: [PATCH 2116/4858] add regression test for #645 --- features/help.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/features/help.feature b/features/help.feature index 10626d66a1..b0225d0c0c 100644 --- a/features/help.feature +++ b/features/help.feature @@ -19,6 +19,36 @@ Feature: Get help about WP-CLI commands Then the return code should be 1 And STDERR should not be empty + Scenario: Help for third-party commands + Given a WP install + And a wp-content/plugins/test-cli/command.php file: + """ + <?php + // Plugin Name: Test CLI Help + + class Test_Help extends WP_CLI_Command { + /** + * A dummy command. + */ + function __invoke() {} + } + + WP_CLI::add_command( 'test-help', 'Test_Help' ); + """ + And I run `wp plugin activate test-cli` + + When I run `wp help` + Then STDOUT should contain: + """ + A dummy command. + """ + + When I run `wp help test-help` + Then STDOUT should contain: + """ + wp test-help + """ + Scenario: Help for incomplete commands Given an empty directory From f44778231014f7531ac8745e43332d1a65600f7f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 7 Aug 2013 01:39:37 +0300 Subject: [PATCH 2117/4858] show commands defined in plugins when running 'wp help' --- php/WP_CLI/Runner.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4d11ffc4a4..1502ac7b30 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -337,8 +337,12 @@ private function init_logger() { WP_CLI::set_logger( $logger ); } + private function wp_exists() { + return is_readable( ABSPATH . 'wp-includes/version.php' ); + } + private function check_wp_version() { - if ( !is_readable( ABSPATH . 'wp-includes/version.php' ) ) { + if ( !$this->wp_exists() ) { WP_CLI::error( "This does not seem to be a WordPress install.\n" . "Pass --path=`path/to/wordpress` or run `wp core download`." ); @@ -410,14 +414,15 @@ public function before_wp_load() { } } + // Handle --path parameter + self::set_wp_root( $this->config ); + // First try at showing man page - if ( $this->cmd_starts_with( array( 'help' ) ) ) { + if ( 'help' === $this->arguments[0] && + ( isset( $this->arguments[1] ) || !$this->wp_exists() ) ) { $this->_run_command(); } - // Handle --path parameter - self::set_wp_root( $this->config ); - // Handle --url and --blog parameters $url = self::guess_url( $this->config ); if ( $url ) { From 9eaab03283f4a8a30e91c0b2c6bf091d67ff0f1e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 7 Aug 2013 02:35:23 +0300 Subject: [PATCH 2118/4858] add test for #634 --- features/option.feature | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/features/option.feature b/features/option.feature index 66c8d78e2e..a009349d33 100644 --- a/features/option.feature +++ b/features/option.feature @@ -3,29 +3,46 @@ Feature: Manage WordPress options Scenario: Option CRUD Given a WP install - When I run `wp option add foo 'bar'` + # String values + When I run `wp option add str_opt 'bar'` Then STDOUT should not be empty - When I run `wp option get foo` + When I run `wp option get str_opt` Then STDOUT should be: """ bar """ - When I run `wp option set foo '[ 1, 2 ]' --format=json` + When I run `wp option delete str_opt` + Then STDOUT should not be empty + + When I try `wp option get str_opt` + Then the return code should be 1 + + + # Integer values + When I run `wp option update blog_public 0` Then STDOUT should not be empty When I run the previous command again Then STDOUT should not be empty - When I run `wp option get foo --format=json` + When I run `wp option get blog_public` Then STDOUT should be: """ - [1,2] + 0 """ - When I run `wp option delete foo` + + # JSON values + When I run `wp option set json_opt '[ 1, 2 ]' --format=json` Then STDOUT should not be empty - When I try `wp option get foo` - Then the return code should be 1 + When I run the previous command again + Then STDOUT should not be empty + + When I run `wp option get json_opt --format=json` + Then STDOUT should be: + """ + [1,2] + """ From f98a6f19fa6ca169e8e97ee3509dc1c410c56598 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 7 Aug 2013 02:26:41 +0300 Subject: [PATCH 2119/4858] option update: use non-strict comparison --- php/commands/option.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index ccefe5bf48..a825342c59 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -67,7 +67,7 @@ public function update( $args, $assoc_args ) { $result = update_option( $key, $value ); // update_option() returns false if the value is the same - if ( !$result && $value !== get_option( $key ) ) { + if ( !$result && $value != get_option( $key ) ) { WP_CLI::error( "Could not update option '$key'." ); } else { WP_CLI::success( "Updated '$key' option." ); From e1f49a5c8ee7d4eaabf5f2be895927890f64249b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 7 Aug 2013 02:55:27 +0300 Subject: [PATCH 2120/4858] bump version to 0.11.1-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index d435efe167..62cff3bfdb 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.11.0' ); +define( 'WP_CLI_VERSION', '0.11.1-alpha' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 57e642f163985713f4eabb9a57ebdbb17d1a987a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 7 Aug 2013 03:16:50 +0300 Subject: [PATCH 2121/4858] move column escaping down into the table iterator see #641 --- php/WP_CLI/Iterators/Table.php | 13 ++++++++----- php/commands/search-replace.php | 1 - 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 6e05cf9ed9..441b69dc7b 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -8,7 +8,7 @@ class Table extends Query { /** - * Creates an iterator over a database table + * Creates an iterator over a database table. * * <code> * foreach( new Iterators\Table( array( 'table' => $wpdb->posts, 'fields' => array( 'ID', 'post_content' ) ) ) as $post ) { @@ -31,7 +31,7 @@ class Table extends Query { * * @param array $args Supported arguments: * table – the name of the database table - * fields – an array of columns to get from the posst table, * is a valid value and the default + * fields – an array of columns to get from the table, '*' is a valid value and the default * where – conditions for filtering rows. Supports two formats: * = string – this will be the where clause * = array – each element is treated as a condition if it's positional, or as column => value if @@ -41,7 +41,7 @@ function __construct( $args = array() ) { global $wpdb; $defaults = array( - 'fields' => array( '*' ), + 'fields' => '*', 'where' => array(), 'table' => null, 'chunk_size' => 500 @@ -51,14 +51,17 @@ function __construct( $args = array() ) { $fields = self::build_fields( $args['fields'] ); $conditions = self::build_where_conditions( $args['where'] ); - $where_sql = $conditions? " WHERE $conditions" : ''; + $where_sql = $conditions ? " WHERE $conditions" : ''; $query = "SELECT $fields FROM $table $where_sql"; parent::__construct( $query, $args['chunk_size'] ); } private static function build_fields( $fields ) { - return implode( ', ', $fields ); + if ( '*' === $fields ) + return $fields; + + return implode( ', ', array_map( function ($v) { return "`$v`"; }, $fields ) ); } private static function build_where_conditions( $where ) { diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c1e4b00700..7cbb520195 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -102,7 +102,6 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry $chunk_size = getenv( 'BEHAT_RUN' ) ? 10 : 1000; $fields = array( $primary_key, $col ); - $fields = array_map( function ($v) { return "`$v`"; }, $fields ); $args = array( 'table' => $table, 'fields' => $fields, From 0a831399559951ff1e8b277c874ed6a42400a731 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Wed, 7 Aug 2013 15:42:03 -0400 Subject: [PATCH 2122/4858] Whoops! parse_error fixed. --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 32f99da43c..b50803de7b 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -338,7 +338,7 @@ protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) // @TODO https://github.com/wp-cli/wp-cli/issues/635 if ( isset( $assoc_args['interactive'] ) ) { // Add key as a field - $fields = array_merge( array( 'key' ), $fields ) : $fields; + $fields = array_merge( array( 'key' ), $fields ); // & infuse object with $key foreach ( $data as $key => $item ) { $item->key = $key; From 3085c6657a6a22e7bad8734b86dfada6d8125117 Mon Sep 17 00:00:00 2001 From: Josh Betz <j@joshbetz.com> Date: Wed, 7 Aug 2013 22:30:08 -0500 Subject: [PATCH 2123/4858] Add is-installed command to wp-cli --- php/commands/plugin.php | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 667e5dc666..48523213fa 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -383,6 +383,30 @@ function uninstall( $args, $assoc_args = array() ) { } } + + /** + * Check if the plugin is installed + * + * ## OPTIONS + * + * <plugin> + * : The plugin to check. + * + * ## EXAMPLES + * + * wp plugin is-installed hello + * + * @subcommand is-installed + * @synopsis <plugin> + */ + function is_installed( $args, $assoc_args = array() ) { + if ( $this->_parse_name( $args[0] ) ) { + exit( 0 ); + } else { + exit( 1 ); + } + } + /** * Delete plugin files. * @@ -463,7 +487,7 @@ protected function get_details( $file ) { * @param string name * @return string */ - private function parse_name( $name ) { + private function _parse_name( $name ) { $plugins = get_plugins( '/' . $name ); if ( !empty( $plugins ) ) { @@ -475,14 +499,22 @@ private function parse_name( $name ) { $plugins = get_plugins(); if ( !isset( $plugins[$file] ) ) { - WP_CLI::error( "The plugin '$name' could not be found." ); - exit(); + return false; } } return $file; } + private function parse_name( $name ) { + if ( $file = $this->_parse_name( $name ) ) { + return $file; + } else { + WP_CLI::error( "The plugin '$name' could not be found." ); + exit(); + } + } + /** * Converts a plugin basename back into a friendly slug. */ From 0440af257a912f21cf8405782a2c85359328ba00 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 8 Aug 2013 16:14:32 +0300 Subject: [PATCH 2124/4858] update .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 310cb19b87..76512b890d 100644 --- a/.mailmap +++ b/.mailmap @@ -1,6 +1,7 @@ andreascreten <andreas@madewithlove.be> bendoh <ben@thinkoomph.com> builtbylane <lanegoldberg@gmail.com> +c10b10 <alex.ciobica@gmail.com> conatus <alex@recordsonribs.com> cyberhobo <dylan.k.kuhn@gmail.com> dangardner <dan@web.nearest.to> From 49c31f899939461569553bf0745ecfea285f6e50 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 8 Aug 2013 16:15:04 +0300 Subject: [PATCH 2125/4858] bump version to 0.11.1 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 62cff3bfdb..27679afdd3 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.11.1-alpha' ); +define( 'WP_CLI_VERSION', '0.11.1' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 37896391908934c16d95effdad3962cf8dc8fe1e Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Thu, 8 Aug 2013 17:00:38 +0300 Subject: [PATCH 2126/4858] Adding some checks for non-existing users --- php/commands/user.php | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 8fcb031bcd..269a38dece 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -470,11 +470,12 @@ public function remove_role( $args, $assoc_args ) { */ public function add_cap( $args, $assoc_args ) { $user = self::get_user( $args[0] ); - $cap = $args[1]; - - $user->add_cap( $cap ); - - WP_CLI::success( sprintf( "Added '%s' capability for %s (%d).", $cap, $user->user_login, $user->ID ) ); + if( $user ) { + $cap = $args[1]; + $user->add_cap( $cap ); + + WP_CLI::success( sprintf( "Added '%s' capability for %s (%d).", $cap, $user->user_login, $user->ID ) ); + } } /** @@ -498,11 +499,12 @@ public function add_cap( $args, $assoc_args ) { */ public function remove_cap( $args, $assoc_args ) { $user = self::get_user( $args[0] ); - $cap = $args[1]; - - $user->remove_cap( $cap ); - - WP_CLI::success( sprintf( "Removed '%s' cap for %s (%d).", $cap, $user->user_login, $user->ID ) ); + if( $user ) { + $cap = $args[1]; + $user->remove_cap( $cap ); + + WP_CLI::success( sprintf( "Removed '%s' cap for %s (%d).", $cap, $user->user_login, $user->ID ) ); + } } /** @@ -523,16 +525,19 @@ public function remove_cap( $args, $assoc_args ) { */ public function list_caps( $args, $assoc_args ) { $user = self::get_user( $args[0] ); - $user->get_role_caps(); - $user_caps_list = $user->allcaps; - $cap_table_titles = array( 'capability', 'status' ); - - WP_CLI::success( "User caps (role and individual) are: " ); - - foreach( $user_caps_list as $cap => $active ) { - if( $active ) { - \cli\line( $cap ); + if( $user ) { + $user->get_role_caps(); + + $user_caps_list = $user->allcaps; + $cap_table_titles = array( 'capability', 'status' ); + + WP_CLI::success( "User caps (role and individual) are: " ); + + foreach( $user_caps_list as $cap => $active ) { + if( $active ) { + \cli\line( $cap ); + } } } } From c4c0f88d898c4c5fa98482e8c3a186568cacdd62 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Thu, 8 Aug 2013 17:19:45 +0300 Subject: [PATCH 2127/4858] Check for existing file when trying to import CSV --- php/commands/user.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index 269a38dece..d7a8a0c219 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -582,6 +582,10 @@ public function import_csv( $args, $assoc_args ) { $blog_users = get_users(); $filename = $args[0]; + + if (! file_exists( $filename ) ) { + WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); + } foreach ( new \WP_CLI\Iterators\CSV( $filename ) as $i => $new_user ) { $defaults = array( From 778f7ad488b2f6704883b5f2a88b2f4bc5cdfe95 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 8 Aug 2013 18:23:50 +0300 Subject: [PATCH 2128/4858] bump version to 0.12-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 27679afdd3..4baaf4d219 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.11.1' ); +define( 'WP_CLI_VERSION', '0.12-alpha' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From ad3a3ee95e491561fadefb9c20ce894fcfbe2d90 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 8 Aug 2013 18:27:10 +0300 Subject: [PATCH 2129/4858] remove success message from 'wp user list-caps'; fix coding standards; see #637 --- php/commands/user.php | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index d7a8a0c219..521e142f7b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -152,7 +152,7 @@ public function delete( $args, $assoc_args ) { 'reassign' => null ) ); - foreach( $args as $key => $arg ) { + foreach ( $args as $key => $arg ) { $args[$key] = self::get_user( $arg )->ID; } parent::delete( $args, $assoc_args ); @@ -279,7 +279,7 @@ protected function _create( $params ) { */ public function update( $args, $assoc_args ) { - foreach( $args as $key => $arg ) { + foreach ( $args as $key => $arg ) { $args[$key] = self::get_user( $arg )->ID; } parent::update( $args, $assoc_args, 'user' ); @@ -448,7 +448,7 @@ public function remove_role( $args, $assoc_args ) { WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); } } - + /** * Add a capability for a user. * @@ -470,14 +470,14 @@ public function remove_role( $args, $assoc_args ) { */ public function add_cap( $args, $assoc_args ) { $user = self::get_user( $args[0] ); - if( $user ) { - $cap = $args[1]; + if ( $user ) { + $cap = $args[1]; $user->add_cap( $cap ); WP_CLI::success( sprintf( "Added '%s' capability for %s (%d).", $cap, $user->user_login, $user->ID ) ); } } - + /** * Remove a user's capability. * @@ -499,14 +499,14 @@ public function add_cap( $args, $assoc_args ) { */ public function remove_cap( $args, $assoc_args ) { $user = self::get_user( $args[0] ); - if( $user ) { + if ( $user ) { $cap = $args[1]; $user->remove_cap( $cap ); WP_CLI::success( sprintf( "Removed '%s' cap for %s (%d).", $cap, $user->user_login, $user->ID ) ); } } - + /** * List all user's capabilities. * @@ -525,17 +525,15 @@ public function remove_cap( $args, $assoc_args ) { */ public function list_caps( $args, $assoc_args ) { $user = self::get_user( $args[0] ); - - if( $user ) { + + if ( $user ) { $user->get_role_caps(); - + $user_caps_list = $user->allcaps; $cap_table_titles = array( 'capability', 'status' ); - - WP_CLI::success( "User caps (role and individual) are: " ); - - foreach( $user_caps_list as $cap => $active ) { - if( $active ) { + + foreach ( $user_caps_list as $cap => $active ) { + if ( $active ) { \cli\line( $cap ); } } @@ -582,8 +580,8 @@ public function import_csv( $args, $assoc_args ) { $blog_users = get_users(); $filename = $args[0]; - - if (! file_exists( $filename ) ) { + + if ( ! file_exists( $filename ) ) { WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); } @@ -634,7 +632,7 @@ public function import_csv( $args, $assoc_args ) { delete_user_option( $user_id, 'user_level' ); } - if (!empty($existing_user)) { + if ( !empty( $existing_user ) ) { WP_CLI::success( $new_user['user_login'] . " updated" ); } else { WP_CLI::success( $new_user['user_login'] . " created" ); From 38c60f387016a589bd9011128cb177ed3a8017a8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 8 Aug 2013 21:31:15 +0300 Subject: [PATCH 2130/4858] add more info about Behat --- CONTRIBUTING.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3580119b93..b049aafae9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,17 +27,30 @@ All the test dependencies can be installed using [Composer](http://getcomposer.o php composer.phar install --dev -Before running the tests, you'll need a MySQL user called `wp_cli_test` with the +### Unit tests + +To run the unit tests, just execute: + + vendor/bin/phpunit + +### Functional tests + +Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; -Finally, to run the tests: +Then, to run the entire test suite: - vendor/bin/phpunit vendor/bin/behat --expand +Or to test a single feature: + + vendor/bin/behat features/core.feature + +More info can be found from `vendor/bin/behat --help`. + Finally... ---------- From c823207310378a91c84c366f094c65512e0348e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 8 Aug 2013 21:33:50 +0300 Subject: [PATCH 2131/4858] mention where the test files are --- CONTRIBUTING.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b049aafae9..a3d736e4f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,14 +9,12 @@ So you've got an awesome idea to throw into WP-CLI. Great! Here's the process, i It doesn't matter if the code isn't perfect. The idea is to get feedback early and iterate. -If you're adding a new feature, please add one or more functional tests for it in the `features` directory. See below. - -Also, please create or update the appropriate `.txt` file in the `man-src` directory. See below. +If you're adding a new feature, please add one or more functional tests for it in the `features/` directory. See below. Lastly, please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). -Running the tests ------------------ +Running and writing tests +------------------------- There are two types of tests: @@ -33,6 +31,8 @@ To run the unit tests, just execute: vendor/bin/phpunit +The test files are in the `tests/` directory. + ### Functional tests Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the @@ -51,6 +51,8 @@ Or to test a single feature: More info can be found from `vendor/bin/behat --help`. +The feature files are in the `features/` directory. + Finally... ---------- From 309875b01ceaa4c567c1033b43b80c97913c7c65 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 02:24:14 +0300 Subject: [PATCH 2132/4858] Add requests support in composer and for core command --- composer.json | 8 +++++--- php/commands/core.php | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index a617277779..0153f1c6be 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ "php": ">=5.3.2", "wp-cli/php-cli-tools": "0.9.3", "mustache/mustache": "~2.4", - "rhumsaa/array_column": "~1.1" + "rhumsaa/array_column": "~1.1", + "rmccue/requests": ">=1.0" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" @@ -21,6 +22,7 @@ "behat/behat": "~2.4" }, "autoload": { - "psr-0": { "WP_CLI": "php" } - } + "psr-0": { "WP_CLI": "php", "Requests": "library/" } + }, + "minimum-stability": "dev" } diff --git a/php/commands/core.php b/php/commands/core.php index 5d21f820de..999d55be6c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -60,16 +60,40 @@ public function download( $args, $assoc_args ) { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). $temp = tempnam( sys_get_temp_dir(), "wp_" ); - $cmd = "curl -f $silent %s > $temp && tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; - WP_CLI::launch( Utils\esc_cmd( $cmd, $download_url, ABSPATH ) ); + + $headers = array('Accept' => 'application/json'); + $options = array( + 'verify' => false, + 'timeout' => 30, + 'filename' => $temp + ); + + try { + $request = Requests::get( $download_url, $headers, $options ); + } catch( Requests_Exception $ex ) { + WP_CLI::error( $ex->getMessage() ); + } + + $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; + + WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); } private static function _read( $url ) { - exec( 'curl -s ' . escapeshellarg( $url ), $lines, $r ); - if ( $r ) exit( $r ); - return implode( "\n", $lines ); + $headers = array('Accept' => 'application/json'); + $options = array(); + + $r = false; + try { + $request = Requests::get( $url, $headers, $options ); + $r = $request->body; + } catch( Requests_Exception $ex ) { + WP_CLI::error( $ex->getMessage() ); + } + + return $r; } private function get_download_offer( $locale ) { @@ -155,11 +179,11 @@ public function config( $_, $assoc_args ) { } // TODO: adapt more resilient code from wp-admin/setup-config.php + $assoc_args['keys-and-salts'] = self::_read( 'https://api.wordpress.org/secret-key/1.1/salt/' ); $out = Utils\mustache_render( 'wp-config.mustache', $assoc_args ); - file_put_contents( ABSPATH . 'wp-config.php', $out ); WP_CLI::success( 'Generated wp-config.php file.' ); From de42b819c3ebc310aa78084c8ac3d165fd6778d1 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 02:43:19 +0300 Subject: [PATCH 2133/4858] Remove the minimum-stability argument --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0153f1c6be..1926311cfc 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,5 @@ }, "autoload": { "psr-0": { "WP_CLI": "php", "Requests": "library/" } - }, - "minimum-stability": "dev" + } } From e5ba26e5369c2b66448f7e4ccd4f7b017636fdba Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 02:46:58 +0300 Subject: [PATCH 2134/4858] Remove Requests: library/ from composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1926311cfc..57edd006b0 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,6 @@ "behat/behat": "~2.4" }, "autoload": { - "psr-0": { "WP_CLI": "php", "Requests": "library/" } + "psr-0": { "WP_CLI": "php" } } } From 257f4648fbd49e94590ba229dee187a27f5537ef Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 02:53:17 +0300 Subject: [PATCH 2135/4858] Return minimum-stability due to https://github.com/rmccue/Requests/issues/43 --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 57edd006b0..1cf0a55101 100644 --- a/composer.json +++ b/composer.json @@ -23,5 +23,6 @@ }, "autoload": { "psr-0": { "WP_CLI": "php" } - } + }, + "minimum-stability": "dev" } From 17d6323e71b023033d0bb70d2deb5ef0d66fc399 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 03:13:32 +0300 Subject: [PATCH 2136/4858] Add fallback to verify=false argument which works when certificate issues occur --- php/commands/core.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 999d55be6c..88632e4255 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -63,7 +63,6 @@ public function download( $args, $assoc_args ) { $headers = array('Accept' => 'application/json'); $options = array( - 'verify' => false, 'timeout' => 30, 'filename' => $temp ); @@ -71,7 +70,14 @@ public function download( $args, $assoc_args ) { try { $request = Requests::get( $download_url, $headers, $options ); } catch( Requests_Exception $ex ) { - WP_CLI::error( $ex->getMessage() ); + // Handle SSL certificate issues gracefully + $options['verify'] = false; + try { + $request = Requests::get( $download_url, $headers, $options ); + } + catch( Requests_Exception $ex ) { + WP_CLI::error( $ex->getMessage() ); + } } $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; @@ -90,7 +96,14 @@ private static function _read( $url ) { $request = Requests::get( $url, $headers, $options ); $r = $request->body; } catch( Requests_Exception $ex ) { - WP_CLI::error( $ex->getMessage() ); + // Handle SSL certificate issues gracefully + $options['verify'] = false; + try { + $request = Requests::get( $url, $headers, $options ); + $r = $request->body; + } catch( Requests_Exception $ex ) { + WP_CLI::error( $ex->getMessage() ); + } } return $r; From deff1ce419b4ecc18e07aaba7b16dbe9bddc537a Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 03:15:49 +0300 Subject: [PATCH 2137/4858] Add Behat tests for comments (approve/unapprove/exists commands) --- features/comment.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 features/comment.feature diff --git a/features/comment.feature b/features/comment.feature new file mode 100644 index 0000000000..c2ca7bf320 --- /dev/null +++ b/features/comment.feature @@ -0,0 +1,20 @@ +Feature: Manage WordPress comments + + Scenario: Creating/updating/deleting comments + Given a WP install + + When I run `wp comment create --comment_post_ID=1 --comment_content='Hello' --porcelain` + Then STDOUT should match '%d' + And save STDOUT as {COMMENT_ID} + + When I run `wp comment exists {POST_ID}` + Then STDOUT should be: + """ + Success: Comment with ID {POST_ID} exists. + """ + + When I run `wp comment delete {POST_ID}` + Then STDOUT should be: + """ + Success: Deleted comment {POST_ID}. + """ From 1b837585c6a530dc9677d54db9fb82def81acd64 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Thu, 8 Aug 2013 23:13:27 -0400 Subject: [PATCH 2138/4858] Remove 'search=$key' helper text --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index b50803de7b..5626ffe339 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -331,7 +331,7 @@ protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) if ( ! isset( $data ) ) \WP_CLI::error( __( 'API error. Try Again.' ) ); - \WP_CLI::success( 'Showing '. count( $data ) .' of '. $count .' '. $plural .'. \'search=$key\' in place of slug available for '. $data_type .' commands.' ); + \WP_CLI::success( 'Showing '. count( $data ) .' of '. $count .' '. $plural .'.' ); $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; From b1dec554cf73a4a3c667d1921b2d7af6d43d7521 Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Thu, 8 Aug 2013 23:13:56 -0400 Subject: [PATCH 2139/4858] 3rd parameter needs to be $assoc_args --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 8637b6b9fa..9adcce6edd 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -79,7 +79,7 @@ public function search( $args, $assoc_args = array() ) { 'search' => $term, ) ); - parent::_search( $api, $fields, 'theme' ); + parent::_search( $api, $fields, $assoc_args, 'theme' ); } From aa5d71879cf3f2946f02b3bcb63c72f122473a5f Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Thu, 8 Aug 2013 23:14:27 -0400 Subject: [PATCH 2140/4858] Add a plugin/theme search behat test --- features/upgradables.feature | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 7ca5b06ae2..a7fe00a80c 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -93,8 +93,17 @@ Feature: Manage WordPress themes and plugins """ And the <file_to_check> file should not exist + When I run `wp <type> search <item> --per-page=1 --fields=name,slug` + Then STDOUT should contain: + """ + Showing 1 of + """ + And STDOUT should contain: + """ + <item_title> + """ Examples: - | type | type_name | item | version | zip_file | file_to_check | - | theme | Theme | p2 | 1.0.1 | http://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css | - | plugin | Plugin | category-checklist-tree | 1.2 | http://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | + | type | type_name | item | item_title | version | zip_file | file_to_check | + | theme | Theme | p2 | P2 | 1.0.1 | http://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css | + | plugin | Plugin | category-checklist-tree | Category Checklist Tree | 1.2 | http://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | From 8567deff150b25b3094140be07df5fd145b4228c Mon Sep 17 00:00:00 2001 From: jtsternberg <me@jtsternberg.com> Date: Fri, 9 Aug 2013 02:21:51 -0400 Subject: [PATCH 2141/4858] Add a new test, "should end with a table containing rows:" --- features/steps/basic_steps.php | 34 ++++++++++++++++++++++++++++++++++ features/upgradables.feature | 7 +++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 6d84fdc604..74d494b575 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -190,6 +190,40 @@ function ( $world, TableNode $expected ) { } ); +$steps->Then( '/^STDOUT should end with a table containing rows:$/', + function ( $world, TableNode $expected ) { + $output = $world->result->STDOUT; + $outputRows = explode( "\n", rtrim( $output, "\n" ) ); + + $expectedRows = array(); + foreach ( $expected->getRows() as $row ) { + $expectedRows[] = $world->replace_variables( implode( "\t", $row ) ); + } + + $remainingRows = array(); + $start = false; + foreach( $outputRows as $key => $row ) { + + // the first row is the header and must be present + if ( $expectedRows[0] == $row ) + $start = true; + + if ( $start ) + $remainingRows[] = $row; + } + + if ( ! $start ) + throw new \Exception( $output ); + + unset($remainingRows[0]); + unset($expectedRows[0]); + $matches = array_intersect( $expectedRows, $remainingRows ); + + if ( count( $expectedRows ) != count( $matches ) ) + throw new \Exception( $output ); + } +); + $steps->Then( '/^STDOUT should be JSON containing:$/', function ( $world, PyStringNode $expected ) { $output = $world->result->STDOUT; diff --git a/features/upgradables.feature b/features/upgradables.feature index a7fe00a80c..fc9c322766 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -98,10 +98,9 @@ Feature: Manage WordPress themes and plugins """ Showing 1 of """ - And STDOUT should contain: - """ - <item_title> - """ + And STDOUT should end with a table containing rows: + | name | slug | + | <item_title> | <item> | Examples: | type | type_name | item | item_title | version | zip_file | file_to_check | From 1a37ef465df03aac20a14694951264a2ea149bc9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 9 Aug 2013 15:09:09 +0300 Subject: [PATCH 2142/4858] use dev-master for rmccue/requests and remove minimum-stability flag see #655 --- composer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 1cf0a55101..c852f8b04b 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "wp-cli/php-cli-tools": "0.9.3", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", - "rmccue/requests": ">=1.0" + "rmccue/requests": "dev-master" }, "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" @@ -23,6 +23,5 @@ }, "autoload": { "psr-0": { "WP_CLI": "php" } - }, - "minimum-stability": "dev" + } } From 56d597a7890436ae5519e953b1deb8e06b49c0b5 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 16:19:56 +0300 Subject: [PATCH 2143/4858] Comment functions for exists and fetch helper --- php/commands/comment.php | 41 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 179b08a6d6..a5b696ae9a 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -83,9 +83,9 @@ private function call( $args, $status, $success, $failure ) { } private function set_status( $args, $status, $success ) { - list( $comment_id ) = $args; - - $r = wp_set_comment_status( $comment_id, 'approve', true ); + $comment = $this->_fetch_comment( $args ); + + $r = wp_set_comment_status( $comment->comment_ID, 'approve', true ); if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); @@ -296,6 +296,41 @@ function last( $args = array(), $assoc_args = array() ) { WP_CLI::line( str_pad( "$key:", 23 ) . $comment->$key ); } } + + /** + * Verify whether a comment exists. + * + * ## OPTIONS + * + * <ID> + * : The ID of the comment to check from. + * + * ## EXAMPLES + * + * wp comment exists 1337 + * + * @synopsis <id> + */ + public function exists( $args ) { + if ( $this->_fetch_comment( $args ) ) { + WP_CLI::success( "Comment with ID $args[0] exists." ); + } + } + + /** + * A helper function fetching a comment object from comment_id. + * + */ + private function _fetch_comment( $args ) { + $comment_id = (int) $args[0]; + $comment = get_comment( $comment_id ); + + if ( is_null( $comment ) ) { + WP_CLI::error( "Comment with ID $args[0] does not exist." ); + } + + return $comment; + } } WP_CLI::add_command( 'comment', 'Comment_Command' ); From 85f50580065282a6ec6a527a320dcb68186e1b7b Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 16:20:12 +0300 Subject: [PATCH 2144/4858] Role enhancements for exists function --- php/commands/role.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index 3c032e8c16..9259875e43 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -78,8 +78,10 @@ public function exists( $args ) { global $wp_roles; if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { - exit(1); + WP_CLI::error( "Role with ID $args[0] does not exist." ); } + + WP_CLI::success( "Role with ID $args[0] exists." ); } /** From cb91693c60a3d009c493e4575db882b1c1ab3760 Mon Sep 17 00:00:00 2001 From: mpeshev <mario@peshev.net> Date: Fri, 9 Aug 2013 16:40:08 +0300 Subject: [PATCH 2145/4858] Fixed variables in comment feature --- features/comment.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index c2ca7bf320..1641d33a8c 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -7,14 +7,14 @@ Feature: Manage WordPress comments Then STDOUT should match '%d' And save STDOUT as {COMMENT_ID} - When I run `wp comment exists {POST_ID}` + When I run `wp comment exists {COMMENT_ID}` Then STDOUT should be: """ - Success: Comment with ID {POST_ID} exists. + Success: Comment with ID {COMMENT_ID} exists. """ - When I run `wp comment delete {POST_ID}` + When I run `wp comment delete {COMMENT_ID}` Then STDOUT should be: """ - Success: Deleted comment {POST_ID}. + Success: Deleted comment {COMMENT_ID}. """ From 572eaa32f05573da2b0311bceec57b246b375e6f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 9 Aug 2013 21:57:27 +0300 Subject: [PATCH 2146/4858] add Behat tests for `db export` and `db import` --- features/db.feature | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/features/db.feature b/features/db.feature index 6bef95986a..61bd9f52d2 100644 --- a/features/db.feature +++ b/features/db.feature @@ -11,9 +11,6 @@ Feature: Perform database operations When I try the previous command again Then the return code should be 1 - When I run `wp db reset --yes` - Then STDOUT should not be empty - When I run `wp db optimize` Then STDOUT should not be empty @@ -38,3 +35,39 @@ Feature: Perform database operations """ total """ + + Scenario: DB export/import + Given a WP install + + When I run `wp post list --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp db export /tmp/wp-cli-behat.sql` + Then STDOUT should contain: + """ + Success: Exported + """ + + When I run `wp db reset --yes` + Then STDOUT should contain: + """ + Success: Database reset. + """ + + When I try `wp post list --format=count` + Then STDERR should not be empty + + When I run `wp db import /tmp/wp-cli-behat.sql` + Then STDOUT should contain: + """ + Success: Imported + """ + + When I run `wp post list --format=count` + Then STDOUT should contain: + """ + 1 + """ From 83f3321f413f272f54c9e8d0d051f44b9f135147 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 9 Aug 2013 22:07:08 +0300 Subject: [PATCH 2147/4858] whitespace fixes after #653 --- php/commands/core.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 88632e4255..3e9c922b89 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -60,13 +60,13 @@ public function download( $args, $assoc_args ) { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). $temp = tempnam( sys_get_temp_dir(), "wp_" ); - + $headers = array('Accept' => 'application/json'); $options = array( 'timeout' => 30, 'filename' => $temp ); - + try { $request = Requests::get( $download_url, $headers, $options ); } catch( Requests_Exception $ex ) { @@ -79,9 +79,9 @@ public function download( $args, $assoc_args ) { WP_CLI::error( $ex->getMessage() ); } } - + $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; - + WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); @@ -90,7 +90,7 @@ public function download( $args, $assoc_args ) { private static function _read( $url ) { $headers = array('Accept' => 'application/json'); $options = array(); - + $r = false; try { $request = Requests::get( $url, $headers, $options ); @@ -101,11 +101,11 @@ private static function _read( $url ) { try { $request = Requests::get( $url, $headers, $options ); $r = $request->body; - } catch( Requests_Exception $ex ) { + } catch( Requests_Exception $ex ) { WP_CLI::error( $ex->getMessage() ); - } + } } - + return $r; } From 485c4b44c9394e1ee3e1cc898c34a0e6bd678096 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 9 Aug 2013 22:10:47 +0300 Subject: [PATCH 2148/4858] core version: load only wp-includes/version.php fixes #659 --- features/core.feature | 3 +++ php/commands/core.php | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 27818a62aa..856ddb2f1d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -25,6 +25,9 @@ Feature: Manage WordPress installation Then the return code should be 1 And STDERR should not be empty + When I run `wp core version` + Then STDOUT should not be empty + When I try `wp core install` Then the return code should be 1 And STDERR should be: diff --git a/php/commands/core.php b/php/commands/core.php index 3e9c922b89..8803f8d183 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -525,10 +525,19 @@ private static function get_clean_basedomain() { * --extra * : Show extended version information. * + * @when before_wp_load * @synopsis [--extra] */ public function version( $args = array(), $assoc_args = array() ) { - global $wp_version, $wp_db_version, $tinymce_version; + $versions_path = ABSPATH . 'wp-includes/version.php'; + + if ( !is_readable( $versions_path ) ) { + WP_CLI::error( + "This does not seem to be a WordPress install.\n" . + "Pass --path=`path/to/wordpress` or run `wp core download`." ); + } + + include $versions_path; if ( isset( $assoc_args['extra'] ) ) { preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); From 736cdf7d46589e60f2f560d29b941e4851b1918f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 9 Aug 2013 23:09:11 +0300 Subject: [PATCH 2149/4858] media regenerate: remove erroneus timer and decrease verbosity fixes #660 --- php/commands/media.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 3c3bbafcf6..aaa7c08fe2 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -204,30 +204,30 @@ private function _process_regeneration( $id ) { $fullsizepath = get_attached_file( $image->ID ); + $att_desc = sprintf( '"%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ); + if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - WP_CLI::warning( "{$image->post_title} - Can't find {$fullsizepath}." ); + WP_CLI::warning( "Can't find $att_desc" ); return; } - WP_CLI::log( sprintf( 'Start processing of "%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ) ); - $this->remove_old_images( $image->ID ); $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); - if ( is_wp_error( $metadata ) ) { WP_CLI::warning( $metadata->get_error_message() ); return; } if ( empty( $metadata ) ) { - WP_CLI::warning( "Couldn't regenerate image." ); + WP_CLI::warning( "Couldn't regenerate thumbnails for $att_desc." ); return; } wp_update_attachment_metadata( $image->ID, $metadata ); - WP_CLI::success( "All thumbnails were successfully regenerated in " . timer_stop() . " seconds." ); + WP_CLI::log( "Regenerated thumbnails for $att_desc" ); + } private function remove_old_images( $att_id ) { @@ -244,10 +244,7 @@ private function remove_old_images( $att_id ) { if ( $intermediate_path == $original_path ) continue; - if ( unlink( $intermediate_path ) ) { - WP_CLI::log( sprintf( "Thumbnail %s x %s was deleted.", - $size_info['width'], $size_info['height'] ) ); - } + unlink( $intermediate_path ); } } From ad22bf204ad92cf09e11b9b4ca4b6d6e9302e5ef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Aug 2013 04:39:02 +0300 Subject: [PATCH 2150/4858] first pass at 'wp site list' command --- php/commands/site.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index 1fd1ffa4b0..c87fc63a7c 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -318,6 +318,38 @@ public function create( $_, $assoc_args ) { else WP_CLI::success( "Site $id created: $url" ); } + + /** + * List all sites in a multisite install. + * + * ## OPTIONS + * + * --fields=<fields> + * : Comma-separated list of fields to show. + * + * --format=<format> + * : Output list as table, CSV, JSON. Defaults to table. + * + * ## EXAMPLES + * + * wp site list --fields=domain,path --format=csv + * + * @subcommand list + * @synopsis [--format=<format>] [--fields=<fields>] + */ + function _list( $_, $assoc_args ) { + global $wpdb; + + $defaults = array( + 'format' => 'table', + 'fields' => array( 'blog_id', 'domain', 'path' ) + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $it = new \WP_CLI\Iterators\Table( array( 'table' => $wpdb->blogs ) ); + + WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + } } WP_CLI::add_command( 'site', 'Site_Command' ); From 5a014bb721665c77f2bf7ca15460354ebfc26319 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Aug 2013 16:55:22 +0300 Subject: [PATCH 2151/4858] site list: check for multisite before doing anything --- php/commands/site.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index c87fc63a7c..4f38778093 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -338,6 +338,10 @@ public function create( $_, $assoc_args ) { * @synopsis [--format=<format>] [--fields=<fields>] */ function _list( $_, $assoc_args ) { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + global $wpdb; $defaults = array( From 0ea15f3e548008a6d13c70110e831f7de065cfe9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Aug 2013 16:55:43 +0300 Subject: [PATCH 2152/4858] site list: incorporate into site.feature tests --- features/site.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/site.feature b/features/site.feature index 80a6c94ff7..6cdf914265 100644 --- a/features/site.feature +++ b/features/site.feature @@ -7,6 +7,12 @@ Feature: Manage sites in a multisite installation Then STDOUT should match '%d' And save STDOUT as {SITE_ID} + When I run `wp site list` + Then STDOUT should be a table containing rows: + | blog_id | domain | path | + | 1 | example.com | / | + | 2 | example.com | /first/ | + When I run `wp site delete {SITE_ID} --yes` Then STDOUT should not be empty From 053bc90829a93580e076b8f56a5b332bc270b43c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 10 Aug 2013 22:52:50 +0300 Subject: [PATCH 2153/4858] site list: add --network parameter --- php/commands/site.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 4f38778093..51dc3b4d13 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -324,6 +324,9 @@ public function create( $_, $assoc_args ) { * * ## OPTIONS * + * --network=<id> + * : The network to which the sites belong. + * * --fields=<fields> * : Comma-separated list of fields to show. * @@ -335,7 +338,7 @@ public function create( $_, $assoc_args ) { * wp site list --fields=domain,path --format=csv * * @subcommand list - * @synopsis [--format=<format>] [--fields=<fields>] + * @synopsis [--network=<id>] [--format=<format>] [--fields=<fields>] */ function _list( $_, $assoc_args ) { if ( !is_multisite() ) { @@ -346,11 +349,20 @@ function _list( $_, $assoc_args ) { $defaults = array( 'format' => 'table', - 'fields' => array( 'blog_id', 'domain', 'path' ) + 'fields' => array( 'blog_id', 'domain', 'path' ), ); $assoc_args = array_merge( $defaults, $assoc_args ); - $it = new \WP_CLI\Iterators\Table( array( 'table' => $wpdb->blogs ) ); + $where = array(); + if ( isset( $assoc_args['network'] ) ) { + $where['site_id'] = $assoc_args['network']; + } + + $iterator_args = array( + 'table' => $wpdb->blogs, + 'where' => $where, + ); + $it = new \WP_CLI\Iterators\Table( $iterator_args ); WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); } From eb57761f738445b2404d82336a4e1324b23797ca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 11 Aug 2013 13:45:56 -0700 Subject: [PATCH 2154/4858] Update tests --- features/scaffold.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 5e26019647..d5efe98491 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -48,7 +48,11 @@ Feature: Wordpress code scaffolding When I run `wp scaffold taxonomy zombie-speed --label="Speed"` Then STDOUT should contain: """ - __( 'Speed' + __( 'Speeds' + """ + And STDOUT should contain: + """ + _x( 'Speed', 'taxonomy general name', """ # Test for all flags but --label, --theme, --plugin and --raw From ef5b47b8ae57e7949b513078b2cc2f1f89791158 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 11 Aug 2013 13:53:08 -0700 Subject: [PATCH 2155/4858] Make `--admin_name` required, to discourage use of 'admin' as the default user --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8803f8d183..1e05121396 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -241,7 +241,7 @@ public function is_installed() { * --admin_email=<email> * : The email address for the admin user. * - * @synopsis --url=<url> --title=<site-title> [--admin_name=<username>] --admin_email=<email> --admin_password=<password> + * @synopsis --url=<url> --title=<site-title> --admin_name=<username> --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -312,7 +312,7 @@ public function multisite_convert( $args, $assoc_args ) { * : The email address for the admin user. * * @subcommand multisite-install - * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] [--admin_name=<username>] --admin_email=<email> --admin_password=<password> + * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] --admin_name=<username> --admin_email=<email> --admin_password=<password> */ public function multisite_install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { From bfc56731eee840b0393068c0033b6d6db0565546 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 11 Aug 2013 14:16:39 -0700 Subject: [PATCH 2156/4858] Convert `--admin_name` to `--admin_user`, which is more semantic. --- php/WP_CLI/Runner.php | 6 ++++++ php/commands/core.php | 14 +++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 1502ac7b30..8e5931645f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -262,6 +262,12 @@ private static function back_compat_conversions( $args, $assoc_args ) { } } + // core (multsite-)install --admin_name= -> --admin_user= + if ( count( $args ) > 0 && 'core' == $args[0] && isset( $assoc_args['admin_name'] ) ) { + $assoc_args['admin_user'] = $assoc_args['admin_name']; + unset( $assoc_args['admin_name'] ); + } + // site --site_id= -> site --network_id= if ( count( $args ) > 0 && 'site' == $args[0] && isset( $assoc_args['site_id'] ) ) { $assoc_args['network_id'] = $assoc_args['site_id']; diff --git a/php/commands/core.php b/php/commands/core.php index 1e05121396..1189f9dadc 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -232,8 +232,8 @@ public function is_installed() { * --title=<site-title> * : The title of the new site. * - * --admin_name=<username> - * : The name of the admin user. Default: 'admin' + * --admin_user=<username> + * : The name of the admin user. * * --admin_password=<password> * : The password for the admin user. @@ -241,7 +241,7 @@ public function is_installed() { * --admin_email=<email> * : The email address for the admin user. * - * @synopsis --url=<url> --title=<site-title> --admin_name=<username> --admin_email=<email> --admin_password=<password> + * @synopsis --url=<url> --title=<site-title> --admin_user=<username> --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -302,7 +302,7 @@ public function multisite_convert( $args, $assoc_args ) { * --title=<site-title> * : The title of the new site. * - * --admin_name=<username> + * --admin_user=<username> * : The name of the admin user. Default: 'admin' * * --admin_password=<password> @@ -312,7 +312,7 @@ public function multisite_convert( $args, $assoc_args ) { * : The email address for the admin user. * * @subcommand multisite-install - * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] --admin_name=<username> --admin_email=<email> --admin_password=<password> + * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] --admin_user=<username> --admin_email=<email> --admin_password=<password> */ public function multisite_install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -381,14 +381,14 @@ private function _install( $assoc_args ) { extract( wp_parse_args( $assoc_args, array( 'title' => '', - 'admin_name' => 'admin', + 'admin_user' => '', 'admin_email' => '', 'admin_password' => '' ) ), EXTR_SKIP ); $public = true; - $result = wp_install( $title, $admin_name, $admin_email, $public, '', $admin_password ); + $result = wp_install( $title, $admin_user, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::error_to_string($result) . ').' ); From 421495471748712d648ff7a574444cffe5a36539 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 11 Aug 2013 14:18:27 -0700 Subject: [PATCH 2157/4858] Update tests --- features/bootstrap/FeatureContext.php | 1 + features/core.feature | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index b60c007b1a..76afc463dd 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -179,6 +179,7 @@ public function install_wp( $subdir = '' ) { $install_args = array( 'url' => 'http://example.com', 'title' => 'WP CLI Site', + 'admin_user' => 'wpcli', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' ); diff --git a/features/core.feature b/features/core.feature index 856ddb2f1d..7f7363f78b 100644 --- a/features/core.feature +++ b/features/core.feature @@ -80,7 +80,7 @@ Feature: Manage WordPress installation Run `wp core install`. """ - When I run `wp core install --url='localhost:8001' --title='Test' --admin_email=admin@example.com --admin_password=1` + When I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty When I run `wp eval 'echo home_url();'` @@ -108,7 +108,7 @@ Feature: Manage WordPress installation """ # Can complain that it's already installed, but don't exit with an error code - When I try `wp core install --url='localhost:8001' --title='Test' --admin_email=admin@example.com --admin_password=1` + When I try `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then the return code should be 0 Scenario: Convert install to multisite @@ -138,7 +138,7 @@ Feature: Manage WordPress installation And wp-config.php And a database - When I run `wp core multisite-install --url=foobar.org --title=Test --admin_email=admin@example.com --admin_password=1` + When I run `wp core multisite-install --url=foobar.org --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty When I run `wp eval 'echo $GLOBALS["current_site"]->domain;'` @@ -148,14 +148,14 @@ Feature: Manage WordPress installation """ # Can complain that it's already installed, but don't exit with an error code - When I try `wp core multisite-install --url=foobar.org --title=Test --admin_email=admin@example.com --admin_password=1` + When I try `wp core multisite-install --url=foobar.org --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then the return code should be 0 Scenario: Install multisite from scratch, with MULTISITE already set in wp-config.php Given a WP multisite install And I run `wp db reset --yes` - When I run `wp core multisite-install --title=Test --admin_email=admin@example.com --admin_password=1` + When I run `wp core multisite-install --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty When I run `wp eval 'echo $GLOBALS["current_site"]->domain;'` From c1fa867669d2226004da260af1c86cf04ec87f2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 11 Aug 2013 14:32:14 -0700 Subject: [PATCH 2158/4858] Cleverness kills tests --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 76afc463dd..0207b0c103 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -179,7 +179,7 @@ public function install_wp( $subdir = '' ) { $install_args = array( 'url' => 'http://example.com', 'title' => 'WP CLI Site', - 'admin_user' => 'wpcli', + 'admin_user' => 'admin', 'admin_email' => 'admin@example.com', 'admin_password' => 'password1' ); From a76d8ca666c5bd2bb8f86037a3770d4b3b22e3f6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 12:40:17 +0300 Subject: [PATCH 2159/4858] tests: first pass at using global PHPUnit and Behat --- CONTRIBUTING.md | 22 ++++++++++++++++------ bin/ci/install_dependencies.sh | 6 +++++- bin/ci/run_build.sh | 4 ++-- composer.json | 4 ---- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3d736e4f9..07a7bcfc27 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,20 +21,30 @@ There are two types of tests: * unit tests, implemented using [PHPUnit](http://phpunit.de/) * functional tests, implemented using [Behat](http://behat.org) -All the test dependencies can be installed using [Composer](http://getcomposer.org/): +### Unit tests - php composer.phar install --dev +Assuming you have `~/.wp-cli/bin/` in your PATH, you can do: -### Unit tests +```bash +# Install PHPUnit +curl http://pear.phpunit.de/get/phpunit.phar > ~/.wp-cli/bin/phpunit +chmod +x ~/.wp-cli/bin/phpunit To run the unit tests, just execute: - vendor/bin/phpunit + phpunit The test files are in the `tests/` directory. ### Functional tests +Assuming you have `~/.wp-cli/bin/` in your PATH, to install Behat, you can do: + +```bash +curl http://behat.org/downloads/behat.phar > ~/.wp-cli/bin/behat +chmod +x ~/.wp-cli/bin/behat +``` + Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: @@ -43,11 +53,11 @@ Running the following as root in MySQL should do the trick: Then, to run the entire test suite: - vendor/bin/behat --expand + behat --expand Or to test a single feature: - vendor/bin/behat features/core.feature + behat features/core.feature More info can be found from `vendor/bin/behat --help`. diff --git a/bin/ci/install_dependencies.sh b/bin/ci/install_dependencies.sh index c756510987..7e83e2d251 100755 --- a/bin/ci/install_dependencies.sh +++ b/bin/ci/install_dependencies.sh @@ -4,8 +4,12 @@ set -ex +# install Behat +sudo curl http://behat.org/downloads/behat.phar > /usr/bin/behat +chmod +x /usr/bin/behat + # install dependencies -composer install --dev --no-interaction --prefer-source +composer install --no-interaction --prefer-source composer require d11wtq/boris=dev-master --no-interaction --prefer-source # set up WP install diff --git a/bin/ci/run_build.sh b/bin/ci/run_build.sh index 3ed2e35cdb..2711478a58 100755 --- a/bin/ci/run_build.sh +++ b/bin/ci/run_build.sh @@ -2,6 +2,6 @@ set -ex -vendor/bin/phpunit +phpunit -vendor/bin/behat --format progress +behat --format progress diff --git a/composer.json b/composer.json index c852f8b04b..75262e7714 100644 --- a/composer.json +++ b/composer.json @@ -17,10 +17,6 @@ "suggest": { "d11wtq/boris": "Enhanced `wp shell` functionality" }, - "require-dev": { - "phpunit/phpunit": "~3.7", - "behat/behat": "~2.4" - }, "autoload": { "psr-0": { "WP_CLI": "php" } } From f72c44ff8fe022960b9713647c8295b48c51c186 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 12:44:49 +0300 Subject: [PATCH 2160/4858] travis: install Behat in the local build dir --- bin/ci/install_dependencies.sh | 3 +-- bin/ci/run_build.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bin/ci/install_dependencies.sh b/bin/ci/install_dependencies.sh index 7e83e2d251..6fbef59572 100755 --- a/bin/ci/install_dependencies.sh +++ b/bin/ci/install_dependencies.sh @@ -5,8 +5,7 @@ set -ex # install Behat -sudo curl http://behat.org/downloads/behat.phar > /usr/bin/behat -chmod +x /usr/bin/behat +curl http://behat.org/downloads/behat.phar > behat.phar # install dependencies composer install --no-interaction --prefer-source diff --git a/bin/ci/run_build.sh b/bin/ci/run_build.sh index 2711478a58..2fb25dfead 100755 --- a/bin/ci/run_build.sh +++ b/bin/ci/run_build.sh @@ -4,4 +4,4 @@ set -ex phpunit -behat --format progress +php behat.phar --format progress From 63c6419c01f7ae8d366c32e09eaa5192b340a5f1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 14:14:00 +0300 Subject: [PATCH 2161/4858] site list: add a more useful example see #661 --- php/commands/site.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index 51dc3b4d13..e34fce87ee 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -335,7 +335,8 @@ public function create( $_, $assoc_args ) { * * ## EXAMPLES * - * wp site list --fields=domain,path --format=csv + * # Output the list of site URLs + * wp site list --fields=domain,path --format=csv | tail -n +2 | sed 's/,//' * * @subcommand list * @synopsis [--network=<id>] [--format=<format>] [--fields=<fields>] From 2c249ea2d377068d63386a43049d534b0d97346f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 14:45:44 +0300 Subject: [PATCH 2162/4858] replace PHPUnit assertEquals() with homegrown variant --- features/bootstrap/FeatureContext.php | 2 -- features/bootstrap/support.php | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index b60c007b1a..f2e6855fac 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -7,8 +7,6 @@ use \WP_CLI\Utils; -require_once 'PHPUnit/Framework/Assert/Functions.php'; - require_once __DIR__ . '/../../php/utils.php'; /** diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index d213ea3def..b448519b87 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -2,6 +2,12 @@ // Utility functions used by Behat steps +function assertEquals( $expected, $actual ) { + if ( $expected != $actual ) { + throw new Exception( "Actual value: " . var_export( $actual ) ); + } +} + function checkString( $output, $expected, $action ) { switch ( $action ) { From bcbae42ce51a42d6d8ced2003a48f7dc07c0c91c Mon Sep 17 00:00:00 2001 From: MattiaG <bots@mattiaghedin.it> Date: Mon, 12 Aug 2013 19:28:21 +0200 Subject: [PATCH 2163/4858] allow to use both --locale and --version params for 'wp core download' Ugly coded, but not so different from source. If the requested combination of locale+version is not available, the script fails like with wrong version parameter. Tested setting it_IT and de_DE parameters and various versions. --- php/commands/core.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 1189f9dadc..b49774ca73 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -15,8 +15,7 @@ class Core_Command extends WP_CLI_Command { * ## OPTIONS * * --locale=<locale> - * : Select which language you want to download. The --version parameter is - * ignored in this case. + * : Select which language you want to download. * * --version=<version> * : Select which version you want to download. @@ -41,7 +40,10 @@ public function download( $args, $assoc_args ) { WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); } - if ( isset( $assoc_args['locale'] ) ) { + if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version']) ) { + $download_url = 'https://'. substr($assoc_args['locale'],0,2) .'.wordpress.org/wordpress-' . $assoc_args['version'] . '-' .$assoc_args['locale']. '.tar.gz'; + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $assoc_args['locale'] ) ); + } else if ( isset( $assoc_args['locale'] ) ) { $offer = $this->get_download_offer( $assoc_args['locale'] ); $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', From 0638c636b3bb4993ba455c1f53dda15f1d12f2ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 21:36:13 +0300 Subject: [PATCH 2164/4858] fix coding standards; see #666 --- php/commands/core.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index b49774ca73..3cac1d1115 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -40,13 +40,13 @@ public function download( $args, $assoc_args ) { WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); } - if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version']) ) { - $download_url = 'https://'. substr($assoc_args['locale'],0,2) .'.wordpress.org/wordpress-' . $assoc_args['version'] . '-' .$assoc_args['locale']. '.tar.gz'; - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $assoc_args['locale'] ) ); - } else if ( isset( $assoc_args['locale'] ) ) { + if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version'] ) ) { + $download_url = 'https://'. substr( $assoc_args['locale'],0,2 ) .'.wordpress.org/wordpress-' . $assoc_args['version'] . '-' .$assoc_args['locale']. '.tar.gz'; + WP_CLI::log( sprintf( 'Downloading WordPress %s ( %s )...', $assoc_args['version'], $assoc_args['locale'] ) ); + } else if ( isset( $assoc_args['locale'] ) ) { $offer = $this->get_download_offer( $assoc_args['locale'] ); $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', + WP_CLI::log( sprintf( 'Downloading WordPress %s ( %s )...', $offer['current'], $offer['locale'] ) ); } elseif ( isset( $assoc_args['version'] ) ) { $download_url = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; From a147ee9d03209e8b393f2a5197e754483b16b9a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 21:37:20 +0300 Subject: [PATCH 2165/4858] whitespace is nice, but let's not get ridiculous --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 3cac1d1115..dcb5b957fe 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -42,11 +42,11 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version'] ) ) { $download_url = 'https://'. substr( $assoc_args['locale'],0,2 ) .'.wordpress.org/wordpress-' . $assoc_args['version'] . '-' .$assoc_args['locale']. '.tar.gz'; - WP_CLI::log( sprintf( 'Downloading WordPress %s ( %s )...', $assoc_args['version'], $assoc_args['locale'] ) ); + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $assoc_args['locale'] ) ); } else if ( isset( $assoc_args['locale'] ) ) { $offer = $this->get_download_offer( $assoc_args['locale'] ); $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); - WP_CLI::log( sprintf( 'Downloading WordPress %s ( %s )...', + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $offer['current'], $offer['locale'] ) ); } elseif ( isset( $assoc_args['version'] ) ) { $download_url = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; From be4a66f3e7fef53feeb2cdb46ef332368806c8bf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 21:42:44 +0300 Subject: [PATCH 2166/4858] use sprintf() instead of concatenation; see #666 --- php/commands/core.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index dcb5b957fe..81762a63e3 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -41,7 +41,8 @@ public function download( $args, $assoc_args ) { } if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version'] ) ) { - $download_url = 'https://'. substr( $assoc_args['locale'],0,2 ) .'.wordpress.org/wordpress-' . $assoc_args['version'] . '-' .$assoc_args['locale']. '.tar.gz'; + $download_url = sprintf( 'https://%s.wordpress.org/wordpress-%s-%s.tar.gz', + substr( $assoc_args['locale'], 0, 2 ), $assoc_args['version'], $assoc_args['locale'] ); WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $assoc_args['locale'] ) ); } else if ( isset( $assoc_args['locale'] ) ) { $offer = $this->get_download_offer( $assoc_args['locale'] ); @@ -65,9 +66,9 @@ public function download( $args, $assoc_args ) { $headers = array('Accept' => 'application/json'); $options = array( - 'timeout' => 30, - 'filename' => $temp - ); + 'timeout' => 30, + 'filename' => $temp + ); try { $request = Requests::get( $download_url, $headers, $options ); From 9cde1938c57699c2d0c61ad5b4284e69296c31d5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 22:48:58 +0300 Subject: [PATCH 2167/4858] replace assertStringMatchesFormat() with assertNumeric() --- features/bootstrap/support.php | 6 ++++++ features/comment.feature | 2 +- features/post.feature | 8 ++++---- features/site.feature | 2 +- features/steps/basic_steps.php | 6 +++--- features/term.feature | 4 ++-- features/user.feature | 2 +- 7 files changed, 18 insertions(+), 12 deletions(-) diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index b448519b87..b6245af2c4 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -8,6 +8,12 @@ function assertEquals( $expected, $actual ) { } } +function assertNumeric( $actual ) { + if ( !is_numeric( $actual ) ) { + throw new Exception( "Actual value: " . var_export( $actual ) ); + } +} + function checkString( $output, $expected, $action ) { switch ( $action ) { diff --git a/features/comment.feature b/features/comment.feature index 1641d33a8c..8a9d2502d8 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress comments Given a WP install When I run `wp comment create --comment_post_ID=1 --comment_content='Hello' --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number And save STDOUT as {COMMENT_ID} When I run `wp comment exists {COMMENT_ID}` diff --git a/features/post.feature b/features/post.feature index 38dfb3a935..16c88c6dfe 100644 --- a/features/post.feature +++ b/features/post.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress posts Given a WP install When I run `wp post create --post_title='Test post' --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number And save STDOUT as {POST_ID} When I run `wp post update {POST_ID} --post_title='Updated post'` @@ -40,7 +40,7 @@ Feature: Manage WordPress posts """ When I run `bash command.sh` - Then STDOUT should match '%d' + Then STDOUT should be a number And save STDOUT as {POST_ID} When I run `wp eval '$post_id = {POST_ID}; echo get_post( $post_id )->post_excerpt;'` @@ -74,10 +74,10 @@ Feature: Manage WordPress posts Given a WP install When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number When I run `wp post create --post_title='Draft post' --post_content='Draft post content' --post_status='draft' --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number When I run `wp post list --post_type='post' --fields=post_title,post_name,post_status --format=csv` Then STDOUT should be CSV containing: diff --git a/features/site.feature b/features/site.feature index 6cdf914265..aa53f8c369 100644 --- a/features/site.feature +++ b/features/site.feature @@ -4,7 +4,7 @@ Feature: Manage sites in a multisite installation Given a WP multisite install When I run `wp site create --slug=first --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number And save STDOUT as {SITE_ID} When I run `wp site list` diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 74d494b575..778cb63177 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -160,9 +160,9 @@ function ( $world, $stream, $action, PyStringNode $expected ) { } ); -$steps->Then( '/^(STDOUT|STDERR) should match \'([^\']+)\'$/', - function ( $world, $stream, $format ) { - assertStringMatchesFormat( $format, $world->result->$stream ); +$steps->Then( '/^(STDOUT|STDERR) should be a number$/', + function ( $world, $stream ) { + assertNumeric( $world->result->$stream ); } ); diff --git a/features/term.feature b/features/term.feature index df7dea76c9..97b5ad580e 100644 --- a/features/term.feature +++ b/features/term.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress terms Given a WP install When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term' --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number When I try the previous command again Then STDERR should not be empty @@ -24,7 +24,7 @@ Feature: Manage WordPress terms Given a WP install When I run `wp term create 'Test delete term' post_tag --slug=test-delete --description='This is a test term to be deleted' --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number And save STDOUT as {TERM_ID} When I run `wp term delete {TERM_ID} post_tag` diff --git a/features/user.feature b/features/user.feature index 43bfe2ae47..83f3f90008 100644 --- a/features/user.feature +++ b/features/user.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress users Given a WP install When I run `wp user create testuser testuser@example.com --porcelain` - Then STDOUT should match '%d' + Then STDOUT should be a number And save STDOUT as {USER_ID} When I try the previous command again From 69ea5e58209254d08cdc70cf6c18ccd620cfa448 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 22:56:15 +0300 Subject: [PATCH 2168/4858] replace remaining assertion calls with direct exceptions --- features/steps/basic_steps.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 778cb63177..8b7b337083 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -260,7 +260,9 @@ function ( $world, $stream ) { $steps->Then( '/^(STDOUT|STDERR) should not be empty$/', function ( $world, $stream ) { - assertNotEmpty( rtrim( $world->result->$stream, "\n" ) ); + if ( '' === rtrim( $world->result->$stream, "\n" ) ) { + throw new Exception( "$stream is empty." ); + } } ); @@ -274,13 +276,19 @@ function ( $world, $path, $action, $expected = null ) { switch ( $action ) { case 'exist': - assertFileExists( $path ); + if ( !file_exists( $path ) ) { + throw new Exception( "$path doesn't exist." ); + } break; case 'not exist': - assertFileNotExists( $path ); + if ( file_exists( $path ) ) { + throw new Exception( "$path exists." ); + } break; default: - assertFileExists( $path ); + if ( !file_exists( $path ) ) { + throw new Exception( "$path doesn't exist." ); + } $action = substr( $action, 0, -1 ); $expected = $world->replace_variables( (string) $expected ); checkString( file_get_contents( $path ), $expected, $action ); From f212f4d261bdd84d35caab228b078f8373be7490 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 23:05:39 +0300 Subject: [PATCH 2169/4858] fix assertNumeric() usage --- features/bootstrap/support.php | 4 ++-- features/steps/basic_steps.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index b6245af2c4..1e9809ddf5 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -4,13 +4,13 @@ function assertEquals( $expected, $actual ) { if ( $expected != $actual ) { - throw new Exception( "Actual value: " . var_export( $actual ) ); + throw new Exception( "Actual value: " . var_export( $actual, true ) ); } } function assertNumeric( $actual ) { if ( !is_numeric( $actual ) ) { - throw new Exception( "Actual value: " . var_export( $actual ) ); + throw new Exception( "Actual value: " . var_export( $actual, true ) ); } } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 8b7b337083..d3b267ee6d 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -162,7 +162,7 @@ function ( $world, $stream, $action, PyStringNode $expected ) { $steps->Then( '/^(STDOUT|STDERR) should be a number$/', function ( $world, $stream ) { - assertNumeric( $world->result->$stream ); + assertNumeric( trim( $world->result->$stream, "\n" ) ); } ); From 46fb8dad853d48b28aea5ce64a252d32cc0c27e0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 12 Aug 2013 23:41:16 +0300 Subject: [PATCH 2170/4858] update utils/dev-build --- .gitignore | 2 +- CONTRIBUTING.md | 34 +++++++++++++--------------------- utils/dev-build | 22 ++++++++++++---------- 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 03f9ead5d6..8c20e7a9ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ composer.lock -composer.phar /vendor +/*.phar /phpunit.xml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07a7bcfc27..701e56b21c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,34 +16,28 @@ Lastly, please follow the [WordPress Coding Standards](http://make.wordpress.org Running and writing tests ------------------------- -There are two types of tests: +There are two types of automated tests: * unit tests, implemented using [PHPUnit](http://phpunit.de/) * functional tests, implemented using [Behat](http://behat.org) -### Unit tests - -Assuming you have `~/.wp-cli/bin/` in your PATH, you can do: +To set everything up, just run: ```bash -# Install PHPUnit -curl http://pear.phpunit.de/get/phpunit.phar > ~/.wp-cli/bin/phpunit -chmod +x ~/.wp-cli/bin/phpunit +./utils/dev-build +``` -To run the unit tests, just execute: +### Unit tests - phpunit +The unit test files are in the `tests/` directory. -The test files are in the `tests/` directory. +To run the unit tests, just execute: + + php phpunit.phar ### Functional tests -Assuming you have `~/.wp-cli/bin/` in your PATH, to install Behat, you can do: - -```bash -curl http://behat.org/downloads/behat.phar > ~/.wp-cli/bin/behat -chmod +x ~/.wp-cli/bin/behat -``` +The functional test files are in the `features/` directory. Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. @@ -53,15 +47,13 @@ Running the following as root in MySQL should do the trick: Then, to run the entire test suite: - behat --expand + php behat.phar --expand Or to test a single feature: - behat features/core.feature - -More info can be found from `vendor/bin/behat --help`. + php behat.phar features/core.feature -The feature files are in the `features/` directory. +More info can be found from `php behat.phar --help`. Finally... ---------- diff --git a/utils/dev-build b/utils/dev-build index 2994603608..d4f3f09e4f 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -1,21 +1,23 @@ #!/usr/bin/env bash -# check that PHP is available command -v php > /dev/null || { echo "can't find PHP binary" >&2 exit 1 } -# install Composer -command -v composer > /dev/null || { - curl -sS https://getcomposer.org/installer | php - sudo mv composer.phar /usr/local/bin/composer -} +echo "Downloading Composer..." +curl -sS https://getcomposer.org/installer | php + +echo "Installing dependencies using Composer..." +php composer.phar install + +echo "Downloading PHPUnit..." +curl -sS http://pear.phpunit.de/get/phpunit.phar > phpunit.phar -# install dependencies -composer install --dev +echo "Downloading Behat..." +curl -sS http://behat.org/downloads/behat.phar > behat.phar -# add symlink to wp binary +echo "Creating symlink for the wp command..." for dir in /usr/bin /usr/local/bin; do if [ -d $dir ]; then sudo ln -sf $(pwd)/bin/wp $dir/wp @@ -23,7 +25,7 @@ for dir in /usr/bin /usr/local/bin; do fi done -# install bash completion file +echo "Installing bash completion file..." for dir in /etc/bash_completion.d /usr/local/etc/bash_completion.d; do if [ -d $dir ]; then sudo ln -sf $(pwd)/utils/wp-completion.bash $dir/wp From 94f5fe84823fc32f8d5c56abddbad3149f6e7035 Mon Sep 17 00:00:00 2001 From: Josh Betz <j@joshbetz.com> Date: Mon, 12 Aug 2013 17:37:07 -0500 Subject: [PATCH 2171/4858] First pass at Behat test for `wp plugin is-installed <plugin>` --- features/plugin.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index f48979760a..5616bd6399 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -29,6 +29,12 @@ Feature: Manage WordPress plugins Status: Active """ + When I run `wp plugin is-installed zombieland && echo "Zombieland"` + Then STDOUT should contain: + """ + Zombieland + """ + When I run `wp plugin status` Then STDOUT should not be empty From 09654d1f9e02cb1d515f68938ee9850b4019bd91 Mon Sep 17 00:00:00 2001 From: Josh Betz <j@joshbetz.com> Date: Mon, 12 Aug 2013 17:55:55 -0500 Subject: [PATCH 2172/4858] Fixed test for `wp plugin is-installed <plugin>` There was extra white space in the expected output --- features/plugin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 5616bd6399..299a116d45 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -32,7 +32,7 @@ Feature: Manage WordPress plugins When I run `wp plugin is-installed zombieland && echo "Zombieland"` Then STDOUT should contain: """ - Zombieland + Zombieland """ When I run `wp plugin status` From 3e5d8c8a470e65081479b7785edbe5c938d75951 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Aug 2013 03:13:16 +0300 Subject: [PATCH 2173/4858] site list: add --format=url; see #661 --- php/commands/site.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index e34fce87ee..285c37c394 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -331,12 +331,12 @@ public function create( $_, $assoc_args ) { * : Comma-separated list of fields to show. * * --format=<format> - * : Output list as table, CSV, JSON. Defaults to table. + * : Output list as table, csv, json or url. Defaults to table. * * ## EXAMPLES * * # Output the list of site URLs - * wp site list --fields=domain,path --format=csv | tail -n +2 | sed 's/,//' + * wp site list --format=url * * @subcommand list * @synopsis [--network=<id>] [--format=<format>] [--fields=<fields>] @@ -365,7 +365,13 @@ function _list( $_, $assoc_args ) { ); $it = new \WP_CLI\Iterators\Table( $iterator_args ); - WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + if ( 'url' == $assoc_args['format'] ) { + foreach ( $it as $blog ) { + WP_CLI::line( $blog->domain . $blog->path ); + } + } else { + WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + } } } From 7e615b4047477e61cb7c580c579fd59c9ecdb3d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Aug 2013 16:14:46 +0300 Subject: [PATCH 2174/4858] allow passing 'php://stdin' to WP_CLI\Iterators\CSV --- php/WP_CLI/Iterators/CSV.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Iterators/CSV.php b/php/WP_CLI/Iterators/CSV.php index dde3fb51c9..a349a3e3a1 100644 --- a/php/WP_CLI/Iterators/CSV.php +++ b/php/WP_CLI/Iterators/CSV.php @@ -2,6 +2,9 @@ namespace WP_CLI\Iterators; +/** + * Allows incrementally reading and parsing lines from a CSV file. + */ class CSV implements \Iterator { const ROW_SIZE = 4096; @@ -16,8 +19,9 @@ class CSV implements \Iterator { public function __construct( $filename, $delimiter = ',' ) { $this->filePointer = fopen( $filename, 'r' ); - if ( !is_readable( $filename ) ) + if ( !$this->filePointer ) { \WP_CLI::error( sprintf( 'Could not open file: %s', $filename ) ); + } $this->delimiter = $delimiter; } From 56ca34fb3529466ef6c1b819faba405d097e9d72 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Aug 2013 15:54:08 +0300 Subject: [PATCH 2175/4858] combine 'domain' and 'path' fields into single 'url' field; remove --format=url see #661 --- php/commands/site.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 285c37c394..e0670189a0 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -335,8 +335,8 @@ public function create( $_, $assoc_args ) { * * ## EXAMPLES * - * # Output the list of site URLs - * wp site list --format=url + * # Output a simple list of site URLs + * wp site list --fields=url --format=csv | tail -n +2 * * @subcommand list * @synopsis [--network=<id>] [--format=<format>] [--fields=<fields>] @@ -348,9 +348,13 @@ function _list( $_, $assoc_args ) { global $wpdb; + if ( isset( $assoc_args['fields'] ) ) { + $assoc_args['fields'] = preg_split( '/,[ \t]*/', $assoc_args['fields'] ); + } + $defaults = array( 'format' => 'table', - 'fields' => array( 'blog_id', 'domain', 'path' ), + 'fields' => array( 'blog_id', 'url', 'last_updated', 'registered' ), ); $assoc_args = array_merge( $defaults, $assoc_args ); @@ -365,13 +369,14 @@ function _list( $_, $assoc_args ) { ); $it = new \WP_CLI\Iterators\Table( $iterator_args ); - if ( 'url' == $assoc_args['format'] ) { - foreach ( $it as $blog ) { - WP_CLI::line( $blog->domain . $blog->path ); - } - } else { - WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + $list = array(); + foreach ( $it as $blog ) { + print_r($blog); + $blog->url = $blog->domain . $blog->path; + $list[] = $blog; } + + WP_CLI\Utils\format_items( $assoc_args['format'], $list, $assoc_args['fields'] ); } } From 332caf61f61e7852ca327dc7cf6398d715e020ba Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Aug 2013 16:41:29 +0300 Subject: [PATCH 2176/4858] remove stray print_r() --- php/commands/site.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index e0670189a0..6da3de8c5e 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -371,7 +371,6 @@ function _list( $_, $assoc_args ) { $list = array(); foreach ( $it as $blog ) { - print_r($blog); $blog->url = $blog->domain . $blog->path; $list[] = $blog; } From 4351a5c29a24321170820dc457f1eee007ab4445 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Aug 2013 16:51:44 +0300 Subject: [PATCH 2177/4858] update tests for 'wp site list'. see #661 --- features/site.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/site.feature b/features/site.feature index aa53f8c369..3e872852f4 100644 --- a/features/site.feature +++ b/features/site.feature @@ -7,11 +7,11 @@ Feature: Manage sites in a multisite installation Then STDOUT should be a number And save STDOUT as {SITE_ID} - When I run `wp site list` + When I run `wp site list --fields=blog_id,url` Then STDOUT should be a table containing rows: - | blog_id | domain | path | - | 1 | example.com | / | - | 2 | example.com | /first/ | + | blog_id | url | + | 1 | example.com/ | + | 2 | example.com/first/ | When I run `wp site delete {SITE_ID} --yes` Then STDOUT should not be empty From 556f4c0bd600dce1343ee00ce825e63f62a0bead Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 13 Aug 2013 21:20:52 +0300 Subject: [PATCH 2178/4858] behat: extract compareTables() helper --- features/bootstrap/support.php | 15 ++++++++++ features/steps/basic_steps.php | 55 ++++++++++------------------------ 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index 1e9809ddf5..7b77eb7d0a 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -38,6 +38,21 @@ function checkString( $output, $expected, $action ) { } } +function compareTables( $expected_rows, $actual_rows, $output ) { + // the first row is the header and must be present + if ( $expected_rows[0] != $actual_rows[0] ) { + throw new \Exception( $output ); + } + + unset( $actual_rows[0] ); + unset( $expected_rows[0] ); + + $missing_rows = array_diff( $expected_rows, $actual_rows ); + if ( !empty( $missing_rows ) ) { + throw new \Exception( $output ); + } +} + function compareContents( $expected, $actual ) { if ( gettype( $expected ) != gettype( $actual ) ) { return false; diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index d3b267ee6d..0e1ab48819 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -168,59 +168,34 @@ function ( $world, $stream ) { $steps->Then( '/^STDOUT should be a table containing rows:$/', function ( $world, TableNode $expected ) { - $output = $world->result->STDOUT; - $outputRows = explode( "\n", rtrim( $output, "\n" ) ); + $output = $world->result->STDOUT; + $actual_rows = explode( "\n", rtrim( $output, "\n" ) ); - $expectedRows = array(); + $expected_rows = array(); foreach ( $expected->getRows() as $row ) { - $expectedRows[] = $world->replace_variables( implode( "\t", $row ) ); + $expected_rows[] = $world->replace_variables( implode( "\t", $row ) ); } - // the first row is the header and must be present - if ( $expectedRows[0] != $outputRows[0] ) { - throw new \Exception( $output ); - } - - unset($outputRows[0]); - unset($expectedRows[0]); - $matches = array_intersect( $expectedRows, $outputRows ); - if ( count( $expectedRows ) != count( $matches ) ) { - throw new \Exception( $output ); - } + compareTables( $expected_rows, $actual_rows, $output ); } ); $steps->Then( '/^STDOUT should end with a table containing rows:$/', function ( $world, TableNode $expected ) { - $output = $world->result->STDOUT; - $outputRows = explode( "\n", rtrim( $output, "\n" ) ); + $output = $world->result->STDOUT; + $actual_rows = explode( "\n", rtrim( $output, "\n" ) ); - $expectedRows = array(); + $expected_rows = array(); foreach ( $expected->getRows() as $row ) { - $expectedRows[] = $world->replace_variables( implode( "\t", $row ) ); + $expected_rows[] = $world->replace_variables( implode( "\t", $row ) ); } - $remainingRows = array(); - $start = false; - foreach( $outputRows as $key => $row ) { - - // the first row is the header and must be present - if ( $expectedRows[0] == $row ) - $start = true; + $start = array_search( $expected_rows[0], $actual_rows ); - if ( $start ) - $remainingRows[] = $row; - } - - if ( ! $start ) + if ( false === $start ) throw new \Exception( $output ); - unset($remainingRows[0]); - unset($expectedRows[0]); - $matches = array_intersect( $expectedRows, $remainingRows ); - - if ( count( $expectedRows ) != count( $matches ) ) - throw new \Exception( $output ); + compareTables( $expected_rows, array_slice( $actual_rows, $start ), $output ); } ); @@ -235,17 +210,17 @@ function ( $world, PyStringNode $expected ) { }); $steps->Then( '/^STDOUT should be CSV containing:$/', - function( $world, TableNode $expected ) { + function ( $world, TableNode $expected ) { $output = $world->result->STDOUT; - $expectedRows = $expected->getRows(); + $expected_rows = $expected->getRows(); foreach ( $expected as &$row ) { foreach ( $row as &$value ) { $value = $world->replace_variables( $value ); } } - if ( ! checkThatCsvStringContainsValues( $output, $expectedRows ) ) + if ( ! checkThatCsvStringContainsValues( $output, $expected_rows ) ) throw new \Exception( $output ); } ); From 0d9538f6e45d830dd2ef3644056dd7eb663a1b98 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Tue, 13 Aug 2013 11:49:51 -0700 Subject: [PATCH 2179/4858] Correct `wp user add-role` example --- php/commands/user.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 521e142f7b..b694aaa678 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -397,8 +397,8 @@ public function set_role( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user set-role bob author - * wp user set-role 12 author + * wp user add-role bob author + * wp user add-role 12 author * * @subcommand add-role * @synopsis <user> <role> From e7144cfb9055b67df6b5ab49ef3a39e8cfd4241d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 02:51:15 +0300 Subject: [PATCH 2180/4858] add support for PsySH in `wp shell` also, replace Boris as suggested package --- bin/ci/install_dependencies.sh | 1 - composer.json | 2 +- php/commands/shell.php | 21 ++++++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/bin/ci/install_dependencies.sh b/bin/ci/install_dependencies.sh index 6fbef59572..1b2e5723a1 100755 --- a/bin/ci/install_dependencies.sh +++ b/bin/ci/install_dependencies.sh @@ -9,7 +9,6 @@ curl http://behat.org/downloads/behat.phar > behat.phar # install dependencies composer install --no-interaction --prefer-source -composer require d11wtq/boris=dev-master --no-interaction --prefer-source # set up WP install ./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ diff --git a/composer.json b/composer.json index a572e0a852..0e5aa5451c 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "rmccue/requests": "dev-master" }, "suggest": { - "d11wtq/boris": "Enhanced `wp shell` functionality" + "psy/psysh": "Enhanced `wp shell` functionality" }, "autoload": { "psr-0": { "WP_CLI": "php" } diff --git a/php/commands/shell.php b/php/commands/shell.php index ef0869e853..ee95860e64 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -18,20 +18,27 @@ class Shell_Command extends \WP_CLI_Command { */ public function __invoke( $_, $assoc_args ) { $implementations = array( + '\\Psy\\Shell', '\\Boris\\Boris', '\\WP_CLI\\REPL', ); if ( isset( $assoc_args['basic'] ) ) { - unset( $implementations[0] ); + $class = '\\WP_CLI\\REPL'; + } else { + foreach ( $implementations as $candidate ) { + if ( class_exists( $candidate ) ) { + $class = $candidate; + break; + } + } } - foreach ( $implementations as $class ) { - if ( class_exists( $class ) ) { - $repl = new $class( 'wp> ' ); - $repl->start(); - break; - } + if ( '\\Psy\\Shell' == $class ) { + \Psy\Shell::debug(); + } else { + $repl = new $class( 'wp> ' ); + $repl->start(); } } } From fd881948697f91b29e91fead91b007f5b22db31a Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Wed, 14 Aug 2013 14:37:54 +0100 Subject: [PATCH 2181/4858] Let's use the simpler `array_merge()` instead of `wp_parse_args()` --- php/WP_CLI/CommandWithUpgrade.php | 6 +++--- php/commands/post.php | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index dac45fa87c..6568bd21db 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -220,16 +220,16 @@ function update_all( $args, $assoc_args ) { } protected function _list( $_, $assoc_args ) { - $values = array( + $defaults = array( 'format' => 'table', 'fields' => $this->fields ); - $values = wp_parse_args( $assoc_args, $values ); + $assoc_args = array_merge( $defaults, $assoc_args ); $all_items = $this->get_all_items(); $items = $this->create_objects( $all_items ); - \WP_CLI\Utils\format_items( $values['format'], $items, $values['fields'] ); + \WP_CLI\Utils\format_items( $assoc_args['format'], $items, $assoc_args['fields'] ); } /** diff --git a/php/commands/post.php b/php/commands/post.php index fb6355461a..22e09078f0 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -163,9 +163,10 @@ protected function _edit( $content, $title ) { * @synopsis [--format=<format>] <ID> */ public function get( $args, $assoc_args ) { - $assoc_args = wp_parse_args( $assoc_args, array( + $defaults = array( 'format' => 'table' - ) ); + ); + $assoc_args = array_merge( $defaults, $assoc_args ); $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) @@ -216,9 +217,10 @@ public function get( $args, $assoc_args ) { * @synopsis <id>... [--force] */ public function delete( $args, $assoc_args ) { - $assoc_args = wp_parse_args( $assoc_args, array( + $defaults = array( 'force' => false - ) ); + ); + $assoc_args = array_merge( $defaults, $assoc_args ); parent::delete( $args, $assoc_args ); } @@ -265,12 +267,11 @@ public function _list( $_, $assoc_args ) { 'posts_per_page' => -1, 'post_status' => 'any', ); - - $values = array( + $defaults = array( 'format' => 'table', 'fields' => $this->fields ); - $values = wp_parse_args( $assoc_args, $values ); + $assoc_args = array_merge( $defaults, $assoc_args ); foreach ( $assoc_args as $key => $value ) { if ( true === $value ) @@ -279,12 +280,12 @@ public function _list( $_, $assoc_args ) { $query_args[ $key ] = $value; } - if ( 'ids' == $values['format'] ) + if ( 'ids' == $assoc_args['format'] ) $query_args['fields'] = 'ids'; $query = new WP_Query( $query_args ); - WP_CLI\Utils\format_items( $values['format'], $query->posts, $values['fields'] ); + WP_CLI\Utils\format_items( $assoc_args['format'], $query->posts, $assoc_args['fields'] ); } /** @@ -328,7 +329,7 @@ public function generate( $args, $assoc_args ) { 'post_date' => current_time( 'mysql' ), ); - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); + extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); if ( !post_type_exists( $post_type ) ) { WP_CLI::error( sprintf( "'%s' is not a registered post type.", $post_type ) ); From 10845a747904cf2a6ddefbf9b6c07e1d769238c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 17:40:20 +0300 Subject: [PATCH 2182/4858] Don't pretend we're in wp-admin, but continue to load all admin APIs. The WP_CLI context is not like the WP_ADMIN context. It's a different animal. See #674 for more details. Fixes #477, #519, #574, #579, #582, #669 --- features/core.feature | 8 +------- php/WP_CLI/CommandWithUpgrade.php | 3 +++ php/wp-cli.php | 8 +------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/features/core.feature b/features/core.feature index 7f7363f78b..9d248d6316 100644 --- a/features/core.feature +++ b/features/core.feature @@ -98,15 +98,9 @@ Feature: Manage WordPress installation When I run `wp eval 'var_export( is_admin() );'` Then STDOUT should be: """ - true + false """ - When I run `wp eval 'var_export( function_exists( 'media_handle_upload' ) );'` - Then STDOUT should be: - """ - true - """ - # Can complain that it's already installed, but don't exit with an error code When I try `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then the return code should be 0 diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 6568bd21db..96ce4df28f 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -220,6 +220,9 @@ function update_all( $args, $assoc_args ) { } protected function _list( $_, $assoc_args ) { + // Force WordPress to check for updates + call_user_func( $this->upgrade_refresh ); + $defaults = array( 'format' => 'table', 'fields' => $this->fields diff --git a/php/wp-cli.php b/php/wp-cli.php index 4baaf4d219..d3638664d4 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -19,20 +19,14 @@ // Load wp-config.php code, in the global scope eval( WP_CLI::get_runner()->get_wp_config_code() ); -// Simulate a /wp-admin/ page load -$_SERVER['PHP_SELF'] = '/wp-admin/index.php'; -define( 'WP_ADMIN', true ); -define( 'WP_NETWORK_ADMIN', false ); -define( 'WP_USER_ADMIN', false ); - // Load Core, mu-plugins, plugins, themes etc. require WP_CLI_ROOT . '/php/wp-settings-cli.php'; // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); +// Load all the admin APIs, for convenience require ABSPATH . 'wp-admin/includes/admin.php'; -do_action( 'admin_init' ); WP_CLI::get_runner()->after_wp_load(); From 5322b2bd65d8d08206d4f0a8a3f71bc801715d69 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 17:54:10 +0300 Subject: [PATCH 2183/4858] whitespace fixes [ci skip] --- php/commands/import.php | 4 ++-- php/commands/user.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index d114d4f9df..39fccb8f64 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -19,7 +19,6 @@ class Import_Command extends WP_CLI_Command { * @synopsis <file> --authors=<authors> [--skip=<data-type>] */ public function __invoke( $args, $assoc_args ) { - list( $file ) = $args; if ( ! file_exists( $file ) ) @@ -255,14 +254,15 @@ private function process_author_mapping( $authors_arg, $author_data ) { * Read an author mapping file */ private function read_author_mapping_file( $file ) { - $author_mapping = array(); + foreach ( new \WP_CLI\Iterators\CSV( $file ) as $i => $author ) { if ( ! array_key_exists( 'old_user_login', $author ) || ! array_key_exists( 'new_user_login', $author ) ) return new WP_Error( 'invalid-author-mapping', "Author mapping file isn't properly formatted." ); $author_mapping[] = $author; } + return $author_mapping; } diff --git a/php/commands/user.php b/php/commands/user.php index b694aaa678..c14108df52 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -473,7 +473,7 @@ public function add_cap( $args, $assoc_args ) { if ( $user ) { $cap = $args[1]; $user->add_cap( $cap ); - + WP_CLI::success( sprintf( "Added '%s' capability for %s (%d).", $cap, $user->user_login, $user->ID ) ); } } @@ -502,7 +502,7 @@ public function remove_cap( $args, $assoc_args ) { if ( $user ) { $cap = $args[1]; $user->remove_cap( $cap ); - + WP_CLI::success( sprintf( "Removed '%s' cap for %s (%d).", $cap, $user->user_login, $user->ID ) ); } } From d5f2bb15c0bbcef834e3f6863d3d94240acdaae6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 20:00:07 +0300 Subject: [PATCH 2184/4858] bring back accidentally removed test; see #674 --- features/core.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/core.feature b/features/core.feature index 9d248d6316..a06a966c9e 100644 --- a/features/core.feature +++ b/features/core.feature @@ -101,6 +101,12 @@ Feature: Manage WordPress installation false """ + When I run `wp eval 'var_export( function_exists( 'media_handle_upload' ) );'` + Then STDOUT should be: + """ + true + """ + # Can complain that it's already installed, but don't exit with an error code When I try `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then the return code should be 0 From 3106ee674b65b22da7f6139b0040448aaeba3e2c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 22:00:34 +0300 Subject: [PATCH 2185/4858] resurect Phar building code removed in 8483fb709b2285a033515f59b4ad818468a0372a changes: * make WP_CLI_ROOT relative to the root dir, not to php/ * remove man/ and add vendor/rmmcue --- php/boot-phar.php | 6 +++ utils/make-phar.php | 88 ++++++++++++++++++++++++++++++++++++++++ utils/test-phar-download | 6 +++ utils/update-phar | 46 +++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 php/boot-phar.php create mode 100644 utils/make-phar.php create mode 100755 utils/test-phar-download create mode 100755 utils/update-phar diff --git a/php/boot-phar.php b/php/boot-phar.php new file mode 100644 index 0000000000..35b82e3a22 --- /dev/null +++ b/php/boot-phar.php @@ -0,0 +1,6 @@ +<?php + +define( 'WP_CLI_ROOT', 'phar://wp-cli.phar' ); + +include WP_CLI_ROOT . '/php/wp-cli.php'; + diff --git a/utils/make-phar.php b/utils/make-phar.php new file mode 100644 index 0000000000..df96bab379 --- /dev/null +++ b/utils/make-phar.php @@ -0,0 +1,88 @@ +<?php + +if ( !isset( $argv[1] ) ) { + echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet]\n"; + exit(1); +} + +define( 'DEST_PATH', $argv[1] ); + +define( 'BE_QUIET', in_array( '--quiet', $argv ) ); + +function get_iterator( $dir ) { + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ) + ); +} + +function add_file( $phar, $path ) { + $key = str_replace( './', '', $path ); + + if ( !BE_QUIET ) + echo "$key - $path\n"; + + $phar[ $key ] = file_get_contents( $path ); +} + +$phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' ); + +$phar->startBuffering(); + +// php files +foreach ( get_iterator( './php' ) as $path ) { + if ( !preg_match( '/\.php$/', $path ) ) + continue; + + add_file( $phar, $path ); +} + +// non-php files +$additional_dirs = array( + './templates', +); + +foreach ( $additional_dirs as $dir ) { + foreach ( get_iterator( $dir ) as $path ) { + add_file( $phar, $path ); + } +} + +// dependencies +$ignored_paths = array( + '/.git', +); + +$vendor_dirs = array( + './vendor/mustache', + './vendor/rmccue', + './vendor/wp-cli', + './vendor/composer', +); + +foreach ( $vendor_dirs as $vendor_dir ) { + foreach ( get_iterator( $vendor_dir ) as $path ) { + foreach ( $ignored_paths as $ignore ) { + if ( strpos( $path, $ignore ) ) + continue 2; + } + + add_file( $phar, $path ); + } +} + +add_file( $phar, './vendor/autoload.php' ); + +$phar->setStub( <<<EOB +#!/usr/bin/env php +<?php +Phar::mapPhar(); +include 'phar://wp-cli.phar/php/boot-phar.php'; +__HALT_COMPILER(); +?> +EOB +); + +$phar->stopBuffering(); + +echo "Generated " . DEST_PATH . "\n"; + diff --git a/utils/test-phar-download b/utils/test-phar-download new file mode 100755 index 0000000000..f1a47e5190 --- /dev/null +++ b/utils/test-phar-download @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +actual_checksum=$(curl http://wp-cli.org/packages/phar/wp-cli.phar | md5sum | cut -d ' ' -f 1) + +echo "expected:" $(curl -s http://wp-cli.org/packages/phar/wp-cli.phar.md5) +echo "actual: " $actual_checksum diff --git a/utils/update-phar b/utils/update-phar new file mode 100755 index 0000000000..ea79bf1129 --- /dev/null +++ b/utils/update-phar @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -ex + +current_rev=$(git rev-parse HEAD) +current_rev=${current_rev:0:10} + +packages_repo=../wp-cli-packages + +fname="phar/wp-cli.phar" + +# generate archive +php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet + +cd $packages_repo + +# smoke test +php $fname --version + +# check which wp-cli commit the previous Phar archive was based on +# can't use the md5 hash, since it will be different each time the +# archive is generated +new_commit_subj="update wp-cli.phar to wp-cli/wp-cli@$current_rev" + +current_commit_subj=$(git show -s --pretty=format:%s HEAD) + +if [ "$new_commit_subj" = "$current_commit_subj" ]; then + echo "already at latest revision" + exit 1 +fi + +# generate md5 checksum +if [ command -v md5sum > /dev/null ] +then + md5hash=$(md5sum $fname) +else + md5hash=$(md5 -r $fname) +fi + +echo $md5hash | cut -d ' ' -f 1 > $fname.md5 + +git add $fname $fname.md5 + +git commit -m "$new_commit_subj" + +git push From ceefca839c6fb9615f33fbd1258347f548d8e83a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 22:52:47 +0300 Subject: [PATCH 2186/4858] add symfony/finder as dev dependency --- composer.json | 3 ++ utils/make-phar.php | 77 +++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/composer.json b/composer.json index 0e5aa5451c..8e1c9f77c8 100644 --- a/composer.json +++ b/composer.json @@ -19,5 +19,8 @@ }, "autoload": { "psr-0": { "WP_CLI": "php" } + }, + "require-dev": { + "symfony/finder": "~2.3" } } diff --git a/utils/make-phar.php b/utils/make-phar.php index df96bab379..9ce99660d6 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -1,5 +1,9 @@ <?php +require './vendor/autoload.php'; + +use Symfony\Component\Finder\Finder; + if ( !isset( $argv[1] ) ) { echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet]\n"; exit(1); @@ -9,12 +13,6 @@ define( 'BE_QUIET', in_array( '--quiet', $argv ) ); -function get_iterator( $dir ) { - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ) - ); -} - function add_file( $phar, $path ) { $key = str_replace( './', '', $path ); @@ -28,46 +26,37 @@ function add_file( $phar, $path ) { $phar->startBuffering(); -// php files -foreach ( get_iterator( './php' ) as $path ) { - if ( !preg_match( '/\.php$/', $path ) ) - continue; - - add_file( $phar, $path ); -} - -// non-php files -$additional_dirs = array( - './templates', -); - -foreach ( $additional_dirs as $dir ) { - foreach ( get_iterator( $dir ) as $path ) { - add_file( $phar, $path ); - } +// PHP files +$finder = new Finder(); +$finder + ->files() + ->ignoreVCS(true) + ->name('*.php') + ->in('./php') + ->in('./vendor/wp-cli') + ->in('./vendor/mustache') + ->in('./vendor/rmccue/requests') + ->in('./vendor/composer') + ->exclude('test') + ->exclude('tests') + ->exclude('php-cli-tools/examples') + ; + +foreach ( $finder as $file ) { + add_file( $phar, $file ); } -// dependencies -$ignored_paths = array( - '/.git', -); - -$vendor_dirs = array( - './vendor/mustache', - './vendor/rmccue', - './vendor/wp-cli', - './vendor/composer', -); - -foreach ( $vendor_dirs as $vendor_dir ) { - foreach ( get_iterator( $vendor_dir ) as $path ) { - foreach ( $ignored_paths as $ignore ) { - if ( strpos( $path, $ignore ) ) - continue 2; - } - - add_file( $phar, $path ); - } +// other files +$finder = new Finder(); +$finder + ->files() + ->ignoreVCS(true) + ->name('*.mustache') + ->in('./templates') + ; + +foreach ( $finder as $file ) { + add_file( $phar, $file ); } add_file( $phar, './vendor/autoload.php' ); From bad20dad4bebe798c3422968a12ae055795070c3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 23:31:08 +0300 Subject: [PATCH 2187/4858] bump version to 0.12-alpha2 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index d3638664d4..b6fda097ae 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.12-alpha' ); +define( 'WP_CLI_VERSION', '0.12-alpha2' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From b46b4ea747cc687b747b9d8550fa8eb5a570589a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 23:20:29 +0300 Subject: [PATCH 2188/4858] run the functional tests against the Phar file --- bin/ci/run_build.sh | 11 ++++++++++- features/bootstrap/Process.php | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bin/ci/run_build.sh b/bin/ci/run_build.sh index 2fb25dfead..f3cd75e8e8 100755 --- a/bin/ci/run_build.sh +++ b/bin/ci/run_build.sh @@ -4,4 +4,13 @@ set -ex phpunit -php behat.phar --format progress +# Run the functional tests against the Phar file + +WP_CLI_BIN_DIR=/tmp/wp-cli-phar + +mkdir -p $WP_CLI_BIN_DIR +php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet +mv wp-cli.phar $WP_CLI_BIN_DIR/wp +chmod +x $WP_CLI_BIN_DIR/wp + +WP_CLI_BIN_DIR=$WP_CLI_BIN_DIR php behat.phar --format progress diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 992428a0cf..072b6b1859 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -28,8 +28,10 @@ public function run( $subdir = '' ) { ); // Ensure we're using the expected `wp` binary + $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); + $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, array( - 'PATH' => realpath( __DIR__ . "/../../bin" ) . ':' . getenv( 'PATH' ), + 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), 'BEHAT_RUN' => 1 ) ); From b23a23051b81f3fe0677d3fddb487687253120fa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 23:21:32 +0300 Subject: [PATCH 2189/4858] phar: add missing rumsaa/array_column dependency --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 9ce99660d6..a9f5477c49 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -37,6 +37,7 @@ function add_file( $phar, $path ) { ->in('./vendor/mustache') ->in('./vendor/rmccue/requests') ->in('./vendor/composer') + ->in('./vendor/rhumsaa/array_column') ->exclude('test') ->exclude('tests') ->exclude('php-cli-tools/examples') From cef5beb9ca909ceeecb10f19891132d5b978dfcf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 14 Aug 2013 23:38:45 +0300 Subject: [PATCH 2190/4858] phar: add all files from the templates/ directory --- utils/make-phar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index a9f5477c49..8f7bb90cdb 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -52,7 +52,7 @@ function add_file( $phar, $path ) { $finder ->files() ->ignoreVCS(true) - ->name('*.mustache') + ->ignoreDotFiles(false) ->in('./templates') ; From ec9c530c60c64ce8a37aecea8226564873d00b71 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Aug 2013 00:03:38 +0300 Subject: [PATCH 2191/4858] give shorter names to ci scripts --- .travis.yml | 4 ++-- bin/ci/{run_build.sh => build.sh} | 6 +++--- bin/ci/{install_dependencies.sh => prepare.sh} | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename bin/ci/{run_build.sh => build.sh} (79%) rename bin/ci/{install_dependencies.sh => prepare.sh} (100%) diff --git a/.travis.yml b/.travis.yml index 7a642a4544..e05a986c76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,9 @@ matrix: - php: 5.5 env: WP_VERSION=3.4.2 -before_script: ./bin/ci/install_dependencies.sh +before_script: ./bin/ci/prepare.sh -script: ./bin/ci/run_build.sh +script: ./bin/ci/build.sh notifications: email: diff --git a/bin/ci/run_build.sh b/bin/ci/build.sh similarity index 79% rename from bin/ci/run_build.sh rename to bin/ci/build.sh index f3cd75e8e8..1dd2c52e29 100755 --- a/bin/ci/run_build.sh +++ b/bin/ci/build.sh @@ -2,15 +2,15 @@ set -ex +# Run the unit tests phpunit -# Run the functional tests against the Phar file - +# Create the Phar file WP_CLI_BIN_DIR=/tmp/wp-cli-phar - mkdir -p $WP_CLI_BIN_DIR php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet mv wp-cli.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp +# Run the functional tests WP_CLI_BIN_DIR=$WP_CLI_BIN_DIR php behat.phar --format progress diff --git a/bin/ci/install_dependencies.sh b/bin/ci/prepare.sh similarity index 100% rename from bin/ci/install_dependencies.sh rename to bin/ci/prepare.sh From 0b828831e6c9219963a66f2b3ff1e6fcd0e85f9a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Aug 2013 00:07:02 +0300 Subject: [PATCH 2192/4858] move WP_CLI_BIN_DIR env variable to .travis.yml --- .travis.yml | 7 +++++-- bin/ci/build.sh | 3 +-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e05a986c76..41ebe18aaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,11 @@ php: - 5.5 env: - - WP_VERSION=latest - - WP_VERSION=3.4.2 + global: + - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + matrix: + - WP_VERSION=latest + - WP_VERSION=3.4.2 matrix: exclude: diff --git a/bin/ci/build.sh b/bin/ci/build.sh index 1dd2c52e29..4c77a2b8ac 100755 --- a/bin/ci/build.sh +++ b/bin/ci/build.sh @@ -6,11 +6,10 @@ set -ex phpunit # Create the Phar file -WP_CLI_BIN_DIR=/tmp/wp-cli-phar mkdir -p $WP_CLI_BIN_DIR php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet mv wp-cli.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp # Run the functional tests -WP_CLI_BIN_DIR=$WP_CLI_BIN_DIR php behat.phar --format progress +php behat.phar --format progress From a2d38e61a3710f37617be47055e7f1f88ee63e77 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Aug 2013 21:50:05 +0000 Subject: [PATCH 2193/4858] Change load order of autoloaders --- php/utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index 633603435b..70f8100359 100644 --- a/php/utils.php +++ b/php/utils.php @@ -8,8 +8,8 @@ function load_dependencies() { $vendor_paths = array( - WP_CLI_ROOT . '/vendor', // top-level project - WP_CLI_ROOT . '/../../../vendor', // part of a larger project + WP_CLI_ROOT . '/../../../vendor', // part of a larger project / installed via Composer (preferred) + WP_CLI_ROOT . '/vendor', // top-level project / installed as Git clone ); $has_autoload = false; From 1f62efd183976d173c3aa58962dca0a5305c2d6e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Aug 2013 00:47:58 +0300 Subject: [PATCH 2194/4858] move Phar building to ci/prepare.sh and rename ci/build.sh to ci/test.sh --- .travis.yml | 2 +- bin/ci/build.sh | 15 --------------- bin/ci/prepare.sh | 15 +++++++++------ bin/ci/test.sh | 9 +++++++++ 4 files changed, 19 insertions(+), 22 deletions(-) delete mode 100755 bin/ci/build.sh create mode 100755 bin/ci/test.sh diff --git a/.travis.yml b/.travis.yml index 41ebe18aaf..67e8d32caa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ matrix: before_script: ./bin/ci/prepare.sh -script: ./bin/ci/build.sh +script: ./bin/ci/test.sh notifications: email: diff --git a/bin/ci/build.sh b/bin/ci/build.sh deleted file mode 100755 index 4c77a2b8ac..0000000000 --- a/bin/ci/build.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -ex - -# Run the unit tests -phpunit - -# Create the Phar file -mkdir -p $WP_CLI_BIN_DIR -php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet -mv wp-cli.phar $WP_CLI_BIN_DIR/wp -chmod +x $WP_CLI_BIN_DIR/wp - -# Run the functional tests -php behat.phar --format progress diff --git a/bin/ci/prepare.sh b/bin/ci/prepare.sh index 1b2e5723a1..efb241cedd 100755 --- a/bin/ci/prepare.sh +++ b/bin/ci/prepare.sh @@ -4,15 +4,18 @@ set -ex -# install Behat -curl http://behat.org/downloads/behat.phar > behat.phar - -# install dependencies composer install --no-interaction --prefer-source -# set up WP install +# the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR +mkdir -p $WP_CLI_BIN_DIR +php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet +mv wp-cli.phar $WP_CLI_BIN_DIR/wp +chmod +x $WP_CLI_BIN_DIR/wp + +# Travis CI doesn't come with Behat pre-installed +curl http://behat.org/downloads/behat.phar > behat.phar + ./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ -# set up database mysql -e 'CREATE DATABASE wp_cli_test;' -uroot mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot diff --git a/bin/ci/test.sh b/bin/ci/test.sh new file mode 100755 index 0000000000..3a94100a7c --- /dev/null +++ b/bin/ci/test.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex + +# Run the unit tests +phpunit + +# Run the functional tests +php behat.phar --format progress From 7622f0b96e28c05f410496e37a4495e56162391f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Aug 2013 17:08:43 +0300 Subject: [PATCH 2195/4858] automatically deploy Phar file to wp-cli/builds --- .travis.yml | 34 ++++++++++++++++++++++++++++++---- bin/ci/deploy.sh | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100755 bin/ci/deploy.sh diff --git a/.travis.yml b/.travis.yml index 67e8d32caa..536c0f5395 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,20 +6,46 @@ php: env: global: - - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + # Encripted deploy key. See https://gist.github.com/scribu/6241271 + - secure: "U8gOPW2m9fkJW8omnPjFHFZutGIqAAfVs0H1izpSKJhclUfYAGjAGl1Cb6ZiUp3jZE11iWa+fAZ5mmmLAQ5L9ijta40igfFw0s+o/Vt3WBM4a3Vdqpg6civ0rDi9tJYuwtMaEi/kF/yuhKzUT80EAMqVix5xPnf963iIUPyarfY=" + - secure: "W9t7pG5h/Khoi+TrxplpSeTWxaTr7r6cYRVJBsXgghZLDXsU/qn/OhGDdY+IMfSgzO49wjFyLh2EOs8zZSujY75fgFffK2+jd/882NUlpvpXoW9C3yEfZhLJVQZI/1idnpDe9f6zA0XlpBn3bQ2QeS3i2a/JwOGCD8BQjNobk1M=" + - secure: "YsVv3AKeHyr6nwkjhB+VingCdWIzfNP2VYMMHf841rnH6HsAXNw8PJcinnVYeMd15kgjA3Yk8PbITOmzZkf9yjAmbgJTvNempEElF/KG42FkoCACtZ2Wc/jIL9zEi5o47qUicwiS6LLWYx1uQa6vActpE4KdrcDLJ6pQHp/s7ss=" + - secure: "Qsx9+R7VBSdk3st1yVyRMYgAHV58lUUSqXJjvxAkUFXsumCEVFiNpuKepvA5+EZHHnpo7zQOK6EzrIDgUBHGfwEvVumI5eur8G1RKdHnvotuz4D7YCdoRnnrzbhJkAPnVcGrIBIHd5GlDHPTVBij77JwMq5kg2tfKoKcW3RuQTc=" + - secure: "NY3grWJVgnRcA7jQW0/DbPrSkIHVkGxfhdmVSVuSfhsRq5j4kA8/zhWTIwuQ4RtkE88GWye6NarJfjFYnz2KgnCUeaFPFdnB0VE3C3OUeWIsbitjYeqycUd1+JOikPREDZaXjBb79Ve6PGTHv7CUQ+R8vBYSR7eXGqNF9SBDTEw=" + - secure: "XuKAHb35W5vN/JX8iV4FipVdxUH8GbrfheOpOAwgZ0WS5+ua79farr6q73BIPzW8AMAg3p+p1UWNoKLFEaszKuW/mT7dQExsQO04aZ7ESeLbaoKS28EMUCVeOJl0Vo+AxNSruUAIbanvggyAcxq1ILGqH9iaHLpb9BgPei3LdEc=" + - secure: "GSPAeXVhSz5MQ/FRoGFQ7As6a3w/hsq5CslpSCvNz3q7jXUjK+HPzhq3MpWF8sBd6j5IS5YUn1Pl383BDfWj/RYhIzruzIwZhgD+M7VaFFHXcS7y6i9ritXKaw2g4u+16DYQC0zg0jBODXd5NspzyeB6IA5RSecqZeuPW7z/kJc=" + - secure: "BneSPyRBtN8BPNU//rAqFmma0HfVW2GXTgRf/vuTWDnkQ9aE3Uz4S8mlA4lcVpNigvVgRop7MltLVvpWNPDk4tVPu19CkhzKXIEj6Ny6UgD6f4ZHXid/T7I6T50dtJOfcj6leDih92M2JMNaBLPRxOvAUv6yN5FrSV2LNE/0XOw=" + - secure: "URrY5IoJxf40PX+UAldnJK5HZgL5EhJ/n+ildhltyFxDu3E29Ic8Unx89M4Cb09buv1sFBFMC59q3jxck9XOWBsxiRct9y/lvnzI1R1GmVoNiTssg7wLqL6MuD2iy/4fFHFgne2mg7DVDtujCUwTQgtdz7yoh8fQeF/6lBmge1U=" + - secure: "AlNVx6gd7x7lBgrk1Dcna3yfUgdx0wZEdH8V/5NaGirfGMnO7x7ZB1pQ2LVS4EIDCZSELqUCWirFzloJtxOyUJ5AZWCu2YSGzn0cxsHkZDdBsQ1J/oPYpO8PZ9bRBDhGqqqq96F4bPxav1e8G4TH165wBB6MsR1M/He0gPrL57g=" + - secure: "JOvovCe2mKyX6/Ihvqzu93px0RdE/RsNnyDJ6EYTJjFMOhpTP/GTQQcLhMVYq62pM6Ng9/jCQl5VMWEk0f7SGL7X/RW6Rz8HaL1KWy2U9/z67FQPMz+WlJMLTP77PXJouqVemG7Om8Mheg8vMUcgXV1W/vgoljzgeBf1zseQODg=" + - secure: "H7caXIeMS7r6mLuD2aombGuGskD3VwdptcPaY2X/natpMtvHHjbyonUFE26prTWsxFc29wT9Ot705w+yo0DK42SNGaqACpy1tjq6v6xwTCjIIYeGenfnb4FiFjOROCfCXdigJ9ANDS9ufvEd2pgB12BChyLvDVX8pn3FqVzO/wQ=" + - secure: "HbyEWzWOK/dtyYY4J6BcwwCy5EWKzRI1K51Qgsc7nyN6ZlQ4P7vvFmQuLX79zTX9k3PJb58/7Ahl0xQe2mhnpK3awAEuW4ZyqL9CFQnsn7FXAAm7DWcnD8WZvOR0BitiVOEAziuh9dM7FQYBkaq6vSU+Og7NC48osDX/y4PkmG8=" + - secure: "OtXKQFf7ef/1R67U+923TJwx8uafHkhIT3wUmw3QQFkimUDHAH3tPmEk5Qy6a59aMDEO0ESIZdTfwUcMcmfgqhAxNlvmDFSnfOgJmRxzeCD036/sU/8td8VNwRW93iCu48LoGcBfVcP3lM7EJVPK2NGjneBKjna8ekLMcSx8tmE=" + - secure: "G1+MwEPgBswGI3CGtvpwV6ELauqBgBo5b5QLDd44ijqhTOYiUZz5tzU2iKR+5sMm1TqVQjGpSNC/+Hpi4WTKnKCPfKnJh/Z4/859a90GlBytsEGLGK9kAduVeLiJ1T5aOA5lHAhHsWe+CL5+d4LVlFdzBeggcXjJj5+DHHZe7+s=" + - secure: "Z6jHEwZCotrkAvIbj7/fY2fNFvDK6CTZgkpRp+VRdTk8/krWBIBGpTXgSOPXxcx+yNWooRw/mS3sazFQzZ0cv2kqGFtKxTThfAHnWNf2wMlxXvk+FGGGlIOpwt6sB5Eh3N7sF/ZkfioYE66jIVWZg4AiXJ+iEH+DKNFKVrSkwk0=" + - secure: "BzGrbJOSRsuvPrHsSY3zwOn05G9qYq/l8mBltGikRgjMGLEJpH+9+vO5YyCSgS4tDsihSw+SFpNQojS3wDUyNFT7pe0IRnCukletOVp+gwPHdqD8NoEw1gKlWFhgFZNRrc/Ma6bQqPgaQmTV+HKbSM/oAIyW5NKA/+66WTESCrg=" + - secure: "JWzwwyjbZqrCki9ijj75+X2xRS7eLJDahiAS9x87GDz8wbCMuTpWzkA+lbrj5Za3wTRUe5S4wcAELhal2x0CTRO8wUQkxSo2cATN9Bk2p00SJtCBxRJrq2H5QmmYaLIluOmyIQNDpaNS/O+TQGgUCpVg2x8KzqgiCYYGXewgJ1g=" + - secure: "g1QgDqGFAYJqxv3qyT2tQplT62o/3xA19SAjO4sAzgEp8t/h6J9K+ehbyz3tlsGJhOP/b7VGyjvnUKLZ+4BlaRhSsS1TND753+YhWGD2PKhIZ58hdW4m4ARY0yrRkVFMQqEyyIj8D+TBC713yDc58L/tmehf8ZljZpFG2PICidE=" + - secure: "Gj9fw1wM3dfgZab0XqULeR9loDj9Gsa99z8bPgfAEWS7cWqoTitF2Y9SolUX1WZyOJUZ+5Shrl7jnihl8EOlm13wxt680Kmt7jTVX5DUH+NvzWVwkYDrZV7zSFayYZJTdx3FjEvSs+GIVrpzBeBvVFvCTQUuIphPkbxwR0JHonI=" + - secure: "XS4lJJSZ2+4rB+zkt9lsdhG+pZEQ6nUjRSdLcVAgS7f7yvFCOjJYWRXlQ5zP/Gl3/XVe/L8EuGLYZsztauLSd6Ob7nEwnb5vIegLaqzbZd7Yizp9TnBj0AFCqo/ZPY+ZhnURY9OLFqknfQMWhrTeVvGRT94nhnnIF+sxokQgv0M=" + - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" + - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=latest - - WP_VERSION=3.4.2 + - WP_VERSION=latest + - WP_VERSION=3.4.2 DEPLOY_BRANCH=phar-builder matrix: exclude: - php: 5.5 - env: WP_VERSION=3.4.2 + env: WP_VERSION=3.4.2 DEPLOY_BRANCH=phar-builder before_script: ./bin/ci/prepare.sh script: ./bin/ci/test.sh +after_success: ./bin/ci/deploy.sh + notifications: email: on_success: never diff --git a/bin/ci/deploy.sh b/bin/ci/deploy.sh new file mode 100755 index 0000000000..a88cba3ba6 --- /dev/null +++ b/bin/ci/deploy.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# called by Travis CI + +if [[ "false" != "$TRAVIS_PULL_REQUEST" ]]; then + echo "Not deploying pull requests." + exit +fi + +if [[ "$TRAVIS_BRANCH" != "$DEPLOY_BRANCH" ]]; then + echo "Not on the '$DEPLOY_BRANCH' branch." + exit +fi + +# extract private key from decrypted environment variables stored in .travis.yml +echo -n $id_rsa_{00..30} >> ~/.ssh/id_rsa_base64 +base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa +chmod 600 ~/.ssh/id_rsa + +# anyone can read the build log, so it MUST NOT contain any sensitive data +set -x + +# add github's public key +echo "|1|qPmmP7LVZ7Qbpk7AylmkfR0FApQ=|WUy1WS3F4qcr3R5Sc728778goPw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts + +git clone git@github.com:wp-cli/builds.git +cd builds + +git config user.name "Travis CI" +git config user.email "travis@travis-ci.org" +git config push.default "simple" + +mv $WP_CLI_BIN_DIR/wp phar/wp-cli-nightly.phar +chmod -x phar/wp-cli-nightly.phar + +git add phar/wp-cli-nightly.phar +git commit -m "phar build: $TRAVIS_REPO_SLUG@$TRAVIS_COMMIT" + +git push From 68400d36c171a9a92202c68515e7bb744301d908 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 15 Aug 2013 18:15:34 +0300 Subject: [PATCH 2196/4858] set 'master' as the deploy branch; see #658 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 536c0f5395..f683d3af99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,12 @@ env: - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - WP_VERSION=latest - - WP_VERSION=3.4.2 DEPLOY_BRANCH=phar-builder + - WP_VERSION=3.4.2 DEPLOY_BRANCH=master matrix: exclude: - php: 5.5 - env: WP_VERSION=3.4.2 DEPLOY_BRANCH=phar-builder + env: WP_VERSION=3.4.2 DEPLOY_BRANCH=master before_script: ./bin/ci/prepare.sh From f6ab73a592cb3df16b5efb1fabfc9fec1272e7e8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 02:57:15 +0300 Subject: [PATCH 2197/4858] avoid converting iterator into array unless absolutely necessary in format_items() --- php/utils.php | 64 ++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/php/utils.php b/php/utils.php index 70f8100359..ef4c45de67 100644 --- a/php/utils.php +++ b/php/utils.php @@ -230,42 +230,30 @@ function format_items( $format, $items, $fields ) { if ( ! is_array( $fields ) ) $fields = explode( ',', $fields ); - $output_items = array(); - foreach ( $items as $item ) { - - $output_item = new \stdClass; - foreach ( $fields as $key => $field ) { - - if ( ! isset( $item->$field ) ) { - unset( $fields[$key] ); - continue; - } - - $output_item->$field = $item->$field; - } - - $output_items[] = $output_item; - } - switch ( $format ) { case 'table': $table = new \cli\Table(); $table->setHeaders( $fields ); - foreach ( $output_items as $item ) { - $table->addRow( array_values( (array)$item ) ); + foreach ( $items as $item ) { + $table->addRow( array_values( array_pick( $item, $fields ) ) ); } $table->display(); break; + case 'csv': + write_csv( STDOUT, $items, $fields ); + break; + case 'json': + $out = array(); + foreach ( $items as $item ) { + $out[] = array_pick( $item, $fields ); + } - if ( 'json' == $format ) - echo json_encode( $output_items ); - else - write_csv( STDOUT, $output_items, $fields ); + echo json_encode( $out ); break; } } @@ -278,24 +266,32 @@ function format_items( $format, $items, $fields ) { * @param array $headers List of CSV columns (optional) */ function write_csv( $fd, $rows, $headers = array() ) { - - // Prepare the headers if they were specified - if ( ! empty( $headers ) ) + if ( ! empty( $headers ) ) { fputcsv( $fd, $headers ); + } foreach ( $rows as $row ) { - $row = (array) $row; - if ( ! empty( $headers ) ) { - $build_row = array(); - foreach ( $headers as $key ) { - $build_row[] = $row[ $key ]; - } - $row = $build_row; + $row = array_pick( $row, $headers ); } - fputcsv( $fd, $row ); + + fputcsv( $fd, array_values( $row ) ); + } +} + +/** + * Like array_slice(), but for associative arrays. + */ +function array_pick( $item, $fields ) { + $item = (array) $item; + + $values = array(); + + foreach ( $fields as $field ) { + $values[ $field ] = isset( $item[ $field ] ) ? $item[ $field ] : null; } + return $values; } /** From 262245904b21fcec6962eb2728ca520a7011e146 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 03:03:55 +0300 Subject: [PATCH 2198/4858] introduce iterator_map() and avoid converting iterator to array in `wp site list` --- php/WP_CLI/Iterators/Transform.php | 26 ++++++++++++++++++++++++ php/commands/site.php | 9 ++++----- php/utils.php | 32 ++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 php/WP_CLI/Iterators/Transform.php diff --git a/php/WP_CLI/Iterators/Transform.php b/php/WP_CLI/Iterators/Transform.php new file mode 100644 index 0000000000..823e620b10 --- /dev/null +++ b/php/WP_CLI/Iterators/Transform.php @@ -0,0 +1,26 @@ +<?php + +namespace WP_CLI\Iterators; + +/** + * Aplies one or more callbacks to an item before returning it. + */ +class Transform extends \IteratorIterator { + + private $transformers = array(); + + public function add_transform( $fn ) { + $this->transformers[] = $fn; + } + + public function current() { + $value = parent::current(); + + foreach ( $this->transformers as $fn ) { + $value = $fn( $value ); + } + + return $value; + } +} + diff --git a/php/commands/site.php b/php/commands/site.php index 6da3de8c5e..954274842f 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -369,13 +369,12 @@ function _list( $_, $assoc_args ) { ); $it = new \WP_CLI\Iterators\Table( $iterator_args ); - $list = array(); - foreach ( $it as $blog ) { + $it = \WP_CLI\Utils\iterator_map( $it, function( $blog ) { $blog->url = $blog->domain . $blog->path; - $list[] = $blog; - } + return $blog; + } ); - WP_CLI\Utils\format_items( $assoc_args['format'], $list, $assoc_args['fields'] ); + WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); } } diff --git a/php/utils.php b/php/utils.php index ef4c45de67..c313ce9d60 100644 --- a/php/utils.php +++ b/php/utils.php @@ -5,6 +5,7 @@ namespace WP_CLI\Utils; use \WP_CLI\Dispatcher; +use \WP_CLI\Iterators\Transform; function load_dependencies() { $vendor_paths = array( @@ -51,6 +52,37 @@ function load_all_commands() { } } +/** + * Like array_map(), except it returns a new iterator, instead of a modified array. + * + * Example: + * + * $arr = array('Football', 'Socker'); + * + * $it = iterator_map($arr, 'strtolower', function($val) { + * return str_replace('foo', 'bar', $val); + * }); + * + * foreach ( $it as $val ) { + * var_dump($val); + * } + * + * @param array|object Either a plain array or another iterator + * @param callback The function to apply to an element + * @return object An iterator that applies the given callback(s) + */ +function iterator_map( $it, $fn ) { + if ( !is_object( $it ) || !method_exists( $it, 'add_transform' ) ) { + $it = new Transform( $it ); + } + + foreach ( array_slice( func_get_args(), 1 ) as $fn ) { + $it->add_transform( $fn ); + } + + return $it; +} + /** * Search for file by walking up the directory tree until the first file is found or until $stop_check($dir) returns true * @param string|array The files (or file) to search for From b9f16a84e0f252477ee044f63cb0dfde25a81d5f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 03:38:35 +0300 Subject: [PATCH 2199/4858] add some missing conversions to/from iterators --- php/utils.php | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/php/utils.php b/php/utils.php index c313ce9d60..70d5937a9e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -72,7 +72,11 @@ function load_all_commands() { * @return object An iterator that applies the given callback(s) */ function iterator_map( $it, $fn ) { - if ( !is_object( $it ) || !method_exists( $it, 'add_transform' ) ) { + if ( is_array( $it ) ) { + $it = new \ArrayIterator( $it ); + } + + if ( !method_exists( $it, 'add_transform' ) ) { $it = new Transform( $it ); } @@ -250,19 +254,24 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ function format_items( $format, $items, $fields ) { - - if ( 'ids' == $format ) { - echo implode( ' ', $items ); - return; - } else if ( 'count' == $format ) { - echo count( $items ); - return; - } - if ( ! is_array( $fields ) ) $fields = explode( ',', $fields ); switch ( $format ) { + case 'count': + if ( !is_array( $items ) ) { + $items = iterator_to_array( $items ); + } + echo count( $items ); + break; + + case 'ids': + if ( !is_array( $items ) ) { + $items = iterator_to_array( $items ); + } + echo implode( ' ', $items ); + break; + case 'table': $table = new \cli\Table(); From 17487544aa9decfc2d5484b0510d5ae364df4a00 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 03:39:22 +0300 Subject: [PATCH 2200/4858] convert user object to array using its to_array() method --- php/commands/user.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index c14108df52..3f8169287b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -66,13 +66,17 @@ public function _list( $args, $assoc_args ) { $users = get_users( $params ); - if ( 'ids' != $params['format'] ) { - foreach ( $users as $user ) { - $user->roles = implode( ',', $user->roles ); - } - } + $it = WP_CLI\Utils\iterator_map( $users, function ( $user ) { + if ( !is_object( $user ) ) + return $user; + + $new_user = $user->to_array(); + $new_user['roles'] = implode( ',', $user->roles ); + + return $new_user; + } ); - WP_CLI\Utils\format_items( $params['format'], $users, $fields ); + WP_CLI\Utils\format_items( $params['format'], $it, $fields ); } /** From ae1d08bf2b4a3536f2f259444a9d0fbaf32290fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 03:52:30 +0300 Subject: [PATCH 2201/4858] cast arrays to objects instead of the other way around the advantage is that objects that have magic methods don't need special handling --- php/commands/user.php | 5 ++--- php/utils.php | 18 +++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 3f8169287b..3e8bcd4154 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -70,10 +70,9 @@ public function _list( $args, $assoc_args ) { if ( !is_object( $user ) ) return $user; - $new_user = $user->to_array(); - $new_user['roles'] = implode( ',', $user->roles ); + $user->roles = implode( ',', $user->roles ); - return $new_user; + return $user; } ); WP_CLI\Utils\format_items( $params['format'], $it, $fields ); diff --git a/php/utils.php b/php/utils.php index 70d5937a9e..9c9450427c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -278,7 +278,7 @@ function format_items( $format, $items, $fields ) { $table->setHeaders( $fields ); foreach ( $items as $item ) { - $table->addRow( array_values( array_pick( $item, $fields ) ) ); + $table->addRow( array_values( pick_fields( $item, $fields ) ) ); } $table->display(); @@ -291,7 +291,7 @@ function format_items( $format, $items, $fields ) { case 'json': $out = array(); foreach ( $items as $item ) { - $out[] = array_pick( $item, $fields ); + $out[] = pick_fields( $item, $fields ); } echo json_encode( $out ); @@ -313,7 +313,7 @@ function write_csv( $fd, $rows, $headers = array() ) { foreach ( $rows as $row ) { if ( ! empty( $headers ) ) { - $row = array_pick( $row, $headers ); + $row = pick_fields( $row, $headers ); } fputcsv( $fd, array_values( $row ) ); @@ -321,15 +321,19 @@ function write_csv( $fd, $rows, $headers = array() ) { } /** - * Like array_slice(), but for associative arrays. + * Pick fields from an associative array or object. + * + * @param array|object Associative array or object to pick fields from + * @param array List of fields to pick + * @return array */ -function array_pick( $item, $fields ) { - $item = (array) $item; +function pick_fields( $item, $fields ) { + $item = (object) $item; $values = array(); foreach ( $fields as $field ) { - $values[ $field ] = isset( $item[ $field ] ) ? $item[ $field ] : null; + $values[ $field ] = isset( $item->$field ) ? $item->$field : null; } return $values; From 6bb30cc36a960ad900cb08f862460d0c75b6e026 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 18:09:27 +0300 Subject: [PATCH 2202/4858] make wp.bat executable --- bin/wp.bat | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/wp.bat diff --git a/bin/wp.bat b/bin/wp.bat old mode 100644 new mode 100755 From 5e240f3ea3b38899beace7166215387d8830ad8b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 18:11:30 +0300 Subject: [PATCH 2203/4858] always use bundled autoload in Phar file see #658 --- composer.json | 3 ++- php/utils.php | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 8e1c9f77c8..91247c46fc 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "psy/psysh": "Enhanced `wp shell` functionality" }, "autoload": { - "psr-0": { "WP_CLI": "php" } + "psr-0": { "WP_CLI": "php" }, + "files": [ "php/Spyc.php" ] }, "require-dev": { "symfony/finder": "~2.3" diff --git a/php/utils.php b/php/utils.php index 9c9450427c..7db1d122cf 100644 --- a/php/utils.php +++ b/php/utils.php @@ -8,6 +8,11 @@ use \WP_CLI\Iterators\Transform; function load_dependencies() { + if ( 0 === strpos( WP_CLI_ROOT, 'phar:' ) ) { + require WP_CLI_ROOT . '/vendor/autoload.php'; + return; + } + $vendor_paths = array( WP_CLI_ROOT . '/../../../vendor', // part of a larger project / installed via Composer (preferred) WP_CLI_ROOT . '/vendor', // top-level project / installed as Git clone @@ -27,8 +32,6 @@ function load_dependencies() { fputs( STDERR, "Internal error: Can't find Composer autoloader.\n" ); exit(3); } - - include WP_CLI_ROOT . '/php/Spyc.php'; } function load_command( $name ) { From 7bd05bacaf1d92172fe8f1f9c5a97b3b06119da2 Mon Sep 17 00:00:00 2001 From: mattes <matthias.kadenbach@gmail.com> Date: Fri, 16 Aug 2013 19:20:01 +0200 Subject: [PATCH 2204/4858] fixed bug, when having a port number in host --- php/commands/db.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 66ed93d506..fc04951e7e 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -119,9 +119,17 @@ function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( 'mysqldump', Utils\esc_cmd( - '%s --user=%s --host=%s --result-file %s', - DB_NAME, DB_USER, DB_HOST, $result_file ) ); + if( strpos( DB_HOST, ':' ) !== false ) { + // extract port from host + $DB_HOST = preg_split("/:/", DB_HOST); + self::run( 'mysqldump', Utils\esc_cmd( + '%s --user=%s --host=%s --port=%s --result-file %s', + DB_NAME, DB_USER, $DB_HOST[0], $DB_HOST[1], $result_file ) ); + } else { + self::run( 'mysqldump', Utils\esc_cmd( + '%s --user=%s --host=%s --result-file %s', + DB_NAME, DB_USER, DB_HOST, $result_file ) ); + } WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } From e78c3abc194f9866b77b21cdc28b9df5e8cce2de Mon Sep 17 00:00:00 2001 From: mattes <matthias.kadenbach@gmail.com> Date: Fri, 16 Aug 2013 19:45:30 +0200 Subject: [PATCH 2205/4858] adding support for sockets --- php/commands/db.php | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index fc04951e7e..e126ec8839 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -119,17 +119,29 @@ function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - if( strpos( DB_HOST, ':' ) !== false ) { - // extract port from host - $DB_HOST = preg_split("/:/", DB_HOST); - self::run( 'mysqldump', Utils\esc_cmd( - '%s --user=%s --host=%s --port=%s --result-file %s', - DB_NAME, DB_USER, $DB_HOST[0], $DB_HOST[1], $result_file ) ); - } else { - self::run( 'mysqldump', Utils\esc_cmd( - '%s --user=%s --host=%s --result-file %s', - DB_NAME, DB_USER, DB_HOST, $result_file ) ); - } + $host_parts = explode( ':', DB_HOST ); + if ( count( $host_parts ) == 2 ) { + list( $host, $extra ) = $host_parts; + } else { + $host = DB_HOST; + } + + $arg_str = ''; + + if ( isset( $extra ) ) { + if ( is_numeric($extra) ) { + $arg_str .= Utils\esc_cmd( + '--port=%s --protocol=%s', intval( $extra ), 'tcp' ); + } else if ( trim($extra) !== '' ) { + $arg_str .= Utils\esc_cmd( + '--socket=%s', trim( $extra ) ); + } + } + + $arg_str .= Utils\esc_cmd( ' --host=%s --user=%s --result-file=%s %s', + $host, DB_USER, $result_file, DB_NAME ); + + self::run( 'mysqldump', $arg_str ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } From f50f84118ad753c42175310d164c547a338437a6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 21:34:19 +0300 Subject: [PATCH 2206/4858] pass MYSQL_PWD to proc_open(), instead of altering the current environment --- php/utils.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/utils.php b/php/utils.php index 7db1d122cf..b3e02b3418 100644 --- a/php/utils.php +++ b/php/utils.php @@ -395,13 +395,13 @@ function run_mysql_query( $query, $args ) { } function run_mysql_command( $cmd, $arg_str, $pass ) { - $old_val = getenv( 'MYSQL_PWD' ); - $final_cmd = "$cmd --no-defaults $arg_str"; - putenv( 'MYSQL_PWD=' . $pass ); - $r = proc_close( proc_open( $final_cmd, array( STDIN, STDOUT, STDERR ), $pipes ) ); - putenv( 'MYSQL_PWD=' . $old_val ); + $descriptors = array( STDIN, STDOUT, STDERR ); + + $r = proc_close( proc_open( $final_cmd, $descriptors, $pipes, null, array( + 'MYSQL_PWD' => $pass + ) ) ); if ( $r ) exit( $r ); } From a9f7b7c76d6e22f38ae922efa86de13f03324c63 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 23:24:15 +0300 Subject: [PATCH 2207/4858] Refactor MySQL utilities: * extract mysql_host_to_cli_args() helper * make run_mysql_command() accept an associative array of args * remove redundant run_mysql_query() utility --- features/bootstrap/FeatureContext.php | 3 +- php/commands/core.php | 6 ++- php/commands/db.php | 78 ++++++++++++--------------- php/utils.php | 68 +++++++++++++---------- 4 files changed, 81 insertions(+), 74 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 4c5def0e8c..fc3a15c511 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -113,7 +113,8 @@ private function set_cache_dir() { } private static function run_sql( $sql ) { - Utils\run_mysql_query( $sql, array( + Utils\run_mysql_command( 'mysql --no-defaults', array( + 'execute' => $sql, 'host' => 'localhost', 'user' => self::$db_settings['dbuser'], 'pass' => self::$db_settings['dbpass'], diff --git a/php/commands/core.php b/php/commands/core.php index 81762a63e3..5dc62c925c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -184,7 +184,8 @@ public function config( $_, $assoc_args ) { WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); // Check DB connection - Utils\run_mysql_query( ';', array( + Utils\run_mysql_command( 'mysql --no-defaults', array( + 'execute' => ';', 'host' => $assoc_args['dbhost'], 'user' => $assoc_args['dbuser'], 'pass' => $assoc_args['dbpass'], @@ -699,7 +700,8 @@ function init_tests( $args, $assoc_args ) { // Create the database $query = sprintf( 'CREATE DATABASE IF NOT EXISTS `%s`', $assoc_args['dbname'] ); - Utils\run_mysql_query( $query, array( + Utils\run_mysql_command( 'mysql --no-defaults', array( + 'execute' => $query, 'host' => $assoc_args['dbhost'], 'user' => $assoc_args['dbuser'], 'pass' => $assoc_args['dbpass'], diff --git a/php/commands/db.php b/php/commands/db.php index e126ec8839..0f2be91f27 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -63,9 +63,8 @@ function reset( $_, $assoc_args ) { * Optimize the database. */ function optimize() { - self::run( 'mysqlcheck', Utils\esc_cmd( - '--optimize --host=%s --user=%s %s', - DB_HOST, DB_USER, DB_NAME + self::run( Utils\esc_cmd( 'mysqlcheck %s', DB_NAME ), array( + 'optimize' => true, ) ); WP_CLI::success( "Database optimized." ); @@ -75,9 +74,9 @@ function optimize() { * Repair the database. */ function repair() { - self::run( 'mysqlcheck', Utils\esc_cmd( - '--repair --host=%s --user=%s %s', - DB_HOST, DB_USER, DB_NAME ) ); + self::run( Utils\esc_cmd( 'mysqlcheck %s', DB_NAME ), array( + 'repair' => true, + ) ); WP_CLI::success( "Database repaired." ); } @@ -88,9 +87,9 @@ function repair() { * @alias connect */ function cli() { - self::run( 'mysql', Utils\esc_cmd( - '--host=%s --user=%s --database=%s', - DB_HOST, DB_USER, DB_NAME ) ); + self::run( 'mysql --no-defaults', array( + 'database' => DB_NAME + ) ); } /** @@ -99,14 +98,16 @@ function cli() { * @synopsis [<sql>] */ function query( $args ) { - $cmd = '--host=%s --user=%s --database=%s'; - $cmd = Utils\esc_cmd( $cmd, DB_HOST, DB_USER, DB_NAME ); + $assoc_args = array( + 'database' => DB_NAME + ); + // The query might come from STDIN if ( !empty( $args ) ) { - $cmd .= Utils\esc_cmd( ' --execute=%s', $args[0] ); + $assoc_args['execute'] = $args[0]; } - self::run( 'mysql', $cmd ); + self::run( 'mysql --no-defaults', $assoc_args ); } /** @@ -119,29 +120,9 @@ function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - $host_parts = explode( ':', DB_HOST ); - if ( count( $host_parts ) == 2 ) { - list( $host, $extra ) = $host_parts; - } else { - $host = DB_HOST; - } - - $arg_str = ''; - - if ( isset( $extra ) ) { - if ( is_numeric($extra) ) { - $arg_str .= Utils\esc_cmd( - '--port=%s --protocol=%s', intval( $extra ), 'tcp' ); - } else if ( trim($extra) !== '' ) { - $arg_str .= Utils\esc_cmd( - '--socket=%s', trim( $extra ) ); - } - } - - $arg_str .= Utils\esc_cmd( ' --host=%s --user=%s --result-file=%s %s', - $host, DB_USER, $result_file, DB_NAME ); - - self::run( 'mysqldump', $arg_str ); + self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), array( + 'result-file' => $result_file + ) ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } @@ -153,10 +134,19 @@ function export( $args, $assoc_args ) { */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); + if ( !file_exists( $result_file ) ) { + WP_CLI::error( sprintf( 'Import file missing: %s', $result_file ) ); + } + + $descriptors = array( + array( 'file', $result_file, 'r' ), + STDOUT, + STDERR, + ); - self::run( 'mysql', Utils\esc_cmd( - '%s --user=%s --host=%s < %s', - DB_NAME, DB_USER, DB_HOST, $result_file ) ); + self::run( 'mysql --no-defaults', array( + 'database' => DB_NAME + ), $descriptors ); WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } @@ -169,15 +159,17 @@ private function get_file_name( $args ) { } private static function run_query( $query ) { - Utils\run_mysql_query( $query, array( + self::run( 'mysql --no-defaults', array( 'execute' => $query ) ); + } + + private static function run( $cmd, $assoc_args = array(), $descriptors = null ) { + $final_args = array_merge( $assoc_args, array( 'host' => DB_HOST, 'user' => DB_USER, 'pass' => DB_PASSWORD, ) ); - } - private static function run( $cmd, $args ) { - Utils\run_mysql_command( $cmd, $args, DB_PASSWORD ); + Utils\run_mysql_command( $cmd, $final_args, $descriptors ); } } diff --git a/php/utils.php b/php/utils.php index b3e02b3418..5606b02a42 100644 --- a/php/utils.php +++ b/php/utils.php @@ -370,38 +370,50 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { return $output; } -function run_mysql_query( $query, $args ) { - // TODO: use PDO? - - $host_parts = explode( ':', $args['host'] ); - if ( count( $host_parts ) == 2 ) { - list( $host, $extra ) = $host_parts; - } else { - $host = $args['host']; - } - - $arg_str = esc_cmd( '--host=%s --user=%s --execute=%s', - $host, $args['user'], $query ); - - if ( isset( $extra ) ) { - if ( is_numeric($extra) ) { - $arg_str .= esc_cmd( ' --port=%s --protocol=%s', intval( $extra ), 'tcp' ); - } else if ( trim($extra) !== '' ) { - $arg_str .= esc_cmd( ' --socket=%s', trim( $extra ) ); - } - } - - run_mysql_command( 'mysql', $arg_str, $args['pass'] ); +/** + * @param string MySQL host string, as defined in wp-config.php + * @return array + */ +function mysql_host_to_cli_args( $raw_host ) { + $assoc_args = array(); + + $host_parts = explode( ':', $raw_host ); + if ( count( $host_parts ) == 2 ) { + list( $assoc_args['host'], $extra ) = $host_parts; + if ( is_numeric($extra) ) { + $assoc_args['port'] = intval( $extra ); + $assoc_args['protocol'] = 'tcp'; + } else if ( trim($extra) !== '' ) { + $assoc_args['socket'] = trim( $extra ); + } + } else { + $assoc_args['host'] = $raw_host; + } + + return $assoc_args; } -function run_mysql_command( $cmd, $arg_str, $pass ) { - $final_cmd = "$cmd --no-defaults $arg_str"; +function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { + if ( !$descriptors ) + $descriptors = array( STDIN, STDOUT, STDERR ); + + if ( isset( $assoc_args['host'] ) ) { + $assoc_args = array_merge( $assoc_args, mysql_host_to_cli_args( $assoc_args['host'] ) ); + } + + $env = array(); + if ( isset( $assoc_args['pass'] ) ) { + $env['MYSQL_PWD'] = $assoc_args['pass']; + unset( $assoc_args['pass'] ); + } + + $final_cmd = $cmd . assoc_args_to_str( $assoc_args ); - $descriptors = array( STDIN, STDOUT, STDERR ); + $proc = proc_open( $final_cmd, $descriptors, $pipes, null, $env ); + if ( !$proc ) + exit(1); - $r = proc_close( proc_open( $final_cmd, $descriptors, $pipes, null, array( - 'MYSQL_PWD' => $pass - ) ) ); + $r = proc_close( $proc ); if ( $r ) exit( $r ); } From bc27bb4a025f2f966485ababaf7ff82ea79e75ed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 16 Aug 2013 23:45:18 +0300 Subject: [PATCH 2208/4858] minor cleanup in mysql_host_to_cli_args() --- php/utils.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 5606b02a42..125bd969cd 100644 --- a/php/utils.php +++ b/php/utils.php @@ -380,11 +380,12 @@ function mysql_host_to_cli_args( $raw_host ) { $host_parts = explode( ':', $raw_host ); if ( count( $host_parts ) == 2 ) { list( $assoc_args['host'], $extra ) = $host_parts; - if ( is_numeric($extra) ) { + $extra = trim( $extra ); + if ( is_numeric( $extra ) ) { $assoc_args['port'] = intval( $extra ); $assoc_args['protocol'] = 'tcp'; - } else if ( trim($extra) !== '' ) { - $assoc_args['socket'] = trim( $extra ); + } else if ( $extra !== '' ) { + $assoc_args['socket'] = $extra; } } else { $assoc_args['host'] = $raw_host; From 5e9414f982fbf369ee0daa8b3a98ee789099313e Mon Sep 17 00:00:00 2001 From: Nikolay Kolev <nikolay@users.noreply.github.com> Date: Mon, 19 Aug 2013 13:11:16 -0700 Subject: [PATCH 2209/4858] Allows passing existing keys and salts vs generating afresh In a multi-server environment, if you want a consistent configuration without having to patch the automatically generated wp-config.php, there should be a way to pass the common keys and salts. --- php/commands/core.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 5dc62c925c..d26f0e02c4 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -153,6 +153,9 @@ private static function get_initial_locale() { * * --extra-php * : If set, the command reads additional PHP code from STDIN. + * + * --keys-and-salts + * : Use existing secrets versus generating afresh as the default behavior. * * ## EXAMPLES * @@ -196,9 +199,10 @@ public function config( $_, $assoc_args ) { } // TODO: adapt more resilient code from wp-admin/setup-config.php - - $assoc_args['keys-and-salts'] = self::_read( - 'https://api.wordpress.org/secret-key/1.1/salt/' ); + if ( ! isset( $assoc_args['keys-and-salts'] ) ) { + $assoc_args['keys-and-salts'] = self::_read( + 'https://api.wordpress.org/secret-key/1.1/salt/' ); + } $out = Utils\mustache_render( 'wp-config.mustache', $assoc_args ); file_put_contents( ABSPATH . 'wp-config.php', $out ); From 7a9db01d6941953a11e6e6c07e5c7459523da63f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 18 Aug 2013 07:49:33 -0700 Subject: [PATCH 2210/4858] Support for global `wp-cli.yml` and `wp-cli.local.yml` configs --- php/WP_CLI/Runner.php | 10 ++++++++++ php/utils.php | 14 ++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8e5931645f..4c09fe8189 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -62,6 +62,16 @@ private static function get_config_path( $runtime_config ) { return $path; } + // See if there is a global config file specified in the Composer + // install directory + foreach( $config_files as $config_file ) { + foreach( WP_CLI\Utils\get_vendor_paths() as $vendor_path ) { + $config_path = dirname( $vendor_path ) . '/' . $config_file; + if ( file_exists( $config_path ) ) + return $config_path; + } + } + return false; } diff --git a/php/utils.php b/php/utils.php index 125bd969cd..926429a40f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -13,14 +13,9 @@ function load_dependencies() { return; } - $vendor_paths = array( - WP_CLI_ROOT . '/../../../vendor', // part of a larger project / installed via Composer (preferred) - WP_CLI_ROOT . '/vendor', // top-level project / installed as Git clone - ); - $has_autoload = false; - foreach ( $vendor_paths as $vendor_path ) { + foreach ( get_vendor_paths() as $vendor_path ) { if ( file_exists( $vendor_path . '/autoload.php' ) ) { require $vendor_path . '/autoload.php'; $has_autoload = true; @@ -34,6 +29,13 @@ function load_dependencies() { } } +function get_vendor_paths() { + return array( + WP_CLI_ROOT . '/../../../vendor', // part of a larger project / installed via Composer (preferred) + WP_CLI_ROOT . '/vendor', // top-level project / installed as Git clone + ); +} + function load_command( $name ) { $path = WP_CLI_ROOT . "/php/commands/$name.php"; From a85a0c50a2d73d486dd49594fd880c3fd7c204e8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 15:33:44 -0700 Subject: [PATCH 2211/4858] A helper method to prompt the user for some detail --- php/class-wp-cli.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index da3a32be62..6d907f3f71 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -164,6 +164,25 @@ static function confirm( $question, $assoc_args = array() ) { } } + /** + * Prompt a user for some input + */ + static function prompt( $question, $required = false ) { + + do { + + self::out( $question . ': ' ); + + $response = trim( fgets( STDIN ) ); + if ( $required && $response ) + $required = false; + + } while( $required ); + + return $response; + } + + /** * Read a value, from various formats * From 13a61d7edbc52ac824ab9ddb983405afe4bf92da Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 15:34:19 -0700 Subject: [PATCH 2212/4858] If the `--prompt` arg is specified, prompt the user for arguments --- php/WP_CLI/Dispatcher/Subcommand.php | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 45be83bd01..6834bb313b 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -36,6 +36,31 @@ function show_usage( $prefix = 'usage: ' ) { ) ); } + private function prompt_args( $args, $assoc_args ) { + + $synopsis = $this->get_synopsis(); + + if ( ! $synopsis ) + return array( $args, $assoc_args ); + + $spec = array_filter( \WP_CLI\SynopsisParser::parse( $synopsis ), function( $spec_arg ) { + return in_array( $spec_arg['type'], array( 'positional', 'assoc' ) ); + }); + + $spec = array_values( $spec ); + + foreach( $spec as $key => $spec_arg ) { + + $required = ! $spec_arg['optional']; + $prompt = ( $key + 1 ) . '/' . count( $spec ) . ' ' . $spec_arg['token']; + $response = \WP_CLI::prompt( $prompt, $required ); + if ( $response ) + $assoc_args[$spec_arg['name']] = $response; + } + + return array( $args, $assoc_args ); + } + private function validate_args( $args, &$assoc_args ) { $synopsis = $this->get_synopsis(); @@ -76,6 +101,10 @@ private function validate_args( $args, &$assoc_args ) { } function invoke( $args, $assoc_args ) { + + if ( ! empty( $assoc_args['prompt'] ) ) + list( $args, $assoc_args ) = $this->prompt_args( $args, $assoc_args ); + $this->validate_args( $args, $assoc_args ); \WP_CLI::do_action( 'before_invoke:' . $this->get_parent()->get_name() ); From 4579bbcdb53c53f0c6e31956e555e73a1959cf47 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 20 Aug 2013 01:41:51 +0300 Subject: [PATCH 2213/4858] add test for assoc arg with optional value --- tests/test-arg-validation.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test-arg-validation.php b/tests/test-arg-validation.php index f579823c58..e1c74b822a 100644 --- a/tests/test-arg-validation.php +++ b/tests/test-arg-validation.php @@ -46,5 +46,15 @@ function testMissingAssoc() { $this->assertCount( 1, $errors['fatal'] ); $this->assertCount( 1, $errors['warning'] ); } + + function testAssocWithOptionalValue() { + $parser = new SynopsisValidator( '[--network[=<id>]]' ); + + $assoc_args = array( 'network' => true ); + $errors = $parser->validate_assoc( $assoc_args ); + + $this->assertCount( 0, $errors['fatal'] ); + $this->assertCount( 0, $errors['warning'] ); + } } From 7bd41b7880f70c9deca692d6ea446e74a8e4b8f9 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 1 Aug 2013 23:12:55 +0200 Subject: [PATCH 2214/4858] Exclude assoc args with that have an optional value from being unset An assoc args with an option value shouldn't trigger the message "--foo parameter needs a value". Because it doesn't needs a value. Else it would defeat the whole purpose of having `--foo[=<bar>]`. It needs to be available within the command so you can still do something with it. --- php/WP_CLI/SynopsisValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index 90a7cb8773..bee3f1920c 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -50,7 +50,7 @@ public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { $errors['fatal'][] = "missing --$key parameter"; } } else { - if ( true === $assoc_args[ $key ] ) { + if ( true === $assoc_args[ $key ] && !$param['value']['optional'] ) { $error_type = ( !$param['optional'] ) ? 'fatal' : 'warning'; $errors[ $error_type ][] = "--$key parameter needs a value"; From 49f5105b53a99c21a155ce420f6304abee27fd66 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 15:52:45 -0700 Subject: [PATCH 2215/4858] Register `--prompt` as a global argument Doing so is more correct, and avoids this warning: ``` Warning: unknown --prompt parameter ``` --- php/WP_CLI/Dispatcher/Subcommand.php | 12 +++++++++++- php/WP_CLI/Runner.php | 9 +++++++++ php/config-spec.php | 7 +++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 6834bb313b..6b6ceb24c0 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -11,6 +11,8 @@ class Subcommand extends CompositeCommand { private $when_invoked; + private $prompt = false; + function __construct( $parent, $name, $docparser, $when_invoked ) { $this->when_invoked = $when_invoked; @@ -28,6 +30,14 @@ function get_alias() { return $this->alias; } + function set_prompt( $value ) { + $this->prompt = (bool)$value; + } + + function get_prompt() { + return $this->prompt; + } + function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( sprintf( "%s%s %s", $prefix, @@ -102,7 +112,7 @@ private function validate_args( $args, &$assoc_args ) { function invoke( $args, $assoc_args ) { - if ( ! empty( $assoc_args['prompt'] ) ) + if ( $this->get_prompt() ) list( $args, $assoc_args ) = $this->prompt_args( $args, $assoc_args ); $this->validate_args( $args, $assoc_args ); diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8e5931645f..d176181828 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -436,6 +436,15 @@ public function before_wp_load() { self::set_url_params( $url_parts ); } + // Handle --prompt parameter + if ( $this->config['prompt'] ) { + $r = $this->find_command_to_run( $this->arguments ); + if ( is_array( $r ) ) { + list( $command ) = $r; + $command->set_prompt( true ); + } + } + $this->do_early_invoke( 'before_wp_load' ); $this->check_wp_version(); diff --git a/php/config-spec.php b/php/config-spec.php index a2f174769b..8504d7890e 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -57,6 +57,13 @@ 'desc' => 'Show all PHP errors', ), + 'prompt' => array( + 'runtime' => '', + 'file' => false, + 'default' => false, + 'desc' => 'Prompt the user to enter values for all command arguments', + ), + 'quiet' => array( 'runtime' => '', 'file' => '<bool>', From a14b7b575aba23f7a7acb101d5ca9fa9589ec7dc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 16:46:11 -0700 Subject: [PATCH 2216/4858] Properly set positional arguments --- php/WP_CLI/Dispatcher/Subcommand.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 6b6ceb24c0..c784d5eb3c 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -59,13 +59,24 @@ private function prompt_args( $args, $assoc_args ) { $spec = array_values( $spec ); + // 'positional' arguments are positional (aka zero-indexed) + // so $args needs to be reset before prompting for new arguments + $args = array(); foreach( $spec as $key => $spec_arg ) { $required = ! $spec_arg['optional']; $prompt = ( $key + 1 ) . '/' . count( $spec ) . ' ' . $spec_arg['token']; $response = \WP_CLI::prompt( $prompt, $required ); - if ( $response ) - $assoc_args[$spec_arg['name']] = $response; + if ( $response ) { + switch ( $spec_arg['type'] ) { + case 'positional': + $args[] = $response; + break; + case 'assoc': + $assoc_args[$spec_arg['name']] = $response; + break; + } + } } return array( $args, $assoc_args ); From ca3efb7a29939a3f2313366a8a90b099cd5d2487 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 16:58:55 -0700 Subject: [PATCH 2217/4858] Fix synopsis order Make it consistent with other core commands. --- php/commands/post.php | 4 ++-- php/commands/user.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 22e09078f0..c0c37a25e6 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -141,7 +141,7 @@ protected function _edit( $content, $title ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the post to get. * * --format=<format> @@ -160,7 +160,7 @@ protected function _edit( $content, $title ) { * * wp post get 12 > file.txt * - * @synopsis [--format=<format>] <ID> + * @synopsis <id> [--format=<format>] */ public function get( $args, $assoc_args ) { $defaults = array( diff --git a/php/commands/user.php b/php/commands/user.php index 3e8bcd4154..cf3d95624c 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -99,7 +99,7 @@ public function _list( $args, $assoc_args ) { * * wp user get bob --format=json > bob.json * - * @synopsis [--format=<format>] <user> + * @synopsis <user> [--format=<format>] */ public function get( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( From a3bffb472147b889434441ac8f7f36aff644dc34 Mon Sep 17 00:00:00 2001 From: Nikolay Kolev <nikolay@users.noreply.github.com> Date: Mon, 19 Aug 2013 18:37:42 -0700 Subject: [PATCH 2218/4858] Switched from --keys-and-salts="..." option to --skip-salts based on @scribu and @danielbachhuber proposal --- php/commands/core.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index d26f0e02c4..988231cb46 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -154,8 +154,8 @@ private static function get_initial_locale() { * --extra-php * : If set, the command reads additional PHP code from STDIN. * - * --keys-and-salts - * : Use existing secrets versus generating afresh as the default behavior. + * --skip-salts + * : If set, keys and salts won't be generated, but, instead, should be passed via --extra-php. * * ## EXAMPLES * @@ -168,7 +168,7 @@ private static function get_initial_locale() { * define( 'WP_DEBUG_LOG', true ); * PHP * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] [--skip-satls] */ public function config( $_, $assoc_args ) { if ( Utils\locate_wp_config() ) { @@ -199,7 +199,7 @@ public function config( $_, $assoc_args ) { } // TODO: adapt more resilient code from wp-admin/setup-config.php - if ( ! isset( $assoc_args['keys-and-salts'] ) ) { + if ( ! isset( $assoc_args['skip-salts'] ) ) { $assoc_args['keys-and-salts'] = self::_read( 'https://api.wordpress.org/secret-key/1.1/salt/' ); } From 93f2e481fc96f41d89e5aa44eadf7d77c27ae39a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 22:12:24 -0700 Subject: [PATCH 2219/4858] This should explicitly be a public method. --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 9adcce6edd..b2cbc27979 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -156,7 +156,7 @@ private function is_active_theme( $theme ) { * * @synopsis [<theme>] [--dir] */ - function path( $args, $assoc_args ) { + public function path( $args, $assoc_args ) { if ( empty( $args ) ) { $path = WP_CONTENT_DIR . '/themes'; } else { From 0fa67448ba69b92dc0a70c7a5b76e638a2b5a918 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 22:24:03 -0700 Subject: [PATCH 2220/4858] A functional test for `wp theme path` --- features/theme.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index a42199f48c..4231fc5df0 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -68,3 +68,15 @@ Feature: Manage WordPress themes Then STDOUT should be a table containing rows: | name | status | update | version | | p2 | active | available | 1.4.1 | + + Scenario: Get the path of an installed theme + Given a WP install + + When I run `wp theme install twentyeleven` + Then STDOUT should not be empty + + When I run `wp theme path twentyeleven --dir` + Then STDOUT should contain: + """ + wp-content/themes/twentyeleven + """ From f3c5d482d381360c88019ef2fdfb7a57f79ee921 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 22:26:06 -0700 Subject: [PATCH 2221/4858] Clarification on what this command actually does --- php/commands/theme.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index b2cbc27979..4a3c0981e7 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -143,12 +143,12 @@ private function is_active_theme( $theme ) { * ## OPTIONS * * <theme> - * : The theme to get the path to. If not set, will return the path to the - * themes directory. + * : The theme to get the path to. Path includes "style.css" file. + * If not set, will return the path to the themes directory. * * --dir * : If set, get the path to the closest parent directory, instead of the - * theme file. + * theme's "style.css" file. * * ## EXAMPLES * From 460af3f1035958f410f2744813efcc94bb0eb299 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 22:57:01 -0700 Subject: [PATCH 2222/4858] Implement `wp theme get` --- features/theme.feature | 11 +++++++++ php/commands/theme.php | 56 ++++++++++++++++++++++++++++++++++++++++++ php/utils.php | 22 +++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index a42199f48c..9aa1d8b5ba 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -68,3 +68,14 @@ Feature: Manage WordPress themes Then STDOUT should be a table containing rows: | name | status | update | version | | p2 | active | available | 1.4.1 | + + Scenario: Get details about an installed theme + Given a WP install + + When I run `wp theme install twentyeleven` + Then STDOUT should not be empty + + When I run `wp theme get twentyeleven` + Then STDOUT should be a table containing rows: + | Field | Value | + | name | Twenty Eleven | diff --git a/php/commands/theme.php b/php/commands/theme.php index 9adcce6edd..87ce9cccc2 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -249,6 +249,62 @@ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); } + /** + * Get a theme + * + * ## OPTIONS + * + * <theme> + * : The theme to get. + * + * * --format=<format> + * : The format to use when printing the theme, acceptable values: + * + * - **table**: Outputs all fields of the theme as a table. + * + * - **json**: Outputs all fields in JSON format. + * + * ## EXAMPLES + * + * wp theme get twentytwelve + * + * @synopsis <theme> [--format=<format>] + */ + public function get( $args, $assoc_args ) { + + $defaults = array( + 'format' => 'table' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $theme = $this->parse_name( $args[0] ); + + // WP_Theme object employs magic getter, unfortunately + $theme_vars = array( 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', + ); + $theme_obj = new stdClass; + foreach( $theme_vars as $var ) { + $theme_obj->$var = $theme->$var; + } + + switch ( $assoc_args['format'] ) { + + case 'table': + unset( $theme_obj->tags ); + $fields = get_object_vars( $theme_obj ); + \WP_CLI\Utils\assoc_array_to_table( $fields ); + break; + + case 'json': + WP_CLI::print_value( $theme_obj, $assoc_args ); + break; + + default: + \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); + break; + } + } + /** * Update a theme. * diff --git a/php/utils.php b/php/utils.php index 125bd969cd..1b3b1a6ce0 100644 --- a/php/utils.php +++ b/php/utils.php @@ -302,6 +302,28 @@ function format_items( $format, $items, $fields ) { } } +/** + * Format an associative array as a table + * + * @param array $fields Fields and values to format + */ +function assoc_array_to_table( $fields ) { + $rows = array(); + + foreach ( $fields as $field => $value ) { + if ( !is_string($value) ) { + $value = json_encode( $value ); + } + + $rows[] = (object) array( + 'Field' => $field, + 'Value' => $value + ); + } + + format_items( 'table', $rows, array( 'Field', 'Value' ) ); +} + /** * Write data as CSV to a given file. * From 4ac027e3e23be2ed653fb6b79efd520dbb9a6acf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 23:08:13 -0700 Subject: [PATCH 2223/4858] Use P2 for tests instead, which won't fatal 3.4 (twentyeleven is already installed) --- features/theme.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 9aa1d8b5ba..f09a44d92a 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -72,10 +72,10 @@ Feature: Manage WordPress themes Scenario: Get details about an installed theme Given a WP install - When I run `wp theme install twentyeleven` + When I run `wp theme install p2` Then STDOUT should not be empty - When I run `wp theme get twentyeleven` + When I run `wp theme get p2` Then STDOUT should be a table containing rows: | Field | Value | - | name | Twenty Eleven | + | name | P2 | From f669861408e412449e55b9e1efa7d5e0f0bd9c86 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 Aug 2013 07:13:30 -0700 Subject: [PATCH 2224/4858] Use P2, which isn't conditionally present in some WordPress installs --- features/theme.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index e01b40d19d..c05ecd0f25 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -72,13 +72,13 @@ Feature: Manage WordPress themes Scenario: Get the path of an installed theme Given a WP install - When I run `wp theme install twentyeleven` + When I run `wp theme install p2` Then STDOUT should not be empty - When I run `wp theme path twentyeleven --dir` + When I run `wp theme path p2 --dir` Then STDOUT should contain: """ - wp-content/themes/twentyeleven + wp-content/themes/p2 """ Scenario: Get details about an installed theme From 5eb3c0824bd8b0d7b2226a6f46c4ab42ce7e4ef6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 23:02:36 -0700 Subject: [PATCH 2225/4858] Implement `wp comment get` --- php/commands/comment.php | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/php/commands/comment.php b/php/commands/comment.php index a5b696ae9a..dd74730139 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -43,6 +43,56 @@ public function create( $args, $assoc_args ) { WP_CLI::success( "Inserted comment $comment_id." ); } + /** + * Get a comment + * + * ## OPTIONS + * + * <id> + * : The comment to get. + * + * * --format=<format> + * : The format to use when printing the comment, acceptable values: + * + * - **table**: Outputs all fields of the comment as a table. + * + * - **json**: Outputs all fields in JSON format. + * + * ## EXAMPLES + * + * wp comment get 1 + * + * @synopsis <id> [--format=<format>] + */ + public function get( $args, $assoc_args ) { + + $defaults = array( + 'format' => 'table' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $comment_id = (int)$args[0]; + $comment = get_comment( $comment_id ); + if ( empty( $comment ) ) + WP_CLI::error( "Invalid comment ID." ); + + switch ( $assoc_args['format'] ) { + + case 'table': + $fields = get_object_vars( $comment ); + \WP_CLI\Utils\assoc_array_to_table( $fields ); + break; + + case 'json': + WP_CLI::print_value( $comment, $assoc_args ); + break; + + default: + \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); + break; + } + } + /** * Delete a comment. * From 021cf58519f2f20fbe7c45480d5e28f0dd7ba65a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Aug 2013 23:04:48 -0700 Subject: [PATCH 2226/4858] Test for `wp comment get` --- features/comment.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 8a9d2502d8..69dee8dbbc 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -18,3 +18,11 @@ Feature: Manage WordPress comments """ Success: Deleted comment {COMMENT_ID}. """ + + Scenario: Get details about an existing comment + Given a WP install + + When I run `wp comment get 1` + Then STDOUT should be a table containing rows: + | Field | Value | + | comment_author | Mr WordPress | From 52f76428cc1822a8c9e84aa9cf59cfffa73b8008 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 Aug 2013 07:37:59 -0700 Subject: [PATCH 2227/4858] Use our new util function --- php/commands/post.php | 2 +- php/commands/user.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index c0c37a25e6..c14887e173 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -181,7 +181,7 @@ public function get( $args, $assoc_args ) { case 'table': $fields = get_object_vars( $post ); unset( $fields['filter'], $fields['post_content'], $fields['format_content'] ); - $this->assoc_array_to_table( $fields ); + \WP_CLI\Utils\assoc_array_to_table( $fields ); break; case 'json': diff --git a/php/commands/user.php b/php/commands/user.php index cf3d95624c..2e6454a118 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -119,7 +119,7 @@ public function get( $args, $assoc_args ) { switch ( $assoc_args['format'] ) { case 'table': - $this->assoc_array_to_table( $user_data ); + \WP_CLI\Utils\assoc_array_to_table( $user_data ); break; case 'json': From 013f6547d836ddb7b2f75eb2b49b607829a2e87b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 Aug 2013 07:38:31 -0700 Subject: [PATCH 2228/4858] This method has been replaced by a helper util of the same functionality --- php/WP_CLI/CommandWithDBObject.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 083b068758..7978ce37b6 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -68,23 +68,6 @@ protected function success_or_failure( $r ) { return $status; } - protected function assoc_array_to_table( $fields ) { - $rows = array(); - - foreach ( $fields as $field => $value ) { - if ( !is_string($value) ) { - $value = json_encode( $value ); - } - - $rows[] = (object) array( - 'Field' => $field, - 'Value' => $value - ); - } - - \WP_CLI\Utils\format_items( 'table', $rows, array( 'Field', 'Value' ) ); - } - public function delete( $args, $assoc_args ) { $status = 0; From aefd67f9004aff08a309fc6e42a8d3d33b60aa8d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 Aug 2013 08:07:37 -0700 Subject: [PATCH 2229/4858] A subcommand for getting a taxonomy term --- php/commands/term.php | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index 2b400c84e8..43539574cc 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -120,6 +120,60 @@ public function create( $args, $assoc_args ) { } } + /** + * Get a taxonomy term + * + * ## OPTIONS + * + * <term-id> + * : ID of the term to get + * + * <taxonomy> + * : Taxonomy of the term to get + * + * --format=<format> + * : The format to use when printing the term, acceptable values: + * + * - **table**: Outputs all fields of the term as a table. + * + * - **json**: Outputs all fields in JSON format. + * + * ## EXAMPLES + * + * wp term get 1 category + * + * @synopsis <term-id> <taxonomy> [--format=<format>] + */ + public function get( $args, $assoc_args ) { + + list( $term_id, $taxonomy ) = $args; + + $defaults = array( + 'format' => 'table' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $term = get_term_by( 'id', $term_id, $taxonomy ); + if ( ! $term ) + WP_CLI::error( "Term doesn't exist." ); + + switch ( $assoc_args['format'] ) { + + case 'table': + $fields = get_object_vars( $term ); + \WP_CLI\Utils\assoc_array_to_table( $fields ); + break; + + case 'json': + WP_CLI::print_value( $term, $assoc_args ); + break; + + default: + \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); + break; + } + } + /** * Update a term. * From 7fa54a4ccb81942026393cff9b14f33cba017096 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 Aug 2013 08:07:52 -0700 Subject: [PATCH 2230/4858] Test `wp term get` --- features/term.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/term.feature b/features/term.feature index 97b5ad580e..076f65621e 100644 --- a/features/term.feature +++ b/features/term.feature @@ -5,6 +5,7 @@ Feature: Manage WordPress terms When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term' --porcelain` Then STDOUT should be a number + And save STDOUT as {TERM_ID} When I try the previous command again Then STDERR should not be empty @@ -20,6 +21,12 @@ Feature: Manage WordPress terms | name | slug | | Test term | test | + When I run `wp term get {TERM_ID} post_tag` + Then STDOUT should be a table containing rows: + | Field | Value | + | term_id | {TERM_ID} | + | name | Test term | + Scenario: Creating/deleting a term Given a WP install From ec41181d5fc5289bf8d06f1361a3e5548fbbd928 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Tue, 20 Aug 2013 18:57:26 +0100 Subject: [PATCH 2231/4858] Correct the inline docs for the `--hard` flag on `wp rewrite flush` --- php/commands/rewrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 1e04593fdd..1d3e16f7cf 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -13,7 +13,7 @@ class Rewrite_Command extends WP_CLI_Command { * ## OPTIONS * * --hard - * : Perform a hard flush - do not overwrite `.htaccess`. The default is to update `.htaccess` rules as well as rewrite rules in database. + * : Perform a hard flush - update `.htaccess` rules as well as rewrite rules in database. * * @synopsis [--hard] */ From 08aab7a2b41c517fcf6b8b3b53c3950b8d0e50a3 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Tue, 20 Aug 2013 19:22:13 +0100 Subject: [PATCH 2232/4858] Fix the `--format` flag for the `wp rewrite dump` command --- php/commands/rewrite.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 1e04593fdd..995533d583 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -105,12 +105,22 @@ public function dump( $args, $assoc_args ) { $rules = array(); WP_CLI::warning( 'No rewrite rules.' ); } + $defaults = array( + 'format' => '' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + switch ( $assoc_args['format'] ) { + + case 'json': + echo json_encode( $rules ); + break; + + default: + foreach ( $rules as $route => $rule ) + WP_CLI::line( $route . "\t" . $rule ); + break; - if ( isset( $assoc_args['json'] ) ) { - echo json_encode( $rules ); - } else { - foreach ( $rules as $route => $rule ) - WP_CLI::line( $route . "\t" . $rule ); } } From 602c17f23ae3d708320c7ff4057baa7b00315917 Mon Sep 17 00:00:00 2001 From: Nikolay Kolev <nikolay@users.noreply.github.com> Date: Wed, 21 Aug 2013 01:45:23 -0700 Subject: [PATCH 2233/4858] Don't include the comments, which would be irrelevant without the salts. Based on @scribu's idea. --- templates/wp-config.mustache | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index 78cca74884..20b4b6b33e 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -28,6 +28,7 @@ define('DB_CHARSET', 'utf8'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', ''); +{{#keys-and-salts}} /**#@+ * Authentication Unique Keys and Salts. * @@ -37,6 +38,7 @@ define('DB_COLLATE', ''); */ {{{keys-and-salts}}} /**#@-*/ +{{/keys-and-salts}} /** * WordPress Database Table prefix. From 2ccb9af30e1329b38cda054a483a64fda60f7207 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 21 Aug 2013 23:06:36 +0300 Subject: [PATCH 2234/4858] add test that reproduces both #435 and #716 --- features/validation.feature | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 features/validation.feature diff --git a/features/validation.feature b/features/validation.feature new file mode 100644 index 0000000000..683fe735fa --- /dev/null +++ b/features/validation.feature @@ -0,0 +1,15 @@ +Feature: Argument validation + In order to catch errors fast + As a user + I need to see warnings and errors when I pass incorrect arguments + + Scenario: Validation for early commands + Given an empty directory + And WP files + + When I try `wp core config invalid` + Then the return code should be 1 + And STDERR should contain: + """ + Parameter errors: + """ From 31bf236c5acddf518ffe4ea003eddc5460e28369 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 21 Aug 2013 23:58:23 +0300 Subject: [PATCH 2235/4858] behat: show working dir when the return code is wrong --- features/bootstrap/Process.php | 21 +++++++++++++++++---- features/steps/basic_steps.php | 4 +++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 072b6b1859..16b248df42 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -41,24 +41,37 @@ public function run( $subdir = '' ) { $STDERR = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); - return (object) array( + return new ProcessRun( array( 'STDOUT' => $STDOUT, 'STDERR' => $STDERR, 'return_code' => proc_close( $proc ), 'command' => $this->command, 'cwd' => $cwd - ); + ) ); } public function run_check( $subdir = '' ) { $r = $this->run( $subdir ); if ( $r->return_code || !empty( $r->STDERR ) ) { - throw new \RuntimeException( sprintf( "%s: %s\ncwd: %s", - $r->command, $r->STDERR, $r->cwd ) ); + throw new \RuntimeException( $r ); } return $r; } } + +class ProcessRun { + + public function __construct( $props ) { + foreach ( $props as $key => $value ) { + $this->$key = $value; + } + } + + public function __toString() { + return sprintf( "%s: %s\ncwd: %s", $this->command, $this->STDERR, $this->cwd ); + } +} + diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 0e1ab48819..fe171c14a5 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -148,7 +148,9 @@ function ( $world, $stream, $output_filter, $key ) { $steps->Then( '/^the return code should be (\d+)$/', function ( $world, $return_code ) { - assertEquals( $return_code, $world->result->return_code ); + if ( $return_code != $world->result->return_code ) { + throw new RuntimeException( $world->result ); + } } ); From d33530da14fa0144e6df3998e030c07346950285 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 00:05:14 +0300 Subject: [PATCH 2236/4858] core config: use cmd_starts_with() instead of doing a strict array comparison --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8e5931645f..bb4d5c6f89 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -440,7 +440,7 @@ public function before_wp_load() { $this->check_wp_version(); - if ( array( 'core', 'config' ) == $this->arguments ) { + if ( $this->cmd_starts_with( array( 'core', 'config' ) ) ) { $this->_run_command(); exit; } From e5c3195b658e4c78d4f06400d85954b6ddfed808 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 00:27:07 +0300 Subject: [PATCH 2237/4858] behat: replace hidden parameters to 'wp config' with explicit variable --- features/bootstrap/FeatureContext.php | 28 +++++++++------------------ features/core.feature | 2 +- features/steps/basic_steps.php | 4 ++-- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index fc3a15c511..cca8e3924f 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -22,8 +22,6 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { 'dbpass' => 'password1' ); - private static $additional_args; - public $variables = array(); // We cache the results of `wp core download` to improve test performance @@ -43,14 +41,6 @@ private static function cache_wp_files() { */ public static function prepare( SuiteEvent $event ) { self::cache_wp_files(); - - self::$additional_args = array( - 'wp core config' => self::$db_settings, - - 'wp core install-network' => array( - 'title' => 'WP CLI Network' - ) - ); } /** @@ -75,6 +65,7 @@ public function afterScenario( $event ) { public function __construct( array $parameters ) { $this->drop_db(); $this->set_cache_dir(); + $this->variables['CORE_CONFIG_SETTINGS'] = Utils\assoc_args_to_str( self::$db_settings ); } public function getStepDefinitionResources() { @@ -132,13 +123,6 @@ public function drop_db() { } public function proc( $command, $assoc_args = array() ) { - foreach ( self::$additional_args as $start => $additional_args ) { - if ( 0 === strpos( $command, $start ) ) { - $assoc_args = array_merge( $additional_args, $assoc_args ); - break; - } - } - if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); @@ -167,13 +151,19 @@ public function download_wp( $subdir = '' ) { copy( __DIR__ . '/../extra/no-mail.php', $dest_dir . '/wp-content/mu-plugins/no-mail.php' ); } + public function create_config() { + $this->proc( 'wp core config', self::$db_settings )->run_check(); + } + public function install_wp( $subdir = '' ) { $this->create_db(); $this->create_run_dir(); $this->download_wp( $subdir ); - $dbprefix = $subdir ?: 'wp_'; - $this->proc( 'wp core config', compact( 'dbprefix' ) )->run_check( $subdir ); + $db_args = self::$db_settings; + $db_args['dbprefix'] = $subdir ?: 'wp_'; + + $this->proc( 'wp core config', $db_args )->run_check( $subdir ); $install_args = array( 'url' => 'http://example.com', diff --git a/features/core.feature b/features/core.feature index a06a966c9e..8238c0429c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -40,7 +40,7 @@ Feature: Manage WordPress installation """ define( 'WP_DEBUG_LOG', true ); """ - When I run `wp core config --extra-php < wp-config-extra.php` + When I run `wp core config {CORE_CONFIG_SETTINGS} --extra-php < wp-config-extra.php` Then the wp-config.php file should contain: """ define('AUTH_SALT', diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index fe171c14a5..5c699bf7ec 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -36,7 +36,7 @@ function ( $world ) { $steps->Given( '/^wp-config\.php$/', function ( $world ) { - $world->proc( 'wp core config' )->run_check(); + $world->create_config(); } ); @@ -61,7 +61,7 @@ function ( $world, $subdir ) { $steps->Given( '/^a WP multisite install$/', function ( $world ) { $world->install_wp(); - $world->proc( 'wp core install-network' )->run_check(); + $world->proc( 'wp core install-network', array( 'title' => 'WP CLI Network' ) )->run_check(); } ); From 141ed34673b53f61657168a7614fa8b6b89d4a6c Mon Sep 17 00:00:00 2001 From: Nikolay Kolev <nikolaynkolev@gmail.com> Date: Wed, 21 Aug 2013 14:27:42 -0700 Subject: [PATCH 2238/4858] Added tests for the --skip-salts parameter --- features/core.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/core.feature b/features/core.feature index a06a966c9e..4a7b5b0005 100644 --- a/features/core.feature +++ b/features/core.feature @@ -54,6 +54,20 @@ Feature: Manage WordPress installation Then the return code should be 1 And STDERR should not be empty + Scenario: Configure with existing salts + Given an empty directory + And WP files + + Given a wp-config-extra.php file: + """ + define( 'WP_DEBUG_LOG', true ); + """ + When I run `wp core config --extra-php --skip-salts < wp-config-extra.php` + Then the wp-config.php file should not contain: + """ + define('AUTH_SALT', + """ + Scenario: Database doesn't exist Given an empty directory And WP files From 4785e7a1d3b7370fe7b6b7f4eede3e40d6fc2609 Mon Sep 17 00:00:00 2001 From: Nikolay Kolev <nikolaynkolev@gmail.com> Date: Wed, 21 Aug 2013 14:59:07 -0700 Subject: [PATCH 2239/4858] Fixed a typoe in --skip-salts synopsis --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 988231cb46..0bfc0d04f7 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -168,7 +168,7 @@ private static function get_initial_locale() { * define( 'WP_DEBUG_LOG', true ); * PHP * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] [--skip-satls] + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] [--skip-salts] */ public function config( $_, $assoc_args ) { if ( Utils\locate_wp_config() ) { From 5ff289bc4d166d6973b8430268444b951cd447e1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 01:09:24 +0300 Subject: [PATCH 2240/4858] fix and simplify the --skip-salts test. see #696 --- features/core.feature | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index 5bbd71cd7a..0d2a8456e3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -58,11 +58,7 @@ Feature: Manage WordPress installation Given an empty directory And WP files - Given a wp-config-extra.php file: - """ - define( 'WP_DEBUG_LOG', true ); - """ - When I run `wp core config --extra-php --skip-salts < wp-config-extra.php` + When I run `wp core config {CORE_CONFIG_SETTINGS} --skip-salts --extra-php < /dev/null` Then the wp-config.php file should not contain: """ define('AUTH_SALT', From bf51257311cb506a9cd0e52f8a4073e824a3c158 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 21:05:06 +0300 Subject: [PATCH 2241/4858] allow passing multiple items to 'wp plugin update' and 'wp theme update' also, bring back `wp plugin update --all` and `wp theme update --all` --- php/WP_CLI/CommandWithUpgrade.php | 11 +++++- php/WP_CLI/Runner.php | 8 ++-- php/commands/plugin.php | 62 ++++++++++--------------------- php/commands/theme.php | 54 ++++++++++++--------------- 4 files changed, 55 insertions(+), 80 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 96ce4df28f..de2a012977 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -11,6 +11,7 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { abstract protected function get_upgrader_class( $force ); abstract protected function get_item_list(); + abstract protected function filter_item_list( $items, $args ); abstract protected function get_all_items(); abstract protected function get_status( $file ); @@ -174,10 +175,16 @@ protected function get_upgrader( $assoc_args ) { return \WP_CLI\Utils\get_upgrader( $upgrader_class ); } - function update_all( $args, $assoc_args ) { + protected function update_many( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); - $items_to_update = wp_list_filter( $this->get_item_list(), array( + $items = $this->get_item_list(); + + if ( !isset( $assoc_args['all'] ) ) { + $items = $this->filter_item_list( $items, $args ); + } + + $items_to_update = wp_list_filter( $items, array( 'update' => true ) ); diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index bb4d5c6f89..9dab776d78 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -274,12 +274,12 @@ private static function back_compat_conversions( $args, $assoc_args ) { unset( $assoc_args['site_id'] ); } - // {plugin|theme} update --all -> {plugin|theme} update-all + // {plugin|theme} update-all -> {plugin|theme} update --all if ( count( $args ) > 1 && in_array( $args[0], array( 'plugin', 'theme' ) ) - && $args[1] == 'update' && isset( $assoc_args['all'] ) + && $args[1] == 'update-all' ) { - $args[1] = 'update-all'; - unset( $assoc_args['all'] ); + $args[1] = 'update'; + $assoc_args['all'] = true; } // plugin scaffold -> scaffold plugin diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 7c7fb42349..6020f29aaf 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -282,69 +282,40 @@ protected function install_from_repo( $slug, $assoc_args ) { } /** - * Update a plugin. + * Update one or more plugins. * * ## OPTIONS * * <plugin> - * : The plugin to update. + * : The plugin(s) to update. + * + * --all + * : If set, all plugins that have updates will be updated. * * --version=dev * : If set, the plugin will be updated to the latest development version, * regardless of what version is currently installed. * + * --dry-run + * : Preview which plugins would be updated. + * * ## EXAMPLES * * wp plugin update bbpress --version=dev * - * @synopsis <plugin> [--version=<version>] + * @synopsis <plugin>... [--version=<version>] [--all] [--dry-run] */ function update( $args, $assoc_args ) { - $name = $args[0]; - $basename = $this->parse_name( $name ); - if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { - $this->_delete( $basename, false ); - $this->install( $args, $assoc_args ); - } else { - $was_active = is_plugin_active( $basename ); - $was_network_active = is_plugin_active_for_network( $basename ); - - call_user_func( $this->upgrade_refresh ); - - $this->get_upgrader( $assoc_args )->upgrade( $basename ); - - if ( $was_active ) { - $new_args = array( $args[0] ); - - $new_assoc_args = array(); - if ( $was_network_active ) - $new_assoc_args['network'] = true; - - $this->activate( $new_args, $new_assoc_args ); + foreach ( $args as $arg ) { + $this->_delete( $this->parse_name( $arg ) ); + $this->install( array( $arg ), $assoc_args ); } + } else { + parent::update_many( $args, $assoc_args ); } } - /** - * Update all plugins. - * - * ## OPTIONS - * - * --dry-run - * : Pretend to do the updates, to see what would happen. - * - * ## EXAMPLES - * - * wp plugin update-all - * - * @subcommand update-all - * @synopsis [--dry-run] - */ - function update_all( $args, $assoc_args ) { - parent::update_all( $args, $assoc_args ); - } - protected function get_item_list() { $items = array(); @@ -361,6 +332,11 @@ protected function get_item_list() { return $items; } + protected function filter_item_list( $items, $args ) { + $basenames = array_map( array( $this, 'parse_name' ), $args ); + return \WP_CLI\Utils\pick_fields( $items, $basenames ); + } + /** * Install a plugin. * diff --git a/php/commands/theme.php b/php/commands/theme.php index ee12ce23d6..beafcefe7c 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -217,6 +217,15 @@ protected function get_item_list() { return $items; } + protected function filter_item_list( $items, $args ) { + $theme_files = array(); + foreach ( $args as $arg ) { + $theme_files[] = $this->parse_name( $arg )->get_stylesheet_directory(); + } + + return \WP_CLI\Utils\pick_fields( $items, $theme_files ); + } + /** * Install a theme. * @@ -251,23 +260,23 @@ function install( $args, $assoc_args ) { /** * Get a theme - * + * * ## OPTIONS * * <theme> * : The theme to get. - * + * * * --format=<format> * : The format to use when printing the theme, acceptable values: * * - **table**: Outputs all fields of the theme as a table. * * - **json**: Outputs all fields in JSON format. - * + * * ## EXAMPLES * * wp theme get twentytwelve - * + * * @synopsis <theme> [--format=<format>] */ public function get( $args, $assoc_args ) { @@ -306,48 +315,31 @@ public function get( $args, $assoc_args ) { } /** - * Update a theme. + * Update one or more themes. * * ## OPTIONS * * <theme> - * : The theme to update. + * : The theme(s) to update. + * + * --all + * : If set, all themes that have updates will be updated. * * --version=dev * : If set, the theme will be updated to the latest development version, * regardless of what version is currently installed. * - * ## EXAMPLES - * - * wp theme update twentytwelve - * - * @synopsis <theme> [--version=<version>] - */ - function update( $args, $assoc_args ) { - $theme = $this->parse_name( $args[0] ); - - call_user_func( $this->upgrade_refresh ); - - $this->get_upgrader( $assoc_args )->upgrade( $theme->get_stylesheet() ); - } - - /** - * Update all themes. - * - * ## OPTIONS - * * --dry-run - * : Pretend to do the updates, to see what would happen. + * : Preview which themes would be updated. * * ## EXAMPLES * - * wp theme update-all + * wp theme update twentytwelve * - * @subcommand update-all - * @synopsis [--dry-run] + * @synopsis <theme>... [--version=<version>] [--all] [--dry-run] */ - function update_all( $args, $assoc_args ) { - parent::update_all( $args, $assoc_args ); + function update( $args, $assoc_args ) { + parent::update_many( $args, $assoc_args ); } /** From c5f7e6230a81eaf0636b34f07cf83ee10a19c8af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 21:19:12 +0300 Subject: [PATCH 2242/4858] {plugin|theme} update: improve --dry-run output --- php/WP_CLI/CommandWithUpgrade.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index de2a012977..f457282529 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -189,17 +189,16 @@ protected function update_many( $args, $assoc_args ) { ) ); if ( isset( $assoc_args['dry-run'] ) ) { - $item_list = "Available {$this->item_type} updates:"; - if ( empty( $items_to_update ) ) { - $item_list .= " none"; - } else { - foreach ( $items_to_update as $file => $details ) { - $item_list .= "\n\t%y" . $details['name'] . "%n"; - } + \WP_CLI::line( "No {$this->item_type} updates available." ); + return; } - \WP_CLI::line( \WP_CLI::colorize( $item_list ) ); + \WP_CLI::line( "Available {$this->item_type} updates:" ); + + \WP_CLI\Utils\format_items( 'table', $items_to_update, + array( 'name', 'status', 'version' ) ); + return; } From 25bf077ec1eb41eec8657f8bc70e219262b028a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 21:58:25 +0300 Subject: [PATCH 2243/4858] {plugin|theme} update: add more examples [ci skip] --- php/commands/plugin.php | 2 ++ php/commands/theme.php | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 6020f29aaf..8e19109dd2 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -303,6 +303,8 @@ protected function install_from_repo( $slug, $assoc_args ) { * * wp plugin update bbpress --version=dev * + * wp plugin update --all + * * @synopsis <plugin>... [--version=<version>] [--all] [--dry-run] */ function update( $args, $assoc_args ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index beafcefe7c..e777c427d7 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -334,7 +334,9 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp theme update twentytwelve + * wp theme update twentyeleven twentytwelve + * + * wp theme update --all * * @synopsis <theme>... [--version=<version>] [--all] [--dry-run] */ From 83cf1247719a51052d36d3e3ee8477ed111c47e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 22 Aug 2013 23:02:06 +0300 Subject: [PATCH 2244/4858] behat: whitespace fixes --- features/db.feature | 18 ++++++++-------- features/option.feature | 18 ++++++++-------- features/post-meta.feature | 12 +++++------ features/post.feature | 5 ++++- features/shell.feature | 34 +++++++++++++++--------------- features/term.feature | 8 +++++++- features/upgradables.feature | 40 ++++++++++++++++++------------------ features/user-meta.feature | 12 +++++------ features/user.feature | 33 ++++++++++++++++------------- 9 files changed, 97 insertions(+), 83 deletions(-) diff --git a/features/db.feature b/features/db.feature index 61bd9f52d2..f8376e8245 100644 --- a/features/db.feature +++ b/features/db.feature @@ -22,19 +22,19 @@ Feature: Perform database operations When I run `wp db query 'SELECT COUNT(*) as total FROM wp_posts'` Then STDOUT should contain: - """ - total - """ + """ + total + """ Given a debug.sql file: - """ - SELECT COUNT(*) as total FROM wp_posts - """ + """ + SELECT COUNT(*) as total FROM wp_posts + """ When I run `wp db query < debug.sql` Then STDOUT should contain: - """ - total - """ + """ + total + """ Scenario: DB export/import Given a WP install diff --git a/features/option.feature b/features/option.feature index a009349d33..28ea9a8c4c 100644 --- a/features/option.feature +++ b/features/option.feature @@ -9,9 +9,9 @@ Feature: Manage WordPress options When I run `wp option get str_opt` Then STDOUT should be: - """ - bar - """ + """ + bar + """ When I run `wp option delete str_opt` Then STDOUT should not be empty @@ -29,9 +29,9 @@ Feature: Manage WordPress options When I run `wp option get blog_public` Then STDOUT should be: - """ - 0 - """ + """ + 0 + """ # JSON values @@ -43,6 +43,6 @@ Feature: Manage WordPress options When I run `wp option get json_opt --format=json` Then STDOUT should be: - """ - [1,2] - """ + """ + [1,2] + """ diff --git a/features/post-meta.feature b/features/post-meta.feature index 5c3ecd1167..b756062a93 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -8,18 +8,18 @@ Feature: Manage post custom fields When I run `wp post-meta get 1 foo` Then STDOUT should be: - """ - bar - """ + """ + bar + """ When I run `wp post-meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty When I run `wp post-meta get 1 foo --format=json` Then STDOUT should be: - """ - ["1","2"] - """ + """ + ["1","2"] + """ When I run `wp post-meta delete 1 foo` Then STDOUT should not be empty diff --git a/features/post.feature b/features/post.feature index 16c88c6dfe..8d6816ad8d 100644 --- a/features/post.feature +++ b/features/post.feature @@ -67,7 +67,10 @@ Feature: Manage WordPress posts When I run `wp post get --format=json {POST_ID}` Then STDOUT should be JSON containing: """ - {"ID":{POST_ID},"post_title":"Test post"} + { + "ID": {POST_ID}, + "post_title": "Test post" + } """ Scenario: Creating/listing posts diff --git a/features/shell.feature b/features/shell.feature index 1e855ae7f2..d415c6c4ed 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -11,32 +11,32 @@ Feature: WordPress REPL Scenario: Persistent environment Given a WP install And a session file: - """ - function is_empty_string( $str ) { return strlen( $str ) == 0; } - $a = get_option('home'); - is_empty_string( $a ); - """ + """ + function is_empty_string( $str ) { return strlen( $str ) == 0; } + $a = get_option('home'); + is_empty_string( $a ); + """ When I run `wp shell --basic < session` Then STDOUT should contain: - """ - bool(false) - """ + """ + bool(false) + """ Scenario: Multiline support (basic) Given a WP install And a session file: - """ - function is_empty_string( $str ) { \ - return strlen( $str ) == 0; \ - } + """ + function is_empty_string( $str ) { \ + return strlen( $str ) == 0; \ + } - function_exists( 'is_empty_string' ); - """ + function_exists( 'is_empty_string' ); + """ When I run `wp shell --basic < session` Then STDOUT should be: - """ - bool(true) - """ + """ + bool(true) + """ diff --git a/features/term.feature b/features/term.feature index 076f65621e..b658eb97e9 100644 --- a/features/term.feature +++ b/features/term.feature @@ -13,7 +13,13 @@ Feature: Manage WordPress terms When I run `wp term list post_tag --format=json` Then STDOUT should be JSON containing: """ - [{"name":"Test term","slug":"test","description":"This is a test term","parent":"0","count":"0"}] + [{ + "name": "Test term", + "slug":"test", + "description":"This is a test term", + "parent":"0", + "count":"0" + }] """ When I run `wp term list post_tag --fields=name,slug --format=csv` diff --git a/features/upgradables.feature b/features/upgradables.feature index fc9c322766..023f6fee36 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -3,12 +3,12 @@ Feature: Manage WordPress themes and plugins Scenario Outline: Installing, upgrading and deleting a theme or plugin Given a WP install And download: - | path | url | + | path | url | | {CACHE_DIR}/<item>.zip | <zip_file> | And I run `wp <type> path` And save STDOUT as {CONTENT_DIR} - # Install an out of date <item> from WordPress.org repository + # Install an out of date <item> from WordPress.org repository When I run `wp <type> install <item> --version=<version>` Then STDOUT should contain: """ @@ -51,46 +51,46 @@ Feature: Manage WordPress themes and plugins # Install <item> from a local zip file When I run `wp <type> install {CACHE_DIR}/<item>.zip` Then STDOUT should contain: - """ - <type_name> installed successfully. - """ + """ + <type_name> installed successfully. + """ And the <file_to_check> file should exist When I run `wp <type> delete <item>` Then STDOUT should contain: - """ - Success: Deleted '<item>' <type>. - """ + """ + Success: Deleted '<item>' <type>. + """ And the <file_to_check> file should not exist # Install <item> from a remote zip file (standard URL with no GET parameters) When I run `wp <type> install <zip_file>` Then STDOUT should contain: - """ - <type_name> installed successfully. - """ + """ + <type_name> installed successfully. + """ And the <file_to_check> file should exist When I run `wp <type> delete <item>` Then STDOUT should contain: - """ - Success: Deleted '<item>' <type>. - """ + """ + Success: Deleted '<item>' <type>. + """ And the <file_to_check> file should not exist # Install <item> from a remote zip file (complex URL with GET parameters) When I run `wp <type> install '<zip_file>?AWSAccessKeyId=123&Expires=456&Signature=abcdef'` Then STDOUT should contain: - """ - <type_name> installed successfully. - """ + """ + <type_name> installed successfully. + """ And the <file_to_check> file should exist When I run `wp <type> delete <item>` Then STDOUT should contain: - """ - Success: Deleted '<item>' <type>. - """ + """ + Success: Deleted '<item>' <type>. + """ And the <file_to_check> file should not exist When I run `wp <type> search <item> --per-page=1 --fields=name,slug` diff --git a/features/user-meta.feature b/features/user-meta.feature index 9452371538..7d3ac2b5f6 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -8,18 +8,18 @@ Feature: Manage user custom fields When I run `wp user-meta get 1 foo` Then STDOUT should be: - """ - bar - """ + """ + bar + """ When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty When I run `wp user-meta get 1 foo --format=json` Then STDOUT should be: - """ - ["1","2"] - """ + """ + ["1","2"] + """ When I run `wp user-meta delete 1 foo` Then STDOUT should not be empty diff --git a/features/user.feature b/features/user.feature index 83f3f90008..1e39b3eb0b 100644 --- a/features/user.feature +++ b/features/user.feature @@ -58,9 +58,14 @@ Feature: Manage WordPress users When I run `wp user list --format=json` Then STDOUT should be JSON containing: - """ - [{"user_login":"admin","display_name":"Existing User","user_email":"admin@domain.com","roles":"administrator"}] - """ + """ + [{ + "user_login":"admin", + "display_name":"Existing User", + "user_email":"admin@domain.com", + "roles":"administrator" + }] + """ Scenario: Managing user roles Given a WP install @@ -98,18 +103,18 @@ Feature: Manage WordPress users When I run `wp user add-cap 1 edit_vip_product` Then STDOUT should be: - """ - Success: Added 'edit_vip_product' capability for admin (1). - """ - + """ + Success: Added 'edit_vip_product' capability for admin (1). + """ + And I run `wp user list-caps 1 | tail -n 1` Then STDOUT should be: - """ - edit_vip_product - """ - + """ + edit_vip_product + """ + And I run `wp user remove-cap 1 edit_vip_product` Then STDOUT should be: - """ - Success: Removed 'edit_vip_product' cap for admin (1). - """ + """ + Success: Removed 'edit_vip_product' cap for admin (1). + """ From 69e93e3e9ec620a86f9d8f25db6540b988aaef44 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 25 Aug 2013 15:28:42 +0300 Subject: [PATCH 2245/4858] first pass at supporting multiple plugin/theme installs --- php/WP_CLI/CommandWithUpgrade.php | 51 +++++++++++++++++-------------- php/commands/plugin.php | 11 +++---- php/commands/theme.php | 14 +++------ 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index f457282529..b8999b8116 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -99,40 +99,45 @@ function install( $args, $assoc_args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); - $slug = stripslashes( $args[0] ); + foreach ( $args as $slug ) { + $local_or_remote_zip_file = false; - $local_or_remote_zip_file = ''; - - // Check if a URL to a remote zip file has been specified - $url_path = parse_url( $slug, PHP_URL_PATH ); - if ( ! empty( $url_path ) && '.zip' === substr( $url_path, - 4 ) ) { - $local_or_remote_zip_file = $slug; - } else { - // Check if a local zip file has been specified - if ( 'zip' === pathinfo( $slug, PATHINFO_EXTENSION ) && file_exists( $slug ) ) { + // Check if a URL to a remote zip file has been specified + $url_path = parse_url( $slug, PHP_URL_PATH ); + if ( ! empty( $url_path ) && '.zip' === substr( $url_path, - 4 ) ) { $local_or_remote_zip_file = $slug; + } else { + // Check if a local zip file has been specified + if ( 'zip' === pathinfo( $slug, PATHINFO_EXTENSION ) && file_exists( $slug ) ) { + $local_or_remote_zip_file = $slug; + } } - } - if ( ! empty( $local_or_remote_zip_file ) ) { + if ( $local_or_remote_zip_file ) { + // Install from local or remote zip file + $file_upgrader = $this->get_upgrader( $assoc_args ); + + if ( $file_upgrader->install( $local_or_remote_zip_file ) ) { + $slug = $file_upgrader->result['destination_name']; - // Install from local or remote zip file - $file_upgrader = $this->get_upgrader( $assoc_args ); + if ( isset( $assoc_args['activate'] ) ) { + \WP_CLI::log( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); + } + } + } else { + // Assume a plugin/theme slug from the WordPress.org repository has been specified + $result = $this->install_from_repo( $slug, $assoc_args ); - if ( $file_upgrader->install( $local_or_remote_zip_file ) ) { - $slug = $file_upgrader->result['destination_name']; + if ( is_wp_error( $result ) ) { + \WP_CLI::warning( $result ); + } - if ( isset( $assoc_args['activate'] ) ) { + if ( $result && isset( $assoc_args['activate'] ) ) { \WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } - } else { - exit(1); } - - } else { - // Assume a plugin/theme slug from the WordPress.org repository has been specified - $this->install_from_repo( $slug, $assoc_args ); } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 8e19109dd2..442c321928 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -258,7 +258,7 @@ protected function install_from_repo( $slug, $assoc_args ) { $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { - WP_CLI::error( $api ); + return $api; } if ( isset( $assoc_args['version'] ) ) { @@ -269,16 +269,13 @@ protected function install_from_repo( $slug, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && 'install' != $status['status'] ) { // We know this will fail, so avoid a needless download of the package. - WP_CLI::error( 'Plugin already installed.' ); + return new WP_Error( 'already_installed', "$slug already installed." ); } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); - if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } + return $result; } /** @@ -372,7 +369,7 @@ protected function filter_item_list( $items, $args ) { * # Install from a remote zip file * wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef * - * @synopsis <plugin|zip|url> [--version=<version>] [--force] [--activate] + * @synopsis <plugin|zip|url>... [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); diff --git a/php/commands/theme.php b/php/commands/theme.php index e777c427d7..ef1d8fc600 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -172,12 +172,10 @@ public function path( $args, $assoc_args ) { } protected function install_from_repo( $slug, $assoc_args ) { - $result = NULL; - $api = themes_api( 'theme_information', array( 'slug' => $slug ) ); if ( is_wp_error( $api ) ) { - WP_CLI::error( $api ); + return $api; } if ( isset( $assoc_args['version'] ) ) { @@ -186,17 +184,13 @@ protected function install_from_repo( $slug, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && wp_get_theme( $slug )->exists() ) { // We know this will fail, so avoid a needless download of the package. - WP_CLI::error( 'Theme already installed.' ); + return new WP_Error( 'already_installed', "$slug already installed." ); } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); - // Finally, activate theme if requested. - if ( $result && isset( $assoc_args['activate'] ) ) { - WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } + return $result; } protected function get_item_list() { @@ -252,7 +246,7 @@ protected function filter_item_list( $items, $args ) { * # Install from a remote zip file * wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef * - * @synopsis <theme|zip|url> [--version=<version>] [--force] [--activate] + * @synopsis <theme|zip|url>... [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); From b1c2a2723ecd8b8c105d1fd7c1b2435e310e1480 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 25 Aug 2013 16:16:48 +0300 Subject: [PATCH 2246/4858] 'wp theme install' only shows a warning now --- features/theme.feature | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index c05ecd0f25..db0fabc6a1 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -6,9 +6,6 @@ Feature: Manage WordPress themes When I run `wp theme install p2` Then STDOUT should not be empty - When I try the previous command again - Then the return code should be 1 - When I run `wp theme status p2` Then STDOUT should contain: """ From 6b37e7d78494543a791c07546489e591a797d0a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 25 Aug 2013 16:32:26 +0300 Subject: [PATCH 2247/4858] make sure the slug is always part of the warning The standard plugin/theme upgrader strings don't contain the slug. --- php/WP_CLI/CommandWithUpgrade.php | 17 +++++++---------- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index b8999b8116..d1a327c10a 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -101,6 +101,7 @@ function install( $args, $assoc_args ) { foreach ( $args as $slug ) { $local_or_remote_zip_file = false; + $result = false; // Check if a URL to a remote zip file has been specified $url_path = parse_url( $slug, PHP_URL_PATH ); @@ -119,24 +120,20 @@ function install( $args, $assoc_args ) { if ( $file_upgrader->install( $local_or_remote_zip_file ) ) { $slug = $file_upgrader->result['destination_name']; - - if ( isset( $assoc_args['activate'] ) ) { - \WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } + $result = true; } } else { // Assume a plugin/theme slug from the WordPress.org repository has been specified $result = $this->install_from_repo( $slug, $assoc_args ); if ( is_wp_error( $result ) ) { - \WP_CLI::warning( $result ); + \WP_CLI::warning( "$slug: " . $result->get_error_message() ); } + } - if ( $result && isset( $assoc_args['activate'] ) ) { - \WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); - } + if ( $result && isset( $assoc_args['activate'] ) ) { + \WP_CLI::log( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); } } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 442c321928..9611905bd6 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -269,7 +269,7 @@ protected function install_from_repo( $slug, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && 'install' != $status['status'] ) { // We know this will fail, so avoid a needless download of the package. - return new WP_Error( 'already_installed', "$slug already installed." ); + return new WP_Error( 'already_installed', 'Plugin already installed.' ); } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); diff --git a/php/commands/theme.php b/php/commands/theme.php index ef1d8fc600..c64ac16955 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -184,7 +184,7 @@ protected function install_from_repo( $slug, $assoc_args ) { if ( !isset( $assoc_args['force'] ) && wp_get_theme( $slug )->exists() ) { // We know this will fail, so avoid a needless download of the package. - return new WP_Error( 'already_installed', "$slug already installed." ); + return new WP_Error( 'already_installed', 'Theme already installed.' ); } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); From 0f9d7473fa26084e8c2eb11b555fff353eddd3de Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 11:24:18 -0700 Subject: [PATCH 2248/4858] Use `\cli\prompt()` instead of reinventing the wheel See https://github.com/wp-cli/wp-cli/pull/673#issuecomment-22938858 --- php/class-wp-cli.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 6d907f3f71..db2456f1f1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -171,9 +171,7 @@ static function prompt( $question, $required = false ) { do { - self::out( $question . ': ' ); - - $response = trim( fgets( STDIN ) ); + $response = \cli\prompt( $question ); if ( $required && $response ) $required = false; From 274546fea043b25138ad07e719e740a8aa1ff6e5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 11:32:11 -0700 Subject: [PATCH 2249/4858] Support for repeating positional arguments --- php/WP_CLI/Dispatcher/Subcommand.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index c784d5eb3c..e9de964963 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -70,7 +70,11 @@ private function prompt_args( $args, $assoc_args ) { if ( $response ) { switch ( $spec_arg['type'] ) { case 'positional': - $args[] = $response; + if ( $spec_arg['repeating'] ) + $response = explode( ' ', $response ); + else + $response = array( $response ); + $args = array_merge( $args, $response ); break; case 'assoc': $assoc_args[$spec_arg['name']] = $response; From 3b60175a8f2170df0c173d3c7e22f4ca3b046108 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 11:40:43 -0700 Subject: [PATCH 2250/4858] Better use of `\cli\prompt()`, which requires a default argument if the prompt is to be optional --- php/class-wp-cli.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index db2456f1f1..ac9aecb959 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -169,15 +169,12 @@ static function confirm( $question, $assoc_args = array() ) { */ static function prompt( $question, $required = false ) { - do { + if ( ! $required ) + $default = ''; + else + $default = false; - $response = \cli\prompt( $question ); - if ( $required && $response ) - $required = false; - - } while( $required ); - - return $response; + return \cli\prompt( $question, $default ); } From f428b027e9e84ffe4d0a46c9feb420763dbb9b6a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 11:56:54 -0700 Subject: [PATCH 2251/4858] Add support for prompting `--flag` --- php/WP_CLI/Dispatcher/Subcommand.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index e9de964963..2d9772aac2 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -54,7 +54,7 @@ private function prompt_args( $args, $assoc_args ) { return array( $args, $assoc_args ); $spec = array_filter( \WP_CLI\SynopsisParser::parse( $synopsis ), function( $spec_arg ) { - return in_array( $spec_arg['type'], array( 'positional', 'assoc' ) ); + return in_array( $spec_arg['type'], array( 'positional', 'assoc', 'flag' ) ); }); $spec = array_values( $spec ); @@ -66,6 +66,10 @@ private function prompt_args( $args, $assoc_args ) { $required = ! $spec_arg['optional']; $prompt = ( $key + 1 ) . '/' . count( $spec ) . ' ' . $spec_arg['token']; + + if ( 'flag' == $spec_arg['type'] ) + $prompt .= ' (Y/n)'; + $response = \WP_CLI::prompt( $prompt, $required ); if ( $response ) { switch ( $spec_arg['type'] ) { @@ -79,6 +83,10 @@ private function prompt_args( $args, $assoc_args ) { case 'assoc': $assoc_args[$spec_arg['name']] = $response; break; + case 'flag': + if ( 'Y' == $response ) + $assoc_args[$spec_arg['name']] = true; + break; } } } From 27c80945b71cbb0894405520a54fb23d96315aee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 12:23:09 -0700 Subject: [PATCH 2252/4858] Support for generic arguments --- php/WP_CLI/Dispatcher/Subcommand.php | 77 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 2d9772aac2..6b303e55c2 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -54,7 +54,7 @@ private function prompt_args( $args, $assoc_args ) { return array( $args, $assoc_args ); $spec = array_filter( \WP_CLI\SynopsisParser::parse( $synopsis ), function( $spec_arg ) { - return in_array( $spec_arg['type'], array( 'positional', 'assoc', 'flag' ) ); + return in_array( $spec_arg['type'], array( 'generic', 'positional', 'assoc', 'flag' ) ); }); $spec = array_values( $spec ); @@ -64,29 +64,60 @@ private function prompt_args( $args, $assoc_args ) { $args = array(); foreach( $spec as $key => $spec_arg ) { + $current_prompt = ( $key + 1 ) . '/' . count( $spec ) . ' '; $required = ! $spec_arg['optional']; - $prompt = ( $key + 1 ) . '/' . count( $spec ) . ' ' . $spec_arg['token']; - - if ( 'flag' == $spec_arg['type'] ) - $prompt .= ' (Y/n)'; - - $response = \WP_CLI::prompt( $prompt, $required ); - if ( $response ) { - switch ( $spec_arg['type'] ) { - case 'positional': - if ( $spec_arg['repeating'] ) - $response = explode( ' ', $response ); - else - $response = array( $response ); - $args = array_merge( $args, $response ); - break; - case 'assoc': - $assoc_args[$spec_arg['name']] = $response; - break; - case 'flag': - if ( 'Y' == $response ) - $assoc_args[$spec_arg['name']] = true; - break; + + // 'generic' permits arbitrary key=value (e.g. [--<field>=<value>] ) + if ( 'generic' == $spec_arg['type'] ) { + + list( $key_token, $value_token ) = explode( '=', $spec_arg['token'] ); + + $repeat = false; + do { + if ( ! $repeat ) + $key_prompt = $current_prompt . $key_token; + else + $key_prompt = str_repeat( " ", strlen( $current_prompt ) ) . $key_token; + + $key = \WP_CLI::prompt( $key_prompt, $required ); + if ( $key ) { + $key_prompt_count = strlen( $key_prompt ) - strlen( $value_token ) - 1; + $value_prompt = str_repeat( " ", $key_prompt_count ) . '=' . $value_token; + $value = \WP_CLI::prompt( $value_prompt ); + $assoc_args[$key] = $value; + + $repeat = true; + $required = false; + } else { + $repeat = false; + } + + } while( $required || $repeat ); + + } else { + + $prompt = $current_prompt . $spec_arg['token']; + if ( 'flag' == $spec_arg['type'] ) + $prompt .= ' (Y/n)'; + + $response = \WP_CLI::prompt( $prompt, $required ); + if ( $response ) { + switch ( $spec_arg['type'] ) { + case 'positional': + if ( $spec_arg['repeating'] ) + $response = explode( ' ', $response ); + else + $response = array( $response ); + $args = array_merge( $args, $response ); + break; + case 'assoc': + $assoc_args[$spec_arg['name']] = $response; + break; + case 'flag': + if ( 'Y' == $response ) + $assoc_args[$spec_arg['name']] = true; + break; + } } } } From dab1d025d9d8df686c45961a5d21009fbff2eee3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 12:33:16 -0700 Subject: [PATCH 2253/4858] A better way of achieving this. See https://github.com/wp-cli/wp-cli/pull/673/files#r5969302 --- php/WP_CLI/Dispatcher/Subcommand.php | 10 +--------- php/WP_CLI/Runner.php | 9 --------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 6b303e55c2..1f191ead54 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -30,14 +30,6 @@ function get_alias() { return $this->alias; } - function set_prompt( $value ) { - $this->prompt = (bool)$value; - } - - function get_prompt() { - return $this->prompt; - } - function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( sprintf( "%s%s %s", $prefix, @@ -166,7 +158,7 @@ private function validate_args( $args, &$assoc_args ) { function invoke( $args, $assoc_args ) { - if ( $this->get_prompt() ) + if ( \WP_CLI::get_config( 'prompt' ) ) list( $args, $assoc_args ) = $this->prompt_args( $args, $assoc_args ); $this->validate_args( $args, $assoc_args ); diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index cb9c4b3e90..9dab776d78 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -436,15 +436,6 @@ public function before_wp_load() { self::set_url_params( $url_parts ); } - // Handle --prompt parameter - if ( $this->config['prompt'] ) { - $r = $this->find_command_to_run( $this->arguments ); - if ( is_array( $r ) ) { - list( $command ) = $r; - $command->set_prompt( true ); - } - } - $this->do_early_invoke( 'before_wp_load' ); $this->check_wp_version(); From a1decfeb18e7deeefb65974df33f4f3f3dd64e66 Mon Sep 17 00:00:00 2001 From: Andrey Savchenko <contact@rarst.net> Date: Sun, 25 Aug 2013 23:27:27 +0300 Subject: [PATCH 2254/4858] Fixed regex for better matching EOL when cleaning doc block --- php/WP_CLI/DocParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index a999a9e1ea..b95df6e075 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -11,7 +11,7 @@ function __construct( $docComment ) { } private static function remove_decorations( $comment ) { - $comment = preg_replace( '|^/\*\*\n|', '', $comment ); + $comment = preg_replace( '|^/\*\*[\r\n]+|', '', $comment ); $comment = preg_replace( '|\n[\t ]*\*/$|', '', $comment ); $comment = preg_replace( '|^[\t ]*\* ?|m', '', $comment ); From b8be71e93d0eee8d8c6f7cdfd5317c60f7d3cb65 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 13:36:02 -0700 Subject: [PATCH 2255/4858] Implement `wp comment list` --- php/commands/comment.php | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/php/commands/comment.php b/php/commands/comment.php index dd74730139..1adf7c98c9 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -7,6 +7,15 @@ */ class Comment_Command extends WP_CLI_Command { + private $fields = array( + 'comment_ID', + 'comment_post_ID', + 'comment_date', + 'comment_approved', + 'comment_author', + 'comment_author_email', + ); + /** * Insert a comment. * @@ -93,6 +102,58 @@ public function get( $args, $assoc_args ) { } } + /** + * Get a list of comments. + * + * ## OPTIONS + * + * --<field>=<value> + * : One or more args to pass to WP_Comment_Query. + * + * --fields=<fields> + * : Limit the output to specific object fields. Defaults to comment_ID,comment_post_ID,comment_date,comment_approved,comment_author,comment_author_email + * + * --format=<format> + * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * + * ## EXAMPLES + * + * wp comment list --format=ids + * + * wp comment list --post_id=2 + * + * wp comment list --number=20 --comment_approved=1 + * + * @subcommand list + * @synopsis [--<field>=<value>] [--fields=<fields>] [--format=<format>] + */ + public function _list( $_, $assoc_args ) { + $query_args = array(); + $defaults = array( + 'format' => 'table', + 'fields' => $this->fields + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + foreach ( $assoc_args as $key => $value ) { + if ( true === $value ) + continue; + + $query_args[ $key ] = $value; + } + + if ( 'ids' == $assoc_args['format'] ) + $query_args['fields'] = 'ids'; + + $query = new WP_Comment_Query(); + $comments = $query->query( $query_args ); + + if ( 'ids' == $assoc_args['format'] ) + $comments = wp_list_pluck( $comments, 'comment_ID' ); + + WP_CLI\Utils\format_items( $assoc_args['format'], $comments, $assoc_args['fields'] ); + } + /** * Delete a comment. * From 59c469932f66f074f7e9023794edc36ba59b1dc9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 13:36:14 -0700 Subject: [PATCH 2256/4858] A functional test for `wp comment list` --- features/comment.feature | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 69dee8dbbc..e372172f0f 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -26,3 +26,8 @@ Feature: Manage WordPress comments Then STDOUT should be a table containing rows: | Field | Value | | comment_author | Mr WordPress | + + When I run `wp comment list --fields=comment_approved,comment_author` + Then STDOUT should be a table containing rows: + | comment_approved | comment_author | + | 1 | Mr WordPress | From d82037c3c2a07a76a53327a31ad1811d04b7ef02 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 16:26:20 -0700 Subject: [PATCH 2257/4858] Catch the thrown exception --- php/class-wp-cli.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ac9aecb959..ba361a0c6e 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -174,7 +174,12 @@ static function prompt( $question, $required = false ) { else $default = false; - return \cli\prompt( $question, $default ); + try { + $response = \cli\prompt( $question, $default ); + } catch( Exception $e ) { + $response = ''; + } + return $response; } From 25a08b330601068c649fca8ca4d5d84318dadf24 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Aug 2013 17:17:36 -0700 Subject: [PATCH 2258/4858] We don't need a `prompt()` util right now. Instead, let's better utilize PHP cli tools --- php/WP_CLI/Dispatcher/Subcommand.php | 30 ++++++++++++++++++++++++---- php/class-wp-cli.php | 19 ------------------ 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 1f191ead54..5d91b9cab2 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -38,6 +38,18 @@ function show_usage( $prefix = 'usage: ' ) { ) ); } + private function prompt( $question, $default ) { + + try { + $response = \cli\prompt( $question, $default ); + } catch( \Exception $e ) { + \WP_CLI::line(); + return false; + } + + return $response; + } + private function prompt_args( $args, $assoc_args ) { $synopsis = $this->get_synopsis(); @@ -57,7 +69,7 @@ private function prompt_args( $args, $assoc_args ) { foreach( $spec as $key => $spec_arg ) { $current_prompt = ( $key + 1 ) . '/' . count( $spec ) . ' '; - $required = ! $spec_arg['optional']; + $default = ( $spec_arg['optional'] ) ? '' : false; // 'generic' permits arbitrary key=value (e.g. [--<field>=<value>] ) if ( 'generic' == $spec_arg['type'] ) { @@ -71,11 +83,18 @@ private function prompt_args( $args, $assoc_args ) { else $key_prompt = str_repeat( " ", strlen( $current_prompt ) ) . $key_token; - $key = \WP_CLI::prompt( $key_prompt, $required ); + $key = $this->prompt( $key_prompt, $default ); + if ( false === $key ) + return array( $args, $assoc_args ); + if ( $key ) { $key_prompt_count = strlen( $key_prompt ) - strlen( $value_token ) - 1; $value_prompt = str_repeat( " ", $key_prompt_count ) . '=' . $value_token; - $value = \WP_CLI::prompt( $value_prompt ); + + $value = $this->prompt( $value_prompt, $default ); + if ( false === $value ) + return array( $args, $assoc_args ); + $assoc_args[$key] = $value; $repeat = true; @@ -92,7 +111,10 @@ private function prompt_args( $args, $assoc_args ) { if ( 'flag' == $spec_arg['type'] ) $prompt .= ' (Y/n)'; - $response = \WP_CLI::prompt( $prompt, $required ); + $response = $this->prompt( $prompt, $default ); + if ( false === $response ) + return array( $args, $assoc_args ); + if ( $response ) { switch ( $spec_arg['type'] ) { case 'positional': diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ba361a0c6e..da3a32be62 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -164,25 +164,6 @@ static function confirm( $question, $assoc_args = array() ) { } } - /** - * Prompt a user for some input - */ - static function prompt( $question, $required = false ) { - - if ( ! $required ) - $default = ''; - else - $default = false; - - try { - $response = \cli\prompt( $question, $default ); - } catch( Exception $e ) { - $response = ''; - } - return $response; - } - - /** * Read a value, from various formats * From 7d11feb5a7a0ef73c4de4f9e1b30c2fd28a36ba4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 26 Aug 2013 03:24:40 +0300 Subject: [PATCH 2259/4858] remove leftover $prompt property --- php/WP_CLI/Dispatcher/Subcommand.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 5d91b9cab2..8dca6c6d33 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -11,8 +11,6 @@ class Subcommand extends CompositeCommand { private $when_invoked; - private $prompt = false; - function __construct( $parent, $name, $docparser, $when_invoked ) { $this->when_invoked = $when_invoked; From 63e7d6c5df0766c460498d8de2d066ddc70c61a4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 27 Aug 2013 23:23:15 +0300 Subject: [PATCH 2260/4858] add behat test for variadic commands --- features/validation.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/validation.feature b/features/validation.feature index 683fe735fa..cc28649327 100644 --- a/features/validation.feature +++ b/features/validation.feature @@ -3,6 +3,15 @@ Feature: Argument validation As a user I need to see warnings and errors when I pass incorrect arguments + Scenario: Passing zero arguments to a variadic command + Given a WP install + + When I run `wp plugin install` + Then STDOUT should contain: + """ + usage: wp plugin install + """ + Scenario: Validation for early commands Given an empty directory And WP files From 6dec5cb7aea69dc4aa0e7586f2c16732aefab6b0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 27 Aug 2013 23:30:34 +0300 Subject: [PATCH 2261/4858] don't ignore repeating arguments in enough_positionals() check --- php/WP_CLI/SynopsisValidator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index bee3f1920c..300dd67a47 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -23,7 +23,6 @@ public function enough_positionals( $args ) { $positional = $this->query_spec( array( 'type' => 'positional', 'optional' => false, - 'repeating' => false ) ); return count( $args ) >= count( $positional ); From 49e7d2e6076276ef73122a1d6b34e552a68d6a52 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 28 Aug 2013 00:10:51 +0300 Subject: [PATCH 2262/4858] media regenerate: attachment IDs are optional --- php/commands/media.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index aaa7c08fe2..719170c3c9 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -24,18 +24,15 @@ class Media_Command extends WP_CLI_Command { * * wp media regenerate --yes * - * @synopsis <attachment-id>... [--yes] + * @synopsis [<attachment-id>...] [--yes] */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; - // If id is given, skip confirm because it is only one file - if( !empty( $args ) ) { - $assoc_args['yes'] = true; + if ( empty( $args ) ) { + WP_CLI::confirm( 'Do you realy want to regenerate all images?', $assoc_args ); } - WP_CLI::confirm('Do you realy want to regenerate all images?', $assoc_args); - $query_args = array( 'post_type' => 'attachment', 'post__in' => $args, From a07738126eb7447ea53977d9cfa2fea3d75a387e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 28 Aug 2013 00:38:35 +0300 Subject: [PATCH 2263/4858] behat: remove unused 'I try to import it' step --- features/steps/basic_steps.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 5c699bf7ec..c08a64afa6 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -121,15 +121,6 @@ function ( $world, $mode ) { } ); -$steps->When( '/^I try to import it$/', - function ( $world ) { - if ( !isset( $world->variables['DOWNLOADED_IMAGE'] ) ) - throw new \Exception( 'Cached image not available.' ); - - $world->result = $world->proc( 'wp media import ' . $world->variables['DOWNLOADED_IMAGE'] . ' --post_id=1 --featured_image' )->run(); - } -); - $steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', function ( $world, $stream, $output_filter, $key ) { From bac228b347564760f0cf280cc91cb92c8251a3f8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 28 Aug 2013 00:55:29 +0300 Subject: [PATCH 2264/4858] usage errors exit with code 1 --- features/validation.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/validation.feature b/features/validation.feature index cc28649327..803d758af5 100644 --- a/features/validation.feature +++ b/features/validation.feature @@ -6,7 +6,8 @@ Feature: Argument validation Scenario: Passing zero arguments to a variadic command Given a WP install - When I run `wp plugin install` + When I try `wp plugin install` + Then the return code should be 1 Then STDOUT should contain: """ usage: wp plugin install From e5a743932c2697222db2098ef471abfcbea19e3c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 28 Aug 2013 01:28:56 +0300 Subject: [PATCH 2265/4858] behat: pass process result to checkString() for richer error messages --- features/bootstrap/Process.php | 3 ++- features/bootstrap/support.php | 6 ++++-- features/steps/basic_steps.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 16b248df42..e0abcffbe5 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -71,7 +71,8 @@ public function __construct( $props ) { } public function __toString() { - return sprintf( "%s: %s\ncwd: %s", $this->command, $this->STDERR, $this->cwd ); + return sprintf( "%s: %s\n" . "cwd: %s\n" . "exit status: %d", + $this->command, $this->STDERR, $this->cwd, $this->return_code ); } } diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index 7b77eb7d0a..afe96ec1d3 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -14,7 +14,7 @@ function assertNumeric( $actual ) { } } -function checkString( $output, $expected, $action ) { +function checkString( $output, $expected, $action, $message = false ) { switch ( $action ) { case 'be': @@ -34,7 +34,9 @@ function checkString( $output, $expected, $action ) { } if ( !$r ) { - throw new Exception( $output ); + if ( false === $message ) + $message = $output; + throw new Exception( $message ); } } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index c08a64afa6..1557f91c0d 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -149,7 +149,7 @@ function ( $world, $return_code ) { function ( $world, $stream, $action, PyStringNode $expected ) { $expected = $world->replace_variables( (string) $expected ); - checkString( $world->result->$stream, $expected, $action ); + checkString( $world->result->$stream, $expected, $action, $world->result ); } ); From 7a983d338dc8a841a536613ba0ac0caf6079e277 Mon Sep 17 00:00:00 2001 From: = <stianlik@gmail.com> Date: Wed, 28 Aug 2013 12:37:17 +0200 Subject: [PATCH 2266/4858] Support for whitespace in file path --- bin/wp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bin/wp b/bin/wp index 762d6f5d91..4974e1887e 100755 --- a/bin/wp +++ b/bin/wp @@ -7,8 +7,8 @@ # https://github.com/88mph/wpadmin/blob/master/wpadmin.php # Get the absolute path of this executable -ORIGDIR=$(pwd) -SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0") +ORIGDIR="$(pwd)" +SELF_PATH="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" && SELF_PATH="$SELF_PATH/$(basename -- "$0")" # Resolve symlinks - this is the equivalent of "readlink -f", but also works with non-standard OS X readlink. while [ -h "$SELF_PATH" ]; do @@ -16,18 +16,18 @@ while [ -h "$SELF_PATH" ]; do # 2) cd to the directory of where the symlink points # 3) Get the pwd # 4) Append the basename - DIR=$(dirname -- "$SELF_PATH") - SYM=$(readlink $SELF_PATH) - SELF_PATH=$(cd $DIR && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM") + DIR="$(dirname -- "$SELF_PATH")" + SYM="$(readlink "$SELF_PATH")" + SELF_PATH="$(cd "$DIR" && cd "$(dirname -- "$SYM")" && pwd)/$(basename -- "$SYM")" done cd "$ORIGDIR" # Build the path to the root PHP file -SCRIPT_PATH=$(dirname "$SELF_PATH")/../php/boot-fs.php +SCRIPT_PATH="$(dirname "$SELF_PATH")/../php/boot-fs.php" case $(uname -a) in CYGWIN*) - SCRIPT_PATH=$(cygpath -w -a -- "$SCRIPT_PATH") ;; + SCRIPT_PATH="$(cygpath -w -a -- "$SCRIPT_PATH")" ;; esac if [ ! -z "$WP_CLI_PHP" ] ; then @@ -36,11 +36,11 @@ if [ ! -z "$WP_CLI_PHP" ] ; then else # Default to using the php that we find on the PATH. # Note that we need the full path to php here for Dreamhost, which behaves oddly. See http://drupal.org/node/662926 - php=`which php` + php="`which php`" fi # Pass in the path to php so that wp-cli knows which one # to use if it re-launches itself to run subcommands -export WP_CLI_PHP_USED=$php +export WP_CLI_PHP_USED="$php" exec "$php" $WP_CLI_PHP_ARGS "$SCRIPT_PATH" "$@" From 6b268f677298779985db9c7cc460af636a6bfc63 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Aug 2013 11:36:56 -0700 Subject: [PATCH 2267/4858] Support arbitrary filters when listing users --- php/commands/user.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 2e6454a118..8cce7cdfae 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -25,6 +25,9 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * * --role=<role> * : Only display users with a certain role. + * + * * --<field>=<value> + * : Filter by one or more fields. For accepted fields, see get_users(). * * --fields=<fields> * : Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles @@ -41,7 +44,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * wp user list --fields=display_name,user_email * * @subcommand list - * @synopsis [--role=<role>] [--fields=<fields>] [--format=<format>] + * @synopsis [--role=<role>] [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { From fbc41b535c72765de92bd744fb06b1a03bc9d262 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Aug 2013 11:41:07 -0700 Subject: [PATCH 2268/4858] Support arbitrary filtering when listing terms --- php/commands/term.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index 43539574cc..415feb5d35 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -23,6 +23,9 @@ class Term_Command extends WP_CLI_Command { * * <taxonomy> * : List terms of a given taxonomy. + * + * --<field>=<value> + * : Filter by one or more fields. For accepted fields, see get_terms(). * * --fields=<fields> * : Limit the output to specific object fields. Defaults to all of the term object fields. @@ -37,7 +40,7 @@ class Term_Command extends WP_CLI_Command { * wp term list post_tag --fields=name,slug * * @subcommand list - * @synopsis <taxonomy> [--fields=<fields>] [--format=<format>] + * @synopsis <taxonomy> [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { From 74e2f4b25450bc3a463081489be29612680a06a7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Aug 2013 13:51:34 -0700 Subject: [PATCH 2269/4858] Fix erroneous error --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 8cce7cdfae..9674f5e9fb 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -588,7 +588,7 @@ public function import_csv( $args, $assoc_args ) { $filename = $args[0]; if ( ! file_exists( $filename ) ) { - WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); + WP_CLI::warning( sprintf( "Missing file: %s", $filename ) ); } foreach ( new \WP_CLI\Iterators\CSV( $filename ) as $i => $new_user ) { From 7ceea7cf596a2de6a79702819b73a9e077cb35c5 Mon Sep 17 00:00:00 2001 From: Nate Bedortha <nate@oknoway.com> Date: Fri, 30 Aug 2013 01:50:29 -0700 Subject: [PATCH 2270/4858] Fix small typo --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 173ad2d136..94fcaeb4e1 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -406,7 +406,7 @@ private function export_wp( $args = array() ) { ob_end_clean(); WP_CLI::line( 'Exporting ' . count( $all_the_post_ids ) . ' items to be broken into ' . ceil( count( $all_the_post_ids ) / $args['file_item_count'] ) . ' files' ); - WP_CLI::line( 'Exporting ' . count( $cats ) . ' cateogries' ); + WP_CLI::line( 'Exporting ' . count( $cats ) . ' categories' ); WP_CLI::line( 'Exporting ' . count( $tags ) . ' tags' ); WP_CLI::line( 'Exporting ' . count( $terms ) . ' terms' ); WP_CLI::line(); From 0bbf67912bde8a24d62bd73dc2d4bad7b3da0e9a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 30 Aug 2013 16:46:07 +0300 Subject: [PATCH 2271/4858] first pass at making plugin {activate|deactivate|toggle} accept multiple items --- php/commands/plugin.php | 80 +++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 9611905bd6..0cc5914109 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -144,23 +144,26 @@ protected function get_all_items() { * --network * : If set, the plugin will be activated for the entire multisite network. * - * @synopsis <plugin> [--network] + * @synopsis <plugin>... [--network] */ function activate( $args, $assoc_args = array() ) { - $name = $args[0]; - $file = $this->parse_name( $name ); - $network_wide = isset( $assoc_args['network'] ); - activate_plugin( $file, '', $network_wide ); + foreach ( $args as $name ) { + $file = $this->parse_name( $name ); + if ( !$file ) + continue; - if ( $this->check_active( $file, $network_wide ) ) { - if ( $network_wide ) - WP_CLI::success( "Plugin '$name' network activated." ); - else - WP_CLI::success( "Plugin '$name' activated." ); - } else { - WP_CLI::error( 'Could not activate plugin: ' . $name ); + activate_plugin( $file, '', $network_wide ); + + if ( $this->check_active( $file, $network_wide ) ) { + if ( $network_wide ) + WP_CLI::success( "Plugin '$name' network activated." ); + else + WP_CLI::success( "Plugin '$name' activated." ); + } else { + WP_CLI::warning( 'Could not activate plugin: ' . $name ); + } } } @@ -175,23 +178,26 @@ function activate( $args, $assoc_args = array() ) { * --network * : If set, the plugin will be deactivated for the entire multisite network. * - * @synopsis <plugin> [--network] + * @synopsis <plugin>... [--network] */ function deactivate( $args, $assoc_args = array() ) { - $name = $args[0]; - $file = $this->parse_name( $name ); - $network_wide = isset( $assoc_args['network'] ); - deactivate_plugins( $file, false, $network_wide ); + foreach ( $args as $name ) { + $file = $this->parse_name( $name ); + if ( !$file ) + continue; - if ( ! $this->check_active( $file, $network_wide ) ) { - if ( $network_wide ) - WP_CLI::success( "Plugin '$name' network deactivated." ); - else - WP_CLI::success( "Plugin '$name' deactivated." ); - } else { - WP_CLI::error( 'Could not deactivate plugin: ' . $name ); + deactivate_plugins( $file, false, $network_wide ); + + if ( ! $this->check_active( $file, $network_wide ) ) { + if ( $network_wide ) + WP_CLI::success( "Plugin '$name' network deactivated." ); + else + WP_CLI::success( "Plugin '$name' deactivated." ); + } else { + WP_CLI::warning( 'Could not deactivate plugin: ' . $name ); + } } } @@ -206,18 +212,21 @@ function deactivate( $args, $assoc_args = array() ) { * --network * : If set, the plugin will be toggled for the entire multisite network. * - * @synopsis <plugin> [--network] + * @synopsis <plugin>... [--network] */ function toggle( $args, $assoc_args = array() ) { - $name = $args[0]; - $file = $this->parse_name( $name ); - $network_wide = isset( $assoc_args['network'] ); - if ( $this->check_active( $file, $network_wide ) ) { - $this->deactivate( $args, $assoc_args ); - } else { - $this->activate( $args, $assoc_args ); + foreach ( $args as $name ) { + $file = $this->parse_name( $name ); + if ( !$file ) + continue; + + if ( $this->check_active( $file, $network_wide ) ) { + $this->deactivate( array( $name ), $assoc_args ); + } else { + $this->activate( array( $name ), $assoc_args ); + } } } @@ -245,6 +254,9 @@ function path( $args, $assoc_args ) { if ( !empty( $args ) ) { $file = $this->parse_name( $args[0] ); + if ( !$file ) + return; + $path .= '/' . $file; if ( isset( $assoc_args['dir'] ) ) @@ -538,8 +550,8 @@ private function parse_name( $name ) { if ( $file = $this->_parse_name( $name ) ) { return $file; } else { - WP_CLI::error( "The plugin '$name' could not be found." ); - exit(); + WP_CLI::warning( "The plugin '$name' could not be found." ); + return false; } } From 3c701e568c4483d824d9b96efa923a91204c4472 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 30 Aug 2013 18:12:53 +0300 Subject: [PATCH 2272/4858] replace parse_name() with validate_plugin_names(). --- features/plugin.feature | 10 +-- php/WP_CLI/CommandWithUpgrade.php | 7 ++ php/commands/plugin.php | 133 +++++++++++++++--------------- 3 files changed, 76 insertions(+), 74 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 299a116d45..26bd999c16 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -44,10 +44,9 @@ Feature: Manage WordPress plugins | zombieland | active | none | 0.1-alpha | When I try `wp plugin uninstall zombieland` - Then the return code should be 1 - And STDERR should contain: + Then STDERR should contain: """ - The plugin is active. + The 'zombieland' plugin is active. """ When I run `wp plugin deactivate zombieland` @@ -61,10 +60,9 @@ Feature: Manage WordPress plugins And the {PLUGIN_DIR}/zombieland file should not exist When I try the previous command again - Then the return code should be 1 - And STDERR should contain: + Then STDERR should contain: """ - The plugin 'zombieland' could not be found. + The 'zombieland' plugin could not be found. """ Scenario: Install a plugin, activate, then force install an older version of the plugin diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index d1a327c10a..04d365dec4 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -11,7 +11,14 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { abstract protected function get_upgrader_class( $force ); abstract protected function get_item_list(); + + /** + * @param array List of update candidates + * @param array List of item names + * @return array List of update candidates + */ abstract protected function filter_item_list( $items, $args ); + abstract protected function get_all_items(); abstract protected function get_status( $file ); diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 0cc5914109..5aeeed7986 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -97,20 +97,23 @@ public function search( $args, $assoc_args = array() ) { } protected function status_single( $args ) { - $name = $args[0]; - $file = $this->parse_name( $name ); + $plugins = $this->validate_plugin_names( $args ); + if ( empty( $plugins ) ) + exit(1); - $details = $this->get_details( $file ); + list( $plugin ) = $plugins; - $status = $this->format_status( $this->get_status( $file ), 'long' ); + $details = $this->get_details( $plugin->file ); - $version = $details[ 'Version' ]; + $status = $this->format_status( $this->get_status( $plugin->file ), 'long' ); - if ( $this->has_update( $file ) ) + $version = $details['Version']; + + if ( $this->has_update( $plugin->file ) ) $version .= ' (%gUpdate available%n)'; echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'plugin-status.mustache', array( - 'slug' => $name, + 'slug' => $plugin->name, 'status' => $status, 'version' => $version, 'name' => $details['Name'], @@ -149,20 +152,16 @@ protected function get_all_items() { function activate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - foreach ( $args as $name ) { - $file = $this->parse_name( $name ); - if ( !$file ) - continue; - - activate_plugin( $file, '', $network_wide ); + foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + activate_plugin( $plugin->file, '', $network_wide ); - if ( $this->check_active( $file, $network_wide ) ) { + if ( $this->check_active( $plugin->file, $network_wide ) ) { if ( $network_wide ) - WP_CLI::success( "Plugin '$name' network activated." ); + WP_CLI::success( "Plugin '{$plugin->name}' network activated." ); else - WP_CLI::success( "Plugin '$name' activated." ); + WP_CLI::success( "Plugin '{$plugin->name}' activated." ); } else { - WP_CLI::warning( 'Could not activate plugin: ' . $name ); + WP_CLI::warning( "Could not activate the '{$plugin->name}' plugin." ); } } } @@ -183,20 +182,16 @@ function activate( $args, $assoc_args = array() ) { function deactivate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - foreach ( $args as $name ) { - $file = $this->parse_name( $name ); - if ( !$file ) - continue; - - deactivate_plugins( $file, false, $network_wide ); + foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + deactivate_plugins( $plugin->file, false, $network_wide ); - if ( ! $this->check_active( $file, $network_wide ) ) { + if ( ! $this->check_active( $plugin->file, $network_wide ) ) { if ( $network_wide ) - WP_CLI::success( "Plugin '$name' network deactivated." ); + WP_CLI::success( "Plugin '{$plugin->name}' network deactivated." ); else - WP_CLI::success( "Plugin '$name' deactivated." ); + WP_CLI::success( "Plugin '{$plugin->name}' deactivated." ); } else { - WP_CLI::warning( 'Could not deactivate plugin: ' . $name ); + WP_CLI::warning( "Could not deactivate the '{$plugin->name}' plugin." ); } } } @@ -217,15 +212,11 @@ function deactivate( $args, $assoc_args = array() ) { function toggle( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - foreach ( $args as $name ) { - $file = $this->parse_name( $name ); - if ( !$file ) - continue; - - if ( $this->check_active( $file, $network_wide ) ) { - $this->deactivate( array( $name ), $assoc_args ); + foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + if ( $this->check_active( $plugin->file, $network_wide ) ) { + $this->deactivate( array( $plugin->name ), $assoc_args ); } else { - $this->activate( array( $name ), $assoc_args ); + $this->activate( array( $plugin->name ), $assoc_args ); } } } @@ -253,11 +244,13 @@ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); if ( !empty( $args ) ) { - $file = $this->parse_name( $args[0] ); - if ( !$file ) + $plugins = $this->validate_plugin_names( $args ); + if ( empty( $plugins ) ) return; - $path .= '/' . $file; + list( $plugin ) = $plugins; + + $path .= '/' . $plugin->file; if ( isset( $assoc_args['dir'] ) ) $path = dirname( $path ); @@ -318,9 +311,9 @@ protected function install_from_repo( $slug, $assoc_args ) { */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { - foreach ( $args as $arg ) { - $this->_delete( $this->parse_name( $arg ) ); - $this->install( array( $arg ), $assoc_args ); + foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + $this->_delete( $plugin->file ); + $this->install( array( $plugin->name ), $assoc_args ); } } else { parent::update_many( $args, $assoc_args ); @@ -344,7 +337,7 @@ protected function get_item_list() { } protected function filter_item_list( $items, $args ) { - $basenames = array_map( array( $this, 'parse_name' ), $args ); + $basenames = wp_list_pluck( $this->validate_plugin_names( $args ), 'file' ); return \WP_CLI\Utils\pick_fields( $items, $basenames ); } @@ -403,27 +396,23 @@ function install( $args, $assoc_args ) { * * wp plugin uninstall hello * - * @synopsis <plugin> [--no-delete] + * @synopsis <plugin>... [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { - $name = $args[0]; - $file = $this->parse_name( $name ); - - if ( is_plugin_active( $file ) ) { - WP_CLI::error( 'The plugin is active.' ); - } - - uninstall_plugin( $file ); + foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + if ( is_plugin_active( $plugin->file ) ) { + WP_CLI::warning( "The '{$plugin->name}' plugin is active." ); + continue; + } - if ( isset( $assoc_args['no-delete'] ) ) - return; + uninstall_plugin( $plugin->file ); - if ( $this->_delete( $file ) ) { - WP_CLI::success( sprintf( "Uninstalled '%s' plugin.", $name ) ); + if ( !isset( $assoc_args['no-delete'] ) && $this->_delete( $plugin->file ) ) { + WP_CLI::success( "Uninstalled '$plugin->name' plugin." ); + } } } - /** * Check if the plugin is installed * @@ -459,14 +448,13 @@ function is_installed( $args, $assoc_args = array() ) { * * wp plugin delete hello * - * @synopsis <plugin> + * @synopsis <plugin>... */ function delete( $args, $assoc_args = array() ) { - $name = $args[0]; - $file = $this->parse_name( $name ); - - if ( $this->_delete( $file ) ) { - WP_CLI::success( sprintf( "Deleted '%s' plugin.", $name ) ); + foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + if ( $this->_delete( $plugin->file ) ) { + WP_CLI::success( "Deleted '{$plugin->name}' plugin." ); + } } } @@ -546,13 +534,22 @@ private function _parse_name( $name ) { return $file; } - private function parse_name( $name ) { - if ( $file = $this->_parse_name( $name ) ) { - return $file; - } else { - WP_CLI::warning( "The plugin '$name' could not be found." ); - return false; + private function validate_plugin_names( $args ) { + $plugins = array(); + + foreach ( $args as $name ) { + $file = $this->_parse_name( $name ); + if ( $file ) { + $plugins[] = (object) array( + 'name' => $name, + 'file' => $file + ); + } else { + WP_CLI::warning( "The '$name' plugin could not be found." ); + } } + + return $plugins; } /** From c4f01fa50a40ab6624c84aeb9d1d9746f45f4118 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 30 Aug 2013 19:22:07 +0300 Subject: [PATCH 2273/4858] make _delete() accept a plugin object --- php/commands/plugin.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 5aeeed7986..e217d751e7 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -312,7 +312,7 @@ protected function install_from_repo( $slug, $assoc_args ) { function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { foreach ( $this->validate_plugin_names( $args ) as $plugin ) { - $this->_delete( $plugin->file ); + $this->_delete( $plugin ); $this->install( array( $plugin->name ), $assoc_args ); } } else { @@ -407,7 +407,7 @@ function uninstall( $args, $assoc_args = array() ) { uninstall_plugin( $plugin->file ); - if ( !isset( $assoc_args['no-delete'] ) && $this->_delete( $plugin->file ) ) { + if ( !isset( $assoc_args['no-delete'] ) && $this->_delete( $plugin ) ) { WP_CLI::success( "Uninstalled '$plugin->name' plugin." ); } } @@ -452,7 +452,7 @@ function is_installed( $args, $assoc_args = array() ) { */ function delete( $args, $assoc_args = array() ) { foreach ( $this->validate_plugin_names( $args ) as $plugin ) { - if ( $this->_delete( $plugin->file ) ) { + if ( $this->_delete( $plugin ) ) { WP_CLI::success( "Deleted '{$plugin->name}' plugin." ); } } @@ -564,8 +564,8 @@ private function get_name( $file ) { return $name; } - private function _delete( $file ) { - $plugin_dir = dirname( $file ); + private function _delete( $plugin ) { + $plugin_dir = dirname( $plugin->file ); if ( '.' == $plugin_dir ) $plugin_dir = $file; From 84b1fb5123f54a9de6cc381454aa025686af7e93 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 30 Aug 2013 19:24:44 +0300 Subject: [PATCH 2274/4858] make get_details() accept a plugin object --- php/commands/plugin.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e217d751e7..8348f9334a 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -103,7 +103,7 @@ protected function status_single( $args ) { list( $plugin ) = $plugins; - $details = $this->get_details( $plugin->file ); + $details = $this->get_details( $plugin ); $status = $this->format_status( $this->get_status( $plugin->file ), 'long' ); @@ -497,14 +497,16 @@ protected function get_status( $file ) { } /** - * Get the details of a plugin + * Get the details of a plugin. * - * @param string $file + * @param object * @return array */ - protected function get_details( $file ) { + private function get_details( $plugin ) { + $file = $plugin->file; + $plugin_folder = get_plugins( '/' . plugin_basename( dirname( $file ) ) ); - $plugin_file = basename( ( $file ) ); + $plugin_file = basename( $file ); return $plugin_folder[$plugin_file]; } From 59f72ed557b536fe95ffc2ff78483f1505ae6f94 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 30 Aug 2013 19:39:42 +0300 Subject: [PATCH 2275/4858] clean up _search() helper: * replace <plugin>/<theme> in synopsis with <search> * check is_wp_error() before using $api * rename $data to $items * remove unused code for --interactive; no point supporting it if it's not functional yet see #630 --- php/WP_CLI/CommandWithUpgrade.php | 36 ++++++++++--------------------- php/commands/plugin.php | 18 ++++++++++------ php/commands/theme.php | 19 +++++++++------- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 04d365dec4..db20e649aa 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -321,7 +321,7 @@ private function get_color( $status ) { } /** - * Search wordpress.org plugin repo + * Search wordpress.org repo. * * @param object $api Data from WP plugin/theme API * @param array $fields Data fields to display in table. @@ -329,38 +329,24 @@ private function get_color( $status ) { * @param string $data_type Plugin or Theme api endpoint */ protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { + if ( is_wp_error( $api ) ) + \WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); // Sanitize to 1 of 2 types - $data_type = 'plugin' === $data_type ? 'plugin' : 'theme'; + $data_type = ( 'plugin' === $data_type ) ? 'plugin' : 'theme'; $plural = $data_type . 's'; - $data = $api->$plural; - $count = isset( $api->info['results'] ) ? $api->info['results'] : 'unknown'; - - if ( is_wp_error( $api ) ) - \WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); - if ( ! isset( $data ) ) + if ( ! isset( $api->$plural ) ) \WP_CLI::error( __( 'API error. Try Again.' ) ); - \WP_CLI::success( 'Showing '. count( $data ) .' of '. $count .' '. $plural .'.' ); - - $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; + $items = $api->$plural; - // @TODO https://github.com/wp-cli/wp-cli/issues/635 - if ( isset( $assoc_args['interactive'] ) ) { - // Add key as a field - $fields = array_merge( array( 'key' ), $fields ); - // & infuse object with $key - foreach ( $data as $key => $item ) { - $item->key = $key; - $data[$key] = $item; - } - } - - $fields = isset( $assoc_args['interactive'] ) ? array_merge( array( 'key' ), $fields ) : $fields; + $count = isset( $api->info['results'] ) ? $api->info['results'] : 'unknown'; + \WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) ); - \WP_CLI\Utils\format_items( $format, $data, $fields ); + $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; + \WP_CLI\Utils\format_items( $format, $items, $assoc_args['fields'] ); } - } + diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 8348f9334a..93cb0331e0 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -44,12 +44,12 @@ function status( $args ) { } /** - * Search wordpress.org plugin repo + * Search the wordpress.org plugin repository. * * ## OPTIONS * - * <plugin> - * : A particular plugin to search for. + * <search> + * : The string to search for. * * --per-page * : Optional number of results to display. Defaults to 10. @@ -81,15 +81,19 @@ function status( $args ) { * * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings * - * @synopsis <plugin> [--per-page=<per-page>] [--fields=<fields>] [--format=<format>] + * @synopsis <search> [--per-page=<per-page>] [--fields=<fields>] [--format=<format>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; - $per_page = isset( $assoc_args['per-page'] ) ? (int) $assoc_args['per-page'] : 10; - $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'rating' ); + + $defaults = array( + 'per-page' => 10, + 'fields' => array( 'name', 'slug', 'rating' ) + ); + $assoc_args = array_merge( $defaults, $assoc_args ); $api = plugins_api( 'query_plugins', array( - 'per_page' => $per_page, + 'per_page' => (int) $assoc_args['per-page'], 'search' => $term, ) ); diff --git a/php/commands/theme.php b/php/commands/theme.php index c64ac16955..d71cd53232 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -37,12 +37,12 @@ function status( $args ) { } /** - * Search wordpress.org theme repo + * Search the wordpress.org theme repository. * * ## OPTIONS * - * <theme> - * : A particular theme to search for. + * <search> + * : The string to search for. * * --per-page * : Optional number of results to display. Defaults to 10. @@ -67,20 +67,23 @@ function status( $args ) { * * wp theme search automattic --fields=name,version,slug,rating,num_ratings,description * - * @synopsis <theme> [--per-page=<per-page>] [--fields=<fields>] + * @synopsis <search> [--per-page=<per-page>] [--fields=<fields>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; - $per_page = isset( $assoc_args['per-page'] ) ? (int) $assoc_args['per-page'] : 10; - $fields = isset( $assoc_args['fields'] ) ? $assoc_args['fields'] : array( 'name', 'slug', 'author', 'rating' ); + + $defaults = array( + 'per-page' => 10, + 'fields' => array( 'name', 'slug', 'author', 'rating' ) + ); + $assoc_args = array_merge( $defaults, $assoc_args ); $api = themes_api( 'query_themes', array( - 'per_page' => $per_page, + 'per_page' => (int) $assoc_args['per-page'], 'search' => $term, ) ); parent::_search( $api, $fields, $assoc_args, 'theme' ); - } protected function status_single( $args ) { From 1c3f9e5b5a00a9ba976572e736b47c8f28808d9a Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Thu, 5 Sep 2013 17:05:45 -0700 Subject: [PATCH 2276/4858] Specify DB_CHARSET as default-character-set for wp-db-import A DB export followed by a DB import of the same file was resulting in corrupted UTF-8 characters. The script was being run in the varying-vagrant-vagrants environment which has latin1 as the default charset: mysql> show variables like "character_set_%"; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ --- php/commands/db.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/db.php b/php/commands/db.php index 0f2be91f27..2068248fa1 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -167,6 +167,7 @@ private static function run( $cmd, $assoc_args = array(), $descriptors = null ) 'host' => DB_HOST, 'user' => DB_USER, 'pass' => DB_PASSWORD, + 'default-character-set' => DB_CHARSET, ) ); Utils\run_mysql_command( $cmd, $final_args, $descriptors ); From 7a2fb31fca5022d4cfa82b895b7418575ef79523 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Sep 2013 19:11:05 +0300 Subject: [PATCH 2277/4858] don't pass the message through colorization; only the label fixes #744 --- php/WP_CLI/Loggers/Regular.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index b33a7f84b9..56c63f564e 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -4,8 +4,8 @@ class Regular { - private function _line( $message, $handle = STDOUT ) { - fwrite( $handle, \WP_CLI::colorize( $message . "\n" ) ); + private function _line( $message, $label, $color, $handle = STDOUT ) { + fwrite( $handle, \WP_CLI::colorize( "$color$label:%n" ) . " $message\n" ); } function info( $message ) { @@ -13,16 +13,15 @@ function info( $message ) { } function success( $message, $label ) { - $this->_line( "%G$label:%n $message" ); + $this->_line( $message, $label, '%G' ); } function warning( $message, $label ) { - $this->_line( "%C$label:%n $message", STDERR ); + $this->_line( $message, $label, '%C', STDERR ); } function error( $message, $label ) { - $msg = '%R' . $label . ': %n' . $message; - $this->_line( $msg, STDERR ); + $this->_line( $message, $label, '%R', STDERR ); } } From 8ee1854dd766187e0234490549b1664c3de8937b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Sep 2013 19:27:01 +0300 Subject: [PATCH 2278/4858] remove $label parameter from logging methods The label text and color are just a way to signal to the user the type of message. Changing it can lead to confusion. Example: WP_CLI::error( 'Something bad happened!', 'Success' ); --- php/WP_CLI/Loggers/Quiet.php | 8 ++++---- php/WP_CLI/Loggers/Regular.php | 12 ++++++------ php/class-wp-cli.php | 15 ++++++--------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 926986c5e3..6f32fbef33 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -8,16 +8,16 @@ function info( $message ) { // nothing } - function success( $message, $label ) { + function success( $message ) { // nothing } - function warning( $message, $label ) { + function warning( $message ) { // nothing } - function error( $message, $label ) { - fwrite( STDERR, \WP_CLI::colorize( "%R$label:%n $message\n" ) ); + function error( $message ) { + fwrite( STDERR, \WP_CLI::colorize( "%RError:%n $message\n" ) ); } } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index 56c63f564e..b992faa1e2 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -12,16 +12,16 @@ function info( $message ) { fwrite( STDOUT, $message . "\n" ); } - function success( $message, $label ) { - $this->_line( $message, $label, '%G' ); + function success( $message ) { + $this->_line( $message, 'Success', '%G' ); } - function warning( $message, $label ) { - $this->_line( $message, $label, '%C', STDERR ); + function warning( $message ) { + $this->_line( $message, 'Warning', '%C', STDERR ); } - function error( $message, $label ) { - $this->_line( $message, $label, '%R', STDERR ); + function error( $message ) { + $this->_line( $message, 'Error', '%R', STDERR ); } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index da3a32be62..67d06ea43c 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -120,31 +120,28 @@ static function log( $message ) { * Display a success in the CLI and end with a newline * * @param string $message - * @param string $label */ - static function success( $message, $label = 'Success' ) { - self::$logger->success( $message, $label ); + static function success( $message ) { + self::$logger->success( $message ); } /** * Display a warning in the CLI and end with a newline * * @param string $message - * @param string $label */ - static function warning( $message, $label = 'Warning' ) { - self::$logger->warning( self::error_to_string( $message ), $label ); + static function warning( $message ) { + self::$logger->warning( self::error_to_string( $message ) ); } /** * Display an error in the CLI and end with a newline * * @param string $message - * @param string $label */ - static function error( $message, $label = 'Error' ) { + static function error( $message ) { if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) ) { - self::$logger->error( self::error_to_string( $message ), $label ); + self::$logger->error( self::error_to_string( $message ) ); } exit(1); From 7c86825b63cfb0a273ec9e70cf019dce2304efc1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Sep 2013 19:54:53 +0300 Subject: [PATCH 2279/4858] add unit test for regular logger --- php/WP_CLI/Loggers/Regular.php | 13 +++++++++++-- php/WP_CLI/Runner.php | 2 +- tests/test-logging.php | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 tests/test-logging.php diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index b992faa1e2..b3ad21213c 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -4,12 +4,21 @@ class Regular { + function __construct( $in_color ) { + $this->in_color = $in_color; + } + + protected function write( $handle, $str ) { + fwrite( $handle, $str ); + } + private function _line( $message, $label, $color, $handle = STDOUT ) { - fwrite( $handle, \WP_CLI::colorize( "$color$label:%n" ) . " $message\n" ); + $label = \cli\Colors::colorize( "$color$label:%n", $this->in_color ); + $this->write( $handle, "$label $message\n" ); } function info( $message ) { - fwrite( STDOUT, $message . "\n" ); + $this->write( STDOUT, $message . "\n" ); } function success( $message ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9dab776d78..a81e0d5a8f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -338,7 +338,7 @@ private function init_logger() { if ( $this->config['quiet'] ) $logger = new \WP_CLI\Loggers\Quiet; else - $logger = new \WP_CLI\Loggers\Regular; + $logger = new \WP_CLI\Loggers\Regular( $this->in_color() ); WP_CLI::set_logger( $logger ); } diff --git a/tests/test-logging.php b/tests/test-logging.php new file mode 100644 index 0000000000..02899d9a8e --- /dev/null +++ b/tests/test-logging.php @@ -0,0 +1,22 @@ +<?php + +class LoggerMock extends WP_CLI\Loggers\Regular { + + protected function write( $handle, $str ) { + echo $str; + } +} + + +class LoggingTests extends PHPUnit_Framework_TestCase { + + function testLogEscaping() { + $logger = new LoggerMock( false ); + + $message = 'foo%20bar'; + + $this->expectOutputString( "Success: $message\n" ); + $logger->success( $message ); + } +} + From 78782996e2870d927582e619cbd141984a314e13 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 6 Sep 2013 21:46:19 +0300 Subject: [PATCH 2280/4858] fix usage of $label parameter in WP_CLI::error() --- php/WP_CLI/Dispatcher/Subcommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 8dca6c6d33..c5d4c0c199 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -161,12 +161,12 @@ private function validate_args( $args, &$assoc_args ) { $errors = $parser->validate_assoc( $assoc_args, array_keys( \WP_CLI::get_config() ) ); if ( !empty( $errors['fatal'] ) ) { - $out = ''; + $out = 'Parameter errors:'; foreach ( $errors['fatal'] as $error ) { $out .= "\n " . $error; } - \WP_CLI::error( $out, "Parameter errors" ); + \WP_CLI::error( $out ); } array_map( '\\WP_CLI::warning', $errors['warning'] ); From 7856b70d154418b27cd4e9377e01de446ae9e65d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 10 Sep 2013 21:25:35 +0300 Subject: [PATCH 2281/4858] make 'update --all' work again and add test --- features/upgradables.feature | 3 +++ php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 023f6fee36..b7d1a34788 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -31,6 +31,9 @@ Feature: Manage WordPress themes and plugins When I run `wp <type> update <item>` Then STDOUT should not be empty + When I run `wp <type> update --all` + Then STDOUT should not be empty + When I run `wp <type> status <item>` Then STDOUT should not contain: """ diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 93cb0331e0..ff1784ebfc 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -311,7 +311,7 @@ protected function install_from_repo( $slug, $assoc_args ) { * * wp plugin update --all * - * @synopsis <plugin>... [--version=<version>] [--all] [--dry-run] + * @synopsis [<plugin>...] [--version=<version>] [--all] [--dry-run] */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index d71cd53232..4a8293b82d 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -335,7 +335,7 @@ public function get( $args, $assoc_args ) { * * wp theme update --all * - * @synopsis <theme>... [--version=<version>] [--all] [--dry-run] + * @synopsis [<theme>...] [--version=<version>] [--all] [--dry-run] */ function update( $args, $assoc_args ) { parent::update_many( $args, $assoc_args ); From 819665c338a006334dd16d16ef527ec0263820c2 Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Tue, 10 Sep 2013 11:56:45 -0700 Subject: [PATCH 2282/4858] wp core config: Add dbcharset and dbcollate params Allow dbcharset and dbcollate to be set on config to avoid character set problems during migrations --- php/commands/core.php | 12 ++++++++++-- templates/wp-config.mustache | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 0bfc0d04f7..5fb0c4632d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -148,12 +148,18 @@ private static function get_initial_locale() { * --dbprefix=<dbprefix> * : Set the database table prefix. Default: 'wp_' * + * --dbcharset=<dbcharset> + * : Set the database charset. Default: 'utf8' + * + * --dbcollate=<dbcollate> + * : Set the database collation. Default: '' + * * --locale=<locale> * : Set the WPLANG constant. Defaults to $wp_local_package variable. * * --extra-php * : If set, the command reads additional PHP code from STDIN. - * + * * --skip-salts * : If set, keys and salts won't be generated, but, instead, should be passed via --extra-php. * @@ -168,7 +174,7 @@ private static function get_initial_locale() { * define( 'WP_DEBUG_LOG', true ); * PHP * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--locale=<locale>] [--extra-php] [--skip-salts] + * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--dbcharset=<charset>] [--dbcollate=<collation>] [--locale=<locale>] [--extra-php] [--skip-salts] */ public function config( $_, $assoc_args ) { if ( Utils\locate_wp_config() ) { @@ -179,6 +185,8 @@ public function config( $_, $assoc_args ) { 'dbhost' => 'localhost', 'dbpass' => '', 'dbprefix' => 'wp_', + 'dbcharset' => 'utf8', + 'dbcollate' => '', 'locale' => self::get_initial_locale() ); $assoc_args = array_merge( $defaults, $assoc_args ); diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index 20b4b6b33e..d0cec68c14 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -23,10 +23,10 @@ define('DB_PASSWORD', '{{dbpass}}'); define('DB_HOST', '{{dbhost}}'); /** Database Charset to use in creating database tables. */ -define('DB_CHARSET', 'utf8'); +define('DB_CHARSET', '{{dbcharset}}'); /** The Database Collate type. Don't change this if in doubt. */ -define('DB_COLLATE', ''); +define('DB_COLLATE', '{{dbcollate}}'); {{#keys-and-salts}} /**#@+ From a9adf7b78bcefe3b5db03e167f53c6263dab1549 Mon Sep 17 00:00:00 2001 From: smhmic <smhmic@gmail.com> Date: Tue, 10 Sep 2013 15:29:23 -0400 Subject: [PATCH 2283/4858] allow (but ignore) a leading "[no-]" before flag name in @synopsis `no-` prefix on flag name sets it to `false`, but there was no valid way to show this in usage synopsis. Showing this is relevant for flags with a dynamic default value (like `--color` config flag). This change makes `@synopsis [--[no-]flag]` valid. --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 1da1504ef5..37cc3aca03 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -44,7 +44,7 @@ private static function classify_token( $token ) { $param['type'] = 'generic'; } elseif ( preg_match( "/^<$p_value>$/", $token, $matches ) ) { $param['type'] = 'positional'; - } elseif ( preg_match( "/^--$p_name/", $token, $matches ) ) { + } elseif ( preg_match( "/^--(?:\\[no-\\])?$p_name/", $token, $matches ) ) { $param['name'] = $matches[1]; $value = substr( $token, strlen( $matches[0] ) ); From fb803a141ad53271faf413657631c351c3c1fa73 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 11 Sep 2013 16:40:34 +0300 Subject: [PATCH 2284/4858] mention dev-build in README. fixes #757 --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 83a5f567d3..b6f4de5557 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,12 @@ WP-CLI WP-CLI is a set of command-line tools for managing WordPress installations. +Installation +------------ +If you just want to use WP-CLI, see <http://wp-cli.org/#install>. + +If you want to hack on WP-CLI, then clone this repository and run `./utils/dev-build`. + Where can I get more info? -------------------------- For documentation, usage, and examples, check out [wp-cli.org](http://wp-cli.org/). From 9a30af2cbe8a724a957fd3c97166cc595d4024b0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 12 Sep 2013 00:31:27 +0300 Subject: [PATCH 2285/4858] first pass at extracting synopsis from longdesc --- php/WP_CLI/Dispatcher/Subcommand.php | 13 +++++++++++-- php/commands/core.php | 8 +++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index c5d4c0c199..e51f1f7020 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -12,12 +12,21 @@ class Subcommand extends CompositeCommand { private $when_invoked; function __construct( $parent, $name, $docparser, $when_invoked ) { + parent::__construct( $parent, $name, $docparser ); + $this->when_invoked = $when_invoked; - $this->synopsis = $docparser->get_synopsis(); $this->alias = $docparser->get_tag( 'alias' ); - parent::__construct( $parent, $name, $docparser ); + $this->synopsis = $docparser->get_synopsis(); + if ( !$this->synopsis && $this->longdesc ) { + $this->synopsis = self::extract_synopsis( $this->longdesc ); + } + } + + private static function extract_synopsis( $longdesc ) { + preg_match_all( '/(.+)\n:/', $longdesc, $matches ); + return implode( ' ', $matches[1] ); } function get_synopsis() { diff --git a/php/commands/core.php b/php/commands/core.php index 5fb0c4632d..8657cf8047 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -14,21 +14,19 @@ class Core_Command extends WP_CLI_Command { * * ## OPTIONS * - * --locale=<locale> + * [--locale=<locale>] * : Select which language you want to download. * - * --version=<version> + * [--version=<version>] * : Select which version you want to download. * - * --force + * [--force] * : Overwrites existing files, if present. * * ## EXAMPLES * * wp core download --version=3.3 * - * @synopsis [--locale=<locale>] [--version=<version>] [--path=<path>] [--force] - * * @when before_wp_load */ public function download( $args, $assoc_args ) { From eb84ccfbd390a970a6c765913bf99618901cb854 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 12 Sep 2013 01:34:39 +0300 Subject: [PATCH 2286/4858] remove synopsis tag from the rest of the core subcommands --- php/commands/core.php | 56 +++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8657cf8047..248f34d63a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -137,28 +137,28 @@ private static function get_initial_locale() { * --dbuser=<dbuser> * : Set the database user. * - * --dbpass=<dbpass> + * [--dbpass=<dbpass>] * : Set the database user password. * - * --dbhost=<dbhost> + * [--dbhost=<dbhost>] * : Set the database host. Default: 'localhost' * - * --dbprefix=<dbprefix> + * [--dbprefix=<dbprefix>] * : Set the database table prefix. Default: 'wp_' * - * --dbcharset=<dbcharset> + * [--dbcharset=<dbcharset>] * : Set the database charset. Default: 'utf8' * - * --dbcollate=<dbcollate> + * [--dbcollate=<dbcollate>] * : Set the database collation. Default: '' * - * --locale=<locale> + * [--locale=<locale>] * : Set the WPLANG constant. Defaults to $wp_local_package variable. * - * --extra-php + * [--extra-php] * : If set, the command reads additional PHP code from STDIN. * - * --skip-salts + * [--skip-salts] * : If set, keys and salts won't be generated, but, instead, should be passed via --extra-php. * * ## EXAMPLES @@ -171,8 +171,6 @@ private static function get_initial_locale() { * define( 'WP_DEBUG', true ); * define( 'WP_DEBUG_LOG', true ); * PHP - * - * @synopsis --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] [--dbprefix=<prefix>] [--dbcharset=<charset>] [--dbcollate=<collation>] [--locale=<locale>] [--extra-php] [--skip-salts] */ public function config( $_, $assoc_args ) { if ( Utils\locate_wp_config() ) { @@ -254,8 +252,6 @@ public function is_installed() { * * --admin_email=<email> * : The email address for the admin user. - * - * @synopsis --url=<url> --title=<site-title> --admin_user=<username> --admin_email=<email> --admin_password=<password> */ public function install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -270,19 +266,18 @@ public function install( $args, $assoc_args ) { * * ## OPTIONS * - * --title=<site-title> + * [--title=<network-title>] * : The title of the new network. * - * --base=<url-path> + * [--base=<url-path>] * : Base path after the domain name that each site url will start with. * Default: '/' * - * --subdomains + * [--subdomains] * : If passed, the network will use subdomains, instead of subdirectories. * * @subcommand multisite-convert * @alias install-network - * @synopsis [--title=<network-title>] [--base=<url-path>] [--subdomains] */ public function multisite_convert( $args, $assoc_args ) { if ( is_multisite() ) @@ -306,11 +301,11 @@ public function multisite_convert( $args, $assoc_args ) { * --url=<url> * : The address of the new site. * - * --base=<url-path> + * [--base=<url-path>] * : Base path after the domain name that each site url in the network will start with. * Default: '/' * - * --subdomains + * [--subdomains] * : If passed, the network will use subdomains, instead of subdirectories. * * --title=<site-title> @@ -326,7 +321,6 @@ public function multisite_convert( $args, $assoc_args ) { * : The email address for the admin user. * * @subcommand multisite-install - * @synopsis --url=<url> --title=<site-title> [--base=<url-path>] [--subdomains] --admin_user=<username> --admin_email=<email> --admin_password=<password> */ public function multisite_install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -536,11 +530,10 @@ private static function get_clean_basedomain() { * * ## OPTIONS * - * --extra + * [--extra] * : Show extended version information. * * @when before_wp_load - * @synopsis [--extra] */ public function version( $args = array(), $assoc_args = array() ) { $versions_path = ABSPATH . 'wp-includes/version.php'; @@ -575,11 +568,13 @@ public function version( $args = array(), $assoc_args = array() ) { * * ## OPTIONS * - * --version=<new_version> [package/zip] - * : When passed, updates to new_version, optionally using package/zip as - * input. + * [<zip>] + * : Path to zip file to use, instead of downloading from wordpress.org. + * + * [--version=<version>] + * : Update to this version, instead of to the latest version. * - * --force + * [--force] * : Will update even when current WP version < passed version. Use with * caution. * @@ -592,8 +587,6 @@ public function version( $args = array(), $assoc_args = array() ) { * wp core update --version=3.1 --force * * @alias upgrade - * - * @synopsis [<zip>] [--version=<version>] [--force] */ function update( $args, $assoc_args ) { global $wp_version; @@ -674,7 +667,7 @@ function update_db() { * * ## OPTIONS * - * <path> + * [<path>] * : The directory in which to download the testing suite files. (Optional) * * --dbname=<dbname> @@ -684,14 +677,15 @@ function update_db() { * --dbuser=<dbuser> * : Set the database user. * - * --dbpass=<dbpass> + * [--dbpass=<dbpass>] * : Set the database user password. * + * [--dbhost=<host>] + * : Set the database host. + * * ## EXAMPLE * * wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test - * - * @synopsis [<path>] --dbname=<name> --dbuser=<user> [--dbpass=<password>] [--dbhost=<host>] */ function init_tests( $args, $assoc_args ) { if ( isset( $args[0] ) ) From e48aa6863c422c23ee0833a679d751a6cbab659b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 12 Sep 2013 03:18:53 +0300 Subject: [PATCH 2287/4858] use fwrite() instead of echo, to prevent buffering --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 67d06ea43c..12b759e23c 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -152,7 +152,7 @@ static function error( $message ) { */ static function confirm( $question, $assoc_args = array() ) { if ( !isset( $assoc_args['yes'] ) ) { - echo $question . " [y/n] "; + fwrite( STDOUT, $question . " [y/n] " ); $answer = trim( fgets( STDIN ) ); From 93cc47b1949056ed90866e9438e7b4f49e7042fc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 12 Sep 2013 02:02:30 +0300 Subject: [PATCH 2288/4858] remove synopsis tag where not needed --- php/commands/comment.php | 106 ++++++++++++-------------------- php/commands/export.php | 24 ++++---- php/commands/import.php | 4 +- php/commands/media.php | 10 ++- php/commands/option.php | 2 +- php/commands/plugin.php | 87 ++++++++++---------------- php/commands/post-meta.php | 2 +- php/commands/post.php | 53 ++++++---------- php/commands/rewrite.php | 21 ++++--- php/commands/role.php | 34 ++++------ php/commands/scaffold.php | 76 +++++++++++------------ php/commands/search-replace.php | 17 +++-- php/commands/shell.php | 4 +- php/commands/site.php | 22 +++---- php/commands/term.php | 46 ++++++-------- php/commands/theme.php | 66 +++++++------------- php/commands/user.php | 67 ++++++++------------ 17 files changed, 258 insertions(+), 383 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 1adf7c98c9..d59e134c92 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -8,13 +8,13 @@ class Comment_Command extends WP_CLI_Command { private $fields = array( - 'comment_ID', - 'comment_post_ID', - 'comment_date', - 'comment_approved', - 'comment_author', - 'comment_author_email', - ); + 'comment_ID', + 'comment_post_ID', + 'comment_date', + 'comment_approved', + 'comment_author', + 'comment_author_email', + ); /** * Insert a comment. @@ -22,16 +22,14 @@ class Comment_Command extends WP_CLI_Command { * ## OPTIONS * * --<field>=<value> - * : Field values for the new comment. See wp_insert_comment(). + * : Associative args for the new comment. See wp_insert_comment(). * - * --porcelain + * [--porcelain] * : Output just the new comment id. * * ## EXAMPLES * * wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" - * - * @synopsis --<field>=<value> [--porcelain] */ public function create( $args, $assoc_args ) { $post = get_post( $assoc_args['comment_post_ID'] ); @@ -53,25 +51,22 @@ public function create( $args, $assoc_args ) { } /** - * Get a comment - * + * Get a single comment. + * * ## OPTIONS * * <id> * : The comment to get. - * - * * --format=<format> + * + * [--format=<format>] * : The format to use when printing the comment, acceptable values: * * - **table**: Outputs all fields of the comment as a table. - * * - **json**: Outputs all fields in JSON format. - * + * * ## EXAMPLES * * wp comment get 1 - * - * @synopsis <id> [--format=<format>] */ public function get( $args, $assoc_args ) { @@ -107,13 +102,13 @@ public function get( $args, $assoc_args ) { * * ## OPTIONS * - * --<field>=<value> + * [--<field>=<value>] * : One or more args to pass to WP_Comment_Query. * - * --fields=<fields> + * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to comment_ID,comment_post_ID,comment_date,comment_approved,comment_author,comment_author_email * - * --format=<format> + * [--format=<format>] * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. * * ## EXAMPLES @@ -125,7 +120,6 @@ public function get( $args, $assoc_args ) { * wp comment list --number=20 --comment_approved=1 * * @subcommand list - * @synopsis [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $_, $assoc_args ) { $query_args = array(); @@ -159,17 +153,15 @@ public function _list( $_, $assoc_args ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to delete. * - * --force + * [--force] * : Skip the trash bin. * * ## EXAMPLES * * wp comment delete 1337 --force - * - * @synopsis <id> [--force] */ public function delete( $args, $assoc_args ) { list( $comment_id ) = $args; @@ -195,7 +187,7 @@ private function call( $args, $status, $success, $failure ) { private function set_status( $args, $status, $success ) { $comment = $this->_fetch_comment( $args ); - + $r = wp_set_comment_status( $comment->comment_ID, 'approve', true ); if ( is_wp_error( $r ) ) { @@ -210,14 +202,12 @@ private function set_status( $args, $status, $success ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to trash. * * ## EXAMPLES * * wp comment trash 1337 - * - * @synopsis <id> */ public function trash( $args, $assoc_args ) { $this->call( $args, __FUNCTION__, 'Trashed', 'Failed trashing' ); @@ -228,14 +218,12 @@ public function trash( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to untrash. * * ## EXAMPLES * * wp comment untrash 1337 - * - * @synopsis <id> */ public function untrash( $args, $assoc_args ) { $this->call( $args, __FUNCTION__, 'Untrashed', 'Failed untrashing' ); @@ -246,14 +234,12 @@ public function untrash( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to mark as spam. * * ## EXAMPLES * * wp comment spam 1337 - * - * @synopsis <id> */ public function spam( $args, $assoc_args ) { $this->call( $args, __FUNCTION__, 'Marked as spam', 'Failed marking as spam' ); @@ -264,13 +250,12 @@ public function spam( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to unmark as spam. * * ## EXAMPLES * * wp comment unspam 1337 - * @synopsis <id> */ public function unspam( $args, $assoc_args ) { $this->call( $args, __FUNCTION__, 'Unspammed', 'Failed unspamming' ); @@ -281,14 +266,12 @@ public function unspam( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to approve. * * ## EXAMPLES * * wp comment approve 1337 - * - * @synopsis <id> */ public function approve( $args, $assoc_args ) { $this->set_status( $args, 'approve', "Approved" ); @@ -299,14 +282,12 @@ public function approve( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> + * <id> * : The ID of the comment to unapprove. * * ## EXAMPLES * * wp comment unapprove 1337 - * - * @synopsis <id> */ public function unapprove( $args, $assoc_args ) { $this->set_status( $args, 'hold', "Unapproved" ); @@ -317,15 +298,13 @@ public function unapprove( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> - * : The ID of the post to count comments in + * <post-id> + * : The ID of the post to count comments in. * * ## EXAMPLES * * wp comment count * wp comment count 42 - * - * @synopsis [<post-id>] */ public function count( $args, $assoc_args ) { $post_id = isset( $args[0] ) ? $args[0] : 0; @@ -347,14 +326,12 @@ public function count( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> - * : The ID of the comment to check + * <id> + * : The ID of the comment to check. * * ## EXAMPLES * * wp comment status 1337 - * - * @synopsis <id> */ public function status( $args, $assoc_args ) { list( $comment_id ) = $args; @@ -373,17 +350,15 @@ public function status( $args, $assoc_args ) { * * ## OPTIONS * - * --id + * [--id] * : Output just the last comment id. * - * --full + * [--full] * : Output complete comment information. * * ## EXAMPLES * * wp comment last --full - * - * @synopsis [--id] [--full] */ function last( $args = array(), $assoc_args = array() ) { $last = get_comments( array( 'number' => 1, 'status' => 'approve' ) ); @@ -407,39 +382,36 @@ function last( $args = array(), $assoc_args = array() ) { WP_CLI::line( str_pad( "$key:", 23 ) . $comment->$key ); } } - + /** * Verify whether a comment exists. * * ## OPTIONS * - * <ID> - * : The ID of the comment to check from. + * <id> + * : The ID of the comment to check. * * ## EXAMPLES * * wp comment exists 1337 - * - * @synopsis <id> */ public function exists( $args ) { if ( $this->_fetch_comment( $args ) ) { WP_CLI::success( "Comment with ID $args[0] exists." ); } } - + /** - * A helper function fetching a comment object from comment_id. - * + * A helper function fetching a comment object from comment_id. */ private function _fetch_comment( $args ) { $comment_id = (int) $args[0]; $comment = get_comment( $comment_id ); - + if ( is_null( $comment ) ) { WP_CLI::error( "Comment with ID $args[0] does not exist." ); } - + return $comment; } } diff --git a/php/commands/export.php b/php/commands/export.php index 94fcaeb4e1..59781549ef 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -13,40 +13,40 @@ class Export_Command extends WP_CLI_Command { * * ## OPTIONS * - * --dir=<dirname> + * [--dir=<dirname>] * : Full path to directory where WXR export files should be stored. Defaults * to current working directory. * - * --skip_comments + * [--skip_comments] * : Don't export comments. * - * --file_item_count=<count> + * [--file_item_count=<count>] * : Break export into files with N posts. * - * --verbose + * [--verbose] * : Show more information about the process on STDOUT. * * ## FILTERS * - * --start_date=<date> + * [--start_date=<date>] * : Export only posts newer than this date, in format YYYY-MM-DD. * - * --end_date=<date> + * [--end_date=<date>] * : Export only posts older than this date, in format YYYY-MM-DD. * - * --post_type=<post_type> + * [--post_type=<post_type>] * : Export only posts with this post_type. * - * --post__in=<pid> + * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. * - * --author=<login/id> + * [--author=<login/id>] * : Export only posts by this author. * - * --category=<category-id> + * [--category=<category-id>] * : Export only posts in this category. * - * --post_status=<status> + * [--post_status=<status>] * : Export only posts with this status. * * ## EXAMPLES @@ -54,8 +54,6 @@ class Export_Command extends WP_CLI_Command { * wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 * * wp export --dir=/tmp/ --post__in=123,124,125 - * - * @synopsis [--dir=<dir>] [--start_date=<date>] [--end_date=<date>] [--post_type=<ptype>] [--post_status=<status>] [--post__in=<pids>] [--author=<login>] [--category=<cat>] [--skip_comments] [--file_item_count=<count>] [--verbose] */ public function __invoke( $_, $assoc_args ) { $defaults = array( diff --git a/php/commands/import.php b/php/commands/import.php index 39fccb8f64..493badb64e 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -13,10 +13,8 @@ class Import_Command extends WP_CLI_Command { * --authors=<authors> * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. * - * --skip=<data-type> + * [--skip=<data-type>] * : Skip importing specific data. Supported option is 'attachment'. - * - * @synopsis <file> --authors=<authors> [--skip=<data-type>] */ public function __invoke( $args, $assoc_args ) { list( $file ) = $args; diff --git a/php/commands/media.php b/php/commands/media.php index 719170c3c9..eb5e4e938e 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -12,19 +12,17 @@ class Media_Command extends WP_CLI_Command { * * ## OPTIONS * - * --yes - * : Answer yes to the confirmation message. - * - * <attachment-id> + * [<attachment-id>...] * : One or more IDs of the attachments to regenerate. * + * [--yes] + * : Answer yes to the confirmation message. + * * ## EXAMPLES * * wp media regenerate 123 1337 * * wp media regenerate --yes - * - * @synopsis [<attachment-id>...] [--yes] */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; diff --git a/php/commands/option.php b/php/commands/option.php index a825342c59..7f3e87a16b 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -5,7 +5,7 @@ * * ## OPTIONS * - * --format=json + * [--format=json] * : Encode/decode values as JSON. * * ## EXAMPLES diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ff1784ebfc..46a655f09b 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -34,10 +34,8 @@ protected function get_upgrader_class( $force ) { * * ## OPTIONS * - * <plugin> + * [<plugin>] * : A particular plugin to show the status for. - * - * @synopsis [<plugin>] */ function status( $args ) { parent::status( $args ); @@ -51,14 +49,14 @@ function status( $args ) { * <search> * : The string to search for. * - * --per-page + * [--per-page=<per-page>] * : Optional number of results to display. Defaults to 10. * - * --format + * [--format=<format>] * : Output list as table, CSV or JSON. Defaults to table. * - * --fields - * : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. acceptable values: + * [--fields=<fields>] + * : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. Acceptable values: * * **name**: Plugin Name * **slug**: Plugin Slug @@ -80,8 +78,6 @@ function status( $args ) { * wp plugin search dsgnwrks --per-page=20 --format=json * * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings - * - * @synopsis <search> [--per-page=<per-page>] [--fields=<fields>] [--format=<format>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; @@ -145,13 +141,11 @@ protected function get_all_items() { * * ## OPTIONS * - * <plugin> - * : The plugin to activate. + * <plugin>... + * : One or more plugins to activate. * - * --network + * [--network] * : If set, the plugin will be activated for the entire multisite network. - * - * @synopsis <plugin>... [--network] */ function activate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); @@ -175,13 +169,11 @@ function activate( $args, $assoc_args = array() ) { * * ## OPTIONS * - * <plugin> - * : The plugin to deactivate. + * <plugin>... + * : One or more plugins to deactivate. * - * --network + * [--network] * : If set, the plugin will be deactivated for the entire multisite network. - * - * @synopsis <plugin>... [--network] */ function deactivate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); @@ -205,13 +197,11 @@ function deactivate( $args, $assoc_args = array() ) { * * ## OPTIONS * - * <plugin> - * : The plugin to toggle. + * <plugin>... + * : One or more plugins to toggle. * - * --network + * [--network] * : If set, the plugin will be toggled for the entire multisite network. - * - * @synopsis <plugin>... [--network] */ function toggle( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); @@ -230,19 +220,17 @@ function toggle( $args, $assoc_args = array() ) { * * ## OPTIONS * - * <plugin> + * [<plugin>] * : The plugin to get the path to. If not set, will return the path to the * plugins directory. * - * --dir + * [--dir] * : If set, get the path to the closest parent directory, instead of the * plugin file. * * ## EXAMPLES * * cd $(wp theme path) - * - * @synopsis [<plugin>] [--dir] */ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); @@ -292,17 +280,17 @@ protected function install_from_repo( $slug, $assoc_args ) { * * ## OPTIONS * - * <plugin> - * : The plugin(s) to update. + * [<plugin>...] + * : One or more plugins to update. * - * --all + * [--all] * : If set, all plugins that have updates will be updated. * - * --version=dev + * [--version=<version>] * : If set, the plugin will be updated to the latest development version, * regardless of what version is currently installed. * - * --dry-run + * [--dry-run] * : Preview which plugins would be updated. * * ## EXAMPLES @@ -310,8 +298,6 @@ protected function install_from_repo( $slug, $assoc_args ) { * wp plugin update bbpress --version=dev * * wp plugin update --all - * - * @synopsis [<plugin>...] [--version=<version>] [--all] [--dry-run] */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { @@ -350,18 +336,18 @@ protected function filter_item_list( $items, $args ) { * * ## OPTIONS * - * <plugin|zip|url> + * <plugin|zip|url>... * : A plugin slug, the path to a local zip file, or URL to a remote zip file. * - * --version=<version> + * [--version=<version>] * : If set, get that particular version from wordpress.org, instead of the * stable version. * - * --force + * [--force] * : If set, the command will overwrite any installed version of the plugin, without prompting * for confirmation. * - * --activate + * [--activate] * : If set, the plugin will be activated immediately after install. * * ## EXAMPLES @@ -377,8 +363,6 @@ protected function filter_item_list( $items, $args ) { * * # Install from a remote zip file * wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef - * - * @synopsis <plugin|zip|url>... [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); @@ -389,18 +373,16 @@ function install( $args, $assoc_args ) { * * ## OPTIONS * - * <plugin> - * : The plugin to uninstall. + * <plugin>... + * : One or more plugins to uninstall. * - * --no-delete + * [--no-delete] * : If set, the plugin files will not be deleted. Only the uninstall procedure * will be run. * * ## EXAMPLES * * wp plugin uninstall hello - * - * @synopsis <plugin>... [--no-delete] */ function uninstall( $args, $assoc_args = array() ) { foreach ( $this->validate_plugin_names( $args ) as $plugin ) { @@ -430,7 +412,6 @@ function uninstall( $args, $assoc_args = array() ) { * wp plugin is-installed hello * * @subcommand is-installed - * @synopsis <plugin> */ function is_installed( $args, $assoc_args = array() ) { if ( $this->_parse_name( $args[0] ) ) { @@ -445,14 +426,12 @@ function is_installed( $args, $assoc_args = array() ) { * * ## OPTIONS * - * <plugin> - * : The plugin to delete. + * <plugin>... + * : One or more plugins to delete. * * ## EXAMPLES * * wp plugin delete hello - * - * @synopsis <plugin>... */ function delete( $args, $assoc_args = array() ) { foreach ( $this->validate_plugin_names( $args ) as $plugin ) { @@ -467,16 +446,14 @@ function delete( $args, $assoc_args = array() ) { * * ## OPTIONS * - * * `--format`=<format>: - * - * Output list as table, CSV or JSON. Defaults to table. + * [--format=<format>] + * : Output list as table, CSV or JSON. Defaults to table. * * ## EXAMPLES * * wp plugin list --format=json * * @subcommand list - * @synopsis [--format=<format>] */ function _list( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); diff --git a/php/commands/post-meta.php b/php/commands/post-meta.php index 31cf7572c3..be99bd813a 100644 --- a/php/commands/post-meta.php +++ b/php/commands/post-meta.php @@ -5,7 +5,7 @@ * * ## OPTIONS * - * --format=json + * [--format=json] * : Encode/decode values as JSON. * * ## EXAMPLES diff --git a/php/commands/post.php b/php/commands/post.php index c14887e173..5b8a734670 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -22,23 +22,23 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { * * ## OPTIONS * - * <filename> + * [<filename>] * : Read post content from <filename>. If this value is present, the * `--post_content` argument will be ignored. * * Passing `-` as the filename will cause post content to * be read from STDIN. * - * --<field>=<value> - * : Field values for the new post. See wp_insert_post(). + * [--<field>=<value>] + * : Associative args for the new post. See wp_insert_post(). * - * --edit + * [--edit] * : Immediately open system's editor to write or edit post content. * * If content is read from a file, from STDIN, or from the `--post_content` * argument, that text will be loaded into the editor. * - * --porcelain + * [--porcelain] * : Output just the new post id. * * ## EXAMPLES @@ -46,8 +46,6 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { * wp post create --post_type=page --post_status=publish --post_title='A future post' --post-status=future --post_date='2020-12-01 07:00:00' * * wp post create page.txt --post_type=page --post_title='Page from file' - * - * @synopsis [<filename>] --<field>=<value> [--edit] [--porcelain] */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { @@ -85,8 +83,8 @@ protected function _create( $params ) { * * ## OPTIONS * - * <ID> - * : The ID of the post to update. + * <id>... + * : One or more IDs of posts to update. * * --<field>=<value> * : One or more fields to update. See wp_update_post(). @@ -94,8 +92,6 @@ protected function _create( $params ) { * ## EXAMPLES * * wp post update 123 --post_name=something --post_status=draft - * - * @synopsis <id>... --<field>=<value> */ public function update( $args, $assoc_args ) { parent::update( $args, $assoc_args ); @@ -116,8 +112,6 @@ protected function _update( $params ) { * ## EXAMPLES * * wp post edit 123 - * - * @synopsis <id> */ public function edit( $args, $_ ) { $post_id = $args[0]; @@ -144,7 +138,7 @@ protected function _edit( $content, $title ) { * <id> * : The ID of the post to get. * - * --format=<format> + * [--format=<format>] * : The format to use when printing the post, acceptable values: * * - **content**: Outputs only the post's content. @@ -159,8 +153,6 @@ protected function _edit( $content, $title ) { * wp post get 12 --format=content * * wp post get 12 > file.txt - * - * @synopsis <id> [--format=<format>] */ public function get( $args, $assoc_args ) { $defaults = array( @@ -202,10 +194,10 @@ public function get( $args, $assoc_args ) { * * ## OPTIONS * - * <ID> - * : The ID of the post to delete. + * <id>... + * : One or more IDs of posts to delete. * - * --force + * [--force] * : Skip the trash bin. * * ## EXAMPLES @@ -213,8 +205,6 @@ public function get( $args, $assoc_args ) { * wp post delete 123 --force * * wp post delete $(wp post list --post_type='page' --format=ids) - * - * @synopsis <id>... [--force] */ public function delete( $args, $assoc_args ) { $defaults = array( @@ -242,13 +232,13 @@ protected function _delete( $post_id, $assoc_args ) { * * ## OPTIONS * - * --<field>=<value> + * [--<field>=<value>] * : One or more args to pass to WP_Query. * - * --fields=<fields> + * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. * - * --format=<format> + * [--format=<format>] * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. * * ## EXAMPLES @@ -260,7 +250,6 @@ protected function _delete( $post_id, $assoc_args ) { * wp post list --post_type=page --fields=post_title,post_status * * @subcommand list - * @synopsis [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $_, $assoc_args ) { $query_args = array( @@ -293,29 +282,27 @@ public function _list( $_, $assoc_args ) { * * ## OPTIONS * - * --count=<number> + * [--count=<number>] * : How many posts to generate. Default: 100 * - * --post_type=<type> + * [--post_type=<type>] * : The type of the generated posts. Default: 'post' * - * --post_status=<status> + * [--post_status=<status>] * : The status of the generated posts. Default: 'publish' * - * --post_author=<login> + * [--post_author=<login>] * : The author of the generated posts. Default: none * - * --post_date=<yyyy-mm-dd> + * [--post_date=<yyyy-mm-dd>] * : The date of the generated posts. Default: current date * - * --max_depth=<number> + * [--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 - * - * @synopsis [--count=<number>] [--post_type=<type>] [--post_status=<status>] [--post_author=<login>] [--post_date=<yyyy-mm-dd>] [--max_depth=<number>] */ public function generate( $args, $assoc_args ) { global $wpdb; diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 1d3e16f7cf..bf6616425d 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -12,10 +12,8 @@ class Rewrite_Command extends WP_CLI_Command { * * ## OPTIONS * - * --hard + * [--hard] * : Perform a hard flush - update `.htaccess` rules as well as rewrite rules in database. - * - * @synopsis [--hard] */ public function flush( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config @@ -31,17 +29,18 @@ public function flush( $args, $assoc_args ) { * <permastruct> * : The new permalink structure to apply. * - * --category-base=<categorybase> + * [--category-base=<base>] * : Set the base for category permalinks, i.e. '/category/'. * - * --tag-base=<tagbase> + * [--tag-base=<base>] * : Set the base for tag permalinks, i.e. '/tag/'. * + * [--hard] + * : Perform a hard flush - update `.htaccess` rules as well as rewrite rules in database. + * * ## EXAMPLES * * wp rewrite structure '/%year%/%monthnum%/%postname%' - * - * @synopsis <permastruct> [--category-base=<base>] [--tag-base=<base>] [--hard] */ public function structure( $args, $assoc_args ) { global $wp_rewrite; @@ -94,10 +93,12 @@ public function structure( $args, $assoc_args ) { * * ## OPTIONS * - * --format=json - * : Output rules in JSON format. + * [--format=<format>] + * : Output list as JSON. Defaults to tab-separated lines. + * + * ## EXAMPLES * - * @synopsis [--format=<format>] + * wp rewrite dump --format=json */ public function dump( $args, $assoc_args ) { $rules = get_option( 'rewrite_rules' ); diff --git a/php/commands/role.php b/php/commands/role.php index 9259875e43..78a5fbdaf1 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -17,10 +17,10 @@ class Role_Command extends WP_CLI_Command { * * ## OPTIONS * - * --fields=<fields> + * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to name,role. * - * --format=<format> + * [--format=<format>] * : Output list as table, CSV or JSON. Defaults to table. * * ## EXAMPLES @@ -28,7 +28,6 @@ class Role_Command extends WP_CLI_Command { * wp role list --fields=role --format=csv * * @subcommand list - * @synopsis [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { global $wp_roles; @@ -64,15 +63,12 @@ public function _list( $args, $assoc_args ) { * * ## OPTIONS * - * * <role-key>: - * - * The internal name of the role, e.g. editor + * <role-key> + * : The internal name of the role. * * ## EXAMPLES * * wp role exists editor - * - * @synopsis <role-key> */ public function exists( $args ) { global $wp_roles; @@ -80,7 +76,7 @@ public function exists( $args ) { if ( ! in_array($args[0], array_keys( $wp_roles->roles ) ) ) { WP_CLI::error( "Role with ID $args[0] does not exist." ); } - + WP_CLI::success( "Role with ID $args[0] exists." ); } @@ -89,21 +85,17 @@ public function exists( $args ) { * * ## OPTIONS * - * * <role-key>: - * - * The internal name of the role, e.g. editor - * - * * <role-name>: + * <role-key> + * : The internal name of the role. * - * The publically visible name of the role, e.g. Editor + * <role-name> + * : The publicly visible name of the role. * * ## EXAMPLES * * wp role create approver Approver * * wp role create productadmin "Product Administrator" - * - * @synopsis <role-key> <role-name> */ public function create( $args ) { self::persistence_check(); @@ -125,20 +117,16 @@ public function create( $args ) { * * ## OPTIONS * - * * <role-key>: - * - * The internal name of the role, e.g. editor + * <role-key> + * : The internal name of the role. * * ## EXAMPLES * * wp role delete approver * * wp role delete productadmin - * - * @synopsis <role-key> */ public function delete( $args ) { - global $wp_roles; self::persistence_check(); diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index af10af5fbb..5e7ba7269a 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -18,28 +18,28 @@ function __construct() { * * ## OPTIONS * - * --label=<label> + * <slug> + * : The internal name of the post type. + * + * [--label=<label>] * : The text used to translate the update messages * - * --textdomain=<textdomain> + * [--textdomain=<textdomain>] * : The textdomain to use for the labels. * - * --theme + * [--theme] * : Create a file in the active theme directory, instead of sending to * STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. * - * --plugin=<plugin> - * : Create a file in the given plugin's directory, instead of sending to - * STDOUT. + * [--plugin=<plugin>] + * : Create a file in the given plugin's directory, instead of sending to STDOUT. * - * --raw + * [--raw] * : Just generate the `register_post_type()` call and nothing else. * * @subcommand post-type * * @alias cpt - * - * @synopsis <slug> [--label=<label>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function post_type( $args, $assoc_args ) { $defaults = array( @@ -57,24 +57,26 @@ function post_type( $args, $assoc_args ) { * * ## OPTIONS * - * --post_types=<post_types> + * <slug> + * : The internal name of the taxonomy. + * + * [--post_types=<post-types>] * : Post types to register for use with the taxonomy. * - * --label=<label> + * [--label=<label>] * : The text used to translate the update messages * - * --textdomain=<textdomain> + * [--textdomain=<textdomain>] * : The textdomain to use for the labels. * - * --theme + * [--theme] * : Create a file in the active theme directory, instead of sending to * STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. * - * --plugin=<plugin> - * : Create a file in the given plugin's directory, instead of sending to - * STDOUT. + * [--plugin=<plugin>] + * : Create a file in the given plugin's directory, instead of sending to STDOUT. * - * --raw + * [--raw] * : Just generate the `register_taxonomy()` call and nothing else. * * ## EXAMPLES @@ -84,8 +86,6 @@ function post_type( $args, $assoc_args ) { * @subcommand taxonomy * * @alias tax - * - * @synopsis <slug> [--post_types=<post-types>] [--label=<label>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--raw] */ function taxonomy( $args, $assoc_args ) { $defaults = array( @@ -164,19 +164,17 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * <slug> * : The slug for the new theme, used for prefixing functions. * - * --activate + * [--activate] * : Activate the newly downloaded theme. * - * --theme_name=<title> + * [--theme_name=<title>] * : What to put in the 'Theme Name:' header in style.css * - * --author=<full name> + * [--author=<full-name>] * : What to put in the 'Author:' header in style.css * - * --author_uri=<http url> + * [--author_uri=<uri>] * : What to put in the 'Author URI:' header in style.css - * - * @synopsis <slug> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--activate] */ function _s( $args, $assoc_args ) { @@ -226,24 +224,22 @@ function _s( $args, $assoc_args ) { * --parent_theme=<slug> * : What to put in the 'Template:' header in style.css * - * --theme_name=<title> + * [--theme_name=<title>] * : What to put in the 'Theme Name:' header in style.css * - * --author=<full name> + * [--author=<full-name>] * : What to put in the 'Author:' header in style.css * - * --author_uri=<http url> + * [--author_uri=<uri>] * : What to put in the 'Author URI:' header in style.css * - * --theme_uri=<http url> + * [--theme_uri=<uri>] * : What to put in the 'Theme URI:' header in style.css * - * --activate + * [--activate] * : Activate the newly created child theme. * * @subcommand child-theme - * - * @synopsis <slug> --parent_theme=<slug> [--theme_name=<title>] [--author=<full-name>] [--author_uri=<http-url>] [--theme_uri=<http-url>] [--activate] */ function child_theme( $args, $assoc_args ) { $theme_slug = $args[0]; @@ -295,13 +291,14 @@ private function get_output_path( $assoc_args, $subdir ) { * * ## OPTIONS * - * --activate + * <slug> + * : The internal name of the plugin. + * + * [--activate] * : Activate the newly generated plugin. * - * --plugin_name=<title> + * [--plugin_name=<title>] * : What to put in the 'Plugin Name:' header - * - * @synopsis <slug> [--plugin_name=<title>] [--activate] */ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; @@ -342,13 +339,16 @@ function plugin( $args, $assoc_args ) { * The `tests/bootstrap.php` file looks for the WP_TESTS_DIR environment * variable. * + * ## OPTIONS + * + * <plugin> + * : The name of the plugin to generate test files for. + * * ## EXAMPLE * * wp scaffold plugin-tests hello * * @subcommand plugin-tests - * - * @synopsis <plugin> */ function plugin_tests( $args, $assoc_args ) { global $wp_filesystem; diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7cbb520195..c7e80dac3f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -18,13 +18,22 @@ class Search_Replace_Command extends WP_CLI_Command { * * ## OPTIONS * - * --network + * <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> + * [--skip-columns=<columns>] * : Do not perform the replacement in the comma-separated columns. * - * --dry-run + * [--dry-run] * : Show report, but don't perform the changes. * * ## EXAMPLES @@ -32,8 +41,6 @@ class Search_Replace_Command extends WP_CLI_Command { * 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 - * - * @synopsis <old> <new> [<table>...] [--skip-columns=<columns>] [--dry-run] [--network] */ public function __invoke( $args, $assoc_args ) { $old = array_shift( $args ); diff --git a/php/commands/shell.php b/php/commands/shell.php index ee95860e64..82b96484d0 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -11,10 +11,8 @@ class Shell_Command extends \WP_CLI_Command { * * ## OPTIONS * - * --basic + * [--basic] * : Start in fail-safe mode, even if Boris is available. - * - * @synopsis [--basic] */ public function __invoke( $_, $assoc_args ) { $implementations = array( diff --git a/php/commands/site.php b/php/commands/site.php index 954274842f..9a49c69c18 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -112,11 +112,10 @@ private function _insert_default_terms() { * * ## OPTIONS * - * --yes + * [--yes] * : Proceed to empty the site without a confirmation prompt. * * @subcommand empty - * @synopsis [--yes] */ public function _empty( $args, $assoc_args ) { @@ -135,19 +134,17 @@ public function _empty( $args, $assoc_args ) { * * ## OPTIONS * - * <blog-id> - * : The id of the blog to delete. If not provided, you must set the --slug parameter. + * [<site-id>] + * : The id of the site to delete. If not provided, you must set the --slug parameter. * - * --slug=<slug> + * [--slug=<slug>] * : Path of the blog to be deleted. Subdomain on subdomain installs, directory on subdirectory installs. * - * --yes + * [--yes] * : Answer yes to the confirmation message. * - * --keep-tables + * [--keep-tables] * : Delete the blog from the list, but don't drop it's tables. - * - * @synopsis [<site-id>] [--slug=<slug>] [--yes] [--keep-tables] */ function delete( $args, $assoc_args ) { if ( !is_multisite() ) { @@ -324,13 +321,13 @@ public function create( $_, $assoc_args ) { * * ## OPTIONS * - * --network=<id> + * [--network=<id>] * : The network to which the sites belong. * - * --fields=<fields> + * [--fields=<fields>] * : Comma-separated list of fields to show. * - * --format=<format> + * [--format=<format>] * : Output list as table, csv, json or url. Defaults to table. * * ## EXAMPLES @@ -339,7 +336,6 @@ public function create( $_, $assoc_args ) { * wp site list --fields=url --format=csv | tail -n +2 * * @subcommand list - * @synopsis [--network=<id>] [--format=<format>] [--fields=<fields>] */ function _list( $_, $assoc_args ) { if ( !is_multisite() ) { diff --git a/php/commands/term.php b/php/commands/term.php index 415feb5d35..bcf58ac44d 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -23,14 +23,14 @@ class Term_Command extends WP_CLI_Command { * * <taxonomy> * : List terms of a given taxonomy. - * - * --<field>=<value> + * + * [--<field>=<value>] * : Filter by one or more fields. For accepted fields, see get_terms(). * - * --fields=<fields> + * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to all of the term object fields. * - * --format=<format> + * [--format=<format>] * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. * * ## EXAMPLES @@ -40,7 +40,6 @@ class Term_Command extends WP_CLI_Command { * wp term list post_tag --fields=name,slug * * @subcommand list - * @synopsis <taxonomy> [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { @@ -75,23 +74,21 @@ public function _list( $args, $assoc_args ) { * <taxonomy> * : Taxonomy for the new term. * - * --slug=<slug> + * [--slug=<slug>] * : A unique slug for the new term. Defaults to sanitized version of name. * - * --description=<description> + * [--description=<description>] * : A description for the new term. * - * --parent=<term-id> + * [--parent=<term-id>] * : A parent for the new term. * - * --porcelain + * [--porcelain] * : Output just the new term id. * * ## EXAMPLES * * wp term create Apple category --description="A type of fruit" - * - * @synopsis <term> <taxonomy> [--slug=<slug>] [--description=<description>] [--parent=<term-id>] [--porcelain] */ public function create( $args, $assoc_args ) { @@ -125,27 +122,24 @@ public function create( $args, $assoc_args ) { /** * Get a taxonomy term - * + * * ## OPTIONS * * <term-id> * : ID of the term to get - * + * * <taxonomy> * : Taxonomy of the term to get - * - * --format=<format> + * + * [--format=<format>] * : The format to use when printing the term, acceptable values: * * - **table**: Outputs all fields of the term as a table. - * * - **json**: Outputs all fields in JSON format. - * + * * ## EXAMPLES * - * wp term get 1 category - * - * @synopsis <term-id> <taxonomy> [--format=<format>] + * wp term get 1 category --format=json */ public function get( $args, $assoc_args ) { @@ -188,23 +182,21 @@ public function get( $args, $assoc_args ) { * <taxonomy> * : Taxonomy of the term to update. * - * --name=<name> + * [--name=<name>] * : A new name for the term. * - * --slug=<slug> + * [--slug=<slug>] * : A new slug for the term. * - * --description=<description> + * [--description=<description>] * : A new description for the term. * - * --parent=<term-id> + * [--parent=<term-id>] * : A new parent for the term. * * ## EXAMPLES * * wp term update 15 category --name=Apple - * - * @synopsis <term-id> <taxonomy> [--name=<name>] [--slug=<slug>] [--description=<description>] [--parent=<term-id>] */ public function update( $args, $assoc_args ) { @@ -245,8 +237,6 @@ public function update( $args, $assoc_args ) { * ## EXAMPLES * * wp term delete 15 category - * - * @synopsis <term-id> <taxonomy> */ public function delete( $args ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 4a8293b82d..7f23b4278d 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -27,10 +27,8 @@ protected function get_upgrader_class( $force ) { * * ## OPTIONS * - * <theme> + * [<theme>] * : A particular theme to show the status for. - * - * @synopsis [<theme>] */ function status( $args ) { parent::status( $args ); @@ -44,11 +42,11 @@ function status( $args ) { * <search> * : The string to search for. * - * --per-page + * [--per-page=<per-page>] * : Optional number of results to display. Defaults to 10. * - * --fields - * : Ask for specific fields from the API. Defaults to name,slug,author,rating. acceptable values: + * [--fields=<fields>] + * : Ask for specific fields from the API. Defaults to name,slug,author,rating. Acceptable values: * * **name**: Theme Name * **slug**: Theme Slug @@ -66,8 +64,6 @@ function status( $args ) { * wp theme search automattic --per-page=20 * * wp theme search automattic --fields=name,version,slug,rating,num_ratings,description - * - * @synopsis <search> [--per-page=<per-page>] [--fields=<fields>] */ public function search( $args, $assoc_args = array() ) { $term = $args[0]; @@ -119,8 +115,6 @@ protected function get_status( $theme ) { * * <theme> * : The theme to activate. - * - * @synopsis <theme> */ public function activate( $args = array() ) { $theme = $this->parse_name( $args[0] ); @@ -145,19 +139,17 @@ private function is_active_theme( $theme ) { * * ## OPTIONS * - * <theme> + * [<theme>] * : The theme to get the path to. Path includes "style.css" file. * If not set, will return the path to the themes directory. * - * --dir + * [--dir] * : If set, get the path to the closest parent directory, instead of the * theme's "style.css" file. * * ## EXAMPLES * * cd $(wp theme path) - * - * @synopsis [<theme>] [--dir] */ public function path( $args, $assoc_args ) { if ( empty( $args ) ) { @@ -228,14 +220,18 @@ protected function filter_item_list( $items, $args ) { * * ## OPTIONS * - * <theme|zip|url> + * <theme|zip|url>... * : A theme slug, the path to a local zip file, or URL to a remote zip file. * - * --force + * [--version=<version>] + * : If set, get that particular version from wordpress.org, instead of the + * stable version. + * + * [--force] * : If set, the command will overwrite any installed version of the theme, without prompting * for confirmation. * - * --activate + * [--activate] * : If set, the theme will be activated immediately after install. * * ## EXAMPLES @@ -248,8 +244,6 @@ protected function filter_item_list( $items, $args ) { * * # Install from a remote zip file * wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef - * - * @synopsis <theme|zip|url>... [--version=<version>] [--force] [--activate] */ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); @@ -263,21 +257,14 @@ function install( $args, $assoc_args ) { * <theme> * : The theme to get. * - * * --format=<format> - * : The format to use when printing the theme, acceptable values: - * - * - **table**: Outputs all fields of the theme as a table. - * - * - **json**: Outputs all fields in JSON format. + * [--format=<format>] + * : Output list as table or JSON. Defaults to table. * * ## EXAMPLES * - * wp theme get twentytwelve - * - * @synopsis <theme> [--format=<format>] + * wp theme get twentytwelve --format=json */ public function get( $args, $assoc_args ) { - $defaults = array( 'format' => 'table' ); @@ -316,17 +303,17 @@ public function get( $args, $assoc_args ) { * * ## OPTIONS * - * <theme> - * : The theme(s) to update. + * [<theme>...] + * : One or more themes to update. * - * --all + * [--all] * : If set, all themes that have updates will be updated. * - * --version=dev + * [--version=<version>] * : If set, the theme will be updated to the latest development version, * regardless of what version is currently installed. * - * --dry-run + * [--dry-run] * : Preview which themes would be updated. * * ## EXAMPLES @@ -334,8 +321,6 @@ public function get( $args, $assoc_args ) { * wp theme update twentyeleven twentytwelve * * wp theme update --all - * - * @synopsis [<theme>...] [--version=<version>] [--all] [--dry-run] */ function update( $args, $assoc_args ) { parent::update_many( $args, $assoc_args ); @@ -352,8 +337,6 @@ function update( $args, $assoc_args ) { * ## EXAMPLES * * wp theme delete twentyeleven - * - * @synopsis <theme> */ function delete( $args ) { $theme = $this->parse_name( $args[0] ); @@ -377,16 +360,14 @@ function delete( $args ) { * * ## OPTIONS * - * * `--format`=<format>: - * - * Output list as table, CSV or JSON. Defaults to table. + * [--format=<format>] + * : Output list as table, CSV or JSON. Defaults to table. * * ## EXAMPLES * * wp theme list --format=csv * * @subcommand list - * @synopsis [--format=<format>] */ function _list( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); @@ -408,7 +389,6 @@ private function parse_name( $name ) { return $theme; } - } WP_CLI::add_command( 'theme', 'Theme_Command' ); diff --git a/php/commands/user.php b/php/commands/user.php index 9674f5e9fb..5a0abe55fe 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -23,16 +23,16 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * * ## OPTIONS * - * --role=<role> + * [--role=<role>] * : Only display users with a certain role. - * - * * --<field>=<value> + * + * [--<field>=<value>] * : Filter by one or more fields. For accepted fields, see get_users(). * - * --fields=<fields> + * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles * - * --format=<format> + * [--format=<format>] * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. * * ## EXAMPLES @@ -44,7 +44,6 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * wp user list --fields=display_name,user_email * * @subcommand list - * @synopsis [--role=<role>] [--<field>=<value>] [--fields=<fields>] [--format=<format>] */ public function _list( $args, $assoc_args ) { @@ -89,7 +88,7 @@ public function _list( $args, $assoc_args ) { * <user> * : User ID or user login. * - * --format=<format> + * [--format=<format>] * : The format to use when printing the user; acceptable values: * * **table**: Outputs all fields of the user as a table. @@ -101,8 +100,6 @@ public function _list( $args, $assoc_args ) { * wp user get 12 * * wp user get bob --format=json > bob.json - * - * @synopsis <user> [--format=<format>] */ public function get( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( @@ -141,17 +138,15 @@ public function get( $args, $assoc_args ) { * * ## OPTIONS * - * <user> - * : The user login or ID of the user to delete. + * <user>... + * : The user login or ID of the user(s) to update. * - * --reassign=<ID> - * : User to reassign the posts to. + * [--reassign=<user-id>] + * : User ID to reassign the posts to. * * ## EXAMPLES * * wp user delete 123 --reassign=567 - * - * @synopsis <user>... [--reassign=<id>] */ public function delete( $args, $assoc_args ) { $assoc_args = wp_parse_args( $assoc_args, array( @@ -189,26 +184,24 @@ protected function _delete( $user_id, $assoc_args ) { * <user-email> * : The email address of the user to create. * - * --role=<role> + * [--role=<role>] * : The role of the user to create. Default: default role * - * --user_pass=<password> + * [--user_pass=<password>] * : The user password. Default: randomly generated * - * --user_registered=<yyyy-mm-dd> + * [--user_registered=<yyyy-mm-dd>] * : The date the user registered. Default: current date * - * --display_name=<name> + * [--display_name=<name>] * : The display name. * - * --porcelain + * [--porcelain] * : Output just the new user id. * * ## EXAMPLES * * wp user create bob bob@example.com --role=author - * - * @synopsis <user-login> <user-email> [--role=<role>] [--user_pass=<password>] [--user_registered=<yyyy-mm-dd>] [--display_name=<name>] [--porcelain] */ public function create( $args, $assoc_args ) { list( $user_login, $user_email ) = $args; @@ -269,8 +262,8 @@ protected function _create( $params ) { * * ## OPTIONS * - * <user> - * : The user login or ID of the user to update. + * <user>... + * : The user login or ID of the user(s) to update. * * --<field>=<value> * : One or more fields to update. For accepted fields, see wp_update_user(). @@ -280,8 +273,6 @@ protected function _create( $params ) { * wp user update 123 --user_login=mary --display_name=Mary * * wp user update mary --user_pass=marypass - * - * @synopsis <user>... --<field>=<value> */ public function update( $args, $assoc_args ) { @@ -300,13 +291,11 @@ protected function _update( $params ) { * * ## OPTIONS * - * --count=<number> + * [--count=<number>] * : How many users to generate. Default: 100 * - * --role=<role> + * [--role=<role>] * : The role of the generated users. Default: default role from WP - * - * @synopsis [--count=<number>] [--role=<role>] */ public function generate( $args, $assoc_args ) { global $blog_id; @@ -374,7 +363,6 @@ public function generate( $args, $assoc_args ) { * wp user set-role 12 author * * @subcommand set-role - * @synopsis <user> [<role>] */ public function set_role( $args, $assoc_args ) { $user = self::get_user( $args[0] ); @@ -407,7 +395,6 @@ public function set_role( $args, $assoc_args ) { * wp user add-role 12 author * * @subcommand add-role - * @synopsis <user> <role> */ public function add_role( $args, $assoc_args ) { $user = self::get_user( $args[0] ); @@ -427,13 +414,15 @@ public function add_role( $args, $assoc_args ) { * <user> * : User ID or user login. * + * [<role>] + * : A specific role to remove. + * * ## EXAMPLES * * wp user remove-role bob - * wp user remove-role 12 + * wp user remove-role 12 editor * * @subcommand remove-role - * @synopsis <user> [<role>] */ public function remove_role( $args, $assoc_args ) { $user = self::get_user( $args[0] ); @@ -464,7 +453,7 @@ public function remove_role( $args, $assoc_args ) { * : User ID or user login. * * <cap> - * : Add the specified capability for the user. + * : The capability to add. * * ## EXAMPLES * @@ -472,7 +461,6 @@ public function remove_role( $args, $assoc_args ) { * wp user add-cap 15 edit_product * * @subcommand add-cap - * @synopsis <user> <cap> */ public function add_cap( $args, $assoc_args ) { $user = self::get_user( $args[0] ); @@ -493,7 +481,7 @@ public function add_cap( $args, $assoc_args ) { * : User ID or user login. * * <cap> - * : Capability to be removed. + * : The capability to be removed. * * ## EXAMPLES * @@ -501,7 +489,6 @@ public function add_cap( $args, $assoc_args ) { * wp user remove-cap 11 publish_newsletters * * @subcommand remove-cap - * @synopsis <user> <cap> */ public function remove_cap( $args, $assoc_args ) { $user = self::get_user( $args[0] ); @@ -519,7 +506,7 @@ public function remove_cap( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID or login. * * ## EXAMPLES * @@ -527,7 +514,6 @@ public function remove_cap( $args, $assoc_args ) { * wp user list-caps 21 * * @subcommand list-caps - * @synopsis <user> */ public function list_caps( $args, $assoc_args ) { $user = self::get_user( $args[0] ); @@ -579,7 +565,6 @@ private static function get_user( $id_or_login ) { * existinguser,existinguser@domain.com,Existing User,administrator * * @subcommand import-csv - * @synopsis <file> */ public function import_csv( $args, $assoc_args ) { From d1eeb09a959c62ef946a11f4e9b22f0171edfa5f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 16 Sep 2013 01:38:08 +0300 Subject: [PATCH 2289/4858] rename some variables, for clarity. --- php/WP_CLI/Dispatcher/Subcommand.php | 10 ++++---- php/WP_CLI/SynopsisValidator.php | 5 ++-- tests/test-arg-validation.php | 34 ++++++++++++++-------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index e51f1f7020..7e528c145d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -152,22 +152,22 @@ private function validate_args( $args, &$assoc_args ) { if ( !$synopsis ) return; - $parser = new \WP_CLI\SynopsisValidator( $synopsis ); + $validator = new \WP_CLI\SynopsisValidator( $synopsis ); $cmd_path = implode( ' ', get_path( $this ) ); - foreach ( $parser->get_unknown() as $token ) { + foreach ( $validator->get_unknown() as $token ) { \WP_CLI::warning( sprintf( "The `%s` command has an invalid synopsis part: %s", $cmd_path, $token ) ); } - if ( !$parser->enough_positionals( $args ) ) { + if ( !$validator->enough_positionals( $args ) ) { $this->show_usage(); exit(1); } - $errors = $parser->validate_assoc( $assoc_args, array_keys( \WP_CLI::get_config() ) ); + $errors = $validator->validate_assoc( $assoc_args, array_keys( \WP_CLI::get_config() ) ); if ( !empty( $errors['fatal'] ) ) { $out = 'Parameter errors:'; @@ -180,7 +180,7 @@ private function validate_args( $args, &$assoc_args ) { array_map( '\\WP_CLI::warning', $errors['warning'] ); - foreach ( $parser->unknown_assoc( $assoc_args ) as $key ) { + foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { \WP_CLI::warning( "unknown --$key parameter" ); } } diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index 300dd67a47..c4490bd781 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -28,8 +28,9 @@ public function enough_positionals( $args ) { return count( $args ) >= count( $positional ); } + // Checks that all required keys are present and that they have values. public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { - $assoc = $this->query_spec( array( + $assoc_spec = $this->query_spec( array( 'type' => 'assoc', ) ); @@ -38,7 +39,7 @@ public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { 'warning' => array() ); - foreach ( $assoc as $param ) { + foreach ( $assoc_spec as $param ) { $key = $param['name']; if ( in_array( $key, $ignored_keys ) ) diff --git a/tests/test-arg-validation.php b/tests/test-arg-validation.php index e1c74b822a..3d1a2fa109 100644 --- a/tests/test-arg-validation.php +++ b/tests/test-arg-validation.php @@ -5,53 +5,53 @@ class ArgValidationTests extends PHPUnit_Framework_TestCase { function testMissingPositional() { - $parser = new SynopsisValidator( '<foo> <bar> [<baz>]' ); + $validator = new SynopsisValidator( '<foo> <bar> [<baz>]' ); - $this->assertFalse( $parser->enough_positionals( array() ) ); - $this->assertTrue( $parser->enough_positionals( array( 1, 2 ) ) ); - $this->assertTrue( $parser->enough_positionals( array( 1, 2, 3, 4 ) ) ); + $this->assertFalse( $validator->enough_positionals( array() ) ); + $this->assertTrue( $validator->enough_positionals( array( 1, 2 ) ) ); + $this->assertTrue( $validator->enough_positionals( array( 1, 2, 3, 4 ) ) ); } function testRepeatingPositional() { - $parser = new SynopsisValidator( '<foo> [<bar>...]' ); + $validator = new SynopsisValidator( '<foo> [<bar>...]' ); - $this->assertFalse( $parser->enough_positionals( array() ) ); - $this->assertTrue( $parser->enough_positionals( array( 1 ) ) ); - $this->assertTrue( $parser->enough_positionals( array( 1, 2, 3 ) ) ); + $this->assertFalse( $validator->enough_positionals( array() ) ); + $this->assertTrue( $validator->enough_positionals( array( 1 ) ) ); + $this->assertTrue( $validator->enough_positionals( array( 1, 2, 3 ) ) ); } function testUnknownAssocEmpty() { - $parser = new SynopsisValidator( '' ); + $validator = new SynopsisValidator( '' ); $assoc_args = array( 'foo' => true, 'bar' => false ); - $this->assertEquals( array_keys( $assoc_args ), $parser->unknown_assoc( $assoc_args ) ); + $this->assertEquals( array_keys( $assoc_args ), $validator->unknown_assoc( $assoc_args ) ); } function testUnknownAssoc() { - $parser = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); + $validator = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); $assoc_args = array( 'type' => 'analog', 'brand' => true, 'flag' => true ); - $this->assertEmpty( $parser->unknown_assoc( $assoc_args ) ); + $this->assertEmpty( $validator->unknown_assoc( $assoc_args ) ); $assoc_args['another'] = true; - $this->assertContains( 'another', $parser->unknown_assoc( $assoc_args ) ); + $this->assertContains( 'another', $validator->unknown_assoc( $assoc_args ) ); } function testMissingAssoc() { - $parser = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); + $validator = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); $assoc_args = array( 'brand' => true, 'flag' => true ); - $errors = $parser->validate_assoc( $assoc_args ); + $errors = $validator->validate_assoc( $assoc_args ); $this->assertCount( 1, $errors['fatal'] ); $this->assertCount( 1, $errors['warning'] ); } function testAssocWithOptionalValue() { - $parser = new SynopsisValidator( '[--network[=<id>]]' ); + $validator = new SynopsisValidator( '[--network[=<id>]]' ); $assoc_args = array( 'network' => true ); - $errors = $parser->validate_assoc( $assoc_args ); + $errors = $validator->validate_assoc( $assoc_args ); $this->assertCount( 0, $errors['fatal'] ); $this->assertCount( 0, $errors['warning'] ); From d2d9f5ba3c38e756d81c1039e4167b61d38f38ed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 16 Sep 2013 02:13:48 +0300 Subject: [PATCH 2290/4858] add test that catches #663 --- features/core.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/core.feature b/features/core.feature index 0d2a8456e3..07849eda64 100644 --- a/features/core.feature +++ b/features/core.feature @@ -90,6 +90,13 @@ Feature: Manage WordPress installation Run `wp core install`. """ + When I try `wp core install` + Then the return code should be 1 + And STDERR should contain: + """ + missing --url parameter + """ + When I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty From 0486d2b7adab67b2015a32e9fae09b73db87152c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 16 Sep 2013 02:06:14 +0300 Subject: [PATCH 2291/4858] instead of ignoring them, pass config values along with regular assoc args to validate_assoc() --- php/WP_CLI/Dispatcher/Subcommand.php | 6 +++++- php/WP_CLI/SynopsisValidator.php | 11 +++++------ php/commands/core.php | 2 +- tests/test-arg-validation.php | 4 ++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 7e528c145d..6d36411d3a 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -167,7 +167,7 @@ private function validate_args( $args, &$assoc_args ) { exit(1); } - $errors = $validator->validate_assoc( $assoc_args, array_keys( \WP_CLI::get_config() ) ); + list( $errors, $to_unset ) = $validator->validate_assoc( array_merge( \WP_CLI::get_config(), $assoc_args ) ); if ( !empty( $errors['fatal'] ) ) { $out = 'Parameter errors:'; @@ -180,6 +180,10 @@ private function validate_args( $args, &$assoc_args ) { array_map( '\\WP_CLI::warning', $errors['warning'] ); + foreach ( $to_unset as $key ) { + unset( $assoc_args[ $key ] ); + } + foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { \WP_CLI::warning( "unknown --$key parameter" ); } diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index c4490bd781..ed67928efa 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -29,7 +29,7 @@ public function enough_positionals( $args ) { } // Checks that all required keys are present and that they have values. - public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { + public function validate_assoc( $assoc_args ) { $assoc_spec = $this->query_spec( array( 'type' => 'assoc', ) ); @@ -39,12 +39,11 @@ public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { 'warning' => array() ); + $to_unset = array(); + foreach ( $assoc_spec as $param ) { $key = $param['name']; - if ( in_array( $key, $ignored_keys ) ) - continue; - if ( !isset( $assoc_args[ $key ] ) ) { if ( !$param['optional'] ) { $errors['fatal'][] = "missing --$key parameter"; @@ -54,12 +53,12 @@ public function validate_assoc( &$assoc_args, $ignored_keys = array() ) { $error_type = ( !$param['optional'] ) ? 'fatal' : 'warning'; $errors[ $error_type ][] = "--$key parameter needs a value"; - unset( $assoc_args[ $key ] ); + $to_unset[] = $key; } } } - return $errors; + return array( $errors, $to_unset ); } public function unknown_assoc( $assoc_args ) { diff --git a/php/commands/core.php b/php/commands/core.php index 248f34d63a..40c26a7cb2 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -298,7 +298,7 @@ public function multisite_convert( $args, $assoc_args ) { * * ## OPTIONS * - * --url=<url> + * [--url=<url>] * : The address of the new site. * * [--base=<url-path>] diff --git a/tests/test-arg-validation.php b/tests/test-arg-validation.php index 3d1a2fa109..7db636a52d 100644 --- a/tests/test-arg-validation.php +++ b/tests/test-arg-validation.php @@ -41,7 +41,7 @@ function testMissingAssoc() { $validator = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' ); $assoc_args = array( 'brand' => true, 'flag' => true ); - $errors = $validator->validate_assoc( $assoc_args ); + list( $errors, $to_unset ) = $validator->validate_assoc( $assoc_args ); $this->assertCount( 1, $errors['fatal'] ); $this->assertCount( 1, $errors['warning'] ); @@ -51,7 +51,7 @@ function testAssocWithOptionalValue() { $validator = new SynopsisValidator( '[--network[=<id>]]' ); $assoc_args = array( 'network' => true ); - $errors = $validator->validate_assoc( $assoc_args ); + list( $errors, $to_unset ) = $validator->validate_assoc( $assoc_args ); $this->assertCount( 0, $errors['fatal'] ); $this->assertCount( 0, $errors['warning'] ); From 510bd2c282bb6d7b06311b9820a401dcdc3023c3 Mon Sep 17 00:00:00 2001 From: LA Watts <luke@thisis.la> Date: Mon, 16 Sep 2013 05:20:26 +0100 Subject: [PATCH 2292/4858] Adds show_admin_column --- templates/taxonomy.mustache | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index f4431bf488..24f317c768 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -1,6 +1,7 @@ register_taxonomy( '{{slug}}', array( {{post_types}} ), array( 'hierarchical' => false, 'public' => true, + 'show_admin_column' => false, 'show_in_nav_menus' => true, 'show_ui' => true, 'query_var' => true, From 092f4a135c6eaf353a0d8a99cec2470766bc91d8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 16 Sep 2013 12:15:10 +0300 Subject: [PATCH 2293/4858] remove extra spaces in scaffold templates --- templates/post_type.mustache | 18 +++++++------- templates/taxonomy.mustache | 48 ++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 429e002264..cd242e053c 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -1,13 +1,13 @@ register_post_type( '{{slug}}', array( - 'hierarchical' => false, - 'public' => true, - 'show_in_nav_menus' => true, - 'show_ui' => true, - 'supports' => array( 'title', 'editor' ), - 'has_archive' => true, - 'query_var' => true, - 'rewrite' => true, - 'labels' => array( + 'hierarchical' => false, + 'public' => true, + 'show_in_nav_menus' => true, + 'show_ui' => true, + 'supports' => array( 'title', 'editor' ), + 'has_archive' => true, + 'query_var' => true, + 'rewrite' => true, + 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), 'add_new' => __( 'Add new {{label}}', '{{textdomain}}' ), diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index 24f317c768..911a6881c6 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -1,32 +1,32 @@ register_taxonomy( '{{slug}}', array( {{post_types}} ), array( - 'hierarchical' => false, - 'public' => true, - 'show_admin_column' => false, - 'show_in_nav_menus' => true, - 'show_ui' => true, - 'query_var' => true, - 'rewrite' => true, - 'capabilities' => array( + 'hierarchical' => false, + 'public' => true, + 'show_in_nav_menus' => true, + 'show_ui' => true, + 'show_admin_column' => false, + 'query_var' => true, + 'rewrite' => true, + 'capabilities' => array( 'manage_terms' => 'edit_posts', 'edit_terms' => 'edit_posts', 'delete_terms' => 'edit_posts', 'assign_terms' => 'edit_posts' ), - 'labels' => array( - 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), - 'singular_name' => _x( '{{label_ucfirst}}', 'taxonomy general name', '{{textdomain}}' ), - 'search_items' => __( 'Search {{label_plural}}', '{{textdomain}}' ), - 'popular_items' => __( 'Popular {{label_plural}}', '{{textdomain}}' ), - 'all_items' => __( 'All {{label_plural}}', '{{textdomain}}' ), - 'parent_item' => __( 'Parent {{label}}', '{{textdomain}}' ), - 'parent_item_colon' => __( 'Parent {{label}}:', '{{textdomain}}' ), - 'edit_item' => __( 'Edit {{label}}', '{{textdomain}}' ), - 'update_item' => __( 'Update {{label}}', '{{textdomain}}' ), - 'add_new_item' => __( 'New {{label}}', '{{textdomain}}' ), - 'new_item_name' => __( 'New {{label}}', '{{textdomain}}' ), - 'separate_items_with_commas' => __( '{{label_plural_ucfirst}} separated by comma', '{{textdomain}}' ), - 'add_or_remove_items' => __( 'Add or remove {{label_plural}}', '{{textdomain}}' ), - 'choose_from_most_used' => __( 'Choose from the most used {{label_plural}}', '{{textdomain}}' ), - 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'labels' => array( + 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'singular_name' => _x( '{{label_ucfirst}}', 'taxonomy general name', '{{textdomain}}' ), + 'search_items' => __( 'Search {{label_plural}}', '{{textdomain}}' ), + 'popular_items' => __( 'Popular {{label_plural}}', '{{textdomain}}' ), + 'all_items' => __( 'All {{label_plural}}', '{{textdomain}}' ), + 'parent_item' => __( 'Parent {{label}}', '{{textdomain}}' ), + 'parent_item_colon' => __( 'Parent {{label}}:', '{{textdomain}}' ), + 'edit_item' => __( 'Edit {{label}}', '{{textdomain}}' ), + 'update_item' => __( 'Update {{label}}', '{{textdomain}}' ), + 'add_new_item' => __( 'New {{label}}', '{{textdomain}}' ), + 'new_item_name' => __( 'New {{label}}', '{{textdomain}}' ), + 'separate_items_with_commas' => __( '{{label_plural_ucfirst}} separated by comma', '{{textdomain}}' ), + 'add_or_remove_items' => __( 'Add or remove {{label_plural}}', '{{textdomain}}' ), + 'choose_from_most_used' => __( 'Choose from the most used {{label_plural}}', '{{textdomain}}' ), + 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), ), ) ); From 7f43b89f915fddca980a4ffaab34ab1289322422 Mon Sep 17 00:00:00 2001 From: Andrey Savchenko <contact@rarst.net> Date: Tue, 17 Sep 2013 20:15:02 +0300 Subject: [PATCH 2294/4858] Trimmed whitespace on extracted synopsis lines Fixes #770 on Windows --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 6d36411d3a..208b90f1c9 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -26,7 +26,7 @@ function __construct( $parent, $name, $docparser, $when_invoked ) { private static function extract_synopsis( $longdesc ) { preg_match_all( '/(.+)\n:/', $longdesc, $matches ); - return implode( ' ', $matches[1] ); + return implode( ' ', array_map( 'trim', $matches[1] ) ); } function get_synopsis() { From 679fd370fc8597cfd02e6d739587315739b6c8ae Mon Sep 17 00:00:00 2001 From: Andrey Savchenko <contact@rarst.net> Date: Wed, 18 Sep 2013 13:31:31 +0300 Subject: [PATCH 2295/4858] Refactored end of line trim of synopsis extraction into regex. --- php/WP_CLI/Dispatcher/Subcommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 208b90f1c9..5d6145f37c 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -25,8 +25,8 @@ function __construct( $parent, $name, $docparser, $when_invoked ) { } private static function extract_synopsis( $longdesc ) { - preg_match_all( '/(.+)\n:/', $longdesc, $matches ); - return implode( ' ', array_map( 'trim', $matches[1] ) ); + preg_match_all( '/(.+?)[\r\n]+:/', $longdesc, $matches ); + return implode( ' ', $matches[1] ); } function get_synopsis() { From 4002f0d18c1b41cdf21db50f42580fce6bc980dd Mon Sep 17 00:00:00 2001 From: Alex Ciobica <alex.ciobica@gmail.com> Date: Thu, 19 Sep 2013 18:14:27 +0300 Subject: [PATCH 2296/4858] Fix mysql environment issue. --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 1b3b1a6ce0..7ef0475e09 100644 --- a/php/utils.php +++ b/php/utils.php @@ -424,7 +424,7 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { $assoc_args = array_merge( $assoc_args, mysql_host_to_cli_args( $assoc_args['host'] ) ); } - $env = array(); + $env = (array) $_ENV; if ( isset( $assoc_args['pass'] ) ) { $env['MYSQL_PWD'] = $assoc_args['pass']; unset( $assoc_args['pass'] ); From 5458bd5d4574f64f18ac90d798d713823e286aac Mon Sep 17 00:00:00 2001 From: Alex Ciobica <alex.ciobica@gmail.com> Date: Thu, 19 Sep 2013 18:14:49 +0300 Subject: [PATCH 2297/4858] Lint. --- php/utils.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 7ef0475e09..84289730ec 100644 --- a/php/utils.php +++ b/php/utils.php @@ -43,7 +43,7 @@ function load_command( $name ) { } function load_all_commands() { - $cmd_dir = WP_CLI_ROOT . "/php/commands"; + $cmd_dir = WP_CLI_ROOT . '/php/commands'; $iterator = new \DirectoryIterator( $cmd_dir ); @@ -217,7 +217,7 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria } elseif ( is_array( $data ) ) { - $_tmp = array( ); + $_tmp = array(); foreach ( $data as $key => $value ) { $_tmp[ $key ] = recursive_unserialize_replace( $from, $to, $value, false ); } @@ -311,7 +311,7 @@ function assoc_array_to_table( $fields ) { $rows = array(); foreach ( $fields as $field => $value ) { - if ( !is_string($value) ) { + if ( ! is_string( $value ) ) { $value = json_encode( $value ); } From 8e3202c23b3d5726d1eb9165443a9d004c2e14a9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 19 Sep 2013 23:18:49 +0300 Subject: [PATCH 2298/4858] add --field arg to 'wp post get' --- features/post.feature | 2 +- php/commands/post.php | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/features/post.feature b/features/post.feature index 8d6816ad8d..8b7844714d 100644 --- a/features/post.feature +++ b/features/post.feature @@ -50,7 +50,7 @@ Feature: Manage WordPress posts excerpt """ - When I run `wp post get --format=content {POST_ID}` + When I run `wp post get --field=content {POST_ID}` Then STDOUT should be: """ This is some content. diff --git a/php/commands/post.php b/php/commands/post.php index 5b8a734670..dc1d1d218c 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -138,11 +138,13 @@ protected function _edit( $content, $title ) { * <id> * : The ID of the post to get. * + * [--field=<field>] + * : Instead of returning the whole post, returns the value of a single field. The --format= + * parameter is ignored in this case. + * * [--format=<format>] * : The format to use when printing the post, acceptable values: * - * - **content**: Outputs only the post's content. - * * - **table**: Outputs all fields of the post as a table. Note that the * post_content field is omitted so that the table is readable. * @@ -150,9 +152,8 @@ protected function _edit( $content, $title ) { * * ## EXAMPLES * - * wp post get 12 --format=content - * - * wp post get 12 > file.txt + * # save the post content to a file + * wp post get 12 --field=content > file.txt */ public function get( $args, $assoc_args ) { $defaults = array( @@ -162,13 +163,32 @@ public function get( $args, $assoc_args ) { $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) - \WP_CLI::error( "Failed opening post $post_id to get." ); + \WP_CLI::error( "Could not find the post with ID $post_id." ); - switch ( $assoc_args['format'] ) { + if ( isset( $assoc_args['field'] ) ) { + self::show_single_field( $post, $assoc_args['field'] ); + } else { + self::show_multiple_fields( $post, $assoc_args ); + } + } - case 'content': - WP_CLI::print_value( $post->post_content ); - break; + private function show_single_field( $post, $field ) { + $value = null; + + foreach ( array( $field, "post_$field" ) as $key ) { + if ( isset( $post->$key ) ) + $value = $post->$key; + } + + if ( null === $value ) { + \WP_CLI::error( "Invalid post field: $field." ); + } else { + WP_CLI::print_value( $value ); + } + } + + private function show_multiple_fields( $post, $assoc_args ) { + switch ( $assoc_args['format'] ) { case 'table': $fields = get_object_vars( $post ); From 65a6161078717a3e51f97701eaa46ea09c3df632 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 19 Sep 2013 23:32:02 +0300 Subject: [PATCH 2299/4858] add --field arg to 'wp user get' --- features/user.feature | 9 +++++---- php/WP_CLI/CommandWithDBObject.php | 30 +++++++++++++++++++++++------- php/commands/post.php | 24 ++++-------------------- php/commands/user.php | 13 ++++++++++++- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/features/user.feature b/features/user.feature index 1e39b3eb0b..1f0413be92 100644 --- a/features/user.feature +++ b/features/user.feature @@ -72,10 +72,11 @@ Feature: Manage WordPress users When I run `wp user add-role 1 editor` Then STDOUT should not be empty - And I run `wp user get 1` - Then STDOUT should be a table containing rows: - | Field | Value | - | roles | administrator, editor | + And I run `wp user get 1 --field=roles` + Then STDOUT should be: + """ + administrator, editor + """ When I run `wp user set-role 1 author` Then STDOUT should not be empty diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 7978ce37b6..3a751ce476 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -47,6 +47,17 @@ public function update( $args, $assoc_args ) { exit( $status ); } + public function delete( $args, $assoc_args ) { + $status = 0; + + foreach ( $args as $obj_id ) { + $r = $this->_delete( $obj_id, $assoc_args ); + $status = $this->success_or_failure( $r ); + } + + exit( $status ); + } + protected function wp_error_to_resp( $r, $success_msg ) { if ( is_wp_error( $r ) ) return array( 'error', $r->get_error_message() ); @@ -68,16 +79,21 @@ protected function success_or_failure( $r ) { return $status; } - public function delete( $args, $assoc_args ) { - $status = 0; + protected function show_single_field( $post, $field ) { + $value = null; - foreach ( $args as $obj_id ) { - $r = $this->_delete( $obj_id, $assoc_args ); - $status = $this->success_or_failure( $r ); + foreach ( array( $field, $this->obj_type . '_' . $field ) as $key ) { + if ( isset( $post->$key ) ) { + $value = $post->$key; + break; + } } - exit( $status ); + if ( null === $value ) { + \WP_CLI::error( "Invalid $this->obj_type field: $field." ); + } else { + \WP_CLI::print_value( $value ); + } } - } diff --git a/php/commands/post.php b/php/commands/post.php index dc1d1d218c..3bf21ec33f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -139,8 +139,7 @@ protected function _edit( $content, $title ) { * : The ID of the post to get. * * [--field=<field>] - * : Instead of returning the whole post, returns the value of a single field. The --format= - * parameter is ignored in this case. + * : Instead of returning the whole post, returns the value of a single field. * * [--format=<format>] * : The format to use when printing the post, acceptable values: @@ -152,7 +151,7 @@ protected function _edit( $content, $title ) { * * ## EXAMPLES * - * # save the post content to a file + * # save the post content to a file * wp post get 12 --field=content > file.txt */ public function get( $args, $assoc_args ) { @@ -166,24 +165,9 @@ public function get( $args, $assoc_args ) { \WP_CLI::error( "Could not find the post with ID $post_id." ); if ( isset( $assoc_args['field'] ) ) { - self::show_single_field( $post, $assoc_args['field'] ); + $this->show_single_field( $post, $assoc_args['field'] ); } else { - self::show_multiple_fields( $post, $assoc_args ); - } - } - - private function show_single_field( $post, $field ) { - $value = null; - - foreach ( array( $field, "post_$field" ) as $key ) { - if ( isset( $post->$key ) ) - $value = $post->$key; - } - - if ( null === $value ) { - \WP_CLI::error( "Invalid post field: $field." ); - } else { - WP_CLI::print_value( $value ); + $this->show_multiple_fields( $post, $assoc_args ); } } diff --git a/php/commands/user.php b/php/commands/user.php index 5a0abe55fe..e4c8e2befd 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -88,6 +88,9 @@ public function _list( $args, $assoc_args ) { * <user> * : User ID or user login. * + * [--field=<field>] + * : Instead of returning the whole user, returns the value of a single field. + * * [--format=<format>] * : The format to use when printing the user; acceptable values: * @@ -97,7 +100,7 @@ public function _list( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user get 12 + * wp user get 12 --field=login * * wp user get bob --format=json > bob.json */ @@ -116,6 +119,14 @@ public function get( $args, $assoc_args ) { } $user_data['roles'] = implode( ', ', $user->roles ); + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( (object) $user_data, $assoc_args['field'] ); + } else { + $this->show_multiple_fields( $user_data, $assoc_args ); + } + } + + private function show_multiple_fields( $user_data, $assoc_args ) { switch ( $assoc_args['format'] ) { case 'table': From 53c1cf3a86fd91c016b31ecc1332b609921f9eaf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 20 Sep 2013 00:20:28 +0300 Subject: [PATCH 2300/4858] make Comment_Command extend CommandWithDbObject --- features/comment.feature | 10 ++++- php/WP_CLI/CommandWithDBObject.php | 7 +++- php/commands/comment.php | 60 ++++++++++++++++++++++++------ 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index e372172f0f..551c870aa1 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -3,7 +3,7 @@ Feature: Manage WordPress comments Scenario: Creating/updating/deleting comments Given a WP install - When I run `wp comment create --comment_post_ID=1 --comment_content='Hello' --porcelain` + When I run `wp comment create --comment_post_ID=1 --comment_content='Hello' --comment_author='Billy' --porcelain` Then STDOUT should be a number And save STDOUT as {COMMENT_ID} @@ -13,6 +13,14 @@ Feature: Manage WordPress comments Success: Comment with ID {COMMENT_ID} exists. """ + When I run `wp comment update {COMMENT_ID} --comment_author='Johnny'` + Then STDOUT should not be empty + + When I run `wp comment get {COMMENT_ID}` + Then STDOUT should be a table containing rows: + | Field | Value | + | comment_author | Johnny | + When I run `wp comment delete {COMMENT_ID}` Then STDOUT should be: """ diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 7978ce37b6..d574b8e049 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -9,12 +9,15 @@ */ abstract class CommandWithDBObject extends \WP_CLI_Command { + protected $obj_type; + protected $obj_id_key = 'ID'; + abstract protected function _create( $params ); abstract protected function _update( $params ); abstract protected function _delete( $obj_id, $assoc_args ); public function create( $args, $assoc_args ) { - unset( $assoc_args['ID'] ); + unset( $assoc_args[ $this->obj_id_key ] ); $obj_id = $this->_create( $assoc_args ); @@ -36,7 +39,7 @@ public function update( $args, $assoc_args ) { } foreach ( $args as $obj_id ) { - $params = array_merge( $assoc_args, array( 'ID' => $obj_id ) ); + $params = array_merge( $assoc_args, array( $this->obj_id_key => $obj_id ) ); $status = $this->success_or_failure( $this->wp_error_to_resp( $this->_update( $params ), diff --git a/php/commands/comment.php b/php/commands/comment.php index d59e134c92..a480969d6a 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -5,7 +5,10 @@ * * @package wp-cli */ -class Comment_Command extends WP_CLI_Command { +class Comment_Command extends \WP_CLI\CommandWithDBObject { + + protected $obj_type = 'comment'; + protected $obj_id_key = 'comment_ID'; private $fields = array( 'comment_ID', @@ -32,22 +35,51 @@ class Comment_Command extends WP_CLI_Command { * wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" */ public function create( $args, $assoc_args ) { + parent::create( $args, $assoc_args ); + } + + protected function _create( $assoc_args ) { $post = get_post( $assoc_args['comment_post_ID'] ); if ( !$post ) { - WP_CLI::error( "Cannot find post $comment_post_ID" ); + return new WP_Error( 'no_post', "Can't find post $comment_post_ID." ); } - // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and avoid wp_die() formatted messages or notifications + // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and + // avoid wp_die() formatted messages or notifications $comment_id = wp_insert_comment( $assoc_args ); if ( !$comment_id ) { - WP_CLI::error( "Could not create comment" ); + return new WP_Error( 'db_error', 'Could not create comment.' ); + } + + return $comment_id; + } + + /** + * Update one or more comments. + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of comments to update. + * + * --<field>=<value> + * : One or more fields to update. See wp_update_comment(). + * + * ## EXAMPLES + * + * wp comment update 123 --comment_author='That Guy' + */ + public function update( $args, $assoc_args ) { + parent::update( $args, $assoc_args ); + } + + protected function _update( $params ) { + if ( !wp_update_comment( $params ) ) { + return new WP_Error( 'Could not update comment.' ); } - if ( isset( $assoc_args['porcelain'] ) ) - WP_CLI::line( $comment_id ); - else - WP_CLI::success( "Inserted comment $comment_id." ); + return true; } /** @@ -164,12 +196,16 @@ public function _list( $_, $assoc_args ) { * wp comment delete 1337 --force */ public function delete( $args, $assoc_args ) { - list( $comment_id ) = $args; + parent::delete( $args, $assoc_args ); + } + + protected function _delete( $comment_id, $assoc_args ) { + $r = wp_delete_comment( $comment_id, isset( $assoc_args['force'] ) ); - if ( wp_delete_comment( $comment_id, isset( $assoc_args['force'] ) ) ) { - WP_CLI::success( "Deleted comment $comment_id." ); + if ( $r ) { + return array( 'success', "Deleted comment $comment_id." ); } else { - WP_CLI::error( "Failed deleting comment $comment_id" ); + return array( 'error', "Failed deleting comment $comment_id" ); } } From 9f09f4f29cbf7d6701e92b99e03d59c773ad74b9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 20 Sep 2013 00:40:41 +0300 Subject: [PATCH 2301/4858] add --field arg to 'wp comment get' --- features/comment.feature | 9 +++++---- php/commands/comment.php | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 551c870aa1..3ffebb8216 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -16,10 +16,11 @@ Feature: Manage WordPress comments When I run `wp comment update {COMMENT_ID} --comment_author='Johnny'` Then STDOUT should not be empty - When I run `wp comment get {COMMENT_ID}` - Then STDOUT should be a table containing rows: - | Field | Value | - | comment_author | Johnny | + When I run `wp comment get {COMMENT_ID} --field=author` + Then STDOUT should be: + """ + Johnny + """ When I run `wp comment delete {COMMENT_ID}` Then STDOUT should be: diff --git a/php/commands/comment.php b/php/commands/comment.php index a480969d6a..8120a81b07 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -90,6 +90,9 @@ protected function _update( $params ) { * <id> * : The comment to get. * + * [--field=<field>] + * : Instead of returning the whole comment, returns the value of a single field. + * * [--format=<format>] * : The format to use when printing the comment, acceptable values: * @@ -98,10 +101,9 @@ protected function _update( $params ) { * * ## EXAMPLES * - * wp comment get 1 + * wp comment get 1 --field=content */ public function get( $args, $assoc_args ) { - $defaults = array( 'format' => 'table' ); @@ -112,10 +114,19 @@ public function get( $args, $assoc_args ) { if ( empty( $comment ) ) WP_CLI::error( "Invalid comment ID." ); + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( $comment, $assoc_args['field'] ); + } else { + $this->show_multiple_fields( $comment, $assoc_args ); + } + } + + private function show_multiple_fields( $comment, $assoc_args ) { switch ( $assoc_args['format'] ) { case 'table': $fields = get_object_vars( $comment ); + unset( $fields['comment_content'] ); \WP_CLI\Utils\assoc_array_to_table( $fields ); break; From 670e66fb8103bbd6f4e530c4c5c8d37841f14094 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 20 Sep 2013 03:52:07 +0300 Subject: [PATCH 2302/4858] behat: use Background feature --- features/comment.feature | 5 ++--- features/media.feature | 14 +++----------- features/post.feature | 8 +++----- features/scaffold.feature | 17 +++++------------ features/term.feature | 5 ++--- features/user.feature | 12 +++--------- 6 files changed, 18 insertions(+), 43 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 3ffebb8216..1b7da523ff 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -1,8 +1,9 @@ Feature: Manage WordPress comments - Scenario: Creating/updating/deleting comments + Background: Given a WP install + Scenario: Creating/updating/deleting comments When I run `wp comment create --comment_post_ID=1 --comment_content='Hello' --comment_author='Billy' --porcelain` Then STDOUT should be a number And save STDOUT as {COMMENT_ID} @@ -29,8 +30,6 @@ Feature: Manage WordPress comments """ Scenario: Get details about an existing comment - Given a WP install - When I run `wp comment get 1` Then STDOUT should be a table containing rows: | Field | Value | diff --git a/features/media.feature b/features/media.feature index 74752d2771..81a1d5bf13 100644 --- a/features/media.feature +++ b/features/media.feature @@ -1,39 +1,31 @@ Feature: Manage WordPress attachments - @images - Scenario: Regenerate all images while none exists + Background: Given a WP install + Scenario: Regenerate all images while none exists When I try `wp media regenerate --yes` Then STDERR should contain: """ Error: Unable to find the images """ - @images Scenario: Import image from remote URL - Given a WP install - When I run `wp media import 'http://s.wordpress.org/style/images/codeispoetry.png' --post_id=1` Then STDOUT should contain: """ Success: Imported file http://s.wordpress.org/style/images/codeispoetry.png """ - @images Scenario: Fail to import missing image - Given a WP install - When I try `wp media import gobbledygook.png` Then STDERR should contain: """ Unable to import file gobbledygook.png. Reason: File doesn't exist. """ - @images Scenario: Import a file as attachment from a local image - Given a WP install - And download: + Given download: | path | url | | {CACHE_DIR}/large-image.jpg | http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg | diff --git a/features/post.feature b/features/post.feature index 8b7844714d..84d864b98a 100644 --- a/features/post.feature +++ b/features/post.feature @@ -1,8 +1,9 @@ Feature: Manage WordPress posts - Scenario: Creating/updating/deleting posts + Background: Given a WP install + Scenario: Creating/updating/deleting posts When I run `wp post create --post_title='Test post' --porcelain` Then STDOUT should be a number And save STDOUT as {POST_ID} @@ -26,8 +27,7 @@ Feature: Manage WordPress posts Then the return code should be 1 Scenario: Creating/getting posts - Given a WP install - And a content.html file: + Given a content.html file: """ This is some content. @@ -74,8 +74,6 @@ Feature: Manage WordPress posts """ Scenario: Creating/listing posts - Given a WP install - When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` Then STDOUT should be a number diff --git a/features/scaffold.feature b/features/scaffold.feature index d5efe98491..69431b33ba 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,9 +1,11 @@ Feature: Wordpress code scaffolding + Background: + Given a WP install + @theme Scenario: Scaffold a child theme - Given a WP install - And I run `wp theme path` + Given I run `wp theme path` And save STDOUT as {THEME_DIR} When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --activate` @@ -12,8 +14,7 @@ Feature: Wordpress code scaffolding @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme - Given a WP install - And I run `wp eval 'echo STYLESHEETPATH;'` + Given I run `wp eval 'echo STYLESHEETPATH;'` And save STDOUT as {STYLESHEETPATH} When I run `wp scaffold taxonomy zombie-speed --theme` @@ -25,8 +26,6 @@ Feature: Wordpress code scaffolding # Test for all flags but --label, --theme, --plugin and --raw @tax Scenario: Scaffold a Custom Taxonomy and attach it to CPTs including one that is prefixed and has a text domain - Given a WP install - When I run `wp scaffold taxonomy zombie-speed --post_types="prefix-zombie,wraith" --textdomain=zombieland` Then STDOUT should contain: """ @@ -43,8 +42,6 @@ Feature: Wordpress code scaffolding @tax Scenario: Scaffold a Custom Taxonomy with label "Speed" - Given a WP install - When I run `wp scaffold taxonomy zombie-speed --label="Speed"` Then STDOUT should contain: """ @@ -58,8 +55,6 @@ Feature: Wordpress code scaffolding # Test for all flags but --label, --theme, --plugin and --raw @cpt Scenario: Scaffold a Custom Post Type - Given a WP install - When I run `wp scaffold post-type zombie --textdomain=zombieland` Then STDOUT should contain: """ @@ -72,8 +67,6 @@ Feature: Wordpress code scaffolding @cpt Scenario: Scaffold a Custom Post Type with label - Given a WP install - When I run `wp scaffold post-type zombie --label="Brain eater"` Then STDOUT should contain: """ diff --git a/features/term.feature b/features/term.feature index b658eb97e9..b0e1e04879 100644 --- a/features/term.feature +++ b/features/term.feature @@ -1,8 +1,9 @@ Feature: Manage WordPress terms - Scenario: Creating/listing a term + Background: Given a WP install + Scenario: Creating/listing a term When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term' --porcelain` Then STDOUT should be a number And save STDOUT as {TERM_ID} @@ -34,8 +35,6 @@ Feature: Manage WordPress terms | name | Test term | Scenario: Creating/deleting a term - Given a WP install - When I run `wp term create 'Test delete term' post_tag --slug=test-delete --description='This is a test term to be deleted' --porcelain` Then STDOUT should be a number And save STDOUT as {TERM_ID} diff --git a/features/user.feature b/features/user.feature index 1f0413be92..68f85a9ade 100644 --- a/features/user.feature +++ b/features/user.feature @@ -1,8 +1,9 @@ Feature: Manage WordPress users - Scenario: User CRUD operations + Background: Given a WP install + Scenario: User CRUD operations When I run `wp user create testuser testuser@example.com --porcelain` Then STDOUT should be a number And save STDOUT as {USER_ID} @@ -21,8 +22,6 @@ Feature: Manage WordPress users Then STDOUT should not be empty Scenario: Generating and deleting users - Given a WP install - When I run `wp user generate --count=9` And I run `wp user list --format=count` Then STDOUT should be: @@ -38,8 +37,7 @@ Feature: Manage WordPress users """ Scenario: Importing users from a CSV file - Given a WP install - And a users.csv file: + Given a users.csv file: """ user_login,user_email,display_name,role bobjones,bobjones@domain.com,Bob Jones,contributor @@ -68,8 +66,6 @@ Feature: Manage WordPress users """ Scenario: Managing user roles - Given a WP install - When I run `wp user add-role 1 editor` Then STDOUT should not be empty And I run `wp user get 1 --field=roles` @@ -100,8 +96,6 @@ Feature: Manage WordPress users | roles | | Scenario: Managing user capabilities - Given a WP install - When I run `wp user add-cap 1 edit_vip_product` Then STDOUT should be: """ From 72c6671393f038ee1f8005606e88e4a7a279a49e Mon Sep 17 00:00:00 2001 From: Corey Taylor <ctaylor@thinkoomph.com> Date: Sun, 22 Sep 2013 13:11:29 -0400 Subject: [PATCH 2303/4858] Adds --skip=image_resize to 'wp import' command. Gives import user the option to skip image thumbnail generation during image attachment import. Image resizing is extremely CPU intensive and makes imports run much slower, especially during test runs that don't necessarily require all image sizes. Image resizing can always be deferred post import by running the 'wp media regenerate' command. --- php/commands/import.php | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/php/commands/import.php b/php/commands/import.php index 493badb64e..e5c6c33a05 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -124,6 +124,58 @@ private function import_wxr( $args ) { 'user_map' => $user_select, 'fetch_attachments' => $wp_import->fetch_attachments, ); + + if( in_array( 'image_resize', $args['skip'] ) ) { + add_filter( 'intermediate_image_sizes_advanced', function ($sizes) { + // Save the given sizes so that when the wp_generate_attachment_metadata hook + // is called we can place this info on to the $metadata array so that the + // info gets saved to the database, but the actual resize processing does + // not occur. + $this->sizes = $sizes; + + return null; + } ); + + add_filter( 'wp_generate_attachment_metadata', function ($metadata, $attachment_id) { + if( !isset( $metadata['file'] ) ) + return $metadata; + + $upload_dir = wp_upload_dir(); + $file_path = $upload_dir['basedir'] . '/' . $metadata['file']; + $path_info = pathinfo( $file_path ); + $mime_type = get_post_mime_type( $attachment_id ); + + // Return current meta untouched if can't determine current image mime type. + if( !$mime_type ) + return $metadata; + + $metadata['sizes'] = array( ); + + // Now time to generate the image size metadata since some resized files + // should already be on disk. We just have to point WordPress to them. + // Note: this logic will not find all possibled resized thumbnail files. + // To be sure _wp_attachment_metadata gets populated with all possible + // custom image sizes, run a command like WP-CLI's 'media regenerate' in order + // to re-generate and link to all the various configured image sizes. + foreach( $this->sizes as $size => $size_data ) { + $file = $path_info['filename'] . '-' . $size_data['width'] . 'x' . $size_data['height'] . '.' . $path_info['extension']; + + // Make sure the file exists before adding a size entry to the meta array. + if( !file_exists( $path_info['dirname'] . '/' . $file ) ) + continue; // File does not exist, don't point to it. + + $metadata['sizes'][$size] = array( + 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $file ) ), + 'width' => $size_data['width'], + 'height' => $size_data['height'], + 'mime-type' => $mime_type, + ); + } + + return $metadata; + }, 10, 2 ); + } + $wp_import->import( $args['file'] ); return true; From cb57cc0a7c7d57d595eeb275940d612da12f6522 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 23 Sep 2013 16:59:57 +0300 Subject: [PATCH 2304/4858] account for XDebug not being installed when setting 'display_errors' --- php/utils-wp.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index 4a307e7538..1d925c6be1 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -22,8 +22,8 @@ function wp_debug_mode() { \wp_debug_mode(); } - // Never show errors on STDOUT; only on STDERR - ini_set( 'display_errors', false ); + // XDebug already sends errors to STDERR + ini_set( 'display_errors', function_exists( 'xdebug_debug_zval' ) ? false : 'STDERR' ); } function replace_wp_die_handler() { From 44d72dab035e8c45cf1c56918e88316384867296 Mon Sep 17 00:00:00 2001 From: Corey Taylor <ctaylor@thinkoomph.com> Date: Tue, 24 Sep 2013 16:23:23 -0400 Subject: [PATCH 2305/4858] Re-factored patch to work with PHP < 5.4. --- php/commands/import.php | 99 +++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index e5c6c33a05..eeff977cc9 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -126,54 +126,8 @@ private function import_wxr( $args ) { ); if( in_array( 'image_resize', $args['skip'] ) ) { - add_filter( 'intermediate_image_sizes_advanced', function ($sizes) { - // Save the given sizes so that when the wp_generate_attachment_metadata hook - // is called we can place this info on to the $metadata array so that the - // info gets saved to the database, but the actual resize processing does - // not occur. - $this->sizes = $sizes; - - return null; - } ); - - add_filter( 'wp_generate_attachment_metadata', function ($metadata, $attachment_id) { - if( !isset( $metadata['file'] ) ) - return $metadata; - - $upload_dir = wp_upload_dir(); - $file_path = $upload_dir['basedir'] . '/' . $metadata['file']; - $path_info = pathinfo( $file_path ); - $mime_type = get_post_mime_type( $attachment_id ); - - // Return current meta untouched if can't determine current image mime type. - if( !$mime_type ) - return $metadata; - - $metadata['sizes'] = array( ); - - // Now time to generate the image size metadata since some resized files - // should already be on disk. We just have to point WordPress to them. - // Note: this logic will not find all possibled resized thumbnail files. - // To be sure _wp_attachment_metadata gets populated with all possible - // custom image sizes, run a command like WP-CLI's 'media regenerate' in order - // to re-generate and link to all the various configured image sizes. - foreach( $this->sizes as $size => $size_data ) { - $file = $path_info['filename'] . '-' . $size_data['width'] . 'x' . $size_data['height'] . '.' . $path_info['extension']; - - // Make sure the file exists before adding a size entry to the meta array. - if( !file_exists( $path_info['dirname'] . '/' . $file ) ) - continue; // File does not exist, don't point to it. - - $metadata['sizes'][$size] = array( - 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $file ) ), - 'width' => $size_data['width'], - 'height' => $size_data['height'], - 'mime-type' => $mime_type, - ); - } - - return $metadata; - }, 10, 2 ); + add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_set_image_sizes' ) ); + add_filter( 'wp_generate_attachment_metadata', array( $this, 'filter_set_image_metadata' ), 10, 2 ); } $wp_import->import( $args['file'] ); @@ -181,6 +135,55 @@ private function import_wxr( $args ) { return true; } + public function filter_set_image_sizes( $sizes ) { + // Save the given sizes so that when the wp_generate_attachment_metadata hook + // is called we can place this info on to the $metadata array so that the + // info gets saved to the database, but the actual resize processing does + // not occur. + $this->image_sizes = $sizes; + + return null; + } + + public function filter_set_image_metadata( $metadata, $attachment_id ) { + if( !isset( $metadata['file'] ) ) + return $metadata; + + $upload_dir = wp_upload_dir(); + $file_path = $upload_dir['basedir'] . '/' . $metadata['file']; + $path_info = pathinfo( $file_path ); + $mime_type = get_post_mime_type( $attachment_id ); + + // Return current meta untouched if can't determine current image mime type. + if( !$mime_type ) + return $metadata; + + $metadata['sizes'] = array( ); + + // Now time to generate the image size metadata since some resized files + // should already be on disk. We just have to point WordPress to them. + // Note: this logic will not find all possibled resized thumbnail files. + // To be sure _wp_attachment_metadata gets populated with all possible + // custom image sizes, run a command like WP-CLI's 'media regenerate' in order + // to re-generate and link to all the various configured image sizes. + foreach( $this->image_sizes as $size => $size_data ) { + $file = $path_info['filename'] . '-' . $size_data['width'] . 'x' . $size_data['height'] . '.' . $path_info['extension']; + + // Make sure the file exists before adding a size entry to the meta array. + if( !file_exists( $path_info['dirname'] . '/' . $file ) ) + continue; // File does not exist, don't point to it. + + $metadata['sizes'][$size] = array( + 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $file ) ), + 'width' => $size_data['width'], + 'height' => $size_data['height'], + 'mime-type' => $mime_type, + ); + } + + return $metadata; + } + /** * Useful verbosity filters for the WXR importer */ From f6285d3b674e01fff81e37a2978a1436e1f94e69 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 27 Sep 2013 02:17:47 +0300 Subject: [PATCH 2306/4858] pass subcommand implementations as callbacks This allows child classes to implement only some of the subcommands. --- php/WP_CLI/CommandWithDBObject.php | 16 +++---- php/commands/comment.php | 68 ++++++++++++++---------------- php/commands/post.php | 36 +++++++--------- php/commands/user.php | 41 +++++++----------- 4 files changed, 68 insertions(+), 93 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 62f04f237b..c231fe79c4 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -12,14 +12,10 @@ abstract class CommandWithDBObject extends \WP_CLI_Command { protected $obj_type; protected $obj_id_key = 'ID'; - abstract protected function _create( $params ); - abstract protected function _update( $params ); - abstract protected function _delete( $obj_id, $assoc_args ); - - public function create( $args, $assoc_args ) { + protected function _create( $args, $assoc_args, $callback ) { unset( $assoc_args[ $this->obj_id_key ] ); - $obj_id = $this->_create( $assoc_args ); + $obj_id = $callback( $assoc_args ); if ( is_wp_error( $obj_id ) ) { \WP_CLI::error( $obj_id ); @@ -31,7 +27,7 @@ public function create( $args, $assoc_args ) { \WP_CLI::success( "Created $this->obj_type $obj_id." ); } - public function update( $args, $assoc_args ) { + protected function _update( $args, $assoc_args, $callback ) { $status = 0; if ( empty( $assoc_args ) ) { @@ -42,7 +38,7 @@ public function update( $args, $assoc_args ) { $params = array_merge( $assoc_args, array( $this->obj_id_key => $obj_id ) ); $status = $this->success_or_failure( $this->wp_error_to_resp( - $this->_update( $params ), + $callback( $params ), "Updated $this->obj_type $obj_id." ) ); } @@ -50,11 +46,11 @@ public function update( $args, $assoc_args ) { exit( $status ); } - public function delete( $args, $assoc_args ) { + protected function _delete( $args, $assoc_args, $callback ) { $status = 0; foreach ( $args as $obj_id ) { - $r = $this->_delete( $obj_id, $assoc_args ); + $r = $callback( $obj_id, $assoc_args ); $status = $this->success_or_failure( $r ); } diff --git a/php/commands/comment.php b/php/commands/comment.php index 8120a81b07..61f989bea2 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -35,24 +35,22 @@ class Comment_Command extends \WP_CLI\CommandWithDBObject { * wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" */ public function create( $args, $assoc_args ) { - parent::create( $args, $assoc_args ); - } - - protected function _create( $assoc_args ) { - $post = get_post( $assoc_args['comment_post_ID'] ); - if ( !$post ) { - return new WP_Error( 'no_post', "Can't find post $comment_post_ID." ); - } - - // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and - // avoid wp_die() formatted messages or notifications - $comment_id = wp_insert_comment( $assoc_args ); - - if ( !$comment_id ) { - return new WP_Error( 'db_error', 'Could not create comment.' ); - } - - return $comment_id; + parent::_create( $args, $assoc_args, function ( $params ) { + $post = get_post( $params['comment_post_ID'] ); + if ( !$post ) { + return new WP_Error( 'no_post', "Can't find post $comment_post_ID." ); + } + + // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and + // avoid wp_die() formatted messages or notifications + $comment_id = wp_insert_comment( $params ); + + if ( !$comment_id ) { + return new WP_Error( 'db_error', 'Could not create comment.' ); + } + + return $comment_id; + } ); } /** @@ -71,15 +69,13 @@ protected function _create( $assoc_args ) { * wp comment update 123 --comment_author='That Guy' */ public function update( $args, $assoc_args ) { - parent::update( $args, $assoc_args ); - } + parent::_update( $args, $assoc_args, function ( $params ) { + if ( !wp_update_comment( $params ) ) { + return new WP_Error( 'Could not update comment.' ); + } - protected function _update( $params ) { - if ( !wp_update_comment( $params ) ) { - return new WP_Error( 'Could not update comment.' ); - } - - return true; + return true; + } ); } /** @@ -207,17 +203,15 @@ public function _list( $_, $assoc_args ) { * wp comment delete 1337 --force */ public function delete( $args, $assoc_args ) { - parent::delete( $args, $assoc_args ); - } - - protected function _delete( $comment_id, $assoc_args ) { - $r = wp_delete_comment( $comment_id, isset( $assoc_args['force'] ) ); - - if ( $r ) { - return array( 'success', "Deleted comment $comment_id." ); - } else { - return array( 'error', "Failed deleting comment $comment_id" ); - } + parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { + $r = wp_delete_comment( $comment_id, isset( $assoc_args['force'] ) ); + + if ( $r ) { + return array( 'success', "Deleted comment $comment_id." ); + } else { + return array( 'error', "Failed deleting comment $comment_id" ); + } + } ); } private function call( $args, $status, $success, $failure ) { diff --git a/php/commands/post.php b/php/commands/post.php index 3bf21ec33f..d946293cff 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -71,11 +71,9 @@ public function create( $args, $assoc_args ) { $assoc_args['post_content'] = $input; } - parent::create( $args, $assoc_args ); - } - - protected function _create( $params ) { - return wp_insert_post( $params, true ); + parent::_create( $args, $assoc_args, function ( $params ) { + return wp_insert_post( $params, true ); + } ); } /** @@ -94,11 +92,9 @@ protected function _create( $params ) { * wp post update 123 --post_name=something --post_status=draft */ public function update( $args, $assoc_args ) { - parent::update( $args, $assoc_args ); - } - - protected function _update( $params ) { - return wp_update_post( $params, true ); + parent::_update( $args, $assoc_args, function ( $params ) { + return wp_update_post( $params, true ); + } ); } /** @@ -216,19 +212,17 @@ public function delete( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); - parent::delete( $args, $assoc_args ); - } - - protected function _delete( $post_id, $assoc_args ) { - $r = wp_delete_post( $post_id, $assoc_args['force'] ); + parent::_delete( $args, $assoc_args, function ( $post_id, $assoc_args ) { + $r = wp_delete_post( $post_id, $assoc_args['force'] ); - if ( $r ) { - $action = $assoc_args['force'] ? 'Deleted' : 'Trashed'; + if ( $r ) { + $action = $assoc_args['force'] ? 'Deleted' : 'Trashed'; - return array( 'success', "$action post $post_id." ); - } else { - return array( 'error', "Failed deleting post $post_id." ); - } + return array( 'success', "$action post $post_id." ); + } else { + return array( 'error', "Failed deleting post $post_id." ); + } + } ); } /** diff --git a/php/commands/user.php b/php/commands/user.php index e4c8e2befd..f1ffaa7fb0 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -165,23 +165,22 @@ public function delete( $args, $assoc_args ) { ) ); foreach ( $args as $key => $arg ) { - $args[$key] = self::get_user( $arg )->ID; + $args[ $key ] = self::get_user( $arg )->ID; } - parent::delete( $args, $assoc_args ); - } - protected function _delete( $user_id, $assoc_args ) { - if ( is_multisite() ) { - $r = wpmu_delete_user( $user_id ); - } else { - $r = wp_delete_user( $user_id, $assoc_args['reassign'] ); - } + parent::_delete( $args, $assoc_args, function ( $user_id, $assoc_args ) { + if ( is_multisite() ) { + $r = wpmu_delete_user( $user_id ); + } else { + $r = wp_delete_user( $user_id, $assoc_args['reassign'] ); + } - if ( $r ) { - return array( 'success', "Deleted user $user_id." ); - } else { - return array( 'error', "Failed deleting user $user_id." ); - } + if ( $r ) { + return array( 'success', "Deleted user $user_id." ); + } else { + return array( 'error', "Failed deleting user $user_id." ); + } + } ); } /** @@ -237,7 +236,7 @@ public function create( $args, $assoc_args ) { $generated_pass = true; } - $user_id = $this->_create( array( + $user_id = wp_insert_user( array( 'user_email' => $user_email, 'user_login' => $user_login, 'user_pass' => $user_pass, @@ -264,10 +263,6 @@ public function create( $args, $assoc_args ) { } } - protected function _create( $params ) { - return wp_insert_user( $params ); - } - /** * Update a user. * @@ -286,15 +281,11 @@ protected function _create( $params ) { * wp user update mary --user_pass=marypass */ public function update( $args, $assoc_args ) { - foreach ( $args as $key => $arg ) { - $args[$key] = self::get_user( $arg )->ID; + $args[ $key ] = self::get_user( $arg )->ID; } - parent::update( $args, $assoc_args, 'user' ); - } - protected function _update( $params ) { - return wp_update_user( $params ); + parent::_update( $args, $assoc_args, 'wp_update_user' ); } /** From fad4f75e705c86edb73abf6fac1b8ec95c1f6c63 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 27 Sep 2013 02:37:44 +0300 Subject: [PATCH 2307/4858] make Site_Command extend CommandWithDBObject --- php/commands/site.php | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 9a49c69c18..52a61b96dd 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -5,7 +5,7 @@ * * @package wp-cli */ -class Site_Command extends WP_CLI_Command { +class Site_Command extends \WP_CLI\CommandWithDBObject { /** * Delete comments. @@ -174,24 +174,6 @@ function delete( $args, $assoc_args ) { WP_CLI::success( "The site at $blog->siteurl was deleted." ); } - /** - * Get site (network) data for a given id. - * - * @param int $site_id - * @return bool|array False if no network found with given id, array otherwise - */ - private function _get_site( $site_id ) { - global $wpdb; - // Load site data - $sites = $wpdb->get_results( "SELECT * FROM $wpdb->site WHERE `id` = ".$wpdb->escape( $site_id ) ); - if ( count( $sites ) > 0 ) { - // Only care about domain and path which are set here - return $sites[0]; - } - - return false; - } - /** * Create a site in a multisite install. * @@ -372,6 +354,27 @@ function _list( $_, $assoc_args ) { WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); } + + /** + * Get site (network) data for a given id. + * + * @param int $site_id + * @return bool|array False if no network found with given id, array otherwise + */ + private function _get_site( $site_id ) { + global $wpdb; + + // Load site data + $sites = $wpdb->get_results( $wpdb->prepare( + "SELECT * FROM $wpdb->site WHERE id = %d", $site_id ) ); + + if ( !empty( $sites ) ) { + // Only care about domain and path which are set here + return $sites[0]; + } + + return false; + } } WP_CLI::add_command( 'site', 'Site_Command' ); From f89c6f51d71fe0ff50773c6055d709d4ae61402a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 27 Sep 2013 03:39:43 +0300 Subject: [PATCH 2308/4858] behat: show STDOUT on error --- features/bootstrap/Process.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index e0abcffbe5..1cbb194d9a 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -71,8 +71,12 @@ public function __construct( $props ) { } public function __toString() { - return sprintf( "%s: %s\n" . "cwd: %s\n" . "exit status: %d", - $this->command, $this->STDERR, $this->cwd, $this->return_code ); + $out = "$ $this->command\n"; + $out .= "$this->STDOUT\n$this->STDERR"; + $out .= "cwd: $this->cwd\n"; + $out .= "exit status: $this->return_code"; + + return $out; } } From f592cff085f7279d7319d111e26fdf1ae488d731 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Fri, 27 Sep 2013 12:09:20 -0700 Subject: [PATCH 2309/4858] Apply default filters in content in `wp post edit` I noticed that without applying the `the_editor_content` and `content_save_pre` filters to the post content being edited, unexpected things could happen when editing posts with the system editor. For example, the Syntaxhighlighter Extended plugin uses these filters cto decode entities when retrieving a post from that database to edit, and then re-encode them on save. There may be some extra thought required as to what the expected behavior should be, but this apporach seems to make the most sense to me. --- php/commands/post.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index d946293cff..51e288f52e 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -123,7 +123,9 @@ public function edit( $args, $_ ) { } protected function _edit( $content, $title ) { - return \WP_CLI\Utils\launch_editor_for_input( $content, $title ); + $content = apply_filters( 'the_editor_content', $content ); + $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title ); + return apply_filters( 'content_save_pre', $output ); } /** From 601f03ecff216d02d0bd58e0e325c8dbc62a4670 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 28 Sep 2013 17:35:28 +0300 Subject: [PATCH 2310/4858] fix `wp post edit` see #779 --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index d946293cff..a92b2f4f9e 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -119,7 +119,7 @@ public function edit( $args, $_ ) { if ( $r === false ) \WP_CLI::warning( 'No change made to post content.', 'Aborted' ); else - parent::update( $args, array( 'post_content' => $r ) ); + self::update( $args, array( 'post_content' => $r ) ); } protected function _edit( $content, $title ) { From b0dfe97c6caf0bcea59b5567411c8b50587c845a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 27 Sep 2013 03:41:24 +0300 Subject: [PATCH 2311/4858] implement --field= parameter for post, user and comment `list` subcommands --- features/comment.feature | 6 ++++++ features/post.feature | 6 ++++++ features/user.feature | 2 +- php/WP_CLI/CommandWithDBObject.php | 23 +++++++++++++---------- php/commands/comment.php | 16 ++++++++++++---- php/commands/post.php | 22 +++++++++++++++------- php/commands/user.php | 15 +++++++++++---- 7 files changed, 64 insertions(+), 26 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 1b7da523ff..96b21e701b 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -39,3 +39,9 @@ Feature: Manage WordPress comments Then STDOUT should be a table containing rows: | comment_approved | comment_author | | 1 | Mr WordPress | + + When I run `wp comment list --field=approved` + Then STDOUT should be: + """ + 1 + """ diff --git a/features/post.feature b/features/post.feature index 84d864b98a..e12db9ef25 100644 --- a/features/post.feature +++ b/features/post.feature @@ -85,3 +85,9 @@ Feature: Manage WordPress posts | post_title | post_name | post_status | | Publish post | publish-post | publish | | Draft post | | draft | + + When I run `wp post list --post_type='page' --field=title` + Then STDOUT should be: + """ + Sample Page + """ diff --git a/features/user.feature b/features/user.feature index 68f85a9ade..5f3319d117 100644 --- a/features/user.feature +++ b/features/user.feature @@ -29,7 +29,7 @@ Feature: Manage WordPress users 10 """ - When I try `wp user delete invalid-user $(wp user list --format=ids)` + When I try `wp user list --field=ID | xargs wp user delete invalid-user` And I run `wp user list --format=count` Then STDOUT should be: """ diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index c231fe79c4..1c69d81c28 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -78,21 +78,24 @@ protected function success_or_failure( $r ) { return $status; } - protected function show_single_field( $post, $field ) { - $value = null; + protected function show_single_field( $items, $field ) { + foreach ( $items as $item ) { + if ( !isset( $key ) ) { + $key = $this->find_field( $item, $field ); + } + + \WP_CLI::print_value( $item->$key ); + } + } + private function find_field( $item, $field ) { foreach ( array( $field, $this->obj_type . '_' . $field ) as $key ) { - if ( isset( $post->$key ) ) { - $value = $post->$key; - break; + if ( isset( $item->$key ) ) { + return $key; } } - if ( null === $value ) { - \WP_CLI::error( "Invalid $this->obj_type field: $field." ); - } else { - \WP_CLI::print_value( $value ); - } + \WP_CLI::error( "Invalid $this->obj_type field: $field." ); } } diff --git a/php/commands/comment.php b/php/commands/comment.php index 61f989bea2..7d91cf7f32 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -111,7 +111,7 @@ public function get( $args, $assoc_args ) { WP_CLI::error( "Invalid comment ID." ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( $comment, $assoc_args['field'] ); + $this->show_single_field( array( $comment ), $assoc_args['field'] ); } else { $this->show_multiple_fields( $comment, $assoc_args ); } @@ -144,6 +144,9 @@ private function show_multiple_fields( $comment, $assoc_args ) { * [--<field>=<value>] * : One or more args to pass to WP_Comment_Query. * + * [--field=<field>] + * : Prints the value of a single field for each comment. + * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to comment_ID,comment_post_ID,comment_date,comment_approved,comment_author,comment_author_email * @@ -152,7 +155,7 @@ private function show_multiple_fields( $comment, $assoc_args ) { * * ## EXAMPLES * - * wp comment list --format=ids + * wp comment list --field=ID * * wp comment list --post_id=2 * @@ -181,10 +184,15 @@ public function _list( $_, $assoc_args ) { $query = new WP_Comment_Query(); $comments = $query->query( $query_args ); - if ( 'ids' == $assoc_args['format'] ) + if ( 'ids' == $assoc_args['format'] ) { $comments = wp_list_pluck( $comments, 'comment_ID' ); + } - WP_CLI\Utils\format_items( $assoc_args['format'], $comments, $assoc_args['fields'] ); + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( $comments, $assoc_args['field'] ); + } else { + WP_CLI\Utils\format_items( $assoc_args['format'], $comments, $assoc_args['fields'] ); + } } /** diff --git a/php/commands/post.php b/php/commands/post.php index ebe36de9d1..1c6673a556 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -163,7 +163,7 @@ public function get( $args, $assoc_args ) { \WP_CLI::error( "Could not find the post with ID $post_id." ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( $post, $assoc_args['field'] ); + $this->show_single_field( array( $post ), $assoc_args['field'] ); } else { $this->show_multiple_fields( $post, $assoc_args ); } @@ -235,6 +235,9 @@ public function delete( $args, $assoc_args ) { * [--<field>=<value>] * : One or more args to pass to WP_Query. * + * [--field=<field>] + * : Prints the value of a single field for each post. + * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. * @@ -243,7 +246,7 @@ public function delete( $args, $assoc_args ) { * * ## EXAMPLES * - * wp post list --format=ids + * wp post list --field=ID * * wp post list --post_type=post --posts_per_page=5 --format=json * @@ -252,16 +255,17 @@ public function delete( $args, $assoc_args ) { * @subcommand list */ public function _list( $_, $assoc_args ) { - $query_args = array( - 'posts_per_page' => -1, - 'post_status' => 'any', - ); $defaults = array( 'format' => 'table', 'fields' => $this->fields ); $assoc_args = array_merge( $defaults, $assoc_args ); + $query_args = array( + 'posts_per_page' => -1, + 'post_status' => 'any', + ); + foreach ( $assoc_args as $key => $value ) { if ( true === $value ) continue; @@ -274,7 +278,11 @@ public function _list( $_, $assoc_args ) { $query = new WP_Query( $query_args ); - WP_CLI\Utils\format_items( $assoc_args['format'], $query->posts, $assoc_args['fields'] ); + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( $query->posts, $assoc_args['field'] ); + } else { + WP_CLI\Utils\format_items( $assoc_args['format'], $query->posts, $assoc_args['fields'] ); + } } /** diff --git a/php/commands/user.php b/php/commands/user.php index f1ffaa7fb0..eb0784546b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -29,6 +29,9 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * [--<field>=<value>] * : Filter by one or more fields. For accepted fields, see get_users(). * + * [--field=<field>] + * : Prints the value of a single field for each user. + * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles * @@ -37,11 +40,11 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * * ## EXAMPLES * - * wp user list --format=ids + * wp user list --field=ID * * wp user list --role=administrator --format=csv * - * wp user list --fields=display_name,user_email + * wp user list --fields=display_name,user_email --format=json * * @subcommand list */ @@ -77,7 +80,11 @@ public function _list( $args, $assoc_args ) { return $user; } ); - WP_CLI\Utils\format_items( $params['format'], $it, $fields ); + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( $it, $assoc_args['field'] ); + } else { + WP_CLI\Utils\format_items( $params['format'], $it, $fields ); + } } /** @@ -120,7 +127,7 @@ public function get( $args, $assoc_args ) { $user_data['roles'] = implode( ', ', $user->roles ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( (object) $user_data, $assoc_args['field'] ); + $this->show_single_field( array( (object) $user_data ), $assoc_args['field'] ); } else { $this->show_multiple_fields( $user_data, $assoc_args ); } From 71155041f52aecf250a6f6f485b4f6b96eae6119 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 28 Sep 2013 20:44:52 +0300 Subject: [PATCH 2312/4858] implement --field= parameter for 'wp site list' --- features/site.feature | 7 +++++++ php/WP_CLI/CommandWithDBObject.php | 7 +++++-- php/commands/site.php | 18 ++++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/features/site.feature b/features/site.feature index 3e872852f4..bfbd49218d 100644 --- a/features/site.feature +++ b/features/site.feature @@ -13,6 +13,13 @@ Feature: Manage sites in a multisite installation | 1 | example.com/ | | 2 | example.com/first/ | + When I run `wp site list --field=url` + Then STDOUT should be: + """ + example.com/ + example.com/first/ + """ + When I run `wp site delete {SITE_ID} --yes` Then STDOUT should not be empty diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 1c69d81c28..d8dbe84339 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -82,20 +82,23 @@ protected function show_single_field( $items, $field ) { foreach ( $items as $item ) { if ( !isset( $key ) ) { $key = $this->find_field( $item, $field ); + if ( !$key ) { + \WP_CLI::error( "Invalid $this->obj_type field: $field." ); + } } \WP_CLI::print_value( $item->$key ); } } - private function find_field( $item, $field ) { + protected function find_field( $item, $field ) { foreach ( array( $field, $this->obj_type . '_' . $field ) as $key ) { if ( isset( $item->$key ) ) { return $key; } } - \WP_CLI::error( "Invalid $this->obj_type field: $field." ); + return false; } } diff --git a/php/commands/site.php b/php/commands/site.php index 52a61b96dd..f62585407b 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -306,6 +306,9 @@ public function create( $_, $assoc_args ) { * [--network=<id>] * : The network to which the sites belong. * + * [--field=<field>] + * : Prints the value of a single field for each site. + * * [--fields=<fields>] * : Comma-separated list of fields to show. * @@ -315,7 +318,7 @@ public function create( $_, $assoc_args ) { * ## EXAMPLES * * # Output a simple list of site URLs - * wp site list --fields=url --format=csv | tail -n +2 + * wp site list --field=url * * @subcommand list */ @@ -352,7 +355,18 @@ function _list( $_, $assoc_args ) { return $blog; } ); - WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( $it, $assoc_args['field'] ); + } else { + WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + } + } + + protected function find_field( $item, $field ) { + if ( 'url' == $field ) + return 'url'; + + return parent::find_field( $item, $field ); } /** From 1abe600b1bacc9c151fddaae04f87e497b980989 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 28 Sep 2013 21:23:14 +0300 Subject: [PATCH 2313/4858] move plugin/theme prepping code closer to where it's used --- php/WP_CLI/CommandWithUpgrade.php | 47 ++++++++++++------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index db20e649aa..51bc3719a7 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -245,9 +245,25 @@ protected function _list( $_, $assoc_args ) { $assoc_args = array_merge( $defaults, $assoc_args ); $all_items = $this->get_all_items(); - $items = $this->create_objects( $all_items ); + if ( !is_array( $all_items ) ) + \WP_CLI::error( "No {$this->item_type}s found." ); - \WP_CLI\Utils\format_items( $assoc_args['format'], $items, $assoc_args['fields'] ); + $it = \WP_CLI\Utils\iterator_map( $all_items, function( $item ) { + if ( empty( $item['version'] ) ) + $item['version'] = ''; + + foreach ( $item as $field => &$value ) { + if ( $value === true ) { + $value = 'available'; + } else if ( $value === false ) { + $value = 'none'; + } + } + + return $item; + } ); + + \WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); } /** @@ -278,33 +294,6 @@ protected function has_update( $slug ) { ) ); - private function create_objects( $items ) { - if ( !is_array( $items ) && !empty( $items ) ) - \WP_CLI::error( sprintf( "No '$this->item_type's found." ) ); - - $objects = array(); - - foreach ( $items as $item ) { - $object = new \stdClass; - - if ( empty( $item['version'] ) ) - $item['version'] = ""; - - foreach ( $item as $field => $value ) { - if ( $value === true ) { - $value = "available"; - } else if ( $value === false) { - $value = "none"; - } - - $object->{$field} = $value; - } - $objects[] = $object; - } - - return $objects; - } - protected function format_status( $status, $format ) { return $this->get_color( $status ) . $this->map[ $format ][ $status ]; } From d5d58cd973153bb1d7e2949fce07a85bfe0f378a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 28 Sep 2013 22:40:44 +0300 Subject: [PATCH 2314/4858] implement --field= parameter for 'wp plugin list' and 'wp theme list' --- features/upgradables.feature | 11 +++++++++++ php/WP_CLI/CommandWithUpgrade.php | 13 ++++++++++++- php/commands/plugin.php | 6 ++++++ php/commands/theme.php | 6 ++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index b7d1a34788..df5080414e 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -15,6 +15,17 @@ Feature: Manage WordPress themes and plugins <type_name> installed successfully """ + When I run `wp <type> list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | <item> | inactive | available | <version> | + + When I run `wp <type> list --field=name` + Then STDOUT should contain: + """ + <item> + """ + When I run `wp <type> status` Then STDOUT should contain: """ diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 51bc3719a7..d868cf7721 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -263,7 +263,18 @@ protected function _list( $_, $assoc_args ) { return $item; } ); - \WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + if ( isset( $assoc_args['field'] ) ) { + $field = $assoc_args['field']; + + foreach ( $it as $item ) { + if ( !isset( $item[ $field ] ) ) { + \WP_CLI::error( "Invalid $this->item_type field: $field." ); + } + \WP_CLI::print_value( $item[ $field ] ); + } + } else { + \WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); + } } /** diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 46a655f09b..92568e6eda 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -446,6 +446,12 @@ function delete( $args, $assoc_args = array() ) { * * ## OPTIONS * + * [--field=<field>] + * : Prints the value of a single field for each plugin. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to name,status,update,version. + * * [--format=<format>] * : Output list as table, CSV or JSON. Defaults to table. * diff --git a/php/commands/theme.php b/php/commands/theme.php index 7f23b4278d..ec1bd1709a 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -360,6 +360,12 @@ function delete( $args ) { * * ## OPTIONS * + * [--field=<field>] + * : Prints the value of a single field for each theme. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to name,status,update,version. + * * [--format=<format>] * : Output list as table, CSV or JSON. Defaults to table. * From 3deed97c7cea704e8ca0dd0ba3f34dfefbc749f1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 01:34:18 +0300 Subject: [PATCH 2315/4858] rewrap argument descriptions --- php/commands/help.php | 14 +++++++++++++- php/commands/scaffold.php | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index 6e90600b25..b2aba852f8 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -54,13 +54,25 @@ private static function show_help( $command ) { $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); // definition lists - $out = preg_replace( '/\n([^\n]+)\n: (.+?)\n/s', "\n\t\\1\n\t\t\\2\n", $out ); + $out = preg_replace_callback( '/([^\n]+)\n: (.+?)\n\n/s', function( $matches ) { + $param = $matches[1]; + $desc = self::indent( "\t\t", wordwrap( $matches[2] ) ); + return "\t$param\n$desc\n\n"; + }, $out ); $out = str_replace( "\t", ' ', $out ); self::pass_through_pager( WP_CLI::colorize( $out ) ); } + private static function indent( $whitespace, $text ) { + $lines = explode( "\n", $text ); + foreach ( $lines as &$line ) { + $line = $whitespace . $line; + } + return implode( $lines, "\n" ); + } + private static function pass_through_pager( $out ) { if ( strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ) { // no paging for Windows cmd.exe; sorry diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5e7ba7269a..c69d1a342c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -64,7 +64,7 @@ function post_type( $args, $assoc_args ) { * : Post types to register for use with the taxonomy. * * [--label=<label>] - * : The text used to translate the update messages + * : The text used to translate the update messages. * * [--textdomain=<textdomain>] * : The textdomain to use for the labels. From 86d519ecc3dad0f208ae8f3e1a00c420da7c18fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 01:50:23 +0300 Subject: [PATCH 2316/4858] wordwrap synopsis --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index b2aba852f8..c8cf35e91b 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -102,7 +102,7 @@ private static function get_initial_markdown( $command ) { 'shortdesc' => $command->get_shortdesc(), ); - $binding['synopsis'] = "$name " . $command->get_synopsis(); + $binding['synopsis'] = wordwrap( "$name " . $command->get_synopsis(), 79 ); if ( $command->has_subcommands() ) { $binding['has-subcommands']['subcommands'] = self::render_subcommands( $command ); From 73141b2c6bca4ce4f0bda4269335f51320e68b2e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 02:11:09 +0300 Subject: [PATCH 2317/4858] in PHP 5.3, self:: does not work inside closures --- php/commands/help.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index c8cf35e91b..36348b21a3 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -54,17 +54,19 @@ private static function show_help( $command ) { $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); // definition lists - $out = preg_replace_callback( '/([^\n]+)\n: (.+?)\n\n/s', function( $matches ) { - $param = $matches[1]; - $desc = self::indent( "\t\t", wordwrap( $matches[2] ) ); - return "\t$param\n$desc\n\n"; - }, $out ); + $out = preg_replace_callback( '/([^\n]+)\n: (.+?)\n\n/s', array( __CLASS__, 'rewrap_param_desc' ), $out ); $out = str_replace( "\t", ' ', $out ); self::pass_through_pager( WP_CLI::colorize( $out ) ); } + private static function rewrap_param_desc( $matches ) { + $param = $matches[1]; + $desc = self::indent( "\t\t", wordwrap( $matches[2] ) ); + return "\t$param\n$desc\n\n"; + } + private static function indent( $whitespace, $text ) { $lines = explode( "\n", $text ); foreach ( $lines as &$line ) { From 8d98f69199a3c8ec8feae6feec4c1473b2fbc4aa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 03:24:54 +0300 Subject: [PATCH 2318/4858] handle case where there is nothing after the last parameter description --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 36348b21a3..343b4e3558 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -54,7 +54,7 @@ private static function show_help( $command ) { $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); // definition lists - $out = preg_replace_callback( '/([^\n]+)\n: (.+?)\n\n/s', array( __CLASS__, 'rewrap_param_desc' ), $out ); + $out = preg_replace_callback( '/([^\n]+)\n: (.+?)(\n\n|$)/s', array( __CLASS__, 'rewrap_param_desc' ), $out ); $out = str_replace( "\t", ' ', $out ); From f2938b9cf44adac7a8cd1c2a41cae1a22f5d1a0a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 03:52:52 +0300 Subject: [PATCH 2319/4858] remove 'wp comment last' subcommand was superseded by 'wp comment list' fixes #760 --- php/commands/comment.php | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 7d91cf7f32..8ca730efda 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -394,44 +394,6 @@ public function status( $args, $assoc_args ) { } } - /** - * Get last approved comment. - * - * ## OPTIONS - * - * [--id] - * : Output just the last comment id. - * - * [--full] - * : Output complete comment information. - * - * ## EXAMPLES - * - * wp comment last --full - */ - function last( $args = array(), $assoc_args = array() ) { - $last = get_comments( array( 'number' => 1, 'status' => 'approve' ) ); - - list( $comment ) = $last; - - if ( isset( $assoc_args['id'] ) ) { - WP_CLI::line( $comment->comment_ID ); - exit( 1 ); - } - - WP_CLI::line( "%yLast approved comment:%n " ); - - if ( isset( $assoc_args['full'] ) ) { - $keys = array_keys( get_object_vars( $comment ) ); - } else { - $keys = array( 'comment_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); - } - - foreach ( $keys as $key ) { - WP_CLI::line( str_pad( "$key:", 23 ) . $comment->$key ); - } - } - /** * Verify whether a comment exists. * From 80781ca8ac233231dcefad8a02d591f8be740061 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 04:06:55 +0300 Subject: [PATCH 2320/4858] make 'wp theme delete' support multiple args --- features/theme.feature | 5 ++--- php/commands/theme.php | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index db0fabc6a1..4001977882 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -35,10 +35,9 @@ Feature: Manage WordPress themes Then STDOUT should not be empty When I try the previous command again - Then the return code should be 1 - And STDERR should contain: + Then STDERR should contain: """ - Error: The theme 'p2' could not be found. + The 'p2' theme could not be found. """ When I run `wp theme list` diff --git a/php/commands/theme.php b/php/commands/theme.php index ec1bd1709a..e8932ee059 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -331,28 +331,29 @@ function update( $args, $assoc_args ) { * * ## OPTIONS * - * <theme> - * : The theme to delete. + * <theme>... + * : One or more themes to delete. * * ## EXAMPLES * * wp theme delete twentyeleven */ function delete( $args ) { - $theme = $this->parse_name( $args[0] ); - $theme_slug = $theme->get_stylesheet(); + foreach ( $this->validate_theme_names( $args ) as $theme ) { + $theme_slug = $theme->get_stylesheet(); - if ( $this->is_active_theme( $theme ) ) { - WP_CLI::error( "Can't delete the currently active theme." ); - } + if ( $this->is_active_theme( $theme ) ) { + WP_CLI::warning( "Can't delete the currently active theme: $theme_slug" ); + } - $r = delete_theme( $theme_slug ); + $r = delete_theme( $theme_slug ); - if ( is_wp_error( $r ) ) { - WP_CLI::error( $r ); + if ( is_wp_error( $r ) ) { + WP_CLI::warning( $r ); + } else { + WP_CLI::success( "Deleted '$theme_slug' theme." ); + } } - - WP_CLI::success( sprintf( "Deleted '%s' theme.", $theme_slug ) ); } /** @@ -395,6 +396,22 @@ private function parse_name( $name ) { return $theme; } + + private function validate_theme_names( $args ) { + $themes = array(); + + foreach ( $args as $name ) { + $theme = wp_get_theme( $name ); + + if ( !$theme->exists() ) { + WP_CLI::warning( "The '$name' theme could not be found." ); + } else { + $themes[] = $theme; + } + } + + return $themes; + } } WP_CLI::add_command( 'theme', 'Theme_Command' ); From b074fd054d83527eddb2623134373fbb88ec7389 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 04:56:03 +0300 Subject: [PATCH 2321/4858] add warning when unregistered positional parameters are passed --- php/WP_CLI/Dispatcher/Subcommand.php | 6 ++++++ php/WP_CLI/SynopsisValidator.php | 17 +++++++++++++++++ tests/test-arg-validation.php | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 5d6145f37c..07cbee7b3c 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -167,6 +167,12 @@ private function validate_args( $args, &$assoc_args ) { exit(1); } + $unknown_positionals = $validator->unknown_positionals( $args ); + if ( !empty( $unknown_positionals ) ) { + \WP_CLI::warning( 'Too many positional arguments: ' . + implode( ' ', $unknown_positionals ) ); + } + list( $errors, $to_unset ) = $validator->validate_assoc( array_merge( \WP_CLI::get_config(), $assoc_args ) ); if ( !empty( $errors['fatal'] ) ) { diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index ed67928efa..ee0b824c4c 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -28,6 +28,23 @@ public function enough_positionals( $args ) { return count( $args ) >= count( $positional ); } + public function unknown_positionals( $args ) { + $positional_repeating = $this->query_spec( array( + 'type' => 'positional', + 'repeating' => true, + ) ); + + if ( !empty( $positional_repeating ) ) + return array(); + + $positional = $this->query_spec( array( + 'type' => 'positional', + 'repeating' => false, + ) ); + + return array_slice( $args, count( $positional ) ); + } + // Checks that all required keys are present and that they have values. public function validate_assoc( $assoc_args ) { $assoc_spec = $this->query_spec( array( diff --git a/tests/test-arg-validation.php b/tests/test-arg-validation.php index 7db636a52d..4a3b3680c2 100644 --- a/tests/test-arg-validation.php +++ b/tests/test-arg-validation.php @@ -10,6 +10,8 @@ function testMissingPositional() { $this->assertFalse( $validator->enough_positionals( array() ) ); $this->assertTrue( $validator->enough_positionals( array( 1, 2 ) ) ); $this->assertTrue( $validator->enough_positionals( array( 1, 2, 3, 4 ) ) ); + + $this->assertEquals( array( 4 ), $validator->unknown_positionals( array( 1, 2, 3, 4 ) ) ); } function testRepeatingPositional() { @@ -18,6 +20,8 @@ function testRepeatingPositional() { $this->assertFalse( $validator->enough_positionals( array() ) ); $this->assertTrue( $validator->enough_positionals( array( 1 ) ) ); $this->assertTrue( $validator->enough_positionals( array( 1, 2, 3 ) ) ); + + $this->assertEmpty( $validator->unknown_positionals( array( 1, 2, 3 ) ) ); } function testUnknownAssocEmpty() { From e03258378c66a5665cb417afa7c23ece4ae38f7a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 05:17:44 +0300 Subject: [PATCH 2322/4858] fix synopsis for 'wp help' --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 343b4e3558..c56e47f125 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -16,7 +16,7 @@ class Help_Command extends WP_CLI_Command { * # get help for `core download` subcommand * wp help core download * - * @synopsis [<command>] + * @synopsis [<command>...] */ function __invoke( $args, $assoc_args ) { $command = self::find_subcommand( $args ); From 7295a52e62575f1edbbef776aa6f27ca51d1237d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 05:24:21 +0300 Subject: [PATCH 2323/4858] fix synopsis for 'wp option' --- php/commands/option.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index 7f3e87a16b..1c4c66095d 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -39,7 +39,7 @@ public function get( $args, $assoc_args ) { /** * Add an option. * - * @synopsis <key> [--format=<format>] + * @synopsis <key> <value> [--format=<format>] */ public function add( $args, $assoc_args ) { $key = $args[0]; @@ -57,7 +57,7 @@ public function add( $args, $assoc_args ) { * Update an option. * * @alias set - * @synopsis <key> [--format=<format>] + * @synopsis <key> <value> [--format=<format>] */ public function update( $args, $assoc_args ) { $key = $args[0]; From 5e9c78fe9a1ee44887d00dc03d9a1e846e4327c3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 29 Sep 2013 06:02:38 +0300 Subject: [PATCH 2324/4858] fix bug where $_SERVER['SERVER_NAME'] was set incorrectly closes #765 --- features/flags.feature | 10 +++++++--- php/WP_CLI/Runner.php | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index ee07a67c70..7cd0288f76 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -3,10 +3,14 @@ Feature: Global flags Scenario: Setting the URL Given a WP install - When I run `wp --url=localhost:8001 eval 'echo $_SERVER["SERVER_PORT"];'` - Then STDOUT should be: + When I run `wp --url=localhost:8001 eval 'echo json_encode( $_SERVER );'` + Then STDOUT should be JSON containing: """ - 8001 + { + "HTTP_HOST": "localhost:8001", + "SERVER_NAME": "localhost", + "SERVER_PORT": "8001" + } """ Scenario: Quiet run diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a81e0d5a8f..0d37f11a32 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -154,7 +154,7 @@ private static function set_url_params( $url_parts ) { $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; } - $_SERVER['SERVER_NAME'] = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.')); + $_SERVER['SERVER_NAME'] = $url_parts['host']; } $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); From b84a9541cf42262d47ec56ebac0b84cb6a500a37 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 30 Sep 2013 15:09:51 +0200 Subject: [PATCH 2325/4858] Implement `wp theme get --field=<field>` --- features/theme.feature | 6 +++++ php/WP_CLI/CommandWithUpgrade.php | 41 +++++++++++++++++++++++++++++++ php/commands/theme.php | 22 ++++++----------- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 4001977882..59dfb00969 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -87,3 +87,9 @@ Feature: Manage WordPress themes Then STDOUT should be a table containing rows: | Field | Value | | name | P2 | + + When I run `wp theme get p2 --field=title` + Then STDOUT should contain: + """ + P2 + """ diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index d868cf7721..efe1c3eb60 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -102,6 +102,47 @@ private function show_legend( $items ) { \WP_CLI::line( 'Legend: ' . implode( ', ', \WP_CLI::colorize( $legend_line ) ) ); } + protected function find_field( $item, $field ) { + foreach ( array( $field, $this->obj_type . '_' . $field ) as $key ) { + if ( isset( $item->$key ) ) { + return $key; + } + } + + return false; + } + + protected function show_single_field( $items, $field ) { + foreach ( $items as $item ) { + if ( !isset( $key ) ) { + $key = $this->find_field( $item, $field ); + if ( !$key ) { + \WP_CLI::error( "Invalid $this->obj_type field: $field." ); + } + } + + \WP_CLI::print_value( $item->$key ); + } + } + + protected function show_multiple_fields( $data, $assoc_args ) { + switch ( $assoc_args['format'] ) { + + case 'table': + \WP_CLI\Utils\assoc_array_to_table( $data ); + break; + + case 'json': + WP_CLI::print_value( $data, $assoc_args ); + break; + + default: + \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); + break; + + } + } + function install( $args, $assoc_args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); diff --git a/php/commands/theme.php b/php/commands/theme.php index e8932ee059..4f85066a02 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -256,6 +256,9 @@ function install( $args, $assoc_args ) { * * <theme> * : The theme to get. + * + * [--field=<field>] + * : Instead of returning the whole theme, returns the value of a single field. * * [--format=<format>] * : Output list as table or JSON. Defaults to table. @@ -280,21 +283,10 @@ public function get( $args, $assoc_args ) { $theme_obj->$var = $theme->$var; } - switch ( $assoc_args['format'] ) { - - case 'table': - unset( $theme_obj->tags ); - $fields = get_object_vars( $theme_obj ); - \WP_CLI\Utils\assoc_array_to_table( $fields ); - break; - - case 'json': - WP_CLI::print_value( $theme_obj, $assoc_args ); - break; - - default: - \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); - break; + if ( isset( $assoc_args['field'] ) ) { + $this->show_single_field( array( $theme_obj ), $assoc_args['field'] ); + } else { + $this->show_multiple_fields( $theme_obj, $assoc_args ); } } From e82a04ef45e492855e95cda785e6df7d3c4ddea0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 30 Sep 2013 15:18:15 +0200 Subject: [PATCH 2326/4858] Wordwrap the description --- php/commands/theme.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 4f85066a02..abb66bf0b1 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -283,6 +283,8 @@ public function get( $args, $assoc_args ) { $theme_obj->$var = $theme->$var; } + $theme_obj->description = wordwrap( $theme_obj->description ); + if ( isset( $assoc_args['field'] ) ) { $this->show_single_field( array( $theme_obj ), $assoc_args['field'] ); } else { From a91d8b186059b0fe56230c605ab94bea0102ed28 Mon Sep 17 00:00:00 2001 From: Mike Schroder <mike.schroder@dreamhost.com> Date: Mon, 30 Sep 2013 11:51:56 -0700 Subject: [PATCH 2327/4858] framework: Allow third-party Mustache templates Allow arbitrary mustache template to be supplied in mustache_render. --- php/utils.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 84289730ec..ad4129ed59 100644 --- a/php/utils.php +++ b/php/utils.php @@ -442,7 +442,10 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { } function mustache_render( $template_name, $data ) { - $template = file_get_contents( WP_CLI_ROOT . "/templates/$template_name" ); + if ( ! file_exists( $template_name ) ) + $template_name = WP_CLI_ROOT . "/templates/$template_name"; + + $template = file_get_contents( $template_name ); $m = new \Mustache_Engine; From a66f523c3c0569f984dce897e6e43914b6c00bd2 Mon Sep 17 00:00:00 2001 From: Doug Cone <nullvariable@gmail.com> Date: Mon, 30 Sep 2013 17:59:37 -0400 Subject: [PATCH 2328/4858] rewrote the object loop to only deal with top level values that are unserialized. Anything deeper than the first level will be ignored. --- php/utils.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 84289730ec..0b8e568751 100644 --- a/php/utils.php +++ b/php/utils.php @@ -197,6 +197,7 @@ function locate_wp_config() { /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. + * Will only handle the first level of any object to avoid recursions. * * @source https://github.com/interconnectit/Search-Replace-DB * @@ -228,7 +229,20 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria elseif ( is_object( $data ) ) { $_tmp = clone( $data ); foreach ( $data as $key => $value ) { - $_tmp->$key = recursive_unserialize_replace( $from, $to, $value, false ); + + if ( is_string( $value ) ) { + $data[$key] = str_replace( $from, $to, $value ); + } + + elseif ( is_array( $value ) ) { + $_tmp = array(); + foreach ( $value as $key => $sub_value ) { + $_tmp[ $key ] = str_replace( $from, $to, $sub_value ); + } + + $value = $_tmp; + } + } $data = $_tmp; @@ -237,6 +251,7 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria else { if ( is_string( $data ) ) $data = str_replace( $from, $to, $data ); + } if ( $serialised ) From ca668676b8bcc836a6119678bc92e463db0a3785 Mon Sep 17 00:00:00 2001 From: Doug Cone <nullvariable@gmail.com> Date: Mon, 30 Sep 2013 18:28:18 -0400 Subject: [PATCH 2329/4858] search-replace will ignore all object data types to avoid recursion. --- php/utils.php | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/php/utils.php b/php/utils.php index 0b8e568751..55b1cffc52 100644 --- a/php/utils.php +++ b/php/utils.php @@ -197,7 +197,7 @@ function locate_wp_config() { /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. - * Will only handle the first level of any object to avoid recursions. + * Ignores any serialized objects.. * * @source https://github.com/interconnectit/Search-Replace-DB * @@ -226,32 +226,9 @@ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $seria $data = $_tmp; } - elseif ( is_object( $data ) ) { - $_tmp = clone( $data ); - foreach ( $data as $key => $value ) { - - if ( is_string( $value ) ) { - $data[$key] = str_replace( $from, $to, $value ); - } - - elseif ( is_array( $value ) ) { - $_tmp = array(); - foreach ( $value as $key => $sub_value ) { - $_tmp[ $key ] = str_replace( $from, $to, $sub_value ); - } - - $value = $_tmp; - } - - } - - $data = $_tmp; - } - else { if ( is_string( $data ) ) $data = str_replace( $from, $to, $data ); - } if ( $serialised ) From aca91d24968dd21181ede202ad049e0728edb67f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 01:58:30 +0300 Subject: [PATCH 2330/4858] rename `wp rewrite dump` to `wp rewrite list` ... and make its output consistent with the rest of the commands --- php/commands/rewrite.php | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 8b8ebc5520..27888bd07a 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -94,35 +94,31 @@ public function structure( $args, $assoc_args ) { * ## OPTIONS * * [--format=<format>] - * : Output list as JSON. Defaults to tab-separated lines. + * : Output list as table, JSON or CSV. Defaults to table. * * ## EXAMPLES * - * wp rewrite dump --format=json + * wp rewrite list --format=csv + * @subcommand list */ - public function dump( $args, $assoc_args ) { + public function _list( $args, $assoc_args ) { $rules = get_option( 'rewrite_rules' ); if ( ! $rules ) { $rules = array(); WP_CLI::warning( 'No rewrite rules.' ); } + $defaults = array( - 'format' => '' + 'format' => 'table' ); $assoc_args = array_merge( $defaults, $assoc_args ); - switch ( $assoc_args['format'] ) { - - case 'json': - echo json_encode( $rules ); - break; - - default: - foreach ( $rules as $route => $rule ) - WP_CLI::line( $route . "\t" . $rule ); - break; - + $rule_list = array(); + foreach ( $rules as $match => $query ) { + $rule_list[] = compact( 'match', 'query' ); } + + WP_CLI\Utils\format_items( $assoc_args['format'], $rule_list, array('match', 'query') ); } /** From ca826c7d2156f8d21c9529858ac59e7f19e297f4 Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Mon, 30 Sep 2013 16:07:20 -0700 Subject: [PATCH 2331/4858] Check for non-string exit code after `wp post edit` Fixes bug introduced in f592cff, where quitting out of the system editor would erase a post, because the `content_save_pre` filter would fail to interpret system exit codes, and treat them as an empty string. There must be a way to write a test for behavior like this, but how to actually do that is beyond my knowledge. I did test with several different $EDITOR settings (vi/nano/gedit), though, and this worked each time for me. --- php/commands/post.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 51e288f52e..ae2127735b 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -125,7 +125,8 @@ public function edit( $args, $_ ) { protected function _edit( $content, $title ) { $content = apply_filters( 'the_editor_content', $content ); $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title ); - return apply_filters( 'content_save_pre', $output ); + return ( is_string( $output ) ) ? + apply_filters( 'content_save_pre', $output ) : $output; } /** From eaebd7d42b8139ff6fc94cecb182b8e64db87839 Mon Sep 17 00:00:00 2001 From: Doug Cone <nullvariable@gmail.com> Date: Mon, 30 Sep 2013 19:23:54 -0400 Subject: [PATCH 2332/4858] removed unneeded object test case. --- tests/test-unserialize-replace.php | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 tests/test-unserialize-replace.php diff --git a/tests/test-unserialize-replace.php b/tests/test-unserialize-replace.php deleted file mode 100644 index 3389336f38..0000000000 --- a/tests/test-unserialize-replace.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -class UnserializeReplaceTest extends PHPUnit_Framework_TestCase { - - function testPrivateConstructor() { - $old_obj = ClassWithPrivateConstructor::get_instance(); - - $new_obj = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_obj ); - $this->assertEquals( 'bar', $new_obj->prop ); - } -} - - -class ClassWithPrivateConstructor { - - public $prop = 'foo'; - - private function __construct() {} - - public static function get_instance() { - return new self; - } -} - From 8decffd8893fd471497108e5079ff33b39e23f74 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 02:38:36 +0300 Subject: [PATCH 2333/4858] move recursive_unserialize_replace() into Search_Replace_Command class it's not meant to be a general-purpose utility; its behaviour changes according to the needs of the search-replace command --- php/commands/search-replace.php | 47 ++++++++++++++++++++++++++++++++- php/utils.php | 47 --------------------------------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c7e80dac3f..fbeeec184c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -124,7 +124,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry if ( '' === $row->$col ) continue; - $value = \WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col ); + $value = self::recursive_unserialize_replace( $old, $new, $row->$col ); if ( $dry_run ) { if ( $value != $row->$col ) @@ -140,6 +140,51 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry return $count; } + /** + * Take a serialised array and unserialise it replacing elements as needed and + * unserialising any subordinate arrays and performing the replace on those too. + * Ignores any serialized objects. + * + * Initial code from https://github.com/interconnectit/Search-Replace-DB + * + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with + * @param array $data Used to pass any subordinate arrays back to in. + * @param bool $serialised Does the array passed via $data need serialising. + * + * @return array The original array with all elements replaced as needed. + */ + private static function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) { + + // some unseriliased data cannot be re-serialised eg. SimpleXMLElements + try { + + if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { + $data = self::recursive_unserialize_replace( $from, $to, $unserialized, true ); + } + + elseif ( is_array( $data ) ) { + $_tmp = array(); + foreach ( $data as $key => $value ) { + $_tmp[ $key ] = self::recursive_unserialize_replace( $from, $to, $value, false ); + } + $data = $_tmp; + } + + else if ( is_string( $data ) ) { + $data = str_replace( $from, $to, $data ); + } + + if ( $serialised ) + return serialize( $data ); + + } catch( Exception $error ) { + + } + + return $data; + } + private static function get_columns( $table ) { global $wpdb; diff --git a/php/utils.php b/php/utils.php index 404d8d51db..c44e6e4de7 100644 --- a/php/utils.php +++ b/php/utils.php @@ -194,53 +194,6 @@ function locate_wp_config() { return $path; } -/** - * Take a serialised array and unserialise it replacing elements as needed and - * unserialising any subordinate arrays and performing the replace on those too. - * Ignores any serialized objects.. - * - * @source https://github.com/interconnectit/Search-Replace-DB - * - * @param string $from String we're looking to replace. - * @param string $to What we want it to be replaced with - * @param array $data Used to pass any subordinate arrays back to in. - * @param bool $serialised Does the array passed via $data need serialising. - * - * @return array The original array with all elements replaced as needed. - */ -function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) { - - // some unseriliased data cannot be re-serialised eg. SimpleXMLElements - try { - - if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { - $data = recursive_unserialize_replace( $from, $to, $unserialized, true ); - } - - elseif ( is_array( $data ) ) { - $_tmp = array(); - foreach ( $data as $key => $value ) { - $_tmp[ $key ] = recursive_unserialize_replace( $from, $to, $value, false ); - } - - $data = $_tmp; - } - - else { - if ( is_string( $data ) ) - $data = str_replace( $from, $to, $data ); - } - - if ( $serialised ) - return serialize( $data ); - - } catch( Exception $error ) { - - } - - return $data; -} - /** * Output items in a table, JSON, CSV, ids, or the total count * From c20384efc717514f31dc3b0a6eeed254db84b0b7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 04:31:48 +0200 Subject: [PATCH 2334/4858] Introduce `show_single_field()` and `show_multiple_fields()`, helper methods for printing object data --- php/utils.php | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/php/utils.php b/php/utils.php index 84289730ec..823627cf69 100644 --- a/php/utils.php +++ b/php/utils.php @@ -364,6 +364,63 @@ function pick_fields( $item, $fields ) { return $values; } +/** + * Show a single field from a list of items + * + * @param array Array of objects to show fields from + * @param string The field to show + * @param string Whether or not the field is typically prefixed (e.g. "content" => "post_content") + */ +function show_single_field( $items, $field, $field_prefix = '' ) { + + foreach ( $items as $item ) { + + if ( ! isset( $key ) ) { + + foreach ( array( $field, $field_prefix . '_' . $field ) as $maybe_key ) { + if ( isset( $item->$maybe_key ) ) { + $key = $maybe_key; + break; + } + } + + if ( ! $key ) { + \WP_CLI::error( "Invalid field: $field." ); + } + + } + + \WP_CLI::print_value( $item->$key ); + } + +} + +/** + * Show multiple fields of an object + * + * @param object|array Data to display + * @param string Format to display the data in + */ +function show_multiple_fields( $data, $format ) { + + switch ( $format ) { + + case 'table': + assoc_array_to_table( $data ); + break; + + case 'json': + \WP_CLI::print_value( $data, array( 'format' => $format ) ); + break; + + default: + \WP_CLI::error( "Invalid format: " . $format ); + break; + + } + +} + /** * Launch system's $EDITOR to edit text * From ee618c07266d02ea47497b6187bf7a5d4dcb73c1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 04:38:16 +0200 Subject: [PATCH 2335/4858] Convert `wp theme get` to use new util function --- php/WP_CLI/CommandWithUpgrade.php | 41 ------------------------------- php/commands/theme.php | 4 +-- 2 files changed, 2 insertions(+), 43 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index efe1c3eb60..d868cf7721 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -102,47 +102,6 @@ private function show_legend( $items ) { \WP_CLI::line( 'Legend: ' . implode( ', ', \WP_CLI::colorize( $legend_line ) ) ); } - protected function find_field( $item, $field ) { - foreach ( array( $field, $this->obj_type . '_' . $field ) as $key ) { - if ( isset( $item->$key ) ) { - return $key; - } - } - - return false; - } - - protected function show_single_field( $items, $field ) { - foreach ( $items as $item ) { - if ( !isset( $key ) ) { - $key = $this->find_field( $item, $field ); - if ( !$key ) { - \WP_CLI::error( "Invalid $this->obj_type field: $field." ); - } - } - - \WP_CLI::print_value( $item->$key ); - } - } - - protected function show_multiple_fields( $data, $assoc_args ) { - switch ( $assoc_args['format'] ) { - - case 'table': - \WP_CLI\Utils\assoc_array_to_table( $data ); - break; - - case 'json': - WP_CLI::print_value( $data, $assoc_args ); - break; - - default: - \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); - break; - - } - } - function install( $args, $assoc_args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); diff --git a/php/commands/theme.php b/php/commands/theme.php index abb66bf0b1..20c460e5e2 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -286,9 +286,9 @@ public function get( $args, $assoc_args ) { $theme_obj->description = wordwrap( $theme_obj->description ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( array( $theme_obj ), $assoc_args['field'] ); + \WP_CLI\Utils\show_single_field( array( $theme_obj ), $assoc_args['field'] ); } else { - $this->show_multiple_fields( $theme_obj, $assoc_args ); + \WP_CLI\Utils\show_multiple_fields( $theme_obj, $assoc_args['format'] ); } } From 2fbde59b1139fbd3da4828025e25242528adbeae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 04:43:18 +0200 Subject: [PATCH 2336/4858] Convert `wp comment get` to new util functions --- php/commands/comment.php | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 8ca730efda..fecff3cb77 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -111,28 +111,16 @@ public function get( $args, $assoc_args ) { WP_CLI::error( "Invalid comment ID." ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( array( $comment ), $assoc_args['field'] ); - } else { - $this->show_multiple_fields( $comment, $assoc_args ); - } - } - private function show_multiple_fields( $comment, $assoc_args ) { - switch ( $assoc_args['format'] ) { + \WP_CLI\Utils\show_single_field( array( $comment ), $assoc_args['field'], 'comment' ); - case 'table': - $fields = get_object_vars( $comment ); - unset( $fields['comment_content'] ); - \WP_CLI\Utils\assoc_array_to_table( $fields ); - break; + } else { - case 'json': - WP_CLI::print_value( $comment, $assoc_args ); - break; + $comment = get_object_vars( $comment ); + if ( 'table' == $assoc_args['format'] ) + unset( $comment['comment_content'] ); - default: - \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); - break; + \WP_CLI\Utils\show_multiple_fields( $comment, $assoc_args['format'] ); } } @@ -189,7 +177,7 @@ public function _list( $_, $assoc_args ) { } if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( $comments, $assoc_args['field'] ); + \WP_CLI\Utils\show_single_field( $comments, $assoc_args['field'], 'comment' ); } else { WP_CLI\Utils\format_items( $assoc_args['format'], $comments, $assoc_args['fields'] ); } From cff0bb698d3bbec857f67a8b6b28ee45eb091ca7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 04:52:55 +0200 Subject: [PATCH 2337/4858] Have `show_single_field()` logically persist the `--format` argument. --- features/theme.feature | 6 ++++++ php/commands/comment.php | 4 ++-- php/commands/theme.php | 2 +- php/utils.php | 13 +++++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 59dfb00969..a57480f471 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -93,3 +93,9 @@ Feature: Manage WordPress themes """ P2 """ + + When I run `wp theme get p2 --field=title --format=json` + Then STDOUT should contain: + """ + {"title":"P2"} + """ diff --git a/php/commands/comment.php b/php/commands/comment.php index fecff3cb77..707e02a41c 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -112,7 +112,7 @@ public function get( $args, $assoc_args ) { if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( array( $comment ), $assoc_args['field'], 'comment' ); + \WP_CLI\Utils\show_single_field( array( $comment ), $assoc_args['field'], $assoc_args['format'], 'comment' ); } else { @@ -177,7 +177,7 @@ public function _list( $_, $assoc_args ) { } if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( $comments, $assoc_args['field'], 'comment' ); + \WP_CLI\Utils\show_single_field( $comments, $assoc_args['field'], $assoc_args['format'], 'comment' ); } else { WP_CLI\Utils\format_items( $assoc_args['format'], $comments, $assoc_args['fields'] ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index 20c460e5e2..abea4ae6b9 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -286,7 +286,7 @@ public function get( $args, $assoc_args ) { $theme_obj->description = wordwrap( $theme_obj->description ); if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( array( $theme_obj ), $assoc_args['field'] ); + \WP_CLI\Utils\show_single_field( array( $theme_obj ), $assoc_args['field'], $assoc_args['format'] ); } else { \WP_CLI\Utils\show_multiple_fields( $theme_obj, $assoc_args['format'] ); } diff --git a/php/utils.php b/php/utils.php index 823627cf69..062db61c26 100644 --- a/php/utils.php +++ b/php/utils.php @@ -369,9 +369,10 @@ function pick_fields( $item, $fields ) { * * @param array Array of objects to show fields from * @param string The field to show + * @param string The format to show the field in * @param string Whether or not the field is typically prefixed (e.g. "content" => "post_content") */ -function show_single_field( $items, $field, $field_prefix = '' ) { +function show_single_field( $items, $field, $format = '', $field_prefix = '' ) { foreach ( $items as $item ) { @@ -390,7 +391,15 @@ function show_single_field( $items, $field, $field_prefix = '' ) { } - \WP_CLI::print_value( $item->$key ); + // Persist the field name for JSON + if ( 'json' == $format ) { + $data = new \stdClass; + $data->$key = $item->$key; + } else { + $data = $item->$key; + } + + \WP_CLI::print_value( $data, array( 'format' => $format ) ); } } From 1639e9bd84a315cf88e405a698095d95bd7abca6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:00:16 +0200 Subject: [PATCH 2338/4858] Run moar faster --- features/theme.feature | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index a57480f471..d8c18f5cda 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -1,8 +1,9 @@ Feature: Manage WordPress themes - Scenario: Installing a theme + Background: Given a WP install + Scenario: Installing a theme When I run `wp theme install p2` Then STDOUT should not be empty @@ -44,8 +45,6 @@ Feature: Manage WordPress themes Then STDOUT should not be empty Scenario: Install a theme, activate, then force install an older version of the theme - Given a WP install - When I run `wp theme install p2 --version=1.4.2` Then STDOUT should not be empty @@ -66,8 +65,6 @@ Feature: Manage WordPress themes | p2 | active | available | 1.4.1 | Scenario: Get the path of an installed theme - Given a WP install - When I run `wp theme install p2` Then STDOUT should not be empty @@ -78,8 +75,6 @@ Feature: Manage WordPress themes """ Scenario: Get details about an installed theme - Given a WP install - When I run `wp theme install p2` Then STDOUT should not be empty From 9ca5a468f59ebf60516c8122f9c145159f62fa00 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:03:16 +0200 Subject: [PATCH 2339/4858] Convert `wp user *` to new util functions. --- php/commands/user.php | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index eb0784546b..171d91da59 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -81,7 +81,7 @@ public function _list( $args, $assoc_args ) { } ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( $it, $assoc_args['field'] ); + \WP_CLI\Utils\show_single_field( $it, $assoc_args['field'], $assoc_args['format'], 'user' ); } else { WP_CLI\Utils\format_items( $params['format'], $it, $fields ); } @@ -127,27 +127,9 @@ public function get( $args, $assoc_args ) { $user_data['roles'] = implode( ', ', $user->roles ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( array( (object) $user_data ), $assoc_args['field'] ); + \WP_CLI\Utils\show_single_field( array( (object) $user_data ), $assoc_args['field'], $assoc_args['format'], 'user' ); } else { - $this->show_multiple_fields( $user_data, $assoc_args ); - } - } - - private function show_multiple_fields( $user_data, $assoc_args ) { - switch ( $assoc_args['format'] ) { - - case 'table': - \WP_CLI\Utils\assoc_array_to_table( $user_data ); - break; - - case 'json': - WP_CLI::print_value( $user_data, $assoc_args ); - break; - - default: - \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); - break; - + \WP_CLI\Utils\show_multiple_fields( $user_data, $assoc_args['format'] ); } } From 537c215404705bbb05b1971074c5d42f5c29404f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:07:30 +0200 Subject: [PATCH 2340/4858] Convert `wp site list` to new util function. --- php/commands/site.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index f62585407b..782d621277 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -356,7 +356,7 @@ function _list( $_, $assoc_args ) { } ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( $it, $assoc_args['field'] ); + WP_CLI\Utils\show_single_field( $it, $assoc_args['field'], $assoc_args['format'], 'site' ); } else { WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); } From 5aee26adc1ea16cfea9585cb3298b67970149b0d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:08:35 +0200 Subject: [PATCH 2341/4858] Method isn't used anymore --- php/commands/site.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 782d621277..5af9489a73 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -362,13 +362,6 @@ function _list( $_, $assoc_args ) { } } - protected function find_field( $item, $field ) { - if ( 'url' == $field ) - return 'url'; - - return parent::find_field( $item, $field ); - } - /** * Get site (network) data for a given id. * From d9b509e6229028e729437aa0f245907e8e8c4cc6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:09:03 +0200 Subject: [PATCH 2342/4858] Convert `wp post *` to new util functions. --- php/commands/post.php | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 1c6673a556..422106096a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -163,31 +163,19 @@ public function get( $args, $assoc_args ) { \WP_CLI::error( "Could not find the post with ID $post_id." ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( array( $post ), $assoc_args['field'] ); - } else { - $this->show_multiple_fields( $post, $assoc_args ); - } - } - private function show_multiple_fields( $post, $assoc_args ) { - switch ( $assoc_args['format'] ) { + \WP_CLI\Utils\show_single_field( array( $post ), $assoc_args['field'], $assoc_args['format'], 'post' ); - case 'table': - $fields = get_object_vars( $post ); - unset( $fields['filter'], $fields['post_content'], $fields['format_content'] ); - \WP_CLI\Utils\assoc_array_to_table( $fields ); - break; + } else { - case 'json': $fields = get_object_vars( $post ); - unset( $fields['filter'] ); - WP_CLI::print_value( $fields, $assoc_args ); - break; - - default: - \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); - break; + if ( 'table' == $assoc_args['format'] ) + unset( $fields['filter'], $fields['post_content'], $fields['format_content'] ); + else if ( 'json' == $assoc_args['format'] ) + unset( $fields['filter'] ); + + \WP_CLI\Utils\show_multiple_fields( $fields, $assoc_args['format'] ); } } @@ -279,7 +267,7 @@ public function _list( $_, $assoc_args ) { $query = new WP_Query( $query_args ); if ( isset( $assoc_args['field'] ) ) { - $this->show_single_field( $query->posts, $assoc_args['field'] ); + WP_CLI\Utils\show_single_field( $query->posts, $assoc_args['field'], $assoc_args['format'], 'post' ); } else { WP_CLI\Utils\format_items( $assoc_args['format'], $query->posts, $assoc_args['fields'] ); } From 97741b2c5de8768e964f5bc615a2bea412e45767 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:09:33 +0200 Subject: [PATCH 2343/4858] Remove unused methods --- php/WP_CLI/CommandWithDBObject.php | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index d8dbe84339..a9ed660bef 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -78,27 +78,5 @@ protected function success_or_failure( $r ) { return $status; } - protected function show_single_field( $items, $field ) { - foreach ( $items as $item ) { - if ( !isset( $key ) ) { - $key = $this->find_field( $item, $field ); - if ( !$key ) { - \WP_CLI::error( "Invalid $this->obj_type field: $field." ); - } - } - - \WP_CLI::print_value( $item->$key ); - } - } - - protected function find_field( $item, $field ) { - foreach ( array( $field, $this->obj_type . '_' . $field ) as $key ) { - if ( isset( $item->$key ) ) { - return $key; - } - } - - return false; - } } From cd2dc66bd7ef87e1449a8e3d3b061ea5bc894c27 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:36:00 +0200 Subject: [PATCH 2344/4858] Simplify again --- features/plugin.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 26bd999c16..698e63ad3a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -1,7 +1,9 @@ Feature: Manage WordPress plugins - Scenario: Create, activate and check plugin status + Background: Given a WP install + + Scenario: Create, activate and check plugin status And I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} @@ -66,8 +68,6 @@ Feature: Manage WordPress plugins """ Scenario: Install a plugin, activate, then force install an older version of the plugin - Given a WP install - When I run `wp plugin install akismet --version=2.5.7 --force` Then STDOUT should not be empty From f2a52c40f5823c1832dacc241779327037e676ac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:37:45 +0200 Subject: [PATCH 2345/4858] Introduce `wp plugin get` Closes #796 --- features/plugin.feature | 21 +++++++++++++++++ php/commands/plugin.php | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 698e63ad3a..d641f64a1e 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -86,3 +86,24 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | update | version | | akismet | active | available | 2.5.6 | + + Scenario: Get details about an installed plugin + + When I run `wp plugin get akismet` + Then STDOUT should be a table containing rows: + | Field | Value | + | name | akismet | + + + When I run `wp plugin get akismet --field=title` + Then STDOUT should contain: + """ + Akismet + """ + + When I run `wp plugin get akismet --field=title --format=json` + Then STDOUT should contain: + """ + {"title":"Akismet"} + """ + diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 92568e6eda..1ca6670e54 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -368,6 +368,56 @@ function install( $args, $assoc_args ) { parent::install( $args, $assoc_args ); } + /** + * Get a plugin. + * + * ## OPTIONS + * + * <plugin> + * : The plugin to get. + * + * [--field=<field>] + * : Instead of returning the whole plugin, returns the value of a single field. + * + * [--format=<format>] + * : Output list as table or JSON. Defaults to table. + * + * ## EXAMPLES + * + * wp plugin get bbpress --format=json + */ + public function get( $args, $assoc_args ) { + + $defaults = array( + 'format' => 'table' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $file = $this->_parse_name( $args[0] ); + + $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false ); + + $plugin_obj = (object)array( + 'name' => $this->get_name( $file ), + 'title' => $plugin_data['Name'], + 'author' => $plugin_data['Author'], + 'version' => $plugin_data['Version'], + 'description' => wordwrap( $plugin_data['Description'] ), + 'status' => $this->get_status( $file ), + 'update' => $this->has_update( $file ), + ); + + if ( isset( $assoc_args['field'] ) ) { + + \WP_CLI\Utils\show_single_field( array( $plugin_obj ), $assoc_args['field'], $assoc_args['format'] ); + + } else { + + \WP_CLI\Utils\show_multiple_fields( $plugin_obj, $assoc_args['format'] ); + + } + } + /** * Uninstall a plugin. * From 18c90b3508365d8175b9cfc63037a18b39a29993 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 05:49:52 +0200 Subject: [PATCH 2346/4858] `--field=<field>` support for `wp term list` and `wp term get` --- features/term.feature | 6 ++++++ php/commands/term.php | 35 +++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/features/term.feature b/features/term.feature index b0e1e04879..6d0b6df92f 100644 --- a/features/term.feature +++ b/features/term.feature @@ -39,6 +39,12 @@ Feature: Manage WordPress terms Then STDOUT should be a number And save STDOUT as {TERM_ID} + When I run `wp term get {TERM_ID} post_tag --field=slug --format=json` + Then STDOUT should contain: + """ + {"slug":"test-delete"} + """ + When I run `wp term delete {TERM_ID} post_tag` Then STDOUT should contain: """ diff --git a/php/commands/term.php b/php/commands/term.php index bcf58ac44d..c2d760238b 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -26,6 +26,9 @@ class Term_Command extends WP_CLI_Command { * * [--<field>=<value>] * : Filter by one or more fields. For accepted fields, see get_terms(). + * + * [--field=<field>] + * : Prints the value of a single field for each term. * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to all of the term object fields. @@ -60,7 +63,16 @@ public function _list( $args, $assoc_args ) { if ( 'ids' == $assoc_args['format'] ) $terms = wp_list_pluck( $terms, 'term_id' ); - WP_CLI\Utils\format_items( $assoc_args['format'], $terms, $fields ); + if ( isset( $assoc_args['field'] ) ) { + + WP_CLI\Utils\show_single_field( $terms, $assoc_args['field'], $assoc_args['format'], 'term' ); + + } else { + + WP_CLI\Utils\format_items( $assoc_args['format'], $terms, $fields ); + + } + } /** @@ -130,6 +142,9 @@ public function create( $args, $assoc_args ) { * * <taxonomy> * : Taxonomy of the term to get + * + * [--field=<field>] + * : Instead of returning the whole term, returns the value of a single field. * * [--format=<format>] * : The format to use when printing the term, acceptable values: @@ -154,21 +169,17 @@ public function get( $args, $assoc_args ) { if ( ! $term ) WP_CLI::error( "Term doesn't exist." ); - switch ( $assoc_args['format'] ) { + if ( isset( $assoc_args['field'] ) ) { - case 'table': - $fields = get_object_vars( $term ); - \WP_CLI\Utils\assoc_array_to_table( $fields ); - break; + \WP_CLI\Utils\show_single_field( array( $term ), $assoc_args['field'], $assoc_args['format'], 'term' ); - case 'json': - WP_CLI::print_value( $term, $assoc_args ); - break; + } else { - default: - \WP_CLI::error( "Invalid format: " . $assoc_args['format'] ); - break; + $term = get_object_vars( $term ); + + \WP_CLI\Utils\show_multiple_fields( $term, $assoc_args['format'] ); } + } /** From 22809e03ed89a4327564b588571783b18b9430ca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 14:02:07 +0200 Subject: [PATCH 2347/4858] This is a better format See https://github.com/wp-cli/wp-cli/pull/795#issuecomment-25442654 --- features/plugin.feature | 2 +- features/term.feature | 2 +- features/theme.feature | 2 +- php/utils.php | 10 +--------- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index d641f64a1e..3cd5337833 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -104,6 +104,6 @@ Feature: Manage WordPress plugins When I run `wp plugin get akismet --field=title --format=json` Then STDOUT should contain: """ - {"title":"Akismet"} + {"Akismet"} """ diff --git a/features/term.feature b/features/term.feature index 6d0b6df92f..0d60c3c8de 100644 --- a/features/term.feature +++ b/features/term.feature @@ -42,7 +42,7 @@ Feature: Manage WordPress terms When I run `wp term get {TERM_ID} post_tag --field=slug --format=json` Then STDOUT should contain: """ - {"slug":"test-delete"} + {"test-delete"} """ When I run `wp term delete {TERM_ID} post_tag` diff --git a/features/theme.feature b/features/theme.feature index d8c18f5cda..03064df9a5 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -92,5 +92,5 @@ Feature: Manage WordPress themes When I run `wp theme get p2 --field=title --format=json` Then STDOUT should contain: """ - {"title":"P2"} + {"P2"} """ diff --git a/php/utils.php b/php/utils.php index 062db61c26..a07b0ab879 100644 --- a/php/utils.php +++ b/php/utils.php @@ -391,15 +391,7 @@ function show_single_field( $items, $field, $format = '', $field_prefix = '' ) { } - // Persist the field name for JSON - if ( 'json' == $format ) { - $data = new \stdClass; - $data->$key = $item->$key; - } else { - $data = $item->$key; - } - - \WP_CLI::print_value( $data, array( 'format' => $format ) ); + \WP_CLI::print_value( $item->$key, array( 'format' => $format ) ); } } From 6a3ec7076af7e67f053a9b10d234eca5fa0f1929 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Oct 2013 14:03:07 +0200 Subject: [PATCH 2348/4858] Strings are strings --- features/plugin.feature | 2 +- features/term.feature | 2 +- features/theme.feature | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 3cd5337833..bde1d71dde 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -104,6 +104,6 @@ Feature: Manage WordPress plugins When I run `wp plugin get akismet --field=title --format=json` Then STDOUT should contain: """ - {"Akismet"} + "Akismet" """ diff --git a/features/term.feature b/features/term.feature index 0d60c3c8de..375bc1d78f 100644 --- a/features/term.feature +++ b/features/term.feature @@ -42,7 +42,7 @@ Feature: Manage WordPress terms When I run `wp term get {TERM_ID} post_tag --field=slug --format=json` Then STDOUT should contain: """ - {"test-delete"} + "test-delete" """ When I run `wp term delete {TERM_ID} post_tag` diff --git a/features/theme.feature b/features/theme.feature index 03064df9a5..2cdf61a367 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -92,5 +92,5 @@ Feature: Manage WordPress themes When I run `wp theme get p2 --field=title --format=json` Then STDOUT should contain: """ - {"P2"} + "P2" """ From afb78ae980cc378d95e86300af405f4fa8388f08 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 16:36:55 +0300 Subject: [PATCH 2349/4858] whitespace fixes --- php/commands/plugin.php | 2 +- php/commands/post.php | 2 +- php/commands/term.php | 6 +++--- php/commands/theme.php | 2 +- php/utils.php | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 1ca6670e54..1f1605ac7e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -375,7 +375,7 @@ function install( $args, $assoc_args ) { * * <plugin> * : The plugin to get. - * + * * [--field=<field>] * : Instead of returning the whole plugin, returns the value of a single field. * diff --git a/php/commands/post.php b/php/commands/post.php index 422106096a..91ee1a47ca 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -174,7 +174,7 @@ public function get( $args, $assoc_args ) { unset( $fields['filter'], $fields['post_content'], $fields['format_content'] ); else if ( 'json' == $assoc_args['format'] ) unset( $fields['filter'] ); - + \WP_CLI\Utils\show_multiple_fields( $fields, $assoc_args['format'] ); } } diff --git a/php/commands/term.php b/php/commands/term.php index c2d760238b..e9aad44006 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -26,7 +26,7 @@ class Term_Command extends WP_CLI_Command { * * [--<field>=<value>] * : Filter by one or more fields. For accepted fields, see get_terms(). - * + * * [--field=<field>] * : Prints the value of a single field for each term. * @@ -142,7 +142,7 @@ public function create( $args, $assoc_args ) { * * <taxonomy> * : Taxonomy of the term to get - * + * * [--field=<field>] * : Instead of returning the whole term, returns the value of a single field. * @@ -176,7 +176,7 @@ public function get( $args, $assoc_args ) { } else { $term = get_object_vars( $term ); - + \WP_CLI\Utils\show_multiple_fields( $term, $assoc_args['format'] ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index abea4ae6b9..8b0c7b61e7 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -256,7 +256,7 @@ function install( $args, $assoc_args ) { * * <theme> * : The theme to get. - * + * * [--field=<field>] * : Instead of returning the whole theme, returns the value of a single field. * diff --git a/php/utils.php b/php/utils.php index 5404fa2292..bdcaba1245 100644 --- a/php/utils.php +++ b/php/utils.php @@ -310,8 +310,8 @@ function pick_fields( $item, $fields ) { } /** - * Show a single field from a list of items - * + * Show a single field from a list of items. + * * @param array Array of objects to show fields from * @param string The field to show * @param string The format to show the field in @@ -342,8 +342,8 @@ function show_single_field( $items, $field, $format = '', $field_prefix = '' ) { } /** - * Show multiple fields of an object - * + * Show multiple fields of an object. + * * @param object|array Data to display * @param string Format to display the data in */ From a2f4ac8a3d23c14af76a9dace20455fb70c2e03e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 18:15:21 +0300 Subject: [PATCH 2350/4858] introduce WP_CLI\Formatter class --- php/WP_CLI/CommandWithDBObject.php | 4 +++ php/WP_CLI/CommandWithUpgrade.php | 4 +++ php/WP_CLI/Formatter.php | 50 ++++++++++++++++++++++++++++++ php/commands/comment.php | 50 ++++++------------------------ php/commands/plugin.php | 19 ++---------- php/commands/post.php | 50 ++++++------------------------ php/commands/site.php | 9 +++--- php/commands/term.php | 48 ++++++---------------------- php/commands/theme.php | 12 ++----- php/commands/user.php | 42 +++++-------------------- 10 files changed, 104 insertions(+), 184 deletions(-) create mode 100644 php/WP_CLI/Formatter.php diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index a9ed660bef..a0785db231 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -11,6 +11,7 @@ abstract class CommandWithDBObject extends \WP_CLI_Command { protected $obj_type; protected $obj_id_key = 'ID'; + protected $obj_fields = null; protected function _create( $args, $assoc_args, $callback ) { unset( $assoc_args[ $this->obj_id_key ] ); @@ -78,5 +79,8 @@ protected function success_or_failure( $r ) { return $status; } + protected function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, $this->obj_type ); + } } diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index d868cf7721..39f7544621 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -348,5 +348,9 @@ protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) \WP_CLI\Utils\format_items( $format, $items, $assoc_args['fields'] ); } + + protected function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, null, $this->item_type ); + } } diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php new file mode 100644 index 0000000000..244ad9e6a0 --- /dev/null +++ b/php/WP_CLI/Formatter.php @@ -0,0 +1,50 @@ +<?php + +namespace WP_CLI; + +class Formatter { + + private $args; + private $prefix; + + public function __construct( &$assoc_args, $fields = null, $prefix = false ) { + $format_args = array( + 'format' => 'table', + 'fields' => $fields, + 'field' => null + ); + + foreach ( array( 'format', 'fields', 'field' ) as $key ) { + if ( isset( $assoc_args[ $key ] ) ) { + $format_args[ $key ] = $assoc_args[ $key ]; + unset( $assoc_args[ $key ] ); + } + } + + $this->args = $format_args; + $this->prefix = $prefix; + } + + public function __get( $key ) { + return $this->args[ $key ]; + } + + public function display_items( $items ) { + if ( $this->args['field'] ) { + \WP_CLI\Utils\show_single_field( $items, $this->args['field'], $this->args['format'], $this->prefix ); + } elseif ( $this->args['fields'] ) { + \WP_CLI\Utils\format_items( $this->args['format'], $items, $this->args['fields'] ); + } else { + trigger_error( 'Both --field= and --fields= parameters are missing.', E_USER_ERROR ); + } + } + + public function display_item( $item ) { + if ( isset( $this->args['field'] ) ) { + \WP_CLI\Utils\show_single_field( array( (object) $item ), $this->args['field'], $this->args['format'], $this->prefix ); + } else { + \WP_CLI\Utils\show_multiple_fields( $item, $this->args['format'] ); + } + } +} + diff --git a/php/commands/comment.php b/php/commands/comment.php index 707e02a41c..adefbcada9 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -9,8 +9,7 @@ class Comment_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'comment'; protected $obj_id_key = 'comment_ID'; - - private $fields = array( + protected $obj_fields = array( 'comment_ID', 'comment_post_ID', 'comment_date', @@ -100,28 +99,13 @@ public function update( $args, $assoc_args ) { * wp comment get 1 --field=content */ public function get( $args, $assoc_args ) { - $defaults = array( - 'format' => 'table' - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - $comment_id = (int)$args[0]; $comment = get_comment( $comment_id ); if ( empty( $comment ) ) WP_CLI::error( "Invalid comment ID." ); - if ( isset( $assoc_args['field'] ) ) { - - \WP_CLI\Utils\show_single_field( array( $comment ), $assoc_args['field'], $assoc_args['format'], 'comment' ); - - } else { - - $comment = get_object_vars( $comment ); - if ( 'table' == $assoc_args['format'] ) - unset( $comment['comment_content'] ); - - \WP_CLI\Utils\show_multiple_fields( $comment, $assoc_args['format'] ); - } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $comment ); } /** @@ -152,35 +136,19 @@ public function get( $args, $assoc_args ) { * @subcommand list */ public function _list( $_, $assoc_args ) { - $query_args = array(); - $defaults = array( - 'format' => 'table', - 'fields' => $this->fields - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - - foreach ( $assoc_args as $key => $value ) { - if ( true === $value ) - continue; - - $query_args[ $key ] = $value; - } + $formatter = $this->get_formatter( $assoc_args ); - if ( 'ids' == $assoc_args['format'] ) - $query_args['fields'] = 'ids'; + if ( 'ids' == $formatter->format ) + $assoc_args['fields'] = 'ids'; $query = new WP_Comment_Query(); - $comments = $query->query( $query_args ); + $comments = $query->query( $assoc_args ); - if ( 'ids' == $assoc_args['format'] ) { + if ( 'ids' == $formatter->format ) { $comments = wp_list_pluck( $comments, 'comment_ID' ); } - if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( $comments, $assoc_args['field'], $assoc_args['format'], 'comment' ); - } else { - WP_CLI\Utils\format_items( $assoc_args['format'], $comments, $assoc_args['fields'] ); - } + $formatter->display_items( $comments ); } /** diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 1f1605ac7e..e7742f6662 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -387,12 +387,6 @@ function install( $args, $assoc_args ) { * wp plugin get bbpress --format=json */ public function get( $args, $assoc_args ) { - - $defaults = array( - 'format' => 'table' - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - $file = $this->_parse_name( $args[0] ); $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false ); @@ -405,17 +399,10 @@ public function get( $args, $assoc_args ) { 'description' => wordwrap( $plugin_data['Description'] ), 'status' => $this->get_status( $file ), 'update' => $this->has_update( $file ), - ); - - if ( isset( $assoc_args['field'] ) ) { - - \WP_CLI\Utils\show_single_field( array( $plugin_obj ), $assoc_args['field'], $assoc_args['format'] ); - - } else { - - \WP_CLI\Utils\show_multiple_fields( $plugin_obj, $assoc_args['format'] ); + ); - } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $plugin_obj ); } /** diff --git a/php/commands/post.php b/php/commands/post.php index 91ee1a47ca..e4271d16d5 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -8,8 +8,7 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'post'; - - private $fields = array( + protected $obj_fields = array( 'ID', 'post_title', 'post_name', @@ -153,30 +152,15 @@ protected function _edit( $content, $title ) { * wp post get 12 --field=content > file.txt */ public function get( $args, $assoc_args ) { - $defaults = array( - 'format' => 'table' - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - $post_id = $args[0]; if ( !$post_id || !$post = get_post( $post_id ) ) \WP_CLI::error( "Could not find the post with ID $post_id." ); - if ( isset( $assoc_args['field'] ) ) { - - \WP_CLI\Utils\show_single_field( array( $post ), $assoc_args['field'], $assoc_args['format'], 'post' ); - - } else { - - $fields = get_object_vars( $post ); - - if ( 'table' == $assoc_args['format'] ) - unset( $fields['filter'], $fields['post_content'], $fields['format_content'] ); - else if ( 'json' == $assoc_args['format'] ) - unset( $fields['filter'] ); + $post_arr = get_object_vars( $post ); + unset( $post_arr['filter'] ); - \WP_CLI\Utils\show_multiple_fields( $fields, $assoc_args['format'] ); - } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $post_arr ); } /** @@ -243,34 +227,20 @@ public function delete( $args, $assoc_args ) { * @subcommand list */ public function _list( $_, $assoc_args ) { - $defaults = array( - 'format' => 'table', - 'fields' => $this->fields - ); - $assoc_args = array_merge( $defaults, $assoc_args ); + $formatter = $this->get_formatter( $assoc_args ); - $query_args = array( + $defaults = array( 'posts_per_page' => -1, 'post_status' => 'any', ); + $query_args = array_merge( $defaults, $assoc_args ); - foreach ( $assoc_args as $key => $value ) { - if ( true === $value ) - continue; - - $query_args[ $key ] = $value; - } - - if ( 'ids' == $assoc_args['format'] ) + if ( 'ids' == $formatter->format ) $query_args['fields'] = 'ids'; $query = new WP_Query( $query_args ); - if ( isset( $assoc_args['field'] ) ) { - WP_CLI\Utils\show_single_field( $query->posts, $assoc_args['field'], $assoc_args['format'], 'post' ); - } else { - WP_CLI\Utils\format_items( $assoc_args['format'], $query->posts, $assoc_args['fields'] ); - } + $formatter->display_items( $query->posts ); } /** diff --git a/php/commands/site.php b/php/commands/site.php index 5af9489a73..5bcdf6d627 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -7,6 +7,8 @@ */ class Site_Command extends \WP_CLI\CommandWithDBObject { + protected $obj_type = 'site'; + /** * Delete comments. */ @@ -355,11 +357,8 @@ function _list( $_, $assoc_args ) { return $blog; } ); - if ( isset( $assoc_args['field'] ) ) { - WP_CLI\Utils\show_single_field( $it, $assoc_args['field'], $assoc_args['format'], 'site' ); - } else { - WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); - } + $formatter = new \WP_CLI\Formatter( $assoc_args, null, 'site' ); + $formatter->display_items( $it ); } /** diff --git a/php/commands/term.php b/php/commands/term.php index e9aad44006..770e5f3dad 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -45,34 +45,18 @@ class Term_Command extends WP_CLI_Command { * @subcommand list */ public function _list( $args, $assoc_args ) { - - list( $taxonomy ) = $args; + $formatter = $this->get_formatter( $assoc_args ); $defaults = array( - 'fields' => implode( ',', $this->fields ), - 'format' => 'table', 'hide_empty' => false, ); - $assoc_args = wp_parse_args( $assoc_args, $defaults ); - - $fields = $assoc_args['fields']; - unset( $assoc_args['fields'] ); - - $terms = get_terms( array( $taxonomy ), $assoc_args ); + $assoc_args = array_merge( $defaults, $assoc_args ); - if ( 'ids' == $assoc_args['format'] ) + $terms = get_terms( $args, $assoc_args ); + if ( 'ids' == $formatter->format ) $terms = wp_list_pluck( $terms, 'term_id' ); - if ( isset( $assoc_args['field'] ) ) { - - WP_CLI\Utils\show_single_field( $terms, $assoc_args['field'], $assoc_args['format'], 'term' ); - - } else { - - WP_CLI\Utils\format_items( $assoc_args['format'], $terms, $fields ); - - } - + $formatter->display_items( $terms ); } /** @@ -157,29 +141,14 @@ public function create( $args, $assoc_args ) { * wp term get 1 category --format=json */ public function get( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); list( $term_id, $taxonomy ) = $args; - - $defaults = array( - 'format' => 'table' - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - $term = get_term_by( 'id', $term_id, $taxonomy ); if ( ! $term ) WP_CLI::error( "Term doesn't exist." ); - if ( isset( $assoc_args['field'] ) ) { - - \WP_CLI\Utils\show_single_field( array( $term ), $assoc_args['field'], $assoc_args['format'], 'term' ); - - } else { - - $term = get_object_vars( $term ); - - \WP_CLI\Utils\show_multiple_fields( $term, $assoc_args['format'] ); - } - + $formatter->display_item( $term ); } /** @@ -263,6 +232,9 @@ public function delete( $args ) { WP_CLI::error( "Term doesn't exist." ); } + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'term' ); + } } WP_CLI::add_command( 'term', 'Term_Command' ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 8b0c7b61e7..01533a754f 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -268,11 +268,6 @@ function install( $args, $assoc_args ) { * wp theme get twentytwelve --format=json */ public function get( $args, $assoc_args ) { - $defaults = array( - 'format' => 'table' - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - $theme = $this->parse_name( $args[0] ); // WP_Theme object employs magic getter, unfortunately @@ -285,11 +280,8 @@ public function get( $args, $assoc_args ) { $theme_obj->description = wordwrap( $theme_obj->description ); - if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( array( $theme_obj ), $assoc_args['field'], $assoc_args['format'] ); - } else { - \WP_CLI\Utils\show_multiple_fields( $theme_obj, $assoc_args['format'] ); - } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $theme_obj ); } /** diff --git a/php/commands/user.php b/php/commands/user.php index 171d91da59..bc8f9afb1d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -8,8 +8,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'user'; - - private $fields = array( + protected $obj_fields = array( 'ID', 'user_login', 'display_name', @@ -49,27 +48,13 @@ class User_Command extends \WP_CLI\CommandWithDBObject { * @subcommand list */ public function _list( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); - $defaults = array( - 'blog_id' => get_current_blog_id(), - 'fields' => implode( ',', $this->fields ), - 'format' => 'table', - ); - $params = array_merge( $defaults, $assoc_args ); - - $fields = $params['fields']; - unset( $params['fields'] ); - - if ( array_key_exists( 'role', $assoc_args ) ) { - $params['role'] = $assoc_args['role']; + if ( 'ids' == $formatter->format ) { + $assoc_args['fields'] = 'ids'; } - if ( 'ids' == $params['format'] ) - $params['fields'] = 'ids'; - else - $params['fields'] = 'all_with_meta'; - - $users = get_users( $params ); + $users = get_users( $assoc_args ); $it = WP_CLI\Utils\iterator_map( $users, function ( $user ) { if ( !is_object( $user ) ) @@ -80,11 +65,7 @@ public function _list( $args, $assoc_args ) { return $user; } ); - if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( $it, $assoc_args['field'], $assoc_args['format'], 'user' ); - } else { - WP_CLI\Utils\format_items( $params['format'], $it, $fields ); - } + $formatter->display_items( $it ); } /** @@ -112,10 +93,6 @@ public function _list( $args, $assoc_args ) { * wp user get bob --format=json > bob.json */ public function get( $args, $assoc_args ) { - $assoc_args = wp_parse_args( $assoc_args, array( - 'format' => 'table' - ) ); - $user = self::get_user( $args[0] ); if ( method_exists( $user, 'to_array' ) ) { @@ -126,11 +103,8 @@ public function get( $args, $assoc_args ) { } $user_data['roles'] = implode( ', ', $user->roles ); - if ( isset( $assoc_args['field'] ) ) { - \WP_CLI\Utils\show_single_field( array( (object) $user_data ), $assoc_args['field'], $assoc_args['format'], 'user' ); - } else { - \WP_CLI\Utils\show_multiple_fields( $user_data, $assoc_args['format'] ); - } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $user_data ); } /** From 801a6c19c7703f318ebb294fc1819f884949ddf4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 18:39:35 +0300 Subject: [PATCH 2351/4858] move disparate formatting utilities into the WP_CLI\Formatter class --- php/WP_CLI/Formatter.php | 86 ++++++++++++++++++++++++++++++++++++++-- php/utils.php | 80 ------------------------------------- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 244ad9e6a0..65cf878134 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -31,7 +31,7 @@ public function __get( $key ) { public function display_items( $items ) { if ( $this->args['field'] ) { - \WP_CLI\Utils\show_single_field( $items, $this->args['field'], $this->args['format'], $this->prefix ); + self::show_single_field( $items, $this->args['field'], $this->args['format'], $this->prefix ); } elseif ( $this->args['fields'] ) { \WP_CLI\Utils\format_items( $this->args['format'], $items, $this->args['fields'] ); } else { @@ -41,10 +41,90 @@ public function display_items( $items ) { public function display_item( $item ) { if ( isset( $this->args['field'] ) ) { - \WP_CLI\Utils\show_single_field( array( (object) $item ), $this->args['field'], $this->args['format'], $this->prefix ); + self::show_single_field( array( (object) $item ), $this->args['field'], $this->args['format'], $this->prefix ); } else { - \WP_CLI\Utils\show_multiple_fields( $item, $this->args['format'] ); + self::show_multiple_fields( $item, $this->args['format'] ); } } + + /** + * Show a single field from a list of items. + * + * @param array Array of objects to show fields from + * @param string The field to show + * @param string The format to show the field in + * @param string Whether or not the field is typically prefixed (e.g. "content" => "post_content") + */ + private static function show_single_field( $items, $field, $format = '', $field_prefix = '' ) { + + foreach ( $items as $item ) { + + if ( ! isset( $key ) ) { + + foreach ( array( $field, $field_prefix . '_' . $field ) as $maybe_key ) { + if ( isset( $item->$maybe_key ) ) { + $key = $maybe_key; + break; + } + } + + if ( ! $key ) { + \WP_CLI::error( "Invalid field: $field." ); + } + + } + + \WP_CLI::print_value( $item->$key, array( 'format' => $format ) ); + } + + } + + /** + * Show multiple fields of an object. + * + * @param object|array Data to display + * @param string Format to display the data in + */ + private static function show_multiple_fields( $data, $format ) { + + switch ( $format ) { + + case 'table': + self::assoc_array_to_table( $data ); + break; + + case 'json': + \WP_CLI::print_value( $data, array( 'format' => $format ) ); + break; + + default: + \WP_CLI::error( "Invalid format: " . $format ); + break; + + } + + } + + /** + * Format an associative array as a table + * + * @param array $fields Fields and values to format + */ + private static function assoc_array_to_table( $fields ) { + $rows = array(); + + foreach ( $fields as $field => $value ) { + if ( ! is_string( $value ) ) { + $value = json_encode( $value ); + } + + $rows[] = (object) array( + 'Field' => $field, + 'Value' => $value + ); + } + + \WP_CLI\Utils\format_items( 'table', $rows, array( 'Field', 'Value' ) ); + } } diff --git a/php/utils.php b/php/utils.php index bdcaba1245..eff73ced73 100644 --- a/php/utils.php +++ b/php/utils.php @@ -247,28 +247,6 @@ function format_items( $format, $items, $fields ) { } } -/** - * Format an associative array as a table - * - * @param array $fields Fields and values to format - */ -function assoc_array_to_table( $fields ) { - $rows = array(); - - foreach ( $fields as $field => $value ) { - if ( ! is_string( $value ) ) { - $value = json_encode( $value ); - } - - $rows[] = (object) array( - 'Field' => $field, - 'Value' => $value - ); - } - - format_items( 'table', $rows, array( 'Field', 'Value' ) ); -} - /** * Write data as CSV to a given file. * @@ -309,64 +287,6 @@ function pick_fields( $item, $fields ) { return $values; } -/** - * Show a single field from a list of items. - * - * @param array Array of objects to show fields from - * @param string The field to show - * @param string The format to show the field in - * @param string Whether or not the field is typically prefixed (e.g. "content" => "post_content") - */ -function show_single_field( $items, $field, $format = '', $field_prefix = '' ) { - - foreach ( $items as $item ) { - - if ( ! isset( $key ) ) { - - foreach ( array( $field, $field_prefix . '_' . $field ) as $maybe_key ) { - if ( isset( $item->$maybe_key ) ) { - $key = $maybe_key; - break; - } - } - - if ( ! $key ) { - \WP_CLI::error( "Invalid field: $field." ); - } - - } - - \WP_CLI::print_value( $item->$key, array( 'format' => $format ) ); - } - -} - -/** - * Show multiple fields of an object. - * - * @param object|array Data to display - * @param string Format to display the data in - */ -function show_multiple_fields( $data, $format ) { - - switch ( $format ) { - - case 'table': - assoc_array_to_table( $data ); - break; - - case 'json': - \WP_CLI::print_value( $data, array( 'format' => $format ) ); - break; - - default: - \WP_CLI::error( "Invalid format: " . $format ); - break; - - } - -} - /** * Launch system's $EDITOR to edit text * From dcead64385dccaae82a3f8e7023124147fc6ab45 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 18:42:18 +0300 Subject: [PATCH 2352/4858] let format_items() handle case where fields aren't set, for now --- php/WP_CLI/Formatter.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 65cf878134..d9c5c029aa 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -32,10 +32,8 @@ public function __get( $key ) { public function display_items( $items ) { if ( $this->args['field'] ) { self::show_single_field( $items, $this->args['field'], $this->args['format'], $this->prefix ); - } elseif ( $this->args['fields'] ) { - \WP_CLI\Utils\format_items( $this->args['format'], $items, $this->args['fields'] ); } else { - trigger_error( 'Both --field= and --fields= parameters are missing.', E_USER_ERROR ); + \WP_CLI\Utils\format_items( $this->args['format'], $items, $this->args['fields'] ); } } From 47ac3ac68e7be1731738ee5de1f12ebd9544eb71 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 19:09:11 +0300 Subject: [PATCH 2353/4858] fix get_formatter() --- php/WP_CLI/CommandWithDBObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index a0785db231..7ea97c7007 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -80,7 +80,7 @@ protected function success_or_failure( $r ) { } protected function get_formatter( &$assoc_args ) { - return new \WP_CLI\Formatter( $assoc_args, $this->fields, $this->obj_type ); + return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); } } From 1942964401013a7b3a715e57e4a22818679cd500 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 19:12:52 +0300 Subject: [PATCH 2354/4858] extract find_item_key() method --- php/WP_CLI/Formatter.php | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index d9c5c029aa..6cdb5d0972 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -31,7 +31,7 @@ public function __get( $key ) { public function display_items( $items ) { if ( $this->args['field'] ) { - self::show_single_field( $items, $this->args['field'], $this->args['format'], $this->prefix ); + $this->show_single_field( $items, $this->args['field'] ); } else { \WP_CLI\Utils\format_items( $this->args['format'], $items, $this->args['fields'] ); } @@ -39,7 +39,7 @@ public function display_items( $items ) { public function display_item( $item ) { if ( isset( $this->args['field'] ) ) { - self::show_single_field( array( (object) $item ), $this->args['field'], $this->args['format'], $this->prefix ); + $this->show_single_field( array( (object) $item ), $this->args['field'] ); } else { self::show_multiple_fields( $item, $this->args['format'] ); } @@ -50,31 +50,30 @@ public function display_item( $item ) { * * @param array Array of objects to show fields from * @param string The field to show - * @param string The format to show the field in - * @param string Whether or not the field is typically prefixed (e.g. "content" => "post_content") */ - private static function show_single_field( $items, $field, $format = '', $field_prefix = '' ) { - + private function show_single_field( $items, $field ) { foreach ( $items as $item ) { - if ( ! isset( $key ) ) { + $key = $this->find_item_key( $item, $field ); + } - foreach ( array( $field, $field_prefix . '_' . $field ) as $maybe_key ) { - if ( isset( $item->$maybe_key ) ) { - $key = $maybe_key; - break; - } - } - - if ( ! $key ) { - \WP_CLI::error( "Invalid field: $field." ); - } + \WP_CLI::print_value( $item->$key, array( 'format' => $this->args['format'] ) ); + } + } + private function find_item_key( $item, $field ) { + foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { + if ( isset( $item->$maybe_key ) ) { + $key = $maybe_key; + break; } + } - \WP_CLI::print_value( $item->$key, array( 'format' => $format ) ); + if ( ! $key ) { + \WP_CLI::error( "Invalid field: $field." ); } + return $key; } /** From 5d4cdf075d9a231c639226b9526c38d62c5e077b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 19:24:34 +0300 Subject: [PATCH 2355/4858] move logic from format_items() into WP_CLI\Formatter class --- php/WP_CLI/Formatter.php | 57 ++++++++++++++++++++++++++++++++++++++-- php/utils.php | 46 +++----------------------------- 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 6cdb5d0972..4b8a3cfc2a 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -21,6 +21,10 @@ public function __construct( &$assoc_args, $fields = null, $prefix = false ) { } } + if ( ! is_array( $format_args['fields'] ) ) { + $format_args['fields'] = explode( ',', $format_args['fields'] ); + } + $this->args = $format_args; $this->prefix = $prefix; } @@ -33,7 +37,7 @@ public function display_items( $items ) { if ( $this->args['field'] ) { $this->show_single_field( $items, $this->args['field'] ); } else { - \WP_CLI\Utils\format_items( $this->args['format'], $items, $this->args['fields'] ); + $this->format( $items ); } } @@ -45,6 +49,43 @@ public function display_item( $item ) { } } + private function format( $items ) { + $fields = $this->args['fields']; + + switch ( $this->args['format'] ) { + case 'count': + if ( !is_array( $items ) ) { + $items = iterator_to_array( $items ); + } + echo count( $items ); + break; + + case 'ids': + if ( !is_array( $items ) ) { + $items = iterator_to_array( $items ); + } + echo implode( ' ', $items ); + break; + + case 'table': + self::show_table( $items, $fields ); + break; + + case 'csv': + \WP_CLI\Utils\write_csv( STDOUT, $items, $fields ); + break; + + case 'json': + $out = array(); + foreach ( $items as $item ) { + $out[] = \WP_CLI\Utils\pick_fields( $item, $fields ); + } + + echo json_encode( $out ); + break; + } + } + /** * Show a single field from a list of items. * @@ -102,6 +143,18 @@ private static function show_multiple_fields( $data, $format ) { } + private static function show_table( $items, $fields ) { + $table = new \cli\Table(); + + $table->setHeaders( $fields ); + + foreach ( $items as $item ) { + $table->addRow( array_values( \WP_CLI\Utils\pick_fields( $item, $fields ) ) ); + } + + $table->display(); + } + /** * Format an associative array as a table * @@ -121,7 +174,7 @@ private static function assoc_array_to_table( $fields ) { ); } - \WP_CLI\Utils\format_items( 'table', $rows, array( 'Field', 'Value' ) ); + self::show_table( $rows, array( 'Field', 'Value' ) ); } } diff --git a/php/utils.php b/php/utils.php index eff73ced73..020b8aef7f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -202,49 +202,9 @@ function locate_wp_config() { * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list */ function format_items( $format, $items, $fields ) { - if ( ! is_array( $fields ) ) - $fields = explode( ',', $fields ); - - switch ( $format ) { - case 'count': - if ( !is_array( $items ) ) { - $items = iterator_to_array( $items ); - } - echo count( $items ); - break; - - case 'ids': - if ( !is_array( $items ) ) { - $items = iterator_to_array( $items ); - } - echo implode( ' ', $items ); - break; - - case 'table': - $table = new \cli\Table(); - - $table->setHeaders( $fields ); - - foreach ( $items as $item ) { - $table->addRow( array_values( pick_fields( $item, $fields ) ) ); - } - - $table->display(); - break; - - case 'csv': - write_csv( STDOUT, $items, $fields ); - break; - - case 'json': - $out = array(); - foreach ( $items as $item ) { - $out[] = pick_fields( $item, $fields ); - } - - echo json_encode( $out ); - break; - } + $assoc_args = compact( 'format', 'fields' ); + $formatter = new \WP_CLI\Formatter( $assoc_args ); + $formatter->display_items( $items ); } /** From 97b8c81dcc37f3742ad64813b30c892e127854f2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 19:41:57 +0300 Subject: [PATCH 2356/4858] use formatter in 'wp role list' --- features/roles.feature | 11 +++++++++++ php/commands/role.php | 12 ++---------- 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 features/roles.feature diff --git a/features/roles.feature b/features/roles.feature new file mode 100644 index 0000000000..139cc41b9e --- /dev/null +++ b/features/roles.feature @@ -0,0 +1,11 @@ +Feature: Manage WordPress roles + + Background: + Given a WP install + + Scenario: Role CRUD operations + When I run `wp role list` + Then STDOUT should be a table containing rows: + | name | role | + | Subscriber | subscriber | + | Editor | editor | diff --git a/php/commands/role.php b/php/commands/role.php index 78a5fbdaf1..97674ffbfe 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -32,15 +32,6 @@ class Role_Command extends WP_CLI_Command { public function _list( $args, $assoc_args ) { global $wp_roles; - $defaults = array( - 'fields' => implode( ',', $this->fields ), - 'format' => 'table', - ); - $params = array_merge( $defaults, $assoc_args ); - - $fields = $params['fields']; - unset( $params['fields'] ); - $output_roles = array(); foreach ( $wp_roles->roles as $key => $role ) { $output_role = new stdClass; @@ -51,7 +42,8 @@ public function _list( $args, $assoc_args ) { $output_roles[] = $output_role; } - WP_CLI\Utils\format_items( $params['format'], $output_roles, $fields ); + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); + $formatter->display_items( $output_roles ); } /** From c37f184eaf76e929f264229d544163781ba48893 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 20:26:29 +0300 Subject: [PATCH 2357/4858] use Formatter in CommandWithUpgrade->_list() --- php/WP_CLI/CommandWithUpgrade.php | 24 +++++------------------- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 39f7544621..e491dfdeaa 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -5,6 +5,8 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $item_type; + protected $obj_fields; + protected $upgrade_refresh; protected $upgrade_transient; @@ -238,12 +240,6 @@ protected function _list( $_, $assoc_args ) { // Force WordPress to check for updates call_user_func( $this->upgrade_refresh ); - $defaults = array( - 'format' => 'table', - 'fields' => $this->fields - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - $all_items = $this->get_all_items(); if ( !is_array( $all_items ) ) \WP_CLI::error( "No {$this->item_type}s found." ); @@ -263,18 +259,8 @@ protected function _list( $_, $assoc_args ) { return $item; } ); - if ( isset( $assoc_args['field'] ) ) { - $field = $assoc_args['field']; - - foreach ( $it as $item ) { - if ( !isset( $item[ $field ] ) ) { - \WP_CLI::error( "Invalid $this->item_type field: $field." ); - } - \WP_CLI::print_value( $item[ $field ] ); - } - } else { - \WP_CLI\Utils\format_items( $assoc_args['format'], $it, $assoc_args['fields'] ); - } + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $it ); } /** @@ -350,7 +336,7 @@ protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) } protected function get_formatter( &$assoc_args ) { - return new \WP_CLI\Formatter( $assoc_args, null, $this->item_type ); + return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->item_type ); } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e7742f6662..b257689171 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -11,7 +11,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade { protected $upgrade_refresh = 'wp_update_plugins'; protected $upgrade_transient = 'update_plugins'; - protected $fields = array( + protected $obj_fields = array( 'name', 'status', 'update', diff --git a/php/commands/theme.php b/php/commands/theme.php index 01533a754f..8f1f4dbbbf 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -11,7 +11,7 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { protected $upgrade_refresh = 'wp_update_themes'; protected $upgrade_transient = 'update_themes'; - protected $fields = array( + protected $obj_fields = array( 'name', 'status', 'update', From 58229e326383688ac283408fd93a8a0a562feec2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 20:38:00 +0300 Subject: [PATCH 2358/4858] respect --format=json when --field= is passed in list subcommands --- features/steps/basic_steps.php | 14 ++++++++++++++ features/upgradables.feature | 6 ++++++ php/WP_CLI/Formatter.php | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 1557f91c0d..092c6c3fd9 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -202,6 +202,20 @@ function ( $world, PyStringNode $expected ) { } }); +$steps->Then( '/^STDOUT should be a JSON array containing:$/', + function ( $world, PyStringNode $expected ) { + $output = $world->result->STDOUT; + $expected = $world->replace_variables( (string) $expected ); + + $actualValues = json_decode( $output ); + $expectedValues = json_decode( $expected ); + + $missing = array_diff( $expectedValues, $actualValues ); + if ( !empty( $missing ) ) { + throw new \Exception( $output ); + } +}); + $steps->Then( '/^STDOUT should be CSV containing:$/', function ( $world, TableNode $expected ) { $output = $world->result->STDOUT; diff --git a/features/upgradables.feature b/features/upgradables.feature index df5080414e..56ee10ddbb 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -26,6 +26,12 @@ Feature: Manage WordPress themes and plugins <item> """ + When I run `wp <type> list --field=name --format=json` + Then STDOUT should be a JSON array containing: + """ + ["<item>"] + """ + When I run `wp <type> status` Then STDOUT should contain: """ diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 4b8a3cfc2a..17b580ed76 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -43,7 +43,9 @@ public function display_items( $items ) { public function display_item( $item ) { if ( isset( $this->args['field'] ) ) { - $this->show_single_field( array( (object) $item ), $this->args['field'] ); + $item = (object) $item; + $key = $this->find_item_key( $item, $this->args['field'] ); + \WP_CLI::print_value( $item->$key, array( 'format' => $this->args['format'] ) ); } else { self::show_multiple_fields( $item, $this->args['format'] ); } @@ -94,11 +96,21 @@ private function format( $items ) { */ private function show_single_field( $items, $field ) { foreach ( $items as $item ) { + $item = (object) $item; + if ( ! isset( $key ) ) { $key = $this->find_item_key( $item, $field ); } - \WP_CLI::print_value( $item->$key, array( 'format' => $this->args['format'] ) ); + if ( 'json' == $this->args['format'] ) { + $values[] = $item->$key; + } else { + \WP_CLI::print_value( $item->$key, array( 'format' => $this->args['format'] ) ); + } + } + + if ( 'json' == $this->args['format'] ) { + echo json_encode( $values ); } } From be0ff407fa73be3c8537c886ad66c28faba15e84 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 1 Oct 2013 22:32:06 +0300 Subject: [PATCH 2359/4858] set all_with_meta, for WP 3.4 --- php/commands/user.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index bc8f9afb1d..10fb90d18f 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -51,7 +51,9 @@ public function _list( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); if ( 'ids' == $formatter->format ) { - $assoc_args['fields'] = 'ids'; + $assoc_args['fields'] = 'ids'; + } else { + $assoc_args['fields'] = 'all_with_meta'; } $users = get_users( $assoc_args ); From be316e0b0f8305fb7e7a554d8b6b018d1b3aa83e Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Tue, 1 Oct 2013 13:58:23 -0700 Subject: [PATCH 2360/4858] wp post edit should no longer call parent::update This broke in f6285d3 when CommandWithDBObject::update was removed and _update made protected. It should have been defined as $this->update from the beginning. --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index ae2127735b..10ee29bace 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -119,7 +119,7 @@ public function edit( $args, $_ ) { if ( $r === false ) \WP_CLI::warning( 'No change made to post content.', 'Aborted' ); else - parent::update( $args, array( 'post_content' => $r ) ); + $this->update( $args, array( 'post_content' => $r ) ); } protected function _edit( $content, $title ) { From 280f980364952d03fd130783c2b8e686f591c0fd Mon Sep 17 00:00:00 2001 From: goldenapples <goldenapplesdesign@gmail.com> Date: Tue, 1 Oct 2013 13:59:46 -0700 Subject: [PATCH 2361/4858] Add feature tests for `wp post edit` Adds two new feature tests for wp post edit: one that simulates opening an editor and quitting right out of it, and one that simulates chnaging a word and then saving. --- features/post.feature | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/features/post.feature b/features/post.feature index 84d864b98a..a7bf089985 100644 --- a/features/post.feature +++ b/features/post.feature @@ -26,7 +26,7 @@ Feature: Manage WordPress posts When I try the previous command again Then the return code should be 1 - Scenario: Creating/getting posts + Scenario: Creating/getting/editing posts Given a content.html file: """ This is some content. @@ -73,6 +73,27 @@ Feature: Manage WordPress posts } """ + When I try `EDITOR='ex -i NONE -c q!' wp post edit {POST_ID}` + Then STDERR should contain: + """ + No change made to post content. + """ + And the return code should be 0 + + When I try `EDITOR='ex -i NONE -c %s/content/bunkum -c wq' wp post edit {POST_ID}` + Then STDERR should be empty + Then STDOUT should contain: + """ + Updated post {POST_ID}. + """ + + When I run `wp post get --field=content {POST_ID}` + Then STDOUT should contain: + """ + This is some bunkum. + """ + + Scenario: Creating/listing posts When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` Then STDOUT should be a number From c3a2dfec6e2f2b939bd53d35200d1c2db9776bdd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 00:16:07 +0200 Subject: [PATCH 2362/4858] peg rmccue/requests to a specific revision still waiting for a stable tag: https://github.com/rmccue/Requests/issues/43 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 91247c46fc..4cfe2e0de1 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "wp-cli/php-cli-tools": "0.9.3", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", - "rmccue/requests": "dev-master" + "rmccue/requests": "dev-master#ca0f58b6523a6d11c815ae25c79cc810cea69be7" }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" From 7cea2ca5e0b8a79ebcc70d476c2ab5da310f2433 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 00:44:25 +0200 Subject: [PATCH 2363/4858] bump version to 0.12-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index b6fda097ae..3ce45aaf4d 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.12-alpha2' ); +define( 'WP_CLI_VERSION', '0.12-beta' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From f62a50c6a341f94bfcccde5c579ded1c9340bec4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 14:24:37 +0200 Subject: [PATCH 2364/4858] check response from _parse_name() --- features/upgradables.feature | 4 ++++ php/commands/plugin.php | 3 +++ 2 files changed, 7 insertions(+) diff --git a/features/upgradables.feature b/features/upgradables.feature index 56ee10ddbb..4a21f41568 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -8,6 +8,10 @@ Feature: Manage WordPress themes and plugins And I run `wp <type> path` And save STDOUT as {CONTENT_DIR} + When I try `wp <type> get <item>` + Then the return code should be 1 + And STDERR should not be empty + # Install an out of date <item> from WordPress.org repository When I run `wp <type> install <item> --version=<version>` Then STDOUT should contain: diff --git a/php/commands/plugin.php b/php/commands/plugin.php index b257689171..4686b5f6a3 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -388,6 +388,9 @@ function install( $args, $assoc_args ) { */ public function get( $args, $assoc_args ) { $file = $this->_parse_name( $args[0] ); + if ( !$file ) { + WP_CLI::error( "The '{$args[0]}' plugin could not be found." ); + } $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false ); From 12a68a89a5277c18a8e5f10ed9d52e135ffdd578 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 14:28:39 +0200 Subject: [PATCH 2365/4858] combine tests for plugin|theme get --- features/plugin.feature | 21 --------------------- features/theme.feature | 21 --------------------- features/upgradables.feature | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 42 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index bde1d71dde..698e63ad3a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -86,24 +86,3 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | update | version | | akismet | active | available | 2.5.6 | - - Scenario: Get details about an installed plugin - - When I run `wp plugin get akismet` - Then STDOUT should be a table containing rows: - | Field | Value | - | name | akismet | - - - When I run `wp plugin get akismet --field=title` - Then STDOUT should contain: - """ - Akismet - """ - - When I run `wp plugin get akismet --field=title --format=json` - Then STDOUT should contain: - """ - "Akismet" - """ - diff --git a/features/theme.feature b/features/theme.feature index 2cdf61a367..7898f9d097 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -73,24 +73,3 @@ Feature: Manage WordPress themes """ wp-content/themes/p2 """ - - Scenario: Get details about an installed theme - When I run `wp theme install p2` - Then STDOUT should not be empty - - When I run `wp theme get p2` - Then STDOUT should be a table containing rows: - | Field | Value | - | name | P2 | - - When I run `wp theme get p2 --field=title` - Then STDOUT should contain: - """ - P2 - """ - - When I run `wp theme get p2 --field=title --format=json` - Then STDOUT should contain: - """ - "P2" - """ diff --git a/features/upgradables.feature b/features/upgradables.feature index 4a21f41568..4f4fea55cc 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -19,6 +19,23 @@ Feature: Manage WordPress themes and plugins <type_name> installed successfully """ + When I run `wp <type> get <item>` + Then STDOUT should be a table containing rows: + | Field | Value | + | title | <item_title> | + + When I run `wp <type> get <item> --field=title` + Then STDOUT should contain: + """ + <item_title> + """ + + When I run `wp <type> get <item> --field=title --format=json` + Then STDOUT should contain: + """ + "<item_title>" + """ + When I run `wp <type> list` Then STDOUT should be a table containing rows: | name | status | update | version | From 1bd8e82be15441d4957fa259cf79c311b43cebba Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 14:46:26 +0200 Subject: [PATCH 2366/4858] implement 'wp theme is-installed' --- features/plugin.feature | 6 ------ features/upgradables.feature | 7 +++++++ php/commands/plugin.php | 2 +- php/commands/theme.php | 24 ++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 698e63ad3a..b9ebc00f2f 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -31,12 +31,6 @@ Feature: Manage WordPress plugins Status: Active """ - When I run `wp plugin is-installed zombieland && echo "Zombieland"` - Then STDOUT should contain: - """ - Zombieland - """ - When I run `wp plugin status` Then STDOUT should not be empty diff --git a/features/upgradables.feature b/features/upgradables.feature index 4f4fea55cc..672ab6c034 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -8,6 +8,10 @@ Feature: Manage WordPress themes and plugins And I run `wp <type> path` And save STDOUT as {CONTENT_DIR} + When I try `wp <type> is-installed <item>` + Then the return code should be 1 + And STDERR should be empty + When I try `wp <type> get <item>` Then the return code should be 1 And STDERR should not be empty @@ -19,6 +23,9 @@ Feature: Manage WordPress themes and plugins <type_name> installed successfully """ + When I try `wp <type> is-installed <item>` + Then the return code should be 0 + When I run `wp <type> get <item>` Then STDOUT should be a table containing rows: | Field | Value | diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 4686b5f6a3..54fd8dfbb4 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -440,7 +440,7 @@ function uninstall( $args, $assoc_args = array() ) { } /** - * Check if the plugin is installed + * Check if the plugin is installed. * * ## OPTIONS * diff --git a/php/commands/theme.php b/php/commands/theme.php index 8f1f4dbbbf..1d9ac2dd42 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -312,6 +312,30 @@ function update( $args, $assoc_args ) { parent::update_many( $args, $assoc_args ); } + /** + * Check if the theme is installed. + * + * ## OPTIONS + * + * <theme> + * : The theme to check. + * + * ## EXAMPLES + * + * wp theme is-installed twentytwelve + * + * @subcommand is-installed + */ + function is_installed( $args, $assoc_args = array() ) { + $theme = wp_get_theme( $args[0] ); + + if ( $theme->exists() ) { + exit( 0 ); + } else { + exit( 1 ); + } + } + /** * Delete a theme. * From 2772a74044c43e09f71bd10ef5e17c2a6b18756a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 15:41:39 +0200 Subject: [PATCH 2367/4858] add new contributors since the 0.11.2 release --- .mailmap | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.mailmap b/.mailmap index 76512b890d..72fbae088c 100644 --- a/.mailmap +++ b/.mailmap @@ -23,6 +23,7 @@ jmslbam <jmslbam@gmail.com> johnbillion <johnbillion@gmail.com> johnpbloch <jbloch@John-Blochs-iMac.local> johnpbloch <johnpbloch@gmail.com> +joshbetz <j@joshbetz.com> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> @@ -37,21 +38,29 @@ mwilliamson <mike@zwobble.org> nacin <andrewnacin@gmail.com> navitronic <adrian@navitronic.co.uk> nb <nb@nikolay.bg> +nikolay <nikolay@users.noreply.github.com> +nikolay <nikolaynkolev@gmail.com> +nullvariable <nullvariable@gmail.com> ocean90 <dominikschilling+git@gmail.com> +oknoway <nate@oknoway.com> om4james <james@jamesc.id.au> om4james <james@om4.com.au> +Rarst <contact@rarst.net> roelven <roel@soundcloud.com> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> soulou <leo@soulou.fr> spuriousdata <spuriousdata@gmail.com> +stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> taupecat <tracy@taupecat.com> tddewey <td@tddewey.com> +thisislawatts <luke@thisis.la> tlovett1 <admin@taylorlovett.com> tollmanz <zack@zackdev.com> toszcze <toszcze@gmail.com> tott <tott@automattic.com> +trepmal <trepmal@gmail.com> twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> westonruter <weston@x-team.com> From 594430cbef8a2366f3a41f30b875842ecc1af64f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 15:44:00 +0200 Subject: [PATCH 2368/4858] contrib-list: add newline --- utils/contrib-list | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/contrib-list b/utils/contrib-list index b47f016973..6d0e0897e9 100755 --- a/utils/contrib-list +++ b/utils/contrib-list @@ -24,6 +24,7 @@ githubify() { if [ '-l' == "$linked" ] then git log --format="%aN" $prev_version -- | sort -f | uniq | githubify | tr '\n' ',' + echo else git log --format="%aN <%aE>" $prev_version -- | sort -f | uniq fi From a9b9c2d37ae80c927d378cda2ede2442cbeafc0c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 4 Oct 2013 15:54:34 +0200 Subject: [PATCH 2369/4858] bump version to 0.12.0 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 3ce45aaf4d..29acc3635b 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.12-beta' ); +define( 'WP_CLI_VERSION', '0.12.0' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 30ceac062d70c98c1248e681ad598c9f8ca0c1f6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 13:07:37 +0000 Subject: [PATCH 2370/4858] Verbosity when the rewrite structure is set --- php/commands/rewrite.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 27888bd07a..fab148c2b3 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -86,6 +86,7 @@ public function structure( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config self::apache_modules(); flush_rewrite_rules( isset( $assoc_args['hard'] ) ); + WP_CLI::success( "Rewrite structure set." ); } /** From 610e0e20ac62fc28bf4c1bad5be1788078d247f0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 15:51:47 +0200 Subject: [PATCH 2371/4858] Functional tests for rewrite --- features/rewrite.feature | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 features/rewrite.feature diff --git a/features/rewrite.feature b/features/rewrite.feature new file mode 100644 index 0000000000..1fee10929f --- /dev/null +++ b/features/rewrite.feature @@ -0,0 +1,33 @@ +Feature: Manage WordPress rewrites + + Background: + Given a WP install + + Scenario: Change site permastructs + When I run `wp rewrite structure /blog/%year%/%monthnum%/%day%/%postname%/ --category-base=section --tag-base=topic` + And I run `wp rewrite flush` + + When I run `wp option get permalink_structure` + Then STDOUT should contain: + """ + /blog/%year%/%monthnum%/%day%/%postname%/ + """ + + When I run `wp option get category_base` + Then STDOUT should contain: + """ + section + """ + + When I run `wp option get tag_base` + Then STDOUT should contain: + """ + topic + """ + + When I run `wp rewrite list --format=csv` + Then STDOUT should be CSV containing: + | match | query | + | blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(/[0-9]+)?/?$ | index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5] | + | topic/([^/]+)/?$ | index.php?tag=$matches[1] | + | section/(.+?)/?$ | index.php?category_name=$matches[1] | From 3b850aa7903523a13b03be785b44be73c64e04ab Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 15:53:18 +0200 Subject: [PATCH 2372/4858] Support for `wp rewrite list --match=<url>` --- features/rewrite.feature | 5 +++++ php/commands/rewrite.php | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/features/rewrite.feature b/features/rewrite.feature index 1fee10929f..c6a1854a98 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -31,3 +31,8 @@ Feature: Manage WordPress rewrites | blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(/[0-9]+)?/?$ | index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5] | | topic/([^/]+)/?$ | index.php?tag=$matches[1] | | section/(.+?)/?$ | index.php?category_name=$matches[1] | + + When I run `wp rewrite list --match=/topic/apple/ --format=csv` + Then STDOUT should be CSV containing: + | match | query | + | topic/([^/]+)/?$ | index.php?tag=$matches[1] | diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index fab148c2b3..7a95a96032 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -93,6 +93,9 @@ public function structure( $args, $assoc_args ) { * Print current rewrite rules. * * ## OPTIONS + * + * [--match=<url>] + * : Show rewrite rules matching a particular URL. * * [--format=<format>] * : Output list as table, JSON or CSV. Defaults to table. @@ -110,12 +113,18 @@ public function _list( $args, $assoc_args ) { } $defaults = array( + 'match' => '', 'format' => 'table' ); $assoc_args = array_merge( $defaults, $assoc_args ); $rule_list = array(); foreach ( $rules as $match => $query ) { + + if ( ! empty( $assoc_args['match'] ) + && ! preg_match( "!^$match!", trim( $assoc_args['match'], '/' ) ) ) + continue; + $rule_list[] = compact( 'match', 'query' ); } From 2a5af5aebe10432ca841a9f81ea092670e07e6ea Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 6 Oct 2013 16:38:57 +0200 Subject: [PATCH 2373/4858] bump version to 0.13.0-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 29acc3635b..8eea440200 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if wp-cli is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.12.0' ); +define( 'WP_CLI_VERSION', '0.13.0-alpha' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 23b295a7a8ab2222264db9bc289fb207ccd4d6c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 6 Oct 2013 16:37:56 +0200 Subject: [PATCH 2374/4858] update to Requests 1.6 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4cfe2e0de1..510a10275d 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "wp-cli/php-cli-tools": "0.9.3", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", - "rmccue/requests": "dev-master#ca0f58b6523a6d11c815ae25c79cc810cea69be7" + "rmccue/requests": "~1.6" }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" From b0e7e20f92d412b51b0359373695339dd85e447b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 17:10:28 +0200 Subject: [PATCH 2375/4858] Support for displaying and filtering by the source of a given rewrite rule Mostly copied from Rewrite Rules Inspector. --- features/rewrite.feature | 12 +++++----- php/commands/rewrite.php | 49 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index c6a1854a98..a942bf5cb6 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -27,12 +27,12 @@ Feature: Manage WordPress rewrites When I run `wp rewrite list --format=csv` Then STDOUT should be CSV containing: - | match | query | - | blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(/[0-9]+)?/?$ | index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5] | - | topic/([^/]+)/?$ | index.php?tag=$matches[1] | - | section/(.+?)/?$ | index.php?category_name=$matches[1] | + | match | query | source | + | blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(/[0-9]+)?/?$ | index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5] | post | + | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | + | section/(.+?)/?$ | index.php?category_name=$matches[1] | category | When I run `wp rewrite list --match=/topic/apple/ --format=csv` Then STDOUT should be CSV containing: - | match | query | - | topic/([^/]+)/?$ | index.php?tag=$matches[1] | + | match | query | source | + | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 7a95a96032..1d46d84cd1 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -96,6 +96,9 @@ public function structure( $args, $assoc_args ) { * * [--match=<url>] * : Show rewrite rules matching a particular URL. + * + * [--source=<source>] + * : Show rewrite rules from a particular source. * * [--format=<format>] * : Output list as table, JSON or CSV. Defaults to table. @@ -106,6 +109,8 @@ public function structure( $args, $assoc_args ) { * @subcommand list */ public function _list( $args, $assoc_args ) { + global $wp_rewrite; + $rules = get_option( 'rewrite_rules' ); if ( ! $rules ) { $rules = array(); @@ -113,11 +118,41 @@ public function _list( $args, $assoc_args ) { } $defaults = array( + 'source' => '', 'match' => '', 'format' => 'table' ); $assoc_args = array_merge( $defaults, $assoc_args ); + $rewrite_rules_by_source = array(); + $rewrite_rules_by_source['post'] = $wp_rewrite->generate_rewrite_rules( $wp_rewrite->permalink_structure, EP_PERMALINK ); + $rewrite_rules_by_source['date'] = $wp_rewrite->generate_rewrite_rules( $wp_rewrite->get_date_permastruct(), EP_DATE ); + $rewrite_rules_by_source['root'] = $wp_rewrite->generate_rewrite_rules( $wp_rewrite->root . '/', EP_ROOT ); + $rewrite_rules_by_source['comments'] = $wp_rewrite->generate_rewrite_rules( $wp_rewrite->root . $wp_rewrite->comments_base, EP_COMMENTS, true, true, true, false ); + $rewrite_rules_by_source['search'] = $wp_rewrite->generate_rewrite_rules( $wp_rewrite->get_search_permastruct(), EP_SEARCH ); + $rewrite_rules_by_source['author'] = $wp_rewrite->generate_rewrite_rules($wp_rewrite->get_author_permastruct(), EP_AUTHORS ); + $rewrite_rules_by_source['page'] = $wp_rewrite->page_rewrite_rules(); + + // Extra permastructs including tags, categories, etc. + foreach ( $wp_rewrite->extra_permastructs as $permastructname => $permastruct ) { + if ( is_array( $permastruct ) ) { + // Pre 3.4 compat + if ( count( $permastruct ) == 2 ) + $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct[0], $permastruct[1] ); + else + $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct['struct'], $permastruct['ep_mask'], $permastruct['paged'], $permastruct['feed'], $permastruct['forcomments'], $permastruct['walk_dirs'], $permastruct['endpoints'] ); + } else { + $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct, EP_NONE ); + } + } + + // Apply the filters used in core just in case + foreach( $rewrite_rules_by_source as $source => $source_rules ) { + $rewrite_rules_by_source[$source] = apply_filters( $source . '_rewrite_rules', $source_rules ); + if ( 'post_tag' == $source ) + $rewrite_rules_by_source[$source] = apply_filters( 'tag_rewrite_rules', $source_rules ); + } + $rule_list = array(); foreach ( $rules as $match => $query ) { @@ -125,10 +160,20 @@ public function _list( $args, $assoc_args ) { && ! preg_match( "!^$match!", trim( $assoc_args['match'], '/' ) ) ) continue; - $rule_list[] = compact( 'match', 'query' ); + $source = 'other'; + foreach( $rewrite_rules_by_source as $rules_source => $source_rules ) { + if ( array_key_exists( $match, $source_rules ) ) { + $source = $rules_source; + } + } + + if ( ! empty( $assoc_args['source'] ) && $source != $assoc_args['source'] ) + continue; + + $rule_list[] = compact( 'match', 'query', 'source' ); } - WP_CLI\Utils\format_items( $assoc_args['format'], $rule_list, array('match', 'query') ); + WP_CLI\Utils\format_items( $assoc_args['format'], $rule_list, array('match', 'query', 'source' ) ); } /** From 8636260d4c038d5d992fd0b68f3724ae36f06bfa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 17:20:16 +0200 Subject: [PATCH 2376/4858] Special treatment for `__` arguments (e.g. post__in, post__not_in) --- php/commands/post.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/post.php b/php/commands/post.php index b8c670fe84..a07b934edf 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -236,6 +236,11 @@ public function _list( $_, $assoc_args ) { ); $query_args = array_merge( $defaults, $assoc_args ); + foreach( $query_args as $key => $query_arg ) { + if ( false !== strpos( $key, '__' ) ) + $query_args[$key] = explode( ',', $query_arg ); + } + if ( 'ids' == $formatter->format ) $query_args['fields'] = 'ids'; From bf6cefb7f848d1430d1a51850d5ba8f62ab4bb8c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 17:23:21 +0200 Subject: [PATCH 2377/4858] Test `post__in` scenario --- features/post.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/post.feature b/features/post.feature index c530ffb96b..b97f1c2849 100644 --- a/features/post.feature +++ b/features/post.feature @@ -97,6 +97,7 @@ Feature: Manage WordPress posts Scenario: Creating/listing posts When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` Then STDOUT should be a number + And save STDOUT as {POST_ID} When I run `wp post create --post_title='Draft post' --post_content='Draft post content' --post_status='draft' --porcelain` Then STDOUT should be a number @@ -107,6 +108,11 @@ Feature: Manage WordPress posts | Publish post | publish-post | publish | | Draft post | | draft | + When I run `wp post list --post_type='post' --post__in={POST_ID} --fields=post_title,post_name,post_status --format=csv` + Then STDOUT should be CSV containing: + | post_title | post_name | post_status | + | Publish post | publish-post | publish | + When I run `wp post list --post_type='page' --field=title` Then STDOUT should be: """ From e1b3cb926272b133539850bd3b106a9fc9ae9d63 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 17:30:28 +0200 Subject: [PATCH 2378/4858] Drop pre-3.4 compat See https://github.com/wp-cli/wp-cli/pull/813#discussion_r6786977 --- php/commands/rewrite.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 1d46d84cd1..0f85ddc123 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -136,11 +136,7 @@ public function _list( $args, $assoc_args ) { // Extra permastructs including tags, categories, etc. foreach ( $wp_rewrite->extra_permastructs as $permastructname => $permastruct ) { if ( is_array( $permastruct ) ) { - // Pre 3.4 compat - if ( count( $permastruct ) == 2 ) - $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct[0], $permastruct[1] ); - else - $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct['struct'], $permastruct['ep_mask'], $permastruct['paged'], $permastruct['feed'], $permastruct['forcomments'], $permastruct['walk_dirs'], $permastruct['endpoints'] ); + $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct['struct'], $permastruct['ep_mask'], $permastruct['paged'], $permastruct['feed'], $permastruct['forcomments'], $permastruct['walk_dirs'], $permastruct['endpoints'] ); } else { $rewrite_rules_by_source[$permastructname] = $wp_rewrite->generate_rewrite_rules( $permastruct, EP_NONE ); } From 861b1df97b94ab97ee1b83ad748c02fae48234a1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 6 Oct 2013 17:33:18 +0200 Subject: [PATCH 2379/4858] A more precise test See https://github.com/wp-cli/wp-cli/pull/777#discussion_r6787013 --- features/post.feature | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/features/post.feature b/features/post.feature index b97f1c2849..d4231c87c3 100644 --- a/features/post.feature +++ b/features/post.feature @@ -108,10 +108,11 @@ Feature: Manage WordPress posts | Publish post | publish-post | publish | | Draft post | | draft | - When I run `wp post list --post_type='post' --post__in={POST_ID} --fields=post_title,post_name,post_status --format=csv` - Then STDOUT should be CSV containing: - | post_title | post_name | post_status | - | Publish post | publish-post | publish | + When I run `wp post list --post__in={POST_ID} --format=count` + Then STDOUT should be: + """ + 1 + """ When I run `wp post list --post_type='page' --field=title` Then STDOUT should be: From 4a04bdacc0e4609a796a99a37fed07bb70004eaf Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Sun, 6 Oct 2013 15:29:59 -0400 Subject: [PATCH 2380/4858] Allow db export to accept all mysqldump args --- php/commands/db.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 2068248fa1..f9c971b065 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -111,20 +111,18 @@ function query( $args ) { } /** - * Exports the database using mysqldump. + * Exports the database using mysqldump. Accepts all of mysqldump's arguments. * * @alias dump * - * @synopsis [<file>] + * @synopsis [<file>] [--extended-insert=FALSE] [--comments] [--replace] ... */ function export( $args, $assoc_args ) { - $result_file = $this->get_file_name( $args ); + $assoc_args['result-file'] = $this->get_file_name( $args ); - self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), array( - 'result-file' => $result_file - ) ); + self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), $assoc_args ); - WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); + WP_CLI::success( sprintf( 'Exported to %s', $assoc_args['result-file'] ) ); } /** From c523af4f36ff6ecf100fe088cd4ab07479687df5 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Sun, 6 Oct 2013 16:15:03 -0400 Subject: [PATCH 2381/4858] Add assoc arg for arbitrary mysqldump args Props @danielbachhuber --- php/commands/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index f9c971b065..06d2013fa6 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -115,7 +115,7 @@ function query( $args ) { * * @alias dump * - * @synopsis [<file>] [--extended-insert=FALSE] [--comments] [--replace] ... + * @synopsis [<file>] [--extended-insert] [--skip-comments] [--<field>=<value>] */ function export( $args, $assoc_args ) { $assoc_args['result-file'] = $this->get_file_name( $args ); From bfb37aa2ed5e74e773b568cf237b872839c75279 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 7 Oct 2013 14:29:32 +0200 Subject: [PATCH 2382/4858] fix delete logic after plugin refactoring see c4f01fa50a40ab6624c84aeb9d1d9746f45f4118 props francescolaffi --- php/commands/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 54fd8dfbb4..b0c8160885 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -596,7 +596,7 @@ private function get_name( $file ) { private function _delete( $plugin ) { $plugin_dir = dirname( $plugin->file ); if ( '.' == $plugin_dir ) - $plugin_dir = $file; + $plugin_dir = $plugin->file; $command = 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ); From daeea3d199bba725d57b5ab84d8dcd0db5408ea8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 7 Oct 2013 14:53:18 +0200 Subject: [PATCH 2383/4858] first pass at 'wp super-admin' commmand --- php/commands/super-admin.php | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 php/commands/super-admin.php diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php new file mode 100644 index 0000000000..6d973a28d0 --- /dev/null +++ b/php/commands/super-admin.php @@ -0,0 +1,59 @@ +<?php + +class SuperAdminCommand extends WP_CLI_Command { + + /** + * Show a list of users with super-admin capabilities. + * + * @subcommand list + */ + public function _list( $_, $assoc_args ) { + $super_admins = self::get_admins(); + foreach ( $super_admins as $user_login ) { + WP_CLI::line( $user_login ); + } + } + + /** + * Grant super-admin privileges to one or more users. + * + * <user>... + * : One or more user logins. + */ + public function add( $args, $_ ) { + $super_admins = self::get_admins(); + + foreach ( $args as $user_login ) { + $user = get_user_by( 'login', $user_login ); + if ( !$user ) { + WP_CLI::warning( "Couldn't find {$user_login} user." ); + } else { + $super_admins[] = $user->user_login; + } + } + + update_site_option( 'site_admins' , $super_admins ); + WP_CLI::success( 'Granted super-admin capabilities.' ); + } + + /** + * Revoke super-admin privileges to one or more users. + * + * <user>... + * : One or more user logins. + */ + public function remove( $args, $_ ) { + $super_admins = self::get_admins(); + $super_admins = array_diff( $super_admins, $args ); + update_site_option( 'site_admins' , $super_admins ); + WP_CLI::success( 'Revoked super-admin capabilities.' ); + } + + private static function get_admins() { + // We don't use get_super_admins() because we don't want to mess with the global + return get_site_option( 'site_admins', array('admin') ); + } +} + +WP_CLI::add_command( 'super-admin', 'SuperAdminCommand' ); + From e8f4778b067e7f986f45065f63e3d3363f64ef7c Mon Sep 17 00:00:00 2001 From: Japh <japhie@gmail.com> Date: Mon, 7 Oct 2013 15:55:50 +0200 Subject: [PATCH 2384/4858] Implements wp term generate, Fixes #389. --- php/commands/term.php | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index bcf58ac44d..07d8225120 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -252,6 +252,102 @@ public function delete( $args ) { WP_CLI::error( "Term doesn't exist." ); } + /** + * Generate some terms. + * + * ## OPTIONS + * + * [--count=<number>] + * : How many terms to generate. Default: 100 + * + * [--taxonomy=<taxonomy>] + * : The taxonomy of the generated terms. Default: 'category' + * + * [--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; + + $defaults = array( + 'count' => 100, + 'max_depth' => 1, + 'taxonomy' => 'category', + ); + + extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); + + if ( !taxonomy_exists( $taxonomy ) ) { + WP_CLI::error( sprintf( "'%s' is not a registered taxonomy.", $taxonomy ) ); + } + + // Get the total number of terms + $total = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->terms" ); + + $label = get_taxonomy( $taxonomy )->labels->singular_name; + $slug = sanitize_title_with_dashes( $label ); + + $hierarchical = get_taxonomy( $taxonomy )->hierarchical; + + $limit = $count + $total; + + $notify = \WP_CLI\Utils\make_progress_bar( 'Generating terms', $count ); + + $current_depth = 1; + $current_parent = 0; + + $args = array( + 'orderby' => 'id', + 'hierarchical' => $hierarchical, + ); + + for ( $i = $total; $i < $limit; $i++ ) { + + if ( $hierarchical ) { + + if ( $this->maybe_make_child() && $current_depth < $max_depth ) { + + $current_parent = $term['term_id']; + $current_depth++; + + } else if ( $this->maybe_reset_depth() ) { + + $current_depth = 1; + $current_parent = 0; + + } + + } + + $args = array( + 'parent' => $current_parent, + 'slug' => $slug . "-$i", + ); + + $term = wp_insert_term( "$label $i", $taxonomy, $args ); + + $notify->tick(); + } + + delete_option( $taxonomy . '_children' ); + + $notify->finish(); + } + + private function maybe_make_child() { + // 50% chance of making child term + return ( mt_rand(1, 2) == 1 ); + } + + private function maybe_reset_depth() { + // 10% chance of reseting to root depth + return ( mt_rand(1, 10) == 7 ); + } + } WP_CLI::add_command( 'term', 'Term_Command' ); From 8a267589b6e2ddb216a6f4cdb730c056a27dc2c0 Mon Sep 17 00:00:00 2001 From: Julio Potier <juliobosk@gmail.com> Date: Mon, 7 Oct 2013 16:24:02 +0200 Subject: [PATCH 2385/4858] Fix notice + start manage windows OS --- php/commands/post.php | 3 ++- php/commands/scaffold.php | 2 +- php/utils.php | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index a07b934edf..8a03d3057c 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -123,7 +123,8 @@ public function edit( $args, $_ ) { protected function _edit( $content, $title ) { $content = apply_filters( 'the_editor_content', $content ); - $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title ); + $os = strpos( $_SERVER['OS'], 'indows' )===false ? 'linux' : 'windows'; + $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title, $os ); return ( is_string( $output ) ) ? apply_filters( 'content_save_pre', $output ) : $output; } diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c69d1a342c..02684a1343 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -202,7 +202,7 @@ function _s( $args, $assoc_args ) { $tmpfname = wp_tempnam($url); $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); - if ( $response['response']['code'] == 200 ) + if ( !is_wp_error( $response ) && $response['response']['code'] == 200 ) WP_CLI::success( "Created theme '".$data['theme_name']."'." ); unzip_file( $tmpfname, $theme_path ); diff --git a/php/utils.php b/php/utils.php index 020b8aef7f..c6cf0ee55a 100644 --- a/php/utils.php +++ b/php/utils.php @@ -254,16 +254,20 @@ function pick_fields( $item, $fields ) { * @return str|bool Edited text, if file is saved from editor * False, if no change to file */ -function launch_editor_for_input( $input, $title = 'WP-CLI' ) { +function launch_editor_for_input( $input, $title = 'WP-CLI', $os='linux' ) { $tmpfile = wp_tempnam( $title ); if ( !$tmpfile ) \WP_CLI::error( 'Error creating temporary file.' ); + $output = ''; file_put_contents( $tmpfile, $input ); + if( $os==='linux' ) \WP_CLI::launch( "\${EDITOR:-vi} '$tmpfile'" ); + else + exec("notepad $tmpfile" ); $output = file_get_contents( $tmpfile ); From 5d0bcc0a0c48605b9f8d9f7b7a52769ec3182a15 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 7 Oct 2013 17:17:47 +0200 Subject: [PATCH 2386/4858] move CI scripts out of the bin/ directory the idea is that the CI setup might contain other files besides executables --- .travis.yml | 6 +++--- {bin/ci => ci}/deploy.sh | 0 {bin/ci => ci}/prepare.sh | 0 {bin/ci => ci}/test.sh | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename {bin/ci => ci}/deploy.sh (100%) rename {bin/ci => ci}/prepare.sh (100%) rename {bin/ci => ci}/test.sh (100%) diff --git a/.travis.yml b/.travis.yml index f683d3af99..e36beae361 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,11 +40,11 @@ matrix: - php: 5.5 env: WP_VERSION=3.4.2 DEPLOY_BRANCH=master -before_script: ./bin/ci/prepare.sh +before_script: ./ci/prepare.sh -script: ./bin/ci/test.sh +script: ./ci/test.sh -after_success: ./bin/ci/deploy.sh +after_success: ./ci/deploy.sh notifications: email: diff --git a/bin/ci/deploy.sh b/ci/deploy.sh similarity index 100% rename from bin/ci/deploy.sh rename to ci/deploy.sh diff --git a/bin/ci/prepare.sh b/ci/prepare.sh similarity index 100% rename from bin/ci/prepare.sh rename to ci/prepare.sh diff --git a/bin/ci/test.sh b/ci/test.sh similarity index 100% rename from bin/ci/test.sh rename to ci/test.sh From 09d6f366e29bfd3aafc117b8a4c86df584e57edf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 7 Oct 2013 15:01:11 +0200 Subject: [PATCH 2387/4858] move dev dependencies after regular dependencies --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 510a10275d..96170b90b4 100644 --- a/composer.json +++ b/composer.json @@ -14,14 +14,14 @@ "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6" }, + "require-dev": { + "symfony/finder": "~2.3" + }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" }, "autoload": { "psr-0": { "WP_CLI": "php" }, "files": [ "php/Spyc.php" ] - }, - "require-dev": { - "symfony/finder": "~2.3" } } From af36f237a3422d9375587583b3e534793c395cce Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 7 Oct 2013 16:58:05 +0200 Subject: [PATCH 2388/4858] travis: run CodeSniffer to detect undefined variable usage --- ci/prepare-codesniffer.sh | 6 ++++++ ci/prepare.sh | 3 +++ ci/ruleset.xml | 8 ++++++++ ci/test.sh | 3 +++ 4 files changed, 20 insertions(+) create mode 100755 ci/prepare-codesniffer.sh create mode 100644 ci/ruleset.xml diff --git a/ci/prepare-codesniffer.sh b/ci/prepare-codesniffer.sh new file mode 100755 index 0000000000..630b818e34 --- /dev/null +++ b/ci/prepare-codesniffer.sh @@ -0,0 +1,6 @@ +#!/bin/bash +composer create-project squizlabs/php_codesniffer:1.4.7 codesniffer + +git clone https://github.com/illusori/PHP_Codesniffer-VariableAnalysis.git +cd PHP_Codesniffer-VariableAnalysis +./install.sh -d ../codesniffer/CodeSniffer diff --git a/ci/prepare.sh b/ci/prepare.sh index efb241cedd..6d18180a8c 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -15,6 +15,9 @@ chmod +x $WP_CLI_BIN_DIR/wp # Travis CI doesn't come with Behat pre-installed curl http://behat.org/downloads/behat.phar > behat.phar +# Install CodeSniffer things +./ci/prepare-codesniffer.sh + ./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ mysql -e 'CREATE DATABASE wp_cli_test;' -uroot diff --git a/ci/ruleset.xml b/ci/ruleset.xml new file mode 100644 index 0000000000..748ba7a8c3 --- /dev/null +++ b/ci/ruleset.xml @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<ruleset name="WP-CLI"> + <description>WP-CLI coding standards.</description> + + <rule ref="Generic.CodeAnalysis.VariableAnalysis"> + <property name="allowUnusedFunctionParameters" value="1"/> + </rule> +</ruleset> diff --git a/ci/test.sh b/ci/test.sh index 3a94100a7c..c213a42318 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -7,3 +7,6 @@ phpunit # Run the functional tests php behat.phar --format progress + +# Run CodeSniffer +./codesniffer/scripts/phpcs --standard=./ci/ php/ From ccf5954f390fd2671dce2d537bbea18a5953f424 Mon Sep 17 00:00:00 2001 From: Japh <japhie@gmail.com> Date: Wed, 9 Oct 2013 09:29:39 +0200 Subject: [PATCH 2389/4858] Added Behat tests for term generate command --- features/term.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/term.feature b/features/term.feature index 375bc1d78f..69e05f3d00 100644 --- a/features/term.feature +++ b/features/term.feature @@ -53,3 +53,11 @@ Feature: Manage WordPress terms When I try the previous command again Then STDERR should not be empty + + Scenario: Generating terms + When I run `wp term generate --count=10` + And I run `wp term list category --format=count` + Then STDOUT should be: + """ + 11 + """ From 647047bec3b295f081da0c1cf92c95e22c65525b Mon Sep 17 00:00:00 2001 From: Matthias Kadenbach <matthias.kadenbach@gmail.com> Date: Wed, 9 Oct 2013 16:59:18 +0200 Subject: [PATCH 2390/4858] fix for issue #825 --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 020b8aef7f..d298b1a22b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -126,7 +126,7 @@ function find_file_upward( $files, $dir = null, $stop_check = null ) { function is_path_absolute( $path ) { // Windows - if ( ':' === $path[1] ) + if ( isset($path[1]) && ':' === $path[1] ) return true; return $path[0] === '/'; From 6c6ab9d42e2e0e115aa6bb363a19bf00a650b46a Mon Sep 17 00:00:00 2001 From: Japh <japhie@gmail.com> Date: Thu, 10 Oct 2013 09:50:00 +0200 Subject: [PATCH 2391/4858] Taxonomy no longer has a default value for term generate --- php/commands/term.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index e1b49d2c5d..3e594978be 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -237,12 +237,12 @@ public function delete( $args ) { * * ## OPTIONS * + * <taxonomy> + * : The taxonomy for the generated terms. + * * [--count=<number>] * : How many terms to generate. Default: 100 * - * [--taxonomy=<taxonomy>] - * : The taxonomy of the generated terms. Default: 'category' - * * [--max_depth=<number>] * : Generate child terms down to a certain depth. Default: 1 * @@ -253,10 +253,11 @@ public function delete( $args ) { public function generate( $args, $assoc_args ) { global $wpdb; + list ( $taxonomy ) = $args; + $defaults = array( 'count' => 100, 'max_depth' => 1, - 'taxonomy' => 'category', ); extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); From 0d90bffde8a736d5cb225808b8a658264bf4b747 Mon Sep 17 00:00:00 2001 From: Japh <japhie@gmail.com> Date: Thu, 10 Oct 2013 09:54:22 +0200 Subject: [PATCH 2392/4858] Term generate no longer makes redundant DB query for existing terms --- php/commands/term.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 3e594978be..efa52c2171 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -266,16 +266,11 @@ public function generate( $args, $assoc_args ) { WP_CLI::error( sprintf( "'%s' is not a registered taxonomy.", $taxonomy ) ); } - // Get the total number of terms - $total = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->terms" ); - $label = get_taxonomy( $taxonomy )->labels->singular_name; $slug = sanitize_title_with_dashes( $label ); $hierarchical = get_taxonomy( $taxonomy )->hierarchical; - $limit = $count + $total; - $notify = \WP_CLI\Utils\make_progress_bar( 'Generating terms', $count ); $current_depth = 1; @@ -286,7 +281,7 @@ public function generate( $args, $assoc_args ) { 'hierarchical' => $hierarchical, ); - for ( $i = $total; $i < $limit; $i++ ) { + for ( $i = 0; $i < $count; $i++ ) { if ( $hierarchical ) { From c9d6bfd12dc10922faaab598a13fa25dfca682fb Mon Sep 17 00:00:00 2001 From: Japh <japhie@gmail.com> Date: Thu, 10 Oct 2013 10:01:24 +0200 Subject: [PATCH 2393/4858] Updated term generate test with new required parameter --- features/term.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/term.feature b/features/term.feature index 69e05f3d00..c2b6e8ef29 100644 --- a/features/term.feature +++ b/features/term.feature @@ -55,7 +55,7 @@ Feature: Manage WordPress terms Then STDERR should not be empty Scenario: Generating terms - When I run `wp term generate --count=10` + When I run `wp term generate category --count=10` And I run `wp term list category --format=count` Then STDOUT should be: """ From 3797134c9c4d646229cbb021cf45fe7ad7c41344 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 10 Oct 2013 21:01:40 +0300 Subject: [PATCH 2394/4858] add <properties> tag to ruleset --- ci/ruleset.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/ruleset.xml b/ci/ruleset.xml index 748ba7a8c3..e8d39efb7a 100644 --- a/ci/ruleset.xml +++ b/ci/ruleset.xml @@ -3,6 +3,8 @@ <description>WP-CLI coding standards.</description> <rule ref="Generic.CodeAnalysis.VariableAnalysis"> - <property name="allowUnusedFunctionParameters" value="1"/> + <properties> + <property name="allowUnusedFunctionParameters" value="1"/> + </properties> </rule> </ruleset> From 8c2f9726a0bcdfbb74508fc450cf7c1325525e68 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 8 Oct 2013 23:51:35 +0200 Subject: [PATCH 2395/4858] combine plugin/theme search code besides reducing duplication, it also fixes an undefined $fields variable notice --- php/WP_CLI/CommandWithUpgrade.php | 33 ++++++++++++++++++++++--------- php/commands/plugin.php | 24 +++++++--------------- php/commands/theme.php | 23 ++++++++------------- 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e491dfdeaa..9d23c5a5c6 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -310,17 +310,34 @@ private function get_color( $status ) { * Search wordpress.org repo. * * @param object $api Data from WP plugin/theme API - * @param array $fields Data fields to display in table. * @param array $assoc_args Data passed in from command. - * @param string $data_type Plugin or Theme api endpoint */ - protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) { + protected function _search( $args, $assoc_args ) { + $term = $args[0]; + + $defaults = array( + 'per-page' => 10, + 'fields' => array( 'name', 'slug', 'rating' ) + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $formatter = $this->get_formatter( $assoc_args ); + + $api_args = array( + 'per_page' => (int) $assoc_args['per-page'], + 'search' => $term, + ); + + if ( 'plugin' == $this->item_type ) { + $api = plugins_api( 'query_plugins', $api_args ); + } else { + $api = themes_api( 'query_themes', $api_args ); + } + if ( is_wp_error( $api ) ) \WP_CLI::error( $api->get_error_message() . __( ' Try again' ) ); - // Sanitize to 1 of 2 types - $data_type = ( 'plugin' === $data_type ) ? 'plugin' : 'theme'; - $plural = $data_type . 's'; + $plural = $this->item_type . 's'; if ( ! isset( $api->$plural ) ) \WP_CLI::error( __( 'API error. Try Again.' ) ); @@ -330,9 +347,7 @@ protected function _search( $api, $fields, $assoc_args, $data_type = 'plugin' ) $count = isset( $api->info['results'] ) ? $api->info['results'] : 'unknown'; \WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) ); - $format = isset( $assoc_args['format'] ) ? $assoc_args['format'] : 'table'; - - \WP_CLI\Utils\format_items( $format, $items, $assoc_args['fields'] ); + $formatter->display_items( $items ); } protected function get_formatter( &$assoc_args ) { diff --git a/php/commands/plugin.php b/php/commands/plugin.php index b0c8160885..535a3f4699 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -52,8 +52,8 @@ function status( $args ) { * [--per-page=<per-page>] * : Optional number of results to display. Defaults to 10. * - * [--format=<format>] - * : Output list as table, CSV or JSON. Defaults to table. + * [--field=<field>] + * : Prints the value of a single field for each plugin. * * [--fields=<fields>] * : Ask for specific fields from the API. Defaults to name,slug,author_profile,rating. Acceptable values: @@ -73,27 +73,17 @@ function status( $args ) { * **description**: Plugin's Description * **short_description**: Plugin's Short Description * + * [--format=<format>] + * : Output list as table, CSV or JSON. Defaults to table. + * * ## EXAMPLES * * wp plugin search dsgnwrks --per-page=20 --format=json * * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings */ - public function search( $args, $assoc_args = array() ) { - $term = $args[0]; - - $defaults = array( - 'per-page' => 10, - 'fields' => array( 'name', 'slug', 'rating' ) - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - - $api = plugins_api( 'query_plugins', array( - 'per_page' => (int) $assoc_args['per-page'], - 'search' => $term, - ) ); - - parent::_search( $api, $fields, $assoc_args, 'plugin' ); + public function search( $args, $assoc_args ) { + parent::_search( $args, $assoc_args ); } protected function status_single( $args ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 1d9ac2dd42..7e093a85f6 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -45,6 +45,9 @@ function status( $args ) { * [--per-page=<per-page>] * : Optional number of results to display. Defaults to 10. * + * [--field=<field>] + * : Prints the value of a single field for each plugin. + * * [--fields=<fields>] * : Ask for specific fields from the API. Defaults to name,slug,author,rating. Acceptable values: * @@ -59,27 +62,17 @@ function status( $args ) { * **homepage**: Theme Author's Homepage * **description**: Theme Description * + * [--format=<format>] + * : Output list as table, CSV or JSON. Defaults to table. + * * ## EXAMPLES * * wp theme search automattic --per-page=20 * * wp theme search automattic --fields=name,version,slug,rating,num_ratings,description */ - public function search( $args, $assoc_args = array() ) { - $term = $args[0]; - - $defaults = array( - 'per-page' => 10, - 'fields' => array( 'name', 'slug', 'author', 'rating' ) - ); - $assoc_args = array_merge( $defaults, $assoc_args ); - - $api = themes_api( 'query_themes', array( - 'per_page' => (int) $assoc_args['per-page'], - 'search' => $term, - ) ); - - parent::_search( $api, $fields, $assoc_args, 'theme' ); + public function search( $args, $assoc_args ) { + parent::_search( $args, $assoc_args ); } protected function status_single( $args ) { From cb97cff413c77af7a32622dc70f0ca7d258ccb67 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Tue, 30 Jul 2013 10:14:17 +0200 Subject: [PATCH 2396/4858] packages cache by caching wp http api --- composer.json | 3 +- php/WP_CLI/CommandWithUpgrade.php | 18 +- php/WP_CLI/FileCache.php | 329 ++++++++++++++++++++++++++++++ php/WP_CLI/WpHttpCacheManager.php | 124 +++++++++++ php/class-wp-cli.php | 37 ++++ php/commands/plugin.php | 9 +- php/commands/theme.php | 8 +- 7 files changed, 524 insertions(+), 4 deletions(-) create mode 100644 php/WP_CLI/FileCache.php create mode 100644 php/WP_CLI/WpHttpCacheManager.php diff --git a/composer.json b/composer.json index 96170b90b4..3531bcc1cd 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "wp-cli/php-cli-tools": "0.9.3", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", - "rmccue/requests": "~1.6" + "rmccue/requests": "~1.6", + "symfony/finder": "~2.3" }, "require-dev": { "symfony/finder": "~2.3" diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 9d23c5a5c6..c1054e211b 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -208,7 +208,7 @@ protected function update_many( $args, $assoc_args ) { \WP_CLI::line( "Available {$this->item_type} updates:" ); \WP_CLI\Utils\format_items( 'table', $items_to_update, - array( 'name', 'status', 'version' ) ); + array( 'name', 'status', 'version', 'update_version' ) ); return; } @@ -217,6 +217,10 @@ protected function update_many( $args, $assoc_args ) { // Only attempt to update if there is something to update if ( !empty( $items_to_update ) ) { + $cache_manager = \WP_CLI::get_http_cache_manager(); + foreach ($items_to_update as $item) { + $cache_manager->whitelist_package($item['update_package'], $this->item_type, $item['name'], $item['update_version']); + } $upgrader = $this->get_upgrader( $assoc_args ); $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); } @@ -276,6 +280,18 @@ protected function has_update( $slug ) { return isset( $update_list->response[ $slug ] ); } + /** + * Get the available update info + * + * @param string $slug The plugin/theme slug + * + * @return array|null + */ + protected function get_update_info( $slug ) { + $update_list = get_site_transient( $this->upgrade_transient ); + return isset( $update_list->response[ $slug ] ) ? (array) $update_list->response[ $slug ] : null; + } + private $map = array( 'short' => array( 'inactive' => 'I', diff --git a/php/WP_CLI/FileCache.php b/php/WP_CLI/FileCache.php new file mode 100644 index 0000000000..65ee7487e3 --- /dev/null +++ b/php/WP_CLI/FileCache.php @@ -0,0 +1,329 @@ +<?php + +/* + * This file is heavily inspired and use code from Composer(getcomposer.org), + * in particular Composer/Cache and Composer/Util/FileSystem from 1.0.0-alpha7 + * + * The original code and this file are both released under MIT license. + * + * The copyright holders of the original code are: + * (c) Nils Adermann <naderman@naderman.de> + * Jordi Boggiano <j.boggiano@seld.be> + */ + +namespace WP_CLI; + +use Symfony\Component\Finder\Finder; + +/** + * Reads/writes to a filesystem cache + */ +class FileCache { + + /** + * @var string cache path + */ + protected $root; + /** + * @var bool + */ + protected $enabled = true; + /** + * @var int files time to live + */ + protected $ttl; + /** + * @var int max total size + */ + protected $maxSize; + /** + * @var string key allowed chars (regex class) + */ + protected $whitelist; + + /** + * @param string $cacheDir location of the cache + * @param int $ttl cache files default time to live (expiration) + * @param int $maxSize max total cache size + * @param string $whitelist List of characters that are allowed in path names (used in a regex character class) + */ + public function __construct( $cacheDir, $ttl, $maxSize, $whitelist = 'a-z0-9.' ) { + $this->root = rtrim( $cacheDir, '/\\' ) . '/'; + $this->ttl = (int) $ttl; + $this->maxSize = (int) $maxSize; + $this->whitelist = $whitelist; + + if ( !$this->ensure_dir_exists( $this->root ) ) { + $this->enabled = false; + } + + } + + /** + * Cache is enabled + * + * @return bool + */ + public function is_enabled() { + return $this->enabled; + } + + /** + * Cache root + * + * @return string + */ + public function get_root() { + return $this->root; + } + + + /** + * Check if a file is in cache and return its filename + * + * @param string $key cache key + * @param int $ttl time to live + * @return bool|string filename or false + */ + public function has( $key, $ttl = null ) { + if ( !$this->enabled ) { + return false; + } + + $filename = $this->filename( $key ); + + if ( !file_exists( $filename ) ) { + return false; + } + + // use ttl param or global ttl + if ( $ttl === null ) { + $ttl = $this->ttl; + } elseif ( $this->ttl > 0 ) { + $ttl = min( (int) $ttl, $this->ttl ); + } else { + $ttl = (int) $ttl; + } + + // + if ( $ttl > 0 && filemtime( $filename ) + $ttl < time() ) { + if ( $this->ttl > 0 && $ttl >= $this->ttl ) { + unlink( $filename ); + } + return false; + } + + return $filename; + } + + /** + * Write to cache file + * + * @param string $key cache key + * @param string $contents file contents + * @return bool + */ + public function write( $key, $contents ) { + $filename = $this->prepare_write( $key ); + + if ( $filename ) { + return file_put_contents( $filename, $contents ) && touch( $filename ); + } else { + return false; + } + } + + /** + * Read from cache file + * + * @param string $key cache key + * @param int $ttl time to live + * @return bool|string file contents or false + */ + public function read( $key, $ttl = null ) { + $filename = $this->has( $key, $ttl ); + + if ( $filename ) { + return file_get_contents( $filename ); + } else { + return false; + } + } + + /** + * Copy a file into the cache + * + * @param string $key cache key + * @param string $source source filename + * @return bool + */ + public function import( $key, $source ) { + $filename = $this->prepare_write( $key ); + + if ( $filename ) { + return copy( $source, $filename ) && touch( $filename ); + } else { + return false; + } + } + + /** + * Copy a file out of the cache + * + * @param string $key cache key + * @param string $target target filename + * @param int $ttl time to live + * @return bool + */ + public function export( $key, $target, $ttl = null ) { + $filename = $this->has( $key, $ttl ); + + if ( $filename ) { + return copy( $filename, $target ); + } else { + return false; + } + } + + /** + * Remove file from cache + * + * @param string $key cache key + * @return bool + */ + public function remove( $key ) { + if ( !$this->enabled ) { + return false; + } + + $filename = $this->filename( $key ); + + if ( file_exists( $filename ) ) { + return unlink( $filename ); + } else { + return false; + } + } + + /** + * Clean cache based on time to live and max size + * + * @return bool + */ + public function clean() { + if ( !$this->enabled ) { + return false; + } + + $ttl = $this->ttl; + $maxSize = $this->maxSize; + + // unlink expired files + if ( $ttl > 0 ) { + $expire = new \DateTime(); + $expire->modify( '-' . $ttl . ' seconds' ); + + $finder = $this->get_finder()->date( 'until ' . $expire->format( 'Y-m-d H:i:s' ) ); + foreach ( $finder as $file ) { + unlink( $file->getRealPath() ); + } + } + + // unlink older files if max cache size is exceeded + if ( $maxSize > 0 ) { + $files = array_reverse( iterator_to_array( $this->get_finder()->sortByAccessedTime()->getIterator() ) ); + $total = 0; + + foreach ( $files as $file ) { + if ( $total + $file->getSize() <= $maxSize ) { + $total += $file->getSize(); + } else { + unlink( $file->getRealPath() ); + } + } + } + + return true; + } + + /** + * Ensure directory exists + * + * @param string $dir directory + * @return bool + */ + protected function ensure_dir_exists( $dir ) { + if ( !is_dir( $dir ) ) { + if ( file_exists( $dir ) ) { + // exists and not a dir + return false; + } + if ( !@mkdir( $dir, 0777, true ) ) { + return false; + } + } + + return true; + } + + /** + * Prepare cache write + * + * @param string $key cache key + * @return bool|string filename or false + */ + protected function prepare_write( $key ) { + if ( !$this->enabled ) { + return false; + } + + $filename = $this->filename( $key ); + + if ( !$this->ensure_dir_exists( dirname( $filename ) ) ) { + return false; + } + + return $filename; + } + + /** + * Validate cache key + * + * @param string $key cache key + * @return string relative filename + */ + protected function validate_key( $key ) { + $url_parts = parse_url( $key ); + if ( $url_parts['scheme'] ) { // is url + $parts = array('misc'); + $parts[] = $url_parts['host'] . ( $url_parts['port'] ? '-' . $url_parts['port'] : '' ); + $parts[] = $url_parts['path'] . ( $url_parts['query'] ? '-' . $url_parts['query'] : '' ); + } else { + $key = str_replace( '\\', '/', $key ); + $parts = explode( '/', ltrim( $key ) ); + } + + $parts = preg_replace( "#[^{$this->whitelist}]#i", '-', $parts ); + + return implode( '/', $parts ); + } + + /** + * Filename from key + * + * @param string $key + * @return string filename + */ + protected function filename( $key ){ + return $this->root . $this->validate_key( $key ); + } + + /** + * Get a Finder that iterates in cache root only the files + * + * @return Finder + */ + protected function get_finder() { + return Finder::create()->in( $this->root )->files(); + } +} diff --git a/php/WP_CLI/WpHttpCacheManager.php b/php/WP_CLI/WpHttpCacheManager.php new file mode 100644 index 0000000000..1fe5a89611 --- /dev/null +++ b/php/WP_CLI/WpHttpCacheManager.php @@ -0,0 +1,124 @@ +<?php + + +namespace WP_CLI; +use WP_CLI; + + +/** + * Manage caching with whitelisting + * + * @package WP_CLI + */ +class WpHttpCacheManager { + + /** + * @var array map whitelisted urls to keys and ttls + */ + protected $whitelist = array(); + /** + * @var FileCache + */ + protected $cache; + + /** + * @param FileCache $cache + */ + public function __construct( FileCache $cache ) { + $this->cache = $cache; + + // hook into wp http api + add_filter( 'pre_http_request', array($this, 'filter_pre_http_request'), 10, 3 ); + add_filter( 'http_response', array($this, 'filter_http_response'), 10, 3 ); + } + + + /** + * short circuit wp http api with cached file + */ + public function filter_pre_http_request( $response, $args, $url ) { + // check if whitelisted + if ( !isset( $this->whitelist[$url] ) ) { + return $response; + } + // check if downloading + if ( 'GET' !== $args['method'] || empty( $args['filename'] ) ) { + return $response; + } + // check cache and export to designated location + $filename = $this->cache->has( $this->whitelist[$url]['key'], $this->whitelist[$url]['ttl'] ); + if ( $filename ) { + WP_CLI::log( sprintf( 'Using cached file \'%s\'...', $filename, $url ) ); + if ( copy( $filename, $args['filename'] ) ) { + // simulate successful download response + return array( + 'response' => array('code' => ( 200 ), 'message' => 'OK'), + 'filename' => $args['filename'] + ); + } else { + WP_CLI::error( sprintf( 'Error copying cached file %s to %s', $filename, $url ) ); + } + } + return $response; + } + + + /** + * cache wp http api downloads + */ + public function filter_http_response( $response, $args, $url ) { + // check if whitelisted + if ( !isset( $this->whitelist[$url] ) ) { + return $response; + } + // check if downloading + if ( 'GET' !== $args['method'] || empty( $args['filename'] ) ) { + return $response; + } + // check if download was successful + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + return $response; + } + // cache downloaded file + $this->cache->import( $this->whitelist[$url]['key'], $response['filename']); + return $response; + } + + /** + * whitelist a package url + * + * @param string $url + * @param string $group package group (themes, plugins, ...) + * @param string $slug package slug + * @param string $version package version + * @param int $ttl + */ + public function whitelist_package( $url, $group, $slug, $version, $ttl = null ) { + $ext = pathinfo( parse_url( $url, PHP_URL_PATH ), PATHINFO_EXTENSION ); + $key = "$group/$slug-$version.$ext"; + $this->whitelist_url( $url, $key, $ttl ); + wp_update_plugins(); + } + + /** + * whitelist a url + * + * @param string $url + * @param string $key + * @param int $ttl + */ + public function whitelist_url( $url, $key = null, $ttl = null ) { + $key = $key ? : $url; + $this->whitelist[$url] = compact( 'key', 'ttl' ); + } + + /** + * check if url is whitelisted + * + * @param string $url + * @return bool + */ + public function is_whitelisted( $url ) { + return isset( $this->whitelist[$url] ); + } +} \ No newline at end of file diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 12b759e23c..7be4ac939e 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -2,6 +2,8 @@ use \WP_CLI\Utils; use \WP_CLI\Dispatcher; +use \WP_CLI\FileCache; +use \WP_CLI\WpHttpCacheManager; /** * Various utilities for WP-CLI commands. @@ -54,6 +56,41 @@ static function get_runner() { return $runner; } + /** + * @return FileCache + */ + static function get_cache() { + static $cache; + + if ( !$cache ) { + $home = getenv( 'HOME' ) ? : getenv( 'HOMEDRIVE' ) . '/' . getenv( 'HOMEPATH' ); + $dir = getenv( 'WP_CLI_CACHE_DIR' ) ? : "$home/.wp-cli/cache"; + // 6 months, 300mb + $cache = new FileCache( $dir, 15552000, 314572800); + + if (0 === mt_rand( 0, 50 ) ) { + register_shutdown_function( function () use ( $cache ) { + $cache->clean(); + } ); + } + } + + return $cache; + } + + /** + * @return WpHttpCacheManager + */ + static function get_http_cache_manager() { + static $http_cacher; + + if ( !$http_cacher ) { + $http_cacher = new WpHttpCacheManager( self::get_cache() ); + } + + return $http_cacher; + } + static function colorize( $string ) { return \cli\Colors::colorize( $string, self::get_runner()->in_color() ); } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 535a3f4699..da853957bb 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -260,6 +260,9 @@ protected function install_from_repo( $slug, $assoc_args ) { } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + if ( 'dev' !== $assoc_args['version'] ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); + } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); return $result; @@ -304,10 +307,14 @@ protected function get_item_list() { $items = array(); foreach ( get_plugins() as $file => $details ) { + $update_info = $this->get_update_info( $file ); + $items[ $file ] = array( 'name' => $this->get_name( $file ), 'status' => $this->get_status( $file ), - 'update' => $this->has_update( $file ), + 'update' => (bool) $update_info, + 'update_version' => $update_info['new_version'], + 'update_package' => $update_info['package'], 'version' => $details['Version'], 'update_id' => $file, ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 7e093a85f6..f5cf3ce976 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -176,6 +176,9 @@ protected function install_from_repo( $slug, $assoc_args ) { } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + if ( 'dev' !== $assoc_args['version'] ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); + } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); return $result; @@ -186,11 +189,14 @@ protected function get_item_list() { foreach ( wp_get_themes() as $key => $theme ) { $file = $theme->get_stylesheet_directory(); + $update_info = $this->get_update_info( $theme->get_stylesheet() ); $items[ $file ] = array( 'name' => $key, 'status' => $this->get_status( $theme ), - 'update' => $this->has_update( $theme->get_stylesheet() ), + 'update' => (bool) $update_info, + 'update_version' => $update_info['new_version'], + 'update_package' => $update_info['package'], 'version' => $theme->get('Version'), 'update_id' => $theme->get_stylesheet(), ); From 10b8234acbd73e5a441a66690b0e3009a526f27d Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Thu, 10 Oct 2013 21:09:41 +0200 Subject: [PATCH 2397/4858] packages cache behat tests --- features/bootstrap/FeatureContext.php | 15 +++++++++++++-- features/bootstrap/Process.php | 13 ++++++++----- features/steps/basic_steps.php | 2 +- features/upgradables.feature | 27 +++++++++++++++++++++++---- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index cca8e3924f..733c596e96 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -14,7 +14,7 @@ */ class FeatureContext extends BehatContext implements ClosuredContextInterface { - private static $cache_dir; + private static $cache_dir, $suite_cache_dir; private static $db_settings = array( 'dbname' => 'wp_cli_test', @@ -41,6 +41,15 @@ private static function cache_wp_files() { */ public static function prepare( SuiteEvent $event ) { self::cache_wp_files(); + self::$suite_cache_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-suite-cache-", TRUE ); + mkdir( self::$suite_cache_dir ); + } + + /** + * @AfterSuite + */ + public static function afterSuite( SuiteEvent $event ) { + Process::create( Utils\esc_cmd( 'rm -r %s', self::$suite_cache_dir ) )->run(); } /** @@ -66,6 +75,7 @@ public function __construct( array $parameters ) { $this->drop_db(); $this->set_cache_dir(); $this->variables['CORE_CONFIG_SETTINGS'] = Utils\assoc_args_to_str( self::$db_settings ); + $this->variables['SUITE_CACHE_DIR'] = self::$suite_cache_dir; } public function getStepDefinitionResources() { @@ -126,7 +136,8 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - return Process::create( $command, $this->variables['RUN_DIR'] ); + return Process::create( $command, $this->variables['RUN_DIR'], + array( 'WP_CLI_CACHE_DIR' => $this->variables['SUITE_CACHE_DIR'] ) ); } public function move_files( $src, $dest ) { diff --git a/features/bootstrap/Process.php b/features/bootstrap/Process.php index 1cbb194d9a..a8a3334b5d 100644 --- a/features/bootstrap/Process.php +++ b/features/bootstrap/Process.php @@ -2,16 +2,17 @@ class Process { - public static function create( $command, $cwd = null ) { + public static function create( $command, $cwd = null, $env = array() ) { $proc = new self; $proc->command = $command; $proc->cwd = $cwd; + $proc->env = $env; return $proc; } - private $command, $cwd; + private $command, $cwd, $env; private function __construct() {} @@ -29,12 +30,13 @@ public function run( $subdir = '' ) { // Ensure we're using the expected `wp` binary $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); - - $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, array( + $env = array_merge( $this->env, array( 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), 'BEHAT_RUN' => 1 ) ); + $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, $env ); + $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); @@ -46,7 +48,8 @@ public function run( $subdir = '' ) { 'STDERR' => $STDERR, 'return_code' => proc_close( $proc ), 'command' => $this->command, - 'cwd' => $cwd + 'cwd' => $cwd, + 'env' => $env ) ); } diff --git a/features/steps/basic_steps.php b/features/steps/basic_steps.php index 092c6c3fd9..44342b50b1 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/basic_steps.php @@ -116,7 +116,7 @@ function ( $world, $mode ) { if ( !isset( $world->result ) ) throw new \Exception( 'No previous command.' ); - $proc = Process::create( $world->result->command, $world->result->cwd ); + $proc = Process::create( $world->result->command, $world->result->cwd, $world->result->env ); $world->result = invoke_proc( $proc, $mode ); } ); diff --git a/features/upgradables.feature b/features/upgradables.feature index 672ab6c034..527160f615 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -2,9 +2,6 @@ Feature: Manage WordPress themes and plugins Scenario Outline: Installing, upgrading and deleting a theme or plugin Given a WP install - And download: - | path | url | - | {CACHE_DIR}/<item>.zip | <zip_file> | And I run `wp <type> path` And save STDOUT as {CONTENT_DIR} @@ -22,6 +19,7 @@ Feature: Manage WordPress themes and plugins """ <type_name> installed successfully """ + And the {SUITE_CACHE_DIR}/<type>/<item>-<version>.zip file should exist When I try `wp <type> is-installed <item>` Then the return code should be 0 @@ -96,8 +94,29 @@ Feature: Manage WordPress themes and plugins And STDERR should not be empty + # Install and update <item> from cache + When I run `wp <type> install <item> --version=<version>` + Then STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/<type>/<item>-<version>.zip'... + """ + + When I run `wp <type> update <item>` + Then STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/<type>/<item>- + """ + + When I run `wp <type> delete <item>` + Then STDOUT should contain: + """ + Success: Deleted '<item>' <type>. + """ + And the <file_to_check> file should not exist + + # Install <item> from a local zip file - When I run `wp <type> install {CACHE_DIR}/<item>.zip` + When I run `wp <type> install {SUITE_CACHE_DIR}/<type>/<item>-<version>.zip` Then STDOUT should contain: """ <type_name> installed successfully. From 3ca1fdf5f1c65fc41478467ef3d473630bc7fb35 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Thu, 10 Oct 2013 22:52:14 +0200 Subject: [PATCH 2398/4858] stricter update package from cache test --- features/upgradables.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 527160f615..830291fe70 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -72,7 +72,9 @@ Feature: Manage WordPress themes and plugins """ When I run `wp <type> update <item>` + And save STDOUT 'Downloading update from .*\/<item>\.%s\.zip' as {NEW_VERSION} Then STDOUT should not be empty + And the {SUITE_CACHE_DIR}/<type>/<item>-{NEW_VERSION}.zip file should exist When I run `wp <type> update --all` Then STDOUT should not be empty @@ -104,7 +106,7 @@ Feature: Manage WordPress themes and plugins When I run `wp <type> update <item>` Then STDOUT should contain: """ - Using cached file '{SUITE_CACHE_DIR}/<type>/<item>- + Using cached file '{SUITE_CACHE_DIR}/<type>/<item>-{NEW_VERSION}.zip'... """ When I run `wp <type> delete <item>` From 0eb1431870b8a487c341078ac081ffb59ac13ab5 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Fri, 11 Oct 2013 00:56:25 +0200 Subject: [PATCH 2399/4858] better validation of urls as cache key --- php/WP_CLI/FileCache.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/FileCache.php b/php/WP_CLI/FileCache.php index 65ee7487e3..a6a9fa6244 100644 --- a/php/WP_CLI/FileCache.php +++ b/php/WP_CLI/FileCache.php @@ -294,10 +294,12 @@ protected function prepare_write( $key ) { */ protected function validate_key( $key ) { $url_parts = parse_url( $key ); - if ( $url_parts['scheme'] ) { // is url + if ( ! empty($url_parts['scheme']) ) { // is url $parts = array('misc'); - $parts[] = $url_parts['host'] . ( $url_parts['port'] ? '-' . $url_parts['port'] : '' ); - $parts[] = $url_parts['path'] . ( $url_parts['query'] ? '-' . $url_parts['query'] : '' ); + $parts[] = $url_parts['scheme'] . '-' . $url_parts['host'] . + ( empty( $url_parts['port'] ) ? '' : '-' . $url_parts['port'] ); + $parts[] = substr($url_parts['path'], 1) . + ( empty( $url_parts['query'] ) ? '' : '-' . $url_parts['query'] ); } else { $key = str_replace( '\\', '/', $key ); $parts = explode( '/', ltrim( $key ) ); From ed2111ab33391cf52062b82f86da8feb95cd26fa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 12:38:06 +0300 Subject: [PATCH 2400/4858] show response exception message as a warning --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 40c26a7cb2..a224e487e4 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -70,7 +70,8 @@ public function download( $args, $assoc_args ) { try { $request = Requests::get( $download_url, $headers, $options ); - } catch( Requests_Exception $ex ) { + } catch ( Requests_Exception $ex ) { + WP_CLI::warning( $ex->getMessage() ); // Handle SSL certificate issues gracefully $options['verify'] = false; try { From 94a9277c9bf5383574897c204080df1ebd7d77e2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 12:59:06 +0300 Subject: [PATCH 2401/4858] enable SSL verification by default --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index a224e487e4..dc3a48cbed 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -91,7 +91,7 @@ public function download( $args, $assoc_args ) { private static function _read( $url ) { $headers = array('Accept' => 'application/json'); - $options = array(); + $options = array('verify' => true); $r = false; try { From f4e1db61f13619d99f17c42c5356a8644d598121 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Fri, 11 Oct 2013 12:54:52 +0200 Subject: [PATCH 2402/4858] include symfony finder in phar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … and remove duplicate dependency in composer.json from a rebase --- composer.json | 3 --- utils/make-phar.php | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 3531bcc1cd..dad44f9cf7 100644 --- a/composer.json +++ b/composer.json @@ -15,9 +15,6 @@ "rmccue/requests": "~1.6", "symfony/finder": "~2.3" }, - "require-dev": { - "symfony/finder": "~2.3" - }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" }, diff --git a/utils/make-phar.php b/utils/make-phar.php index 8f7bb90cdb..0a7b16d83c 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -37,6 +37,7 @@ function add_file( $phar, $path ) { ->in('./vendor/mustache') ->in('./vendor/rmccue/requests') ->in('./vendor/composer') + ->in('./vendor/symfony/finder') ->in('./vendor/rhumsaa/array_column') ->exclude('test') ->exclude('tests') From 577f415354e99bf5b9c8a2bbd60d7169e5968ee8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 14:05:05 +0300 Subject: [PATCH 2403/4858] extract duplicated request logic into a helper method --- php/commands/core.php | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index dc3a48cbed..981f5bcaa1 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -68,19 +68,7 @@ public function download( $args, $assoc_args ) { 'filename' => $temp ); - try { - $request = Requests::get( $download_url, $headers, $options ); - } catch ( Requests_Exception $ex ) { - WP_CLI::warning( $ex->getMessage() ); - // Handle SSL certificate issues gracefully - $options['verify'] = false; - try { - $request = Requests::get( $download_url, $headers, $options ); - } - catch( Requests_Exception $ex ) { - WP_CLI::error( $ex->getMessage() ); - } - } + self::_request( 'GET', $download_url, $headers, $options ); $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; @@ -89,26 +77,24 @@ public function download( $args, $assoc_args ) { WP_CLI::success( 'WordPress downloaded.' ); } - private static function _read( $url ) { - $headers = array('Accept' => 'application/json'); - $options = array('verify' => true); - - $r = false; + private static function _request( $method, $url, $headers = array(), $options = array() ) { try { - $request = Requests::get( $url, $headers, $options ); - $r = $request->body; + $options['verify'] = true; + return Requests::get( $url, $headers, $options ); } catch( Requests_Exception $ex ) { // Handle SSL certificate issues gracefully $options['verify'] = false; try { - $request = Requests::get( $url, $headers, $options ); - $r = $request->body; + return Requests::get( $url, $headers, $options ); } catch( Requests_Exception $ex ) { WP_CLI::error( $ex->getMessage() ); } } + } - return $r; + private static function _read( $url ) { + $headers = array('Accept' => 'application/json'); + return self::_request( 'GET', $url, $headers )->body; } private function get_download_offer( $locale ) { From d153411f477e2c165fc90e05eafb5360686d085a Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Fri, 11 Oct 2013 13:42:41 +0200 Subject: [PATCH 2404/4858] make WP_CLI::get_cache more readable and private --- php/class-wp-cli.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7be4ac939e..0476c43ba9 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -59,16 +59,22 @@ static function get_runner() { /** * @return FileCache */ - static function get_cache() { + private static function get_cache() { static $cache; if ( !$cache ) { - $home = getenv( 'HOME' ) ? : getenv( 'HOMEDRIVE' ) . '/' . getenv( 'HOMEPATH' ); + $home = getenv( 'HOME' ); + if ( !$home ) { + // sometime in windows $HOME is not defined + $home = getenv( 'HOMEDRIVE' ) . '/' . getenv( 'HOMEPATH' ); + } $dir = getenv( 'WP_CLI_CACHE_DIR' ) ? : "$home/.wp-cli/cache"; + // 6 months, 300mb - $cache = new FileCache( $dir, 15552000, 314572800); + $cache = new FileCache( $dir, 15552000, 314572800 ); - if (0 === mt_rand( 0, 50 ) ) { + // clean older files on shutdown with 1/50 probability + if ( 0 === mt_rand( 0, 50 ) ) { register_shutdown_function( function () use ( $cache ) { $cache->clean(); } ); From 1294a677817c8bb6b2a14dd38ca02fe3b508baa2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 15:03:33 +0300 Subject: [PATCH 2405/4858] add back warning message --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index 981f5bcaa1..ec14f2a294 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -83,6 +83,7 @@ private static function _request( $method, $url, $headers = array(), $options = return Requests::get( $url, $headers, $options ); } catch( Requests_Exception $ex ) { // Handle SSL certificate issues gracefully + WP_CLI::warning( $ex->getMessage() ); $options['verify'] = false; try { return Requests::get( $url, $headers, $options ); From 73bfb93704dd90c126c56cc65463a2047423d2e6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 15:34:39 +0300 Subject: [PATCH 2406/4858] update contributor list since 0.12.0 --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 72fbae088c..5b7349285c 100644 --- a/.mailmap +++ b/.mailmap @@ -29,6 +29,7 @@ lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> marcoceppi <marco@ceppi.net> matiskay <matiskay@gmail.com> +mattes <matthias.kadenbach@gmail.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> milesj <mileswjohnson@gmail.com> From 1d71878436072c63c0c41dcb9064210ff1930dfb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 15:35:58 +0300 Subject: [PATCH 2407/4858] branding --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 8eea440200..e923f211fd 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -1,6 +1,6 @@ <?php -// Can be used by plugins/themes to check if wp-cli is running or not +// Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); define( 'WP_CLI_VERSION', '0.13.0-alpha' ); From b1241f9544131696cc4319cc72bd22ebdda3c53b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 15:36:09 +0300 Subject: [PATCH 2408/4858] set version to 0.12.1 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index e923f211fd..95335b0f75 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13.0-alpha' ); +define( 'WP_CLI_VERSION', '0.12.1' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From e9d7494e5180397f8966966b22eec330b21dafe1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 11 Oct 2013 22:49:15 +0300 Subject: [PATCH 2409/4858] test the waters before diving in --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 701e56b21c..74af3fa221 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,14 @@ Contribute ========== -So you've got an awesome idea to throw into WP-CLI. Great! Here's the process, in a nutshell: +Whether you want to fix a bug or implement a new feature, the process is pretty much the same: +0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, open a new issue so that you can get some initial feedback. 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. 2. Make the code changes in your fork. 3. Open a pull request. -It doesn't matter if the code isn't perfect. The idea is to get feedback early and iterate. +It doesn't matter if the code isn't perfect. The idea is to get it reviewed early and iterate on it. If you're adding a new feature, please add one or more functional tests for it in the `features/` directory. See below. From e4cbd9372319e884d52a1bd7bc76dafd16d33ece Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 14:43:48 +0300 Subject: [PATCH 2410/4858] restrict codesniffer warnings to undefined variables --- ci/prepare-codesniffer.sh | 2 +- ci/test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/prepare-codesniffer.sh b/ci/prepare-codesniffer.sh index 630b818e34..a5f5fa8746 100755 --- a/ci/prepare-codesniffer.sh +++ b/ci/prepare-codesniffer.sh @@ -1,5 +1,5 @@ #!/bin/bash -composer create-project squizlabs/php_codesniffer:1.4.7 codesniffer +composer create-project squizlabs/php_codesniffer:1.5.0RC4 codesniffer git clone https://github.com/illusori/PHP_Codesniffer-VariableAnalysis.git cd PHP_Codesniffer-VariableAnalysis diff --git a/ci/test.sh b/ci/test.sh index c213a42318..7aeaaf1974 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -9,4 +9,4 @@ phpunit php behat.phar --format progress # Run CodeSniffer -./codesniffer/scripts/phpcs --standard=./ci/ php/ +./codesniffer/scripts/phpcs --standard=./ci/ --sniffs=Generic.CodeAnalysis.VariableAnalysis.UndefinedVariable php/ From 7d3df119ab7858eefe430ac4647b1530b6377ab1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:03:49 +0300 Subject: [PATCH 2411/4858] reset temporary $levs array on each iteration also, use rsort(), since $levs isn't associative --- php/commands/import.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index 493badb64e..fb06220198 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -351,11 +351,12 @@ private function suggest_user( $author_user_login, $author_user_email = '' ) { if ( $author_user_email && $user->user_email == $author_user_email ) return $user->user_login; + $levs = array(); $levs[] = levenshtein( $author_user_login, $user->display_name ); $levs[] = levenshtein( $author_user_login, $user->user_login ); $levs[] = levenshtein( $author_user_login, $user->user_email ); $levs[] = levenshtein( $author_user_login, array_shift( explode( "@", $user->user_email ) ) ); - arsort( $levs ); + rsort( $levs ); $lev = array_pop( $levs ); if ( 0 == $lev ) { $closest = $user->user_login; From 0abbda1287b169eb63899452d22959305addc6da Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:05:25 +0300 Subject: [PATCH 2412/4858] remove unused $silent parameter from when cURL was used directly --- php/commands/core.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index ec14f2a294..9ffcecc125 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -55,9 +55,6 @@ public function download( $args, $assoc_args ) { WP_CLI::log( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); } - $silent = WP_CLI::get_config('quiet') || \cli\Shell::isPiped() ? - '--silent ' : ''; - // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). $temp = tempnam( sys_get_temp_dir(), "wp_" ); From 7af168b782e8e4b7ece3a03d42c9abee0222948b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:05:46 +0300 Subject: [PATCH 2413/4858] remove unused $wpdb variable --- php/WP_CLI/Iterators/Table.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 441b69dc7b..eb7d1d60fd 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -38,8 +38,6 @@ class Table extends Query { * it's a key/value pair. In the latter case the value is automatically quoted and escaped */ function __construct( $args = array() ) { - global $wpdb; - $defaults = array( 'fields' => '*', 'where' => array(), From a18dd9ec9bb24329acc529c24bf6bb9ef3b05e90 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:08:20 +0300 Subject: [PATCH 2414/4858] fix undefined variables in comment.php --- php/commands/comment.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index adefbcada9..8d97df2e83 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -35,9 +35,10 @@ class Comment_Command extends \WP_CLI\CommandWithDBObject { */ public function create( $args, $assoc_args ) { parent::_create( $args, $assoc_args, function ( $params ) { - $post = get_post( $params['comment_post_ID'] ); + $post_id = $params['comment_post_ID']; + $post = get_post( $post_id ); if ( !$post ) { - return new WP_Error( 'no_post', "Can't find post $comment_post_ID." ); + return new WP_Error( 'no_post', "Can't find post $post_id." ); } // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and @@ -198,7 +199,7 @@ private function set_status( $args, $status, $success ) { if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); } else { - WP_CLI::success( "$success comment $comment_id" ); + WP_CLI::success( "$success comment $comment->comment_ID" ); } } From 727d3d40743f3a6e5b3efcaf09bf49197571ac64 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:10:14 +0300 Subject: [PATCH 2415/4858] fix undefined variables in Formatter.php --- php/WP_CLI/Formatter.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 17b580ed76..6f971b28b4 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -95,10 +95,13 @@ private function format( $items ) { * @param string The field to show */ private function show_single_field( $items, $field ) { + $key = null; + $values = array(); + foreach ( $items as $item ) { $item = (object) $item; - if ( ! isset( $key ) ) { + if ( null === $key ) { $key = $this->find_item_key( $item, $field ); } From 90633a9690c04a180391c0d23a98b5833ecd1384 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:13:20 +0300 Subject: [PATCH 2416/4858] fix undefined variables in scaffold.php --- php/commands/scaffold.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c69d1a342c..6ee800cc78 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -191,6 +191,7 @@ function _s( $args, $assoc_args ) { $theme_description = "Custom theme: ".$data['theme_name']." developed by, ".$data['author']; + $body = array(); $body['underscoresme_name'] = $data['theme_name']; $body['underscoresme_slug'] = $theme_slug; $body['underscoresme_author'] = $data['author']; @@ -265,14 +266,14 @@ function child_theme( $args, $assoc_args ) { } private function get_output_path( $assoc_args, $subdir ) { - extract( $assoc_args, EXTR_SKIP ); - - if ( $theme ) { + if ( $assoc_args['theme'] ) { + $theme = $assoc_args['theme']; if ( is_string( $theme ) ) $path = get_theme_root( $theme ) . '/' . $theme; else $path = get_stylesheet_directory(); - } elseif ( ! empty( $plugin ) ) { + } elseif ( $assoc_args['plugin'] ) { + $plugin = $assoc_args['plugin']; $path = WP_PLUGIN_DIR . '/' . $plugin; if ( !is_dir( $path ) ) { WP_CLI::error( "Can't find '$plugin' plugin." ); From a78ccafaf32f1dfb058858e53dc7510d59111dc4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:14:31 +0300 Subject: [PATCH 2417/4858] fix undefined variables in site.php --- php/commands/site.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index 5bcdf6d627..e3d500da41 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -61,6 +61,7 @@ private function _empty_taxonomies() { // Empty taxonomies and terms $terms = $wpdb->get_results( "SELECT term_id, taxonomy FROM $wpdb->term_taxonomy" ); $ids = array(); + $taxonomies = array(); foreach ( (array) $terms as $term ) { $taxonomies[] = $term->taxonomy; $ids[] = $term->term_id; @@ -68,6 +69,7 @@ private function _empty_taxonomies() { } $taxonomies = array_unique( $taxonomies ); + $cleaned = array(); foreach ( $taxonomies as $taxonomy ) { if ( isset( $cleaned[$taxonomy] ) ) continue; From e7637a28724651e01dba63bd73111750f096b6de Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:19:12 +0300 Subject: [PATCH 2418/4858] bump version to 0.13-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 95335b0f75..ad8cd8d360 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.12.1' ); +define( 'WP_CLI_VERSION', '0.13-alpha' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From e398a82471dbb525f7ceb40ca3ea7b2b74bda505 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:38:46 +0300 Subject: [PATCH 2419/4858] ignore codesniffer warnings in core.php some are caused by using variables defined in wp-includes/version.php and some are caused by using extract(), which isn't that evil when used with EXTR_SKIP --- php/commands/core.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9ffcecc125..d8e34e7754 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -105,8 +105,10 @@ private function get_download_offer( $locale ) { private static function get_initial_locale() { include ABSPATH . '/wp-includes/version.php'; + // @codingStandardsIgnoreStart if ( isset( $wp_local_package ) ) return $wp_local_package; + // @codingStandardsIgnoreEnd return ''; } @@ -381,11 +383,13 @@ private function _install( $assoc_args ) { $public = true; + // @codingStandardsIgnoreStart $result = wp_install( $title, $admin_user, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { WP_CLI::error( 'Installation failed (' . WP_CLI::error_to_string($result) . ').' ); } + // @codingStandardsIgnoreEnd return true; } @@ -531,9 +535,13 @@ public function version( $args = array(), $assoc_args = array() ) { include $versions_path; + // @codingStandardsIgnoreStart if ( isset( $assoc_args['extra'] ) ) { - preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ); - $human_readable_tiny_mce = $match ? $match[1] . '.' . $match[2] : ''; + if ( preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ) ) { + $human_readable_tiny_mce = $match[1] . '.' . $match[2]; + } else { + $human_readable_tiny_mce = ''; + } echo \WP_CLI\Utils\mustache_render( 'versions.mustache', array( 'wp-version' => $wp_version, @@ -546,6 +554,7 @@ public function version( $args = array(), $assoc_args = array() ) { } else { WP_CLI::line( $wp_version ); } + // @codingStandardsIgnoreEnd } /** From d6f4e47eaf67775b133ff8ded700ca41ba7a2452 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 15:44:04 +0300 Subject: [PATCH 2420/4858] make codesniffer ignore Spyc library --- ci/test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/test.sh b/ci/test.sh index 7aeaaf1974..5939c599ac 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -9,4 +9,6 @@ phpunit php behat.phar --format progress # Run CodeSniffer -./codesniffer/scripts/phpcs --standard=./ci/ --sniffs=Generic.CodeAnalysis.VariableAnalysis.UndefinedVariable php/ +./codesniffer/scripts/phpcs \ + --standard=./ci/ --sniffs=Generic.CodeAnalysis.VariableAnalysis.UndefinedVariable \ + --ignore=php/Spyc.php php/ From 1d321ccc804773c4ecec002e281dbba69bd11494 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 16:11:29 +0300 Subject: [PATCH 2421/4858] ignore undefined variable warnings in post.php --- php/commands/post.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index a07b934edf..c4d8f24ba2 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -287,9 +287,9 @@ public function generate( $args, $assoc_args ) { 'post_author' => false, 'post_date' => current_time( 'mysql' ), ); - 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 ) ); } @@ -334,7 +334,7 @@ public function generate( $args, $assoc_args ) { $args = array( 'post_type' => $post_type, - 'post_title' => "$label $i", + 'post_title' => "$label $i", 'post_status' => $post_status, 'post_author' => $post_author, 'post_parent' => $current_parent, @@ -346,8 +346,8 @@ public function generate( $args, $assoc_args ) { $notify->tick(); } - $notify->finish(); + // @codingStandardsIgnoreEnd } private function maybe_make_child() { From 07618f93d902e7c8d7baa0854556dc262d04c477 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 16:14:04 +0300 Subject: [PATCH 2422/4858] fix undefined variable warnings in wp-settings-cli.php --- php/wp-settings-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 50687b3de0..7af8816975 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -80,11 +80,14 @@ require_wp_db(); // WP-CLI: Handle db error ourselves, instead of waiting for dead_db() +global $wpdb; if ( !empty( $wpdb->error ) ) wp_die( $wpdb->error ); // Set the database table prefix and the format specifiers for database table columns. +// @codingStandardsIgnoreStart $GLOBALS['table_prefix'] = $table_prefix; +// @codingStandardsIgnoreEnd wp_set_wpdb_vars(); // Start the WordPress object cache, or an external object cache if the drop-in is present. @@ -298,6 +301,7 @@ $GLOBALS['wp_locale'] = new WP_Locale(); // Load the functions for the active theme, for both parent and child theme if applicable. +global $pagenow; if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) { if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) include( STYLESHEETPATH . '/functions.php' ); From 708fe74088c92ea0af9de944d339208a00358691 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 16:15:58 +0300 Subject: [PATCH 2423/4858] ignore undefined variable warnings in Runner.php --- php/WP_CLI/Runner.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 0d37f11a32..7ac2e56fb0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -358,6 +358,7 @@ private function check_wp_version() { $minimum_version = '3.4'; + // @codingStandardsIgnoreStart if ( version_compare( $wp_version, $minimum_version, '<' ) ) { WP_CLI::error( "WP-CLI needs WordPress $minimum_version or later to work properly. " . @@ -365,6 +366,7 @@ private function check_wp_version() { "Try running `wp core download --force`." ); } + // @codingStandardsIgnoreEnd } private function init_config() { From a3c62b8eff8224200e7485ab6a19104ba0302637 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 16:02:39 +0300 Subject: [PATCH 2424/4858] extract validate_role() helper method --- php/commands/user.php | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 10fb90d18f..c6272ac605 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -187,14 +187,9 @@ public function create( $args, $assoc_args ) { 'user_registered' => strftime( "%F %T", time() ), 'display_name' => false, ); + extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - if ( 'none' == $role ) { - $role = false; - } elseif ( is_null( get_role( $role ) ) ) { - WP_CLI::error( "Invalid role." ); - } + $role = self::validate_role( $role ); if ( !$user_pass ) { $user_pass = wp_generate_password(); @@ -274,12 +269,7 @@ public function generate( $args, $assoc_args ) { extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - if ( 'none' == $role ) { - $role = false; - } elseif ( is_null( get_role( $role ) ) ) { - WP_CLI::warning( "invalid role." ); - exit; - } + $role = self::validate_role( $role ); $user_count = count_users(); @@ -552,9 +542,8 @@ public function import_csv( $args, $assoc_args ) { ); $new_user = array_merge( $defaults, $new_user ); - if ( 'none' == $new_user['role'] ) { + if ( 'none' === $new_user['role'] ) { $new_user['role'] = false; - } elseif ( is_null( get_role( $new_user['role'] ) ) ) { WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); continue; @@ -597,6 +586,14 @@ public function import_csv( $args, $assoc_args ) { } } } + + private static function validate_role( $role ) { + if ( 'none' === $role ) { + $role = false; + } elseif ( is_null( get_role( $role ) ) ) { + WP_CLI::error( "Invalid role: $role" ); + } + } } WP_CLI::add_command( 'user', 'User_Command' ); From e231ce642acd619801a060252f9730419b94c3fb Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 16:07:20 +0300 Subject: [PATCH 2425/4858] fix undefined variable warnings in user.php --- php/commands/user.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index c6272ac605..95c4d05f31 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -191,6 +191,7 @@ public function create( $args, $assoc_args ) { $role = self::validate_role( $role ); + // @codingStandardsIgnoreStart if ( !$user_pass ) { $user_pass = wp_generate_password(); $generated_pass = true; @@ -221,6 +222,7 @@ public function create( $args, $assoc_args ) { if ( isset( $generated_pass ) ) WP_CLI::line( "Password: $user_pass" ); } + // @codingStandardsIgnoreEnd } /** @@ -266,18 +268,15 @@ public function generate( $args, $assoc_args ) { 'count' => 100, 'role' => get_option('default_role'), ); + $assoc_args = array_merge( $defaults, $assoc_args ); - extract( wp_parse_args( $assoc_args, $defaults ), EXTR_SKIP ); - - $role = self::validate_role( $role ); + $role = self::validate_role( $assoc_args['role'] ); $user_count = count_users(); - $total = $user_count['total_users']; + $limit = $assoc_args['count'] + $total; - $limit = $count + $total; - - $notify = \WP_CLI\Utils\make_progress_bar( 'Generating users', $count ); + $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 ); From 2389790947ad0d3d26c8be86e4f4fc506ff8311b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 16:51:38 +0300 Subject: [PATCH 2426/4858] move codesniffer parameters to ruleset.xml --- ci/ruleset.xml | 4 ++++ ci/test.sh | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ci/ruleset.xml b/ci/ruleset.xml index e8d39efb7a..29a843d56c 100644 --- a/ci/ruleset.xml +++ b/ci/ruleset.xml @@ -2,7 +2,11 @@ <ruleset name="WP-CLI"> <description>WP-CLI coding standards.</description> + <exclude-pattern>php/Spyc.php</exclude-pattern> + <rule ref="Generic.CodeAnalysis.VariableAnalysis"> + <exclude name="Generic.CodeAnalysis.VariableAnalysis.UnusedVariable"/> + <properties> <property name="allowUnusedFunctionParameters" value="1"/> </properties> diff --git a/ci/test.sh b/ci/test.sh index 5939c599ac..c213a42318 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -9,6 +9,4 @@ phpunit php behat.phar --format progress # Run CodeSniffer -./codesniffer/scripts/phpcs \ - --standard=./ci/ --sniffs=Generic.CodeAnalysis.VariableAnalysis.UndefinedVariable \ - --ignore=php/Spyc.php php/ +./codesniffer/scripts/phpcs --standard=./ci/ php/ From c333de1c2b1f7e87c2cf7e5ef90b066b4f96b772 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 17:07:26 +0300 Subject: [PATCH 2427/4858] enable DisallowSpaceIndent sniff --- ci/ruleset.xml | 2 ++ php/WP_CLI/Configurator.php | 2 +- php/WP_CLI/Runner.php | 3 +-- php/WP_CLI/SynopsisParser.php | 4 +--- php/boot-fs.php | 2 +- php/commands/help.php | 2 +- php/commands/search-replace.php | 3 +-- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/ci/ruleset.xml b/ci/ruleset.xml index 29a843d56c..624677051f 100644 --- a/ci/ruleset.xml +++ b/ci/ruleset.xml @@ -4,6 +4,8 @@ <exclude-pattern>php/Spyc.php</exclude-pattern> + <rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/> + <rule ref="Generic.CodeAnalysis.VariableAnalysis"> <exclude name="Generic.CodeAnalysis.VariableAnalysis.UnusedVariable"/> diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 239e95f23e..1065fe4d2a 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -93,7 +93,7 @@ function load_config( $yml_file ) { $value = array( $value ); } } else { - $value = $details['default']; + $value = $details['default']; } $sanitized_config[ $key ] = $value; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7ac2e56fb0..c3b52e1737 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -426,8 +426,7 @@ public function before_wp_load() { self::set_wp_root( $this->config ); // First try at showing man page - if ( 'help' === $this->arguments[0] && - ( isset( $this->arguments[1] ) || !$this->wp_exists() ) ) { + if ( 'help' === $this->arguments[0] && ( isset( $this->arguments[1] ) || !$this->wp_exists() ) ) { $this->_run_command(); } diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 37cc3aca03..4996000535 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -17,9 +17,7 @@ static function parse( $synopsis ) { // Some types of parameters shouldn't be mandatory if ( isset( $param['optional'] ) && !$param['optional'] ) { - if ( 'flag' === $param['type'] || - ( 'assoc' === $param['type'] && $param['value']['optional'] ) - ) { + if ( 'flag' === $param['type'] || ( 'assoc' === $param['type'] && $param['value']['optional'] ) ) { $param['type'] = 'unknown'; } } diff --git a/php/boot-fs.php b/php/boot-fs.php index 7a13744db4..c39ea2a473 100644 --- a/php/boot-fs.php +++ b/php/boot-fs.php @@ -8,7 +8,7 @@ } if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) { - printf( "Error: WP-CLI requires PHP %s or newer. You are running version %s.\n", '5.3.0', PHP_VERSION ); + printf( "Error: WP-CLI requires PHP %s or newer. You are running version %s.\n", '5.3.0', PHP_VERSION ); die(-1); } diff --git a/php/commands/help.php b/php/commands/help.php index c56e47f125..d7eb30c830 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -116,7 +116,7 @@ private static function get_initial_markdown( $command ) { private static function render_subcommands( $command ) { $subcommands = array(); foreach ( $command->get_subcommands() as $subcommand ) { - $subcommands[ $subcommand->get_name() ] = $subcommand->get_shortdesc(); + $subcommands[ $subcommand->get_name() ] = $subcommand->get_shortdesc(); } $max_len = self::get_max_len( array_keys( $subcommands ) ); diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index fbeeec184c..24f3d0f23e 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -73,8 +73,7 @@ public function __invoke( $args, $assoc_args ) { if ( in_array( $col, $skip_columns ) ) continue; - $count = self::handle_col( $col, $primary_key, $table, $old, $new, - $dry_run ); + $count = self::handle_col( $col, $primary_key, $table, $old, $new, $dry_run ); $report[] = array( $table, $col, $count ); From 6449289df09269e5ba110075479af15325946666 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 17:14:44 +0300 Subject: [PATCH 2428/4858] enable EndFileNewline sniff --- ci/ruleset.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/ruleset.xml b/ci/ruleset.xml index 624677051f..8208bd2a59 100644 --- a/ci/ruleset.xml +++ b/ci/ruleset.xml @@ -5,6 +5,7 @@ <exclude-pattern>php/Spyc.php</exclude-pattern> <rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/> + <rule ref="Generic.Files.EndFileNewline"/> <rule ref="Generic.CodeAnalysis.VariableAnalysis"> <exclude name="Generic.CodeAnalysis.VariableAnalysis.UnusedVariable"/> From 8e9f8359558560fa705bf4a5e1a34c338f471a89 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 17:28:05 +0300 Subject: [PATCH 2429/4858] split overly long lines --- php/WP_CLI/CommandWithUpgrade.php | 5 ++++- php/WP_CLI/Dispatcher/Subcommand.php | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 9d23c5a5c6..0197439e16 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -46,7 +46,10 @@ private function status_all() { $n = count( $items ); // Not interested in the translation, just the number logic - \WP_CLI::log( sprintf( _n( "%d installed {$this->item_type}:", "%d installed {$this->item_type}s:", $n ), $n ) ); + \WP_CLI::log( sprintf( _n( + "%d installed {$this->item_type}:", + "%d installed {$this->item_type}s:", + $n ), $n ) ); $padding = $this->get_padding($items); diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 07cbee7b3c..78cda45c12 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -173,7 +173,9 @@ private function validate_args( $args, &$assoc_args ) { implode( ' ', $unknown_positionals ) ); } - list( $errors, $to_unset ) = $validator->validate_assoc( array_merge( \WP_CLI::get_config(), $assoc_args ) ); + list( $errors, $to_unset ) = $validator->validate_assoc( + array_merge( \WP_CLI::get_config(), $assoc_args ) + ); if ( !empty( $errors['fatal'] ) ) { $out = 'Parameter errors:'; From aef71e17abdda752fa7596d9c1f1582d585d4f76 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Oct 2013 17:29:40 +0300 Subject: [PATCH 2430/4858] simplify error message for --user= global parameter --- features/flags.feature | 2 +- php/WP_CLI/Runner.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 7cd0288f76..8f290a0a74 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -62,7 +62,7 @@ Feature: Global flags Then the return code should be 1 And STDERR should be: """ - Error: Could not get a user_id for this user: 'non-existing-user' + Error: Could not find user: non-existing-user """ Scenario: Using a custom logger diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c3b52e1737..be1b7fa242 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -93,7 +93,7 @@ private static function set_user( $assoc_args ) { } if ( !$user_id || !wp_set_current_user( $user_id ) ) { - \WP_CLI::error( sprintf( 'Could not get a user_id for this user: %s', var_export( $user, true ) ) ); + \WP_CLI::error( "Could not find user: $user" ); } } From f074393deca33c5b5134c1c844bed3bff945eab9 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Mon, 14 Oct 2013 13:51:57 +0200 Subject: [PATCH 2431/4858] fix undefined index notice --- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index da853957bb..3bb17465fd 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -260,7 +260,7 @@ protected function install_from_repo( $slug, $assoc_args ) { } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - if ( 'dev' !== $assoc_args['version'] ) { + if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); diff --git a/php/commands/theme.php b/php/commands/theme.php index f5cf3ce976..b5dccf3fb3 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -176,7 +176,7 @@ protected function install_from_repo( $slug, $assoc_args ) { } WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); - if ( 'dev' !== $assoc_args['version'] ) { + if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); From ed075ed50d252d2c857f4adf56f9391658eebd8b Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Mon, 14 Oct 2013 13:52:23 +0200 Subject: [PATCH 2432/4858] fix composer.json whitespace --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dad44f9cf7..4fd173fb5a 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", - "symfony/finder": "~2.3" + "symfony/finder": "~2.3" }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" From a6bc7a966c281d3abd36472c25a3384baf476768 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Tue, 15 Oct 2013 11:27:36 +0200 Subject: [PATCH 2433/4858] fix missing EOF newline --- php/WP_CLI/WpHttpCacheManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/WpHttpCacheManager.php b/php/WP_CLI/WpHttpCacheManager.php index 1fe5a89611..f9e9efff97 100644 --- a/php/WP_CLI/WpHttpCacheManager.php +++ b/php/WP_CLI/WpHttpCacheManager.php @@ -121,4 +121,4 @@ public function whitelist_url( $url, $key = null, $ttl = null ) { public function is_whitelisted( $url ) { return isset( $this->whitelist[$url] ); } -} \ No newline at end of file +} From 66a02a66d8a3af8362ab9549a5313493d32d3ef5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 16 Oct 2013 21:52:33 +0300 Subject: [PATCH 2434/4858] colorize only section headers fixes #832 --- php/commands/help.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index d7eb30c830..d722a92050 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -51,14 +51,14 @@ private static function show_help( $command ) { } // section headers - $out = preg_replace( '/^## ([A-Z ]+)/m', '%9\1%n', $out ); + $out = preg_replace( '/^## ([A-Z ]+)/m', WP_CLI::colorize( '%9\1%n' ), $out ); // definition lists $out = preg_replace_callback( '/([^\n]+)\n: (.+?)(\n\n|$)/s', array( __CLASS__, 'rewrap_param_desc' ), $out ); $out = str_replace( "\t", ' ', $out ); - self::pass_through_pager( WP_CLI::colorize( $out ) ); + self::pass_through_pager( $out ); } private static function rewrap_param_desc( $matches ) { From b7dc8635a1a910e50f70e44b5b69022a4efb91aa Mon Sep 17 00:00:00 2001 From: Corey Taylor <ctaylor@thinkoomph.com> Date: Thu, 17 Oct 2013 10:38:14 -0400 Subject: [PATCH 2435/4858] Removed thumbnail detection logic. --- php/commands/import.php | 47 +---------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index eeff977cc9..21ad061cb3 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -127,7 +127,6 @@ private function import_wxr( $args ) { if( in_array( 'image_resize', $args['skip'] ) ) { add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_set_image_sizes' ) ); - add_filter( 'wp_generate_attachment_metadata', array( $this, 'filter_set_image_metadata' ), 10, 2 ); } $wp_import->import( $args['file'] ); @@ -136,54 +135,10 @@ private function import_wxr( $args ) { } public function filter_set_image_sizes( $sizes ) { - // Save the given sizes so that when the wp_generate_attachment_metadata hook - // is called we can place this info on to the $metadata array so that the - // info gets saved to the database, but the actual resize processing does - // not occur. - $this->image_sizes = $sizes; - + // Return null here to prevent the core image resizing logic from running. return null; } - public function filter_set_image_metadata( $metadata, $attachment_id ) { - if( !isset( $metadata['file'] ) ) - return $metadata; - - $upload_dir = wp_upload_dir(); - $file_path = $upload_dir['basedir'] . '/' . $metadata['file']; - $path_info = pathinfo( $file_path ); - $mime_type = get_post_mime_type( $attachment_id ); - - // Return current meta untouched if can't determine current image mime type. - if( !$mime_type ) - return $metadata; - - $metadata['sizes'] = array( ); - - // Now time to generate the image size metadata since some resized files - // should already be on disk. We just have to point WordPress to them. - // Note: this logic will not find all possibled resized thumbnail files. - // To be sure _wp_attachment_metadata gets populated with all possible - // custom image sizes, run a command like WP-CLI's 'media regenerate' in order - // to re-generate and link to all the various configured image sizes. - foreach( $this->image_sizes as $size => $size_data ) { - $file = $path_info['filename'] . '-' . $size_data['width'] . 'x' . $size_data['height'] . '.' . $path_info['extension']; - - // Make sure the file exists before adding a size entry to the meta array. - if( !file_exists( $path_info['dirname'] . '/' . $file ) ) - continue; // File does not exist, don't point to it. - - $metadata['sizes'][$size] = array( - 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $file ) ), - 'width' => $size_data['width'], - 'height' => $size_data['height'], - 'mime-type' => $mime_type, - ); - } - - return $metadata; - } - /** * Useful verbosity filters for the WXR importer */ From 4635a195283d27cedb4d097d9ef84dc2f0143eba Mon Sep 17 00:00:00 2001 From: Corey Taylor <ctaylor@thinkoomph.com> Date: Thu, 17 Oct 2013 11:02:27 -0400 Subject: [PATCH 2436/4858] Added functional test for new --skip=image_resize option. Also added option to command doc output. --- features/import.feature | 3 +++ php/commands/import.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/features/import.feature b/features/import.feature index 5a4c940cab..60ed6582ae 100644 --- a/features/import.feature +++ b/features/import.feature @@ -34,3 +34,6 @@ Feature: Import content. """ 7 """ + + When I run `wp import {EXPORT_FILE} --skip=image_resize` + Then STDOUT should not be empty \ No newline at end of file diff --git a/php/commands/import.php b/php/commands/import.php index 21ad061cb3..4964de155f 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -14,7 +14,7 @@ class Import_Command extends WP_CLI_Command { * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. * * [--skip=<data-type>] - * : Skip importing specific data. Supported option is 'attachment'. + * : Skip importing specific data. Supported options are: 'attachment' and 'image_resize' (skip time-consuming thumbnail generation). */ public function __invoke( $args, $assoc_args ) { list( $file ) = $args; From 679c36accfaf90a977f5b2ff5a1b52a4f1528f4e Mon Sep 17 00:00:00 2001 From: Corey Taylor <ctaylor@thinkoomph.com> Date: Thu, 17 Oct 2013 11:21:30 -0400 Subject: [PATCH 2437/4858] Fixed functional test (import requires --authors param to run correctly). --- features/import.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/import.feature b/features/import.feature index 60ed6582ae..f143224208 100644 --- a/features/import.feature +++ b/features/import.feature @@ -35,5 +35,5 @@ Feature: Import content. 7 """ - When I run `wp import {EXPORT_FILE} --skip=image_resize` + When I run `wp import {EXPORT_FILE} --authors=skip --skip=image_resize` Then STDOUT should not be empty \ No newline at end of file From 3bc97c0f927bb88a88ccf910594bfa11d3b4ebda Mon Sep 17 00:00:00 2001 From: Corey Taylor <ctaylor@thinkoomph.com> Date: Thu, 17 Oct 2013 11:56:30 -0400 Subject: [PATCH 2438/4858] Added newline to EOF. --- features/import.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/import.feature b/features/import.feature index f143224208..c5375053b4 100644 --- a/features/import.feature +++ b/features/import.feature @@ -36,4 +36,4 @@ Feature: Import content. """ When I run `wp import {EXPORT_FILE} --authors=skip --skip=image_resize` - Then STDOUT should not be empty \ No newline at end of file + Then STDOUT should not be empty From 9059abe2664e00ee90343a2852116937fc959812 Mon Sep 17 00:00:00 2001 From: Simon Wheatley <simonw@codeforthepeople.com> Date: Thu, 17 Oct 2013 17:22:02 +0100 Subject: [PATCH 2439/4858] Correct namespace. --- php/WP_CLI/Iterators/Query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Iterators/Query.php b/php/WP_CLI/Iterators/Query.php index 4fea0301ee..03e7fbe40c 100644 --- a/php/WP_CLI/Iterators/Query.php +++ b/php/WP_CLI/Iterators/Query.php @@ -73,7 +73,7 @@ private function load_items_from_db() { if ( !$this->results ) { if ( $this->db->last_error ) { - throw new Iterators\Exception( 'Database error: ' . $this->db->last_error ); + throw new Exception( 'Database error: ' . $this->db->last_error ); } else { return false; } From bb158fad4a161507be05ef7c5dc115698c1895b3 Mon Sep 17 00:00:00 2001 From: Simon Wheatley <simonw@codeforthepeople.com> Date: Thu, 17 Oct 2013 17:22:19 +0100 Subject: [PATCH 2440/4858] Wrap `invoke` in try/catch. --- php/WP_CLI/Runner.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index be1b7fa242..6621a72721 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -210,7 +210,11 @@ public function run_command( $args, $assoc_args = array() ) { list( $command, $final_args ) = $r; - $command->invoke( $final_args, $assoc_args ); + try { + $command->invoke( $final_args, $assoc_args ); + } catch ( WP_CLI\Iterators\Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } } private function _run_command() { From ab049844962bfae564ca1b127a3632e43d05a9e7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 17 Oct 2013 22:02:06 +0300 Subject: [PATCH 2441/4858] link to WPSE --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6f4de5557..abb95cf6d9 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ If you want to hack on WP-CLI, then clone this repository and run `./utils/dev-b Where can I get more info? -------------------------- -For documentation, usage, and examples, check out [wp-cli.org](http://wp-cli.org/). +For documentation and examples, check out [wp-cli.org](http://wp-cli.org/) and the [wiki](https://github.com/wp-cli/wp-cli/wiki). -Read our [wiki](https://github.com/wp-cli/wp-cli/wiki) and find out how to create your own commands with our [commands cookbook](https://github.com/wp-cli/wp-cli/wiki/Commands-Cookbook). +Also, WordPress Answers has a growing list of [WP-CLI related questions](http://wordpress.stackexchange.com/questions/tagged/wp-cli). I'm running into troubles, what can I do? ----------------------------------------- From 0b581dfbe4ca5c69df6981b7c2fbbd37ab28cb09 Mon Sep 17 00:00:00 2001 From: Nick Daugherty <ndaugherty987@gmail.com> Date: Fri, 18 Oct 2013 15:34:52 -0600 Subject: [PATCH 2442/4858] Conditionally load `wp-includes/date.php` Add support for the new `WP_Date_Query` class, used internally by `WP_Query`. http://core.trac.wordpress.org/changeset/25139 --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 7af8816975..c944799317 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -122,6 +122,7 @@ require( ABSPATH . WPINC . '/formatting.php' ); require( ABSPATH . WPINC . '/capabilities.php' ); require( ABSPATH . WPINC . '/query.php' ); +Utils\maybe_require( '3.7-alpha-25139', ABSPATH . WPINC . '/date.php' ); require( ABSPATH . WPINC . '/theme.php' ); Utils\maybe_require( '3.4', ABSPATH . WPINC . '/class-wp-theme.php' ); Utils\maybe_require( '3.4', ABSPATH . WPINC . '/template.php' ); From ad97b366a4f68b06afcc0c24d7d5c4ec33b05dad Mon Sep 17 00:00:00 2001 From: QWp6t <QWp6t+github@xpdnc.org> Date: Fri, 18 Oct 2013 17:55:41 -0700 Subject: [PATCH 2443/4858] Use PharData class to extract tarball In some environments (read: mine), tar binary cannot access temp file because it is locked by php. This will resolve that issue. --- php/commands/core.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index d8e34e7754..2d3d8f21f2 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -66,10 +66,14 @@ public function download( $args, $assoc_args ) { ); self::_request( 'GET', $download_url, $headers, $options ); - - $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; - - WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); + + if ( class_exists( 'PharData' ) ) { + $tar = new PharData( $temp ); + $tar->extractTo( ABSPATH, null, true ); + } else { + $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; + WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); + } WP_CLI::success( 'WordPress downloaded.' ); } From fc2a63db801214e81c9c158202784591d181f856 Mon Sep 17 00:00:00 2001 From: Ryan Duff <ryan@fusionized.com> Date: Sat, 19 Oct 2013 10:20:34 -0400 Subject: [PATCH 2444/4858] escape abspath so paths with spaces work --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d8e34e7754..d5dd5d40f4 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -69,7 +69,7 @@ public function download( $args, $assoc_args ) { $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; - WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); + WP_CLI::launch( Utils\esc_cmd( $cmd, ABSPATH ) ); WP_CLI::success( 'WordPress downloaded.' ); } From b0164cd155d05bec4f1dbb08218fc701419328be Mon Sep 17 00:00:00 2001 From: QWp6t <QWp6t+github@xpdnc.org> Date: Sat, 19 Oct 2013 15:41:07 -0700 Subject: [PATCH 2445/4858] Fixes PharData extraction bugs * $temp gets '.tar.gz' extension * _extract() method is created * PharData uses workaround for '--strip-components' compatibility --- php/commands/core.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 2d3d8f21f2..cc347fde98 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -57,7 +57,7 @@ public function download( $args, $assoc_args ) { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). - $temp = tempnam( sys_get_temp_dir(), "wp_" ); + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; $headers = array('Accept' => 'application/json'); $options = array( @@ -67,16 +67,28 @@ public function download( $args, $assoc_args ) { self::_request( 'GET', $download_url, $headers, $options ); - if ( class_exists( 'PharData' ) ) { - $tar = new PharData( $temp ); - $tar->extractTo( ABSPATH, null, true ); - } else { - $cmd = "tar xz --strip-components=1 --directory=%s -f $temp && rm $temp"; - WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); - } + self::_extract( $temp ); WP_CLI::success( 'WordPress downloaded.' ); } + + private static function _extract( $tarball ) { + if ( ! class_exists( 'PharData' ) ) { + $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball && rm $tarball"; + WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); + return ABSPATH; + } + $flags = FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO; + $tempdir = substr( $tarball, 0, -7 ); + $tempOffset = strlen( $tempdir ) + 10; + $phar = new PharData( $tarball ); + $phar->extractTo( $tempdir, null, true ); + foreach( new RecursiveDirectoryIterator( $tempdir . '/wordpress', $flags ) as $path ) { + rename( $path->getPathName(), ABSPATH . substr( $path, $tempOffset ) ); + } + rmdir( $tempdir . '/wordpress' ); + rmdir( $tempdir ); + } private static function _request( $method, $url, $headers = array(), $options = array() ) { try { From c881793985b67179c7aa08e07d57c5a0f91edf93 Mon Sep 17 00:00:00 2001 From: QWp6t <QWp6t+github@xpdnc.org> Date: Sun, 20 Oct 2013 01:40:58 -0700 Subject: [PATCH 2446/4858] Makes extraction routine more readable / Fixes overwrite routine * creates separate _move_overwrite_files() method * more accurately simulates --strip-components=1 by using $phar->getFileName() --- php/commands/core.php | 50 ++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index cc347fde98..7518356d01 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -67,27 +67,53 @@ public function download( $args, $assoc_args ) { self::_request( 'GET', $download_url, $headers, $options ); - self::_extract( $temp ); + self::_extract( $temp, ABSPATH ); WP_CLI::success( 'WordPress downloaded.' ); } - private static function _extract( $tarball ) { + private static function _extract( $tarball, $dest ) { if ( ! class_exists( 'PharData' ) ) { $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball && rm $tarball"; - WP_CLI::launch( sprintf( $cmd, ABSPATH ) ); - return ABSPATH; + WP_CLI::launch( sprintf( $cmd, $dest ) ); + return; } - $flags = FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO; - $tempdir = substr( $tarball, 0, -7 ); - $tempOffset = strlen( $tempdir ) + 10; $phar = new PharData( $tarball ); - $phar->extractTo( $tempdir, null, true ); - foreach( new RecursiveDirectoryIterator( $tempdir . '/wordpress', $flags ) as $path ) { - rename( $path->getPathName(), ABSPATH . substr( $path, $tempOffset ) ); + $tempdir = implode( DIRECTORY_SEPARATOR, Array ( + dirname( $tarball ), + basename( $tarball, '.tar.gz' ), + $phar->getFileName() + ) ); + + $phar->extractTo( dirname( $tempdir ), null, true ); + + self::_move_overwrite_files( $tempdir, $dest ); + + rmdir( dirname( $tempdir ) ); + } + + private static function _move_overwrite_files( $source, $dest ) { + $flags = FilesystemIterator::SKIP_DOTS + | FilesystemIterator::KEY_AS_PATHNAME + | FilesystemIterator::CURRENT_AS_FILEINFO; + + $dstOffset = strlen( $source ); + + foreach( new RecursiveIteratorIterator ( + new RecursiveDirectoryIterator( $source, $flags ), + RecursiveIteratorIterator::CHILD_FIRST + ) as $src ) { + $dst = $dest . substr( $src, $dstOffset ); + $dstdir = dirname( $dst ); + if ( ! is_dir( $dstdir ) ) continue; + + if ( $src->isDir() && is_dir( $dst ) ) { + rmdir( $src ); + continue; + } + rename( $src, $dst ); } - rmdir( $tempdir . '/wordpress' ); - rmdir( $tempdir ); + rmdir( $source ); } private static function _request( $method, $url, $headers = array(), $options = array() ) { From 75c28fed9cda8ed2afd97ce771221e76b2fc7bec Mon Sep 17 00:00:00 2001 From: QWp6t <QWp6t+github@xpdnc.org> Date: Sun, 20 Oct 2013 01:56:15 -0700 Subject: [PATCH 2447/4858] Fixes readability * two lines were indented with spaces, converted to tabs --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 7518356d01..57b5dbeebf 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -94,8 +94,8 @@ private static function _extract( $tarball, $dest ) { private static function _move_overwrite_files( $source, $dest ) { $flags = FilesystemIterator::SKIP_DOTS - | FilesystemIterator::KEY_AS_PATHNAME - | FilesystemIterator::CURRENT_AS_FILEINFO; + | FilesystemIterator::KEY_AS_PATHNAME + | FilesystemIterator::CURRENT_AS_FILEINFO; $dstOffset = strlen( $source ); From 7b182713e230175135eedd06dc7edec9b648cdd4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Oct 2013 02:33:12 +0300 Subject: [PATCH 2448/4858] bump version to 0.13-alpha2 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index ad8cd8d360..5380e8a271 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13-alpha' ); +define( 'WP_CLI_VERSION', '0.13-alpha2' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 8e0c1f6d0e1b781a11b40b3f38f08f5d30828810 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Oct 2013 02:37:03 +0300 Subject: [PATCH 2449/4858] use Utils\esc_cmd() for consistency --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d5dd5d40f4..9965db4e7c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -35,7 +35,7 @@ public function download( $args, $assoc_args ) { if ( !is_dir( ABSPATH ) ) { WP_CLI::log( sprintf( 'Creating directory %s', ABSPATH ) ); - WP_CLI::launch( sprintf( 'mkdir -p %s', escapeshellarg( ABSPATH ) ) ); + WP_CLI::launch( Utils\esc_cmd( 'mkdir -p %s', ABSPATH ) ); } if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version'] ) ) { From 3977c84d11396c5bd22d243517a8323910144d3f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Oct 2013 02:39:28 +0300 Subject: [PATCH 2450/4858] add space in download cache dir, for catching #839 --- ci/prepare.sh | 2 +- features/bootstrap/FeatureContext.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index 6d18180a8c..2a5b0e8e82 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -18,7 +18,7 @@ curl http://behat.org/downloads/behat.phar > behat.phar # Install CodeSniffer things ./ci/prepare-codesniffer.sh -./bin/wp core download --version=$WP_VERSION --path=/tmp/wp-cli-test-core-download-cache/ +./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' mysql -e 'CREATE DATABASE wp_cli_test;' -uroot mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 733c596e96..498e442b27 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -27,7 +27,7 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { // We cache the results of `wp core download` to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests private static function cache_wp_files() { - self::$cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache'; + self::$cache_dir = sys_get_temp_dir() . '/wp-cli-test core-download-cache'; if ( is_readable( self::$cache_dir . '/wp-config-sample.php' ) ) return; From 89e0f55ca6195b1cdfbe14776d1c4047614cf1f3 Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Tue, 22 Oct 2013 02:27:19 +0000 Subject: [PATCH 2451/4858] Output WP-CLI error if config file couldn't be created --- php/commands/core.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9965db4e7c..22c5136d3b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -196,9 +196,13 @@ public function config( $_, $assoc_args ) { } $out = Utils\mustache_render( 'wp-config.mustache', $assoc_args ); - file_put_contents( ABSPATH . 'wp-config.php', $out ); - WP_CLI::success( 'Generated wp-config.php file.' ); + $bytes_written = file_put_contents( ABSPATH . 'wp-config.php', $out ); + if ( ! $bytes_written ) { + WP_CLI::error( 'Could not create new config file.' ); + } else { + WP_CLI::success( 'Generated wp-config.php file.' ); + } } /** From d8dbe549e7235698535a64e5a7fc8ea14e590fde Mon Sep 17 00:00:00 2001 From: Taylor Lovett <admin@taylorlovett.com> Date: Tue, 22 Oct 2013 02:28:27 +0000 Subject: [PATCH 2452/4858] Tweak error message fixes #837 --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 22c5136d3b..b093b16846 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -199,7 +199,7 @@ public function config( $_, $assoc_args ) { $bytes_written = file_put_contents( ABSPATH . 'wp-config.php', $out ); if ( ! $bytes_written ) { - WP_CLI::error( 'Could not create new config file.' ); + WP_CLI::error( 'Could not create new wp-config.php file.' ); } else { WP_CLI::success( 'Generated wp-config.php file.' ); } From f8ab4d14729354180172685b070437685ca07910 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Oct 2013 12:51:54 +0300 Subject: [PATCH 2453/4858] send REPL output directly to STDOUT, to avoid output buffers started by plugins fixes #719 --- php/WP_CLI/REPL.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index c065091a29..b3f902316a 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -26,7 +26,10 @@ public function start() { if ( !self::starts_with( 'return', $line ) ) $line = 'return ' . $line; + // Write directly to STDOUT, to sidestep any output buffers created by plugins + ob_start(); var_dump( eval( $line ) ); + fwrite( STDOUT, ob_get_clean() ); } } } From 6ba67fba88be9ee5107eca96b0bc96defd0e7505 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 22 Oct 2013 12:53:59 +0300 Subject: [PATCH 2454/4858] use fwrite() instead of echo in WP_CLI::out(), to avoid output buffers --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0476c43ba9..f9d9908f29 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -314,7 +314,7 @@ static function add_man_dir() { // back-compat static function out( $str ) { - echo $str; + fwrite( STDOUT, $str ); } // back-compat From 85a927471a5585f702125f996af101c644d32c3b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 23 Oct 2013 22:50:45 +0300 Subject: [PATCH 2455/4858] Introduce WP_CLI_CONFIG_PATH environment variable. It allows defining an additional config file, which gets loaded before any project config file. Also, remove the --config= global parameter, which becomes redundant. see #698 --- features/config.feature | 8 ++++---- php/WP_CLI/Configurator.php | 14 +++++++++---- php/WP_CLI/Runner.php | 40 ++++++++++++------------------------- php/class-wp-cli.php | 4 ---- php/commands/cli.php | 5 ++++- php/config-spec.php | 6 ------ 6 files changed, 31 insertions(+), 46 deletions(-) diff --git a/features/config.feature b/features/config.feature index a51d366c06..42dfe081f1 100644 --- a/features/config.feature +++ b/features/config.feature @@ -68,14 +68,14 @@ Feature: Have a config file """ Scenario: Disabled subcommands - Given a WP install - And a wp-cli.yml file: + Given an empty directory + And a config.yml file: """ disabled_commands: - - db drop + - core version """ - When I try `wp db drop --yes` + When I try `WP_CLI_CONFIG_PATH=config.yml wp core version` Then STDERR should contain: """ command has been disabled diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 239e95f23e..42b867a7bd 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -92,11 +92,9 @@ function load_config( $yml_file ) { if ( $details['multiple'] && !is_array( $value ) ) { $value = array( $value ); } - } else { - $value = $details['default']; - } - $sanitized_config[ $key ] = $value; + $sanitized_config[ $key ] = $value; + } } // Make sure config-file-relative paths are made absolute. @@ -114,6 +112,14 @@ function load_config( $yml_file ) { return $sanitized_config; } + public function get_defaults() { + $defaults = array(); + foreach ( $this->spec as $key => $details ) { + $defaults[ $key ] = $details['default']; + } + return $defaults; + } + private static function absolutize( &$path, $base ) { if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { $path = $base . DIRECTORY_SEPARATOR . $path; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4c09fe8189..f6620b1dc6 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -8,7 +8,7 @@ class Runner { - private $config_path, $config; + private $global_config_path, $project_config_path, $config; private $arguments, $assoc_args; @@ -37,11 +37,7 @@ private function do_early_invoke( $when ) { } } - private static function get_config_path( $runtime_config ) { - if ( isset( $runtime_config['config'] ) && file_exists( $runtime_config['config'] ) ) { - return $runtime_config['config']; - } - + private static function get_project_config_path() { $config_files = array( 'wp-cli.local.yml', 'wp-cli.yml' @@ -49,7 +45,7 @@ private static function get_config_path( $runtime_config ) { // Stop looking upward when we find we have emerged from a subdirectory // install into a parent install - $path = Utils\find_file_upward( $config_files, getcwd(), function ( $dir ) { + return Utils\find_file_upward( $config_files, getcwd(), function ( $dir ) { static $wp_load_count = 0; $wp_load_path = $dir . DIRECTORY_SEPARATOR . 'wp-load.php'; if ( file_exists( $wp_load_path ) ) { @@ -57,22 +53,6 @@ private static function get_config_path( $runtime_config ) { } return $wp_load_count > 1; } ); - - if ( $path ) { - return $path; - } - - // See if there is a global config file specified in the Composer - // install directory - foreach( $config_files as $config_file ) { - foreach( WP_CLI\Utils\get_vendor_paths() as $vendor_path ) { - $config_path = dirname( $vendor_path ) . '/' . $config_file; - if ( file_exists( $config_path ) ) - return $config_path; - } - } - - return false; } private static function set_wp_root( $config ) { @@ -378,16 +358,22 @@ private function check_wp_version() { } private function init_config() { + $this->global_config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + $this->project_config_path = self::get_project_config_path(); + + $configurator = \WP_CLI::get_configurator(); + $this->config = array_merge( + $configurator->get_defaults(), + $configurator->load_config( $this->global_config_path ), + $configurator->load_config( $this->project_config_path ) + ); + list( $args, $assoc_args, $runtime_config ) = \WP_CLI::get_configurator()->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( $args, $assoc_args ); - $this->config_path = self::get_config_path( $runtime_config ); - - $this->config = \WP_CLI::get_configurator()->load_config( $this->config_path ); - foreach ( $runtime_config as $key => $value ) { if ( isset( $this->config[ $key ] ) && is_array( $this->config[ $key ] ) ) { $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index da3a32be62..12e3b108a7 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -237,10 +237,6 @@ static function launch( $command, $exit_on_error = true ) { return $r; } - static function get_config_path() { - return self::get_runner()->config_path; - } - static function get_config( $key = null ) { if ( null === $key ) { return self::get_runner()->config; diff --git a/php/commands/cli.php b/php/commands/cli.php index d0046d4d13..3749b0452c 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -41,11 +41,14 @@ function version() { function info() { $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + $runner = WP_CLI::get_runner(); + WP_CLI::line( "PHP binary:\t" . $php_bin ); WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); WP_CLI::line( "WP-CLI root:\t" . WP_CLI_ROOT ); - WP_CLI::line( "WP-CLI config:\t" . WP_CLI::get_config_path() ); + WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); + WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); } diff --git a/php/config-spec.php b/php/config-spec.php index a2f174769b..f105ca533d 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -1,12 +1,6 @@ <?php return array( - 'config' => array( - 'runtime' => '=<path>', - 'file' => false, - 'desc' => 'Path to the wp-cli config file', - ), - 'path' => array( 'runtime' => '=<path>', 'file' => '<path>', From b980dad962218af3a7d3d1b4c760ecfcf4fd052e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 00:24:33 +0300 Subject: [PATCH 2456/4858] add back deprecated --config global parameter, for backwards compatibility --- php/WP_CLI/Runner.php | 16 ++++++++++------ php/config-spec.php | 5 +++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4436933736..39c237e347 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -360,7 +360,17 @@ private function check_wp_version() { } private function init_config() { + list( $args, $assoc_args, $runtime_config ) = \WP_CLI::get_configurator()->parse_args( + array_slice( $GLOBALS['argv'], 1 ) ); + + list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( + $args, $assoc_args ); + $this->global_config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + if ( isset( $runtime_config['config'] ) ) { + $this->global_config_path = $runtime_config['config']; + } + $this->project_config_path = self::get_project_config_path(); $configurator = \WP_CLI::get_configurator(); @@ -370,12 +380,6 @@ private function init_config() { $configurator->load_config( $this->project_config_path ) ); - list( $args, $assoc_args, $runtime_config ) = \WP_CLI::get_configurator()->parse_args( - array_slice( $GLOBALS['argv'], 1 ) ); - - list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( - $args, $assoc_args ); - foreach ( $runtime_config as $key => $value ) { if ( isset( $this->config[ $key ] ) && is_array( $this->config[ $key ] ) ) { $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); diff --git a/php/config-spec.php b/php/config-spec.php index 4bae081b53..399862e63c 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -17,6 +17,11 @@ 'runtime' => '', ), + 'config' => array( + 'deprecated' => 'Use the WP_CLI_CONFIG_PATH environment variable instead', + 'runtime' => '=<path>', + ), + 'user' => array( 'runtime' => '=<id|login>', 'file' => '<id|login>', From eb6e7a8d686abfbbe84a97274fc4c5bbbe8bb376 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 00:27:40 +0300 Subject: [PATCH 2457/4858] show warning when deprecated global parameter is used --- php/WP_CLI/Configurator.php | 23 ++++++++++++++--------- php/WP_CLI/Runner.php | 4 +--- php/config-spec.php | 6 +++--- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 42b867a7bd..27969b8770 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -57,16 +57,21 @@ function parse_args( $arguments ) { foreach ( $mixed_args as $tmp ) { list( $key, $value ) = $tmp; - $enabled = isset( $this->spec[ $key ] ) ? $this->spec[ $key ]['runtime'] : false; - - if ( false === $enabled ) { - $assoc_args[ $key ] = $value; - } else { - if ( $this->spec[ $key ]['multiple'] ) { - $runtime_config[ $key ][] = $value; - } else { - $runtime_config[ $key ] = $value; + if ( isset( $this->spec[ $key ] ) ) { + $details = $this->spec[ $key ]; + if ( $details['runtime'] ) { + if ( isset( $details['deprecated'] ) ) { + fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" ); + } + + if ( $details['multiple'] ) { + $runtime_config[ $key ][] = $value; + } else { + $runtime_config[ $key ] = $value; + } } + } else { + $assoc_args[ $key ] = $value; } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 39c237e347..643769c180 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -90,8 +90,6 @@ private static function set_user( $assoc_args ) { private static function guess_url( $assoc_args ) { if ( isset( $assoc_args['blog'] ) ) { $assoc_args['url'] = $assoc_args['blog']; - unset( $assoc_args['blog'] ); - WP_CLI::warning( 'The --blog parameter is deprecated. Use --url instead.' ); } if ( isset( $assoc_args['url'] ) ) { @@ -430,7 +428,7 @@ public function before_wp_load() { $this->_run_command(); } - // Handle --url and --blog parameters + // Handle --url parameter $url = self::guess_url( $this->config ); if ( $url ) { $url_parts = self::parse_url( $url ); diff --git a/php/config-spec.php b/php/config-spec.php index 399862e63c..d4e206e7e9 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -13,12 +13,12 @@ 'desc' => 'Pretend request came from given URL', ), 'blog' => array( - 'deprecated' => 'Use --url instead', - 'runtime' => '', + 'deprecated' => 'Use --url instead.', + 'runtime' => '=<url>', ), 'config' => array( - 'deprecated' => 'Use the WP_CLI_CONFIG_PATH environment variable instead', + 'deprecated' => 'Use the WP_CLI_CONFIG_PATH environment variable instead.', 'runtime' => '=<path>', ), From 915fd1c7e7c495258f57eb1e2cdc03bda3f025ae Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 02:09:31 +0300 Subject: [PATCH 2458/4858] initialized configurator on demand --- php/class-wp-cli.php | 15 +++++++-------- php/wp-cli.php | 2 -- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e0996fada0..abe3a59288 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -16,13 +16,6 @@ class WP_CLI { private static $hooks = array(), $hooks_passed = array(); - /** - * Initialize WP_CLI static variables. - */ - static function init() { - self::$configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); - } - /** * Set the logger instance. * @@ -33,7 +26,13 @@ static function set_logger( $logger ) { } static function get_configurator() { - return self::$configurator; + static $configurator; + + if ( !$configurator ) { + $configurator = new WP_CLI\Configurator( WP_CLI_ROOT . '/php/config-spec.php' ); + } + + return $configurator; } static function get_root_command() { diff --git a/php/wp-cli.php b/php/wp-cli.php index 5380e8a271..f1fa299cea 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -12,8 +12,6 @@ \WP_CLI\Utils\load_dependencies(); -WP_CLI::init(); - WP_CLI::get_runner()->before_wp_load(); // Load wp-config.php code, in the global scope From 8f25e9d1dee9e65da7bac40003f2955d699847c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 02:22:12 +0300 Subject: [PATCH 2459/4858] properly merge keys that can contain multiple values --- php/WP_CLI/Configurator.php | 45 +++++++++++++++++-------------------- php/WP_CLI/Runner.php | 8 +++---- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 27969b8770..ed79ee580f 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -5,6 +5,7 @@ class Configurator { private $spec; + private $config = array(); function __construct( $path ) { $this->spec = include $path; @@ -17,11 +18,17 @@ function __construct( $path ) { 'multiple' => false, ); - foreach ( $this->spec as &$option ) { - $option = array_merge( $defaults, $option ); + foreach ( $this->spec as $key => &$details ) { + $details = array_merge( $defaults, $details ); + + $this->config[ $key ] = $details['default']; } } + function to_array() { + return $this->config; + } + /** * Get configuration specification, i.e. list of accepted keys. * @@ -80,8 +87,6 @@ function parse_args( $arguments ) { /** * Load values from a YML file and sanitize them according to the spec. - * - * @return array */ function load_config( $yml_file ) { if ( $yml_file ) @@ -89,40 +94,32 @@ function load_config( $yml_file ) { else $config = array(); - $sanitized_config = array(); - foreach ( $this->spec as $key => $details ) { if ( $details['file'] && isset( $config[ $key ] ) ) { $value = $config[ $key ]; - if ( $details['multiple'] && !is_array( $value ) ) { - $value = array( $value ); - } + if ( $details['multiple'] ) { + if ( !is_array( $value ) ) { + $value = array( $value ); + } - $sanitized_config[ $key ] = $value; + $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); + } else { + $this->config[ $key ] = $value; + } } } // Make sure config-file-relative paths are made absolute. $yml_file_dir = dirname( $yml_file ); - if ( isset( $sanitized_config['path'] ) ) - self::absolutize( $sanitized_config['path'], $yml_file_dir ); + if ( isset( $this->config['path'] ) ) + self::absolutize( $this->config['path'], $yml_file_dir ); - if ( isset( $sanitized_config['require'] ) ) { - foreach ( $sanitized_config['require'] as &$path ) { + if ( isset( $this->config['require'] ) ) { + foreach ( $this->config['require'] as &$path ) { self::absolutize( $path, $yml_file_dir ); } } - - return $sanitized_config; - } - - public function get_defaults() { - $defaults = array(); - foreach ( $this->spec as $key => $details ) { - $defaults[ $key ] = $details['default']; - } - return $defaults; } private static function absolutize( &$path, $base ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 643769c180..e70b429ea9 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -372,11 +372,9 @@ private function init_config() { $this->project_config_path = self::get_project_config_path(); $configurator = \WP_CLI::get_configurator(); - $this->config = array_merge( - $configurator->get_defaults(), - $configurator->load_config( $this->global_config_path ), - $configurator->load_config( $this->project_config_path ) - ); + $configurator->load_config( $this->global_config_path ); + $configurator->load_config( $this->project_config_path ); + $this->config = $configurator->to_array(); foreach ( $runtime_config as $key => $value ) { if ( isset( $this->config[ $key ] ) && is_array( $this->config[ $key ] ) ) { From 1c4d4bea0c18a11d57ee71ec3d0d6036b387fcbe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 03:08:07 +0300 Subject: [PATCH 2460/4858] fix case where a file-only config key would make a runtime arg of the same name disappear --- php/WP_CLI/Configurator.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index ed79ee580f..ff2d20456b 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -64,18 +64,17 @@ function parse_args( $arguments ) { foreach ( $mixed_args as $tmp ) { list( $key, $value ) = $tmp; - if ( isset( $this->spec[ $key ] ) ) { + if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] ) { $details = $this->spec[ $key ]; - if ( $details['runtime'] ) { - if ( isset( $details['deprecated'] ) ) { - fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" ); - } - if ( $details['multiple'] ) { - $runtime_config[ $key ][] = $value; - } else { - $runtime_config[ $key ] = $value; - } + if ( isset( $details['deprecated'] ) ) { + fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" ); + } + + if ( $details['multiple'] ) { + $runtime_config[ $key ][] = $value; + } else { + $runtime_config[ $key ] = $value; } } else { $assoc_args[ $key ] = $value; From 6b26aad4a4bd9c53c5f2294ee02848687978a74f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 03:13:52 +0300 Subject: [PATCH 2461/4858] global flags have 'runtime' key '', which is falsy --- php/WP_CLI/Configurator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index ff2d20456b..7be52c1b9c 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -64,7 +64,7 @@ function parse_args( $arguments ) { foreach ( $mixed_args as $tmp ) { list( $key, $value ) = $tmp; - if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] ) { + if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) { $details = $this->spec[ $key ]; if ( isset( $details['deprecated'] ) ) { From 19fb920fbae11001f120957420c3626029a5a186 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 03:14:50 +0300 Subject: [PATCH 2462/4858] separate YAML parsing from config merging --- php/WP_CLI/Configurator.php | 30 ++------------------------ php/WP_CLI/Runner.php | 42 +++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 7be52c1b9c..791c6c5a14 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -84,47 +84,21 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args, $runtime_config ); } - /** - * Load values from a YML file and sanitize them according to the spec. - */ - function load_config( $yml_file ) { - if ( $yml_file ) - $config = spyc_load_file( $yml_file ); - else - $config = array(); - + function merge_config( $config ) { foreach ( $this->spec as $key => $details ) { if ( $details['file'] && isset( $config[ $key ] ) ) { $value = $config[ $key ]; + if ( $details['multiple'] ) { if ( !is_array( $value ) ) { $value = array( $value ); } - $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); } else { $this->config[ $key ] = $value; } } } - - // Make sure config-file-relative paths are made absolute. - $yml_file_dir = dirname( $yml_file ); - - if ( isset( $this->config['path'] ) ) - self::absolutize( $this->config['path'], $yml_file_dir ); - - if ( isset( $this->config['require'] ) ) { - foreach ( $this->config['require'] as &$path ) { - self::absolutize( $path, $yml_file_dir ); - } - } - } - - private static function absolutize( &$path, $base ) { - if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { - $path = $base . DIRECTORY_SEPARATOR . $path; - } } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e70b429ea9..498815bd43 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -372,20 +372,44 @@ private function init_config() { $this->project_config_path = self::get_project_config_path(); $configurator = \WP_CLI::get_configurator(); - $configurator->load_config( $this->global_config_path ); - $configurator->load_config( $this->project_config_path ); + foreach ( array( $this->global_config_path, $this->project_config_path ) as $config_path ) { + $configurator->merge_config( self::load_config( $config_path ) ); + } + $configurator->merge_config( $runtime_config ); $this->config = $configurator->to_array(); - foreach ( $runtime_config as $key => $value ) { - if ( isset( $this->config[ $key ] ) && is_array( $this->config[ $key ] ) ) { - $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); - } else { - $this->config[ $key ] = $value; + if ( !isset( $this->config['path'] ) ) { + $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); + } + } + + /** + * Load values from a YML file. + */ + private static function load_config( $yml_file ) { + if ( !$yml_file ) + return array(); + + $config = spyc_load_file( $yml_file ); + + // Make sure config-file-relative paths are made absolute. + $yml_file_dir = dirname( $yml_file ); + + if ( isset( $config['path'] ) ) + self::absolutize( $config['path'], $yml_file_dir ); + + if ( isset( $config['require'] ) ) { + foreach ( $config['require'] as &$path ) { + self::absolutize( $path, $yml_file_dir ); } } - if ( !isset( $this->config['path'] ) ) { - $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); + return $config; + } + + private static function absolutize( &$path, $base ) { + if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { + $path = $base . DIRECTORY_SEPARATOR . $path; } } From c848c9c3bc39c1ed161d716808b0b5579b0b863d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 03:34:03 +0300 Subject: [PATCH 2463/4858] arrayify require: key --- php/WP_CLI/Runner.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 498815bd43..42a943dae2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -399,6 +399,7 @@ private static function load_config( $yml_file ) { self::absolutize( $config['path'], $yml_file_dir ); if ( isset( $config['require'] ) ) { + self::arrayify( $config['require'] ); foreach ( $config['require'] as &$path ) { self::absolutize( $path, $yml_file_dir ); } @@ -407,6 +408,12 @@ private static function load_config( $yml_file ) { return $config; } + private static function arrayify( &$val ) { + if ( !is_array( $val ) ) { + $val = array( $val ); + } + } + private static function absolutize( &$path, $base ) { if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { $path = $base . DIRECTORY_SEPARATOR . $path; From d6d8771791e7e9a71dacabe8371608e095520798 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 24 Oct 2013 03:53:28 +0300 Subject: [PATCH 2464/4858] behat: replace --config with WP_CLI_CONFIG_PATH --- features/flags.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/flags.feature b/features/flags.feature index 8f290a0a74..9d1dcc93ee 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -134,7 +134,7 @@ Feature: Global flags This is a custom command. """ - When I run `wp --config=wp-cli2.yml test req 'This is a custom command.'` + When I run `WP_CLI_CONFIG_PATH=wp-cli2.yml wp test req 'This is a custom command.'` Then STDOUT should contain: """ This is a custom command. From 4fff53f07a111a6b16751701489a270d2c1692fc Mon Sep 17 00:00:00 2001 From: wojsmol <wojsmol@wp.pl> Date: Thu, 24 Oct 2013 20:57:06 +0200 Subject: [PATCH 2465/4858] Change cd $(wp theme path) is cd $(wp plugin path) in plugin.php --- php/commands/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 3bb17465fd..a9a2e838b4 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -220,7 +220,7 @@ function toggle( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * cd $(wp theme path) + * cd $(wp plugin path) */ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); From 7a1499e0a3683f9d51dc18d73d8b087685a9e318 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Oct 2013 00:39:57 +0300 Subject: [PATCH 2466/4858] set default global config path; also, ignore if config file doesn't exist see #698 --- php/WP_CLI/Runner.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 42a943dae2..2e59a706ab 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -37,6 +37,22 @@ private function do_early_invoke( $when ) { } } + private static function get_global_config_path() { + $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + if ( isset( $runtime_config['config'] ) ) { + $config_path = $runtime_config['config']; + } + + if ( !$config_path ) { + $config_path = getenv( 'HOME' ) . '/.config/wp-cli.yml'; + } + + if ( !is_readable( $config_path ) ) + return false; + + return $config_path; + } + private static function get_project_config_path() { $config_files = array( 'wp-cli.local.yml', @@ -364,11 +380,7 @@ private function init_config() { list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( $args, $assoc_args ); - $this->global_config_path = getenv( 'WP_CLI_CONFIG_PATH' ); - if ( isset( $runtime_config['config'] ) ) { - $this->global_config_path = $runtime_config['config']; - } - + $this->global_config_path = self::get_global_config_path(); $this->project_config_path = self::get_project_config_path(); $configurator = \WP_CLI::get_configurator(); From 570b8b078a37a95ef4c6b3390aad3371d264c9c3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Oct 2013 01:04:46 +0300 Subject: [PATCH 2467/4858] move link to contributor guide higher up --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index abb95cf6d9..c334da4859 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ WP-CLI -======== +====== [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) @@ -17,15 +17,20 @@ For documentation and examples, check out [wp-cli.org](http://wp-cli.org/) and t Also, WordPress Answers has a growing list of [WP-CLI related questions](http://wordpress.stackexchange.com/questions/tagged/wp-cli). +If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. + I'm running into troubles, what can I do? ----------------------------------------- To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). If you're reporting a bug, please also post the output from `wp --info`. +How can I help? +--------------- +See [CONTRIBUTING.md](CONTRIBUTING.md). + Credits ------- - Besides the libraries defined in [composer.json](composer.json), we have used code or ideas from the following projects: * [Drush](http://drush.ws/) for... a lot of things @@ -41,9 +46,3 @@ Who's behind this thing? We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). - -Contributing ------------- -See [CONTRIBUTING.md](CONTRIBUTING.md). - -If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. From 370d40c047e2b448f77a668734691955bca475b4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Oct 2013 01:18:07 +0300 Subject: [PATCH 2468/4858] behat: avoid making a request to the wp.org API each time a wp-config.php is needed it's not worth it for throwaway test installs --- features/bootstrap/FeatureContext.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 498e442b27..35d921724a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -162,8 +162,12 @@ public function download_wp( $subdir = '' ) { copy( __DIR__ . '/../extra/no-mail.php', $dest_dir . '/wp-content/mu-plugins/no-mail.php' ); } - public function create_config() { - $this->proc( 'wp core config', self::$db_settings )->run_check(); + public function create_config( $subdir = '' ) { + $params = self::$db_settings; + $params['dbprefix'] = $subdir ?: 'wp_'; + + $params['skip-salts'] = true; + $this->proc( 'wp core config', $params )->run_check( $subdir ); } public function install_wp( $subdir = '' ) { @@ -171,10 +175,7 @@ public function install_wp( $subdir = '' ) { $this->create_run_dir(); $this->download_wp( $subdir ); - $db_args = self::$db_settings; - $db_args['dbprefix'] = $subdir ?: 'wp_'; - - $this->proc( 'wp core config', $db_args )->run_check( $subdir ); + $this->create_config( $subdir ); $install_args = array( 'url' => 'http://example.com', From 8b97fa9f156c40f2adb277f8ee42479fbb808145 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 26 Oct 2013 23:28:57 +0300 Subject: [PATCH 2469/4858] replace 'subcommand' with 'command' in doc strings and inline comments see #848 --- bin/wp | 2 +- features/config.feature | 2 +- php/WP_CLI/Dispatcher/CompositeCommand.php | 4 ++-- templates/man-params.mustache | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/wp b/bin/wp index 4974e1887e..25ea35d275 100755 --- a/bin/wp +++ b/bin/wp @@ -40,7 +40,7 @@ else fi # Pass in the path to php so that wp-cli knows which one -# to use if it re-launches itself to run subcommands +# to use if it re-launches itself to run other commands. export WP_CLI_PHP_USED="$php" exec "$php" $WP_CLI_PHP_ARGS "$SCRIPT_PATH" "$@" diff --git a/features/config.feature b/features/config.feature index 42dfe081f1..6771d130d1 100644 --- a/features/config.feature +++ b/features/config.feature @@ -67,7 +67,7 @@ Feature: Have a config file wp-cli.yml """ - Scenario: Disabled subcommands + Scenario: Disabled commands Given an empty directory And a config.yml file: """ diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 98cbbe734f..f57d1f9249 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -56,7 +56,7 @@ function get_longdesc() { } function get_synopsis() { - return '<subcommand>'; + return '<command>'; } function invoke( $args, $assoc_args ) { @@ -75,7 +75,7 @@ function show_usage() { } \WP_CLI::line(); - \WP_CLI::line( "See 'wp help $this->name <subcommand>' for more information on a specific subcommand." ); + \WP_CLI::line( "See 'wp help $this->name <command>' for more information on a specific command." ); } function find_subcommand( &$args ) { diff --git a/templates/man-params.mustache b/templates/man-params.mustache index 2d3383f57f..990412b748 100644 --- a/templates/man-params.mustache +++ b/templates/man-params.mustache @@ -5,4 +5,4 @@ {{desc}} {{/parameters}} -Run 'wp help <subcommand>' to get more information on a specific command. +Run 'wp help <command>' to get more information on a specific command. From ef23a97bdafeaac00061ed54913fd500e02a78b5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 27 Oct 2013 23:29:53 +0200 Subject: [PATCH 2470/4858] behat: split step definition files --- features/bootstrap/FeatureContext.php | 2 +- features/steps/given.php | 105 +++++++++++++++ features/steps/{basic_steps.php => then.php} | 134 ------------------- features/steps/when.php | 39 ++++++ 4 files changed, 145 insertions(+), 135 deletions(-) create mode 100644 features/steps/given.php rename features/steps/{basic_steps.php => then.php} (54%) create mode 100644 features/steps/when.php diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 35d921724a..d1650f5ba7 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -79,7 +79,7 @@ public function __construct( array $parameters ) { } public function getStepDefinitionResources() { - return array( __DIR__ . '/../steps/basic_steps.php' ); + return glob( __DIR__ . '/../steps/*.php' ); } public function getHookDefinitionResources() { diff --git a/features/steps/given.php b/features/steps/given.php new file mode 100644 index 0000000000..998a013139 --- /dev/null +++ b/features/steps/given.php @@ -0,0 +1,105 @@ +<?php + +use Behat\Gherkin\Node\PyStringNode, + Behat\Gherkin\Node\TableNode; + +$steps->Given( '/^an empty directory$/', + function ( $world ) { + $world->create_run_dir(); + } +); + +$steps->Given( '/^a ([^\s]+) file:$/', + function ( $world, $path, PyStringNode $content ) { + $content = (string) $content . "\n"; + $full_path = $world->variables['RUN_DIR'] . "/$path"; + Process::create( \WP_CLI\utils\esc_cmd( 'mkdir -p %s', dirname( $full_path ) ) )->run_check(); + file_put_contents( $full_path, $content ); + } +); + +$steps->Given( '/^WP files$/', + function ( $world ) { + $world->download_wp(); + } +); + +$steps->Given( '/^wp-config\.php$/', + function ( $world ) { + $world->create_config(); + } +); + +$steps->Given( '/^a database$/', + function ( $world ) { + $world->create_db(); + } +); + +$steps->Given( '/^a WP install$/', + function ( $world ) { + $world->install_wp(); + } +); + +$steps->Given( "/^a WP install in '([^\s]+)'$/", + function ( $world, $subdir ) { + $world->install_wp( $subdir ); + } +); + +$steps->Given( '/^a WP multisite install$/', + function ( $world ) { + $world->install_wp(); + $world->proc( 'wp core install-network', array( 'title' => 'WP CLI Network' ) )->run_check(); + } +); + +$steps->Given( '/^a custom wp-content directory$/', + function ( $world ) { + $wp_config_path = $world->variables['RUN_DIR'] . "/wp-config.php"; + + $wp_config_code = file_get_contents( $wp_config_path ); + + $world->move_files( 'wp-content', 'my-content' ); + $world->add_line_to_wp_config( $wp_config_code, + "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); + + $world->move_files( 'my-content/plugins', 'my-plugins' ); + $world->add_line_to_wp_config( $wp_config_code, + "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); + + file_put_contents( $wp_config_path, $wp_config_code ); + } +); + +$steps->Given( '/^download:$/', + function ( $world, TableNode $table ) { + foreach ( $table->getHash() as $row ) { + $path = $world->replace_variables( $row['path'] ); + if ( file_exists( $path ) ) { + // assume it's the same file and skip re-download + continue; + } + + \Process::create( \WP_CLI\Utils\esc_cmd( 'curl -sSL %s > %s', $row['url'], $path ) )->run_check(); + } + } +); + +$steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', + function ( $world, $stream, $output_filter, $key ) { + + if ( $output_filter ) { + $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; + if ( false !== preg_match( $output_filter, $world->result->$stream, $matches ) ) + $output = array_pop( $matches ); + else + $output = ''; + } else { + $output = $world->result->$stream; + } + $world->variables[ $key ] = trim( $output, "\n" ); + } +); + diff --git a/features/steps/basic_steps.php b/features/steps/then.php similarity index 54% rename from features/steps/basic_steps.php rename to features/steps/then.php index 44342b50b1..75845c0fa3 100644 --- a/features/steps/basic_steps.php +++ b/features/steps/then.php @@ -3,140 +3,6 @@ use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; -function invoke_proc( $proc, $mode, $subdir = null ) { - $map = array( - 'run' => 'run_check', - 'try' => 'run' - ); - $method = $map[ $mode ]; - - return $proc->$method( $subdir ); -} - -$steps->Given( '/^an empty directory$/', - function ( $world ) { - $world->create_run_dir(); - } -); - -$steps->Given( '/^a ([^\s]+) file:$/', - function ( $world, $path, PyStringNode $content ) { - $content = (string) $content . "\n"; - $full_path = $world->variables['RUN_DIR'] . "/$path"; - Process::create( \WP_CLI\utils\esc_cmd( 'mkdir -p %s', dirname( $full_path ) ) )->run_check(); - file_put_contents( $full_path, $content ); - } -); - -$steps->Given( '/^WP files$/', - function ( $world ) { - $world->download_wp(); - } -); - -$steps->Given( '/^wp-config\.php$/', - function ( $world ) { - $world->create_config(); - } -); - -$steps->Given( '/^a database$/', - function ( $world ) { - $world->create_db(); - } -); - -$steps->Given( '/^a WP install$/', - function ( $world ) { - $world->install_wp(); - } -); - -$steps->Given( "/^a WP install in '([^\s]+)'$/", - function ( $world, $subdir ) { - $world->install_wp( $subdir ); - } -); - -$steps->Given( '/^a WP multisite install$/', - function ( $world ) { - $world->install_wp(); - $world->proc( 'wp core install-network', array( 'title' => 'WP CLI Network' ) )->run_check(); - } -); - -$steps->Given( '/^a custom wp-content directory$/', - function ( $world ) { - $wp_config_path = $world->variables['RUN_DIR'] . "/wp-config.php"; - - $wp_config_code = file_get_contents( $wp_config_path ); - - $world->move_files( 'wp-content', 'my-content' ); - $world->add_line_to_wp_config( $wp_config_code, - "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" ); - - $world->move_files( 'my-content/plugins', 'my-plugins' ); - $world->add_line_to_wp_config( $wp_config_code, - "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" ); - - file_put_contents( $wp_config_path, $wp_config_code ); - } -); - -$steps->Given( '/^download:$/', - function ( $world, TableNode $table ) { - foreach ( $table->getHash() as $row ) { - $path = $world->replace_variables( $row['path'] ); - if ( file_exists( $path ) ) { - // assume it's the same file and skip re-download - continue; - } - - \Process::create( \WP_CLI\Utils\esc_cmd( 'curl -sSL %s > %s', $row['url'], $path ) )->run_check(); - } - } -); - -$steps->When( '/^I (run|try) `([^`]+)`$/', - function ( $world, $mode, $cmd ) { - $cmd = $world->replace_variables( $cmd ); - $world->result = invoke_proc( $world->proc( $cmd ), $mode ); - } -); - -$steps->When( "/^I (run|try) `([^`]+)` from '([^\s]+)'$/", - function ( $world, $mode, $cmd, $subdir ) { - $cmd = $world->replace_variables( $cmd ); - $world->result = invoke_proc( $world->proc( $cmd ), $mode, $subdir ); - } -); - -$steps->When( '/^I (run|try) the previous command again$/', - function ( $world, $mode ) { - if ( !isset( $world->result ) ) - throw new \Exception( 'No previous command.' ); - - $proc = Process::create( $world->result->command, $world->result->cwd, $world->result->env ); - $world->result = invoke_proc( $proc, $mode ); - } -); - -$steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', - function ( $world, $stream, $output_filter, $key ) { - - if ( $output_filter ) { - $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; - if ( false !== preg_match( $output_filter, $world->result->$stream, $matches ) ) - $output = array_pop( $matches ); - else - $output = ''; - } else { - $output = $world->result->$stream; - } - $world->variables[ $key ] = trim( $output, "\n" ); - } -); - $steps->Then( '/^the return code should be (\d+)$/', function ( $world, $return_code ) { if ( $return_code != $world->result->return_code ) { diff --git a/features/steps/when.php b/features/steps/when.php new file mode 100644 index 0000000000..81b4c9a6d2 --- /dev/null +++ b/features/steps/when.php @@ -0,0 +1,39 @@ +<?php + +use Behat\Gherkin\Node\PyStringNode, + Behat\Gherkin\Node\TableNode; + +function invoke_proc( $proc, $mode, $subdir = null ) { + $map = array( + 'run' => 'run_check', + 'try' => 'run' + ); + $method = $map[ $mode ]; + + return $proc->$method( $subdir ); +} + +$steps->When( '/^I (run|try) `([^`]+)`$/', + function ( $world, $mode, $cmd ) { + $cmd = $world->replace_variables( $cmd ); + $world->result = invoke_proc( $world->proc( $cmd ), $mode ); + } +); + +$steps->When( "/^I (run|try) `([^`]+)` from '([^\s]+)'$/", + function ( $world, $mode, $cmd, $subdir ) { + $cmd = $world->replace_variables( $cmd ); + $world->result = invoke_proc( $world->proc( $cmd ), $mode, $subdir ); + } +); + +$steps->When( '/^I (run|try) the previous command again$/', + function ( $world, $mode ) { + if ( !isset( $world->result ) ) + throw new \Exception( 'No previous command.' ); + + $proc = Process::create( $world->result->command, $world->result->cwd, $world->result->env ); + $world->result = invoke_proc( $proc, $mode ); + } +); + From fb4258e554bc9ef29278480e88b120849fcc35e6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 27 Oct 2013 23:39:01 +0200 Subject: [PATCH 2471/4858] behat: always show all the details when an error occurs --- features/steps/then.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/features/steps/then.php b/features/steps/then.php index 75845c0fa3..f638004670 100644 --- a/features/steps/then.php +++ b/features/steps/then.php @@ -52,7 +52,7 @@ function ( $world, TableNode $expected ) { $start = array_search( $expected_rows[0], $actual_rows ); if ( false === $start ) - throw new \Exception( $output ); + throw new \Exception( $world->result ); compareTables( $expected_rows, array_slice( $actual_rows, $start ), $output ); } @@ -64,7 +64,7 @@ function ( $world, PyStringNode $expected ) { $expected = $world->replace_variables( (string) $expected ); if ( !checkThatJsonStringContainsJsonString( $output, $expected ) ) { - throw new \Exception( $output ); + throw new \Exception( $world->result ); } }); @@ -78,7 +78,7 @@ function ( $world, PyStringNode $expected ) { $missing = array_diff( $expectedValues, $actualValues ); if ( !empty( $missing ) ) { - throw new \Exception( $output ); + throw new \Exception( $world->result ); } }); @@ -94,14 +94,14 @@ function ( $world, TableNode $expected ) { } if ( ! checkThatCsvStringContainsValues( $output, $expected_rows ) ) - throw new \Exception( $output ); + throw new \Exception( $world->result ); } ); $steps->Then( '/^(STDOUT|STDERR) should be empty$/', function ( $world, $stream ) { if ( !empty( $world->result->$stream ) ) { - throw new \Exception( $world->result->$stream ); + throw new \Exception( $world->result ); } } ); @@ -109,7 +109,7 @@ function ( $world, $stream ) { $steps->Then( '/^(STDOUT|STDERR) should not be empty$/', function ( $world, $stream ) { if ( '' === rtrim( $world->result->$stream, "\n" ) ) { - throw new Exception( "$stream is empty." ); + throw new Exception( $world->result ); } } ); @@ -125,12 +125,12 @@ function ( $world, $path, $action, $expected = null ) { switch ( $action ) { case 'exist': if ( !file_exists( $path ) ) { - throw new Exception( "$path doesn't exist." ); + throw new Exception( $world->result ); } break; case 'not exist': if ( file_exists( $path ) ) { - throw new Exception( "$path exists." ); + throw new Exception( $world->result ); } break; default: From 89da305935cc6c2cc388b32c02166b2dbfce3372 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 27 Oct 2013 23:58:59 +0200 Subject: [PATCH 2472/4858] behat: show downloaded core version particularly useful when WP_VERSION=latest --- ci/prepare.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/prepare.sh b/ci/prepare.sh index 2a5b0e8e82..5627017400 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -19,6 +19,7 @@ curl http://behat.org/downloads/behat.phar > behat.phar ./ci/prepare-codesniffer.sh ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' +./bin/wp core version --path='/tmp/wp-cli-test core-download-cache/' mysql -e 'CREATE DATABASE wp_cli_test;' -uroot mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot From d8dda0714a8b2432f563923587085a50d8af5f06 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 28 Oct 2013 00:37:47 +0200 Subject: [PATCH 2473/4858] travis: test against WP 3.6.1 for now; see #846 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e36beae361..a5bf15a94f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=latest + - WP_VERSION=3.6.1 - WP_VERSION=3.4.2 DEPLOY_BRANCH=master matrix: From 30eafbd71ba740c0bf7a7b3a85d4c1a9b06b7d19 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 28 Oct 2013 21:34:54 +0200 Subject: [PATCH 2474/4858] handle case where request to underscor.es fails see #822 --- php/commands/scaffold.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f7ba9b89e4..31e672109e 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -203,12 +203,20 @@ function _s( $args, $assoc_args ) { $tmpfname = wp_tempnam($url); $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); - if ( !is_wp_error( $response ) && $response['response']['code'] == 200 ) - WP_CLI::success( "Created theme '".$data['theme_name']."'." ); + if ( is_wp_error( $response ) ) { + WP_CLI::error( $response ); + } + + $response_code = wp_remote_retrieve_response_code( $response ); + if ( 200 != $response_code ) { + WP_CLI::error( "Couldn't create theme (received $response_code response)." ); + } unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); + WP_CLI::success( "Created theme '{$data['theme_name']}'." ); + if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); From 49dc008412aa845b62a5f6193d06552828f5de94 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 28 Oct 2013 21:43:15 +0200 Subject: [PATCH 2475/4858] move OS detection to launch_editor_for_input() see #822 --- php/commands/post.php | 3 +-- php/utils.php | 15 ++++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 0dfc2763db..c4d8f24ba2 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -123,8 +123,7 @@ public function edit( $args, $_ ) { protected function _edit( $content, $title ) { $content = apply_filters( 'the_editor_content', $content ); - $os = strpos( $_SERVER['OS'], 'indows' )===false ? 'linux' : 'windows'; - $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title, $os ); + $output = \WP_CLI\Utils\launch_editor_for_input( $content, $title ); return ( is_string( $output ) ) ? apply_filters( 'content_save_pre', $output ) : $output; } diff --git a/php/utils.php b/php/utils.php index 1b7d956fa6..23f6d5e362 100644 --- a/php/utils.php +++ b/php/utils.php @@ -256,7 +256,7 @@ function pick_fields( $item, $fields ) { * @return str|bool Edited text, if file is saved from editor * False, if no change to file */ -function launch_editor_for_input( $input, $title = 'WP-CLI', $os='linux' ) { +function launch_editor_for_input( $input, $title = 'WP-CLI' ) { $tmpfile = wp_tempnam( $title ); @@ -266,10 +266,15 @@ function launch_editor_for_input( $input, $title = 'WP-CLI', $os='linux' ) { $output = ''; file_put_contents( $tmpfile, $input ); - if( $os==='linux' ) - \WP_CLI::launch( "\${EDITOR:-vi} '$tmpfile'" ); - else - exec("notepad $tmpfile" ); + $editor = getenv( 'EDITOR' ); + if ( !$editor ) { + if ( isset( $_SERVER['OS'] ) && false !== strpos( $_SERVER['OS'], 'indows' ) ) + $editor = 'notepad'; + else + $editor = 'vi'; + } + + \WP_CLI::launch( \WP_CLI\Utils\esc_cmd( "$editor %s", $tmpfile ) ); $output = file_get_contents( $tmpfile ); From c6c0a4ddeff4c565ca090488b7e554dee730c4b4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 28 Oct 2013 21:55:41 +0200 Subject: [PATCH 2476/4858] use escapeshellarg() instead of esc_cmd(), because the $editor variable can contain %s see #822 --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 23f6d5e362..d1713b54e1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -274,7 +274,7 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { $editor = 'vi'; } - \WP_CLI::launch( \WP_CLI\Utils\esc_cmd( "$editor %s", $tmpfile ) ); + \WP_CLI::launch( "$editor " . escapeshellarg( $tmpfile ) ); $output = file_get_contents( $tmpfile ); From 5b7bfb25ef6b33934a404474a253af5eada90946 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 30 Oct 2013 13:40:38 +0200 Subject: [PATCH 2477/4858] replace rename() with copy() + unlink() --- php/commands/core.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index b0ddcd23ba..97ebc1ecce 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -111,7 +111,10 @@ private static function _move_overwrite_files( $source, $dest ) { rmdir( $src ); continue; } - rename( $src, $dst ); + + // rename() is not reliable inside VMs: https://github.com/wp-cli/wp-cli/issues/853 + copy( $src, $dst ); + unlink( $src ); } rmdir( $source ); } From 532bb25f29a713cfff6466b52bcf31f17a4800c1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 30 Oct 2013 14:06:26 +0200 Subject: [PATCH 2478/4858] first copy all the files, then remove the temporary dir --- php/commands/core.php | 48 ++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 97ebc1ecce..d129ac67f5 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -87,36 +87,38 @@ private static function _extract( $tarball, $dest ) { $phar->extractTo( dirname( $tempdir ), null, true ); - self::_move_overwrite_files( $tempdir, $dest ); + self::_copy_overwrite_files( $tempdir, $dest ); - rmdir( dirname( $tempdir ) ); + self::_rmdir( dirname( $tempdir ) ); } - private static function _move_overwrite_files( $source, $dest ) { - $flags = FilesystemIterator::SKIP_DOTS - | FilesystemIterator::KEY_AS_PATHNAME - | FilesystemIterator::CURRENT_AS_FILEINFO; - - $dstOffset = strlen( $source ); + private static function _copy_overwrite_files( $source, $dest ) { + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( $source, RecursiveDirectoryIterator::SKIP_DOTS ), + RecursiveIteratorIterator::SELF_FIRST); + + foreach ( $iterator as $item ) { + if ( $item->isDir() ) { + $dest_path = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); + if ( !is_dir( $dest_path ) ) { + mkdir( $dest_path ); + } + } else { + copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ); + } + } + } - foreach( new RecursiveIteratorIterator ( - new RecursiveDirectoryIterator( $source, $flags ), + private static function _rmdir( $dir ) { + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( $dir, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST - ) as $src ) { - $dst = $dest . substr( $src, $dstOffset ); - $dstdir = dirname( $dst ); - if ( ! is_dir( $dstdir ) ) continue; - - if ( $src->isDir() && is_dir( $dst ) ) { - rmdir( $src ); - continue; - } + ); - // rename() is not reliable inside VMs: https://github.com/wp-cli/wp-cli/issues/853 - copy( $src, $dst ); - unlink( $src ); + foreach ( $files as $fileinfo ) { + $todo = $fileinfo->isDir() ? 'rmdir' : 'unlink'; + $todo( $fileinfo->getRealPath() ); } - rmdir( $source ); } private static function _request( $method, $url, $headers = array(), $options = array() ) { From 5c52aa949334a205932ffc1f10426c814d9632a7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 30 Oct 2013 14:18:34 +0200 Subject: [PATCH 2479/4858] bump version to 0.13-alpha3 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index f1fa299cea..ebeac71ea4 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13-alpha2' ); +define( 'WP_CLI_VERSION', '0.13-alpha3' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From fd211be75df0f101777ffa8c280f8892cefb65ca Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 30 Oct 2013 14:19:57 +0200 Subject: [PATCH 2480/4858] travis: switch back to WP_VERSION=latest see #846 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a5bf15a94f..4bff5686fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=3.6.1 + - WP_VERSION=latest - WP_VERSION=3.4.2 DEPLOY_BRANCH=master matrix: From d133837c8c494b03ca4b068b7de8c178518b80cd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Nov 2013 23:39:35 +0200 Subject: [PATCH 2481/4858] test against latest stable release of WP, instead of the master revision from the github mirror --- templates/.travis.yml | 4 ++-- templates/install-wp-tests.sh | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index de2d819e56..4f688b98d4 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -5,8 +5,8 @@ php: - 5.4 env: - - WP_VERSION=master WP_MULTISITE=0 - - WP_VERSION=master WP_MULTISITE=1 + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=latest WP_MULTISITE=1 - WP_VERSION=3.5.1 WP_MULTISITE=0 - WP_VERSION=3.5.1 WP_MULTISITE=1 diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 82cd598ed8..2320e61fd0 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -16,7 +16,14 @@ set -ex # set up a WP install WP_CORE_DIR=/tmp/wordpress/ mkdir -p $WP_CORE_DIR -wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION + +if [ $WP_VERSION == 'latest' ]; then + ARCHIVE_NAME='latest' +else + ARCHIVE_NAME="wordpress-$WP_VERSION" +fi + +wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR # set up testing suite From d72b08d3ee9a78a568454554b0779c03fe3c168e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 1 Nov 2013 23:47:42 +0200 Subject: [PATCH 2482/4858] bump previous tested version to 3.6.1 --- templates/.travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 4f688b98d4..bc729686e9 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -7,8 +7,8 @@ php: env: - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.5.1 WP_MULTISITE=0 - - WP_VERSION=3.5.1 WP_MULTISITE=1 + - WP_VERSION=3.6.1 WP_MULTISITE=0 + - WP_VERSION=3.6.1 WP_MULTISITE=1 before_script: - export WP_TESTS_DIR=/tmp/wordpress-tests/ From 64bce08a4dffc581a2eb57204cb21ac7bbeb1f0b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 4 Nov 2013 10:41:48 -0800 Subject: [PATCH 2483/4858] Include `--path` argument in `wp core download` --- php/commands/core.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index d129ac67f5..d24f497129 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -13,6 +13,9 @@ class Core_Command extends WP_CLI_Command { * Download core WordPress files. * * ## OPTIONS + * + * [--path=<path>] + * : Specify the path in which to install WordPress. * * [--locale=<locale>] * : Select which language you want to download. From 074011c3476645c760e921d8bb1f60ffdda29692 Mon Sep 17 00:00:00 2001 From: Dion Hulse <contact-atlassian@dd32.id.au> Date: Thu, 7 Nov 2013 22:42:42 +1100 Subject: [PATCH 2484/4858] Use the SSL CA bundle that Requests includes, rather than relying upon the systems CA bundle which is often unavailable, or out of date. --- php/commands/core.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d24f497129..2a11de3a74 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -126,7 +126,6 @@ private static function _rmdir( $dir ) { private static function _request( $method, $url, $headers = array(), $options = array() ) { try { - $options['verify'] = true; return Requests::get( $url, $headers, $options ); } catch( Requests_Exception $ex ) { // Handle SSL certificate issues gracefully From 24e296d1af078297c86a6eef49cd5bc0381ce2f2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 7 Nov 2013 18:10:51 +0200 Subject: [PATCH 2485/4858] make cacert.pem file available from Phar; closes #859 --- php/commands/core.php | 12 +++++++++++- utils/make-phar.php | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 2a11de3a74..e0f2d78743 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -13,7 +13,7 @@ class Core_Command extends WP_CLI_Command { * Download core WordPress files. * * ## OPTIONS - * + * * [--path=<path>] * : Specify the path in which to install WordPress. * @@ -125,6 +125,16 @@ private static function _rmdir( $dir ) { } private static function _request( $method, $url, $headers = array(), $options = array() ) { + // cURL can't read Phar archives + if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { + $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; + + copy( + WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem', + $options['verify'] + ); + } + try { return Requests::get( $url, $headers, $options ); } catch( Requests_Exception $ex ) { diff --git a/utils/make-phar.php b/utils/make-phar.php index 0a7b16d83c..4563f60a79 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -62,6 +62,7 @@ function add_file( $phar, $path ) { } add_file( $phar, './vendor/autoload.php' ); +add_file( $phar, './vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); $phar->setStub( <<<EOB #!/usr/bin/env php From a5c0302ba4fd8977b118ffc3a029ad9f72f6e83f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 9 Nov 2013 23:52:40 +0200 Subject: [PATCH 2486/4858] add behat test for #862 --- features/user.feature | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/user.feature b/features/user.feature index 5f3319d117..14ecdf18a0 100644 --- a/features/user.feature +++ b/features/user.feature @@ -4,6 +4,10 @@ Feature: Manage WordPress users Given a WP install Scenario: User CRUD operations + When I try `wp user get bogus-user` + Then the return code should be 1 + And STDOUT should be empty + When I run `wp user create testuser testuser@example.com --porcelain` Then STDOUT should be a number And save STDOUT as {USER_ID} From 60a19d7361bc34d089938ae99da3368106c9ab1f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 9 Nov 2013 23:54:22 +0200 Subject: [PATCH 2487/4858] move utilities for validating user ids/logins to FetcherUser class --- php/WP_CLI/Fetcher.php | 16 +++++++++++++ php/WP_CLI/FetcherUser.php | 41 +++++++++++++++++++++++++++++++++ php/commands/user.php | 47 ++++++++++++++++---------------------- 3 files changed, 77 insertions(+), 27 deletions(-) create mode 100644 php/WP_CLI/Fetcher.php create mode 100644 php/WP_CLI/FetcherUser.php diff --git a/php/WP_CLI/Fetcher.php b/php/WP_CLI/Fetcher.php new file mode 100644 index 0000000000..f1de345c9e --- /dev/null +++ b/php/WP_CLI/Fetcher.php @@ -0,0 +1,16 @@ +<?php + +namespace WP_CLI; + +interface Fetcher { + + // Returns the object if found; otherwise returns false + function get( $id ); + + // Returns the object if found; otherwise calls WP_CLI::error() + function get_check( $id ); + + // Returns the list of found objects + function get_many( $ids ); +} + diff --git a/php/WP_CLI/FetcherUser.php b/php/WP_CLI/FetcherUser.php new file mode 100644 index 0000000000..1ed29bfcb4 --- /dev/null +++ b/php/WP_CLI/FetcherUser.php @@ -0,0 +1,41 @@ +<?php + +namespace WP_CLI; + +class FetcherUser implements Fetcher { + + public function get( $id_or_login ) { + if ( is_numeric( $id_or_login ) ) + $user = get_user_by( 'id', $id_or_login ); + else + $user = get_user_by( 'login', $id_or_login ); + + return $user; + } + + public function get_check( $id_or_login ) { + $user = $this->get( $id_or_login ); + + if ( ! $user ) { + \WP_CLI::error( "Invalid user ID or login: $id_or_login" ); + } + + return $user; + } + + public function get_many( $ids_or_logins ) { + $users = array(); + + foreach ( $ids_or_logins as $id_or_login ) { + $user = $this->get( $id_or_login ); + if ( $user ) { + $users[] = $user; + } else { + \WP_CLI::warning( "Invalid user ID or login: $id_or_login" ); + } + } + + return $users; + } +} + diff --git a/php/commands/user.php b/php/commands/user.php index 95c4d05f31..cf18fcb041 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -17,6 +17,10 @@ class User_Command extends \WP_CLI\CommandWithDBObject { 'roles' ); + public function __construct() { + $this->fetcher = new \WP_CLI\FetcherUser; + } + /** * List users. * @@ -95,7 +99,7 @@ public function _list( $args, $assoc_args ) { * wp user get bob --format=json > bob.json */ public function get( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); if ( method_exists( $user, 'to_array' ) ) { $user_data = $user->to_array(); @@ -129,11 +133,11 @@ public function delete( $args, $assoc_args ) { 'reassign' => null ) ); - foreach ( $args as $key => $arg ) { - $args[ $key ] = self::get_user( $arg )->ID; - } + $users = $this->fetcher->get_many( $args ); + + parent::_delete( $users, $assoc_args, function ( $user, $assoc_args ) { + $user_id = $user->ID; - parent::_delete( $args, $assoc_args, function ( $user_id, $assoc_args ) { if ( is_multisite() ) { $r = wpmu_delete_user( $user_id ); } else { @@ -243,11 +247,13 @@ public function create( $args, $assoc_args ) { * wp user update mary --user_pass=marypass */ public function update( $args, $assoc_args ) { - foreach ( $args as $key => $arg ) { - $args[ $key ] = self::get_user( $arg )->ID; + $user_ids = array(); + + foreach ( $this->fetcher->get_many( $args ) as $user ) { + $user_ids[] = $user->ID; } - parent::_update( $args, $assoc_args, 'wp_update_user' ); + parent::_update( $user_ids, $assoc_args, 'wp_update_user' ); } /** @@ -321,7 +327,7 @@ public function generate( $args, $assoc_args ) { * @subcommand set-role */ public function set_role( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); $role = isset( $args[1] ) ? $args[1] : get_option( 'default_role' ); @@ -353,7 +359,7 @@ public function set_role( $args, $assoc_args ) { * @subcommand add-role */ public function add_role( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); $role = $args[1]; @@ -381,7 +387,7 @@ public function add_role( $args, $assoc_args ) { * @subcommand remove-role */ public function remove_role( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); if ( isset( $args[1] ) ) { $role = $args[1]; @@ -419,7 +425,7 @@ public function remove_role( $args, $assoc_args ) { * @subcommand add-cap */ public function add_cap( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); if ( $user ) { $cap = $args[1]; $user->add_cap( $cap ); @@ -447,7 +453,7 @@ public function add_cap( $args, $assoc_args ) { * @subcommand remove-cap */ public function remove_cap( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); if ( $user ) { $cap = $args[1]; $user->remove_cap( $cap ); @@ -472,7 +478,7 @@ public function remove_cap( $args, $assoc_args ) { * @subcommand list-caps */ public function list_caps( $args, $assoc_args ) { - $user = self::get_user( $args[0] ); + $user = $this->fetcher->get_check( $args[0] ); if ( $user ) { $user->get_role_caps(); @@ -488,19 +494,6 @@ public function list_caps( $args, $assoc_args ) { } } - private static function get_user( $id_or_login ) { - if ( is_numeric( $id_or_login ) ) - $user = get_user_by( 'id', $id_or_login ); - else - $user = get_user_by( 'login', $id_or_login ); - - if ( ! $user ) { - WP_CLI::warning( "Invalid user ID or login: $id_or_login" ); - } - - return $user; - } - /** * Import users from a CSV file. * From 733299f84f7cb39684db91fe010c51648356522d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 00:15:47 +0200 Subject: [PATCH 2488/4858] move utilities for validating plugin names to FetcherPlugin class --- php/WP_CLI/Fetcher.php | 6 +-- php/WP_CLI/FetcherPlugin.php | 57 ++++++++++++++++++++++++ php/commands/plugin.php | 86 ++++++++---------------------------- 3 files changed, 78 insertions(+), 71 deletions(-) create mode 100644 php/WP_CLI/FetcherPlugin.php diff --git a/php/WP_CLI/Fetcher.php b/php/WP_CLI/Fetcher.php index f1de345c9e..58cf01f9b1 100644 --- a/php/WP_CLI/Fetcher.php +++ b/php/WP_CLI/Fetcher.php @@ -4,13 +4,13 @@ interface Fetcher { - // Returns the object if found; otherwise returns false + // Returns the item if found; otherwise returns false function get( $id ); - // Returns the object if found; otherwise calls WP_CLI::error() + // Returns the item if found; otherwise calls WP_CLI::error() function get_check( $id ); - // Returns the list of found objects + // Returns the list of found items function get_many( $ids ); } diff --git a/php/WP_CLI/FetcherPlugin.php b/php/WP_CLI/FetcherPlugin.php new file mode 100644 index 0000000000..03c656905c --- /dev/null +++ b/php/WP_CLI/FetcherPlugin.php @@ -0,0 +1,57 @@ +<?php + +namespace WP_CLI; + +class FetcherPlugin implements Fetcher { + + /** + * @param string $name The plugin slug + * @return string|false The plugin filename + */ + public function get( $name ) { + $plugins = get_plugins( '/' . $name ); + + if ( !empty( $plugins ) ) { + $file = $name . '/' . key( $plugins ); + } else { + $file = $name . '.php'; + + $plugins = get_plugins(); + + if ( !isset( $plugins[$file] ) ) { + return false; + } + } + + return $file; + } + + public function get_check( $name ) { + $file = $this->get( $name ); + + if ( ! $file ) { + \WP_CLI::error( "The '$name' plugin could not be found." ); + } + + return $file; + } + + public function get_many( $args ) { + $plugins = array(); + + foreach ( $args as $name ) { + $file = $this->get( $name ); + if ( $file ) { + $plugins[] = (object) array( + 'name' => $name, + 'file' => $file + ); + } else { + \WP_CLI::warning( "The '$name' plugin could not be found." ); + } + } + + return $plugins; + } +} + diff --git a/php/commands/plugin.php b/php/commands/plugin.php index a9a2e838b4..948fa054ff 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -23,6 +23,8 @@ function __construct() { require_once ABSPATH.'wp-admin/includes/plugin-install.php'; parent::__construct(); + + $this->fetcher = new \WP_CLI\FetcherPlugin; } protected function get_upgrader_class( $force ) { @@ -87,23 +89,19 @@ public function search( $args, $assoc_args ) { } protected function status_single( $args ) { - $plugins = $this->validate_plugin_names( $args ); - if ( empty( $plugins ) ) - exit(1); - - list( $plugin ) = $plugins; + $file = $this->fetcher->get_check( $args[0] ); - $details = $this->get_details( $plugin ); + $details = $this->get_details( $file ); - $status = $this->format_status( $this->get_status( $plugin->file ), 'long' ); + $status = $this->format_status( $this->get_status( $file ), 'long' ); $version = $details['Version']; - if ( $this->has_update( $plugin->file ) ) + if ( $this->has_update( $file ) ) $version .= ' (%gUpdate available%n)'; echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'plugin-status.mustache', array( - 'slug' => $plugin->name, + 'slug' => $this->get_name( $file ), 'status' => $status, 'version' => $version, 'name' => $details['Name'], @@ -140,7 +138,7 @@ protected function get_all_items() { function activate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { activate_plugin( $plugin->file, '', $network_wide ); if ( $this->check_active( $plugin->file, $network_wide ) ) { @@ -168,7 +166,7 @@ function activate( $args, $assoc_args = array() ) { function deactivate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { deactivate_plugins( $plugin->file, false, $network_wide ); if ( ! $this->check_active( $plugin->file, $network_wide ) ) { @@ -196,7 +194,7 @@ function deactivate( $args, $assoc_args = array() ) { function toggle( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { if ( $this->check_active( $plugin->file, $network_wide ) ) { $this->deactivate( array( $plugin->name ), $assoc_args ); } else { @@ -226,7 +224,7 @@ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); if ( !empty( $args ) ) { - $plugins = $this->validate_plugin_names( $args ); + $plugins = $this->fetcher->get_many( $args ); if ( empty( $plugins ) ) return; @@ -294,7 +292,7 @@ protected function install_from_repo( $slug, $assoc_args ) { */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { - foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { $this->_delete( $plugin ); $this->install( array( $plugin->name ), $assoc_args ); } @@ -324,7 +322,7 @@ protected function get_item_list() { } protected function filter_item_list( $items, $args ) { - $basenames = wp_list_pluck( $this->validate_plugin_names( $args ), 'file' ); + $basenames = wp_list_pluck( $this->fetcher->get_many( $args ), 'file' ); return \WP_CLI\Utils\pick_fields( $items, $basenames ); } @@ -384,10 +382,7 @@ function install( $args, $assoc_args ) { * wp plugin get bbpress --format=json */ public function get( $args, $assoc_args ) { - $file = $this->_parse_name( $args[0] ); - if ( !$file ) { - WP_CLI::error( "The '{$args[0]}' plugin could not be found." ); - } + $file = $this->get_check( $args[0] ); $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false ); @@ -422,7 +417,7 @@ public function get( $args, $assoc_args ) { * wp plugin uninstall hello */ function uninstall( $args, $assoc_args = array() ) { - foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { if ( is_plugin_active( $plugin->file ) ) { WP_CLI::warning( "The '{$plugin->name}' plugin is active." ); continue; @@ -451,7 +446,7 @@ function uninstall( $args, $assoc_args = array() ) { * @subcommand is-installed */ function is_installed( $args, $assoc_args = array() ) { - if ( $this->_parse_name( $args[0] ) ) { + if ( $this->fetcher->get( $args[0] ) ) { exit( 0 ); } else { exit( 1 ); @@ -471,7 +466,7 @@ function is_installed( $args, $assoc_args = array() ) { * wp plugin delete hello */ function delete( $args, $assoc_args = array() ) { - foreach ( $this->validate_plugin_names( $args ) as $plugin ) { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { if ( $this->_delete( $plugin ) ) { WP_CLI::success( "Deleted '{$plugin->name}' plugin." ); } @@ -526,58 +521,13 @@ protected function get_status( $file ) { * @param object * @return array */ - private function get_details( $plugin ) { - $file = $plugin->file; - + private function get_details( $file ) { $plugin_folder = get_plugins( '/' . plugin_basename( dirname( $file ) ) ); $plugin_file = basename( $file ); return $plugin_folder[$plugin_file]; } - /** - * Parse the name of a plugin to a filename; check if it exists. - * - * @param string name - * @return string - */ - private function _parse_name( $name ) { - $plugins = get_plugins( '/' . $name ); - - if ( !empty( $plugins ) ) { - $file = $name . '/' . key( $plugins ); - } - else { - $file = $name . '.php'; - - $plugins = get_plugins(); - - if ( !isset( $plugins[$file] ) ) { - return false; - } - } - - return $file; - } - - private function validate_plugin_names( $args ) { - $plugins = array(); - - foreach ( $args as $name ) { - $file = $this->_parse_name( $name ); - if ( $file ) { - $plugins[] = (object) array( - 'name' => $name, - 'file' => $file - ); - } else { - WP_CLI::warning( "The '$name' plugin could not be found." ); - } - } - - return $plugins; - } - /** * Converts a plugin basename back into a friendly slug. */ From 87a91609259700d243d0e5a49f852fd5eec4ba09 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 00:41:55 +0200 Subject: [PATCH 2489/4858] convert Fetcher to abstract class --- php/WP_CLI/Fetcher.php | 55 +++++++++++++++++++++++++++++++----- php/WP_CLI/FetcherPlugin.php | 39 ++++--------------------- php/WP_CLI/FetcherUser.php | 27 +----------------- php/commands/plugin.php | 8 ++++-- php/commands/user.php | 2 +- 5 files changed, 60 insertions(+), 71 deletions(-) diff --git a/php/WP_CLI/Fetcher.php b/php/WP_CLI/Fetcher.php index 58cf01f9b1..bf24465154 100644 --- a/php/WP_CLI/Fetcher.php +++ b/php/WP_CLI/Fetcher.php @@ -2,15 +2,56 @@ namespace WP_CLI; -interface Fetcher { +abstract class Fetcher { - // Returns the item if found; otherwise returns false - function get( $id ); + protected $msg; - // Returns the item if found; otherwise calls WP_CLI::error() - function get_check( $id ); + /** + * @param string $msg The message to display when an item is not found + */ + function __construct( $msg ) { + $this->msg = $msg; + } - // Returns the list of found items - function get_many( $ids ); + /** + * @param string $arg The raw CLI argument + * @return mixed|false The item if found; false otherwise + */ + abstract public function get( $arg ); + + /** + * Like get(), but calls WP_CLI::error() instead of returning false. + * + * @param string $arg The raw CLI argument + */ + public function get_check( $arg ) { + $item = $this->get( $arg ); + + if ( ! $item ) { + \WP_CLI::error( sprintf( $this->msg, $arg ) ); + } + + return $item; + } + + /** + * @param array The raw CLI arguments + * @return array The list of found items + */ + public function get_many( $args ) { + $items = array(); + + foreach ( $args as $arg ) { + $item = $this->get( $arg ); + + if ( $item ) { + $items[] = $item; + } else { + \WP_CLI::warning( sprintf( $this->msg, $arg ) ); + } + } + + return $items; + } } diff --git a/php/WP_CLI/FetcherPlugin.php b/php/WP_CLI/FetcherPlugin.php index 03c656905c..3c8893a6ea 100644 --- a/php/WP_CLI/FetcherPlugin.php +++ b/php/WP_CLI/FetcherPlugin.php @@ -2,12 +2,8 @@ namespace WP_CLI; -class FetcherPlugin implements Fetcher { +class FetcherPlugin extends Fetcher { - /** - * @param string $name The plugin slug - * @return string|false The plugin filename - */ public function get( $name ) { $plugins = get_plugins( '/' . $name ); @@ -23,35 +19,10 @@ public function get( $name ) { } } - return $file; - } - - public function get_check( $name ) { - $file = $this->get( $name ); - - if ( ! $file ) { - \WP_CLI::error( "The '$name' plugin could not be found." ); - } - - return $file; - } - - public function get_many( $args ) { - $plugins = array(); - - foreach ( $args as $name ) { - $file = $this->get( $name ); - if ( $file ) { - $plugins[] = (object) array( - 'name' => $name, - 'file' => $file - ); - } else { - \WP_CLI::warning( "The '$name' plugin could not be found." ); - } - } - - return $plugins; + return (object) array( + 'name' => $name, + 'file' => $file + ); } } diff --git a/php/WP_CLI/FetcherUser.php b/php/WP_CLI/FetcherUser.php index 1ed29bfcb4..aea6ffbe1f 100644 --- a/php/WP_CLI/FetcherUser.php +++ b/php/WP_CLI/FetcherUser.php @@ -2,7 +2,7 @@ namespace WP_CLI; -class FetcherUser implements Fetcher { +class FetcherUser extends Fetcher { public function get( $id_or_login ) { if ( is_numeric( $id_or_login ) ) @@ -12,30 +12,5 @@ public function get( $id_or_login ) { return $user; } - - public function get_check( $id_or_login ) { - $user = $this->get( $id_or_login ); - - if ( ! $user ) { - \WP_CLI::error( "Invalid user ID or login: $id_or_login" ); - } - - return $user; - } - - public function get_many( $ids_or_logins ) { - $users = array(); - - foreach ( $ids_or_logins as $id_or_login ) { - $user = $this->get( $id_or_login ); - if ( $user ) { - $users[] = $user; - } else { - \WP_CLI::warning( "Invalid user ID or login: $id_or_login" ); - } - } - - return $users; - } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 948fa054ff..ab0bd6bed4 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -24,7 +24,7 @@ function __construct() { parent::__construct(); - $this->fetcher = new \WP_CLI\FetcherPlugin; + $this->fetcher = new \WP_CLI\FetcherPlugin( "The '%s' plugin could not be found." ); } protected function get_upgrader_class( $force ) { @@ -89,7 +89,8 @@ public function search( $args, $assoc_args ) { } protected function status_single( $args ) { - $file = $this->fetcher->get_check( $args[0] ); + $plugin = $this->fetcher->get_check( $args[0] ); + $file = $plugin->file; $details = $this->get_details( $file ); @@ -382,7 +383,8 @@ function install( $args, $assoc_args ) { * wp plugin get bbpress --format=json */ public function get( $args, $assoc_args ) { - $file = $this->get_check( $args[0] ); + $plugin = $this->fetcher->get_check( $args[0] ); + $file = $plugin->file; $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false ); diff --git a/php/commands/user.php b/php/commands/user.php index cf18fcb041..df0c65e002 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -18,7 +18,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { ); public function __construct() { - $this->fetcher = new \WP_CLI\FetcherUser; + $this->fetcher = new \WP_CLI\FetcherUser( "Invalid user ID or login: '%s'" ); } /** From 34b4c9d8e8f8defe3207b9131c07145595489235 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 00:50:14 +0200 Subject: [PATCH 2490/4858] extract FetcherTheme class --- php/WP_CLI/FetcherTheme.php | 17 +++++++++++++ php/commands/theme.php | 51 +++++++++---------------------------- 2 files changed, 29 insertions(+), 39 deletions(-) create mode 100644 php/WP_CLI/FetcherTheme.php diff --git a/php/WP_CLI/FetcherTheme.php b/php/WP_CLI/FetcherTheme.php new file mode 100644 index 0000000000..032776343b --- /dev/null +++ b/php/WP_CLI/FetcherTheme.php @@ -0,0 +1,17 @@ +<?php + +namespace WP_CLI; + +class FetcherTheme extends Fetcher { + + public function get( $name ) { + $theme = wp_get_theme( $name ); + + if ( !$theme->exists() ) { + return false; + } + + return $theme; + } +} + diff --git a/php/commands/theme.php b/php/commands/theme.php index b5dccf3fb3..8a8d6dd9ed 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -18,6 +18,12 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { 'version' ); + function __construct() { + parent::__construct(); + + $this->fetcher = new \WP_CLI\FetcherTheme( "The '%s' theme could not be found." ); + } + protected function get_upgrader_class( $force ) { return $force ? '\\WP_CLI\\DestructiveThemeUpgrader' : 'Theme_Upgrader'; } @@ -76,7 +82,7 @@ public function search( $args, $assoc_args ) { } protected function status_single( $args ) { - $theme = $this->parse_name( $args[0] ); + $theme = $this->fetcher->get_check( $args[0] ); $status = $this->format_status( $this->get_status( $theme ), 'long' ); @@ -110,7 +116,7 @@ protected function get_status( $theme ) { * : The theme to activate. */ public function activate( $args = array() ) { - $theme = $this->parse_name( $args[0] ); + $theme = $this->fetcher->get_check( $args[0] ); switch_theme( $theme->get_template(), $theme->get_stylesheet() ); @@ -148,7 +154,7 @@ public function path( $args, $assoc_args ) { if ( empty( $args ) ) { $path = WP_CONTENT_DIR . '/themes'; } else { - $theme = $this->parse_name( $args[0] ); + $theme = $this->fetcher->get_check( $args[0] ); $path = $theme->get_stylesheet_directory(); @@ -208,7 +214,7 @@ protected function get_item_list() { protected function filter_item_list( $items, $args ) { $theme_files = array(); foreach ( $args as $arg ) { - $theme_files[] = $this->parse_name( $arg )->get_stylesheet_directory(); + $theme_files[] = $this->fetcher->get_check( $arg )->get_stylesheet_directory(); } return \WP_CLI\Utils\pick_fields( $items, $theme_files ); @@ -267,7 +273,7 @@ function install( $args, $assoc_args ) { * wp theme get twentytwelve --format=json */ public function get( $args, $assoc_args ) { - $theme = $this->parse_name( $args[0] ); + $theme = $this->fetcher->get_check( $args[0] ); // WP_Theme object employs magic getter, unfortunately $theme_vars = array( 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', @@ -348,7 +354,7 @@ function is_installed( $args, $assoc_args = array() ) { * wp theme delete twentyeleven */ function delete( $args ) { - foreach ( $this->validate_theme_names( $args ) as $theme ) { + foreach ( $this->fetcher->get_many( $args ) as $theme ) { $theme_slug = $theme->get_stylesheet(); if ( $this->is_active_theme( $theme ) ) { @@ -388,39 +394,6 @@ function delete( $args ) { function _list( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); } - - /** - * Parse the name of a plugin to a filename; check if it exists. - * - * @param string name - * @return object - */ - private function parse_name( $name ) { - $theme = wp_get_theme( $name ); - - if ( !$theme->exists() ) { - WP_CLI::error( "The theme '$name' could not be found." ); - exit; - } - - return $theme; - } - - private function validate_theme_names( $args ) { - $themes = array(); - - foreach ( $args as $name ) { - $theme = wp_get_theme( $name ); - - if ( !$theme->exists() ) { - WP_CLI::warning( "The '$name' theme could not be found." ); - } else { - $themes[] = $theme; - } - } - - return $themes; - } } WP_CLI::add_command( 'theme', 'Theme_Command' ); From 794ad160c041dd92f127a34fe88907db814efd4f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 00:58:23 +0200 Subject: [PATCH 2491/4858] extract FetcherComment class --- php/WP_CLI/FetcherComment.php | 18 ++++++++++++++++++ php/commands/comment.php | 22 ++++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 php/WP_CLI/FetcherComment.php diff --git a/php/WP_CLI/FetcherComment.php b/php/WP_CLI/FetcherComment.php new file mode 100644 index 0000000000..806ece1f0f --- /dev/null +++ b/php/WP_CLI/FetcherComment.php @@ -0,0 +1,18 @@ +<?php + +namespace WP_CLI; + +class FetcherComment extends Fetcher { + + public function get( $arg ) { + $comment_id = (int) $arg; + $comment = get_comment( $comment_id ); + + if ( is_null( $comment ) ) { + return false; + } + + return $comment; + } +} + diff --git a/php/commands/comment.php b/php/commands/comment.php index 8d97df2e83..cb7c4f06d1 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -18,6 +18,10 @@ class Comment_Command extends \WP_CLI\CommandWithDBObject { 'comment_author_email', ); + public function __construct() { + $this->fetcher = new \WP_CLI\FetcherComment( "Comment with ID %s does not exist." ); + } + /** * Insert a comment. * @@ -192,7 +196,7 @@ private function call( $args, $status, $success, $failure ) { } private function set_status( $args, $status, $success ) { - $comment = $this->_fetch_comment( $args ); + $comment = $this->fetcher->get_check( $args[0] ); $r = wp_set_comment_status( $comment->comment_ID, 'approve', true ); @@ -364,24 +368,10 @@ public function status( $args, $assoc_args ) { * wp comment exists 1337 */ public function exists( $args ) { - if ( $this->_fetch_comment( $args ) ) { + if ( $this->fetcher->get( $args[0] ) ) { WP_CLI::success( "Comment with ID $args[0] exists." ); } } - - /** - * A helper function fetching a comment object from comment_id. - */ - private function _fetch_comment( $args ) { - $comment_id = (int) $args[0]; - $comment = get_comment( $comment_id ); - - if ( is_null( $comment ) ) { - WP_CLI::error( "Comment with ID $args[0] does not exist." ); - } - - return $comment; - } } WP_CLI::add_command( 'comment', 'Comment_Command' ); From 69c005a97b59c09274eb05b644f26ccb9f47722b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 01:01:38 +0200 Subject: [PATCH 2492/4858] keep 'not found' message in Fetcher child classes otherwise, might get a mismatch between the class and the message --- php/WP_CLI/Fetcher.php | 6 +----- php/WP_CLI/FetcherComment.php | 2 ++ php/WP_CLI/FetcherPlugin.php | 2 ++ php/WP_CLI/FetcherTheme.php | 2 ++ php/WP_CLI/FetcherUser.php | 2 ++ php/commands/comment.php | 2 +- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- php/commands/user.php | 2 +- 9 files changed, 13 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Fetcher.php b/php/WP_CLI/Fetcher.php index bf24465154..0ef9f92a57 100644 --- a/php/WP_CLI/Fetcher.php +++ b/php/WP_CLI/Fetcher.php @@ -4,14 +4,10 @@ abstract class Fetcher { - protected $msg; - /** * @param string $msg The message to display when an item is not found */ - function __construct( $msg ) { - $this->msg = $msg; - } + protected $msg; /** * @param string $arg The raw CLI argument diff --git a/php/WP_CLI/FetcherComment.php b/php/WP_CLI/FetcherComment.php index 806ece1f0f..167b0432e4 100644 --- a/php/WP_CLI/FetcherComment.php +++ b/php/WP_CLI/FetcherComment.php @@ -4,6 +4,8 @@ class FetcherComment extends Fetcher { + protected $msg = "Comment with ID %s does not exist."; + public function get( $arg ) { $comment_id = (int) $arg; $comment = get_comment( $comment_id ); diff --git a/php/WP_CLI/FetcherPlugin.php b/php/WP_CLI/FetcherPlugin.php index 3c8893a6ea..bd68712905 100644 --- a/php/WP_CLI/FetcherPlugin.php +++ b/php/WP_CLI/FetcherPlugin.php @@ -4,6 +4,8 @@ class FetcherPlugin extends Fetcher { + protected $msg = "The '%s' plugin could not be found."; + public function get( $name ) { $plugins = get_plugins( '/' . $name ); diff --git a/php/WP_CLI/FetcherTheme.php b/php/WP_CLI/FetcherTheme.php index 032776343b..5066983f0f 100644 --- a/php/WP_CLI/FetcherTheme.php +++ b/php/WP_CLI/FetcherTheme.php @@ -4,6 +4,8 @@ class FetcherTheme extends Fetcher { + protected $msg = "The '%s' theme could not be found."; + public function get( $name ) { $theme = wp_get_theme( $name ); diff --git a/php/WP_CLI/FetcherUser.php b/php/WP_CLI/FetcherUser.php index aea6ffbe1f..e1111e0ecc 100644 --- a/php/WP_CLI/FetcherUser.php +++ b/php/WP_CLI/FetcherUser.php @@ -4,6 +4,8 @@ class FetcherUser extends Fetcher { + protected $msg = "Invalid user ID or login: '%s'"; + public function get( $id_or_login ) { if ( is_numeric( $id_or_login ) ) $user = get_user_by( 'id', $id_or_login ); diff --git a/php/commands/comment.php b/php/commands/comment.php index cb7c4f06d1..aa73d16197 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -19,7 +19,7 @@ class Comment_Command extends \WP_CLI\CommandWithDBObject { ); public function __construct() { - $this->fetcher = new \WP_CLI\FetcherComment( "Comment with ID %s does not exist." ); + $this->fetcher = new \WP_CLI\FetcherComment; } /** diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ab0bd6bed4..ff90c5c30a 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -24,7 +24,7 @@ function __construct() { parent::__construct(); - $this->fetcher = new \WP_CLI\FetcherPlugin( "The '%s' plugin could not be found." ); + $this->fetcher = new \WP_CLI\FetcherPlugin; } protected function get_upgrader_class( $force ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 8a8d6dd9ed..d5437785b9 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -21,7 +21,7 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { function __construct() { parent::__construct(); - $this->fetcher = new \WP_CLI\FetcherTheme( "The '%s' theme could not be found." ); + $this->fetcher = new \WP_CLI\FetcherTheme; } protected function get_upgrader_class( $force ) { diff --git a/php/commands/user.php b/php/commands/user.php index df0c65e002..cf18fcb041 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -18,7 +18,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { ); public function __construct() { - $this->fetcher = new \WP_CLI\FetcherUser( "Invalid user ID or login: '%s'" ); + $this->fetcher = new \WP_CLI\FetcherUser; } /** From d71f95de6dcdd16b83d9db52fe4524aa919f6dc1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 01:14:08 +0200 Subject: [PATCH 2493/4858] extract FetcherPost class --- php/WP_CLI/FetcherComment.php | 2 +- php/WP_CLI/FetcherPost.php | 13 +++++++++++++ php/commands/post.php | 12 ++++++------ 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 php/WP_CLI/FetcherPost.php diff --git a/php/WP_CLI/FetcherComment.php b/php/WP_CLI/FetcherComment.php index 167b0432e4..cc02cbb974 100644 --- a/php/WP_CLI/FetcherComment.php +++ b/php/WP_CLI/FetcherComment.php @@ -4,7 +4,7 @@ class FetcherComment extends Fetcher { - protected $msg = "Comment with ID %s does not exist."; + protected $msg = "Could not find the comment with ID %d."; public function get( $arg ) { $comment_id = (int) $arg; diff --git a/php/WP_CLI/FetcherPost.php b/php/WP_CLI/FetcherPost.php new file mode 100644 index 0000000000..62f12711f7 --- /dev/null +++ b/php/WP_CLI/FetcherPost.php @@ -0,0 +1,13 @@ +<?php + +namespace WP_CLI; + +class FetcherPost extends Fetcher { + + protected $msg = "Could not find the post with ID %d."; + + public function get( $arg ) { + return get_post( $arg ); + } +} + diff --git a/php/commands/post.php b/php/commands/post.php index c4d8f24ba2..143b02e9e1 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -16,6 +16,10 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { 'post_status' ); + public function __construct() { + $this->fetcher = new \WP_CLI\FetcherPost; + } + /** * Create a post. * @@ -109,9 +113,7 @@ public function update( $args, $assoc_args ) { * wp post edit 123 */ public function edit( $args, $_ ) { - $post_id = $args[0]; - if ( !$post_id || !$post = get_post( $post_id ) ) - \WP_CLI::error( "Failed opening post $post_id to edit." ); + $post = $this->fetcher->get_check( $args[0] ); $r = $this->_edit( $post->post_content, "WP-CLI post $post_id" ); @@ -153,9 +155,7 @@ protected function _edit( $content, $title ) { * wp post get 12 --field=content > file.txt */ public function get( $args, $assoc_args ) { - $post_id = $args[0]; - if ( !$post_id || !$post = get_post( $post_id ) ) - \WP_CLI::error( "Could not find the post with ID $post_id." ); + $post = $this->fetcher->get_check( $args[0] ); $post_arr = get_object_vars( $post ); unset( $post_arr['filter'] ); From 5948aac4375a40b34e045209b78608e1b1985d25 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 10 Nov 2013 02:14:13 +0200 Subject: [PATCH 2494/4858] move fetcher classes to their own directory; see #863 --- php/WP_CLI/{Fetcher.php => Fetchers/Base.php} | 4 ++-- php/WP_CLI/{FetcherComment.php => Fetchers/Comment.php} | 4 ++-- php/WP_CLI/{FetcherPlugin.php => Fetchers/Plugin.php} | 4 ++-- php/WP_CLI/{FetcherPost.php => Fetchers/Post.php} | 4 ++-- php/WP_CLI/{FetcherTheme.php => Fetchers/Theme.php} | 4 ++-- php/WP_CLI/{FetcherUser.php => Fetchers/User.php} | 4 ++-- php/commands/comment.php | 2 +- php/commands/plugin.php | 2 +- php/commands/post.php | 2 +- php/commands/theme.php | 2 +- php/commands/user.php | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) rename php/WP_CLI/{Fetcher.php => Fetchers/Base.php} (94%) rename php/WP_CLI/{FetcherComment.php => Fetchers/Comment.php} (81%) rename php/WP_CLI/{FetcherPlugin.php => Fetchers/Plugin.php} (88%) rename php/WP_CLI/{FetcherPost.php => Fetchers/Post.php} (70%) rename php/WP_CLI/{FetcherTheme.php => Fetchers/Theme.php} (79%) rename php/WP_CLI/{FetcherUser.php => Fetchers/User.php} (82%) diff --git a/php/WP_CLI/Fetcher.php b/php/WP_CLI/Fetchers/Base.php similarity index 94% rename from php/WP_CLI/Fetcher.php rename to php/WP_CLI/Fetchers/Base.php index 0ef9f92a57..9e4ebc3100 100644 --- a/php/WP_CLI/Fetcher.php +++ b/php/WP_CLI/Fetchers/Base.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Fetchers; -abstract class Fetcher { +abstract class Base { /** * @param string $msg The message to display when an item is not found diff --git a/php/WP_CLI/FetcherComment.php b/php/WP_CLI/Fetchers/Comment.php similarity index 81% rename from php/WP_CLI/FetcherComment.php rename to php/WP_CLI/Fetchers/Comment.php index cc02cbb974..296b2533b9 100644 --- a/php/WP_CLI/FetcherComment.php +++ b/php/WP_CLI/Fetchers/Comment.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Fetchers; -class FetcherComment extends Fetcher { +class Comment extends Base { protected $msg = "Could not find the comment with ID %d."; diff --git a/php/WP_CLI/FetcherPlugin.php b/php/WP_CLI/Fetchers/Plugin.php similarity index 88% rename from php/WP_CLI/FetcherPlugin.php rename to php/WP_CLI/Fetchers/Plugin.php index bd68712905..247192bfa4 100644 --- a/php/WP_CLI/FetcherPlugin.php +++ b/php/WP_CLI/Fetchers/Plugin.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Fetchers; -class FetcherPlugin extends Fetcher { +class Plugin extends Base { protected $msg = "The '%s' plugin could not be found."; diff --git a/php/WP_CLI/FetcherPost.php b/php/WP_CLI/Fetchers/Post.php similarity index 70% rename from php/WP_CLI/FetcherPost.php rename to php/WP_CLI/Fetchers/Post.php index 62f12711f7..4944561e3a 100644 --- a/php/WP_CLI/FetcherPost.php +++ b/php/WP_CLI/Fetchers/Post.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Fetchers; -class FetcherPost extends Fetcher { +class Post extends Base { protected $msg = "Could not find the post with ID %d."; diff --git a/php/WP_CLI/FetcherTheme.php b/php/WP_CLI/Fetchers/Theme.php similarity index 79% rename from php/WP_CLI/FetcherTheme.php rename to php/WP_CLI/Fetchers/Theme.php index 5066983f0f..1c3380502e 100644 --- a/php/WP_CLI/FetcherTheme.php +++ b/php/WP_CLI/Fetchers/Theme.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Fetchers; -class FetcherTheme extends Fetcher { +class Theme extends Base { protected $msg = "The '%s' theme could not be found."; diff --git a/php/WP_CLI/FetcherUser.php b/php/WP_CLI/Fetchers/User.php similarity index 82% rename from php/WP_CLI/FetcherUser.php rename to php/WP_CLI/Fetchers/User.php index e1111e0ecc..81bbbc20ac 100644 --- a/php/WP_CLI/FetcherUser.php +++ b/php/WP_CLI/Fetchers/User.php @@ -1,8 +1,8 @@ <?php -namespace WP_CLI; +namespace WP_CLI\Fetchers; -class FetcherUser extends Fetcher { +class User extends Base { protected $msg = "Invalid user ID or login: '%s'"; diff --git a/php/commands/comment.php b/php/commands/comment.php index aa73d16197..06b4b64a42 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -19,7 +19,7 @@ class Comment_Command extends \WP_CLI\CommandWithDBObject { ); public function __construct() { - $this->fetcher = new \WP_CLI\FetcherComment; + $this->fetcher = new \WP_CLI\Fetchers\Comment; } /** diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ff90c5c30a..3edf31cb30 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -24,7 +24,7 @@ function __construct() { parent::__construct(); - $this->fetcher = new \WP_CLI\FetcherPlugin; + $this->fetcher = new \WP_CLI\Fetchers\Plugin; } protected function get_upgrader_class( $force ) { diff --git a/php/commands/post.php b/php/commands/post.php index 143b02e9e1..ca9a156fd5 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -17,7 +17,7 @@ class Post_Command extends \WP_CLI\CommandWithDBObject { ); public function __construct() { - $this->fetcher = new \WP_CLI\FetcherPost; + $this->fetcher = new \WP_CLI\Fetchers\Post; } /** diff --git a/php/commands/theme.php b/php/commands/theme.php index d5437785b9..87c806c723 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -21,7 +21,7 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { function __construct() { parent::__construct(); - $this->fetcher = new \WP_CLI\FetcherTheme; + $this->fetcher = new \WP_CLI\Fetchers\Theme; } protected function get_upgrader_class( $force ) { diff --git a/php/commands/user.php b/php/commands/user.php index cf18fcb041..ae1733a4da 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -18,7 +18,7 @@ class User_Command extends \WP_CLI\CommandWithDBObject { ); public function __construct() { - $this->fetcher = new \WP_CLI\FetcherUser; + $this->fetcher = new \WP_CLI\Fetchers\User; } /** From 04655edbb69b0739b5be72046dab2f2b8184741e Mon Sep 17 00:00:00 2001 From: Jonathan Bardo <jonathanbardo@users.noreply.github.com> Date: Mon, 11 Nov 2013 09:15:33 -0500 Subject: [PATCH 2495/4858] Minor typo --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 2e59a706ab..c521c69d02 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -511,7 +511,7 @@ public function before_wp_load() { } if ( 'multisite-install' == $this->arguments[1] ) { - // need to fake some globals to skip the checks in wp-inclues/ms-settings.php + // need to fake some globals to skip the checks in wp-includes/ms-settings.php self::fake_current_site_blog( $url_parts ); if ( !defined( 'COOKIEHASH' ) ) { From 72d8062072f49898f79c5e30a4f66f6ce7b8bea3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Nov 2013 00:21:29 +0200 Subject: [PATCH 2496/4858] introduce --skip-tests flag for 'wp scaffold plugin' --- php/commands/scaffold.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 31e672109e..26ee0064ac 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -303,11 +303,14 @@ private function get_output_path( $assoc_args, $subdir ) { * <slug> * : The internal name of the plugin. * - * [--activate] - * : Activate the newly generated plugin. - * * [--plugin_name=<title>] * : What to put in the 'Plugin Name:' header + * + * [--skip-tests] + * : Don't generate files for unit testing. + * + * [--activate] + * : Activate the newly generated plugin. */ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; @@ -325,10 +328,13 @@ function plugin( $args, $assoc_args ) { WP_CLI::success( "Created $plugin_dir" ); - WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ) ); + if ( !isset( $assoc_args['skip-tests'] ) ) { + WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ) ); + } - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); + } } /** From 7ed61de22f23390c0621ba0185d86028c9f347fd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Nov 2013 00:25:57 +0200 Subject: [PATCH 2497/4858] add behat test for --skip-tests --- features/plugin.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index b9ebc00f2f..93c693a528 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -7,9 +7,15 @@ Feature: Manage WordPress plugins And I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} + When I run `wp plugin scaffold --skip-tests plugin1` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/plugin1/plugin1.php file should exist + And the {PLUGIN_DIR}/zombieland/phpunit.xml file should not exist + When I run `wp plugin scaffold zombieland --plugin_name="Zombieland"` Then STDOUT should not be empty And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist + And the {PLUGIN_DIR}/zombieland/phpunit.xml file should exist When I run `wp plugin status zombieland` Then STDOUT should contain: From acd70eec775745d87a299d4dc71e5033e10582d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Nov 2013 00:55:43 +0200 Subject: [PATCH 2498/4858] don't pick up php files inside plugin subdirs --- features/plugin.feature | 4 +++- php/WP_CLI/Fetchers/Plugin.php | 32 ++++++++++++++++++++------------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 93c693a528..be9c51cebe 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -17,7 +17,9 @@ Feature: Manage WordPress plugins And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist And the {PLUGIN_DIR}/zombieland/phpunit.xml file should exist - When I run `wp plugin status zombieland` + # Check that the inner-plugin is not picked up + When I run `mv {PLUGIN_DIR}/plugin1 {PLUGIN_DIR}/zombieland/` + And I run `wp plugin status zombieland` Then STDOUT should contain: """ Plugin zombieland details: diff --git a/php/WP_CLI/Fetchers/Plugin.php b/php/WP_CLI/Fetchers/Plugin.php index 247192bfa4..f59672570d 100644 --- a/php/WP_CLI/Fetchers/Plugin.php +++ b/php/WP_CLI/Fetchers/Plugin.php @@ -9,22 +9,30 @@ class Plugin extends Base { public function get( $name ) { $plugins = get_plugins( '/' . $name ); - if ( !empty( $plugins ) ) { - $file = $name . '/' . key( $plugins ); - } else { - $file = $name . '.php'; + // some-plugin/the-plugin.php + while ( !empty( $plugins ) ) { + $file = key( $plugins ); + array_shift( $plugins ); + + // ignore files inside a plugin's subdirectory (like WP does) + if ( dirname( $file ) == '.' ) { + return (object) array( + 'name' => $name, + 'file' => $name . '/' . $file + ); + } + } - $plugins = get_plugins(); + // some-plugin.php + $file = $name . '.php'; - if ( !isset( $plugins[$file] ) ) { - return false; - } + $plugins = get_plugins(); + + if ( isset( $plugins[ $file ] ) ) { + return (object) compact( 'name', 'file' ); } - return (object) array( - 'name' => $name, - 'file' => $file - ); + return false; } } From 482e4abc37121bdf8690beac182b4b885bb78a02 Mon Sep 17 00:00:00 2001 From: Kevin Leary <info@kevinleary.net> Date: Tue, 12 Nov 2013 14:54:31 -0500 Subject: [PATCH 2499/4858] Use consistent capitalization for "Add New" in post type scaffold to match WordPress default for Post and Page. --- templates/post_type.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index cd242e053c..51f0faa24a 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -10,9 +10,9 @@ 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), - 'add_new' => __( 'Add new {{label}}', '{{textdomain}}' ), + 'add_new' => __( 'Add New {{label}}', '{{textdomain}}' ), 'all_items' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), - 'add_new_item' => __( 'Add new {{label}}', '{{textdomain}}' ), + 'add_new_item' => __( 'Add New {{label}}', '{{textdomain}}' ), 'edit_item' => __( 'Edit {{label}}', '{{textdomain}}' ), 'new_item' => __( 'New {{label}}', '{{textdomain}}' ), 'view_item' => __( 'View {{label}}', '{{textdomain}}' ), From 74beb8c8a0708cd11d78723bd62c084be03f17c2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 12 Nov 2013 22:41:56 +0200 Subject: [PATCH 2500/4858] remove label from add_new default and move it above add_new_item, to make the difference clearer see #868 --- templates/post_type.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 51f0faa24a..201a2fa132 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -10,11 +10,11 @@ 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), - 'add_new' => __( 'Add New {{label}}', '{{textdomain}}' ), 'all_items' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'new_item' => __( 'New {{label}}', '{{textdomain}}' ), + 'add_new' => __( 'Add New', '{{textdomain}}' ), 'add_new_item' => __( 'Add New {{label}}', '{{textdomain}}' ), 'edit_item' => __( 'Edit {{label}}', '{{textdomain}}' ), - 'new_item' => __( 'New {{label}}', '{{textdomain}}' ), 'view_item' => __( 'View {{label}}', '{{textdomain}}' ), 'search_items' => __( 'Search {{label_plural}}', '{{textdomain}}' ), 'not_found' => __( 'No {{label_plural}} found', '{{textdomain}}' ), From db61e2c9528254d0b78a652623607810d145d1c7 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 14 Nov 2013 01:24:35 +0200 Subject: [PATCH 2501/4858] increase timeout threshold for 'wp core download'. fixes #748 --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index e0f2d78743..09d15da96d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -64,7 +64,7 @@ public function download( $args, $assoc_args ) { $headers = array('Accept' => 'application/json'); $options = array( - 'timeout' => 30, + 'timeout' => 600, // 10 minutes ought to be enough for everybody 'filename' => $temp ); From 72ddf7408d0b59e433bc8b5430290c04a48a67c4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 14 Nov 2013 22:17:56 +0200 Subject: [PATCH 2502/4858] fix --category synopsis for 'wp export' closes #872 --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 59781549ef..a2df80bfb2 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -43,7 +43,7 @@ class Export_Command extends WP_CLI_Command { * [--author=<login/id>] * : Export only posts by this author. * - * [--category=<category-id>] + * [--category=<name>] * : Export only posts in this category. * * [--post_status=<status>] From f1310a7f08b8efb5a4e684847f5031f4e92fc856 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 15 Nov 2013 13:18:52 -0200 Subject: [PATCH 2503/4858] 'wp theme delete' should not delete active theme --- features/theme.feature | 30 ++++++++++++++++++++++++++++++ php/commands/theme.php | 1 + 2 files changed, 31 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 7898f9d097..121c2c3dbc 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -73,3 +73,33 @@ Feature: Manage WordPress themes """ wp-content/themes/p2 """ + + Scenario: Deleting a theme + When I run `wp theme install p2` + Then STDOUT should not be empty + + When I try `wp theme delete invalid-theme` + Then STDERR should contain: + """ + Warning: The 'invalid-theme' theme could not be found. + """ + And STDOUT should be empty + + When I run `wp theme delete p2` + Then STDOUT should be: + """ + Success: Deleted 'p2' theme. + """ + And STDERR should be empty + + When I run `wp theme install p2 --activate` + Then STDOUT should not be empty + + When I try `wp theme delete p2` + Then STDERR should be: + """ + Warning: Can't delete the currently active theme: p2 + """ + And STDOUT should be empty + + \ No newline at end of file diff --git a/php/commands/theme.php b/php/commands/theme.php index 87c806c723..3cfdfaeea6 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -359,6 +359,7 @@ function delete( $args ) { if ( $this->is_active_theme( $theme ) ) { WP_CLI::warning( "Can't delete the currently active theme: $theme_slug" ); + continue; } $r = delete_theme( $theme_slug ); From 1a2143717617b06d2e19ae48843a8d3c97cb1dc2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 17 Nov 2013 14:15:08 +0200 Subject: [PATCH 2504/4858] merge theme install and delete scenarios; see #874 --- features/theme.feature | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 121c2c3dbc..f14a82003d 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -3,7 +3,7 @@ Feature: Manage WordPress themes Background: Given a WP install - Scenario: Installing a theme + Scenario: Installing and deleting theme When I run `wp theme install p2` Then STDOUT should not be empty @@ -29,6 +29,13 @@ Feature: Manage WordPress themes Success: Switched to 'P2' theme. """ + When I try `wp theme delete p2` + Then STDERR should be: + """ + Warning: Can't delete the currently active theme: p2 + """ + And STDOUT should be empty + When I run `wp theme activate {PREVIOUS_THEME}` Then STDOUT should not be empty @@ -73,33 +80,3 @@ Feature: Manage WordPress themes """ wp-content/themes/p2 """ - - Scenario: Deleting a theme - When I run `wp theme install p2` - Then STDOUT should not be empty - - When I try `wp theme delete invalid-theme` - Then STDERR should contain: - """ - Warning: The 'invalid-theme' theme could not be found. - """ - And STDOUT should be empty - - When I run `wp theme delete p2` - Then STDOUT should be: - """ - Success: Deleted 'p2' theme. - """ - And STDERR should be empty - - When I run `wp theme install p2 --activate` - Then STDOUT should not be empty - - When I try `wp theme delete p2` - Then STDERR should be: - """ - Warning: Can't delete the currently active theme: p2 - """ - And STDOUT should be empty - - \ No newline at end of file From dca87a7f6512044cb90eaf0d66b7864bb61f0f68 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 20 Nov 2013 13:27:32 -0800 Subject: [PATCH 2505/4858] Copy, meet paste. Introduce `wp comment-meta`, derived from `wp user-meta` --- features/comment-meta.feature | 28 ++++++++++++++++++++++++++++ php/commands/comment-meta.php | 19 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 features/comment-meta.feature create mode 100644 php/commands/comment-meta.php diff --git a/features/comment-meta.feature b/features/comment-meta.feature new file mode 100644 index 0000000000..5eedef6169 --- /dev/null +++ b/features/comment-meta.feature @@ -0,0 +1,28 @@ +Feature: Manage comment custom fields + + Scenario: Comment meta CRUD + Given a WP install + + When I run `wp comment-meta add 1 foo 'bar'` + Then STDOUT should not be empty + + When I run `wp comment-meta get 1 foo` + Then STDOUT should be: + """ + bar + """ + + When I run `wp comment-meta set 1 foo '[ "1", "2" ]' --format=json` + Then STDOUT should not be empty + + When I run `wp comment-meta get 1 foo --format=json` + Then STDOUT should be: + """ + ["1","2"] + """ + + When I run `wp comment-meta delete 1 foo` + Then STDOUT should not be empty + + When I try `wp comment-meta get 1 foo` + Then the return code should be 1 diff --git a/php/commands/comment-meta.php b/php/commands/comment-meta.php new file mode 100644 index 0000000000..b1aba174b9 --- /dev/null +++ b/php/commands/comment-meta.php @@ -0,0 +1,19 @@ +<?php + +/** + * Manage comment custom fields. + * + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp comment-meta set 123 description "Mary is a WordPress developer." + */ +class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'comment'; +} + +WP_CLI::add_command( 'comment-meta', 'Comment_Meta_Command' ); From 855a989d28e13ee1644d08af2a4075f8c09ad5aa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 20 Nov 2013 14:19:27 -0800 Subject: [PATCH 2506/4858] Restore the use of `--prompt` as a runtime argument. The argument is unique of it's kind, and there isn't a great way of doing this otherwise. --- php/WP_CLI/Runner.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e09a54a584..4893ded7c4 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -394,6 +394,10 @@ private function init_config() { $configurator->merge_config( $runtime_config ); $this->config = $configurator->to_array(); + // --prompt can't be set in file, but is still a valid runtime arg + if ( ! empty( $runtime_config['prompt'] ) ) + $this->config['prompt'] = true; + if ( !isset( $this->config['path'] ) ) { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); } From 93cb822b285e66af1f834743fb2bbf628440e167 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 20 Nov 2013 14:44:05 -0800 Subject: [PATCH 2507/4858] Use new public methods of `\WP_CLI\Runner` to set the `url` if it was passed as an assoc arg by prompting. --- php/WP_CLI/Runner.php | 4 ++-- php/commands/core.php | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4893ded7c4..315a04227d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -147,7 +147,7 @@ private static function guess_url( $assoc_args ) { return false; } - private static function set_url_params( $url_parts ) { + public static function set_url_params( $url_parts ) { $f = function( $key ) use ( $url_parts ) { return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; }; @@ -534,7 +534,7 @@ public function before_wp_load() { } } - private static function parse_url( $url ) { + public static function parse_url( $url ) { $url_parts = parse_url( $url ); if ( !isset( $url_parts['scheme'] ) ) { diff --git a/php/commands/core.php b/php/commands/core.php index 09d15da96d..ab644f7872 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -444,6 +444,13 @@ private function _install( $assoc_args ) { 'admin_password' => '' ) ), EXTR_SKIP ); + // Support prompting for the `--url=<url>`, + // which is normally a runtime argument + if ( isset( $assoc_args['url'] ) ) { + $url_parts = \WP_CLI\Runner::parse_url( $assoc_args['url'] ); + \WP_CLI\Runner::set_url_params( $url_parts ); + } + $public = true; // @codingStandardsIgnoreStart From f18d0f052df559d6d8b8cdf31e76ffd49d9cfa0c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Nov 2013 11:12:44 +0200 Subject: [PATCH 2508/4858] avoid leaking private \WP_CLI\Runner properties and methods --- php/WP_CLI/Runner.php | 2 +- php/utils.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e09a54a584..17826954c0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -450,7 +450,7 @@ public function before_wp_load() { if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { - require $path; + Utils\load_file( $path ); } } diff --git a/php/utils.php b/php/utils.php index d1713b54e1..64a165fb0f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -36,6 +36,11 @@ function get_vendor_paths() { ); } +// Using require() directly inside a class grants access to private methods to the loaded code +function load_file( $path ) { + require $path; +} + function load_command( $name ) { $path = WP_CLI_ROOT . "/php/commands/$name.php"; From b87528f441b087bc5ad84e4a9bf0e34a8b5b99fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Nov 2013 11:12:55 +0200 Subject: [PATCH 2509/4858] implement `wp cli info --format=json` --- php/commands/cli.php | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 3749b0452c..36d9055cef 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -37,19 +37,33 @@ function version() { /** * Print various data about the CLI environment. + * + * @synopsis [--format=<format>] */ - function info() { + function info( $_, $assoc_args ) { $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); $runner = WP_CLI::get_runner(); - WP_CLI::line( "PHP binary:\t" . $php_bin ); - WP_CLI::line( "PHP version:\t" . PHP_VERSION ); - WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); - WP_CLI::line( "WP-CLI root:\t" . WP_CLI_ROOT ); - WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); - WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); - WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); + if ( isset( $assoc_args['format'] ) && 'json' === $assoc_args['format'] ) { + $info = array( + 'php_binary_path' => $php_bin, + 'global_config_path' => $runner->global_config_path, + 'project_config_path' => $runner->project_config_path, + 'wp_cli_dir_path' => WP_CLI_ROOT, + 'wp_cli_version' => WP_CLI_VERSION, + ); + + WP_CLI::line( json_encode( $info ) ); + } else { + WP_CLI::line( "PHP binary:\t" . $php_bin ); + WP_CLI::line( "PHP version:\t" . PHP_VERSION ); + WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); + WP_CLI::line( "WP-CLI root dir:\t" . WP_CLI_ROOT ); + WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); + WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); + WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); + } } /** From 174d33ae33a1497755a71b46755c7c8d1854a2ff Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 21 Nov 2013 11:32:18 +0200 Subject: [PATCH 2510/4858] fix 'Warning: unknown --info parameter' --- php/WP_CLI/Runner.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 17826954c0..10c06148d0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -322,6 +322,7 @@ private static function back_compat_conversions( $args, $assoc_args ) { foreach ( $special_flags as $key ) { if ( isset( $assoc_args[ $key ] ) ) { $args = array( 'cli', $key ); + unset( $assoc_args[ $key ] ); break; } } From 8949dc2a09152019d4ede3ecfcf07a3d59ec3fa6 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 21 Nov 2013 16:28:39 -0200 Subject: [PATCH 2511/4858] implement 'wp post generate --post_content=<content>' --- php/commands/post.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index ca9a156fd5..1f8f7100e3 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -268,7 +268,10 @@ public function _list( $_, $assoc_args ) { * * [--post_date=<yyyy-mm-dd>] * : The date of the generated posts. Default: current date - * + * + * [--post_content=<content>] + * : The content of the generated posts. Default: empty + * * [--max_depth=<number>] * : For hierarchical post types, generate child posts down to a certain depth. Default: 1 * @@ -286,6 +289,7 @@ public function generate( $args, $assoc_args ) { 'post_status' => 'publish', 'post_author' => false, 'post_date' => current_time( 'mysql' ), + 'post_content' => '', ); extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); @@ -340,6 +344,7 @@ public function generate( $args, $assoc_args ) { 'post_parent' => $current_parent, 'post_name' => "post-$i", 'post_date' => $post_date, + 'post_content' => $post_content, ); wp_insert_post( $args, true ); From ab45bfd97b83e3e4fcd66add340f6e985a38ebb2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 08:14:11 -0800 Subject: [PATCH 2512/4858] Introduce `\WP_CLI::set_url()`, which will set the URL context for the execution. --- php/WP_CLI/Runner.php | 11 +++++------ php/class-wp-cli.php | 8 ++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4f7b0fa7d7..68b345ffc6 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -480,10 +480,8 @@ public function before_wp_load() { // Handle --url parameter $url = self::guess_url( $this->config ); - if ( $url ) { - $url_parts = self::parse_url( $url ); - self::set_url_params( $url_parts ); - } + if ( $url ) + \WP_CLI::set_url( $url ); $this->do_early_invoke( 'before_wp_load' ); @@ -515,12 +513,13 @@ public function before_wp_load() { // We really need a URL here if ( !isset( $_SERVER['HTTP_HOST'] ) ) { - $url_parts = self::parse_url( 'http://example.com' ); - self::set_url_params( $url_parts ); + $url = 'http://example.com'; + \WP_CLI::set_url( $url ); } if ( 'multisite-install' == $this->arguments[1] ) { // need to fake some globals to skip the checks in wp-includes/ms-settings.php + $url_parts = self::parse_url( $url ); self::fake_current_site_blog( $url_parts ); if ( !defined( 'COOKIEHASH' ) ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index abe3a59288..d412adb1c5 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -83,6 +83,14 @@ private static function get_cache() { return $cache; } + /** + * Set the context in which WP-CLI should be run + */ + static function set_url( $url ) { + $url_parts = WP_CLI\Runner::parse_url( $url ); + WP_CLI\Runner::set_url_params( $url_parts ); + } + /** * @return WpHttpCacheManager */ From 8a8b1044d43e9e0db4be4a1079bc933ed152d65d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 08:21:19 -0800 Subject: [PATCH 2513/4858] Use the new `set_url()` method introduced in ab45bfd --- php/commands/core.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index ab644f7872..732b7d5993 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -446,10 +446,8 @@ private function _install( $assoc_args ) { // Support prompting for the `--url=<url>`, // which is normally a runtime argument - if ( isset( $assoc_args['url'] ) ) { - $url_parts = \WP_CLI\Runner::parse_url( $assoc_args['url'] ); - \WP_CLI\Runner::set_url_params( $url_parts ); - } + if ( isset( $assoc_args['url'] ) ) + $url_parts = WP_CLI::set_url( $assoc_args['url'] ); $public = true; From 8881f63add12d67fd7788bfbca9e87f094b05057 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 08:26:15 -0800 Subject: [PATCH 2514/4858] Move these methods to where they should be --- php/WP_CLI/Runner.php | 34 +--------------------------------- php/class-wp-cli.php | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 68b345ffc6..01abb7fc25 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -147,28 +147,6 @@ private static function guess_url( $assoc_args ) { return false; } - public static function set_url_params( $url_parts ) { - $f = function( $key ) use ( $url_parts ) { - return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; - }; - - if ( isset( $url_parts['host'] ) ) { - $_SERVER['HTTP_HOST'] = $url_parts['host']; - if ( isset( $url_parts['port'] ) ) { - $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; - } - - $_SERVER['SERVER_NAME'] = $url_parts['host']; - } - - $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); - $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; - $_SERVER['QUERY_STRING'] = $f('query'); - $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; - $_SERVER['HTTP_USER_AGENT'] = ''; - $_SERVER['REQUEST_METHOD'] = 'GET'; - } - private function cmd_starts_with( $prefix ) { return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); } @@ -519,7 +497,7 @@ public function before_wp_load() { if ( 'multisite-install' == $this->arguments[1] ) { // need to fake some globals to skip the checks in wp-includes/ms-settings.php - $url_parts = self::parse_url( $url ); + $url_parts = \WP_CLI::parse_url( $url ); self::fake_current_site_blog( $url_parts ); if ( !defined( 'COOKIEHASH' ) ) { @@ -534,16 +512,6 @@ public function before_wp_load() { } } - public static function parse_url( $url ) { - $url_parts = parse_url( $url ); - - if ( !isset( $url_parts['scheme'] ) ) { - $url_parts = parse_url( 'http://' . $url ); - } - - return $url_parts; - } - private static function fake_current_site_blog( $url_parts ) { global $current_site, $current_blog; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d412adb1c5..27051d4757 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -87,8 +87,40 @@ private static function get_cache() { * Set the context in which WP-CLI should be run */ static function set_url( $url ) { - $url_parts = WP_CLI\Runner::parse_url( $url ); - WP_CLI\Runner::set_url_params( $url_parts ); + $url_parts = self::parse_url( $url ); + self::set_url_params( $url_parts ); + } + + static function parse_url( $url ) { + $url_parts = parse_url( $url ); + + if ( !isset( $url_parts['scheme'] ) ) { + $url_parts = parse_url( 'http://' . $url ); + } + + return $url_parts; + } + + private static function set_url_params( $url_parts ) { + $f = function( $key ) use ( $url_parts ) { + return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; + }; + + if ( isset( $url_parts['host'] ) ) { + $_SERVER['HTTP_HOST'] = $url_parts['host']; + if ( isset( $url_parts['port'] ) ) { + $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; + } + + $_SERVER['SERVER_NAME'] = $url_parts['host']; + } + + $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); + $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; + $_SERVER['QUERY_STRING'] = $f('query'); + $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; + $_SERVER['HTTP_USER_AGENT'] = ''; + $_SERVER['REQUEST_METHOD'] = 'GET'; } /** From 5fe976cdff3123015e3c63fbf26506e4689f9b35 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 08:26:34 -0800 Subject: [PATCH 2515/4858] Test install via prompting --- features/core.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/features/core.feature b/features/core.feature index 07849eda64..59c78a4f52 100644 --- a/features/core.feature +++ b/features/core.feature @@ -106,6 +106,29 @@ Feature: Manage WordPress installation http://localhost:8001 """ + Scenario: Install WordPress by prompting + Given an empty directory + And WP files + And wp-config.php + And a database + And a session file: + """ + localhost:8001 + Test + wpcli + wpcli + admin@example.com + """ + + When I run `wp core install --prompt < session` + Then STDOUT should not be empty + + When I run `wp eval 'echo home_url();'` + Then STDOUT should be: + """ + http://localhost:8001 + """ + Scenario: Full install Given a WP install From 9d532c0ee824958cfe7e1788bfaeab9824767652 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 09:19:43 -0800 Subject: [PATCH 2516/4858] Introduce a helper method for launching a new WP-CLI process using the same context as the current process. --- php/class-wp-cli.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index abe3a59288..8b0c18a596 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -276,6 +276,36 @@ static function launch( $command, $exit_on_error = true ) { return $r; } + /** + * Launch another WP-CLI command using the runtime arguments for the current process + * + * @param string Command to call + * @param array $args Positional arguments to use + * @param array $assoc_args Associative arguments to use + * @param bool Whether to exit if the command returns an error status + * + * @return int The command exit status + */ + static function launch_wpcli( $command, $args, $assoc_args, $exit_on_error = true ) { + + $reused_runtime_args = array( + 'path', + 'url', + 'user', + ); + foreach( $reused_runtime_args as $key ) { + if ( $value = self::get_runner()->config[ $key ] ) + $assoc_args[$key] = $value; + } + + $full_command = constant( 'WP_CLI_ROOT' ) . '/bin/wp ' . $command . ' ' . implode( ' ', $args ); + foreach( $assoc_args as $key => $value ) { + $full_command .= ' --' . $key . '=' . $value; + } + + return self::launch( $full_command, $exit_on_error ); + } + static function get_config( $key = null ) { if ( null === $key ) { return self::get_runner()->config; From 3be1d9877a9739a6642248c4965c22618a1e4056 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 09:20:28 -0800 Subject: [PATCH 2517/4858] Now that we have a method to launch new WP-CLI processes, use it to flush rewrite rules after setting the structure. Fixes #814 --- features/rewrite.feature | 1 - php/commands/rewrite.php | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index a942bf5cb6..9ccb04f0c7 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -5,7 +5,6 @@ Feature: Manage WordPress rewrites Scenario: Change site permastructs When I run `wp rewrite structure /blog/%year%/%monthnum%/%day%/%postname%/ --category-base=section --tag-base=topic` - And I run `wp rewrite flush` When I run `wp option get permalink_structure` Then STDOUT should contain: diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 0f85ddc123..1597d97262 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -85,7 +85,14 @@ public function structure( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config self::apache_modules(); - flush_rewrite_rules( isset( $assoc_args['hard'] ) ); + + // Launch a new process to flush rewrites because core expects flush + // to happen after rewrites are set + $new_assoc_args = array(); + if ( isset( $assoc_args['hard'] ) ) + $new_assoc_args['hard'] = true; + \WP_CLI::launch_wpcli( 'rewrite flush', array(), $new_assoc_args ); + WP_CLI::success( "Rewrite structure set." ); } From bf90f46695a4fd150836e9c543bb5f95c90dddf0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 09:58:38 -0800 Subject: [PATCH 2518/4858] Support for filtering plugin and theme lists based on object attributes. --- php/WP_CLI/CommandWithUpgrade.php | 12 ++++++++++++ php/commands/plugin.php | 3 +++ php/commands/theme.php | 3 +++ 3 files changed, 18 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 73c2162c07..7ded3098a6 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -266,6 +266,18 @@ protected function _list( $_, $assoc_args ) { return $item; } ); + foreach( $it as $key => $item ) { + + foreach( $this->obj_fields as $field ) { + + if ( isset( $assoc_args[$field] ) + && $assoc_args[$field] != $item[$field] ) + $it->offsetUnset( $key ); + + } + + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $it ); } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 3edf31cb30..59436c641f 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -479,6 +479,9 @@ function delete( $args, $assoc_args = array() ) { * Get a list of plugins. * * ## OPTIONS + * + * [--<field>=<value>] + * : Filter results based on the value of a field. * * [--field=<field>] * : Prints the value of a single field for each plugin. diff --git a/php/commands/theme.php b/php/commands/theme.php index 3cfdfaeea6..1fdf3cbfe1 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -376,6 +376,9 @@ function delete( $args ) { * Get a list of themes. * * ## OPTIONS + * + * [--<field>=<value>] + * : Filter results based on the value of a field. * * [--field=<field>] * : Prints the value of a single field for each theme. From c2f22eb53256b36b0e5a1e4b77c8aa49abda0d1c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 22 Nov 2013 20:08:04 +0200 Subject: [PATCH 2519/4858] move parse_url() to utils.php, since it's a standalone utility --- php/WP_CLI/Runner.php | 2 +- php/class-wp-cli.php | 12 +----------- php/utils.php | 10 ++++++++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 01abb7fc25..a107a28508 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -497,7 +497,7 @@ public function before_wp_load() { if ( 'multisite-install' == $this->arguments[1] ) { // need to fake some globals to skip the checks in wp-includes/ms-settings.php - $url_parts = \WP_CLI::parse_url( $url ); + $url_parts = Utils\parse_url( $url ); self::fake_current_site_blog( $url_parts ); if ( !defined( 'COOKIEHASH' ) ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 27051d4757..c510a84bfc 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -87,20 +87,10 @@ private static function get_cache() { * Set the context in which WP-CLI should be run */ static function set_url( $url ) { - $url_parts = self::parse_url( $url ); + $url_parts = Utils\parse_url( $url ); self::set_url_params( $url_parts ); } - static function parse_url( $url ) { - $url_parts = parse_url( $url ); - - if ( !isset( $url_parts['scheme'] ) ) { - $url_parts = parse_url( 'http://' . $url ); - } - - return $url_parts; - } - private static function set_url_params( $url_parts ) { $f = function( $key ) use ( $url_parts ) { return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; diff --git a/php/utils.php b/php/utils.php index 64a165fb0f..c3abfdf193 100644 --- a/php/utils.php +++ b/php/utils.php @@ -358,3 +358,13 @@ function make_progress_bar( $message, $count ) { return new \cli\progress\Bar( $message, $count ); } +function parse_url( $url ) { + $url_parts = \parse_url( $url ); + + if ( !isset( $url_parts['scheme'] ) ) { + $url_parts = parse_url( 'http://' . $url ); + } + + return $url_parts; +} + From fd679d4ea3858be6a959dc44c7325c646ed0627d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 10:21:11 -0800 Subject: [PATCH 2520/4858] Test filtering based on object attribute --- features/plugin.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index be9c51cebe..da767952b9 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -88,3 +88,16 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | update | version | | akismet | active | available | 2.5.6 | + + + Scenario: List plugins + When I run `wp plugin activate akismet hello` + Then STDOUT should not be empty + + When I run `wp plugin list --status=inactive` + Then STDOUT should be empty + + When I run `wp plugin list --status=active` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | akismet | active | available | 2.5.6 | From e96494ae3f3d22376613f4d2adf787e652c16e86 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 10:50:19 -0800 Subject: [PATCH 2521/4858] These arguments should be optional --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 8b0c18a596..bd8bb68928 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -286,7 +286,7 @@ static function launch( $command, $exit_on_error = true ) { * * @return int The command exit status */ - static function launch_wpcli( $command, $args, $assoc_args, $exit_on_error = true ) { + static function launch_wpcli( $command, $args = array(), $assoc_args = array(), $exit_on_error = true ) { $reused_runtime_args = array( 'path', From e1c4c29450b16add144366ccd148a40efe01b769 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 11:05:26 -0800 Subject: [PATCH 2522/4858] Call the PHP binary directly, and ensure all arguments are escaped --- php/class-wp-cli.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index bd8bb68928..7b6fa98c83 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -298,10 +298,17 @@ static function launch_wpcli( $command, $args = array(), $assoc_args = array(), $assoc_args[$key] = $value; } - $full_command = constant( 'WP_CLI_ROOT' ) . '/bin/wp ' . $command . ' ' . implode( ' ', $args ); - foreach( $assoc_args as $key => $value ) { - $full_command .= ' --' . $key . '=' . $value; - } + $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + + $boot_fs_path = $GLOBALS['argv'][0]; + $wp_cli_root = constant( 'WP_CLI_ROOT' ); + if ( false === stripos( $boot_fs_path, $wp_cli_root ) ) + $boot_fs_path = $wp_cli_root . '/' . $boot_fs_path; + + $args = implode( ' ', array_map( 'escapeshellarg', $args ) ); + $assoc_args = \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); + + $full_command = "{$php_bin} {$boot_fs_path} {$command} {$args} {$assoc_args}"; return self::launch( $full_command, $exit_on_error ); } From c90a3245d77ce52ddac85186142567a20e9f4526 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 22 Nov 2013 11:12:18 -0800 Subject: [PATCH 2523/4858] Skip the iterator entirely --- features/plugin.feature | 8 ++++---- php/WP_CLI/CommandWithUpgrade.php | 12 ++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index da767952b9..ecd3aab3f9 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -94,10 +94,10 @@ Feature: Manage WordPress plugins When I run `wp plugin activate akismet hello` Then STDOUT should not be empty - When I run `wp plugin list --status=inactive` + When I run `wp plugin list --status=inactive --field=name` Then STDOUT should be empty - When I run `wp plugin list --status=active` + When I run `wp plugin list --status=active --fields=name,status` Then STDOUT should be a table containing rows: - | name | status | update | version | - | akismet | active | available | 2.5.6 | + | name | status | + | akismet | active | diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 7ded3098a6..1e931bff1c 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -251,7 +251,8 @@ protected function _list( $_, $assoc_args ) { if ( !is_array( $all_items ) ) \WP_CLI::error( "No {$this->item_type}s found." ); - $it = \WP_CLI\Utils\iterator_map( $all_items, function( $item ) { + foreach( $all_items as $key => &$item ) { + if ( empty( $item['version'] ) ) $item['version'] = ''; @@ -263,23 +264,18 @@ protected function _list( $_, $assoc_args ) { } } - return $item; - } ); - - foreach( $it as $key => $item ) { - foreach( $this->obj_fields as $field ) { if ( isset( $assoc_args[$field] ) && $assoc_args[$field] != $item[$field] ) - $it->offsetUnset( $key ); + unset( $all_items[$key] ); } } $formatter = $this->get_formatter( $assoc_args ); - $formatter->display_items( $it ); + $formatter->display_items( $all_items ); } /** From 4762bead90589baf4e5b6bca4884a18746e8964b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 22 Nov 2013 22:07:41 +0200 Subject: [PATCH 2524/4858] fix formatting and update examples --- php/WP_CLI/CommandWithUpgrade.php | 7 ++----- php/commands/plugin.php | 4 ++-- php/commands/theme.php | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 1e931bff1c..e4047e0991 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -251,7 +251,7 @@ protected function _list( $_, $assoc_args ) { if ( !is_array( $all_items ) ) \WP_CLI::error( "No {$this->item_type}s found." ); - foreach( $all_items as $key => &$item ) { + foreach ( $all_items as $key => &$item ) { if ( empty( $item['version'] ) ) $item['version'] = ''; @@ -264,14 +264,11 @@ protected function _list( $_, $assoc_args ) { } } - foreach( $this->obj_fields as $field ) { - + foreach ( $this->obj_fields as $field ) { if ( isset( $assoc_args[$field] ) && $assoc_args[$field] != $item[$field] ) unset( $all_items[$key] ); - } - } $formatter = $this->get_formatter( $assoc_args ); diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 59436c641f..f91aa01d08 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -479,7 +479,7 @@ function delete( $args, $assoc_args = array() ) { * Get a list of plugins. * * ## OPTIONS - * + * * [--<field>=<value>] * : Filter results based on the value of a field. * @@ -494,7 +494,7 @@ function delete( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * wp plugin list --format=json + * wp plugin list --status=active --format=json * * @subcommand list */ diff --git a/php/commands/theme.php b/php/commands/theme.php index 1fdf3cbfe1..e9fa1e70a9 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -376,7 +376,7 @@ function delete( $args ) { * Get a list of themes. * * ## OPTIONS - * + * * [--<field>=<value>] * : Filter results based on the value of a field. * @@ -391,7 +391,7 @@ function delete( $args ) { * * ## EXAMPLES * - * wp theme list --format=csv + * wp theme list --status=inactive --format=csv * * @subcommand list */ From db15b9c44bc2c8f6cb0f0af196e9105969c7f8dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 11:39:26 +0200 Subject: [PATCH 2525/4858] make merge_config() work for runtime args too --- php/WP_CLI/Configurator.php | 4 ++-- php/WP_CLI/Runner.php | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 791c6c5a14..2bfeacf25e 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -84,9 +84,9 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args, $runtime_config ); } - function merge_config( $config ) { + function merge_config( $config, $type ) { foreach ( $this->spec as $key => $details ) { - if ( $details['file'] && isset( $config[ $key ] ) ) { + if ( false !== $details[ $type ] && isset( $config[ $key ] ) ) { $value = $config[ $key ]; if ( $details['multiple'] ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a107a28508..707b371f6e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -368,15 +368,11 @@ private function init_config() { $configurator = \WP_CLI::get_configurator(); foreach ( array( $this->global_config_path, $this->project_config_path ) as $config_path ) { - $configurator->merge_config( self::load_config( $config_path ) ); + $configurator->merge_config( self::load_config( $config_path ), 'file' ); } - $configurator->merge_config( $runtime_config ); + $configurator->merge_config( $runtime_config, 'runtime' ); $this->config = $configurator->to_array(); - // --prompt can't be set in file, but is still a valid runtime arg - if ( ! empty( $runtime_config['prompt'] ) ) - $this->config['prompt'] = true; - if ( !isset( $this->config['path'] ) ) { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); } From 0b4792e67eaa3f9f459530752e290f801bbe7401 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 12:02:05 +0200 Subject: [PATCH 2526/4858] move YAML loading to Configurator --- php/WP_CLI/Configurator.php | 51 ++++++++++++++++++++++++++++++++++--- php/WP_CLI/Runner.php | 50 +++++------------------------------- 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 2bfeacf25e..283e0eb8b9 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -84,15 +84,21 @@ function parse_args( $arguments ) { return array( $regular_args, $assoc_args, $runtime_config ); } - function merge_config( $config, $type ) { + function merge_yml( $path ) { + $this->merge_config( self::load_yml( $path ), 'file' ); + } + + function merge_array( $config ) { + $this->merge_config( $config, 'runtime' ); + } + + private function merge_config( $config, $type ) { foreach ( $this->spec as $key => $details ) { if ( false !== $details[ $type ] && isset( $config[ $key ] ) ) { $value = $config[ $key ]; if ( $details['multiple'] ) { - if ( !is_array( $value ) ) { - $value = array( $value ); - } + self::arrayify( $value ); $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); } else { $this->config[ $key ] = $value; @@ -100,5 +106,42 @@ function merge_config( $config, $type ) { } } } + + /** + * Load values from a YAML file. + */ + private static function load_yml( $yml_file ) { + if ( !$yml_file ) + return array(); + + $config = spyc_load_file( $yml_file ); + + // Make sure config-file-relative paths are made absolute. + $yml_file_dir = dirname( $yml_file ); + + if ( isset( $config['path'] ) ) + self::absolutize( $config['path'], $yml_file_dir ); + + if ( isset( $config['require'] ) ) { + self::arrayify( $config['require'] ); + foreach ( $config['require'] as &$path ) { + self::absolutize( $path, $yml_file_dir ); + } + } + + return $config; + } + + private static function arrayify( &$val ) { + if ( !is_array( $val ) ) { + $val = array( $val ); + } + } + + private static function absolutize( &$path, $base ) { + if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { + $path = $base . DIRECTORY_SEPARATOR . $path; + } + } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 707b371f6e..76e716f505 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -357,7 +357,9 @@ private function check_wp_version() { } private function init_config() { - list( $args, $assoc_args, $runtime_config ) = \WP_CLI::get_configurator()->parse_args( + $configurator = \WP_CLI::get_configurator(); + + list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( @@ -366,11 +368,10 @@ private function init_config() { $this->global_config_path = self::get_global_config_path(); $this->project_config_path = self::get_project_config_path(); - $configurator = \WP_CLI::get_configurator(); - foreach ( array( $this->global_config_path, $this->project_config_path ) as $config_path ) { - $configurator->merge_config( self::load_config( $config_path ), 'file' ); - } - $configurator->merge_config( $runtime_config, 'runtime' ); + $configurator->merge_yml( $this->global_config_path ); + $configurator->merge_yml( $this->project_config_path ); + $configurator->merge_array( $runtime_config ); + $this->config = $configurator->to_array(); if ( !isset( $this->config['path'] ) ) { @@ -378,43 +379,6 @@ private function init_config() { } } - /** - * Load values from a YML file. - */ - private static function load_config( $yml_file ) { - if ( !$yml_file ) - return array(); - - $config = spyc_load_file( $yml_file ); - - // Make sure config-file-relative paths are made absolute. - $yml_file_dir = dirname( $yml_file ); - - if ( isset( $config['path'] ) ) - self::absolutize( $config['path'], $yml_file_dir ); - - if ( isset( $config['require'] ) ) { - self::arrayify( $config['require'] ); - foreach ( $config['require'] as &$path ) { - self::absolutize( $path, $yml_file_dir ); - } - } - - return $config; - } - - private static function arrayify( &$val ) { - if ( !is_array( $val ) ) { - $val = array( $val ); - } - } - - private static function absolutize( &$path, $base ) { - if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { - $path = $base . DIRECTORY_SEPARATOR . $path; - } - } - public function before_wp_load() { $this->init_config(); $this->init_colorization(); From 1ae554bbecebded595b2f05fd13c88205fbb8e8e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 12:23:32 +0200 Subject: [PATCH 2527/4858] runtime config can be set after file config --- php/WP_CLI/Runner.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 76e716f505..25f6c0b03a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -359,18 +359,25 @@ private function check_wp_version() { private function init_config() { $configurator = \WP_CLI::get_configurator(); - list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( - array_slice( $GLOBALS['argv'], 1 ) ); + // File config + { + $this->global_config_path = self::get_global_config_path(); + $this->project_config_path = self::get_project_config_path(); - list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( - $args, $assoc_args ); + $configurator->merge_yml( $this->global_config_path ); + $configurator->merge_yml( $this->project_config_path ); + } + + // Runtime config and args + { + list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( + array_slice( $GLOBALS['argv'], 1 ) ); - $this->global_config_path = self::get_global_config_path(); - $this->project_config_path = self::get_project_config_path(); + list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( + $args, $assoc_args ); - $configurator->merge_yml( $this->global_config_path ); - $configurator->merge_yml( $this->project_config_path ); - $configurator->merge_array( $runtime_config ); + $configurator->merge_array( $runtime_config ); + } $this->config = $configurator->to_array(); From add0b0bfea83523d5445ad7432d1c4a9d16b03fa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 12:51:17 +0200 Subject: [PATCH 2528/4858] keep unknown config values in memory --- php/WP_CLI/Configurator.php | 21 ++++++++++++++------- php/WP_CLI/Runner.php | 6 ++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 283e0eb8b9..e3b178f6af 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -5,7 +5,9 @@ class Configurator { private $spec; + private $config = array(); + private $extra_config = array(); function __construct( $path ) { $this->spec = include $path; @@ -26,7 +28,7 @@ function __construct( $path ) { } function to_array() { - return $this->config; + return array( $this->config, $this->extra_config ); } /** @@ -85,16 +87,21 @@ function parse_args( $arguments ) { } function merge_yml( $path ) { - $this->merge_config( self::load_yml( $path ), 'file' ); + foreach ( self::load_yml( $path ) as $key => $value ) { + if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { + $this->extra_config[ $key ] = $value; + } elseif ( $this->spec[ $key ]['multiple'] ) { + self::arrayify( $value ); + $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); + } else { + $this->config[ $key ] = $value; + } + } } function merge_array( $config ) { - $this->merge_config( $config, 'runtime' ); - } - - private function merge_config( $config, $type ) { foreach ( $this->spec as $key => $details ) { - if ( false !== $details[ $type ] && isset( $config[ $key ] ) ) { + if ( false !== $details['runtime'] && isset( $config[ $key ] ) ) { $value = $config[ $key ]; if ( $details['multiple'] ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 25f6c0b03a..a66ed049a5 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -8,7 +8,9 @@ class Runner { - private $global_config_path, $project_config_path, $config; + private $global_config_path, $project_config_path; + + private $config, $extra_config; private $arguments, $assoc_args; @@ -379,7 +381,7 @@ private function init_config() { $configurator->merge_array( $runtime_config ); } - $this->config = $configurator->to_array(); + list( $this->config, $this->extra_config ) = $configurator->to_array(); if ( !isset( $this->config['path'] ) ) { $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); From 95d6cc05fb91f6724dc08e445e09dc5bf027efba Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 13:09:15 +0200 Subject: [PATCH 2529/4858] pass config values to commands via $assoc_args --- php/WP_CLI/Runner.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a66ed049a5..2dac7b30a5 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -4,7 +4,7 @@ use WP_CLI; use WP_CLI\Utils; - +use WP_CLI\Dispatcher; class Runner { @@ -183,7 +183,7 @@ private function find_command_to_run( $args ) { $command = $subcommand; } - return array( $command, $args ); + return array( $command, $args, $cmd_path ); } public function run_command( $args, $assoc_args = array() ) { @@ -192,7 +192,13 @@ public function run_command( $args, $assoc_args = array() ) { WP_CLI::error( $r ); } - list( $command, $final_args ) = $r; + list( $command, $final_args, $cmd_path ) = $r; + + $name = implode( ' ', $cmd_path ); + + if ( isset( $this->extra_config[ $name ] ) ) { + $assoc_args = array_merge( $this->extra_config[ $name ], $assoc_args ); + } try { $command->invoke( $final_args, $assoc_args ); From 716bd2f424c3125721a36172f61054b174b6c01a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 13:31:39 +0200 Subject: [PATCH 2530/4858] add test for command-specific configs --- features/config.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/config.feature b/features/config.feature index 6771d130d1..76f19a4dae 100644 --- a/features/config.feature +++ b/features/config.feature @@ -80,3 +80,17 @@ Feature: Have a config file """ command has been disabled """ + + Scenario: Command-specific configs + Given a WP install + And a wp-cli.yml file: + """ + eval: + foo: bar + """ + + When I run `wp eval 'echo json_encode( $assoc_args );'` + Then STDOUT should be JSON containing: + """ + {"foo": "bar"} + """ From 96f241bd635f23cef233d6df458855910dae122f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 13:43:57 +0200 Subject: [PATCH 2531/4858] merge command config values after validating positional parameters --- php/WP_CLI/Dispatcher/CompositeCommand.php | 2 +- php/WP_CLI/Dispatcher/Subcommand.php | 5 ++--- php/WP_CLI/Runner.php | 6 ++++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index f57d1f9249..e5af824155 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -59,7 +59,7 @@ function get_synopsis() { return '<command>'; } - function invoke( $args, $assoc_args ) { + function invoke( $args, $assoc_args, $extra_args ) { $this->show_usage(); } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 78cda45c12..465b0d8ee8 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -197,8 +197,7 @@ private function validate_args( $args, &$assoc_args ) { } } - function invoke( $args, $assoc_args ) { - + function invoke( $args, $assoc_args, $extra_args ) { if ( \WP_CLI::get_config( 'prompt' ) ) list( $args, $assoc_args ) = $this->prompt_args( $args, $assoc_args ); @@ -206,7 +205,7 @@ function invoke( $args, $assoc_args ) { \WP_CLI::do_action( 'before_invoke:' . $this->get_parent()->get_name() ); - call_user_func( $this->when_invoked, $args, $assoc_args ); + call_user_func( $this->when_invoked, $args, array_merge( $extra_args, $assoc_args ) ); } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 2dac7b30a5..65c376a436 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -197,11 +197,13 @@ public function run_command( $args, $assoc_args = array() ) { $name = implode( ' ', $cmd_path ); if ( isset( $this->extra_config[ $name ] ) ) { - $assoc_args = array_merge( $this->extra_config[ $name ], $assoc_args ); + $extra_args = $this->extra_config[ $name ]; + } else { + $extra_args = array(); } try { - $command->invoke( $final_args, $assoc_args ); + $command->invoke( $final_args, $assoc_args, $extra_args ); } catch ( WP_CLI\Iterators\Exception $e ) { WP_CLI::error( $e->getMessage() ); } From 302b2af1e03c57f5701e4c40ef4e2d21b084750d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 23 Nov 2013 13:54:09 +0200 Subject: [PATCH 2532/4858] test that CLI args overwrite config values --- features/bootstrap/support.php | 6 ++++++ features/config.feature | 8 ++++++++ features/steps/then.php | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index afe96ec1d3..9df27c18aa 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -14,6 +14,12 @@ function assertNumeric( $actual ) { } } +function assertNotNumeric( $actual ) { + if ( is_numeric( $actual ) ) { + throw new Exception( "Actual value: " . var_export( $actual, true ) ); + } +} + function checkString( $output, $expected, $action, $message = false ) { switch ( $action ) { diff --git a/features/config.feature b/features/config.feature index 76f19a4dae..a39a943fc3 100644 --- a/features/config.feature +++ b/features/config.feature @@ -87,6 +87,8 @@ Feature: Have a config file """ eval: foo: bar + post list: + format: count """ When I run `wp eval 'echo json_encode( $assoc_args );'` @@ -94,3 +96,9 @@ Feature: Have a config file """ {"foo": "bar"} """ + + # CLI args should trump config values + When I run `wp post list` + Then STDOUT should be a number + When I run `wp post list --format=json` + Then STDOUT should not be a number diff --git a/features/steps/then.php b/features/steps/then.php index f638004670..428001a5fc 100644 --- a/features/steps/then.php +++ b/features/steps/then.php @@ -25,6 +25,12 @@ function ( $world, $stream ) { } ); +$steps->Then( '/^(STDOUT|STDERR) should not be a number$/', + function ( $world, $stream ) { + assertNotNumeric( trim( $world->result->$stream, "\n" ) ); + } +); + $steps->Then( '/^STDOUT should be a table containing rows:$/', function ( $world, TableNode $expected ) { $output = $world->result->STDOUT; From baaf3051b96c84a57a341525455db79125c5fe21 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 30 Aug 2013 18:13:53 +0300 Subject: [PATCH 2533/4858] switch to develop.svn and only download the test utilities --- templates/install-wp-tests.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 2320e61fd0..646b8c3d2e 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -26,9 +26,6 @@ fi wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR -# set up testing suite -svn co --ignore-externals --quiet http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR - # portable in-place argument for both GNU sed and Mac OSX sed if [[ $(uname -s) == 'Darwin' ]]; then ioption='-i ""' @@ -36,10 +33,13 @@ else ioption='-i' fi -# generate testing config file +# set up testing suite +mkdir -p $WP_TESTS_DIR cd $WP_TESTS_DIR -cp wp-tests-config-sample.php wp-tests-config.php -sed $ioption "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php +svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ + +wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php +sed -i "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php From 8fee09040440ba1f8efc57444631853bff5de104 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Nov 2013 19:54:22 +0200 Subject: [PATCH 2534/4858] use $ioption for all sed invocations --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 646b8c3d2e..7a7b919475 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -39,7 +39,7 @@ cd $WP_TESTS_DIR svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php -sed -i "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php +sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php From 41da7bf7fe80631261cf6c24f71156eed184bdbe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Nov 2013 20:00:31 +0200 Subject: [PATCH 2535/4858] refactor install-wp-tests.sh into 3 functions --- templates/install-wp-tests.sh | 94 +++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 7a7b919475..2ecb562c0a 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -11,55 +11,65 @@ DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-master} +WP_CORE_DIR=/tmp/wordpress/ + set -ex -# set up a WP install -WP_CORE_DIR=/tmp/wordpress/ -mkdir -p $WP_CORE_DIR +install_wp() { + mkdir -p $WP_CORE_DIR -if [ $WP_VERSION == 'latest' ]; then - ARCHIVE_NAME='latest' -else - ARCHIVE_NAME="wordpress-$WP_VERSION" -fi + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi -wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz -tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR +} -# portable in-place argument for both GNU sed and Mac OSX sed -if [[ $(uname -s) == 'Darwin' ]]; then - ioption='-i ""' -else - ioption='-i' -fi +install_test_suite() { + # portable in-place argument for both GNU sed and Mac OSX sed + if [[ $(uname -s) == 'Darwin' ]]; then + local ioption='-i ""' + else + local ioption='-i' + fi -# set up testing suite -mkdir -p $WP_TESTS_DIR -cd $WP_TESTS_DIR -svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ + # set up testing suite + mkdir -p $WP_TESTS_DIR + cd $WP_TESTS_DIR + svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ -wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php -sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php -sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php -sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php -sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php -sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php + wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php + sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php +} -# parse DB_HOST for port or socket references -PARTS=(${DB_HOST//\:/ }) -DB_HOSTNAME=${PARTS[0]}; -DB_SOCK_OR_PORT=${PARTS[1]}; -EXTRA="" +install_db() { + # parse DB_HOST for port or socket references + local PARTS=(${DB_HOST//\:/ }) + local DB_HOSTNAME=${PARTS[0]}; + local DB_SOCK_OR_PORT=${PARTS[1]}; + local EXTRA="" -if ! [ -z $DB_HOSTNAME ] ; then - if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then - EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" - elif ! [ -z $DB_SOCK_OR_PORT ] ; then - EXTRA=" --socket=$DB_SOCK_OR_PORT" - elif ! [ -z $DB_HOSTNAME ] ; then - EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" - fi -fi + if ! [ -z $DB_HOSTNAME ] ; then + if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi + fi + + # create database + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} -# create database -mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +install_wp +install_test_suite +install_db From d98dcff457c44539773ef6374e60feba2b231187 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Nov 2013 20:03:56 +0200 Subject: [PATCH 2536/4858] fix DB name replacement --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 2ecb562c0a..e92593f0f7 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -43,7 +43,7 @@ install_test_suite() { wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php - sed $ioption "s/yourdbnamehere/$DB_NAME/" wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php From 1b2d6e4a550578267d955e0d7a9f6f537a943238 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Nov 2013 20:09:54 +0200 Subject: [PATCH 2537/4858] install wp-mysqli, to avoid deprecation warnings, which cause PHPUnit to fail --- templates/install-wp-tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index e92593f0f7..82fa4a8ec9 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -26,6 +26,8 @@ install_wp() { wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + + wget -nv -O $WP_CORE_DIR/wp-content/db.php https://raw.github.com/markoheijnen/wp-mysqli/master/db.php } install_test_suite() { From 30f3c0cde9abf9d23354967d10fceaf390c020fc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 24 Nov 2013 20:55:58 +0200 Subject: [PATCH 2538/4858] remove obsolete `wp core init-tests` command --- php/commands/core.php | 71 ------------------------------------------- 1 file changed, 71 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 732b7d5993..d4c4957c8a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -721,77 +721,6 @@ function update_db() { wp_upgrade(); WP_CLI::success( 'WordPress database upgraded successfully.' ); } - - /** - * Set up the official test suite using the current WordPress instance. - * - * @subcommand init-tests - * - * ## OPTIONS - * - * [<path>] - * : The directory in which to download the testing suite files. (Optional) - * - * --dbname=<dbname> - * : Set the database name. **WARNING**: The database will be whipped every time - * you run the tests. - * - * --dbuser=<dbuser> - * : Set the database user. - * - * [--dbpass=<dbpass>] - * : Set the database user password. - * - * [--dbhost=<host>] - * : Set the database host. - * - * ## EXAMPLE - * - * wp core init-tests ~/svn/wp-tests --dbname=wp_test --dbuser=wp_test - */ - function init_tests( $args, $assoc_args ) { - if ( isset( $args[0] ) ) - $tests_dir = trailingslashit( $args[0] ); - else - $tests_dir = ABSPATH . 'unit-tests/'; - - $assoc_args = wp_parse_args( $assoc_args, array( - 'dbpass' => '', - 'dbhost' => 'localhost' - ) ); - - // Download the test suite - WP_CLI::launch( 'svn co https://unit-test.svn.wordpress.org/trunk/ ' . escapeshellarg( $tests_dir ) ); - - // Create the database - $query = sprintf( 'CREATE DATABASE IF NOT EXISTS `%s`', $assoc_args['dbname'] ); - - Utils\run_mysql_command( 'mysql --no-defaults', array( - 'execute' => $query, - 'host' => $assoc_args['dbhost'], - 'user' => $assoc_args['dbuser'], - 'pass' => $assoc_args['dbpass'], - ) ); - - // Create the wp-tests-config.php file - $config_file = file_get_contents( $tests_dir . 'wp-tests-config-sample.php' ); - - $replacements = array( - "dirname( __FILE__ ) . '/wordpress/'" => "'" . ABSPATH . "'", - "yourdbnamehere" => $assoc_args['dbname'], - "yourusernamehere" => $assoc_args['dbuser'], - "yourpasswordhere" => $assoc_args['dbpass'], - "localhost" => $assoc_args['dbhost'], - ); - - $config_file = str_replace( array_keys( $replacements ), array_values( $replacements ), $config_file ); - - $config_file_path = $tests_dir . 'wp-tests-config.php'; - - file_put_contents( $config_file_path, $config_file ); - - WP_CLI::success( "Created $config_file_path" ); - } } WP_CLI::add_command( 'core', 'Core_Command' ); From d9111162635742017d1d20e45de93370e2b8575d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Nov 2013 08:50:38 +0200 Subject: [PATCH 2539/4858] make WP_TESTS_DIR optional, by defaulting to a temporary path --- templates/.travis.yml | 1 - templates/bootstrap.mustache | 7 +++++-- templates/install-wp-tests.sh | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index bc729686e9..81650f76bb 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -11,7 +11,6 @@ env: - WP_VERSION=3.6.1 WP_MULTISITE=1 before_script: - - export WP_TESTS_DIR=/tmp/wordpress-tests/ - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION script: phpunit diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index 18f87a91a5..c18a7fe3ee 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -1,11 +1,14 @@ <?php -require_once getenv( 'WP_TESTS_DIR' ) . '/includes/functions.php'; +$_tests_dir = getenv('WP_TESTS_DIR'); +if ( !$_tests_dir ) $_tests_dir = '/tmp/wordpress-tests-lib'; + +require_once $_tests_dir . '/includes/functions.php'; function _manually_load_plugin() { require dirname( __FILE__ ) . '/../{{plugin_slug}}.php'; } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); -require getenv( 'WP_TESTS_DIR' ) . '/includes/bootstrap.php'; +require $_tests_dir . '/includes/bootstrap.php'; diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 82fa4a8ec9..88e2dd3f2b 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -11,6 +11,7 @@ DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-master} +WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=/tmp/wordpress/ set -ex From 706f978b53991d4dcf3c1449cb97757f9caf3a9d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 25 Nov 2013 09:41:48 +0200 Subject: [PATCH 2540/4858] plugin tests: use better backup extension --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 88e2dd3f2b..782dec87ec 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -34,7 +34,7 @@ install_wp() { install_test_suite() { # portable in-place argument for both GNU sed and Mac OSX sed if [[ $(uname -s) == 'Darwin' ]]; then - local ioption='-i ""' + local ioption='-i .bak' else local ioption='-i' fi From 7de457b231a285c84606225cf0c5167051bae35c Mon Sep 17 00:00:00 2001 From: Tiago Hillebrandt <tiagohillebrandt@ubuntu.com> Date: Mon, 25 Nov 2013 03:10:42 -0600 Subject: [PATCH 2541/4858] Implements 'wp plugin deactivate --all' function --- php/commands/plugin.php | 45 ++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index f91aa01d08..8da2044edb 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -158,25 +158,46 @@ function activate( $args, $assoc_args = array() ) { * * ## OPTIONS * - * <plugin>... + * [<plugin>...] * : One or more plugins to deactivate. * + * [--all] + * : If set, all plugins will be deactivated. + * * [--network] * : If set, the plugin will be deactivated for the entire multisite network. */ function deactivate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - - foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - deactivate_plugins( $plugin->file, false, $network_wide ); - - if ( ! $this->check_active( $plugin->file, $network_wide ) ) { - if ( $network_wide ) - WP_CLI::success( "Plugin '{$plugin->name}' network deactivated." ); - else - WP_CLI::success( "Plugin '{$plugin->name}' deactivated." ); - } else { - WP_CLI::warning( "Could not deactivate the '{$plugin->name}' plugin." ); + $disable_all = isset( $assoc_args['all'] ); + + if ( $disable_all ) { + foreach ( get_plugins() as $file => $details ) { + $name = $this->get_name( $file ); + + deactivate_plugins( $name, false, $network_wide ); + + if ( ! $this->check_active( $file, $network_wide ) ) { + if ( $network_wide ) + WP_CLI::success( "Plugin '{$name}' network deactivated." ); + else + WP_CLI::success( "Plugin '{$name}' deactivated." ); + } else { + WP_CLI::warning( "Could not deactivate the '{$name}' plugin." ); + } + } + } else { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { + deactivate_plugins( $plugin->file, false, $network_wide ); + + if ( ! $this->check_active( $plugin->file, $network_wide ) ) { + if ( $network_wide ) + WP_CLI::success( "Plugin '{$plugin->name}' network deactivated." ); + else + WP_CLI::success( "Plugin '{$plugin->name}' deactivated." ); + } else { + WP_CLI::warning( "Could not deactivate the '{$plugin->name}' plugin." ); + } } } } From 2479dccb14850c034585e0a031b7fffb6a49ba7d Mon Sep 17 00:00:00 2001 From: Tiago Hillebrandt <tiagohillebrandt@ubuntu.com> Date: Mon, 25 Nov 2013 05:05:09 -0600 Subject: [PATCH 2542/4858] Implements the 'wp plugin deactivate --all' function --- php/commands/plugin.php | 44 +++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 8da2044edb..a747747f49 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -142,14 +142,7 @@ function activate( $args, $assoc_args = array() ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { activate_plugin( $plugin->file, '', $network_wide ); - if ( $this->check_active( $plugin->file, $network_wide ) ) { - if ( $network_wide ) - WP_CLI::success( "Plugin '{$plugin->name}' network activated." ); - else - WP_CLI::success( "Plugin '{$plugin->name}' activated." ); - } else { - WP_CLI::warning( "Could not activate the '{$plugin->name}' plugin." ); - } + $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); } } @@ -172,32 +165,18 @@ function deactivate( $args, $assoc_args = array() ) { $disable_all = isset( $assoc_args['all'] ); if ( $disable_all ) { - foreach ( get_plugins() as $file => $details ) { + foreach ( get_plugins() as $file => $details ) { $name = $this->get_name( $file ); - deactivate_plugins( $name, false, $network_wide ); + deactivate_plugins( $file, false, $network_wide ); - if ( ! $this->check_active( $file, $network_wide ) ) { - if ( $network_wide ) - WP_CLI::success( "Plugin '{$name}' network deactivated." ); - else - WP_CLI::success( "Plugin '{$name}' deactivated." ); - } else { - WP_CLI::warning( "Could not deactivate the '{$name}' plugin." ); - } + $this->active_output( $name, $file, $network_wide, "deactivate" ); } } else { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { deactivate_plugins( $plugin->file, false, $network_wide ); - if ( ! $this->check_active( $plugin->file, $network_wide ) ) { - if ( $network_wide ) - WP_CLI::success( "Plugin '{$plugin->name}' network deactivated." ); - else - WP_CLI::success( "Plugin '{$plugin->name}' deactivated." ); - } else { - WP_CLI::warning( "Could not deactivate the '{$plugin->name}' plugin." ); - } + $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); } } } @@ -531,6 +510,19 @@ private function check_active( $file, $network_wide ) { return $required == $this->get_status( $file ); } + private function active_output( $name, $file, $network_wide, $action ) { + $check = $this->check_active( $file, $network_wide ); + + if ( ( $action == "activate" ) ? $check : ! $check ) { + if ( $network_wide ) + WP_CLI::success( "Plugin '{$name}' network {$action}d." ); + else + WP_CLI::success( "Plugin '{$name}' {$action}d." ); + } else { + WP_CLI::warning( "Could not {$action} the '{$name}' plugin." ); + } + } + protected function get_status( $file ) { if ( is_plugin_active_for_network( $file ) ) return 'active-network'; From 829ae8f8545f5081c8dd4b028d201b429fee94d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 26 Nov 2013 09:25:21 +0200 Subject: [PATCH 2543/4858] s/action/hook --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/class-wp-cli.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 465b0d8ee8..534c367d75 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -203,7 +203,7 @@ function invoke( $args, $assoc_args, $extra_args ) { $this->validate_args( $args, $assoc_args ); - \WP_CLI::do_action( 'before_invoke:' . $this->get_parent()->get_name() ); + \WP_CLI::do_hook( 'before_invoke:' . $this->get_parent()->get_name() ); call_user_func( $this->when_invoked, $args, array_merge( $extra_args, $assoc_args ) ); } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index c510a84bfc..946bd304dd 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -133,7 +133,7 @@ static function colorize( $string ) { /** * Schedule a callback to be executed at a certain point (before WP is loaded). */ - static function add_action( $when, $callback ) { + static function add_hook( $when, $callback ) { if ( in_array( $when, self::$hooks_passed ) ) call_user_func( $callback ); @@ -143,7 +143,7 @@ static function add_action( $when, $callback ) { /** * Execute registered callbacks. */ - static function do_action( $when ) { + static function do_hook( $when ) { self::$hooks_passed[] = $when; if ( !isset( self::$hooks[ $when ] ) ) @@ -164,7 +164,7 @@ static function add_command( $name, $class, $args = array() ) { $command = Dispatcher\CommandFactory::create( $name, $class, self::get_root_command() ); if ( isset( $args['before_invoke'] ) ) { - self::add_action( "before_invoke:$name", $args['before_invoke'] ); + self::add_hook( "before_invoke:$name", $args['before_invoke'] ); } self::get_root_command()->add_subcommand( $name, $command ); From 2a226bff97c00a7713418f46327cb1c15c64a77c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 26 Nov 2013 13:24:37 -0800 Subject: [PATCH 2544/4858] Support for `user_email` as a third type of argument that can be passed to `<user>` --- php/WP_CLI/Fetchers/User.php | 13 ++++++++----- php/commands/user.php | 18 +++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/php/WP_CLI/Fetchers/User.php b/php/WP_CLI/Fetchers/User.php index 81bbbc20ac..122dfd0fcc 100644 --- a/php/WP_CLI/Fetchers/User.php +++ b/php/WP_CLI/Fetchers/User.php @@ -4,13 +4,16 @@ class User extends Base { - protected $msg = "Invalid user ID or login: '%s'"; + protected $msg = "Invalid user ID, email or login: '%s'"; - public function get( $id_or_login ) { - if ( is_numeric( $id_or_login ) ) - $user = get_user_by( 'id', $id_or_login ); + public function get( $id_email_or_login ) { + + if ( is_email( $id_email_or_login ) ) + $user = get_user_by( 'email', $id_email_or_login ); + else if ( is_numeric( $id_email_or_login ) ) + $user = get_user_by( 'id', $id_email_or_login ); else - $user = get_user_by( 'login', $id_or_login ); + $user = get_user_by( 'login', $id_email_or_login ); return $user; } diff --git a/php/commands/user.php b/php/commands/user.php index ae1733a4da..b60d4b0210 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -80,7 +80,7 @@ public function _list( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID, user email, or user login. * * [--field=<field>] * : Instead of returning the whole user, returns the value of a single field. @@ -119,7 +119,7 @@ public function get( $args, $assoc_args ) { * ## OPTIONS * * <user>... - * : The user login or ID of the user(s) to update. + * : The user login, user email, or user ID of the user(s) to update. * * [--reassign=<user-id>] * : User ID to reassign the posts to. @@ -235,7 +235,7 @@ public function create( $args, $assoc_args ) { * ## OPTIONS * * <user>... - * : The user login or ID of the user(s) to update. + * : The user login, user email or user ID of the user(s) to update. * * --<field>=<value> * : One or more fields to update. For accepted fields, see wp_update_user(). @@ -313,7 +313,7 @@ public function generate( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID, user email, or user login. * * [<role>] * : Make the user have the specified role. If not passed, the default role is @@ -346,7 +346,7 @@ public function set_role( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID, user email, or user login. * * <role> * : Add the specified role to the user. @@ -374,7 +374,7 @@ public function add_role( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID, user email, or user login. * * [<role>] * : A specific role to remove. @@ -412,7 +412,7 @@ public function remove_role( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID, user email, or user login. * * <cap> * : The capability to add. @@ -440,7 +440,7 @@ public function add_cap( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or user login. + * : User ID, user email, or user login. * * <cap> * : The capability to be removed. @@ -468,7 +468,7 @@ public function remove_cap( $args, $assoc_args ) { * ## OPTIONS * * <user> - * : User ID or login. + * : User ID, user email, or login. * * ## EXAMPLES * From c052ca9286b88744e601ea07aa41864713d865bd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 26 Nov 2013 13:26:41 -0800 Subject: [PATCH 2545/4858] Update functional test with email case --- features/user.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/user.feature b/features/user.feature index 14ecdf18a0..aae1ad930f 100644 --- a/features/user.feature +++ b/features/user.feature @@ -22,6 +22,12 @@ Feature: Manage WordPress users | ID | {USER_ID} | | display_name | Foo | + When I run `wp user get testuser@example.com` + Then STDOUT should be a table containing rows: + | Field | Value | + | ID | {USER_ID} | + | display_name | Foo | + When I run `wp user delete {USER_ID}` Then STDOUT should not be empty From be36a7f29639717303eb64a556dc93d5b9328729 Mon Sep 17 00:00:00 2001 From: Tiago Hillebrandt <tiagohillebrandt@ubuntu.com> Date: Wed, 27 Nov 2013 09:53:12 -0600 Subject: [PATCH 2546/4858] Deactivate only active plugins. --- php/commands/plugin.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index a747747f49..7b1ece99c2 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -166,6 +166,9 @@ function deactivate( $args, $assoc_args = array() ) { if ( $disable_all ) { foreach ( get_plugins() as $file => $details ) { + if ( $this->get_status( $file ) == "inactive" ) + continue; + $name = $this->get_name( $file ); deactivate_plugins( $file, false, $network_wide ); From 27d80a619b1cc2c13b0d65d9904ab56bbb482f53 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Wed, 27 Nov 2013 20:59:12 +0000 Subject: [PATCH 2547/4858] Make validate_role() return a bool. Throw error at caller if required --- php/commands/user.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index ae1733a4da..b774423b95 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -193,7 +193,9 @@ public function create( $args, $assoc_args ) { ); extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); - $role = self::validate_role( $role ); + if ( !self::validate_role( $role ) ) { + WP_CLI::error( "Invalid role: $role" ); + } // @codingStandardsIgnoreStart if ( !$user_pass ) { @@ -276,7 +278,9 @@ public function generate( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); - $role = self::validate_role( $assoc_args['role'] ); + if ( !self::validate_role( $assoc_args['role'] ) ) { + WP_CLI::error( "Invalid role: $role" ); + } $user_count = count_users(); $total = $user_count['total_users']; @@ -580,11 +584,10 @@ public function import_csv( $args, $assoc_args ) { } private static function validate_role( $role ) { - if ( 'none' === $role ) { - $role = false; - } elseif ( is_null( get_role( $role ) ) ) { - WP_CLI::error( "Invalid role: $role" ); + if ( empty( $role ) || ! is_null( get_role( $role ) ) ) { + return true; } + return false; } } From 4c61e978354ab383c49eb3d4549b3227e81d1983 Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Wed, 27 Nov 2013 20:59:22 +0000 Subject: [PATCH 2548/4858] Add tests --- features/user.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/user.feature b/features/user.feature index 14ecdf18a0..008665a94d 100644 --- a/features/user.feature +++ b/features/user.feature @@ -8,6 +8,22 @@ Feature: Manage WordPress users Then the return code should be 1 And STDOUT should be empty + When I run `wp user create testuser2 testuser2@example.com --role=author --porcelain` + Then STDOUT should be a number + And save STDOUT as {USER_ID} + And I run `wp user get {USER_ID}` + Then STDOUT should be a table containing rows: + | Field | Value | + | ID | {USER_ID} | + | roles | author | + + When I run `wp user delete {USER_ID}` + Then STDOUT should not be empty + + When I try `wp user create testuser2 testuser2@example.com --role=wrongrole --porcelain` + Then the return code should be 1 + Then STDOUT should be empty + When I run `wp user create testuser testuser@example.com --porcelain` Then STDOUT should be a number And save STDOUT as {USER_ID} From e2dc3cc8e4deacf7a1a019d3ec26ee862ba19bda Mon Sep 17 00:00:00 2001 From: Lee Willis <leewillis77@gmail.com> Date: Thu, 28 Nov 2013 10:14:58 +0000 Subject: [PATCH 2549/4858] Fix spacing --- features/user.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index 008665a94d..df1ab11d1e 100644 --- a/features/user.feature +++ b/features/user.feature @@ -11,8 +11,8 @@ Feature: Manage WordPress users When I run `wp user create testuser2 testuser2@example.com --role=author --porcelain` Then STDOUT should be a number And save STDOUT as {USER_ID} - And I run `wp user get {USER_ID}` - Then STDOUT should be a table containing rows: + And I run `wp user get {USER_ID}` + Then STDOUT should be a table containing rows: | Field | Value | | ID | {USER_ID} | | roles | author | From cf35c7e6493bce575748de4af00e095ef17477a4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Nov 2013 21:19:09 +0200 Subject: [PATCH 2550/4858] bump version to 0.13-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index ebeac71ea4..c73b198333 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13-alpha3' ); +define( 'WP_CLI_VERSION', '0.13-beta' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 011446f346fff4c66ec23c0a97b6bc0c6f7eb1a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Nov 2013 21:31:41 +0200 Subject: [PATCH 2551/4858] add test case for activating network-only plugins --- features/plugin.feature | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index ecd3aab3f9..48517e4565 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -1,9 +1,7 @@ Feature: Manage WordPress plugins - Background: - Given a WP install - Scenario: Create, activate and check plugin status + Given a WP install And I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} @@ -70,6 +68,8 @@ Feature: Manage WordPress plugins """ Scenario: Install a plugin, activate, then force install an older version of the plugin + Given a WP install + When I run `wp plugin install akismet --version=2.5.7 --force` Then STDOUT should not be empty @@ -89,8 +89,23 @@ Feature: Manage WordPress plugins | name | status | update | version | | akismet | active | available | 2.5.6 | + Scenario: Activate a network-only plugin + Given a WP multisite install + And a wp-content/plugins/network-only.php file: + """ + // Plugin Name: Example Plugin + // Network: true + """ + When I run `wp plugin activate network-only` + And I run `wp plugin status network-only` + Then STDOUT should contain: + """ + Status: Network Active + """ Scenario: List plugins + Given a WP install + When I run `wp plugin activate akismet hello` Then STDOUT should not be empty From c3ae0cfbe7093dd63b9bcea73ee28c294ee3c141 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 28 Nov 2013 21:42:44 +0200 Subject: [PATCH 2552/4858] check if plugin is network-only --- php/commands/plugin.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 7b1ece99c2..5f9277abf2 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -514,6 +514,8 @@ private function check_active( $file, $network_wide ) { } private function active_output( $name, $file, $network_wide, $action ) { + $network_wide = $network_wide || is_network_only_plugin( $file ); + $check = $this->check_active( $file, $network_wide ); if ( ( $action == "activate" ) ? $check : ! $check ) { From 6900ba58f63dccdb18402304e408dcbca83d53d2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Nov 2013 22:41:47 +0200 Subject: [PATCH 2553/4858] clarify inline docs for --format parameter; fixes #884 --- php/commands/cli.php | 5 ++++- php/commands/comment.php | 7 ++----- php/commands/plugin.php | 4 ++-- php/commands/post.php | 11 +++-------- php/commands/rewrite.php | 6 +++--- php/commands/role.php | 2 +- php/commands/site.php | 2 +- php/commands/term.php | 7 ++----- php/commands/theme.php | 6 +++--- php/commands/user.php | 8 ++------ 10 files changed, 23 insertions(+), 35 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 36d9055cef..752b1d603c 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -38,7 +38,10 @@ function version() { /** * Print various data about the CLI environment. * - * @synopsis [--format=<format>] + * ## OPTIONS + * + * [--format=<format>] + * : Accepted values: json */ function info( $_, $assoc_args ) { $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); diff --git a/php/commands/comment.php b/php/commands/comment.php index 06b4b64a42..6a45b839c8 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -94,10 +94,7 @@ public function update( $args, $assoc_args ) { * : Instead of returning the whole comment, returns the value of a single field. * * [--format=<format>] - * : The format to use when printing the comment, acceptable values: - * - * - **table**: Outputs all fields of the comment as a table. - * - **json**: Outputs all fields in JSON format. + * : Accepted values: table, json. Default: table * * ## EXAMPLES * @@ -128,7 +125,7 @@ public function get( $args, $assoc_args ) { * : Limit the output to specific object fields. Defaults to comment_ID,comment_post_ID,comment_date,comment_approved,comment_author,comment_author_email * * [--format=<format>] - * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 5f9277abf2..d0e802f593 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -76,7 +76,7 @@ function status( $args ) { * **short_description**: Plugin's Short Description * * [--format=<format>] - * : Output list as table, CSV or JSON. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * @@ -493,7 +493,7 @@ function delete( $args, $assoc_args = array() ) { * : Limit the output to specific object fields. Defaults to name,status,update,version. * * [--format=<format>] - * : Output list as table, CSV or JSON. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * diff --git a/php/commands/post.php b/php/commands/post.php index ca9a156fd5..f6f11ba669 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -142,12 +142,7 @@ protected function _edit( $content, $title ) { * : Instead of returning the whole post, returns the value of a single field. * * [--format=<format>] - * : The format to use when printing the post, acceptable values: - * - * - **table**: Outputs all fields of the post as a table. Note that the - * post_content field is omitted so that the table is readable. - * - * - **json**: Outputs all fields in JSON format. + * : Accepted values: table, json. Default: table * * ## EXAMPLES * @@ -215,7 +210,7 @@ public function delete( $args, $assoc_args ) { * : Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. * * [--format=<format>] - * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * @@ -236,7 +231,7 @@ public function _list( $_, $assoc_args ) { ); $query_args = array_merge( $defaults, $assoc_args ); - foreach( $query_args as $key => $query_arg ) { + foreach ( $query_args as $key => $query_arg ) { if ( false !== strpos( $key, '__' ) ) $query_args[$key] = explode( ',', $query_arg ); } diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 0f85ddc123..04f15cae71 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -93,15 +93,15 @@ public function structure( $args, $assoc_args ) { * Print current rewrite rules. * * ## OPTIONS - * + * * [--match=<url>] * : Show rewrite rules matching a particular URL. - * + * * [--source=<source>] * : Show rewrite rules from a particular source. * * [--format=<format>] - * : Output list as table, JSON or CSV. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * diff --git a/php/commands/role.php b/php/commands/role.php index 97674ffbfe..99e5ecb60d 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -21,7 +21,7 @@ class Role_Command extends WP_CLI_Command { * : Limit the output to specific object fields. Defaults to name,role. * * [--format=<format>] - * : Output list as table, CSV or JSON. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * diff --git a/php/commands/site.php b/php/commands/site.php index e3d500da41..111a91515a 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -317,7 +317,7 @@ public function create( $_, $assoc_args ) { * : Comma-separated list of fields to show. * * [--format=<format>] - * : Output list as table, csv, json or url. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * diff --git a/php/commands/term.php b/php/commands/term.php index 770e5f3dad..8e9fc9d7c3 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -34,7 +34,7 @@ class Term_Command extends WP_CLI_Command { * : Limit the output to specific object fields. Defaults to all of the term object fields. * * [--format=<format>] - * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * @@ -131,10 +131,7 @@ public function create( $args, $assoc_args ) { * : Instead of returning the whole term, returns the value of a single field. * * [--format=<format>] - * : The format to use when printing the term, acceptable values: - * - * - **table**: Outputs all fields of the term as a table. - * - **json**: Outputs all fields in JSON format. + * : Accepted values: table, json. Default: table * * ## EXAMPLES * diff --git a/php/commands/theme.php b/php/commands/theme.php index e9fa1e70a9..7975acb86c 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -69,7 +69,7 @@ function status( $args ) { * **description**: Theme Description * * [--format=<format>] - * : Output list as table, CSV or JSON. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * @@ -266,7 +266,7 @@ function install( $args, $assoc_args ) { * : Instead of returning the whole theme, returns the value of a single field. * * [--format=<format>] - * : Output list as table or JSON. Defaults to table. + * : Accepted values: table, json. Default: table * * ## EXAMPLES * @@ -387,7 +387,7 @@ function delete( $args ) { * : Limit the output to specific object fields. Defaults to name,status,update,version. * * [--format=<format>] - * : Output list as table, CSV or JSON. Defaults to table. + * : Accepted values: table, json. Default: table * * ## EXAMPLES * diff --git a/php/commands/user.php b/php/commands/user.php index b774423b95..9e02172f8c 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -39,7 +39,7 @@ public function __construct() { * : Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles * * [--format=<format>] - * : Output list as table, CSV, JSON, or simply IDs. Defaults to table. + * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES * @@ -86,11 +86,7 @@ public function _list( $args, $assoc_args ) { * : Instead of returning the whole user, returns the value of a single field. * * [--format=<format>] - * : The format to use when printing the user; acceptable values: - * - * **table**: Outputs all fields of the user as a table. - * - * **json**: Outputs all fields in JSON format. + * : Accepted values: table, json. Default: table * * ## EXAMPLES * From 37b9a38853b083af855b57ec9e289c0b54ad9066 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Nov 2013 23:26:38 +0200 Subject: [PATCH 2554/4858] include extra args when checking required associative parameters; see #883 --- features/config.feature | 11 +++++++++++ php/WP_CLI/Dispatcher/Subcommand.php | 19 ++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/features/config.feature b/features/config.feature index a39a943fc3..12267e573d 100644 --- a/features/config.feature +++ b/features/config.feature @@ -85,12 +85,23 @@ Feature: Have a config file Given a WP install And a wp-cli.yml file: """ + core config: + dbname: wordpress + dbuser: root eval: foo: bar post list: format: count """ + # Required parameters should be recognized + When I try `wp core config` + Then STDERR should not contain: + """ + Parameter errors + """ + + # Arbitrary values should be passed, without warnings When I run `wp eval 'echo json_encode( $assoc_args );'` Then STDOUT should be JSON containing: """ diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 534c367d75..ae9bd32bb0 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -146,9 +146,8 @@ private function prompt_args( $args, $assoc_args ) { return array( $args, $assoc_args ); } - private function validate_args( $args, &$assoc_args ) { + private function validate_args( $args, $assoc_args, $extra_args ) { $synopsis = $this->get_synopsis(); - if ( !$synopsis ) return; @@ -174,7 +173,7 @@ private function validate_args( $args, &$assoc_args ) { } list( $errors, $to_unset ) = $validator->validate_assoc( - array_merge( \WP_CLI::get_config(), $assoc_args ) + array_merge( \WP_CLI::get_config(), $extra_args, $assoc_args ) ); if ( !empty( $errors['fatal'] ) ) { @@ -188,22 +187,24 @@ private function validate_args( $args, &$assoc_args ) { array_map( '\\WP_CLI::warning', $errors['warning'] ); - foreach ( $to_unset as $key ) { - unset( $assoc_args[ $key ] ); - } - foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { \WP_CLI::warning( "unknown --$key parameter" ); } + + return $to_unset; } function invoke( $args, $assoc_args, $extra_args ) { if ( \WP_CLI::get_config( 'prompt' ) ) list( $args, $assoc_args ) = $this->prompt_args( $args, $assoc_args ); - $this->validate_args( $args, $assoc_args ); + $to_unset = $this->validate_args( $args, $assoc_args, $extra_args ); + + foreach ( $to_unset as $key ) { + unset( $assoc_args[ $key ] ); + } - \WP_CLI::do_hook( 'before_invoke:' . $this->get_parent()->get_name() ); + \WP_CLI::do_action( 'before_invoke:' . $this->get_parent()->get_name() ); call_user_func( $this->when_invoked, $args, array_merge( $extra_args, $assoc_args ) ); } From b720f6d92828d4e8654bc0ae1d45f1c52a93c7be Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Nov 2013 23:31:04 +0200 Subject: [PATCH 2555/4858] replace do_action() with do_hook() again; see #883 --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index ae9bd32bb0..41b7a135f0 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -204,7 +204,7 @@ function invoke( $args, $assoc_args, $extra_args ) { unset( $assoc_args[ $key ] ); } - \WP_CLI::do_action( 'before_invoke:' . $this->get_parent()->get_name() ); + \WP_CLI::do_hook( 'before_invoke:' . $this->get_parent()->get_name() ); call_user_func( $this->when_invoked, $args, array_merge( $extra_args, $assoc_args ) ); } From 4fc145153689b3c8a38253bda5e974d7e56058d6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Nov 2013 23:40:00 +0200 Subject: [PATCH 2556/4858] make validate_args() always return an array see #883 --- php/WP_CLI/Dispatcher/Subcommand.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 41b7a135f0..8f112c86b6 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -146,10 +146,13 @@ private function prompt_args( $args, $assoc_args ) { return array( $args, $assoc_args ); } + /** + * @return array list of invalid $assoc_args keys to unset + */ private function validate_args( $args, $assoc_args, $extra_args ) { $synopsis = $this->get_synopsis(); if ( !$synopsis ) - return; + return array(); $validator = new \WP_CLI\SynopsisValidator( $synopsis ); From af6c9ef96c88d96365a340b6959e75fc95952daa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 Nov 2013 23:00:26 +0200 Subject: [PATCH 2557/4858] disable HTML escaping when rendering Mustache templates --- php/utils.php | 9 ++++++++- templates/man-params.mustache | 2 +- templates/man.mustache | 8 ++++---- templates/post_type_extended.mustache | 2 +- templates/taxonomy_extended.mustache | 2 +- templates/wp-config.mustache | 4 ++-- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/php/utils.php b/php/utils.php index c3abfdf193..1972c25057 100644 --- a/php/utils.php +++ b/php/utils.php @@ -340,13 +340,20 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { if ( $r ) exit( $r ); } +/** + * Render PHP or other types of files using Mustache templates. + * + * IMPORTANT: Automatic HTML escaping is disabled! + */ function mustache_render( $template_name, $data ) { if ( ! file_exists( $template_name ) ) $template_name = WP_CLI_ROOT . "/templates/$template_name"; $template = file_get_contents( $template_name ); - $m = new \Mustache_Engine; + $m = new \Mustache_Engine( array( + 'escape' => function ( $val ) { return $val; } + ) ); return $m->render( $template, $data ); } diff --git a/templates/man-params.mustache b/templates/man-params.mustache index 990412b748..dd848d83f9 100644 --- a/templates/man-params.mustache +++ b/templates/man-params.mustache @@ -1,7 +1,7 @@ ## GLOBAL PARAMETERS {{#parameters}} - {{{synopsis}}} + {{synopsis}} {{desc}} {{/parameters}} diff --git a/templates/man.mustache b/templates/man.mustache index 6767c83d87..a42acbcc35 100644 --- a/templates/man.mustache +++ b/templates/man.mustache @@ -1,20 +1,20 @@ ## NAME - {{{name}}} + {{name}} ## DESCRIPTION - {{{shortdesc}}} + {{shortdesc}} ## SYNOPSIS - {{{synopsis}}} + {{synopsis}} {{#has-subcommands}} ## SUBCOMMANDS {{#subcommands}} - {{{.}}} + {{.}} {{/subcommands}} {{/has-subcommands}} diff --git a/templates/post_type_extended.mustache b/templates/post_type_extended.mustache index 9acbbb5d20..b8250fde9a 100644 --- a/templates/post_type_extended.mustache +++ b/templates/post_type_extended.mustache @@ -1,7 +1,7 @@ <?php function {{machine_name}}_init() { -{{{output}}} +{{output}} } add_action( 'init', '{{machine_name}}_init' ); diff --git a/templates/taxonomy_extended.mustache b/templates/taxonomy_extended.mustache index 8e0e1a5c73..e2e584a115 100644 --- a/templates/taxonomy_extended.mustache +++ b/templates/taxonomy_extended.mustache @@ -1,6 +1,6 @@ <?php function {{machine_name}}_init() { -{{{output}}} +{{output}} } add_action( 'init', '{{machine_name}}_init' ); diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index d0cec68c14..e708cc189e 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -36,7 +36,7 @@ define('DB_COLLATE', '{{dbcollate}}'); * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again. */ -{{{keys-and-salts}}} +{{keys-and-salts}} /**#@-*/ {{/keys-and-salts}} @@ -58,7 +58,7 @@ $table_prefix = '{{dbprefix}}'; */ define('WPLANG', '{{locale}}'); -{{{extra-php}}} +{{extra-php}} /* That's all, stop editing! Happy blogging. */ From c7494c543a609ee30681f6724462c7f0396e1d9e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 00:10:03 +0200 Subject: [PATCH 2558/4858] add example of using sort with 'wp cap list'; closes #715 --- php/commands/cap.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/cap.php b/php/commands/cap.php index 97d84113c7..c5cc77745f 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -19,6 +19,11 @@ class Capabilities_Command extends WP_CLI_Command { /** * List capabilities for a given role. * + * ## EXAMPLES + * + * # Display alphabetical list of bbPress moderator capabilities + * wp cap list 'bbp_moderator' | sort + * * @subcommand list * @synopsis <role> */ From 099ecae9fd2ef8ca562fba2284f062fa2229bbb5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 00:30:07 +0200 Subject: [PATCH 2559/4858] exclude Finder tests from Phar --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 4563f60a79..2d789e617f 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -41,6 +41,7 @@ function add_file( $phar, $path ) { ->in('./vendor/rhumsaa/array_column') ->exclude('test') ->exclude('tests') + ->exclude('Tests') ->exclude('php-cli-tools/examples') ; From 81329f749058b5f64f0faa775f344491ade1053d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 00:57:24 +0200 Subject: [PATCH 2560/4858] rename launch_wpcli() to launch_self() and make it work from inside a Phar file --- php/class-wp-cli.php | 38 ++++++++++++++++++++++++-------------- php/commands/rewrite.php | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7b6fa98c83..351782d658 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -278,40 +278,50 @@ static function launch( $command, $exit_on_error = true ) { /** * Launch another WP-CLI command using the runtime arguments for the current process - * + * * @param string Command to call * @param array $args Positional arguments to use * @param array $assoc_args Associative arguments to use * @param bool Whether to exit if the command returns an error status - * + * * @return int The command exit status */ - static function launch_wpcli( $command, $args = array(), $assoc_args = array(), $exit_on_error = true ) { - + static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true ) { $reused_runtime_args = array( 'path', 'url', 'user', - ); - foreach( $reused_runtime_args as $key ) { + ); + + foreach ( $reused_runtime_args as $key ) { if ( $value = self::get_runner()->config[ $key ] ) - $assoc_args[$key] = $value; + $assoc_args[ $key ] = $value; } - $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + $php_bin = self::get_php_binary(); - $boot_fs_path = $GLOBALS['argv'][0]; - $wp_cli_root = constant( 'WP_CLI_ROOT' ); - if ( false === stripos( $boot_fs_path, $wp_cli_root ) ) - $boot_fs_path = $wp_cli_root . '/' . $boot_fs_path; + $script_path = $GLOBALS['argv'][0]; $args = implode( ' ', array_map( 'escapeshellarg', $args ) ); $assoc_args = \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); - $full_command = "{$php_bin} {$boot_fs_path} {$command} {$args} {$assoc_args}"; + $full_command = "{$php_bin} {$script_path} {$command} {$args} {$assoc_args}"; return self::launch( $full_command, $exit_on_error ); - } + } + + private static function get_php_binary() { + if ( defined( 'PHP_BINARY' ) ) + return PHP_BINARY; + + if ( getenv( 'WP_CLI_PHP_USED' ) ) + return getenv( 'WP_CLI_PHP_USED' ); + + if ( getenv( 'WP_CLI_PHP' ) ) + return getenv( 'WP_CLI_PHP' ); + + return 'php'; + } static function get_config( $key = null ) { if ( null === $key ) { diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 1597d97262..4775d88849 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -91,7 +91,7 @@ public function structure( $args, $assoc_args ) { $new_assoc_args = array(); if ( isset( $assoc_args['hard'] ) ) $new_assoc_args['hard'] = true; - \WP_CLI::launch_wpcli( 'rewrite flush', array(), $new_assoc_args ); + \WP_CLI::launch_self( 'rewrite flush', array(), $new_assoc_args ); WP_CLI::success( "Rewrite structure set." ); } From ee6709fa9539f7c46078c752117d4390822e2ba6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 01:00:12 +0200 Subject: [PATCH 2561/4858] clean up rewrite.feature --- features/rewrite.feature | 42 +++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index 9ccb04f0c7..2d5ec586fa 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -1,37 +1,35 @@ Feature: Manage WordPress rewrites - Background: + Scenario: Change site permastructs Given a WP install - Scenario: Change site permastructs When I run `wp rewrite structure /blog/%year%/%monthnum%/%day%/%postname%/ --category-base=section --tag-base=topic` + And I run `wp option get permalink_structure` + Then STDOUT should contain: + """ + /blog/%year%/%monthnum%/%day%/%postname%/ + """ - When I run `wp option get permalink_structure` - Then STDOUT should contain: - """ - /blog/%year%/%monthnum%/%day%/%postname%/ - """ - - When I run `wp option get category_base` - Then STDOUT should contain: - """ - section - """ + When I run `wp option get category_base` + Then STDOUT should contain: + """ + section + """ - When I run `wp option get tag_base` - Then STDOUT should contain: - """ - topic - """ + When I run `wp option get tag_base` + Then STDOUT should contain: + """ + topic + """ - When I run `wp rewrite list --format=csv` - Then STDOUT should be CSV containing: + When I run `wp rewrite list --format=csv` + Then STDOUT should be CSV containing: | match | query | source | | blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(/[0-9]+)?/?$ | index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5] | post | | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | | section/(.+?)/?$ | index.php?category_name=$matches[1] | category | - When I run `wp rewrite list --match=/topic/apple/ --format=csv` - Then STDOUT should be CSV containing: + When I run `wp rewrite list --match=/topic/apple/ --format=csv` + Then STDOUT should be CSV containing: | match | query | source | | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | From 279cb5fc6b1072604f7cce317f017f32007c4e3f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 01:23:23 +0200 Subject: [PATCH 2562/4858] bump version to 0.13-RC --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index c73b198333..c6263f8b9a 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13-beta' ); +define( 'WP_CLI_VERSION', '0.13-RC' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 5bf2b02d59c58852ddff1f12e0d6981ada56b1e8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 29 Nov 2013 23:03:02 -0200 Subject: [PATCH 2563/4858] --post_content as a flag that reads from STDIN --- features/post.feature | 9 +++++++++ php/commands/post.php | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/features/post.feature b/features/post.feature index d4231c87c3..d7d9588dfa 100644 --- a/features/post.feature +++ b/features/post.feature @@ -119,3 +119,12 @@ Feature: Manage WordPress posts """ Sample Page """ + + Scenario: Generating posts + When I run `echo "Content generated by wp post generate" | wp post generate --count=1 --post_content` + And I run `wp post list --field=post_content` + Then STDOUT should contain: + """ + Content generated by wp post generate + """ + And STDERR should be empty \ No newline at end of file diff --git a/php/commands/post.php b/php/commands/post.php index 1f8f7100e3..8b772026e4 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -269,8 +269,8 @@ public function _list( $_, $assoc_args ) { * [--post_date=<yyyy-mm-dd>] * : The date of the generated posts. Default: current date * - * [--post_content=<content>] - * : The content of the generated posts. Default: empty + * [--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 @@ -278,6 +278,7 @@ public function _list( $_, $assoc_args ) { * ## 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; @@ -305,6 +306,10 @@ public function generate( $args, $assoc_args ) { $post_author = $post_author->ID; } + if ( isset( $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 ) ); From 3821c694ae5409a58c779e8806f60ca3a8da4662 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Fri, 29 Nov 2013 17:08:26 -0800 Subject: [PATCH 2564/4858] Allow wp-db-export to write to STDOUT if <file> is - --- php/commands/db.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 2068248fa1..c7ef38cb81 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -120,9 +120,11 @@ function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), array( - 'result-file' => $result_file - ) ); + $cmd_args = array(); + if ( '-' !== $result_file ) { + $cmd_args['result-file'] = $result_file; + } + self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), $cmd_args ); WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } From cdf1c9fef31f5b70d4494140fd8cc8e693bfe1a6 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Fri, 29 Nov 2013 17:37:02 -0800 Subject: [PATCH 2565/4858] Update wp-db-export phpdoc options --- php/commands/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index c7ef38cb81..328aff8695 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -11,7 +11,7 @@ * : Answer yes to the confirmation message. * * <file> - * : The name of the export file. If omitted, it will be '{dbname}.sql' + * : The name of the export file. If '-', then outputs to STDOUT. If omitted, it will be '{dbname}.sql'. * * <SQL> * : A SQL query. From b4381cdc0bf761542e1e63411d86a9c8ff1592dc Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Fri, 29 Nov 2013 18:20:17 -0800 Subject: [PATCH 2566/4858] Suppress success message when exporting to STDOUT --- php/commands/db.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 328aff8695..75eb6272d6 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -119,14 +119,17 @@ function query( $args ) { */ function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); + $stdout = ( '-' === $result_file ); $cmd_args = array(); - if ( '-' !== $result_file ) { + if ( ! $stdout ) { $cmd_args['result-file'] = $result_file; } self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), $cmd_args ); - WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); + if ( ! $stdout ) { + WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); + } } /** From afdd3d3fe0e1cc2e5b552cd23aab22a4c0a81216 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 13:35:34 +0200 Subject: [PATCH 2567/4858] update contributor list for 0.13 release --- .mailmap | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.mailmap b/.mailmap index 5b7349285c..eaec314b56 100644 --- a/.mailmap +++ b/.mailmap @@ -1,17 +1,21 @@ andreascreten <andreas@madewithlove.be> bendoh <ben@thinkoomph.com> +BoiteAWeb <juliobosk@gmail.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> conatus <alex@recordsonribs.com> +ctayloroomphinc <ctaylor@thinkoomph.com> cyberhobo <dylan.k.kuhn@gmail.com> dangardner <dan@web.nearest.to> danielbachhuber <d@danielbachhuber.com> danielbachhuber <danielbachhuber@gmail.com> +dd32 <contact-atlassian@dd32.id.au> drrobotnik <B@Brandons-Mac-Pro-4.local> dwightjack <marco.solazzi@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> eugeneware <eugene@noblesamurai.com> +francescolaffi <francesco.laffi@gmail.com> future500 <ramon@future500.nl> getsource <mike.schroder@dreamhost.com> glebis <glebis@gmail.com> @@ -23,7 +27,9 @@ jmslbam <jmslbam@gmail.com> johnbillion <johnbillion@gmail.com> johnpbloch <jbloch@John-Blochs-iMac.local> johnpbloch <johnpbloch@gmail.com> +jonathanbardo <jonathanbardo@users.noreply.github.com> joshbetz <j@joshbetz.com> +Kevinlearynet <info@kevinleary.net> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> @@ -39,6 +45,7 @@ mwilliamson <mike@zwobble.org> nacin <andrewnacin@gmail.com> navitronic <adrian@navitronic.co.uk> nb <nb@nikolay.bg> +nickdaugherty <ndaugherty987@gmail.com> nikolay <nikolay@users.noreply.github.com> nikolay <nikolaynkolev@gmail.com> nullvariable <nullvariable@gmail.com> @@ -47,9 +54,12 @@ oknoway <nate@oknoway.com> om4james <james@jamesc.id.au> om4james <james@om4.com.au> Rarst <contact@rarst.net> +rodrigoprimo <rodrigo@hacklab.com.br> roelven <roel@soundcloud.com> +ryanduff <ryan@fusionized.com> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> +simonwheatley <simonw@codeforthepeople.com> soulou <leo@soulou.fr> spuriousdata <spuriousdata@gmail.com> stianlik <stianlik@gmail.com> @@ -57,6 +67,7 @@ svaj <chris@chrisbot.(none)> taupecat <tracy@taupecat.com> tddewey <td@tddewey.com> thisislawatts <luke@thisis.la> +tiagohillebrandt <tiagohillebrandt@ubuntu.com> tlovett1 <admin@taylorlovett.com> tollmanz <zack@zackdev.com> toszcze <toszcze@gmail.com> From 931b353757a21e614d2f5f46d8aaad27f895b485 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 14:38:28 +0200 Subject: [PATCH 2568/4858] change default global config path to ~/.wp-cli/config.yml context: #897 --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 65c376a436..06734b7e20 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -46,7 +46,7 @@ private static function get_global_config_path() { } if ( !$config_path ) { - $config_path = getenv( 'HOME' ) . '/.config/wp-cli.yml'; + $config_path = getenv( 'HOME' ) . '/.wp-cli/config.yml'; } if ( !is_readable( $config_path ) ) From a7eaaecc62b8f5004cdf3b32273ed04884cbca2a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 Nov 2013 15:14:44 +0200 Subject: [PATCH 2569/4858] bump version to 0.13.0 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index c6263f8b9a..a98a85d707 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13-RC' ); +define( 'WP_CLI_VERSION', '0.13.0' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From c68837da8102e3acc82fb371d070bb1f5e200f23 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Sat, 30 Nov 2013 15:05:16 -0800 Subject: [PATCH 2570/4858] Make db-import accept - for STDIN Note there seems to be no difference with db-query for this. --- php/commands/db.php | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 75eb6272d6..6661d5107d 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -11,7 +11,7 @@ * : Answer yes to the confirmation message. * * <file> - * : The name of the export file. If '-', then outputs to STDOUT. If omitted, it will be '{dbname}.sql'. + * : The name of the SQL file for import/export. If '-', then inputs from STDIN and outputs to STDOUT. If omitted, it will be '{dbname}.sql'. * * <SQL> * : A SQL query. @@ -133,21 +133,30 @@ function export( $args, $assoc_args ) { } /** - * Import database from a file. + * Import database from a file or from STDIN. * * @synopsis [<file>] */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); - if ( !file_exists( $result_file ) ) { - WP_CLI::error( sprintf( 'Import file missing: %s', $result_file ) ); - } - $descriptors = array( - array( 'file', $result_file, 'r' ), - STDOUT, - STDERR, - ); + if ( '-' === $result_file ) { + $descriptors = array( + STDIN, + STDOUT, + STDERR, + ); + } else { + if ( ! file_exists( $result_file ) ) { + WP_CLI::error( sprintf( 'Import file missing: %s', $result_file ) ); + } + + $descriptors = array( + array( 'file', $result_file, 'r' ), + STDOUT, + STDERR, + ); + } self::run( 'mysql --no-defaults', array( 'database' => DB_NAME From 5a94a1a6ad6226309f80a5f95d4b5ed86661fb2a Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 1 Dec 2013 01:55:35 +0100 Subject: [PATCH 2571/4858] Use new PHPUnit url to curl from --- utils/dev-build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/dev-build b/utils/dev-build index d4f3f09e4f..0637d27b94 100755 --- a/utils/dev-build +++ b/utils/dev-build @@ -12,7 +12,7 @@ echo "Installing dependencies using Composer..." php composer.phar install echo "Downloading PHPUnit..." -curl -sS http://pear.phpunit.de/get/phpunit.phar > phpunit.phar +curl -sS https://phar.phpunit.de/phpunit.phar > phpunit.phar echo "Downloading Behat..." curl -sS http://behat.org/downloads/behat.phar > behat.phar From 100ab6a08cf3759ebdb70f9183b696dafbd291fc Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Sun, 1 Dec 2013 22:48:31 +0100 Subject: [PATCH 2572/4858] Simplify STDERR text check --- features/flags.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/flags.feature b/features/flags.feature index 9d1dcc93ee..9c3d4be449 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -40,7 +40,7 @@ Feature: Global flags """ And STDERR should contain: """ - PHP Notice: Use of undefined constant CONST_WITHOUT_QUOTES + Use of undefined constant CONST_WITHOUT_QUOTES """ Scenario: Setting the WP user From d73beb86854715283f85a1103e627796266a85e2 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Sun, 1 Dec 2013 22:53:12 -0200 Subject: [PATCH 2573/4858] stop wp-cli execution when there is an unknown parameter --- features/validation.feature | 8 ++++++++ php/WP_CLI/Dispatcher/Subcommand.php | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/features/validation.feature b/features/validation.feature index 803d758af5..8910f37817 100644 --- a/features/validation.feature +++ b/features/validation.feature @@ -23,3 +23,11 @@ Feature: Argument validation """ Parameter errors: """ + + When I try `wp core config invalid --invalid --other-invalid` + Then the return code should be 1 + And STDERR should contain: + """ + unknown --unknown parameter + unknown --other-unknown parameter + """ \ No newline at end of file diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 8f112c86b6..0e4685ae41 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -179,6 +179,10 @@ private function validate_args( $args, $assoc_args, $extra_args ) { array_merge( \WP_CLI::get_config(), $extra_args, $assoc_args ) ); + foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { + $errors['fatal'][] = "unknown --$key parameter"; + } + if ( !empty( $errors['fatal'] ) ) { $out = 'Parameter errors:'; foreach ( $errors['fatal'] as $error ) { @@ -190,10 +194,6 @@ private function validate_args( $args, $assoc_args, $extra_args ) { array_map( '\\WP_CLI::warning', $errors['warning'] ); - foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { - \WP_CLI::warning( "unknown --$key parameter" ); - } - return $to_unset; } From e38cc235684d43bee3bf77f7af093fe60ab12d56 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 3 Dec 2013 09:48:27 -0200 Subject: [PATCH 2574/4858] fix test --- features/validation.feature | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/features/validation.feature b/features/validation.feature index 8910f37817..ad1f89fefa 100644 --- a/features/validation.feature +++ b/features/validation.feature @@ -28,6 +28,9 @@ Feature: Argument validation Then the return code should be 1 And STDERR should contain: """ - unknown --unknown parameter - unknown --other-unknown parameter - """ \ No newline at end of file + unknown --invalid parameter + """ + And STDERR should contain: + """ + unknown --other-invalid parameter + """ From e10ec5fc7f16d82d4c6148f2949ff1ceeab2b807 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Dec 2013 01:02:46 +0200 Subject: [PATCH 2575/4858] bump version to 0.14.0-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index a98a85d707..a592703db6 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13.0' ); +define( 'WP_CLI_VERSION', '0.14.0-alpha' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 1f1fb69d42edbc73e40851eb568dd72514363328 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Dec 2013 01:43:05 +0200 Subject: [PATCH 2576/4858] db: move parameter descriptions to subcommands --- php/commands/db.php | 48 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 6661d5107d..d0bb9cc4ca 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -4,22 +4,6 @@ /** * Perform basic database operations. - * - * ## OPTIONS - * - * --yes - * : Answer yes to the confirmation message. - * - * <file> - * : The name of the SQL file for import/export. If '-', then inputs from STDIN and outputs to STDOUT. If omitted, it will be '{dbname}.sql'. - * - * <SQL> - * : A SQL query. - * - * ## EXAMPLES - * - * # execute a query stored in a file - * wp db query < debug.sql */ class DB_Command extends WP_CLI_Command { @@ -35,7 +19,10 @@ function create( $_, $assoc_args ) { /** * Delete the database. * - * @synopsis [--yes] + * ## OPTIONS + * + * [--yes] + * : Answer yes to the confirmation message. */ function drop( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); @@ -48,7 +35,10 @@ function drop( $_, $assoc_args ) { /** * Remove all tables from the database. * - * @synopsis [--yes] + * ## OPTIONS + * + * [--yes] + * : Answer yes to the confirmation message. */ function reset( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); @@ -95,7 +85,15 @@ function cli() { /** * Execute a query against the database. * - * @synopsis [<sql>] + * ## OPTIONS + * + * [<sql>] + * : A SQL query. If not passed, will try to read from STDIN. + * + * ## EXAMPLES + * + * # execute a query stored in a file + * wp db query < debug.sql */ function query( $args ) { $assoc_args = array( @@ -111,11 +109,14 @@ function query( $args ) { } /** - * Exports the database using mysqldump. + * Exports the database to a file or to STDOUT. * - * @alias dump + * ## OPTIONS * - * @synopsis [<file>] + * [<file>] + * : The name of the SQL file to export. If '-', then outputs to STDOUT. If omitted, it will be '{dbname}.sql'. + * + * @alias dump */ function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); @@ -135,7 +136,8 @@ function export( $args, $assoc_args ) { /** * Import database from a file or from STDIN. * - * @synopsis [<file>] + * [<file>] + * : The name of the SQL file to export. If '-', then reads from STDIN. If omitted, it will look for '{dbname}.sql'. */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); From 335707f3898c23e58fb217cfaebef8177cfafd81 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 4 Dec 2013 01:46:32 +0200 Subject: [PATCH 2577/4858] I hear copy-pasta is not very nutritious. --- php/commands/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index d0bb9cc4ca..83c60d9ae3 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -137,7 +137,7 @@ function export( $args, $assoc_args ) { * Import database from a file or from STDIN. * * [<file>] - * : The name of the SQL file to export. If '-', then reads from STDIN. If omitted, it will look for '{dbname}.sql'. + * : The name of the SQL file to import. If '-', then reads from STDIN. If omitted, it will look for '{dbname}.sql'. */ function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); From 183595b6f0c9dde97c80310945725a469555c067 Mon Sep 17 00:00:00 2001 From: Justin de Vesine <justin@crowdfavorite.com> Date: Wed, 20 Nov 2013 14:21:59 -0700 Subject: [PATCH 2578/4858] Look for WP installation in simple subdir configs Teach WP-CLI about simple subdirectory installations of WP. If the current directory contains `index.php` and index.php contains a simple require of wp-blog-header.php (as the default index.php and simple modifications of it for WP-in-a-subdirectory both do), look for the WordPress installation based on that information. --- php/WP_CLI/Runner.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 06734b7e20..e4e7910ad2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -81,6 +81,22 @@ private static function set_wp_root( $config ) { $path = $config['path']; else $path .= '/' . $config['path']; + } else { + if ( file_exists( './index.php' ) ) { + $index_code = explode( "\n", file_get_contents( './index.php' ) ); + + foreach ( $index_code as $line ) { + if ( preg_match( '/^\s*require.+([\'"])(.*wp-blog-header\.php)\1/', $line, $matches ) ) { + $new_path = dirname( $matches[2] ); + if ( Utils\is_path_absolute( $new_path ) ) { + $path = $new_path; + } else { + $path .= '/' . $new_path; + } + break; + } + } + } } define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); From b95100eb611fcf51810696f6f6f80068d9f32e30 Mon Sep 17 00:00:00 2001 From: Justin de Vesine <justin@crowdfavorite.com> Date: Wed, 20 Nov 2013 14:38:23 -0700 Subject: [PATCH 2579/4858] Functional test for autodetection of subdir install --- features/config.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/features/config.feature b/features/config.feature index 12267e573d..57f9e69f52 100644 --- a/features/config.feature +++ b/features/config.feature @@ -54,6 +54,19 @@ Feature: Have a config file When I run `wp core is-installed` from 'core/wp-content' Then STDOUT should be empty + Scenario: WP in a subdirectory (autodetected) + Given a WP install in 'core' + And a index.php file: + """ + require('./core/wp-blog-header.php'); + """ + + When I run `wp core is-installed` + Then STDOUT should be empty + + When I run `wp core is-installed` + Then STDOUT should be empty + Scenario: Nested installs Given a WP install And a WP install in 'subsite' From 8c82f96d7579471a7494564998abeeb4271cbfd0 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 12 Dec 2013 12:56:25 -0200 Subject: [PATCH 2580/4858] fix undefined variable --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index d90bc93d6d..c72ddd84cb 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -115,7 +115,7 @@ public function update( $args, $assoc_args ) { public function edit( $args, $_ ) { $post = $this->fetcher->get_check( $args[0] ); - $r = $this->_edit( $post->post_content, "WP-CLI post $post_id" ); + $r = $this->_edit( $post->post_content, "WP-CLI post {$post->ID}" ); if ( $r === false ) \WP_CLI::warning( 'No change made to post content.', 'Aborted' ); From 0feb609e039eb8bd6f3f51385c61f8fb450490dd Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 12 Dec 2013 19:13:49 -0200 Subject: [PATCH 2581/4858] stop wp-cli execution when there are too many positional arguments --- features/validation.feature | 16 ++++++++++++++-- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/features/validation.feature b/features/validation.feature index ad1f89fefa..9f30a30f79 100644 --- a/features/validation.feature +++ b/features/validation.feature @@ -17,14 +17,18 @@ Feature: Argument validation Given an empty directory And WP files - When I try `wp core config invalid` + When I try `wp core config` Then the return code should be 1 And STDERR should contain: """ Parameter errors: """ + And STDERR should contain: + """ + missing --dbname parameter + """ - When I try `wp core config invalid --invalid --other-invalid` + When I try `wp core config --invalid --other-invalid` Then the return code should be 1 And STDERR should contain: """ @@ -34,3 +38,11 @@ Feature: Argument validation """ unknown --other-invalid parameter """ + + When I try `wp core version invalid` + Then the return code should be 1 + And STDERR should contain: + """ + Error: Too many positional arguments: invalid + """ + And STDOUT should be empty \ No newline at end of file diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 0e4685ae41..89402b7b25 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -171,7 +171,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $unknown_positionals = $validator->unknown_positionals( $args ); if ( !empty( $unknown_positionals ) ) { - \WP_CLI::warning( 'Too many positional arguments: ' . + \WP_CLI::error( 'Too many positional arguments: ' . implode( ' ', $unknown_positionals ) ); } From 396c53abadba60a2e4d5860b47575ec62d49ae26 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 12 Dec 2013 19:52:21 -0200 Subject: [PATCH 2582/4858] add url subcommand to post, comment and site commands --- features/comment.feature | 6 ++++++ features/post.feature | 6 ++++++ features/site.feature | 20 +++++++++++++++++- php/WP_CLI/CommandWithDBObject.php | 5 +++++ php/WP_CLI/Fetchers/Site.php | 33 ++++++++++++++++++++++++++++++ php/commands/comment.php | 16 +++++++++++++++ php/commands/post.php | 16 +++++++++++++++ php/commands/site.php | 33 +++++++++++++++--------------- 8 files changed, 117 insertions(+), 18 deletions(-) create mode 100644 php/WP_CLI/Fetchers/Site.php diff --git a/features/comment.feature b/features/comment.feature index 96b21e701b..90f878383f 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -45,3 +45,9 @@ Feature: Manage WordPress comments """ 1 """ + + When I run `wp comment url 1` + Then STDOUT should be: + """ + http://example.com/?p=1#comment-1 + """ \ No newline at end of file diff --git a/features/post.feature b/features/post.feature index d7d9588dfa..a4154e23bb 100644 --- a/features/post.feature +++ b/features/post.feature @@ -92,6 +92,12 @@ Feature: Manage WordPress posts """ This is some bunkum. """ + + When I run `wp post url {POST_ID}` + Then STDOUT should be: + """ + http://example.com/?p=3 + """ Scenario: Creating/listing posts diff --git a/features/site.feature b/features/site.feature index bfbd49218d..d40d99eb37 100644 --- a/features/site.feature +++ b/features/site.feature @@ -1,5 +1,14 @@ Feature: Manage sites in a multisite installation + Scenario: Create a site + Given a WP multisite install + + When I try `wp site create --slug=first --network_id=1000` + Then STDERR should contain: + """ + Network with id 1000 does not exist. + """ + Scenario: Delete a site by id Given a WP multisite install @@ -38,7 +47,7 @@ Feature: Manage sites in a multisite installation When I try the previous command again Then the return code should be 1 - Scenario: Empty a site + Scenario: Empty a site Given a WP install When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` @@ -55,3 +64,12 @@ Feature: Manage sites in a multisite installation When I run `wp term list post_tag --format=ids` Then STDOUT should be empty + + Scenario: Get site info + Given a WP multisite install + + When I run `wp site url 1` + Then STDOUT should be: + """ + http://example.com + """ \ No newline at end of file diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 7ea97c7007..390d95811a 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -82,5 +82,10 @@ protected function success_or_failure( $r ) { protected function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); } + + protected function _url( $args, $callback ) { + $object = $this->fetcher->get_check( $args[0] ); + \WP_CLI::print_value( $callback( $object->{$this->obj_id_key} ) ); + } } diff --git a/php/WP_CLI/Fetchers/Site.php b/php/WP_CLI/Fetchers/Site.php new file mode 100644 index 0000000000..d35eaa797d --- /dev/null +++ b/php/WP_CLI/Fetchers/Site.php @@ -0,0 +1,33 @@ +<?php + +namespace WP_CLI\Fetchers; + +class Site extends Base { + + protected $msg = "Could not find the site with ID %d."; + + public function get( $site_id ) { + return $this->_get_site( $site_id ); + } + + /** + * Get site (network) data for a given id. + * + * @param int $site_id + * @return bool|array False if no network found with given id, array otherwise + */ + private function _get_site( $site_id ) { + global $wpdb; + + // Load site data + $sites = $wpdb->get_results( $wpdb->prepare( + "SELECT * FROM $wpdb->site WHERE id = %d", $site_id ) ); + + if ( !empty( $sites ) ) { + // Only care about domain and path which are set here + return $sites[0]; + } + + return false; + } +} \ No newline at end of file diff --git a/php/commands/comment.php b/php/commands/comment.php index 6a45b839c8..5fbe0e4a9a 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -369,6 +369,22 @@ public function exists( $args ) { WP_CLI::success( "Comment with ID $args[0] exists." ); } } + + /** + * Get comment url + * + * ## OPTIONS + * + * <id> + * : The ID of the comment to get the URL. + * + * ## EXAMPLES + * + * wp comment url 123 + */ + public function url( $args ) { + parent::_url( $args, 'get_comment_link' ); + } } WP_CLI::add_command( 'comment', 'Comment_Command' ); diff --git a/php/commands/post.php b/php/commands/post.php index d90bc93d6d..57624f19c4 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -355,6 +355,22 @@ public function generate( $args, $assoc_args ) { // @codingStandardsIgnoreEnd } + /** + * Get post url + * + * ## OPTIONS + * + * <id> + * : The ID of the post to get the URL. + * + * ## EXAMPLES + * + * wp post url 123 + */ + public function url( $args ) { + parent::_url( $args, 'get_permalink' ); + } + private function maybe_make_child() { // 50% chance of making child post return ( mt_rand(1, 2) == 1 ); diff --git a/php/commands/site.php b/php/commands/site.php index 111a91515a..48f40b3798 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -9,6 +9,10 @@ class Site_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'site'; + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\Site; + } + /** * Delete comments. */ @@ -217,7 +221,7 @@ public function create( $_, $assoc_args ) { // Site if ( !empty( $assoc_args['network_id'] ) ) { - $site = $this->_get_site( $assoc_args['network_id'] ); + $site = $this->fetcher->get( $assoc_args['network_id'] ); if ( $site === false ) { WP_CLI::error( sprintf( 'Network with id %d does not exist.', $assoc_args['network_id'] ) ); } @@ -364,24 +368,19 @@ function _list( $_, $assoc_args ) { } /** - * Get site (network) data for a given id. + * Get site url + * + * ## OPTIONS + * + * <id> + * : The ID of the site to get the URL. + * + * ## EXAMPLES * - * @param int $site_id - * @return bool|array False if no network found with given id, array otherwise + * wp site url 123 */ - private function _get_site( $site_id ) { - global $wpdb; - - // Load site data - $sites = $wpdb->get_results( $wpdb->prepare( - "SELECT * FROM $wpdb->site WHERE id = %d", $site_id ) ); - - if ( !empty( $sites ) ) { - // Only care about domain and path which are set here - return $sites[0]; - } - - return false; + public function url( $args ) { + parent::_url( $args, 'get_site_url' ); } } From 0668464556cdd6616d69d691c2b3bd3fab6d5846 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 12 Dec 2013 20:54:42 -0200 Subject: [PATCH 2583/4858] add new line at the end of file --- features/validation.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/validation.feature b/features/validation.feature index 9f30a30f79..a431787643 100644 --- a/features/validation.feature +++ b/features/validation.feature @@ -45,4 +45,4 @@ Feature: Argument validation """ Error: Too many positional arguments: invalid """ - And STDOUT should be empty \ No newline at end of file + And STDOUT should be empty From 9bd25a7a0a360d572039a7be092fb3852cc91731 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 13 Dec 2013 00:56:32 +0200 Subject: [PATCH 2584/4858] make 'wp import' accept multiple files also, remove unused support for different import formats --- php/commands/import.php | 97 +++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 61 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index 2a1b8e987f..d0963b50ab 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -7,8 +7,8 @@ class Import_Command extends WP_CLI_Command { * * ## OPTIONS * - * <file> - * : Path to a valid WXR file for importing. + * <file>... + * : Path to one or more valid WXR files for importing. * * --authors=<authors> * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. @@ -17,62 +17,46 @@ class Import_Command extends WP_CLI_Command { * : Skip importing specific data. Supported options are: 'attachment' and 'image_resize' (skip time-consuming thumbnail generation). */ public function __invoke( $args, $assoc_args ) { - list( $file ) = $args; - - if ( ! file_exists( $file ) ) - WP_CLI::error( "File to import doesn't exist." ); - $defaults = array( - 'type' => 'wxr', 'authors' => null, 'skip' => array(), ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); - $assoc_args['file'] = $file; - - if ( ! empty( $assoc_args['skip'] ) ) + if ( ! is_array( $assoc_args['skip'] ) ) { $assoc_args['skip'] = explode( ',', $assoc_args['skip'] ); + } - $importer = $this->is_importer_available( $assoc_args['type'] ); - if ( is_wp_error( $importer ) ) - WP_CLI::error( $importer->get_error_message() ); + $importer = $this->is_importer_available(); + if ( is_wp_error( $importer ) ) { + WP_CLI::error( $importer ); + } - $ret = $this->import( $assoc_args ); + $this->add_wxr_filters(); - if ( is_wp_error( $ret ) ) { - WP_CLI::error( $ret->get_error_message() ); - } else { - WP_CLI::line(); // WXR import ends with HTML, so make sure message is on next line - WP_CLI::success( "Import complete." ); - } - } + foreach ( $args as $file ) { + if ( ! is_readable( $file ) ) { + WP_CLI::warning( "Can't read $file file." ); + } - /** - * Import a file into WordPress. - */ - private function import( $args ) { + $ret = $this->import_wxr( $file, $assoc_args ); - switch( $args['type'] ) { - case 'wxr': - case 'wordpress': - $this->add_wxr_filters(); - $ret = $this->import_wxr( $args ); - break; - default: - $ret = new WP_Error( 'missing-import-type', "Import type doesn't exist." ); - break; + if ( is_wp_error( $ret ) ) { + WP_CLI::warning( $ret ); + } else { + WP_CLI::line(); // WXR import ends with HTML, so make sure message is on next line + WP_CLI::success( "Finished importing from $file file." ); + } } - return $ret; } /** * Import a WXR file */ - private function import_wxr( $args ) { + private function import_wxr( $file, $args ) { $wp_import = new WP_Import; - $import_data = $wp_import->parse( $args['file'] ); + $import_data = $wp_import->parse( $file ); if ( is_wp_error( $import_data ) ) return $import_data; @@ -125,11 +109,11 @@ private function import_wxr( $args ) { 'fetch_attachments' => $wp_import->fetch_attachments, ); - if( in_array( 'image_resize', $args['skip'] ) ) { + if ( in_array( 'image_resize', $args['skip'] ) ) { add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_set_image_sizes' ) ); } - $wp_import->import( $args['file'] ); + $wp_import->import( $file ); return true; } @@ -201,30 +185,21 @@ private function add_wxr_filters() { /** * Is the requested importer available? */ - private function is_importer_available( $importer ) { - + private function is_importer_available() { require_once ABSPATH . 'wp-admin/includes/plugin.php'; - switch ( $importer ) { - case 'wxr': - case 'wordpress': - if ( class_exists( 'WP_Import' ) ) { - $ret = true; - } else { - $plugins = get_plugins(); - $wordpress_importer = 'wordpress-importer/wordpress-importer.php'; - if ( array_key_exists( $wordpress_importer, $plugins ) ) - $error_msg = "WordPress Importer needs to be activated. Try 'wp plugin activate wordpress-importer'."; - else - $error_msg = "WordPress Importer needs to be installed. Try 'wp plugin install wordpress-importer --activate'."; - $ret = new WP_Error( 'importer-missing', $error_msg ); - } - break; - default: - $ret = new WP_Error( 'missing-import-type', "Import type doesn't exist." ); - break; + if ( class_exists( 'WP_Import' ) ) { + return true; } - return $ret; + + $plugins = get_plugins(); + $wordpress_importer = 'wordpress-importer/wordpress-importer.php'; + if ( array_key_exists( $wordpress_importer, $plugins ) ) + $error_msg = "WordPress Importer needs to be activated. Try 'wp plugin activate wordpress-importer'."; + else + $error_msg = "WordPress Importer needs to be installed. Try 'wp plugin install wordpress-importer --activate'."; + + return new WP_Error( 'importer-missing', $error_msg ); } /** From 5e60c38b07986455d41d7b5fc156575be3394fe7 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 12 Dec 2013 20:57:54 -0200 Subject: [PATCH 2585/4858] add new line to the end of files --- features/comment.feature | 2 +- features/site.feature | 2 +- php/WP_CLI/Fetchers/Site.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 90f878383f..00e197d450 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -50,4 +50,4 @@ Feature: Manage WordPress comments Then STDOUT should be: """ http://example.com/?p=1#comment-1 - """ \ No newline at end of file + """ diff --git a/features/site.feature b/features/site.feature index d40d99eb37..2c260f87e9 100644 --- a/features/site.feature +++ b/features/site.feature @@ -72,4 +72,4 @@ Feature: Manage sites in a multisite installation Then STDOUT should be: """ http://example.com - """ \ No newline at end of file + """ diff --git a/php/WP_CLI/Fetchers/Site.php b/php/WP_CLI/Fetchers/Site.php index d35eaa797d..abb9791cc4 100644 --- a/php/WP_CLI/Fetchers/Site.php +++ b/php/WP_CLI/Fetchers/Site.php @@ -30,4 +30,4 @@ private function _get_site( $site_id ) { return false; } -} \ No newline at end of file +} From 6195f60319634648b1c56620c6fe8080358956b9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 14 Dec 2013 02:44:55 +0200 Subject: [PATCH 2586/4858] run regex once, using the PCRE_MULTILINE modifier; see #878 --- php/WP_CLI/Runner.php | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e4e7910ad2..dd5e5953fc 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -81,20 +81,15 @@ private static function set_wp_root( $config ) { $path = $config['path']; else $path .= '/' . $config['path']; - } else { - if ( file_exists( './index.php' ) ) { - $index_code = explode( "\n", file_get_contents( './index.php' ) ); - - foreach ( $index_code as $line ) { - if ( preg_match( '/^\s*require.+([\'"])(.*wp-blog-header\.php)\1/', $line, $matches ) ) { - $new_path = dirname( $matches[2] ); - if ( Utils\is_path_absolute( $new_path ) ) { - $path = $new_path; - } else { - $path .= '/' . $new_path; - } - break; - } + } elseif ( file_exists( './index.php' ) ) { + $index_code = file_get_contents( './index.php' ); + + if ( preg_match( '/^\s*require.+([\'"])(.*wp-blog-header\.php)\1/m', $index_code, $matches ) ) { + $new_path = dirname( $matches[2] ); + if ( Utils\is_path_absolute( $new_path ) ) { + $path = $new_path; + } else { + $path .= '/' . $new_path; } } } From 6d0c75e93aa4df7b3c7ff111ab96a716b84ab25a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 14 Dec 2013 03:42:42 +0200 Subject: [PATCH 2587/4858] add oxymel to Phar file --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 2d789e617f..bda5002a32 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -38,6 +38,7 @@ function add_file( $phar, $path ) { ->in('./vendor/rmccue/requests') ->in('./vendor/composer') ->in('./vendor/symfony/finder') + ->in('./vendor/nb/oxymel') ->in('./vendor/rhumsaa/array_column') ->exclude('test') ->exclude('tests') From e5fa03a09ee00c6ab01fc700d7f4286a757262a1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 14 Dec 2013 04:07:43 +0200 Subject: [PATCH 2588/4858] add start log --- php/commands/import.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/import.php b/php/commands/import.php index d0963b50ab..451db0e6a6 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -34,6 +34,8 @@ public function __invoke( $args, $assoc_args ) { $this->add_wxr_filters(); + WP_CLI::log( 'Starting the import process...' ); + foreach ( $args as $file ) { if ( ! is_readable( $file ) ) { WP_CLI::warning( "Can't read $file file." ); From 50ec479bba0aed4fd2307d254f4041c1ba525574 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 16 Dec 2013 09:52:40 -0200 Subject: [PATCH 2589/4858] replace WP_CLI::print_value() with WP_CLI::line() --- php/WP_CLI/CommandWithDBObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 390d95811a..b0e52438a5 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -85,7 +85,7 @@ protected function get_formatter( &$assoc_args ) { protected function _url( $args, $callback ) { $object = $this->fetcher->get_check( $args[0] ); - \WP_CLI::print_value( $callback( $object->{$this->obj_id_key} ) ); + \WP_CLI::line( $callback( $object->{$this->obj_id_key} ) ); } } From 58ea052de3090dc5738ef933fde2120ac39fe64e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 17 Dec 2013 04:48:08 +0200 Subject: [PATCH 2590/4858] fix issues around plugin activation by setting $GLOBALS['pagenow'] to the expected value closes #917 --- php/WP_CLI/Runner.php | 4 ++++ php/wp-settings-cli.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index dd5e5953fc..3cd76b388f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -498,6 +498,10 @@ public function before_wp_load() { define( 'WP_LOAD_IMPORTERS', true ); define( 'WP_IMPORTING', true ); } + + if ( $this->cmd_starts_with( array( 'plugin' ) ) ) { + $GLOBALS['pagenow'] = 'plugins.php'; + } } private static function fake_current_site_blog( $url_parts ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index c944799317..d43118d8db 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -198,7 +198,7 @@ wp_ssl_constants( ); // Create common globals. -require( ABSPATH . WPINC . '/vars.php' ); +// require( ABSPATH . WPINC . '/vars.php' ); // Make taxonomies and posts available to plugins and themes. // @plugin authors: warning: these get registered again on the init hook. From 4a81e021e907a4c1fd6dc01ac59a5ee761dc509d Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 17 Dec 2013 10:59:14 -0200 Subject: [PATCH 2591/4858] Fix wrong example in 'wp comment list' documentation --- php/commands/comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 6a45b839c8..28652b8fa9 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -133,7 +133,7 @@ public function get( $args, $assoc_args ) { * * wp comment list --post_id=2 * - * wp comment list --number=20 --comment_approved=1 + * wp comment list --number=20 --status=approve * * @subcommand list */ From 6337d1f861a7c9368413aa06af6e71415b679a9b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 17 Dec 2013 11:20:52 -0200 Subject: [PATCH 2592/4858] make url subcommand accept multiple ids --- features/post.feature | 5 +++-- php/WP_CLI/CommandWithDBObject.php | 7 ++++--- php/commands/comment.php | 4 ++-- php/commands/post.php | 6 ++++-- php/commands/site.php | 4 ++-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/features/post.feature b/features/post.feature index a4154e23bb..df556cc7d0 100644 --- a/features/post.feature +++ b/features/post.feature @@ -92,10 +92,11 @@ Feature: Manage WordPress posts """ This is some bunkum. """ - - When I run `wp post url {POST_ID}` + + When I run `wp post url 1 {POST_ID}` Then STDOUT should be: """ + http://example.com/?p=1 http://example.com/?p=3 """ diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index b0e52438a5..de831bab64 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -84,8 +84,9 @@ protected function get_formatter( &$assoc_args ) { } protected function _url( $args, $callback ) { - $object = $this->fetcher->get_check( $args[0] ); - \WP_CLI::line( $callback( $object->{$this->obj_id_key} ) ); + foreach ( $args as $obj_id ) { + $object = $this->fetcher->get_check( $obj_id ); + \WP_CLI::line( $callback( $object->{$this->obj_id_key} ) ); + } } } - diff --git a/php/commands/comment.php b/php/commands/comment.php index 5fbe0e4a9a..b642170dde 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -375,8 +375,8 @@ public function exists( $args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to get the URL. + * <id>... + * : One or more IDs of comments to get the URL. * * ## EXAMPLES * diff --git a/php/commands/post.php b/php/commands/post.php index 57624f19c4..20c04f709f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -360,12 +360,14 @@ public function generate( $args, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the post to get the URL. + * <id>... + * : One or more IDs of posts get the URL. * * ## EXAMPLES * * wp post url 123 + * + * wp post url 123 324 */ public function url( $args ) { parent::_url( $args, 'get_permalink' ); diff --git a/php/commands/site.php b/php/commands/site.php index 48f40b3798..72f3ef3ea0 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -372,8 +372,8 @@ function _list( $_, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the site to get the URL. + * <id>... + * : One or more IDs of sites to get the URL. * * ## EXAMPLES * From 4863063f98e0c4c02a627d05d35498a62612e9dc Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 17 Dec 2013 17:47:50 -0200 Subject: [PATCH 2593/4858] make 'wp comment delete' accept multiple IDs --- features/comment.feature | 9 +++++++++ php/commands/comment.php | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 96b21e701b..162c40c985 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -28,6 +28,15 @@ Feature: Manage WordPress comments """ Success: Deleted comment {COMMENT_ID}. """ + + When I run `wp comment create --comment_post_ID=1` + And I run `wp comment create --comment_post_ID=1` + And I run `wp comment delete 3 4` + Then STDOUT should be: + """ + Success: Deleted comment 3. + Success: Deleted comment 4. + """ Scenario: Get details about an existing comment When I run `wp comment get 1` diff --git a/php/commands/comment.php b/php/commands/comment.php index 6a45b839c8..90df4bff02 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -158,8 +158,8 @@ public function _list( $_, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to delete. + * <id>... + * : One or more IDs of comments to delete. * * [--force] * : Skip the trash bin. @@ -167,6 +167,8 @@ public function _list( $_, $assoc_args ) { * ## EXAMPLES * * wp comment delete 1337 --force + * + * wp comment delete 1337 2341 --force */ public function delete( $args, $assoc_args ) { parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { From 621913fa254fcc335faa7c05f89ce6f3e7fda071 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 19 Dec 2013 10:02:46 -0200 Subject: [PATCH 2594/4858] Fix bug in wp site url --- features/site.feature | 11 ++++++++--- php/WP_CLI/Fetchers/Site.php | 12 ++++++------ php/commands/site.php | 38 ++++++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/features/site.feature b/features/site.feature index 2c260f87e9..da4c2cb10e 100644 --- a/features/site.feature +++ b/features/site.feature @@ -67,9 +67,14 @@ Feature: Manage sites in a multisite installation Scenario: Get site info Given a WP multisite install - - When I run `wp site url 1` + + When I run `wp site create --slug=first --porcelain` + Then STDOUT should be a number + And save STDOUT as {SITE_ID} + + When I run `wp site url {SITE_ID}` Then STDOUT should be: """ - http://example.com + http://example.com/first """ + diff --git a/php/WP_CLI/Fetchers/Site.php b/php/WP_CLI/Fetchers/Site.php index abb9791cc4..1eaca959ee 100644 --- a/php/WP_CLI/Fetchers/Site.php +++ b/php/WP_CLI/Fetchers/Site.php @@ -11,21 +11,21 @@ public function get( $site_id ) { } /** - * Get site (network) data for a given id. + * Get site (blog) data for a given id. * * @param int $site_id - * @return bool|array False if no network found with given id, array otherwise + * @return bool|array False if no site found with given id, array otherwise */ private function _get_site( $site_id ) { global $wpdb; // Load site data - $sites = $wpdb->get_results( $wpdb->prepare( - "SELECT * FROM $wpdb->site WHERE id = %d", $site_id ) ); + $site = $wpdb->get_row( $wpdb->prepare( + "SELECT * FROM $wpdb->blogs WHERE blog_id = %d", $site_id ) ); - if ( !empty( $sites ) ) { + if ( !empty( $site ) ) { // Only care about domain and path which are set here - return $sites[0]; + return $site; } return false; diff --git a/php/commands/site.php b/php/commands/site.php index 72f3ef3ea0..79eb8d924b 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -8,6 +8,7 @@ class Site_Command extends \WP_CLI\CommandWithDBObject { protected $obj_type = 'site'; + protected $obj_id_key = 'blog_id'; public function __construct() { $this->fetcher = new \WP_CLI\Fetchers\Site; @@ -219,15 +220,15 @@ public function create( $_, $assoc_args ) { $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; - // Site + // Network if ( !empty( $assoc_args['network_id'] ) ) { - $site = $this->fetcher->get( $assoc_args['network_id'] ); - if ( $site === false ) { + $network = $this->_get_network( $assoc_args['network_id'] ); + if ( $network === false ) { WP_CLI::error( sprintf( 'Network with id %d does not exist.', $assoc_args['network_id'] ) ); } } else { - $site = wpmu_current_site(); + $network = wpmu_current_site(); } $public = !isset( $assoc_args['private'] ); @@ -264,12 +265,12 @@ public function create( $_, $assoc_args ) { if ( is_subdomain_install() ) { $path = '/'; - $url = $newdomain = $base.'.'.preg_replace( '|^www\.|', '', $site->domain ); + $url = $newdomain = $base.'.'.preg_replace( '|^www\.|', '', $network->domain ); } else { - $newdomain = $site->domain; + $newdomain = $network->domain; $path = '/' . trim( $base, '/' ) . '/'; - $url = $site->domain . $path; + $url = $network->domain . $path; } $user_id = email_exists( $email ); @@ -285,7 +286,7 @@ public function create( $_, $assoc_args ) { } $wpdb->hide_errors(); - $id = wpmu_create_blog( $newdomain, $path, $title, $user_id, array( 'public' => $public ), $site->id ); + $id = wpmu_create_blog( $newdomain, $path, $title, $user_id, array( 'public' => $public ), $network->id ); $wpdb->show_errors(); if ( !is_wp_error( $id ) ) { if ( !is_super_admin( $user_id ) && !get_user_option( 'primary_blog', $user_id ) ) { @@ -306,6 +307,27 @@ public function create( $_, $assoc_args ) { WP_CLI::success( "Site $id created: $url" ); } + /** + * Get network data for a given id. + * + * @param int $network_id + * @return bool|array False if no network found with given id, array otherwise + */ + private function _get_network( $network_id ) { + global $wpdb; + + // Load network data + $networks = $wpdb->get_results( $wpdb->prepare( + "SELECT * FROM $wpdb->site WHERE id = %d", $network_id ) ); + + if ( !empty( $networks ) ) { + // Only care about domain and path which are set here + return $networks[0]; + } + + return false; + } + /** * List all sites in a multisite install. * From 8871c7dc7a12f6022a6a22767f99f00fa1cf7c4d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 19 Dec 2013 17:30:11 +0200 Subject: [PATCH 2595/4858] doc improvements for 'wp core config' --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index d4c4957c8a..9faf236b69 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -173,7 +173,7 @@ private static function get_initial_locale() { } /** - * Set up a wp-config.php file. + * Generate a wp-config.php file. * * ## OPTIONS * @@ -205,7 +205,7 @@ private static function get_initial_locale() { * : If set, the command reads additional PHP code from STDIN. * * [--skip-salts] - * : If set, keys and salts won't be generated, but, instead, should be passed via --extra-php. + * : If set, keys and salts won't be generated, but should instead be passed via `--extra-php`. * * ## EXAMPLES * From c6283fe371fe35e36a2803642c0fb317652c0b5c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 20 Dec 2013 02:33:47 +0200 Subject: [PATCH 2596/4858] core multisite-install: stop creating blogs.dir; it's deprecated see http://core.trac.wordpress.org/ticket/19235 closes #927 --- php/commands/core.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9faf236b69..d01e2067b1 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -519,8 +519,6 @@ private function _multisite_convert( $assoc_args ) { WP_CLI::log( 'Added multisite constants to wp-config.php.' ); } - wp_mkdir_p( WP_CONTENT_DIR . '/blogs.dir' ); - return true; } From 2e5a1b628d5c5e37694dab71ea1cb6290a6e9612 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 20 Dec 2013 08:38:48 -0200 Subject: [PATCH 2597/4858] exit with an error when 'wp site url' is called on a non-multisite install --- features/site.feature | 6 ++++++ php/commands/site.php | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/features/site.feature b/features/site.feature index da4c2cb10e..26f7678416 100644 --- a/features/site.feature +++ b/features/site.feature @@ -50,6 +50,12 @@ Feature: Manage sites in a multisite installation Scenario: Empty a site Given a WP install + When I try `wp site url 1` + Then STDERR should be: + """ + Error: This is not a multisite install. + """ + When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` Then STDOUT should not be empty diff --git a/php/commands/site.php b/php/commands/site.php index 79eb8d924b..14ef186482 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -402,6 +402,10 @@ function _list( $_, $assoc_args ) { * wp site url 123 */ public function url( $args ) { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + parent::_url( $args, 'get_site_url' ); } } From 80f264392bb223a9e24e6ea665ed84b563e07b0e Mon Sep 17 00:00:00 2001 From: Simon Wheatley <simonw@codeforthepeople.com> Date: Fri, 20 Dec 2013 10:53:49 +0000 Subject: [PATCH 2598/4858] Add better docs around authors mapping CSV. --- php/commands/import.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index 451db0e6a6..36d2c46cf8 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -11,7 +11,7 @@ class Import_Command extends WP_CLI_Command { * : Path to one or more valid WXR files for importing. * * --authors=<authors> - * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The last option will skip any author mapping. + * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The CSV requires two columns, and a header row like "old_user_login,new_user_login". The last option will skip any author mapping. * * [--skip=<data-type>] * : Skip importing specific data. Supported options are: 'attachment' and 'image_resize' (skip time-consuming thumbnail generation). From d775c111b30808179cbaf88a40e13788f7853824 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 21 Dec 2013 01:59:49 +0200 Subject: [PATCH 2599/4858] let the user know that --user_login= doesn't work see #926 --- php/commands/user.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 9e02172f8c..ddee96e2ac 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -240,13 +240,15 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user update 123 --user_login=mary --display_name=Mary - * - * wp user update mary --user_pass=marypass + * wp user update 123 --display_name=Mary --user_pass=marypass */ public function update( $args, $assoc_args ) { - $user_ids = array(); + if ( isset( $assoc_args['user_login'] ) ) { + WP_CLI::warning( "User logins can't be changed." ); + unset( $assoc_args['user_login'] ); + } + $user_ids = array(); foreach ( $this->fetcher->get_many( $args ) as $user ) { $user_ids[] = $user->ID; } From e062b9a070bc73f85b9df30c0cbb7f11de76545a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 23 Dec 2013 17:18:52 +0200 Subject: [PATCH 2600/4858] media regenerate: add seq example --- php/commands/media.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index eb5e4e938e..97393e41bf 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -20,9 +20,11 @@ class Media_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp media regenerate 123 1337 - * + * # re-generate all thumbnails, without confirmation * wp media regenerate --yes + * + * # re-generate all thumbnails that have IDs between 1000 and 2000 + * seq 1000 2000 | xargs wp media regenerate */ function regenerate( $args, $assoc_args = array() ) { global $wpdb; From e84a830a71433ff5a46723d648d6f844919d9189 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 23 Dec 2013 17:24:10 +0200 Subject: [PATCH 2601/4858] don't list all invalid attachment IDs it gets too long when using `seq` --- php/commands/media.php | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 97393e41bf..6faff8edf4 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -44,19 +44,15 @@ function regenerate( $args, $assoc_args = array() ) { $images = new WP_Query( $query_args ); - if ( $images->post_count == 0 ) { - //No images, so all keys in $args are not found within WP - WP_CLI::error( $this->_not_found_message( $args ) ); - } $count = $images->post_count; - WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); - - $not_found = array_diff( $args, $images->posts ); - if( !empty($not_found) ) { - WP_CLI::warning( $this->_not_found_message( $not_found ) ); + if ( !$count ) { + WP_CLI::log( 'No images found.' ); + return; } + WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); + foreach ( $images->posts as $id ) { $this->_process_regeneration( $id ); } @@ -244,17 +240,6 @@ private function remove_old_images( $att_id ) { unlink( $intermediate_path ); } } - - private function _not_found_message( $not_found_ids ){ - $count = count( $not_found_ids ); - - return vsprintf( 'Unable to find the %1$s (%2$s). Are you sure %3$s %4$s?', array( - ngettext('image', 'images', $count), - implode(", ", $not_found_ids), - ngettext('it', 'they', $count), - ngettext('exists', 'exist', $count), - ) ); - } } WP_CLI::add_command( 'media', 'Media_Command' ); From 5a7d75ead72ee06a93f04f2b4b52e18a6c09ee7f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 23 Dec 2013 17:52:12 +0200 Subject: [PATCH 2602/4858] make 'No images found' message a warning --- features/media.feature | 2 +- php/commands/media.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/features/media.feature b/features/media.feature index 81a1d5bf13..0dca83a0ca 100644 --- a/features/media.feature +++ b/features/media.feature @@ -7,7 +7,7 @@ Feature: Manage WordPress attachments When I try `wp media regenerate --yes` Then STDERR should contain: """ - Error: Unable to find the images + No images found. """ Scenario: Import image from remote URL diff --git a/php/commands/media.php b/php/commands/media.php index 6faff8edf4..5f57f5d9a2 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -47,11 +47,12 @@ function regenerate( $args, $assoc_args = array() ) { $count = $images->post_count; if ( !$count ) { - WP_CLI::log( 'No images found.' ); + WP_CLI::warning( 'No images found.' ); return; } - WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, ngettext('image', 'images', $count) ) ); + WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, + ngettext( 'image', 'images', $count ) ) ); foreach ( $images->posts as $id ) { $this->_process_regeneration( $id ); From 496d07b36223734f16121760eb22e0589e4a5351 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 25 Dec 2013 19:13:50 +0200 Subject: [PATCH 2603/4858] introduce is_windows() helper --- php/commands/help.php | 2 +- php/utils.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index d722a92050..46cf470b30 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -76,7 +76,7 @@ private static function indent( $whitespace, $text ) { } private static function pass_through_pager( $out ) { - if ( strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ) { + if ( Utils\is_windows() ) { // no paging for Windows cmd.exe; sorry echo $out; return 0; diff --git a/php/utils.php b/php/utils.php index 1972c25057..a281bd1677 100644 --- a/php/utils.php +++ b/php/utils.php @@ -375,3 +375,10 @@ function parse_url( $url ) { return $url_parts; } +/** + * Check if we're running in a Windows environment (cmd.exe). + */ +function is_windows() { + return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; +} + From e51666bf210ac5b7881161e7445aa16ea3dc0013 Mon Sep 17 00:00:00 2001 From: eliorivero <eliorivero@gmail.com> Date: Wed, 25 Dec 2013 17:32:27 -0300 Subject: [PATCH 2604/4858] Fix wp plugin delete on Windows --- php/commands/plugin.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index d0e802f593..6a66483f82 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -568,9 +568,16 @@ private function _delete( $plugin ) { if ( '.' == $plugin_dir ) $plugin_dir = $plugin->file; - $command = 'rm -rf ' . path_join( WP_PLUGIN_DIR, $plugin_dir ); + $path = path_join( WP_PLUGIN_DIR, $plugin_dir ); - return ! WP_CLI::launch( $command ); + if ( \WP_CLI\Utils\is_windows() ) { + $command = 'rd /s /q '; + $path = str_replace( "/", "\\", $path ); + } else { + $command = 'rm -rf '; + } + + return ! WP_CLI::launch( $command . $path ); } } From 87c4801895cd21d7b2a2c5f12ee7a2b5632ecebf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 26 Dec 2013 12:26:51 -0800 Subject: [PATCH 2605/4858] Perform `is_numeric()` checks before `is_email()`, as the former will be faster. --- php/WP_CLI/Fetchers/User.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Fetchers/User.php b/php/WP_CLI/Fetchers/User.php index 122dfd0fcc..65e2f9c0fb 100644 --- a/php/WP_CLI/Fetchers/User.php +++ b/php/WP_CLI/Fetchers/User.php @@ -8,10 +8,10 @@ class User extends Base { public function get( $id_email_or_login ) { - if ( is_email( $id_email_or_login ) ) - $user = get_user_by( 'email', $id_email_or_login ); - else if ( is_numeric( $id_email_or_login ) ) + if ( is_numeric( $id_email_or_login ) ) $user = get_user_by( 'id', $id_email_or_login ); + else if ( is_email( $id_email_or_login ) ) + $user = get_user_by( 'email', $id_email_or_login ); else $user = get_user_by( 'login', $id_email_or_login ); From e9a09d30938d1d87b8fcc21e82445588389ff02f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 26 Dec 2013 12:32:28 -0800 Subject: [PATCH 2606/4858] Support for using a user's email address in the `--user` flag. --- features/flags.feature | 6 ++++++ php/WP_CLI/Runner.php | 3 +++ 2 files changed, 9 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index 9d1dcc93ee..86baa34589 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -58,6 +58,12 @@ Feature: Global flags admin """ + When I run `wp --user=admin@example.com eval 'echo wp_get_current_user()->user_login;'` + Then STDOUT should be: + """ + admin + """ + When I try `wp --user=non-existing-user eval 'echo wp_get_current_user()->user_login;'` Then the return code should be 1 And STDERR should be: diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 65c376a436..7c9151b816 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -96,6 +96,9 @@ private static function set_user( $assoc_args ) { if ( is_numeric( $user ) ) { $user_id = (int) $user; + } else if ( is_email( $user ) ) { + $user_obj = get_user_by( 'email', $user ); + $user_id = ( $user_obj ) ? $user_obj->ID : 0; } else { $user_id = (int) username_exists( $user ); } From 37025efeab97e9529d66edfaedadca21d335f7c0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 26 Dec 2013 12:33:59 -0800 Subject: [PATCH 2607/4858] Apparently this helper function exists --- php/WP_CLI/Runner.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7c9151b816..3a00dd31f0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -97,8 +97,7 @@ private static function set_user( $assoc_args ) { if ( is_numeric( $user ) ) { $user_id = (int) $user; } else if ( is_email( $user ) ) { - $user_obj = get_user_by( 'email', $user ); - $user_id = ( $user_obj ) ? $user_obj->ID : 0; + $user_id = email_exists( $user ); } else { $user_id = (int) username_exists( $user ); } From 1b04e06fca552b7f400cec7a361da79f0805e2dc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 26 Dec 2013 12:45:58 -0800 Subject: [PATCH 2608/4858] Use the fetcher instead --- features/flags.feature | 2 +- php/WP_CLI/Runner.php | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 86baa34589..3bd8dfa690 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -68,7 +68,7 @@ Feature: Global flags Then the return code should be 1 And STDERR should be: """ - Error: Could not find user: non-existing-user + Error: Invalid user ID, email or login: 'non-existing-user' """ Scenario: Using a custom logger diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3a00dd31f0..312c3ac116 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -92,19 +92,10 @@ private static function set_user( $assoc_args ) { if ( !isset( $assoc_args['user'] ) ) return; - $user = $assoc_args['user']; + $fetcher = new \WP_CLI\Fetchers\User; + $user = $fetcher->get_check( $assoc_args['user'] ); + wp_set_current_user( $user->ID ); - if ( is_numeric( $user ) ) { - $user_id = (int) $user; - } else if ( is_email( $user ) ) { - $user_id = email_exists( $user ); - } else { - $user_id = (int) username_exists( $user ); - } - - if ( !$user_id || !wp_set_current_user( $user_id ) ) { - \WP_CLI::error( "Could not find user: $user" ); - } } private static function guess_url( $assoc_args ) { From e8704a743469ce2d88f648ef780167305d2da261 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 26 Dec 2013 22:54:48 +0200 Subject: [PATCH 2609/4858] fix default for WP_VERSION; see #679 --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 782dec87ec..1e39064a59 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -9,7 +9,7 @@ DB_NAME=$1 DB_USER=$2 DB_PASS=$3 DB_HOST=${4-localhost} -WP_VERSION=${5-master} +WP_VERSION=${5-latest} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=/tmp/wordpress/ From 264050706d1988875ab9abe867ca09845f935def Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Fri, 27 Dec 2013 12:33:25 -0500 Subject: [PATCH 2610/4858] Adding theme enable/disable commands for multisite installs. Closes #918. These commands allow the user to enable or disable themes for a site in a multisite network, or network enable/disable themes. --- php/commands/theme.php | 86 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 7975acb86c..40ef185525 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -129,6 +129,92 @@ public function activate( $args = array() ) { } } + /** + * Enable a theme. + * + * ## OPTIONS + * + * <theme> + * : The theme to enable. + * + * [--network] + * : If set, the theme is enabled for the entire network + * + * [--activate] + * : If set, the theme is activated for the current site. Note that + * the "network" flag has no influence on this. + * + * ## EXAMPLES + * + * wp theme enable twentythirteen + * + * wp theme enable twentythirteen --network + * + * wp theme enable twentythirteen --activate + */ + public function enable( $args, $assoc_args ) { + $theme = $this->fetcher->get_check( $args[0] ); + $name = $theme->get( 'Name' ); + + # If the --network flag is set, we'll be calling the (get|update)_site_option functions + $_site = ! empty( $assoc_args['network'] ) ? '_site' : ''; + + # Add the current theme to the allowed themes option or site option + $allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' ); + if ( empty( $allowed_themes ) ) + $allowed_themes = array(); + $allowed_themes[ $theme->get_template() ] = true; + call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes ); + + if ( ! empty( $assoc_args['network'] ) ) + WP_CLI::success( "Network enabled the '$name' theme." ); + else + WP_CLI::success( "Enabled the '$name' theme." ); + + # If the --activate flag is set, activate the theme for the current site + if ( ! empty( $assoc_args['activate'] ) ) { + $this->activate( $args ); + } + } + + /** + * Disable a theme. + * + * ## OPTIONS + * + * <theme> + * : The theme to disable. + * + * [--network] + * : If set, the theme is disabled on the network level. Note that + * individual sites may still have this theme enabled if it was + * enabled for them independently. + * + * ## EXAMPLES + * + * wp theme disable twentythirteen + * + * wp theme disable twentythirteen --network + */ + public function disable( $args, $assoc_args ) { + $theme = $this->fetcher->get_check( $args[0] ); + $name = $theme->get( 'Name' ); + + # If the --network flag is set, we'll be calling the (get|update)_site_option functions + $_site = ! empty( $assoc_args['network'] ) ? '_site' : ''; + + # Add the current theme to the allowed themes option or site option + $allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' ); + if ( ! empty( $allowed_themes[ $theme->get_template() ] ) ) + unset( $allowed_themes[ $theme->get_template() ] ); + call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes ); + + if ( ! empty( $assoc_args['network'] ) ) + WP_CLI::success( "Network disabled the '$name' theme." ); + else + WP_CLI::success( "Disabled the '$name' theme." ); + } + private function is_active_theme( $theme ) { return $theme->get_stylesheet_directory() == get_stylesheet_directory(); } From 89162a1c82c41ef65635f0ed13faee3c3276448a Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Fri, 27 Dec 2013 15:41:44 -0500 Subject: [PATCH 2611/4858] Ensuring that theme enable/disable commands are only ever run on multisite installs --- php/commands/theme.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 40ef185525..61c42f87b9 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -153,6 +153,10 @@ public function activate( $args = array() ) { * wp theme enable twentythirteen --activate */ public function enable( $args, $assoc_args ) { + if ( ! is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + $theme = $this->fetcher->get_check( $args[0] ); $name = $theme->get( 'Name' ); @@ -197,6 +201,10 @@ public function enable( $args, $assoc_args ) { * wp theme disable twentythirteen --network */ public function disable( $args, $assoc_args ) { + if ( ! is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + $theme = $this->fetcher->get_check( $args[0] ); $name = $theme->get( 'Name' ); From 5fac5102747ded46bbc93dc62f748178585078fb Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Fri, 27 Dec 2013 15:42:24 -0500 Subject: [PATCH 2612/4858] Adding feature tests for `theme enable` and `theme disable` --- features/theme.feature | 59 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index f14a82003d..24c4237dfe 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -1,9 +1,8 @@ Feature: Manage WordPress themes - Background: + Scenario: Installing and deleting theme Given a WP install - Scenario: Installing and deleting theme When I run `wp theme install p2` Then STDOUT should not be empty @@ -52,6 +51,8 @@ Feature: Manage WordPress themes Then STDOUT should not be empty Scenario: Install a theme, activate, then force install an older version of the theme + Given a WP install + When I run `wp theme install p2 --version=1.4.2` Then STDOUT should not be empty @@ -72,6 +73,8 @@ Feature: Manage WordPress themes | p2 | active | available | 1.4.1 | Scenario: Get the path of an installed theme + Given a WP install + When I run `wp theme install p2` Then STDOUT should not be empty @@ -80,3 +83,55 @@ Feature: Manage WordPress themes """ wp-content/themes/p2 """ + + Scenario: Enabling and disabling a theme + Given a WP multisite install + + When I run `wp theme install p2` + Then STDOUT should not be empty + + When I run `wp theme enable p2` + Then STDOUT should contain: + """ + Success: Enabled the 'P2' theme. + """ + + When I run `wp theme disable p2` + Then STDOUT should contain: + """ + Success: Disabled the 'P2' theme. + """ + + When I run `wp theme enable p2 --activate` + Then STDOUT should contain: + """ + Success: Enabled the 'P2' theme. + Success: Switched to 'P2' theme. + """ + + When I run `wp theme enable p2 --network` + Then STDOUT should contain: + """ + Success: Network enabled the 'P2' theme. + """ + + When I run `wp theme disable p2 --network` + Then STDOUT should contain: + """ + Success: Network disabled the 'P2' theme. + """ + + Scenario: Enabling and disabling a theme without multisite + Given a WP install + + When I try `wp theme enable p2` + Then STDERR should be: + """ + Error: This is not a multisite install. + """ + + When I try `wp theme disable p2` + Then STDERR should be: + """ + Error: This is not a multisite install. + """ From d6bfb7261953d4bcbcda5c10879eb22f9caa0f6e Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Sat, 28 Dec 2013 00:47:20 -0500 Subject: [PATCH 2613/4858] Testing that themes are actually being en/disabled --- features/theme.feature | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 24c4237dfe..98153957f7 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -90,18 +90,34 @@ Feature: Manage WordPress themes When I run `wp theme install p2` Then STDOUT should not be empty + When I try `wp option get allowedthemes` + Then the return code should be 1 + And STDERR should be empty + When I run `wp theme enable p2` Then STDOUT should contain: """ Success: Enabled the 'P2' theme. """ + When I run `wp option get allowedthemes` + Then STDOUT should contain: + """ + 'p2' => true + """ + When I run `wp theme disable p2` Then STDOUT should contain: """ Success: Disabled the 'P2' theme. """ + When I run `wp option get allowedthemes` + Then STDOUT should not contain: + """ + 'p2' => true + """ + When I run `wp theme enable p2 --activate` Then STDOUT should contain: """ @@ -109,18 +125,36 @@ Feature: Manage WordPress themes Success: Switched to 'P2' theme. """ + When I run `wp network-meta get 1 allowedthemes` + Then STDOUT should not contain: + """ + 'p2' => true + """ + When I run `wp theme enable p2 --network` Then STDOUT should contain: """ Success: Network enabled the 'P2' theme. """ + When I run `wp network-meta get 1 allowedthemes` + Then STDOUT should contain: + """ + 'p2' => true + """ + When I run `wp theme disable p2 --network` Then STDOUT should contain: """ Success: Network disabled the 'P2' theme. """ + When I run `wp network-meta get 1 allowedthemes` + Then STDOUT should not contain: + """ + 'p2' => true + """ + Scenario: Enabling and disabling a theme without multisite Given a WP install From 2054bf0e5b4606934a12205dd7ab8b7b3c1c76f1 Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Sat, 28 Dec 2013 01:28:54 -0500 Subject: [PATCH 2614/4858] Adding site and network enabled columns to wp theme list --- php/commands/theme.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 7975acb86c..2d4128014e 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -19,6 +19,10 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { ); function __construct() { + if ( is_multisite() ) { + $this->obj_fields[] = 'site_enabled'; + $this->obj_fields[] = 'network_enabled'; + } parent::__construct(); $this->fetcher = new \WP_CLI\Fetchers\Theme; @@ -193,6 +197,16 @@ protected function install_from_repo( $slug, $assoc_args ) { protected function get_item_list() { $items = array(); + if ( is_multisite() ) { + $site_enabled = get_option( 'allowedthemes' ); + if ( empty( $site_enabled ) ) + $site_enabled = array(); + + $network_enabled = get_site_option( 'allowedthemes' ); + if ( empty( $network_enabled ) ) + $network_enabled = array(); + } + foreach ( wp_get_themes() as $key => $theme ) { $file = $theme->get_stylesheet_directory(); $update_info = $this->get_update_info( $theme->get_stylesheet() ); @@ -206,6 +220,11 @@ protected function get_item_list() { 'version' => $theme->get('Version'), 'update_id' => $theme->get_stylesheet(), ); + + if ( is_multisite() ) { + $items[ $file ]['site_enabled'] = ! empty( $site_enabled[ $key ] ) ? 'enabled' : 'disabled'; + $items[ $file ]['network_enabled'] = ! empty( $network_enabled[ $key ] ) ? 'enabled' : 'disabled'; + } } return $items; From d801aca947726330c797f826e32b04c8cc9bdb6b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 28 Dec 2013 08:42:27 +0200 Subject: [PATCH 2615/4858] clarify description for theme 'enable' and 'disable' subcommands see #938 --- php/commands/theme.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 61c42f87b9..cac57cd447 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -130,7 +130,7 @@ public function activate( $args = array() ) { } /** - * Enable a theme. + * Enable a theme in a multisite install. * * ## OPTIONS * @@ -182,7 +182,7 @@ public function enable( $args, $assoc_args ) { } /** - * Disable a theme. + * Disable a theme in a multisite install. * * ## OPTIONS * From a7a72433e25ed3fa46569ab6fa2851443583b86a Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Sat, 28 Dec 2013 02:21:00 -0500 Subject: [PATCH 2616/4858] Merging the network and site enabled columns for `wp theme list` --- php/commands/theme.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 2d4128014e..9f1c6efeb6 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -20,8 +20,7 @@ class Theme_Command extends \WP_CLI\CommandWithUpgrade { function __construct() { if ( is_multisite() ) { - $this->obj_fields[] = 'site_enabled'; - $this->obj_fields[] = 'network_enabled'; + $this->obj_fields[] = 'enabled'; } parent::__construct(); @@ -222,8 +221,14 @@ protected function get_item_list() { ); if ( is_multisite() ) { - $items[ $file ]['site_enabled'] = ! empty( $site_enabled[ $key ] ) ? 'enabled' : 'disabled'; - $items[ $file ]['network_enabled'] = ! empty( $network_enabled[ $key ] ) ? 'enabled' : 'disabled'; + if ( ! empty( $site_enabled[ $key ] ) && ! empty( $network_enabled[ $key ] ) ) + $items[ $file ]['enabled'] = 'network,site'; + elseif ( ! empty( $network_enabled[ $key ] ) ) + $items[ $file ]['enabled'] = 'network'; + elseif ( ! empty( $site_enabled[ $key ] ) ) + $items[ $file ]['enabled'] = 'site'; + else + $items[ $file ]['enabled'] = 'no'; } } From 263390f25c3c0386c3371ec78e8cbf027bb6e2a8 Mon Sep 17 00:00:00 2001 From: Mike Burns <mgburns@bu.edu> Date: Fri, 3 Jan 2014 15:29:05 -0500 Subject: [PATCH 2617/4858] Store post ids during `wp post generate`. Fixes --max_depth which was broken in fe2be3169b. Closes #820. --- php/commands/post.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 3f9326837d..3d57cf2de2 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -316,6 +316,7 @@ public function generate( $args, $assoc_args ) { $notify = \WP_CLI\Utils\make_progress_bar( 'Generating posts', $count ); + $post_ids = array(); $current_depth = 1; $current_parent = 0; @@ -347,7 +348,7 @@ public function generate( $args, $assoc_args ) { 'post_content' => $post_content, ); - wp_insert_post( $args, true ); + $post_ids[$i] = wp_insert_post( $args, true ); $notify->tick(); } From 29454e3b568a1d9d21e0487ab88579fde94d3b36 Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Sat, 4 Jan 2014 00:57:36 -0800 Subject: [PATCH 2618/4858] Add a --recurse-objects flag Including --recurse-objects enables recursive find/replace into objects. This change also detects cycles in objects and arrays. If a cycle is detected, or the XDebug max nesting level is reached, the function stops recursing --- php/commands/search-replace.php | 62 ++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 24f3d0f23e..06fffd9d90 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -36,6 +36,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--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 @@ -48,6 +51,7 @@ public function __invoke( $args, $assoc_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'] ); @@ -73,7 +77,7 @@ public function __invoke( $args, $assoc_args ) { if ( in_array( $col, $skip_columns ) ) continue; - $count = self::handle_col( $col, $primary_key, $table, $old, $new, $dry_run ); + $count = self::handle_col( $col, $primary_key, $table, $old, $new, $dry_run, $recurse_objects ); $report[] = array( $table, $col, $count ); @@ -101,7 +105,7 @@ private static function get_table_list( $args, $network ) { return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } - private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run ) { + private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run, $recurse_objects ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite @@ -123,7 +127,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry if ( '' === $row->$col ) continue; - $value = self::recursive_unserialize_replace( $old, $new, $row->$col ); + $value = self::recursive_unserialize_replace( $old, $new, $row->$col, false, $recurse_objects ); if ( $dry_run ) { if ( $value != $row->$col ) @@ -146,28 +150,60 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry * * Initial code from https://github.com/interconnectit/Search-Replace-DB * - * @param string $from String we're looking to replace. - * @param string $to What we want it to be replaced with - * @param array $data Used to pass any subordinate arrays back to in. - * @param bool $serialised Does the array passed via $data need serialising. + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with + * @param array|string $data Used to pass any subordinate arrays back to in. + * @param bool $serialised Does the array passed via $data need serialising. + * @param bool $recurse_objects Should objects be recursively replaced. + * @param int $max_recursion How many levels to recurse into the data, if $recurse_objects is set to true. + * @param int $recursion_level Current recursion depth within the original data. + * @param array $visited_data Data that has been seen in previous recursion iterations. * - * @return array The original array with all elements replaced as needed. + * @return array The original array with all elements replaced as needed. */ - private static function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) { + private static function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { // some unseriliased data cannot be re-serialised eg. SimpleXMLElements try { + if ( $recurse_objects ) { + + // If no maximum recursion level is set, use the XDebug limit if it exists + if ( -1 == $max_recursion ) { + // Get the XDebug nesting level. Will be zero (no limit) if no value is set + $max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) ); + } + + // If we've reached the maximum recursion level, short circuit + if ( $max_recursion != 0 && $recursion_level >= $max_recursion ) { + WP_CLI::warning("Maximum recursion level of $max_recursion reached"); + return $data; + } + + if ( ( is_array( $data ) || is_object( $data ) ) ) { + // If we've seen this exact object or array before, short circuit + if ( in_array( $data, $visited_data, true ) ) { + return $data; // Avoid infinite loops when there's a cycle + } + // Add this data to the list of + $visited_data[] = $data; + } + } + if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { - $data = self::recursive_unserialize_replace( $from, $to, $unserialized, true ); + $data = self::recursive_unserialize_replace( $from, $to, $unserialized, true, $recurse_objects, $max_recursion, $recursion_level + 1 ); } elseif ( is_array( $data ) ) { - $_tmp = array(); foreach ( $data as $key => $value ) { - $_tmp[ $key ] = self::recursive_unserialize_replace( $from, $to, $value, false ); + $data[ $key ] = &self::recursive_unserialize_replace( $from, $to, $value, false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); + } + } + + elseif ( $recurse_objects && is_object( $data ) ) { + foreach ( $data as $key => $value ) { + $data->$key = self::recursive_unserialize_replace( $from, $to, $value, false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); } - $data = $_tmp; } else if ( is_string( $data ) ) { From b405e9d535de975fd61ec3c93203c9700791aab2 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Sat, 4 Jan 2014 23:59:18 +0000 Subject: [PATCH 2619/4858] Correct spelling of whether --- php/commands/transient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 0691b5f056..11fc6c09d9 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -62,7 +62,7 @@ public function delete( $args ) { } /** - * See wether the transients API is using an object cache or the options table. + * See whether the transients API is using an object cache or the options table. */ public function type() { global $_wp_using_ext_object_cache, $wpdb; From 33b3b00f3bafa7468923a972696d4833dcefdc36 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 18 Dec 2013 01:23:39 +0200 Subject: [PATCH 2620/4858] make `wp core is-installed` exit with 1 when run against a multisite install with no database --- features/core.feature | 3 +++ php/WP_CLI/Runner.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 59c78a4f52..5f41b24fcc 100644 --- a/features/core.feature +++ b/features/core.feature @@ -195,6 +195,9 @@ Feature: Manage WordPress installation Given a WP multisite install And I run `wp db reset --yes` + When I try `wp core is-installed` + Then the return code should be 1 + When I run `wp core multisite-install --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then STDOUT should not be empty diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b7d39592ee..9033d4c0c8 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -466,7 +466,7 @@ public function before_wp_load() { if ( count( $this->arguments ) >= 2 && $this->arguments[0] == 'core' && - in_array( $this->arguments[1], array( 'install', 'multisite-install' ) ) + in_array( $this->arguments[1], array( 'install', 'multisite-install', 'is-installed' ) ) ) { define( 'WP_INSTALLING', true ); From 6c02d63ad5b35eec3b4295647c4e65b570330b8d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 5 Jan 2014 08:19:32 +0200 Subject: [PATCH 2621/4858] fix `wp core is-installed` expectations for singlesite --- features/core.feature | 5 ----- php/WP_CLI/Runner.php | 6 +++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/features/core.feature b/features/core.feature index 5f41b24fcc..bf9fd8ddce 100644 --- a/features/core.feature +++ b/features/core.feature @@ -84,11 +84,6 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 - And STDERR should be: - """ - Error: The site you have requested is not installed. - Run `wp core install`. - """ When I try `wp core install` Then the return code should be 1 diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9033d4c0c8..15729dc0cb 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -463,10 +463,14 @@ public function before_wp_load() { exit; } + if ( $this->cmd_starts_with( array( 'core', 'is-installed' ) ) ) { + define( 'WP_INSTALLING', true ); + } + if ( count( $this->arguments ) >= 2 && $this->arguments[0] == 'core' && - in_array( $this->arguments[1], array( 'install', 'multisite-install', 'is-installed' ) ) + in_array( $this->arguments[1], array( 'install', 'multisite-install' ) ) ) { define( 'WP_INSTALLING', true ); From 6261a9a57d4f0b8106e1dd31518c5459059ec577 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 6 Jan 2014 12:46:35 +0200 Subject: [PATCH 2622/4858] site create: fix description for --title= parameter --- php/commands/site.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 14ef186482..cbd5ef2d27 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -191,7 +191,7 @@ function delete( $args, $assoc_args ) { * --slug=<slug> * : Path for the new site. Subdomain on subdomain installs, directory on subdirectory installs. * - * --title=<title> + * --title=<title> * : Title of the new site. Default: prettified slug. * * --email=<email> @@ -391,7 +391,7 @@ function _list( $_, $assoc_args ) { /** * Get site url - * + * * ## OPTIONS * * <id>... From 5286a18f5b5c62cb842d62d493c80f17fcf750a1 Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Wed, 8 Jan 2014 00:35:31 -0800 Subject: [PATCH 2623/4858] Update documentation header for recursive_unserialize_replace --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 06fffd9d90..b31904f581 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -146,7 +146,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry /** * Take a serialised array and unserialise it replacing elements as needed and * unserialising any subordinate arrays and performing the replace on those too. - * Ignores any serialized objects. + * Ignores any serialized objects unless $recurse_objects is set to true. * * Initial code from https://github.com/interconnectit/Search-Replace-DB * From e41f4fa8aca9a6abbfa900f1a71570ac07fd55fe Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Wed, 8 Jan 2014 02:16:18 -0800 Subject: [PATCH 2624/4858] Update array handling for safer recursive replacements --- php/commands/search-replace.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b31904f581..61615ef7c2 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -161,7 +161,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry * * @return array The original array with all elements replaced as needed. */ - private static function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { + private static function recursive_unserialize_replace( $from = '', $to = '', &$data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { // some unseriliased data cannot be re-serialised eg. SimpleXMLElements try { @@ -195,8 +195,9 @@ private static function recursive_unserialize_replace( $from = '', $to = '', $da } elseif ( is_array( $data ) ) { - foreach ( $data as $key => $value ) { - $data[ $key ] = &self::recursive_unserialize_replace( $from, $to, $value, false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); + $keys = array_keys( $data ); + foreach ( $keys as $key ) { + $data[ $key ]= self::recursive_unserialize_replace( $from, $to, $data[$key], false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); } } From 7833662ef34eaaf95dc91be9df50ee6c91f3ce91 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 05:32:51 +0200 Subject: [PATCH 2625/4858] remove duplicated check --- features/config.feature | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/config.feature b/features/config.feature index 57f9e69f52..8720f451a4 100644 --- a/features/config.feature +++ b/features/config.feature @@ -64,9 +64,6 @@ Feature: Have a config file When I run `wp core is-installed` Then STDOUT should be empty - When I run `wp core is-installed` - Then STDOUT should be empty - Scenario: Nested installs Given a WP install And a WP install in 'subsite' From 1d7af0dc18bbf9de097b86193e17ed39140d9c9a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 05:50:16 +0200 Subject: [PATCH 2626/4858] Don't look for WP files upward when running `wp core download`. If you run `wp core download` in an empty directory, getting an "Error: WordPress files seem to already be present here." message is quite confusing. see #955 --- features/core.feature | 6 +++++- php/WP_CLI/Runner.php | 11 +++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index bf9fd8ddce..30fea76ed6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -8,9 +8,13 @@ Feature: Manage WordPress installation Then the return code should be 1 And STDERR should not be empty - When I run `wp core download --quiet` + When I run `wp core download` Then the wp-settings.php file should exist + When I run `mkdir inner` + And I run `cd inner && wp core download` + Then the inner/wp-settings.php file should exist + @download Scenario: Localized install Given an empty directory diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 15729dc0cb..57f000a250 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -394,10 +394,6 @@ private function init_config() { } list( $this->config, $this->extra_config ) = $configurator->to_array(); - - if ( !isset( $this->config['path'] ) ) { - $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); - } } public function before_wp_load() { @@ -430,6 +426,13 @@ public function before_wp_load() { } // Handle --path parameter + if ( !isset( $this->config['path'] ) ) { + if ( $this->cmd_starts_with( array( 'core', 'download' ) ) ) { + $this->config['path'] = getcwd(); + } else { + $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); + } + } self::set_wp_root( $this->config ); // First try at showing man page From aa7df69a971bf748fee167ba993ff1109bc07809 Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Fri, 10 Jan 2014 23:01:50 -0800 Subject: [PATCH 2627/4858] Move recursive search-replace function to Utils and add unit tests --- php/commands/search-replace.php | 80 +-------------------------------- php/utils.php | 78 ++++++++++++++++++++++++++++++++ tests/test-search-replace.php | 71 +++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 79 deletions(-) create mode 100644 tests/test-search-replace.php diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 61615ef7c2..b8d219d34c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -127,7 +127,7 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry if ( '' === $row->$col ) continue; - $value = self::recursive_unserialize_replace( $old, $new, $row->$col, false, $recurse_objects ); + $value = WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col, false, $recurse_objects ); if ( $dry_run ) { if ( $value != $row->$col ) @@ -143,84 +143,6 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry return $count; } - /** - * Take a serialised array and unserialise it replacing elements as needed and - * unserialising any subordinate arrays and performing the replace on those too. - * Ignores any serialized objects unless $recurse_objects is set to true. - * - * Initial code from https://github.com/interconnectit/Search-Replace-DB - * - * @param string $from String we're looking to replace. - * @param string $to What we want it to be replaced with - * @param array|string $data Used to pass any subordinate arrays back to in. - * @param bool $serialised Does the array passed via $data need serialising. - * @param bool $recurse_objects Should objects be recursively replaced. - * @param int $max_recursion How many levels to recurse into the data, if $recurse_objects is set to true. - * @param int $recursion_level Current recursion depth within the original data. - * @param array $visited_data Data that has been seen in previous recursion iterations. - * - * @return array The original array with all elements replaced as needed. - */ - private static function recursive_unserialize_replace( $from = '', $to = '', &$data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { - - // some unseriliased data cannot be re-serialised eg. SimpleXMLElements - try { - - if ( $recurse_objects ) { - - // If no maximum recursion level is set, use the XDebug limit if it exists - if ( -1 == $max_recursion ) { - // Get the XDebug nesting level. Will be zero (no limit) if no value is set - $max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) ); - } - - // If we've reached the maximum recursion level, short circuit - if ( $max_recursion != 0 && $recursion_level >= $max_recursion ) { - WP_CLI::warning("Maximum recursion level of $max_recursion reached"); - return $data; - } - - if ( ( is_array( $data ) || is_object( $data ) ) ) { - // If we've seen this exact object or array before, short circuit - if ( in_array( $data, $visited_data, true ) ) { - return $data; // Avoid infinite loops when there's a cycle - } - // Add this data to the list of - $visited_data[] = $data; - } - } - - if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { - $data = self::recursive_unserialize_replace( $from, $to, $unserialized, true, $recurse_objects, $max_recursion, $recursion_level + 1 ); - } - - elseif ( is_array( $data ) ) { - $keys = array_keys( $data ); - foreach ( $keys as $key ) { - $data[ $key ]= self::recursive_unserialize_replace( $from, $to, $data[$key], false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); - } - } - - elseif ( $recurse_objects && is_object( $data ) ) { - foreach ( $data as $key => $value ) { - $data->$key = self::recursive_unserialize_replace( $from, $to, $value, false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); - } - } - - else if ( is_string( $data ) ) { - $data = str_replace( $from, $to, $data ); - } - - if ( $serialised ) - return serialize( $data ); - - } catch( Exception $error ) { - - } - - return $data; - } - private static function get_columns( $table ) { global $wpdb; diff --git a/php/utils.php b/php/utils.php index 1972c25057..eba6a3901e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -375,3 +375,81 @@ function parse_url( $url ) { return $url_parts; } + +/** + * Take a serialised array and unserialise it replacing elements as needed and + * unserialising any subordinate arrays and performing the replace on those too. + * Ignores any serialized objects unless $recurse_objects is set to true. + * + * Initial code from https://github.com/interconnectit/Search-Replace-DB + * + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with + * @param array|string $data Used to pass any subordinate arrays back to in. + * @param bool $serialised Does the array passed via $data need serialising. + * @param bool $recurse_objects Should objects be recursively replaced. + * @param int $max_recursion How many levels to recurse into the data, if $recurse_objects is set to true. + * @param int $recursion_level Current recursion depth within the original data. + * @param array $visited_data Data that has been seen in previous recursion iterations. + * + * @return array The original array with all elements replaced as needed. + */ +function recursive_unserialize_replace( $from = '', $to = '', &$data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { + + // some unseriliased data cannot be re-serialised eg. SimpleXMLElements + try { + + if ( $recurse_objects ) { + + // If no maximum recursion level is set, use the XDebug limit if it exists + if ( -1 == $max_recursion ) { + // Get the XDebug nesting level. Will be zero (no limit) if no value is set + $max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) ); + } + + // If we've reached the maximum recursion level, short circuit + if ( $max_recursion != 0 && $recursion_level >= $max_recursion ) { + return $data; + } + + if ( ( is_array( $data ) || is_object( $data ) ) ) { + // If we've seen this exact object or array before, short circuit + if ( in_array( $data, $visited_data, true ) ) { + return $data; // Avoid infinite loops when there's a cycle + } + // Add this data to the list of + $visited_data[] = $data; + } + } + + if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { + $data = recursive_unserialize_replace( $from, $to, $unserialized, true, $recurse_objects, $max_recursion, $recursion_level + 1 ); + } + + elseif ( is_array( $data ) ) { + $keys = array_keys( $data ); + foreach ( $keys as $key ) { + $data[ $key ]= recursive_unserialize_replace( $from, $to, $data[$key], false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); + } + } + + elseif ( $recurse_objects && is_object( $data ) ) { + foreach ( $data as $key => $value ) { + $data->$key = recursive_unserialize_replace( $from, $to, $value, false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); + } + } + + else if ( is_string( $data ) ) { + $data = str_replace( $from, $to, $data ); + } + + if ( $serialised ) + return serialize( $data ); + + } catch( Exception $error ) { + + } + + return $data; +} + diff --git a/tests/test-search-replace.php b/tests/test-search-replace.php new file mode 100644 index 0000000000..696d487ffc --- /dev/null +++ b/tests/test-search-replace.php @@ -0,0 +1,71 @@ +<?php + +require_once getcwd() . '/php/class-wp-cli.php'; +require_once getcwd() . '/php/class-wp-cli-command.php'; +require_once getcwd() . '/php/commands/search-replace.php'; + +class UnserializeReplaceTest extends PHPUnit_Framework_TestCase { + + function testReplaceString() { + $orig = 'foo'; + $replacement = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $orig ); + $this->assertEquals( 'bar', $replacement ); + } + + function testPrivateConstructor() { + $old_obj = ClassWithPrivateConstructor::get_instance(); + + $new_obj = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_obj, false, true ); + $this->assertEquals( 'bar', $new_obj->prop ); + } + + function testObjectLoop() { + $old_object = new stdClass(); + $old_object->prop = 'foo'; + $old_object->self = $old_object; + + $new_obj = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_object, false, true ); + $this->assertEquals( 'bar', $new_obj->prop ); + } + + function testArrayLoop() { + $old_array = array( 'prop' => 'foo' ); + $old_array['self'] = &$old_array; + + $new_array = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_array, false, true ); + $this->assertEquals( 'bar', $new_array['prop'] ); + } + + function testMixedObjectArrayLoop() { + $old_object = new stdClass(); + $old_object->prop = 'foo'; + $old_object->array = array('prop' => 'foo'); + $old_object->array['object'] = $old_object; + + $new_object = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_object, false, true ); + $this->assertEquals( 'bar', $new_object->prop ); + $this->assertEquals( 'bar', $new_object->array['prop']); + } + + function testMixedArrayObjectLoop() { + $old_array = array( 'prop' => 'foo', 'object' => new stdClass() ); + $old_array['object']->prop = 'foo'; + $old_array['object']->array = &$old_array; + + $new_array = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_array, false, true ); + $this->assertEquals( 'bar', $new_array['prop'] ); + $this->assertEquals( 'bar', $new_array['object']->prop); + } +} + + +class ClassWithPrivateConstructor { + + public $prop = 'foo'; + + private function __construct() {} + + public static function get_instance() { + return new self; + } +} From 52245c9441dd1bb344391249a81667c0e6740b83 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 09:47:19 +0200 Subject: [PATCH 2628/4858] remove unnecessary requires; see #951 --- tests/test-search-replace.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test-search-replace.php b/tests/test-search-replace.php index 696d487ffc..4b9b4078b4 100644 --- a/tests/test-search-replace.php +++ b/tests/test-search-replace.php @@ -1,9 +1,5 @@ <?php -require_once getcwd() . '/php/class-wp-cli.php'; -require_once getcwd() . '/php/class-wp-cli-command.php'; -require_once getcwd() . '/php/commands/search-replace.php'; - class UnserializeReplaceTest extends PHPUnit_Framework_TestCase { function testReplaceString() { From 937a313f814b9bc295770ff1964cd3cbe6d929f6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 09:52:44 +0200 Subject: [PATCH 2629/4858] word-wrap command descriptions --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 46cf470b30..a3f42d3a03 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -47,7 +47,7 @@ private static function show_help( $command ) { $longdesc = $command->get_longdesc(); if ( $longdesc ) { - $out .= $longdesc . "\n"; + $out .= wordwrap( $longdesc, 79 ) . "\n"; } // section headers From 8f9393b7ac317c7e26e50726c89bef84131e4437 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 10:03:00 +0200 Subject: [PATCH 2630/4858] manually wrap long line in search-replace description --- php/commands/search-replace.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b8d219d34c..81980e173b 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -12,7 +12,8 @@ class Search_Replace_Command extends WP_CLI_Command { * * ## DESCRIPTION * - * This command will go through all rows in all tables and will replace all appearances of the old string with the new one. + * 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. * From b23962ae8b94a9f6b0bd45ccca97c2e26e648d51 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 11:45:32 +0200 Subject: [PATCH 2631/4858] remove reference from $data parameter; see #951 also, improve parameter descriptions --- php/utils.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/utils.php b/php/utils.php index 1218dd14e7..43edb34983 100644 --- a/php/utils.php +++ b/php/utils.php @@ -390,17 +390,17 @@ function is_windows() { * Initial code from https://github.com/interconnectit/Search-Replace-DB * * @param string $from String we're looking to replace. - * @param string $to What we want it to be replaced with - * @param array|string $data Used to pass any subordinate arrays back to in. - * @param bool $serialised Does the array passed via $data need serialising. - * @param bool $recurse_objects Should objects be recursively replaced. + * @param string $to What we want it to be replaced with. + * @param array|string $data The data to operate on. + * @param bool $serialised Does the value of $data need to be unserialized? + * @param bool $recurse_objects Should objects be recursively replaced? * @param int $max_recursion How many levels to recurse into the data, if $recurse_objects is set to true. * @param int $recursion_level Current recursion depth within the original data. * @param array $visited_data Data that has been seen in previous recursion iterations. * * @return array The original array with all elements replaced as needed. */ -function recursive_unserialize_replace( $from = '', $to = '', &$data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { +function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { // some unseriliased data cannot be re-serialised eg. SimpleXMLElements try { From 95d97b4c729a10518151ee6e60869b949d838603 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 11 Jan 2014 12:05:53 +0200 Subject: [PATCH 2632/4858] convert recursive_unserialize_replace() function to a class benefits: - avoids exposing intermediate recursion variables, such as $recursion_level - clearer which elements are constant and which change see #951 --- php/WP_CLI/SearchReplacer.php | 96 +++++++++++++++++++++++++++++++++ php/commands/search-replace.php | 4 +- php/utils.php | 77 -------------------------- tests/test-search-replace.php | 17 +++--- 4 files changed, 110 insertions(+), 84 deletions(-) create mode 100644 php/WP_CLI/SearchReplacer.php diff --git a/php/WP_CLI/SearchReplacer.php b/php/WP_CLI/SearchReplacer.php new file mode 100644 index 0000000000..e3910b20b3 --- /dev/null +++ b/php/WP_CLI/SearchReplacer.php @@ -0,0 +1,96 @@ +<?php + +namespace WP_CLI; + +class SearchReplacer { + + private $from, $to; + private $recurse_objects; + private $max_recursion; + + /** + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with. + * @param bool $recurse_objects Should objects be recursively replaced? + */ + function __construct( $from, $to, $recurse_objects = false ) { + $this->from = $from; + $this->to = $to; + $this->recurse_objects = $recurse_objects; + + // Get the XDebug nesting level. Will be zero (no limit) if no value is set + $this->max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) ); + } + + /** + * Take a serialised array and unserialise it replacing elements as needed and + * unserialising any subordinate arrays and performing the replace on those too. + * Ignores any serialized objects unless $recurse_objects is set to true. + * + * @param array|string $data The data to operate on. + * @param bool $serialised Does the value of $data need to be unserialized? + * + * @return array The original array with all elements replaced as needed. + */ + function run( $data, $serialised = false ) { + return $this->_run( $data, $serialised ); + } + + /** + * @param int $recursion_level Current recursion depth within the original data. + * @param array $visited_data Data that has been seen in previous recursion iterations. + */ + private function _run( $data, $serialised, $recursion_level = 0, &$visited_data = array() ) { + + // some unseriliased data cannot be re-serialised eg. SimpleXMLElements + try { + + if ( $this->recurse_objects ) { + + // If we've reached the maximum recursion level, short circuit + if ( $this->max_recursion != 0 && $recursion_level >= $this->max_recursion ) { + return $data; + } + + if ( is_array( $data ) || is_object( $data ) ) { + // If we've seen this exact object or array before, short circuit + if ( in_array( $data, $visited_data, true ) ) { + return $data; // Avoid infinite loops when there's a cycle + } + // Add this data to the list of + $visited_data[] = $data; + } + } + + if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { + $data = $this->_run( $unserialized, true, $recursion_level + 1 ); + } + + elseif ( is_array( $data ) ) { + $keys = array_keys( $data ); + foreach ( $keys as $key ) { + $data[ $key ]= $this->_run( $data[$key], false, $recursion_level + 1, $visited_data ); + } + } + + elseif ( $this->recurse_objects && is_object( $data ) ) { + foreach ( $data as $key => $value ) { + $data->$key = $this->_run( $value, false, $recursion_level + 1, $visited_data ); + } + } + + else if ( is_string( $data ) ) { + $data = str_replace( $this->from, $this->to, $data ); + } + + if ( $serialised ) + return serialize( $data ); + + } catch( Exception $error ) { + + } + + return $data; + } +} + diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 81980e173b..d24d6ce9a3 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -124,11 +124,13 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry $count = 0; + $replacer = new \WP_CLI\SearchReplacer( $old, $new, $recurse_objects ); + foreach ( $it as $row ) { if ( '' === $row->$col ) continue; - $value = WP_CLI\Utils\recursive_unserialize_replace( $old, $new, $row->$col, false, $recurse_objects ); + $value = $replacer->run( $row->$col ); if ( $dry_run ) { if ( $value != $row->$col ) diff --git a/php/utils.php b/php/utils.php index 43edb34983..a281bd1677 100644 --- a/php/utils.php +++ b/php/utils.php @@ -382,80 +382,3 @@ function is_windows() { return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; } -/** - * Take a serialised array and unserialise it replacing elements as needed and - * unserialising any subordinate arrays and performing the replace on those too. - * Ignores any serialized objects unless $recurse_objects is set to true. - * - * Initial code from https://github.com/interconnectit/Search-Replace-DB - * - * @param string $from String we're looking to replace. - * @param string $to What we want it to be replaced with. - * @param array|string $data The data to operate on. - * @param bool $serialised Does the value of $data need to be unserialized? - * @param bool $recurse_objects Should objects be recursively replaced? - * @param int $max_recursion How many levels to recurse into the data, if $recurse_objects is set to true. - * @param int $recursion_level Current recursion depth within the original data. - * @param array $visited_data Data that has been seen in previous recursion iterations. - * - * @return array The original array with all elements replaced as needed. - */ -function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $recurse_objects = false, $max_recursion = -1, $recursion_level = 0, &$visited_data = array() ) { - - // some unseriliased data cannot be re-serialised eg. SimpleXMLElements - try { - - if ( $recurse_objects ) { - - // If no maximum recursion level is set, use the XDebug limit if it exists - if ( -1 == $max_recursion ) { - // Get the XDebug nesting level. Will be zero (no limit) if no value is set - $max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) ); - } - - // If we've reached the maximum recursion level, short circuit - if ( $max_recursion != 0 && $recursion_level >= $max_recursion ) { - return $data; - } - - if ( ( is_array( $data ) || is_object( $data ) ) ) { - // If we've seen this exact object or array before, short circuit - if ( in_array( $data, $visited_data, true ) ) { - return $data; // Avoid infinite loops when there's a cycle - } - // Add this data to the list of - $visited_data[] = $data; - } - } - - if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) { - $data = recursive_unserialize_replace( $from, $to, $unserialized, true, $recurse_objects, $max_recursion, $recursion_level + 1 ); - } - - elseif ( is_array( $data ) ) { - $keys = array_keys( $data ); - foreach ( $keys as $key ) { - $data[ $key ]= recursive_unserialize_replace( $from, $to, $data[$key], false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); - } - } - - elseif ( $recurse_objects && is_object( $data ) ) { - foreach ( $data as $key => $value ) { - $data->$key = recursive_unserialize_replace( $from, $to, $value, false, $recurse_objects, $max_recursion, $recursion_level + 1, $visited_data ); - } - } - - else if ( is_string( $data ) ) { - $data = str_replace( $from, $to, $data ); - } - - if ( $serialised ) - return serialize( $data ); - - } catch( Exception $error ) { - - } - - return $data; -} - diff --git a/tests/test-search-replace.php b/tests/test-search-replace.php index 4b9b4078b4..6b5cd27de7 100644 --- a/tests/test-search-replace.php +++ b/tests/test-search-replace.php @@ -2,16 +2,21 @@ class UnserializeReplaceTest extends PHPUnit_Framework_TestCase { + private static function recursive_unserialize_replace( $from, $to, $data, $serialised = false, $recurse_objects = false ) { + $replacer = new \WP_CLI\SearchReplacer( $from, $to, $recurse_objects ); + return $replacer->run( $data, $serialised ); + } + function testReplaceString() { $orig = 'foo'; - $replacement = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $orig ); + $replacement = self::recursive_unserialize_replace( 'foo', 'bar', $orig ); $this->assertEquals( 'bar', $replacement ); } function testPrivateConstructor() { $old_obj = ClassWithPrivateConstructor::get_instance(); - $new_obj = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_obj, false, true ); + $new_obj = self::recursive_unserialize_replace( 'foo', 'bar', $old_obj, false, true ); $this->assertEquals( 'bar', $new_obj->prop ); } @@ -20,7 +25,7 @@ function testObjectLoop() { $old_object->prop = 'foo'; $old_object->self = $old_object; - $new_obj = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_object, false, true ); + $new_obj = self::recursive_unserialize_replace( 'foo', 'bar', $old_object, false, true ); $this->assertEquals( 'bar', $new_obj->prop ); } @@ -28,7 +33,7 @@ function testArrayLoop() { $old_array = array( 'prop' => 'foo' ); $old_array['self'] = &$old_array; - $new_array = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_array, false, true ); + $new_array = self::recursive_unserialize_replace( 'foo', 'bar', $old_array, false, true ); $this->assertEquals( 'bar', $new_array['prop'] ); } @@ -38,7 +43,7 @@ function testMixedObjectArrayLoop() { $old_object->array = array('prop' => 'foo'); $old_object->array['object'] = $old_object; - $new_object = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_object, false, true ); + $new_object = self::recursive_unserialize_replace( 'foo', 'bar', $old_object, false, true ); $this->assertEquals( 'bar', $new_object->prop ); $this->assertEquals( 'bar', $new_object->array['prop']); } @@ -48,7 +53,7 @@ function testMixedArrayObjectLoop() { $old_array['object']->prop = 'foo'; $old_array['object']->array = &$old_array; - $new_array = WP_CLI\Utils\recursive_unserialize_replace( 'foo', 'bar', $old_array, false, true ); + $new_array = self::recursive_unserialize_replace( 'foo', 'bar', $old_array, false, true ); $this->assertEquals( 'bar', $new_array['prop'] ); $this->assertEquals( 'bar', $new_array['object']->prop); } From 99ff98cbaa49d568f8eb55226c50fbb13733e104 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Sun, 5 Jan 2014 19:55:58 +0100 Subject: [PATCH 2633/4858] core caching on download --- php/WP_CLI/FileCache.php | 2 +- php/class-wp-cli.php | 2 +- php/commands/core.php | 62 ++++++++++++++++++++++++---------------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/php/WP_CLI/FileCache.php b/php/WP_CLI/FileCache.php index a6a9fa6244..6fb0af3d7f 100644 --- a/php/WP_CLI/FileCache.php +++ b/php/WP_CLI/FileCache.php @@ -47,7 +47,7 @@ class FileCache { * @param int $maxSize max total cache size * @param string $whitelist List of characters that are allowed in path names (used in a regex character class) */ - public function __construct( $cacheDir, $ttl, $maxSize, $whitelist = 'a-z0-9.' ) { + public function __construct( $cacheDir, $ttl, $maxSize, $whitelist = 'a-z0-9._-' ) { $this->root = rtrim( $cacheDir, '/\\' ) . '/'; $this->ttl = (int) $ttl; $this->maxSize = (int) $maxSize; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1f53436021..0664869542 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -58,7 +58,7 @@ static function get_runner() { /** * @return FileCache */ - private static function get_cache() { + public static function get_cache() { static $cache; if ( !$cache ) { diff --git a/php/commands/core.php b/php/commands/core.php index d01e2067b1..8da06b6e54 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -41,43 +41,54 @@ public function download( $args, $assoc_args ) { WP_CLI::launch( Utils\esc_cmd( 'mkdir -p %s', ABSPATH ) ); } - if ( isset( $assoc_args['locale'] ) && isset( $assoc_args['version'] ) ) { - $download_url = sprintf( 'https://%s.wordpress.org/wordpress-%s-%s.tar.gz', - substr( $assoc_args['locale'], 0, 2 ), $assoc_args['version'], $assoc_args['locale'] ); - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $assoc_args['locale'] ) ); - } else if ( isset( $assoc_args['locale'] ) ) { - $offer = $this->get_download_offer( $assoc_args['locale'] ); - $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', - $offer['current'], $offer['locale'] ) ); - } elseif ( isset( $assoc_args['version'] ) ) { - $download_url = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.tar.gz'; - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); + $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; + + if ( isset( $assoc_args['version'] ) ) { + $version = $assoc_args['version']; + if ( 'en_US' === $locale ) { + $download_url = 'https://wordpress.org/wordpress-' . $version . '.tar.gz'; + } else { + $download_url = sprintf( 'https://%s.wordpress.org/wordpress-%s-%s.tar.gz', + substr( $assoc_args['locale'], 0, 2 ), $version, $locale ); + } } else { - $download_url = 'https://wordpress.org/latest.tar.gz'; - WP_CLI::log( sprintf( 'Downloading latest WordPress (%s)...', 'en_US' ) ); + $offer = $this->get_download_offer( $locale ); + $version = $offer['current']; + $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); } - // We need to use a temporary file because piping from cURL to tar is flaky - // on MinGW (and probably in other environments too). - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $version, $locale ) ); - $headers = array('Accept' => 'application/json'); - $options = array( - 'timeout' => 600, // 10 minutes ought to be enough for everybody - 'filename' => $temp - ); + $cache = WP_CLI::get_cache(); + $cache_key = "core/$locale-$version.tar.gz"; + $cache_file = $cache->has($cache_key); - self::_request( 'GET', $download_url, $headers, $options ); + if ( $cache_file ) { + WP_CLI::log( "Using cached file '$cache_file'..." ); + self::_extract( $cache_file, ABSPATH ); + } else { + // We need to use a temporary file because piping from cURL to tar is flaky + // on MinGW (and probably in other environments too). + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + + $headers = array('Accept' => 'application/json'); + $options = array( + 'timeout' => 600, // 10 minutes ought to be enough for everybody + 'filename' => $temp + ); - self::_extract( $temp, ABSPATH ); + self::_request( 'GET', $download_url, $headers, $options ); + self::_extract( $temp, ABSPATH ); + $cache->import( $cache_key, $temp ); + unlink($temp); + } WP_CLI::success( 'WordPress downloaded.' ); } private static function _extract( $tarball, $dest ) { if ( ! class_exists( 'PharData' ) ) { - $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball && rm $tarball"; + $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball"; WP_CLI::launch( Utils\esc_cmd( $cmd, $dest ) ); return; } @@ -122,6 +133,7 @@ private static function _rmdir( $dir ) { $todo = $fileinfo->isDir() ? 'rmdir' : 'unlink'; $todo( $fileinfo->getRealPath() ); } + rmdir( $dir ); } private static function _request( $method, $url, $headers = array(), $options = array() ) { From f28da3c2f5caed2cf29b8719c9660f4a02a76abc Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Mon, 13 Jan 2014 14:24:23 +0100 Subject: [PATCH 2634/4858] core download caching tests --- features/core.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/core.feature b/features/core.feature index 30fea76ed6..a7c647917d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -9,17 +9,29 @@ Feature: Manage WordPress installation And STDERR should not be empty When I run `wp core download` + And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} Then the wp-settings.php file should exist + And the {SUITE_CACHE_DIR}/core/en_US-{VERSION}.tar.gz file should exist When I run `mkdir inner` And I run `cd inner && wp core download` Then the inner/wp-settings.php file should exist + # test core tarball cache + When I run `wp core download --force` + Then the wp-settings.php file should exist + And STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/core/en_US-{VERSION}.tar.gz'... + """ + @download Scenario: Localized install Given an empty directory When I run `wp core download --locale=de_DE` + And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} Then the wp-settings.php file should exist + And the {SUITE_CACHE_DIR}/core/de_DE-{VERSION}.tar.gz file should exist Scenario: No wp-config.php Given an empty directory From d57711fbe2c0b58742096119e3c84772fe0ecbdf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 Jan 2014 20:59:16 +0200 Subject: [PATCH 2635/4858] make 'wp term delete' accept multiple args --- features/term.feature | 2 +- php/commands/term.php | 29 ++++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/features/term.feature b/features/term.feature index c2b6e8ef29..454455c641 100644 --- a/features/term.feature +++ b/features/term.feature @@ -45,7 +45,7 @@ Feature: Manage WordPress terms "test-delete" """ - When I run `wp term delete {TERM_ID} post_tag` + When I run `wp term delete post_tag {TERM_ID}` Then STDOUT should contain: """ Deleted post_tag {TERM_ID}. diff --git a/php/commands/term.php b/php/commands/term.php index 5bdaeb5a3c..52a8723da5 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -205,28 +205,31 @@ public function update( $args, $assoc_args ) { * * ## OPTIONS * - * <term-id> - * : ID for the term to delete. - * * <taxonomy> * : Taxonomy of the term to delete. * + * <term-id>... + * : One or more IDs of terms to delete. + * * ## EXAMPLES * - * wp term delete 15 category + * # delete all post tags + * wp term list post_tag --field=ID | xargs wp term delete post_tag */ public function delete( $args ) { + $taxonomy = array_shift( $args ); - list( $term_id, $taxonomy ) = $args; - - $ret = wp_delete_term( $term_id, $taxonomy ); + foreach ( $args as $term_id ) { + $ret = wp_delete_term( $term_id, $taxonomy ); - if ( is_wp_error( $ret ) ) - WP_CLI::error( $ret->get_error_message() ); - else if ( $ret ) - WP_CLI::success( sprintf( "Deleted %s %d.", $taxonomy, $term_id ) ); - else - WP_CLI::error( "Term doesn't exist." ); + if ( is_wp_error( $ret ) ) { + WP_CLI::warning( $ret ); + } else if ( $ret ) { + WP_CLI::success( sprintf( "Deleted %s %d.", $taxonomy, $term_id ) ); + } else { + WP_CLI::warning( sprintf( "%s %d doesn't exist.", $taxonomy, $term_id ) ); + } + } } /** From f44beb9d71213930bed6c048352671360e9ed261 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 Jan 2014 21:42:39 +0200 Subject: [PATCH 2636/4858] improve hierarchy generation; see #821 --- php/commands/post.php | 17 +++++++++++------ php/commands/term.php | 18 ++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 3d57cf2de2..c50eb527da 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -263,10 +263,10 @@ public function _list( $_, $assoc_args ) { * * [--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 * @@ -316,7 +316,7 @@ public function generate( $args, $assoc_args ) { $notify = \WP_CLI\Utils\make_progress_bar( 'Generating posts', $count ); - $post_ids = array(); + $previous_post_id = 0; $current_depth = 1; $current_parent = 0; @@ -348,7 +348,12 @@ public function generate( $args, $assoc_args ) { 'post_content' => $post_content, ); - $post_ids[$i] = wp_insert_post( $args, true ); + $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(); } @@ -358,7 +363,7 @@ public function generate( $args, $assoc_args ) { /** * Get post url - * + * * ## OPTIONS * * <id>... @@ -367,7 +372,7 @@ public function generate( $args, $assoc_args ) { * ## EXAMPLES * * wp post url 123 - * + * * wp post url 123 324 */ public function url( $args ) { diff --git a/php/commands/term.php b/php/commands/term.php index 5bdaeb5a3c..ddb3a56006 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -270,27 +270,28 @@ public function generate( $args, $assoc_args ) { $notify = \WP_CLI\Utils\make_progress_bar( 'Generating terms', $count ); - $current_depth = 1; - $current_parent = 0; - $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 ( $this->maybe_make_child() && $current_depth < $max_depth ) { + if ( $previous_term_id && $this->maybe_make_child() && $current_depth < $max_depth ) { - $current_parent = $term['term_id']; + $current_parent = $previous_term_id; $current_depth++; } else if ( $this->maybe_reset_depth() ) { - $current_depth = 1; $current_parent = 0; + $current_depth = 1; } @@ -302,6 +303,11 @@ public function generate( $args, $assoc_args ) { ); $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(); } From bcf2f68a1ce82b0c2bbd35319bd78f26bca5dcaf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 Jan 2014 21:04:05 +0200 Subject: [PATCH 2637/4858] make all the term subcommands accept the taxonomy as the first parameter --- features/site.feature | 2 +- features/term.feature | 8 ++++---- php/commands/term.php | 30 +++++++++++++++--------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/features/site.feature b/features/site.feature index 26f7678416..3a03820079 100644 --- a/features/site.feature +++ b/features/site.feature @@ -59,7 +59,7 @@ Feature: Manage sites in a multisite installation When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` Then STDOUT should not be empty - When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term'` + When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term'` Then STDOUT should not be empty When I run `wp site empty --yes` diff --git a/features/term.feature b/features/term.feature index 454455c641..ebfae3b2ff 100644 --- a/features/term.feature +++ b/features/term.feature @@ -4,7 +4,7 @@ Feature: Manage WordPress terms Given a WP install Scenario: Creating/listing a term - When I run `wp term create 'Test term' post_tag --slug=test --description='This is a test term' --porcelain` + When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term' --porcelain` Then STDOUT should be a number And save STDOUT as {TERM_ID} @@ -28,18 +28,18 @@ Feature: Manage WordPress terms | name | slug | | Test term | test | - When I run `wp term get {TERM_ID} post_tag` + When I run `wp term get post_tag {TERM_ID}` Then STDOUT should be a table containing rows: | Field | Value | | term_id | {TERM_ID} | | name | Test term | Scenario: Creating/deleting a term - When I run `wp term create 'Test delete term' post_tag --slug=test-delete --description='This is a test term to be deleted' --porcelain` + When I run `wp term create post_tag 'Test delete term' --slug=test-delete --description='This is a test term to be deleted' --porcelain` Then STDOUT should be a number And save STDOUT as {TERM_ID} - When I run `wp term get {TERM_ID} post_tag --field=slug --format=json` + When I run `wp term get post_tag {TERM_ID} --field=slug --format=json` Then STDOUT should contain: """ "test-delete" diff --git a/php/commands/term.php b/php/commands/term.php index 52a8723da5..2033dc10f4 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -64,12 +64,12 @@ public function _list( $args, $assoc_args ) { * * ## OPTIONS * - * <term> - * : A name for the new term. - * * <taxonomy> * : Taxonomy for the new term. * + * <term> + * : A name for the new term. + * * [--slug=<slug>] * : A unique slug for the new term. Defaults to sanitized version of name. * @@ -84,11 +84,11 @@ public function _list( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term create Apple category --description="A type of fruit" + * wp term create category Apple --description="A type of fruit" */ public function create( $args, $assoc_args ) { - list( $term, $taxonomy ) = $args; + list( $taxonomy, $term ) = $args; $defaults = array( 'slug' => sanitize_title( $term ), @@ -121,12 +121,12 @@ public function create( $args, $assoc_args ) { * * ## OPTIONS * - * <term-id> - * : ID of the term to get - * * <taxonomy> * : Taxonomy of the term to get * + * <term-id> + * : ID of the term to get + * * [--field=<field>] * : Instead of returning the whole term, returns the value of a single field. * @@ -135,12 +135,12 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term get 1 category --format=json + * wp term get category 1 --format=json */ public function get( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); - list( $term_id, $taxonomy ) = $args; + list( $taxonomy, $term_id ) = $args; $term = get_term_by( 'id', $term_id, $taxonomy ); if ( ! $term ) WP_CLI::error( "Term doesn't exist." ); @@ -153,12 +153,12 @@ public function get( $args, $assoc_args ) { * * ## OPTIONS * - * <term-id> - * : ID for the term to update. - * * <taxonomy> * : Taxonomy of the term to update. * + * <term-id> + * : ID for the term to update. + * * [--name=<name>] * : A new name for the term. * @@ -173,11 +173,11 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term update 15 category --name=Apple + * wp term update category 15 --name=Apple */ public function update( $args, $assoc_args ) { - list( $term_id, $taxonomy ) = $args; + list( $taxonomy, $term_id ) = $args; $defaults = array( 'name' => null, From d00a3d3e57b71c43285aa1d4ae41ef65b9d7b4d5 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Tue, 14 Jan 2014 21:53:29 +0100 Subject: [PATCH 2638/4858] Unset possible ID column to prevent unwanted behaviour If the ID column isn't unset, then `wp_insert_user` will return this ID while not having created a new user. Therefor passing the `is_wp_error` check and showing the success message without actually having created a new user. --- php/commands/user.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/user.php b/php/commands/user.php index 630df43ff4..85535b20ad 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -561,6 +561,7 @@ public function import_csv( $args, $assoc_args ) { // Create the user } else { + unset( $new_user['ID'] ); // Unset else it will just return the ID $user_id = wp_insert_user( $new_user ); } From ae175ac8d88c61b9e8132f07ca2b200b2437a413 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 14 Jan 2014 22:12:54 +0200 Subject: [PATCH 2639/4858] slight improvement to behat step regex --- features/steps/given.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/given.php b/features/steps/given.php index 998a013139..5998f0d2fa 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -87,7 +87,7 @@ function ( $world, TableNode $table ) { } ); -$steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', +$steps->Given( '/^save (STDOUT|STDERR)( [\'].+[^\'])? as \{(\w+)\}$/', function ( $world, $stream, $output_filter, $key ) { if ( $output_filter ) { From a2b320c8b3e36b2a92bdd576659e0ee624469820 Mon Sep 17 00:00:00 2001 From: Nikolay Bachiyski <nb@nikolay.bg> Date: Fri, 17 Jan 2014 18:13:11 -1000 Subject: [PATCH 2640/4858] Update WordPress stable in Travis CI template The 3.6 times are gone. --- templates/.travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 81650f76bb..64be0af086 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -7,8 +7,8 @@ php: env: - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.6.1 WP_MULTISITE=0 - - WP_VERSION=3.6.1 WP_MULTISITE=1 + - WP_VERSION=3.8 WP_MULTISITE=0 + - WP_VERSION=3.8 WP_MULTISITE=1 before_script: - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION From aad9a9636adbe1ec72f7c336aa280d504ed8f45d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 Jan 2014 17:57:31 +0200 Subject: [PATCH 2641/4858] readme: s/Installation/Installing/ just seems more friendly --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c334da4859..9d6cce8640 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ WP-CLI WP-CLI is a set of command-line tools for managing WordPress installations. -Installation +Installing ------------ If you just want to use WP-CLI, see <http://wp-cli.org/#install>. From b89cacc352a1eaa9d0b3d4704e4f00edec5d43d6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 18 Jan 2014 18:22:11 +0200 Subject: [PATCH 2642/4858] use get_check() in 'wp plugin path' --- features/plugin.feature | 12 ++++++++++++ php/commands/plugin.php | 7 +------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 48517e4565..f198ebb9a3 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -10,6 +10,18 @@ Feature: Manage WordPress plugins And the {PLUGIN_DIR}/plugin1/plugin1.php file should exist And the {PLUGIN_DIR}/zombieland/phpunit.xml file should not exist + When I run `wp plugin path plugin1` + Then STDOUT should be: + """ + {PLUGIN_DIR}/plugin1/plugin1.php + """ + + When I run `wp plugin path plugin1 --dir` + Then STDOUT should be: + """ + {PLUGIN_DIR}/plugin1 + """ + When I run `wp plugin scaffold zombieland --plugin_name="Zombieland"` Then STDOUT should not be empty And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 6a66483f82..fd4932d299 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -228,12 +228,7 @@ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); if ( !empty( $args ) ) { - $plugins = $this->fetcher->get_many( $args ); - if ( empty( $plugins ) ) - return; - - list( $plugin ) = $plugins; - + $plugin = $this->fetcher->get_check( $args[0] ); $path .= '/' . $plugin->file; if ( isset( $assoc_args['dir'] ) ) From c74e89ed90fb42ee41d04f69c5b32bbf8f2b2f8e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 Jan 2014 15:25:23 +0200 Subject: [PATCH 2643/4858] refactor long line in get_update_info() --- php/WP_CLI/CommandWithUpgrade.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e4047e0991..485a8a1b27 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -297,7 +297,11 @@ protected function has_update( $slug ) { */ protected function get_update_info( $slug ) { $update_list = get_site_transient( $this->upgrade_transient ); - return isset( $update_list->response[ $slug ] ) ? (array) $update_list->response[ $slug ] : null; + + if ( !isset( $update_list->response[ $slug ] ) ) + return null; + + return (array) $update_list->response[ $slug ]; } private $map = array( From f7f251a03cde4823780582c52c248f8dcb92e443 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 Jan 2014 16:07:17 +0200 Subject: [PATCH 2644/4858] Revert "slight improvement to behat step regex" The new regex didn't catch all cases. This reverts commit ae175ac8d88c61b9e8132f07ca2b200b2437a413. --- features/steps/given.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/given.php b/features/steps/given.php index 5998f0d2fa..998a013139 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -87,7 +87,7 @@ function ( $world, TableNode $table ) { } ); -$steps->Given( '/^save (STDOUT|STDERR)( [\'].+[^\'])? as \{(\w+)\}$/', +$steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', function ( $world, $stream, $output_filter, $key ) { if ( $output_filter ) { From 12481f91c30753c8a300004ff9b6b55ef6ed350a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 19 Jan 2014 19:22:47 +0200 Subject: [PATCH 2645/4858] wp plugin get: remove unreliable 'update' field we'd have to call wp_update_plugins() on each run, like we do for `wp plugin status` also, `wp theme get` doesn't have it --- php/commands/plugin.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index fd4932d299..18465c57bc 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -393,7 +393,6 @@ public function get( $args, $assoc_args ) { 'version' => $plugin_data['Version'], 'description' => wordwrap( $plugin_data['Description'] ), 'status' => $this->get_status( $file ), - 'update' => $this->has_update( $file ), ); $formatter = $this->get_formatter( $assoc_args ); From 7433cdb85305d867d280b71f9f5f3d71e31e1a4b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 08:17:02 -0800 Subject: [PATCH 2646/4858] Update `wp user-meta` to support `user_login` as a first positional argument --- php/commands/user-meta.php | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php index 1e2dda0385..045bf4d3aa 100644 --- a/php/commands/user-meta.php +++ b/php/commands/user-meta.php @@ -14,6 +14,64 @@ */ class User_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'user'; + + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\User; + } + + /** + * Get meta field value. + * + * @synopsis <user> <key> [--format=<format>] + */ + public function get( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::get( $args, $assoc_args ); + } + + /** + * Delete a meta field. + * + * @synopsis <user> <key> + */ + public function delete( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::delete( $args, $assoc_args ); + } + + /** + * Add a meta field. + * + * @synopsis <user> <key> <value> [--format=<format>] + */ + public function add( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::add( $args, $assoc_args ); + } + + /** + * Update a meta field. + * + * @alias set + * @synopsis <user> <key> <value> [--format=<format>] + */ + public function update( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::update( $args, $assoc_args ); + } + + /** + * Replace user_login value with user ID + * user-meta is a special case that also supports user_login + * + * @param array + * @return array + */ + private function replace_login_with_user_id( $args ) { + $user = $this->fetcher->get_check( $args[0] ); + $args[0] = $user->ID; + return $args; + } } WP_CLI::add_command( 'user-meta', 'User_Meta_Command' ); From 0c8f1a229c7b053a8c7115d32356cee8ed9a7ac0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 08:17:34 -0800 Subject: [PATCH 2647/4858] Update tests to reflect 7433cdb --- features/user-meta.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/user-meta.feature b/features/user-meta.feature index 7d3ac2b5f6..7749419721 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -12,10 +12,10 @@ Feature: Manage user custom fields bar """ - When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` + When I run `wp user-meta set admin foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty - When I run `wp user-meta get 1 foo --format=json` + When I run `wp user-meta get admin foo --format=json` Then STDOUT should be: """ ["1","2"] From fa200a50dc3ad0c1284795ea694362ac31ec9125 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 08:49:43 -0800 Subject: [PATCH 2648/4858] `post_type` is a special key that should also support multiple arguments --- php/commands/post.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index c50eb527da..2f997335d1 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -232,8 +232,10 @@ public function _list( $_, $assoc_args ) { $query_args = array_merge( $defaults, $assoc_args ); foreach ( $query_args as $key => $query_arg ) { - if ( false !== strpos( $key, '__' ) ) + if ( false !== strpos( $key, '__' ) + || 'post_type' == $key ) { $query_args[$key] = explode( ',', $query_arg ); + } } if ( 'ids' == $formatter->format ) From c9bc79fc02806c92ac1e79309a7806bc2d6215b0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 09:00:53 -0800 Subject: [PATCH 2649/4858] Add another example to the description --- php/commands/user-meta.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php index 045bf4d3aa..39021d24a2 100644 --- a/php/commands/user-meta.php +++ b/php/commands/user-meta.php @@ -11,6 +11,8 @@ * ## EXAMPLES * * wp user-meta set 123 description "Mary is a WordPress developer." + * + * wp user-meta update admin first_name "George" */ class User_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'user'; From c5fdadeb289d808c176efdfe921fc93de4d42c42 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 09:03:51 -0800 Subject: [PATCH 2650/4858] Copy and paste some command docs --- php/commands/user-meta.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php index 39021d24a2..dbe0924b41 100644 --- a/php/commands/user-meta.php +++ b/php/commands/user-meta.php @@ -23,6 +23,17 @@ public function __construct() { /** * Get meta field value. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to get metadata for. + * + * <key> + * : The metadata key. + * + * [--format=<format>] + * : Accepted values: table, json. Default: table * * @synopsis <user> <key> [--format=<format>] */ @@ -33,6 +44,12 @@ public function get( $args, $assoc_args ) { /** * Delete a meta field. + * + * <user> + * : The user login, user email, or user ID of the user to delete metadata from. + * + * <key> + * : The metadata key. * * @synopsis <user> <key> */ @@ -43,6 +60,15 @@ public function delete( $args, $assoc_args ) { /** * Add a meta field. + * + * <user> + * : The user login, user email, or user ID of the user to add metadata for. + * + * <key> + * : The metadata key. + * + * <value> + * : The new metadata value. * * @synopsis <user> <key> <value> [--format=<format>] */ @@ -53,6 +79,15 @@ public function add( $args, $assoc_args ) { /** * Update a meta field. + * + * <user> + * : The user login, user email, or user ID of the user to update metadata for. + * + * <key> + * : The metadata key. + * + * <value> + * : The new metadata value. * * @alias set * @synopsis <user> <key> <value> [--format=<format>] From 61a132901c8dc0d6f32b81d74908efda1c67043b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 09:10:05 -0800 Subject: [PATCH 2651/4858] Update `wp post list` examples --- php/commands/post.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 2f997335d1..754d631cdb 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -210,7 +210,7 @@ public function delete( $args, $assoc_args ) { * : Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, ids. Default: table * * ## EXAMPLES * @@ -219,6 +219,8 @@ public function delete( $args, $assoc_args ) { * wp post list --post_type=post --posts_per_page=5 --format=json * * wp post list --post_type=page --fields=post_title,post_status + * + * wp post list --post_type=page,post --format=ids * * @subcommand list */ From 73f382e18078dc3cb2349a8d475b97c0e14df95d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Jan 2014 09:55:41 -0800 Subject: [PATCH 2652/4858] According to core, `post_type` == `any` has to be a string --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 754d631cdb..72f4a87f3f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -235,7 +235,7 @@ public function _list( $_, $assoc_args ) { foreach ( $query_args as $key => $query_arg ) { if ( false !== strpos( $key, '__' ) - || 'post_type' == $key ) { + || ( 'post_type' == $key && 'any' != $query_arg ) ) { $query_args[$key] = explode( ',', $query_arg ); } } From 19c47b7a8ef929d72fcfaf1dc8290dd56e42a5d0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 21 Jan 2014 01:00:44 +0200 Subject: [PATCH 2653/4858] rename _list() to list_() to avoid confusing it with a non-public method --- php/commands/cap.php | 2 +- php/commands/comment.php | 2 +- php/commands/post.php | 2 +- php/commands/rewrite.php | 2 +- php/commands/role.php | 2 +- php/commands/term.php | 2 +- php/commands/user.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index c5cc77745f..afeee5d54c 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -27,7 +27,7 @@ class Capabilities_Command extends WP_CLI_Command { * @subcommand list * @synopsis <role> */ - public function _list( $args ) { + public function list_( $args ) { $role_obj = self::get_role( $args[0] ); foreach ( array_keys( $role_obj->capabilities ) as $cap ) diff --git a/php/commands/comment.php b/php/commands/comment.php index b7481ddb3e..cb27163234 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -137,7 +137,7 @@ public function get( $args, $assoc_args ) { * * @subcommand list */ - public function _list( $_, $assoc_args ) { + public function list_( $_, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); if ( 'ids' == $formatter->format ) diff --git a/php/commands/post.php b/php/commands/post.php index 72f4a87f3f..b73eef0537 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -224,7 +224,7 @@ public function delete( $args, $assoc_args ) { * * @subcommand list */ - public function _list( $_, $assoc_args ) { + public function list_( $_, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); $defaults = array( diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 8328a31e2d..64432ad64a 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -115,7 +115,7 @@ public function structure( $args, $assoc_args ) { * wp rewrite list --format=csv * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { global $wp_rewrite; $rules = get_option( 'rewrite_rules' ); diff --git a/php/commands/role.php b/php/commands/role.php index 99e5ecb60d..896bc0f48f 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -29,7 +29,7 @@ class Role_Command extends WP_CLI_Command { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { global $wp_roles; $output_roles = array(); diff --git a/php/commands/term.php b/php/commands/term.php index d1fabf685b..2e5fd3544e 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -44,7 +44,7 @@ class Term_Command extends WP_CLI_Command { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); $defaults = array( diff --git a/php/commands/user.php b/php/commands/user.php index 85535b20ad..e747d7b472 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -51,7 +51,7 @@ public function __construct() { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); if ( 'ids' == $formatter->format ) { From 515d33f0a5ecd47aef1148860b5b3b68cc71080b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 21 Jan 2014 01:05:57 +0200 Subject: [PATCH 2654/4858] more renaming from _list() to list_() --- php/commands/plugin.php | 2 +- php/commands/site.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 18465c57bc..2b6ebef5e4 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -495,7 +495,7 @@ function delete( $args, $assoc_args = array() ) { * * @subcommand list */ - function _list( $_, $assoc_args ) { + public function list_( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); } diff --git a/php/commands/site.php b/php/commands/site.php index cbd5ef2d27..5d5637d270 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -352,7 +352,7 @@ private function _get_network( $network_id ) { * * @subcommand list */ - function _list( $_, $assoc_args ) { + public function list_( $_, $assoc_args ) { if ( !is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index 4c8cddf60c..45df5cab79 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -513,7 +513,7 @@ function delete( $args ) { * * @subcommand list */ - function _list( $_, $assoc_args ) { + public function list_( $_, $assoc_args ) { parent::_list( $_, $assoc_args ); } } From 16fa5cf1071c38a1e6eed21190a2da45ef971323 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 21 Jan 2014 02:02:40 +0200 Subject: [PATCH 2655/4858] first pass at --skip-plugins flag --- features/flags.feature | 49 +++++++++++++++++++++++++++++++++++++++++ php/commands/plugin.php | 24 ++++++-------------- php/config-spec.php | 8 +++++++ php/utils-wp.php | 22 ++++++++++++++++++ php/wp-settings-cli.php | 6 +++-- 5 files changed, 90 insertions(+), 19 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index b81fdbb65b..c666235e28 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -92,6 +92,55 @@ Feature: Global flags log: called 'error' method """ + Scenario: Skipping plugins + Given a WP install + And I run `wp plugin activate hello akismet` + + When I run `wp eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp eval 'var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + true + """ + + # The specified plugin should be skipped + When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + false + """ + + # The specified plugin should still show up as an active plugin + When I run `wp --skip-plugins=akismet plugin status` + Then STDOUT should contain: + """ + akismet + """ + + # The un-specified plugin should continue to be loaded + When I run `wp --skip-plugins=akismet eval 'var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + true + """ + + # No plugins should be loaded when --skip-plugins doesn't have a value + When I run `wp --skip-plugins eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + false + """ + When I run `wp --skip-plugins eval 'var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + false + """ + Scenario: Using --require Given an empty directory And a custom-cmd.php file: diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 2b6ebef5e4..1d90b756e3 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -1,5 +1,7 @@ <?php +use \WP_CLI\Utils; + /** * Manage plugins. * @@ -102,7 +104,7 @@ protected function status_single( $args ) { $version .= ' (%gUpdate available%n)'; echo WP_CLI::colorize( \WP_CLI\Utils\mustache_render( 'plugin-status.mustache', array( - 'slug' => $this->get_name( $file ), + 'slug' => Utils\get_plugin_name( $file ), 'status' => $status, 'version' => $version, 'name' => $details['Name'], @@ -116,7 +118,7 @@ protected function get_all_items() { foreach ( get_mu_plugins() as $file => $mu_plugin ) { $items[ $file ] = array( - 'name' => $this->get_name( $file ), + 'name' => Utils\get_plugin_name( $file ), 'status' => 'must-use', 'update' => false ); @@ -169,7 +171,7 @@ function deactivate( $args, $assoc_args = array() ) { if ( $this->get_status( $file ) == "inactive" ) continue; - $name = $this->get_name( $file ); + $name = Utils\get_plugin_name( $file ); deactivate_plugins( $file, false, $network_wide ); @@ -307,7 +309,7 @@ protected function get_item_list() { $update_info = $this->get_update_info( $file ); $items[ $file ] = array( - 'name' => $this->get_name( $file ), + 'name' => Utils\get_plugin_name( $file ), 'status' => $this->get_status( $file ), 'update' => (bool) $update_info, 'update_version' => $update_info['new_version'], @@ -387,7 +389,7 @@ public function get( $args, $assoc_args ) { $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $file, false, false ); $plugin_obj = (object)array( - 'name' => $this->get_name( $file ), + 'name' => Utils\get_plugin_name( $file ), 'title' => $plugin_data['Name'], 'author' => $plugin_data['Author'], 'version' => $plugin_data['Version'], @@ -545,18 +547,6 @@ private function get_details( $file ) { return $plugin_folder[$plugin_file]; } - /** - * Converts a plugin basename back into a friendly slug. - */ - private function get_name( $file ) { - if ( false === strpos( $file, '/' ) ) - $name = basename( $file, '.php' ); - else - $name = dirname( $file ); - - return $name; - } - private function _delete( $plugin ) { $plugin_dir = dirname( $plugin->file ); if ( '.' == $plugin_dir ) diff --git a/php/config-spec.php b/php/config-spec.php index d4e206e7e9..dd76121255 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -28,6 +28,14 @@ 'desc' => 'Set the WordPress user', ), + 'skip-plugins' => array( + 'runtime' => '[=<plugin>]', + 'file' => false, + 'desc' => 'Skip loading all or some plugins', + 'multiple' => false, + 'default' => '', + ), + 'require' => array( 'runtime' => '=<path>', 'file' => '<path>', diff --git a/php/utils-wp.php b/php/utils-wp.php index 1d925c6be1..a8a64fbfd2 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -69,3 +69,25 @@ function get_upgrader( $class ) { return new $class( new \WP_CLI\UpgraderSkin ); } +/** + * Converts a plugin basename back into a friendly slug. + */ +function get_plugin_name( $basename ) { + if ( false === strpos( $basename, '/' ) ) + $name = basename( $basename, '.php' ); + else + $name = dirname( $basename ); + + return $name; +} + +function is_plugin_skipped( $file ) { + $name = get_plugin_name( str_replace( WP_PLUGIN_DIR . '/', '', $file ) ); + + $skipped_plugins = \WP_CLI::get_runner()->config['skip-plugins']; + if ( true === $skipped_plugins ) + return true; + + return in_array( $name, array_filter( explode( ',', $skipped_plugins ) ) ); +} + diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index d43118d8db..735e54f75d 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -181,7 +181,8 @@ // Load network activated plugins. if ( is_multisite() ) { foreach( wp_get_active_network_plugins() as $network_plugin ) { - include_once( $network_plugin ); + if ( !Utils\is_plugin_skipped( $network_plugin ) ) + include_once( $network_plugin ); } unset( $network_plugin ); } @@ -210,7 +211,8 @@ // Load active plugins. foreach ( wp_get_active_and_valid_plugins() as $plugin ) - include_once( $plugin ); + if ( !Utils\is_plugin_skipped( $plugin ) ) + include_once( $plugin ); unset( $plugin ); // Load pluggable functions. From dd9299f658f55ab60be5605bdce7a1251831454c Mon Sep 17 00:00:00 2001 From: Wesley Spikes <wesley.spikes@gmail.com> Date: Mon, 20 Jan 2014 21:55:38 -0800 Subject: [PATCH 2656/4858] Don't allow wp-cli as root without --allow_root --- php/WP_CLI/Runner.php | 29 +++++++++++++++++++++++++++++ php/config-spec.php | 6 ++++++ 2 files changed, 35 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 57f000a250..c14bdb05a5 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -396,11 +396,40 @@ private function init_config() { list( $this->config, $this->extra_config ) = $configurator->to_array(); } + private function check_root() { + if ( $this->config['allow_root'] ) + return; # they're aware of the risks! + if ( !function_exists( 'posix_geteuid') ) + return; # posix functions not available + if ( posix_geteuid() !== 0 ) + return; # not root + + WP_CLI::error( + "YIKES! It looks like you're running this as root. You probably meant to" . + "run this as the user that your WordPress install exists under.\n" . + "\n" . + "If you REALLY mean to run this as root, we won't stop you, but just " . + "bear in mind that any code on this site will then have full control of " . + "your server, making it quite DANGEROUS.\n" . + "\n" . + "If you'd like to continue as root, please run this again, adding this " . + "flag: --allow_root\n" . + "\n" . + "If you'd like to run it as the user that this site is under, you can " . + "run the following to become the respective user:\n" . + "\n" . + " su USER -c -- wp ...\n" . + "\n" + ); + } + public function before_wp_load() { $this->init_config(); $this->init_colorization(); $this->init_logger(); + $this->check_root(); + if ( empty( $this->arguments ) ) $this->arguments[] = 'help'; diff --git a/php/config-spec.php b/php/config-spec.php index d4e206e7e9..e052609719 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -76,5 +76,11 @@ 'multiple' => true, 'default' => array(), ), + + 'allow_root' => array( + 'runtime' => '=<allow_root>', + 'desc' => '(NOT RECCOMENDED) Allow wp-cli to run as root. This poses a security risk, so you probably do not want to do this.', + ), + ); From ceb262aca0cabea484d3d4d87d4ae7e8b9d13d7b Mon Sep 17 00:00:00 2001 From: Wesley Spikes <wesley.spikes@gmail.com> Date: Wed, 22 Jan 2014 10:38:35 -0800 Subject: [PATCH 2657/4858] Rename --allow_root to --allow-root --- php/WP_CLI/Runner.php | 4 ++-- php/config-spec.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c14bdb05a5..acb95aaccb 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -397,7 +397,7 @@ private function init_config() { } private function check_root() { - if ( $this->config['allow_root'] ) + if ( $this->config['allow-root'] ) return; # they're aware of the risks! if ( !function_exists( 'posix_geteuid') ) return; # posix functions not available @@ -413,7 +413,7 @@ private function check_root() { "your server, making it quite DANGEROUS.\n" . "\n" . "If you'd like to continue as root, please run this again, adding this " . - "flag: --allow_root\n" . + "flag: --allow-root\n" . "\n" . "If you'd like to run it as the user that this site is under, you can " . "run the following to become the respective user:\n" . diff --git a/php/config-spec.php b/php/config-spec.php index e052609719..ffddb174e7 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -77,8 +77,8 @@ 'default' => array(), ), - 'allow_root' => array( - 'runtime' => '=<allow_root>', + 'allow-root' => array( + 'runtime' => '=<allow-root>', 'desc' => '(NOT RECCOMENDED) Allow wp-cli to run as root. This poses a security risk, so you probably do not want to do this.', ), From 2e2cf11d6aac3663feda6661a17fb3ca520d017d Mon Sep 17 00:00:00 2001 From: Wesley Spikes <wesley.spikes@gmail.com> Date: Wed, 22 Jan 2014 21:57:19 -0800 Subject: [PATCH 2658/4858] Adjust spec for --allow-root I know file=false is the default, but were that to change at any point, having this be true could potentially compromise the system's security if wp-cli was run as root. --- php/config-spec.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/config-spec.php b/php/config-spec.php index ffddb174e7..273ad5dbc1 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -78,7 +78,8 @@ ), 'allow-root' => array( - 'runtime' => '=<allow-root>', + 'file' => false, # Explicit. Just in case the default changes. + 'runtime' => '', 'desc' => '(NOT RECCOMENDED) Allow wp-cli to run as root. This poses a security risk, so you probably do not want to do this.', ), From 68e7e529f54cc11bafd5671120fb9a3c7628dc9c Mon Sep 17 00:00:00 2001 From: Wesley Spikes <wesley.spikes@gmail.com> Date: Thu, 23 Jan 2014 00:18:51 -0800 Subject: [PATCH 2659/4858] Don't show --allow-root in help. It'll still be there, it just won't show up in the man pages anymore, since the "NOT RECCOMENDED" is pretty ugly. :) --- php/WP_CLI/Dispatcher/RootCommand.php | 3 +++ php/config-spec.php | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index d65c79fd4b..d11a9a2151 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -27,6 +27,9 @@ function get_longdesc() { if ( isset( $details['deprecated'] ) ) continue; + if ( isset( $details['hidden'] ) ) + continue; + if ( true === $details['runtime'] ) $synopsis = "--[no-]$key"; else diff --git a/php/config-spec.php b/php/config-spec.php index 273ad5dbc1..811473f178 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -77,10 +77,12 @@ 'default' => array(), ), + # --allow-root => (NOT RECCOMENDED) Allow wp-cli to run as root. This poses + # a security risk, so you probably do not want to do this. 'allow-root' => array( 'file' => false, # Explicit. Just in case the default changes. 'runtime' => '', - 'desc' => '(NOT RECCOMENDED) Allow wp-cli to run as root. This poses a security risk, so you probably do not want to do this.', + 'hidden' => true, ), ); From ea0ede09a2d4facf2484637e47b802350cbf11ce Mon Sep 17 00:00:00 2001 From: Barta Akos <akos@netpositive.hu> Date: Fri, 24 Jan 2014 09:56:08 +0100 Subject: [PATCH 2660/4858] added locale to core update --- php/commands/core.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8da06b6e54..ba0e091f47 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -649,6 +649,9 @@ public function version( $args = array(), $assoc_args = array() ) { * [--force] * : Will update even when current WP version < passed version. Use with * caution. + * + * [--locale=<locale>] + * : Select which language you want to download. * * ## EXAMPLES * @@ -681,7 +684,16 @@ function update( $args, $assoc_args ) { $new_package = null; if ( empty( $args[0] ) ) { - $new_package = 'https://wordpress.org/wordpress-' . $assoc_args['version'] . '.zip'; + $version = $assoc_args['version']; + $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; + + if ( 'en_US' === $locale ) { + $new_package = 'https://wordpress.org/wordpress-' . $version . '.zip'; + } else { + $new_package = sprintf( 'https://%s.wordpress.org/wordpress-%s-%s.zip', + substr( $assoc_args['locale'], 0, 2 ), $version, $locale ); + } + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); } else { $new_package = $args[0]; From 5d70ab3ff106f04089b4ea081d1333fba81ee8b8 Mon Sep 17 00:00:00 2001 From: Barta Akos <akos@netpositive.hu> Date: Fri, 24 Jan 2014 10:06:50 +0100 Subject: [PATCH 2661/4858] added locale information to core update log --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index ba0e091f47..a23c413cf5 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -694,7 +694,7 @@ function update( $args, $assoc_args ) { substr( $assoc_args['locale'], 0, 2 ), $version, $locale ); } - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], 'en_US' ) ); + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $locale ) ); } else { $new_package = $args[0]; $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; From 01c53b37ba6107ce3c5b1280596557c76209ab63 Mon Sep 17 00:00:00 2001 From: Barta Akos <akos@netpositive.hu> Date: Fri, 24 Jan 2014 16:39:47 +0100 Subject: [PATCH 2662/4858] get_download_url --- php/commands/core.php | 44 +++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index a23c413cf5..37a7453af8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -45,12 +45,7 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { $version = $assoc_args['version']; - if ( 'en_US' === $locale ) { - $download_url = 'https://wordpress.org/wordpress-' . $version . '.tar.gz'; - } else { - $download_url = sprintf( 'https://%s.wordpress.org/wordpress-%s-%s.tar.gz', - substr( $assoc_args['locale'], 0, 2 ), $version, $locale ); - } + $download_url = $this->get_download_url($version, $locale, 'tar.gz'); } else { $offer = $this->get_download_offer( $locale ); $version = $offer['current']; @@ -684,15 +679,10 @@ function update( $args, $assoc_args ) { $new_package = null; if ( empty( $args[0] ) ) { - $version = $assoc_args['version']; - $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; + $version = $assoc_args['version']; + $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; - if ( 'en_US' === $locale ) { - $new_package = 'https://wordpress.org/wordpress-' . $version . '.zip'; - } else { - $new_package = sprintf( 'https://%s.wordpress.org/wordpress-%s-%s.zip', - substr( $assoc_args['locale'], 0, 2 ), $version, $locale ); - } + $new_package = $this->get_download_url($version, $locale); WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $locale ) ); } else { @@ -743,6 +733,32 @@ function update_db() { wp_upgrade(); WP_CLI::success( 'WordPress database upgraded successfully.' ); } + + /** + * Gets download url based on version, locale and desired file type. + * + * @param $version + * @param string $locale + * @param string $file_type + * @return string + */ + private function get_download_url($version, $locale = 'en_US', $file_type = 'zip') + { + if ('en_US' === $locale) { + $url = 'https://wordpress.org/wordpress-' . $version . '.' . $file_type; + + return $url; + } else { + $url = sprintf( + 'https://%s.wordpress.org/wordpress-%s-%s.' . $file_type, + substr($locale, 0, 2), + $version, + $locale + ); + + return $url; + } + } } WP_CLI::add_command( 'core', 'Core_Command' ); From 5e6757af68f260c4d5deee841025ea878efe1e4a Mon Sep 17 00:00:00 2001 From: Wesley Spikes <wesley.spikes@gmail.com> Date: Fri, 24 Jan 2014 16:52:40 -0800 Subject: [PATCH 2663/4858] Minor typo fix. --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index acb95aaccb..45821a93ad 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -405,7 +405,7 @@ private function check_root() { return; # not root WP_CLI::error( - "YIKES! It looks like you're running this as root. You probably meant to" . + "YIKES! It looks like you're running this as root. You probably meant to " . "run this as the user that your WordPress install exists under.\n" . "\n" . "If you REALLY mean to run this as root, we won't stop you, but just " . From a2d9a813cfced612aab8614050348e92ef35c690 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 25 Jan 2014 16:41:09 +0200 Subject: [PATCH 2664/4858] extract replace_path_consts() utility --- php/WP_CLI/Runner.php | 14 ++++---------- php/utils.php | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 57f000a250..578d9bf782 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -225,14 +225,6 @@ private function _run_command() { public function get_wp_config_code() { $wp_config_path = Utils\locate_wp_config(); - $replacements = array( - '__FILE__' => "'$wp_config_path'", - '__DIR__' => "'" . dirname( $wp_config_path ) . "'" - ); - - $old = array_keys( $replacements ); - $new = array_values( $replacements ); - $wp_config_code = explode( "\n", file_get_contents( $wp_config_path ) ); $lines_to_run = array(); @@ -241,10 +233,12 @@ public function get_wp_config_code() { if ( preg_match( '/^\s*require.+wp-settings\.php/', $line ) ) continue; - $lines_to_run[] = str_replace( $old, $new, $line ); + $lines_to_run[] = $line; } - return preg_replace( '|^\s*\<\?php\s*|', '', implode( "\n", $lines_to_run ) ); + $source = implode( "\n", $lines_to_run ); + $source = Utils\replace_path_consts( $source, $wp_config_path ); + return preg_replace( '|^\s*\<\?php\s*|', '', $source ); } // Transparently convert old syntaxes diff --git a/php/utils.php b/php/utils.php index a281bd1677..7ce26e81bc 100644 --- a/php/utils.php +++ b/php/utils.php @@ -382,3 +382,21 @@ function is_windows() { return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; } +/** + * Replace magic constants in some PHP source code. + * + * @param string $source The PHP code to manipulate. + * @param string $path The path to use instead of the magic constants + */ +function replace_path_consts( $source, $path ) { + $replacements = array( + '__FILE__' => "'$path'", + '__DIR__' => "'" . dirname( $path ) . "'" + ); + + $old = array_keys( $replacements ); + $new = array_values( $replacements ); + + return str_replace( $old, $new, $source ); +} + From 28a163f3cb9a05c3768b1c0135012aae820bb1c1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 25 Jan 2014 17:05:47 +0200 Subject: [PATCH 2665/4858] make autodetection of WP files in a subdirectory work in more cases fixes #929 --- features/config.feature | 9 ++++++++- php/WP_CLI/Runner.php | 37 ++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/features/config.feature b/features/config.feature index 8720f451a4..d1a1768ab7 100644 --- a/features/config.feature +++ b/features/config.feature @@ -56,11 +56,18 @@ Feature: Have a config file Scenario: WP in a subdirectory (autodetected) Given a WP install in 'core' - And a index.php file: + + Given a index.php file: """ require('./core/wp-blog-header.php'); """ + When I run `wp core is-installed` + Then STDOUT should be empty + Given a index.php file: + """ + require dirname(__FILE__) . '/core/wp-blog-header.php'; + """ When I run `wp core is-installed` Then STDOUT should be empty diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 578d9bf782..81f9a86def 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -73,6 +73,30 @@ private static function get_project_config_path() { } ); } + /** + * Attempts to find the path to the WP install inside index.php + */ + private static function extract_subdir_path( $index_path ) { + if ( !file_exists( $index_path ) ) + return false; + + $index_code = file_get_contents( $index_path ); + + if ( !preg_match( '|^\s*require\s*\(?\s*(.+?)/wp-blog-header\.php([\'"])|m', $index_code, $matches ) ) { + return false; + } + + $wp_path_src = $matches[1] . $matches[2]; + $wp_path_src = Utils\replace_path_consts( $wp_path_src, $index_path ); + $wp_path = eval( "return $wp_path_src;" ); + + if ( !Utils\is_path_absolute( $wp_path ) ) { + $wp_path = dirname( $index_path ) . "/$wp_path"; + } + + return $wp_path; + } + private static function set_wp_root( $config ) { $path = getcwd(); @@ -81,17 +105,8 @@ private static function set_wp_root( $config ) { $path = $config['path']; else $path .= '/' . $config['path']; - } elseif ( file_exists( './index.php' ) ) { - $index_code = file_get_contents( './index.php' ); - - if ( preg_match( '/^\s*require.+([\'"])(.*wp-blog-header\.php)\1/m', $index_code, $matches ) ) { - $new_path = dirname( $matches[2] ); - if ( Utils\is_path_absolute( $new_path ) ) { - $path = $new_path; - } else { - $path .= '/' . $new_path; - } - } + } elseif ( $wp_path = self::extract_subdir_path( $path . '/index.php' ) ) { + $path = $wp_path; } define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); From dcdbe7768cf0baf663b5825b51ae61d424f67705 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 25 Jan 2014 17:10:33 +0200 Subject: [PATCH 2666/4858] behat: allow correct grammar --- features/config.feature | 4 ++-- features/steps/given.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/config.feature b/features/config.feature index d1a1768ab7..86294e962a 100644 --- a/features/config.feature +++ b/features/config.feature @@ -57,14 +57,14 @@ Feature: Have a config file Scenario: WP in a subdirectory (autodetected) Given a WP install in 'core' - Given a index.php file: + Given an index.php file: """ require('./core/wp-blog-header.php'); """ When I run `wp core is-installed` Then STDOUT should be empty - Given a index.php file: + Given an index.php file: """ require dirname(__FILE__) . '/core/wp-blog-header.php'; """ diff --git a/features/steps/given.php b/features/steps/given.php index 998a013139..a7b29d3c25 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -9,7 +9,7 @@ function ( $world ) { } ); -$steps->Given( '/^a ([^\s]+) file:$/', +$steps->Given( '/^an? ([^\s]+) file:$/', function ( $world, $path, PyStringNode $content ) { $content = (string) $content . "\n"; $full_path = $world->variables['RUN_DIR'] . "/$path"; From 5cc18ad4f74f71e9d98ea706fded00c3d834a1d5 Mon Sep 17 00:00:00 2001 From: Wesley Spikes <wesley.spikes@gmail.com> Date: Sat, 25 Jan 2014 15:20:00 -0800 Subject: [PATCH 2667/4858] Recommend sudo instead of su. --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 45821a93ad..fe5ffc90b5 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -418,7 +418,7 @@ private function check_root() { "If you'd like to run it as the user that this site is under, you can " . "run the following to become the respective user:\n" . "\n" . - " su USER -c -- wp ...\n" . + " sudo -u USER -i -- wp ...\n" . "\n" ); } From 14eae59a79858aa553f1a1dedbb76d5df9f1f3b2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 26 Jan 2014 03:07:17 +0200 Subject: [PATCH 2668/4858] fix --max_depth= again and add behat test closes #820 see #943 --- features/post.feature | 10 +++++++++- php/commands/post.php | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/features/post.feature b/features/post.feature index df556cc7d0..aaec9469b3 100644 --- a/features/post.feature +++ b/features/post.feature @@ -134,4 +134,12 @@ Feature: Manage WordPress posts """ Content generated by wp post generate """ - And STDERR should be empty \ No newline at end of file + And STDERR should be empty + + Scenario: Generating pages + When I run `wp post generate --post_type=page --max_depth=10` + And I run `wp post list --post_type=page --field=post_parent` + Then STDOUT should contain: + """ + 1 + """ diff --git a/php/commands/post.php b/php/commands/post.php index b73eef0537..9cae108889 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -219,8 +219,8 @@ public function delete( $args, $assoc_args ) { * wp post list --post_type=post --posts_per_page=5 --format=json * * wp post list --post_type=page --fields=post_title,post_status - * - * wp post list --post_type=page,post --format=ids + * + * wp post list --post_type=page,post --format=ids * * @subcommand list */ @@ -330,7 +330,7 @@ public function generate( $args, $assoc_args ) { if( $this->maybe_make_child() && $current_depth < $max_depth ) { - $current_parent = $post_ids[$i-1]; + $current_parent = $previous_post_id; $current_depth++; } else if( $this->maybe_reset_depth() ) { From 8e0680f7009646f4e912bae53c261ff896daaa2e Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 26 Jan 2014 13:48:34 +0200 Subject: [PATCH 2669/4858] bump version to 0.14.0-alpha2 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index a592703db6..8f70c7353b 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.14.0-alpha' ); +define( 'WP_CLI_VERSION', '0.14.0-alpha2' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From aef5511f1f263c830923cbce33b2a84f9ae1c85d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 Jan 2014 01:57:29 +0200 Subject: [PATCH 2670/4858] group all logic that deals with finding the WP files into a single method --- php/WP_CLI/Runner.php | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 42af9644e6..b4823e10e3 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -97,18 +97,32 @@ private static function extract_subdir_path( $index_path ) { return $wp_path; } - private static function set_wp_root( $config ) { - $path = getcwd(); + /** + * Find the directory that contains the WordPress files. Defaults to the current working dir. + * + * @return string An absolute path + */ + private function find_wp_root() { + if ( !empty( $this->config['path'] ) ) { + $path = $this->config['path']; + if ( !Utils\is_path_absolute( $path ) ) + $path = getcwd() . '/' . $path; - if ( !empty( $config['path'] ) ) { - if ( Utils\is_path_absolute( $config['path'] ) ) - $path = $config['path']; - else - $path .= '/' . $config['path']; - } elseif ( $wp_path = self::extract_subdir_path( $path . '/index.php' ) ) { - $path = $wp_path; + return $path; } + if ( $this->cmd_starts_with( array( 'core', 'download' ) ) ) { + return getcwd(); + } + + if ( $wp_load_path = Utils\find_file_upward( 'wp-load.php' ) ) { + return dirname( $wp_load_path ); + } + + return self::extract_subdir_path( getcwd() . '/index.php' ); + } + + private static function set_wp_root( $path ) { define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); @@ -464,14 +478,7 @@ public function before_wp_load() { } // Handle --path parameter - if ( !isset( $this->config['path'] ) ) { - if ( $this->cmd_starts_with( array( 'core', 'download' ) ) ) { - $this->config['path'] = getcwd(); - } else { - $this->config['path'] = dirname( Utils\find_file_upward( 'wp-load.php' ) ); - } - } - self::set_wp_root( $this->config ); + self::set_wp_root( $this->find_wp_root() ); // First try at showing man page if ( 'help' === $this->arguments[0] && ( isset( $this->arguments[1] ) || !$this->wp_exists() ) ) { From 719097b1cf4b7a15325c8cc20deb53634ba9a5a6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 Jan 2014 02:09:45 +0200 Subject: [PATCH 2671/4858] allow WP-CLI to be invoked from subdirectories other than the subdir the WP files are in --- features/config.feature | 8 ++++++++ php/WP_CLI/Runner.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/config.feature b/features/config.feature index 86294e962a..f3021ecbce 100644 --- a/features/config.feature +++ b/features/config.feature @@ -54,6 +54,10 @@ Feature: Have a config file When I run `wp core is-installed` from 'core/wp-content' Then STDOUT should be empty + When I run `mkdir -p other/subdir` + And I run `wp core is-installed` from 'other/subdir' + Then STDOUT should be empty + Scenario: WP in a subdirectory (autodetected) Given a WP install in 'core' @@ -71,6 +75,10 @@ Feature: Have a config file When I run `wp core is-installed` Then STDOUT should be empty + When I run `mkdir -p other/subdir` + And I run `wp core is-installed` from 'other/subdir' + Then STDOUT should be empty + Scenario: Nested installs Given a WP install And a WP install in 'subsite' diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b4823e10e3..6abb09a131 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -119,7 +119,7 @@ private function find_wp_root() { return dirname( $wp_load_path ); } - return self::extract_subdir_path( getcwd() . '/index.php' ); + return self::extract_subdir_path( Utils\find_file_upward( 'index.php' ) ); } private static function set_wp_root( $path ) { From f3aaf4ba83e383d4ac00eb98fc2b1f020ff39b95 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 Jan 2014 02:36:20 +0200 Subject: [PATCH 2672/4858] continue searching after finding an index.php that doesn't contain the path to wp-blog-header.php --- features/config.feature | 1 + php/WP_CLI/Runner.php | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/features/config.feature b/features/config.feature index f3021ecbce..b103ef73ba 100644 --- a/features/config.feature +++ b/features/config.feature @@ -76,6 +76,7 @@ Feature: Have a config file Then STDOUT should be empty When I run `mkdir -p other/subdir` + And I run `echo '<?php // Silence is golden' > other/subdir/index.php` And I run `wp core is-installed` from 'other/subdir' Then STDOUT should be empty diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6abb09a131..d43b2c75e6 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -77,9 +77,6 @@ private static function get_project_config_path() { * Attempts to find the path to the WP install inside index.php */ private static function extract_subdir_path( $index_path ) { - if ( !file_exists( $index_path ) ) - return false; - $index_code = file_get_contents( $index_path ); if ( !preg_match( '|^\s*require\s*\(?\s*(.+?)/wp-blog-header\.php([\'"])|m', $index_code, $matches ) ) { @@ -115,11 +112,24 @@ private function find_wp_root() { return getcwd(); } - if ( $wp_load_path = Utils\find_file_upward( 'wp-load.php' ) ) { - return dirname( $wp_load_path ); - } + $dir = getcwd(); + + while ( is_readable( $dir ) ) { + if ( file_exists( "$dir/wp-load.php" ) ) { + return $dir; + } - return self::extract_subdir_path( Utils\find_file_upward( 'index.php' ) ); + if ( file_exists( "$dir/index.php" ) ) { + if ( $path = self::extract_subdir_path( "$dir/index.php" ) ) + return $path; + } + + $parent_dir = dirname( $dir ); + if ( empty($parent_dir) || $parent_dir === $dir ) { + break; + } + $dir = $parent_dir; + } } private static function set_wp_root( $path ) { From ff2ef21d352151d8f4739aaff8322a18968e8295 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 Jan 2014 03:32:54 +0200 Subject: [PATCH 2673/4858] allow reading values from STDIN for `wp option` and 'wp *-meta` subcommands --- features/option.feature | 19 +++++++++++++++++ features/post-meta.feature | 7 ++++++ php/WP_CLI/CommandWithMeta.php | 35 ++++++++++++++++++++++++++---- php/class-wp-cli.php | 25 +++++++++++++++++++++- php/commands/option.php | 39 ++++++++++++++++++++++++++++++---- 5 files changed, 116 insertions(+), 9 deletions(-) diff --git a/features/option.feature b/features/option.feature index 28ea9a8c4c..ee9a7a509d 100644 --- a/features/option.feature +++ b/features/option.feature @@ -46,3 +46,22 @@ Feature: Manage WordPress options """ [1,2] """ + + + # Reading from files + Given a value.json file: + """ + { + "foo": "bar", + "list": [1, 2, 3] + } + """ + When I run `wp option set foo --format=json < value.json` + And I run `wp option get foo --format=json` + Then STDOUT should be JSON containing: + """ + { + "foo": "bar", + "list": [1, 2, 3] + } + """ diff --git a/features/post-meta.feature b/features/post-meta.feature index b756062a93..b1daf1bbaf 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -21,6 +21,13 @@ Feature: Manage post custom fields ["1","2"] """ + When I run `echo 'via STDIN' | wp post-meta set 1 foo` + And I run `wp post-meta get 1 foo` + Then STDOUT should be: + """ + via STDIN + """ + When I run `wp post-meta delete 1 foo` Then STDOUT should not be empty diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 6695d1e51c..f09d9fbcd2 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -47,12 +47,25 @@ public function delete( $args, $assoc_args ) { /** * Add a meta field. * - * @synopsis <id> <key> <value> [--format=<format>] + * ## OPTIONS + * + * <id> + * : The ID of the object. + * + * <key> + * : The name of the meta field to create. + * + * [<value>] + * : The value of the meta field. If ommited, the value is read from STDIN. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. */ public function add( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $meta_value = \WP_CLI::read_value( $args[2], $assoc_args ); + $meta_value = \WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); + $meta_value = \WP_CLI::read_value( $meta_value, $assoc_args ); $success = \add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); @@ -66,13 +79,27 @@ public function add( $args, $assoc_args ) { /** * Update a meta field. * + * ## OPTIONS + * + * <id> + * : The ID of the object. + * + * <key> + * : The name of the meta field to update. + * + * [<value>] + * : The new value. If ommited, the value is read from STDIN. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. + * * @alias set - * @synopsis <id> <key> <value> [--format=<format>] */ public function update( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $meta_value = \WP_CLI::read_value( $args[2], $assoc_args ); + $meta_value = \WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); + $meta_value = \WP_CLI::read_value( $meta_value, $assoc_args ); $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0664869542..88db5d790e 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -234,7 +234,30 @@ static function confirm( $question, $assoc_args = array() ) { } /** - * Read a value, from various formats + * Read value from a positional argument or from STDIN. + * + * @param array $args The list of positional arguments. + * @param int $index At which position to check for the value. + * + * @return string + */ + public static function get_value_from_arg_or_stdin( $args, $index ) { + if ( isset( $args[ $index ] ) ) { + $raw_value = $args[ $index ]; + } else { + // We don't use file_get_contents() here because it doesn't handle + // Ctrl-D properly, when typing in the value interactively. + $raw_value = ''; + while ( ( $line = fgets( STDIN ) ) !== false ) { + $raw_value .= $line; + } + } + + return $raw_value; + } + + /** + * Read a value, from various formats. * * @param mixed $value * @param array $assoc_args diff --git a/php/commands/option.php b/php/commands/option.php index 1c4c66095d..f5e025860d 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -39,12 +39,27 @@ public function get( $args, $assoc_args ) { /** * Add an option. * - * @synopsis <key> <value> [--format=<format>] + * ## OPTIONS + * + * <key> + * : The name of the option to add. + * + * [<value>] + * : The value of the option to add. If ommited, the value is read from STDIN. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. + * + * ## EXAMPLES + * + * # Create an option by reading a JSON file + * wp option add my_option --format=json < config.json */ public function add( $args, $assoc_args ) { $key = $args[0]; - $value = WP_CLI::read_value( $args[1], $assoc_args ); + $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); + $value = WP_CLI::read_value( $value, $assoc_args ); if ( !add_option( $key, $value ) ) { WP_CLI::error( "Could not add option '$key'. Does it already exist?" ); @@ -56,13 +71,29 @@ public function add( $args, $assoc_args ) { /** * Update an option. * + * ## OPTIONS + * + * <key> + * : The name of the option to add. + * + * [<value>] + * : The new value. If ommited, the value is read from STDIN. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. + * + * ## EXAMPLES + * + * # Update an option by reading from a file + * wp option update my_option < value.txt + * * @alias set - * @synopsis <key> <value> [--format=<format>] */ public function update( $args, $assoc_args ) { $key = $args[0]; - $value = WP_CLI::read_value( $args[1], $assoc_args ); + $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); + $value = WP_CLI::read_value( $value, $assoc_args ); $result = update_option( $key, $value ); From 656d32f51369cffe1ca3cb0181ce878f694faeda Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Thu, 30 Jan 2014 22:16:13 -0500 Subject: [PATCH 2674/4858] Define $role variable in User_Command::generate() This fixes role-setting when generating users. --- php/commands/user.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index e747d7b472..0ac77e767c 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -276,7 +276,9 @@ public function generate( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); - if ( !self::validate_role( $assoc_args['role'] ) ) { + $role = $assoc_args['role']; + + if ( !self::validate_role( $role ) ) { WP_CLI::error( "Invalid role: $role" ); } From aa74cb83189b473bec106d06015fde6252023ea8 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 31 Jan 2014 14:57:51 +0200 Subject: [PATCH 2675/4858] stop looking for deprecated wp-cli-blog file rationale: - it makes an extra access(2) syscall on each run - it's been deprecated for many versions --- php/WP_CLI/Runner.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index d43b2c75e6..c701d2646d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -158,10 +158,6 @@ private static function guess_url( $assoc_args ) { if ( true === $url ) { WP_CLI::warning( 'The --url parameter expects a value.' ); } - } elseif ( is_readable( ABSPATH . 'wp-cli-blog' ) ) { - WP_CLI::warning( 'The wp-cli-blog file is deprecated. Use wp-cli.yml instead.' ); - - $url = trim( file_get_contents( ABSPATH . 'wp-cli-blog' ) ); } elseif ( $wp_config_path = Utils\locate_wp_config() ) { // Try to find the blog parameter in the wp-config file $wp_config_file = file_get_contents( $wp_config_path ); From 6286442ea6943f8f2318033a1d1b9596f87f36f6 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 1 Feb 2014 22:52:35 +0200 Subject: [PATCH 2676/4858] fix notice in find_item_by_key() --- php/WP_CLI/Formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 6f971b28b4..7d3eacc0b7 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -125,7 +125,7 @@ private function find_item_key( $item, $field ) { } } - if ( ! $key ) { + if ( ! isset( $key ) ) { \WP_CLI::error( "Invalid field: $field." ); } From 75a6a0c4f3619453afafca5ddc9d96e6299d37da Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 1 Feb 2014 22:58:11 +0200 Subject: [PATCH 2677/4858] add Behat test for #985 --- features/user.feature | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index 99aa75990d..f253335196 100644 --- a/features/user.feature +++ b/features/user.feature @@ -48,8 +48,14 @@ Feature: Manage WordPress users Then STDOUT should not be empty Scenario: Generating and deleting users - When I run `wp user generate --count=9` - And I run `wp user list --format=count` + When I run `wp user list --role=editor --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp user generate --count=10 --role=editor` + And I run `wp user list --role=editor --format=count` Then STDOUT should be: """ 10 From e614cb569c631cc7fc29c4774b50fe69efa5e06a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 1 Feb 2014 23:52:19 +0200 Subject: [PATCH 2678/4858] make local plugin lookup case-sensitive the old lookup method returned false positives on case-insensitive filesystems (plugin basenames are treated as case-sensitive by WordPress) fixes #958 --- features/plugin.feature | 37 ++++++++++++++++++++-------------- php/WP_CLI/Fetchers/Plugin.php | 26 ++++-------------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index f198ebb9a3..4bbd84cdec 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -22,17 +22,24 @@ Feature: Manage WordPress plugins {PLUGIN_DIR}/plugin1 """ - When I run `wp plugin scaffold zombieland --plugin_name="Zombieland"` + When I run `wp plugin scaffold Zombieland` Then STDOUT should not be empty - And the {PLUGIN_DIR}/zombieland/zombieland.php file should exist - And the {PLUGIN_DIR}/zombieland/phpunit.xml file should exist + And the {PLUGIN_DIR}/Zombieland/Zombieland.php file should exist + And the {PLUGIN_DIR}/Zombieland/phpunit.xml file should exist + + # Ensure case sensitivity + When I try `wp plugin status zombieLand` + Then STDERR should contain: + """ + The 'zombieLand' plugin could not be found. + """ # Check that the inner-plugin is not picked up - When I run `mv {PLUGIN_DIR}/plugin1 {PLUGIN_DIR}/zombieland/` - And I run `wp plugin status zombieland` + When I run `mv {PLUGIN_DIR}/plugin1 {PLUGIN_DIR}/Zombieland/` + And I run `wp plugin status Zombieland` Then STDOUT should contain: """ - Plugin zombieland details: + Plugin Zombieland details: Name: Zombieland Status: Inactive Version: 0.1-alpha @@ -40,10 +47,10 @@ Feature: Manage WordPress plugins Description: PLUGIN DESCRIPTION HERE """ - When I run `wp plugin activate zombieland` + When I run `wp plugin activate Zombieland` Then STDOUT should not be empty - When I run `wp plugin status zombieland` + When I run `wp plugin status Zombieland` Then STDOUT should contain: """ Status: Active @@ -55,28 +62,28 @@ Feature: Manage WordPress plugins When I run `wp plugin list` Then STDOUT should be a table containing rows: | name | status | update | version | - | zombieland | active | none | 0.1-alpha | + | Zombieland | active | none | 0.1-alpha | - When I try `wp plugin uninstall zombieland` + When I try `wp plugin uninstall Zombieland` Then STDERR should contain: """ - The 'zombieland' plugin is active. + The 'Zombieland' plugin is active. """ - When I run `wp plugin deactivate zombieland` + When I run `wp plugin deactivate Zombieland` Then STDOUT should not be empty - When I run `wp plugin uninstall zombieland` + When I run `wp plugin uninstall Zombieland` Then STDOUT should contain: """ - Success: Uninstalled 'zombieland' plugin. + Success: Uninstalled 'Zombieland' plugin. """ And the {PLUGIN_DIR}/zombieland file should not exist When I try the previous command again Then STDERR should contain: """ - The 'zombieland' plugin could not be found. + The 'Zombieland' plugin could not be found. """ Scenario: Install a plugin, activate, then force install an older version of the plugin diff --git a/php/WP_CLI/Fetchers/Plugin.php b/php/WP_CLI/Fetchers/Plugin.php index f59672570d..37f3e10a0e 100644 --- a/php/WP_CLI/Fetchers/Plugin.php +++ b/php/WP_CLI/Fetchers/Plugin.php @@ -7,31 +7,13 @@ class Plugin extends Base { protected $msg = "The '%s' plugin could not be found."; public function get( $name ) { - $plugins = get_plugins( '/' . $name ); - - // some-plugin/the-plugin.php - while ( !empty( $plugins ) ) { - $file = key( $plugins ); - array_shift( $plugins ); - - // ignore files inside a plugin's subdirectory (like WP does) - if ( dirname( $file ) == '.' ) { - return (object) array( - 'name' => $name, - 'file' => $name . '/' . $file - ); + foreach ( get_plugins() as $file => $_ ) { + if ( $file === "$name.php" || + ( dirname( $file ) === $name && $name !== '.' ) ) { + return (object) compact( 'name', 'file' ); } } - // some-plugin.php - $file = $name . '.php'; - - $plugins = get_plugins(); - - if ( isset( $plugins[ $file ] ) ) { - return (object) compact( 'name', 'file' ); - } - return false; } } From ab09a3d3adb5c6e23e3fb6830ebd5b5dd7e7c9f0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Feb 2014 00:45:07 +0200 Subject: [PATCH 2679/4858] switch to wp-cli/php-cli-tools:dev-master it contains https://github.com/wp-cli/php-cli-tools/commit/6079f27981a5dd91be6ff9f19643a7278dcdfbbb which fixes #947 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index aa1ed6271a..ab68a433cd 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.9.3", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From 6aeee0f26c0fa4dabb42cb2a76aacde9dc023af1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Feb 2014 01:16:29 +0200 Subject: [PATCH 2680/4858] bump version to 0.14.0-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 8f70c7353b..c9667d94bd 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,7 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.14.0-alpha2' ); +define( 'WP_CLI_VERSION', '0.14.0-beta' ); include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; From 6f2367be725fd3aab27276ac616f37a2834805a3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Feb 2014 15:18:59 +0200 Subject: [PATCH 2681/4858] fix deploy script log from Travis CI: error: Malformed value for push.default: simple error: Must be one of nothing, matching, tracking or current. --- ci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index a88cba3ba6..e3b17b39f0 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -28,7 +28,7 @@ cd builds git config user.name "Travis CI" git config user.email "travis@travis-ci.org" -git config push.default "simple" +git config push.default "current" mv $WP_CLI_BIN_DIR/wp phar/wp-cli-nightly.phar chmod -x phar/wp-cli-nightly.phar From b9be949426932aca1c1e9f07d8ddd3a2a8270031 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 3 Feb 2014 22:41:46 +0200 Subject: [PATCH 2682/4858] always set common HTTP headers; closes #989 --- php/class-wp-cli.php | 3 --- php/wp-cli.php | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 88db5d790e..b44d1efb04 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -108,9 +108,6 @@ private static function set_url_params( $url_parts ) { $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; $_SERVER['QUERY_STRING'] = $f('query'); - $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; - $_SERVER['HTTP_USER_AGENT'] = ''; - $_SERVER['REQUEST_METHOD'] = 'GET'; } /** diff --git a/php/wp-cli.php b/php/wp-cli.php index c9667d94bd..04277e0195 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,9 +2,14 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); - define( 'WP_CLI_VERSION', '0.14.0-beta' ); +// Set common headers, to prevent warnings from plugins +$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; +$_SERVER['HTTP_USER_AGENT'] = ''; +$_SERVER['REQUEST_METHOD'] = 'GET'; +$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + include WP_CLI_ROOT . '/php/utils.php'; include WP_CLI_ROOT . '/php/dispatcher.php'; include WP_CLI_ROOT . '/php/class-wp-cli.php'; From fbef65891cd7e6205d69cbcf7001294b89d7d948 Mon Sep 17 00:00:00 2001 From: Alexei Yuzhakov <ayuzhakov@parallels.com> Date: Wed, 5 Feb 2014 13:05:45 +0700 Subject: [PATCH 2683/4858] Ability to obtain titles and descriptions for plugins and themes using list command. --- php/commands/plugin.php | 2 ++ php/commands/theme.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 1d90b756e3..095325c335 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -316,6 +316,8 @@ protected function get_item_list() { 'update_package' => $update_info['package'], 'version' => $details['Version'], 'update_id' => $file, + 'title' => $details['Name'], + 'description' => $details['Description'], ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index 45df5cab79..c0d72003d9 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -312,6 +312,8 @@ protected function get_item_list() { 'update_package' => $update_info['package'], 'version' => $theme->get('Version'), 'update_id' => $theme->get_stylesheet(), + 'title' => $theme->get('Name'), + 'description' => $theme->get('Description'), ); if ( is_multisite() ) { From 8bdd907bc72d1875922e3b1359f499d7efb468ed Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Feb 2014 00:59:36 +0200 Subject: [PATCH 2684/4858] switch php-cli-tools to a tag --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ab68a433cd..19bceac58f 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "wp-cli-0.14.0", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From 56f55d720b657f52c3a00a3cf8c395f98f5182bd Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Feb 2014 01:06:34 +0200 Subject: [PATCH 2685/4858] switch php-cli-tools to 0.9.4-patch46 see #947 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 19bceac58f..0dbcad2cf3 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "wp-cli-0.14.0", + "wp-cli/php-cli-tools": "0.9.4-patch46", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From e9d700f3b5a407e23b79f67b06c0b7abd1eb39dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Feb 2014 02:00:31 +0200 Subject: [PATCH 2686/4858] map contributors for 0.14 release --- .mailmap | 7 +++++++ utils/contrib-list | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index eaec314b56..0086f71984 100644 --- a/.mailmap +++ b/.mailmap @@ -1,6 +1,8 @@ andreascreten <andreas@madewithlove.be> +bartaakos <akos@netpositive.hu> bendoh <ben@thinkoomph.com> BoiteAWeb <juliobosk@gmail.com> +boonebgorges <boonebgorges@gmail.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> conatus <alex@recordsonribs.com> @@ -20,6 +22,7 @@ future500 <ramon@future500.nl> getsource <mike.schroder@dreamhost.com> glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> +itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> jghazally <jeff@bigfish.co.uk> jghazally <jghazally@gmail.com> @@ -36,6 +39,7 @@ leewillis77 <leewillis77@gmail.com> marcoceppi <marco@ceppi.net> matiskay <matiskay@gmail.com> mattes <matthias.kadenbach@gmail.com> +mboynes <mboynes@alleyinteractive.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> milesj <mileswjohnson@gmail.com> @@ -59,8 +63,10 @@ roelven <roel@soundcloud.com> ryanduff <ryan@fusionized.com> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> +sibprogrammer <ayuzhakov@parallels.com> simonwheatley <simonw@codeforthepeople.com> soulou <leo@soulou.fr> +SpikesDivZero <wesley.spikes@gmail.com> spuriousdata <spuriousdata@gmail.com> stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> @@ -78,3 +84,4 @@ twratajczak <tomasz.ratajczak@espeo.pl> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> wopr42 <john@zippykid.com> +ziz <justin@crowdfavorite.com> diff --git a/utils/contrib-list b/utils/contrib-list index 6d0e0897e9..f3c887b841 100755 --- a/utils/contrib-list +++ b/utils/contrib-list @@ -1,7 +1,7 @@ #!/usr/bin/env bash if [ $# -lt 1 ]; then - echo "usage: $(basename $0) v0.8.0..v0.9.0 [-l]" + echo "usage: $(basename $0) v0.8.0..master [-l]" exit 1 fi From 7926fba978ae901758a7794ff0352197e2624647 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Feb 2014 02:02:26 +0200 Subject: [PATCH 2687/4858] bump version to 0.14.0 --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 04277e0195..8b35616ce4 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.14.0-beta' ); +define( 'WP_CLI_VERSION', '0.14.0' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 75656a4740d5093356a8c5d4d28933de6ab3940c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Feb 2014 18:39:39 +0200 Subject: [PATCH 2688/4858] pass allow-root along in launch_self() fixes #997 --- php/class-wp-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index b44d1efb04..e5900ce0b8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -341,6 +341,7 @@ static function launch_self( $command, $args = array(), $assoc_args = array(), $ 'path', 'url', 'user', + 'allow-root', ); foreach ( $reused_runtime_args as $key ) { From 6b90c20266906632199ea819c0adff780fba331d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 6 Feb 2014 18:40:23 +0200 Subject: [PATCH 2689/4858] bump version to 0.14.1-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 8b35616ce4..e9976b54ee 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.14.0' ); +define( 'WP_CLI_VERSION', '0.14.1-alpha' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 6857028f237537c95509e89f00ae433cb842efb4 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 7 Feb 2014 12:30:43 -0800 Subject: [PATCH 2690/4858] Add `wp role reset` - resets any given default role to default capabilities --- php/commands/role.php | 172 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/php/commands/role.php b/php/commands/role.php index 896bc0f48f..cd08a98920 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -139,6 +139,178 @@ public function delete( $args ) { } + /** + * Reset any default role to default capabilities. + * + * ## OPTIONS + * + * <role-key> + * : The internal name of the role. + * + * ## EXAMPLES + * + * wp role reset administrator + * + * wp role reset author + */ + public function reset( $args ) { + + self::persistence_check(); + + $role_key = array_shift( $args ); + + if ( empty( $role_key ) || ! in_array($role_key, array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ) ) ) + WP_CLI::error( "Role key not provided, or is invalid." ); + + if ( $role_key == 'administrator') { + remove_role( $role_key ); + add_role('administrator', 'Administrator'); + $role = get_role('administrator'); + $role->add_cap('switch_themes'); + $role->add_cap('edit_themes'); + $role->add_cap('activate_plugins'); + $role->add_cap('edit_plugins'); + $role->add_cap('edit_users'); + $role->add_cap('edit_files'); + $role->add_cap('manage_options'); + $role->add_cap('moderate_comments'); + $role->add_cap('manage_categories'); + $role->add_cap('manage_links'); + $role->add_cap('upload_files'); + $role->add_cap('import'); + $role->add_cap('unfiltered_html'); + $role->add_cap('edit_posts'); + $role->add_cap('edit_others_posts'); + $role->add_cap('edit_published_posts'); + $role->add_cap('publish_posts'); + $role->add_cap('edit_pages'); + $role->add_cap('read'); + $role->add_cap('level_10'); + $role->add_cap('level_9'); + $role->add_cap('level_8'); + $role->add_cap('level_7'); + $role->add_cap('level_6'); + $role->add_cap('level_5'); + $role->add_cap('level_4'); + $role->add_cap('level_3'); + $role->add_cap('level_2'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + $role->add_cap('edit_others_pages'); + $role->add_cap('edit_published_pages'); + $role->add_cap('publish_pages'); + $role->add_cap('delete_pages'); + $role->add_cap('delete_others_pages'); + $role->add_cap('delete_published_pages'); + $role->add_cap('delete_posts'); + $role->add_cap('delete_others_posts'); + $role->add_cap('delete_published_posts'); + $role->add_cap('delete_private_posts'); + $role->add_cap('edit_private_posts'); + $role->add_cap('read_private_posts'); + $role->add_cap('delete_private_pages'); + $role->add_cap('edit_private_pages'); + $role->add_cap('read_private_pages'); + $role->add_cap('delete_users'); + $role->add_cap('create_users'); + $role->add_cap( 'unfiltered_upload' ); + $role->add_cap( 'edit_dashboard' ); + $role->add_cap( 'update_plugins' ); + $role->add_cap( 'delete_plugins' ); + $role->add_cap( 'install_plugins' ); + $role->add_cap( 'update_themes' ); + $role->add_cap( 'install_themes' ); + $role->add_cap( 'update_core' ); + $role->add_cap( 'list_users' ); + $role->add_cap( 'remove_users' ); + + // Never used, will be removed. create_users or + // promote_users is the capability you're looking for. + $role->add_cap( 'add_users' ); + + $role->add_cap( 'promote_users' ); + $role->add_cap( 'edit_theme_options' ); + $role->add_cap( 'delete_themes' ); + $role->add_cap( 'export' ); + + } + if ( 'editor' == $role_key ) { + remove_role( $role_key ); + add_role('editor', 'Editor'); + $role = get_role('editor'); + $role->add_cap('moderate_comments'); + $role->add_cap('manage_categories'); + $role->add_cap('manage_links'); + $role->add_cap('upload_files'); + $role->add_cap('unfiltered_html'); + $role->add_cap('edit_posts'); + $role->add_cap('edit_others_posts'); + $role->add_cap('edit_published_posts'); + $role->add_cap('publish_posts'); + $role->add_cap('edit_pages'); + $role->add_cap('read'); + $role->add_cap('level_7'); + $role->add_cap('level_6'); + $role->add_cap('level_5'); + $role->add_cap('level_4'); + $role->add_cap('level_3'); + $role->add_cap('level_2'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + $role->add_cap('edit_others_pages'); + $role->add_cap('edit_published_pages'); + $role->add_cap('publish_pages'); + $role->add_cap('delete_pages'); + $role->add_cap('delete_others_pages'); + $role->add_cap('delete_published_pages'); + $role->add_cap('delete_posts'); + $role->add_cap('delete_others_posts'); + $role->add_cap('delete_published_posts'); + $role->add_cap('delete_private_posts'); + $role->add_cap('edit_private_posts'); + $role->add_cap('read_private_posts'); + $role->add_cap('delete_private_pages'); + $role->add_cap('edit_private_pages'); + $role->add_cap('read_private_pages'); + + } + if ( 'author' == $role_key ) { + remove_role( $role_key ); + add_role('author', 'Author'); + $role = get_role('author'); + $role->add_cap('upload_files'); + $role->add_cap('edit_posts'); + $role->add_cap('edit_published_posts'); + $role->add_cap('publish_posts'); + $role->add_cap('read'); + $role->add_cap('level_2'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + $role->add_cap('delete_posts'); + $role->add_cap('delete_published_posts'); + } + if ( 'contributor' == $role_key ) { + remove_role( $role_key ); + add_role('contributor', 'Contributor'); + $role = get_role('contributor'); + $role->add_cap('edit_posts'); + $role->add_cap('read'); + $role->add_cap('level_1'); + $role->add_cap('level_0'); + $role->add_cap('delete_posts'); + } + if ( 'subscriber' == $role_key ) { + remove_role( $role_key ); + add_role('subscriber', 'Subscriber'); + $role = get_role('subscriber'); + $role->add_cap('read'); + $role->add_cap('level_0'); + } + + WP_CLI::success( sprintf( "Role with key %s reset.", $role_key ) ); + + } + private static function persistence_check() { global $wp_roles; From 3c086188abbfbeb79d175b763a8e236dc163b756 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 7 Feb 2014 15:33:56 -0800 Subject: [PATCH 2691/4858] formatting cleanup --- php/commands/role.php | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index cd08a98920..df7f6a0c5a 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -213,25 +213,23 @@ public function reset( $args ) { $role->add_cap('read_private_pages'); $role->add_cap('delete_users'); $role->add_cap('create_users'); - $role->add_cap( 'unfiltered_upload' ); - $role->add_cap( 'edit_dashboard' ); - $role->add_cap( 'update_plugins' ); - $role->add_cap( 'delete_plugins' ); - $role->add_cap( 'install_plugins' ); - $role->add_cap( 'update_themes' ); - $role->add_cap( 'install_themes' ); - $role->add_cap( 'update_core' ); - $role->add_cap( 'list_users' ); - $role->add_cap( 'remove_users' ); - - // Never used, will be removed. create_users or - // promote_users is the capability you're looking for. - $role->add_cap( 'add_users' ); - + $role->add_cap('unfiltered_upload'); + $role->add_cap('edit_dashboard'); + $role->add_cap('update_plugins'); + $role->add_cap('delete_plugins'); + $role->add_cap('install_plugins'); + $role->add_cap('update_themes'); + $role->add_cap('install_themes'); + $role->add_cap('update_core'); + $role->add_cap('list_users'); + $role->add_cap('remove_users'); $role->add_cap( 'promote_users' ); $role->add_cap( 'edit_theme_options' ); $role->add_cap( 'delete_themes' ); $role->add_cap( 'export' ); + // Never used, will be removed. create_users or + // promote_users is the capability you're looking for. + $role->add_cap( 'add_users' ); } if ( 'editor' == $role_key ) { From b62050002f7252143f695859291de80dae91ef15 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 7 Feb 2014 16:19:35 -0800 Subject: [PATCH 2692/4858] switch instead of ifs --- php/commands/role.php | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index df7f6a0c5a..6e47adc2be 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -154,15 +154,17 @@ public function delete( $args ) { * wp role reset author */ public function reset( $args ) { + global $wp_roles; self::persistence_check(); $role_key = array_shift( $args ); - if ( empty( $role_key ) || ! in_array($role_key, array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ) ) ) + if ( empty( $role_key ) ) WP_CLI::error( "Role key not provided, or is invalid." ); - if ( $role_key == 'administrator') { + switch ( $role_key ) { + case 'administrator': remove_role( $role_key ); add_role('administrator', 'Administrator'); $role = get_role('administrator'); @@ -230,9 +232,9 @@ public function reset( $args ) { // Never used, will be removed. create_users or // promote_users is the capability you're looking for. $role->add_cap( 'add_users' ); + break; - } - if ( 'editor' == $role_key ) { + case 'editor': remove_role( $role_key ); add_role('editor', 'Editor'); $role = get_role('editor'); @@ -270,9 +272,9 @@ public function reset( $args ) { $role->add_cap('delete_private_pages'); $role->add_cap('edit_private_pages'); $role->add_cap('read_private_pages'); + break; - } - if ( 'author' == $role_key ) { + case 'author': remove_role( $role_key ); add_role('author', 'Author'); $role = get_role('author'); @@ -286,8 +288,9 @@ public function reset( $args ) { $role->add_cap('level_0'); $role->add_cap('delete_posts'); $role->add_cap('delete_published_posts'); - } - if ( 'contributor' == $role_key ) { + break; + + case 'contributor': remove_role( $role_key ); add_role('contributor', 'Contributor'); $role = get_role('contributor'); @@ -296,13 +299,19 @@ public function reset( $args ) { $role->add_cap('level_1'); $role->add_cap('level_0'); $role->add_cap('delete_posts'); - } - if ( 'subscriber' == $role_key ) { + break; + + case 'subscriber': remove_role( $role_key ); add_role('subscriber', 'Subscriber'); $role = get_role('subscriber'); $role->add_cap('read'); $role->add_cap('level_0'); + break; + + default: + WP_CLI::error( 'Must specify a default role to reset.' ); + } WP_CLI::success( sprintf( "Role with key %s reset.", $role_key ) ); From 380165285c2d26b843bbc242a14e640d6fbaa648 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 7 Feb 2014 16:22:30 -0800 Subject: [PATCH 2693/4858] global not needed in command --- php/commands/role.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index 6e47adc2be..78f9649f13 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -154,7 +154,6 @@ public function delete( $args ) { * wp role reset author */ public function reset( $args ) { - global $wp_roles; self::persistence_check(); From c5bdf2d9be85b3cab32202c05e53b31c28c5194d Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 7 Feb 2014 18:21:56 -0800 Subject: [PATCH 2694/4858] Reset without hard-coded list of caps. Add reset all option --- php/commands/role.php | 200 +++++++++++------------------------------- 1 file changed, 53 insertions(+), 147 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 78f9649f13..7732612edb 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -162,155 +162,61 @@ public function reset( $args ) { if ( empty( $role_key ) ) WP_CLI::error( "Role key not provided, or is invalid." ); - switch ( $role_key ) { - case 'administrator': - remove_role( $role_key ); - add_role('administrator', 'Administrator'); - $role = get_role('administrator'); - $role->add_cap('switch_themes'); - $role->add_cap('edit_themes'); - $role->add_cap('activate_plugins'); - $role->add_cap('edit_plugins'); - $role->add_cap('edit_users'); - $role->add_cap('edit_files'); - $role->add_cap('manage_options'); - $role->add_cap('moderate_comments'); - $role->add_cap('manage_categories'); - $role->add_cap('manage_links'); - $role->add_cap('upload_files'); - $role->add_cap('import'); - $role->add_cap('unfiltered_html'); - $role->add_cap('edit_posts'); - $role->add_cap('edit_others_posts'); - $role->add_cap('edit_published_posts'); - $role->add_cap('publish_posts'); - $role->add_cap('edit_pages'); - $role->add_cap('read'); - $role->add_cap('level_10'); - $role->add_cap('level_9'); - $role->add_cap('level_8'); - $role->add_cap('level_7'); - $role->add_cap('level_6'); - $role->add_cap('level_5'); - $role->add_cap('level_4'); - $role->add_cap('level_3'); - $role->add_cap('level_2'); - $role->add_cap('level_1'); - $role->add_cap('level_0'); - $role->add_cap('edit_others_pages'); - $role->add_cap('edit_published_pages'); - $role->add_cap('publish_pages'); - $role->add_cap('delete_pages'); - $role->add_cap('delete_others_pages'); - $role->add_cap('delete_published_pages'); - $role->add_cap('delete_posts'); - $role->add_cap('delete_others_posts'); - $role->add_cap('delete_published_posts'); - $role->add_cap('delete_private_posts'); - $role->add_cap('edit_private_posts'); - $role->add_cap('read_private_posts'); - $role->add_cap('delete_private_pages'); - $role->add_cap('edit_private_pages'); - $role->add_cap('read_private_pages'); - $role->add_cap('delete_users'); - $role->add_cap('create_users'); - $role->add_cap('unfiltered_upload'); - $role->add_cap('edit_dashboard'); - $role->add_cap('update_plugins'); - $role->add_cap('delete_plugins'); - $role->add_cap('install_plugins'); - $role->add_cap('update_themes'); - $role->add_cap('install_themes'); - $role->add_cap('update_core'); - $role->add_cap('list_users'); - $role->add_cap('remove_users'); - $role->add_cap( 'promote_users' ); - $role->add_cap( 'edit_theme_options' ); - $role->add_cap( 'delete_themes' ); - $role->add_cap( 'export' ); - // Never used, will be removed. create_users or - // promote_users is the capability you're looking for. - $role->add_cap( 'add_users' ); - break; - - case 'editor': - remove_role( $role_key ); - add_role('editor', 'Editor'); - $role = get_role('editor'); - $role->add_cap('moderate_comments'); - $role->add_cap('manage_categories'); - $role->add_cap('manage_links'); - $role->add_cap('upload_files'); - $role->add_cap('unfiltered_html'); - $role->add_cap('edit_posts'); - $role->add_cap('edit_others_posts'); - $role->add_cap('edit_published_posts'); - $role->add_cap('publish_posts'); - $role->add_cap('edit_pages'); - $role->add_cap('read'); - $role->add_cap('level_7'); - $role->add_cap('level_6'); - $role->add_cap('level_5'); - $role->add_cap('level_4'); - $role->add_cap('level_3'); - $role->add_cap('level_2'); - $role->add_cap('level_1'); - $role->add_cap('level_0'); - $role->add_cap('edit_others_pages'); - $role->add_cap('edit_published_pages'); - $role->add_cap('publish_pages'); - $role->add_cap('delete_pages'); - $role->add_cap('delete_others_pages'); - $role->add_cap('delete_published_pages'); - $role->add_cap('delete_posts'); - $role->add_cap('delete_others_posts'); - $role->add_cap('delete_published_posts'); - $role->add_cap('delete_private_posts'); - $role->add_cap('edit_private_posts'); - $role->add_cap('read_private_posts'); - $role->add_cap('delete_private_pages'); - $role->add_cap('edit_private_pages'); - $role->add_cap('read_private_pages'); - break; - - case 'author': - remove_role( $role_key ); - add_role('author', 'Author'); - $role = get_role('author'); - $role->add_cap('upload_files'); - $role->add_cap('edit_posts'); - $role->add_cap('edit_published_posts'); - $role->add_cap('publish_posts'); - $role->add_cap('read'); - $role->add_cap('level_2'); - $role->add_cap('level_1'); - $role->add_cap('level_0'); - $role->add_cap('delete_posts'); - $role->add_cap('delete_published_posts'); - break; - - case 'contributor': - remove_role( $role_key ); - add_role('contributor', 'Contributor'); - $role = get_role('contributor'); - $role->add_cap('edit_posts'); - $role->add_cap('read'); - $role->add_cap('level_1'); - $role->add_cap('level_0'); - $role->add_cap('delete_posts'); - break; - - case 'subscriber': - remove_role( $role_key ); - add_role('subscriber', 'Subscriber'); - $role = get_role('subscriber'); - $role->add_cap('read'); - $role->add_cap('level_0'); - break; - - default: + // WP_CLI::error( ABSPATH.'wp-admin/includes/schema.php' ); + if ( ! function_exists( 'populate_roles' ) ) { + require_once( ABSPATH.'wp-admin/includes/schema.php' ); + } + + // get our default roles + $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); + + if ( 'all' == $role_key ) { + foreach( $preserve as $role ) { + remove_role( $role ); + } + populate_roles(); + + WP_CLI::success( sprintf( "All default roles reset.", $role_key ) ); + return; + + } + + // if key not found, bail + $key = array_search( $role_key, $preserve ); + if ( false === $key ) { WP_CLI::error( 'Must specify a default role to reset.' ); + } + + // remove the one to reset + unset( $preserve[ $key ] ); + + // for the roles we're not resetting + foreach( $preserve as $k => $role ) { + /* save roles + * if get_role is null + * save role name for re-removal + */ + $roleobj = get_role( $role ); + $preserve[$k] = is_null( $roleobj ) ? $role : $roleobj; + + remove_role( $role ); + } + + remove_role( $role_key ); + // put back all default roles and capabilities + populate_roles(); + + // restore the preserved roles + foreach( $preserve as $k => $roleobj ) { + // re-remove after populating + if ( is_a( $roleobj, 'WP_Role' ) ) { + remove_role( $roleobj->name ); + add_role( $roleobj->name, ucwords( $roleobj->name ), $roleobj->capabilities ); + } else { + // when not an object, that means the role didn't exist before + remove_role( $roleobj ); + } } WP_CLI::success( sprintf( "Role with key %s reset.", $role_key ) ); From 37bd3ab58f14215c7de0b9f0bfdac31948bf8ddc Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 7 Feb 2014 18:30:16 -0800 Subject: [PATCH 2695/4858] remove commented debug line and unnecessary sprintf --- php/commands/role.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 7732612edb..02ce4873b3 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -162,7 +162,6 @@ public function reset( $args ) { if ( empty( $role_key ) ) WP_CLI::error( "Role key not provided, or is invalid." ); - // WP_CLI::error( ABSPATH.'wp-admin/includes/schema.php' ); if ( ! function_exists( 'populate_roles' ) ) { require_once( ABSPATH.'wp-admin/includes/schema.php' ); } @@ -176,7 +175,7 @@ public function reset( $args ) { } populate_roles(); - WP_CLI::success( sprintf( "All default roles reset.", $role_key ) ); + WP_CLI::success( 'All default roles reset.' ); return; } From 5cfa8f82d14611ee5333210724d053b77e9a7e13 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Sat, 8 Feb 2014 20:20:39 -0800 Subject: [PATCH 2696/4858] reset multiple roles at once change `wp role reset all` to `wp role reset --all` compare before/after roles to determine success --- php/commands/role.php | 57 ++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 02ce4873b3..f11d99f501 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -144,22 +144,23 @@ public function delete( $args ) { * * ## OPTIONS * - * <role-key> - * : The internal name of the role. + * [<role-key>...] + * : The internal name of one or more roles to reset. + * + * [--all] + * : If set, all default roles will be reset. * * ## EXAMPLES * - * wp role reset administrator + * wp role reset administrator author contributor * - * wp role reset author + * wp role reset --all */ - public function reset( $args ) { + public function reset( $args, $assoc_args ) { self::persistence_check(); - $role_key = array_shift( $args ); - - if ( empty( $role_key ) ) + if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) WP_CLI::error( "Role key not provided, or is invalid." ); if ( ! function_exists( 'populate_roles' ) ) { @@ -167,10 +168,10 @@ public function reset( $args ) { } // get our default roles - $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); + $default_roles = $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); - if ( 'all' == $role_key ) { - foreach( $preserve as $role ) { + if ( isset( $assoc_args['all'] ) ) { + foreach( $default_roles as $role ) { remove_role( $role ); } populate_roles(); @@ -180,14 +181,23 @@ public function reset( $args ) { } - // if key not found, bail - $key = array_search( $role_key, $preserve ); - if ( false === $key ) { - WP_CLI::error( 'Must specify a default role to reset.' ); + foreach( $args as $k => $role_key ) { + $key = array_search( $role_key, $default_roles ); + if ( false !== $key ) { + unset( $preserve[ $key ] ); + $before[ $role_key ] = get_role( $role_key ); + remove_role( $role_key ); + } else { + unset( $args[ $k ] ); + } } - // remove the one to reset - unset( $preserve[ $key ] ); + $num_to_reset = count( $args ); + + // no roles were unset, bail + if ( count( $default_roles ) == count( $preserve ) ) { + WP_CLI::error( 'Must specify a default role to reset.' ); + } // for the roles we're not resetting foreach( $preserve as $k => $role ) { @@ -201,8 +211,6 @@ public function reset( $args ) { remove_role( $role ); } - remove_role( $role_key ); - // put back all default roles and capabilities populate_roles(); @@ -218,7 +226,16 @@ public function reset( $args ) { } } - WP_CLI::success( sprintf( "Role with key %s reset.", $role_key ) ); + $num_reset = 0; + foreach( $args as $role_key ) { + $after[ $role_key ] = get_role( $role_key ); + + if ( $after[ $role_key ] != $before[ $role_key ] ) { + ++$num_reset; + } + } + + WP_CLI::success( "Reset $num_reset/$num_to_reset roles" ); } From 17860a741218d6230720d43cafa1c32f6a8a5ed2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 15:28:53 +0200 Subject: [PATCH 2697/4858] wp user create: validate fields before calling wp_insert_user() see #358 --- php/commands/user.php | 49 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 0ac77e767c..46c6b6d8f7 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -179,34 +179,38 @@ public function delete( $args, $assoc_args ) { * wp user create bob bob@example.com --role=author */ public function create( $args, $assoc_args ) { - list( $user_login, $user_email ) = $args; + $user = new stdClass; - $defaults = array( - 'role' => get_option('default_role'), - 'user_pass' => false, - 'user_registered' => strftime( "%F %T", time() ), - 'display_name' => false, - ); - extract( array_merge( $defaults, $assoc_args ), EXTR_SKIP ); + list( $user->user_login, $user->user_email ) = $args; - if ( !self::validate_role( $role ) ) { - WP_CLI::error( "Invalid role: $role" ); + if ( username_exists( $user->user_login ) ) { + WP_CLI::error( "The '{$user->user_login}' username is already registered." ); } - // @codingStandardsIgnoreStart - if ( !$user_pass ) { - $user_pass = wp_generate_password(); - $generated_pass = true; + if ( !is_email( $user->user_email ) ) { + WP_CLI::error( "The '{$user->user_email}' email address is invalid." ); } - $user_id = wp_insert_user( array( - 'user_email' => $user_email, - 'user_login' => $user_login, - 'user_pass' => $user_pass, - 'user_registered' => $user_registered, - 'display_name' => $display_name, - 'role' => $role, - ) ); + $user->user_registered = isset( $assoc_args['user_registered'] ) + ? $assoc_args['user_registered'] : strftime( "%F %T", current_time('timestamp') ); + + $user->display_name = isset( $assoc_args['display_name'] ) + ? $assoc_args['display_name'] : false; + + $user->user_pass = isset( $assoc_args['user_pass'] ) + ? $assoc_args['user_pass'] : wp_generate_password(); + + if ( isset( $assoc_args['role'] ) ) { + $role = $assoc_args['role']; + if ( !self::validate_role( $role ) ) { + WP_CLI::error( "Invalid role: $role" ); + } + } else { + $role = get_option('default_role'); + } + $user->role = $role; + + $user_id = wp_insert_user( $user ); if ( is_wp_error( $user_id ) ) { WP_CLI::error( $user_id ); @@ -224,7 +228,6 @@ public function create( $args, $assoc_args ) { if ( isset( $generated_pass ) ) WP_CLI::line( "Password: $user_pass" ); } - // @codingStandardsIgnoreEnd } /** From 79f2f06f6d688d7907ee2e75eb15e2e16d797f95 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 15:40:45 +0200 Subject: [PATCH 2698/4858] wp core install: validate admin email closes #358 --- php/commands/core.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 37a7453af8..7390abf09f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -459,6 +459,10 @@ private function _install( $assoc_args ) { $public = true; // @codingStandardsIgnoreStart + if ( !is_email( $admin_email ) ) { + WP_CLI::error( "The '{$admin_email}' email address is invalid." ); + } + $result = wp_install( $title, $admin_user, $admin_email, $public, '', $admin_password ); if ( is_wp_error( $result ) ) { From c1c28aaac34a480df0ab7d68598044798d03b78f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 16:13:26 +0200 Subject: [PATCH 2699/4858] bump minimum required WP version to 3.5.2 --- .travis.yml | 4 ++-- php/WP_CLI/Runner.php | 2 +- php/commands/core.php | 2 +- php/commands/user.php | 10 ++-------- php/wp-settings-cli.php | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4bff5686fb..508251d011 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,12 @@ env: - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - WP_VERSION=latest - - WP_VERSION=3.4.2 DEPLOY_BRANCH=master + - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: exclude: - php: 5.5 - env: WP_VERSION=3.4.2 DEPLOY_BRANCH=master + env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master before_script: ./ci/prepare.sh diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c701d2646d..c8ffc2452f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -386,7 +386,7 @@ private function check_wp_version() { include ABSPATH . 'wp-includes/version.php'; - $minimum_version = '3.4'; + $minimum_version = '3.5.2'; // @codingStandardsIgnoreStart if ( version_compare( $wp_version, $minimum_version, '<' ) ) { diff --git a/php/commands/core.php b/php/commands/core.php index 7390abf09f..8e0eee05b9 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -656,7 +656,7 @@ public function version( $args = array(), $assoc_args = array() ) { * * wp core update * - * wp core update --version=3.4 ../latest.zip + * wp core update --version=3.8 ../latest.zip * * wp core update --version=3.1 --force * diff --git a/php/commands/user.php b/php/commands/user.php index 46c6b6d8f7..0267309dea 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -96,13 +96,7 @@ public function list_( $args, $assoc_args ) { */ public function get( $args, $assoc_args ) { $user = $this->fetcher->get_check( $args[0] ); - - if ( method_exists( $user, 'to_array' ) ) { - $user_data = $user->to_array(); - } else { - // WP 3.4 compat - $user_data = (array) $user->data; - } + $user_data = $user->to_array(); $user_data['roles'] = implode( ', ', $user->roles ); $formatter = $this->get_formatter( $assoc_args ); @@ -566,7 +560,7 @@ public function import_csv( $args, $assoc_args ) { // Create the user } else { - unset( $new_user['ID'] ); // Unset else it will just return the ID + unset( $new_user['ID'] ); // Unset else it will just return the ID $user_id = wp_insert_user( $new_user ); } diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 735e54f75d..8223901c01 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -124,8 +124,8 @@ require( ABSPATH . WPINC . '/query.php' ); Utils\maybe_require( '3.7-alpha-25139', ABSPATH . WPINC . '/date.php' ); require( ABSPATH . WPINC . '/theme.php' ); -Utils\maybe_require( '3.4', ABSPATH . WPINC . '/class-wp-theme.php' ); -Utils\maybe_require( '3.4', ABSPATH . WPINC . '/template.php' ); +require( ABSPATH . WPINC . '/class-wp-theme.php' ); +require( ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); require( ABSPATH . WPINC . '/meta.php' ); require( ABSPATH . WPINC . '/general-template.php' ); From ece9ef48b5fbd1d91ea49c0e30f1a5b5c0ebc5aa Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 17:35:40 +0200 Subject: [PATCH 2700/4858] wp media regenerate: check if there is platform support for generating images before starting --- php/commands/media.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 5f57f5d9a2..c10f25b61d 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -27,7 +27,10 @@ class Media_Command extends WP_CLI_Command { * seq 1000 2000 | xargs wp media regenerate */ function regenerate( $args, $assoc_args = array() ) { - global $wpdb; + if ( !wp_image_editor_supports() ) { + WP_CLI::error( 'No support for generating images found. ' . + 'Please install the Imagick or GD PHP extensions.' ); + } if ( empty( $args ) ) { WP_CLI::confirm( 'Do you realy want to regenerate all images?', $assoc_args ); From c9724c546fcb6380c146657a0872ec583e52dba5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 17:42:26 +0200 Subject: [PATCH 2701/4858] check for platform support before calling 'wp media import' too --- php/commands/media.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index c10f25b61d..254942f4f3 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -27,11 +27,6 @@ class Media_Command extends WP_CLI_Command { * seq 1000 2000 | xargs wp media regenerate */ function regenerate( $args, $assoc_args = array() ) { - if ( !wp_image_editor_supports() ) { - WP_CLI::error( 'No support for generating images found. ' . - 'Please install the Imagick or GD PHP extensions.' ); - } - if ( empty( $args ) ) { WP_CLI::confirm( 'Do you realy want to regenerate all images?', $assoc_args ); } @@ -246,5 +241,12 @@ private function remove_old_images( $att_id ) { } } -WP_CLI::add_command( 'media', 'Media_Command' ); +WP_CLI::add_command( 'media', 'Media_Command', array( + 'before_invoke' => function () { + if ( !wp_image_editor_supports() ) { + WP_CLI::error( 'No support for generating images found. ' . + 'Please install the Imagick or GD PHP extensions.' ); + } + } +) ); From a298be35273bc44beb17f78492343f82393403fe Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 22:19:56 +0200 Subject: [PATCH 2702/4858] support arbitrary command nesting --- php/WP_CLI/Dispatcher/CompositeCommand.php | 18 +++++++++++--- php/WP_CLI/Dispatcher/Subcommand.php | 8 +++++-- php/class-wp-cli.php | 28 ++++++++++++++++++---- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index e5af824155..45217ed3ca 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -59,8 +59,12 @@ function get_synopsis() { return '<command>'; } - function invoke( $args, $assoc_args, $extra_args ) { - $this->show_usage(); + function get_usage( $prefix ) { + return sprintf( "%s%s %s", + $prefix, + implode( ' ', get_path( $this ) ), + $this->get_synopsis() + ); } function show_usage() { @@ -71,13 +75,17 @@ function show_usage() { foreach ( $methods as $name => $subcommand ) { $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; - $subcommand->show_usage( $prefix ); + \WP_CLI::line( $subcommand->get_usage( $prefix ) ); } \WP_CLI::line(); \WP_CLI::line( "See 'wp help $this->name <command>' for more information on a specific command." ); } + function invoke( $args, $assoc_args, $extra_args ) { + $this->show_usage(); + } + function find_subcommand( &$args ) { $name = array_shift( $args ); @@ -108,5 +116,9 @@ private static function get_aliases( $subcommands ) { return $aliases; } + + function get_alias() { + return false; + } } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 89402b7b25..1eebdea4be 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -38,11 +38,15 @@ function get_alias() { } function show_usage( $prefix = 'usage: ' ) { - \WP_CLI::line( sprintf( "%s%s %s", + \WP_CLI::line( $this->get_usage( $prefix ) ); + } + + function get_usage( $prefix ) { + return sprintf( "%s%s %s", $prefix, implode( ' ', get_path( $this ) ), $this->get_synopsis() - ) ); + ); } private function prompt( $question, $default ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e5900ce0b8..ad2ddf79eb 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -152,19 +152,39 @@ static function do_hook( $when ) { /** * Add a command to the wp-cli list of commands * - * @param string $name The name of the command that will be used in the cli + * @param string $name The name of the command that will be used in the CLI * @param string $class The command implementation * @param array $args An associative array with additional parameters: * 'before_invoke' => callback to execute before invoking the command */ static function add_command( $name, $class, $args = array() ) { - $command = Dispatcher\CommandFactory::create( $name, $class, self::get_root_command() ); - if ( isset( $args['before_invoke'] ) ) { self::add_hook( "before_invoke:$name", $args['before_invoke'] ); } - self::get_root_command()->add_subcommand( $name, $command ); + $path = preg_split( '/\s+/', $name ); + + $leaf_name = array_pop( $path ); + + $command = self::get_root_command(); + + while ( !empty( $path ) ) { + $subcommand_name = $path[0]; + $subcommand = $command->find_subcommand( $path ); + + // create an empty container + if ( !$subcommand ) { + $subcommand = new Dispatcher\CompositeCommand( $command, $subcommand_name, + new \WP_CLI\DocParser( '' ) ); + $command->add_subcommand( $subcommand_name, $subcommand ); + } + + $command = $subcommand; + } + + $leaf_command = Dispatcher\CommandFactory::create( $leaf_name, $class, $command ); + + $command->add_subcommand( $leaf_name, $leaf_command ); } /** From 776388eab6d0433e85706c68f016b252cb31dc21 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Feb 2014 23:40:58 +0200 Subject: [PATCH 2703/4858] prevent registering subcommands for concrete commands --- php/WP_CLI/Dispatcher/CompositeCommand.php | 4 ++-- php/WP_CLI/Dispatcher/RootCommand.php | 5 ----- php/WP_CLI/Dispatcher/Subcommand.php | 4 ++++ php/WP_CLI/Runner.php | 4 ++-- php/class-wp-cli.php | 6 ++++++ php/commands/help.php | 4 ++-- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 45217ed3ca..2edb23687b 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -33,8 +33,8 @@ function add_subcommand( $name, $command ) { $this->subcommands[ $name ] = $command; } - function has_subcommands() { - return !empty( $this->subcommands ); + function can_have_subcommands() { + return true; } function get_subcommands() { diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index d11a9a2151..853cfa1976 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -61,10 +61,5 @@ function get_subcommands() { return parent::get_subcommands(); } - - function has_subcommands() { - // Commands are lazy-loaded, so we need to assume there will be some - return true; - } } diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 1eebdea4be..c8d1acc18d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -29,6 +29,10 @@ private static function extract_synopsis( $longdesc ) { return implode( ' ', $matches[1] ); } + function can_have_subcommands() { + return false; + } + function get_synopsis() { return $this->synopsis; } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c8ffc2452f..4e9811fff2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -199,7 +199,7 @@ private function find_command_to_run( $args ) { $disabled_commands = $this->config['disabled_commands']; - while ( !empty( $args ) && $command->has_subcommands() ) { + while ( !empty( $args ) && $command->can_have_subcommands() ) { $cmd_path[] = $args[0]; $full_name = implode( ' ', $cmd_path ); @@ -477,7 +477,7 @@ public function before_wp_load() { if ( is_array( $r ) ) { list( $command ) = $r; - if ( $command->has_subcommands() ) { + if ( $command->can_have_subcommands() ) { $command->show_usage(); exit; } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ad2ddf79eb..ca650fc2c0 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -165,6 +165,7 @@ static function add_command( $name, $class, $args = array() ) { $path = preg_split( '/\s+/', $name ); $leaf_name = array_pop( $path ); + $full_path = $path; $command = self::get_root_command(); @@ -184,6 +185,11 @@ static function add_command( $name, $class, $args = array() ) { $leaf_command = Dispatcher\CommandFactory::create( $leaf_name, $class, $command ); + if ( ! $command->can_have_subcommands() ) { + throw new Exception( sprintf( "'%s' can't have subcommands.", + implode( ' ' , Dispatcher\get_path( $command ) ) ) ); + } + $command->add_subcommand( $leaf_name, $leaf_command ); } diff --git a/php/commands/help.php b/php/commands/help.php index a3f42d3a03..b9abfcc0c3 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -35,7 +35,7 @@ function __invoke( $args, $assoc_args ) { private static function find_subcommand( $args ) { $command = \WP_CLI::get_root_command(); - while ( !empty( $args ) && $command && $command->has_subcommands() ) { + while ( !empty( $args ) && $command && $command->can_have_subcommands() ) { $command = $command->find_subcommand( $args ); } @@ -106,7 +106,7 @@ private static function get_initial_markdown( $command ) { $binding['synopsis'] = wordwrap( "$name " . $command->get_synopsis(), 79 ); - if ( $command->has_subcommands() ) { + if ( $command->can_have_subcommands() ) { $binding['has-subcommands']['subcommands'] = self::render_subcommands( $command ); } From ac4437a68359ee67234769860c2ff6fdd704f5bf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Feb 2014 02:34:29 +0200 Subject: [PATCH 2704/4858] generate bash completions unambiguously for fourth-level subcommands --- php/WP_CLI/Configurator.php | 34 +++++++++++++++++++++++++--------- php/WP_CLI/Runner.php | 2 +- php/commands/cli.php | 28 +++++++++++++++++++++++----- utils/wp-completion.bash | 25 ++++++------------------- 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index e3b178f6af..8a9ce8ac72 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -43,24 +43,40 @@ function get_spec() { /** * Splits a list of arguments into positional, associative and config. * - * @param string - * @return array + * @param array(string) + * @return array(array) + */ + public function parse_args( $arguments ) { + list( $positional_args, $mixed_args ) = self::extract_assoc( $arguments ); + list( $assoc_args, $runtime_config ) = $this->unmix_assoc_args( $mixed_args ); + return array( $positional_args, $assoc_args, $runtime_config ); + } + + /** + * Splits positional args from associative args. + * + * @param array + * @return array(array) */ - function parse_args( $arguments ) { - $regular_args = $mixed_args = array(); + public static function extract_assoc( $arguments ) { + $positional_args = $assoc_args = array(); foreach ( $arguments as $arg ) { if ( preg_match( '|^--no-([^=]+)$|', $arg, $matches ) ) { - $mixed_args[] = array( $matches[1], false ); + $assoc_args[] = array( $matches[1], false ); } elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { - $mixed_args[] = array( $matches[1], true ); + $assoc_args[] = array( $matches[1], true ); } elseif ( preg_match( '|^--([^=]+)=(.+)|s', $arg, $matches ) ) { - $mixed_args[] = array( $matches[1], $matches[2] ); + $assoc_args[] = array( $matches[1], $matches[2] ); } else { - $regular_args[] = $arg; + $positional_args[] = $arg; } } + return array( $positional_args, $assoc_args ); + } + + private function unmix_assoc_args( $mixed_args ) { $assoc_args = $runtime_config = array(); foreach ( $mixed_args as $tmp ) { @@ -83,7 +99,7 @@ function parse_args( $arguments ) { } } - return array( $regular_args, $assoc_args, $runtime_config ); + return array( $assoc_args, $runtime_config ); } function merge_yml( $path ) { diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4e9811fff2..3827656b7e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -192,7 +192,7 @@ private function cmd_starts_with( $prefix ) { return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); } - private function find_command_to_run( $args ) { + public function find_command_to_run( $args ) { $command = \WP_CLI::get_root_command(); $cmd_path = array(); diff --git a/php/commands/cli.php b/php/commands/cli.php index 752b1d603c..2df3f4fcb2 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -89,13 +89,31 @@ function cmd_dump() { /** * Generate tab completion strings. + * + * ## OPTIONS + * + * --line=<line> + * : The current command line to be executed + * + * --point=<point> + * : The index to the current cursor position relative to the beginning of the command */ - function completions() { - foreach ( WP_CLI::get_root_command()->get_subcommands() as $name => $command ) { - $subcommands = $command->get_subcommands(); + function completions( $_, $assoc_args ) { + $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); + $ends_with_space = ( ' ' === substr( $line, -1 ) ); - WP_CLI::line( $name . ' ' . implode( ' ', array_keys( $subcommands ) ) ); - } + // TODO: properly parse single and double quotes + $words = explode( ' ', $line ); + + array_shift( $words ); // first word is always `wp` + array_pop( $words ); // last word is either a space or an incomplete subcommand + + list( $positional_args, $assoc_args ) = \WP_CLI\Configurator::extract_assoc( $words ); + list( $command ) = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); + + $subcommands = $command->get_subcommands(); + + WP_CLI::line( implode( ' ', array_keys( $subcommands ) ) ); } } diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index f3822d3503..5d772e8854 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -1,21 +1,8 @@ -# bash completion for the wp command +# bash completion for the `wp` command -_wp() { - local cur prev opts - - cur=${COMP_WORDS[COMP_CWORD]} - prev=${COMP_WORDS[COMP_CWORD-1]} - - if [[ 'wp' = $prev ]]; then - opts=$(wp --completions | cut -d ' ' -f 1 | tr '\n' ' ') - else - opts=$(wp --completions | grep ^$prev | cut -d ' ' -f 2- | tr '\n' ' ') - fi - - if [[ 'create' = $prev ]]; then - COMPREPLY=( $(compgen -f "$cur") ) - else - COMPREPLY=( $(compgen -W "$opts" -- $cur) ) - fi +_wp_complete() { + local cur=${COMP_WORDS[COMP_CWORD]} + local opts=$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT") + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) } -complete -F _wp wp +complete -F _wp_complete wp From acbb757838501b39e55e5e9bf936859b6939d08d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Feb 2014 03:06:08 +0200 Subject: [PATCH 2705/4858] complete with filenames for commands that have <file> in their synopsis --- php/WP_CLI/SynopsisParser.php | 3 ++- php/commands/cli.php | 24 ++++++++++++++++++++---- php/commands/eval-file.php | 5 ++--- php/commands/post.php | 4 ++-- utils/wp-completion.bash | 8 +++++++- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 4996000535..fb581ea881 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -40,8 +40,9 @@ private static function classify_token( $token ) { if ( '--<field>=<value>' === $token ) { $param['type'] = 'generic'; - } elseif ( preg_match( "/^<$p_value>$/", $token, $matches ) ) { + } elseif ( preg_match( "/^<($p_value)>$/", $token, $matches ) ) { $param['type'] = 'positional'; + $param['name'] = $matches[1]; } elseif ( preg_match( "/^--(?:\\[no-\\])?$p_name/", $token, $matches ) ) { $param['name'] = $matches[1]; diff --git a/php/commands/cli.php b/php/commands/cli.php index 2df3f4fcb2..d4b89d860c 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -100,6 +100,24 @@ function cmd_dump() { */ function completions( $_, $assoc_args ) { $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); + + list( $command, $args, $assoc_args ) = self::parse_line( $line ); + + $spec = \WP_CLI\SynopsisParser::parse( $command->get_synopsis() ); + + foreach ( $spec as $arg ) { + if ( $arg['type'] == 'positional' && $arg['name'] == 'file' ) { + WP_CLI::line( '<file>' ); + return; + } + } + + $subcommands = $command->get_subcommands(); + + WP_CLI::line( implode( ' ', array_keys( $subcommands ) ) ); + } + + private static function parse_line( $line ) { $ends_with_space = ( ' ' === substr( $line, -1 ) ); // TODO: properly parse single and double quotes @@ -109,11 +127,9 @@ function completions( $_, $assoc_args ) { array_pop( $words ); // last word is either a space or an incomplete subcommand list( $positional_args, $assoc_args ) = \WP_CLI\Configurator::extract_assoc( $words ); - list( $command ) = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); + list( $command, $args ) = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); - $subcommands = $command->get_subcommands(); - - WP_CLI::line( implode( ' ', array_keys( $subcommands ) ) ); + return array( $command, $args, $assoc_args ); } } diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 330c384dd1..201bc1b340 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -7,9 +7,8 @@ class EvalFile_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp eval-file my-code.php - * - * @synopsis <path> + * [<file>] + * : The path to the PHP file to execute. */ public function __invoke( $args, $assoc_args ) { foreach ( $args as $file ) { diff --git a/php/commands/post.php b/php/commands/post.php index 9cae108889..44362dbd4a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -25,8 +25,8 @@ public function __construct() { * * ## OPTIONS * - * [<filename>] - * : Read post content from <filename>. If this value is present, the + * [<file>] + * : Read post content from <file>. If this value is present, the * `--post_content` argument will be ignored. * * Passing `-` as the filename will cause post content to diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index 5d772e8854..008e32c6be 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -3,6 +3,12 @@ _wp_complete() { local cur=${COMP_WORDS[COMP_CWORD]} local opts=$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT") - COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + + if [[ "$opts" = "<file>" ]] + then + COMPREPLY=( $(compgen -f -- $cur) ) + else + COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + fi } complete -F _wp_complete wp From 4b875b82181baf9aa1e82b3c0ec4a224c64fbdef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Feb 2014 03:19:28 +0200 Subject: [PATCH 2706/4858] update Behat tests for completions --- features/flags.feature | 14 ++++++++++++-- php/commands/cli.php | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index c666235e28..dfbb1aae80 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -212,8 +212,18 @@ Feature: Global flags Scenario: Generate completions Given an empty directory - When I run `wp --completions` + + When I run `wp cli completions --line='wp bogus-comand ' --point=100` + Then STDOUT should be empty + + When I run `wp cli completions --line='wp media ' --point=100` + Then STDOUT should contain: + """ + import regenerate + """ + + When I run `wp cli completions --line='wp media import ' --point=100` Then STDOUT should contain: """ - transient delete get set type + <file> """ diff --git a/php/commands/cli.php b/php/commands/cli.php index d4b89d860c..e03bbfdb44 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -101,7 +101,12 @@ function cmd_dump() { function completions( $_, $assoc_args ) { $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); - list( $command, $args, $assoc_args ) = self::parse_line( $line ); + $r = self::parse_line( $line ); + if ( !is_array( $r ) ) { + return; + } + + list( $command, $args, $assoc_args ) = $r; $spec = \WP_CLI\SynopsisParser::parse( $command->get_synopsis() ); @@ -127,7 +132,13 @@ private static function parse_line( $line ) { array_pop( $words ); // last word is either a space or an incomplete subcommand list( $positional_args, $assoc_args ) = \WP_CLI\Configurator::extract_assoc( $words ); - list( $command, $args ) = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); + + $r = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); + if ( !is_array( $r ) ) { + return $r; + } + + list( $command, $args ) = $r; return array( $command, $args, $assoc_args ); } From efe2deedb1e96254b23b550f81965384a84a0317 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Feb 2014 03:41:19 +0200 Subject: [PATCH 2707/4858] complete with command flags and associative parameters --- features/flags.feature | 22 +++++-- php/WP_CLI/Completions.php | 103 +++++++++++++++++++++++++++++++ php/WP_CLI/SynopsisValidator.php | 2 +- php/commands/cli.php | 43 +------------ utils/wp-completion.bash | 10 +-- 5 files changed, 130 insertions(+), 50 deletions(-) create mode 100644 php/WP_CLI/Completions.php diff --git a/features/flags.feature b/features/flags.feature index dfbb1aae80..acb13f7700 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -216,14 +216,28 @@ Feature: Global flags When I run `wp cli completions --line='wp bogus-comand ' --point=100` Then STDOUT should be empty - When I run `wp cli completions --line='wp media ' --point=100` - Then STDOUT should contain: + When I run `wp cli completions --line='wp eva' --point=100` + Then STDOUT should be: + """ + eval + eval-file + """ + + When I run `wp cli completions --line='wp core config --dbname=' --point=100` + Then STDOUT should be empty + + When I run `wp cli completions --line='wp core config --dbname=foo ' --point=100` + Then STDOUT should not contain: + """ + --dbname= + """ + And STDOUT should contain: """ - import regenerate + --extra-php """ When I run `wp cli completions --line='wp media import ' --point=100` Then STDOUT should contain: """ - <file> + <file> """ diff --git a/php/WP_CLI/Completions.php b/php/WP_CLI/Completions.php new file mode 100644 index 0000000000..63bacbae7b --- /dev/null +++ b/php/WP_CLI/Completions.php @@ -0,0 +1,103 @@ +<?php + +namespace WP_CLI; + +class Completions { + + private $words; + private $opts = array(); + + function __construct( $line ) { + // TODO: properly parse single and double quotes + $this->words = explode( ' ', $line ); + + // first word is always `wp` + array_shift( $this->words ); + + // last word is either empty or an incomplete subcommand + $this->cur_word = end( $this->words ); + + $r = $this->get_command( $this->words ); + if ( !is_array( $r ) ) { + return; + } + + list( $command, $args, $assoc_args ) = $r; + + $spec = SynopsisParser::parse( $command->get_synopsis() ); + + foreach ( $spec as $arg ) { + if ( $arg['type'] == 'positional' && $arg['name'] == 'file' ) { + $this->add( '<file> ' ); + return; + } + } + + if ( $command->can_have_subcommands() ) { + foreach ( $command->get_subcommands() as $name => $_ ) { + $this->add( "$name " ); + } + } else { + foreach ( $spec as $arg ) { + if ( in_array( $arg['type'], array( 'flag', 'assoc' ) ) ) { + if ( isset( $assoc_args[ $arg['name'] ] ) ) { + continue; + } + + $opt = "--{$arg['name']}"; + + if ( $arg['type'] == 'flag' ) { + $opt .= ' '; + } elseif ( !$arg['value']['optional'] ) { + $opt .= '='; + } + + $this->add( $opt ); + } + } + } + + } + + private function get_command( $words ) { + $positional_args = $assoc_args = array(); + + foreach ( $words as $arg ) { + if ( preg_match( '|^--([^=]+)=?|', $arg, $matches ) ) { + $assoc_args[ $matches[1] ] = true; + } else { + $positional_args[] = $arg; + } + } + + $r = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); + if ( !is_array( $r ) && array_pop( $positional_args ) == $this->cur_word ) { + $r = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); + } + + if ( !is_array( $r ) ) { + return $r; + } + + list( $command, $args ) = $r; + + return array( $command, $args, $assoc_args ); + } + + private function add( $opt ) { + if ( $this->cur_word !== '' ) { + if ( strpos( $opt, $this->cur_word ) !== 0 ) { + return; + } + } + + $this->opts[] = $opt; + } + + public function render() { + foreach ( $this->opts as $opt ) { + \WP_CLI::line( $opt ); + } + } +} + diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index ee0b824c4c..7c56f98e87 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -97,7 +97,7 @@ public function unknown_assoc( $assoc_args ) { } /** - * Filters a list of associatve arrays, based on a set of key => value arguments. + * Filters a list of associative arrays, based on a set of key => value arguments. * * @param array $args An array of key => value arguments to match against * @param string $operator diff --git a/php/commands/cli.php b/php/commands/cli.php index e03bbfdb44..bfc3a91a3c 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -100,47 +100,8 @@ function cmd_dump() { */ function completions( $_, $assoc_args ) { $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); - - $r = self::parse_line( $line ); - if ( !is_array( $r ) ) { - return; - } - - list( $command, $args, $assoc_args ) = $r; - - $spec = \WP_CLI\SynopsisParser::parse( $command->get_synopsis() ); - - foreach ( $spec as $arg ) { - if ( $arg['type'] == 'positional' && $arg['name'] == 'file' ) { - WP_CLI::line( '<file>' ); - return; - } - } - - $subcommands = $command->get_subcommands(); - - WP_CLI::line( implode( ' ', array_keys( $subcommands ) ) ); - } - - private static function parse_line( $line ) { - $ends_with_space = ( ' ' === substr( $line, -1 ) ); - - // TODO: properly parse single and double quotes - $words = explode( ' ', $line ); - - array_shift( $words ); // first word is always `wp` - array_pop( $words ); // last word is either a space or an incomplete subcommand - - list( $positional_args, $assoc_args ) = \WP_CLI\Configurator::extract_assoc( $words ); - - $r = \WP_CLI::get_runner()->find_command_to_run( $positional_args ); - if ( !is_array( $r ) ) { - return $r; - } - - list( $command, $args ) = $r; - - return array( $command, $args, $assoc_args ); + $compl = new \WP_CLI\Completions( $line ); + $compl->render(); } } diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index 008e32c6be..682d53d9ad 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -2,13 +2,15 @@ _wp_complete() { local cur=${COMP_WORDS[COMP_CWORD]} - local opts=$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT") - if [[ "$opts" = "<file>" ]] + IFS=$'\n'; # want to preserve spaces at the end + local opts=( $(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT") ) + + if [[ $opts = "<file>" ]] then COMPREPLY=( $(compgen -f -- $cur) ) else - COMPREPLY=( $(compgen -W "$opts" -- $cur) ) + COMPREPLY=$opts fi } -complete -F _wp_complete wp +complete -o nospace -F _wp_complete wp From 5a3e4f26b7d50f029b277ef877d28222abaf9015 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Feb 2014 05:01:11 +0200 Subject: [PATCH 2708/4858] remove conversion from 'wp --completions' to 'wp cli completions' the format is different and associative parameters are required --- php/WP_CLI/Runner.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3827656b7e..26af00ad09 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -337,9 +337,9 @@ private static function back_compat_conversions( $args, $assoc_args ) { unset( $assoc_args['json'] ); } - // --{version|info|completions} -> cli {version|info|completions} + // --{version|info} -> cli {version|info} if ( empty( $args ) ) { - $special_flags = array( 'version', 'info', 'completions' ); + $special_flags = array( 'version', 'info' ); foreach ( $special_flags as $key ) { if ( isset( $assoc_args[ $key ] ) ) { $args = array( 'cli', $key ); From 28c7aebc099b9806d4ba151aa1acb02457acce8b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 10 Feb 2014 05:12:48 +0200 Subject: [PATCH 2709/4858] bump version to 0.15-alpha --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index e9976b54ee..cda6d57d24 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.14.1-alpha' ); +define( 'WP_CLI_VERSION', '0.15-alpha' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 0d2fc1d571800ed3797fd588f3c31334b6ade605 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Feb 2014 03:17:30 +0200 Subject: [PATCH 2710/4858] convert `wp *-meta` subcommands to `wp * meta` --- features/network-meta.feature | 2 +- php/WP_CLI/Runner.php | 9 +- php/commands/comment-meta.php | 19 --- php/commands/comment.php | 23 +++- .../{network-meta.php => network.php} | 4 +- php/commands/post-meta.php | 20 --- php/commands/post.php | 18 +++ php/commands/user-meta.php | 115 ------------------ php/commands/user.php | 112 +++++++++++++++++ 9 files changed, 161 insertions(+), 161 deletions(-) delete mode 100644 php/commands/comment-meta.php rename php/commands/{network-meta.php => network.php} (81%) delete mode 100644 php/commands/post-meta.php delete mode 100644 php/commands/user-meta.php diff --git a/features/network-meta.feature b/features/network-meta.feature index dd6bf9c886..f81c3b1b56 100644 --- a/features/network-meta.feature +++ b/features/network-meta.feature @@ -6,7 +6,7 @@ Feature: Manage network-wide custom fields. When I try `wp network-meta` Then STDOUT should contain: """ - usage: wp network-meta + usage: wp network meta """ When I try `wp network-meta get 1 site_admins` diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 26af00ad09..57ac14284e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -291,7 +291,14 @@ private static function back_compat_conversions( $args, $assoc_args ) { } } - // core (multsite-)install --admin_name= -> --admin_user= + // *-meta -> * meta + if ( !empty( $args ) && preg_match( '/(post|comment|user|network)-meta/', $args[0], $matches ) ) { + array_shift( $args ); + array_unshift( $args, 'meta' ); + array_unshift( $args, $matches[1] ); + } + + // core (multsite-)install --admin_name= -> --admin_user= if ( count( $args ) > 0 && 'core' == $args[0] && isset( $assoc_args['admin_name'] ) ) { $assoc_args['admin_user'] = $assoc_args['admin_name']; unset( $assoc_args['admin_name'] ); diff --git a/php/commands/comment-meta.php b/php/commands/comment-meta.php deleted file mode 100644 index b1aba174b9..0000000000 --- a/php/commands/comment-meta.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -/** - * Manage comment custom fields. - * - * ## OPTIONS - * - * --format=json - * : Encode/decode values as JSON. - * - * ## EXAMPLES - * - * wp comment-meta set 123 description "Mary is a WordPress developer." - */ -class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'comment'; -} - -WP_CLI::add_command( 'comment-meta', 'Comment_Meta_Command' ); diff --git a/php/commands/comment.php b/php/commands/comment.php index cb27163234..285059757d 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -167,7 +167,7 @@ public function list_( $_, $assoc_args ) { * ## EXAMPLES * * wp comment delete 1337 --force - * + * * wp comment delete 1337 2341 --force */ public function delete( $args, $assoc_args ) { @@ -371,10 +371,10 @@ public function exists( $args ) { WP_CLI::success( "Comment with ID $args[0] exists." ); } } - + /** * Get comment url - * + * * ## OPTIONS * * <id>... @@ -389,5 +389,22 @@ public function url( $args ) { } } +/** + * Manage comment custom fields. + * + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp comment meta set 123 description "Mary is a WordPress developer." + */ +class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'comment'; +} + WP_CLI::add_command( 'comment', 'Comment_Command' ); +WP_CLI::add_command( 'comment meta', 'Comment_Meta_Command' ); diff --git a/php/commands/network-meta.php b/php/commands/network.php similarity index 81% rename from php/commands/network-meta.php rename to php/commands/network.php index 181d22949e..709c16b497 100644 --- a/php/commands/network-meta.php +++ b/php/commands/network.php @@ -14,13 +14,13 @@ * ## EXAMPLES * * # get a list of super-admins - * wp network-meta get 1 site_admins + * wp network meta get 1 site_admins */ class Network_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'site'; } -WP_CLI::add_command( 'network-meta', 'Network_Meta_Command', array( +WP_CLI::add_command( 'network meta', 'Network_Meta_Command', array( 'before_invoke' => function () { if ( !is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); diff --git a/php/commands/post-meta.php b/php/commands/post-meta.php deleted file mode 100644 index be99bd813a..0000000000 --- a/php/commands/post-meta.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -/** - * Manage post custom fields. - * - * ## OPTIONS - * - * [--format=json] - * : Encode/decode values as JSON. - * - * ## EXAMPLES - * - * wp post-meta set 123 _wp_page_template about.php - */ -class Post_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'post'; -} - -WP_CLI::add_command( 'post-meta', 'Post_Meta_Command' ); - diff --git a/php/commands/post.php b/php/commands/post.php index 44362dbd4a..e289e95a14 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -394,4 +394,22 @@ private function maybe_reset_depth() { } } +/** + * Manage post custom fields. + * + * ## OPTIONS + * + * [--format=json] + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp post meta set 123 _wp_page_template about.php + */ +class Post_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'post'; +} + WP_CLI::add_command( 'post', 'Post_Command' ); +WP_CLI::add_command( 'post meta', 'Post_Meta_Command' ); + diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php deleted file mode 100644 index dbe0924b41..0000000000 --- a/php/commands/user-meta.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php - -/** - * Manage user custom fields. - * - * ## OPTIONS - * - * --format=json - * : Encode/decode values as JSON. - * - * ## EXAMPLES - * - * wp user-meta set 123 description "Mary is a WordPress developer." - * - * wp user-meta update admin first_name "George" - */ -class User_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'user'; - - public function __construct() { - $this->fetcher = new \WP_CLI\Fetchers\User; - } - - /** - * Get meta field value. - * - * ## OPTIONS - * - * <user> - * : The user login, user email, or user ID of the user to get metadata for. - * - * <key> - * : The metadata key. - * - * [--format=<format>] - * : Accepted values: table, json. Default: table - * - * @synopsis <user> <key> [--format=<format>] - */ - public function get( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::get( $args, $assoc_args ); - } - - /** - * Delete a meta field. - * - * <user> - * : The user login, user email, or user ID of the user to delete metadata from. - * - * <key> - * : The metadata key. - * - * @synopsis <user> <key> - */ - public function delete( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::delete( $args, $assoc_args ); - } - - /** - * Add a meta field. - * - * <user> - * : The user login, user email, or user ID of the user to add metadata for. - * - * <key> - * : The metadata key. - * - * <value> - * : The new metadata value. - * - * @synopsis <user> <key> <value> [--format=<format>] - */ - public function add( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::add( $args, $assoc_args ); - } - - /** - * Update a meta field. - * - * <user> - * : The user login, user email, or user ID of the user to update metadata for. - * - * <key> - * : The metadata key. - * - * <value> - * : The new metadata value. - * - * @alias set - * @synopsis <user> <key> <value> [--format=<format>] - */ - public function update( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::update( $args, $assoc_args ); - } - - /** - * Replace user_login value with user ID - * user-meta is a special case that also supports user_login - * - * @param array - * @return array - */ - private function replace_login_with_user_id( $args ) { - $user = $this->fetcher->get_check( $args[0] ); - $args[0] = $user->ID; - return $args; - } -} - -WP_CLI::add_command( 'user-meta', 'User_Meta_Command' ); - diff --git a/php/commands/user.php b/php/commands/user.php index 0267309dea..1767f80eda 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -589,5 +589,117 @@ private static function validate_role( $role ) { } } +/** + * Manage user custom fields. + * + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp user meta set 123 description "Mary is a WordPress developer." + * + * wp user meta update admin first_name "George" + */ +class User_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'user'; + + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\User; + } + + /** + * Get meta field value. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to get metadata for. + * + * <key> + * : The metadata key. + * + * [--format=<format>] + * : Accepted values: table, json. Default: table + * + * @synopsis <user> <key> [--format=<format>] + */ + public function get( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::get( $args, $assoc_args ); + } + + /** + * Delete a meta field. + * + * <user> + * : The user login, user email, or user ID of the user to delete metadata from. + * + * <key> + * : The metadata key. + * + * @synopsis <user> <key> + */ + public function delete( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::delete( $args, $assoc_args ); + } + + /** + * Add a meta field. + * + * <user> + * : The user login, user email, or user ID of the user to add metadata for. + * + * <key> + * : The metadata key. + * + * <value> + * : The new metadata value. + * + * @synopsis <user> <key> <value> [--format=<format>] + */ + public function add( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::add( $args, $assoc_args ); + } + + /** + * Update a meta field. + * + * <user> + * : The user login, user email, or user ID of the user to update metadata for. + * + * <key> + * : The metadata key. + * + * <value> + * : The new metadata value. + * + * @alias set + * @synopsis <user> <key> <value> [--format=<format>] + */ + public function update( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::update( $args, $assoc_args ); + } + + /** + * Replace user_login value with user ID + * user meta is a special case that also supports user_login + * + * @param array + * @return array + */ + private function replace_login_with_user_id( $args ) { + $user = $this->fetcher->get_check( $args[0] ); + $args[0] = $user->ID; + return $args; + } +} + WP_CLI::add_command( 'user', 'User_Command' ); +WP_CLI::add_command( 'user meta', 'User_Meta_Command' ); From 7504a233cfbcb0c8b12e0da4f709be8d506a413d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 11 Feb 2014 03:38:18 +0200 Subject: [PATCH 2711/4858] pass full path to 'before_invoke:' --- php/WP_CLI/Dispatcher/Subcommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index c8d1acc18d..860b3c3666 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -215,7 +215,8 @@ function invoke( $args, $assoc_args, $extra_args ) { unset( $assoc_args[ $key ] ); } - \WP_CLI::do_hook( 'before_invoke:' . $this->get_parent()->get_name() ); + $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 ) ); } From c248604bd145b4af095edc495b7ff3a54bab02fa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 06:53:56 -0800 Subject: [PATCH 2712/4858] Correct casing --- php/commands/super-admin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 6d973a28d0..531146eeba 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -1,6 +1,6 @@ <?php -class SuperAdminCommand extends WP_CLI_Command { +class Super_Admin_Command extends WP_CLI_Command { /** * Show a list of users with super-admin capabilities. @@ -55,5 +55,5 @@ private static function get_admins() { } } -WP_CLI::add_command( 'super-admin', 'SuperAdminCommand' ); +WP_CLI::add_command( 'super-admin', 'Super_Admin_Command' ); From ce0695081676bc9aae4d34ed754289577e50704a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 06:57:53 -0800 Subject: [PATCH 2713/4858] Command description --- php/commands/super-admin.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 531146eeba..07588f6de2 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -1,5 +1,8 @@ <?php +/** + * List, add, and remove super admins from a network. + */ class Super_Admin_Command extends WP_CLI_Command { /** From 59486e5cc1f39527a143167e917672e2789f668d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 07:03:45 -0800 Subject: [PATCH 2714/4858] Basic Behat tests for `wp super-admin` --- features/super-admin.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 features/super-admin.feature diff --git a/features/super-admin.feature b/features/super-admin.feature new file mode 100644 index 0000000000..421f3506c1 --- /dev/null +++ b/features/super-admin.feature @@ -0,0 +1,30 @@ +Feature: Manage super admins associated with a multisite instance + + Scenario: Add, list, and remove super admins. + Given a WP multisite install + + When I try `wp user create superadmin superadmin@example.com` + Then STDERR should be empty + + When I try `wp super-admin list` + Then STDOUT should contain: + """ + admin + """ + + When I try `wp super-admin add superadmin` + Then STDERR should be empty + + When I try `wp super-admin list` + Then STDOUT should contain: + """ + admin + superadmin + """ + + When I try `wp super-admin remove admin` + And I run `wp super-admin list` + Then STDOUT should contain: + """ + superadmin + """ From fd23fb66c12a1004b620dd9319b831bab2d8850e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 07:07:27 -0800 Subject: [PATCH 2715/4858] Support adding / removing super admins based on user ID or user login --- php/commands/super-admin.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 07588f6de2..ba0329212e 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -5,6 +5,10 @@ */ class Super_Admin_Command extends WP_CLI_Command { + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\User; + } + /** * Show a list of users with super-admin capabilities. * @@ -21,12 +25,15 @@ public function _list( $_, $assoc_args ) { * Grant super-admin privileges to one or more users. * * <user>... - * : One or more user logins. + * : One or more user IDs, user emails, or user logins. */ public function add( $args, $_ ) { + + $users = $this->fetcher->get_many( $args ); + $user_logins = wp_list_pluck( $users, 'user_login' ); $super_admins = self::get_admins(); - foreach ( $args as $user_login ) { + foreach ( $user_logins as $user_login ) { $user = get_user_by( 'login', $user_login ); if ( !$user ) { WP_CLI::warning( "Couldn't find {$user_login} user." ); @@ -43,11 +50,14 @@ public function add( $args, $_ ) { * Revoke super-admin privileges to one or more users. * * <user>... - * : One or more user logins. + * : One or more user IDs, user emails, or user logins. */ public function remove( $args, $_ ) { + $users = $this->fetcher->get_many( $args ); + $user_logins = wp_list_pluck( $users, 'user_login' ); + $super_admins = self::get_admins(); - $super_admins = array_diff( $super_admins, $args ); + $super_admins = array_diff( $super_admins, $user_logins ); update_site_option( 'site_admins' , $super_admins ); WP_CLI::success( 'Revoked super-admin capabilities.' ); } From 8ae2147a0653e3bbe7748b5a9986eb1af8bdbbef Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 07:09:37 -0800 Subject: [PATCH 2716/4858] Don't do anything if this isn't multisite --- php/commands/super-admin.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index ba0329212e..b966fcd3d6 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -68,5 +68,10 @@ private static function get_admins() { } } -WP_CLI::add_command( 'super-admin', 'Super_Admin_Command' ); - +WP_CLI::add_command( 'super-admin', 'Super_Admin_Command', array( + 'before_invoke' => function () { + if ( !is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + } + ) ); From 976de5fb6a0260649dbef6ef38874d6ae844827f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 07:43:08 -0800 Subject: [PATCH 2717/4858] Basic nav menu CRUD --- features/menu.feature | 23 +++++++++ php/commands/menu.php | 108 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 features/menu.feature create mode 100644 php/commands/menu.php diff --git a/features/menu.feature b/features/menu.feature new file mode 100644 index 0000000000..1e45bcfa66 --- /dev/null +++ b/features/menu.feature @@ -0,0 +1,23 @@ +Feature: Manage WordPress menus + + Background: + Given a WP install + + Scenario: Menu CRUD operations + + When I try `wp menu create "My Menu"` + Then STDERR should be empty + + When I run `wp menu list --fields=name,slug` + Then STDOUT should be a table containing rows: + | name | slug | + | My Menu | my-menu | + + When I try `wp menu delete "My Menu"` + Then STDERR should be empty + + When I run `wp menu list --format=count` + Then STDOUT should be: + """ + 0 + """ diff --git a/php/commands/menu.php b/php/commands/menu.php new file mode 100644 index 0000000000..58c801930c --- /dev/null +++ b/php/commands/menu.php @@ -0,0 +1,108 @@ +<?php + +/** + * List, create, assign, and delete menus + */ +class Menu_Command extends WP_CLI_Command { + + protected $obj_type = 'nav_menu'; + protected $obj_fields = array( + 'term_id', + 'name', + 'slug', + 'count', + ); + + /** + * Create a new menu + * + * <menu-name> + * : A descriptive name for the menu + * + * [--porcelain] + * : Output just the new menu id. + * + * ## EXAMPLES + * + * wp menu create "My Menu" + */ + public function create( $args, $assoc_args ) { + + $ret = wp_create_nav_menu( $args[0] ); + + if ( is_wp_error( $ret ) ) { + + WP_CLI::error( $ret->get_error_message() ); + + } else { + + if ( isset( $assoc_args['porcelain'] ) ) { + WP_CLI::line( $ret->term_id ); + } else { + WP_CLI::success( "Created menu $ret->term_id." ); + } + + } + } + + /** + * Delete a menu + * + * <menu> + * : The name, slug, or term ID for the menu + * + * ## EXAMPLES + * + * wp menu delete "My Menu" + */ + public function delete( $args, $_ ) { + + $ret = wp_delete_nav_menu( $args[0] ); + + if ( is_wp_error( $ret ) ) { + + WP_CLI::error( $ret->get_error_message() ); + + } else if ( ! $ret ) { + + WP_CLI::error( "Error deleting menu." ); + + } else { + + WP_CLI::success( "Menu deleted." ); + + } + } + + /** + * Get a list of menus. + * + * ## OPTIONS + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to term_id,name,slug,count + * + * [--format=<format>] + * : Accepted values: table, csv, json, count, ids. Default: table + * + * ## EXAMPLES + * + * wp menu list + * + * @subcommand list + */ + public function list_( $_, $assoc_args ) { + + $menus = wp_get_nav_menus(); + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $menus ); + + } + + protected function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); + } + +} + +WP_CLI::add_command( 'menu', 'Menu_Command' ); From 491457a0cb5eb68ccc53e38491bf21681632be50 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 07:56:23 -0800 Subject: [PATCH 2718/4858] Present assigned nav menu locations in `wp menu list` --- php/commands/menu.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index 58c801930c..3234d3e5e4 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -10,6 +10,7 @@ class Menu_Command extends WP_CLI_Command { 'term_id', 'name', 'slug', + 'locations', 'count', ); @@ -94,6 +95,25 @@ public function delete( $args, $_ ) { public function list_( $_, $assoc_args ) { $menus = wp_get_nav_menus(); + + $menu_locations = get_nav_menu_locations(); + foreach( $menus as &$menu ) { + + $menu->locations = array(); + foreach( $menu_locations as $location => $term_id ) { + + if ( $term_id == $menu->term_id ) { + $menu->locations[] = $location; + } + + } + + // Normalize the data for some output formats + if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table' ) ) ) { + $menu->locations = implode( ',', $menu->locations ); + } + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $menus ); From 89f7e76cd7ec234359d2e6a536613a0035f747d8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 08:00:32 -0800 Subject: [PATCH 2719/4858] Easier to consolidate this code --- php/commands/menu.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 3234d3e5e4..e6c9d25746 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -60,14 +60,10 @@ public function delete( $args, $_ ) { $ret = wp_delete_nav_menu( $args[0] ); - if ( is_wp_error( $ret ) ) { - - WP_CLI::error( $ret->get_error_message() ); - - } else if ( ! $ret ) { + if ( ! $ret || is_wp_error( $ret ) ) { WP_CLI::error( "Error deleting menu." ); - + } else { WP_CLI::success( "Menu deleted." ); From bd12d3b6193646fc4b73f94fa4ceb995d85bc2a8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 08:08:35 -0800 Subject: [PATCH 2720/4858] Use the nifty sub-sub-command functionality for `wp menu list` --- php/commands/menu.php | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index e6c9d25746..25107e26be 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -121,4 +121,55 @@ protected function get_formatter( &$assoc_args ) { } +/** + * List, add, and delete items associated with a menu + */ +class Menu_Item_Command extends WP_CLI_Command { + + protected $obj_fields = array( + 'db_id', + 'type', + 'title', + 'url', + ); + + /** + * Get a list of items associated with a menu + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to db_id,type,title,url + * + * [--format=<format>] + * : Accepted values: table, csv, json, count, ids. Default: table + * + * ## EXAMPLES + * + * wp menu item list <menu> + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + + $items = wp_get_nav_menu_items( $args[0] ); + if ( false === $items || is_wp_error( $items ) ) { + WP_CLI::error( "Invalid menu" ); + } + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $items ); + + } + + protected function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields ); + } + +} + WP_CLI::add_command( 'menu', 'Menu_Command' ); +WP_CLI::add_command( 'menu item', 'Menu_Item_Command' ); From 40f8ba7595d6f3ac1308f2743f75377793bd630b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 10:08:56 -0800 Subject: [PATCH 2721/4858] Update formatting of behat tests --- features/super-admin.feature | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/features/super-admin.feature b/features/super-admin.feature index 421f3506c1..e2f383e581 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -2,27 +2,24 @@ Feature: Manage super admins associated with a multisite instance Scenario: Add, list, and remove super admins. Given a WP multisite install - - When I try `wp user create superadmin superadmin@example.com` + When I run `wp user create superadmin superadmin@example.com` Then STDERR should be empty - - When I try `wp super-admin list` + And I run `wp super-admin list` Then STDOUT should contain: """ admin """ - When I try `wp super-admin add superadmin` + When I run `wp super-admin add superadmin` Then STDERR should be empty - - When I try `wp super-admin list` + And I run `wp super-admin list` Then STDOUT should contain: """ admin superadmin """ - When I try `wp super-admin remove admin` + When I run `wp super-admin remove admin` And I run `wp super-admin list` Then STDOUT should contain: """ From d8f59e47743b7edad0825309ce2b345022f59a50 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 13:28:30 -0800 Subject: [PATCH 2722/4858] WordPress is getting a Redis persistent object cache --- php/commands/cache.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/cache.php b/php/commands/cache.php index e522c4be51..ad0a8eafe4 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -209,6 +209,11 @@ public function type( $args, $assoc_args ) { // Test for APC object cache (http://wordpress.org/extend/plugins/apc/) } elseif ( class_exists( 'APC_Object_Cache' ) ) { $message = 'APC'; + + // Test for Redis Object Cache (https://github.com/alleyinteractive/wp-redis) + } elseif ( isset( $wp_object_cache->redis ) && is_a( $wp_object_cache->redis, 'Redis' ) ) { + $message = 'Redis'; + } else { $message = 'Unknown'; } From a2006ab77a989aa2c12a575746014ce9c3b9ce0e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 15:38:10 -0800 Subject: [PATCH 2723/4858] Less verbosity --- features/super-admin.feature | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/features/super-admin.feature b/features/super-admin.feature index e2f383e581..a7a5ea1e40 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -3,17 +3,15 @@ Feature: Manage super admins associated with a multisite instance Scenario: Add, list, and remove super admins. Given a WP multisite install When I run `wp user create superadmin superadmin@example.com` - Then STDERR should be empty And I run `wp super-admin list` - Then STDOUT should contain: + Then STDOUT should be: """ admin """ When I run `wp super-admin add superadmin` - Then STDERR should be empty And I run `wp super-admin list` - Then STDOUT should contain: + Then STDOUT should be: """ admin superadmin @@ -21,7 +19,7 @@ Feature: Manage super admins associated with a multisite instance When I run `wp super-admin remove admin` And I run `wp super-admin list` - Then STDOUT should contain: + Then STDOUT should be: """ superadmin """ From cc99285428c6fd1e09581daa673f910cc28f9e99 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 15:38:50 -0800 Subject: [PATCH 2724/4858] Fix indentation --- php/commands/super-admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index b966fcd3d6..4410f345cd 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -74,4 +74,4 @@ private static function get_admins() { WP_CLI::error( 'This is not a multisite install.' ); } } - ) ); +) ); From f425dc23503992c9c8ff9a0a226c38a625f78f7d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 16:26:13 -0800 Subject: [PATCH 2725/4858] Consolidate Behat tests --- features/menu.feature | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index 1e45bcfa66..b35ce104b2 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -5,18 +5,14 @@ Feature: Manage WordPress menus Scenario: Menu CRUD operations - When I try `wp menu create "My Menu"` - Then STDERR should be empty - - When I run `wp menu list --fields=name,slug` + When I run `wp menu create "My Menu"` + And I run `wp menu list --fields=name,slug` Then STDOUT should be a table containing rows: | name | slug | | My Menu | my-menu | - When I try `wp menu delete "My Menu"` - Then STDERR should be empty - - When I run `wp menu list --format=count` + When I run `wp menu delete "My Menu"` + And I run `wp menu list --format=count` Then STDOUT should be: """ 0 From 04317ca387275bca3bae060f27b0d79208cb0343 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 18:01:12 -0800 Subject: [PATCH 2726/4858] List, assign, and remove locations from menus --- features/menu.feature | 22 +++++++++++ php/commands/menu.php | 88 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index b35ce104b2..1e50911b46 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -17,3 +17,25 @@ Feature: Manage WordPress menus """ 0 """ + + Scenario: Assign / remove location from a menu + + When I run `wp theme activate twentythirteen` + And I run `wp menu theme-locations` + Then STDOUT should be a table containing rows: + | location | description | + | primary | Navigation Menu | + + When I run `wp menu create "Primary Menu"` + And I run `wp menu assign-location primary-menu primary` + And I run `wp menu list --fields=slug,locations` + Then STDOUT should be a table containing rows: + | slug | locations | + | primary-menu | primary | + + When I run `wp menu remove-location primary-menu primary` + And I run `wp menu list --fields=slug,locations` + Then STDOUT should be a table containing rows: + | slug | locations | + | primary-menu | | + diff --git a/php/commands/menu.php b/php/commands/menu.php index 25107e26be..c5e602d383 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -46,6 +46,94 @@ public function create( $args, $assoc_args ) { } } + /** + * List locations for the current theme. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count, ids. Default: table + * + * @subcommand theme-locations + */ + public function theme_locations( $_, $assoc_args ) { + + $locations = get_registered_nav_menus(); + $location_objs = array(); + foreach( $locations as $location => $description ) { + $location_obj = new \stdClass; + $location_obj->location = $location; + $location_obj->description = $description; + $location_objs[] = $location_obj; + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'location', 'description' ) ); + $formatter->display_items( $location_objs ); + } + + /** + * Assign a location to a menu + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <location> + * : Location's slug + * + * @subcommand assign-location + */ + public function assign_location( $args, $_ ) { + + list( $menu, $location ) = $args; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $locations = get_registered_nav_menus(); + if ( ! array_key_exists( $location, $locations ) ) { + WP_CLI::error( "Invalid location." ); + } + + $locations = get_nav_menu_locations(); + $locations[ $location ] = $menu->term_id; + + set_theme_mod( 'nav_menu_locations', $locations ); + + WP_CLI::success( "Assigned location to menu." ); + } + + /** + * Remove a location from a menu + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <location> + * : Location's slug + * + * @subcommand remove-location + */ + public function remove_location( $args, $_ ) { + + list( $menu, $location ) = $args; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $locations = get_nav_menu_locations(); + if ( ! isset( $locations[ $location ] ) || $locations[ $location ] != $menu->term_id ) { + WP_CLI::error( "Menu isn't assigned to location." ); + } + + $locations[ $location ] = 0; + set_theme_mod( 'nav_menu_locations', $locations ); + + WP_CLI::success( "Removed location from menu." ); + + } + /** * Delete a menu * From 8d2cbca57459061f78430d745497e380f9b7e0b6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 11 Feb 2014 18:17:57 -0800 Subject: [PATCH 2727/4858] Ensure `$menu_locations` is always an array --- php/commands/menu.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index c5e602d383..fcb9bb83d7 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -181,6 +181,10 @@ public function list_( $_, $assoc_args ) { $menus = wp_get_nav_menus(); $menu_locations = get_nav_menu_locations(); + // < 3.6 $menu_locations could be false + if ( ! $menu_locations ) { + $menu_locations = array(); + } foreach( $menus as &$menu ) { $menu->locations = array(); From 8473ffbae52d38041888df61688bb0354783b3c1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 13:28:35 -0800 Subject: [PATCH 2728/4858] Sneak in `wp term url`, which I need for testing --- php/commands/term.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index 2e5fd3544e..001fc40dc0 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -320,6 +320,32 @@ public function generate( $args, $assoc_args ) { $notify->finish(); } + /** + * Get term url + * + * ## OPTIONS + * + * <taxonomy> + * : Taxonomy of the term(s) to get. + * + * <term-id>... + * : One or more IDs of terms to get the URL. + * + * ## EXAMPLES + * + * wp term url post_tag 123 + * + * wp term url post_tag 123 324 + */ + public function url( $args ) { + $term_link = get_term_link( (int)$args[1], $args[0] ); + if ( $term_link && ! is_wp_error( $term_link ) ) { + WP_CLI::line( $term_link ); + } else { + WP_CLI::error( "Invalid term." ); + } + } + private function maybe_make_child() { // 50% chance of making child term return ( mt_rand(1, 2) == 1 ); From 241258e5ddf8ceddfae4c77319f63399c81ae920 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 13:39:32 -0800 Subject: [PATCH 2729/4858] First pass at CRUD for menu items --- features/menu.feature | 36 ++++++++ php/commands/menu.php | 189 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index 1e50911b46..60aea57b04 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -39,3 +39,39 @@ Feature: Manage WordPress menus | slug | locations | | primary-menu | | + + Scenario: Add / remove items from a menu + + When I run `wp post create --post_title='Test post' --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID} + + When I run `wp post url {POST_ID}` + Then save STDOUT as {POST_LINK} + + When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term' --porcelain` + Then STDOUT should be a number + And save STDOUT as {TERM_ID} + + When I run `wp term url post_tag {TERM_ID}` + Then save STDOUT as {TERM_LINK} + + When I run `wp menu create "Sidebar Menu"` + And I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post"` + And I run `wp menu item add-term sidebar-menu post_tag {TERM_ID}` + And I run `wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain` + Then save STDOUT as {ITEM_ID} + + When I run `wp menu item list sidebar-menu --fields=type,title,url` + Then STDOUT should be a table containing rows: + | type | title | url | + | post_type | Custom Test Post | {POST_LINK} | + | taxonomy | Test term | {TERM_LINK} | + | custom | Apple | http://apple.com | + + When I run `wp menu item remove {ITEM_ID}` + And I run `wp menu item list sidebar-menu --format=count` + Then STDOUT should be: + """ + 2 + """ diff --git a/php/commands/menu.php b/php/commands/menu.php index fcb9bb83d7..e76dceec09 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -223,6 +223,7 @@ class Menu_Item_Command extends WP_CLI_Command { 'type', 'title', 'url', + 'position', ); /** @@ -257,6 +258,194 @@ public function list_( $args, $assoc_args ) { } + /** + * Add a post as a menu item + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <post-id> + * : Post ID to add to the menu + * + * [--title=<title>] + * : Set a custom title for the menu item + * + * [--description=<description>] + * : Set a custom description for the menu item + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item + * + * [--porcelain] + * : Output just the new menu item id. + * + * @subcommand add-post + */ + public function add_post( $args, $assoc_args ) { + + $assoc_args['object-id'] = $args[1]; + unset( $args[1] ); + $post = get_post( $assoc_args['object-id'] ); + if ( ! $post ) { + WP_CLI::error( "Invalid post." ); + } + $assoc_args['object'] = $post->post_type; + + $this->add_or_update_item( 'post_type', $args, $assoc_args ); + } + + /** + * Add a taxonomy term as a menu item + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <taxonomy> + * : Taxonomy of the term to be added + * + * <term-id> + * : Term ID of the term to be added + * + * [--porcelain] + * : Output just the new menu item id. + * + * @subcommand add-term + */ + public function add_term( $args, $assoc_args ) { + + $assoc_args['object'] = $args[1]; + unset( $args[1] ); + $assoc_args['object-id'] = $args[2]; + unset( $args[2] ); + + if ( ! get_term_by( 'id', $assoc_args['object-id'], $assoc_args['object'] ) ) { + WP_CLI::error( "Invalid term." ); + } + + $this->add_or_update_item( 'taxonomy', $args, $assoc_args ); + } + + /** + * Add a custom menu item + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <title> + * : Title for the link + * + * <url> + * : Target URL for the link + * + * [--porcelain] + * : Output just the new menu item id. + * + * @subcommand add-custom + */ + public function add_custom( $args, $assoc_args ) { + + $assoc_args['title'] = $args[1]; + unset( $args[1] ); + $assoc_args['url'] = $args[2]; + unset( $args[2] ); + $this->add_or_update_item( 'custom', $args, $assoc_args ); + } + + /** + * Remove an item from a menu + * + * <db-id> + * : Database ID for the menu item. + * + * @subcommand remove + */ + public function remove( $args, $_ ) { + + $ret = wp_delete_post( $args[0], true ); + if ( $ret ) { + WP_CLI::success( "Menu item deleted." ); + } else { + WP_CLI::error( "Couldn't delete menu item." ); + } + + } + + /** + * Worker method to create new items or update existing ones + */ + private function add_or_update_item( $type, $args, $assoc_args ) { + + $menu = $args[0]; + $menu_item_db_id = ( isset( $args[1] ) ) ? $args[1] : 0; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $default_args = array( + 'position' => 0, + 'title' => '', + 'url' => '', + 'description' => '', + 'object' => '', + 'object-id' => '', + 'attr-title' => '', + 'target' => '', + 'classes' => '', + 'xfn' => '', + 'status' => '', + ); + $menu_item_args = array(); + foreach( $default_args as $key => $default_value ) { + // wp_update_nav_menu_item() has a weird argument prefix + $new_key = 'menu-item-' . $key; + if ( isset( $assoc_args[ $key ] ) ) { + $menu_item_args[ $new_key ] = $assoc_args[ $key ]; + } + } + + // Core oddly defaults to 'draft' for create, + // and 'publish' for update + // Easiest to always work with publish + if ( ! isset( $menu_item_args['menu-item-status'] ) ) { + $menu_item_args['menu-item-status'] = 'publish'; + } + + $menu_item_args['menu-item-type'] = $type; + $ret = wp_update_nav_menu_item( $menu->term_id, $menu_item_db_id, $menu_item_args ); + + if ( is_wp_error( $ret ) ) { + WP_CLI::error( $ret->get_error_message() ); + } else if ( ! $ret ) { + WP_CLI::error( "Couldn't add menu item." ); + } else { + + /** + * Set the menu + * + * wp_update_nav_menu_item() *should* take care of this, but + * depends on wp_insert_post()'s "tax_input" argument, which + * is ignored if the user can't edit the taxonomy + * + * @see https://core.trac.wordpress.org/ticket/27113 + */ + if ( ! is_object_in_term( $ret, 'nav_menu', (int) $menu->term_id ) ) { + wp_set_object_terms( $ret, array( (int)$menu->term_id ), 'nav_menu' ); + } + + if ( ! empty( $assoc_args['porcelain'] ) ) { + WP_CLI::line( $ret ); + } else { + WP_CLI::success( "Menu item added." ); + } + } + + } + protected function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields ); } From 507d339769452eb2c27e24dbae762fecee1899ce Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 13:48:37 -0800 Subject: [PATCH 2730/4858] Fix position inconsistency --- features/menu.feature | 10 +++++----- php/commands/menu.php | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index 60aea57b04..531af86665 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -62,12 +62,12 @@ Feature: Manage WordPress menus And I run `wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain` Then save STDOUT as {ITEM_ID} - When I run `wp menu item list sidebar-menu --fields=type,title,url` + When I run `wp menu item list sidebar-menu --fields=type,title,position,url` Then STDOUT should be a table containing rows: - | type | title | url | - | post_type | Custom Test Post | {POST_LINK} | - | taxonomy | Test term | {TERM_LINK} | - | custom | Apple | http://apple.com | + | type | title | position | url | + | post_type | Custom Test Post | 1 | {POST_LINK} | + | taxonomy | Test term | 2 | {TERM_LINK} | + | custom | Apple | 3 | http://apple.com | When I run `wp menu item remove {ITEM_ID}` And I run `wp menu item list sidebar-menu --format=count` diff --git a/php/commands/menu.php b/php/commands/menu.php index e76dceec09..035148bdb6 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -253,6 +253,12 @@ public function list_( $args, $assoc_args ) { WP_CLI::error( "Invalid menu" ); } + // Correct position inconsistency + $items = array_map( function( $item ) { + $item->position = $item->menu_order; + return $item; + }, $items ); + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $items ); From 6cbfd9f89e3557b36118fc7a1602e9f20848b9c3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 14:18:47 -0800 Subject: [PATCH 2731/4858] First pass at update support for menu items --- features/menu.feature | 13 +++-- php/commands/menu.php | 124 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 125 insertions(+), 12 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index 531af86665..e139492a97 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -40,7 +40,7 @@ Feature: Manage WordPress menus | primary-menu | | - Scenario: Add / remove items from a menu + Scenario: Add / update / remove items from a menu When I run `wp post create --post_title='Test post' --porcelain` Then STDOUT should be a number @@ -62,12 +62,15 @@ Feature: Manage WordPress menus And I run `wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain` Then save STDOUT as {ITEM_ID} + When I run `wp menu item update {ITEM_ID} --title=WordPress --url='http://wordpress.org' --target=_blank --position=2` + Then STDERR should be empty + When I run `wp menu item list sidebar-menu --fields=type,title,position,url` Then STDOUT should be a table containing rows: - | type | title | position | url | - | post_type | Custom Test Post | 1 | {POST_LINK} | - | taxonomy | Test term | 2 | {TERM_LINK} | - | custom | Apple | 3 | http://apple.com | + | type | title | position | url | + | post_type | Custom Test Post | 1 | {POST_LINK} | + | custom | WordPress | 2 | http://wordpress.org | + | taxonomy | Test term | 3 | {TERM_LINK} | When I run `wp menu item remove {ITEM_ID}` And I run `wp menu item list sidebar-menu --format=count` diff --git a/php/commands/menu.php b/php/commands/menu.php index 035148bdb6..58bbc196a5 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -276,9 +276,21 @@ public function list_( $args, $assoc_args ) { * [--title=<title>] * : Set a custom title for the menu item * + * [--url=<url>] + * : Set a custom url for the menu item + * * [--description=<description>] * : Set a custom description for the menu item * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item + * + * [--target=<target>] + * : Set a custom link target for the menu item + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item + * * [--position=<position>] * : Specify the position of this menu item. * @@ -300,7 +312,7 @@ public function add_post( $args, $assoc_args ) { } $assoc_args['object'] = $post->post_type; - $this->add_or_update_item( 'post_type', $args, $assoc_args ); + $this->add_or_update_item( 'add', 'post_type', $args, $assoc_args ); } /** @@ -315,6 +327,30 @@ public function add_post( $args, $assoc_args ) { * <term-id> * : Term ID of the term to be added * + * [--title=<title>] + * : Set a custom title for the menu item + * + * [--url=<url>] + * : Set a custom url for the menu item + * + * [--description=<description>] + * : Set a custom description for the menu item + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item + * + * [--target=<target>] + * : Set a custom link target for the menu item + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item + * * [--porcelain] * : Output just the new menu item id. * @@ -331,7 +367,7 @@ public function add_term( $args, $assoc_args ) { WP_CLI::error( "Invalid term." ); } - $this->add_or_update_item( 'taxonomy', $args, $assoc_args ); + $this->add_or_update_item( 'add', 'taxonomy', $args, $assoc_args ); } /** @@ -346,6 +382,24 @@ public function add_term( $args, $assoc_args ) { * <url> * : Target URL for the link * + * [--description=<description>] + * : Set a custom description for the menu item + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item + * + * [--target=<target>] + * : Set a custom link target for the menu item + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item + * * [--porcelain] * : Output just the new menu item id. * @@ -357,7 +411,54 @@ public function add_custom( $args, $assoc_args ) { unset( $args[1] ); $assoc_args['url'] = $args[2]; unset( $args[2] ); - $this->add_or_update_item( 'custom', $args, $assoc_args ); + $this->add_or_update_item( 'add', 'custom', $args, $assoc_args ); + } + + /** + * Update a menu item + * + * <db-id> + * : Database ID for the menu item. + * + * [--title=<title>] + * : Set a custom title for the menu item + * + * [--url=<url>] + * : Set a custom url for the menu item + * + * [--description=<description>] + * : Set a custom description for the menu item + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item + * + * [--target=<target>] + * : Set a custom link target for the menu item + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item + * + * @subcommand update + */ + public function update( $args, $assoc_args ) { + + // Shuffle the position of these + $args[1] = $args[0]; + $terms = get_the_terms( $args[1], 'nav_menu' ); + if ( $terms && ! is_wp_error( $terms ) ) { + $args[0] = (int)$terms[0]->term_id; + } else { + $args[0] = 0; + } + $type = get_post_meta( $args[1], '_menu_item_type', true ); + $this->add_or_update_item( 'update', $type, $args, $assoc_args ); + } /** @@ -382,7 +483,7 @@ public function remove( $args, $_ ) { /** * Worker method to create new items or update existing ones */ - private function add_or_update_item( $type, $args, $assoc_args ) { + private function add_or_update_item( $method, $type, $args, $assoc_args ) { $menu = $args[0]; $menu_item_db_id = ( isset( $args[1] ) ) ? $args[1] : 0; @@ -405,6 +506,7 @@ private function add_or_update_item( $type, $args, $assoc_args ) { 'xfn' => '', 'status' => '', ); + $menu_item_args = array(); foreach( $default_args as $key => $default_value ) { // wp_update_nav_menu_item() has a weird argument prefix @@ -427,7 +529,11 @@ private function add_or_update_item( $type, $args, $assoc_args ) { if ( is_wp_error( $ret ) ) { WP_CLI::error( $ret->get_error_message() ); } else if ( ! $ret ) { - WP_CLI::error( "Couldn't add menu item." ); + if ( 'add' == $method ) { + WP_CLI::error( "Couldn't add menu item." ); + } else if ( 'update' == $method ) { + WP_CLI::error( "Couldn't update menu item." ); + } } else { /** @@ -443,10 +549,14 @@ private function add_or_update_item( $type, $args, $assoc_args ) { wp_set_object_terms( $ret, array( (int)$menu->term_id ), 'nav_menu' ); } - if ( ! empty( $assoc_args['porcelain'] ) ) { + if ( 'add' == $method && ! empty( $assoc_args['porcelain'] ) ) { WP_CLI::line( $ret ); } else { - WP_CLI::success( "Menu item added." ); + if ( 'add' == $method ) { + WP_CLI::success( "Menu item added." ); + } else if ( 'update' == $method ) { + WP_CLI::success( "Menu item updated." ); + } } } From 63eb7da0706a9a52ab80c49532f5519e724319e0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 14:25:19 -0800 Subject: [PATCH 2732/4858] `url` is protected in WP-CLI-landia, so let's use `link` instead --- features/menu.feature | 6 +++--- php/commands/menu.php | 23 +++++++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index e139492a97..fc28a86021 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -62,12 +62,12 @@ Feature: Manage WordPress menus And I run `wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain` Then save STDOUT as {ITEM_ID} - When I run `wp menu item update {ITEM_ID} --title=WordPress --url='http://wordpress.org' --target=_blank --position=2` + When I run `wp menu item update {ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` Then STDERR should be empty - When I run `wp menu item list sidebar-menu --fields=type,title,position,url` + When I run `wp menu item list sidebar-menu --fields=type,title,position,link` Then STDOUT should be a table containing rows: - | type | title | position | url | + | type | title | position | link | | post_type | Custom Test Post | 1 | {POST_LINK} | | custom | WordPress | 2 | http://wordpress.org | | taxonomy | Test term | 3 | {TERM_LINK} | diff --git a/php/commands/menu.php b/php/commands/menu.php index 58bbc196a5..17a1e1138f 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -222,7 +222,7 @@ class Menu_Item_Command extends WP_CLI_Command { 'db_id', 'type', 'title', - 'url', + 'link', 'position', ); @@ -235,7 +235,7 @@ class Menu_Item_Command extends WP_CLI_Command { * : The name, slug, or term ID for the menu * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to db_id,type,title,url + * : Limit the output to specific object fields. Defaults to db_id,type,title,link * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table @@ -253,9 +253,11 @@ public function list_( $args, $assoc_args ) { WP_CLI::error( "Invalid menu" ); } - // Correct position inconsistency + // Correct position inconsistency and + // protected `url` param in WP-CLI $items = array_map( function( $item ) { $item->position = $item->menu_order; + $item->link = $item->url; return $item; }, $items ); @@ -276,7 +278,7 @@ public function list_( $args, $assoc_args ) { * [--title=<title>] * : Set a custom title for the menu item * - * [--url=<url>] + * [--link=<link>] * : Set a custom url for the menu item * * [--description=<description>] @@ -330,7 +332,7 @@ public function add_post( $args, $assoc_args ) { * [--title=<title>] * : Set a custom title for the menu item * - * [--url=<url>] + * [--link=<link>] * : Set a custom url for the menu item * * [--description=<description>] @@ -379,7 +381,7 @@ public function add_term( $args, $assoc_args ) { * <title> * : Title for the link * - * <url> + * <link> * : Target URL for the link * * [--description=<description>] @@ -409,7 +411,7 @@ public function add_custom( $args, $assoc_args ) { $assoc_args['title'] = $args[1]; unset( $args[1] ); - $assoc_args['url'] = $args[2]; + $assoc_args['link'] = $args[2]; unset( $args[2] ); $this->add_or_update_item( 'add', 'custom', $args, $assoc_args ); } @@ -423,7 +425,7 @@ public function add_custom( $args, $assoc_args ) { * [--title=<title>] * : Set a custom title for the menu item * - * [--url=<url>] + * [--link=<link>] * : Set a custom url for the menu item * * [--description=<description>] @@ -493,6 +495,11 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { WP_CLI::error( "Invalid menu." ); } + // `url` is protected in WP-CLI, so we use `link` instead + if ( isset( $assoc_args['link'] ) ) { + $assoc_args['url'] = $assoc_args['link']; + } + $default_args = array( 'position' => 0, 'title' => '', From 1402dc39f087e1b150a784a515fef787a0452294 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 16:33:23 -0800 Subject: [PATCH 2733/4858] Use twentyeleven, which is available in all tested versions --- features/menu.feature | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index fc28a86021..94ccf7f354 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -20,11 +20,11 @@ Feature: Manage WordPress menus Scenario: Assign / remove location from a menu - When I run `wp theme activate twentythirteen` + When I run `wp theme activate twentyeleven` And I run `wp menu theme-locations` Then STDOUT should be a table containing rows: | location | description | - | primary | Navigation Menu | + | primary | Primary Menu | When I run `wp menu create "Primary Menu"` And I run `wp menu assign-location primary-menu primary` @@ -39,7 +39,6 @@ Feature: Manage WordPress menus | slug | locations | | primary-menu | | - Scenario: Add / update / remove items from a menu When I run `wp post create --post_title='Test post' --porcelain` From 37a6152466bac0c848f1fa016e50e87ab1498819 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Feb 2014 16:50:57 -0800 Subject: [PATCH 2734/4858] twentyeleven was removed from trunk. Let's try this one more time. --- features/menu.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/menu.feature b/features/menu.feature index 94ccf7f354..b9309253c4 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -20,7 +20,7 @@ Feature: Manage WordPress menus Scenario: Assign / remove location from a menu - When I run `wp theme activate twentyeleven` + When I run `wp theme install p2 --activate` And I run `wp menu theme-locations` Then STDOUT should be a table containing rows: | location | description | From 35ea33ff3ef93ececfa9547491a6781bdab6d6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane?= <stephane.boisvert@automattic.com> Date: Thu, 13 Feb 2014 15:11:55 -0500 Subject: [PATCH 2735/4858] Add comma as valid character in synopsis parser Add a comma as a valid character in the value field of the synopsis parser. Example: [--allowed_themes=<themeA,themeB>] --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index fb581ea881..0d62ace789 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -36,7 +36,7 @@ private static function classify_token( $token ) { list( $param['repeating'], $token ) = self::is_repeating( $token ); $p_name = '([a-z-_]+)'; - $p_value = '([a-zA-Z-|]+)'; + $p_value = '([a-zA-Z-|,]+)'; if ( '--<field>=<value>' === $token ) { $param['type'] = 'generic'; From 8739fcce99925f5ccadcf8f0748c980c7d7492b5 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Feb 2014 22:24:33 +0200 Subject: [PATCH 2736/4858] wp eval-file: allow multiple files again fixes #1012 --- features/eval.feature | 28 ++++++++++++++++++++++++++++ php/commands/eval-file.php | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 features/eval.feature diff --git a/features/eval.feature b/features/eval.feature new file mode 100644 index 0000000000..eff54bcc41 --- /dev/null +++ b/features/eval.feature @@ -0,0 +1,28 @@ +Feature: Evaluating PHP code and files. + + Scenario: Basics + Given a WP install + + When I run `wp eval 'var_dump(defined("WP_CONTENT_DIR"));'` + Then STDOUT should be: + """ + bool(true) + """ + + Given a script1.php file: + """ + <?php + WP_CLI::line("script 1"); + """ + And a script2.php file: + """ + <?php + WP_CLI::line("script 2"); + """ + + When I run `wp eval-file script1.php script2.php` + Then STDOUT should be: + """ + script 1 + script 2 + """ diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 201bc1b340..509e624838 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -7,7 +7,7 @@ class EvalFile_Command extends WP_CLI_Command { * * ## EXAMPLES * - * [<file>] + * [<file>...] * : The path to the PHP file to execute. */ public function __invoke( $args, $assoc_args ) { From fd40c3159eaa96585c2af69941e3f7d399623d05 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Feb 2014 23:00:57 +0200 Subject: [PATCH 2737/4858] wp eval-file: allow passing arbitrary arguments to the script this behavior is more useful than evaluating multiple files, which can be replicated using --require= multiple times closes #1014 --- features/eval.feature | 14 ++++---------- php/commands/eval-file.php | 25 ++++++++++++++++--------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/features/eval.feature b/features/eval.feature index eff54bcc41..1e3e2bdf08 100644 --- a/features/eval.feature +++ b/features/eval.feature @@ -9,20 +9,14 @@ Feature: Evaluating PHP code and files. bool(true) """ - Given a script1.php file: + Given a script.php file: """ <?php - WP_CLI::line("script 1"); - """ - And a script2.php file: - """ - <?php - WP_CLI::line("script 2"); + WP_CLI::line( implode( ' ', $args ) ); """ - When I run `wp eval-file script1.php script2.php` + When I run `wp eval-file script.php foo bar` Then STDOUT should be: """ - script 1 - script 2 + foo bar """ diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 509e624838..62fac6c29c 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -5,19 +5,26 @@ class EvalFile_Command extends WP_CLI_Command { /** * Load and execute a PHP file after loading WordPress. * - * ## EXAMPLES + * ## OPTIONS * - * [<file>...] + * <file> * : The path to the PHP file to execute. + * + * [<arg>...] + * : One or more arguments to pass to the file. */ - public function __invoke( $args, $assoc_args ) { - foreach ( $args as $file ) { - if ( !file_exists( $file ) ) { - WP_CLI::error( "'$file' does not exist." ); - } else { - include( $file ); - } + public function __invoke( $args ) { + $file = array_shift( $args ); + + if ( !file_exists( $file ) ) { + WP_CLI::error( "'$file' does not exist." ); } + + self::_eval( $file, $args ); + } + + private static function _eval( $file, $args ) { + include( $file ); } } From 3a6589733dce3a87d9539200fac390896771b86c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Feb 2014 15:47:51 +0200 Subject: [PATCH 2738/4858] remove non-portable utils/dev-build closes #995 --- CONTRIBUTING.md | 21 ++++++++++++++------- README.md | 6 +----- utils/dev-build | 34 ---------------------------------- 3 files changed, 15 insertions(+), 46 deletions(-) delete mode 100755 utils/dev-build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74af3fa221..5390d3149a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,24 @@ Contribute ========== +Setting up +---------- + +1. Clone this git repository on your local machine. +2. Install [Composer](https://getcomposer.org/) if you don't already have it. +2. Run `composer install` to fetch all the dependencies. +3. Run `./bin/wp --info` to test if everything was installed properly. +4. Download PHPUnit: `curl -L https://phar.phpunit.de/phpunit.phar > phpunit.phar` +5. Download Behat: `curl -L http://behat.org/downloads/behat.phar > behat.phar` + +Submitting patches +------------------ + Whether you want to fix a bug or implement a new feature, the process is pretty much the same: 0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, open a new issue so that you can get some initial feedback. 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. -2. Make the code changes in your fork. +2. Push the code changes from your local clone to your fork. 3. Open a pull request. It doesn't matter if the code isn't perfect. The idea is to get it reviewed early and iterate on it. @@ -22,12 +35,6 @@ There are two types of automated tests: * unit tests, implemented using [PHPUnit](http://phpunit.de/) * functional tests, implemented using [Behat](http://behat.org) -To set everything up, just run: - -```bash -./utils/dev-build -``` - ### Unit tests The unit test files are in the `tests/` directory. diff --git a/README.md b/README.md index 9d6cce8640..cff45cfe7c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Installing ------------ If you just want to use WP-CLI, see <http://wp-cli.org/#install>. -If you want to hack on WP-CLI, then clone this repository and run `./utils/dev-build`. +If you want to hack on WP-CLI, see [CONTRIBUTING.md](CONTRIBUTING.md). Where can I get more info? -------------------------- @@ -25,10 +25,6 @@ To suggest a feature, report a bug, or general discussion, visit the [issues sec If you're reporting a bug, please also post the output from `wp --info`. -How can I help? ---------------- -See [CONTRIBUTING.md](CONTRIBUTING.md). - Credits ------- Besides the libraries defined in [composer.json](composer.json), we have used code or ideas from the following projects: diff --git a/utils/dev-build b/utils/dev-build deleted file mode 100755 index 0637d27b94..0000000000 --- a/utils/dev-build +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -command -v php > /dev/null || { - echo "can't find PHP binary" >&2 - exit 1 -} - -echo "Downloading Composer..." -curl -sS https://getcomposer.org/installer | php - -echo "Installing dependencies using Composer..." -php composer.phar install - -echo "Downloading PHPUnit..." -curl -sS https://phar.phpunit.de/phpunit.phar > phpunit.phar - -echo "Downloading Behat..." -curl -sS http://behat.org/downloads/behat.phar > behat.phar - -echo "Creating symlink for the wp command..." -for dir in /usr/bin /usr/local/bin; do - if [ -d $dir ]; then - sudo ln -sf $(pwd)/bin/wp $dir/wp - break - fi -done - -echo "Installing bash completion file..." -for dir in /etc/bash_completion.d /usr/local/etc/bash_completion.d; do - if [ -d $dir ]; then - sudo ln -sf $(pwd)/utils/wp-completion.bash $dir/wp - break - fi -done From 2f9268f1900bc6b0393ccf909932df3c4e0d2d6b Mon Sep 17 00:00:00 2001 From: "John P. Bloch" <johnpbloch@gmail.com> Date: Sat, 15 Feb 2014 12:13:28 -0500 Subject: [PATCH 2739/4858] Define the $wp_plugin_paths global array This fixes the Invalid argument supplied for foreach() warnings generated by `plugin_basename()`. Related to wp-cli/wp-cli#1015 --- php/wp-settings-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 8223901c01..7831a022a9 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -172,6 +172,8 @@ // Define must-use plugin directory constants, which may be overridden in the sunrise.php drop-in. wp_plugin_directory_constants( ); +$GLOBALS['wp_plugin_paths'] = array(); + // Load must-use plugins. foreach ( wp_get_mu_plugins() as $mu_plugin ) { include_once( $mu_plugin ); From 2af7afbc22cfe651c3bc3b940cde81b0dc7ec4ac Mon Sep 17 00:00:00 2001 From: "John P. Bloch" <johnpbloch@gmail.com> Date: Sat, 15 Feb 2014 12:21:29 -0500 Subject: [PATCH 2740/4858] Add support for symlinking plugins if available Adds support for the (new in 3.9) automatic detection and handling of symlinked plugins. Related to wp-cli/wp-cli#1015 --- php/wp-settings-cli.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 7831a022a9..d566ec1d2a 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -172,10 +172,15 @@ // Define must-use plugin directory constants, which may be overridden in the sunrise.php drop-in. wp_plugin_directory_constants( ); -$GLOBALS['wp_plugin_paths'] = array(); +$symlinked_plugins_supported = function_exists( 'wp_register_plugin_realpath' ); +if ( $symlinked_plugins_supported ) { + $GLOBALS['wp_plugin_paths'] = array(); +} // Load must-use plugins. foreach ( wp_get_mu_plugins() as $mu_plugin ) { + if ( $symlinked_plugins_supported ) + wp_register_plugin_realpath( $mu_plugin ); include_once( $mu_plugin ); } unset( $mu_plugin ); @@ -183,8 +188,11 @@ // Load network activated plugins. if ( is_multisite() ) { foreach( wp_get_active_network_plugins() as $network_plugin ) { - if ( !Utils\is_plugin_skipped( $network_plugin ) ) + if ( !Utils\is_plugin_skipped( $network_plugin ) ) { + if ( $symlinked_plugins_supported ) + wp_register_plugin_realpath( $network_plugin ); include_once( $network_plugin ); + } } unset( $network_plugin ); } @@ -212,10 +220,14 @@ register_theme_directory( get_theme_root() ); // Load active plugins. -foreach ( wp_get_active_and_valid_plugins() as $plugin ) - if ( !Utils\is_plugin_skipped( $plugin ) ) +foreach ( wp_get_active_and_valid_plugins() as $plugin ) { + if ( !Utils\is_plugin_skipped( $plugin ) ) { + if ( $symlinked_plugins_supported ) + wp_register_plugin_realpath( $plugin ); include_once( $plugin ); -unset( $plugin ); + } +} +unset( $plugin, $symlinked_plugins_supported ); // Load pluggable functions. require( ABSPATH . WPINC . '/pluggable.php' ); From b35e302bae4db4d79c9fbba0480c990749054db0 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Sat, 15 Feb 2014 22:58:56 -0800 Subject: [PATCH 2741/4858] add functional tests --- features/roles.feature | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/features/roles.feature b/features/roles.feature index 139cc41b9e..bf62c1c2b0 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -9,3 +9,36 @@ Feature: Manage WordPress roles | name | role | | Subscriber | subscriber | | Editor | editor | + + Scenario: Resetting a role + When I run `wp role reset author` + Then STDOUT should be: + """ + Success: Reset 0/1 roles + """ + + When I run `wp cap remove author read` + And I run `wp role reset author` + Then STDOUT should be: + """ + Success: Reset 1/1 roles + """ + + When I run `wp role reset author editor` + Then STDOUT should be: + """ + Success: Reset 0/2 roles + """ + + When I run `wp cap remove author read` + And I run `wp role reset author editor` + Then STDOUT should be: + """ + Success: Reset 1/2 roles + """ + + When I run `wp role reset --all` + Then STDOUT should be: + """ + Success: All default roles reset. + """ \ No newline at end of file From 38cbf81a445b2e153341cc30914a0bf2c05fc584 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Sun, 16 Feb 2014 14:32:24 -0800 Subject: [PATCH 2742/4858] First pass at 'wp theme mod' commands. With functional tests --- features/theme-mod.feature | 63 +++++++++++++++++++ features/thememod.feature | 23 +++++++ php/commands/theme.php | 126 +++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 features/theme-mod.feature create mode 100644 features/thememod.feature diff --git a/features/theme-mod.feature b/features/theme-mod.feature new file mode 100644 index 0000000000..7ef2115f7e --- /dev/null +++ b/features/theme-mod.feature @@ -0,0 +1,63 @@ +Feature: Manage WordPress theme mods + + Scenario: Getting theme mods + Given a WP install + + When I run `wp theme mod get --all` + Then STDOUT should be a table containing rows: + | key | value | + + When I try `wp theme mod get` + Then STDERR should contain: + """ + You must specify at least one mod or use --all. + """ + + When I run `wp theme mod set background_color 123456` + And I run `wp theme mod get --all` + Then STDOUT should be a table containing rows: + | key | value | + | background_color | 123456 | + + When I run `wp theme mod set background_color 123456` + And I run `wp theme mod get background_color header_textcolor` + Then STDOUT should be a table containing rows: + | key | value | + | background_color | 123456 | + | header_textcolor | | + + Scenario: Setting theme mods + Given a WP install + + When I run `wp theme mod set background_color 123456` + Then STDOUT should be: + """ + Success: Theme mod background_color set to 123456 + """ + + Scenario: Removing theme mods + Given a WP install + + When I run `wp theme mod remove --all` + Then STDOUT should be: + """ + Success: Theme mods removed. + """ + + When I try `wp theme mod remove` + Then STDERR should contain: + """ + You must specify at least one mod or use --all. + """ + + When I run `wp theme mod remove background_color` + Then STDOUT should be: + """ + Success: 1 mods removed. + """ + + When I run `wp theme mod remove background_color header_textcolor` + Then STDOUT should be: + """ + Success: 2 mods removed. + """ diff --git a/features/thememod.feature b/features/thememod.feature new file mode 100644 index 0000000000..6dccbf816c --- /dev/null +++ b/features/thememod.feature @@ -0,0 +1,23 @@ +Feature: Manage WordPress theme mods + + Scenario: Getting theme mods + Given a WP install + + When I run `wp theme mod get --all` + Then STDOUT should be a table containing rows: + | key | value | + + Scenario: Setting theme mods + Given a WP install + + When I run `wp theme mod set background_color 123456` + Then STDOUT should be: + """ + Success: Theme mod background_color set to 123456 + """ + + When I run `wp theme mod set background_color 123456` + And I run `wp theme mod get --all` + Then STDOUT should be a table containing rows: + | key | value | + | background_color | 123456 | diff --git a/php/commands/theme.php b/php/commands/theme.php index c0d72003d9..24df49e2ee 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -520,5 +520,131 @@ public function list_( $_, $assoc_args ) { } } +/** + * Manage theme mods. + * + */ +class Theme_Mod_command extends WP_CLI_Command { + + /** + * Get theme mod(s). + * + * ## OPTIONS + * + * [<mod>...] + * : One or more mods to get. + * + * [--all] + * : List all theme mods + * + * ## EXAMPLES + * + * wp theme mod get --all + * wp theme mod get background_color + * wp theme mod get background_color header_textcolor + */ + public function get( $args = array(), $assoc_args = array() ) { + + if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) { + WP_CLI::error( "You must specify at least one mod or use --all." ); + } + + if ( isset( $assoc_args['all'] ) && $assoc_args['all'] ) { + $args = array(); + } + + $list = array(); + $mods = get_theme_mods(); + if ( ! empty( $mods ) ) + foreach( $mods as $k => $v ) { + // if mods were given, skip the others + if ( ! empty( $args ) && ! in_array( $k, $args ) ) continue; + + if ( is_array( $v ) ) { + $list[] = array( 'key' => $k, 'value' => '=>' ); + foreach( $v as $_k => $_v ) { + $list[] = array( 'key' => " $_k", 'value' => $_v ); + } + } else { + $list[] = array( 'key' => $k, 'value' => $v ); + } + + } + + // For unset mods, show blank value + foreach( $args as $mod ) { + if ( ! isset( $mods[ $mod ] ) ) { + $list[] = array( 'key' => $mod, 'value' => '' ); + } + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, array('key', 'value'), 'thememods' ); + $formatter->display_items( $list ); + + } + + /** + * Remove theme mod(s). + * + * ## OPTIONS + * + * [<mod>...] + * : One or more mods to get. + * + * [--all] + * : Remove all theme mods + * + * ## EXAMPLES + * + * wp theme mod remove --all + * wp theme mod remove background_color + * wp theme mod remove background_color header_textcolor + */ + public function remove( $args = array(), $assoc_args = array() ) { + + if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) { + WP_CLI::error( "You must specify at least one mod or use --all." ); + } + + if ( isset( $assoc_args['all'] ) && $assoc_args['all'] ) { + remove_theme_mods(); + WP_CLI::success( 'Theme mods removed.' ); + return; + } + + foreach( $args as $mod ) { + remove_theme_mod( $mod ); + } + + WP_CLI::success( sprintf( '%d mods removed.', count( $args ) ) ); + + } + + /** + * Set a theme mod. + * + * ## OPTIONS + * + * <mod> + * : Theme mod to set. + * + * <value> + * : Value to for mod. + * + * ## EXAMPLES + * + * wp theme mod set background_color 000000 + */ + public function set( $args = array(), $assoc_args = array() ) { + list( $mod, $value ) = $args; + set_theme_mod( $mod, $value ); + + if ( $value == get_theme_mod( $mod ) ) + WP_CLI::success( sprintf( "Theme mod %s set to %s", $mod, $value ) ); + } + +} + WP_CLI::add_command( 'theme', 'Theme_Command' ); +WP_CLI::add_command( 'theme mod', 'Theme_Mod_Command' ); From a45c8be9fe2c88d8ac448f9d03b98eb1edbdc286 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Sun, 16 Feb 2014 14:35:02 -0800 Subject: [PATCH 2743/4858] remove old file --- features/thememod.feature | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 features/thememod.feature diff --git a/features/thememod.feature b/features/thememod.feature deleted file mode 100644 index 6dccbf816c..0000000000 --- a/features/thememod.feature +++ /dev/null @@ -1,23 +0,0 @@ -Feature: Manage WordPress theme mods - - Scenario: Getting theme mods - Given a WP install - - When I run `wp theme mod get --all` - Then STDOUT should be a table containing rows: - | key | value | - - Scenario: Setting theme mods - Given a WP install - - When I run `wp theme mod set background_color 123456` - Then STDOUT should be: - """ - Success: Theme mod background_color set to 123456 - """ - - When I run `wp theme mod set background_color 123456` - And I run `wp theme mod get --all` - Then STDOUT should be a table containing rows: - | key | value | - | background_color | 123456 | From 859385d884776ec0f8b7af6d80eec9cbb3cd1737 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Sun, 16 Feb 2014 18:37:20 -0800 Subject: [PATCH 2744/4858] doc fix for theme mod --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 24df49e2ee..4467beea76 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -589,7 +589,7 @@ public function get( $args = array(), $assoc_args = array() ) { * ## OPTIONS * * [<mod>...] - * : One or more mods to get. + * : One or more mods to remove. * * [--all] * : Remove all theme mods From 1bbf78c712a132d1c0e1329907d04ef6f12de8e9 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Mon, 17 Feb 2014 08:47:49 -0800 Subject: [PATCH 2745/4858] formatting fixes for theme mod --- php/commands/theme.php | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 4467beea76..e5ccf8cdcd 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -399,7 +399,7 @@ public function get( $args, $assoc_args ) { $theme_vars = array( 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', ); $theme_obj = new stdClass; - foreach( $theme_vars as $var ) { + foreach ( $theme_vars as $var ) { $theme_obj->$var = $theme->$var; } @@ -537,10 +537,13 @@ class Theme_Mod_command extends WP_CLI_Command { * [--all] * : List all theme mods * + * [--format=<format>] + * : Accepted values: table, json. Default: table + * * ## EXAMPLES * * wp theme mod get --all - * wp theme mod get background_color + * wp theme mod get background_color --format=json * wp theme mod get background_color header_textcolor */ public function get( $args = array(), $assoc_args = array() ) { @@ -555,14 +558,17 @@ public function get( $args = array(), $assoc_args = array() ) { $list = array(); $mods = get_theme_mods(); - if ( ! empty( $mods ) ) - foreach( $mods as $k => $v ) { + if ( ! is_array( $mods ) ) { + // if no mods are set (perhaps new theme), make sure foreach still works + $mods = array(); + } + foreach ( $mods as $k => $v ) { // if mods were given, skip the others if ( ! empty( $args ) && ! in_array( $k, $args ) ) continue; if ( is_array( $v ) ) { $list[] = array( 'key' => $k, 'value' => '=>' ); - foreach( $v as $_k => $_v ) { + foreach ( $v as $_k => $_v ) { $list[] = array( 'key' => " $_k", 'value' => $_v ); } } else { @@ -572,7 +578,7 @@ public function get( $args = array(), $assoc_args = array() ) { } // For unset mods, show blank value - foreach( $args as $mod ) { + foreach ( $args as $mod ) { if ( ! isset( $mods[ $mod ] ) ) { $list[] = array( 'key' => $mod, 'value' => '' ); } @@ -612,7 +618,7 @@ public function remove( $args = array(), $assoc_args = array() ) { return; } - foreach( $args as $mod ) { + foreach ( $args as $mod ) { remove_theme_mod( $mod ); } @@ -626,10 +632,10 @@ public function remove( $args = array(), $assoc_args = array() ) { * ## OPTIONS * * <mod> - * : Theme mod to set. + * : The name of the theme mod to set or update. * - * <value> - * : Value to for mod. + * [<value>] + * : The new value. * * ## EXAMPLES * @@ -637,10 +643,14 @@ public function remove( $args = array(), $assoc_args = array() ) { */ public function set( $args = array(), $assoc_args = array() ) { list( $mod, $value ) = $args; + set_theme_mod( $mod, $value ); - if ( $value == get_theme_mod( $mod ) ) - WP_CLI::success( sprintf( "Theme mod %s set to %s", $mod, $value ) ); + if ( $value == get_theme_mod( $mod ) ) { + WP_CLI::success( sprintf( "Theme mod %s set to %s", $mod, $value ) ); + } else { + WP_CLI::success( sprintf( "Could not update theme mod %s", $mod ) ); + } } } From b6054e42223008533713723d44e135f768a747a6 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Mon, 17 Feb 2014 08:53:37 -0800 Subject: [PATCH 2746/4858] value not optional in theme mod set --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index e5ccf8cdcd..d3fa8fe6ec 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -634,7 +634,7 @@ public function remove( $args = array(), $assoc_args = array() ) { * <mod> * : The name of the theme mod to set or update. * - * [<value>] + * <value> * : The new value. * * ## EXAMPLES From be2230e3de81e019011142655c79ccb4893c38c5 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Mon, 17 Feb 2014 19:10:05 +0100 Subject: [PATCH 2747/4858] fix wp rewrite flush --hard doesn't generate .htaccess --- features/rewrite.feature | 11 +++++++++++ php/commands/rewrite.php | 3 +++ 2 files changed, 14 insertions(+) diff --git a/features/rewrite.feature b/features/rewrite.feature index 2d5ec586fa..f78c8504ef 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -33,3 +33,14 @@ Feature: Manage WordPress rewrites Then STDOUT should be CSV containing: | match | query | source | | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | + + Scenario: Generate .htaccess on hard flush + Given a WP install + And a wp-cli.yml file: + """ + apache_modules: [mod_rewrite] + """ + + When I run `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/` + And I run `wp rewrite flush --hard` + Then the .htaccess file should exist diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 64432ad64a..3f33c1c92b 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -208,6 +208,9 @@ private static function apache_modules() { global $is_apache; $is_apache = true; + // needed for get_home_path() and .htaccess location + $_SERVER['SCRIPT_FILENAME'] = ABSPATH; + function apache_get_modules() { return WP_CLI::get_config( 'apache_modules' ); } From a960d9f75c427d65eec3070cd0e1d810bcf62e71 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Tue, 18 Feb 2014 20:52:38 +0100 Subject: [PATCH 2748/4858] make all mysql command run with --no-defaults fix #377 regression introduced in a9f7b7c76d6e22f38ae922efa86de13f03324c63 --- php/commands/db.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 4afa05da3a..712bc65a55 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -53,7 +53,7 @@ function reset( $_, $assoc_args ) { * Optimize the database. */ function optimize() { - self::run( Utils\esc_cmd( 'mysqlcheck %s', DB_NAME ), array( + self::run( Utils\esc_cmd( 'mysqlcheck --no-defaults %s', DB_NAME ), array( 'optimize' => true, ) ); @@ -64,7 +64,7 @@ function optimize() { * Repair the database. */ function repair() { - self::run( Utils\esc_cmd( 'mysqlcheck %s', DB_NAME ), array( + self::run( Utils\esc_cmd( 'mysqlcheck --no-defaults %s', DB_NAME ), array( 'repair' => true, ) ); @@ -133,7 +133,7 @@ function export( $args, $assoc_args ) { $assoc_args['result-file'] = $result_file; } - self::run( Utils\esc_cmd( 'mysqldump %s', DB_NAME ), $assoc_args ); + self::run( Utils\esc_cmd( 'mysqldump --no-defaults %s', DB_NAME ), $assoc_args ); if ( ! $stdout ) { WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); From 11991d09ce981315b9bc97af42ff7fb34fa4ce09 Mon Sep 17 00:00:00 2001 From: Clemens Tolboom <clemens@build2be.com> Date: Wed, 19 Feb 2014 12:31:03 +0100 Subject: [PATCH 2749/4858] Add require-dev in order to remove downloads of phars. --- CONTRIBUTING.md | 10 ++++------ composer.json | 4 ++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5390d3149a..3efb618b3d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,8 +8,6 @@ Setting up 2. Install [Composer](https://getcomposer.org/) if you don't already have it. 2. Run `composer install` to fetch all the dependencies. 3. Run `./bin/wp --info` to test if everything was installed properly. -4. Download PHPUnit: `curl -L https://phar.phpunit.de/phpunit.phar > phpunit.phar` -5. Download Behat: `curl -L http://behat.org/downloads/behat.phar > behat.phar` Submitting patches ------------------ @@ -41,7 +39,7 @@ The unit test files are in the `tests/` directory. To run the unit tests, just execute: - php phpunit.phar + vendor/phpunit/phpunit/phpunit.php ### Functional tests @@ -55,13 +53,13 @@ Running the following as root in MySQL should do the trick: Then, to run the entire test suite: - php behat.phar --expand + vendor/behat/behat/bin/behat --expand Or to test a single feature: - php behat.phar features/core.feature + vendor/behat/behat/bin/behat features/core.feature -More info can be found from `php behat.phar --help`. +More info can be found from `vendor/behat/behat/bin/behat --help`. Finally... ---------- diff --git a/composer.json b/composer.json index 0dbcad2cf3..db7c484be5 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,10 @@ "symfony/finder": "~2.3", "nb/oxymel": "0.1.0" }, + "require-dev": { + "phpunit/phpunit": "3.7.*", + "behat/behat": "2.5.*@dev" + }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" }, From 93d721c6c0c051c622a7faa80050d140f74cb1a7 Mon Sep 17 00:00:00 2001 From: Clemens Tolboom <clemens@build2be.com> Date: Wed, 19 Feb 2014 13:31:32 +0100 Subject: [PATCH 2750/4858] Use vendor/bin --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3efb618b3d..aaf85e2f4e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,7 @@ The unit test files are in the `tests/` directory. To run the unit tests, just execute: - vendor/phpunit/phpunit/phpunit.php + vendor/bin/phpunit ### Functional tests @@ -53,11 +53,11 @@ Running the following as root in MySQL should do the trick: Then, to run the entire test suite: - vendor/behat/behat/bin/behat --expand + vendor/bin/behat --expand Or to test a single feature: - vendor/behat/behat/bin/behat features/core.feature + vendor/bin/behat features/core.feature More info can be found from `vendor/behat/behat/bin/behat --help`. From 3bdec1cbf8323b564157bf4035f35fdc6c8ae682 Mon Sep 17 00:00:00 2001 From: Clemens Tolboom <clemens@build2be.com> Date: Wed, 19 Feb 2014 14:30:02 +0100 Subject: [PATCH 2751/4858] No need for behat through ci/perpare.sh --- ci/prepare.sh | 3 --- ci/test.sh | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index 5627017400..611a068de1 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -12,9 +12,6 @@ php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet mv wp-cli.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp -# Travis CI doesn't come with Behat pre-installed -curl http://behat.org/downloads/behat.phar > behat.phar - # Install CodeSniffer things ./ci/prepare-codesniffer.sh diff --git a/ci/test.sh b/ci/test.sh index c213a42318..9e14eacf90 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -3,10 +3,10 @@ set -ex # Run the unit tests -phpunit +vendor/bin/phpunit # Run the functional tests -php behat.phar --format progress +vendor/bin/behat --format progress # Run CodeSniffer ./codesniffer/scripts/phpcs --standard=./ci/ php/ From 818ac72ef457a427b22a3c69d6b4399205ccd7bd Mon Sep 17 00:00:00 2001 From: Clemens Tolboom <clemens@build2be.com> Date: Wed, 19 Feb 2014 14:31:59 +0100 Subject: [PATCH 2752/4858] No behat @dev versions. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index db7c484be5..f2972a1450 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ }, "require-dev": { "phpunit/phpunit": "3.7.*", - "behat/behat": "2.5.*@dev" + "behat/behat": "2.5.*" }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" From 38ff3823614b034185f0929393e64d3208dbc32c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 19 Feb 2014 14:05:59 +0000 Subject: [PATCH 2753/4858] make phpunit & behat paths more tab-completion friendly --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aaf85e2f4e..563153a4e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,7 @@ The unit test files are in the `tests/` directory. To run the unit tests, just execute: - vendor/bin/phpunit + ./vendor/bin/phpunit ### Functional tests @@ -53,13 +53,13 @@ Running the following as root in MySQL should do the trick: Then, to run the entire test suite: - vendor/bin/behat --expand + ./vendor/bin/behat --expand Or to test a single feature: - vendor/bin/behat features/core.feature + ./vendor/bin/behat features/core.feature -More info can be found from `vendor/behat/behat/bin/behat --help`. +More info can be found by using `./vendor/bin/behat --help`. Finally... ---------- From 9098f32af60b1bafcdca0797875fd36ad29199f0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 19 Feb 2014 22:46:11 +0000 Subject: [PATCH 2754/4858] wp eval-file: mention $args and add example see #1014 --- php/commands/eval-file.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 62fac6c29c..92798f5447 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -11,7 +11,11 @@ class EvalFile_Command extends WP_CLI_Command { * : The path to the PHP file to execute. * * [<arg>...] - * : One or more arguments to pass to the file. + * : One or more arguments to pass to the file. They are placed in the $args variable. + * + * ## EXAMPLES + * + * wp eval-file my-code.php value1 value2 */ public function __invoke( $args ) { $file = array_shift( $args ); From 888f06973307fd86de8baf072e8f93d4bffc5c59 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 21 Feb 2014 13:46:46 -0300 Subject: [PATCH 2755/4858] fix test that was passing with the wrong error message --- features/help.feature | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/help.feature b/features/help.feature index b0225d0c0c..ac576ad9ad 100644 --- a/features/help.feature +++ b/features/help.feature @@ -1,7 +1,7 @@ Feature: Get help about WP-CLI commands Scenario: Help for internal commands - Given an empty directory + Given a WP install When I run `wp help` Then STDOUT should not be empty @@ -17,7 +17,10 @@ Feature: Get help about WP-CLI commands When I try `wp help non-existent-command` Then the return code should be 1 - And STDERR should not be empty + And STDERR should be: + """ + Error: 'non-existent-command' is not a registered wp command. + """ Scenario: Help for third-party commands Given a WP install From 0e63bd32a329800d1febc1e86e82e3423c638e06 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 21 Feb 2014 14:08:52 -0300 Subject: [PATCH 2756/4858] fix error message when fetching help for nested commands (fixes #1017) --- features/help.feature | 7 +++++++ php/commands/help.php | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index ac576ad9ad..05c2f99751 100644 --- a/features/help.feature +++ b/features/help.feature @@ -21,6 +21,13 @@ Feature: Get help about WP-CLI commands """ Error: 'non-existent-command' is not a registered wp command. """ + + When I try `wp help non-existent-command non-existent-subcommand` + Then the return code should be 1 + And STDERR should be: + """ + Error: 'non-existent-command non-existent-subcommand' is not a registered wp command. + """ Scenario: Help for third-party commands Given a WP install diff --git a/php/commands/help.php b/php/commands/help.php index b9abfcc0c3..6d5001da52 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -28,7 +28,8 @@ function __invoke( $args, $assoc_args ) { // WordPress is already loaded, so there's no chance we'll find the command if ( function_exists( 'add_filter' ) ) { - \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $args[0] ) ); + $command_string = implode( ' ', $args ); + \WP_CLI::error( sprintf( "'%s' is not a registered wp command.", $command_string ) ); } } From cc48e675739b2a22f469b61abe7663e0efc329d2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 22 Feb 2014 23:04:38 +0000 Subject: [PATCH 2757/4858] set only the MYSQL_PWD environment variable this avoids having to use the unreliable $_ENV superglobal fixes #950 --- php/utils.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/utils.php b/php/utils.php index 7ce26e81bc..a46e45f65c 100644 --- a/php/utils.php +++ b/php/utils.php @@ -323,15 +323,14 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { $assoc_args = array_merge( $assoc_args, mysql_host_to_cli_args( $assoc_args['host'] ) ); } - $env = (array) $_ENV; if ( isset( $assoc_args['pass'] ) ) { - $env['MYSQL_PWD'] = $assoc_args['pass']; + $cmd = esc_cmd( 'MYSQL_PWD=%s ', $assoc_args['pass'] ) . $cmd; unset( $assoc_args['pass'] ); } $final_cmd = $cmd . assoc_args_to_str( $assoc_args ); - $proc = proc_open( $final_cmd, $descriptors, $pipes, null, $env ); + $proc = proc_open( $final_cmd, $descriptors, $pipes ); if ( !$proc ) exit(1); From d99477a64dc60c1d5f18387d8e27bd42320add34 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 24 Feb 2014 12:15:13 -0300 Subject: [PATCH 2758/4858] split test scenario for help command (one for when wp is installed and other for when it is not) see #1034 --- features/help.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index 05c2f99751..994358c3f2 100644 --- a/features/help.feature +++ b/features/help.feature @@ -1,7 +1,7 @@ Feature: Get help about WP-CLI commands Scenario: Help for internal commands - Given a WP install + Given an empty directory When I run `wp help` Then STDOUT should not be empty @@ -15,6 +15,9 @@ Feature: Get help about WP-CLI commands When I run `wp help help` Then STDOUT should not be empty + Scenario: Help for nonexistent commands + Given a WP install + When I try `wp help non-existent-command` Then the return code should be 1 And STDERR should be: From 38feb897bb07e9ecb06b48250ec4c5eeb40c8a5b Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Mon, 24 Feb 2014 23:03:16 -0800 Subject: [PATCH 2759/4858] Add support for exporting specific tables --- php/commands/db.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index 712bc65a55..cb69d67403 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -119,6 +119,9 @@ function query( $args ) { * [--<field>=<value>] * : Extra arguments to pass to mysqldump * + * [--tables=<tables>] + * : The comma separated list of specific tables to export. Excluding this parameter will export all tables + * * ## EXAMPLES * * wp db dump --add-drop-table @@ -133,7 +136,13 @@ function export( $args, $assoc_args ) { $assoc_args['result-file'] = $result_file; } - self::run( Utils\esc_cmd( 'mysqldump --no-defaults %s', DB_NAME ), $assoc_args ); + if ( isset( $assoc_args['tables'] ) ) { + $tables = explode( ',', $assoc_args['tables'] ); + unset( $assoc_args['tables'] ); + self::run( Utils\esc_cmd( 'mysqldump --no-defaults %s --tables %s', DB_NAME, implode( ' ', $tables ) ), $assoc_args ); + } else { + self::run( Utils\esc_cmd( 'mysqldump --no-defaults %s', DB_NAME ), $assoc_args ); + } if ( ! $stdout ) { WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); From 31031e30b93dadfc51a0f9b58d4f1f62b45083cc Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Wed, 26 Feb 2014 03:54:08 -0800 Subject: [PATCH 2760/4858] Dynamically build mysqldump command rather than repeating it --- php/commands/db.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index cb69d67403..b3b0cd2384 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -136,14 +136,23 @@ function export( $args, $assoc_args ) { $assoc_args['result-file'] = $result_file; } + $command = 'mysqldump --no-defaults %s'; + $command_esc_args = array( DB_NAME ); + if ( isset( $assoc_args['tables'] ) ) { $tables = explode( ',', $assoc_args['tables'] ); unset( $assoc_args['tables'] ); - self::run( Utils\esc_cmd( 'mysqldump --no-defaults %s --tables %s', DB_NAME, implode( ' ', $tables ) ), $assoc_args ); - } else { - self::run( Utils\esc_cmd( 'mysqldump --no-defaults %s', DB_NAME ), $assoc_args ); + $command .= ' --tables'; + foreach ( $tables as $table ) { + $command .= ' %s'; + $command_esc_args[] = trim( $table ); + } } + $escaped_command = call_user_func_array( '\WP_CLI\Utils\esc_cmd', array_merge( array( $command ), $command_esc_args ) ); + + self::run( $escaped_command, $assoc_args ); + if ( ! $stdout ) { WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } From f69a55cfd6f6e4b684a852f73876747da517bb7e Mon Sep 17 00:00:00 2001 From: Will Anderson <will@itsananderson.com> Date: Wed, 26 Feb 2014 03:56:09 -0800 Subject: [PATCH 2761/4858] Add example for exporting specific tables --- php/commands/db.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/db.php b/php/commands/db.php index b3b0cd2384..998b4ab42d 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -125,6 +125,7 @@ function query( $args ) { * ## EXAMPLES * * wp db dump --add-drop-table + * wp db dump --tables=wp_options,wp_users * * @alias dump */ From 193b6d8a2e05931bc990f5c6990be4d4369f92b7 Mon Sep 17 00:00:00 2001 From: Andrey Savchenko <contact@rarst.net> Date: Wed, 26 Feb 2014 21:16:44 +0200 Subject: [PATCH 2762/4858] Whitelisted underscore in synopsis values. --- php/WP_CLI/SynopsisParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 0d62ace789..3d440a000e 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -36,7 +36,7 @@ private static function classify_token( $token ) { list( $param['repeating'], $token ) = self::is_repeating( $token ); $p_name = '([a-z-_]+)'; - $p_value = '([a-zA-Z-|,]+)'; + $p_value = '([a-zA-Z-_|,]+)'; if ( '--<field>=<value>' === $token ) { $param['type'] = 'generic'; From b26d090c63ab39036109569c9ff45ca5d6b75608 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 2 Mar 2014 14:16:14 +0000 Subject: [PATCH 2763/4858] increase wordwrap width to 90 fixes display of long 'wp core config' example --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 6d5001da52..33d1d9e46a 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -48,7 +48,7 @@ private static function show_help( $command ) { $longdesc = $command->get_longdesc(); if ( $longdesc ) { - $out .= wordwrap( $longdesc, 79 ) . "\n"; + $out .= wordwrap( $longdesc, 90 ) . "\n"; } // section headers From 30bdbace08718944aa8681184a2655c08363ac78 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Mar 2014 14:18:22 -0800 Subject: [PATCH 2764/4858] Turn `validate_role()` into a more helpful method and apply it in more places --- php/commands/user.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 1767f80eda..a72b33ead0 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -196,9 +196,7 @@ public function create( $args, $assoc_args ) { if ( isset( $assoc_args['role'] ) ) { $role = $assoc_args['role']; - if ( !self::validate_role( $role ) ) { - WP_CLI::error( "Invalid role: $role" ); - } + self::validate_role( $role ); } else { $role = get_option('default_role'); } @@ -275,9 +273,7 @@ public function generate( $args, $assoc_args ) { $role = $assoc_args['role']; - if ( !self::validate_role( $role ) ) { - WP_CLI::error( "Invalid role: $role" ); - } + self::validate_role( $role ); $user_count = count_users(); $total = $user_count['total_users']; @@ -332,6 +328,8 @@ public function set_role( $args, $assoc_args ) { $role = isset( $args[1] ) ? $args[1] : get_option( 'default_role' ); + self::validate_role( $role ); + // Multisite if ( function_exists( 'add_user_to_blog' ) ) add_user_to_blog( get_current_blog_id(), $user->ID, $role ); @@ -364,6 +362,8 @@ public function add_role( $args, $assoc_args ) { $role = $args[1]; + self::validate_role( $role ); + $user->add_role( $role ); WP_CLI::success( sprintf( "Added '%s' role for %s (%d).", $role, $user->user_login, $user->ID ) ); @@ -581,12 +581,19 @@ public function import_csv( $args, $assoc_args ) { } } + /** + * Check whether the role is valid + * + * @param string + */ private static function validate_role( $role ) { - if ( empty( $role ) || ! is_null( get_role( $role ) ) ) { - return true; + + if ( ! empty( $role ) && is_null( get_role( $role ) ) ) { + WP_CLI::error( sprintf( "Role doesn't exist: %s", $role ) ); } - return false; + } + } /** @@ -698,6 +705,7 @@ private function replace_login_with_user_id( $args ) { $args[0] = $user->ID; return $args; } + } WP_CLI::add_command( 'user', 'User_Command' ); From 54ceede7b04a6f45ed8968f6ee0da6406997e75e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Mar 2014 15:28:03 -0800 Subject: [PATCH 2765/4858] Also validate `wp user remove-role` --- php/commands/user.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index a72b33ead0..4ba5d734b0 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -393,6 +393,8 @@ public function remove_role( $args, $assoc_args ) { if ( isset( $args[1] ) ) { $role = $args[1]; + self::validate_role( $role ); + $user->remove_role( $role ); WP_CLI::success( sprintf( "Removed '%s' role for %s (%d).", $role, $user->user_login, $user->ID ) ); From 2b305d2fdf84d6aee6239295bc284dc472c723bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Mar 2014 15:29:08 -0800 Subject: [PATCH 2766/4858] `$role` can be empty for `wp user generate` --- php/commands/user.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 4ba5d734b0..256b12b334 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -273,7 +273,9 @@ public function generate( $args, $assoc_args ) { $role = $assoc_args['role']; - self::validate_role( $role ); + if ( ! empty( $role ) ) { + self::validate_role( $role ); + } $user_count = count_users(); $total = $user_count['total_users']; From 63a152e9f9b24f98b34d68cb594ec1b27979ae18 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Mar 2014 15:29:52 -0800 Subject: [PATCH 2767/4858] Add some tests for error conditions with roles --- features/user.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/user.feature b/features/user.feature index f253335196..18cf6d950f 100644 --- a/features/user.feature +++ b/features/user.feature @@ -106,6 +106,15 @@ Feature: Manage WordPress users administrator, editor """ + When I try `wp user add-role 1 edit` + Then STDERR should not be empty + + When I try `wp user set-role 1 edit` + Then STDERR should not be empty + + When I try `wp user remove-role 1 edit` + Then STDERR should not be empty + When I run `wp user set-role 1 author` Then STDOUT should not be empty And I run `wp user get 1` From 2a457208c6d5f2e2561a416a554b9573a3fff324 Mon Sep 17 00:00:00 2001 From: Clemens Tolboom <clemens@build2be.com> Date: Thu, 6 Mar 2014 17:34:48 +0100 Subject: [PATCH 2768/4858] Changed dump into export. --- php/commands/db.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 998b4ab42d..2230470dec 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -124,8 +124,8 @@ function query( $args ) { * * ## EXAMPLES * - * wp db dump --add-drop-table - * wp db dump --tables=wp_options,wp_users + * wp db export --add-drop-table + * wp db export --tables=wp_options,wp_users * * @alias dump */ From 13ee41b59271a1e80dfc3278e48272bed6d27de2 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Mar 2014 12:21:09 +0000 Subject: [PATCH 2769/4858] show error when invalid format is passed --- php/WP_CLI/Formatter.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 7d3eacc0b7..3b349f6de9 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -85,6 +85,9 @@ private function format( $items ) { echo json_encode( $out ); break; + + default: + \WP_CLI::error( 'Invalid format: ' . $this->args['format'] ); } } From f7f6d605af901adaa09034f96389bbe37d2ee6af Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Mar 2014 12:30:06 +0000 Subject: [PATCH 2770/4858] move --format=ids handling to individual commands --- php/commands/post.php | 12 +++++++----- php/commands/term.php | 9 ++++++--- php/commands/user.php | 18 +++++++++++------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index e289e95a14..f179634192 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -240,12 +240,14 @@ public function list_( $_, $assoc_args ) { } } - if ( 'ids' == $formatter->format ) + if ( 'ids' == $formatter->format ) { $query_args['fields'] = 'ids'; - - $query = new WP_Query( $query_args ); - - $formatter->display_items( $query->posts ); + $query = new WP_Query( $query_args ); + echo implode( ' ', $query->posts ); + } else { + $query = new WP_Query( $query_args ); + $formatter->display_items( $query->posts ); + } } /** diff --git a/php/commands/term.php b/php/commands/term.php index 2e5fd3544e..43f2e081ca 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -53,10 +53,13 @@ public function list_( $args, $assoc_args ) { $assoc_args = array_merge( $defaults, $assoc_args ); $terms = get_terms( $args, $assoc_args ); - if ( 'ids' == $formatter->format ) - $terms = wp_list_pluck( $terms, 'term_id' ); - $formatter->display_items( $terms ); + if ( 'ids' == $formatter->format ) { + $terms = wp_list_pluck( $terms, 'term_id' ); + echo implode( ' ', $terms ); + } else { + $formatter->display_items( $terms ); + } } /** diff --git a/php/commands/user.php b/php/commands/user.php index 1767f80eda..41dab92ce9 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -62,16 +62,20 @@ public function list_( $args, $assoc_args ) { $users = get_users( $assoc_args ); - $it = WP_CLI\Utils\iterator_map( $users, function ( $user ) { - if ( !is_object( $user ) ) - return $user; + if ( 'ids' == $formatter->format ) { + echo implode( ' ', $users ); + } else { + $it = WP_CLI\Utils\iterator_map( $users, function ( $user ) { + if ( !is_object( $user ) ) + return $user; - $user->roles = implode( ',', $user->roles ); + $user->roles = implode( ',', $user->roles ); - return $user; - } ); + return $user; + } ); - $formatter->display_items( $it ); + $formatter->display_items( $it ); + } } /** From a6539d7db710a47df7a9a7be1ebb953c34c1b4e4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 7 Mar 2014 21:12:33 +0000 Subject: [PATCH 2771/4858] test that failure is due to expected error --- features/user.feature | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/features/user.feature b/features/user.feature index 18cf6d950f..038d184654 100644 --- a/features/user.feature +++ b/features/user.feature @@ -107,13 +107,22 @@ Feature: Manage WordPress users """ When I try `wp user add-role 1 edit` - Then STDERR should not be empty + Then STDERR should contain: + """ + Role doesn't exist + """ When I try `wp user set-role 1 edit` - Then STDERR should not be empty + Then STDERR should contain: + """ + Role doesn't exist + """ When I try `wp user remove-role 1 edit` - Then STDERR should not be empty + Then STDERR should contain: + """ + Role doesn't exist + """ When I run `wp user set-role 1 author` Then STDOUT should not be empty From 6b6a300561ed35b6ad74315ba24d02e4591b5ef9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Mar 2014 17:12:14 +0000 Subject: [PATCH 2772/4858] throw error when wp-config.php looks invalid --- php/WP_CLI/Runner.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 57ac14284e..bec000fb7f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -262,15 +262,23 @@ public function get_wp_config_code() { $wp_config_code = explode( "\n", file_get_contents( $wp_config_path ) ); + $found_wp_settings = false; + $lines_to_run = array(); foreach ( $wp_config_code as $line ) { - if ( preg_match( '/^\s*require.+wp-settings\.php/', $line ) ) + if ( preg_match( '/^\s*require.+wp-settings\.php/', $line ) ) { + $found_wp_settings = true; continue; + } $lines_to_run[] = $line; } + if ( !$found_wp_settings ) { + WP_CLI::error( 'Strange wp-config.php file: wp-settings.php is not loaded directly.' ); + } + $source = implode( "\n", $lines_to_run ); $source = Utils\replace_path_consts( $source, $wp_config_path ); return preg_replace( '|^\s*\<\?php\s*|', '', $source ); From 4d379cbbeeb08780364a77cc3ca9ba74ebdbc485 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 9 Mar 2014 20:00:56 +0000 Subject: [PATCH 2773/4858] show full command name in usage output; fixes #1016 --- php/WP_CLI/Dispatcher/CompositeCommand.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 2edb23687b..6f77789694 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -78,8 +78,10 @@ function show_usage() { \WP_CLI::line( $subcommand->get_usage( $prefix ) ); } + $cmd_name = implode( ' ', array_slice( get_path( $this ), 1 ) ); + \WP_CLI::line(); - \WP_CLI::line( "See 'wp help $this->name <command>' for more information on a specific command." ); + \WP_CLI::line( "See 'wp help $cmd_name <command>' for more information on a specific command." ); } function invoke( $args, $assoc_args, $extra_args ) { From b878b484cc35dca90af96e71c927b8988dc1e5dc Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Mon, 10 Mar 2014 17:32:19 -0700 Subject: [PATCH 2774/4858] allow --skip-plugins to be set in wp-cli.yml --- php/config-spec.php | 3 +-- php/utils-wp.php | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index df260551e0..e4bfa1f5da 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -30,9 +30,8 @@ 'skip-plugins' => array( 'runtime' => '[=<plugin>]', - 'file' => false, + 'file' => '<list>', 'desc' => 'Skip loading all or some plugins', - 'multiple' => false, 'default' => '', ), diff --git a/php/utils-wp.php b/php/utils-wp.php index a8a64fbfd2..4048a8d061 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -88,6 +88,10 @@ function is_plugin_skipped( $file ) { if ( true === $skipped_plugins ) return true; - return in_array( $name, array_filter( explode( ',', $skipped_plugins ) ) ); + if ( ! is_array( $skipped_plugins ) ) { + $skipped_plugins = explode( ',', $skipped_plugins ); + } + + return in_array( $name, array_filter( $skipped_plugins ) ); } From 07cc5b20c26168c47bff8fa1d48e41ecb29cc384 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Mar 2014 07:03:08 -0700 Subject: [PATCH 2775/4858] Support for network-activating a plugin upon install Usage `wp plugin install user-switching --network` --- features/plugin.feature | 11 +++++++++++ php/WP_CLI/CommandWithUpgrade.php | 4 ++-- php/commands/plugin.php | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 4bbd84cdec..a933943f05 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -122,6 +122,17 @@ Feature: Manage WordPress plugins Status: Network Active """ + Scenario: Network activate a plugin + Given a WP multisite install + + When I run `wp plugin install user-switching --network` + Then STDOUT should not be empty + + When I run `wp plugin list --fields=name,status` + Then STDOUT should be a table containing rows: + | name | status | + | user-switching | active-network | + Scenario: List plugins Given a WP install diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 485a8a1b27..88debb6e49 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -143,9 +143,9 @@ function install( $args, $assoc_args ) { } } - if ( $result && isset( $assoc_args['activate'] ) ) { + if ( $result && ( isset( $assoc_args['activate'] ) || isset( $assoc_args['network'] ) ) ) { \WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ) ); + $this->activate( array( $slug ), $assoc_args ); } } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 095325c335..0a5a66bbf6 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -347,6 +347,9 @@ protected function filter_item_list( $items, $args ) { * * [--activate] * : If set, the plugin will be activated immediately after install. + * + * [--network] + * : If set, the plugin will be network activated immediately after install * * ## EXAMPLES * From 6723e54cb63fcb80a85cd511b9ec22dfa172dd5c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Mar 2014 07:15:14 -0700 Subject: [PATCH 2776/4858] Use the `$current_site` global instead of `wpmu_current_site()`, which is being removed in trunk See http://irclogs.wordpress.org/chanlog.php?channel=wordpress-dev&day=2014-03-04&sort=asc#m803847 --- php/commands/site.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 5d5637d270..7aa6ab2efd 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -213,7 +213,7 @@ public function create( $_, $assoc_args ) { WP_CLI::error( 'This is not a multisite install.' ); } - global $wpdb; + global $wpdb, $current_site; $base = $assoc_args['slug']; $title = isset( $assoc_args['title'] ) ? $assoc_args['title'] : ucfirst( $base ); @@ -228,7 +228,7 @@ public function create( $_, $assoc_args ) { } } else { - $network = wpmu_current_site(); + $network = $current_site; } $public = !isset( $assoc_args['private'] ); From 9bdca32dd6babfb71d3af24a78ac70bc828fe9e0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 12 Mar 2014 19:42:56 +0000 Subject: [PATCH 2777/4858] run functional tests against WP 3.9-beta1 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 508251d011..9a3e92cbe6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=latest + - WP_VERSION=3.9-beta1 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: From dd4cf87b5bc1aa857096bcc27a8da0a90b70259a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 13 Mar 2014 11:07:00 -0700 Subject: [PATCH 2778/4858] Change syntax from `--network` to `--activate-network` for clarity --- features/plugin.feature | 2 +- php/WP_CLI/CommandWithUpgrade.php | 2 +- php/commands/plugin.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index a933943f05..dcad447784 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -125,7 +125,7 @@ Feature: Manage WordPress plugins Scenario: Network activate a plugin Given a WP multisite install - When I run `wp plugin install user-switching --network` + When I run `wp plugin install user-switching --activate-network` Then STDOUT should not be empty When I run `wp plugin list --fields=name,status` diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 88debb6e49..79783fa2d2 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -143,7 +143,7 @@ function install( $args, $assoc_args ) { } } - if ( $result && ( isset( $assoc_args['activate'] ) || isset( $assoc_args['network'] ) ) ) { + if ( $result && ( isset( $assoc_args['activate'] ) || isset( $assoc_args['activate-network'] ) ) ) { \WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ), $assoc_args ); } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 0a5a66bbf6..fbe6d2a569 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -139,7 +139,7 @@ protected function get_all_items() { * : If set, the plugin will be activated for the entire multisite network. */ function activate( $args, $assoc_args = array() ) { - $network_wide = isset( $assoc_args['network'] ); + $network_wide = ( isset( $assoc_args['network'] ) || isset( $assoc_args['activate-network'] ) ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { activate_plugin( $plugin->file, '', $network_wide ); @@ -348,7 +348,7 @@ protected function filter_item_list( $items, $args ) { * [--activate] * : If set, the plugin will be activated immediately after install. * - * [--network] + * [--activate-network] * : If set, the plugin will be network activated immediately after install * * ## EXAMPLES From cc77c9a58435b8848fd9061504b631c05462739b Mon Sep 17 00:00:00 2001 From: Robert Boloc <robertboloc@gmail.com> Date: Thu, 13 Mar 2014 20:33:36 +0100 Subject: [PATCH 2779/4858] added skip-check param for core.config --- php/commands/core.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8e0eee05b9..c632c9e2dd 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -214,6 +214,9 @@ private static function get_initial_locale() { * [--skip-salts] * : If set, keys and salts won't be generated, but should instead be passed via `--extra-php`. * + * [--skip-check] + * : If set, the datbase connection is not checked. + * * ## EXAMPLES * * # Standard wp-config.php file @@ -244,12 +247,14 @@ public function config( $_, $assoc_args ) { WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); // Check DB connection - Utils\run_mysql_command( 'mysql --no-defaults', array( - 'execute' => ';', - 'host' => $assoc_args['dbhost'], - 'user' => $assoc_args['dbuser'], - 'pass' => $assoc_args['dbpass'], - ) ); + if ( !isset( $assoc_args['skip-check'] ) ) { + Utils\run_mysql_command( 'mysql --no-defaults', array( + 'execute' => ';', + 'host' => $assoc_args['dbhost'], + 'user' => $assoc_args['dbuser'], + 'pass' => $assoc_args['dbpass'], + ) ); + } if ( isset( $assoc_args['extra-php'] ) ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); From a8f1056aaafeb11e698c9045109470339350990f Mon Sep 17 00:00:00 2001 From: Robert Boloc <robertboloc@gmail.com> Date: Thu, 13 Mar 2014 20:39:24 +0100 Subject: [PATCH 2780/4858] fixed typo --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index c632c9e2dd..f2c9247ba7 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -215,7 +215,7 @@ private static function get_initial_locale() { * : If set, keys and salts won't be generated, but should instead be passed via `--extra-php`. * * [--skip-check] - * : If set, the datbase connection is not checked. + * : If set, the database connection is not checked. * * ## EXAMPLES * From d9d43d026215e0e37554062127ddbde284bc4cc4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 13 Mar 2014 12:48:13 -0700 Subject: [PATCH 2781/4858] Fix the semantics of where `activate-network` is handled --- php/WP_CLI/CommandWithUpgrade.php | 8 +++++++- php/commands/plugin.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 79783fa2d2..0fba0e500a 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -143,7 +143,13 @@ function install( $args, $assoc_args ) { } } - if ( $result && ( isset( $assoc_args['activate'] ) || isset( $assoc_args['activate-network'] ) ) ) { + if ( isset( $assoc_args['activate-network'] ) ) { + $assoc_args['activate'] = true; + $assoc_args['network'] = true; + unset( $assoc_args['activate-network'] ); + } + + if ( $result && isset( $assoc_args['activate'] ) ) { \WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ), $assoc_args ); } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index fbe6d2a569..bb4e5eaad3 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -139,7 +139,7 @@ protected function get_all_items() { * : If set, the plugin will be activated for the entire multisite network. */ function activate( $args, $assoc_args = array() ) { - $network_wide = ( isset( $assoc_args['network'] ) || isset( $assoc_args['activate-network'] ) ); + $network_wide = isset( $assoc_args['network'] ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { activate_plugin( $plugin->file, '', $network_wide ); From 7f3bc8de0e181e2e29152287c877c24654b320ef Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Mar 2014 20:42:48 +0000 Subject: [PATCH 2782/4858] 'wp plugin activate' doesn't have an --activate flag --- php/WP_CLI/CommandWithUpgrade.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 0fba0e500a..79bba9ca4a 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -144,7 +144,6 @@ function install( $args, $assoc_args ) { } if ( isset( $assoc_args['activate-network'] ) ) { - $assoc_args['activate'] = true; $assoc_args['network'] = true; unset( $assoc_args['activate-network'] ); } From 92a046ae67f9dc45e50632aa8fd0972718fe486d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Mar 2014 21:25:38 +0000 Subject: [PATCH 2783/4858] avoid reusing $assoc_args when invoking the activate() subcommand --- php/WP_CLI/CommandWithUpgrade.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 79bba9ca4a..5aa067c2ca 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -143,14 +143,16 @@ function install( $args, $assoc_args ) { } } - if ( isset( $assoc_args['activate-network'] ) ) { - $assoc_args['network'] = true; - unset( $assoc_args['activate-network'] ); - } + if ( $result ) { + if ( isset( $assoc_args['activate-network'] ) ) { + \WP_CLI::log( "Network-activating '$slug'..." ); + $this->activate( array( $slug ), array( 'network' => true ) ); + } - if ( $result && isset( $assoc_args['activate'] ) ) { - \WP_CLI::log( "Activating '$slug'..." ); - $this->activate( array( $slug ), $assoc_args ); + if ( isset( $assoc_args['activate'] ) ) { + \WP_CLI::log( "Activating '$slug'..." ); + $this->activate( array( $slug ) ); + } } } } From 1d76f83a007774dd39c0fcb4ac5e60b2f26b5d39 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Mar 2014 22:25:26 +0000 Subject: [PATCH 2784/4858] add functional test for 'wp user delete --reassign' --- features/user.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/features/user.feature b/features/user.feature index 038d184654..5d2170e100 100644 --- a/features/user.feature +++ b/features/user.feature @@ -47,6 +47,27 @@ Feature: Manage WordPress users When I run `wp user delete {USER_ID}` Then STDOUT should not be empty + Scenario: Reassigning user posts + When I run `wp user create bob bob@example.com --role=author --porcelain` + And save STDOUT as {BOB_ID} + + And I run `wp user create sally sally@example.com --role=editor --porcelain` + And save STDOUT as {SALLY_ID} + + When I run `wp post generate --count=3 --post_author=bob` + And I run `wp post list --author={BOB_ID} --format=count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp user delete bob --reassign={SALLY_ID}` + And I run `wp post list --author={SALLY_ID} --format=count` + Then STDOUT should be: + """ + 3 + """ + Scenario: Generating and deleting users When I run `wp user list --role=editor --format=count` Then STDOUT should be: From 30cd4ea914aa03d5b3e2e1dd833df3533d685318 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 13 Mar 2014 22:27:36 +0000 Subject: [PATCH 2785/4858] avoid using wpmu_delete_user(), which doesn't support reassigning posts --- features/user.feature | 17 +++++++++++++---- php/commands/user.php | 8 +------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/features/user.feature b/features/user.feature index 5d2170e100..793c3bf6ad 100644 --- a/features/user.feature +++ b/features/user.feature @@ -1,9 +1,8 @@ Feature: Manage WordPress users - Background: + Scenario: User CRUD operations Given a WP install - Scenario: User CRUD operations When I try `wp user get bogus-user` Then the return code should be 1 And STDOUT should be empty @@ -11,7 +10,8 @@ Feature: Manage WordPress users When I run `wp user create testuser2 testuser2@example.com --role=author --porcelain` Then STDOUT should be a number And save STDOUT as {USER_ID} - And I run `wp user get {USER_ID}` + + When I run `wp user get {USER_ID}` Then STDOUT should be a table containing rows: | Field | Value | | ID | {USER_ID} | @@ -48,6 +48,8 @@ Feature: Manage WordPress users Then STDOUT should not be empty Scenario: Reassigning user posts + Given a WP multisite install + When I run `wp user create bob bob@example.com --role=author --porcelain` And save STDOUT as {BOB_ID} @@ -69,6 +71,8 @@ Feature: Manage WordPress users """ Scenario: Generating and deleting users + Given a WP install + When I run `wp user list --role=editor --format=count` Then STDOUT should be: """ @@ -90,7 +94,8 @@ Feature: Manage WordPress users """ Scenario: Importing users from a CSV file - Given a users.csv file: + Given a WP install + And a users.csv file: """ user_login,user_email,display_name,role bobjones,bobjones@domain.com,Bob Jones,contributor @@ -119,6 +124,8 @@ Feature: Manage WordPress users """ Scenario: Managing user roles + Given a WP install + When I run `wp user add-role 1 editor` Then STDOUT should not be empty And I run `wp user get 1 --field=roles` @@ -167,6 +174,8 @@ Feature: Manage WordPress users | roles | | Scenario: Managing user capabilities + Given a WP install + When I run `wp user add-cap 1 edit_vip_product` Then STDOUT should be: """ diff --git a/php/commands/user.php b/php/commands/user.php index 49ad2b6c64..cb327b24ca 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -132,13 +132,7 @@ public function delete( $args, $assoc_args ) { parent::_delete( $users, $assoc_args, function ( $user, $assoc_args ) { $user_id = $user->ID; - if ( is_multisite() ) { - $r = wpmu_delete_user( $user_id ); - } else { - $r = wp_delete_user( $user_id, $assoc_args['reassign'] ); - } - - if ( $r ) { + if ( wp_delete_user( $user_id, $assoc_args['reassign'] ) ) { return array( 'success', "Deleted user $user_id." ); } else { return array( 'error', "Failed deleting user $user_id." ); From f3018676e3de83cb85383b6e9e194caae2664fad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Mar 2014 15:00:05 +0000 Subject: [PATCH 2786/4858] clarify scope of 'wp user delete'; see #1072 --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index cb327b24ca..b3ce47bc34 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -108,7 +108,7 @@ public function get( $args, $assoc_args ) { } /** - * Delete one or more users. + * Delete one or more users from the current site. * * ## OPTIONS * From c5b7d154b6977a771e475616da365c9eaf4c5592 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 14 Mar 2014 14:07:12 -0700 Subject: [PATCH 2787/4858] tests for skip-plugins flag --- features/flags.feature | 86 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index acb13f7700..97ddb16b01 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -241,3 +241,89 @@ Feature: Global flags """ <file> """ + + Scenario: Not skipping a plugin + Given a WP install + + When I run `wp plugin activate hello` + And I run `wp eval 'echo hello_dolly();'` + Then STDOUT should contain: + """ + id='dolly' + """ + + Scenario: Skipping a plugin + Given a WP install + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();' --skip-plugins=hello` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + Scenario: Skipping multiple plugins + Given a WP install + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();' --skip-plugins=hello,akismet` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + Scenario: Skipping all plugins + Given a WP install + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();' --skip-plugins` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + Scenario: Skipping a plugin with wp-cli.yml + Given a WP install + And a wp-cli.yml file: + """ + skip-plugins: + - hello + """ + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();'` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + Scenario: Skipping multiple plugins with wp-cli.yml + Given a WP install + And a wp-cli.yml file: + """ + skip-plugins: + - hello + - akismet + """ + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();'` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + Scenario: Skipping all plugins with wp-cli.yml + Given a WP install + And a wp-cli.yml file: + """ + skip-plugins: true + """ + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();'` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + From f3e8883475aab0ceb80b9a962271e929e2f5c13d Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 14 Mar 2014 21:39:25 +0000 Subject: [PATCH 2788/4858] remove duplicate --skip-plugins tests and move to separate file see #1062 --- features/flags.feature | 135 ---------------------------------- features/skip-plugins.feature | 87 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 135 deletions(-) create mode 100644 features/skip-plugins.feature diff --git a/features/flags.feature b/features/flags.feature index 97ddb16b01..064648099e 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -92,55 +92,6 @@ Feature: Global flags log: called 'error' method """ - Scenario: Skipping plugins - Given a WP install - And I run `wp plugin activate hello akismet` - - When I run `wp eval 'var_export( defined("AKISMET_VERSION") );'` - Then STDOUT should be: - """ - true - """ - - When I run `wp eval 'var_export( function_exists( "hello_dolly" ) );'` - Then STDOUT should be: - """ - true - """ - - # The specified plugin should be skipped - When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );'` - Then STDOUT should be: - """ - false - """ - - # The specified plugin should still show up as an active plugin - When I run `wp --skip-plugins=akismet plugin status` - Then STDOUT should contain: - """ - akismet - """ - - # The un-specified plugin should continue to be loaded - When I run `wp --skip-plugins=akismet eval 'var_export( function_exists( "hello_dolly" ) );'` - Then STDOUT should be: - """ - true - """ - - # No plugins should be loaded when --skip-plugins doesn't have a value - When I run `wp --skip-plugins eval 'var_export( defined("AKISMET_VERSION") );'` - Then STDOUT should be: - """ - false - """ - When I run `wp --skip-plugins eval 'var_export( function_exists( "hello_dolly" ) );'` - Then STDOUT should be: - """ - false - """ - Scenario: Using --require Given an empty directory And a custom-cmd.php file: @@ -241,89 +192,3 @@ Feature: Global flags """ <file> """ - - Scenario: Not skipping a plugin - Given a WP install - - When I run `wp plugin activate hello` - And I run `wp eval 'echo hello_dolly();'` - Then STDOUT should contain: - """ - id='dolly' - """ - - Scenario: Skipping a plugin - Given a WP install - - When I run `wp plugin activate hello` - And I try `wp eval 'echo hello_dolly();' --skip-plugins=hello` - Then STDERR should contain: - """ - Call to undefined function hello_dolly() - """ - - Scenario: Skipping multiple plugins - Given a WP install - - When I run `wp plugin activate hello` - And I try `wp eval 'echo hello_dolly();' --skip-plugins=hello,akismet` - Then STDERR should contain: - """ - Call to undefined function hello_dolly() - """ - - Scenario: Skipping all plugins - Given a WP install - - When I run `wp plugin activate hello` - And I try `wp eval 'echo hello_dolly();' --skip-plugins` - Then STDERR should contain: - """ - Call to undefined function hello_dolly() - """ - - Scenario: Skipping a plugin with wp-cli.yml - Given a WP install - And a wp-cli.yml file: - """ - skip-plugins: - - hello - """ - - When I run `wp plugin activate hello` - And I try `wp eval 'echo hello_dolly();'` - Then STDERR should contain: - """ - Call to undefined function hello_dolly() - """ - - Scenario: Skipping multiple plugins with wp-cli.yml - Given a WP install - And a wp-cli.yml file: - """ - skip-plugins: - - hello - - akismet - """ - - When I run `wp plugin activate hello` - And I try `wp eval 'echo hello_dolly();'` - Then STDERR should contain: - """ - Call to undefined function hello_dolly() - """ - - Scenario: Skipping all plugins with wp-cli.yml - Given a WP install - And a wp-cli.yml file: - """ - skip-plugins: true - """ - - When I run `wp plugin activate hello` - And I try `wp eval 'echo hello_dolly();'` - Then STDERR should contain: - """ - Call to undefined function hello_dolly() - """ - diff --git a/features/skip-plugins.feature b/features/skip-plugins.feature new file mode 100644 index 0000000000..2dc828d8c8 --- /dev/null +++ b/features/skip-plugins.feature @@ -0,0 +1,87 @@ +Feature: Skipping plugins + + Scenario: Skipping plugins via global flag + Given a WP install + And I run `wp plugin activate hello akismet` + + When I run `wp eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp eval 'var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + true + """ + + # The specified plugin should be skipped + When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + false + """ + + # The specified plugin should still show up as an active plugin + When I run `wp --skip-plugins=akismet plugin status` + Then STDOUT should contain: + """ + akismet + """ + + # The un-specified plugin should continue to be loaded + When I run `wp --skip-plugins=akismet eval 'var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + true + """ + + # Can specify multiple plugins to skip + When I try `wp eval --skip-plugins=hello,akismet 'echo hello_dolly();'` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + # No plugins should be loaded when --skip-plugins doesn't have a value + When I run `wp --skip-plugins eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + false + """ + When I run `wp --skip-plugins eval 'var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + false + """ + + Scenario: Skipping multiple plugins via config file + Given a WP install + And a wp-cli.yml file: + """ + skip-plugins: + - hello + - akismet + """ + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();'` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ + + Scenario: Skipping all plugins via config file + Given a WP install + And a wp-cli.yml file: + """ + skip-plugins: true + """ + + When I run `wp plugin activate hello` + And I try `wp eval 'echo hello_dolly();'` + Then STDERR should contain: + """ + Call to undefined function hello_dolly() + """ From f6fae0eb17807df135d42ba58e5ab5ba5e2b4701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Mon, 17 Mar 2014 16:15:17 +0100 Subject: [PATCH 2789/4858] removing block comments --- templates/wp-config.mustache | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index e708cc189e..6951c9bb0c 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -1,15 +1,7 @@ <?php -/** - * The base configurations of the WordPress. - * - * This file has the following configurations: MySQL settings, Table Prefix, - * Secret Keys, WordPress Language, and ABSPATH. You can find more information - * by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing - * wp-config.php} Codex page. You can get the MySQL settings from your web host. - * @package WordPress - */ -// ** MySQL settings - You can get this info from your web host ** // + +// ** MySQL settings ** // /** The name of the database for WordPress */ define('DB_NAME', '{{dbname}}'); @@ -29,37 +21,16 @@ define('DB_CHARSET', '{{dbcharset}}'); define('DB_COLLATE', '{{dbcollate}}'); {{#keys-and-salts}} -/**#@+ - * Authentication Unique Keys and Salts. - * - * Change these to different unique phrases! - * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} - * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again. - */ {{keys-and-salts}} -/**#@-*/ {{/keys-and-salts}} -/** - * WordPress Database Table prefix. - * - * You can have multiple installations in one database if you give each a unique - * prefix. Only numbers, letters, and underscores please! - */ $table_prefix = '{{dbprefix}}'; -/** - * WordPress Localized Language, defaults to English. - * - * Change this to localize WordPress. A corresponding MO file for the chosen - * language must be installed to wp-content/languages. For example, install - * de_DE.mo to wp-content/languages and set WPLANG to 'de_DE' to enable German - * language support. - */ define('WPLANG', '{{locale}}'); {{extra-php}} + /* That's all, stop editing! Happy blogging. */ /** Absolute path to the WordPress directory. */ From 6f8bbe2771e8246adaf59b9473b76215375966dc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Mar 2014 17:56:25 +0200 Subject: [PATCH 2790/4858] add missing OPTIONS header to 'wp db import' docs --- php/commands/db.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/db.php b/php/commands/db.php index 2230470dec..15e1b1e635 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -162,6 +162,8 @@ function export( $args, $assoc_args ) { /** * Import database from a file or from STDIN. * + * ## OPTIONS + * * [<file>] * : The name of the SQL file to import. If '-', then reads from STDIN. If omitted, it will look for '{dbname}.sql'. */ From bbc6e08065f19119638c064dce0a37c7ea37e933 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Mon, 24 Mar 2014 17:56:54 +0200 Subject: [PATCH 2791/4858] first pass at 'wp db tables' command --- php/WP_CLI/Runner.php | 2 +- php/commands/db.php | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index bec000fb7f..7a4cf01639 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -526,7 +526,7 @@ public function before_wp_load() { "Either create one manually or use `wp core config`." ); } - if ( $this->cmd_starts_with( array( 'db' ) ) ) { + if ( $this->cmd_starts_with( array( 'db' ) ) && !$this->cmd_starts_with( array( 'db', 'tables' ) ) ) { eval( $this->get_wp_config_code() ); $this->_run_command(); exit; diff --git a/php/commands/db.php b/php/commands/db.php index 15e1b1e635..72ccd75268 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -195,6 +195,31 @@ function import( $args, $assoc_args ) { WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); } + /** + * List the database tables. + * + * ## OPTIONS + * + * [--scope=<scope>] + * : Can be all, global, ms_global, blog, or old tables. Defaults to all. + * + * ## EXAMPLES + * + * # Export only tables for a single site + * wp db export --tables=$(wp db tables --url=sub.example.com | tr '\n' ',') + */ + function tables( $args, $assoc_args ) { + global $wpdb; + + $scope = isset( $assoc_args['scope'] ) ? $assoc_args['scope'] : 'all'; + + $tables = $wpdb->tables( $scope ); + + foreach ( $tables as $table ) { + WP_CLI::line( $table ); + } + } + private function get_file_name( $args ) { if ( empty( $args ) ) return sprintf( '%s.sql', DB_NAME ); From 65cf004239eb29b4003f0b854a31af677b5d12a0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 25 Mar 2014 09:55:14 +0200 Subject: [PATCH 2792/4858] fix handling of --post_category parameter; closes #986 --- php/commands/post.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index f179634192..05a2184dfb 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -48,7 +48,7 @@ public function __construct() { * * wp post create --post_type=page --post_status=publish --post_title='A future post' --post-status=future --post_date='2020-12-01 07:00:00' * - * wp post create page.txt --post_type=page --post_title='Page from file' + * wp post create ./post-content.txt --post_category=201,345 --post_title='Post from file' */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { @@ -74,6 +74,10 @@ public function create( $args, $assoc_args ) { $assoc_args['post_content'] = $input; } + if ( isset( $assoc_args['post_category'] ) ) { + $assoc_args['post_category'] = explode( ',', $assoc_args['post_category'] ); + } + parent::_create( $args, $assoc_args, function ( $params ) { return wp_insert_post( $params, true ); } ); From 0f97042c634dd6f115d9d9c67700294890996736 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 27 Mar 2014 07:49:55 +0200 Subject: [PATCH 2793/4858] use putenv() instead of relying on Bash inline variables fixes #1086 --- php/utils.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/php/utils.php b/php/utils.php index a46e45f65c..b918d1824e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -323,10 +323,11 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { $assoc_args = array_merge( $assoc_args, mysql_host_to_cli_args( $assoc_args['host'] ) ); } - if ( isset( $assoc_args['pass'] ) ) { - $cmd = esc_cmd( 'MYSQL_PWD=%s ', $assoc_args['pass'] ) . $cmd; - unset( $assoc_args['pass'] ); - } + $pass = $assoc_args['pass']; + unset( $assoc_args['pass'] ); + + $old_pass = getenv( 'MYSQL_PWD' ); + putenv( 'MYSQL_PWD=' . $pass ); $final_cmd = $cmd . assoc_args_to_str( $assoc_args ); @@ -336,6 +337,8 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { $r = proc_close( $proc ); + putenv( 'MYSQL_PWD=' . $old_pass ); + if ( $r ) exit( $r ); } From fb4942f6bbbece59344f29c6c20e318272ed7c7f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 27 Mar 2014 08:22:52 +0200 Subject: [PATCH 2794/4858] wp cache: remove redundant exit calls and use WP_CLI::line() --- php/commands/cache.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/php/commands/cache.php b/php/commands/cache.php index ad0a8eafe4..0c9274811b 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -25,7 +25,6 @@ public function add( $args, $assoc_args ) { if ( ! wp_cache_add( $key, $value, $group, $expiration ) ) { WP_CLI::error( "Could not add object '$key' in group '$group'. Does it already exist?" ); - exit; } WP_CLI::success( "Added object '$key' in group '$group'." ); @@ -66,7 +65,6 @@ public function delete( $args, $assoc_args ) { if ( false === $result ) { WP_CLI::error( 'The object was not deleted.' ); - exit; } WP_CLI::success( 'Object deleted.' ); @@ -80,7 +78,6 @@ public function flush( $args, $assoc_args ) { if ( false === $value ) { WP_CLI::error( 'The object cache could not be flushed.' ); - exit; } WP_CLI::success( 'The cache was flushed.' ); @@ -100,7 +97,6 @@ public function get( $args, $assoc_args ) { if ( false === $value ) { WP_CLI::error( "Object with key '$key' and group '$group' not found." ); - exit; } WP_CLI::print_value( $value, $assoc_args ); @@ -122,7 +118,6 @@ public function incr( $args, $assoc_args ) { if ( false === $value ) { WP_CLI::error( 'The value was not incremented.' ); - exit; } WP_CLI::print_value( $value, $assoc_args ); @@ -144,7 +139,6 @@ public function replace( $args, $assoc_args ) { if ( false === $result ) { WP_CLI::error( "Could not replace object '$key' in group '$group'. Does it already exist?" ); - exit; } WP_CLI::success( "Replaced object '$key' in group '$group'." ); @@ -166,7 +160,6 @@ public function set( $args, $assoc_args ) { if ( false === $result ) { WP_CLI::error( "Could not add object '$key' in group '$group'." ); - exit; } WP_CLI::success( "Set object '$key' in group '$group'." ); @@ -221,7 +214,7 @@ public function type( $args, $assoc_args ) { $message = 'Default'; } - WP_CLI::print_value( $message ); + WP_CLI::line( $message ); } } From 08121cb4df0a305eae1fccd3875c80994c2ed626 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 27 Mar 2014 08:38:53 +0200 Subject: [PATCH 2795/4858] abort loading if APC object cache is detected see #283 --- php/wp-settings-cli.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index d566ec1d2a..3d3d2ba17e 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -93,6 +93,11 @@ // Start the WordPress object cache, or an external object cache if the drop-in is present. wp_start_object_cache(); +// WP-CLI: the APC cache is not available on the command-line, so bail, to prevent cache poisoning +if ( wp_using_ext_object_cache() && class_exists( 'APC_Object_Cache' ) ) { + WP_CLI::error( 'WP-CLI is not compatible with the APC object cache.' ); +} + // Attach the default filters. require( ABSPATH . WPINC . '/default-filters.php' ); From b24ddf1b0423542db6db3520bd04774b41e7f3fc Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 27 Mar 2014 08:49:54 +0200 Subject: [PATCH 2796/4858] avoid using wp_using_ext_object_cache() function, which was only introduced in WP 3.7 --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 3d3d2ba17e..4014958818 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -94,7 +94,7 @@ wp_start_object_cache(); // WP-CLI: the APC cache is not available on the command-line, so bail, to prevent cache poisoning -if ( wp_using_ext_object_cache() && class_exists( 'APC_Object_Cache' ) ) { +if ( $GLOBALS['_wp_using_ext_object_cache'] && class_exists( 'APC_Object_Cache' ) ) { WP_CLI::error( 'WP-CLI is not compatible with the APC object cache.' ); } From 98e7f61fd2569f9ded5625efc2a1eb2dc13aa101 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 27 Mar 2014 09:03:24 +0200 Subject: [PATCH 2797/4858] make search-replace work with tables that have a composite primary key --- php/commands/search-replace.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index d24d6ce9a3..e6a8739dfd 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -65,11 +65,11 @@ public function __invoke( $args, $assoc_args ) { $tables = self::get_table_list( $args, isset( $assoc_args['network'] ) ); foreach ( $tables as $table ) { - list( $primary_key, $columns ) = self::get_columns( $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 ( null === $primary_key ) { + if ( empty( $primary_keys ) ) { $report[] = array( $table, '', 'skipped' ); continue; } @@ -78,7 +78,7 @@ public function __invoke( $args, $assoc_args ) { if ( in_array( $col, $skip_columns ) ) continue; - $count = self::handle_col( $col, $primary_key, $table, $old, $new, $dry_run, $recurse_objects ); + $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); $report[] = array( $table, $col, $count ); @@ -106,13 +106,15 @@ private static function get_table_list( $args, $network ) { return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } - private static function handle_col( $col, $primary_key, $table, $old, $new, $dry_run, $recurse_objects ) { + private static function handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite $chunk_size = getenv( 'BEHAT_RUN' ) ? 10 : 1000; - $fields = array( $primary_key, $col ); + $fields = $primary_keys; + $fields[] = $col; + $args = array( 'table' => $table, 'fields' => $fields, @@ -136,10 +138,12 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry if ( $value != $row->$col ) $count++; } else { - $count += $wpdb->update( $table, - array( $col => $value ), - array( $primary_key => $row->$primary_key ) - ); + $where = array(); + foreach ( $primary_keys as $primary_key ) { + $where[ $primary_key ] = $row->$primary_key; + } + + $count += $wpdb->update( $table, array( $col => $value ), $where ); } } @@ -149,13 +153,13 @@ private static function handle_col( $col, $primary_key, $table, $old, $new, $dry private static function get_columns( $table ) { global $wpdb; - $primary_key = null; + $primary_keys = array(); $columns = array(); foreach ( $wpdb->get_results( "DESCRIBE $table" ) as $col ) { if ( 'PRI' === $col->Key ) { - $primary_key = $col->Field; + $primary_keys[] = $col->Field; continue; } @@ -165,7 +169,7 @@ private static function get_columns( $table ) { $columns[] = $col->Field; } - return array( $primary_key, $columns ); + return array( $primary_keys, $columns ); } private static function is_text_col( $type ) { From 2c83d8a408dcd3af1d6bc0698268802c854d0d0f Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 12:34:40 +0000 Subject: [PATCH 2798/4858] delete all and expired transient commands --- php/commands/transient.php | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index 11fc6c09d9..d212607729 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -74,6 +74,54 @@ public function type() { WP_CLI::line( $message ); } + + /** + * Delete all expired transients. + * + * @subcommand delete-expired + */ + public function delete_expired() { + global $wpdb; + + // Always delete all transients from DB too. + $time = time(); + $wpdb->query( + "DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE + a.option_name LIKE '\_transient\_%' AND + a.option_name NOT LIKE '\_transient\_timeout\_%' AND + b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) ) + AND b.option_value < $time" + ); + + WP_CLI::success( 'Expired transients deleted from the database.' ); + + if ( wp_using_ext_object_cache() ) { + WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); + } + } + + /** + * Delete all transients. + * + * @subcommand delete-all + */ + public function delete_all() { + global $wpdb; + + // Always delete all transients from DB too. + $wpdb->query( + "DELETE FROM $wpdb->options + WHERE option_name LIKE '\_transient\_%' + OR option_name LIKE '\_site\_transient\_%'" + ); + + WP_CLI::success( 'All transients deleted from the database.' ); + + if ( wp_using_ext_object_cache() ) { + WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); + } + } + } WP_CLI::add_command( 'transient', 'Transient_Command' ); From b36d7240963459ac0d018b409a0cac8cc50324b3 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 13:09:27 +0000 Subject: [PATCH 2799/4858] Use global _wp_using_ext_object_cache directly for backwards compatibility --- php/commands/transient.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index d212607729..6bdfc3a201 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -81,7 +81,7 @@ public function type() { * @subcommand delete-expired */ public function delete_expired() { - global $wpdb; + global $wpdb, $_wp_using_ext_object_cache; // Always delete all transients from DB too. $time = time(); @@ -95,7 +95,7 @@ public function delete_expired() { WP_CLI::success( 'Expired transients deleted from the database.' ); - if ( wp_using_ext_object_cache() ) { + if ( $_wp_using_ext_object_cache ) { WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); } } @@ -106,7 +106,7 @@ public function delete_expired() { * @subcommand delete-all */ public function delete_all() { - global $wpdb; + global $wpdb, $_wp_using_ext_object_cache; // Always delete all transients from DB too. $wpdb->query( @@ -117,7 +117,7 @@ public function delete_all() { WP_CLI::success( 'All transients deleted from the database.' ); - if ( wp_using_ext_object_cache() ) { + if ( $_wp_using_ext_object_cache ) { WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); } } From 50350a8892c22a2bdb456af84e94d00c9d6fca92 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 13:09:51 +0000 Subject: [PATCH 2800/4858] Use WordPress current_time instead of PHP time --- php/commands/transient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 6bdfc3a201..4c4b094044 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -84,8 +84,8 @@ public function delete_expired() { global $wpdb, $_wp_using_ext_object_cache; // Always delete all transients from DB too. - $time = time(); - $wpdb->query( + $time = current_time(); + $count = $wpdb->query( "DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE a.option_name LIKE '\_transient\_%' AND a.option_name NOT LIKE '\_transient\_timeout\_%' AND From 56b9b696bd4d8774c74acc610063a7961c30e380 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 13:10:17 +0000 Subject: [PATCH 2801/4858] Pass count rows affected to success message --- php/commands/transient.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 4c4b094044..fa275dff3e 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -93,7 +93,7 @@ public function delete_expired() { AND b.option_value < $time" ); - WP_CLI::success( 'Expired transients deleted from the database.' ); + WP_CLI::success( "$count expired transients deleted from the database." ); if ( $_wp_using_ext_object_cache ) { WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); @@ -109,13 +109,13 @@ public function delete_all() { global $wpdb, $_wp_using_ext_object_cache; // Always delete all transients from DB too. - $wpdb->query( - "DELETE FROM $wpdb->options - WHERE option_name LIKE '\_transient\_%' + $count = $wpdb->query( + "DELETE FROM $wpdb->options + WHERE option_name LIKE '\_transient\_%' OR option_name LIKE '\_site\_transient\_%'" ); - WP_CLI::success( 'All transients deleted from the database.' ); + WP_CLI::success( "$count expired transients deleted from the database." ); if ( $_wp_using_ext_object_cache ) { WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); From 91bb83cf4d9ad4a8254a80d66ff4b7cb405c31b7 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 13:39:16 +0000 Subject: [PATCH 2802/4858] display different notice if no transients found --- php/commands/transient.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index fa275dff3e..8caec0c3bc 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -93,7 +93,11 @@ public function delete_expired() { AND b.option_value < $time" ); - WP_CLI::success( "$count expired transients deleted from the database." ); + if ( $count > 0 ) { + WP_CLI::success( "$count expired transients deleted from the database." ); + } else { + WP_CLI::success( "No transients found" ); + } if ( $_wp_using_ext_object_cache ) { WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); @@ -115,7 +119,11 @@ public function delete_all() { OR option_name LIKE '\_site\_transient\_%'" ); - WP_CLI::success( "$count expired transients deleted from the database." ); + if ( $count > 0 ) { + WP_CLI::success( "$count transients deleted from the database." ); + } else { + WP_CLI::success( "No transients found" ); + } if ( $_wp_using_ext_object_cache ) { WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.'); From b9f540c786517c2b2fdce7d18eec3681ece2c255 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 13:40:54 +0000 Subject: [PATCH 2803/4858] oops... pass timestamp to current_time --- php/commands/transient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 8caec0c3bc..f76461e94f 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -84,7 +84,7 @@ public function delete_expired() { global $wpdb, $_wp_using_ext_object_cache; // Always delete all transients from DB too. - $time = current_time(); + $time = current_time('timestamp'); $count = $wpdb->query( "DELETE a, b FROM $wpdb->options a, $wpdb->options b WHERE a.option_name LIKE '\_transient\_%' AND From 5862de31ba694dd8bc147da9d06e1f6515497f88 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 28 Mar 2014 13:42:23 +0000 Subject: [PATCH 2804/4858] better message text --- php/commands/transient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index f76461e94f..16248d4548 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -96,7 +96,7 @@ public function delete_expired() { if ( $count > 0 ) { WP_CLI::success( "$count expired transients deleted from the database." ); } else { - WP_CLI::success( "No transients found" ); + WP_CLI::success( "No expired transients found" ); } if ( $_wp_using_ext_object_cache ) { From 68b46b747ca3404391cd5c2f9bd53b36c4e6ff92 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 28 Mar 2014 20:55:24 -0700 Subject: [PATCH 2805/4858] Make post id optional in wp comment count --- php/commands/comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 285059757d..8c19ed0a73 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -307,7 +307,7 @@ public function unapprove( $args, $assoc_args ) { * * ## OPTIONS * - * <post-id> + * [<post-id>] * : The ID of the post to count comments in. * * ## EXAMPLES From f47e6b9523e4d546ee66907e8d12a0b8fdc3d04a Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Fri, 28 Mar 2014 22:07:00 -0700 Subject: [PATCH 2806/4858] behat tests for 'wp comment count' --- features/comment.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 269ae1015f..1451e79063 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -60,3 +60,26 @@ Feature: Manage WordPress comments """ http://example.com/?p=1#comment-1 """ + + Scenario: Count comments + When I run `wp comment count 1` + Then STDOUT should be: + """ + approved: 1 + moderated: 0 + spam: 0 + trash: 0 + post-trashed: 0 + total_comments: 1 + """ + + When I run `wp comment count` + Then STDOUT should be: + """ + approved: 1 + moderated: 0 + spam: 0 + trash: 0 + post-trashed: 0 + total_comments: 1 + """ From 56953f76600b011cade9d54ecd1d382e881ec34f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 31 Mar 2014 08:25:39 -0700 Subject: [PATCH 2807/4858] Few PHP docs for the `Subcommand` class --- php/WP_CLI/Dispatcher/Subcommand.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 860b3c3666..c3e0d3badc 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -37,14 +37,32 @@ function get_synopsis() { return $this->synopsis; } + /** + * If an alias is set, grant access to it + * Aliases permit subcommands to be instantiated + * with a secondary identity + * + * @return string + */ function get_alias() { return $this->alias; } + /** + * Print the usage details to the end user + * + * @param string $prefix + */ function show_usage( $prefix = 'usage: ' ) { \WP_CLI::line( $this->get_usage( $prefix ) ); } + /** + * Get the usage of the subcommand as a formatted string + * + * @param string $prefix + * @return string + */ function get_usage( $prefix ) { return sprintf( "%s%s %s", $prefix, From c9963f39b5eecdf6a77fa22145ab8e3ac8450198 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 31 Mar 2014 08:28:39 -0700 Subject: [PATCH 2808/4858] Docs for the User fetcher --- php/WP_CLI/Fetchers/User.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/WP_CLI/Fetchers/User.php b/php/WP_CLI/Fetchers/User.php index 65e2f9c0fb..5b8e0a63ae 100644 --- a/php/WP_CLI/Fetchers/User.php +++ b/php/WP_CLI/Fetchers/User.php @@ -2,10 +2,22 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress user based on one of its attributes. + */ class User extends Base { + /** + * @param string $msg Error message to use when invalid data is provided + */ protected $msg = "Invalid user ID, email or login: '%s'"; + /** + * Get a user object by one of its identifying attributes + * + * @param mixed $id_email_or_login + * @return WP_User|false + */ public function get( $id_email_or_login ) { if ( is_numeric( $id_email_or_login ) ) From d0ff55cd2fa658cf52f44337c6ce7b1fe5038344 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 31 Mar 2014 08:29:48 -0700 Subject: [PATCH 2809/4858] PHPdoc for Fetcher base command --- php/WP_CLI/Fetchers/Base.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/Fetchers/Base.php b/php/WP_CLI/Fetchers/Base.php index 9e4ebc3100..262e1bfab1 100644 --- a/php/WP_CLI/Fetchers/Base.php +++ b/php/WP_CLI/Fetchers/Base.php @@ -2,6 +2,9 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress entity for use in a subcommand. + */ abstract class Base { /** From ed47187207ee98eb8cc91e8cc31d2215c551849f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 31 Mar 2014 08:35:14 -0700 Subject: [PATCH 2810/4858] Copy pasta documentation for the rest of the fetcher classes --- php/WP_CLI/Fetchers/Comment.php | 12 ++++++++++++ php/WP_CLI/Fetchers/Plugin.php | 12 ++++++++++++ php/WP_CLI/Fetchers/Post.php | 12 ++++++++++++ php/WP_CLI/Fetchers/Site.php | 12 ++++++++++++ php/WP_CLI/Fetchers/Theme.php | 12 ++++++++++++ 5 files changed, 60 insertions(+) diff --git a/php/WP_CLI/Fetchers/Comment.php b/php/WP_CLI/Fetchers/Comment.php index 296b2533b9..027030452c 100644 --- a/php/WP_CLI/Fetchers/Comment.php +++ b/php/WP_CLI/Fetchers/Comment.php @@ -2,10 +2,22 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress comment based on one of its attributes. + */ class Comment extends Base { + /** + * @param string $msg Error message to use when invalid data is provided + */ protected $msg = "Could not find the comment with ID %d."; + /** + * Get a comment object by ID + * + * @param int $arg + * @return object|false + */ public function get( $arg ) { $comment_id = (int) $arg; $comment = get_comment( $comment_id ); diff --git a/php/WP_CLI/Fetchers/Plugin.php b/php/WP_CLI/Fetchers/Plugin.php index 37f3e10a0e..36235a85a7 100644 --- a/php/WP_CLI/Fetchers/Plugin.php +++ b/php/WP_CLI/Fetchers/Plugin.php @@ -2,10 +2,22 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress plugin based on one of its attributes. + */ class Plugin extends Base { + /** + * @param string $msg Error message to use when invalid data is provided + */ protected $msg = "The '%s' plugin could not be found."; + /** + * Get a plugin object by name + * + * @param string $name + * @return object|false + */ public function get( $name ) { foreach ( get_plugins() as $file => $_ ) { if ( $file === "$name.php" || diff --git a/php/WP_CLI/Fetchers/Post.php b/php/WP_CLI/Fetchers/Post.php index 4944561e3a..402a6f1f1e 100644 --- a/php/WP_CLI/Fetchers/Post.php +++ b/php/WP_CLI/Fetchers/Post.php @@ -2,10 +2,22 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress post based on one of its attributes. + */ class Post extends Base { + /** + * @param string $msg Error message to use when invalid data is provided + */ protected $msg = "Could not find the post with ID %d."; + /** + * Get a post object by ID + * + * @param int $arg + * @return WP_Post|false + */ public function get( $arg ) { return get_post( $arg ); } diff --git a/php/WP_CLI/Fetchers/Site.php b/php/WP_CLI/Fetchers/Site.php index 1eaca959ee..b3de873603 100644 --- a/php/WP_CLI/Fetchers/Site.php +++ b/php/WP_CLI/Fetchers/Site.php @@ -2,10 +2,22 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress site based on one of its attributes. + */ class Site extends Base { + /** + * @param string $msg Error message to use when invalid data is provided + */ protected $msg = "Could not find the site with ID %d."; + /** + * Get a site object by ID + * + * @param int $site_id + * @return object|false + */ public function get( $site_id ) { return $this->_get_site( $site_id ); } diff --git a/php/WP_CLI/Fetchers/Theme.php b/php/WP_CLI/Fetchers/Theme.php index 1c3380502e..c3e3357e4e 100644 --- a/php/WP_CLI/Fetchers/Theme.php +++ b/php/WP_CLI/Fetchers/Theme.php @@ -2,10 +2,22 @@ namespace WP_CLI\Fetchers; +/** + * Fetch a WordPress theme based on one of its attributes. + */ class Theme extends Base { + /** + * @param string $msg Error message to use when invalid data is provided + */ protected $msg = "The '%s' theme could not be found."; + /** + * Get a theme object by name + * + * @param string $name + * @return object|false + */ public function get( $name ) { $theme = wp_get_theme( $name ); From 5476ebf556fe74b8972ffd68bee5d3d2c12605fa Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Sat, 5 Apr 2014 20:49:02 +0100 Subject: [PATCH 2811/4858] fix wp-cli/wp-cli#1036 --- php/commands/media.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 254942f4f3..f6e0261a25 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -236,7 +236,8 @@ private function remove_old_images( $att_id ) { if ( $intermediate_path == $original_path ) continue; - unlink( $intermediate_path ); + if ( file_exists( $intermediate_path ) ) + unlink( $intermediate_path ); } } } From 20099c177db002643cc2e9a924dc7183aa2c0d5d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 12:56:29 -0700 Subject: [PATCH 2812/4858] Command to list registered sidebars --- features/sidebar.feature | 12 +++++++++++ php/commands/sidebar.php | 46 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 features/sidebar.feature create mode 100644 php/commands/sidebar.php diff --git a/features/sidebar.feature b/features/sidebar.feature new file mode 100644 index 0000000000..1126cfa98e --- /dev/null +++ b/features/sidebar.feature @@ -0,0 +1,12 @@ +Feature: Manage WordPress sidebars + + Scenario: List available sidebars + Given a WP install + + When I run `wp theme install p2 --activate` + Then STDOUT should not be empty + + When I run `wp sidebar list --fields=name,id` + Then STDOUT should be a table containing rows: + | name | id | + | Sidebar | sidebar-1 | diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php new file mode 100644 index 0000000000..9e930f83f3 --- /dev/null +++ b/php/commands/sidebar.php @@ -0,0 +1,46 @@ +<?php + +/** + * Manage sidebars. + */ +class Sidebar_Command extends WP_CLI_Command { + + private $fields = array( + 'name', + 'id', + 'description' + ); + + /** + * List registered sidebars. + * + * ## OPTIONS + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to name, id, description + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## EXAMPLES + * + * wp sidebar list --fields=role --format=csv + * + * @subcommand list + */ + public function _list( $args, $assoc_args ) { + global $wp_registered_sidebars; + + $output_sidebars = array(); + foreach( $wp_registered_sidebars as $registered_sidebar ) { + $output_sidebars[] = (object)$registered_sidebar; + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); + $formatter->display_items( $output_sidebars ); + + } + +} + +WP_CLI::add_command( 'sidebar', 'Sidebar_Command' ); From dba201d62eadccc3ed3331c73023e0fd30b6f7a6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 13:15:31 -0700 Subject: [PATCH 2813/4858] Fix copy pasta --- php/commands/sidebar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 9e930f83f3..afd55d8606 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -24,7 +24,7 @@ class Sidebar_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp sidebar list --fields=role --format=csv + * wp sidebar list --fields=name,id --format=csv * * @subcommand list */ From 16892f074fc2d688f267299cdfabd63c68e3bc27 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 15:15:29 -0700 Subject: [PATCH 2814/4858] Update `WP_CLI\Utils\load_command()` to handle commands like `sidebar widget` Previously, `load_command()` only supported commands where the name matched exactly (e.g. `wp post` and `post.php`). The `* meta` commands escaped this by defining their classes within the parent class file. This change means `wp sidebar widget` will resolve to `sidebar-widget.php`, as well as `sidebar.php` --- php/WP_CLI/Runner.php | 2 +- php/utils.php | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7a4cf01639..b685ee3377 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -479,7 +479,7 @@ public function before_wp_load() { // Load bundled commands early, so that they're forced to use the same // APIs as non-bundled commands. - Utils\load_command( $this->arguments[0] ); + Utils\load_command( $this->arguments ); if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { diff --git a/php/utils.php b/php/utils.php index b918d1824e..c697df9289 100644 --- a/php/utils.php +++ b/php/utils.php @@ -41,12 +41,30 @@ function load_file( $path ) { require $path; } +/** + * Load a given internal WP-CLI command + * + * @param mixed + */ function load_command( $name ) { - $path = WP_CLI_ROOT . "/php/commands/$name.php"; - if ( is_readable( $path ) ) { - include_once $path; + if ( is_string( $name ) ) { + $name = array( $name ); } + + do { + + $file_name = implode( '-', $name ); + $path = WP_CLI_ROOT . "/php/commands/{$file_name}.php"; + + if ( is_readable( $path ) ) { + include_once $path; + } + + array_pop( $name ); + + } while( $name ); + } function load_all_commands() { From c7900b78be44d859532f576a82ee3793a662531c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 15:19:34 -0700 Subject: [PATCH 2815/4858] Introduce `wp sidebar widget` with list, update, and remove --- php/commands/sidebar-widget.php | 228 ++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 php/commands/sidebar-widget.php diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php new file mode 100644 index 0000000000..99c454daf4 --- /dev/null +++ b/php/commands/sidebar-widget.php @@ -0,0 +1,228 @@ +<?php + +/** + * Manage sidebar widgets. + */ + +class Widget_Command extends WP_CLI_Command { + + private $fields = array( + 'name', + 'position', + 'options', + ); + + /** + * List widgets associated with a sidebar. + * + * <sidebar-id> + * : ID for the corresponding sidebar. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to name, id, description + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## EXAMPLES + * + * wp sidebar widget list <sidebar> --fields=name --format=csv + * + * @subcommand list + */ + public function _list( $args, $assoc_args ) { + + list( $sidebar_id ) = $args; + + $this->validate_sidebar( $sidebar_id ); + + $output_widgets = $this->get_sidebar_widgets( $sidebar_id ); + + if ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv') ) ) { + foreach( $output_widgets as &$output_widget ) { + $output_widget->options = json_encode( $output_widget->options ); + } + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); + $formatter->display_items( $output_widgets ); + + } + + /** + * Update a given widget's options. + * + * <sidebar-id> + * : ID for the corresponding sidebar. + * + * <name> + * : Widget name. + * + * <position> + * : Widget's current position within the sidebar. + * + * [--<field>=<value>] + * : Field to update, with its new value + * + * @subcommand update + */ + public function update( $args, $assoc_args ) { + + list( $sidebar_id, $name, $position ) = $args; + $this->validate_sidebar_widget( $sidebar_id, $name, $position ); + + if ( empty( $assoc_args ) ) { + WP_CLI::error( "No options specified to update." ); + } + + $option_key = 'widget_' . $name; + $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); + $widget_options = get_option( $option_key ); + if ( ! isset( $widget_options[ $option_index ] ) ) { + $widget_options[ $option_index ] = $assoc_args; + } else { + $widget_options[ $option_index ] = array_merge( $widget_options[ $option_index ], $assoc_args ); + } + update_option( $option_key, $widget_options ); + + WP_CLI::success( "Widget updated." ); + + } + + /** + * Remove a widget from a sidebar. + * + * <sidebar-id> + * : ID for the corresponding sidebar. + * + * <name> + * : Widget name. + * + * <position> + * : Widget's current position within the sidebar. + * + * @subcommand + */ + public function remove( $args, $assoc_args ) { + + list( $sidebar_id, $name, $position ) = $args; + $this->validate_sidebar_widget( $sidebar_id, $name, $position ); + + // Remove the widget's settings + $option_key = 'widget_' . $name; + $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); + $widget_options = get_option( $option_key ); + unset( $widget_options[ $option_index ] ); + update_option( $option_key, $widget_options ); + + // Remove the widget from the sidebar + $all_widgets = wp_get_sidebars_widgets(); + $position--; + unset( $all_widgets[ $sidebar_id ][ $position ] ); + update_option( 'sidebars_widgets', $all_widgets ); + + // Reset the global just in case + wp_get_sidebars_widgets(); + + WP_CLI::success( "Widget removed from sidebar." ); + } + + /** + * Check whether a sidebar is a valid sidebar + * + * @param string $sidebar_id + */ + private function validate_sidebar( $sidebar_id ) { + global $wp_registered_sidebars; + + if ( ! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) { + WP_CLI::error( "Invalid sidebar." ); + } + } + + /** + * Check whether the specified widget is on the sidebar + * + * @param string $sidebar_id + * @param string $name + * @param int $position + */ + private function validate_sidebar_widget( $sidebar_id, $name, $position ) { + + $this->validate_sidebar( $sidebar_id ); + + $sidebar_widgets = $this->get_sidebar_widgets( $sidebar_id ); + + $widget_exists = false; + foreach( $sidebar_widgets as $sidebar_widget ) { + + if ( $name == $sidebar_widget->name && $position == $sidebar_widget->position ) { + $widget_exists = true; + break; + } + + } + + if ( false === $widget_exists ) { + WP_CLI::error( "Specified widget isn't present on sidebar." ); + } + + } + + /** + * Get the widgets (and their associated data) for a given sidebar + * + * @param string $sidebar_id + * @return array + */ + private function get_sidebar_widgets( $sidebar_id ) { + + $all_widgets = wp_get_sidebars_widgets(); + + if ( empty( $all_widgets[ $sidebar_id ] ) ) { + return array(); + } + + $prepared_widgets = array(); + foreach( $all_widgets[ $sidebar_id ] as $key => $widget_name ) { + + $prepared_widget = new stdClass; + + $parts = explode( '-', $widget_name ); + $option_index = array_pop( $parts ); + $widget_name = implode( '-', $parts ); + + $prepared_widget->name = $widget_name; + $prepared_widget->position = $key + 1; + $widget_options = get_option( 'widget_' . $widget_name ); + $prepared_widget->options = $widget_options[ $option_index ]; + + $prepared_widgets[] = $prepared_widget; + } + + return $prepared_widgets; + } + + /** + * Get the widget's option index from its location on the sidebar + * + * @param string $sidebar_id + * @param string $name + * @param int $position + * @return int + */ + private function get_widget_option_index( $sidebar_id, $name, $position ) { + + $all_widgets = wp_get_sidebars_widgets(); + $sidebar_widgets = $all_widgets[ $sidebar_id ]; + $position--; + $widget_real_name = $sidebar_widgets[ $position ]; + $parts = explode( '-', $widget_real_name ); + $option_index = array_pop( $parts ); + + return $option_index; + } + +} + +WP_CLI::add_command( 'sidebar widget', 'Widget_Command' ); From c13b56a69b7376b81a00109a55d8afab9b87b9e0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 15:49:37 -0700 Subject: [PATCH 2816/4858] Re-index the sidebar's list of widgets after a widget is removed --- php/commands/sidebar-widget.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index 99c454daf4..79f6735813 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -119,6 +119,7 @@ public function remove( $args, $assoc_args ) { $all_widgets = wp_get_sidebars_widgets(); $position--; unset( $all_widgets[ $sidebar_id ][ $position ] ); + $all_widgets[ $sidebar_id ] = array_values( $all_widgets[ $sidebar_id ] ); update_option( 'sidebars_widgets', $all_widgets ); // Reset the global just in case From d5c55c363f2b5c860acadddccbad87d7c44de6c9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 16:06:47 -0700 Subject: [PATCH 2817/4858] Move widgets between positions on a sidebar --- php/commands/sidebar-widget.php | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index 79f6735813..6858d08bc5 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -89,6 +89,51 @@ public function update( $args, $assoc_args ) { } + /** + * Move a widget from one position on a sidebar to another. + * + * <sidebar-id> + * : ID for the corresponding sidebar. + * + * <name> + * : Widget name. + * + * <current-position> + * : Widget's current position within the sidebar. + * + * <new-position> + * : Widget's new position within the sidebar. + * + * @subcommand move + */ + public function move( $args, $assoc_args ) { + + list( $sidebar_id, $name, $current_position, $new_position ) = $args; + $this->validate_sidebar_widget( $sidebar_id, $name, $current_position ); + + if ( $new_position < -1 ) { + $new_position = 1; + } + + // Human-readable positions are different than numerically indexed array + $current_position--; + $new_position--; + + // Reposition and update + $all_widgets = wp_get_sidebars_widgets(); + $sidebar_widgets = $all_widgets[ $sidebar_id ]; + $part = array_splice( $sidebar_widgets, $current_position, 1 ); + array_splice( $sidebar_widgets, $new_position, 0, $part ); + $all_widgets[ $sidebar_id ] = array_values( $sidebar_widgets ); + update_option( 'sidebars_widgets', $all_widgets ); + + // Reset the global just in case + wp_get_sidebars_widgets(); + + WP_CLI::success( "Widget moved." ); + + } + /** * Remove a widget from a sidebar. * From 91cdd40baaccc1d92ec5bbd09322cf0248d19d55 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 16:14:07 -0700 Subject: [PATCH 2818/4858] Basic tests for sidebar widgets --- features/sidebar-widget.feature | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 features/sidebar-widget.feature diff --git a/features/sidebar-widget.feature b/features/sidebar-widget.feature new file mode 100644 index 0000000000..17ce7cd1c1 --- /dev/null +++ b/features/sidebar-widget.feature @@ -0,0 +1,55 @@ +Feature: Manage widgets in WordPress sidebar + + Scenario: Widget CRUD + Given a WP install + + When I run `wp theme install p2 --activate` + Then STDOUT should not be empty + + When I run `wp sidebar widget list sidebar-1 --fields=name,position` + Then STDOUT should be a table containing rows: + | name | position | + | search | 1 | + | recent-posts | 2 | + | recent-comments | 3 | + | archives | 4 | + | categories | 5 | + | meta | 6 | + + When I run `wp sidebar widget move sidebar-1 recent-comments 3 2` + Then STDOUT should not be empty + + When I run `wp sidebar widget list sidebar-1 --fields=name,position` + Then STDOUT should be a table containing rows: + | name | position | + | search | 1 | + | recent-comments | 2 | + | recent-posts | 3 | + | archives | 4 | + | categories | 5 | + | meta | 6 | + + When I run `wp sidebar widget move sidebar-1 recent-comments 2 5` + Then STDOUT should not be empty + + When I run `wp sidebar widget list sidebar-1 --fields=name,position` + Then STDOUT should be a table containing rows: + | name | position | + | search | 1 | + | recent-posts | 2 | + | archives | 3 | + | categories | 4 | + | recent-comments | 5 | + | meta | 6 | + + When I run `wp sidebar widget remove sidebar-1 recent-comments 5` + Then STDOUT should not be empty + + When I run `wp sidebar widget list sidebar-1 --fields=name,position` + Then STDOUT should be a table containing rows: + | name | position | + | search | 1 | + | recent-posts | 2 | + | archives | 3 | + | categories | 4 | + | meta | 5 | From df80294d501fc47e45b5c6ec3d256d0859a22510 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 16:21:30 -0700 Subject: [PATCH 2819/4858] Register the "Inactive Widgets" sidebar, because core doesn't normally do this for us --- php/commands/sidebar-widget.php | 2 ++ php/commands/sidebar.php | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index 6858d08bc5..02c48e2ac9 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -181,6 +181,8 @@ public function remove( $args, $assoc_args ) { private function validate_sidebar( $sidebar_id ) { global $wp_registered_sidebars; + Sidebar_Command::register_unused_sidebar(); + if ( ! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) { WP_CLI::error( "Invalid sidebar." ); } diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index afd55d8606..a52cadb47a 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -29,7 +29,9 @@ class Sidebar_Command extends WP_CLI_Command { * @subcommand list */ public function _list( $args, $assoc_args ) { - global $wp_registered_sidebars; + global $wp_registered_sidebars; + + self::register_unused_sidebar(); $output_sidebars = array(); foreach( $wp_registered_sidebars as $registered_sidebar ) { @@ -41,6 +43,25 @@ public function _list( $args, $assoc_args ) { } + /** + * Register the sidebar for unused widgets + * Core does this in /wp-admin/widgets.php, which isn't helpful + */ + public static function register_unused_sidebar() { + + register_sidebar(array( + 'name' => __('Inactive Widgets'), + 'id' => 'wp_inactive_widgets', + 'class' => 'inactive-sidebar', + 'description' => __( 'Drag widgets here to remove them from the sidebar but keep their settings.' ), + 'before_widget' => '', + 'after_widget' => '', + 'before_title' => '', + 'after_title' => '', + )); + + } + } WP_CLI::add_command( 'sidebar', 'Sidebar_Command' ); From ee5057af3f4e9c343da413a1cf6eef6c3756b3d3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 16:49:10 -0700 Subject: [PATCH 2820/4858] Sanitize a widget's options using its defined callback --- php/commands/sidebar-widget.php | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index 02c48e2ac9..f3b46f5f27 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -78,11 +78,8 @@ public function update( $args, $assoc_args ) { $option_key = 'widget_' . $name; $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); $widget_options = get_option( $option_key ); - if ( ! isset( $widget_options[ $option_index ] ) ) { - $widget_options[ $option_index ] = $assoc_args; - } else { - $widget_options[ $option_index ] = array_merge( $widget_options[ $option_index ], $assoc_args ); - } + $clean_options = $this->sanitize_widget_options( $name, $assoc_args, $widget_options[ $option_index ] ); + $widget_options[ $option_index ] = array_merge( (array)$widget_options[ $option_index ], $clean_options ); update_option( $option_key, $widget_options ); WP_CLI::success( "Widget updated." ); @@ -271,6 +268,27 @@ private function get_widget_option_index( $sidebar_id, $name, $position ) { return $option_index; } + /** + * Clean up a widget's options based on its update callback + * + * @param string $id_base Name of the widget + * @param mixed $dirty_options + * @param mixed $old_options + * @return mixed + */ + private function sanitize_widget_options( $id_base, $dirty_options, $old_options ) { + global $wp_widget_factory; + + $widget = wp_filter_object_list( $wp_widget_factory->widgets, array( 'id_base' => $id_base ) ); + if ( empty( $widget ) ) { + return array(); + } + + $widget = array_pop( $widget ); + return $widget->update( $dirty_options, $old_options ); + + } + } WP_CLI::add_command( 'sidebar widget', 'Widget_Command' ); From f6f2cc92b1f04f4be2884932e80b88bbfee8777d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 16:54:28 -0700 Subject: [PATCH 2821/4858] Further abstraction that will be useful down the line --- php/commands/sidebar-widget.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index f3b46f5f27..96c0dd05eb 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -268,6 +268,23 @@ private function get_widget_option_index( $sidebar_id, $name, $position ) { return $option_index; } + /** + * Get a widget's instantiated object based on its name + * + * @param string $id_base Name of the widget + * @return WP_Widget|false + */ + private function get_widget_obj( $id_base ) { + global $wp_widget_factory; + + $widget = wp_filter_object_list( $wp_widget_factory->widgets, array( 'id_base' => $id_base ) ); + if ( empty( $widget ) ) { + false; + } + + return array_pop( $widget ); + } + /** * Clean up a widget's options based on its update callback * @@ -277,14 +294,12 @@ private function get_widget_option_index( $sidebar_id, $name, $position ) { * @return mixed */ private function sanitize_widget_options( $id_base, $dirty_options, $old_options ) { - global $wp_widget_factory; - $widget = wp_filter_object_list( $wp_widget_factory->widgets, array( 'id_base' => $id_base ) ); + $widget = $this->get_widget_obj( $id_base ); if ( empty( $widget ) ) { return array(); } - $widget = array_pop( $widget ); return $widget->update( $dirty_options, $old_options ); } From 06c3598ba91f560d1afbe72d79555075b15dda9b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 17:29:34 -0700 Subject: [PATCH 2822/4858] Utility functions for getting and updating options associated with a given widget --- php/commands/sidebar-widget.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index 96c0dd05eb..cb6894e118 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -268,6 +268,26 @@ private function get_widget_option_index( $sidebar_id, $name, $position ) { return $option_index; } + /** + * Get the options for a given widget + * + * @param string $name + * @return array + */ + private function get_widget_options( $name ) { + return get_option( 'widget_' . $name, array() ); + } + + /** + * Update the options for a given widget + * + * @param string $name + * @param mixed + */ + private function update_widget_options( $name, $value ) { + update_option( 'widget_' . $name, $value ); + } + /** * Get a widget's instantiated object based on its name * From 7ce1e184e75157981f8a0532755dab9fd67fb0e0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 17:32:27 -0700 Subject: [PATCH 2823/4858] Support for adding a widget to a sidebar --- features/sidebar-widget.feature | 13 +++++++ php/commands/sidebar-widget.php | 62 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/features/sidebar-widget.feature b/features/sidebar-widget.feature index 17ce7cd1c1..ae68e0e374 100644 --- a/features/sidebar-widget.feature +++ b/features/sidebar-widget.feature @@ -53,3 +53,16 @@ Feature: Manage widgets in WordPress sidebar | archives | 3 | | categories | 4 | | meta | 5 | + + When I run `wp sidebar widget add sidebar-1 calendar 2 --title="Calendar"` + Then STDOUT should not be empty + + When I run `wp sidebar widget list sidebar-1 --fields=name,position` + Then STDOUT should be a table containing rows: + | name | position | + | search | 1 | + | calendar | 2 | + | recent-posts | 3 | + | archives | 4 | + | categories | 5 | + | meta | 6 | diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index cb6894e118..fe88141c3e 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -49,6 +49,68 @@ public function _list( $args, $assoc_args ) { } + /** + * Add a widget to a sidebar. + * + * <sidebar-id> + * : ID for the corresponding sidebar. + * + * <name> + * : Widget name. + * + * [<position>] + * : Widget's current position within the sidebar. Defaults to last + * + * [--<field>=<value>] + * : Widget option to add, with its new value + * + * @subcommand add + */ + public function add( $args, $assoc_args ) { + + list( $sidebar_id, $name ) = $args; + if ( isset( $args[2] ) ) { + $position = (int) $args[2]; + } else { + $position = false; + } + $this->validate_sidebar( $sidebar_id ); + + if ( false == ( $widget = $this->get_widget_obj( $name ) ) ) { + WP_CLI::error( "Invalid widget type." ); + } + + /** + * Adding a widget is as easy as: + * 1. Creating a new widget option + * 2. Adding the widget to the sidebar + * 3. Positioning appropriately + */ + $widget_options = $option_keys = $this->get_widget_options( $name ); + unset( $option_keys['_multiwidget'] ); + $option_keys = array_keys( $option_keys ); + $last_key = array_pop( $option_keys ); + $option_index = $last_key + 1; + $widget_options[ $option_index ] = $this->sanitize_widget_options( $name, $assoc_args, array() ); + $this->update_widget_options( $name, $widget_options ); + + $all_widgets = wp_get_sidebars_widgets(); + $sidebar_widgets = $all_widgets[ $sidebar_id ]; + $sidebar_widgets[] = $name . '-' . $option_index; + + $current_position = count( $sidebar_widgets ) - 1; + if ( $position ) { + $new_position = $position - 1; + $part = array_splice( $sidebar_widgets, $current_position, 1 ); + array_splice( $sidebar_widgets, $new_position, 0, $part ); + $all_widgets[ $sidebar_id ] = array_values( $sidebar_widgets ); + } + update_option( 'sidebars_widgets', $all_widgets ); + + WP_CLI::success( "Added widget." ); + + } + /** * Update a given widget's options. * From db8b4f290e7344b070a9f24832fafe9e12cf23e3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 17:51:19 -0700 Subject: [PATCH 2824/4858] Refactor to use new sidebar widget getter Core's private function isn't doing it for us because it's dependent on the global --- php/commands/sidebar-widget.php | 70 +++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index fe88141c3e..8225c6c77a 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -137,12 +137,11 @@ public function update( $args, $assoc_args ) { WP_CLI::error( "No options specified to update." ); } - $option_key = 'widget_' . $name; $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); - $widget_options = get_option( $option_key ); + $widget_options = $this->get_widget_options( $name ); $clean_options = $this->sanitize_widget_options( $name, $assoc_args, $widget_options[ $option_index ] ); $widget_options[ $option_index ] = array_merge( (array)$widget_options[ $option_index ], $clean_options ); - update_option( $option_key, $widget_options ); + $this->update_widget_options( $name, $widget_options ); WP_CLI::success( "Widget updated." ); @@ -174,20 +173,7 @@ public function move( $args, $assoc_args ) { $new_position = 1; } - // Human-readable positions are different than numerically indexed array - $current_position--; - $new_position--; - - // Reposition and update - $all_widgets = wp_get_sidebars_widgets(); - $sidebar_widgets = $all_widgets[ $sidebar_id ]; - $part = array_splice( $sidebar_widgets, $current_position, 1 ); - array_splice( $sidebar_widgets, $new_position, 0, $part ); - $all_widgets[ $sidebar_id ] = array_values( $sidebar_widgets ); - update_option( 'sidebars_widgets', $all_widgets ); - - // Reset the global just in case - wp_get_sidebars_widgets(); + $this->reposition_sidebar_widget( $sidebar_id, $current_position, $new_position ); WP_CLI::success( "Widget moved." ); @@ -213,22 +199,18 @@ public function remove( $args, $assoc_args ) { $this->validate_sidebar_widget( $sidebar_id, $name, $position ); // Remove the widget's settings - $option_key = 'widget_' . $name; $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); - $widget_options = get_option( $option_key ); + $widget_options = $this->get_widget_options( $name ); unset( $widget_options[ $option_index ] ); - update_option( $option_key, $widget_options ); + $this->update_widget_options( $name, $widget_options ); // Remove the widget from the sidebar - $all_widgets = wp_get_sidebars_widgets(); + $all_widgets = $this->wp_get_sidebars_widgets(); $position--; unset( $all_widgets[ $sidebar_id ][ $position ] ); $all_widgets[ $sidebar_id ] = array_values( $all_widgets[ $sidebar_id ] ); update_option( 'sidebars_widgets', $all_widgets ); - // Reset the global just in case - wp_get_sidebars_widgets(); - WP_CLI::success( "Widget removed from sidebar." ); } @@ -284,7 +266,7 @@ private function validate_sidebar_widget( $sidebar_id, $name, $position ) { */ private function get_sidebar_widgets( $sidebar_id ) { - $all_widgets = wp_get_sidebars_widgets(); + $all_widgets = $this->wp_get_sidebars_widgets(); if ( empty( $all_widgets[ $sidebar_id ] ) ) { return array(); @@ -310,6 +292,19 @@ private function get_sidebar_widgets( $sidebar_id ) { return $prepared_widgets; } + /** + * Re-implementation of wp_get_sidebars_widgets() + */ + private function wp_get_sidebars_widgets() { + $sidebars_widgets = get_option( 'sidebars_widgets', array() ); + + if ( is_array( $sidebars_widgets ) && isset( $sidebars_widgets['array_version'] ) ) { + unset( $sidebars_widgets['array_version'] ); + } + + return $sidebars_widgets; + } + /** * Get the widget's option index from its location on the sidebar * @@ -320,7 +315,7 @@ private function get_sidebar_widgets( $sidebar_id ) { */ private function get_widget_option_index( $sidebar_id, $name, $position ) { - $all_widgets = wp_get_sidebars_widgets(); + $all_widgets = $this->wp_get_sidebars_widgets(); $sidebar_widgets = $all_widgets[ $sidebar_id ]; $position--; $widget_real_name = $sidebar_widgets[ $position ]; @@ -350,6 +345,29 @@ private function update_widget_options( $name, $value ) { update_option( 'widget_' . $name, $value ); } + /** + * Reposition a widget within a sidebar + * + * @param string $sidebar_id + * @param int $current_position + * @param int $new_position + */ + private function reposition_sidebar_widget( $sidebar_id, $current_position, $new_position ) { + + // Human-readable positions are different than numerically indexed array + $current_position--; + $new_position--; + + // Reposition and update + $all_widgets = $this->wp_get_sidebars_widgets(); + $sidebar_widgets = $all_widgets[ $sidebar_id ]; + $part = array_splice( $sidebar_widgets, $current_position, 1 ); + array_splice( $sidebar_widgets, $new_position, 0, $part ); + $all_widgets[ $sidebar_id ] = array_values( $sidebar_widgets ); + update_option( 'sidebars_widgets', $all_widgets ); + + } + /** * Get a widget's instantiated object based on its name * From 483fe97b814488e9e17c4348668f6dbbb148928d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 17:55:03 -0700 Subject: [PATCH 2825/4858] Update tests to include `wp sidebar widget update` case --- features/sidebar-widget.feature | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/features/sidebar-widget.feature b/features/sidebar-widget.feature index ae68e0e374..1d924e3d06 100644 --- a/features/sidebar-widget.feature +++ b/features/sidebar-widget.feature @@ -54,7 +54,7 @@ Feature: Manage widgets in WordPress sidebar | categories | 4 | | meta | 5 | - When I run `wp sidebar widget add sidebar-1 calendar 2 --title="Calendar"` + When I run `wp sidebar widget add sidebar-1 calendar 2` Then STDOUT should not be empty When I run `wp sidebar widget list sidebar-1 --fields=name,position` @@ -66,3 +66,11 @@ Feature: Manage widgets in WordPress sidebar | archives | 4 | | categories | 5 | | meta | 6 | + + When I run `wp sidebar widget update sidebar-1 calendar 2 --title="Calendar"` + Then STDOUT should not be empty + + When I run `wp sidebar widget list sidebar-1 --fields=name,position,options` + Then STDOUT should be a table containing rows: + | name | position | options | + | calendar | 2 | {"title":"Calendar"} | From 36626ab80eefbf26b348a91238307ef77cff6063 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 8 Apr 2014 17:55:23 -0700 Subject: [PATCH 2826/4858] Continue consolidation and refactor --- php/commands/sidebar-widget.php | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/php/commands/sidebar-widget.php b/php/commands/sidebar-widget.php index 8225c6c77a..aef7d59093 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/sidebar-widget.php @@ -69,11 +69,7 @@ public function _list( $args, $assoc_args ) { public function add( $args, $assoc_args ) { list( $sidebar_id, $name ) = $args; - if ( isset( $args[2] ) ) { - $position = (int) $args[2]; - } else { - $position = false; - } + $new_position = ( isset( $args[2] ) ) ? (int) $args[2] : false; $this->validate_sidebar( $sidebar_id ); if ( false == ( $widget = $this->get_widget_obj( $name ) ) ) { @@ -87,6 +83,9 @@ public function add( $args, $assoc_args ) { * 3. Positioning appropriately */ $widget_options = $option_keys = $this->get_widget_options( $name ); + if ( ! isset( $widget_options['_multiwidget'] ) ) { + $widget_options['_multiwidget'] = 1; + } unset( $option_keys['_multiwidget'] ); $option_keys = array_keys( $option_keys ); $last_key = array_pop( $option_keys ); @@ -94,19 +93,15 @@ public function add( $args, $assoc_args ) { $widget_options[ $option_index ] = $this->sanitize_widget_options( $name, $assoc_args, array() ); $this->update_widget_options( $name, $widget_options ); - $all_widgets = wp_get_sidebars_widgets(); - $sidebar_widgets = $all_widgets[ $sidebar_id ]; - $sidebar_widgets[] = $name . '-' . $option_index; - - $current_position = count( $sidebar_widgets ) - 1; - if ( $position ) { - $new_position = $position - 1; - $part = array_splice( $sidebar_widgets, $current_position, 1 ); - array_splice( $sidebar_widgets, $new_position, 0, $part ); - $all_widgets[ $sidebar_id ] = array_values( $sidebar_widgets ); - } + $all_widgets = $this->wp_get_sidebars_widgets(); + $all_widgets[ $sidebar_id ][] = $name . '-' . $option_index; update_option( 'sidebars_widgets', $all_widgets ); + $current_position = count( $all_widgets[ $sidebar_id ] ); + if ( $new_position ) { + $this->reposition_sidebar_widget( $sidebar_id, $current_position, $new_position ); + } + WP_CLI::success( "Added widget." ); } From 88e7b6f75b2fc46f4c6fe67174ab4ec4c6023369 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 Apr 2014 12:32:57 +0300 Subject: [PATCH 2827/4858] bump to WP 3.9-RC1 see https://core.trac.wordpress.org/changeset/27999 --- .travis.yml | 2 +- php/wp-settings-cli.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9a3e92cbe6..94c066ac1a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=3.9-beta1 + - WP_VERSION=3.9-RC1 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 4014958818..67ad27f981 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -184,8 +184,6 @@ // Load must-use plugins. foreach ( wp_get_mu_plugins() as $mu_plugin ) { - if ( $symlinked_plugins_supported ) - wp_register_plugin_realpath( $mu_plugin ); include_once( $mu_plugin ); } unset( $mu_plugin ); From 77222f7967b989e174b75b2852d9fad66ae90bfa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 07:17:50 -0700 Subject: [PATCH 2828/4858] Revert "Update `WP_CLI\Utils\load_command()` to handle commands like `sidebar widget`" This reverts commit 16892f074fc2d688f267299cdfabd63c68e3bc27. See https://github.com/wp-cli/wp-cli/commit/16892f074fc2d688f267299cdfabd63c68e3bc27#commitcomment-5951766 --- php/WP_CLI/Runner.php | 2 +- php/utils.php | 24 +++--------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b685ee3377..7a4cf01639 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -479,7 +479,7 @@ public function before_wp_load() { // Load bundled commands early, so that they're forced to use the same // APIs as non-bundled commands. - Utils\load_command( $this->arguments ); + Utils\load_command( $this->arguments[0] ); if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { diff --git a/php/utils.php b/php/utils.php index c697df9289..b918d1824e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -41,30 +41,12 @@ function load_file( $path ) { require $path; } -/** - * Load a given internal WP-CLI command - * - * @param mixed - */ function load_command( $name ) { + $path = WP_CLI_ROOT . "/php/commands/$name.php"; - if ( is_string( $name ) ) { - $name = array( $name ); + if ( is_readable( $path ) ) { + include_once $path; } - - do { - - $file_name = implode( '-', $name ); - $path = WP_CLI_ROOT . "/php/commands/{$file_name}.php"; - - if ( is_readable( $path ) ) { - include_once $path; - } - - array_pop( $name ); - - } while( $name ); - } function load_all_commands() { From d4b940d6e5a79d45b12ad062afef6a06fa181a8c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 07:26:16 -0700 Subject: [PATCH 2829/4858] Rename and refactor to accommodate 77222f7967b989e174b75b2852d9fad66ae90bfa --- ...{sidebar-widget.feature => widget.feature} | 22 +++++++++---------- php/commands/sidebar.php | 21 +----------------- .../{sidebar-widget.php => widget.php} | 4 ++-- php/utils-wp.php | 18 +++++++++++++++ 4 files changed, 32 insertions(+), 33 deletions(-) rename features/{sidebar-widget.feature => widget.feature} (72%) rename php/commands/{sidebar-widget.php => widget.php} (98%) diff --git a/features/sidebar-widget.feature b/features/widget.feature similarity index 72% rename from features/sidebar-widget.feature rename to features/widget.feature index 1d924e3d06..0758c05620 100644 --- a/features/sidebar-widget.feature +++ b/features/widget.feature @@ -6,7 +6,7 @@ Feature: Manage widgets in WordPress sidebar When I run `wp theme install p2 --activate` Then STDOUT should not be empty - When I run `wp sidebar widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,position` Then STDOUT should be a table containing rows: | name | position | | search | 1 | @@ -16,10 +16,10 @@ Feature: Manage widgets in WordPress sidebar | categories | 5 | | meta | 6 | - When I run `wp sidebar widget move sidebar-1 recent-comments 3 2` + When I run `wp widget move sidebar-1 recent-comments 3 2` Then STDOUT should not be empty - When I run `wp sidebar widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,position` Then STDOUT should be a table containing rows: | name | position | | search | 1 | @@ -29,10 +29,10 @@ Feature: Manage widgets in WordPress sidebar | categories | 5 | | meta | 6 | - When I run `wp sidebar widget move sidebar-1 recent-comments 2 5` + When I run `wp widget move sidebar-1 recent-comments 2 5` Then STDOUT should not be empty - When I run `wp sidebar widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,position` Then STDOUT should be a table containing rows: | name | position | | search | 1 | @@ -42,10 +42,10 @@ Feature: Manage widgets in WordPress sidebar | recent-comments | 5 | | meta | 6 | - When I run `wp sidebar widget remove sidebar-1 recent-comments 5` + When I run `wp widget remove sidebar-1 recent-comments 5` Then STDOUT should not be empty - When I run `wp sidebar widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,position` Then STDOUT should be a table containing rows: | name | position | | search | 1 | @@ -54,10 +54,10 @@ Feature: Manage widgets in WordPress sidebar | categories | 4 | | meta | 5 | - When I run `wp sidebar widget add sidebar-1 calendar 2` + When I run `wp widget add sidebar-1 calendar 2` Then STDOUT should not be empty - When I run `wp sidebar widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,position` Then STDOUT should be a table containing rows: | name | position | | search | 1 | @@ -67,10 +67,10 @@ Feature: Manage widgets in WordPress sidebar | categories | 5 | | meta | 6 | - When I run `wp sidebar widget update sidebar-1 calendar 2 --title="Calendar"` + When I run `wp widget update sidebar-1 calendar 2 --title="Calendar"` Then STDOUT should not be empty - When I run `wp sidebar widget list sidebar-1 --fields=name,position,options` + When I run `wp widget list sidebar-1 --fields=name,position,options` Then STDOUT should be a table containing rows: | name | position | options | | calendar | 2 | {"title":"Calendar"} | diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index a52cadb47a..3ba865d695 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -31,7 +31,7 @@ class Sidebar_Command extends WP_CLI_Command { public function _list( $args, $assoc_args ) { global $wp_registered_sidebars; - self::register_unused_sidebar(); + \WP_CLI\Utils\wp_register_unused_sidebar(); $output_sidebars = array(); foreach( $wp_registered_sidebars as $registered_sidebar ) { @@ -43,25 +43,6 @@ public function _list( $args, $assoc_args ) { } - /** - * Register the sidebar for unused widgets - * Core does this in /wp-admin/widgets.php, which isn't helpful - */ - public static function register_unused_sidebar() { - - register_sidebar(array( - 'name' => __('Inactive Widgets'), - 'id' => 'wp_inactive_widgets', - 'class' => 'inactive-sidebar', - 'description' => __( 'Drag widgets here to remove them from the sidebar but keep their settings.' ), - 'before_widget' => '', - 'after_widget' => '', - 'before_title' => '', - 'after_title' => '', - )); - - } - } WP_CLI::add_command( 'sidebar', 'Sidebar_Command' ); diff --git a/php/commands/sidebar-widget.php b/php/commands/widget.php similarity index 98% rename from php/commands/sidebar-widget.php rename to php/commands/widget.php index aef7d59093..0a6b1c605c 100644 --- a/php/commands/sidebar-widget.php +++ b/php/commands/widget.php @@ -217,7 +217,7 @@ public function remove( $args, $assoc_args ) { private function validate_sidebar( $sidebar_id ) { global $wp_registered_sidebars; - Sidebar_Command::register_unused_sidebar(); + \WP_CLI\Utils\wp_register_unused_sidebar(); if ( ! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) { WP_CLI::error( "Invalid sidebar." ); @@ -401,4 +401,4 @@ private function sanitize_widget_options( $id_base, $dirty_options, $old_options } -WP_CLI::add_command( 'sidebar widget', 'Widget_Command' ); +WP_CLI::add_command( 'widget', 'Widget_Command' ); diff --git a/php/utils-wp.php b/php/utils-wp.php index 4048a8d061..dba28dfc29 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -95,3 +95,21 @@ function is_plugin_skipped( $file ) { return in_array( $name, array_filter( $skipped_plugins ) ); } +/** + * Register the sidebar for unused widgets + * Core does this in /wp-admin/widgets.php, which isn't helpful + */ +function wp_register_unused_sidebar() { + + register_sidebar(array( + 'name' => __('Inactive Widgets'), + 'id' => 'wp_inactive_widgets', + 'class' => 'inactive-sidebar', + 'description' => __( 'Drag widgets here to remove them from the sidebar but keep their settings.' ), + 'before_widget' => '', + 'after_widget' => '', + 'before_title' => '', + 'after_title' => '', + )); + +} From 2d9b281e30ce51af1dd4714b67f6eb07563f9126 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 07:46:51 -0700 Subject: [PATCH 2830/4858] Clarify why this method required re-implementing --- php/commands/widget.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/widget.php b/php/commands/widget.php index 0a6b1c605c..bfdb8ea54b 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -289,6 +289,7 @@ private function get_sidebar_widgets( $sidebar_id ) { /** * Re-implementation of wp_get_sidebars_widgets() + * because the original has a nasty global component */ private function wp_get_sidebars_widgets() { $sidebars_widgets = get_option( 'sidebars_widgets', array() ); From 4fb3d033a44875d7b61f6f188a1f91690f8c672e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 08:58:52 -0700 Subject: [PATCH 2831/4858] Refactor: `widget-id` is a unique widget key we can use across the board --- features/widget.feature | 90 +++++++++--------- php/commands/widget.php | 205 ++++++++++++++++++++++------------------ 2 files changed, 159 insertions(+), 136 deletions(-) diff --git a/features/widget.feature b/features/widget.feature index 0758c05620..76c0cc6b13 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -6,68 +6,70 @@ Feature: Manage widgets in WordPress sidebar When I run `wp theme install p2 --activate` Then STDOUT should not be empty - When I run `wp widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: - | name | position | - | search | 1 | - | recent-posts | 2 | - | recent-comments | 3 | - | archives | 4 | - | categories | 5 | - | meta | 6 | + | name | id | position | + | search | search-2 | 1 | + | recent-posts | recent-posts-2 | 2 | + | recent-comments | recent-comments-2 | 3 | + | archives | archives-2 | 4 | + | categories | categories-2 | 5 | + | meta | meta-2 | 6 | - When I run `wp widget move sidebar-1 recent-comments 3 2` + When I run `wp widget move recent-comments-2 --position=2` Then STDOUT should not be empty - When I run `wp widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: - | name | position | - | search | 1 | - | recent-comments | 2 | - | recent-posts | 3 | - | archives | 4 | - | categories | 5 | - | meta | 6 | + | name | id | position | + | search | search-2 | 1 | + | recent-comments | recent-comments-2 | 2 | + | recent-posts | recent-posts-2 | 3 | + | archives | archives-2 | 4 | + | categories | categories-2 | 5 | + | meta | meta-2 | 6 | - When I run `wp widget move sidebar-1 recent-comments 2 5` + When I run `wp widget move recent-comments-2 --sidebar-id=wp_inactive_widgets` Then STDOUT should not be empty - When I run `wp widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: - | name | position | - | search | 1 | - | recent-posts | 2 | - | archives | 3 | - | categories | 4 | - | recent-comments | 5 | - | meta | 6 | + | name | id | position | + | search | search-2 | 1 | + | recent-posts | recent-posts-2 | 2 | + | archives | archives-2 | 3 | + | categories | categories-2 | 4 | + | meta | meta-2 | 5 | - When I run `wp widget remove sidebar-1 recent-comments 5` + When I run `wp widget list wp_inactive_widgets --fields=name,id,position` + Then STDOUT should be a table containing rows: + | name | id | position | + | recent-comments | recent-comments-2 | 1 | + + When I run `wp widget delete archives-2` Then STDOUT should not be empty - When I run `wp widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: - | name | position | - | search | 1 | - | recent-posts | 2 | - | archives | 3 | - | categories | 4 | - | meta | 5 | + | name | id | position | + | search | search-2 | 1 | + | recent-posts | recent-posts-2 | 2 | + | categories | categories-2 | 3 | + | meta | meta-2 | 4 | - When I run `wp widget add sidebar-1 calendar 2` + When I run `wp widget add calendar sidebar-1 2` Then STDOUT should not be empty - When I run `wp widget list sidebar-1 --fields=name,position` + When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: - | name | position | - | search | 1 | - | calendar | 2 | - | recent-posts | 3 | - | archives | 4 | - | categories | 5 | - | meta | 6 | + | name | id | position | + | search | search-2 | 1 | + | calendar | calendar-1 | 2 | + | recent-posts | recent-posts-2 | 3 | + | categories | categories-2 | 4 | + | meta | meta-2 | 5 | - When I run `wp widget update sidebar-1 calendar 2 --title="Calendar"` + When I run `wp widget update calendar-1 --title="Calendar"` Then STDOUT should not be empty When I run `wp widget list sidebar-1 --fields=name,position,options` diff --git a/php/commands/widget.php b/php/commands/widget.php index bfdb8ea54b..cf247a9876 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -8,6 +8,7 @@ class Widget_Command extends WP_CLI_Command { private $fields = array( 'name', + 'id', 'position', 'options', ); @@ -52,12 +53,12 @@ public function _list( $args, $assoc_args ) { /** * Add a widget to a sidebar. * - * <sidebar-id> - * : ID for the corresponding sidebar. - * * <name> * : Widget name. * + * <sidebar-id> + * : ID for the corresponding sidebar. + * * [<position>] * : Widget's current position within the sidebar. Defaults to last * @@ -68,8 +69,8 @@ public function _list( $args, $assoc_args ) { */ public function add( $args, $assoc_args ) { - list( $sidebar_id, $name ) = $args; - $new_position = ( isset( $args[2] ) ) ? (int) $args[2] : false; + list( $name, $sidebar_id ) = $args; + $position = ( isset( $args[2] ) ) ? (int) $args[2] - 1 : 0; $this->validate_sidebar( $sidebar_id ); if ( false == ( $widget = $this->get_widget_obj( $name ) ) ) { @@ -93,30 +94,19 @@ public function add( $args, $assoc_args ) { $widget_options[ $option_index ] = $this->sanitize_widget_options( $name, $assoc_args, array() ); $this->update_widget_options( $name, $widget_options ); - $all_widgets = $this->wp_get_sidebars_widgets(); - $all_widgets[ $sidebar_id ][] = $name . '-' . $option_index; - update_option( 'sidebars_widgets', $all_widgets ); - - $current_position = count( $all_widgets[ $sidebar_id ] ); - if ( $new_position ) { - $this->reposition_sidebar_widget( $sidebar_id, $current_position, $new_position ); - } + $widget_id = $name . '-' . $option_index; + $this->move_sidebar_widget( $widget_id, null, $sidebar_id, null, $position ); - WP_CLI::success( "Added widget." ); + WP_CLI::success( "Added widget to sidebar." ); + } /** * Update a given widget's options. * - * <sidebar-id> - * : ID for the corresponding sidebar. - * - * <name> - * : Widget name. - * - * <position> - * : Widget's current position within the sidebar. + * <widget-id> + * : Unique ID for the widget * * [--<field>=<value>] * : Field to update, with its new value @@ -125,14 +115,15 @@ public function add( $args, $assoc_args ) { */ public function update( $args, $assoc_args ) { - list( $sidebar_id, $name, $position ) = $args; - $this->validate_sidebar_widget( $sidebar_id, $name, $position ); + list( $widget_id ) = $args; + $this->validate_sidebar_widget( $widget_id ); if ( empty( $assoc_args ) ) { WP_CLI::error( "No options specified to update." ); } - $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); + list( $name, $option_index ) = $this->get_widget_data( $widget_id ); + $widget_options = $this->get_widget_options( $name ); $clean_options = $this->sanitize_widget_options( $name, $assoc_args, $widget_options[ $option_index ] ); $widget_options[ $option_index ] = array_merge( (array)$widget_options[ $option_index ], $clean_options ); @@ -145,64 +136,66 @@ public function update( $args, $assoc_args ) { /** * Move a widget from one position on a sidebar to another. * - * <sidebar-id> - * : ID for the corresponding sidebar. - * - * <name> - * : Widget name. + * <widget-id> + * : Unique ID for the widget * - * <current-position> - * : Widget's current position within the sidebar. + * [--position=<position>] + * : Assign the widget to a new position. * - * <new-position> - * : Widget's new position within the sidebar. + * [--sidebar-id=<sidebar-id>] + * : Assign the widget to a new sidebar * * @subcommand move */ public function move( $args, $assoc_args ) { - list( $sidebar_id, $name, $current_position, $new_position ) = $args; - $this->validate_sidebar_widget( $sidebar_id, $name, $current_position ); + list( $widget_id ) = $args; + $this->validate_sidebar_widget( $widget_id ); + + if ( empty( $assoc_args['position'] ) && empty( $assoc_args['sidebar-id'] ) ) { + WP_CLI::error( "A new position or new sidebar must be specified." ); + } + + list( $name, $option_index, $current_sidebar_id, $current_sidebar_index ) = $this->get_widget_data( $widget_id ); + + $new_sidebar_id = ! empty( $assoc_args['sidebar-id'] ) ? $assoc_args['sidebar-id'] : $current_sidebar_id; + $this->validate_sidebar( $new_sidebar_id ); - if ( $new_position < -1 ) { - $new_position = 1; + $new_sidebar_index = ! empty( $assoc_args['position'] ) ? $assoc_args['position'] - 1 : $current_sidebar_index; + // Moving between sidebars adds to the top + if ( $new_sidebar_id != $current_sidebar_id && $new_sidebar_index == $current_sidebar_index ) { + // Human-readable positions are different than numerically indexed array + $new_sidebar_index = 0; } - $this->reposition_sidebar_widget( $sidebar_id, $current_position, $new_position ); + $this->move_sidebar_widget( $widget_id, $current_sidebar_id, $new_sidebar_id, $current_sidebar_index, $new_sidebar_index ); WP_CLI::success( "Widget moved." ); } /** - * Remove a widget from a sidebar. - * - * <sidebar-id> - * : ID for the corresponding sidebar. - * - * <name> - * : Widget name. + * Delete a widget from a sidebar. * - * <position> - * : Widget's current position within the sidebar. + * <widget-id> + * : Unique ID for the widget * - * @subcommand + * @subcommand delete */ - public function remove( $args, $assoc_args ) { + public function delete( $args, $assoc_args ) { - list( $sidebar_id, $name, $position ) = $args; - $this->validate_sidebar_widget( $sidebar_id, $name, $position ); + list( $widget_id ) = $args; + $this->validate_sidebar_widget( $widget_id ); // Remove the widget's settings - $option_index = $this->get_widget_option_index( $sidebar_id, $name, $position ); + list( $name, $option_index, $sidebar_id, $sidebar_index ) = $this->get_widget_data( $widget_id ); $widget_options = $this->get_widget_options( $name ); unset( $widget_options[ $option_index ] ); $this->update_widget_options( $name, $widget_options ); // Remove the widget from the sidebar $all_widgets = $this->wp_get_sidebars_widgets(); - $position--; - unset( $all_widgets[ $sidebar_id ][ $position ] ); + unset( $all_widgets[ $sidebar_id ][ $sidebar_index ] ); $all_widgets[ $sidebar_id ] = array_values( $all_widgets[ $sidebar_id ] ); update_option( 'sidebars_widgets', $all_widgets ); @@ -227,20 +220,16 @@ private function validate_sidebar( $sidebar_id ) { /** * Check whether the specified widget is on the sidebar * - * @param string $sidebar_id - * @param string $name - * @param int $position + * @param string $widget_id */ - private function validate_sidebar_widget( $sidebar_id, $name, $position ) { - - $this->validate_sidebar( $sidebar_id ); + private function validate_sidebar_widget( $widget_id ) { - $sidebar_widgets = $this->get_sidebar_widgets( $sidebar_id ); + $sidebars_widgets = $this->wp_get_sidebars_widgets(); $widget_exists = false; - foreach( $sidebar_widgets as $sidebar_widget ) { + foreach( $sidebars_widgets as $sidebar_id => $widgets ) { - if ( $name == $sidebar_widget->name && $position == $sidebar_widget->position ) { + if ( in_array( $widget_id, $widgets ) ) { $widget_exists = true; break; } @@ -268,15 +257,16 @@ private function get_sidebar_widgets( $sidebar_id ) { } $prepared_widgets = array(); - foreach( $all_widgets[ $sidebar_id ] as $key => $widget_name ) { + foreach( $all_widgets[ $sidebar_id ] as $key => $widget_id ) { $prepared_widget = new stdClass; - $parts = explode( '-', $widget_name ); + $parts = explode( '-', $widget_id ); $option_index = array_pop( $parts ); $widget_name = implode( '-', $parts ); $prepared_widget->name = $widget_name; + $prepared_widget->id = $widget_id; $prepared_widget->position = $key + 1; $widget_options = get_option( 'widget_' . $widget_name ); $prepared_widget->options = $widget_options[ $option_index ]; @@ -302,23 +292,31 @@ private function wp_get_sidebars_widgets() { } /** - * Get the widget's option index from its location on the sidebar - * - * @param string $sidebar_id - * @param string $name - * @param int $position - * @return int + * Get the widget's name, option index, sidebar, and sidebar index from its ID + * + * @param string $widget_id + * @return array */ - private function get_widget_option_index( $sidebar_id, $name, $position ) { + private function get_widget_data( $widget_id ) { - $all_widgets = $this->wp_get_sidebars_widgets(); - $sidebar_widgets = $all_widgets[ $sidebar_id ]; - $position--; - $widget_real_name = $sidebar_widgets[ $position ]; - $parts = explode( '-', $widget_real_name ); + $parts = explode( '-', $widget_id ); $option_index = array_pop( $parts ); + $name = implode( '-', $parts ); + + $sidebar_id = false; + $sidebar_index = false; + $all_widgets = $this->wp_get_sidebars_widgets(); + foreach( $all_widgets as $s_id => &$widgets ) { + + if ( false !== ( $key = array_search( $widget_id, $widgets ) ) ) { + $sidebar_id = $s_id; + $sidebar_index = $key; + break; + } + + } - return $option_index; + return array( $name, $option_index, $sidebar_id, $sidebar_index ); } /** @@ -344,22 +342,45 @@ private function update_widget_options( $name, $value ) { /** * Reposition a widget within a sidebar * - * @param string $sidebar_id - * @param int $current_position - * @param int $new_position + * @param string $widget_id + * @param string $current_sidebar_id + * @param string $new_sidebar_id + * @param int $current_index + * @param int $new_index */ - private function reposition_sidebar_widget( $sidebar_id, $current_position, $new_position ) { + private function move_sidebar_widget( $widget_id, $current_sidebar_id, $new_sidebar_id, $current_index, $new_index ) { - // Human-readable positions are different than numerically indexed array - $current_position--; - $new_position--; - - // Reposition and update $all_widgets = $this->wp_get_sidebars_widgets(); - $sidebar_widgets = $all_widgets[ $sidebar_id ]; - $part = array_splice( $sidebar_widgets, $current_position, 1 ); - array_splice( $sidebar_widgets, $new_position, 0, $part ); - $all_widgets[ $sidebar_id ] = array_values( $sidebar_widgets ); + $needs_placement = true; + // Existing widget + if ( $current_sidebar_id && $current_index ) { + + $widgets = $all_widgets[ $current_sidebar_id ]; + if ( $current_sidebar_id != $new_sidebar_id ) { + + unset( $widgets[ $current_index ] ); + + } else { + + $part = array_splice( $widgets, $current_index, 1 ); + array_splice( $widgets, $new_index, 0, $part ); + + $needs_placement = false; + + } + + $all_widgets[ $current_sidebar_id ] = array_values( $widgets ); + + } + + if ( $needs_placement ) { + $widgets = $all_widgets[ $new_sidebar_id ]; + $before = array_slice( $widgets, 0, $new_index, true ); + $after = array_slice( $widgets, $new_index, count( $widgets ), true ); + $widgets = array_merge( $before, array( $widget_id ), $after ); + $all_widgets[ $new_sidebar_id ] = array_values( $widgets ); + } + update_option( 'sidebars_widgets', $all_widgets ); } From fea27789eaaa430e60b66a3b563af573a2bf987a Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 Apr 2014 19:06:33 +0300 Subject: [PATCH 2832/4858] remove unnecessary casting to objects --- php/commands/sidebar.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 3ba865d695..a88c93ab06 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -13,7 +13,7 @@ class Sidebar_Command extends WP_CLI_Command { /** * List registered sidebars. - * + * * ## OPTIONS * * [--fields=<fields>] @@ -33,14 +33,8 @@ public function _list( $args, $assoc_args ) { \WP_CLI\Utils\wp_register_unused_sidebar(); - $output_sidebars = array(); - foreach( $wp_registered_sidebars as $registered_sidebar ) { - $output_sidebars[] = (object)$registered_sidebar; - } - $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); - $formatter->display_items( $output_sidebars ); - + $formatter->display_items( $wp_registered_sidebars ); } } From 30b47132df3b339af58ccc0a8e69254bcb52d662 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 9 Apr 2014 19:07:06 +0300 Subject: [PATCH 2833/4858] s/_list/list_/g --- php/commands/sidebar.php | 2 +- php/commands/widget.php | 54 ++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index a88c93ab06..626476868e 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -28,7 +28,7 @@ class Sidebar_Command extends WP_CLI_Command { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { global $wp_registered_sidebars; \WP_CLI\Utils\wp_register_unused_sidebar(); diff --git a/php/commands/widget.php b/php/commands/widget.php index cf247a9876..4282a04fc4 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -15,10 +15,10 @@ class Widget_Command extends WP_CLI_Command { /** * List widgets associated with a sidebar. - * + * * <sidebar-id> * : ID for the corresponding sidebar. - * + * * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to name, id, description * @@ -31,7 +31,7 @@ class Widget_Command extends WP_CLI_Command { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { list( $sidebar_id ) = $args; @@ -52,19 +52,19 @@ public function _list( $args, $assoc_args ) { /** * Add a widget to a sidebar. - * + * * <name> * : Widget name. - * + * * <sidebar-id> * : ID for the corresponding sidebar. - * + * * [<position>] * : Widget's current position within the sidebar. Defaults to last - * + * * [--<field>=<value>] * : Widget option to add, with its new value - * + * * @subcommand add */ public function add( $args, $assoc_args ) { @@ -98,19 +98,19 @@ public function add( $args, $assoc_args ) { $this->move_sidebar_widget( $widget_id, null, $sidebar_id, null, $position ); WP_CLI::success( "Added widget to sidebar." ); - + } /** * Update a given widget's options. - * + * * <widget-id> * : Unique ID for the widget - * + * * [--<field>=<value>] * : Field to update, with its new value - * + * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -135,16 +135,16 @@ public function update( $args, $assoc_args ) { /** * Move a widget from one position on a sidebar to another. - * + * * <widget-id> * : Unique ID for the widget - * + * * [--position=<position>] * : Assign the widget to a new position. - * + * * [--sidebar-id=<sidebar-id>] * : Assign the widget to a new sidebar - * + * * @subcommand move */ public function move( $args, $assoc_args ) { @@ -176,10 +176,10 @@ public function move( $args, $assoc_args ) { /** * Delete a widget from a sidebar. - * + * * <widget-id> * : Unique ID for the widget - * + * * @subcommand delete */ public function delete( $args, $assoc_args ) { @@ -204,7 +204,7 @@ public function delete( $args, $assoc_args ) { /** * Check whether a sidebar is a valid sidebar - * + * * @param string $sidebar_id */ private function validate_sidebar( $sidebar_id ) { @@ -244,7 +244,7 @@ private function validate_sidebar_widget( $widget_id ) { /** * Get the widgets (and their associated data) for a given sidebar - * + * * @param string $sidebar_id * @return array */ @@ -280,7 +280,7 @@ private function get_sidebar_widgets( $sidebar_id ) { /** * Re-implementation of wp_get_sidebars_widgets() * because the original has a nasty global component - */ + */ private function wp_get_sidebars_widgets() { $sidebars_widgets = get_option( 'sidebars_widgets', array() ); @@ -293,7 +293,7 @@ private function wp_get_sidebars_widgets() { /** * Get the widget's name, option index, sidebar, and sidebar index from its ID - * + * * @param string $widget_id * @return array */ @@ -321,7 +321,7 @@ private function get_widget_data( $widget_id ) { /** * Get the options for a given widget - * + * * @param string $name * @return array */ @@ -331,7 +331,7 @@ private function get_widget_options( $name ) { /** * Update the options for a given widget - * + * * @param string $name * @param mixed */ @@ -341,7 +341,7 @@ private function update_widget_options( $name, $value ) { /** * Reposition a widget within a sidebar - * + * * @param string $widget_id * @param string $current_sidebar_id * @param string $new_sidebar_id @@ -387,7 +387,7 @@ private function move_sidebar_widget( $widget_id, $current_sidebar_id, $new_side /** * Get a widget's instantiated object based on its name - * + * * @param string $id_base Name of the widget * @return WP_Widget|false */ @@ -404,7 +404,7 @@ private function get_widget_obj( $id_base ) { /** * Clean up a widget's options based on its update callback - * + * * @param string $id_base Name of the widget * @param mixed $dirty_options * @param mixed $old_options From 6cb10ef5e4ae07cc4a1c5d7935a0f89ffedd54d9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 09:18:05 -0700 Subject: [PATCH 2834/4858] Support deleting multiple widgets in one go --- features/widget.feature | 12 +++++------- php/commands/widget.php | 33 +++++++++++++++++---------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/features/widget.feature b/features/widget.feature index 76c0cc6b13..49dfb2a839 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -46,16 +46,15 @@ Feature: Manage widgets in WordPress sidebar | name | id | position | | recent-comments | recent-comments-2 | 1 | - When I run `wp widget delete archives-2` + When I run `wp widget delete archives-2 recent-posts-2` Then STDOUT should not be empty When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: | name | id | position | | search | search-2 | 1 | - | recent-posts | recent-posts-2 | 2 | - | categories | categories-2 | 3 | - | meta | meta-2 | 4 | + | categories | categories-2 | 2 | + | meta | meta-2 | 3 | When I run `wp widget add calendar sidebar-1 2` Then STDOUT should not be empty @@ -65,9 +64,8 @@ Feature: Manage widgets in WordPress sidebar | name | id | position | | search | search-2 | 1 | | calendar | calendar-1 | 2 | - | recent-posts | recent-posts-2 | 3 | - | categories | categories-2 | 4 | - | meta | meta-2 | 5 | + | categories | categories-2 | 3 | + | meta | meta-2 | 4 | When I run `wp widget update calendar-1 --title="Calendar"` Then STDOUT should not be empty diff --git a/php/commands/widget.php b/php/commands/widget.php index 4282a04fc4..a9aa724146 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -175,31 +175,32 @@ public function move( $args, $assoc_args ) { } /** - * Delete a widget from a sidebar. + * Delete one or more widgets from a sidebar. * - * <widget-id> - * : Unique ID for the widget + * <widget-id>... + * : Unique ID for the widget(s) * * @subcommand delete */ public function delete( $args, $assoc_args ) { - list( $widget_id ) = $args; - $this->validate_sidebar_widget( $widget_id ); + foreach( $args as $widget_id ) { + $this->validate_sidebar_widget( $widget_id ); - // Remove the widget's settings - list( $name, $option_index, $sidebar_id, $sidebar_index ) = $this->get_widget_data( $widget_id ); - $widget_options = $this->get_widget_options( $name ); - unset( $widget_options[ $option_index ] ); - $this->update_widget_options( $name, $widget_options ); + // Remove the widget's settings + list( $name, $option_index, $sidebar_id, $sidebar_index ) = $this->get_widget_data( $widget_id ); + $widget_options = $this->get_widget_options( $name ); + unset( $widget_options[ $option_index ] ); + $this->update_widget_options( $name, $widget_options ); - // Remove the widget from the sidebar - $all_widgets = $this->wp_get_sidebars_widgets(); - unset( $all_widgets[ $sidebar_id ][ $sidebar_index ] ); - $all_widgets[ $sidebar_id ] = array_values( $all_widgets[ $sidebar_id ] ); - update_option( 'sidebars_widgets', $all_widgets ); + // Remove the widget from the sidebar + $all_widgets = $this->wp_get_sidebars_widgets(); + unset( $all_widgets[ $sidebar_id ][ $sidebar_index ] ); + $all_widgets[ $sidebar_id ] = array_values( $all_widgets[ $sidebar_id ] ); + update_option( 'sidebars_widgets', $all_widgets ); + } - WP_CLI::success( "Widget removed from sidebar." ); + WP_CLI::success( "Widget(s) removed from sidebar." ); } /** From c2eb40ad3ed8cf7d5d0ee92a2bded59330bf67e0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 09:29:50 -0700 Subject: [PATCH 2835/4858] Hook up some widget examples --- php/commands/widget.php | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index a9aa724146..eaf30131d7 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -2,6 +2,20 @@ /** * Manage sidebar widgets. + * + * ## EXAMPLES + * + * # List widgets on a given sidebar + * wp widget list sidebar-1 + * + * # Add a calendar widget to the second position on the sidebar + * wp widget add calendar sidebar-1 2 + * + * # Update option(s) associated with a given widget + * wp widget update calendar-1 --title="Calendar" + * + * # Delete one or more widgets entirely + * wp widget delete calendar-2 archive-1 */ class Widget_Command extends WP_CLI_Command { @@ -27,7 +41,7 @@ class Widget_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp sidebar widget list <sidebar> --fields=name --format=csv + * wp sidebar widget list <sidebar-id> --fields=name --format=csv * * @subcommand list */ @@ -65,6 +79,10 @@ public function list_( $args, $assoc_args ) { * [--<field>=<value>] * : Widget option to add, with its new value * + * ## EXAMPLES + * + * wp widget add calendar sidebar-1 2 --title="Calendar" + * * @subcommand add */ public function add( $args, $assoc_args ) { @@ -111,6 +129,10 @@ public function add( $args, $assoc_args ) { * [--<field>=<value>] * : Field to update, with its new value * + * ## EXAMPLES + * + * wp widget update calendar-1 --title="Calendar" + * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -145,6 +167,12 @@ public function update( $args, $assoc_args ) { * [--sidebar-id=<sidebar-id>] * : Assign the widget to a new sidebar * + * ## EXAMPLES + * + * wp widget move recent-comments-2 --position=2 + * + * wp widget move recent-comments-2 --sidebar-id=wp_inactive_widgets + * * @subcommand move */ public function move( $args, $assoc_args ) { @@ -180,6 +208,10 @@ public function move( $args, $assoc_args ) { * <widget-id>... * : Unique ID for the widget(s) * + * ## EXAMPLES + * + * wp widget delete recent-comments-2 + * * @subcommand delete */ public function delete( $args, $assoc_args ) { From b081e5332a34d7f348d3ba5be7c5261d63ca91b8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 09:36:48 -0700 Subject: [PATCH 2836/4858] Add `wp widget deactivate` for moving widgets to the deactivated sidebar --- features/widget.feature | 9 +++++---- php/commands/widget.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/features/widget.feature b/features/widget.feature index 49dfb2a839..b5c7317613 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -32,6 +32,9 @@ Feature: Manage widgets in WordPress sidebar When I run `wp widget move recent-comments-2 --sidebar-id=wp_inactive_widgets` Then STDOUT should not be empty + When I run `wp widget deactivate meta-2` + Then STDOUT should not be empty + When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: | name | id | position | @@ -39,12 +42,12 @@ Feature: Manage widgets in WordPress sidebar | recent-posts | recent-posts-2 | 2 | | archives | archives-2 | 3 | | categories | categories-2 | 4 | - | meta | meta-2 | 5 | When I run `wp widget list wp_inactive_widgets --fields=name,id,position` Then STDOUT should be a table containing rows: | name | id | position | - | recent-comments | recent-comments-2 | 1 | + | meta | meta-2 | 1 | + | recent-comments | recent-comments-2 | 2 | When I run `wp widget delete archives-2 recent-posts-2` Then STDOUT should not be empty @@ -54,7 +57,6 @@ Feature: Manage widgets in WordPress sidebar | name | id | position | | search | search-2 | 1 | | categories | categories-2 | 2 | - | meta | meta-2 | 3 | When I run `wp widget add calendar sidebar-1 2` Then STDOUT should not be empty @@ -65,7 +67,6 @@ Feature: Manage widgets in WordPress sidebar | search | search-2 | 1 | | calendar | calendar-1 | 2 | | categories | categories-2 | 3 | - | meta | meta-2 | 4 | When I run `wp widget update calendar-1 --title="Calendar"` Then STDOUT should not be empty diff --git a/php/commands/widget.php b/php/commands/widget.php index eaf30131d7..00ca77231b 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -202,6 +202,36 @@ public function move( $args, $assoc_args ) { } + /** + * Deactivate one or more widgets from an active sidebar. + * + * <widget-id>... + * : Unique ID for the widget(s) + * + * ## EXAMPLES + * + * wp widget deactivate recent-comments-2 + * + * @subcommand deactivate + */ + public function deactivate( $args, $assoc_args ) { + + foreach( $args as $widget_id ) { + $this->validate_sidebar_widget( $widget_id ); + + list( $name, $option_index, $sidebar_id, $sidebar_index ) = $this->get_widget_data( $widget_id ); + if ( 'wp_inactive_widgets' == $sidebar_id ) { + WP_CLI::warning( sprintf( "'%s' is already deactivated.", $widget_id ) ); + continue; + } + + $this->move_sidebar_widget( $widget_id, $sidebar_id, 'wp_inactive_widgets', $sidebar_index, 0 ); + + } + + WP_CLI::success( "Widget(s) deactivated" ); + } + /** * Delete one or more widgets from a sidebar. * From 45789f75e0a3c7520dcf9c28f2225365e7c95309 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 11:45:04 -0700 Subject: [PATCH 2837/4858] Add `--network` support for `wp core is-installed` --- features/core.feature | 16 ++++++++++++++-- php/commands/core.php | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index a7c647917d..73ac9662c3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -101,6 +101,9 @@ Feature: Manage WordPress installation When I try `wp core is-installed` Then the return code should be 1 + When I try `wp core is-installed --network` + Then the return code should be 1 + When I try `wp core install` Then the return code should be 1 And STDERR should contain: @@ -117,6 +120,9 @@ Feature: Manage WordPress installation http://localhost:8001 """ + When I try `wp core is-installed --network` + Then the return code should be 1 + Scenario: Install WordPress by prompting Given an empty directory And WP files @@ -169,7 +175,10 @@ Feature: Manage WordPress installation Then STDOUT should be: """ false - """ + """ + + When I try `wp core is-installed --network` + Then the return code should be 1 When I run `wp core install-network --title='test network'` Then STDOUT should not be empty @@ -178,7 +187,10 @@ Feature: Manage WordPress installation Then STDOUT should be: """ true - """ + """ + + When I run `wp core is-installed --network` + Then the return code should be 0 When I try `wp core install-network --title='test network'` Then the return code should be 1 diff --git a/php/commands/core.php b/php/commands/core.php index f2c9247ba7..8bec2be5ab 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -279,6 +279,9 @@ public function config( $_, $assoc_args ) { /** * Determine if the WordPress tables are installed. * + * [--network] + * : Check if this is a multisite install + * * ## EXAMPLES * * if ! $(wp core is-installed); then @@ -287,8 +290,15 @@ public function config( $_, $assoc_args ) { * * @subcommand is-installed */ - public function is_installed() { - if ( is_blog_installed() ) { + public function is_installed( $_, $assoc_args ) { + + if ( isset( $assoc_args['network'] ) ) { + if ( is_blog_installed() && is_multisite() ) { + exit( 0 ); + } else { + exit( 1 ); + } + } else if ( is_blog_installed() ) { exit( 0 ); } else { exit( 1 ); From 5bcba9124feea5bdc933f38554eeed0d1585c177 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 12:00:43 -0700 Subject: [PATCH 2838/4858] Optionally send an email to the user when their account is created --- php/commands/user.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index b3ce47bc34..a7622b6adf 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -163,6 +163,9 @@ public function delete( $args, $assoc_args ) { * [--display_name=<name>] * : The display name. * + * [--send-email] + * : Send an email to the user with their new account details. + * * [--porcelain] * : Output just the new user id. * @@ -201,6 +204,9 @@ public function create( $args, $assoc_args ) { $user->role = $role; $user_id = wp_insert_user( $user ); + if ( isset( $assoc_args['send-email'] ) ) { + wp_new_user_notification( $user_id, $user->user_pass ); + } if ( is_wp_error( $user_id ) ) { WP_CLI::error( $user_id ); @@ -505,6 +511,9 @@ public function list_caps( $args, $assoc_args ) { * <file> * : The CSV file of users to import. * + * [--send-email] + * : Send an email to new users with their account details. + * * ## EXAMPLES * * wp user import-csv /path/to/users.csv @@ -564,6 +573,9 @@ public function import_csv( $args, $assoc_args ) { } else { unset( $new_user['ID'] ); // Unset else it will just return the ID $user_id = wp_insert_user( $new_user ); + if ( isset( $assoc_args['send-email'] ) ) { + wp_new_user_notification( $user_id, $new_user['user_pass'] ); + } } if ( is_wp_error( $user_id ) ) { From 7390b8b1dbe4ad250548841a636c265ed4ef34ee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 14:31:18 -0700 Subject: [PATCH 2839/4858] Whitespace cleanup --- php/commands/menu.php | 136 +++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 17a1e1138f..b9f3ea5d8f 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -16,13 +16,13 @@ class Menu_Command extends WP_CLI_Command { /** * Create a new menu - * + * * <menu-name> * : A descriptive name for the menu * * [--porcelain] - * : Output just the new menu id. - * + * : Output just the new menu id. + * * ## EXAMPLES * * wp menu create "My Menu" @@ -48,10 +48,10 @@ public function create( $args, $assoc_args ) { /** * List locations for the current theme. - * + * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table - * + * * @subcommand theme-locations */ public function theme_locations( $_, $assoc_args ) { @@ -71,10 +71,10 @@ public function theme_locations( $_, $assoc_args ) { /** * Assign a location to a menu - * + * * <menu> * : The name, slug, or term ID for the menu - * + * * <location> * : Location's slug * @@ -87,7 +87,7 @@ public function assign_location( $args, $_ ) { $menu = wp_get_nav_menu_object( $menu ); if ( ! $menu || is_wp_error( $menu ) ) { WP_CLI::error( "Invalid menu." ); - } + } $locations = get_registered_nav_menus(); if ( ! array_key_exists( $location, $locations ) ) { @@ -95,7 +95,7 @@ public function assign_location( $args, $_ ) { } $locations = get_nav_menu_locations(); - $locations[ $location ] = $menu->term_id; + $locations[ $location ] = $menu->term_id; set_theme_mod( 'nav_menu_locations', $locations ); @@ -104,10 +104,10 @@ public function assign_location( $args, $_ ) { /** * Remove a location from a menu - * + * * <menu> * : The name, slug, or term ID for the menu - * + * * <location> * : Location's slug * @@ -120,14 +120,14 @@ public function remove_location( $args, $_ ) { $menu = wp_get_nav_menu_object( $menu ); if ( ! $menu || is_wp_error( $menu ) ) { WP_CLI::error( "Invalid menu." ); - } + } $locations = get_nav_menu_locations(); if ( ! isset( $locations[ $location ] ) || $locations[ $location ] != $menu->term_id ) { WP_CLI::error( "Menu isn't assigned to location." ); } - $locations[ $location ] = 0; + $locations[ $location ] = 0; set_theme_mod( 'nav_menu_locations', $locations ); WP_CLI::success( "Removed location from menu." ); @@ -136,10 +136,10 @@ public function remove_location( $args, $_ ) { /** * Delete a menu - * + * * <menu> * : The name, slug, or term ID for the menu - * + * * ## EXAMPLES * * wp menu delete "My Menu" @@ -195,7 +195,7 @@ public function list_( $_, $assoc_args ) { } } - + // Normalize the data for some output formats if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table' ) ) ) { $menu->locations = implode( ',', $menu->locations ); @@ -230,7 +230,7 @@ class Menu_Item_Command extends WP_CLI_Command { * Get a list of items associated with a menu * * ## OPTIONS - * + * * <menu> * : The name, slug, or term ID for the menu * @@ -268,40 +268,40 @@ public function list_( $args, $assoc_args ) { /** * Add a post as a menu item - * + * * <menu> * : The name, slug, or term ID for the menu - * + * * <post-id> * : Post ID to add to the menu - * + * * [--title=<title>] * : Set a custom title for the menu item - * + * * [--link=<link>] * : Set a custom url for the menu item - * + * * [--description=<description>] * : Set a custom description for the menu item - * + * * [--attr-title=<attr-title>] * : Set a custom title attribute for the menu item - * + * * [--target=<target>] * : Set a custom link target for the menu item - * + * * [--classes=<classes>] * : Set a custom link classes for the menu item - * + * * [--position=<position>] * : Specify the position of this menu item. - * + * * [--parent-id=<parent-id>] * : Make this menu item a child of another menu item - * + * * [--porcelain] * : Output just the new menu item id. - * + * * @subcommand add-post */ public function add_post( $args, $assoc_args ) { @@ -319,43 +319,43 @@ public function add_post( $args, $assoc_args ) { /** * Add a taxonomy term as a menu item - * + * * <menu> * : The name, slug, or term ID for the menu - * + * * <taxonomy> * : Taxonomy of the term to be added - * + * * <term-id> * : Term ID of the term to be added - * + * * [--title=<title>] * : Set a custom title for the menu item - * + * * [--link=<link>] * : Set a custom url for the menu item - * + * * [--description=<description>] * : Set a custom description for the menu item - * + * * [--attr-title=<attr-title>] * : Set a custom title attribute for the menu item - * + * * [--target=<target>] * : Set a custom link target for the menu item - * + * * [--classes=<classes>] * : Set a custom link classes for the menu item - * + * * [--position=<position>] * : Specify the position of this menu item. - * + * * [--parent-id=<parent-id>] * : Make this menu item a child of another menu item - * + * * [--porcelain] * : Output just the new menu item id. - * + * * @subcommand add-term */ public function add_term( $args, $assoc_args ) { @@ -374,37 +374,37 @@ public function add_term( $args, $assoc_args ) { /** * Add a custom menu item - * + * * <menu> * : The name, slug, or term ID for the menu - * + * * <title> * : Title for the link - * + * * <link> * : Target URL for the link - * + * * [--description=<description>] * : Set a custom description for the menu item - * + * * [--attr-title=<attr-title>] * : Set a custom title attribute for the menu item - * + * * [--target=<target>] * : Set a custom link target for the menu item - * + * * [--classes=<classes>] * : Set a custom link classes for the menu item - * + * * [--position=<position>] * : Specify the position of this menu item. - * + * * [--parent-id=<parent-id>] * : Make this menu item a child of another menu item - * + * * [--porcelain] * : Output just the new menu item id. - * + * * @subcommand add-custom */ public function add_custom( $args, $assoc_args ) { @@ -418,34 +418,34 @@ public function add_custom( $args, $assoc_args ) { /** * Update a menu item - * + * * <db-id> * : Database ID for the menu item. - * + * * [--title=<title>] * : Set a custom title for the menu item - * + * * [--link=<link>] * : Set a custom url for the menu item - * + * * [--description=<description>] * : Set a custom description for the menu item - * + * * [--attr-title=<attr-title>] * : Set a custom title attribute for the menu item - * + * * [--target=<target>] * : Set a custom link target for the menu item - * + * * [--classes=<classes>] * : Set a custom link classes for the menu item - * + * * [--position=<position>] * : Specify the position of this menu item. - * + * * [--parent-id=<parent-id>] * : Make this menu item a child of another menu item - * + * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -465,10 +465,10 @@ public function update( $args, $assoc_args ) { /** * Remove an item from a menu - * + * * <db-id> * : Database ID for the menu item. - * + * * @subcommand remove */ public function remove( $args, $_ ) { @@ -516,7 +516,7 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { $menu_item_args = array(); foreach( $default_args as $key => $default_value ) { - // wp_update_nav_menu_item() has a weird argument prefix + // wp_update_nav_menu_item() has a weird argument prefix $new_key = 'menu-item-' . $key; if ( isset( $assoc_args[ $key ] ) ) { $menu_item_args[ $new_key ] = $assoc_args[ $key ]; @@ -545,11 +545,11 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { /** * Set the menu - * + * * wp_update_nav_menu_item() *should* take care of this, but * depends on wp_insert_post()'s "tax_input" argument, which * is ignored if the user can't edit the taxonomy - * + * * @see https://core.trac.wordpress.org/ticket/27113 */ if ( ! is_object_in_term( $ret, 'nav_menu', (int) $menu->term_id ) ) { From 10445774053543fa10138596d73f53aa97b0f24e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 14:36:16 -0700 Subject: [PATCH 2840/4858] Put menu location management in its own sub-sub-command --- features/menu.feature | 6 +- php/commands/menu.php | 185 ++++++++++++++++++++++-------------------- 2 files changed, 100 insertions(+), 91 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index b9309253c4..65d7774c98 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -21,19 +21,19 @@ Feature: Manage WordPress menus Scenario: Assign / remove location from a menu When I run `wp theme install p2 --activate` - And I run `wp menu theme-locations` + And I run `wp menu location list` Then STDOUT should be a table containing rows: | location | description | | primary | Primary Menu | When I run `wp menu create "Primary Menu"` - And I run `wp menu assign-location primary-menu primary` + And I run `wp menu location assign primary-menu primary` And I run `wp menu list --fields=slug,locations` Then STDOUT should be a table containing rows: | slug | locations | | primary-menu | primary | - When I run `wp menu remove-location primary-menu primary` + When I run `wp menu location remove primary-menu primary` And I run `wp menu list --fields=slug,locations` Then STDOUT should be a table containing rows: | slug | locations | diff --git a/php/commands/menu.php b/php/commands/menu.php index b9f3ea5d8f..b20934690a 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -46,94 +46,6 @@ public function create( $args, $assoc_args ) { } } - /** - * List locations for the current theme. - * - * [--format=<format>] - * : Accepted values: table, csv, json, count, ids. Default: table - * - * @subcommand theme-locations - */ - public function theme_locations( $_, $assoc_args ) { - - $locations = get_registered_nav_menus(); - $location_objs = array(); - foreach( $locations as $location => $description ) { - $location_obj = new \stdClass; - $location_obj->location = $location; - $location_obj->description = $description; - $location_objs[] = $location_obj; - } - - $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'location', 'description' ) ); - $formatter->display_items( $location_objs ); - } - - /** - * Assign a location to a menu - * - * <menu> - * : The name, slug, or term ID for the menu - * - * <location> - * : Location's slug - * - * @subcommand assign-location - */ - public function assign_location( $args, $_ ) { - - list( $menu, $location ) = $args; - - $menu = wp_get_nav_menu_object( $menu ); - if ( ! $menu || is_wp_error( $menu ) ) { - WP_CLI::error( "Invalid menu." ); - } - - $locations = get_registered_nav_menus(); - if ( ! array_key_exists( $location, $locations ) ) { - WP_CLI::error( "Invalid location." ); - } - - $locations = get_nav_menu_locations(); - $locations[ $location ] = $menu->term_id; - - set_theme_mod( 'nav_menu_locations', $locations ); - - WP_CLI::success( "Assigned location to menu." ); - } - - /** - * Remove a location from a menu - * - * <menu> - * : The name, slug, or term ID for the menu - * - * <location> - * : Location's slug - * - * @subcommand remove-location - */ - public function remove_location( $args, $_ ) { - - list( $menu, $location ) = $args; - - $menu = wp_get_nav_menu_object( $menu ); - if ( ! $menu || is_wp_error( $menu ) ) { - WP_CLI::error( "Invalid menu." ); - } - - $locations = get_nav_menu_locations(); - if ( ! isset( $locations[ $location ] ) || $locations[ $location ] != $menu->term_id ) { - WP_CLI::error( "Menu isn't assigned to location." ); - } - - $locations[ $location ] = 0; - set_theme_mod( 'nav_menu_locations', $locations ); - - WP_CLI::success( "Removed location from menu." ); - - } - /** * Delete a menu * @@ -575,5 +487,102 @@ protected function get_formatter( &$assoc_args ) { } +/** + * Manage a menu's assignment to locations. + */ +class Menu_Location_Command extends WP_CLI_Command { + + /** + * List locations for the current theme. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count, ids. Default: table + * + * @subcommand list + */ + public function list_( $_, $assoc_args ) { + + $locations = get_registered_nav_menus(); + $location_objs = array(); + foreach( $locations as $location => $description ) { + $location_obj = new \stdClass; + $location_obj->location = $location; + $location_obj->description = $description; + $location_objs[] = $location_obj; + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'location', 'description' ) ); + $formatter->display_items( $location_objs ); + } + + /** + * Assign a location to a menu + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <location> + * : Location's slug + * + * @subcommand assign + */ + public function assign( $args, $_ ) { + + list( $menu, $location ) = $args; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $locations = get_registered_nav_menus(); + if ( ! array_key_exists( $location, $locations ) ) { + WP_CLI::error( "Invalid location." ); + } + + $locations = get_nav_menu_locations(); + $locations[ $location ] = $menu->term_id; + + set_theme_mod( 'nav_menu_locations', $locations ); + + WP_CLI::success( "Assigned location to menu." ); + } + + /** + * Remove a location from a menu + * + * <menu> + * : The name, slug, or term ID for the menu + * + * <location> + * : Location's slug + * + * @subcommand remove + */ + public function remove( $args, $_ ) { + + list( $menu, $location ) = $args; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $locations = get_nav_menu_locations(); + if ( ! isset( $locations[ $location ] ) || $locations[ $location ] != $menu->term_id ) { + WP_CLI::error( "Menu isn't assigned to location." ); + } + + $locations[ $location ] = 0; + set_theme_mod( 'nav_menu_locations', $locations ); + + WP_CLI::success( "Removed location from menu." ); + + } + + +} + WP_CLI::add_command( 'menu', 'Menu_Command' ); WP_CLI::add_command( 'menu item', 'Menu_Item_Command' ); +WP_CLI::add_command( 'menu location', 'Menu_Location_Command' ); From f69026bb5a8fb46362a5fb4dbe1848aa4a4338e1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 14:41:30 -0700 Subject: [PATCH 2841/4858] First pass at updating examples --- php/commands/menu.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index b20934690a..ed397bf4b3 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -214,6 +214,10 @@ public function list_( $args, $assoc_args ) { * [--porcelain] * : Output just the new menu item id. * + * ## EXAMPLES + * + * wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * * @subcommand add-post */ public function add_post( $args, $assoc_args ) { @@ -268,6 +272,10 @@ public function add_post( $args, $assoc_args ) { * [--porcelain] * : Output just the new menu item id. * + * ## EXAMPLES + * + * wp menu item add-term sidebar-menu post_tag 24 + * * @subcommand add-term */ public function add_term( $args, $assoc_args ) { @@ -317,6 +325,10 @@ public function add_term( $args, $assoc_args ) { * [--porcelain] * : Output just the new menu item id. * + * ## EXAMPLES + * + * wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain + * * @subcommand add-custom */ public function add_custom( $args, $assoc_args ) { @@ -358,6 +370,10 @@ public function add_custom( $args, $assoc_args ) { * [--parent-id=<parent-id>] * : Make this menu item a child of another menu item * + * ## EXAMPLES + * + * wp menu item update 45 --title=WordPress --link='http://wordpress.org' --target=_blank --position=2 + * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -381,6 +397,10 @@ public function update( $args, $assoc_args ) { * <db-id> * : Database ID for the menu item. * + * ## EXAMPLES + * + * wp menu item remove 45 + * * @subcommand remove */ public function remove( $args, $_ ) { From 08a649468171924299f827ff1c23615e244bb2b4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 14:50:36 -0700 Subject: [PATCH 2842/4858] More example coverage --- php/commands/menu.php | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index ed397bf4b3..240db7dc68 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -2,6 +2,14 @@ /** * List, create, assign, and delete menus + * + * ## EXAMPLES + * + * # Create a new menu + * wp menu create "My Menu" + * + * # List existing menus + * wp menu list */ class Menu_Command extends WP_CLI_Command { @@ -127,6 +135,14 @@ protected function get_formatter( &$assoc_args ) { /** * List, add, and delete items associated with a menu + * + * ## EXAMPLES + * + * # Add an existing post to an existing menu + * wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * + * # Create a new menu link item + * wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain */ class Menu_Item_Command extends WP_CLI_Command { @@ -509,6 +525,17 @@ protected function get_formatter( &$assoc_args ) { /** * Manage a menu's assignment to locations. + * + * ## EXAMPLES + * + * # List available menu locations + * wp menu location list + * + * # Assign the 'primary-menu' menu to the 'primary' location + * wp menu location assign primary-menu primary + * + * # Remove the 'primary-menu' menu from the 'primary' location + * wp menu location remove primary-menu primary */ class Menu_Location_Command extends WP_CLI_Command { @@ -518,6 +545,10 @@ class Menu_Location_Command extends WP_CLI_Command { * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * + * ## EXAMPLES + * + * wp menu location list + * * @subcommand list */ public function list_( $_, $assoc_args ) { @@ -544,6 +575,10 @@ public function list_( $_, $assoc_args ) { * <location> * : Location's slug * + * ## EXAMPLES + * + * wp menu location assign primary-menu primary + * * @subcommand assign */ public function assign( $args, $_ ) { @@ -577,6 +612,10 @@ public function assign( $args, $_ ) { * <location> * : Location's slug * + * ## EXAMPLES + * + * wp menu location remove primary-menu primary + * * @subcommand remove */ public function remove( $args, $_ ) { From acc9c1ae2341e86f3e411f8f9c46fbfa971c673b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 14:51:22 -0700 Subject: [PATCH 2843/4858] Because `wp menu` is the "top"-level entity, offer discoverability for its children commands --- php/commands/menu.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index 240db7dc68..902e89c347 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -10,6 +10,12 @@ * * # List existing menus * wp menu list + * + * # Create a new menu link item + * wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain + * + * # Assign the 'primary-menu' menu to the 'primary' location + * wp menu location assign primary-menu primary */ class Menu_Command extends WP_CLI_Command { From 94c66ba97c945508aa6a7f22a8348a3cd4a17a58 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 15:23:44 -0700 Subject: [PATCH 2844/4858] Core PHPdoc lies, `wp_create_nav_menu()` returns a term ID See https://core.trac.wordpress.org/ticket/27745 --- php/commands/menu.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 902e89c347..b359df3ae9 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -43,18 +43,18 @@ class Menu_Command extends WP_CLI_Command { */ public function create( $args, $assoc_args ) { - $ret = wp_create_nav_menu( $args[0] ); + $menu_id = wp_create_nav_menu( $args[0] ); - if ( is_wp_error( $ret ) ) { + if ( is_wp_error( $menu_id ) ) { - WP_CLI::error( $ret->get_error_message() ); + WP_CLI::error( $menu_id->get_error_message() ); } else { if ( isset( $assoc_args['porcelain'] ) ) { - WP_CLI::line( $ret->term_id ); + WP_CLI::line( $menu_id ); } else { - WP_CLI::success( "Created menu $ret->term_id." ); + WP_CLI::success( "Created menu $menu_id." ); } } From 50b05e17df97da471a2b3aaa1817b733b7b1d0fd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 15:25:34 -0700 Subject: [PATCH 2845/4858] For consistency, let's call this `delete` instead of `remove` It permanently destroys the menu item. --- features/menu.feature | 2 +- php/commands/menu.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index 65d7774c98..60862576ee 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -71,7 +71,7 @@ Feature: Manage WordPress menus | custom | WordPress | 2 | http://wordpress.org | | taxonomy | Test term | 3 | {TERM_LINK} | - When I run `wp menu item remove {ITEM_ID}` + When I run `wp menu item delete {ITEM_ID}` And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: """ diff --git a/php/commands/menu.php b/php/commands/menu.php index b359df3ae9..af45013129 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -414,7 +414,7 @@ public function update( $args, $assoc_args ) { } /** - * Remove an item from a menu + * Delete an item from a menu * * <db-id> * : Database ID for the menu item. @@ -423,9 +423,9 @@ public function update( $args, $assoc_args ) { * * wp menu item remove 45 * - * @subcommand remove + * @subcommand delete */ - public function remove( $args, $_ ) { + public function delete( $args, $_ ) { $ret = wp_delete_post( $args[0], true ); if ( $ret ) { From 0600b1700c3db6acfcb571d351b928be2f662f80 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 9 Apr 2014 15:29:22 -0700 Subject: [PATCH 2846/4858] Support for deleting more than one menu or menu item --- php/commands/menu.php | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index af45013129..47160a541f 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -61,10 +61,10 @@ public function create( $args, $assoc_args ) { } /** - * Delete a menu + * Delete one or more menus * - * <menu> - * : The name, slug, or term ID for the menu + * <menu>... + * : The name, slug, or term ID for the menu(s) * * ## EXAMPLES * @@ -72,17 +72,20 @@ public function create( $args, $assoc_args ) { */ public function delete( $args, $_ ) { - $ret = wp_delete_nav_menu( $args[0] ); + foreach( $args as $arg ) { - if ( ! $ret || is_wp_error( $ret ) ) { + $ret = wp_delete_nav_menu( $args[0] ); - WP_CLI::error( "Error deleting menu." ); + if ( ! $ret || is_wp_error( $ret ) ) { - } else { + WP_CLI::warning( "Error deleting menu." ); - WP_CLI::success( "Menu deleted." ); + } } + + WP_CLI::success( "Menu(s) deleted." ); + } /** @@ -414,10 +417,10 @@ public function update( $args, $assoc_args ) { } /** - * Delete an item from a menu + * Delete one or more items from a menu * - * <db-id> - * : Database ID for the menu item. + * <db-id>... + * : Database ID for the menu item(s). * * ## EXAMPLES * @@ -427,12 +430,15 @@ public function update( $args, $assoc_args ) { */ public function delete( $args, $_ ) { - $ret = wp_delete_post( $args[0], true ); - if ( $ret ) { - WP_CLI::success( "Menu item deleted." ); - } else { - WP_CLI::error( "Couldn't delete menu item." ); + foreach( $args as $arg ) { + + $ret = wp_delete_post( $arg, true ); + if ( ! $ret ) { + WP_CLI::warning( "Couldn't delete menu item." ); + } + } + WP_CLI::success( "Menu item(s) deleted." ); } From cffcf6958f3d38e77ba22fcd5e08cd469ef0d3f3 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 10 Apr 2014 02:49:03 +0300 Subject: [PATCH 2847/4858] allow shared cache in non-cache related behat tests --- features/bootstrap/FeatureContext.php | 21 +++++++++++++++------ features/core.feature | 2 ++ features/steps/given.php | 6 ++++++ features/upgradables.feature | 3 +++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d1650f5ba7..20dda8ab5c 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -41,15 +41,15 @@ private static function cache_wp_files() { */ public static function prepare( SuiteEvent $event ) { self::cache_wp_files(); - self::$suite_cache_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-suite-cache-", TRUE ); - mkdir( self::$suite_cache_dir ); } /** * @AfterSuite */ public static function afterSuite( SuiteEvent $event ) { - Process::create( Utils\esc_cmd( 'rm -r %s', self::$suite_cache_dir ) )->run(); + if ( self::$suite_cache_dir ) { + Process::create( Utils\esc_cmd( 'rm -r %s', self::$suite_cache_dir ) )->run(); + } } /** @@ -65,6 +65,12 @@ public function afterScenario( $event ) { } } + public static function create_cache_dir() { + self::$suite_cache_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-suite-cache-", TRUE ); + mkdir( self::$suite_cache_dir ); + return self::$suite_cache_dir; + } + /** * Initializes context. * Every scenario gets it's own context object. @@ -75,7 +81,6 @@ public function __construct( array $parameters ) { $this->drop_db(); $this->set_cache_dir(); $this->variables['CORE_CONFIG_SETTINGS'] = Utils\assoc_args_to_str( self::$db_settings ); - $this->variables['SUITE_CACHE_DIR'] = self::$suite_cache_dir; } public function getStepDefinitionResources() { @@ -136,8 +141,12 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - return Process::create( $command, $this->variables['RUN_DIR'], - array( 'WP_CLI_CACHE_DIR' => $this->variables['SUITE_CACHE_DIR'] ) ); + $env = array(); + if ( isset( $this->variables['SUITE_CACHE_DIR'] ) ) { + $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; + } + + return Process::create( $command, $this->variables['RUN_DIR'], $env ); } public function move_files( $src, $dest ) { diff --git a/features/core.feature b/features/core.feature index 73ac9662c3..fd7793eaa0 100644 --- a/features/core.feature +++ b/features/core.feature @@ -3,6 +3,7 @@ Feature: Manage WordPress installation @download Scenario: Empty dir Given an empty directory + And an empty cache When I try `wp core is-installed` Then the return code should be 1 @@ -28,6 +29,7 @@ Feature: Manage WordPress installation @download Scenario: Localized install Given an empty directory + And an empty cache When I run `wp core download --locale=de_DE` And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} Then the wp-settings.php file should exist diff --git a/features/steps/given.php b/features/steps/given.php index a7b29d3c25..21117c55b2 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -9,6 +9,12 @@ function ( $world ) { } ); +$steps->Given( '/^an empty cache/', + function ( $world ) { + $world->variables['SUITE_CACHE_DIR'] = FeatureContext::create_cache_dir(); + } +); + $steps->Given( '/^an? ([^\s]+) file:$/', function ( $world, $path, PyStringNode $content ) { $content = (string) $content . "\n"; diff --git a/features/upgradables.feature b/features/upgradables.feature index 830291fe70..2bc9c2e06a 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -1,5 +1,8 @@ Feature: Manage WordPress themes and plugins + Background: + Given an empty cache + Scenario Outline: Installing, upgrading and deleting a theme or plugin Given a WP install And I run `wp <type> path` From 108d875956ba973219473c5e71f95358bef463f4 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 10 Apr 2014 14:14:54 +0300 Subject: [PATCH 2848/4858] wp core update: fix description for --force parameter closes #1110 --- php/commands/core.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8bec2be5ab..a112cc4f99 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -661,8 +661,7 @@ public function version( $args = array(), $assoc_args = array() ) { * : Update to this version, instead of to the latest version. * * [--force] - * : Will update even when current WP version < passed version. Use with - * caution. + * : Update even when installed WP version is greater than the requested version. * * [--locale=<locale>] * : Select which language you want to download. From 7d26d6afb59486e42200e76d612ed39cc5c6a791 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 10 Apr 2014 11:22:09 -0300 Subject: [PATCH 2849/4858] use wp locale instead of 'en_US' if locale argument is not used in wp core update --- php/commands/core.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index a112cc4f99..3a064aaf58 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -685,7 +685,6 @@ function update( $args, $assoc_args ) { if ( empty( $assoc_args['version'] ) ) { wp_version_check(); $from_api = get_site_transient( 'update_core' ); - if ( empty( $from_api->updates ) ) $update = false; else @@ -698,7 +697,7 @@ function update( $args, $assoc_args ) { if ( empty( $args[0] ) ) { $version = $assoc_args['version']; - $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; + $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : get_locale(); $new_package = $this->get_download_url($version, $locale); From 6161a641b7d28ec6bfc81c4b104651a90ddf8cc4 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 10 Apr 2014 15:05:47 -0300 Subject: [PATCH 2850/4858] add again line removed by mistake --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index 3a064aaf58..1ea378638c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -685,6 +685,7 @@ function update( $args, $assoc_args ) { if ( empty( $assoc_args['version'] ) ) { wp_version_check(); $from_api = get_site_transient( 'update_core' ); + if ( empty( $from_api->updates ) ) $update = false; else From 43f6ed09674f7bc6d6f18d274da0d8d726ef10b3 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 11 Apr 2014 23:43:14 -0300 Subject: [PATCH 2851/4858] add --autoload option to 'wp option add' command --- php/commands/option.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index f5e025860d..ded55ce2be 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -50,6 +50,9 @@ public function get( $args, $assoc_args ) { * [--format=<format>] * : The serialization format for the value. Default is plaintext. * + * [--autoload=<autoload>] + * : Should this option be automatically loaded. Accepted values: yes, no. Default: yes + * * ## EXAMPLES * * # Create an option by reading a JSON file @@ -61,7 +64,13 @@ public function add( $args, $assoc_args ) { $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); $value = WP_CLI::read_value( $value, $assoc_args ); - if ( !add_option( $key, $value ) ) { + if ( isset( $assoc_args['autoload'] ) && $assoc_args['autoload'] == 'no' ) { + $autoload = 'no'; + } else { + $autoload = 'yes'; + } + + if ( !add_option( $key, $value, '', $autoload ) ) { WP_CLI::error( "Could not add option '$key'. Does it already exist?" ); } else { WP_CLI::success( "Added '$key' option." ); From f3c70ecbccdcffa897ef936fd511e3bb73485a1b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Apr 2014 16:48:07 +0300 Subject: [PATCH 2852/4858] wp core download: error if the requested locale is not found fixes #1117 --- php/commands/core.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 1ea378638c..2853b27ecf 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -28,7 +28,7 @@ class Core_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp core download --version=3.3 + * wp core download --locale=nl_NL * * @when before_wp_load */ @@ -48,6 +48,9 @@ public function download( $args, $assoc_args ) { $download_url = $this->get_download_url($version, $locale, 'tar.gz'); } else { $offer = $this->get_download_offer( $locale ); + if ( !$offer ) { + WP_CLI::error( "The requested locale ($locale) was not found." ); + } $version = $offer['current']; $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); } @@ -165,7 +168,13 @@ private function get_download_offer( $locale ) { $out = unserialize( self::_read( 'https://api.wordpress.org/core/version-check/1.6/?locale=' . $locale ) ); - return $out['offers'][0]; + $offer = $out['offers'][0]; + + if ( $offer['locale'] != $locale ) { + return false; + } + + return $offer; } private static function get_initial_locale() { From a8e0ff31edfdbae0ac4e455eda613414146e0a40 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Apr 2014 17:37:21 +0300 Subject: [PATCH 2853/4858] introduce --network flag for 'wp user delete' --- features/user.feature | 15 +++++++++++++++ php/commands/user.php | 27 +++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/features/user.feature b/features/user.feature index 793c3bf6ad..abda339176 100644 --- a/features/user.feature +++ b/features/user.feature @@ -70,6 +70,21 @@ Feature: Manage WordPress users 3 """ + Scenario: Deleting user from the whole network + Given a WP multisite install + + When I run `wp user create bob bob@example.com --role=author --porcelain` + And save STDOUT as {BOB_ID} + + When I run `wp user get bob` + Then STDOUT should not be empty + + When I run `wp user delete bob --network` + Then STDOUT should not be empty + + When I try `wp user get bob` + Then STDERR should not be empty + Scenario: Generating and deleting users Given a WP install diff --git a/php/commands/user.php b/php/commands/user.php index a7622b6adf..2ce568b260 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -115,25 +115,40 @@ public function get( $args, $assoc_args ) { * <user>... * : The user login, user email, or user ID of the user(s) to update. * + * [--network] + * : On multisite, delete the user from the entire network. + * * [--reassign=<user-id>] * : User ID to reassign the posts to. * * ## EXAMPLES * + * # Delete user 123 and reassign posts to user 567 * wp user delete 123 --reassign=567 */ public function delete( $args, $assoc_args ) { - $assoc_args = wp_parse_args( $assoc_args, array( - 'reassign' => null - ) ); + $network = isset( $assoc_args['network'] ) && is_multisite(); + $reassign = isset( $assoc_args['reassign'] ) ? $assoc_args['reassign'] : null; + + if ( $network && $reassign ) { + WP_CLI::error('Reassigning content to a different user is not supported on multisite.'); + } $users = $this->fetcher->get_many( $args ); - parent::_delete( $users, $assoc_args, function ( $user, $assoc_args ) { + parent::_delete( $users, $assoc_args, function ( $user ) use ( $network, $reassign ) { $user_id = $user->ID; - if ( wp_delete_user( $user_id, $assoc_args['reassign'] ) ) { - return array( 'success', "Deleted user $user_id." ); + if ( $network ) { + $r = wpmu_delete_user( $user_id ); + $message = "Deleted user $user_id."; + } else { + $r = wp_delete_user( $user_id, $reassign ); + $message = "Removed user $user_id from " . home_url(); + } + + if ( $r ) { + return array( 'success', $message ); } else { return array( 'error', "Failed deleting user $user_id." ); } From 0a7cac5a1340a299231b5a3833967a035bb8636f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Apr 2014 17:50:08 +0300 Subject: [PATCH 2854/4858] show confirmation prompt before deleting user without reassigning posts --- features/user.feature | 8 ++++---- php/commands/user.php | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/features/user.feature b/features/user.feature index abda339176..ba508535fd 100644 --- a/features/user.feature +++ b/features/user.feature @@ -17,7 +17,7 @@ Feature: Manage WordPress users | ID | {USER_ID} | | roles | author | - When I run `wp user delete {USER_ID}` + When I run `wp user delete {USER_ID} --yes` Then STDOUT should not be empty When I try `wp user create testuser2 testuser2@example.com --role=wrongrole --porcelain` @@ -44,7 +44,7 @@ Feature: Manage WordPress users | ID | {USER_ID} | | display_name | Foo | - When I run `wp user delete {USER_ID}` + When I run `wp user delete {USER_ID} --yes` Then STDOUT should not be empty Scenario: Reassigning user posts @@ -79,7 +79,7 @@ Feature: Manage WordPress users When I run `wp user get bob` Then STDOUT should not be empty - When I run `wp user delete bob --network` + When I run `wp user delete bob --network --yes` Then STDOUT should not be empty When I try `wp user get bob` @@ -101,7 +101,7 @@ Feature: Manage WordPress users 10 """ - When I try `wp user list --field=ID | xargs wp user delete invalid-user` + When I try `wp user list --field=ID | xargs wp user delete invalid-user --yes` And I run `wp user list --format=count` Then STDOUT should be: """ diff --git a/php/commands/user.php b/php/commands/user.php index 2ce568b260..68771013fe 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -121,6 +121,9 @@ public function get( $args, $assoc_args ) { * [--reassign=<user-id>] * : User ID to reassign the posts to. * + * [--yes] + * : Answer yes to any confirmation propmts. + * * ## EXAMPLES * * # Delete user 123 and reassign posts to user 567 @@ -134,6 +137,10 @@ public function delete( $args, $assoc_args ) { WP_CLI::error('Reassigning content to a different user is not supported on multisite.'); } + if ( !$reassign ) { + WP_CLI::confirm( '--reassign parameter not passed. All associated posts will be deleted. Proceed?', $assoc_args ); + } + $users = $this->fetcher->get_many( $args ); parent::_delete( $users, $assoc_args, function ( $user ) use ( $network, $reassign ) { From 1fa1a5cd2d2995577c7bbf6ca324ee044473ca51 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Apr 2014 18:15:04 +0300 Subject: [PATCH 2855/4858] allow defining --extra-php in wp-cli.yml --- features/config.feature | 25 ++++++++++++++++--------- php/commands/core.php | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/features/config.feature b/features/config.feature index b103ef73ba..b8711ae2da 100644 --- a/features/config.feature +++ b/features/config.feature @@ -107,26 +107,33 @@ Feature: Have a config file command has been disabled """ - Scenario: Command-specific configs - Given a WP install + Scenario: 'core config' parameters + Given an empty directory + And WP files And a wp-cli.yml file: """ core config: dbname: wordpress dbuser: root + extra-php: | + define( 'WP_DEBUG', true ); + define( 'WP_POST_REVISIONS', 50 ); + """ + + When I run `wp core config --skip-check` + And I run `grep WP_POST_REVISIONS wp-config.php` + Then STDOUT should not be empty + + Scenario: Command-specific configs + Given a WP install + And a wp-cli.yml file: + """ eval: foo: bar post list: format: count """ - # Required parameters should be recognized - When I try `wp core config` - Then STDERR should not contain: - """ - Parameter errors - """ - # Arbitrary values should be passed, without warnings When I run `wp eval 'echo json_encode( $assoc_args );'` Then STDOUT should be JSON containing: diff --git a/php/commands/core.php b/php/commands/core.php index 2853b27ecf..2f365e515d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -265,7 +265,7 @@ public function config( $_, $assoc_args ) { ) ); } - if ( isset( $assoc_args['extra-php'] ) ) { + if ( isset( $assoc_args['extra-php'] ) && $assoc_args['extra-php'] === true ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); } From 8d9acb3d59de16a5b547b5977d596eb47dc3e282 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Apr 2014 19:05:56 +0300 Subject: [PATCH 2856/4858] enable unfiltered HTML when an explicit user is not passed fixes #945 --- features/post.feature | 15 ++++++--------- php/WP_CLI/Runner.php | 14 +++++++------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/features/post.feature b/features/post.feature index aaec9469b3..e1993e1f1f 100644 --- a/features/post.feature +++ b/features/post.feature @@ -31,7 +31,9 @@ Feature: Manage WordPress posts """ This is some content. - It will be inserted in a post. + <script> + alert('This should not be stripped.'); + </script> """ And a command.sh file: """ @@ -43,20 +45,15 @@ Feature: Manage WordPress posts Then STDOUT should be a number And save STDOUT as {POST_ID} - When I run `wp eval '$post_id = {POST_ID}; echo get_post( $post_id )->post_excerpt;'` + When I run `wp post get --field=excerpt {POST_ID}` Then STDOUT should be: """ A multiline excerpt """ - When I run `wp post get --field=content {POST_ID}` - Then STDOUT should be: - """ - This is some content. - - It will be inserted in a post. - """ + When I run `wp post get --field=content {POST_ID} | diff -Bu content.html -` + Then STDOUT should be empty When I run `wp post get --format=table {POST_ID}` Then STDOUT should be a table containing rows: diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7a4cf01639..10db74c196 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -139,13 +139,13 @@ private static function set_wp_root( $path ) { } private static function set_user( $assoc_args ) { - if ( !isset( $assoc_args['user'] ) ) - return; - - $fetcher = new \WP_CLI\Fetchers\User; - $user = $fetcher->get_check( $assoc_args['user'] ); - wp_set_current_user( $user->ID ); - + if ( isset( $assoc_args['user'] ) ) { + $fetcher = new \WP_CLI\Fetchers\User; + $user = $fetcher->get_check( $assoc_args['user'] ); + wp_set_current_user( $user->ID ); + } else { + kses_remove_filters(); + } } private static function guess_url( $assoc_args ) { From fd5a95f208bb0fa9422a03cf40091e1a7704e481 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sun, 13 Apr 2014 20:06:28 +0300 Subject: [PATCH 2857/4858] bump version to 0.15-beta --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index cda6d57d24..a98ce59e32 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.15-alpha' ); +define( 'WP_CLI_VERSION', '0.15-beta' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 5206df754c8370d441a23a0fcc7071e45d1656e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 15 Apr 2014 18:32:15 +0300 Subject: [PATCH 2858/4858] bump version to 0.15.0 and update .mailmap --- .mailmap | 7 +++++++ php/wp-cli.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 0086f71984..001d93e0a6 100644 --- a/.mailmap +++ b/.mailmap @@ -5,11 +5,13 @@ BoiteAWeb <juliobosk@gmail.com> boonebgorges <boonebgorges@gmail.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> +clemens-tolboom <clemens@build2be.com> conatus <alex@recordsonribs.com> ctayloroomphinc <ctaylor@thinkoomph.com> cyberhobo <dylan.k.kuhn@gmail.com> dangardner <dan@web.nearest.to> danielbachhuber <d@danielbachhuber.com> +danielbachhuber <daniel@handbuilt.co> danielbachhuber <danielbachhuber@gmail.com> dd32 <contact-atlassian@dd32.id.au> drrobotnik <B@Brandons-Mac-Pro-4.local> @@ -39,6 +41,7 @@ leewillis77 <leewillis77@gmail.com> marcoceppi <marco@ceppi.net> matiskay <matiskay@gmail.com> mattes <matthias.kadenbach@gmail.com> +mattheu <matthew@matth.eu> mboynes <mboynes@alleyinteractive.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> @@ -53,14 +56,17 @@ nickdaugherty <ndaugherty987@gmail.com> nikolay <nikolay@users.noreply.github.com> nikolay <nikolaynkolev@gmail.com> nullvariable <nullvariable@gmail.com> +nyordanov <me@nyordanov.com> ocean90 <dominikschilling+git@gmail.com> oknoway <nate@oknoway.com> om4james <james@jamesc.id.au> om4james <james@om4.com.au> Rarst <contact@rarst.net> +robertboloc <robertboloc@gmail.com> rodrigoprimo <rodrigo@hacklab.com.br> roelven <roel@soundcloud.com> ryanduff <ryan@fusionized.com> +sboisvert <stephane.boisvert@automattic.com> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> sibprogrammer <ayuzhakov@parallels.com> @@ -70,6 +76,7 @@ SpikesDivZero <wesley.spikes@gmail.com> spuriousdata <spuriousdata@gmail.com> stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> +szepeviktor <viktor@szepe.net> taupecat <tracy@taupecat.com> tddewey <td@tddewey.com> thisislawatts <luke@thisis.la> diff --git a/php/wp-cli.php b/php/wp-cli.php index a98ce59e32..f9615aded1 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.15-beta' ); +define( 'WP_CLI_VERSION', '0.15.0' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From b56ef13961fde7ace574e79b26186d3d36a16482 Mon Sep 17 00:00:00 2001 From: jmslbam <jmslbam@gmail.com> Date: Thu, 17 Apr 2014 12:50:48 +0200 Subject: [PATCH 2859/4858] Use the WP _n instead of ngettext function --- php/commands/media.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index f6e0261a25..08770b097d 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -50,7 +50,7 @@ function regenerate( $args, $assoc_args = array() ) { } WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, - ngettext( 'image', 'images', $count ) ) ); + _n( 'image', 'images', $count ) ) ); foreach ( $images->posts as $id ) { $this->_process_regeneration( $id ); @@ -58,7 +58,7 @@ function regenerate( $args, $assoc_args = array() ) { WP_CLI::success( sprintf( 'Finished regenerating %1$s.', - ngettext('the image', 'all images', $count) + _n('the image', 'all images', $count) ) ); } From ce532edd6fa64b0febcf1da65b802497b2969dcc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 17 Apr 2014 06:37:03 -0700 Subject: [PATCH 2860/4858] Internalize remote assets used in behat tests This way, we aren't at the mercy of external services that go down. Except our own. --- features/media.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/media.feature b/features/media.feature index 0dca83a0ca..ee77d30bc3 100644 --- a/features/media.feature +++ b/features/media.feature @@ -11,10 +11,10 @@ Feature: Manage WordPress attachments """ Scenario: Import image from remote URL - When I run `wp media import 'http://s.wordpress.org/style/images/codeispoetry.png' --post_id=1` + When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1` Then STDOUT should contain: """ - Success: Imported file http://s.wordpress.org/style/images/codeispoetry.png + Success: Imported file http://wp-cli.org/behat-data/codeispoetry.png """ Scenario: Fail to import missing image @@ -26,8 +26,8 @@ Feature: Manage WordPress attachments Scenario: Import a file as attachment from a local image Given download: - | path | url | - | {CACHE_DIR}/large-image.jpg | http://wordpresswallpaper.com/wp-content/gallery/photo-based-wallpaper/1058.jpg | + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1 --featured_image` Then STDOUT should contain: From 4e8c7191c84233affe6fef25c642c765a5fadc9b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 17 Apr 2014 07:15:18 -0700 Subject: [PATCH 2861/4858] To prevent PHP error notices, also pass `version` in the update object Core began using the `version` attribute in the stats it reports back to WordPress.org: https://core.trac.wordpress.org/changeset/25863 When `--version` is explicitly passed, or we're performing an update, we can include the version data for stats purposes. When we're performing an update from a provided ZIP file, it's not worth it to try and parse the version from the provided zip file. --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 2f365e515d..ea3c8e3f4b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -703,7 +703,7 @@ function update( $args, $assoc_args ) { } else if ( version_compare( $wp_version, $assoc_args['version'], '<' ) || isset( $assoc_args['force'] ) ) { - $new_package = null; + $new_package = $version = null; if ( empty( $args[0] ) ) { $version = $assoc_args['version']; @@ -727,6 +727,7 @@ function update( $args, $assoc_args ) { 'no_content' => null, 'full' => $new_package, ), + 'version' => $version, ); } else { From b6ae4202652a679271f3c5276c78a20b79faa3e1 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 17 Apr 2014 19:43:34 +0300 Subject: [PATCH 2862/4858] update list of maintainers [ci skip] --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cff45cfe7c..35090ea9aa 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,10 @@ Besides the libraries defined in [composer.json](composer.json), we have used co Who's behind this thing? ------------------------ -We are [Andreas Creten](https://github.com/andreascreten) and [Cristi Burcă](https://github.com/scribu), friendly guys from Europe. For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). +* [Andreas Creten](https://github.com/andreascreten) - founder +* [Cristi Burcă](https://github.com/scribu) - previous maintainer +* [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer + +For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). From 32118f3a3f3e649247432f6f8fbdd2043a27a690 Mon Sep 17 00:00:00 2001 From: Ryan Duff <ryan@fusionized.com> Date: Thu, 17 Apr 2014 13:12:53 -0400 Subject: [PATCH 2863/4858] Wrap with quotes for ZSH support --- utils/wp-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index 682d53d9ad..bc109024a9 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -4,7 +4,7 @@ _wp_complete() { local cur=${COMP_WORDS[COMP_CWORD]} IFS=$'\n'; # want to preserve spaces at the end - local opts=( $(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT") ) + local opts="$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT")" if [[ $opts = "<file>" ]] then From c40f2386e137669b50d6f27b2303e8a43cca8d00 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 21 Apr 2014 16:47:46 +0100 Subject: [PATCH 2864/4858] Introduce `\WP_CLI\Utils\interval()` and `\WP_CLI\Utils\time_since()` functions for working with human-readable time intervals --- php/utils.php | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/php/utils.php b/php/utils.php index b918d1824e..d17b3f387b 100644 --- a/php/utils.php +++ b/php/utils.php @@ -402,3 +402,72 @@ function replace_path_consts( $source, $path ) { return str_replace( $old, $new, $source ); } +/** + * Convert a time interval into human-readable format. + * + * Similar to WordPress' built-in `human_time_diff()` but returns two time period chunks instead of just one. + * + * @param int $since An interval of time in seconds + * @return string The interval in human readable format + */ +function interval( $since ) { + if ( $since <= 0 ) { + return 'now'; + } + + $since = absint( $since ); + + // array of time period chunks + $chunks = array( + array( 60 * 60 * 24 * 365 , \_n_noop( '%s year', '%s years' ) ), + array( 60 * 60 * 24 * 30 , \_n_noop( '%s month', '%s months' ) ), + array( 60 * 60 * 24 * 7, \_n_noop( '%s week', '%s weeks' ) ), + array( 60 * 60 * 24 , \_n_noop( '%s day', '%s days' ) ), + array( 60 * 60 , \_n_noop( '%s hour', '%s hours' ) ), + array( 60 , \_n_noop( '%s minute', '%s minutes' ) ), + array( 1 , \_n_noop( '%s second', '%s seconds' ) ), + ); + + // we only want to output two chunks of time here, eg: + // x years, xx months + // x days, xx hours + // so there's only two bits of calculation below: + + // step one: the first chunk + for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) { + $seconds = $chunks[$i][0]; + $name = $chunks[$i][1]; + + // finding the biggest chunk (if the chunk fits, break) + if ( ( $count = floor( $since / $seconds ) ) != 0 ){ + break; + } + } + + // set output var + $output = sprintf( \_n( $name[0], $name[1], $count ), $count ); + + // step two: the second chunk + if ( $i + 1 < $j ) { + $seconds2 = $chunks[$i + 1][0]; + $name2 = $chunks[$i + 1][1]; + + if ( ( $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ) ) != 0 ) { + // add to output var + $output .= ' ' . sprintf( \_n( $name2[0], $name2[1], $count2 ), $count2 ); + } + } + + return $output; +} + +/** + * Returns a human-readable time difference between two times. + * + * @param int $older_date A Unix timestamp + * @param int $newer_date A Unix timestamp + * @return string The time difference in a human-readable format + */ +function time_since( $older_date, $newer_date ) { + return interval( $newer_date - $older_date ); +} From 7fb389b94cc8babfb467f1a20aea64dcabaab1b6 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 21 Apr 2014 16:49:36 +0100 Subject: [PATCH 2865/4858] First pass at initial `wp cron` commands. Available commands: * `wp cron event list` * `wp cron event run <hook>` * `wp cron event delete <hook>` * `wp cron schedule list` * `wp cron test` --- php/commands/cron.php | 336 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 php/commands/cron.php diff --git a/php/commands/cron.php b/php/commands/cron.php new file mode 100644 index 0000000000..987f25ba5a --- /dev/null +++ b/php/commands/cron.php @@ -0,0 +1,336 @@ +<?php + +/** + * Manage WP-Cron events. + * + * @package wp-cli + */ +class Cron_Event_Command extends WP_CLI_Command { + + /** + * List scheduled cron events. + * + * @subcommand list + * @synopsis [--format=<format>] + */ + public function _list( $args, $assoc_args ) { + + $values = array_merge( array( + 'format' => 'table', + ), $assoc_args ); + $events = self::get_cron_events(); + + if ( is_wp_error( $events ) ) { + WP_CLI::line( WP_CLI::error_to_string( $events ) ); + exit; + } + + $fields = array( + 'hook', + 'next_run', + 'next_run_gmt', + 'next_run_relative', + 'recurrence', + ); + + \WP_CLI\Utils\format_items( $values['format'], $events, $fields ); + + } + + /** + * Run the next scheduled cron event for the given hook. + * + * ## OPTIONS + * + * <hook> + * : The hook name + * + * @synopsis <hook> + */ + public function run( $args, $assoc_args ) { + + $hook = $args[0]; + $result = false; + $events = self::get_cron_events(); + + if ( is_wp_error( $events ) ) { + WP_CLI::error( $events ); + } + + foreach ( $events as $id => $event ) { + if ( $event->hook == $hook ) { + $result = self::run_event( $event ); + break; + } + } + + if ( $result ) { + WP_CLI::success( sprintf( "Successfully executed the cron event '%s'", $hook ) ); + } else { + WP_CLI::error( sprintf( "Failed to the execute the cron event '%s'", $hook ) ); + } + + } + + /** + * Executes an event immediately by scheduling a new single event with the same arguments. + * + * @param stdClass $event The event + * @return bool Whether the event was successfully executed or not. + */ + protected static function run_event( stdClass $event ) { + + delete_transient( 'doing_cron' ); + $scheduled = wp_schedule_single_event( time()-1, $event->hook, $event->args ); + + if ( false === $scheduled ) { + return false; + } + + spawn_cron(); + + return true; + + } + + /** + * Delete the next scheduled cron event for the given hook. + * + * ## OPTIONS + * + * <hook> + * : The hook name + * + * @synopsis <hook> + */ + public function delete( $args, $assoc_args ) { + + $hook = $args[0]; + $result = false; + $events = self::get_cron_events(); + + if ( is_wp_error( $events ) ) { + WP_CLI::error( $events ); + } + + foreach ( $events as $id => $event ) { + if ( $event->hook == $hook ) { + $result = self::delete_event( $event ); + break; + } + } + + if ( $result ) { + WP_CLI::success( sprintf( "Successfully deleted the cron event '%s'", $hook ) ); + } else { + WP_CLI::error( sprintf( "Failed to the delete the cron event '%s'", $hook ) ); + } + + } + + /** + * Deletes a cron event. + * + * @param stdClass $event The event + * @return bool Whether the event was successfully deleted or not. + */ + protected static function delete_event( stdClass $event ) { + $crons = _get_cron_array(); + + if ( ! isset( $crons[$event->time][$event->hook][$event->sig] ) ) { + return false; + } + + wp_unschedule_event( $event->time, $event->hook, $event->args ); + return true; + } + + /** + * Callback function to format a cron event. + * + * @param stdClass $event The event. + * @return stdClass The formatted event object. + */ + protected static function format_event( stdClass $event ) { + $time_format = 'Y-m-d H:i:s'; + + $event->next_run = get_date_from_gmt( date( 'Y-m-d H:i:s', $event->time ), $time_format ); + $event->next_run_gmt = date( $time_format, $event->time ); + $event->next_run_relative = \WP_CLI\Utils\time_since( time(), $event->time ); + $event->recurrence = ( $event->schedule ) ? \WP_CLI\Utils\interval( $event->interval ) : 'Non-repeating'; + + return $event; + } + + /** + * Fetch an array of scheduled cron events. + * + * @return array|WP_Error An array of event objects, or a WP_Error object if there are no events scheduled. + */ + protected static function get_cron_events() { + + $crons = _get_cron_array(); + $events = array(); + + if ( empty( $crons ) ) { + return new WP_Error( + 'no_events', + 'You currently have no scheduled cron events.' + ); + } + + // @TODO rename these vars a bit more better nicely nicer: + foreach ( $crons as $time => $cron ) { + foreach ( $cron as $hook => $dings ) { + foreach ( $dings as $sig => $data ) { + + $events["$hook-$sig"] = (object) array( + 'hook' => $hook, + 'time' => $time, + 'sig' => $sig, + 'args' => $data['args'], + 'schedule' => $data['schedule'], + 'interval' => isset( $data['interval'] ) ? $data['interval'] : null, + ); + + } + } + } + + $events = array_map( 'Cron_Event_Command::format_event', $events ); + + return $events; + + } + +} + +/** + * Manage WP-Cron schedules. + */ +class Cron_Schedule_Command extends WP_CLI_Command { + + /** + * List available cron schedules. + * + * @subcommand list + * @synopsis [--format=<format>] + */ + public function _list( $args, $assoc_args ) { + + $values = array_merge( array( + 'format' => 'table', + ), $assoc_args ); + + $schedules = self::get_schedules(); + + $fields = array( + 'name', + 'display', + 'interval', + ); + + \WP_CLI\Utils\format_items( $values['format'], $schedules, $fields ); + + } + + /** + * Callback function to format a cron schedule. + * + * @param array $schedule The schedule. + * @param string $name The schedule name. + * @return array The formatted schedule. + */ + protected static function format_schedule( array $schedule, $name ) { + $schedule['name'] = $name; + return $schedule; + } + + /** + * Return a list of the cron schedules sorted according to interval. + * + * @return array The array of cron schedules. Each schedule is itself an array. + */ + protected static function get_schedules() { + $schedules = wp_get_schedules(); + if ( !empty( $schedules ) ) { + uasort( $schedules, 'Cron_Schedule_Command::sort' ); + $schedules = array_map( 'Cron_Schedule_Command::format_schedule', $schedules, array_keys( $schedules ) ); + } + return $schedules; + } + + /** + * Callback function to sort the cron schedule array by interval. + * + */ + protected static function sort( array $a, array $b ) { + return $a['interval'] - $b['interval']; + } + +} + +/** + * Manage WP-Cron events and schedules. + */ +class Cron_Command extends WP_CLI_Command { + + /** + * Test the WP Cron spawning system and report back any errors. + */ + public function test() { + + $status = self::test_cron_spawn(); + + if ( is_wp_error( $status ) ) { + WP_CLI::error( $status ); + } else { + WP_CLI::success( 'WP-Cron is working as expected.' ); + } + + } + + /** + * Gets the status of WP-Cron functionality on the site by performing a test spawn. + * + * This function is designed to mimic the functionality in `spawn_cron()` with the addition of checking + * the return value of the call to `wp_remote_post()`. + * + * @return bool|WP_Error Boolean true if the cron spawn test is successful, WP_Error object if not. + */ + protected static function test_cron_spawn() { + + if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { + return true; + } + + $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); + + $cron_request = apply_filters( 'cron_request', array( + 'url' => site_url( 'wp-cron.php?doing_wp_cron=' . $doing_wp_cron ), + 'key' => $doing_wp_cron, + 'args' => array( + 'timeout' => 3, + 'blocking' => true, + 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) + ) + ) ); + + # Enforce a blocking request in case something that's hooked onto the 'cron_request' filter sets it to false + $cron_request['args']['blocking'] = true; + + $result = wp_remote_post( $cron_request['url'], $cron_request['args'] ); + + if ( is_wp_error( $result ) ) { + return $result; + } else { + return true; + } + + } + +} + +WP_CLI::add_command( 'cron', 'Cron_Command' ); +WP_CLI::add_command( 'cron event', 'Cron_Event_Command' ); +WP_CLI::add_command( 'cron schedule', 'Cron_Schedule_Command' ); From e5089a44df3f8f8610a8f615c5d0558a9fbf5b7c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 21 Apr 2014 16:48:29 -0700 Subject: [PATCH 2866/4858] Throw an error if plugin(s) / theme(s) aren't specified for update `wp plugin update` and `wp theme update` both require either passed plugin(s) / theme(s), or an `--all` argument. Our synopsis parser isn't smart enough to require one argument or another, so this will be the catch-all instead. --- features/plugin.feature | 9 +++++++++ features/theme.feature | 9 +++++++++ php/WP_CLI/CommandWithUpgrade.php | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index dcad447784..a683999dd8 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -108,6 +108,15 @@ Feature: Manage WordPress plugins | name | status | update | version | | akismet | active | available | 2.5.6 | + When I try `wp plugin update` + Then STDERR should be: + """ + Error: Please specify one or more plugins, or use --all. + """ + + When I run `wp plugin update --all` + Then STDOUT should not be empty + Scenario: Activate a network-only plugin Given a WP multisite install And a wp-content/plugins/network-only.php file: diff --git a/features/theme.feature b/features/theme.feature index 98153957f7..76ef76a820 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -72,6 +72,15 @@ Feature: Manage WordPress themes | name | status | update | version | | p2 | active | available | 1.4.1 | + When I try `wp theme update` + Then STDERR should be: + """ + Error: Please specify one or more themes, or use --all. + """ + + When I run `wp theme update --all` + Then STDOUT should not be empty + Scenario: Get the path of an installed theme Given a WP install diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 5aa067c2ca..1bbe9ae56f 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -199,6 +199,10 @@ protected function get_upgrader( $assoc_args ) { protected function update_many( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); + if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) { + \WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." ); + } + $items = $this->get_item_list(); if ( !isset( $assoc_args['all'] ) ) { From a4d947a9da4c7fb2de05680d17c08b40746ae1ce Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 21 Apr 2014 19:21:35 -0700 Subject: [PATCH 2867/4858] If the sidebar doesn't exist yet, `array_slice()` will fail on a null value --- php/commands/widget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index 00ca77231b..b3ff2c8796 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -437,7 +437,7 @@ private function move_sidebar_widget( $widget_id, $current_sidebar_id, $new_side } if ( $needs_placement ) { - $widgets = $all_widgets[ $new_sidebar_id ]; + $widgets = ! empty( $all_widgets[ $new_sidebar_id ] ) ? $all_widgets[ $new_sidebar_id ] : array(); $before = array_slice( $widgets, 0, $new_index, true ); $after = array_slice( $widgets, $new_index, count( $widgets ), true ); $widgets = array_merge( $before, array( $widget_id ), $after ); From 46f9b87b865825806d4d1f4c611773ad3199b443 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 23 Apr 2014 14:47:42 -0700 Subject: [PATCH 2868/4858] Suppress errors when using a Widget's `update()` callback Each widget can expect arbitrary array keys, and it's not possible to know what those array keys might be without processing `form()`. This is much easier for our purposes. --- php/commands/widget.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index b3ff2c8796..5a5ec7a056 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -480,7 +480,9 @@ private function sanitize_widget_options( $id_base, $dirty_options, $old_options return array(); } - return $widget->update( $dirty_options, $old_options ); + // No easy way to determine expected array keys for $dirty_options + // because Widget API dependent on the form fields + return @$widget->update( $dirty_options, $old_options ); } From 32b70759aa3e97417fb3b0aec423876ee9aefcb0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 23 Apr 2014 17:46:33 -0700 Subject: [PATCH 2869/4858] Make regenerating rewrite rules more user-friendly * Throw a warning if the user is trying to regenerate `.htaccess` without the special declaration. * Add directions on how to resolve the problem in the usage docs for each relevant command. --- php/commands/rewrite.php | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 3f33c1c92b..8b380afbd6 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -10,6 +10,16 @@ class Rewrite_Command extends WP_CLI_Command { /** * Flush rewrite rules. * + * ## DESCRIPTION + * + * Resets WordPress' rewrite rules based on registered post types, etc. + * + * To regenerate a .htaccess file with WP-CLI, you'll need to add the mod_rewrite module + * to your wp-cli.yml or config.yml. For example: + * + * apache_modules: + * - mod_rewrite + * * ## OPTIONS * * [--hard] @@ -18,12 +28,25 @@ class Rewrite_Command extends WP_CLI_Command { public function flush( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config self::apache_modules(); + if ( isset( $assoc_args['hard'] ) && ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { + WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); + } flush_rewrite_rules( isset( $assoc_args['hard'] ) ); } /** * Update the permalink structure. * + * ## DESCRIPTION + * + * Updates the post permalink structure. + * + * To regenerate a .htaccess file with WP-CLI, you'll need to add the mod_rewrite module + * to your wp-cli.yml or config.yml. For example: + * + * apache_modules: + * - mod_rewrite + * * ## OPTIONS * * <permastruct> @@ -89,8 +112,13 @@ public function structure( $args, $assoc_args ) { // Launch a new process to flush rewrites because core expects flush // to happen after rewrites are set $new_assoc_args = array(); - if ( isset( $assoc_args['hard'] ) ) + if ( isset( $assoc_args['hard'] ) ) { $new_assoc_args['hard'] = true; + if ( ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { + WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); + } + } + \WP_CLI::launch_self( 'rewrite flush', array(), $new_assoc_args ); WP_CLI::success( "Rewrite structure set." ); From 9fae0ab780349b7471e2423c30ff2a564755ece0 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 16:58:50 +0100 Subject: [PATCH 2870/4858] Docblock updates --- php/commands/cron.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 987f25ba5a..cdf15eab53 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -3,15 +3,18 @@ /** * Manage WP-Cron events. * - * @package wp-cli */ class Cron_Event_Command extends WP_CLI_Command { /** * List scheduled cron events. * + * ## OPTIONS + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to all of the cron event fields. + * * @subcommand list - * @synopsis [--format=<format>] */ public function _list( $args, $assoc_args ) { @@ -213,8 +216,12 @@ class Cron_Schedule_Command extends WP_CLI_Command { /** * List available cron schedules. * + * ## OPTIONS + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to all of the cron schedule fields. + * * @subcommand list - * @synopsis [--format=<format>] */ public function _list( $args, $assoc_args ) { From d523a82f83fd5a318655b2899cfb840a5d5f18bb Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 17:02:09 +0100 Subject: [PATCH 2871/4858] Switch from `\WP_CLI\Utils\format_items()` to the newer `\WP_CLI\Formatter->display_items()` method. --- php/commands/cron.php | 58 ++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index cdf15eab53..6e24a5b6e4 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -6,6 +6,15 @@ */ class Cron_Event_Command extends WP_CLI_Command { + private $fields = array( + 'hook', + 'next_run', + 'next_run_gmt', + 'next_run_relative', + 'next_run_diff', + 'recurrence', + ); + /** * List scheduled cron events. * @@ -17,10 +26,8 @@ class Cron_Event_Command extends WP_CLI_Command { * @subcommand list */ public function _list( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); - $values = array_merge( array( - 'format' => 'table', - ), $assoc_args ); $events = self::get_cron_events(); if ( is_wp_error( $events ) ) { @@ -28,15 +35,11 @@ public function _list( $args, $assoc_args ) { exit; } - $fields = array( - 'hook', - 'next_run', - 'next_run_gmt', - 'next_run_relative', - 'recurrence', - ); - - \WP_CLI\Utils\format_items( $values['format'], $events, $fields ); + if ( 'ids' == $formatter->format ) { + echo implode( ' ', wp_list_pluck( $events, 'hook' ) ); + } else { + $formatter->display_items( $events ); + } } @@ -206,6 +209,10 @@ protected static function get_cron_events() { } + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'event' ); + } + } /** @@ -213,6 +220,12 @@ protected static function get_cron_events() { */ class Cron_Schedule_Command extends WP_CLI_Command { + private $fields = array( + 'name', + 'display', + 'interval', + ); + /** * List available cron schedules. * @@ -224,20 +237,15 @@ class Cron_Schedule_Command extends WP_CLI_Command { * @subcommand list */ public function _list( $args, $assoc_args ) { - - $values = array_merge( array( - 'format' => 'table', - ), $assoc_args ); + $formatter = $this->get_formatter( $assoc_args ); $schedules = self::get_schedules(); - $fields = array( - 'name', - 'display', - 'interval', - ); - - \WP_CLI\Utils\format_items( $values['format'], $schedules, $fields ); + if ( 'ids' == $formatter->format ) { + echo implode( ' ', wp_list_pluck( $schedules, 'name' ) ); + } else { + $formatter->display_items( $schedules ); + } } @@ -275,6 +283,10 @@ protected static function sort( array $a, array $b ) { return $a['interval'] - $b['interval']; } + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'schedule' ); + } + } /** From 6073535a202adf90c91c4404c9f65039a7fb5742 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 17:02:56 +0100 Subject: [PATCH 2872/4858] Output an empty table instead of a message when there are no cron events on the site --- php/commands/cron.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 6e24a5b6e4..747a581588 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -31,8 +31,7 @@ public function _list( $args, $assoc_args ) { $events = self::get_cron_events(); if ( is_wp_error( $events ) ) { - WP_CLI::line( WP_CLI::error_to_string( $events ) ); - exit; + $events = array(); } if ( 'ids' == $formatter->format ) { From 5d84bffd6b46ddd19d1084266599f10f2d4904fd Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 17:03:42 +0100 Subject: [PATCH 2873/4858] Remove some test code --- php/commands/cron.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 747a581588..67693d65cf 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -11,7 +11,6 @@ class Cron_Event_Command extends WP_CLI_Command { 'next_run', 'next_run_gmt', 'next_run_relative', - 'next_run_diff', 'recurrence', ); From b2d474909cc2ad5d3f0a75dd2d80a33a32eade2a Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 17:03:57 +0100 Subject: [PATCH 2874/4858] Correct indentation --- php/utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index d17b3f387b..393c06ee24 100644 --- a/php/utils.php +++ b/php/utils.php @@ -412,7 +412,7 @@ function replace_path_consts( $source, $path ) { */ function interval( $since ) { if ( $since <= 0 ) { - return 'now'; + return 'now'; } $since = absint( $since ); @@ -469,5 +469,5 @@ function interval( $since ) { * @return string The time difference in a human-readable format */ function time_since( $older_date, $newer_date ) { - return interval( $newer_date - $older_date ); + return interval( $newer_date - $older_date ); } From d01050b0bce02d8d24571cbbabe85470ae293610 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 24 Apr 2014 10:08:18 -0700 Subject: [PATCH 2875/4858] When scaffolding a theme or plugin, create the `themes` or `plugins` directory if it doesn't exist For developers who use the scaffolding commands on brand new projects, this can save a moment of d'oh. --- php/commands/scaffold.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 26ee0064ac..fff531796c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -212,6 +212,8 @@ function _s( $args, $assoc_args ) { WP_CLI::error( "Couldn't create theme (received $response_code response)." ); } + $this->maybe_create_themes_dir(); + unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); @@ -265,6 +267,8 @@ function child_theme( $args, $assoc_args ) { $theme_dir = WP_CONTENT_DIR . "/themes" . "/$theme_slug"; $theme_style_path = "$theme_dir/style.css"; + $this->maybe_create_themes_dir(); + $this->create_file( $theme_style_path, Utils\mustache_render( 'child_theme.mustache', $data ) ); WP_CLI::success( "Created $theme_dir" ); @@ -324,6 +328,8 @@ function plugin( $args, $assoc_args ) { $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; $plugin_path = "$plugin_dir/$plugin_slug.php"; + $this->maybe_create_plugins_dir(); + $this->create_file( $plugin_path, Utils\mustache_render( 'plugin.mustache', $data ) ); WP_CLI::success( "Created $plugin_dir" ); @@ -491,6 +497,30 @@ protected function extract_args( $assoc_args, $defaults ) { protected function quote_comma_list_elements( $comma_list ) { return "'" . implode( "', '", explode( ',', $comma_list ) ) . "'"; } + + /** + * Create the themes directory if it doesn't already exist + */ + protected function maybe_create_themes_dir() { + + $themes_dir = WP_CONTENT_DIR . '/themes'; + if ( ! is_dir( $themes_dir ) ) { + wp_mkdir_p( $themes_dir ); + } + + } + + /** + * Create the plugins directory if it doesn't already exist + */ + protected function maybe_create_plugins_dir() { + + if ( ! is_dir( WP_PLUGIN_DIR ) ) { + wp_mkdir_p( WP_PLUGIN_DIR ); + } + + } + } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); From 36c55889cb984983386e0365f45583d61d7a97fd Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 21:16:52 +0100 Subject: [PATCH 2876/4858] Important bugfix --- features/scaffold.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 69431b33ba..0d1d011cf4 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,4 +1,4 @@ -Feature: Wordpress code scaffolding +Feature: WordPress code scaffolding Background: Given a WP install From 60327a7e70fe3a4e90094d339851e49fc88ed9d2 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 21:46:11 +0100 Subject: [PATCH 2877/4858] Rename `_list()` methods to `list_()` --- php/commands/cron.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 67693d65cf..c2104db0b7 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -24,7 +24,7 @@ class Cron_Event_Command extends WP_CLI_Command { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); $events = self::get_cron_events(); @@ -234,7 +234,7 @@ class Cron_Schedule_Command extends WP_CLI_Command { * * @subcommand list */ - public function _list( $args, $assoc_args ) { + public function list_( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); $schedules = self::get_schedules(); From c26ad22ff5dbfeba5189419f440b35db5c8ff1c9 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 23:29:00 +0100 Subject: [PATCH 2878/4858] Make `$time_format` a property on the `Cron_Event_Command` class --- php/commands/cron.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index c2104db0b7..fba436472d 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -13,6 +13,7 @@ class Cron_Event_Command extends WP_CLI_Command { 'next_run_relative', 'recurrence', ); + private static $time_format = 'Y-m-d H:i:s'; /** * List scheduled cron events. @@ -156,10 +157,9 @@ protected static function delete_event( stdClass $event ) { * @return stdClass The formatted event object. */ protected static function format_event( stdClass $event ) { - $time_format = 'Y-m-d H:i:s'; - $event->next_run = get_date_from_gmt( date( 'Y-m-d H:i:s', $event->time ), $time_format ); - $event->next_run_gmt = date( $time_format, $event->time ); + $event->next_run = get_date_from_gmt( date( 'Y-m-d H:i:s', $event->time ), self::$time_format ); + $event->next_run_gmt = date( self::$time_format, $event->time ); $event->next_run_relative = \WP_CLI\Utils\time_since( time(), $event->time ); $event->recurrence = ( $event->schedule ) ? \WP_CLI\Utils\interval( $event->interval ) : 'Non-repeating'; From 75e033048a3e96a8b41ebc0ae70850c6f7c276b4 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 23:29:34 +0100 Subject: [PATCH 2879/4858] Introduce `wp cron event schedule` for scheduling new events --- php/commands/cron.php | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index fba436472d..206094e6ea 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -42,6 +42,76 @@ public function list_( $args, $assoc_args ) { } + /** + * Schedule a new cron event. + * + * ## OPTIONS + * + * <hook> + * : The hook name + * + * [--next_run=<value>] + * : A Unix timestamp or an English textual datetime description compatible with `strtotime()`. Defaults to now. + * + * [--recurrence=<value>] + * : How often the event should recur. See `wp cron schedule list` for available schedule names. Defaults to no recurrence. + * + * [--<field>=<value>] + * : Associative args for the event. + * + * ## EXAMPLES + * + * wp cron event schedule cron_test + * + * wp cron event schedule cron_test --next_run='+1 hour' --recurrence=hourly + * + * wp cron event schedule cron_test --recurrence=daily --foo=1 --bar=2 + */ + public function schedule( $args, $assoc_args ) { + + list( $hook ) = $args; + + if ( !isset( $assoc_args['next_run'] ) ) { + $timestamp = time(); + } else if ( is_numeric( $assoc_args['next_run'] ) ) { + $timestamp = absint( $assoc_args['next_run'] ); + } else { + $timestamp = strtotime( $assoc_args['next_run'] ); + } + + if ( ! $timestamp ) { + WP_CLI::error( sprintf( "'%s' is not a valid datetime.", $assoc_args['next_run'] ) ); + } + + $event_args = array_diff_key( $assoc_args, array_flip( array( + 'next_run', 'recurrence' + ) ) ); + + if ( isset( $assoc_args['recurrence'] ) ) { + + $recurrence = $assoc_args['recurrence']; + $schedules = wp_get_schedules(); + + if ( ! isset( $schedules[$recurrence] ) ) { + WP_CLI::error( sprintf( "'%s' is not a valid schedule name for recurrence.", $recurrence ) ); + } + + $event = wp_schedule_event( $timestamp, $recurrence, $hook, $event_args ); + + } else { + + $event = wp_schedule_single_event( $timestamp, $hook, $event_args ); + + } + + if ( false !== $event ) { + WP_CLI::success( sprintf( "Scheduled event with hook '%s' for %s.", $hook, date( self::$time_format, $timestamp ) ) ); + } else { + WP_CLI::error( 'Event not scheduled' ); + } + + } + /** * Run the next scheduled cron event for the given hook. * From 494ff810e83bdeff1e2aebf6905d926faf72fb59 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 24 Apr 2014 23:30:04 +0100 Subject: [PATCH 2880/4858] Remove `next_run` from the default list of event fields for now --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 206094e6ea..02e69c8584 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -8,7 +8,7 @@ class Cron_Event_Command extends WP_CLI_Command { private $fields = array( 'hook', - 'next_run', + // 'next_run', 'next_run_gmt', 'next_run_relative', 'recurrence', From c45cc9ea0c90be2582beba8aa30f9033138afd50 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 25 Apr 2014 00:48:20 +0100 Subject: [PATCH 2881/4858] Add the `--format` argument to our `list` commands --- php/commands/cron.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index 02e69c8584..4e342365d8 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -23,6 +23,9 @@ class Cron_Event_Command extends WP_CLI_Command { * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to all of the cron event fields. * + * [--format=<format>] + * : Accepted values: table, json, csv, ids. Default: table. + * * @subcommand list */ public function list_( $args, $assoc_args ) { @@ -302,6 +305,9 @@ class Cron_Schedule_Command extends WP_CLI_Command { * [--fields=<fields>] * : Limit the output to specific object fields. Defaults to all of the cron schedule fields. * + * [--format=<format>] + * : Accepted values: table, json, csv, ids. Default: table. + * * @subcommand list */ public function list_( $args, $assoc_args ) { From 080cd8cb534c2bba45e7f02952b60e097064e15c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 09:57:09 -0700 Subject: [PATCH 2882/4858] Fuller PHPdoc coverage for `WP_CLI\Dispatcher\Subcommand` --- php/WP_CLI/Dispatcher/Subcommand.php | 67 ++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index c3e0d3badc..673bc99f3f 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -4,6 +4,8 @@ /** * A leaf node in the command tree. + * + * @package WP_CLI */ class Subcommand extends CompositeCommand { @@ -24,24 +26,43 @@ function __construct( $parent, $name, $docparser, $when_invoked ) { } } + /** + * Extract the synopsis from PHPdoc string. + * + * @param string $longdesc Command docs via PHPdoc + * @return string + */ private static function extract_synopsis( $longdesc ) { preg_match_all( '/(.+?)[\r\n]+:/', $longdesc, $matches ); return implode( ' ', $matches[1] ); } + /** + * Subcommands can't have subcommands because they + * represent code to be executed. + * + * @return bool + */ function can_have_subcommands() { return false; } + /** + * Get the synopsis string for this subcommand. + * A synopsis defines what runtime arguments are + * expected, useful to humans and argument validation. + * + * @return string + */ function get_synopsis() { return $this->synopsis; } /** - * If an alias is set, grant access to it + * If an alias is set, grant access to it. * Aliases permit subcommands to be instantiated - * with a secondary identity - * + * with a secondary identity. + * * @return string */ function get_alias() { @@ -49,8 +70,8 @@ function get_alias() { } /** - * Print the usage details to the end user - * + * Print the usage details to the end user. + * * @param string $prefix */ function show_usage( $prefix = 'usage: ' ) { @@ -58,8 +79,8 @@ function show_usage( $prefix = 'usage: ' ) { } /** - * Get the usage of the subcommand as a formatted string - * + * Get the usage of the subcommand as a formatted string. + * * @param string $prefix * @return string */ @@ -71,6 +92,13 @@ function get_usage( $prefix ) { ); } + /** + * Wrapper for CLI Tools' prompt() method. + * + * @param string $question + * @param string $default + * @return string|false + */ private function prompt( $question, $default ) { try { @@ -83,6 +111,14 @@ private function prompt( $question, $default ) { return $response; } + /** + * Interactively prompt the user for input + * based on defined synopsis and passed arguments. + * + * @param array $args + * @param array $assoc_args + * @return array + */ private function prompt_args( $args, $assoc_args ) { $synopsis = $this->get_synopsis(); @@ -173,6 +209,13 @@ private function prompt_args( $args, $assoc_args ) { } /** + * Validate the supplied arguments to the command. + * Throws warnings or errors if arguments are missing + * or invalid. + * + * @param array $args + * @param array $assoc_args + * @param array $extra_args * @return array list of invalid $assoc_args keys to unset */ private function validate_args( $args, $assoc_args, $extra_args ) { @@ -223,7 +266,15 @@ private function validate_args( $args, $assoc_args, $extra_args ) { return $to_unset; } - function invoke( $args, $assoc_args, $extra_args ) { + /** + * 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 ); From 5647c4afd2ef8915b6cc9010e0aabdfb773f4aec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 09:58:59 -0700 Subject: [PATCH 2883/4858] Document `WP_CLI\Dispatcher\get_path()` --- php/dispatcher.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/dispatcher.php b/php/dispatcher.php index 8157d21b6b..bd11a3927e 100644 --- a/php/dispatcher.php +++ b/php/dispatcher.php @@ -2,6 +2,12 @@ namespace WP_CLI\Dispatcher; +/** + * Get the path to a command, e.g. "core download" + * + * @param WP_CLI\Dispatcher\Subcommand $command + * @return string + */ function get_path( $command ) { $path = array(); From 88bb66d0cf82b0216aed0d4c205f8e1cf9e54db9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 10:17:31 -0700 Subject: [PATCH 2884/4858] PHPdoc and explicit method definitions for `WP_CLI\Dispatcher\RootCommand` --- php/WP_CLI/Dispatcher/RootCommand.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index 853cfa1976..d5c19826b5 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -6,10 +6,12 @@ /** * The root node in the command tree. + * + * @package WP_CLI */ class RootCommand extends CompositeCommand { - function __construct() { + public function __construct() { $this->parent = false; $this->name = 'wp'; @@ -17,7 +19,12 @@ function __construct() { $this->shortdesc = 'Manage WordPress through the command-line.'; } - function get_longdesc() { + /** + * Get the human-readable long description. + * + * @return string + */ + public function get_longdesc() { $binding = array(); foreach ( \WP_CLI::get_configurator()->get_spec() as $key => $details ) { @@ -44,7 +51,14 @@ function get_longdesc() { return Utils\mustache_render( 'man-params.mustache', $binding ); } - function find_subcommand( &$args ) { + /** + * Find a subcommand registered on the root + * command. + * + * @param array $args + * @return \WP_CLI\Dispatcher\Subcommand|false + */ + public function find_subcommand( &$args ) { $command = array_shift( $args ); Utils\load_command( $command ); @@ -56,7 +70,12 @@ function find_subcommand( &$args ) { return $this->subcommands[ $command ]; } - function get_subcommands() { + /** + * Get all registered subcommands. + * + * @return array + */ + public function get_subcommands() { Utils\load_all_commands(); return parent::get_subcommands(); From eb9ddf0ec7b25cdc1fe7891c90f12248a41e11e1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 10:39:50 -0700 Subject: [PATCH 2885/4858] PHPdoc coverage for `\WP_CLI\Dispatcher\CompositeCommand` --- php/WP_CLI/Dispatcher/CompositeCommand.php | 120 ++++++++++++++++++--- 1 file changed, 107 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 6f77789694..30e6e00387 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -4,6 +4,9 @@ /** * A non-leaf node in the command tree. + * Contains one or more Subcommands. + * + * @package WP_CLI */ class CompositeCommand { @@ -11,6 +14,13 @@ class CompositeCommand { protected $parent, $subcommands = array(); + /** + * Instantiate a new CompositeCommand + * + * @param mixed $parent Parent command (either Root or Composite) + * @param string $name Represents how command should be invoked + * @param \WP_CLI\DocParser + */ public function __construct( $parent, $name, $docparser ) { $this->parent = $parent; @@ -25,41 +35,94 @@ public function __construct( $parent, $name, $docparser ) { } } - function get_parent() { + /** + * Get the parent composite (or root) command + * + * @return mixed + */ + public function get_parent() { return $this->parent; } - function add_subcommand( $name, $command ) { + /** + * Add a named subcommand to this composite command's + * set of contained subcommands. + * + * @param string $name Represents how subcommand should be invoked + * @param \WP_CLI\Dispatcher\Subcommand + */ + public function add_subcommand( $name, $command ) { $this->subcommands[ $name ] = $command; } - function can_have_subcommands() { + /** + * Composite commands always contain subcommands. + * + * @return true + */ + public function can_have_subcommands() { return true; } - function get_subcommands() { + /** + * Get the subcommands contained by this composite + * command. + * + * @return array + */ + public function get_subcommands() { ksort( $this->subcommands ); return $this->subcommands; } - function get_name() { + /** + * Get the name of this composite command. + * + * @return string + */ + public function get_name() { return $this->name; } - function get_shortdesc() { + /** + * Get the short description for this composite + * command. + * + * @return string + */ + public function get_shortdesc() { return $this->shortdesc; } - function get_longdesc() { + /** + * Get the long description for this composite + * command. + * + * @return string + */ + public function get_longdesc() { return $this->longdesc; } - function get_synopsis() { + /** + * Get the synopsis for this composite command. + * As a collection of subcommands, the composite + * command is only intended to invoke those + * subcommands. + * + * @return string + */ + public function get_synopsis() { return '<command>'; } - function get_usage( $prefix ) { + /** + * Get the usage for this composite command. + * + * @return string + */ + public function get_usage( $prefix ) { return sprintf( "%s%s %s", $prefix, implode( ' ', get_path( $this ) ), @@ -67,7 +130,11 @@ function get_usage( $prefix ) { ); } - function show_usage() { + /** + * Show the usage for all subcommands contained + * by the composite command. + */ + public function show_usage() { $methods = $this->get_subcommands(); $i = 0; @@ -84,11 +151,26 @@ function show_usage() { \WP_CLI::line( "See 'wp help $cmd_name <command>' for more information on a specific command." ); } - function invoke( $args, $assoc_args, $extra_args ) { + /** + * When a composite command is invoked, it shows usage + * docs for its subcommands. + * + * @param array $args + * @param array $assoc_args + * @param array $extra_args + */ + public function invoke( $args, $assoc_args, $extra_args ) { $this->show_usage(); } - function find_subcommand( &$args ) { + /** + * Given supplied arguments, find a contained + * subcommand + * + * @param array $args + * @return \WP_CLI\Dispatcher\Subcommand|false + */ + public function find_subcommand( &$args ) { $name = array_shift( $args ); $subcommands = $this->get_subcommands(); @@ -107,6 +189,13 @@ function find_subcommand( &$args ) { return $subcommands[ $name ]; } + /** + * Get any registered aliases for this composite command's + * subcommands. + * + * @param array $subcommands + * @return array + */ private static function get_aliases( $subcommands ) { $aliases = array(); @@ -119,7 +208,12 @@ private static function get_aliases( $subcommands ) { return $aliases; } - function get_alias() { + /** + * Composite commands can only be known by one name. + * + * @return false + */ + public function get_alias() { return false; } } From 7f75f8d6e8d1a32548711396b36e53c54816c926 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 10:49:10 -0700 Subject: [PATCH 2886/4858] PHPdoc for `\WP_CLI\Dispatcher\CommandFactory` --- php/WP_CLI/Dispatcher/CommandFactory.php | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index 4e7a0aae14..2bc884e013 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -4,9 +4,18 @@ /** * Creates CompositeCommand or Subcommand instances. + * + * @package WP_CLI */ class CommandFactory { + /** + * Create a new CompositeCommand (or Subcommand if class has __invoke()) + * + * @param string $name Represents how the command should be invoked + * @param string $class A subclass of WP_CLI_Command + * @param mixed $parent The new command's parent Composite (or Root) command + */ public static function create( $name, $class, $parent ) { $reflection = new \ReflectionClass( $class ); @@ -20,6 +29,14 @@ public static function create( $name, $class, $parent ) { return $command; } + /** + * Create a new Subcommand instance. + * + * @param mixed $parent The new command's parent Composite command + * @param string $name Represents how the command should be invoked + * @param string $class A subclass of WP_CLI_Command + * @param string $method Class method to be called upon invocation. + */ private static function create_subcommand( $parent, $name, $class_name, $method ) { $docparser = new \WP_CLI\DocParser( $method->getDocComment() ); @@ -38,6 +55,13 @@ private static function create_subcommand( $parent, $name, $class_name, $method return new Subcommand( $parent, $name, $docparser, $when_invoked ); } + /** + * Create a new Composite command instance. + * + * @param mixed $parent The new command's parent Root or Composite command + * @param string $name Represents how the command should be invoked + * @param ReflectionClass $reflection + */ private static function create_composite_command( $parent, $name, $reflection ) { $docparser = new \WP_CLI\DocParser( $reflection->getDocComment() ); @@ -57,6 +81,12 @@ private static function create_composite_command( $parent, $name, $reflection ) return $container; } + /** + * Check whether a method is actually callable. + * + * @param ReflectionMethod $method + * @return bool + */ private static function is_good_method( $method ) { return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); } From beb7b4cef8b61f35bb9b98c417ada045b63a3230 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 10:58:50 -0700 Subject: [PATCH 2887/4858] More PHPdoc for `\WP_CLI\Runner` --- php/WP_CLI/Runner.php | 81 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 10db74c196..49ff4c012e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -6,6 +6,11 @@ use WP_CLI\Utils; use WP_CLI\Dispatcher; +/** + * Performs the execution of a command. + * + * @package WP_CLI + */ class Runner { private $global_config_path, $project_config_path; @@ -23,10 +28,21 @@ public function __get( $key ) { return $this->$key; } + /** + * Register a command for early invocation, generally before WordPress loads. + * + * @param string $when Named execution hook + * @param WP_CLI\Dispatcher\Subcommand $command + */ public function register_early_invoke( $when, $command ) { $this->_early_invoke[ $when ][] = array_slice( Dispatcher\get_path( $command ), 1 ); } + /** + * Perform the early invocation of a command. + * + * @param string $when Named execution hook + */ private function do_early_invoke( $when ) { if ( !isset( $this->_early_invoke[ $when ] ) ) return; @@ -39,6 +55,11 @@ private function do_early_invoke( $when ) { } } + /** + * Get the path to the global configuration YAML file. + * + * @return string|false + */ private static function get_global_config_path() { $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); if ( isset( $runtime_config['config'] ) ) { @@ -55,6 +76,13 @@ private static function get_global_config_path() { return $config_path; } + /** + * Get the path to the project-specific configuration + * YAML file. + * wp-cli.local.yml takes priority over wp-cli.yml. + * + * @return string|false + */ private static function get_project_config_path() { $config_files = array( 'wp-cli.local.yml', @@ -75,6 +103,9 @@ private static function get_project_config_path() { /** * Attempts to find the path to the WP install inside index.php + * + * @param string $index_path + * @return string|false */ private static function extract_subdir_path( $index_path ) { $index_code = file_get_contents( $index_path ); @@ -95,7 +126,8 @@ private static function extract_subdir_path( $index_path ) { } /** - * Find the directory that contains the WordPress files. Defaults to the current working dir. + * Find the directory that contains the WordPress files. + * Defaults to the current working dir. * * @return string An absolute path */ @@ -132,12 +164,22 @@ private function find_wp_root() { } } + /** + * Set WordPress root as a given path. + * + * @param string $path + */ private static function set_wp_root( $path ) { define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); } + /** + * Set a specific user context for WordPress. + * + * @param array $assoc_args + */ private static function set_user( $assoc_args ) { if ( isset( $assoc_args['user'] ) ) { $fetcher = new \WP_CLI\Fetchers\User; @@ -148,6 +190,12 @@ private static function set_user( $assoc_args ) { } } + /** + * Guess which URL context WP-CLI has been invoked under. + * + * @param array $assoc_args + * @return string|false + */ private static function guess_url( $assoc_args ) { if ( isset( $assoc_args['blog'] ) ) { $assoc_args['url'] = $assoc_args['blog']; @@ -192,6 +240,12 @@ private function cmd_starts_with( $prefix ) { return $prefix == array_slice( $this->arguments, 0, count( $prefix ) ); } + /** + * Given positional arguments, find the command to execute. + * + * @param array $args + * @return array|string Command, args, and path on success; error message on failure + */ public function find_command_to_run( $args ) { $command = \WP_CLI::get_root_command(); @@ -225,6 +279,13 @@ public function find_command_to_run( $args ) { return array( $command, $args, $cmd_path ); } + /** + * Find the WP-CLI command to run given arguments, + * and invoke it. + * + * @param array $args Positional arguments including command name + * @param array $assoc_args + */ public function run_command( $args, $assoc_args = array() ) { $r = $this->find_command_to_run( $args ); if ( is_string( $r ) ) { @@ -284,7 +345,13 @@ public function get_wp_config_code() { return preg_replace( '|^\s*\<\?php\s*|', '', $source ); } - // Transparently convert old syntaxes + /** + * Transparently convert deprecated syntaxes + * + * @param array $args + * @param array $assoc_args + * @return array + */ private static function back_compat_conversions( $args, $assoc_args ) { $top_level_aliases = array( 'sql' => 'db', @@ -367,6 +434,11 @@ private static function back_compat_conversions( $args, $assoc_args ) { return array( $args, $assoc_args ); } + /** + * Whether or not the output should be rendered in color + * + * @return bool + */ public function in_color() { return $this->colorize; } @@ -388,6 +460,11 @@ private function init_logger() { WP_CLI::set_logger( $logger ); } + /** + * Do WordPress core files exist? + * + * @return bool + */ private function wp_exists() { return is_readable( ABSPATH . 'wp-includes/version.php' ); } From c775c2c299f13054c434f186160bb75fad4a4a46 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 10:59:10 -0700 Subject: [PATCH 2888/4858] `WP_CLI` and `WP_CLI\Configurator` also got some PHPdoc coverage --- php/WP_CLI/Configurator.php | 18 ++++++++++++++++++ php/class-wp-cli.php | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 8a9ce8ac72..92bffd9d52 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -2,6 +2,11 @@ namespace WP_CLI; +/** + * Handles file- and runtime-based configuration values. + * + * @package WP_CLI + */ class Configurator { private $spec; @@ -27,6 +32,11 @@ function __construct( $path ) { } } + /** + * Get declared configuration values as an array. + * + * @return array + */ function to_array() { return array( $this->config, $this->extra_config ); } @@ -132,6 +142,9 @@ function merge_array( $config ) { /** * Load values from a YAML file. + * + * @param string $yml_file Path to the YAML file + * @return array $config Declared configuration values */ private static function load_yml( $yml_file ) { if ( !$yml_file ) @@ -155,6 +168,11 @@ private static function load_yml( $yml_file ) { return $config; } + /** + * Conform a variable to an array. + * + * @param mixed $val A string or an array + */ private static function arrayify( &$val ) { if ( !is_array( $val ) ) { $val = array( $val ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ca650fc2c0..e6dbe54f68 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -25,6 +25,11 @@ static function set_logger( $logger ) { self::$logger = $logger; } + /** + * Get the Configurator instance + * + * @return \WP_CLI\Configurator + */ static function get_configurator() { static $configurator; From aa27fd943291dd750a662a80599f8e65e6684488 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 11:46:25 -0700 Subject: [PATCH 2889/4858] Update @nb's new export API with @dllh's fix for orphaned terms --- php/export/class-wp-export-query.php | 33 +++++++++++++++- php/export/writers.php | 56 +++++++++++++++++++++++----- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index b99636e040..d826d17f68 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -27,6 +27,8 @@ class WP_Export_Query { private $author; private $category; + public $missing_parents = false; + public function __construct( $filters = array() ) { $this->filters = wp_parse_args( $filters, self::$defaults ); $this->post_ids = $this->calculate_post_ids(); @@ -70,13 +72,17 @@ public function authors() { public function categories() { if ( $this->category ) { - return array( $this->category ); + return $this->category; } if ( $this->filters['post_type'] ) { return array(); } $categories = (array) get_categories( array( 'get' => 'all' ) ); + + $this->check_for_orphaned_terms( $categories ); + $categories = self::topologically_sort_terms( $categories ); + return $categories; } @@ -85,6 +91,9 @@ public function tags() { return array(); } $tags = (array) get_tags( array( 'get' => 'all' ) ); + + $this->check_for_orphaned_terms( $tags ); + return $tags; } @@ -94,6 +103,7 @@ public function custom_taxonomies_terms() { } $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) ); $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) ); + $this->check_for_orphaned_terms( $custom_terms ); $custom_terms = self::topologically_sort_terms( $custom_terms ); return $custom_terms; } @@ -271,6 +281,24 @@ private static function topologically_sort_terms( $terms ) { return $sorted; } + private function check_for_orphaned_terms( $terms ) { + $term_ids = array(); + $have_parent = array(); + + foreach ( $terms as $term ) { + $term_ids[ $term->term_id ] = true; + if ( $term->parent != 0 ) + $have_parent[] = $term; + } + + foreach ( $have_parent as $has_parent ) { + if ( ! isset( $term_ids[ $has_parent->parent ] ) ) { + $this->missing_parents = $has_parent; + throw new WP_Export_Term_Exception( __( 'Term is missing a parent.' ) ); + } + } + } + private static function get_terms_for_post( $post ) { $taxonomies = get_object_taxonomies( $post->post_type ); if ( empty( $taxonomies ) ) @@ -309,3 +337,6 @@ private static function get_comments_for_post( $post ) { class WP_Export_Exception extends RuntimeException { } + +class WP_Export_Term_Exception extends RuntimeException { +} diff --git a/php/export/writers.php b/php/export/writers.php index 751d356a10..5aa0927d24 100644 --- a/php/export/writers.php +++ b/php/export/writers.php @@ -26,14 +26,34 @@ function __construct( $formatter, $file_name ) { } public function export() { - header( 'Content-Description: File Transfer' ); - header( 'Content-Disposition: attachment; filename=' . $this->file_name ); - header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true ); - parent::export(); + try { + $export = $this->get_export(); + $this->send_headers(); + echo $export; + } catch ( WP_Export_Exception $e ) { + $message = apply_filters( 'export_error_message', $e->getMessage() ); + wp_die( $message, __( 'Export Error' ), array( 'back_link' => true ) ); + } catch ( WP_Export_Term_Exception $e ) { + do_action( 'export_term_orphaned', $this->formatter->export->missing_parents ); + $message = apply_filters( 'export_term_error_message', $e->getMessage() ); + wp_die( $message, __( 'Export Error' ), array( 'back_link' => true ) ); + } } protected function write( $xml ) { - echo $xml; + $this->result .= $xml; + } + + protected function get_export() { + $this->result = ''; + parent::export(); + return $this->result; + } + + protected function send_headers() { + header( 'Content-Description: File Transfer' ); + header( 'Content-Disposition: attachment; filename=' . $this->file_name ); + header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true ); } } @@ -42,7 +62,17 @@ class WP_Export_Returner extends WP_Export_Base_Writer { public function export() { $this->private = ''; - parent::export(); + try { + parent::export(); + } catch ( WP_Export_Exception $e ) { + $message = apply_filters( 'export_error_message', $e->getMessage() ); + return new WP_Error( 'wp-export-error', $message ); + + } catch ( WP_Export_Term_Exception $e ) { + do_action( 'export_term_orphaned', $this->formatter->export->missing_parents ); + $message = apply_filters( 'export_term_error_message', $e->getMessage() ); + return new WP_Error( 'wp-export-error', $message ); + } return $this->result; } protected function write( $xml ) { @@ -64,7 +94,15 @@ public function export() { if ( !$this->f ) { throw new WP_Export_Exception( sprintf( __( 'WP Export: error opening %s for writing.' ), $this->file_name ) ); } - parent::export(); + + try { + parent::export(); + } catch ( WP_Export_Exception $e ) { + throw $e; + } catch ( WP_Export_Term_Exception $e ) { + throw $e; + } + fclose( $this->f ); } @@ -85,7 +123,7 @@ class WP_Export_Split_Files_Writer extends WP_Export_Base_Writer { function __construct( $formatter, $writer_args = array() ) { parent::__construct( $formatter ); //TODO: check if args are not missing - $this->max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $writer_args['max_file_size']; + $this->max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $max_file_size; $this->destination_directory = $writer_args['destination_directory']; $this->filename_template = $writer_args['filename_template']; $this->before_posts_xml = $this->formatter->before_posts(); @@ -95,7 +133,7 @@ function __construct( $formatter, $writer_args = array() ) { public function export() { $this->start_new_file(); foreach( $this->formatter->posts() as $post_xml ) { - if ( ( $this->current_file_size + strlen( $post_xml ) ) > $this->max_file_size ) { + if ( $this->current_file_size + strlen( $post_xml ) > $this->max_file_size ) { $this->start_new_file(); } $this->write( $post_xml ); From b4770d9d66ce60c65bb1bb539ffd39f0d035e2b9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 25 Apr 2014 11:51:46 -0700 Subject: [PATCH 2890/4858] Writer should use passed argument, not unknown variable --- php/export/writers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/writers.php b/php/export/writers.php index 5aa0927d24..989dd18e8d 100644 --- a/php/export/writers.php +++ b/php/export/writers.php @@ -123,7 +123,7 @@ class WP_Export_Split_Files_Writer extends WP_Export_Base_Writer { function __construct( $formatter, $writer_args = array() ) { parent::__construct( $formatter ); //TODO: check if args are not missing - $this->max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $max_file_size; + $this->max_file_size = is_null( $writer_args['max_file_size'] ) ? 15 * MB_IN_BYTES : $writer_args['max_file_size']; $this->destination_directory = $writer_args['destination_directory']; $this->filename_template = $writer_args['filename_template']; $this->before_posts_xml = $this->formatter->before_posts(); From 6ac65d13ff1b0067e6d9a93cd5a3f84bbe69705e Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 17:33:12 +0100 Subject: [PATCH 2891/4858] Docblock updates. --- php/commands/cron.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 4e342365d8..713bcef8ac 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -8,7 +8,6 @@ class Cron_Event_Command extends WP_CLI_Command { private $fields = array( 'hook', - // 'next_run', 'next_run_gmt', 'next_run_relative', 'recurrence', @@ -21,7 +20,7 @@ class Cron_Event_Command extends WP_CLI_Command { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to all of the cron event fields. + * : Limit the output to specific object fields. Available fields: hook, next_run, next_run_gmt, next_run_relative, recurrence. * * [--format=<format>] * : Accepted values: table, json, csv, ids. Default: table. @@ -122,8 +121,6 @@ public function schedule( $args, $assoc_args ) { * * <hook> * : The hook name - * - * @synopsis <hook> */ public function run( $args, $assoc_args ) { @@ -178,8 +175,6 @@ protected static function run_event( stdClass $event ) { * * <hook> * : The hook name - * - * @synopsis <hook> */ public function delete( $args, $assoc_args ) { @@ -303,7 +298,7 @@ class Cron_Schedule_Command extends WP_CLI_Command { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to all of the cron schedule fields. + * : Limit the output to specific object fields. Available fields: name, display, interval. * * [--format=<format>] * : Accepted values: table, json, csv, ids. Default: table. From 721e561f69e4ce5fe940aab0ae5f823b71d7a83b Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 17:39:44 +0100 Subject: [PATCH 2892/4858] Examples for the `list` commands --- php/commands/cron.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index 713bcef8ac..bb82490bf9 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -25,6 +25,12 @@ class Cron_Event_Command extends WP_CLI_Command { * [--format=<format>] * : Accepted values: table, json, csv, ids. Default: table. * + * ## EXAMPLES + * + * wp cron event list + * + * wp cron event list --fields=hook,next_run --format=json + * * @subcommand list */ public function list_( $args, $assoc_args ) { @@ -303,6 +309,12 @@ class Cron_Schedule_Command extends WP_CLI_Command { * [--format=<format>] * : Accepted values: table, json, csv, ids. Default: table. * + * ## EXAMPLES + * + * wp cron schedule list + * + * wp cron schedule list --fields=name --format=ids + * * @subcommand list */ public function list_( $args, $assoc_args ) { From a6683cfb387c0c8fc8da25b03dbd4bf7ecb6aa24 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 18:09:51 +0100 Subject: [PATCH 2893/4858] Move `interval()` into `Cron_Event_Command` as a private method. Remove `time_since()` altogether. --- php/commands/cron.php | 63 ++++++++++++++++++++++++++++++++++++-- php/utils.php | 70 ------------------------------------------- 2 files changed, 61 insertions(+), 72 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index bb82490bf9..5d35027be4 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -234,8 +234,8 @@ protected static function format_event( stdClass $event ) { $event->next_run = get_date_from_gmt( date( 'Y-m-d H:i:s', $event->time ), self::$time_format ); $event->next_run_gmt = date( self::$time_format, $event->time ); - $event->next_run_relative = \WP_CLI\Utils\time_since( time(), $event->time ); - $event->recurrence = ( $event->schedule ) ? \WP_CLI\Utils\interval( $event->interval ) : 'Non-repeating'; + $event->next_run_relative = self::interval( $event->time - time() ); + $event->recurrence = ( $event->schedule ) ? self::interval( $event->interval ) : 'Non-repeating'; return $event; } @@ -281,6 +281,65 @@ protected static function get_cron_events() { } + /** + * Convert a time interval into human-readable format. + * + * Similar to WordPress' built-in `human_time_diff()` but returns two time period chunks instead of just one. + * + * @param int $since An interval of time in seconds + * @return string The interval in human readable format + */ + private static function interval( $since ) { + if ( $since <= 0 ) { + return 'now'; + } + + $since = absint( $since ); + + // array of time period chunks + $chunks = array( + array( 60 * 60 * 24 * 365 , \_n_noop( '%s year', '%s years' ) ), + array( 60 * 60 * 24 * 30 , \_n_noop( '%s month', '%s months' ) ), + array( 60 * 60 * 24 * 7, \_n_noop( '%s week', '%s weeks' ) ), + array( 60 * 60 * 24 , \_n_noop( '%s day', '%s days' ) ), + array( 60 * 60 , \_n_noop( '%s hour', '%s hours' ) ), + array( 60 , \_n_noop( '%s minute', '%s minutes' ) ), + array( 1 , \_n_noop( '%s second', '%s seconds' ) ), + ); + + // we only want to output two chunks of time here, eg: + // x years, xx months + // x days, xx hours + // so there's only two bits of calculation below: + + // step one: the first chunk + for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) { + $seconds = $chunks[$i][0]; + $name = $chunks[$i][1]; + + // finding the biggest chunk (if the chunk fits, break) + if ( ( $count = floor( $since / $seconds ) ) != 0 ){ + break; + } + } + + // set output var + $output = sprintf( \_n( $name[0], $name[1], $count ), $count ); + + // step two: the second chunk + if ( $i + 1 < $j ) { + $seconds2 = $chunks[$i + 1][0]; + $name2 = $chunks[$i + 1][1]; + + if ( ( $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ) ) != 0 ) { + // add to output var + $output .= ' ' . sprintf( \_n( $name2[0], $name2[1], $count2 ), $count2 ); + } + } + + return $output; + } + private function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'event' ); } diff --git a/php/utils.php b/php/utils.php index 393c06ee24..fe21f32e23 100644 --- a/php/utils.php +++ b/php/utils.php @@ -401,73 +401,3 @@ function replace_path_consts( $source, $path ) { return str_replace( $old, $new, $source ); } - -/** - * Convert a time interval into human-readable format. - * - * Similar to WordPress' built-in `human_time_diff()` but returns two time period chunks instead of just one. - * - * @param int $since An interval of time in seconds - * @return string The interval in human readable format - */ -function interval( $since ) { - if ( $since <= 0 ) { - return 'now'; - } - - $since = absint( $since ); - - // array of time period chunks - $chunks = array( - array( 60 * 60 * 24 * 365 , \_n_noop( '%s year', '%s years' ) ), - array( 60 * 60 * 24 * 30 , \_n_noop( '%s month', '%s months' ) ), - array( 60 * 60 * 24 * 7, \_n_noop( '%s week', '%s weeks' ) ), - array( 60 * 60 * 24 , \_n_noop( '%s day', '%s days' ) ), - array( 60 * 60 , \_n_noop( '%s hour', '%s hours' ) ), - array( 60 , \_n_noop( '%s minute', '%s minutes' ) ), - array( 1 , \_n_noop( '%s second', '%s seconds' ) ), - ); - - // we only want to output two chunks of time here, eg: - // x years, xx months - // x days, xx hours - // so there's only two bits of calculation below: - - // step one: the first chunk - for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) { - $seconds = $chunks[$i][0]; - $name = $chunks[$i][1]; - - // finding the biggest chunk (if the chunk fits, break) - if ( ( $count = floor( $since / $seconds ) ) != 0 ){ - break; - } - } - - // set output var - $output = sprintf( \_n( $name[0], $name[1], $count ), $count ); - - // step two: the second chunk - if ( $i + 1 < $j ) { - $seconds2 = $chunks[$i + 1][0]; - $name2 = $chunks[$i + 1][1]; - - if ( ( $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ) ) != 0 ) { - // add to output var - $output .= ' ' . sprintf( \_n( $name2[0], $name2[1], $count2 ), $count2 ); - } - } - - return $output; -} - -/** - * Returns a human-readable time difference between two times. - * - * @param int $older_date A Unix timestamp - * @param int $newer_date A Unix timestamp - * @return string The time difference in a human-readable format - */ -function time_since( $older_date, $newer_date ) { - return interval( $newer_date - $older_date ); -} From 82930548af63acd4cacd0de02c64ea333e5a9eb7 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 18:11:13 +0100 Subject: [PATCH 2894/4858] Convert `next_run` and `recurrence` into optional positional arguments --- php/commands/cron.php | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 5d35027be4..1d9baaa706 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -58,10 +58,10 @@ public function list_( $args, $assoc_args ) { * <hook> * : The hook name * - * [--next_run=<value>] + * [<next-run>] * : A Unix timestamp or an English textual datetime description compatible with `strtotime()`. Defaults to now. * - * [--recurrence=<value>] + * [<recurrence>] * : How often the event should recur. See `wp cron schedule list` for available schedule names. Defaults to no recurrence. * * [--<field>=<value>] @@ -71,44 +71,39 @@ public function list_( $args, $assoc_args ) { * * wp cron event schedule cron_test * - * wp cron event schedule cron_test --next_run='+1 hour' --recurrence=hourly + * wp cron event schedule cron_test now hourly * - * wp cron event schedule cron_test --recurrence=daily --foo=1 --bar=2 + * wp cron event schedule cron_test '+1 hour' --foo=1 --bar=2 */ public function schedule( $args, $assoc_args ) { - list( $hook ) = $args; + list( $hook, $next_run, $recurrence ) = $args; - if ( !isset( $assoc_args['next_run'] ) ) { + if ( !isset( $next_run ) ) { $timestamp = time(); - } else if ( is_numeric( $assoc_args['next_run'] ) ) { - $timestamp = absint( $assoc_args['next_run'] ); + } else if ( is_numeric( $next_run ) ) { + $timestamp = absint( $next_run ); } else { - $timestamp = strtotime( $assoc_args['next_run'] ); + $timestamp = strtotime( $next_run ); } if ( ! $timestamp ) { - WP_CLI::error( sprintf( "'%s' is not a valid datetime.", $assoc_args['next_run'] ) ); + WP_CLI::error( sprintf( "'%s' is not a valid datetime.", $next_run ) ); } - $event_args = array_diff_key( $assoc_args, array_flip( array( - 'next_run', 'recurrence' - ) ) ); + if ( isset( $recurrence ) ) { - if ( isset( $assoc_args['recurrence'] ) ) { - - $recurrence = $assoc_args['recurrence']; - $schedules = wp_get_schedules(); + $schedules = wp_get_schedules(); if ( ! isset( $schedules[$recurrence] ) ) { WP_CLI::error( sprintf( "'%s' is not a valid schedule name for recurrence.", $recurrence ) ); } - $event = wp_schedule_event( $timestamp, $recurrence, $hook, $event_args ); + $event = wp_schedule_event( $timestamp, $recurrence, $hook, $assoc_args ); } else { - $event = wp_schedule_single_event( $timestamp, $hook, $event_args ); + $event = wp_schedule_single_event( $timestamp, $hook, $assoc_args ); } From d3befe68cd8dc6e209c0601d9f1d60d526d478e3 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 18:11:30 +0100 Subject: [PATCH 2895/4858] Clarify that cron event times are in GMT --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 1d9baaa706..1e4e57e739 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -108,7 +108,7 @@ public function schedule( $args, $assoc_args ) { } if ( false !== $event ) { - WP_CLI::success( sprintf( "Scheduled event with hook '%s' for %s.", $hook, date( self::$time_format, $timestamp ) ) ); + WP_CLI::success( sprintf( "Scheduled event with hook '%s' for %s GMT.", $hook, date( self::$time_format, $timestamp ) ) ); } else { WP_CLI::error( 'Event not scheduled' ); } From f03532c9480adcb795636ae97b11768139ac805e Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 20:52:07 +0100 Subject: [PATCH 2896/4858] First pass at a Behat test for `wp cron` --- features/cron.feature | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 features/cron.feature diff --git a/features/cron.feature b/features/cron.feature new file mode 100644 index 0000000000..3791341c6e --- /dev/null +++ b/features/cron.feature @@ -0,0 +1,53 @@ +Feature: Manage WP-Cron events and schedules + + Background: + Given a WP install + + Scenario: Scheduling an event + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour'` + Then STDOUT should contain: + """ + Success: Scheduled event with hook 'wp_cli_test_event_1' + """ + + When I run `wp cron event list --format=csv --fields=hook,recurrence` + Then STDOUT should be CSV containing: + | hook | recurrence | + | wp_cli_test_event_1 | Non-repeating | + + When I run `wp cron event delete wp_cli_test_event_1` + Then STDOUT should contain: + """ + Success: Successfully deleted the cron event 'wp_cli_test_event_1' + """ + + Scenario: Scheduling a recurring event + When I run `wp cron event schedule wp_cli_test_event_2 now daily` + Then STDOUT should contain: + """ + Success: Scheduled event with hook 'wp_cli_test_event_2' + """ + + When I run `wp cron event list --format=csv --fields=hook,recurrence` + Then STDOUT should be CSV containing: + | hook | recurrence | + | wp_cli_test_event_2 | 1 day | + + When I run `wp cron event delete wp_cli_test_event_2` + Then STDOUT should contain: + """ + Success: Successfully deleted the cron event 'wp_cli_test_event_2' + """ + + Scenario: Listing cron schedules + When I run `wp cron schedule list --format=csv --fields=name,interval` + Then STDOUT should be CSV containing: + | name | interval | + | hourly | 3600 | + + Scenario: Testing WP-Cron + When I run `wp cron test` + Then STDOUT should contain: + """ + Success: WP-Cron is working as expected + """ From 41b1d02e03651f8751e6afede9f660e871f76652 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 28 Apr 2014 21:02:04 +0100 Subject: [PATCH 2897/4858] Code tidy up --- php/commands/cron.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 1e4e57e739..5b9b097b51 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -252,10 +252,9 @@ protected static function get_cron_events() { ); } - // @TODO rename these vars a bit more better nicely nicer: - foreach ( $crons as $time => $cron ) { - foreach ( $cron as $hook => $dings ) { - foreach ( $dings as $sig => $data ) { + foreach ( $crons as $time => $hooks ) { + foreach ( $hooks as $hook => $hook_events ) { + foreach ( $hook_events as $sig => $data ) { $events["$hook-$sig"] = (object) array( 'hook' => $hook, From 3f284f1514c2b17edaddf670516275ef3626cb0f Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Tue, 29 Apr 2014 11:08:40 +0100 Subject: [PATCH 2898/4858] Update from develop branch of WP-Crontrol. When testing cron, return an error if `DISABLE_WP_CRON` is set. --- php/commands/cron.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index 5b9b097b51..42f0120948 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -457,6 +457,10 @@ protected static function test_cron_spawn() { return true; } + if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) { + return new WP_Error( 'disable_wp_cron', 'The DISABLE_WP_CRON constant is set to true. WP-Cron is disabled.' ); + } + $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); $cron_request = apply_filters( 'cron_request', array( From b1916775157e3cd37e7b109b6d01e5daeb63a232 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 29 Apr 2014 08:30:51 -0700 Subject: [PATCH 2899/4858] Remove unused `check_verbose()` method Added in 32402827d8e738c7c4e6025b7b3bbc6d7a1a45d2 but doesn't appear to be used. aa542585aeeef589b1ce1e18edf3d4aa30a06786 removed the verbosity argument --- php/commands/export.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index 862818cbd5..31d9d84e22 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -130,12 +130,6 @@ private function validate_args( $args ) { } } - private function check_verbose( $verbose ) { - $this->verbose = $verbose; - - return true; - } - private function check_dir( $path ) { if ( empty( $path ) ) { $path = getcwd(); From e4e0bac7fd7f7605f3d97b0ec3358efcf2af4132 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 2 May 2014 10:33:04 -0300 Subject: [PATCH 2900/4858] add params first_name and last_name to wp user create --- features/user.feature | 14 +++++++++++++- php/commands/user.php | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/features/user.feature b/features/user.feature index ba508535fd..c603a5688f 100644 --- a/features/user.feature +++ b/features/user.feature @@ -7,7 +7,7 @@ Feature: Manage WordPress users Then the return code should be 1 And STDOUT should be empty - When I run `wp user create testuser2 testuser2@example.com --role=author --porcelain` + When I run `wp user create testuser2 testuser2@example.com --first_name=test --last_name=user --role=author --porcelain` Then STDOUT should be a number And save STDOUT as {USER_ID} @@ -17,6 +17,18 @@ Feature: Manage WordPress users | ID | {USER_ID} | | roles | author | + When I run `wp user meta get {USER_ID} first_name` + Then STDOUT should be: + """ + test + """ + + When I run `wp user meta get {USER_ID} last_name` + Then STDOUT should be: + """ + user + """ + When I run `wp user delete {USER_ID} --yes` Then STDOUT should not be empty diff --git a/php/commands/user.php b/php/commands/user.php index 68771013fe..61ea9dd5fd 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -185,6 +185,12 @@ public function delete( $args, $assoc_args ) { * [--display_name=<name>] * : The display name. * + * [--first_name=<first_name>] + * : The user's first name. + * + * [--last_name=<last_name>] + * : The user's last name. + * * [--send-email] * : Send an email to the user with their new account details. * @@ -214,6 +220,12 @@ public function create( $args, $assoc_args ) { $user->display_name = isset( $assoc_args['display_name'] ) ? $assoc_args['display_name'] : false; + $user->first_name = isset( $assoc_args['first_name'] ) + ? $assoc_args['first_name'] : false; + + $user->last_name = isset( $assoc_args['last_name'] ) + ? $assoc_args['last_name'] : false; + $user->user_pass = isset( $assoc_args['user_pass'] ) ? $assoc_args['user_pass'] : wp_generate_password(); From 0bc1a32c27d2831b9d9f7fb73585d7015fda1f93 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 2 May 2014 10:55:22 -0300 Subject: [PATCH 2901/4858] add basic test to 'wp scaffold plugin' command --- features/scaffold.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 0d1d011cf4..2c48377eda 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -72,3 +72,11 @@ Feature: WordPress code scaffolding """ __( 'Brain eaters' """ + + Scenario: Scaffold a plugin + Given I run `wp plugin path` + And save STDOUT as {PLUGIN_DIR} + + When I run `wp scaffold plugin hello-world` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist \ No newline at end of file From 2255a083b6b93b11a3fe4cc716d88e36c42eebb8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 2 May 2014 11:00:32 -0300 Subject: [PATCH 2902/4858] `wp scaffold plugin` generate a sample readme.txt --- features/scaffold.feature | 3 +- php/commands/scaffold.php | 2 + templates/plugin-readme.mustache | 114 +++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 templates/plugin-readme.mustache diff --git a/features/scaffold.feature b/features/scaffold.feature index 2c48377eda..419590e3d5 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -79,4 +79,5 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world` Then STDOUT should not be empty - And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist \ No newline at end of file + And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist + And the {PLUGIN_DIR}/hello-world/readme.txt file should exist \ No newline at end of file diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index fff531796c..e090fa5822 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -327,10 +327,12 @@ function plugin( $args, $assoc_args ) { $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; $plugin_path = "$plugin_dir/$plugin_slug.php"; + $plugin_readme_path = "$plugin_dir/readme.txt"; $this->maybe_create_plugins_dir(); $this->create_file( $plugin_path, Utils\mustache_render( 'plugin.mustache', $data ) ); + $this->create_file( $plugin_readme_path, Utils\mustache_render( 'plugin-readme.mustache', $data ) ); WP_CLI::success( "Created $plugin_dir" ); diff --git a/templates/plugin-readme.mustache b/templates/plugin-readme.mustache new file mode 100644 index 0000000000..44c117a686 --- /dev/null +++ b/templates/plugin-readme.mustache @@ -0,0 +1,114 @@ +=== {{plugin_name}} === +Contributors: (this should be a list of wordpress.org userid's) +Donate link: http://example.com/ +Tags: comments, spam +Requires at least: 3.0.1 +Tested up to: 3.4 +Stable tag: 4.3 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Here is a short description of the plugin. This should be no more than 150 characters. No markup here. + +== Description == + +This is the long description. No limit, and you can use Markdown (as well as in the following sections). + +For backwards compatibility, if this section is missing, the full length of the short description will be used, and +Markdown parsed. + +A few notes about the sections above: + +* "Contributors" is a comma separated list of wp.org/wp-plugins.org usernames +* "Tags" is a comma separated list of tags that apply to the plugin +* "Requires at least" is the lowest version that the plugin will work on +* "Tested up to" is the highest version that you've *successfully used to test the plugin*. Note that it might work on +higher versions... this is just the highest one you've verified. +* Stable tag should indicate the Subversion "tag" of the latest stable version, or "trunk," if you use `/trunk/` for +stable. + + Note that the `readme.txt` of the stable tag is the one that is considered the defining one for the plugin, so +if the `/trunk/readme.txt` file says that the stable tag is `4.3`, then it is `/tags/4.3/readme.txt` that'll be used +for displaying information about the plugin. In this situation, the only thing considered from the trunk `readme.txt` +is the stable tag pointer. Thus, if you develop in trunk, you can update the trunk `readme.txt` to reflect changes in +your in-development version, without having that information incorrectly disclosed about the current stable version +that lacks those changes -- as long as the trunk's `readme.txt` points to the correct stable tag. + + If no stable tag is provided, it is assumed that trunk is stable, but you should specify "trunk" if that's where +you put the stable version, in order to eliminate any doubt. + +== Installation == + +This section describes how to install the plugin and get it working. + +e.g. + +1. Upload `plugin-name.php` to the `/wp-content/plugins/` directory +1. Activate the plugin through the 'Plugins' menu in WordPress +1. Place `<?php do_action('plugin_name_hook'); ?>` in your templates + +== Frequently Asked Questions == + += A question that someone might have = + +An answer to that question. + += What about foo bar? = + +Answer to foo bar dilemma. + +== Screenshots == + +1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from +the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets +directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png` +(or jpg, jpeg, gif). +2. This is the second screen shot + +== Changelog == + += 1.0 = +* A change since the previous version. +* Another change. + += 0.5 = +* List versions from most recent at top to oldest at bottom. + +== Upgrade Notice == + += 1.0 = +Upgrade notices describe the reason a user should upgrade. No more than 300 characters. + += 0.5 = +This version fixes a security related bug. Upgrade immediately. + +== Arbitrary section == + +You may provide arbitrary sections, in the same format as the ones above. This may be of use for extremely complicated +plugins where more information needs to be conveyed that doesn't fit into the categories of "description" or +"installation." Arbitrary sections will be shown below the built-in sections outlined above. + +== A brief Markdown Example == + +Ordered list: + +1. Some feature +1. Another feature +1. Something else about the plugin + +Unordered list: + +* something +* something else +* third thing + +Here's a link to [WordPress](http://wordpress.org/ "Your favorite software") and one to [Markdown's Syntax Documentation][markdown syntax]. +Titles are optional, naturally. + +[markdown syntax]: http://daringfireball.net/projects/markdown/syntax + "Markdown is what the parser uses to process much of the readme file" + +Markdown uses email style notation for blockquotes and I've been told: +> Asterisks for *emphasis*. Double it up for **strong**. + +`<?php code(); // goes in backticks ?>` From 5e47794129a8d6f4a216161d6f50b9edb9e6bd90 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 2 May 2014 08:58:08 -0700 Subject: [PATCH 2903/4858] Add `--fields` support to `wp user get` --- php/commands/user.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index 61ea9dd5fd..11b7f53aea 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -89,6 +89,9 @@ public function list_( $args, $assoc_args ) { * [--field=<field>] * : Instead of returning the whole user, returns the value of a single field. * + * [--fields=<fields>] + * : Get a specific subset of the user's fields. + * * [--format=<format>] * : Accepted values: table, json. Default: table * From 01b55ad79b75d9bb0c152575e591e2023f565d43 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 2 May 2014 08:58:28 -0700 Subject: [PATCH 2904/4858] Add `--skip-update` flag to `wp user import-csv` --- features/user.feature | 33 +++++++++++++++++++++++++++++++++ php/commands/user.php | 11 ++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/features/user.feature b/features/user.feature index c603a5688f..a50e3bb3a6 100644 --- a/features/user.feature +++ b/features/user.feature @@ -150,6 +150,39 @@ Feature: Manage WordPress users }] """ + Scenario: Import new users but don't update existing + Given a WP install + And a users.csv file: + """ + user_login,user_email,display_name,role + bobjones,bobjones@domain.com,Bob Jones,contributor + newuser1,newuser1@domain.com,New User,author + admin,admin@domain.com,Existing User,administrator + """ + + When I run `wp user create bobjones bobjones@domain.com --display_name="Robert Jones" --role=administrator` + Then STDOUT should not be empty + + When I run `wp user import-csv users.csv --skip-update` + Then STDOUT should not be empty + + When I run `wp user list --format=count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp user get bobjones --fields=user_login,display_name,user_email,roles --format=json` + Then STDOUT should be JSON containing: + """ + { + "user_login":"bobjones", + "display_name":"Robert Jones", + "user_email":"bobjones@domain.com", + "roles":"administrator" + } + """ + Scenario: Managing user roles Given a WP install diff --git a/php/commands/user.php b/php/commands/user.php index 11b7f53aea..81bca8f40f 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -551,6 +551,9 @@ public function list_caps( $args, $assoc_args ) { * [--send-email] * : Send an email to new users with their account details. * + * [--skip-update] + * : Don't update users that already exist. + * * ## EXAMPLES * * wp user import-csv /path/to/users.csv @@ -597,7 +600,13 @@ public function import_csv( $args, $assoc_args ) { $existing_user = get_user_by( 'login', $new_user['user_login'] ); } - if ( $existing_user ) { + if ( $existing_user && isset( $assoc_args['skip-update'] ) ) { + + WP_CLI::log( "{$existing_user->user_login} exists and has been skipped" ); + continue; + + } else if ( $existing_user ) { + $new_user['ID'] = $existing_user->ID; $user_id = wp_update_user( $new_user ); From 9d15ec0be6c0ec9f7f590db96e7f0f58c485c785 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 2 May 2014 20:11:06 +0100 Subject: [PATCH 2905/4858] Formatting tweak --- features/cron.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/cron.feature b/features/cron.feature index 3791341c6e..d345940ce8 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -12,7 +12,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event list --format=csv --fields=hook,recurrence` Then STDOUT should be CSV containing: - | hook | recurrence | + | hook | recurrence | | wp_cli_test_event_1 | Non-repeating | When I run `wp cron event delete wp_cli_test_event_1` From bca449463047aa16f3dc91eb0eb401396afced39 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 2 May 2014 20:13:52 +0100 Subject: [PATCH 2906/4858] Alter `wp cron event run <hook>` so it fires the event inline instead of asynchronously --- php/commands/cron.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 42f0120948..e80960bd16 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -141,6 +141,7 @@ public function run( $args, $assoc_args ) { } if ( $result ) { + WP_CLI::line( '' ); WP_CLI::success( sprintf( "Successfully executed the cron event '%s'", $hook ) ); } else { WP_CLI::error( sprintf( "Failed to the execute the cron event '%s'", $hook ) ); @@ -149,21 +150,18 @@ public function run( $args, $assoc_args ) { } /** - * Executes an event immediately by scheduling a new single event with the same arguments. + * Executes an event immediately. * * @param stdClass $event The event * @return bool Whether the event was successfully executed or not. */ protected static function run_event( stdClass $event ) { - delete_transient( 'doing_cron' ); - $scheduled = wp_schedule_single_event( time()-1, $event->hook, $event->args ); - - if ( false === $scheduled ) { - return false; + if ( ! defined( 'DOING_CRON' ) ) { + define( 'DOING_CRON', true ); } - spawn_cron(); + do_action_ref_array( $event->hook, $event->args ); return true; From 1ce77bd1a6648c66d96f1f2c405e79aca7e4aa28 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 2 May 2014 20:17:30 +0100 Subject: [PATCH 2907/4858] More comprehensive testing in `wp cron test`: * Displays an error if `DISABLE_WP_CRON` is set to true * Displays an error if the cron spawn fails * Displays a warning when `ALTERNATE_WP_CRON` is set to true * Displays a warning when the cron spawn request's HTTP status is something other than a 200 --- php/commands/cron.php | 49 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index e80960bd16..15bc3c4516 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -427,37 +427,44 @@ private function get_formatter( &$assoc_args ) { class Cron_Command extends WP_CLI_Command { /** - * Test the WP Cron spawning system and report back any errors. + * Test the WP Cron spawning system and report back its status. */ public function test() { - $status = self::test_cron_spawn(); + if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) { + WP_CLI::error( 'The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.' ); + } + + if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { + WP_CLI::warning( 'The ALTERNATE_WP_CRON constant is set to true. WP-Cron spawning is not asynchronous.' ); + } + + $spawn = self::get_cron_spawn(); + + if ( is_wp_error( $spawn ) ) { + WP_CLI::error( sprintf( 'WP-Cron spawn failed with error: %s', $spawn->get_error_message() ) ); + } + + $code = wp_remote_retrieve_response_code( $spawn ); + $message = wp_remote_retrieve_response_message( $spawn ); - if ( is_wp_error( $status ) ) { - WP_CLI::error( $status ); + if ( 200 === $code ) { + WP_CLI::success( 'WP-Cron spawning is working as expected.' ); } else { - WP_CLI::success( 'WP-Cron is working as expected.' ); + WP_CLI::warning( sprintf( 'WP-Cron spawn succeeded but returned HTTP status code: %1$s %2$s', $code, $message ) ); } } /** - * Gets the status of WP-Cron functionality on the site by performing a test spawn. + * Spawn a request to `wp-cron.php` and return the response. * - * This function is designed to mimic the functionality in `spawn_cron()` with the addition of checking - * the return value of the call to `wp_remote_post()`. + * This function is designed to mimic the functionality in `spawn_cron()` with the addition of returning + * the result of the `wp_remote_post()` request. * - * @return bool|WP_Error Boolean true if the cron spawn test is successful, WP_Error object if not. + * @return WP_Error|array The response or WP_Error on failure. */ - protected static function test_cron_spawn() { - - if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { - return true; - } - - if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) { - return new WP_Error( 'disable_wp_cron', 'The DISABLE_WP_CRON constant is set to true. WP-Cron is disabled.' ); - } + protected static function get_cron_spawn() { $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); @@ -476,11 +483,7 @@ protected static function test_cron_spawn() { $result = wp_remote_post( $cron_request['url'], $cron_request['args'] ); - if ( is_wp_error( $result ) ) { - return $result; - } else { - return true; - } + return $result; } From 4e53c54f7c6b96a7d6b3363de7ac982ed6d37e23 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 2 May 2014 20:36:26 +0100 Subject: [PATCH 2908/4858] Update the behat test for `wp cron test`. Not currently passing. --- features/cron.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index d345940ce8..9d647c8b75 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -47,7 +47,7 @@ Feature: Manage WP-Cron events and schedules Scenario: Testing WP-Cron When I run `wp cron test` - Then STDOUT should contain: + Then STDOUT should not contain: """ - Success: WP-Cron is working as expected + Error: """ From 9c5989dfa060cb494f946fb2d8004c82e091b838 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 2 May 2014 13:01:35 -0700 Subject: [PATCH 2909/4858] Let's see if skipping PHP 5.5.11 does the trick to fix Travis builds --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94c066ac1a..85086d37a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,8 @@ language: php php: - 5.3 - - 5.5 + # WP-CLI currently fails on PHP 5.5.11, which Travis is using + - 5.4 env: global: @@ -32,12 +33,12 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=3.9-RC1 + - WP_VERSION=3.9 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: exclude: - - php: 5.5 + - php: 5.4 env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master before_script: ./ci/prepare.sh From 69b4099ae54fdd157d7c5f7160d3965544d344ee Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 2 May 2014 21:23:43 +0100 Subject: [PATCH 2910/4858] Update the `wp cron test` feature test so it handles STDERR output --- features/cron.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 9d647c8b75..13e3441307 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -46,8 +46,8 @@ Feature: Manage WP-Cron events and schedules | hourly | 3600 | Scenario: Testing WP-Cron - When I run `wp cron test` - Then STDOUT should not contain: + When I try `wp cron test` + Then STDERR should not contain: """ Error: """ From 4cab441f8901deb0920a1f1856621628c748e639 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Fri, 2 May 2014 21:30:25 +0100 Subject: [PATCH 2911/4858] Add tests to check that `wp cron event delete` has worked --- features/cron.feature | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 13e3441307..d33a694b55 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -3,7 +3,7 @@ Feature: Manage WP-Cron events and schedules Background: Given a WP install - Scenario: Scheduling an event + Scenario: Scheduling and then deleting an event When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour'` Then STDOUT should contain: """ @@ -21,7 +21,13 @@ Feature: Manage WP-Cron events and schedules Success: Successfully deleted the cron event 'wp_cli_test_event_1' """ - Scenario: Scheduling a recurring event + When I run `wp cron event list` + Then STDOUT should not contain: + """ + wp_cli_test_event_1 + """ + + Scenario: Scheduling and then deleting a recurring event When I run `wp cron event schedule wp_cli_test_event_2 now daily` Then STDOUT should contain: """ @@ -39,6 +45,12 @@ Feature: Manage WP-Cron events and schedules Success: Successfully deleted the cron event 'wp_cli_test_event_2' """ + When I run `wp cron event list` + Then STDOUT should not contain: + """ + wp_cli_test_event_2 + """ + Scenario: Listing cron schedules When I run `wp cron schedule list --format=csv --fields=name,interval` Then STDOUT should be CSV containing: From f5655d919d890ed0b7ee577b8920973d735ab107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Sat, 3 May 2014 01:07:42 +0200 Subject: [PATCH 2912/4858] don't set user whwn installing Is it all right?? --- php/WP_CLI/Runner.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 49ff4c012e..76419a541d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -681,7 +681,9 @@ public function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); // Handle --user parameter - self::set_user( $this->config ); + if ( ! defined( 'WP_INSTALLING' ) ) { + self::set_user( $this->config ); + } $this->_run_command(); } From 0891e45e63b7759da39020640f814891fd8ede4e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 5 May 2014 11:14:50 -0700 Subject: [PATCH 2913/4858] Functional tests for #1180 --- features/core.feature | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/features/core.feature b/features/core.feature index fd7793eaa0..f8b363b0d5 100644 --- a/features/core.feature +++ b/features/core.feature @@ -238,3 +238,22 @@ Feature: Manage WordPress installation When I run `wp plugin status hello` Then STDOUT should not be empty + + Scenario: User defined in wp-cli.yml + Given an empty directory + And WP files + And wp-config.php + And a database + And a wp-cli.yml file: + """ + user: wpcli + """ + + When I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + Then STDOUT should not be empty + + When I run `wp eval 'echo home_url();'` + Then STDOUT should be: + """ + http://localhost:8001 + """ From 79649ae24b08b9cf2daba8cc8be26c00a039514d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 5 May 2014 11:54:46 -0700 Subject: [PATCH 2914/4858] Support passing `--parent-id` to set the parent of a menu item --- features/menu.feature | 28 +++++++++++++++++----------- php/commands/menu.php | 1 + 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index 60862576ee..f8bef10e90 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -56,22 +56,28 @@ Feature: Manage WordPress menus Then save STDOUT as {TERM_LINK} When I run `wp menu create "Sidebar Menu"` - And I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post"` - And I run `wp menu item add-term sidebar-menu post_tag {TERM_ID}` - And I run `wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain` - Then save STDOUT as {ITEM_ID} + Then STDOUT should not be empty - When I run `wp menu item update {ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` + When I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post" --porcelain` + Then save STDOUT as {POST_ITEM_ID} + + When I run `wp menu item add-term sidebar-menu post_tag {TERM_ID} --porcelain` + Then save STDOUT as {TERM_ITEM_ID} + + When I run `wp menu item add-custom sidebar-menu Apple http://apple.com --parent-id={POST_ITEM_ID} --porcelain` + Then save STDOUT as {CUSTOM_ITEM_ID} + + When I run `wp menu item update {CUSTOM_ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` Then STDERR should be empty - When I run `wp menu item list sidebar-menu --fields=type,title,position,link` + When I run `wp menu item list sidebar-menu --fields=type,title,position,link,menu_item_parent` Then STDOUT should be a table containing rows: - | type | title | position | link | - | post_type | Custom Test Post | 1 | {POST_LINK} | - | custom | WordPress | 2 | http://wordpress.org | - | taxonomy | Test term | 3 | {TERM_LINK} | + | type | title | position | link | menu_item_parent | + | post_type | Custom Test Post | 1 | {POST_LINK} | 0 | + | custom | WordPress | 2 | http://wordpress.org | {POST_ITEM_ID} | + | taxonomy | Test term | 3 | {TERM_LINK} | 0 | - When I run `wp menu item delete {ITEM_ID}` + When I run `wp menu item delete {CUSTOM_ITEM_ID}` And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: """ diff --git a/php/commands/menu.php b/php/commands/menu.php index 47160a541f..25223b9483 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -467,6 +467,7 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { 'description' => '', 'object' => '', 'object-id' => '', + 'parent-id' => '', 'attr-title' => '', 'target' => '', 'classes' => '', From 71b2e2fc65bde06f15cae6781e1314d9f503eb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Mon, 5 May 2014 21:14:06 +0200 Subject: [PATCH 2915/4858] indent --- php/commands/db.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 72ccd75268..6e676e1608 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -205,8 +205,8 @@ function import( $args, $assoc_args ) { * * ## EXAMPLES * - * # Export only tables for a single site - * wp db export --tables=$(wp db tables --url=sub.example.com | tr '\n' ',') + * # Export only tables for a single site + * wp db export --tables=$(wp db tables --url=sub.example.com | tr '\n' ',') */ function tables( $args, $assoc_args ) { global $wpdb; From 1539cb378c8e470ee624fedd2c16106c500c0f7c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 5 May 2014 12:22:58 -0700 Subject: [PATCH 2916/4858] When updating a menu item, always persist its data Fixes a bug in core where the data will be lost https://core.trac.wordpress.org/ticket/28138 --- features/menu.feature | 15 ++++++---- php/commands/menu.php | 69 ++++++++++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index f8bef10e90..75753186c6 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -58,9 +58,12 @@ Feature: Manage WordPress menus When I run `wp menu create "Sidebar Menu"` Then STDOUT should not be empty - When I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post" --porcelain` + When I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post" --description="Georgia peaches" --porcelain` Then save STDOUT as {POST_ITEM_ID} + When I run `wp menu item update {POST_ITEM_ID} --description="Washington Apples"` + Then STDERR should be empty + When I run `wp menu item add-term sidebar-menu post_tag {TERM_ID} --porcelain` Then save STDOUT as {TERM_ITEM_ID} @@ -70,12 +73,12 @@ Feature: Manage WordPress menus When I run `wp menu item update {CUSTOM_ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` Then STDERR should be empty - When I run `wp menu item list sidebar-menu --fields=type,title,position,link,menu_item_parent` + When I run `wp menu item list sidebar-menu --fields=type,title,description,position,link,menu_item_parent` Then STDOUT should be a table containing rows: - | type | title | position | link | menu_item_parent | - | post_type | Custom Test Post | 1 | {POST_LINK} | 0 | - | custom | WordPress | 2 | http://wordpress.org | {POST_ITEM_ID} | - | taxonomy | Test term | 3 | {TERM_LINK} | 0 | + | type | title | description | position | link | menu_item_parent | + | post_type | Custom Test Post | Washington Apples | 1 | {POST_LINK} | 0 | + | custom | WordPress | | 2 | http://wordpress.org | {POST_ITEM_ID} | + | taxonomy | Test term | | 3 | {TERM_LINK} | 0 | When I run `wp menu item delete {CUSTOM_ITEM_ID}` And I run `wp menu item list sidebar-menu --format=count` diff --git a/php/commands/menu.php b/php/commands/menu.php index 25223b9483..8d133a56ca 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -460,35 +460,56 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { $assoc_args['url'] = $assoc_args['link']; } - $default_args = array( - 'position' => 0, - 'title' => '', - 'url' => '', - 'description' => '', - 'object' => '', - 'object-id' => '', - 'parent-id' => '', - 'attr-title' => '', - 'target' => '', - 'classes' => '', - 'xfn' => '', - 'status' => '', - ); + // Need to persist the menu item data. See https://core.trac.wordpress.org/ticket/28138 + if ( 'update' == $method ) { + + $menu_item_obj = get_post( $menu_item_db_id ); + $menu_item_obj = wp_setup_nav_menu_item( $menu_item_obj ); + + $default_args = array( + 'position' => $menu_item_obj->menu_order, + 'title' => $menu_item_obj->title, + 'url' => $menu_item_obj->url, + 'description' => $menu_item_obj->description, + 'object' => $menu_item_obj->object, + 'object-id' => $menu_item_obj->object_id, + 'parent-id' => $menu_item_obj->menu_item_parent, + 'attr-title' => $menu_item_obj->attr_title, + 'target' => $menu_item_obj->target, + 'classes' => implode( ' ', $menu_item_obj->classes ), // stored in the database as array + 'xfn' => $menu_item_obj->xfn, + 'status' => $menu_item_obj->post_status, + ); + + error_log( var_export( $default_args, true ) ); + + } else { + + $default_args = array( + 'position' => 0, + 'title' => '', + 'url' => '', + 'description' => '', + 'object' => '', + 'object-id' => 0, + 'parent-id' => 0, + 'attr-title' => '', + 'target' => '', + 'classes' => '', + 'xfn' => '', + // Core oddly defaults to 'draft' for create, + // and 'publish' for update + // Easiest to always work with publish + 'status' => 'publish', + ); + + } $menu_item_args = array(); foreach( $default_args as $key => $default_value ) { // wp_update_nav_menu_item() has a weird argument prefix $new_key = 'menu-item-' . $key; - if ( isset( $assoc_args[ $key ] ) ) { - $menu_item_args[ $new_key ] = $assoc_args[ $key ]; - } - } - - // Core oddly defaults to 'draft' for create, - // and 'publish' for update - // Easiest to always work with publish - if ( ! isset( $menu_item_args['menu-item-status'] ) ) { - $menu_item_args['menu-item-status'] = 'publish'; + $menu_item_args[ $new_key ] = isset( $assoc_args[ $key ] ) ? $assoc_args[ $key ] : $default_value; } $menu_item_args['menu-item-type'] = $type; From 721bb4f14261f08124a673fb4714cbeae1a2aba9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 5 May 2014 12:31:37 -0700 Subject: [PATCH 2917/4858] Persist the appropriate position when updating a menu item See https://core.trac.wordpress.org/ticket/28140 --- php/commands/menu.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 8d133a56ca..e5de9bfd39 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -466,8 +466,11 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { $menu_item_obj = get_post( $menu_item_db_id ); $menu_item_obj = wp_setup_nav_menu_item( $menu_item_obj ); + // Correct the menu position if this was the first item. See https://core.trac.wordpress.org/ticket/28140 + $position = ( 0 === $menu_item_obj->menu_order ) ? 1 : $menu_item_obj->menu_order; + $default_args = array( - 'position' => $menu_item_obj->menu_order, + 'position' => $position, 'title' => $menu_item_obj->title, 'url' => $menu_item_obj->url, 'description' => $menu_item_obj->description, @@ -481,8 +484,6 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { 'status' => $menu_item_obj->post_status, ); - error_log( var_export( $default_args, true ) ); - } else { $default_args = array( From 0ce031477d31ed4bb0682e60fe8330680d2f214e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 5 May 2014 13:08:52 -0700 Subject: [PATCH 2918/4858] Fix coding standards error --- php/commands/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index e5de9bfd39..55191c8db4 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -486,7 +486,7 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { } else { - $default_args = array( + $default_args = array( 'position' => 0, 'title' => '', 'url' => '', From 1a3e44fe35f0dae2822dae4cab802df24e9d0a08 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 08:08:22 -0700 Subject: [PATCH 2919/4858] Remove extra line --- php/commands/cron.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 15bc3c4516..5f27b3dcb7 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -141,7 +141,6 @@ public function run( $args, $assoc_args ) { } if ( $result ) { - WP_CLI::line( '' ); WP_CLI::success( sprintf( "Successfully executed the cron event '%s'", $hook ) ); } else { WP_CLI::error( sprintf( "Failed to the execute the cron event '%s'", $hook ) ); From 8bc2c5bb79ab269a63beef6be8ccdb9cf95ab38e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 08:13:54 -0700 Subject: [PATCH 2920/4858] When a cron event runs, clear it from cron entries However, if it's scheduled to reoccur, reschedule the cron event. Adds functional tests. --- features/cron.feature | 42 ++++++++++++++++++++++++++++++++++++++++++ php/commands/cron.php | 7 +++++++ 2 files changed, 49 insertions(+) diff --git a/features/cron.feature b/features/cron.feature index d33a694b55..a25404172b 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -27,6 +27,48 @@ Feature: Manage WP-Cron events and schedules wp_cli_test_event_1 """ + Scenario: Scheduling and then running an event + When I run `wp cron event schedule wp_cli_test_event_3 '-1 minutes'` + Then STDOUT should contain: + """ + Success: Scheduled event with hook 'wp_cli_test_event_3' + """ + + When I run `wp cron event list --format=csv --fields=hook,recurrence` + Then STDOUT should be CSV containing: + | hook | recurrence | + | wp_cli_test_event_3 | Non-repeating | + + When I run `wp cron event run wp_cli_test_event_3` + Then STDOUT should not be empty + + When I run `wp cron event list` + Then STDOUT should not contain: + """ + wp_cli_test_event_3 + """ + + Scenario: Scheduling and then running a re-occurring event + When I run `wp cron event schedule wp_cli_test_event_4 now hourly` + Then STDOUT should contain: + """ + Success: Scheduled event with hook 'wp_cli_test_event_4' + """ + + When I run `wp cron event list --format=csv --fields=hook,recurrence` + Then STDOUT should be CSV containing: + | hook | recurrence | + | wp_cli_test_event_4 | 1 hour | + + When I run `wp cron event run wp_cli_test_event_4` + Then STDOUT should not be empty + + When I run `wp cron event list` + Then STDOUT should contain: + """ + wp_cli_test_event_4 + """ + Scenario: Scheduling and then deleting a recurring event When I run `wp cron event schedule wp_cli_test_event_2 now daily` Then STDOUT should contain: diff --git a/php/commands/cron.php b/php/commands/cron.php index 5f27b3dcb7..db4e07dd24 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -160,6 +160,13 @@ protected static function run_event( stdClass $event ) { define( 'DOING_CRON', true ); } + if ( $event->schedule != false ) { + $new_args = array( $event->time, $event->schedule, $event->hook, $event->args ); + call_user_func_array( 'wp_reschedule_event', $new_args ); + } + + wp_unschedule_event( $event->time, $event->hook, $event->args ); + do_action_ref_array( $event->hook, $event->args ); return true; From c2f4c1878089e9cef702e0530561dd2081b81f1f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 08:51:00 -0700 Subject: [PATCH 2921/4858] Support empty `DB_CHARSET` value when running MySQL commands See #1143 --- features/db.feature | 20 ++++++++++++++++++++ php/commands/db.php | 11 ++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/features/db.feature b/features/db.feature index f8376e8245..92074c225a 100644 --- a/features/db.feature +++ b/features/db.feature @@ -71,3 +71,23 @@ Feature: Perform database operations """ 1 """ + + Scenario: DB export no charset + Given a WP install + And a replace-script.php file: + """ + <?php + $wp_config = file_get_contents( 'wp-config.php' ); + $wp_config = str_replace( 'utf8', '', $wp_config ); + file_put_contents( 'wp-config.php', $wp_config ); + WP_CLI::success( "Replaced charset" ); + """ + + When I run `wp eval-file replace-script.php` + Then STDOUT should not be empty + + When I run `wp db export /tmp/wp-cli-behat.sql` + Then STDOUT should contain: + """ + Success: Exported + """ diff --git a/php/commands/db.php b/php/commands/db.php index 6e676e1608..b641c8499a 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -232,12 +232,17 @@ private static function run_query( $query ) { } private static function run( $cmd, $assoc_args = array(), $descriptors = null ) { - $final_args = array_merge( $assoc_args, array( + $required = array( 'host' => DB_HOST, 'user' => DB_USER, 'pass' => DB_PASSWORD, - 'default-character-set' => DB_CHARSET, - ) ); + ); + + if ( defined( 'DB_CHARSET' ) && constant( 'DB_CHARSET' ) ) { + $required['default-character-set'] = constant( 'DB_CHARSET' ); + } + + $final_args = array_merge( $assoc_args, $required ); Utils\run_mysql_command( $cmd, $final_args, $descriptors ); } From 3919514d0e89d26942023bb9686355b5cd44155f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 09:40:03 -0700 Subject: [PATCH 2922/4858] No synopsis needed if the options are properly declared --- php/commands/media.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 08770b097d..5ce897724b 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -67,27 +67,27 @@ function regenerate( $args, $assoc_args = array() ) { * * ## OPTIONS * - * <file> + * <file>... * : Path to file or files to be imported. Supports the glob(3) capabilities of the current shell. * If file is recognized as a URL (for example, with a scheme of http or ftp), the file will be * downloaded to a temp file before being sideloaded. * - * --post_id=<post_id> + * [--post_id=<post_id>] * : ID of the post to attach the imported files to * - * --title=<title> + * [--title=<title>] * : Attachment title (post title field) * - * --caption=<caption> + * [--caption=<caption>] * : Caption for attachent (post excerpt field) * - * --alt=<alt_text> + * [--alt=<alt_text>] * : Alt text for image (saved as post meta) * - * --desc=<description> + * [--desc=<description>] * : "Description" field (post content) of attachment post * - * --featured_image + * [--featured_image] * : If set, set the imported image as the Featured Image of the post its attached to. * * ## EXAMPLES @@ -100,8 +100,6 @@ function regenerate( $args, $assoc_args = array() ) { * * # Import an image from the web * wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" - * - * @synopsis <file>... [--post_id=<id>] [--title=<title>] [--caption=<caption>] [--alt=<text>] [--desc=<description>] [--featured_image] */ function import( $args, $assoc_args = array() ) { $assoc_args = wp_parse_args( $assoc_args, array( From 58d6040951a9385c7cffbca178745ed227626580 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 09:46:11 -0700 Subject: [PATCH 2923/4858] Reduce redundant calls to `is_wp_error()` --- php/commands/media.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 5ce897724b..c6f4f7f412 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -145,14 +145,23 @@ function import( $args, $assoc_args = array() ) { // Deletes the temporary file. $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); + if ( is_wp_error( $success ) ) { + WP_CLI::warning( sprintf( + 'Unable to import file %s. Reason: %s', + $orig_filename, implode( ', ', $success->get_error_messages() ) + ) ); + continue; + } // Set alt text - if ( !is_wp_error( $success ) && $assoc_args['alt'] ) + if ( $assoc_args['alt'] ) { update_post_meta( $success, '_wp_attachment_image_alt', $assoc_args['alt'] ); + } // Set as featured image, if --post_id and --featured_image are set - if ( !is_wp_error( $success ) && $assoc_args['post_id'] && isset($assoc_args['featured_image']) ) + if ( $assoc_args['post_id'] && isset( $assoc_args['featured_image'] ) ) { update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); + } $attachment_success_text = ''; if ( $assoc_args['post_id'] ) { @@ -161,17 +170,10 @@ function import( $args, $assoc_args = array() ) { $attachment_success_text .= ' as featured image'; } - if ( is_wp_error( $success ) ) { - WP_CLI::warning( sprintf( - 'Unable to import file %s. Reason: %s', - $orig_filename, implode( ', ', $success->get_error_messages() ) - ) ); - } else { - WP_CLI::success( sprintf( - 'Imported file %s as attachment ID %d%s.', - $orig_filename, $success, $attachment_success_text - ) ); - } + WP_CLI::success( sprintf( + 'Imported file %s as attachment ID %d%s.', + $orig_filename, $success, $attachment_success_text + ) ); } } From 4d21d944fb2fe829e826d922a3f288606aa8696d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 09:54:11 -0700 Subject: [PATCH 2924/4858] Support for `--porcelain` with `wp media import` `--porcelain` makes it much easier to use a new entity in subsequent commands. --- features/media.feature | 14 ++++++++++++++ php/commands/media.php | 15 +++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/features/media.feature b/features/media.feature index ee77d30bc3..fa28cff858 100644 --- a/features/media.feature +++ b/features/media.feature @@ -39,3 +39,17 @@ Feature: Manage WordPress attachments and attached to post 1 as featured image """ And the {CACHE_DIR}/large-image.jpg file should exist + + Scenario: Import a file as an attachment but porcelain style + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + + When I run `wp post get {ATTACHMENT_ID} --field=title` + Then STDOUT should be: + """ + My imported attachment + """ \ No newline at end of file diff --git a/php/commands/media.php b/php/commands/media.php index c6f4f7f412..0db3794680 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -90,6 +90,9 @@ function regenerate( $args, $assoc_args = array() ) { * [--featured_image] * : If set, set the imported image as the Featured Image of the post its attached to. * + * [--porcelain] + * : Output just the new attachment id. + * * ## EXAMPLES * * # Import all jpgs in the current user's "Pictures" directory, not attached to any post @@ -170,10 +173,14 @@ function import( $args, $assoc_args = array() ) { $attachment_success_text .= ' as featured image'; } - WP_CLI::success( sprintf( - 'Imported file %s as attachment ID %d%s.', - $orig_filename, $success, $attachment_success_text - ) ); + if ( isset( $assoc_args['porcelain'] ) ) { + WP_CLI::line( $success ); + } else { + WP_CLI::success( sprintf( + 'Imported file %s as attachment ID %d%s.', + $orig_filename, $success, $attachment_success_text + ) ); + } } } From 8aa4032e4118fe63020613f443c347fdc9576369 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 10:24:14 -0700 Subject: [PATCH 2925/4858] `wp post generate --post_author=` can accept user login, email address, or ID --- features/post.feature | 12 ++++++++++++ php/commands/post.php | 6 ++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/features/post.feature b/features/post.feature index e1993e1f1f..171508d6ae 100644 --- a/features/post.feature +++ b/features/post.feature @@ -133,6 +133,18 @@ Feature: Manage WordPress posts """ And STDERR should be empty + Scenario: Generating posts by a specific author + + When I run `wp user create dummyuser dummy@example.com --porcelain` + Then save STDOUT as {AUTHOR_ID} + + When I run `wp post generate --post_author={AUTHOR_ID} --post_type=post --count=16` + And I run `wp post list --post_type=post --author={AUTHOR_ID} --format=count` + Then STDOUT should contain: + """ + 16 + """ + Scenario: Generating pages When I run `wp post generate --post_type=page --max_depth=10` And I run `wp post list --post_type=page --field=post_parent` diff --git a/php/commands/post.php b/php/commands/post.php index 05a2184dfb..a7c81ec41f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -305,10 +305,8 @@ public function generate( $args, $assoc_args ) { } if ( $post_author ) { - $post_author = get_user_by( 'login', $post_author ); - - if ( $post_author ) - $post_author = $post_author->ID; + $user_fetcher = new \WP_CLI\Fetchers\User; + $post_author = $user_fetcher->get_check( $post_author )->ID; } if ( isset( $assoc_args['post_content'] ) ) { From 7e2a397069231ea1335c76ada7e896e6cd85e3de Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 10:37:19 -0700 Subject: [PATCH 2926/4858] Correct config spec for `--user=<user>` Works with email addresses since 1b04e06fca552b7f400cec7a361da79f0805e2dc --- php/config-spec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index e4bfa1f5da..519a6880c2 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -23,8 +23,8 @@ ), 'user' => array( - 'runtime' => '=<id|login>', - 'file' => '<id|login>', + 'runtime' => '=<id|login|email>', + 'file' => '<id|login|email>', 'desc' => 'Set the WordPress user', ), From 82a63c61f4b327a8b29a557fccb7001eb0ead7a9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 11:13:54 -0700 Subject: [PATCH 2927/4858] When a command is disabled, hide it from the usage docs Hiding disabled commands makes it more clear to the end user as to what's accessible on the system and what's not. --- features/config.feature | 31 +++++++++++++++++++--- php/WP_CLI/Dispatcher/CompositeCommand.php | 6 +++++ php/commands/help.php | 19 +++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/features/config.feature b/features/config.feature index b8711ae2da..e80d86d77c 100644 --- a/features/config.feature +++ b/features/config.feature @@ -94,14 +94,39 @@ Feature: Have a config file """ Scenario: Disabled commands - Given an empty directory + Given a WP install And a config.yml file: """ disabled_commands: - - core version + - eval-file + - core multisite-convert + """ + + When I run `WP_CLI_CONFIG_PATH=config.yml wp` + Then STDOUT should not contain: + """ + eval-file + """ + + When I try `WP_CLI_CONFIG_PATH=config.yml wp help eval-file` + Then STDERR should be: + """ + Error: The 'eval-file' command has been disabled from the config file. + """ + + When I run `WP_CLI_CONFIG_PATH=config.yml wp core` + Then STDOUT should not contain: + """ + or: wp core multisite-convert + """ + + When I run `WP_CLI_CONFIG_PATH=config.yml wp help core` + Then STDOUT should not contain: + """ + multisite-convert """ - When I try `WP_CLI_CONFIG_PATH=config.yml wp core version` + When I try `WP_CLI_CONFIG_PATH=config.yml wp core multisite-convert` Then STDERR should contain: """ command has been disabled diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 30e6e00387..dba8053a8c 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -139,9 +139,15 @@ public function show_usage() { $i = 0; + $disabled_commands = \WP_CLI::get_runner()->config['disabled_commands']; foreach ( $methods as $name => $subcommand ) { $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; + $path = implode( ' ', array_slice( get_path( $subcommand ), 1 ) ); + if ( in_array( $path, $disabled_commands ) ) { + continue; + } + \WP_CLI::line( $subcommand->get_usage( $prefix ) ); } diff --git a/php/commands/help.php b/php/commands/help.php index 33d1d9e46a..0a74f160a2 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -22,6 +22,15 @@ function __invoke( $args, $assoc_args ) { $command = self::find_subcommand( $args ); if ( $command ) { + + $full_name = implode( ' ', array_slice( WP_CLI\Dispatcher\get_path( $command ), 1 ) ); + if ( in_array( $full_name , self::get_disabled_commands() ) ) { + WP_CLI::error( sprintf( + "The '%s' command has been disabled from the config file.", + $full_name + ) ); + } + self::show_help( $command ); exit; } @@ -117,6 +126,12 @@ private static function get_initial_markdown( $command ) { private static function render_subcommands( $command ) { $subcommands = array(); foreach ( $command->get_subcommands() as $subcommand ) { + + $path = implode( ' ', array_slice( WP_CLI\Dispatcher\get_path( $subcommand ), 1 ) ); + if ( in_array( $path , self::get_disabled_commands() ) ) { + continue; + } + $subcommands[ $subcommand->get_name() ] = $subcommand->get_shortdesc(); } @@ -140,6 +155,10 @@ private static function get_max_len( $strings ) { return $max_len; } + + private static function get_disabled_commands() { + return WP_CLI::get_runner()->config['disabled_commands']; + } } WP_CLI::add_command( 'help', 'Help_Command' ); From 253cbc63f8450bd69a453a608fae1b684605e3c4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 6 May 2014 11:25:50 -0700 Subject: [PATCH 2928/4858] Better abstraction for checking whether a command is disabled --- features/config.feature | 6 ++++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 4 +--- php/WP_CLI/Runner.php | 14 +++++++++++--- php/commands/help.php | 12 ++++-------- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/features/config.feature b/features/config.feature index e80d86d77c..3ed1e17aa1 100644 --- a/features/config.feature +++ b/features/config.feature @@ -132,6 +132,12 @@ Feature: Have a config file command has been disabled """ + When I try `WP_CLI_CONFIG_PATH=config.yml wp help core multisite-convert` + Then STDERR should contain: + """ + Error: The 'core multisite-convert' command has been disabled from the config file. + """ + Scenario: 'core config' parameters Given an empty directory And WP files diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index dba8053a8c..77cad3905a 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -139,12 +139,10 @@ public function show_usage() { $i = 0; - $disabled_commands = \WP_CLI::get_runner()->config['disabled_commands']; foreach ( $methods as $name => $subcommand ) { $prefix = ( 0 == $i++ ) ? 'usage: ' : ' or: '; - $path = implode( ' ', array_slice( get_path( $subcommand ), 1 ) ); - if ( in_array( $path, $disabled_commands ) ) { + if ( \WP_CLI::get_runner()->is_command_disabled( $subcommand ) ) { continue; } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 76419a541d..e7e48a97e7 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -251,8 +251,6 @@ public function find_command_to_run( $args ) { $cmd_path = array(); - $disabled_commands = $this->config['disabled_commands']; - while ( !empty( $args ) && $command->can_have_subcommands() ) { $cmd_path[] = $args[0]; $full_name = implode( ' ', $cmd_path ); @@ -266,7 +264,7 @@ public function find_command_to_run( $args ) { ); } - if ( in_array( $full_name, $disabled_commands ) ) { + if ( $this->is_command_disabled( $subcommand ) ) { return sprintf( "The '%s' command has been disabled from the config file.", $full_name @@ -313,6 +311,16 @@ private function _run_command() { $this->run_command( $this->arguments, $this->assoc_args ); } + /** + * Check whether a given command is disabled by the config + * + * @return bool + */ + public function is_command_disabled( $command ) { + $path = implode( ' ', array_slice( \WP_CLI\Dispatcher\get_path( $command ), 1 ) ); + return in_array( $path, $this->config['disabled_commands'] ); + } + /** * Returns wp-config.php code, skipping the loading of wp-settings.php * diff --git a/php/commands/help.php b/php/commands/help.php index 0a74f160a2..f8c7d9d9ff 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -23,11 +23,11 @@ function __invoke( $args, $assoc_args ) { if ( $command ) { - $full_name = implode( ' ', array_slice( WP_CLI\Dispatcher\get_path( $command ), 1 ) ); - if ( in_array( $full_name , self::get_disabled_commands() ) ) { + if ( WP_CLI::get_runner()->is_command_disabled( $command ) ) { + $path = implode( ' ', array_slice( \WP_CLI\Dispatcher\get_path( $command ), 1 ) ); WP_CLI::error( sprintf( "The '%s' command has been disabled from the config file.", - $full_name + $path ) ); } @@ -127,8 +127,7 @@ private static function render_subcommands( $command ) { $subcommands = array(); foreach ( $command->get_subcommands() as $subcommand ) { - $path = implode( ' ', array_slice( WP_CLI\Dispatcher\get_path( $subcommand ), 1 ) ); - if ( in_array( $path , self::get_disabled_commands() ) ) { + if ( WP_CLI::get_runner()->is_command_disabled( $subcommand ) ) { continue; } @@ -156,9 +155,6 @@ private static function get_max_len( $strings ) { return $max_len; } - private static function get_disabled_commands() { - return WP_CLI::get_runner()->config['disabled_commands']; - } } WP_CLI::add_command( 'help', 'Help_Command' ); From b916290d2d2bc3e869f97258caa37fe62748ac77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Fri, 9 May 2014 13:47:11 +0200 Subject: [PATCH 2929/4858] bash solution for setting array value --- utils/wp-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index bc109024a9..ac7e99250a 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -10,7 +10,7 @@ _wp_complete() { then COMPREPLY=( $(compgen -f -- $cur) ) else - COMPREPLY=$opts + COMPREPLY=( ${opts[*]} ) fi } complete -o nospace -F _wp_complete wp From 37e21459696bd569bc3bc46461a9ec8a3522ad09 Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Sun, 11 May 2014 16:16:01 -0400 Subject: [PATCH 2930/4858] Make sure widget at index=0 is removed from sidebar when deactivated Without this change, deactivating a widget at the beginning of a widget area will appear twice, once in the original sidebar and again in the Inactive Widgets sidebar. --- php/commands/widget.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index 5a5ec7a056..f0b01d5475 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -406,9 +406,9 @@ private function update_widget_options( $name, $value ) { * Reposition a widget within a sidebar * * @param string $widget_id - * @param string $current_sidebar_id + * @param string|null $current_sidebar_id * @param string $new_sidebar_id - * @param int $current_index + * @param int|null $current_index * @param int $new_index */ private function move_sidebar_widget( $widget_id, $current_sidebar_id, $new_sidebar_id, $current_index, $new_index ) { @@ -416,10 +416,10 @@ private function move_sidebar_widget( $widget_id, $current_sidebar_id, $new_side $all_widgets = $this->wp_get_sidebars_widgets(); $needs_placement = true; // Existing widget - if ( $current_sidebar_id && $current_index ) { + if ( $current_sidebar_id && ! is_null( $current_index ) ) { $widgets = $all_widgets[ $current_sidebar_id ]; - if ( $current_sidebar_id != $new_sidebar_id ) { + if ( $current_sidebar_id !== $new_sidebar_id ) { unset( $widgets[ $current_index ] ); From a44af937bb8104bffcff8f9efe6e2fa9b96e42df Mon Sep 17 00:00:00 2001 From: Weston Ruter <weston@x-team.com> Date: Sun, 11 May 2014 16:36:18 -0400 Subject: [PATCH 2931/4858] Update move_sidebar_widget DocBlock Indicate that it also moves to another sidebar --- php/commands/widget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index f0b01d5475..6687265f24 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -403,7 +403,7 @@ private function update_widget_options( $name, $value ) { } /** - * Reposition a widget within a sidebar + * Reposition a widget within a sidebar or move to another sidebar. * * @param string $widget_id * @param string|null $current_sidebar_id From 103bf8891293062a4527833bf066aa7e244781b2 Mon Sep 17 00:00:00 2001 From: Matthew Boynes <mboynes@alleyinteractive.com> Date: Tue, 13 May 2014 13:12:17 -0400 Subject: [PATCH 2932/4858] Fixing typo in menu bulk deleting --- php/commands/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 55191c8db4..adc6ab2f06 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -74,7 +74,7 @@ public function delete( $args, $_ ) { foreach( $args as $arg ) { - $ret = wp_delete_nav_menu( $args[0] ); + $ret = wp_delete_nav_menu( $arg ); if ( ! $ret || is_wp_error( $ret ) ) { From a9337705744859ad388512c8a716ea77b798a0d6 Mon Sep 17 00:00:00 2001 From: Matthew Boynes <mboynes@alleyinteractive.com> Date: Tue, 13 May 2014 14:01:01 -0400 Subject: [PATCH 2933/4858] Add tests for deleting multiple menu items --- features/menu.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index 75753186c6..68a4126631 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -86,3 +86,10 @@ Feature: Manage WordPress menus """ 2 """ + + When I run `wp menu item delete {POST_ITEM_ID} {TERM_ITEM_ID}` + And I run `wp menu item list sidebar-menu --format=count` + Then STDOUT should be: + """ + 0 + """ From c582fa3bf2d62e18de12d124e561a3da80ef9bdf Mon Sep 17 00:00:00 2001 From: Matt Boynes <mboynes@alleyinteractive.com> Date: Tue, 13 May 2014 14:18:38 -0400 Subject: [PATCH 2934/4858] Adding tests for deleting multiple menus --- features/menu.feature | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index 68a4126631..b350f094dc 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -18,6 +18,21 @@ Feature: Manage WordPress menus 0 """ + When I run `wp menu create "First Menu"` + And I run `wp menu create "Second Menu"` + And I run `wp menu list --fields=name,slug` + Then STDOUT should be a table containing rows: + | name | slug | + | First Menu | first-menu | + | Second Menu | second-menu | + + When I run `wp menu delete "First Menu" "Second Menu"` + And I run `wp menu list --format=count` + Then STDOUT should be: + """ + 0 + """ + Scenario: Assign / remove location from a menu When I run `wp theme install p2 --activate` From b8bdfe135fec022ae25c74092d7e461c9a6fb7d8 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Wed, 14 May 2014 10:32:37 -0400 Subject: [PATCH 2935/4858] Use foreach loop rather than array_map() to invoke do_hook() callbacks array_map( 'call_user_func', $hooks ) causes segmentation faults on PHP 5.5.12. --- php/class-wp-cli.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e6dbe54f68..d2e34b754d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -151,7 +151,9 @@ static function do_hook( $when ) { if ( !isset( self::$hooks[ $when ] ) ) return; - array_map( 'call_user_func', self::$hooks[ $when ] ); + foreach ( self::$hooks[ $when ] as $callback ) { + call_user_func( $callback ); + } } /** From c9e15fe62dae5f030f89f7cf355d96a55f56594e Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Wed, 14 May 2014 10:59:22 -0400 Subject: [PATCH 2936/4858] Add PHP 5.5 to travis-ci test matrix. See #1208 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 85086d37a8..2f16bc2ba5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ php: - 5.3 # WP-CLI currently fails on PHP 5.5.11, which Travis is using - 5.4 + - 5.5 env: global: From a97e72c0a9deaa8d3e02d9d1fecebaaa2b573e3d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 May 2014 15:28:52 -0700 Subject: [PATCH 2937/4858] Update matrix to properly test PHP 5.5, but only run three tests instead of five Fixes #1178 --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f16bc2ba5..3e6f78d2a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,6 @@ language: php php: - 5.3 - # WP-CLI currently fails on PHP 5.5.11, which Travis is using - - 5.4 - 5.5 env: @@ -39,7 +37,7 @@ env: matrix: exclude: - - php: 5.4 + - php: 5.5 env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master before_script: ./ci/prepare.sh From 8e90243ce179a589ca7f505f21b6c21e5353d831 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 15 May 2014 09:21:02 -0700 Subject: [PATCH 2938/4858] Update current version [ci-skip] --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index f9615aded1..485cececd2 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.15.0' ); +define( 'WP_CLI_VERSION', '0.15.1' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From e1e241721aa2ac9a8cea1bda87bde48530590480 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 15 May 2014 09:23:04 -0700 Subject: [PATCH 2939/4858] Add example for deleting all spam comments See #1209 [ci-skip] --- php/commands/comment.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/comment.php b/php/commands/comment.php index 8c19ed0a73..6a014cefd6 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -3,6 +3,11 @@ /** * Manage comments. * + * ## EXAMPLES + * + * # delete all spam comments. + * wp comment delete $(wp comment list --status=spam --format=ids) + * * @package wp-cli */ class Comment_Command extends \WP_CLI\CommandWithDBObject { From 48958885f579ec5f2bb9e8858ba6392769c91ba4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 18 May 2014 09:56:50 -0700 Subject: [PATCH 2940/4858] Add `--format=ids` support to `wp widget list` --- features/widget.feature | 6 ++++++ php/commands/widget.php | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/features/widget.feature b/features/widget.feature index b5c7317613..610d963ea0 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -68,6 +68,12 @@ Feature: Manage widgets in WordPress sidebar | calendar | calendar-1 | 2 | | categories | categories-2 | 3 | + When I run `wp widget list sidebar-1 --format=ids` + Then STDOUT should be: + """ + search-2 calendar-1 categories-2 + """ + When I run `wp widget update calendar-1 --title="Calendar"` Then STDOUT should not be empty diff --git a/php/commands/widget.php b/php/commands/widget.php index 6687265f24..32924b557b 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -37,7 +37,7 @@ class Widget_Command extends WP_CLI_Command { * : Limit the output to specific object fields. Defaults to name, id, description * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, ids. Default: table * * ## EXAMPLES * @@ -59,6 +59,10 @@ public function list_( $args, $assoc_args ) { } } + if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) { + $output_widgets = wp_list_pluck( $output_widgets, 'id' ); + } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); $formatter->display_items( $output_widgets ); From 4f5e0271a8b42ed04bb3a38fa73846b922dda554 Mon Sep 17 00:00:00 2001 From: joshlevinson <joshalevinson@gmail.com> Date: Mon, 19 May 2014 14:54:30 -0400 Subject: [PATCH 2941/4858] Create a valid local file location vs a URL I got this fatal error when trying to utilize a cached "wp core download": PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Cannot create a phar archive from a URL like "C://Users/xxx/.wp-cli/cache/core/en_US-3.9.1.tar.gz". Phar objects can only be created from local files' in C:\Users\xxx\wp-cli\php\commands\core.php:93 I'm not sure if my pull is the best solution, but the comments seem to suggest that $home is only manually constructed on Windows, so removing the middle slash may work for everyone. It did for me. After making this change and running the command again, all was well. I'm using PHP 5.5.9.0 on Windows 8.1. --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d2e34b754d..47bcfc6e9b 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -70,7 +70,7 @@ public static function get_cache() { $home = getenv( 'HOME' ); if ( !$home ) { // sometime in windows $HOME is not defined - $home = getenv( 'HOMEDRIVE' ) . '/' . getenv( 'HOMEPATH' ); + $home = getenv( 'HOMEDRIVE' ) . getenv( 'HOMEPATH' ); } $dir = getenv( 'WP_CLI_CACHE_DIR' ) ? : "$home/.wp-cli/cache"; From 262f19117c7ac7b6711b55519e14d1e636da1142 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 May 2014 16:52:16 -0700 Subject: [PATCH 2942/4858] Clarify `wp user list --<field>=<value>` See https://github.com/wp-cli/wp-cli/issues/1213#issuecomment-43615946 [ci-skip] --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 81bca8f40f..7e3ca9cd5d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -30,7 +30,7 @@ public function __construct() { * : Only display users with a certain role. * * [--<field>=<value>] - * : Filter by one or more fields. For accepted fields, see get_users(). + * : Control output by one or more arguments of get_users(). * * [--field=<field>] * : Prints the value of a single field for each user. From 241e57b2e0a65dad4992d8ceea2fced4a87c225a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 13:08:14 -0700 Subject: [PATCH 2943/4858] Throw a warning when rewrite rules end up empty after flushing This has tripped me up more than once, and I'm sure it trips up others. --- features/rewrite.feature | 18 ++++++++++++++++++ php/commands/rewrite.php | 3 +++ 2 files changed, 21 insertions(+) diff --git a/features/rewrite.feature b/features/rewrite.feature index f78c8504ef..6ab22a61ed 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -34,6 +34,24 @@ Feature: Manage WordPress rewrites | match | query | source | | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | + Scenario: Missing permalink_structure + Given a WP install + + When I run `wp option delete permalink_structure` + And I try `wp option get permalink_structure` + Then STDOUT should be empty + + When I try `wp rewrite flush` + Then STDERR should contain: + """ + Warning: Rewrite rules are empty, possibly because of a missing permalink_structure option. + """ + And STDOUT should be empty + + When I run `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/` + Then I run `wp rewrite flush` + Then STDOUT should be empty + Scenario: Generate .htaccess on hard flush Given a WP install And a wp-cli.yml file: diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 8b380afbd6..ccaffbc2ba 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -32,6 +32,9 @@ public function flush( $args, $assoc_args ) { WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); } flush_rewrite_rules( isset( $assoc_args['hard'] ) ); + if ( ! get_option( 'rewrite_rules' ) ) { + WP_CLI::warning( "Rewrite rules are empty, possibly because of a missing permalink_structure option. Use 'wp rewrite list' to verify, or 'wp rewrite structure' to update permalink_structure." ); + } } /** From d36519aee0531f820afd6fa0ffa68977785288ac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 13:26:48 -0700 Subject: [PATCH 2944/4858] Properly catch exporter exceptions, and throw an error if we run into one --- features/export.feature | 12 ++++++++++++ php/commands/export.php | 22 +++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/features/export.feature b/features/export.feature index f0bcfa85c0..593ad65449 100644 --- a/features/export.feature +++ b/features/export.feature @@ -8,3 +8,15 @@ Feature: Export content. """ All done with export """ + + Scenario: Term with a non-existent parent + Given a WP install + + When I run `wp term create category Apple --parent=99 --porcelain` + Then STDOUT should be a number + + When I try `wp export` + Then STDERR should be: + """ + Error: Term is missing a parent. + """ diff --git a/php/commands/export.php b/php/commands/export.php index 31d9d84e22..5af1331741 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -78,15 +78,19 @@ public function __invoke( $_, $assoc_args ) { WP_CLI::log( sprintf( "Writing to file %s", $file_path ) ); } ); - wp_export( array( - 'filters' => $this->export_args, - 'writer' => 'WP_Export_Split_Files_Writer', - 'writer_args' => array( - 'max_file_size' => $this->max_file_size * MB_IN_BYTES, - 'destination_directory' => $this->wxr_path, - 'filename_template' => self::get_filename_template() - ) - ) ); + try { + wp_export( array( + 'filters' => $this->export_args, + 'writer' => 'WP_Export_Split_Files_Writer', + 'writer_args' => array( + 'max_file_size' => $this->max_file_size * MB_IN_BYTES, + 'destination_directory' => $this->wxr_path, + 'filename_template' => self::get_filename_template() + ) + ) ); + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } WP_CLI::success( 'All done with export.' ); } From e8fb64d1996e6181f210ed202c2b93f6e90725c8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 13:33:19 -0700 Subject: [PATCH 2945/4858] Coding standards --- php/commands/export.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 5af1331741..9984d5fc07 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -97,7 +97,9 @@ public function __invoke( $_, $assoc_args ) { private static function get_filename_template() { $sitename = sanitize_key( get_bloginfo( 'name' ) ); - if ( ! empty($sitename) ) $sitename .= '.'; + if ( ! empty( $sitename ) ) { + $sitename .= '.'; + } return $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.%d.xml'; } From 9a70cc28c4d64225d615b31d453b88aa0a87aa9a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 13:36:11 -0700 Subject: [PATCH 2946/4858] Correct typo --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 9984d5fc07..7584ab40d5 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -181,7 +181,7 @@ private function check_post_type( $post_type ) { $post_types = get_post_types(); if ( !in_array( $post_type, $post_types ) ) { - WP_CLI::warning( sprintf( 'The post type %s does not exists. Choose "all" or any of these existing post types instead: %s', $post_type, implode( ", ", $post_types ) ) ); + WP_CLI::warning( sprintf( 'The post type %s does not exist. Choose "all" or any of these existing post types instead: %s', $post_type, implode( ", ", $post_types ) ) ); return false; } $this->export_args['post_type'] = $post_type; From 79fc4df82ced8ba3bb26d9a59a5168e0c753b941 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 13:41:06 -0700 Subject: [PATCH 2947/4858] Add tests for argument validator --- features/export.feature | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/features/export.feature b/features/export.feature index 593ad65449..5d3c55edaf 100644 --- a/features/export.feature +++ b/features/export.feature @@ -20,3 +20,30 @@ Feature: Export content. """ Error: Term is missing a parent. """ + + Scenario: Export argument validator + Given a WP install + + When I try `wp export --post_type=wp-cli-party` + Then STDERR should contain: + """ + Warning: The post type wp-cli-party does not exist. + """ + + When I try `wp export --author=invalid-author` + Then STDERR should contain: + """ + Warning: Could not find a matching author for invalid-author + """ + + When I try `wp export --start_date=invalid-date` + Then STDERR should contain: + """ + Warning: The start_date invalid-date is invalid + """ + + When I try `wp export --end_date=invalid-date` + Then STDERR should contain: + """ + Warning: The end_date invalid-date is invalid + """ From 9a956cde79ae98a3687c6ad7f7bdebe4f41245bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 14:31:06 -0700 Subject: [PATCH 2948/4858] Clarify argument --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 7584ab40d5..bc6fa3d196 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -32,7 +32,7 @@ class Export_Command extends WP_CLI_Command { * : Export only posts older than this date, in format YYYY-MM-DD. * * [--post_type=<post-type>] - * : Export only posts with this post_type. + * : Export only posts with this post_type. Defaults to all. * * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. From 8d936b609f54d60647e867017e3bea2d41d57915 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 14:46:07 -0700 Subject: [PATCH 2949/4858] Update Behat `Given` with support for specifying installed / active plugins --- features/steps/given.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/steps/given.php b/features/steps/given.php index 21117c55b2..ea581d1596 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -61,6 +61,13 @@ function ( $world ) { } ); +$steps->Given( '/^these installed and active plugins:(.+)$/', + function( $world, $plugins ) { + $plugins = implode( ' ', array_map( 'trim', explode( ',', $plugins ) ) ); + $world->proc( "wp plugin install $plugins --activate" )->run_check(); + } +); + $steps->Given( '/^a custom wp-content directory$/', function ( $world ) { $wp_config_path = $world->variables['RUN_DIR'] . "/wp-config.php"; From 336eef9a0b14a974e65b49bcc375ffc8303b145d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 14:54:11 -0700 Subject: [PATCH 2950/4858] Clarify these arguments --- php/commands/export.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index bc6fa3d196..987dcdbc91 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -26,10 +26,10 @@ class Export_Command extends WP_CLI_Command { * ## FILTERS * * [--start_date=<date>] - * : Export only posts newer than this date, in format YYYY-MM-DD. + * : Export only posts published after this date, in format YYYY-MM-DD. * * [--end_date=<date>] - * : Export only posts older than this date, in format YYYY-MM-DD. + * : Export only posts published before this date, in format YYYY-MM-DD. * * [--post_type=<post-type>] * : Export only posts with this post_type. Defaults to all. From fc145ec8b1e6f055b8fa090b6564612a700b42c8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 May 2014 14:54:29 -0700 Subject: [PATCH 2951/4858] Add some tests for exporting with filters --- features/export.feature | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/features/export.feature b/features/export.feature index 5d3c55edaf..c202dd7565 100644 --- a/features/export.feature +++ b/features/export.feature @@ -47,3 +47,71 @@ Feature: Export content. """ Warning: The end_date invalid-date is invalid """ + + Scenario: Export with post_type and post_status argument + Given a WP install + And these installed and active plugins: wordpress-importer + + When I run `wp site empty --yes` + And I run `wp post generate --post_type=page --post_status=draft --count=10` + And I run `wp post list --post_type=page --post_status=draft --format=count` + Then STDOUT should be: + """ + 10 + """ + + When I run `wp export --post_type=page --post_status=draft` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page --post_status=draft --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page --post_status=draft --format=count` + Then STDOUT should be: + """ + 10 + """ + + Scenario: Export posts within a given date range + Given a WP install + And these installed and active plugins: wordpress-importer + + When I run `wp site empty --yes` + And I run `wp post generate --post_type=post --post_date=2013-08-01 --count=10` + And I run `wp post generate --post_type=post --post_date=2013-08-02 --count=10` + And I run `wp post generate --post_type=post --post_date=2013-08-03 --count=10` + And I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 30 + """ + + When I run `wp export --post_type=post --start_date=2013-08-02 --end_date=2013-08-02` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 10 + """ From 44e4246ccf41097d3142072181bd8bdffa9c3c72 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 22 May 2014 05:50:07 -0700 Subject: [PATCH 2952/4858] This syntax is more consistent with our existing configuration --- features/export.feature | 10 ++++++++-- features/steps/given.php | 6 +++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/features/export.feature b/features/export.feature index c202dd7565..7ff5f118b5 100644 --- a/features/export.feature +++ b/features/export.feature @@ -50,7 +50,10 @@ Feature: Export content. Scenario: Export with post_type and post_status argument Given a WP install - And these installed and active plugins: wordpress-importer + And these installed and active plugins: + """ + wordpress-importer + """ When I run `wp site empty --yes` And I run `wp post generate --post_type=page --post_status=draft --count=10` @@ -83,7 +86,10 @@ Feature: Export content. Scenario: Export posts within a given date range Given a WP install - And these installed and active plugins: wordpress-importer + And these installed and active plugins: + """ + wordpress-importer + """ When I run `wp site empty --yes` And I run `wp post generate --post_type=post --post_date=2013-08-01 --count=10` diff --git a/features/steps/given.php b/features/steps/given.php index ea581d1596..8fa71cf42d 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -61,9 +61,9 @@ function ( $world ) { } ); -$steps->Given( '/^these installed and active plugins:(.+)$/', - function( $world, $plugins ) { - $plugins = implode( ' ', array_map( 'trim', explode( ',', $plugins ) ) ); +$steps->Given( '/^these installed and active plugins:$/', + function( $world, $stream ) { + $plugins = implode( ' ', array_map( 'trim', explode( PHP_EOL, (string)$stream ) ) ); $world->proc( "wp plugin install $plugins --activate" )->run_check(); } ); From 295c9938934104d11e5dd22abf3e97e99ae20f3e Mon Sep 17 00:00:00 2001 From: Leonardo Santagada <santagada@gmail.com> Date: Sun, 8 Jun 2014 21:38:23 -0300 Subject: [PATCH 2953/4858] change data directly in mysql for some tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit search-replace on tables that don’t contain serialised data can be changed directly in mysql --- php/commands/search-replace.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e6a8739dfd..384162839f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -78,7 +78,10 @@ public function __invoke( $args, $assoc_args ) { if ( in_array( $col, $skip_columns ) ) continue; - $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + if ( substr( $table, -9 ) == '_comments' || substr( $table, -6 ) == '_posts' ) { + $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); + } else + $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); $report[] = array( $table, $col, $count ); @@ -106,6 +109,15 @@ private static function get_table_list( $args, $network ) { return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } + private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { + global $wpdb; + + if ( $dry_run ) + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT($col) FROM $table WHERE $col LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); + else + return $wpdb->query( $wpdb->prepare( "UPDATE $table SET $col = REPLACE($col, %s, %s);", $old, $new ) ); + } + private static function handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { global $wpdb; From ce49db72d7f62d864d23e389b93e3e6008a2e009 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 15 Jun 2014 16:34:25 -0600 Subject: [PATCH 2954/4858] Clarify method See #1231 --- php/class-wp-cli.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 47bcfc6e9b..ea54f18c04 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -394,6 +394,12 @@ static function launch_self( $command, $args = array(), $assoc_args = array(), $ return self::launch( $full_command, $exit_on_error ); } + /** + * Get the path to the PHP binary used when executing WP-CLI. + * Environment values permit specific binaries to be indicated. + * + * @return string + */ private static function get_php_binary() { if ( defined( 'PHP_BINARY' ) ) return PHP_BINARY; From 79190a0ac8aed2a391081191d22dcdfe79176a3e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 18 Jun 2014 14:51:58 -0700 Subject: [PATCH 2955/4858] If the plugins directory doesn't exist, create it before installing --- features/plugin.feature | 15 +++++++++++++++ php/commands/plugin.php | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index a683999dd8..1794657fb6 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -155,3 +155,18 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | | akismet | active | + + Scenario: Install a plugin when directory doesn't yet exist + Given a WP install + + When I run `rm -rf wp-content/plugins` + And I run `if test -d wp-content/plugins; then echo "fail"; fi` + Then STDOUT should be empty + + When I run `wp plugin activate akismet hello` + Then STDOUT should not be empty + + When I run `wp plugin list --status=active --fields=name,status` + Then STDOUT should be a table containing rows: + | name | status | + | akismet | active | diff --git a/php/commands/plugin.php b/php/commands/plugin.php index bb4e5eaad3..873acffe8a 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -366,6 +366,11 @@ protected function filter_item_list( $items, $args ) { * wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef */ function install( $args, $assoc_args ) { + + if ( ! is_dir( WP_PLUGIN_DIR ) ) { + wp_mkdir_p( WP_PLUGIN_DIR ); + } + parent::install( $args, $assoc_args ); } From 888cbd8cf0f1bf6354cf5183e8cc0bcaaadfc401 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 19 Jun 2014 15:36:38 -0700 Subject: [PATCH 2956/4858] Fix copy pasta --- features/plugin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 1794657fb6..f77be4619c 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -163,7 +163,7 @@ Feature: Manage WordPress plugins And I run `if test -d wp-content/plugins; then echo "fail"; fi` Then STDOUT should be empty - When I run `wp plugin activate akismet hello` + When I run `wp plugin install akismet hello` Then STDOUT should not be empty When I run `wp plugin list --status=active --fields=name,status` From fb236b79a2773fa40d363022e55164148b9256d2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 19 Jun 2014 15:45:53 -0700 Subject: [PATCH 2957/4858] Support for automagically creating the theme directory too --- features/theme.feature | 15 +++++++++++++++ php/commands/theme.php | 6 ++++++ 2 files changed, 21 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 76ef76a820..27613ee399 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -93,6 +93,21 @@ Feature: Manage WordPress themes wp-content/themes/p2 """ + Scenario: Install a theme when the theme directory doesn't yet exist + Given a WP install + + When I run `rm -rf wp-content/themes` + And I run `if test -d wp-content/themes; then echo "fail"; fi` + Then STDOUT should be empty + + When I run `wp theme install p2 --activate` + Then STDOUT should not be empty + + When I run `wp theme list --fields=name,status` + Then STDOUT should be a table containing rows: + | name | status | + | p2 | active | + Scenario: Enabling and disabling a theme Given a WP multisite install diff --git a/php/commands/theme.php b/php/commands/theme.php index d3fa8fe6ec..2bc92e6876 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -371,6 +371,12 @@ protected function filter_item_list( $items, $args ) { * wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef */ function install( $args, $assoc_args ) { + + $theme_root = get_theme_root(); + if ( $theme_root && ! is_dir( $theme_root ) ) { + wp_mkdir_p( $theme_root ); + } + parent::install( $args, $assoc_args ); } From bb61b085e58fedfc47865b97adbc2b1cd5d439cd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 19 Jun 2014 16:25:48 -0700 Subject: [PATCH 2958/4858] Allow updating core directly from a ZIP file Previously, updating core from a ZIP file also required passing `--version` --- php/commands/core.php | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index ea3c8e3f4b..bf9a0a75a0 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -691,31 +691,44 @@ function update( $args, $assoc_args ) { $update = $from_api = null; $upgrader = 'Core_Upgrader'; - if ( empty( $assoc_args['version'] ) ) { + if ( ! empty( $args[0] ) ) { + + $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; + $version = ! empty( $assoc_args['version'] ) ? $assoc_args['version'] : null; + + $update = (object) array( + 'response' => 'upgrade', + 'current' => $version, + 'download' => $args[0], + 'packages' => (object) array ( + 'partial' => null, + 'new_bundled' => null, + 'no_content' => null, + 'full' => $args[0], + ), + 'version' => $version, + ); + + } else if ( empty( $assoc_args['version'] ) ) { + wp_version_check(); $from_api = get_site_transient( 'update_core' ); - if ( empty( $from_api->updates ) ) + if ( empty( $from_api->updates ) ) { $update = false; - else + } else { list( $update ) = $from_api->updates; + } } else if ( version_compare( $wp_version, $assoc_args['version'], '<' ) || isset( $assoc_args['force'] ) ) { - $new_package = $version = null; - - if ( empty( $args[0] ) ) { - $version = $assoc_args['version']; - $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : get_locale(); + $version = $assoc_args['version']; + $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : get_locale(); - $new_package = $this->get_download_url($version, $locale); + $new_package = $this->get_download_url($version, $locale); - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $locale ) ); - } else { - $new_package = $args[0]; - $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; - } + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $locale ) ); $update = (object) array( 'response' => 'upgrade', From 0f4c8d750631c91ef97c4820233d3dd4dd0b543d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 19 Jun 2014 16:40:16 -0700 Subject: [PATCH 2959/4858] Test coverage for permitting updates from file without specifying version --- features/core.feature | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/features/core.feature b/features/core.feature index f8b363b0d5..1d537e4341 100644 --- a/features/core.feature +++ b/features/core.feature @@ -232,6 +232,34 @@ Feature: Manage WordPress installation example.com """ + Scenario: Update from a ZIP file + Given a WP install + + When I run `wp core download --version=3.8 --force` + Then STDOUT should not be empty + + When I run `wp eval 'echo $GLOBALS["wp_version"];'` + Then STDOUT should be: + """ + 3.8 + """ + + When I run `wget http://wordpress.org/wordpress-3.9.zip --quiet` + Then STDOUT should be empty + + When I run `wp core update wordpress-3.9.zip` + Then STDOUT should be: + """ + Unpacking the update... + Success: WordPress updated successfully. + """ + + When I run `wp eval 'echo $GLOBALS["wp_version"];'` + Then STDOUT should be: + """ + 3.9 + """ + Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory From 2899f71ddecbf54e0f6af35b5755d7f28fc1c61b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 23 Jun 2014 19:08:42 -0700 Subject: [PATCH 2960/4858] Fix silly copy and paste error again. `hello` exists in WP.org as `hello-dolly` --- features/plugin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index f77be4619c..78026726ac 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -163,7 +163,7 @@ Feature: Manage WordPress plugins And I run `if test -d wp-content/plugins; then echo "fail"; fi` Then STDOUT should be empty - When I run `wp plugin install akismet hello` + When I run `wp plugin install akismet --activate` Then STDOUT should not be empty When I run `wp plugin list --status=active --fields=name,status` From b6d69f775a740f181b438ce4c48795ce7247e581 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 23 Jun 2014 19:39:32 -0700 Subject: [PATCH 2961/4858] Need to register the theme directory after it's been created --- php/commands/theme.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 2bc92e6876..35410a1757 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -375,6 +375,7 @@ function install( $args, $assoc_args ) { $theme_root = get_theme_root(); if ( $theme_root && ! is_dir( $theme_root ) ) { wp_mkdir_p( $theme_root ); + register_theme_directory( $theme_root ); } parent::install( $args, $assoc_args ); From b4b8a7301d7a5b52e2fd90a7d5cb4e907ab6c85f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 23 Jun 2014 20:05:59 -0700 Subject: [PATCH 2962/4858] List meta for an object, demo commit --- php/WP_CLI/CommandWithMeta.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index f09d9fbcd2..e543d73cce 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -11,6 +11,26 @@ abstract class CommandWithMeta extends \WP_CLI_Command { protected $meta_type; + /** + * List all metadata associated with an object. + * + * <id> + * : ID for the object. + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + + list( $object_id ) = $args; + + $values = get_metadata( $this->meta_type, $object_id ); + + $values = wp_cache_get( $object_id, 'post_meta' ); + + error_log( var_export( $values, true ) ); + + } + /** * Get meta field value. * From 43d24a813dac0d2c8cdc8c357039fb26ffbf71e2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 23 Jun 2014 21:07:15 -0700 Subject: [PATCH 2963/4858] Special treatment for JSON, and tests that fail because meta_value isn't unserialized --- features/user.feature | 25 ++++++++++++++++++ php/WP_CLI/CommandWithMeta.php | 47 ++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index a50e3bb3a6..9ce4273e58 100644 --- a/features/user.feature +++ b/features/user.feature @@ -253,3 +253,28 @@ Feature: Manage WordPress users """ Success: Removed 'edit_vip_product' cap for admin (1). """ + + @ticket + Scenario: List user meta + Given a WP install + + When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` + Then STDOUT should not be empty + + When I run `wp user-meta list 1 --format=json --keys=nickname,foo` + Then STDOUT should be JSON containing: + """ + { + "nickname": "admin", + "foo": ["1","2"] + } + """ + + When I run `wp user-meta list 1 --format=csv --keys=nickname,foo` + Then STDOUT should be CSV containing: + """ + | meta_key | meta_value | + | nickname | admin | + | foo | ["1","2"] | + """ + diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index e543d73cce..5be394d294 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -17,17 +17,60 @@ abstract class CommandWithMeta extends \WP_CLI_Command { * <id> * : ID for the object. * + * [--keys=<keys>] + * : Limit output to metadata of specific keys. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * * @subcommand list */ public function list_( $args, $assoc_args ) { list( $object_id ) = $args; + $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : array(); + $values = get_metadata( $this->meta_type, $object_id ); - $values = wp_cache_get( $object_id, 'post_meta' ); + foreach( $values as $meta_key => $meta_value ) { + + if ( ! empty( $keys ) && ! in_array( $meta_key, $keys ) ) { + unset( $values[ $meta_key ] ); + continue; + } + + if ( count( $values[ $meta_key ] ) == 1 ) { + $values[ $meta_key ] = $values[ $meta_key ][ 0 ]; + } + + } + + // Special treatment for JSON + if ( ! empty( $assoc_args['format'] ) && 'json' === $assoc_args['format'] ) { - error_log( var_export( $values, true ) ); + echo json_encode( $values ); + + } else { + + foreach( $values as $meta_key => $meta_value ) { + + $items = array(); + if ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv' ) ) ) { + $meta_value = json_encode( $meta_value ); + } + + $items[] = (object) array( + 'meta_key' => $meta_key, + 'meta_value' => $meta_value, + ); + + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'meta_key', 'meta_value' ), $this->meta_type ); + $formatter->display_items( $items ); + + } } From 64974979c0b71f18359415ca55ca3026cef468b1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 11:42:00 -0700 Subject: [PATCH 2964/4858] Throw warnings if the plugin is already active --- php/commands/plugin.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 873acffe8a..cffdf77fdf 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -142,6 +142,16 @@ function activate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { + + $status = $this->get_status( $plugin->file ); + if ( ! $network_wide && 'active' === $status ) { + WP_CLI::warning( "The '{$plugin->name}' plugin is already active." ); + continue; + } else if ( $network_wide && 'activate-network' === $status ) { + WP_CLI::warning( "The '{$plugin->name}' plugin is already network active." ); + continue; + } + activate_plugin( $plugin->file, '', $network_wide ); $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); From 516fddb801cc439a298f171b6f32546ef1a84b58 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 12:59:25 -0700 Subject: [PATCH 2965/4858] When a given theme is already active, provide a contextually appropriate message Also prevents triggering of `switch_theme()` if the theme is already activated. --- features/theme.feature | 18 ++++++++++++++++++ php/commands/theme.php | 9 +++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 27613ee399..6ad011a7e2 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -93,6 +93,24 @@ Feature: Manage WordPress themes wp-content/themes/p2 """ + Scenario: Activate an already active theme + Given a WP install + + When I run `wp theme install p2` + Then STDOUT should not be empty + + When I run `wp theme activate p2` + Then STDOUT should be: + """ + Success: Switched to 'P2' theme. + """ + + When I run `wp theme activate p2` + Then STDOUT should be: + """ + Success: The 'P2' theme is already active. + """ + Scenario: Install a theme when the theme directory doesn't yet exist Given a WP install diff --git a/php/commands/theme.php b/php/commands/theme.php index 35410a1757..3fd58af36c 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -121,10 +121,15 @@ protected function get_status( $theme ) { public function activate( $args = array() ) { $theme = $this->fetcher->get_check( $args[0] ); - switch_theme( $theme->get_template(), $theme->get_stylesheet() ); - $name = $theme->get('Name'); + if ( 'active' === $this->get_status( $theme ) ) { + WP_CLI::success( "The '$name' theme is already active." ); + exit; + } + + switch_theme( $theme->get_template(), $theme->get_stylesheet() ); + if ( $this->is_active_theme( $theme ) ) { WP_CLI::success( "Switched to '$name' theme." ); } else { From 56736ce61c5c435811a2c69ce7bc4a0cbadb6b76 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 13:09:34 -0700 Subject: [PATCH 2966/4858] Messaging more consistent with the rest of `wp plugin` --- php/commands/plugin.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index cffdf77fdf..0dff24ee76 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -145,10 +145,10 @@ function activate( $args, $assoc_args = array() ) { $status = $this->get_status( $plugin->file ); if ( ! $network_wide && 'active' === $status ) { - WP_CLI::warning( "The '{$plugin->name}' plugin is already active." ); + WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); continue; - } else if ( $network_wide && 'activate-network' === $status ) { - WP_CLI::warning( "The '{$plugin->name}' plugin is already network active." ); + } else if ( $network_wide && 'active-network' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); continue; } From ba8647f8ad75aa614176de35c4b665bec770b5af Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 13:09:55 -0700 Subject: [PATCH 2967/4858] Test cases for these warning messages --- features/plugin.feature | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 78026726ac..615de8666f 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -170,3 +170,36 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | | akismet | active | + + Scenario: Activate a plugin which is already active + Given a WP multisite install + + When I run `wp plugin activate akismet` + Then STDOUT should be: + """ + Success: Plugin 'akismet' activated. + """ + + When I try `wp plugin activate akismet` + Then STDERR should be: + """ + Warning: Plugin 'akismet' is already active. + """ + + When I run `wp plugin deactivate akismet` + Then STDOUT should be: + """ + Success: Plugin 'akismet' deactivated. + """ + + When I run `wp plugin activate akismet --network` + Then STDOUT should be: + """ + Success: Plugin 'akismet' network activated. + """ + + When I try `wp plugin activate akismet --network` + Then STDERR should be: + """ + Warning: Plugin 'akismet' is already network active. + """ From 2e52f1fdd4fcf4ac35ed621faf78dceeb1d2fe20 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 13:39:40 -0700 Subject: [PATCH 2968/4858] Network-only plugin check should only happen on multisite --- features/plugin.feature | 30 ++++++++++++++++++++++++++++-- php/commands/plugin.php | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 615de8666f..13ffd7b516 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -117,15 +117,41 @@ Feature: Manage WordPress plugins When I run `wp plugin update --all` Then STDOUT should not be empty - Scenario: Activate a network-only plugin + Scenario: Activate a network-only plugin on single site + Given a WP install + And a wp-content/plugins/network-only.php file: + """ + // Plugin Name: Example Plugin + // Network: true + """ + + When I run `wp plugin activate network-only` + Then STDOUT should be: + """ + Success: Plugin 'network-only' activated. + """ + + When I run `wp plugin status network-only` + Then STDOUT should contain: + """ + Status: Active + """ + + Scenario: Activate a network-only plugin on multisite Given a WP multisite install And a wp-content/plugins/network-only.php file: """ // Plugin Name: Example Plugin // Network: true """ + When I run `wp plugin activate network-only` - And I run `wp plugin status network-only` + Then STDOUT should be: + """ + Success: Plugin 'network-only' network activated. + """ + + When I run `wp plugin status network-only` Then STDOUT should contain: """ Status: Network Active diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 0dff24ee76..74af879cb6 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -530,7 +530,7 @@ private function check_active( $file, $network_wide ) { } private function active_output( $name, $file, $network_wide, $action ) { - $network_wide = $network_wide || is_network_only_plugin( $file ); + $network_wide = $network_wide || ( is_multisite() && is_network_only_plugin( $file ) ); $check = $this->check_active( $file, $network_wide ); From b0095bca565b144840e1835987dcc116dc799cee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 14:40:27 -0700 Subject: [PATCH 2969/4858] Move this to its appropriate place --- features/user-meta.feature | 24 ++++++++++++++++++++++++ features/user.feature | 25 ------------------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/features/user-meta.feature b/features/user-meta.feature index 7749419721..f8d23ba251 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -26,3 +26,27 @@ Feature: Manage user custom fields When I try `wp user-meta get 1 foo` Then the return code should be 1 + + @ticket + Scenario: List user meta + Given a WP install + + When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` + Then STDOUT should not be empty + + When I run `wp user-meta list 1 --format=json --keys=nickname,foo` + Then STDOUT should be JSON containing: + """ + { + "nickname": "admin", + "foo": ["1","2"] + } + """ + + When I run `wp user-meta list 1 --format=csv --keys=nickname,foo` + Then STDOUT should be CSV containing: + """ + | meta_key | meta_value | + | nickname | admin | + | foo | ["1","2"] | + """ diff --git a/features/user.feature b/features/user.feature index 9ce4273e58..a50e3bb3a6 100644 --- a/features/user.feature +++ b/features/user.feature @@ -253,28 +253,3 @@ Feature: Manage WordPress users """ Success: Removed 'edit_vip_product' cap for admin (1). """ - - @ticket - Scenario: List user meta - Given a WP install - - When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` - Then STDOUT should not be empty - - When I run `wp user-meta list 1 --format=json --keys=nickname,foo` - Then STDOUT should be JSON containing: - """ - { - "nickname": "admin", - "foo": ["1","2"] - } - """ - - When I run `wp user-meta list 1 --format=csv --keys=nickname,foo` - Then STDOUT should be CSV containing: - """ - | meta_key | meta_value | - | nickname | admin | - | foo | ["1","2"] | - """ - From 0e22a66c3539f5736ea562b2cc30c793de811f38 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 15:02:57 -0700 Subject: [PATCH 2970/4858] Because `get_metadata()` is lossy, roll our own SQL queries --- features/user-meta.feature | 25 ++++----- php/WP_CLI/CommandWithMeta.php | 92 ++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 47 deletions(-) diff --git a/features/user-meta.feature b/features/user-meta.feature index f8d23ba251..1882048d73 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -27,26 +27,23 @@ Feature: Manage user custom fields When I try `wp user-meta get 1 foo` Then the return code should be 1 - @ticket Scenario: List user meta Given a WP install - When I run `wp user-meta set 1 foo '[ "1", "2" ]' --format=json` + When I run `wp user meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty - When I run `wp user-meta list 1 --format=json --keys=nickname,foo` + When I run `wp user meta list 1 --format=json --keys=nickname,foo` Then STDOUT should be JSON containing: """ - { - "nickname": "admin", - "foo": ["1","2"] - } + [{"meta_key":"nickname","meta_value":"admin"},{"meta_key":"foo","meta_value":["1","2"]}] """ - When I run `wp user-meta list 1 --format=csv --keys=nickname,foo` - Then STDOUT should be CSV containing: - """ - | meta_key | meta_value | - | nickname | admin | - | foo | ["1","2"] | - """ + When I run `wp user meta set 1 foo bar` + Then STDOUT should not be empty + + When I run `wp user meta list 1 --keys=nickname,foo --fields=user_id,meta_key,meta_value` + Then STDOUT should be a table containing rows: + | user_id | meta_key | meta_value | + | 1 | nickname | admin | + | 1 | foo | bar | diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 5be394d294..684b2ff25d 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -20,6 +20,9 @@ abstract class CommandWithMeta extends \WP_CLI_Command { * [--keys=<keys>] * : Limit output to metadata of specific keys. * + * [--fields=<fields>] + * : Limit the output to specific row fields. Defaults to meta_key,meta_value. + * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * @@ -29,49 +32,27 @@ public function list_( $args, $assoc_args ) { list( $object_id ) = $args; - $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : array(); - - $values = get_metadata( $this->meta_type, $object_id ); + $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : false; - foreach( $values as $meta_key => $meta_value ) { + $values = $this->get_metadata( $object_id, $keys ); - if ( ! empty( $keys ) && ! in_array( $meta_key, $keys ) ) { - unset( $values[ $meta_key ] ); - continue; - } + foreach( $values as &$value ) { - if ( count( $values[ $meta_key ] ) == 1 ) { - $values[ $meta_key ] = $values[ $meta_key ][ 0 ]; + if ( ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv' ) ) ) && ( is_object( $value->meta_value ) || is_array( $value->meta_value ) ) ) { + $value->meta_value = json_encode( $value->meta_value ); } } - // Special treatment for JSON - if ( ! empty( $assoc_args['format'] ) && 'json' === $assoc_args['format'] ) { - - echo json_encode( $values ); - + if ( ! empty( $assoc_args['fields'] ) ) { + $fields = explode( ',', $assoc_args['fields'] ); } else { - - foreach( $values as $meta_key => $meta_value ) { - - $items = array(); - if ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv' ) ) ) { - $meta_value = json_encode( $meta_value ); - } - - $items[] = (object) array( - 'meta_key' => $meta_key, - 'meta_value' => $meta_value, - ); - - } - - $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'meta_key', 'meta_value' ), $this->meta_type ); - $formatter->display_items( $items ); - + $fields = array( 'meta_key', 'meta_value' ); } + $formatter = new \WP_CLI\Formatter( $assoc_args, $fields, $this->meta_type ); + $formatter->display_items( $values ); + } /** @@ -172,5 +153,50 @@ public function update( $args, $assoc_args ) { \WP_CLI::error( "Failed to update custom field." ); } } + + /** + * Get the fields for this object's meta + * + * @return array + */ + private function get_fields() { + + $fields = array(); + if ( 'user' === $this->meta_type ) { + $fields[] = 'umeta_id'; + } else { + $fields[] = 'meta_id'; + } + $fields[] = "{$this->meta_type}_id"; + $fields[] = 'meta_key'; + $fields[] = 'meta_value'; + + return $fields; + } + + /** + * Non-lossy getter for metadata. + * get_metadata loses track of the meta_id + * + * @param int $object_id + * @return array + */ + private function get_metadata( $object_id, $keys = false ) { + global $wpdb; + + $fields = implode( ', ', $this->get_fields() ); + $table = "{$this->meta_type}meta"; + $query = $wpdb->prepare( "SELECT {$fields} FROM {$wpdb->$table} WHERE {$this->meta_type}_id = %d", $object_id ); + if ( $keys ) { + $query .= " AND meta_key IN ( '" . implode( "','", $keys ) . "')"; + } + $results = $wpdb->get_results( $query ); + + $results = array_map( function( $row ) { + $row->meta_value = maybe_unserialize( $row->meta_value ); + return $row; + }, $results ); + return $results; + } } From cf2e14e6b4cc553f860541e8aeeb206041219135 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 15:21:29 -0700 Subject: [PATCH 2971/4858] As it turns out, `get_metadata()` isn't lossy - it just obscures `meta_id` --- features/user-meta.feature | 13 +++++------- php/WP_CLI/CommandWithMeta.php | 39 ++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/features/user-meta.feature b/features/user-meta.feature index 1882048d73..701af9ac51 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -33,17 +33,14 @@ Feature: Manage user custom fields When I run `wp user meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty - When I run `wp user meta list 1 --format=json --keys=nickname,foo` + When I run `wp user meta list 1 --format=json --keys=nickname,foo --fields=meta_key,meta_value` Then STDOUT should be JSON containing: """ [{"meta_key":"nickname","meta_value":"admin"},{"meta_key":"foo","meta_value":["1","2"]}] """ - When I run `wp user meta set 1 foo bar` - Then STDOUT should not be empty - - When I run `wp user meta list 1 --keys=nickname,foo --fields=user_id,meta_key,meta_value` + When I run `wp user meta list 1 --keys=nickname,foo` Then STDOUT should be a table containing rows: - | user_id | meta_key | meta_value | - | 1 | nickname | admin | - | 1 | foo | bar | + | user_id | meta_key | meta_value | + | 1 | nickname | admin | + | 1 | foo | ["1","2"] | diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 684b2ff25d..3bcdda4549 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -21,7 +21,7 @@ abstract class CommandWithMeta extends \WP_CLI_Command { * : Limit output to metadata of specific keys. * * [--fields=<fields>] - * : Limit the output to specific row fields. Defaults to meta_key,meta_value. + * : Limit the output to specific row fields. Defaults to id,meta_key,meta_value. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table @@ -32,14 +32,32 @@ public function list_( $args, $assoc_args ) { list( $object_id ) = $args; - $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : false; + $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : array(); - $values = $this->get_metadata( $object_id, $keys ); + $metadata = get_metadata( $this->meta_type, $object_id ); - foreach( $values as &$value ) { + $items = array(); + foreach( $metadata as $key => $values ) { + + // Skip if not requested + if ( ! empty( $keys ) && ! in_array( $key, $keys ) ) { + continue; + } + + foreach( $values as $item_value ) { + + $item_value = maybe_unserialize( $item_value ); + + if ( ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv' ) ) )&& ( is_object( $item_value ) || is_array( $item_value ) ) ) { + $item_value = json_encode( $item_value ); + } + + $items[] = (object) array( + "{$this->meta_type}_id" => $object_id, + 'meta_key' => $key, + 'meta_value' => $item_value, + ); - if ( ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv' ) ) ) && ( is_object( $value->meta_value ) || is_array( $value->meta_value ) ) ) { - $value->meta_value = json_encode( $value->meta_value ); } } @@ -47,11 +65,11 @@ public function list_( $args, $assoc_args ) { if ( ! empty( $assoc_args['fields'] ) ) { $fields = explode( ',', $assoc_args['fields'] ); } else { - $fields = array( 'meta_key', 'meta_value' ); + $fields = $this->get_fields(); } $formatter = new \WP_CLI\Formatter( $assoc_args, $fields, $this->meta_type ); - $formatter->display_items( $values ); + $formatter->display_items( $items ); } @@ -162,11 +180,6 @@ public function update( $args, $assoc_args ) { private function get_fields() { $fields = array(); - if ( 'user' === $this->meta_type ) { - $fields[] = 'umeta_id'; - } else { - $fields[] = 'meta_id'; - } $fields[] = "{$this->meta_type}_id"; $fields[] = 'meta_key'; $fields[] = 'meta_value'; From c8a08f550616ac3e9177b1fe688cfc8fe8a3026f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 15:22:51 -0700 Subject: [PATCH 2972/4858] This method isn't needed --- php/WP_CLI/CommandWithMeta.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 3bcdda4549..84d31a17e3 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -187,29 +187,5 @@ private function get_fields() { return $fields; } - /** - * Non-lossy getter for metadata. - * get_metadata loses track of the meta_id - * - * @param int $object_id - * @return array - */ - private function get_metadata( $object_id, $keys = false ) { - global $wpdb; - - $fields = implode( ', ', $this->get_fields() ); - $table = "{$this->meta_type}meta"; - $query = $wpdb->prepare( "SELECT {$fields} FROM {$wpdb->$table} WHERE {$this->meta_type}_id = %d", $object_id ); - if ( $keys ) { - $query .= " AND meta_key IN ( '" . implode( "','", $keys ) . "')"; - } - $results = $wpdb->get_results( $query ); - - $results = array_map( function( $row ) { - $row->meta_value = maybe_unserialize( $row->meta_value ); - return $row; - }, $results ); - return $results; - } } From a2c912ce0f350000651aa4b67c1f252ae01f65eb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 15:29:53 -0700 Subject: [PATCH 2973/4858] Clean this up --- php/WP_CLI/CommandWithMeta.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 84d31a17e3..8a1ffa5a02 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -178,13 +178,11 @@ public function update( $args, $assoc_args ) { * @return array */ private function get_fields() { - - $fields = array(); - $fields[] = "{$this->meta_type}_id"; - $fields[] = 'meta_key'; - $fields[] = 'meta_value'; - - return $fields; + return array( + "{$this->meta_type}_id", + 'meta_key', + 'meta_value', + ); } } From a7afbb4b5496b581da07d9f947722b51e97f5e3a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 15:39:43 -0700 Subject: [PATCH 2974/4858] Tests for post meta --- features/post-meta.feature | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/features/post-meta.feature b/features/post-meta.feature index b1daf1bbaf..19a92cb6f3 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -33,3 +33,20 @@ Feature: Manage post custom fields When I try `wp post-meta get 1 foo` Then the return code should be 1 + + Scenario: List post meta + Given a WP install + + When I run `wp post meta add 1 apple banana` + And I run `wp post meta add 1 apple banana` + Then STDOUT should not be empty + + When I run `wp post meta set 1 banana '["apple", "apple"]' --format=json` + Then STDOUT should not be empty + + When I run `wp post meta list 1` + Then STDOUT should be a table containing rows: + | post_id | meta_key | meta_value | + | 1 | apple | banana | + | 1 | apple | banana | + | 1 | banana | ["apple","apple"] | From 82d2b25dbaed0313279b4c217bbecc5e2d7fa5a2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 28 Jun 2014 16:13:24 -0700 Subject: [PATCH 2975/4858] Fix meta delete. It should support passing a value `delete_metadata()` supports receiving a specific value to only delete rows matching that value. --- features/user-meta.feature | 19 +++++++++++++++++++ php/WP_CLI/CommandWithMeta.php | 16 ++++++++++++++-- php/commands/user.php | 3 ++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/features/user-meta.feature b/features/user-meta.feature index 701af9ac51..a7adffae60 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -27,6 +27,25 @@ Feature: Manage user custom fields When I try `wp user-meta get 1 foo` Then the return code should be 1 + When I run `wp user meta add 1 foo bar` + And I run `wp user meta add 1 foo bar2` + And I run `wp user meta add 1 foo bar3` + Then STDOUT should not be empty + + When I run `wp user meta delete 1 foo bar2` + And I run `wp user meta list 1 --keys=foo --format=count` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp user meta delete 1 foo` + And I run `wp user meta list 1 --keys=foo --format=count` + Then STDOUT should be: + """ + 0 + """ + Scenario: List user meta Given a WP install diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 8a1ffa5a02..2f3d7b49cf 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -35,6 +35,9 @@ public function list_( $args, $assoc_args ) { $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : array(); $metadata = get_metadata( $this->meta_type, $object_id ); + if ( ! $metadata ) { + $metadata = array(); + } $items = array(); foreach( $metadata as $key => $values ) { @@ -92,12 +95,21 @@ public function get( $args, $assoc_args ) { /** * Delete a meta field. * - * @synopsis <id> <key> + * <id> + * : The ID of the object. + * + * <key> + * : The name of the meta field to create. + * + * [<value>] + * : The value to delete. If omitted, all rows with key will deleted. */ public function delete( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $success = \delete_metadata( $this->meta_type, $object_id, $meta_key ); + $meta_value = ! empty( $args[2] ) ? $args[2] : ''; + + $success = \delete_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { \WP_CLI::success( "Deleted custom field." ); diff --git a/php/commands/user.php b/php/commands/user.php index 7e3ca9cd5d..bdb7bc7c85 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -707,7 +707,8 @@ public function get( $args, $assoc_args ) { * <key> * : The metadata key. * - * @synopsis <user> <key> + * [<value>] + * : The value to delete. If omitted, all rows with key will deleted. */ public function delete( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); From 6d6a84095510dd4bf939209dedd50a29ef484ac9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 09:44:59 -0700 Subject: [PATCH 2976/4858] Handle shorter versions of item keys --- php/WP_CLI/Formatter.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 3b349f6de9..5a589a1789 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -37,6 +37,12 @@ public function display_items( $items ) { if ( $this->args['field'] ) { $this->show_single_field( $items, $this->args['field'] ); } else { + $item = isset( $items[0] ) ? $items[0] : array(); + if ( ! empty( $this->args['fields'] ) ) { + foreach( $this->args['fields'] as &$field ) { + $field = $this->find_item_key( $item, $field ); + } + } $this->format( $items ); } } From 3b78b8afaf02b3091530bea9c351331fefe3b705 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 10:34:19 -0700 Subject: [PATCH 2977/4858] Handle non-numerically indexed arrays too --- php/WP_CLI/Formatter.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 5a589a1789..13abf8ec0c 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -37,11 +37,12 @@ public function display_items( $items ) { if ( $this->args['field'] ) { $this->show_single_field( $items, $this->args['field'] ); } else { - $item = isset( $items[0] ) ? $items[0] : array(); - if ( ! empty( $this->args['fields'] ) ) { + $item = ! empty( $items ) ? array_shift( $items ) : array(); + if ( ! empty( $item ) && ! empty( $this->args['fields'] ) ) { foreach( $this->args['fields'] as &$field ) { $field = $this->find_item_key( $item, $field ); } + array_unshift( $items, $item ); } $this->format( $items ); } From 4e468e4261ee6e823a1ce3f2dc703e6c98991db6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 10:41:31 -0700 Subject: [PATCH 2978/4858] Tests for #803 --- features/post.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/post.feature b/features/post.feature index 171508d6ae..1ff2128fed 100644 --- a/features/post.feature +++ b/features/post.feature @@ -112,6 +112,12 @@ Feature: Manage WordPress posts | Publish post | publish-post | publish | | Draft post | | draft | + When I run `wp post list --post_type='post' --fields=title,name,status --format=csv` + Then STDOUT should be CSV containing: + | post_title | post_name | post_status | + | Publish post | publish-post | publish | + | Draft post | | draft | + When I run `wp post list --post__in={POST_ID} --format=count` Then STDOUT should be: """ From 1cc4e270bb764877f6395507a414271b684c4d0d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 11:07:53 -0700 Subject: [PATCH 2979/4858] Accommodate both types of items --- php/WP_CLI/Formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 13abf8ec0c..09cce4176b 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -129,7 +129,7 @@ private function show_single_field( $items, $field ) { private function find_item_key( $item, $field ) { foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { - if ( isset( $item->$maybe_key ) ) { + if ( ( is_object( $item ) && isset( $item->$maybe_key ) ) || ( is_array( $item ) && isset( $item[$maybe_key] ) ) ) { $key = $maybe_key; break; } From 9fbc4bce183f466f6447a8b127bfad202728fb77 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 11:24:46 -0700 Subject: [PATCH 2980/4858] Accommodate array iterators, which can be passed to `display_items()` --- php/WP_CLI/Formatter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 09cce4176b..5b81ec6fd4 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -37,8 +37,8 @@ public function display_items( $items ) { if ( $this->args['field'] ) { $this->show_single_field( $items, $this->args['field'] ); } else { - $item = ! empty( $items ) ? array_shift( $items ) : array(); - if ( ! empty( $item ) && ! empty( $this->args['fields'] ) ) { + $item = is_array( $items ) && ! empty( $items ) ? array_shift( $items ) : false; + if ( $item && ! empty( $this->args['fields'] ) ) { foreach( $this->args['fields'] as &$field ) { $field = $this->find_item_key( $item, $field ); } From 9bd7cce8407aecb94a12f6363e41d234b1d599ed Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 11:58:03 -0700 Subject: [PATCH 2981/4858] Only modify relevant output formats --- php/WP_CLI/Formatter.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 5b81ec6fd4..5f188a7476 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -37,12 +37,14 @@ public function display_items( $items ) { if ( $this->args['field'] ) { $this->show_single_field( $items, $this->args['field'] ); } else { - $item = is_array( $items ) && ! empty( $items ) ? array_shift( $items ) : false; - if ( $item && ! empty( $this->args['fields'] ) ) { - foreach( $this->args['fields'] as &$field ) { - $field = $this->find_item_key( $item, $field ); + if ( in_array( $this->args['format'], array( 'csv', 'json', 'table' ) ) ) { + $item = is_array( $items ) && ! empty( $items ) ? array_shift( $items ) : false; + if ( $item && ! empty( $this->args['fields'] ) ) { + foreach( $this->args['fields'] as &$field ) { + $field = $this->find_item_key( $item, $field ); + } + array_unshift( $items, $item ); } - array_unshift( $items, $item ); } $this->format( $items ); } From 01dd983240fccf3bad45b12fdd13143e7fa57a7e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 13:05:22 -0700 Subject: [PATCH 2982/4858] Update to php-cli-tools latest, which fixes Hungarian cron list --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f2972a1450..eddbf52a9b 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.9.4-patch46", + "wp-cli/php-cli-tools": "0.9.5", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From dfbcac42b284104849d5108fc654ca014083d41a Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:28:12 -0700 Subject: [PATCH 2983/4858] check for serialized before running serial safe replace --- php/commands/search-replace.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 384162839f..6f897a850f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -47,6 +47,7 @@ class Search_Replace_Command extends WP_CLI_Command { * 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; @@ -75,10 +76,13 @@ public function __invoke( $args, $assoc_args ) { } foreach ( $columns as $col ) { - if ( in_array( $col, $skip_columns ) ) + if ( in_array( $col, $skip_columns ) ) { continue; + } + + $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE $col REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( substr( $table, -9 ) == '_comments' || substr( $table, -6 ) == '_posts' ) { + if ( 0 < cont( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } else $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); From 8afdaa22445b2f74d5b25dee92c7d86b20f6d5f1 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:36:59 -0700 Subject: [PATCH 2984/4858] Single quote table and col names for edge cases --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 6f897a850f..63b943de72 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,7 +80,7 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE $col REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + $serialRow = $wpdb->get_col( "SELECT * FROM '$table' WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); if ( 0 < cont( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); From 4a636efbb383bac51ecece36febf3f1f63ef639f Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:39:01 -0700 Subject: [PATCH 2985/4858] now quotes on table name --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 63b943de72..4539c7f367 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,7 +80,7 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_col( "SELECT * FROM '$table' WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); if ( 0 < cont( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); From 32418eec31c013aabd17fd0b84c0bd576b79ab10 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:44:55 -0700 Subject: [PATCH 2986/4858] Spell count correctly --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 4539c7f367..b14e314168 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -82,7 +82,7 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( 0 < cont( $serialized ) ) { + if ( 0 < count( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } else $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); From 34e66b5bc7b1e48e791a9fda72a74acd2be1f165 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:47:55 -0700 Subject: [PATCH 2987/4858] Formatting and variable names --- php/commands/search-replace.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b14e314168..737f0862a8 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -82,10 +82,11 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( 0 < count( $serialized ) ) { + if ( 0 < count( $serialRow ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); - } else + } else { $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + } $report[] = array( $table, $col, $count ); From e8b39904add3474fe97d4ce0e255c067a518cbf2 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:17:39 -0700 Subject: [PATCH 2988/4858] Add backticks and show which replace is used --- php/commands/search-replace.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 737f0862a8..e2bae85848 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,12 +80,13 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - - if ( 0 < count( $serialRow ) ) { - $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); - } else { + $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + if ( NULL !== $serialRow ) { + WP_CLI::line( 'safe-replace' ); $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + } else { + WP_CLI::line( 'fast-replace' ); + $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } $report[] = array( $table, $col, $count ); @@ -117,10 +118,11 @@ private static function get_table_list( $args, $network ) { private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; - if ( $dry_run ) + if ( $dry_run ) { return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT($col) FROM $table WHERE $col LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); - else + } else { return $wpdb->query( $wpdb->prepare( "UPDATE $table SET $col = REPLACE($col, %s, %s);", $old, $new ) ); + } } private static function handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { From cbe88c6ab9752a5d773c6caa12eebc76a9430cc9 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:24:11 -0700 Subject: [PATCH 2989/4858] Back tick all the things and better debuggin --- php/commands/search-replace.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e2bae85848..0445769ffc 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -82,10 +82,10 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); if ( NULL !== $serialRow ) { - WP_CLI::line( 'safe-replace' ); + WP_CLI::line( "safe-replace-$table:$col" ); $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - WP_CLI::line( 'fast-replace' ); + WP_CLI::line( "fast-replace-$table:$col" ); $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } @@ -119,9 +119,9 @@ private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; if ( $dry_run ) { - return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT($col) FROM $table WHERE $col LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); } else { - return $wpdb->query( $wpdb->prepare( "UPDATE $table SET $col = REPLACE($col, %s, %s);", $old, $new ) ); + return $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } } From 8ed36e69f6d4523b6c0d07f7940637f16fe65dd2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 14:25:43 -0700 Subject: [PATCH 2990/4858] Use checksum API to verify core files --- features/core.feature | 29 +++++++++++++++++++++++++++++ php/commands/core.php | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/features/core.feature b/features/core.feature index 1d537e4341..d6ec9ea46e 100644 --- a/features/core.feature +++ b/features/core.feature @@ -267,6 +267,35 @@ Feature: Manage WordPress installation When I run `wp plugin status hello` Then STDOUT should not be empty + Scenario: Verify core checksums + Given a WP install + + When I run `wp core verify-checksums` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ + + When I run `sed -i.bak s/WordPress/Wordpress/g readme.html` + Then STDERR should be empty + + When I try `wp core verify-checksums` + Then STDERR should be: + """ + Warning: File doesn't verify against checksum: readme.html + Error: WordPress install doesn't verify against checksums. + """ + + When I run `rm readme.html` + Then STDERR should be empty + + When I try `wp core verify-checksums` + Then STDERR should be: + """ + Warning: File doesn't exist: readme.html + Error: WordPress install doesn't verify against checksums. + """ + Scenario: User defined in wp-cli.yml Given an empty directory And WP files diff --git a/php/commands/core.php b/php/commands/core.php index bf9a0a75a0..f464f8442d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -658,6 +658,47 @@ public function version( $args = array(), $assoc_args = array() ) { // @codingStandardsIgnoreEnd } + /** + * Verify WordPress files against WordPress.org's checksums. + * + * @subcommand verify-checksums + */ + public function verify_checksums( $args, $assoc_args ) { + global $wp_version, $wp_local_package; + + $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); + + if ( ! is_array( $checksums ) ) { + WP_CLI::error( "Couldn't get checksums from WordPress.org." ); + } + + $has_errors = false; + foreach ( $checksums as $file => $checksum ) { + // Skip files which get updated + if ( 'wp-content' == substr( $file, 0, 10 ) ) { + continue; + } + + if ( ! file_exists( ABSPATH . $file ) ) { + WP_CLI::warning( "File doesn't exist: {$file}" ); + $has_errors = true; + continue; + } + + $md5_file = md5_file( ABSPATH . $file ); + if ( $md5_file !== $checksum ) { + WP_CLI::warning( "File doesn't verify against checksum: {$file}" ); + $has_errors = true; + } + } + + if ( ! $has_errors ) { + WP_CLI::success( "WordPress install verifies against checksums." ); + } else { + WP_CLI::error( "WordPress install doesn't verify against checksums." ); + } + } + /** * Update WordPress. * From 338768b76e1e1886e15a1ff7373fb89519d7b986 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 29 Jun 2014 14:33:09 -0700 Subject: [PATCH 2991/4858] Core only offers checksums down to 3.7, so this will have to do Let's always test against latest though --- features/core.feature | 3 +++ php/commands/core.php | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index d6ec9ea46e..8fec27a7c6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -270,6 +270,9 @@ Feature: Manage WordPress installation Scenario: Verify core checksums Given a WP install + When I run `wp core update` + Then STDOUT should not be empty + When I run `wp core verify-checksums` Then STDOUT should be: """ diff --git a/php/commands/core.php b/php/commands/core.php index f464f8442d..025a543b8d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -666,7 +666,12 @@ public function version( $args = array(), $assoc_args = array() ) { public function verify_checksums( $args, $assoc_args ) { global $wp_version, $wp_local_package; - $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); + // Introduced in 3.7 + if ( function_exists( 'get_core_checksums' ) ) { + $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); + } else { + $checksums = false; + } if ( ! is_array( $checksums ) ) { WP_CLI::error( "Couldn't get checksums from WordPress.org." ); From e10ab16f7173acb0f3cd8f4548a7eba0b8323a6a Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:38:33 -0700 Subject: [PATCH 2992/4858] Safe flag and table output --- php/commands/search-replace.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0445769ffc..f9e17c13a4 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -37,6 +37,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--dry-run] * : Show report, but don't perform the changes. * + * [--safe] + * : Use only serialization safe replacement method. + * * [--recurse-objects] * : Enable recursing into objects to replace strings * @@ -53,6 +56,7 @@ public function __invoke( $args, $assoc_args ) { $total = 0; $report = array(); $dry_run = isset( $assoc_args['dry-run'] ); + $safe_only = isset( $assoc_args['safe'] ); $recurse_objects = isset( $assoc_args['recurse-objects'] ); if ( isset( $assoc_args['skip-columns'] ) ) @@ -80,23 +84,26 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( NULL !== $serialRow ) { - WP_CLI::line( "safe-replace-$table:$col" ); + if ( ! $safe_only ) { + $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + } + + if ( $safe_only || NULL !== $serialRow ) { + $safe = 'Y'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - WP_CLI::line( "fast-replace-$table:$col" ); + $safe = 'N'; $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } - $report[] = array( $table, $col, $count ); + $report[] = array( $table, $col, $count, $safe ); $total += $count; } } $table = new \cli\Table(); - $table->setHeaders( array( 'Table', 'Column', 'Replacements' ) ); + $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Safe Replace' ) ); $table->setRows( $report ); $table->display(); From 55edfb53a21172203f9a2747cbfbf33810dc4254 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:52:56 -0700 Subject: [PATCH 2993/4858] Use 'Fast Replace' as column name to avoid confusion --- php/commands/search-replace.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f9e17c13a4..ea49f8aaf3 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -89,10 +89,10 @@ public function __invoke( $args, $assoc_args ) { } if ( $safe_only || NULL !== $serialRow ) { - $safe = 'Y'; + $safe = 'No'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - $safe = 'N'; + $safe = 'Yes'; $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } @@ -103,7 +103,7 @@ public function __invoke( $args, $assoc_args ) { } $table = new \cli\Table(); - $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Safe Replace' ) ); + $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Fast Replace' ) ); $table->setRows( $report ); $table->display(); From cea783423d1b4ffcf4cd321e2fc2e85de5dea842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Mon, 30 Jun 2014 02:02:29 +0200 Subject: [PATCH 2994/4858] security copy of core function --- php/commands/core.php | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 025a543b8d..2a323402dc 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -658,6 +658,45 @@ public function version( $args = array(), $assoc_args = array() ) { // @codingStandardsIgnoreEnd } + /** + * Security copy of the core funtion - Gets and caches the checksums for the given version of WordPress. + * + * @since 3.7.0 + * + * @param string $version Version string to query. + * @param string $locale Locale to query. + * @return bool|array False on failure. An array of checksums on success. + */ + private static function _get_core_checksums( $version, $locale ) { + $return = array(); + + $url = $http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); + + if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) + $url = set_url_scheme( $url, 'https' ); + + $options = array( + 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ), + ); + + $response = wp_remote_get( $url, $options ); + if ( $ssl && is_wp_error( $response ) ) { + trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); + $response = wp_remote_get( $http_url, $options ); + } + + if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) + return false; + + $body = trim( wp_remote_retrieve_body( $response ) ); + $body = json_decode( $body, true ); + + if ( ! is_array( $body ) || ! isset( $body['checksums'] ) || ! is_array( $body['checksums'] ) ) + return false; + + return $body['checksums']; + } + /** * Verify WordPress files against WordPress.org's checksums. * @@ -668,7 +707,7 @@ public function verify_checksums( $args, $assoc_args ) { // Introduced in 3.7 if ( function_exists( 'get_core_checksums' ) ) { - $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); + $checksums = self::_get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); } else { $checksums = false; } From 81d15849f6917d67d21acdad3db50ccf83439f13 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Sun, 29 Jun 2014 18:17:38 -0700 Subject: [PATCH 2995/4858] filename tab completion --- utils/wp-completion.bash | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index ac7e99250a..8637044070 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -7,6 +7,9 @@ _wp_complete() { local opts="$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT")" if [[ $opts = "<file>" ]] + then + COMPREPLY=( $(compgen -f -- $cur) ) + elif [[ $opts = "" ]] then COMPREPLY=( $(compgen -f -- $cur) ) else From dee969b74ab73899cde1930d5e3f799fa7d1caa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Mon, 30 Jun 2014 03:24:24 +0200 Subject: [PATCH 2996/4858] with Requests --- php/commands/core.php | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 2a323402dc..4a88d6de8e 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -659,36 +659,38 @@ public function version( $args = array(), $assoc_args = array() ) { } /** - * Security copy of the core funtion - Gets and caches the checksums for the given version of WordPress. - * - * @since 3.7.0 + * Security copy of the core function with Requests - Gets the checksums for the given version of WordPress. * * @param string $version Version string to query. * @param string $locale Locale to query. * @return bool|array False on failure. An array of checksums on success. */ - private static function _get_core_checksums( $version, $locale ) { + private static function get_core_checksums( $version, $locale ) { $return = array(); $url = $http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) - $url = set_url_scheme( $url, 'https' ); + $url = 'https' . substr( $url, 4 ); $options = array( - 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ), + 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ) + ); + + $headers = array( + 'Accept' => 'application/json' ); + $response = self::_request( 'GET', $url, $headers, $options ); - $response = wp_remote_get( $url, $options ); - if ( $ssl && is_wp_error( $response ) ) { + if ( $ssl && ! $response->success ) { trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); - $response = wp_remote_get( $http_url, $options ); + $response = self::_request( 'GET', $http_url, $headers, $options ); } - if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) + if ( ! $response->success || 200 != $response->status_code ) return false; - $body = trim( wp_remote_retrieve_body( $response ) ); + $body = trim( $response->body ); $body = json_decode( $body, true ); if ( ! is_array( $body ) || ! isset( $body['checksums'] ) || ! is_array( $body['checksums'] ) ) @@ -705,12 +707,7 @@ private static function _get_core_checksums( $version, $locale ) { public function verify_checksums( $args, $assoc_args ) { global $wp_version, $wp_local_package; - // Introduced in 3.7 - if ( function_exists( 'get_core_checksums' ) ) { - $checksums = self::_get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); - } else { - $checksums = false; - } + $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); if ( ! is_array( $checksums ) ) { WP_CLI::error( "Couldn't get checksums from WordPress.org." ); From 093bb057169c71c82d5379bb8b9871cf074c9baf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 30 Jun 2014 17:02:33 -0700 Subject: [PATCH 2997/4858] Update mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 001d93e0a6..b2fd54a52b 100644 --- a/.mailmap +++ b/.mailmap @@ -34,6 +34,7 @@ johnpbloch <jbloch@John-Blochs-iMac.local> johnpbloch <johnpbloch@gmail.com> jonathanbardo <jonathanbardo@users.noreply.github.com> joshbetz <j@joshbetz.com> +joshlevinson <joshalevinson@gmail.com> Kevinlearynet <info@kevinleary.net> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> From 1e363d53030ff9f1f658fa2b1085ca9c0e2a2c0b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 30 Jun 2014 17:05:47 -0700 Subject: [PATCH 2998/4858] Bumpity bump --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 485cececd2..c0a45246ee 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.15.1' ); +define( 'WP_CLI_VERSION', '0.16.0' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 42af19f1166574a65ca7aab4ffe48aef8218508b Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Tue, 1 Jul 2014 11:47:04 -0700 Subject: [PATCH 2999/4858] trim commas on tables list in wp db export In running `wp db export --tables=$(wp db tables --url=local.dev/msstable/feta --scope=blog | tr '\n' ',')` the list of tables passed looks like `wp_4_posts,wp_4_comments,wp_4_links,wp_4_options,wp_4_postmeta,wp_4_terms,wp_4_term_taxonomy,wp_4_term_relationships,wp_4_commentmeta,` When the list is later explode()d, the trailing comma causes there to be an empty element in the array, and on export an extra table gets included (whatever is first alphabetically). --- php/commands/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index b641c8499a..32543d7a74 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -141,7 +141,7 @@ function export( $args, $assoc_args ) { $command_esc_args = array( DB_NAME ); if ( isset( $assoc_args['tables'] ) ) { - $tables = explode( ',', $assoc_args['tables'] ); + $tables = explode( ',', trim( $assoc_args['tables'], ',' ) ); unset( $assoc_args['tables'] ); $command .= ' --tables'; foreach ( $tables as $table ) { From 54cfda102872ebdd387ec4281f611bb94b27d845 Mon Sep 17 00:00:00 2001 From: Kailey Lampert <trepmal@gmail.com> Date: Wed, 2 Jul 2014 17:47:10 -0700 Subject: [PATCH 3000/4858] tab completion re-fixed --- utils/wp-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index 8637044070..94896ca524 100755 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -6,7 +6,7 @@ _wp_complete() { IFS=$'\n'; # want to preserve spaces at the end local opts="$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT")" - if [[ $opts = "<file>" ]] + if [[ "$opts" =~ \<file\>\s* ]] then COMPREPLY=( $(compgen -f -- $cur) ) elif [[ $opts = "" ]] From bd10a95d8780d125666a55306e50e4d795927303 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Fri, 4 Jul 2014 18:50:41 -0700 Subject: [PATCH 3001/4858] Allow for always fast replace is same str length --- php/commands/search-replace.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index ea49f8aaf3..23100e7594 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -79,24 +79,27 @@ public function __invoke( $args, $assoc_args ) { continue; } + // Can we do everything with a fast replace? + $fast_only = ( ! $safe_only && mb_strlen( $old ) === mb_strlen( $new ) ); + foreach ( $columns as $col ) { if ( in_array( $col, $skip_columns ) ) { continue; } - if ( ! $safe_only ) { + if ( ! $safe_only && ! $fast_only ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } - if ( $safe_only || NULL !== $serialRow ) { - $safe = 'No'; + if ( $safe_only || ! $fast_only || NULL !== $serialRow ) { + $fast = 'No'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - $safe = 'Yes'; + $fast = 'Yes'; $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } - $report[] = array( $table, $col, $count, $safe ); + $report[] = array( $table, $col, $count, $fast ); $total += $count; } From 53dd4f13398776711495905eeeff945ec4c6cbaa Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Fri, 4 Jul 2014 18:51:25 -0700 Subject: [PATCH 3002/4858] Fix behat tests and add one for fast-s-r scenarios --- features/search-replace.feature | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 2031ceb142..684fb67556 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -20,9 +20,9 @@ Feature: Do global search/replace And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` And I run `wp search-replace foo bar --network` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | - | wp_2_posts | guid | 2 | - | wp_blogs | path | 1 | + | Table | Column | Replacements | Fast Replace | + | wp_2_posts | guid | 2 | Yes | + | wp_blogs | path | 1 | Yes | Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install @@ -32,11 +32,28 @@ Feature: Do global search/replace When I run `wp search-replace <flags> {SITEURL} <replacement>` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | - | wp_posts | guid | 22 | + | Table | Column | Replacements | Fast Replace | + | wp_posts | guid | 22 | No | Examples: | replacement | flags | | {SITEURL}/subdir | | | http://newdomain.com | | | http://newdomain.com | --dry-run | + + Scenario Outline: Fast and Safe search/replace due to string length and flags + Given a WP install + And I run `wp option get siteurl` + And save STDOUT as {SITEURL} + And I run `wp search-replace {SITEURL} {SITEURL}/teststring` + + When I run `wp search-replace <flags> {SITEURL}/teststring <replacement>` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Fast Replace | + | wp_options | option_value | 2 | <fast> | + + Examples: + | replacement | flags | fast | + | {SITEURL}/different | | No | + | {SITEURL}/samelength | --safe | No | + | {SITEURL}/samelength | | Yes | From 86efc1528b0537c297b8d741222f90bc9805d9c7 Mon Sep 17 00:00:00 2001 From: Leonardo Santagada <santagada@gmail.com> Date: Sun, 8 Jun 2014 21:38:23 -0300 Subject: [PATCH 3003/4858] change data directly in mysql for some tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit search-replace on tables that don’t contain serialised data can be changed directly in mysql --- php/commands/search-replace.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e6a8739dfd..384162839f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -78,7 +78,10 @@ public function __invoke( $args, $assoc_args ) { if ( in_array( $col, $skip_columns ) ) continue; - $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + if ( substr( $table, -9 ) == '_comments' || substr( $table, -6 ) == '_posts' ) { + $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); + } else + $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); $report[] = array( $table, $col, $count ); @@ -106,6 +109,15 @@ private static function get_table_list( $args, $network ) { return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } + private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { + global $wpdb; + + if ( $dry_run ) + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT($col) FROM $table WHERE $col LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); + else + return $wpdb->query( $wpdb->prepare( "UPDATE $table SET $col = REPLACE($col, %s, %s);", $old, $new ) ); + } + private static function handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { global $wpdb; From 916d1d88d793ce981d041c4e7fe4e6379143862a Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:28:12 -0700 Subject: [PATCH 3004/4858] check for serialized before running serial safe replace --- php/commands/search-replace.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 384162839f..6f897a850f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -47,6 +47,7 @@ class Search_Replace_Command extends WP_CLI_Command { * 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; @@ -75,10 +76,13 @@ public function __invoke( $args, $assoc_args ) { } foreach ( $columns as $col ) { - if ( in_array( $col, $skip_columns ) ) + if ( in_array( $col, $skip_columns ) ) { continue; + } + + $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE $col REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( substr( $table, -9 ) == '_comments' || substr( $table, -6 ) == '_posts' ) { + if ( 0 < cont( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } else $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); From aa91d81563f279ff2282656837e66d2455f8cace Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:36:59 -0700 Subject: [PATCH 3005/4858] Single quote table and col names for edge cases --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 6f897a850f..63b943de72 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,7 +80,7 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE $col REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + $serialRow = $wpdb->get_col( "SELECT * FROM '$table' WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); if ( 0 < cont( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); From 18c04bc464205a8d21a1f453eb639094ea9b9611 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:39:01 -0700 Subject: [PATCH 3006/4858] now quotes on table name --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 63b943de72..4539c7f367 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,7 +80,7 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_col( "SELECT * FROM '$table' WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); if ( 0 < cont( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); From 0b53b222731ac9183aea5af95a12425d30dcae78 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:44:55 -0700 Subject: [PATCH 3007/4858] Spell count correctly --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 4539c7f367..b14e314168 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -82,7 +82,7 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( 0 < cont( $serialized ) ) { + if ( 0 < count( $serialized ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } else $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); From 802d5d4adbc03ce63bff7b364087e63c80d37996 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 13:47:55 -0700 Subject: [PATCH 3008/4858] Formatting and variable names --- php/commands/search-replace.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b14e314168..737f0862a8 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -82,10 +82,11 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( 0 < count( $serialized ) ) { + if ( 0 < count( $serialRow ) ) { $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); - } else + } else { $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + } $report[] = array( $table, $col, $count ); From c56227538d38ae62d52251f8221ab7f94e78574b Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:17:39 -0700 Subject: [PATCH 3009/4858] Add backticks and show which replace is used --- php/commands/search-replace.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 737f0862a8..e2bae85848 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,12 +80,13 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_col( "SELECT * FROM $table WHERE '$col' REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - - if ( 0 < count( $serialRow ) ) { - $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); - } else { + $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + if ( NULL !== $serialRow ) { + WP_CLI::line( 'safe-replace' ); $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + } else { + WP_CLI::line( 'fast-replace' ); + $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } $report[] = array( $table, $col, $count ); @@ -117,10 +118,11 @@ private static function get_table_list( $args, $network ) { private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; - if ( $dry_run ) + if ( $dry_run ) { return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT($col) FROM $table WHERE $col LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); - else + } else { return $wpdb->query( $wpdb->prepare( "UPDATE $table SET $col = REPLACE($col, %s, %s);", $old, $new ) ); + } } private static function handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { From edadb0de61ddde9a08e8bab380e82f2dbb18e158 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:24:11 -0700 Subject: [PATCH 3010/4858] Back tick all the things and better debuggin --- php/commands/search-replace.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e2bae85848..0445769ffc 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -82,10 +82,10 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); if ( NULL !== $serialRow ) { - WP_CLI::line( 'safe-replace' ); + WP_CLI::line( "safe-replace-$table:$col" ); $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - WP_CLI::line( 'fast-replace' ); + WP_CLI::line( "fast-replace-$table:$col" ); $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } @@ -119,9 +119,9 @@ private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; if ( $dry_run ) { - return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT($col) FROM $table WHERE $col LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); } else { - return $wpdb->query( $wpdb->prepare( "UPDATE $table SET $col = REPLACE($col, %s, %s);", $old, $new ) ); + return $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } } From 834d186481aa5ccc7873d89798ba8d2920ce1553 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:38:33 -0700 Subject: [PATCH 3011/4858] Safe flag and table output --- php/commands/search-replace.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0445769ffc..f9e17c13a4 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -37,6 +37,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--dry-run] * : Show report, but don't perform the changes. * + * [--safe] + * : Use only serialization safe replacement method. + * * [--recurse-objects] * : Enable recursing into objects to replace strings * @@ -53,6 +56,7 @@ public function __invoke( $args, $assoc_args ) { $total = 0; $report = array(); $dry_run = isset( $assoc_args['dry-run'] ); + $safe_only = isset( $assoc_args['safe'] ); $recurse_objects = isset( $assoc_args['recurse-objects'] ); if ( isset( $assoc_args['skip-columns'] ) ) @@ -80,23 +84,26 @@ public function __invoke( $args, $assoc_args ) { continue; } - $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); - if ( NULL !== $serialRow ) { - WP_CLI::line( "safe-replace-$table:$col" ); + if ( ! $safe_only ) { + $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); + } + + if ( $safe_only || NULL !== $serialRow ) { + $safe = 'Y'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - WP_CLI::line( "fast-replace-$table:$col" ); + $safe = 'N'; $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } - $report[] = array( $table, $col, $count ); + $report[] = array( $table, $col, $count, $safe ); $total += $count; } } $table = new \cli\Table(); - $table->setHeaders( array( 'Table', 'Column', 'Replacements' ) ); + $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Safe Replace' ) ); $table->setRows( $report ); $table->display(); From a70797022c42962c8a9a3d94fe4ad6f55fa4995f Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 29 Jun 2014 14:52:56 -0700 Subject: [PATCH 3012/4858] Use 'Fast Replace' as column name to avoid confusion --- php/commands/search-replace.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f9e17c13a4..ea49f8aaf3 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -89,10 +89,10 @@ public function __invoke( $args, $assoc_args ) { } if ( $safe_only || NULL !== $serialRow ) { - $safe = 'Y'; + $safe = 'No'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - $safe = 'N'; + $safe = 'Yes'; $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } @@ -103,7 +103,7 @@ public function __invoke( $args, $assoc_args ) { } $table = new \cli\Table(); - $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Safe Replace' ) ); + $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Fast Replace' ) ); $table->setRows( $report ); $table->display(); From 2977eec15c1763d06f4ebe763740a778c5dd5a8b Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Fri, 4 Jul 2014 18:50:41 -0700 Subject: [PATCH 3013/4858] Allow for always fast replace is same str length --- php/commands/search-replace.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index ea49f8aaf3..23100e7594 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -79,24 +79,27 @@ public function __invoke( $args, $assoc_args ) { continue; } + // Can we do everything with a fast replace? + $fast_only = ( ! $safe_only && mb_strlen( $old ) === mb_strlen( $new ) ); + foreach ( $columns as $col ) { if ( in_array( $col, $skip_columns ) ) { continue; } - if ( ! $safe_only ) { + if ( ! $safe_only && ! $fast_only ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } - if ( $safe_only || NULL !== $serialRow ) { - $safe = 'No'; + if ( $safe_only || ! $fast_only || NULL !== $serialRow ) { + $fast = 'No'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - $safe = 'Yes'; + $fast = 'Yes'; $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); } - $report[] = array( $table, $col, $count, $safe ); + $report[] = array( $table, $col, $count, $fast ); $total += $count; } From becf46314327205cb9541458b4062325d7c6a479 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Fri, 4 Jul 2014 18:51:25 -0700 Subject: [PATCH 3014/4858] Fix behat tests and add one for fast-s-r scenarios --- features/search-replace.feature | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 2031ceb142..684fb67556 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -20,9 +20,9 @@ Feature: Do global search/replace And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` And I run `wp search-replace foo bar --network` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | - | wp_2_posts | guid | 2 | - | wp_blogs | path | 1 | + | Table | Column | Replacements | Fast Replace | + | wp_2_posts | guid | 2 | Yes | + | wp_blogs | path | 1 | Yes | Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install @@ -32,11 +32,28 @@ Feature: Do global search/replace When I run `wp search-replace <flags> {SITEURL} <replacement>` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | - | wp_posts | guid | 22 | + | Table | Column | Replacements | Fast Replace | + | wp_posts | guid | 22 | No | Examples: | replacement | flags | | {SITEURL}/subdir | | | http://newdomain.com | | | http://newdomain.com | --dry-run | + + Scenario Outline: Fast and Safe search/replace due to string length and flags + Given a WP install + And I run `wp option get siteurl` + And save STDOUT as {SITEURL} + And I run `wp search-replace {SITEURL} {SITEURL}/teststring` + + When I run `wp search-replace <flags> {SITEURL}/teststring <replacement>` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Fast Replace | + | wp_options | option_value | 2 | <fast> | + + Examples: + | replacement | flags | fast | + | {SITEURL}/different | | No | + | {SITEURL}/samelength | --safe | No | + | {SITEURL}/samelength | | Yes | From dc9e615d19fb04dc5e00b5801248b47c84069e29 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 6 Jul 2014 16:29:49 -0700 Subject: [PATCH 3015/4858] Test for bug in normal circumstances fast replace fails to run --- features/search-replace.feature | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 684fb67556..9f054ed19c 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -50,10 +50,11 @@ Feature: Do global search/replace When I run `wp search-replace <flags> {SITEURL}/teststring <replacement>` Then STDOUT should be a table containing rows: | Table | Column | Replacements | Fast Replace | - | wp_options | option_value | 2 | <fast> | + | wp_options | option_value | 2 | <serial> | + | wp_posts | post_title | 0 | <noserial> | Examples: - | replacement | flags | fast | - | {SITEURL}/different | | No | - | {SITEURL}/samelength | --safe | No | - | {SITEURL}/samelength | | Yes | + | replacement | flags | serial | noserial | + | {SITEURL}/different | | No | Yes | + | {SITEURL}/samelength | --safe | No | No | + | {SITEURL}/samelength | | Yes | Yes | From 59935b48687f6e1e6f4fc8cfe6a589dfbbf7628b Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 6 Jul 2014 16:32:57 -0700 Subject: [PATCH 3016/4858] Guid replace should be fast since there is no serialized data --- features/search-replace.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 9f054ed19c..95027ecef9 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -33,7 +33,7 @@ Feature: Do global search/replace When I run `wp search-replace <flags> {SITEURL} <replacement>` Then STDOUT should be a table containing rows: | Table | Column | Replacements | Fast Replace | - | wp_posts | guid | 22 | No | + | wp_posts | guid | 22 | Yes | Examples: | replacement | flags | From 28dfcf47cc9245f1c93aa576cec664d07bc28397 Mon Sep 17 00:00:00 2001 From: Luke Woodward <woodward.lucas@gmail.com> Date: Sun, 6 Jul 2014 16:33:33 -0700 Subject: [PATCH 3017/4858] Fix conditional to properly switch to fast method --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 23100e7594..c3a725e0c0 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -91,7 +91,7 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } - if ( $safe_only || ! $fast_only || NULL !== $serialRow ) { + if ( $safe_only || ( ! $fast_only && NULL !== $serialRow ) ) { $fast = 'No'; $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { From 6409fdc9f39275c82fe870c5cd086fb6e79ce7bb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 13 Jul 2014 15:38:51 +0000 Subject: [PATCH 3018/4858] Correct line breaks --- CONTRIBUTING.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 563153a4e6..013140f970 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,9 +45,7 @@ To run the unit tests, just execute: The functional test files are in the `features/` directory. -Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the -password `password1` that has full privileges on the MySQL database `wp_cli_test`. -Running the following as root in MySQL should do the trick: +Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; @@ -64,5 +62,4 @@ More info can be found by using `./vendor/bin/behat --help`. Finally... ---------- -Thanks! Hacking on WP-CLI should be fun. If you find any of this hard to figure -out, let us know so we can improve our process or documentation! +Thanks! Hacking on WP-CLI should be fun. If you find any of this hard to figure out, let us know so we can improve our process or documentation! From 32af46f83b5ed44b60b6fd108f8c912b69735437 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 13 Jul 2014 15:40:22 +0000 Subject: [PATCH 3019/4858] Add mention that each contribution should be on a separate branch. --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 013140f970..001b2400e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,8 +16,9 @@ Whether you want to fix a bug or implement a new feature, the process is pretty 0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, open a new issue so that you can get some initial feedback. 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. -2. Push the code changes from your local clone to your fork. -3. Open a pull request. +2. Create a branch for each issue you'd like to address. Commit your changes. +3. Push the code changes from your local clone to your fork. +4. Open a pull request. It doesn't matter if the code isn't perfect. The idea is to get it reviewed early and iterate on it. From 16bf1beaf8a0f65c98535edc46bdb7c5a1c016d3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 14 Jul 2014 15:32:09 +0000 Subject: [PATCH 3020/4858] Fix incorrect argument in example Fixes #1276 --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index a7c81ec41f..84fa861a47 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -46,7 +46,7 @@ public function __construct() { * * ## EXAMPLES * - * wp post create --post_type=page --post_status=publish --post_title='A future post' --post-status=future --post_date='2020-12-01 07:00:00' + * wp post create --post_type=page --post_title='A future post' --post_status=future --post_date='2020-12-01 07:00:00' * * wp post create ./post-content.txt --post_category=201,345 --post_title='Post from file' */ From 74f3f67717fde5327d8aec07d2b0d35430cfd70b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 13:30:34 +0000 Subject: [PATCH 3021/4858] Show generated password when creating a user This is helpful to the end developer, and was accidentally removed in 17860a741218d6230720d43cafa1c32f6a8a5ed2 --- features/user.feature | 15 +++++++++++++++ php/commands/user.php | 10 +++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/features/user.feature b/features/user.feature index a50e3bb3a6..2809ac97c5 100644 --- a/features/user.feature +++ b/features/user.feature @@ -253,3 +253,18 @@ Feature: Manage WordPress users """ Success: Removed 'edit_vip_product' cap for admin (1). """ + + Scenario: Show password when creating a user + Given a WP install + + When I run `wp user create testrandompass testrandompass@example.com` + Then STDOUT should contain: + """ + Password: + """ + + When I run `wp user create testsuppliedpass testsuppliedpass@example.com --user_pass=suppliedpass` + Then STDOUT should not contain: + """ + Password: + """ diff --git a/php/commands/user.php b/php/commands/user.php index bdb7bc7c85..b93cf1c4b1 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -229,8 +229,12 @@ public function create( $args, $assoc_args ) { $user->last_name = isset( $assoc_args['last_name'] ) ? $assoc_args['last_name'] : false; - $user->user_pass = isset( $assoc_args['user_pass'] ) - ? $assoc_args['user_pass'] : wp_generate_password(); + if ( isset( $assoc_args['user_pass'] ) ) { + $user->user_pass = $assoc_args['user_pass']; + } else { + $user->user_pass = wp_generate_password(); + $generated_pass = true; + } if ( isset( $assoc_args['role'] ) ) { $role = $assoc_args['role']; @@ -259,7 +263,7 @@ public function create( $args, $assoc_args ) { } else { WP_CLI::success( "Created user $user_id." ); if ( isset( $generated_pass ) ) - WP_CLI::line( "Password: $user_pass" ); + WP_CLI::line( "Password: $user->user_pass" ); } } From ef851ba7fff305b649bc910e14f3ab7d6adc4733 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 13:44:28 +0000 Subject: [PATCH 3022/4858] Test case to confirm #1272 --- features/config.feature | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/features/config.feature b/features/config.feature index 3ed1e17aa1..9fadc2273d 100644 --- a/features/config.feature +++ b/features/config.feature @@ -177,3 +177,24 @@ Feature: Have a config file Then STDOUT should be a number When I run `wp post list --format=json` Then STDOUT should not be a number + + Scenario: Required files should not be loaded twice + Given an empty directory + And a custom-file.php file: + """ + <?php + define( 'FOOBUG', 'BAR' ); + """ + And a config.yml file: + """ + require: + - custom-file.php + """ + And a wp-cli.yml file: + """ + require: + - custom-file.php + """ + + When I run `WP_CLI_CONFIG_PATH=config.yml wp help` + Then STDERR should be empty From ca07b8a3c1eecc01c185e7ee176a6c70fcdd977c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 13:48:41 +0000 Subject: [PATCH 3023/4858] Ensure config.yml in a separate directory is tested --- features/config.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/config.feature b/features/config.feature index 9fadc2273d..ad5f2e05e5 100644 --- a/features/config.feature +++ b/features/config.feature @@ -185,10 +185,10 @@ Feature: Have a config file <?php define( 'FOOBUG', 'BAR' ); """ - And a config.yml file: + And a test-dir/config.yml file: """ require: - - custom-file.php + - ../custom-file.php """ And a wp-cli.yml file: """ @@ -196,5 +196,5 @@ Feature: Have a config file - custom-file.php """ - When I run `WP_CLI_CONFIG_PATH=config.yml wp help` + When I run `WP_CLI_CONFIG_PATH=test-dir/config.yml wp help` Then STDERR should be empty From 5c1c6fd96603b66d0c77f9a7e162adb75d859ced Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 13:50:52 +0000 Subject: [PATCH 3024/4858] Use `require_once()` to prevent a given file from being loaded twice --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index fe21f32e23..e033be5bb1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -38,7 +38,7 @@ function get_vendor_paths() { // Using require() directly inside a class grants access to private methods to the loaded code function load_file( $path ) { - require $path; + require_once $path; } function load_command( $name ) { From 869c29037863e267757aa2de8bddcb5e91a21feb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 14:17:59 +0000 Subject: [PATCH 3025/4858] Update step to handle directories too --- features/steps/then.php | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/features/steps/then.php b/features/steps/then.php index 428001a5fc..ef11a52bbb 100644 --- a/features/steps/then.php +++ b/features/steps/then.php @@ -120,32 +120,47 @@ function ( $world, $stream ) { } ); -$steps->Then( '/^the (.+) file should (exist|not exist|be:|contain:|not contain:)$/', - function ( $world, $path, $action, $expected = null ) { +$steps->Then( '/^the (.+) (file|directory) should (exist|not exist|be:|contain:|not contain:)$/', + function ( $world, $path, $type, $action, $expected = null ) { $path = $world->replace_variables( $path ); // If it's a relative path, make it relative to the current test dir if ( '/' !== $path[0] ) $path = $world->variables['RUN_DIR'] . "/$path"; + if ( 'file' == $type ) { + $test = 'file_exists'; + } else if ( 'directory' == $type ) { + $test = 'is_dir'; + } + switch ( $action ) { case 'exist': - if ( !file_exists( $path ) ) { + if ( ! $test( $path ) ) { throw new Exception( $world->result ); } break; case 'not exist': - if ( file_exists( $path ) ) { + if ( $test( $path ) ) { throw new Exception( $world->result ); } break; default: - if ( !file_exists( $path ) ) { + if ( ! $test( $path ) ) { throw new Exception( "$path doesn't exist." ); } $action = substr( $action, 0, -1 ); $expected = $world->replace_variables( (string) $expected ); - checkString( file_get_contents( $path ), $expected, $action ); + if ( 'file' == $type ) { + $contents = file_get_contents( $path ); + } else if ( 'directory' == $type ) { + $files = glob( rtrim( $path, '/' ) . '/*' ); + foreach( $files as &$file ) { + $file = str_replace( $path . '/', '', $file ); + } + $contents = implode( PHP_EOL, $files ); + } + checkString( $contents, $expected, $action ); } } ); From 10c30e447781d7a38787349141bd5a29b2ba7cf3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 14:18:15 +0000 Subject: [PATCH 3026/4858] Test coverage for scaffolding plugin unit tests --- features/scaffold.feature | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 419590e3d5..f660474913 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -80,4 +80,28 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world` Then STDOUT should not be empty And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist - And the {PLUGIN_DIR}/hello-world/readme.txt file should exist \ No newline at end of file + And the {PLUGIN_DIR}/hello-world/readme.txt file should exist + + Scenario: Scaffold plugin tests + When I run `wp plugin path` + Then save STDOUT as {PLUGIN_DIR} + + When I run `wp scaffold plugin hello-world --skip-tests` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist + And the {PLUGIN_DIR}/hello-world/readme.txt file should exist + And the {PLUGIN_DIR}/hello-world/tests directory should not exist + + When I run `wp scaffold plugin-tests hello-world` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/tests directory should contain: + """ + bootstrap.php + test-sample.php + """ + And the {PLUGIN_DIR}/hello-world/bin directory should contain: + """ + install-wp-tests.sh + """ + And the {PLUGIN_DIR}/hello-world/phpunit.xml file should exist + And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist From a9dd218f25d73a8bc7f64676007f1d098ddfa499 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 14:27:49 +0000 Subject: [PATCH 3027/4858] Mark install script as executable after copy --- features/scaffold.feature | 6 ++++++ php/commands/scaffold.php | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index f660474913..f7fa235fda 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -105,3 +105,9 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/phpunit.xml file should exist And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist + + When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-wp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` + Then STDOUT should be: + """ + executable + """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index e090fa5822..0aa9addee1 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -397,6 +397,11 @@ function plugin_tests( $args, $assoc_args ) { foreach ( $to_copy as $file => $dir ) { $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); + if ( 'install-wp-tests.sh' === $file ) { + if ( ! $wp_filesystem->chmod( "$dir/$file", '0755' ) ) { + WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); + } + } } WP_CLI::success( "Created test files." ); From 4288363866e9985776560a4cdb89741ba35a3db5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 17:47:22 +0000 Subject: [PATCH 3028/4858] Add methods to DocParser for getting arg descriptions --- php/WP_CLI/DocParser.php | 31 +++++++++++++++++++++++++++++++ tests/test-doc-parser.php | 14 ++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index b95df6e075..948db70092 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -57,5 +57,36 @@ function get_synopsis() { return $matches[1]; } + + /** + * Get the description for a given argument. + * + * @param string $name Argument's doc name. + * @return string + */ + public function get_argdesc( $name ) { + + if ( preg_match( "/\[?<{$name}>[\S]+\n: (.+?)(\n|$)/s", $this->docComment, $matches ) ) { + return $matches[1]; + } + + return ''; + + } + + /** + * Get the description for a given parameter. + * + * @param string $key Parameter's key. + * @return string + */ + public function get_paramdesc( $key ) { + + if ( preg_match( "/\[?--{$key}=[\S]+\n: (.+?)(\n|$)/s", $this->docComment, $matches ) ) { + return $matches[1]; + } + + return ''; + } } diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index 4138481910..fc82020934 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -50,9 +50,15 @@ function test_complete() { * * ## OPTIONS * + * <genre>... + * : Start with one or more genres. + * * --volume=<number> * : Sets the volume. * + * --artist=<artist-name> + * : Limit to a specific artist. + * * ## EXAMPLES * * wp rock-on --volume=11 @@ -65,14 +71,22 @@ function test_complete() { $this->assertEquals( 'Rock and roll!', $doc->get_shortdesc() ); $this->assertEquals( '[--volume=<number>]', $doc->get_synopsis() ); + $this->assertEquals( 'Start with one or more genres.', $doc->get_argdesc( 'genre' ) ); + $this->assertEquals( 'Sets the volume.', $doc->get_paramdesc( 'volume' ) ); $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); $longdesc = <<<EOB ## OPTIONS +<genre>... +: Start with one or more genres. + --volume=<number> : Sets the volume. +--artist=<artist-name> +: Limit to a specific artist. + ## EXAMPLES wp rock-on --volume=11 From 8bc33d7efaf9721e0711a3eb06753554adc53466 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 17:48:44 +0000 Subject: [PATCH 3029/4858] Show param description when required param is missing --- features/core.feature | 2 +- php/WP_CLI/Dispatcher/CompositeCommand.php | 3 ++- php/WP_CLI/Dispatcher/Subcommand.php | 7 +++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index 8fec27a7c6..f7f1b86903 100644 --- a/features/core.feature +++ b/features/core.feature @@ -110,7 +110,7 @@ Feature: Manage WordPress installation Then the return code should be 1 And STDERR should contain: """ - missing --url parameter + missing --url parameter (The address of the new site.) """ When I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 77cad3905a..7296652f7e 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -10,7 +10,7 @@ */ class CompositeCommand { - protected $name, $shortdesc, $synopsis; + protected $name, $shortdesc, $synopsis, $docparser; protected $parent, $subcommands = array(); @@ -28,6 +28,7 @@ public function __construct( $parent, $name, $docparser ) { $this->shortdesc = $docparser->get_shortdesc(); $this->longdesc = $docparser->get_longdesc(); + $this->docparser = $docparser; $when_to_invoke = $docparser->get_tag( 'when' ); if ( $when_to_invoke ) { diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 673bc99f3f..d970f428dc 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -254,8 +254,11 @@ private function validate_args( $args, $assoc_args, $extra_args ) { if ( !empty( $errors['fatal'] ) ) { $out = 'Parameter errors:'; - foreach ( $errors['fatal'] as $error ) { - $out .= "\n " . $error; + foreach ( $errors['fatal'] as $key => $error ) { + $out .= "\n {$error}"; + if ( $desc = $this->docparser->get_paramdesc( $key ) ) { + $out .= " ({$desc})"; + } } \WP_CLI::error( $out ); From f904673c9cf31b6c340d0359bb79a2243a9bce5d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 17:52:44 +0000 Subject: [PATCH 3030/4858] Don't be so grabby, and accommodate trailing whitespace --- php/WP_CLI/DocParser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index 948db70092..b9b046583a 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -66,7 +66,7 @@ function get_synopsis() { */ public function get_argdesc( $name ) { - if ( preg_match( "/\[?<{$name}>[\S]+\n: (.+?)(\n|$)/s", $this->docComment, $matches ) ) { + if ( preg_match( "/\[?<{$name}>.+\n: (.+?)(\n|$)/", $this->docComment, $matches ) ) { return $matches[1]; } @@ -82,7 +82,7 @@ public function get_argdesc( $name ) { */ public function get_paramdesc( $key ) { - if ( preg_match( "/\[?--{$key}=[\S]+\n: (.+?)(\n|$)/s", $this->docComment, $matches ) ) { + if ( preg_match( "/\[?--{$key}=.+\n: (.+?)(\n|$)/", $this->docComment, $matches ) ) { return $matches[1]; } From 2646ef86cc64f8c28d161a1dc3b5311c3693d085 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 18:27:06 +0000 Subject: [PATCH 3031/4858] Support for detailed results from `WP_CLI::launch()` and `::launch_self()` --- php/class-wp-cli.php | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ea54f18c04..f7c528c8e2 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -347,16 +347,42 @@ static function error_to_string( $errors ) { * * @param string Command to call * @param bool Whether to exit if the command returns an error status + * @param bool Whether to return an exit status (default) or detailed execution results * * @return int The command exit status */ - static function launch( $command, $exit_on_error = true ) { - $r = proc_close( proc_open( $command, array( STDIN, STDOUT, STDERR ), $pipes ) ); + static function launch( $command, $exit_on_error = true, $return_detailed = false ) { + + if ( $return_detailed ) { + $descriptorspec = array( + 0 => array( 'file', 'php://stdin', 'r' ), + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ); + } else { + $descriptorspec = array( STDIN, STDOUT, STDERR ); + } + + $process = proc_open( $command, $descriptorspec, $pipes ); + + if ( $return_detailed ) { + $ret_val = array( + 'stdout' => stream_get_contents( $pipes[1] ), + 'stderr' => stream_get_contents( $pipes[2] ), + ); + } + + $r = proc_close( $process ); if ( $r && $exit_on_error ) exit($r); - return $r; + if ( $return_detailed ) { + $ret_val['exit_status'] = $r; + return $ret_val; + } else { + return $r; + } } /** @@ -366,10 +392,11 @@ static function launch( $command, $exit_on_error = true ) { * @param array $args Positional arguments to use * @param array $assoc_args Associative arguments to use * @param bool Whether to exit if the command returns an error status + * @param bool Whether to return an exit status (default) or detailed execution results * * @return int The command exit status */ - static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true ) { + static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false ) { $reused_runtime_args = array( 'path', 'url', @@ -391,7 +418,7 @@ static function launch_self( $command, $args = array(), $assoc_args = array(), $ $full_command = "{$php_bin} {$script_path} {$command} {$args} {$assoc_args}"; - return self::launch( $full_command, $exit_on_error ); + return self::launch( $full_command, $exit_on_error, $return_detailed ); } /** From 893df5603a0f1cccc3d8ce4aad5b956d346a91b0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 18:32:32 +0000 Subject: [PATCH 3032/4858] Better naming for these methods. --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/WP_CLI/DocParser.php | 4 ++-- tests/test-doc-parser.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index d970f428dc..373ee4e61e 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -256,7 +256,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $out = 'Parameter errors:'; foreach ( $errors['fatal'] as $key => $error ) { $out .= "\n {$error}"; - if ( $desc = $this->docparser->get_paramdesc( $key ) ) { + if ( $desc = $this->docparser->get_param_desc( $key ) ) { $out .= " ({$desc})"; } } diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index b9b046583a..29e51e66a2 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -64,7 +64,7 @@ function get_synopsis() { * @param string $name Argument's doc name. * @return string */ - public function get_argdesc( $name ) { + public function get_arg_desc( $name ) { if ( preg_match( "/\[?<{$name}>.+\n: (.+?)(\n|$)/", $this->docComment, $matches ) ) { return $matches[1]; @@ -80,7 +80,7 @@ public function get_argdesc( $name ) { * @param string $key Parameter's key. * @return string */ - public function get_paramdesc( $key ) { + public function get_param_desc( $key ) { if ( preg_match( "/\[?--{$key}=.+\n: (.+?)(\n|$)/", $this->docComment, $matches ) ) { return $matches[1]; diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index fc82020934..150a33158d 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -71,8 +71,8 @@ function test_complete() { $this->assertEquals( 'Rock and roll!', $doc->get_shortdesc() ); $this->assertEquals( '[--volume=<number>]', $doc->get_synopsis() ); - $this->assertEquals( 'Start with one or more genres.', $doc->get_argdesc( 'genre' ) ); - $this->assertEquals( 'Sets the volume.', $doc->get_paramdesc( 'volume' ) ); + $this->assertEquals( 'Start with one or more genres.', $doc->get_arg_desc( 'genre' ) ); + $this->assertEquals( 'Sets the volume.', $doc->get_param_desc( 'volume' ) ); $this->assertEquals( 'rock-on', $doc->get_tag('alias') ); $longdesc = <<<EOB From ebbcf6788dd61e9e2172f63abb7e411b5ec066ee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 18:36:55 +0000 Subject: [PATCH 3033/4858] Include the key in the error response This is later used to look up more details about the argument. --- php/WP_CLI/SynopsisValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index 7c56f98e87..ea2f59394b 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -63,12 +63,12 @@ public function validate_assoc( $assoc_args ) { if ( !isset( $assoc_args[ $key ] ) ) { if ( !$param['optional'] ) { - $errors['fatal'][] = "missing --$key parameter"; + $errors['fatal'][$key] = "missing --$key parameter"; } } else { if ( true === $assoc_args[ $key ] && !$param['value']['optional'] ) { $error_type = ( !$param['optional'] ) ? 'fatal' : 'warning'; - $errors[ $error_type ][] = "--$key parameter needs a value"; + $errors[ $error_type ][$key] = "--$key parameter needs a value"; $to_unset[] = $key; } From 5f691cad3e14fe4ca106c06c2ccdb85824208567 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 18:46:40 +0000 Subject: [PATCH 3034/4858] Relocate the Process class so we can use it in WP-CLI --- features/bootstrap/FeatureContext.php | 2 ++ {features/bootstrap => php/WP_CLI}/Process.php | 2 ++ 2 files changed, 4 insertions(+) rename {features/bootstrap => php/WP_CLI}/Process.php (98%) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 20dda8ab5c..1ddc7d753f 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -5,9 +5,11 @@ Behat\Behat\Context\BehatContext, Behat\Behat\Event\SuiteEvent; +use \WP_CLI\Process; use \WP_CLI\Utils; require_once __DIR__ . '/../../php/utils.php'; +require_once __DIR__ . '/../../php/WP_CLI/Process.php'; /** * Features context. diff --git a/features/bootstrap/Process.php b/php/WP_CLI/Process.php similarity index 98% rename from features/bootstrap/Process.php rename to php/WP_CLI/Process.php index a8a3334b5d..a2589385b6 100644 --- a/features/bootstrap/Process.php +++ b/php/WP_CLI/Process.php @@ -1,5 +1,7 @@ <?php +namespace WP_CLI; + class Process { public static function create( $command, $cwd = null, $env = array() ) { From 2421b382f74f48792b43663ba596a8ba4b07aa47 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 18:55:24 +0000 Subject: [PATCH 3035/4858] Refactor `WP_CLI\Process` so it isn't Behat-specific --- features/bootstrap/FeatureContext.php | 26 ++++++++++++++++++++------ features/steps/given.php | 3 ++- features/steps/when.php | 3 ++- php/WP_CLI/Process.php | 11 ++--------- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 1ddc7d753f..5227497087 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -26,6 +26,20 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { public $variables = array(); + /** + * Get the environment variables required for launched `wp` processes + * @beforeSuite + */ + private static function get_process_env_variables() { + // Ensure we're using the expected `wp` binary + $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); + $env = array( + 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), + 'BEHAT_RUN' => 1 + ); + return $env; + } + // We cache the results of `wp core download` to improve test performance // Ideally, we'd cache at the HTTP layer for more reliable tests private static function cache_wp_files() { @@ -35,7 +49,7 @@ private static function cache_wp_files() { return; $cmd = Utils\esc_cmd( 'wp core download --force --path=%s', self::$cache_dir ); - Process::create( $cmd )->run_check(); + Process::create( $cmd, null, self::get_process_env_variables() )->run_check(); } /** @@ -50,7 +64,7 @@ public static function prepare( SuiteEvent $event ) { */ public static function afterSuite( SuiteEvent $event ) { if ( self::$suite_cache_dir ) { - Process::create( Utils\esc_cmd( 'rm -r %s', self::$suite_cache_dir ) )->run(); + Process::create( Utils\esc_cmd( 'rm -r %s', self::$suite_cache_dir ), null, self::get_process_env_variables() )->run(); } } @@ -63,7 +77,7 @@ public function afterScenario( $event ) { // remove altered WP install, unless there's an error if ( $event->getResult() < 4 ) { - Process::create( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ) )->run(); + Process::create( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ), null, self::get_process_env_variables() )->run(); } } @@ -116,7 +130,7 @@ public function create_run_dir() { private function set_cache_dir() { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); + Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ), null, self::get_process_env_variables() )->run_check(); $this->variables['CACHE_DIR'] = $path; } @@ -143,7 +157,7 @@ public function proc( $command, $assoc_args = array() ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); - $env = array(); + $env = self::get_process_env_variables(); if ( isset( $this->variables['SUITE_CACHE_DIR'] ) ) { $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; } @@ -166,7 +180,7 @@ public function download_wp( $subdir = '' ) { if ( $subdir ) mkdir( $dest_dir ); - Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ) )->run_check(); + Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ), null, self::get_process_env_variables() )->run_check(); // disable emailing mkdir( $dest_dir . '/wp-content/mu-plugins' ); diff --git a/features/steps/given.php b/features/steps/given.php index 8fa71cf42d..10eb318f02 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -1,7 +1,8 @@ <?php use Behat\Gherkin\Node\PyStringNode, - Behat\Gherkin\Node\TableNode; + Behat\Gherkin\Node\TableNode, + WP_CLI\Process; $steps->Given( '/^an empty directory$/', function ( $world ) { diff --git a/features/steps/when.php b/features/steps/when.php index 81b4c9a6d2..68ff28baf5 100644 --- a/features/steps/when.php +++ b/features/steps/when.php @@ -1,7 +1,8 @@ <?php use Behat\Gherkin\Node\PyStringNode, - Behat\Gherkin\Node\TableNode; + Behat\Gherkin\Node\TableNode, + WP_CLI\Process; function invoke_proc( $proc, $mode, $subdir = null ) { $map = array( diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index a2589385b6..9e853c438b 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -30,14 +30,7 @@ public function run( $subdir = '' ) { 2 => array( 'pipe', 'w' ), ); - // Ensure we're using the expected `wp` binary - $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); - $env = array_merge( $this->env, array( - 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), - 'BEHAT_RUN' => 1 - ) ); - - $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, $env ); + $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, $this->env ); $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); @@ -51,7 +44,7 @@ public function run( $subdir = '' ) { 'return_code' => proc_close( $proc ), 'command' => $this->command, 'cwd' => $cwd, - 'env' => $env + 'env' => $this->env ) ); } From ab394eb23f49ca41bc78ab99081d064231a0fd3b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 18:55:46 +0000 Subject: [PATCH 3036/4858] Use our new Process class for `WP_CLI::launch()` --- php/class-wp-cli.php | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f7c528c8e2..8b5ba0e34f 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -353,35 +353,16 @@ static function error_to_string( $errors ) { */ static function launch( $command, $exit_on_error = true, $return_detailed = false ) { - if ( $return_detailed ) { - $descriptorspec = array( - 0 => array( 'file', 'php://stdin', 'r' ), - 1 => array( 'pipe', 'w' ), - 2 => array( 'pipe', 'w' ), - ); - } else { - $descriptorspec = array( STDIN, STDOUT, STDERR ); - } - - $process = proc_open( $command, $descriptorspec, $pipes ); - - if ( $return_detailed ) { - $ret_val = array( - 'stdout' => stream_get_contents( $pipes[1] ), - 'stderr' => stream_get_contents( $pipes[2] ), - ); - } - - $r = proc_close( $process ); + $proc = new Process( $command ); + $results = $proc->run(); - if ( $r && $exit_on_error ) - exit($r); + if ( $results['return_code'] && $exit_on_error ) + exit( $results['return_code'] ); if ( $return_detailed ) { - $ret_val['exit_status'] = $r; - return $ret_val; + return $results; } else { - return $r; + return $results['return_code']; } } From 1f8b5679644e48df1ddd84341f76ecde574fd968 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 19:02:00 +0000 Subject: [PATCH 3037/4858] Fix my broken code :( --- php/class-wp-cli.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 8b5ba0e34f..ce801abbcf 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -3,6 +3,7 @@ use \WP_CLI\Utils; use \WP_CLI\Dispatcher; use \WP_CLI\FileCache; +use \WP_CLI\Process; use \WP_CLI\WpHttpCacheManager; /** @@ -353,8 +354,8 @@ static function error_to_string( $errors ) { */ static function launch( $command, $exit_on_error = true, $return_detailed = false ) { - $proc = new Process( $command ); - $results = $proc->run(); + $proc = Process::create( $command ); + $results = (array)$proc->run(); if ( $results['return_code'] && $exit_on_error ) exit( $results['return_code'] ); From 53acced15c3048cefb8d87ddcb22d30a6c47931c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 19:03:54 +0000 Subject: [PATCH 3038/4858] Returning the instance will give more flexibility in the future --- php/class-wp-cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ce801abbcf..3ec3d0cb87 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -350,20 +350,20 @@ static function error_to_string( $errors ) { * @param bool Whether to exit if the command returns an error status * @param bool Whether to return an exit status (default) or detailed execution results * - * @return int The command exit status + * @return int|ProcessRun The command exit status, or a ProcessRun instance */ static function launch( $command, $exit_on_error = true, $return_detailed = false ) { $proc = Process::create( $command ); - $results = (array)$proc->run(); + $results = $proc->run(); - if ( $results['return_code'] && $exit_on_error ) - exit( $results['return_code'] ); + if ( $results->return_code && $exit_on_error ) + exit( $results->return_code ); if ( $return_detailed ) { return $results; } else { - return $results['return_code']; + return $results->return_code; } } @@ -376,7 +376,7 @@ static function launch( $command, $exit_on_error = true, $return_detailed = fals * @param bool Whether to exit if the command returns an error status * @param bool Whether to return an exit status (default) or detailed execution results * - * @return int The command exit status + * @return int|ProcessRun The command exit status, or a ProcessRun instance */ static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false ) { $reused_runtime_args = array( From 05d0a8fea8d9493d9a174fa380a30c2db21e30a0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 19:12:05 +0000 Subject: [PATCH 3039/4858] Throw an error when post type slug is too long --- features/scaffold.feature | 7 +++++++ php/commands/scaffold.php | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index f7fa235fda..3ec35028b6 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -65,6 +65,13 @@ Feature: WordPress code scaffolding __( 'Zombies', 'zombieland' """ + Scenario: CPT slug is too long + When I try `wp scaffold post-type slugiswaytoolonginfact` + Then STDERR should be: + """ + Error: Post type slugs cannot exceed 20 characters in length. + """ + @cpt Scenario: Scaffold a Custom Post Type with label When I run `wp scaffold post-type zombie --label="Brain eater"` diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 0aa9addee1..b35ce22b33 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -42,6 +42,11 @@ function __construct() { * @alias cpt */ function post_type( $args, $assoc_args ) { + + if ( strlen( $args[0] ) > 20 ) { + WP_CLI::error( "Post type slugs cannot exceed 20 characters in length." ); + } + $defaults = array( 'textdomain' => '', ); From 35444539dd871b44acaef86054353e982593f6e2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 19:14:36 +0000 Subject: [PATCH 3040/4858] This class is now in local scope --- features/steps/given.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/given.php b/features/steps/given.php index 10eb318f02..5f88f60a82 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -96,7 +96,7 @@ function ( $world, TableNode $table ) { continue; } - \Process::create( \WP_CLI\Utils\esc_cmd( 'curl -sSL %s > %s', $row['url'], $path ) )->run_check(); + Process::create( \WP_CLI\Utils\esc_cmd( 'curl -sSL %s > %s', $row['url'], $path ) )->run_check(); } } ); From da7462a11c983f7e01ad18da0548d5a9c3d4f379 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:01:01 +0000 Subject: [PATCH 3041/4858] Only constants should be uppercased --- php/WP_CLI/Process.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index 9e853c438b..7a0add5bca 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -32,15 +32,15 @@ public function run( $subdir = '' ) { $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, $this->env ); - $STDOUT = stream_get_contents( $pipes[1] ); + $stdout = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); - $STDERR = stream_get_contents( $pipes[2] ); + $stderr = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); return new ProcessRun( array( - 'STDOUT' => $STDOUT, - 'STDERR' => $STDERR, + 'stdout' => $stdout, + 'stderr' => $stderr, 'return_code' => proc_close( $proc ), 'command' => $this->command, 'cwd' => $cwd, From 837c4984e0578d16121f6193892b6578271b6275 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:05:10 +0000 Subject: [PATCH 3042/4858] Couple more instances need to be lowercase --- php/WP_CLI/Process.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index 7a0add5bca..88f05666b9 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -51,7 +51,7 @@ public function run( $subdir = '' ) { public function run_check( $subdir = '' ) { $r = $this->run( $subdir ); - if ( $r->return_code || !empty( $r->STDERR ) ) { + if ( $r->return_code || !empty( $r->stderr ) ) { throw new \RuntimeException( $r ); } @@ -70,7 +70,7 @@ public function __construct( $props ) { public function __toString() { $out = "$ $this->command\n"; - $out .= "$this->STDOUT\n$this->STDERR"; + $out .= "$this->stdout\n$this->stderr"; $out .= "cwd: $this->cwd\n"; $out .= "exit status: $this->return_code"; From 282b6b9782c115cca2814d0418a88b225328dc61 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:05:32 +0000 Subject: [PATCH 3043/4858] Deprecate this argument, which should be a part of construct anyway --- features/bootstrap/FeatureContext.php | 9 +++++---- php/WP_CLI/Process.php | 9 +++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 5227497087..994313bf16 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -153,7 +153,7 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - public function proc( $command, $assoc_args = array() ) { + public function proc( $command, $assoc_args = array(), $path = '' ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); @@ -162,7 +162,8 @@ public function proc( $command, $assoc_args = array() ) { $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; } - return Process::create( $command, $this->variables['RUN_DIR'], $env ); + $path = $this->variables['RUN_DIR'] + $path; + return Process::create( $command, $path, $env ); } public function move_files( $src, $dest ) { @@ -192,7 +193,7 @@ public function create_config( $subdir = '' ) { $params['dbprefix'] = $subdir ?: 'wp_'; $params['skip-salts'] = true; - $this->proc( 'wp core config', $params )->run_check( $subdir ); + $this->proc( 'wp core config', $params, $subdir )->run_check(); } public function install_wp( $subdir = '' ) { @@ -210,7 +211,7 @@ public function install_wp( $subdir = '' ) { 'admin_password' => 'password1' ); - $this->proc( 'wp core install', $install_args )->run_check( $subdir ); + $this->proc( 'wp core install', $install_args, $subdir )->run_check(); } } diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index 88f05666b9..e17ba66e26 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -18,11 +18,8 @@ public static function create( $command, $cwd = null, $env = array() ) { private function __construct() {} - public function run( $subdir = '' ) { + public function run() { $cwd = $this->cwd; - if ( $subdir ) { - $cwd .= '/' . $subdir; - } $descriptors = array( 0 => STDIN, @@ -48,8 +45,8 @@ public function run( $subdir = '' ) { ) ); } - public function run_check( $subdir = '' ) { - $r = $this->run( $subdir ); + public function run_check() { + $r = $this->run(); if ( $r->return_code || !empty( $r->stderr ) ) { throw new \RuntimeException( $r ); From d311435472ea5b4436725a2c1c983489ba71c680 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:08:54 +0000 Subject: [PATCH 3044/4858] Backwards compat, because a lot of stuff breaks --- php/WP_CLI/Process.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index e17ba66e26..712bf475a6 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -62,6 +62,11 @@ class ProcessRun { public function __construct( $props ) { foreach ( $props as $key => $value ) { $this->$key = $value; + // Backwards compat + if ( in_array( $key, array( 'stdout', 'stderr' ) ) ) { + $key = strtoupper( $key ); + $this->$key = $value; + } } } From c8cd93788841318d1fdefa7bec17e933571a4380 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:10:48 +0000 Subject: [PATCH 3045/4858] Revert "Only constants should be uppercased" This reverts commit da7462a11c983f7e01ad18da0548d5a9c3d4f379. --- php/WP_CLI/Process.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index 712bf475a6..d5d73576ef 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -29,15 +29,15 @@ public function run() { $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, $this->env ); - $stdout = stream_get_contents( $pipes[1] ); + $STDOUT = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); - $stderr = stream_get_contents( $pipes[2] ); + $STDERR = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); return new ProcessRun( array( - 'stdout' => $stdout, - 'stderr' => $stderr, + 'STDOUT' => $STDOUT, + 'STDERR' => $STDERR, 'return_code' => proc_close( $proc ), 'command' => $this->command, 'cwd' => $cwd, From 3a27f2bd9c7c73b03705e2eaba92d3166f2c5c20 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:11:10 +0000 Subject: [PATCH 3046/4858] Revert "Couple more instances need to be lowercase" This reverts commit 837c4984e0578d16121f6193892b6578271b6275. --- php/WP_CLI/Process.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index d5d73576ef..2f45f8f0fc 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -48,7 +48,7 @@ public function run() { public function run_check() { $r = $this->run(); - if ( $r->return_code || !empty( $r->stderr ) ) { + if ( $r->return_code || !empty( $r->STDERR ) ) { throw new \RuntimeException( $r ); } @@ -72,7 +72,7 @@ public function __construct( $props ) { public function __toString() { $out = "$ $this->command\n"; - $out .= "$this->stdout\n$this->stderr"; + $out .= "$this->STDOUT\n$this->STDERR"; $out .= "cwd: $this->cwd\n"; $out .= "exit status: $this->return_code"; From 2474fea3a1ad7763eceb7f0c6bd09e1a8ecdaf28 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:13:28 +0000 Subject: [PATCH 3047/4858] Properly handle `$path` --- features/bootstrap/FeatureContext.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 994313bf16..7a4c24e382 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -153,7 +153,7 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - public function proc( $command, $assoc_args = array(), $path = '' ) { + public function proc( $command, $assoc_args = array(), $path = null ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); @@ -162,7 +162,12 @@ public function proc( $command, $assoc_args = array(), $path = '' ) { $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; } - $path = $this->variables['RUN_DIR'] + $path; + if ( $path ) { + $path = $this->variables['RUN_DIR'] + $path; + } else { + $path = $this->variables['RUN_DIR']; + } + return Process::create( $command, $path, $env ); } From 563b84b38cd85ddf7c64de5d647fb62b4034e359 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 18 Jul 2014 20:13:51 +0000 Subject: [PATCH 3048/4858] Revert "Backwards compat, because a lot of stuff breaks" This reverts commit d311435472ea5b4436725a2c1c983489ba71c680. --- php/WP_CLI/Process.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index 2f45f8f0fc..eb8ae700c0 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -62,11 +62,6 @@ class ProcessRun { public function __construct( $props ) { foreach ( $props as $key => $value ) { $this->$key = $value; - // Backwards compat - if ( in_array( $key, array( 'stdout', 'stderr' ) ) ) { - $key = strtoupper( $key ); - $this->$key = $value; - } } } From d921af93be02de5216777ae700d93b585b70160c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 19 Jul 2014 19:44:53 +0000 Subject: [PATCH 3049/4858] Lowercase for STDOUT and STDERR as variables --- features/steps/given.php | 2 ++ features/steps/then.php | 15 +++++++++++++++ php/WP_CLI/Process.php | 10 +++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/features/steps/given.php b/features/steps/given.php index 5f88f60a82..3e7a7b26d8 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -104,6 +104,8 @@ function ( $world, TableNode $table ) { $steps->Given( '/^save (STDOUT|STDERR) ([\'].+[^\'])?as \{(\w+)\}$/', function ( $world, $stream, $output_filter, $key ) { + $stream = strtolower( $stream ); + if ( $output_filter ) { $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; if ( false !== preg_match( $output_filter, $world->result->$stream, $matches ) ) diff --git a/features/steps/then.php b/features/steps/then.php index ef11a52bbb..819899ff91 100644 --- a/features/steps/then.php +++ b/features/steps/then.php @@ -13,6 +13,9 @@ function ( $world, $return_code ) { $steps->Then( '/^(STDOUT|STDERR) should (be|contain|not contain):$/', function ( $world, $stream, $action, PyStringNode $expected ) { + + $stream = strtolower( $stream ); + $expected = $world->replace_variables( (string) $expected ); checkString( $world->result->$stream, $expected, $action, $world->result ); @@ -21,12 +24,18 @@ function ( $world, $stream, $action, PyStringNode $expected ) { $steps->Then( '/^(STDOUT|STDERR) should be a number$/', function ( $world, $stream ) { + + $stream = strtolower( $stream ); + assertNumeric( trim( $world->result->$stream, "\n" ) ); } ); $steps->Then( '/^(STDOUT|STDERR) should not be a number$/', function ( $world, $stream ) { + + $stream = strtolower( $stream ); + assertNotNumeric( trim( $world->result->$stream, "\n" ) ); } ); @@ -106,6 +115,9 @@ function ( $world, TableNode $expected ) { $steps->Then( '/^(STDOUT|STDERR) should be empty$/', function ( $world, $stream ) { + + $stream = strtolower( $stream ); + if ( !empty( $world->result->$stream ) ) { throw new \Exception( $world->result ); } @@ -114,6 +126,9 @@ function ( $world, $stream ) { $steps->Then( '/^(STDOUT|STDERR) should not be empty$/', function ( $world, $stream ) { + + $stream = strtolower( $stream ); + if ( '' === rtrim( $world->result->$stream, "\n" ) ) { throw new Exception( $world->result ); } diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index eb8ae700c0..8245e47145 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -29,15 +29,15 @@ public function run() { $proc = proc_open( $this->command, $descriptors, $pipes, $cwd, $this->env ); - $STDOUT = stream_get_contents( $pipes[1] ); + $stdout = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); - $STDERR = stream_get_contents( $pipes[2] ); + $stderr = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); return new ProcessRun( array( - 'STDOUT' => $STDOUT, - 'STDERR' => $STDERR, + 'stdout' => $stdout, + 'stderr' => $stderr, 'return_code' => proc_close( $proc ), 'command' => $this->command, 'cwd' => $cwd, @@ -67,7 +67,7 @@ public function __construct( $props ) { public function __toString() { $out = "$ $this->command\n"; - $out .= "$this->STDOUT\n$this->STDERR"; + $out .= "$this->stdout\n$this->stderr"; $out .= "cwd: $this->cwd\n"; $out .= "exit status: $this->return_code"; From 77eda6203a6ca24c847c1b7b8c752025c6d62734 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 19 Jul 2014 19:46:41 +0000 Subject: [PATCH 3050/4858] Few more instances need to be lowercased --- features/steps/then.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/steps/then.php b/features/steps/then.php index 819899ff91..f2e15fb323 100644 --- a/features/steps/then.php +++ b/features/steps/then.php @@ -42,7 +42,7 @@ function ( $world, $stream ) { $steps->Then( '/^STDOUT should be a table containing rows:$/', function ( $world, TableNode $expected ) { - $output = $world->result->STDOUT; + $output = $world->result->stdout; $actual_rows = explode( "\n", rtrim( $output, "\n" ) ); $expected_rows = array(); @@ -56,7 +56,7 @@ function ( $world, TableNode $expected ) { $steps->Then( '/^STDOUT should end with a table containing rows:$/', function ( $world, TableNode $expected ) { - $output = $world->result->STDOUT; + $output = $world->result->stdout; $actual_rows = explode( "\n", rtrim( $output, "\n" ) ); $expected_rows = array(); @@ -75,7 +75,7 @@ function ( $world, TableNode $expected ) { $steps->Then( '/^STDOUT should be JSON containing:$/', function ( $world, PyStringNode $expected ) { - $output = $world->result->STDOUT; + $output = $world->result->stdout; $expected = $world->replace_variables( (string) $expected ); if ( !checkThatJsonStringContainsJsonString( $output, $expected ) ) { @@ -85,7 +85,7 @@ function ( $world, PyStringNode $expected ) { $steps->Then( '/^STDOUT should be a JSON array containing:$/', function ( $world, PyStringNode $expected ) { - $output = $world->result->STDOUT; + $output = $world->result->stdout; $expected = $world->replace_variables( (string) $expected ); $actualValues = json_decode( $output ); @@ -99,7 +99,7 @@ function ( $world, PyStringNode $expected ) { $steps->Then( '/^STDOUT should be CSV containing:$/', function ( $world, TableNode $expected ) { - $output = $world->result->STDOUT; + $output = $world->result->stdout; $expected_rows = $expected->getRows(); foreach ( $expected as &$row ) { From 445ccd55a6deb20b3d0269116192096e2276f43b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 19 Jul 2014 19:50:28 +0000 Subject: [PATCH 3051/4858] Coding standards --- features/bootstrap/FeatureContext.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 7a4c24e382..de58f738ce 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -184,7 +184,9 @@ public function add_line_to_wp_config( &$wp_config_code, $line ) { public function download_wp( $subdir = '' ) { $dest_dir = $this->variables['RUN_DIR'] . "/$subdir"; - if ( $subdir ) mkdir( $dest_dir ); + if ( $subdir ) { + mkdir( $dest_dir ); + } Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ), null, self::get_process_env_variables() )->run_check(); From 8e7f082e6f10afb4509ee34a1e97ed9b4be880c5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 19 Jul 2014 19:51:36 +0000 Subject: [PATCH 3052/4858] Fix string concatenation --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index de58f738ce..6881e6d22b 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -163,7 +163,7 @@ public function proc( $command, $assoc_args = array(), $path = null ) { } if ( $path ) { - $path = $this->variables['RUN_DIR'] + $path; + $path = rtrim( $this->variables['RUN_DIR'], '/' ) . '/' . $path; } else { $path = $this->variables['RUN_DIR']; } From ee8a2d54bc381e85c3072dc83115f0587a6d5696 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 19 Jul 2014 20:03:37 +0000 Subject: [PATCH 3053/4858] Pass subdir when instantiating --- features/steps/when.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/steps/when.php b/features/steps/when.php index 68ff28baf5..55651d9b39 100644 --- a/features/steps/when.php +++ b/features/steps/when.php @@ -4,14 +4,14 @@ Behat\Gherkin\Node\TableNode, WP_CLI\Process; -function invoke_proc( $proc, $mode, $subdir = null ) { +function invoke_proc( $proc, $mode ) { $map = array( 'run' => 'run_check', 'try' => 'run' ); $method = $map[ $mode ]; - return $proc->$method( $subdir ); + return $proc->$method(); } $steps->When( '/^I (run|try) `([^`]+)`$/', @@ -24,7 +24,7 @@ function ( $world, $mode, $cmd ) { $steps->When( "/^I (run|try) `([^`]+)` from '([^\s]+)'$/", function ( $world, $mode, $cmd, $subdir ) { $cmd = $world->replace_variables( $cmd ); - $world->result = invoke_proc( $world->proc( $cmd ), $mode, $subdir ); + $world->result = invoke_proc( $world->proc( $cmd, array(), $subdir ), $mode ); } ); From 3c542ab6f74ae8b07cfe99c53e1e8444d9dcd7f5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 19 Jul 2014 20:04:37 +0000 Subject: [PATCH 3054/4858] Better way of building the string --- features/bootstrap/FeatureContext.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 6881e6d22b..803c3379f1 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -153,7 +153,7 @@ public function drop_db() { self::run_sql( "DROP DATABASE IF EXISTS $dbname" ); } - public function proc( $command, $assoc_args = array(), $path = null ) { + public function proc( $command, $assoc_args = array(), $path = '' ) { if ( !empty( $assoc_args ) ) $command .= Utils\assoc_args_to_str( $assoc_args ); @@ -162,12 +162,7 @@ public function proc( $command, $assoc_args = array(), $path = null ) { $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; } - if ( $path ) { - $path = rtrim( $this->variables['RUN_DIR'], '/' ) . '/' . $path; - } else { - $path = $this->variables['RUN_DIR']; - } - + $path = "{$this->variables['RUN_DIR']}/{$path}"; return Process::create( $command, $path, $env ); } From 01791f19ff1e0a57f55e4e6519a45ee9ab0fadd7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 12:37:23 +0000 Subject: [PATCH 3055/4858] Doc coverage for `CommandWithDBObject` --- php/WP_CLI/CommandWithDBObject.php | 51 +++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index de831bab64..e7fed7a085 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -13,6 +13,14 @@ abstract class CommandWithDBObject extends \WP_CLI_Command { protected $obj_id_key = 'ID'; protected $obj_fields = null; + /** + * Create a given database object. + * Exits with status. + * + * @param array $args Arguments passed to command. Generally unused. + * @param array $assoc_args Parameters passed to command to be passed to callback. + * @param string $callback Function used to create object. + */ protected function _create( $args, $assoc_args, $callback ) { unset( $assoc_args[ $this->obj_id_key ] ); @@ -28,6 +36,14 @@ protected function _create( $args, $assoc_args, $callback ) { \WP_CLI::success( "Created $this->obj_type $obj_id." ); } + /** + * Update a given database object. + * Exits with status. + * + * @param array $args Collection of one or more object ids to update. + * @param array $assoc_args Fields => values to update on each object. + * @param string $callback Function used to update object. + */ protected function _update( $args, $assoc_args, $callback ) { $status = 0; @@ -47,6 +63,14 @@ protected function _update( $args, $assoc_args, $callback ) { exit( $status ); } + /** + * Delete a given database object. + * Exits with status. + * + * @param array $args Collection of one or more object ids to delete. + * @param array $assoc_args Any arguments needed for the callback function. + * @param string $callback Function used to delete object. + */ protected function _delete( $args, $assoc_args, $callback ) { $status = 0; @@ -58,6 +82,13 @@ protected function _delete( $args, $assoc_args, $callback ) { exit( $status ); } + /** + * Format callback response to consistent format. + * + * @param WP_Error|true $r Response from CRUD callback. + * @param string $success_msg + * @return array + */ protected function wp_error_to_resp( $r, $success_msg ) { if ( is_wp_error( $r ) ) return array( 'error', $r->get_error_message() ); @@ -65,6 +96,12 @@ protected function wp_error_to_resp( $r, $success_msg ) { return array( 'success', $success_msg ); } + /** + * Display success or warning based on response; return proper exit code. + * + * @param array $r Formatted from a CRUD callback. + * @return int $status + */ protected function success_or_failure( $r ) { list( $type, $msg ) = $r; @@ -79,10 +116,22 @@ protected function success_or_failure( $r ) { return $status; } + /** + * Get Formatter object based on supplied parameters. + * + * @param array $assoc_args Parameters passed to command. Determines formatting. + * @return \WP_CLI\Formatter + */ protected function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); } - + + /** + * Given a callback, display the URL for one or more objects. + * + * @param array $args One or more object references. + * @param string $callback Function to get URL for the object. + */ protected function _url( $args, $callback ) { foreach ( $args as $obj_id ) { $object = $this->fetcher->get_check( $obj_id ); From fc227023ac1446600758c61715250f4b6fd66b75 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 12:40:26 +0000 Subject: [PATCH 3056/4858] Param doc coverage for `CommandWithDBObject` --- php/WP_CLI/CommandWithDBObject.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index e7fed7a085..f7f99ff7f7 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -9,8 +9,19 @@ */ abstract class CommandWithDBObject extends \WP_CLI_Command { + /** + * @param string $object_type WordPress' expected name for the object. + */ protected $obj_type; + + /** + * @param string $obj_id_key Key representing object's PK field in db. + */ protected $obj_id_key = 'ID'; + + /** + * @param array $obj_fields Default fields to display for each object. + */ protected $obj_fields = null; /** From 8760566abf333b6f973703e68dcd00637344216e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 12:43:33 +0000 Subject: [PATCH 3057/4858] Mark these explicitly `public` --- php/class-wp-cli.php | 52 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 3ec3d0cb87..63fb63f38a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -22,7 +22,7 @@ class WP_CLI { * * @param object $logger */ - static function set_logger( $logger ) { + public static function set_logger( $logger ) { self::$logger = $logger; } @@ -31,7 +31,7 @@ static function set_logger( $logger ) { * * @return \WP_CLI\Configurator */ - static function get_configurator() { + public static function get_configurator() { static $configurator; if ( !$configurator ) { @@ -41,7 +41,7 @@ static function get_configurator() { return $configurator; } - static function get_root_command() { + public static function get_root_command() { static $root; if ( !$root ) { @@ -51,7 +51,7 @@ static function get_root_command() { return $root; } - static function get_runner() { + public static function get_runner() { static $runner; if ( !$runner ) { @@ -92,7 +92,7 @@ public static function get_cache() { /** * Set the context in which WP-CLI should be run */ - static function set_url( $url ) { + public static function set_url( $url ) { $url_parts = Utils\parse_url( $url ); self::set_url_params( $url_parts ); } @@ -119,7 +119,7 @@ private static function set_url_params( $url_parts ) { /** * @return WpHttpCacheManager */ - static function get_http_cache_manager() { + public static function get_http_cache_manager() { static $http_cacher; if ( !$http_cacher ) { @@ -129,14 +129,14 @@ static function get_http_cache_manager() { return $http_cacher; } - static function colorize( $string ) { + public static function colorize( $string ) { return \cli\Colors::colorize( $string, self::get_runner()->in_color() ); } /** * Schedule a callback to be executed at a certain point (before WP is loaded). */ - static function add_hook( $when, $callback ) { + public static function add_hook( $when, $callback ) { if ( in_array( $when, self::$hooks_passed ) ) call_user_func( $callback ); @@ -146,7 +146,7 @@ static function add_hook( $when, $callback ) { /** * Execute registered callbacks. */ - static function do_hook( $when ) { + public static function do_hook( $when ) { self::$hooks_passed[] = $when; if ( !isset( self::$hooks[ $when ] ) ) @@ -165,7 +165,7 @@ static function do_hook( $when ) { * @param array $args An associative array with additional parameters: * 'before_invoke' => callback to execute before invoking the command */ - static function add_command( $name, $class, $args = array() ) { + public static function add_command( $name, $class, $args = array() ) { if ( isset( $args['before_invoke'] ) ) { self::add_hook( "before_invoke:$name", $args['before_invoke'] ); } @@ -206,7 +206,7 @@ static function add_command( $name, $class, $args = array() ) { * * @param string $message */ - static function line( $message = '' ) { + public static function line( $message = '' ) { echo $message . "\n"; } @@ -215,7 +215,7 @@ static function line( $message = '' ) { * * @param string $message */ - static function log( $message ) { + public static function log( $message ) { self::$logger->info( $message ); } @@ -224,7 +224,7 @@ static function log( $message ) { * * @param string $message */ - static function success( $message ) { + public static function success( $message ) { self::$logger->success( $message ); } @@ -233,7 +233,7 @@ static function success( $message ) { * * @param string $message */ - static function warning( $message ) { + public static function warning( $message ) { self::$logger->warning( self::error_to_string( $message ) ); } @@ -242,7 +242,7 @@ static function warning( $message ) { * * @param string $message */ - static function error( $message ) { + public static function error( $message ) { if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) ) { self::$logger->error( self::error_to_string( $message ) ); } @@ -253,7 +253,7 @@ static function error( $message ) { /** * Ask for confirmation before running a destructive operation. */ - static function confirm( $question, $assoc_args = array() ) { + public static function confirm( $question, $assoc_args = array() ) { if ( !isset( $assoc_args['yes'] ) ) { fwrite( STDOUT, $question . " [y/n] " ); @@ -293,7 +293,7 @@ public static function get_value_from_arg_or_stdin( $args, $index ) { * @param mixed $value * @param array $assoc_args */ - static function read_value( $raw_value, $assoc_args = array() ) { + public static function read_value( $raw_value, $assoc_args = array() ) { if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { $value = json_decode( $raw_value, true ); if ( null === $value ) { @@ -312,7 +312,7 @@ static function read_value( $raw_value, $assoc_args = array() ) { * @param mixed $value * @param array $assoc_args */ - static function print_value( $value, $assoc_args = array() ) { + public static function print_value( $value, $assoc_args = array() ) { if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { $value = json_encode( $value ); } elseif ( is_array( $value ) || is_object( $value ) ) { @@ -328,7 +328,7 @@ static function print_value( $value, $assoc_args = array() ) { * @param mixed $errors * @return string */ - static function error_to_string( $errors ) { + public static function error_to_string( $errors ) { if ( is_string( $errors ) ) { return $errors; } @@ -352,7 +352,7 @@ static function error_to_string( $errors ) { * * @return int|ProcessRun The command exit status, or a ProcessRun instance */ - static function launch( $command, $exit_on_error = true, $return_detailed = false ) { + public static function launch( $command, $exit_on_error = true, $return_detailed = false ) { $proc = Process::create( $command ); $results = $proc->run(); @@ -378,7 +378,7 @@ static function launch( $command, $exit_on_error = true, $return_detailed = fals * * @return int|ProcessRun The command exit status, or a ProcessRun instance */ - static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false ) { + public static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false ) { $reused_runtime_args = array( 'path', 'url', @@ -422,7 +422,7 @@ private static function get_php_binary() { return 'php'; } - static function get_config( $key = null ) { + public static function get_config( $key = null ) { if ( null === $key ) { return self::get_runner()->config; } @@ -441,7 +441,7 @@ static function get_config( $key = null ) { * @param array * @param array */ - static function run_command( $args, $assoc_args = array() ) { + public static function run_command( $args, $assoc_args = array() ) { self::get_runner()->run_command( $args, $assoc_args ); } @@ -449,17 +449,17 @@ static function run_command( $args, $assoc_args = array() ) { // DEPRECATED STUFF - static function add_man_dir() { + public static function add_man_dir() { trigger_error( 'WP_CLI::add_man_dir() is deprecated. Add docs inline.', E_USER_WARNING ); } // back-compat - static function out( $str ) { + public static function out( $str ) { fwrite( STDOUT, $str ); } // back-compat - static function addCommand( $name, $class ) { + public static function addCommand( $name, $class ) { trigger_error( sprintf( 'wp %s: %s is deprecated. use WP_CLI::add_command() instead.', $name, __FUNCTION__ ), E_USER_WARNING ); self::add_command( $name, $class ); From 94f600a3e91a1e0f9e413ab10ff461b8e74e0638 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 13:48:08 +0000 Subject: [PATCH 3058/4858] PHPdoc for standard logger --- php/WP_CLI/Loggers/Regular.php | 50 ++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index b3ad21213c..f5dda04fcb 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -2,35 +2,75 @@ namespace WP_CLI\Loggers; +/** + * Default logger for success, warning, error, and standard messages. + */ class Regular { + /** + * @param bool $in_color Whether or not to Colorize strings. + */ function __construct( $in_color ) { $this->in_color = $in_color; } + /** + * Write a string to a resource. + * + * @param resource $handle Commonly STDOUT or STDERR. + * @param string $str Message to write. + */ protected function write( $handle, $str ) { fwrite( $handle, $str ); } + /** + * Output one line of message to a resource. + * + * @param string $message Message to write. + * @param string $label Prefix message with a label. + * @param string $color Colorize label with a given color. + * @param resource $handle Resource to write to. Defaults to STDOUT. + */ private function _line( $message, $label, $color, $handle = STDOUT ) { $label = \cli\Colors::colorize( "$color$label:%n", $this->in_color ); $this->write( $handle, "$label $message\n" ); } - function info( $message ) { + /** + * Write an informational message to STDOUT. + * + * @param string $message Message to write. + */ + public function info( $message ) { $this->write( STDOUT, $message . "\n" ); } - function success( $message ) { + /** + * Write a success message, prefixed with "Success: ". + * + * @param string $message Message to write. + */ + public function success( $message ) { $this->_line( $message, 'Success', '%G' ); } - function warning( $message ) { + /** + * Write a warning message to STDERR, prefixed with "Warning: ". + * + * @param string $message Message to write. + */ + public function warning( $message ) { $this->_line( $message, 'Warning', '%C', STDERR ); } - function error( $message ) { + /** + * Write an message to STDERR, prefixed with "Error: ". + * + * @param string $message Message to write. + */ + public function error( $message ) { $this->_line( $message, 'Error', '%R', STDERR ); } -} +} From ca34d8b7069bbefbcb1b27ff614b585ae298c703 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 13:50:50 +0000 Subject: [PATCH 3059/4858] PHPdoc for the Quiet logger --- php/WP_CLI/Loggers/Quiet.php | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 6f32fbef33..6ccbb4029b 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -2,22 +2,45 @@ namespace WP_CLI\Loggers; +/** + * Quiet logger only logs errors. + */ class Quiet { - function info( $message ) { + /** + * Informational messages aren't logged. + * + * @param string $message Message to write. + */ + public function info( $message ) { // nothing } - function success( $message ) { + /** + * Success messages aren't logged. + * + * @param string $message Message to write. + */ + public function success( $message ) { // nothing } - function warning( $message ) { + /** + * Warning messages aren't logged. + * + * @param string $message Message to write. + */ + public function warning( $message ) { // nothing } - function error( $message ) { + /** + * Write an error message to STDERR, prefixed with "Error: ". + * + * @param string $message Message to write. + */ + public function error( $message ) { fwrite( STDERR, \WP_CLI::colorize( "%RError:%n $message\n" ) ); } -} +} From f82103f13b145eb0295ade266f16b96c148e6b0a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 14:37:00 +0000 Subject: [PATCH 3060/4858] These two should be explicitly public --- php/WP_CLI/Configurator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 92bffd9d52..9d79b110b2 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -112,7 +112,7 @@ private function unmix_assoc_args( $mixed_args ) { return array( $assoc_args, $runtime_config ); } - function merge_yml( $path ) { + public function merge_yml( $path ) { foreach ( self::load_yml( $path ) as $key => $value ) { if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { $this->extra_config[ $key ] = $value; @@ -125,7 +125,7 @@ function merge_yml( $path ) { } } - function merge_array( $config ) { + public function merge_array( $config ) { foreach ( $this->spec as $key => $details ) { if ( false !== $details['runtime'] && isset( $config[ $key ] ) ) { $value = $config[ $key ]; From cc23fa99d23ee72aba84b2aed9313777ccdddb1a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 14:42:40 +0000 Subject: [PATCH 3061/4858] PHPdoc for `Configurator` --- php/WP_CLI/Configurator.php | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 9d79b110b2..533629a42c 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -9,11 +9,24 @@ */ class Configurator { + /** + * @param array $spec Configurator argument specification. + */ private $spec; + /** + * @param array $config Values for keys defined in Configurator spec. + */ private $config = array(); + + /** + * @param array $extra_config Extra config values not specified in spec. + */ private $extra_config = array(); + /** + * @param string $path Path to config spec file. + */ function __construct( $path ) { $this->spec = include $path; @@ -86,6 +99,12 @@ public static function extract_assoc( $arguments ) { return array( $positional_args, $assoc_args ); } + /** + * Separate runtime parameters from command-specific parameters. + * + * @param array $mixed_args + * @return array + */ private function unmix_assoc_args( $mixed_args ) { $assoc_args = $runtime_config = array(); @@ -112,6 +131,11 @@ private function unmix_assoc_args( $mixed_args ) { return array( $assoc_args, $runtime_config ); } + /** + * Load a YAML file of parameters into scope. + * + * @param string $path Path to YAML file. + */ public function merge_yml( $path ) { foreach ( self::load_yml( $path ) as $key => $value ) { if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { @@ -125,6 +149,11 @@ public function merge_yml( $path ) { } } + /** + * Merge an array of values into the configurator config. + * + * @param array $config + */ public function merge_array( $config ) { foreach ( $this->spec as $key => $details ) { if ( false !== $details['runtime'] && isset( $config[ $key ] ) ) { @@ -179,10 +208,16 @@ private static function arrayify( &$val ) { } } + /** + * Make a path absolute. + * + * @param string $path Path to file. + * @param string $base Base path to prepend. + */ private static function absolutize( &$path, $base ) { if ( !empty( $path ) && !\WP_CLI\Utils\is_path_absolute( $path ) ) { $path = $base . DIRECTORY_SEPARATOR . $path; } } -} +} From 00cb543253538a661859706e7f02b77bc3a9f167 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 14:49:44 +0000 Subject: [PATCH 3062/4858] PHPdoc for `DocParser` --- php/WP_CLI/DocParser.php | 49 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index 29e51e66a2..0166fca492 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -2,14 +2,30 @@ namespace WP_CLI; +/** + * Parse command attributes from its PHPdoc. + * Used to determine execution characteristics (arguments, etc.). + */ class DocParser { + /** + * @param string $docComment PHPdoc command for the command. + */ protected $docComment; - function __construct( $docComment ) { + /** + * @param string $docComment + */ + public function __construct( $docComment ) { $this->docComment = self::remove_decorations( $docComment ); } + /** + * Remove unused cruft from PHPdoc comment. + * + * @param string $comment PHPdoc comment. + * @return string + */ private static function remove_decorations( $comment ) { $comment = preg_replace( '|^/\*\*[\r\n]+|', '', $comment ); $comment = preg_replace( '|\n[\t ]*\*/$|', '', $comment ); @@ -18,14 +34,24 @@ private static function remove_decorations( $comment ) { return $comment; } - function get_shortdesc() { + /** + * Get the command's short description (e.g. summary). + * + * @return string + */ + public function get_shortdesc() { if ( !preg_match( '|^([^@][^\n]+)\n*|', $this->docComment, $matches ) ) return ''; return $matches[1]; } - function get_longdesc() { + /** + * Get the command's full description + * + * @return string + */ + public function get_longdesc() { $shortdesc = $this->get_shortdesc(); if ( !$shortdesc ) return ''; @@ -44,14 +70,25 @@ function get_longdesc() { return $longdesc; } - function get_tag( $name ) { + /** + * Get the value for a given tag (e.g. "@alias" or "@subcommand") + * + * @param string $name Name for the tag, without '@' + * @return string + */ + public function get_tag( $name ) { if ( preg_match( '|^@' . $name . '\s+([a-z-_]+)|m', $this->docComment, $matches ) ) return $matches[1]; return ''; } - function get_synopsis() { + /** + * Get the command's synopsis. + * + * @return string + */ + public function get_synopsis() { if ( !preg_match( '|^@synopsis\s+(.+)|m', $this->docComment, $matches ) ) return ''; @@ -88,5 +125,5 @@ public function get_param_desc( $key ) { return ''; } -} +} From f51c3c1dbf1975f73e6c88dd2fcf9b25935705f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 14:51:48 +0000 Subject: [PATCH 3063/4858] Params are passed to methods --- php/WP_CLI/CommandWithDBObject.php | 6 +++--- php/WP_CLI/Configurator.php | 6 +++--- php/WP_CLI/DocParser.php | 2 +- php/WP_CLI/Fetchers/Base.php | 2 +- php/WP_CLI/Fetchers/Comment.php | 2 +- php/WP_CLI/Fetchers/Plugin.php | 2 +- php/WP_CLI/Fetchers/Post.php | 2 +- php/WP_CLI/Fetchers/Site.php | 2 +- php/WP_CLI/Fetchers/Theme.php | 2 +- php/WP_CLI/Fetchers/User.php | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index f7f99ff7f7..90adb0933f 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -10,17 +10,17 @@ abstract class CommandWithDBObject extends \WP_CLI_Command { /** - * @param string $object_type WordPress' expected name for the object. + * @var string $object_type WordPress' expected name for the object. */ protected $obj_type; /** - * @param string $obj_id_key Key representing object's PK field in db. + * @var string $obj_id_key Key representing object's PK field in db. */ protected $obj_id_key = 'ID'; /** - * @param array $obj_fields Default fields to display for each object. + * @var array $obj_fields Default fields to display for each object. */ protected $obj_fields = null; diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 533629a42c..f8120926ff 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -10,17 +10,17 @@ class Configurator { /** - * @param array $spec Configurator argument specification. + * @var array $spec Configurator argument specification. */ private $spec; /** - * @param array $config Values for keys defined in Configurator spec. + * @var array $config Values for keys defined in Configurator spec. */ private $config = array(); /** - * @param array $extra_config Extra config values not specified in spec. + * @var array $extra_config Extra config values not specified in spec. */ private $extra_config = array(); diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index 0166fca492..06d57d328d 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -9,7 +9,7 @@ class DocParser { /** - * @param string $docComment PHPdoc command for the command. + * @var string $docComment PHPdoc command for the command. */ protected $docComment; diff --git a/php/WP_CLI/Fetchers/Base.php b/php/WP_CLI/Fetchers/Base.php index 262e1bfab1..639efe1037 100644 --- a/php/WP_CLI/Fetchers/Base.php +++ b/php/WP_CLI/Fetchers/Base.php @@ -8,7 +8,7 @@ abstract class Base { /** - * @param string $msg The message to display when an item is not found + * @var string $msg The message to display when an item is not found */ protected $msg; diff --git a/php/WP_CLI/Fetchers/Comment.php b/php/WP_CLI/Fetchers/Comment.php index 027030452c..0cf0f9a0cc 100644 --- a/php/WP_CLI/Fetchers/Comment.php +++ b/php/WP_CLI/Fetchers/Comment.php @@ -8,7 +8,7 @@ class Comment extends Base { /** - * @param string $msg Error message to use when invalid data is provided + * @var string $msg Error message to use when invalid data is provided */ protected $msg = "Could not find the comment with ID %d."; diff --git a/php/WP_CLI/Fetchers/Plugin.php b/php/WP_CLI/Fetchers/Plugin.php index 36235a85a7..5f29dfc31d 100644 --- a/php/WP_CLI/Fetchers/Plugin.php +++ b/php/WP_CLI/Fetchers/Plugin.php @@ -8,7 +8,7 @@ class Plugin extends Base { /** - * @param string $msg Error message to use when invalid data is provided + * @var string $msg Error message to use when invalid data is provided */ protected $msg = "The '%s' plugin could not be found."; diff --git a/php/WP_CLI/Fetchers/Post.php b/php/WP_CLI/Fetchers/Post.php index 402a6f1f1e..20b7d98551 100644 --- a/php/WP_CLI/Fetchers/Post.php +++ b/php/WP_CLI/Fetchers/Post.php @@ -8,7 +8,7 @@ class Post extends Base { /** - * @param string $msg Error message to use when invalid data is provided + * @var string $msg Error message to use when invalid data is provided */ protected $msg = "Could not find the post with ID %d."; diff --git a/php/WP_CLI/Fetchers/Site.php b/php/WP_CLI/Fetchers/Site.php index b3de873603..981e52b41b 100644 --- a/php/WP_CLI/Fetchers/Site.php +++ b/php/WP_CLI/Fetchers/Site.php @@ -8,7 +8,7 @@ class Site extends Base { /** - * @param string $msg Error message to use when invalid data is provided + * @var string $msg Error message to use when invalid data is provided */ protected $msg = "Could not find the site with ID %d."; diff --git a/php/WP_CLI/Fetchers/Theme.php b/php/WP_CLI/Fetchers/Theme.php index c3e3357e4e..d72a7ad12b 100644 --- a/php/WP_CLI/Fetchers/Theme.php +++ b/php/WP_CLI/Fetchers/Theme.php @@ -8,7 +8,7 @@ class Theme extends Base { /** - * @param string $msg Error message to use when invalid data is provided + * @var string $msg Error message to use when invalid data is provided */ protected $msg = "The '%s' theme could not be found."; diff --git a/php/WP_CLI/Fetchers/User.php b/php/WP_CLI/Fetchers/User.php index 5b8e0a63ae..e7fe2f93d6 100644 --- a/php/WP_CLI/Fetchers/User.php +++ b/php/WP_CLI/Fetchers/User.php @@ -8,7 +8,7 @@ class User extends Base { /** - * @param string $msg Error message to use when invalid data is provided + * @var string $msg Error message to use when invalid data is provided */ protected $msg = "Invalid user ID, email or login: '%s'"; From 681c74b4298ff5e35c60af5c7bf66435189099d1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 15:00:01 +0000 Subject: [PATCH 3064/4858] PHPdoc for `Formatter` --- php/WP_CLI/Formatter.php | 54 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 5f188a7476..7f70aa800c 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -2,11 +2,26 @@ namespace WP_CLI; +/** + * Output one or more items in a given format (e.g. table, JSON). + */ class Formatter { + /** + * @var array $args How the items should be output. + */ private $args; + + /** + * @var string $prefix Standard prefix for object fields. + */ private $prefix; + /** + * @param array $assoc_args Output format arguments. + * @param array $fields Fields to display of each item. + * @param string $prefix Check if fields have a standard prefix. + */ public function __construct( &$assoc_args, $fields = null, $prefix = false ) { $format_args = array( 'format' => 'table', @@ -29,10 +44,21 @@ public function __construct( &$assoc_args, $fields = null, $prefix = false ) { $this->prefix = $prefix; } + /** + * Magic getter for arguments. + * + * @param string $key + * @return mixed + */ public function __get( $key ) { return $this->args[ $key ]; } + /** + * Display multiple items according to the output arguments. + * + * @param array $items + */ public function display_items( $items ) { if ( $this->args['field'] ) { $this->show_single_field( $items, $this->args['field'] ); @@ -50,6 +76,11 @@ public function display_items( $items ) { } } + /** + * Display a single item according to the output arguments. + * + * @param mixed $item + */ public function display_item( $item ) { if ( isset( $this->args['field'] ) ) { $item = (object) $item; @@ -60,6 +91,11 @@ public function display_item( $item ) { } } + /** + * Format items according to arguments. + * + * @param array $items + */ private function format( $items ) { $fields = $this->args['fields']; @@ -129,6 +165,14 @@ private function show_single_field( $items, $field ) { } } + /** + * Find an object's key. + * If $prefix is set, a key with that prefix will be prioritized. + * + * @param object $item + * @param string $field + * @return string $key + */ private function find_item_key( $item, $field ) { foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { if ( ( is_object( $item ) && isset( $item->$maybe_key ) ) || ( is_array( $item ) && isset( $item[$maybe_key] ) ) ) { @@ -170,6 +214,12 @@ private static function show_multiple_fields( $data, $format ) { } + /** + * Show items in a \cli\Table. + * + * @param array $items + * @param array $fields + */ private static function show_table( $items, $fields ) { $table = new \cli\Table(); @@ -183,7 +233,7 @@ private static function show_table( $items, $fields ) { } /** - * Format an associative array as a table + * Format an associative array as a table. * * @param array $fields Fields and values to format */ @@ -203,5 +253,5 @@ private static function assoc_array_to_table( $fields ) { self::show_table( $rows, array( 'Field', 'Value' ) ); } -} +} From eb9c3e6591560f3c07c83be4a0c8722748577dc8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 15:01:15 +0000 Subject: [PATCH 3065/4858] PHPdoc for `NoOp` --- php/WP_CLI/NoOp.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/NoOp.php b/php/WP_CLI/NoOp.php index 9334aff22e..1aca5f9b31 100644 --- a/php/WP_CLI/NoOp.php +++ b/php/WP_CLI/NoOp.php @@ -2,6 +2,9 @@ namespace WP_CLI; +/** + * Escape route for not doing anything. + */ final class NoOp { function __set( $key, $value ) { From efb55b4138fb0d6e883e46993eaa00d541ce536d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 15:06:34 +0000 Subject: [PATCH 3066/4858] PHPdoc for `Process` and `ProcessRun` --- php/WP_CLI/Process.php | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Process.php b/php/WP_CLI/Process.php index 8245e47145..5be6a0d36d 100644 --- a/php/WP_CLI/Process.php +++ b/php/WP_CLI/Process.php @@ -2,8 +2,16 @@ namespace WP_CLI; +/** + * Run a system process, and learn what happened. + */ class Process { + /** + * @param string $command Command to execute. + * @param string $cwd Directory to execute the command in. + * @param array $env Environment variables to set when running the command. + */ public static function create( $command, $cwd = null, $env = array() ) { $proc = new self; @@ -18,6 +26,11 @@ public static function create( $command, $cwd = null, $env = array() ) { private function __construct() {} + /** + * Run the command. + * + * @return ProcessRun + */ public function run() { $cwd = $this->cwd; @@ -45,6 +58,11 @@ public function run() { ) ); } + /** + * Run the command, but throw an Exception on error. + * + * @return ProcessRun + */ public function run_check() { $r = $this->run(); @@ -56,15 +74,25 @@ public function run_check() { } } - +/** + * Results of an executed command. + */ class ProcessRun { + /** + * @var array $props Properties of executed command. + */ public function __construct( $props ) { foreach ( $props as $key => $value ) { $this->$key = $value; } } + /** + * Return properties of executed command as a string. + * + * @return string + */ public function __toString() { $out = "$ $this->command\n"; $out .= "$this->stdout\n$this->stderr"; @@ -73,5 +101,5 @@ public function __toString() { return $out; } -} +} From 9970e7923a25d471c17a41ade228bdec167586e3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 11:14:58 -0400 Subject: [PATCH 3067/4858] PHPdoc for Synopsis parser --- php/WP_CLI/SynopsisParser.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 3d440a000e..271af49ece 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -2,13 +2,16 @@ namespace WP_CLI; +/** + * Generate a synopsis from a command's PHPdoc arguments. + */ class SynopsisParser { /** * @param string A synopsis * @return array List of parameters */ - static function parse( $synopsis ) { + public static function parse( $synopsis ) { $tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) ); $params = array(); @@ -29,6 +32,12 @@ static function parse( $synopsis ) { return $params; } + /** + * Classify argument attributes based on its syntax. + * + * @param string $token + * @return array $param + */ private static function classify_token( $token ) { $param = array(); @@ -70,6 +79,9 @@ private static function classify_token( $token ) { /** * An optional parameter is surrounded by square brackets. + * + * @param string $token + * @return array */ private static function is_optional( $token ) { if ( '[' == substr( $token, 0, 1 ) && ']' == substr( $token, -1 ) ) { @@ -81,6 +93,9 @@ private static function is_optional( $token ) { /** * A repeating parameter is followed by an ellipsis. + * + * @param string $token + * @return array */ private static function is_repeating( $token ) { if ( '...' === substr( $token, -3 ) ) { From ad8238fc7d886829728e8d033672a361c29bd477 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 11:16:34 -0400 Subject: [PATCH 3068/4858] Example for the `SynopsisParser` --- php/WP_CLI/SynopsisParser.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 271af49ece..43b89cc80f 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -4,6 +4,8 @@ /** * Generate a synopsis from a command's PHPdoc arguments. + * Turns something like "<object-id>..." + * into [ optional=>false, type=>positional, repeating=>true, name=>object-id ] */ class SynopsisParser { From 609bb89b0c8924162ccd31c3c4df5db8766fe007 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 11:27:00 -0400 Subject: [PATCH 3069/4858] Docs for SynopsisValidator --- php/WP_CLI/SynopsisValidator.php | 39 ++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php index ea2f59394b..f2dd2e5ff6 100644 --- a/php/WP_CLI/SynopsisValidator.php +++ b/php/WP_CLI/SynopsisValidator.php @@ -7,18 +7,35 @@ */ class SynopsisValidator { + /** + * @var array $spec Structured representation of command synopsis. + */ private $spec = array(); + /** + * @param string $synopsis Command's synopsis. + */ public function __construct( $synopsis ) { $this->spec = SynopsisParser::parse( $synopsis ); } + /** + * Get any unknown arugments. + * + * @return array + */ public function get_unknown() { return array_column( $this->query_spec( array( 'type' => 'unknown', ) ), 'token' ); } + /** + * Check whether there are enough positional arguments. + * + * @param array $args Positional arguments. + * @return bool + */ public function enough_positionals( $args ) { $positional = $this->query_spec( array( 'type' => 'positional', @@ -28,12 +45,19 @@ public function enough_positionals( $args ) { return count( $args ) >= count( $positional ); } + /** + * Check for any unknown positionals. + * + * @param array $args Positional arguments. + * @return array + */ public function unknown_positionals( $args ) { $positional_repeating = $this->query_spec( array( 'type' => 'positional', 'repeating' => true, ) ); + // At least one positional supports as many as possible. if ( !empty( $positional_repeating ) ) return array(); @@ -45,7 +69,12 @@ public function unknown_positionals( $args ) { return array_slice( $args, count( $positional ) ); } - // Checks that all required keys are present and that they have values. + /** + * Check that all required keys are present and that they have values. + * + * @param array $assoc_args Parameters passed to command. + * @return array + */ public function validate_assoc( $assoc_args ) { $assoc_spec = $this->query_spec( array( 'type' => 'assoc', @@ -78,6 +107,12 @@ public function validate_assoc( $assoc_args ) { return array( $errors, $to_unset ); } + /** + * Check whether there are unknown parameters supplied. + * + * @param array $assoc_args Parameters passed to command. + * @return array|false + */ public function unknown_assoc( $assoc_args ) { $generic = $this->query_spec( array( 'type' => 'generic', @@ -124,5 +159,5 @@ private function query_spec( $args, $operator = 'AND' ) { return $filtered; } -} +} From 1ec65482c42072f41f9331cb499dc297878907f6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 20 Jul 2014 11:29:25 -0400 Subject: [PATCH 3070/4858] Couple changes to `WpHttpCacheManager` --- php/WP_CLI/WpHttpCacheManager.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/WpHttpCacheManager.php b/php/WP_CLI/WpHttpCacheManager.php index f9e9efff97..a9cad95dbf 100644 --- a/php/WP_CLI/WpHttpCacheManager.php +++ b/php/WP_CLI/WpHttpCacheManager.php @@ -16,6 +16,7 @@ class WpHttpCacheManager { * @var array map whitelisted urls to keys and ttls */ protected $whitelist = array(); + /** * @var FileCache */ @@ -32,7 +33,6 @@ public function __construct( FileCache $cache ) { add_filter( 'http_response', array($this, 'filter_http_response'), 10, 3 ); } - /** * short circuit wp http api with cached file */ @@ -65,6 +65,10 @@ public function filter_pre_http_request( $response, $args, $url ) { /** * cache wp http api downloads + * + * @param array $response + * @param array $args + * @param string $url */ public function filter_http_response( $response, $args, $url ) { // check if whitelisted @@ -121,4 +125,5 @@ public function whitelist_url( $url, $key = null, $ttl = null ) { public function is_whitelisted( $url ) { return isset( $this->whitelist[$url] ); } + } From fa1bcd8aa0b976ac74451bc77c6f20fce99974d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Mon, 21 Jul 2014 16:19:30 +0200 Subject: [PATCH 3071/4858] clarification Now I understand it also. --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 4a88d6de8e..a3c064a9fe 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -218,7 +218,7 @@ private static function get_initial_locale() { * : Set the WPLANG constant. Defaults to $wp_local_package variable. * * [--extra-php] - * : If set, the command reads additional PHP code from STDIN. + * : If set, the command copies additional PHP code into wp-config.php from STDIN. * * [--skip-salts] * : If set, keys and salts won't be generated, but should instead be passed via `--extra-php`. From 23a1ea90324694e6b32f83c4cbd448657a9e06bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Mon, 21 Jul 2014 20:37:01 +0200 Subject: [PATCH 3072/4858] DOING_CRON left in --- php/commands/core.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index a3c064a9fe..a32e886d5a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -666,15 +666,13 @@ public function version( $args = array(), $assoc_args = array() ) { * @return bool|array False on failure. An array of checksums on success. */ private static function get_core_checksums( $version, $locale ) { - $return = array(); - $url = $http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) $url = 'https' . substr( $url, 4 ); $options = array( - 'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ) + 'timeout' => 30 ); $headers = array( @@ -683,7 +681,7 @@ private static function get_core_checksums( $version, $locale ) { $response = self::_request( 'GET', $url, $headers, $options ); if ( $ssl && ! $response->success ) { - trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); + trigger_error( __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); $response = self::_request( 'GET', $http_url, $headers, $options ); } From cafee1829c8be77bd8effbd7098e12548a1901ba Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 22 Jul 2014 05:23:21 -0700 Subject: [PATCH 3073/4858] A test for #1288 --- features/core.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/core.feature b/features/core.feature index f7f1b86903..e168e5dad7 100644 --- a/features/core.feature +++ b/features/core.feature @@ -153,6 +153,7 @@ Feature: Manage WordPress installation When I run `wp core is-installed` Then STDOUT should be empty + And the wp-content/uploads directory should exist When I run `wp eval 'var_export( is_admin() );'` Then STDOUT should be: From 604e5836c4df501af72f81966b53cab31c7a5693 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 22 Jul 2014 05:34:06 -0700 Subject: [PATCH 3074/4858] Create the uploads directory during the install process --- php/commands/core.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4a88d6de8e..8f0cda1fc9 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -494,6 +494,12 @@ private function _install( $assoc_args ) { } // @codingStandardsIgnoreEnd + // Confirm the uploads directory exists + $upload_dir = wp_upload_dir(); + if ( ! empty( $upload_dir['error'] ) ) { + WP_CLI::warning( $upload_dir['error'] ); + } + return true; } From 971696e79180664b82242d7d07ecf0e94d27f8e5 Mon Sep 17 00:00:00 2001 From: David Herrera <david@alleyinteractive.com> Date: Wed, 23 Jul 2014 00:56:20 -0400 Subject: [PATCH 3075/4858] Scaffold post type args in order of documentation --- templates/post_type.mustache | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 201a2fa132..4cf479eb6c 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -1,12 +1,4 @@ register_post_type( '{{slug}}', array( - 'hierarchical' => false, - 'public' => true, - 'show_in_nav_menus' => true, - 'show_ui' => true, - 'supports' => array( 'title', 'editor' ), - 'has_archive' => true, - 'query_var' => true, - 'rewrite' => true, 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), @@ -22,4 +14,12 @@ 'parent_item_colon' => __( 'Parent {{label}}', '{{textdomain}}' ), 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), ), + 'public' => true, + 'hierarchical' => false, + 'show_ui' => true, + 'show_in_nav_menus' => true, + 'supports' => array( 'title', 'editor' ), + 'has_archive' => true, + 'rewrite' => true, + 'query_var' => true, ) ); From 0d510b84848e87aa7c4a6d8c40b4b3ee29e35ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Wed, 23 Jul 2014 16:42:17 +0200 Subject: [PATCH 3076/4858] WP_CLI::warning --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index a32e886d5a..14de43ecfd 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -681,7 +681,7 @@ private static function get_core_checksums( $version, $locale ) { $response = self::_request( 'GET', $url, $headers, $options ); if ( $ssl && ! $response->success ) { - trigger_error( __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE ); + WP_CLI::warning( 'wp-cli could not establish a secure connection to WordPress.org. Please contact your server administrator.' ); $response = self::_request( 'GET', $http_url, $headers, $options ); } From b849d079aa81631241c2180d174ed9a02201e4d4 Mon Sep 17 00:00:00 2001 From: Tom Willmot <tom@humanmade.co.uk> Date: Fri, 25 Jul 2014 13:15:31 +0100 Subject: [PATCH 3077/4858] Remove extraneous space in wp_plugin_directory_constants `wp_plugin_directory_constants( )` should be `wp_plugin_directory_constants()` --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 67ad27f981..d189f412f1 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -175,7 +175,7 @@ // Define constants that rely on the API to obtain the default value. // Define must-use plugin directory constants, which may be overridden in the sunrise.php drop-in. -wp_plugin_directory_constants( ); +wp_plugin_directory_constants(); $symlinked_plugins_supported = function_exists( 'wp_register_plugin_realpath' ); if ( $symlinked_plugins_supported ) { From f9c4f7a99f5613d1db4a7b86e99d96dfdb5cbae0 Mon Sep 17 00:00:00 2001 From: Taylor Dewey <td@tddewey.com> Date: Sun, 27 Jul 2014 12:24:54 -0700 Subject: [PATCH 3078/4858] * Add new test for Search/Replace to ensure serializd data isn't mangled, * Remove length check for strings to determine if the MYSQL version could be used. Instead just use PHP. * Change some test verbiage for clarity. * Refactor 'fast' and 'safe' to 'mysql' and 'php' in method and variable names * Change the 'safe' flag to 'precise' to better explain its purpose. --- features/search-replace.feature | 50 +++++++++++++++++++++++---------- php/commands/search-replace.php | 29 +++++++++---------- 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 95027ecef9..cd0dc39ff4 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -20,9 +20,9 @@ Feature: Do global search/replace And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` And I run `wp search-replace foo bar --network` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | Fast Replace | - | wp_2_posts | guid | 2 | Yes | - | wp_blogs | path | 1 | Yes | + | Table | Column | Replacements | Type | + | wp_2_posts | guid | 2 | SQL | + | wp_blogs | path | 1 | SQL | Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install @@ -32,8 +32,8 @@ Feature: Do global search/replace When I run `wp search-replace <flags> {SITEURL} <replacement>` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | Fast Replace | - | wp_posts | guid | 22 | Yes | + | Table | Column | Replacements | Type | + | wp_posts | guid | 22 | SQL | Examples: | replacement | flags | @@ -41,20 +41,40 @@ Feature: Do global search/replace | http://newdomain.com | | | http://newdomain.com | --dry-run | - Scenario Outline: Fast and Safe search/replace due to string length and flags + Scenario Outline: Choose replacement method (PHP or MySQL) given proper flags or data. Given a WP install And I run `wp option get siteurl` And save STDOUT as {SITEURL} - And I run `wp search-replace {SITEURL} {SITEURL}/teststring` + When I run `wp search-replace <flags> {SITEURL} http://wordpress.org` - When I run `wp search-replace <flags> {SITEURL}/teststring <replacement>` Then STDOUT should be a table containing rows: - | Table | Column | Replacements | Fast Replace | - | wp_options | option_value | 2 | <serial> | - | wp_posts | post_title | 0 | <noserial> | + | Table | Column | Replacements | Type | + | wp_options | option_value | 2 | <serial> | + | wp_posts | post_title | 0 | <noserial> | Examples: - | replacement | flags | serial | noserial | - | {SITEURL}/different | | No | Yes | - | {SITEURL}/samelength | --safe | No | No | - | {SITEURL}/samelength | | Yes | Yes | + | flags | serial | noserial | + | | PHP | SQL | + | --precise | PHP | PHP | + +Scenario Outline: Ensure search and replace uses PHP (precise) mode when serialized data is found + Given a WP install + And I run `wp post create --post_content='<input>' --porcelain` + And save STDOUT as {CONTROLPOST} + And I run `wp search-replace --precise foo bar` + And I run `wp post get {CONTROLPOST} --field=content` + And save STDOUT as {CONTROL} + And I run `wp post create --post_content='<input>' --porcelain` + And save STDOUT as {TESTPOST} + And I run `wp search-replace foo bar` + + When I run `wp post get {TESTPOST} --field=content` + Then STDOUT should be: + """ + {CONTROL} + """ + + Examples: + | input | + | a:1:{s:3:"bar";s:3:"foo";} | + | O:8:"stdClass":1:{s:1:"a";s:3:"foo";} | \ No newline at end of file diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c3a725e0c0..410fda2290 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -37,8 +37,8 @@ class Search_Replace_Command extends WP_CLI_Command { * [--dry-run] * : Show report, but don't perform the changes. * - * [--safe] - * : Use only serialization safe replacement method. + * [--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 @@ -56,7 +56,7 @@ public function __invoke( $args, $assoc_args ) { $total = 0; $report = array(); $dry_run = isset( $assoc_args['dry-run'] ); - $safe_only = isset( $assoc_args['safe'] ); + $php_only = isset( $assoc_args['precise'] ); $recurse_objects = isset( $assoc_args['recurse-objects'] ); if ( isset( $assoc_args['skip-columns'] ) ) @@ -79,34 +79,31 @@ public function __invoke( $args, $assoc_args ) { continue; } - // Can we do everything with a fast replace? - $fast_only = ( ! $safe_only && mb_strlen( $old ) === mb_strlen( $new ) ); - foreach ( $columns as $col ) { if ( in_array( $col, $skip_columns ) ) { continue; } - if ( ! $safe_only && ! $fast_only ) { + if ( ! $php_only ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } - if ( $safe_only || ( ! $fast_only && NULL !== $serialRow ) ) { - $fast = 'No'; - $count = self::handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + if ( $php_only || NULL !== $serialRow ) { + $type = 'PHP'; + $count = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); } else { - $fast = 'Yes'; - $count = self::fast_handle_col( $col, $table, $old, $new, $dry_run ); + $type = 'SQL'; + $count = self::sql_handle_col( $col, $table, $old, $new, $dry_run ); } - $report[] = array( $table, $col, $count, $fast ); + $report[] = array( $table, $col, $count, $type ); $total += $count; } } $table = new \cli\Table(); - $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Fast Replace' ) ); + $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Type' ) ); $table->setRows( $report ); $table->display(); @@ -125,7 +122,7 @@ private static function get_table_list( $args, $network ) { return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } - private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { + private static function sql_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; if ( $dry_run ) { @@ -135,7 +132,7 @@ private static function fast_handle_col( $col, $table, $old, $new, $dry_run ) { } } - private static function handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { + private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite From c76bd7c61a302778de07e60123f39b1c4ff51cd9 Mon Sep 17 00:00:00 2001 From: Taylor Dewey <td@tddewey.com> Date: Sun, 27 Jul 2014 12:31:57 -0700 Subject: [PATCH 3079/4858] Add newline at EOF --- features/search-replace.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index cd0dc39ff4..c01d64f897 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -77,4 +77,4 @@ Scenario Outline: Ensure search and replace uses PHP (precise) mode when seriali Examples: | input | | a:1:{s:3:"bar";s:3:"foo";} | - | O:8:"stdClass":1:{s:1:"a";s:3:"foo";} | \ No newline at end of file + | O:8:"stdClass":1:{s:1:"a";s:3:"foo";} | From 7b062d2edd4e0ca34fb55e61e5b47023c14b2b1e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 28 Jul 2014 07:39:16 -0700 Subject: [PATCH 3080/4858] Fix indent See #1261 --- features/search-replace.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index c01d64f897..86f67cbaaf 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -57,7 +57,7 @@ Feature: Do global search/replace | | PHP | SQL | | --precise | PHP | PHP | -Scenario Outline: Ensure search and replace uses PHP (precise) mode when serialized data is found + Scenario Outline: Ensure search and replace uses PHP (precise) mode when serialized data is found Given a WP install And I run `wp post create --post_content='<input>' --porcelain` And save STDOUT as {CONTROLPOST} From 303a06a7cbebb47c8f9cf7d655eeaa140331cdb7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 30 Jul 2014 07:10:03 -0700 Subject: [PATCH 3081/4858] Support `--quiet` config arg for `wp search-replace` Previously #1230 --- features/search-replace.feature | 6 ++++++ php/commands/search-replace.php | 16 ++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 86f67cbaaf..0b90f81aec 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -24,6 +24,12 @@ Feature: Do global search/replace | wp_2_posts | guid | 2 | SQL | | wp_blogs | path | 1 | SQL | + Scenario: Quiet search/replace + Given a WP install + + When I run `wp search-replace foo bar --quiet` + Then STDOUT should be empty + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install And I run `wp option get siteurl` diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 410fda2290..c19d8ab5ed 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -102,13 +102,17 @@ public function __invoke( $args, $assoc_args ) { } } - $table = new \cli\Table(); - $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Type' ) ); - $table->setRows( $report ); - $table->display(); + if ( ! WP_CLI::get_config( 'quiet' ) ) { - if ( !$dry_run ) - WP_CLI::success( "Made $total replacements." ); + $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." ); + + } } private static function get_table_list( $args, $network ) { From 7e83172c7fe75133fed1e3fdfb5bd4f54a69f3bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 30 Jul 2014 09:40:46 -0700 Subject: [PATCH 3082/4858] Only perform search / replace on tables registered to `$wpdb` `$wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%'` is lossy, as it matches a separate WordPress install with similar prefix (e.g. `wp_` and `wp_en_`) --- php/commands/search-replace.php | 38 ++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c19d8ab5ed..7406eca9d8 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -122,8 +122,44 @@ private static function get_table_list( $args, $network ) { return $args; $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; + $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); + + $allowed_tables = array(); + $allowed_table_types = array( 'tables', 'global_tables' ); + if ( $network ) { + $allowed_table_types[] = 'ms_global_tables'; + } + foreach( $allowed_table_types as $table_type ) { + foreach( $wpdb->$table_type as $table ) { + $allowed_tables[] = $prefix . $table; + } + } + + // Given our matching tables, also allow site-specific tables on the network + foreach( $matching_tables as $key => $matched_table ) { + + if ( in_array( $matched_table, $allowed_tables ) ) { + continue; + } + + if ( $network ) { + $valid_table = false; + foreach( array_merge( $wpdb->tables, $wpdb->old_tables ) as $maybe_site_table ) { + if ( preg_match( "#{$prefix}([\d]+)_{$maybe_site_table}#", $matched_table ) ) { + $valid_table = true; + } + } + if ( $valid_table ) { + continue; + } + } + + unset( $matching_tables[ $key ] ); + + } + + return array_values( $matching_tables ); - return $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); } private static function sql_handle_col( $col, $table, $old, $new, $dry_run ) { From 5ddad9b0906eb4725b41c117c4a9ec409ac8d6f2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 30 Jul 2014 09:46:53 -0700 Subject: [PATCH 3083/4858] Explicit test to make sure we aren't clobbering unexpected tables --- features/search-replace.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index 0b90f81aec..43207edbec 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -24,6 +24,16 @@ Feature: Do global search/replace | wp_2_posts | guid | 2 | SQL | | wp_blogs | path | 1 | SQL | + Scenario: Don't run on unregistered tables + Given a WP install + And I run `wp db query "CREATE TABLE wp_awesome ( id int(11) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"` + + When I run `wp search-replace foo bar` + Then STDOUT should not contain: + """ + wp_awesome + """ + Scenario: Quiet search/replace Given a WP install From f001fb61a673e264525685610dfd64269b938c18 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 08:21:19 -0400 Subject: [PATCH 3084/4858] Make the scaffold command conditionally dependent on WP_Filesystem --- php/commands/scaffold.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index b35ce22b33..14cb569a84 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -9,10 +9,6 @@ */ class Scaffold_Command extends WP_CLI_Command { - function __construct() { - WP_Filesystem(); - } - /** * Generate PHP code for registering a custom post type. * @@ -109,7 +105,7 @@ function taxonomy( $args, $assoc_args ) { } private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) { - global $wp_filesystem; + $wp_filesystem = $this->init_wp_filesystem(); $control_args = $this->extract_args( $assoc_args, array( 'label' => preg_replace( '/_|-/', ' ', strtolower( $slug ) ), @@ -379,7 +375,7 @@ function plugin( $args, $assoc_args ) { * @subcommand plugin-tests */ function plugin_tests( $args, $assoc_args ) { - global $wp_filesystem; + $wp_filesystem = $this->init_wp_filesystem(); $plugin_slug = $args[0]; @@ -413,7 +409,7 @@ function plugin_tests( $args, $assoc_args ) { } private function create_file( $filename, $contents ) { - global $wp_filesystem; + $wp_filesystem = $this->init_wp_filesystem(); $wp_filesystem->mkdir( dirname( $filename ) ); @@ -533,6 +529,15 @@ protected function maybe_create_plugins_dir() { } + /** + * Initialize WP Filesystem + */ + private function init_wp_filesystem() { + global $wp_filesystem; + WP_Filesystem(); + return $wp_filesystem; + } + } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); From e5253e5dda5c003fa27bba6754af33f1407c0d47 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 08:21:59 -0400 Subject: [PATCH 3085/4858] Allow community packages to use WP-CLI testing framework First pass --- features/scaffold.feature | 33 +++++++++++++++++++ php/commands/scaffold.php | 61 +++++++++++++++++++++++++++++++++++ templates/load-wp-cli.feature | 10 ++++++ utils/make-phar.php | 1 + 4 files changed, 105 insertions(+) create mode 100644 templates/load-wp-cli.feature diff --git a/features/scaffold.feature b/features/scaffold.feature index 3ec35028b6..2e4f538de6 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -118,3 +118,36 @@ Feature: WordPress code scaffolding """ executable """ + + Scenario: Scaffold package tests + Given a community-command/command.php file: + """ + <?php + """ + + When I run `wp scaffold package-tests community-command` + Then STDOUT should not be empty + And the community-command/features directory should contain: + """ + bootstrap + extra + load-wp-cli.feature + steps + """ + And the community-command/features/bootstrap directory should contain: + """ + FeatureContext.php + Process.php + support.php + utils.php + """ + And the community-command/features/steps directory should contain: + """ + given.php + then.php + when.php + """ + And the community-command/features/extra directory should contain: + """ + no-mail.php + """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 14cb569a84..d59e6e9127 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -1,6 +1,7 @@ <?php use WP_CLI\Utils; +use WP_CLI\Process; /** * Generate code for post types, taxonomies, etc. @@ -300,6 +301,66 @@ private function get_output_path( $assoc_args, $subdir ) { return $path; } + /** + * Generate files needed for running PHPUnit tests. + * + * ## DESCRIPTION + * + * These are the files that are generated: + * + * * `.travis.yml` is the configuration file for Travis CI + * + * ## OPTIONS + * + * <dir> + * : The package directory to generate tests for + * + * ## EXAMPLE + * + * wp scaffold package-tests /path/to/command/dir/ + * + * @when before_wp_load + * @subcommand package-tests + */ + public function package_tests( $args, $assoc_args ) { + + list( $package_dir ) = $args; + + $package_dir = rtrim( $package_dir, '/' ) . '/'; + $features_dir = $package_dir . 'features/'; + $bootstrap_dir = $features_dir . 'bootstrap/'; + $steps_dir = $features_dir . 'steps/'; + $extra_dir = $features_dir . 'extra/'; + foreach( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir ) as $dir ) { + if ( ! is_dir( $dir ) ) { + Process::create( Utils\esc_cmd( 'mkdir %s', $dir ) )->run(); + } + } + + $to_copy = array( + 'templates/load-wp-cli.feature' => $features_dir, + 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, + 'features/bootstrap/support.php' => $bootstrap_dir, + 'php/WP_CLI/Process.php' => $bootstrap_dir, + 'php/utils.php' => $bootstrap_dir, + 'features/steps/given.php' => $steps_dir, + 'features/steps/when.php' => $steps_dir, + 'features/steps/then.php' => $steps_dir, + 'features/extra/no-mail.php' => $extra_dir, + ); + + foreach ( $to_copy as $file => $dir ) { + // file_get_contents() works with Phar-archived files + $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); + $file_path = $dir . basename( $file ); + $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); + file_put_contents( $file_path, $contents ); + } + + WP_CLI::success( "Created test files." ); + + } + /** * Generate starter code for a plugin. * diff --git a/templates/load-wp-cli.feature b/templates/load-wp-cli.feature new file mode 100644 index 0000000000..035b86730d --- /dev/null +++ b/templates/load-wp-cli.feature @@ -0,0 +1,10 @@ +Feature: Test that WP-CLI loads. + + Scenario: WP-CLI loads for your tests + Given a WP install + + When I run `wp eval 'echo "Hello world.";'` + Then STDOUT should contain: + """ + Hello world. + """ diff --git a/utils/make-phar.php b/utils/make-phar.php index bda5002a32..e75d5a93c2 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -33,6 +33,7 @@ function add_file( $phar, $path ) { ->ignoreVCS(true) ->name('*.php') ->in('./php') + ->in('./features') ->in('./vendor/wp-cli') ->in('./vendor/mustache') ->in('./vendor/rmccue/requests') From caf41749c0a1c8dc4eb292f18b11bbf381b96a97 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 09:27:55 -0400 Subject: [PATCH 3086/4858] Handle community package context where these files are copied --- features/bootstrap/FeatureContext.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 803c3379f1..dc14eda1c7 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -8,8 +8,15 @@ use \WP_CLI\Process; use \WP_CLI\Utils; -require_once __DIR__ . '/../../php/utils.php'; -require_once __DIR__ . '/../../php/WP_CLI/Process.php'; +// Inside a community package +if ( file_exists( __DIR__ . '/utils.php' ) ) { + require_once __DIR__ . '/utils.php'; + require_once __DIR__ . '/Process.php'; +// Inside WP-CLI +} else { + require_once __DIR__ . '/../../php/utils.php'; + require_once __DIR__ . '/../../php/WP_CLI/Process.php'; +} /** * Features context. From dfbf026966a76ac5a574622fb092f07f73df9235 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 10:04:48 -0400 Subject: [PATCH 3087/4858] Travis file for package tests --- features/scaffold.feature | 1 + php/commands/scaffold.php | 2 ++ templates/.travis.package.yml | 14 ++++++++++++++ 3 files changed, 17 insertions(+) create mode 100644 templates/.travis.package.yml diff --git a/features/scaffold.feature b/features/scaffold.feature index 2e4f538de6..3d34237135 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -127,6 +127,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold package-tests community-command` Then STDOUT should not be empty + And the community-command/.travis.yml file should exist And the community-command/features directory should contain: """ bootstrap diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d59e6e9127..f76ce5a0c2 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -338,6 +338,7 @@ public function package_tests( $args, $assoc_args ) { } $to_copy = array( + 'templates/.travis.package.yml' => $package_dir, 'templates/load-wp-cli.feature' => $features_dir, 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, 'features/bootstrap/support.php' => $bootstrap_dir, @@ -353,6 +354,7 @@ public function package_tests( $args, $assoc_args ) { // file_get_contents() works with Phar-archived files $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); $file_path = $dir . basename( $file ); + $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml'), $file_path ); $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); file_put_contents( $file_path, $contents ); } diff --git a/templates/.travis.package.yml b/templates/.travis.package.yml new file mode 100644 index 0000000000..09641d59d6 --- /dev/null +++ b/templates/.travis.package.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 5.3 + - 5.5 + +env: + global: + - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + +before_script: + - bash bin/install-package-tests.sh + +script: php behat.phar From 86cc38d4c3c74a511d1b95cd4616baae1cb92cd0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 10:25:18 -0400 Subject: [PATCH 3088/4858] Helper utility for building the test config --- features/scaffold.feature | 1 + php/commands/scaffold.php | 4 +++- utils/make-phar.php | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 3d34237135..e467e5ed77 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -128,6 +128,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold package-tests community-command` Then STDOUT should not be empty And the community-command/.travis.yml file should exist + And the community-command/utils/get-package-require-from-composer.php file should exist And the community-command/features directory should contain: """ bootstrap diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f76ce5a0c2..bd68b0500c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -327,11 +327,12 @@ public function package_tests( $args, $assoc_args ) { list( $package_dir ) = $args; $package_dir = rtrim( $package_dir, '/' ) . '/'; + $utils_dir = $package_dir . 'utils/'; $features_dir = $package_dir . 'features/'; $bootstrap_dir = $features_dir . 'bootstrap/'; $steps_dir = $features_dir . 'steps/'; $extra_dir = $features_dir . 'extra/'; - foreach( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir ) as $dir ) { + foreach( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir, $utils_dir ) as $dir ) { if ( ! is_dir( $dir ) ) { Process::create( Utils\esc_cmd( 'mkdir %s', $dir ) )->run(); } @@ -344,6 +345,7 @@ public function package_tests( $args, $assoc_args ) { 'features/bootstrap/support.php' => $bootstrap_dir, 'php/WP_CLI/Process.php' => $bootstrap_dir, 'php/utils.php' => $bootstrap_dir, + 'utils/get-package-require-from-composer.php' => $utils_dir, 'features/steps/given.php' => $steps_dir, 'features/steps/when.php' => $steps_dir, 'features/steps/then.php' => $steps_dir, diff --git a/utils/make-phar.php b/utils/make-phar.php index e75d5a93c2..4558cfbfb9 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -65,6 +65,7 @@ function add_file( $phar, $path ) { } add_file( $phar, './vendor/autoload.php' ); +add_file( $phar, './utils/get-package-require-from-composer.php' ); add_file( $phar, './vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); $phar->setStub( <<<EOB From 3cc14fa5998a638edf2c7feb105c824207eff1b0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 10:32:54 -0400 Subject: [PATCH 3089/4858] Commit the helper utility --- utils/get-package-require-from-composer.php | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 utils/get-package-require-from-composer.php diff --git a/utils/get-package-require-from-composer.php b/utils/get-package-require-from-composer.php new file mode 100644 index 0000000000..33e30ccfdd --- /dev/null +++ b/utils/get-package-require-from-composer.php @@ -0,0 +1,23 @@ +<?php + +$file = $argv[1]; +if ( ! file_exists( $file ) ) { + echo 'File does not exist.'; + exit(1); +} + +$contents = file_get_contents( $file ); +$composer = json_decode( $contents ); + +if ( empty( $composer ) || ! is_object( $composer ) ) { + echo 'Invalid composer.json for package.'; + exit(1); +} + +if ( empty( $composer->autoload->files ) ) { + echo 'composer.json must specify valid "autoload" => "files"'; + exit(1); +} + +echo implode( PHP_EOL, $composer->autoload->files ); +exit(0); \ No newline at end of file From cd1b17a669db0a4e6a79eddb8be24b5baf162df5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 10:42:42 -0400 Subject: [PATCH 3090/4858] Persist a supplied config path variable --- features/bootstrap/FeatureContext.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index dc14eda1c7..ae06d8eaa4 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -44,6 +44,9 @@ private static function get_process_env_variables() { 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), 'BEHAT_RUN' => 1 ); + if ( $config_path = getenv( 'WP_CLI_CONFIG_PATH' ) ) { + $env['WP_CLI_CONFIG_PATH'] = $config_path; + } return $env; } From 09f85bb0b1894eb3a16628b8e4201aa6164b7f33 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 10:43:08 -0400 Subject: [PATCH 3091/4858] Bash script for installing package tests --- features/scaffold.feature | 1 + php/commands/scaffold.php | 2 ++ templates/.travis.package.yml | 3 +- templates/install-package-tests.sh | 46 ++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 templates/install-package-tests.sh diff --git a/features/scaffold.feature b/features/scaffold.feature index e467e5ed77..3379020c2e 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -128,6 +128,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold package-tests community-command` Then STDOUT should not be empty And the community-command/.travis.yml file should exist + And the community-command/bin/install-package-tests.sh file should exist And the community-command/utils/get-package-require-from-composer.php file should exist And the community-command/features directory should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index bd68b0500c..6a70e8b1e8 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -327,6 +327,7 @@ public function package_tests( $args, $assoc_args ) { list( $package_dir ) = $args; $package_dir = rtrim( $package_dir, '/' ) . '/'; + $bin_dir = $package_dir . 'bin/'; $utils_dir = $package_dir . 'utils/'; $features_dir = $package_dir . 'features/'; $bootstrap_dir = $features_dir . 'bootstrap/'; @@ -341,6 +342,7 @@ public function package_tests( $args, $assoc_args ) { $to_copy = array( 'templates/.travis.package.yml' => $package_dir, 'templates/load-wp-cli.feature' => $features_dir, + 'templates/install-package-tests.sh' => $bin_dir, 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, 'features/bootstrap/support.php' => $bootstrap_dir, 'php/WP_CLI/Process.php' => $bootstrap_dir, diff --git a/templates/.travis.package.yml b/templates/.travis.package.yml index 09641d59d6..737aea1227 100644 --- a/templates/.travis.package.yml +++ b/templates/.travis.package.yml @@ -7,8 +7,9 @@ php: env: global: - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + - WP_CLI_CONFIG_PATH=/tmp/wp-cli-phar/config.yml before_script: - bash bin/install-package-tests.sh -script: php behat.phar +script: ./vendor/bin/behat diff --git a/templates/install-package-tests.sh b/templates/install-package-tests.sh new file mode 100644 index 0000000000..74c76b5878 --- /dev/null +++ b/templates/install-package-tests.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -ex + +PACKAGE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../ && pwd )" + +install_wp_cli() { + + # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR + mkdir -p $WP_CLI_BIN_DIR + wget https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli-nightly.phar + mv wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp + chmod +x $WP_CLI_BIN_DIR/wp + +} + +set_package_context() { + + touch $WP_CLI_CONFIG_PATH + printf 'require:' > $WP_CLI_CONFIG_PATH + requires=$(php $PACKAGE_DIR/utils/get-package-require-from-composer.php composer.json) + for require in "${requires[@]}" + do + printf "\n%2s-%1s$PACKAGE_DIR/$require" >> $WP_CLI_CONFIG_PATH + done + printf "\n" >> $WP_CLI_CONFIG_PATH + +} + +download_behat() { + + cd $PACKAGE_DIR + curl -s https://getcomposer.org/installer | php + php composer.phar require --dev behat/behat='~2.5' + +} + +install_db() { + mysql -e 'CREATE DATABASE IF NOT EXISTS wp_cli_test;' -uroot + mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot +} + +install_wp_cli +set_package_context +download_behat +install_db From e2b3fd9e0897618b9612126b8a9e8c19f7759bea Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 10:54:36 -0400 Subject: [PATCH 3092/4858] Make sure the bin directory is created --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 6a70e8b1e8..198d7c788d 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -333,7 +333,7 @@ public function package_tests( $args, $assoc_args ) { $bootstrap_dir = $features_dir . 'bootstrap/'; $steps_dir = $features_dir . 'steps/'; $extra_dir = $features_dir . 'extra/'; - foreach( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir, $utils_dir ) as $dir ) { + foreach( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir, $utils_dir, $bin_dir ) as $dir ) { if ( ! is_dir( $dir ) ) { Process::create( Utils\esc_cmd( 'mkdir %s', $dir ) )->run(); } From 054e3e22855e0a2b7f10fb3db313209335a3ef39 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 2 Aug 2014 11:16:44 -0400 Subject: [PATCH 3093/4858] Update the docs some --- php/commands/scaffold.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 198d7c788d..675cd0b045 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -302,18 +302,28 @@ private function get_output_path( $assoc_args, $subdir ) { } /** - * Generate files needed for running PHPUnit tests. + * Generate files needed for writing Behat tests for your command. * * ## DESCRIPTION * * These are the files that are generated: * * * `.travis.yml` is the configuration file for Travis CI + * * `bin/install-package-tests.sh` will configure environment to run tests. Script expects WP_CLI_BIN_DIR and WP_CLI_CONFIG_PATH environment variables. + * * `features/load-wp-cli.feature` is a basic test to confirm WP-CLI can load. + * * `features/bootstrap`, `features/steps`, `features/extra` are Behat configuration files. + * * `utils/generate-package-require-from-composer.php` generates a test config.yml file from your package's composer.json + * + * ## ENVIRONMENT + * + * The `features/bootstrap/FeatureContext.php` file expects the WP_CLI_BIN_DIR and WP_CLI_CONFIG_PATH environment variables. + * + * WP-CLI Behat framework uses Behat ~2.5. * * ## OPTIONS * * <dir> - * : The package directory to generate tests for + * : The package directory to generate tests for. * * ## EXAMPLE * From fc0170b54d7cc5a46ce9570ebc9b3a6108510876 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Aug 2014 07:31:27 -0400 Subject: [PATCH 3094/4858] Ignore `config.yml`, which means developer has cloned into `~/.wp-cli` --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8c20e7a9ff..2f087dd74a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ composer.lock +config.yml /vendor /*.phar /phpunit.xml From 3800713894ba241ae1d866934fa06cd7661d673f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Aug 2014 12:59:49 -0400 Subject: [PATCH 3095/4858] Test explicitly for composer.json file --- features/scaffold.feature | 27 +++++++++++++++++++++++++++ php/commands/scaffold.php | 12 +++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 3379020c2e..c535c18096 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -124,6 +124,27 @@ Feature: WordPress code scaffolding """ <?php """ + And a community-command/composer.json file: + """ + { + "name": "wp-cli/community-command", + "description": "A demo community command.", + "license": "MIT", + "minimum-stability": "dev", + "require": { + }, + "autoload": { + "files": [ "dictator.php" ] + }, + "require-dev": { + "behat/behat": "~2.5" + } + } + """ + And a invalid-command/command.php file: + """ + <?php + """ When I run `wp scaffold package-tests community-command` Then STDOUT should not be empty @@ -154,3 +175,9 @@ Feature: WordPress code scaffolding """ no-mail.php """ + + When I try `wp scaffold package-tests invalid-command` + Then STDERR should be: + """ + Error: Invalid package directory. composer.json file must be present. + """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 675cd0b045..c61930cc35 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -336,7 +336,17 @@ public function package_tests( $args, $assoc_args ) { list( $package_dir ) = $args; - $package_dir = rtrim( $package_dir, '/' ) . '/'; + if ( is_file( $package_dir ) ) { + $package_dir = dirname( $package_dir ); + } else if ( is_dir( $package_dir ) ) { + $package_dir = rtrim( $package_dir, '/' ); + } + + if ( ! is_dir( $package_dir ) || ! file_exists( $package_dir . '/composer.json' ) ) { + WP_CLI::error( "Invalid package directory. composer.json file must be present." ); + } + + $package_dir .= '/'; $bin_dir = $package_dir . 'bin/'; $utils_dir = $package_dir . 'utils/'; $features_dir = $package_dir . 'features/'; From b346493afc1266966ab26f98782e05311d05e18f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 3 Aug 2014 13:09:05 -0400 Subject: [PATCH 3096/4858] Ensure `install-package-tests.sh` ends up as executable --- features/scaffold.feature | 6 ++++++ php/commands/scaffold.php | 3 +++ 2 files changed, 9 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index c535c18096..a02d3d9f20 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -176,6 +176,12 @@ Feature: WordPress code scaffolding no-mail.php """ + When I run `wp eval "if ( is_executable( 'community-command/bin/install-package-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` + Then STDOUT should be: + """ + executable + """ + When I try `wp scaffold package-tests invalid-command` Then STDERR should be: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c61930cc35..3fd04361d1 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -381,6 +381,9 @@ public function package_tests( $args, $assoc_args ) { $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml'), $file_path ); $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); file_put_contents( $file_path, $contents ); + if ( 'templates/install-package-tests.sh' === $file ) { + Process::create( Utils\esc_cmd( 'chmod +x %s', $file_path ) )->run(); + } } WP_CLI::success( "Created test files." ); From 1e06f0f05597b594f07a722e58c3b327e83bb07b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 4 Aug 2014 11:16:37 -0400 Subject: [PATCH 3097/4858] Update importer to handle one or more directories Specify one or more directories when using `wp import`, and it will find and import `.xml` and `.wxr` files. --- features/import.feature | 43 +++++++++++++++++++++++++++++++++++++++++ php/commands/import.php | 13 ++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/features/import.feature b/features/import.feature index bbb869e68c..b401e3164f 100644 --- a/features/import.feature +++ b/features/import.feature @@ -36,3 +36,46 @@ Feature: Import content. When I run `wp import {EXPORT_FILE} --authors=skip --skip=image_resize` Then STDOUT should not be empty + + Scenario: Export and import a directory of files + Given a WP install + And I run `mkdir export-posts` + And I run `mkdir export-pages` + + When I run `wp post generate --count=49` + When I run `wp post generate --post_type=page --count=49` + And I run `wp post list --post_type=post,page --format=count` + Then STDOUT should be: + """ + 100 + """ + + When I run `wp export --dir=export-posts --post_type=post` + When I run `wp export --dir=export-pages --post_type=page` + Then STDOUT should not be empty + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post,page --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `find export-* -type f | wc -l` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp plugin install wordpress-importer --activate` + And I run `wp import export-posts --authors=skip --skip=image_resize` + And I run `wp import export-pages --authors=skip --skip=image_resize` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post,page --format=count` + Then STDOUT should be: + """ + 100 + """ diff --git a/php/commands/import.php b/php/commands/import.php index 36d2c46cf8..a0fd39d54e 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -8,7 +8,7 @@ class Import_Command extends WP_CLI_Command { * ## OPTIONS * * <file>... - * : Path to one or more valid WXR files for importing. + * : Path to one or more valid WXR files for importing. Directories are also accepted. * * --authors=<authors> * : How the author mapping should be handled. Options are 'create', 'mapping.csv', or 'skip'. The first will create any non-existent users from the WXR file. The second will read author mapping associations from a CSV, or create a CSV for editing if the file path doesn't exist. The CSV requires two columns, and a header row like "old_user_login,new_user_login". The last option will skip any author mapping. @@ -36,6 +36,17 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::log( 'Starting the import process...' ); + $new_args = array(); + foreach( $args as $arg ) { + if ( is_dir( $arg ) ) { + $files = glob( rtrim( $arg, '/' ) . '/*.{wxr,xml}', GLOB_BRACE ); + $new_args = array_merge( $new_args, $files ); + } else { + $new_args[] = $arg; + } + } + $args = $new_args; + foreach ( $args as $file ) { if ( ! is_readable( $file ) ) { WP_CLI::warning( "Can't read $file file." ); From dd24ddea35e8307fe00220d73ccf3826c7f5864d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 4 Aug 2014 14:50:44 -0400 Subject: [PATCH 3098/4858] Failing test for #1296 --- features/db.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/db.feature b/features/db.feature index 92074c225a..877d2edada 100644 --- a/features/db.feature +++ b/features/db.feature @@ -91,3 +91,19 @@ Feature: Perform database operations """ Success: Exported """ + + Scenario: Persist DB collation + Given a WP install + And I run `sed -i.bak s/define\(\'DB_COLLATE\'\,\s\'\'\)\;/define\(\'DB_COLLATE\'\,\s'utf8-hungarian-ci\'\)\;/ wp-config.php` + + When I run `wp db reset --yes` + Then STDOUT should not be empty + + When I run `wp core install --title="WP-CLI Test" --url=example.com --admin_user=admin --admin_password=admin --admin_email=admin@example.com` + Then STDOUT should not be empty + + When I run `wp db query 'SHOW variables LIKE "collation_database";'` + Then STDOUT should contain: + """ + utf8-hungarian-ci + """ From 3c739623433252b300654af4620a01589eb8ad74 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 4 Aug 2014 15:26:37 -0400 Subject: [PATCH 3099/4858] Persist `DB_COLLATE` value when creating database --- features/db.feature | 35 +++++++++++++++++++++++++++++++---- php/commands/db.php | 17 +++++++++++++++-- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/features/db.feature b/features/db.feature index 877d2edada..2fc9b71e55 100644 --- a/features/db.feature +++ b/features/db.feature @@ -92,9 +92,30 @@ Feature: Perform database operations Success: Exported """ - Scenario: Persist DB collation - Given a WP install - And I run `sed -i.bak s/define\(\'DB_COLLATE\'\,\s\'\'\)\;/define\(\'DB_COLLATE\'\,\s'utf8-hungarian-ci\'\)\;/ wp-config.php` + Scenario: Persist DB charset and collation + Given an empty directory + And WP files + + When I run `wp core config {CORE_CONFIG_SETTINGS} --dbcharset=latin1 --dbcollate=latin1_spanish_ci` + Then STDOUT should not be empty + + When I run `wp db create` + Then STDERR should be empty + + When I run `wp core install --title="WP-CLI Test" --url=example.com --admin_user=admin --admin_password=admin --admin_email=admin@example.com` + Then STDOUT should not be empty + + When I run `wp db query 'SHOW variables LIKE "character_set_database";'` + Then STDOUT should contain: + """ + latin1 + """ + + When I run `wp db query 'SHOW variables LIKE "collation_database";'` + Then STDOUT should contain: + """ + latin1_spanish_ci + """ When I run `wp db reset --yes` Then STDOUT should not be empty @@ -102,8 +123,14 @@ Feature: Perform database operations When I run `wp core install --title="WP-CLI Test" --url=example.com --admin_user=admin --admin_password=admin --admin_email=admin@example.com` Then STDOUT should not be empty + When I run `wp db query 'SHOW variables LIKE "character_set_database";'` + Then STDOUT should contain: + """ + latin1 + """ + When I run `wp db query 'SHOW variables LIKE "collation_database";'` Then STDOUT should contain: """ - utf8-hungarian-ci + latin1_spanish_ci """ diff --git a/php/commands/db.php b/php/commands/db.php index 32543d7a74..edaa20aa58 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -11,7 +11,8 @@ class DB_Command extends WP_CLI_Command { * Create the database, as specified in wp-config.php */ function create( $_, $assoc_args ) { - self::run_query( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); + + self::run_query( self::get_create_query() ); WP_CLI::success( "Database created." ); } @@ -44,7 +45,7 @@ function reset( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); self::run_query( sprintf( 'DROP DATABASE IF EXISTS `%s`', DB_NAME ) ); - self::run_query( sprintf( 'CREATE DATABASE `%s`', DB_NAME ) ); + self::run_query( self::get_create_query() ); WP_CLI::success( "Database reset." ); } @@ -227,6 +228,18 @@ private function get_file_name( $args ) { return $args[0]; } + private static function get_create_query() { + + $create_query = sprintf( 'CREATE DATABASE `%s`', DB_NAME ); + if ( defined( 'DB_CHARSET' ) && constant( 'DB_CHARSET' ) ) { + $create_query .= sprintf( ' DEFAULT CHARSET `%s`', constant( 'DB_CHARSET' ) ); + } + if ( defined( 'DB_COLLATE' ) && constant( 'DB_COLLATE' ) ) { + $create_query .= sprintf( ' DEFAULT COLLATE `%s`', constant( 'DB_COLLATE' ) ); + } + return $create_query; + } + private static function run_query( $query ) { self::run( 'mysql --no-defaults', array( 'execute' => $query ) ); } From d56c5841c20031e4512a752f75474fa86df1e92f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 4 Aug 2014 17:22:05 -0400 Subject: [PATCH 3100/4858] Switch php-cli-tools to dev-master We'll let WP-CLI users dogfood php-cli-tools during the release cycle. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index eddbf52a9b..40ec7edf61 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.9.5", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From e4f7ef1dc413054b7709f71dc6c672452b431e17 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Wed, 6 Aug 2014 19:34:37 +0300 Subject: [PATCH 3101/4858] core update: add intermediate message to break the long silence --- php/commands/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 70a1053eaa..85004dcb4a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -836,6 +836,8 @@ function update( $args, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + WP_CLI::log( "Updating to version {$update->version} ({$update->locale})..." ); + $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); if ( is_wp_error($result) ) { From 9a3b764f19fd2f6a2c539de67d8750af1e9027fd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 7 Aug 2014 08:46:29 -0700 Subject: [PATCH 3102/4858] Broken test to establish #1318 --- features/export.feature | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/features/export.feature b/features/export.feature index 7ff5f118b5..b7878a96b4 100644 --- a/features/export.feature +++ b/features/export.feature @@ -84,6 +84,39 @@ Feature: Export content. 10 """ + Scenario: Export only one post + Given a WP install + And these installed and active plugins: + """ + wordpress-importer + """ + + When I run `wp post generate --count=10` + And I run `wp post list --format=count` + Then STDOUT should be: + """ + 11 + """ + + When I run `wp post create --post_title='Test post' --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID} + + When I run `wp export --post__in={POST_ID}` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 1 + """ + Scenario: Export posts within a given date range Given a WP install And these installed and active plugins: From 91d62fbcf411527797fd544014ae9c0fa41459b4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 7 Aug 2014 08:51:29 -0700 Subject: [PATCH 3103/4858] Pass `post__in` to new exporter in a format it understands --- php/commands/export.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 987dcdbc91..4569d6d082 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -197,7 +197,8 @@ private function check_post__in( $post__in ) { WP_CLI::warning( "post__in should be comma-separated post IDs" ); return false; } - $this->export_args['post__in'] = implode( ',', $post__in ); + // New exporter uses a different argument + $this->export_args['post_ids'] = $post__in; return true; } From 352fb6bbdb98deb3e7b0c2e77e0d5577150ca6da Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Thu, 7 Aug 2014 23:59:29 +0300 Subject: [PATCH 3104/4858] fix cases when update version isn't known --- features/core.feature | 5 ++--- php/commands/core.php | 8 +++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index e168e5dad7..a8998aecd0 100644 --- a/features/core.feature +++ b/features/core.feature @@ -246,11 +246,10 @@ Feature: Manage WordPress installation """ When I run `wget http://wordpress.org/wordpress-3.9.zip --quiet` - Then STDOUT should be empty - - When I run `wp core update wordpress-3.9.zip` + And I run `wp core update wordpress-3.9.zip` Then STDOUT should be: """ + Starting update... Unpacking the update... Success: WordPress updated successfully. """ diff --git a/php/commands/core.php b/php/commands/core.php index 85004dcb4a..8982223c02 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -793,6 +793,7 @@ function update( $args, $assoc_args ) { 'full' => $args[0], ), 'version' => $version, + 'locale' => null ); } else if ( empty( $assoc_args['version'] ) ) { @@ -827,6 +828,7 @@ function update( $args, $assoc_args ) { 'full' => $new_package, ), 'version' => $version, + 'locale' => $locale ); } else { @@ -836,7 +838,11 @@ function update( $args, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - WP_CLI::log( "Updating to version {$update->version} ({$update->locale})..." ); + if ( $update->version ) { + WP_CLI::log( "Updating to version {$update->version} ({$update->locale})..." ); + } else { + WP_CLI::log( "Starting update..." ); + } $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); From b3eb03c747b58a1e3a20df72b0a05b82fa5a4c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Fri, 8 Aug 2014 16:14:53 +0200 Subject: [PATCH 3105/4858] delete CA file --- php/commands/core.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 8982223c02..e3a2c31abe 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -146,10 +146,13 @@ private static function _request( $method, $url, $headers = array(), $options = } try { - return Requests::get( $url, $headers, $options ); + $request = Requests::get( $url, $headers, $options ); + unlink( $options['verify'] ); + return $request; } catch( Requests_Exception $ex ) { // Handle SSL certificate issues gracefully WP_CLI::warning( $ex->getMessage() ); + unlink( $options['verify'] ); $options['verify'] = false; try { return Requests::get( $url, $headers, $options ); From f09919a33c28249221f2b451225a88454230c9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sz=C3=A9pe=20Viktor?= <viktor@szepe.net> Date: Fri, 8 Aug 2014 16:25:51 +0200 Subject: [PATCH 3106/4858] only when CA file is copied could be `if ( ! empty( $options['verify'] ) ) {` --- php/commands/core.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index e3a2c31abe..1358f6a5c8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -147,12 +147,16 @@ private static function _request( $method, $url, $headers = array(), $options = try { $request = Requests::get( $url, $headers, $options ); - unlink( $options['verify'] ); + if ( $options['verify'] ) { + unlink( $options['verify'] ); + } return $request; } catch( Requests_Exception $ex ) { // Handle SSL certificate issues gracefully WP_CLI::warning( $ex->getMessage() ); - unlink( $options['verify'] ); + if ( $options['verify'] ) { + unlink( $options['verify'] ); + } $options['verify'] = false; try { return Requests::get( $url, $headers, $options ); From 1e810f7b0fbe464c40210329539764f728361d02 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 10 Aug 2014 12:42:30 -0700 Subject: [PATCH 3107/4858] Ignore WP-CLI's cache directory when installed to `~/.wp-cli` Related fc0170b54d7cc5a46ce9570ebc9b3a6108510876 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2f087dd74a..ee37a1d64c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ composer.lock config.yml +/cache /vendor /*.phar /phpunit.xml From 0be771a370e8de8e1c1b02115d5c5664151d5d16 Mon Sep 17 00:00:00 2001 From: Noah Schoenholtz <noah@alleyinteractive.com> Date: Mon, 11 Aug 2014 16:02:47 -0400 Subject: [PATCH 3108/4858] esc_url before outputting GUID to WXR to avoid 'unterminated entity reference' error when GUID contains ampersand --- php/export/class-wp-export-wxr-formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php index c169029feb..5a99543a79 100644 --- a/php/export/class-wp-export-wxr-formatter.php +++ b/php/export/class-wp-export-wxr-formatter.php @@ -166,7 +166,7 @@ public function post( $post ) { ->link( esc_url( apply_filters('the_permalink_rss', get_permalink() ) ) ) ->pubDate( mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ) ) ->tag( 'dc:creator', get_the_author_meta( 'login' ) ) - ->guid( get_the_guid(), array( 'isPermaLink' => 'false' ) ) + ->guid( esc_url( get_the_guid() ), array( 'isPermaLink' => 'false' ) ) ->description( '' ) ->tag( 'content:encoded' )->contains->cdata( $post->post_content )->end ->tag( 'excerpt:encoded' )->contains->cdata( $post->post_excerpt )->end From 67b98de33e3d036893b2f5886eba4390467de485 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 13 Aug 2014 16:58:12 -0700 Subject: [PATCH 3109/4858] Update `wp term list` to support multiple taxonomies Fortunately, `get_terms()` does the heavy lifting behind the scenes. --- features/term.feature | 9 +++++++++ php/commands/term.php | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/features/term.feature b/features/term.feature index ebfae3b2ff..90b2a0b076 100644 --- a/features/term.feature +++ b/features/term.feature @@ -28,6 +28,15 @@ Feature: Manage WordPress terms | name | slug | | Test term | test | + When I run `wp term create category 'Test category' --slug=test-category --description='This is a test category'` + Then STDOUT should not be empty + + When I run `wp term list post_tag category --fields=name,slug --format=csv` + Then STDOUT should be CSV containing: + | name | slug | + | Test term | test | + | Test category | test-category | + When I run `wp term get post_tag {TERM_ID}` Then STDOUT should be a table containing rows: | Field | Value | diff --git a/php/commands/term.php b/php/commands/term.php index 55569a4e47..a073ff601f 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -21,8 +21,8 @@ class Term_Command extends WP_CLI_Command { * * ## OPTIONS * - * <taxonomy> - * : List terms of a given taxonomy. + * <taxonomy>... + * : List terms of one or more taxonomies * * [--<field>=<value>] * : Filter by one or more fields. For accepted fields, see get_terms(). From 0bffc3cb0ef2b16b72da25c2b48cf0a20db61180 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 14 Aug 2014 11:38:17 -0700 Subject: [PATCH 3110/4858] Clarify `--url` global config argument For new users working with multisite, let's be explicit. --- php/config-spec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/config-spec.php b/php/config-spec.php index 519a6880c2..37f98fbf5e 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -10,7 +10,7 @@ 'url' => array( 'runtime' => '=<url>', 'file' => '<url>', - 'desc' => 'Pretend request came from given URL', + 'desc' => 'Pretend request came from given URL. In multisite, this argument is how the target site is specified.', ), 'blog' => array( 'deprecated' => 'Use --url instead.', From c0f62830ce95a1a4727a8b3952ba7d0c2316bca3 Mon Sep 17 00:00:00 2001 From: Matth_eu <matthew@matth.eu> Date: Fri, 15 Aug 2014 17:02:13 +0100 Subject: [PATCH 3111/4858] Fix term delete example --- php/commands/term.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index a073ff601f..503fb9dacf 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -217,7 +217,7 @@ public function update( $args, $assoc_args ) { * ## EXAMPLES * * # delete all post tags - * wp term list post_tag --field=ID | xargs wp term delete post_tag + * wp term list post_tag --field=term_id | xargs wp term delete post_tag */ public function delete( $args ) { $taxonomy = array_shift( $args ); @@ -327,7 +327,7 @@ public function generate( $args, $assoc_args ) { * Get term url * * ## OPTIONS - * + * * <taxonomy> * : Taxonomy of the term(s) to get. * From e32fce99655cb70d4a94d817a1efaab22b7394f7 Mon Sep 17 00:00:00 2001 From: Pippin Williamson <pippin@pippinsplugins.com> Date: Sun, 17 Aug 2014 17:22:12 -0500 Subject: [PATCH 3112/4858] Better error message for update() Improves the error message for update() when the existing value is the same as the new one, as suggested in #1254 --- php/commands/option.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index ded55ce2be..7b9bc80af4 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -108,7 +108,7 @@ public function update( $args, $assoc_args ) { // update_option() returns false if the value is the same if ( !$result && $value != get_option( $key ) ) { - WP_CLI::error( "Could not update option '$key'." ); + WP_CLI::error( "Option '$key' value is already set to '$value'." ); } else { WP_CLI::success( "Updated '$key' option." ); } From e427c8ee0c7ff8e265b9fdc560ff099e2bb9c40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Mon, 18 Aug 2014 22:00:30 +0200 Subject: [PATCH 3113/4858] Update core.php --- php/commands/core.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 1358f6a5c8..c9c084a4ee 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -135,6 +135,8 @@ private static function _rmdir( $dir ) { } private static function _request( $method, $url, $headers = array(), $options = array() ) { + $pem_copied = false; + // cURL can't read Phar archives if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; @@ -143,18 +145,19 @@ private static function _request( $method, $url, $headers = array(), $options = WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem', $options['verify'] ); + $pem_copied = true; } try { $request = Requests::get( $url, $headers, $options ); - if ( $options['verify'] ) { + if ( $pem_copied ) { unlink( $options['verify'] ); } return $request; } catch( Requests_Exception $ex ) { // Handle SSL certificate issues gracefully WP_CLI::warning( $ex->getMessage() ); - if ( $options['verify'] ) { + if ( $pem_copied ) { unlink( $options['verify'] ); } $options['verify'] = false; From 913d706f70082a9ea339028e60c00a2bdd210ea7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 19 Aug 2014 08:47:34 -0700 Subject: [PATCH 3114/4858] Explicit support for importing remote CSVs It worked before, but threw a warning that the file was missing. --- php/commands/user.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index b93cf1c4b1..5f84ca4f29 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -550,7 +550,7 @@ public function list_caps( $args, $assoc_args ) { * ## OPTIONS * * <file> - * : The CSV file of users to import. + * : The local or remote CSV file of users to import. * * [--send-email] * : Send an email to new users with their account details. @@ -561,6 +561,7 @@ public function list_caps( $args, $assoc_args ) { * ## EXAMPLES * * wp user import-csv /path/to/users.csv + * wp user import-csv http://example.com/users.csv * * Sample users.csv file: * @@ -577,7 +578,13 @@ public function import_csv( $args, $assoc_args ) { $filename = $args[0]; - if ( ! file_exists( $filename ) ) { + if ( 0 === stripos( $filename, 'http://' ) || 0 === stripos( $filename, 'https://' ) ) { + $response = wp_remote_head( $filename ); + $response_code = (string)wp_remote_retrieve_response_code( $response ); + if ( in_array( $response_code[0], array( 4, 5 ) ) ) { + WP_CLI::error( "Couldn't access remote CSV file." ); + } + } else if ( ! file_exists( $filename ) ) { WP_CLI::warning( sprintf( "Missing file: %s", $filename ) ); } From a7a329ba6be52d3dc2cce015418b67d2c46a2616 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 19 Aug 2014 08:49:54 -0700 Subject: [PATCH 3115/4858] Throw an explicit warning when the file doesn't exist The iterator will eventually error anyway. Let's do this before we get to that. --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 5f84ca4f29..919b8c25da 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -585,7 +585,7 @@ public function import_csv( $args, $assoc_args ) { WP_CLI::error( "Couldn't access remote CSV file." ); } } else if ( ! file_exists( $filename ) ) { - WP_CLI::warning( sprintf( "Missing file: %s", $filename ) ); + WP_CLI::error( sprintf( "Missing file: %s", $filename ) ); } foreach ( new \WP_CLI\Iterators\CSV( $filename ) as $i => $new_user ) { From 9e91d1a4c7284a21cf068edb1887abef5a83629e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 19 Aug 2014 08:51:25 -0700 Subject: [PATCH 3116/4858] Make this error more explicit by including response code --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 919b8c25da..a46378d183 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -582,7 +582,7 @@ public function import_csv( $args, $assoc_args ) { $response = wp_remote_head( $filename ); $response_code = (string)wp_remote_retrieve_response_code( $response ); if ( in_array( $response_code[0], array( 4, 5 ) ) ) { - WP_CLI::error( "Couldn't access remote CSV file." ); + WP_CLI::error( "Couldn't access remote CSV file (HTTP {$response_code} response)." ); } } else if ( ! file_exists( $filename ) ) { WP_CLI::error( sprintf( "Missing file: %s", $filename ) ); From 8d43e20744af1a1e7d5ceb682f708b851029c9d0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 19 Aug 2014 08:55:35 -0700 Subject: [PATCH 3117/4858] Add tests for error case --- features/user.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/user.feature b/features/user.feature index 2809ac97c5..3f99421c68 100644 --- a/features/user.feature +++ b/features/user.feature @@ -130,6 +130,12 @@ Feature: Manage WordPress users admin,admin@domain.com,Existing User,administrator """ + When I try `wp user import-csv users-incorrect.csv --skip-update` + Then STDERR should be: + """ + Error: Missing file: users-incorrect.csv + """ + When I run `wp user import-csv users.csv` Then STDOUT should not be empty From 50809e4d577277a108fa5c2492580da9cb2c0293 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 19 Aug 2014 08:57:34 -0700 Subject: [PATCH 3118/4858] Test case for remote csv error --- features/user.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/user.feature b/features/user.feature index 3f99421c68..ddbea8ab76 100644 --- a/features/user.feature +++ b/features/user.feature @@ -136,6 +136,12 @@ Feature: Manage WordPress users Error: Missing file: users-incorrect.csv """ + When I try `wp user import-csv http://example.com/users.csv --skip-update` + Then STDERR should be: + """ + Error: Couldn't access remote CSV file (HTTP 404 response). + """ + When I run `wp user import-csv users.csv` Then STDOUT should not be empty From f76be9c4de8bf49c94cd7a0339a59aa2925aa070 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 07:35:52 -0700 Subject: [PATCH 3119/4858] Allow themes and plugins to be listed with `update_version` When there's no `update_version` available, the attribute is `null` on the plugin info array. `isset()` returns false for null values, but `array_key_exists()` and `property_exists()` do the job --- features/plugin.feature | 10 +++++++--- php/WP_CLI/Formatter.php | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 13ffd7b516..0d582808fa 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -92,10 +92,14 @@ Feature: Manage WordPress plugins When I run `wp plugin install akismet --version=2.5.7 --force` Then STDOUT should not be empty - When I run `wp plugin list` + When I run `wp plugin list --name=akismet --field=update_version` + Then STDOUT should not be empty + And save STDOUT as {UPDATE_VERSION} + + When I run `wp plugin list --fields=name,status,update,version,update_version` Then STDOUT should be a table containing rows: - | name | status | update | version | - | akismet | inactive | available | 2.5.7 | + | name | status | update | version | update_version | + | akismet | inactive | available | 2.5.7 | {UPDATE_VERSION} | When I run `wp plugin activate akismet` Then STDOUT should not be empty diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 7f70aa800c..cd9717a7de 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -175,7 +175,7 @@ private function show_single_field( $items, $field ) { */ private function find_item_key( $item, $field ) { foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { - if ( ( is_object( $item ) && isset( $item->$maybe_key ) ) || ( is_array( $item ) && isset( $item[$maybe_key] ) ) ) { + if ( ( is_object( $item ) && property_exists( $item, $maybe_key ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { $key = $maybe_key; break; } From e703e18251edb1f1c681780598844ed0650a282a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 07:49:06 -0700 Subject: [PATCH 3120/4858] Check if `Spyc` exists before including it Other projects may have included it via Composer, and this will prevent a fatal --- php/Spyc.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/Spyc.php b/php/Spyc.php index b6a42af675..13b4c34156 100644 --- a/php/Spyc.php +++ b/php/Spyc.php @@ -32,6 +32,7 @@ function spyc_load_file ($file) { } } +if ( ! class_exists( 'Spyc' ) ) : /** * The Simple PHP YAML Class. * @@ -1031,3 +1032,4 @@ private function stripGroup ($line, $group) { } } +endif; From 20c4aa696c0e7d314d2922c19edfa39bf5fd802d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 07:50:27 -0700 Subject: [PATCH 3121/4858] Make it clearer where the `function_exists()` check ends --- php/Spyc.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/Spyc.php b/php/Spyc.php index 13b4c34156..4227b3ed96 100644 --- a/php/Spyc.php +++ b/php/Spyc.php @@ -10,7 +10,7 @@ * @package Spyc */ -if (!function_exists('spyc_load')) { +if (!function_exists('spyc_load')) : /** * Parses YAML to array. * @param string $string YAML string. @@ -19,9 +19,9 @@ function spyc_load ($string) { return Spyc::YAMLLoadString($string); } -} +endif; -if (!function_exists('spyc_load_file')) { +if (!function_exists('spyc_load_file')) : /** * Parses YAML to array. * @param string $file Path to YAML file. @@ -30,7 +30,7 @@ function spyc_load ($string) { function spyc_load_file ($file) { return Spyc::YAMLLoad($file); } -} +endif; if ( ! class_exists( 'Spyc' ) ) : /** From b9cef4020c279e6c9e8e313a9336aee1a44ab695 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 08:14:52 -0700 Subject: [PATCH 3122/4858] More clearly specify which fields are available on a cron event --- php/commands/cron.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index db4e07dd24..ebe9f95f9c 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -20,11 +20,27 @@ class Cron_Event_Command extends WP_CLI_Command { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Available fields: hook, next_run, next_run_gmt, next_run_relative, recurrence. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, json, csv, ids. Default: table. * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each cron event: + * * hook + * * next_run_gmt + * * next_run_relative + * * recurrence + * + * These fields are optionally available: + * * time + * * sig + * * args + * * schedule + * * interval + * * next_run + * * ## EXAMPLES * * wp cron event list From 537c60a96e03b6c47489cc330f772955064aad09 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 08:18:18 -0700 Subject: [PATCH 3123/4858] Prevent error notices when these variables aren't set --- php/commands/cron.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index ebe9f95f9c..640925fa1b 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -58,6 +58,13 @@ public function list_( $args, $assoc_args ) { $events = array(); } + if ( in_array( $formatter->format, array( 'table', 'csv' ) ) ) { + $events = array_map( function( $event ){ + $event->args = json_encode( $event->args ); + return $event; + }, $events ); + } + if ( 'ids' == $formatter->format ) { echo implode( ' ', wp_list_pluck( $events, 'hook' ) ); } else { @@ -93,9 +100,11 @@ public function list_( $args, $assoc_args ) { */ public function schedule( $args, $assoc_args ) { - list( $hook, $next_run, $recurrence ) = $args; + $hook = $args[0]; + $next_run = ( isset( $args[1] ) ) ? $args[1] : false; + $recurrence = ( isset( $args[2] ) ) ? $args[2] : false; - if ( !isset( $next_run ) ) { + if ( ! empty( $next_run ) ) { $timestamp = time(); } else if ( is_numeric( $next_run ) ) { $timestamp = absint( $next_run ); @@ -107,7 +116,7 @@ public function schedule( $args, $assoc_args ) { WP_CLI::error( sprintf( "'%s' is not a valid datetime.", $next_run ) ); } - if ( isset( $recurrence ) ) { + if ( ! empty( $recurrence ) ) { $schedules = wp_get_schedules(); From dd17b1930e8dfdf67916a3c172ad7ff320911dd7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 08:23:18 -0700 Subject: [PATCH 3124/4858] Tests for 537c60a96e03b6c47489cc330f772955064aad09 --- features/cron.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index a25404172b..e8596301e1 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -4,16 +4,16 @@ Feature: Manage WP-Cron events and schedules Given a WP install Scenario: Scheduling and then deleting an event - When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour'` + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour' --apple=banana` Then STDOUT should contain: """ Success: Scheduled event with hook 'wp_cli_test_event_1' """ - When I run `wp cron event list --format=csv --fields=hook,recurrence` + When I run `wp cron event list --format=csv --fields=hook,recurrence,args` Then STDOUT should be CSV containing: - | hook | recurrence | - | wp_cli_test_event_1 | Non-repeating | + | hook | recurrence | args | + | wp_cli_test_event_1 | Non-repeating | {"apple":"banana"} | When I run `wp cron event delete wp_cli_test_event_1` Then STDOUT should contain: From 3004b1b0c1454e7d4fe885626ca5191b42ab00c4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 08:57:47 -0700 Subject: [PATCH 3125/4858] If there is more than one instance of an event, perform action on all instances Previously, the `break;` meant only the first instance would be affected. --- features/cron.feature | 61 +++++++++++++++++++++++++++++++++++++++++-- php/commands/cron.php | 28 +++++++++++++------- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index e8596301e1..dbce7c356e 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -18,7 +18,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event delete wp_cli_test_event_1` Then STDOUT should contain: """ - Success: Successfully deleted the cron event 'wp_cli_test_event_1' + Success: Deleted 1 instances of the cron event 'wp_cli_test_event_1' """ When I run `wp cron event list` @@ -48,6 +48,63 @@ Feature: Manage WP-Cron events and schedules wp_cli_test_event_3 """ + Scenario: Scheduling, running, and deleting duplicate events + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --apple=banana` + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --foo=bar` + Then STDOUT should not be empty + + When I run `wp cron event list --format=csv --fields=hook,recurrence,args` + Then STDOUT should be CSV containing: + | hook | recurrence | args | + | wp_cli_test_event_5 | Non-repeating | {"apple":"banana"} | + | wp_cli_test_event_5 | Non-repeating | {"foo":"bar"} | + + When I run `wp cron event run wp_cli_test_event_5` + Then STDOUT should be: + """ + Success: Executed 2 instances of the cron event 'wp_cli_test_event_5' + """ + + When I run `wp cron event list` + Then STDOUT should not contain: + """ + wp_cli_test_event_5 + """ + + When I try `wp cron event run wp_cli_test_event_5` + Then STDERR should be: + """ + Error: Invalid cron event 'wp_cli_test_event_5' + """ + + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --apple=banana` + When I run `wp cron event schedule wp_cli_test_event_5 '+20 minutes' --foo=bar` + Then STDOUT should not be empty + + When I run `wp cron event list` + Then STDOUT should contain: + """ + wp_cli_test_event_5 + """ + + When I run `wp cron event delete wp_cli_test_event_5` + Then STDOUT should be: + """ + Success: Deleted 2 instances of the cron event 'wp_cli_test_event_5' + """ + + When I run `wp cron event list` + Then STDOUT should not contain: + """ + wp_cli_test_event_5 + """ + + When I try `wp cron event delete wp_cli_test_event_5` + Then STDERR should be: + """ + Error: Invalid cron event 'wp_cli_test_event_5' + """ + Scenario: Scheduling and then running a re-occurring event When I run `wp cron event schedule wp_cli_test_event_4 now hourly` Then STDOUT should contain: @@ -84,7 +141,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event delete wp_cli_test_event_2` Then STDOUT should contain: """ - Success: Successfully deleted the cron event 'wp_cli_test_event_2' + Success: Deleted 1 instances of the cron event 'wp_cli_test_event_2' """ When I run `wp cron event list` diff --git a/php/commands/cron.php b/php/commands/cron.php index 640925fa1b..9e73d145d3 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -151,24 +151,28 @@ public function schedule( $args, $assoc_args ) { public function run( $args, $assoc_args ) { $hook = $args[0]; - $result = false; $events = self::get_cron_events(); if ( is_wp_error( $events ) ) { WP_CLI::error( $events ); } + $executed = 0; foreach ( $events as $id => $event ) { if ( $event->hook == $hook ) { $result = self::run_event( $event ); - break; + if ( $result ) { + $executed++; + } else { + WP_CLI::warning( sprintf( "Failed to the execute the cron event '%s'", $hook ) ); + } } } - if ( $result ) { - WP_CLI::success( sprintf( "Successfully executed the cron event '%s'", $hook ) ); + if ( $executed ) { + WP_CLI::success( sprintf( "Executed %d instances of the cron event '%s'", $executed, $hook ) ); } else { - WP_CLI::error( sprintf( "Failed to the execute the cron event '%s'", $hook ) ); + WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); } } @@ -209,24 +213,28 @@ protected static function run_event( stdClass $event ) { public function delete( $args, $assoc_args ) { $hook = $args[0]; - $result = false; $events = self::get_cron_events(); if ( is_wp_error( $events ) ) { WP_CLI::error( $events ); } + $deleted = 0; foreach ( $events as $id => $event ) { if ( $event->hook == $hook ) { $result = self::delete_event( $event ); - break; + if ( $result ) { + $deleted++; + } else { + WP_CLI::warning( sprintf( "Failed to the delete the cron event '%s'", $hook ) ); + } } } - if ( $result ) { - WP_CLI::success( sprintf( "Successfully deleted the cron event '%s'", $hook ) ); + if ( $deleted ) { + WP_CLI::success( sprintf( "Deleted %d instances of the cron event '%s'", $deleted, $hook ) ); } else { - WP_CLI::error( sprintf( "Failed to the delete the cron event '%s'", $hook ) ); + WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); } } From 2e57b4eed6d1f946e051690bd45029fc99f08348 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 10:55:40 -0700 Subject: [PATCH 3126/4858] Abstract `_request()` to a common utility so we can use inside a filter --- php/commands/core.php | 43 ++++--------------------------------------- php/utils.php | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index c9c084a4ee..8a6fa747c8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -75,7 +75,7 @@ public function download( $args, $assoc_args ) { 'filename' => $temp ); - self::_request( 'GET', $download_url, $headers, $options ); + Utils\get_request( $download_url, $headers, $options ); self::_extract( $temp, ABSPATH ); $cache->import( $cache_key, $temp ); unlink($temp); @@ -134,44 +134,9 @@ private static function _rmdir( $dir ) { rmdir( $dir ); } - private static function _request( $method, $url, $headers = array(), $options = array() ) { - $pem_copied = false; - - // cURL can't read Phar archives - if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { - $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; - - copy( - WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem', - $options['verify'] - ); - $pem_copied = true; - } - - try { - $request = Requests::get( $url, $headers, $options ); - if ( $pem_copied ) { - unlink( $options['verify'] ); - } - return $request; - } catch( Requests_Exception $ex ) { - // Handle SSL certificate issues gracefully - WP_CLI::warning( $ex->getMessage() ); - if ( $pem_copied ) { - unlink( $options['verify'] ); - } - $options['verify'] = false; - try { - return Requests::get( $url, $headers, $options ); - } catch( Requests_Exception $ex ) { - WP_CLI::error( $ex->getMessage() ); - } - } - } - private static function _read( $url ) { $headers = array('Accept' => 'application/json'); - return self::_request( 'GET', $url, $headers )->body; + return Utils\get_request( $url, $headers )->body; } private function get_download_offer( $locale ) { @@ -694,11 +659,11 @@ private static function get_core_checksums( $version, $locale ) { $headers = array( 'Accept' => 'application/json' ); - $response = self::_request( 'GET', $url, $headers, $options ); + $response = Utils\get_request( $url, $headers, $options ); if ( $ssl && ! $response->success ) { WP_CLI::warning( 'wp-cli could not establish a secure connection to WordPress.org. Please contact your server administrator.' ); - $response = self::_request( 'GET', $http_url, $headers, $options ); + $response = Utils\get_request( $http_url, $headers, $options ); } if ( ! $response->success || 200 != $response->status_code ) diff --git a/php/utils.php b/php/utils.php index e033be5bb1..60362ad7b4 100644 --- a/php/utils.php +++ b/php/utils.php @@ -401,3 +401,45 @@ function replace_path_consts( $source, $path ) { return str_replace( $old, $new, $source ); } + +/** + * Download a remote URL + * + * @param string $url + * @param array $headers + * @param array $options + */ +function get_request( $url, $headers = array(), $options = array() ) { + $pem_copied = false; + + // cURL can't read Phar archives + if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { + $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; + + copy( + WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem', + $options['verify'] + ); + $pem_copied = true; + } + + try { + $request = \Requests::get( $url, $headers, $options ); + if ( $pem_copied ) { + unlink( $options['verify'] ); + } + return $request; + } catch( \Requests_Exception $ex ) { + // Handle SSL certificate issues gracefully + \WP_CLI::warning( $ex->getMessage() ); + if ( $pem_copied ) { + unlink( $options['verify'] ); + } + $options['verify'] = false; + try { + return \Requests::get( $url, $headers, $options ); + } catch( \Requests_Exception $ex ) { + \WP_CLI::error( $ex->getMessage() ); + } + } +} From 7e4d2f685608b33fa6210b0c3e20b8b082272635 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 11:01:21 -0700 Subject: [PATCH 3127/4858] `wp core update` should use cached files too --- features/core.feature | 20 ++++++++++++++++++++ php/commands/core.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/features/core.feature b/features/core.feature index a8998aecd0..4191bdb6fc 100644 --- a/features/core.feature +++ b/features/core.feature @@ -299,6 +299,26 @@ Feature: Manage WordPress installation Error: WordPress install doesn't verify against checksums. """ + Scenario: Core update from cache + Given a WP install + And an empty cache + + When I run `wp core update --version=3.8.1 --force` + Then STDOUT should not contain: + """ + Using cached file + """ + + When I run `wp core update --version=3.9 --force` + Then STDOUT should not be empty + + When I run `wp core update --version=3.8.1 --force` + Then STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/core/en_US-3.8.1.tar.gz'... + """ + + Scenario: User defined in wp-cli.yml Given an empty directory And WP files diff --git a/php/commands/core.php b/php/commands/core.php index 8a6fa747c8..c8483cdb1b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -819,7 +819,38 @@ function update( $args, $assoc_args ) { WP_CLI::log( "Starting update..." ); } + $defer_cached_file = function( $reply, $package, $upgrader ) use ( $update ) { + + if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists( $package ) ) //Local file or remote? + return $reply; //must be a local file.. + + $cache = WP_CLI::get_cache(); + $cache_key = "core/{$update->locale}-{$update->version}.tar.gz"; + $cache_file = $cache->has( $cache_key ); + + if ( $cache_file ) { + WP_CLI::log( "Using cached file '$cache_file'..." ); + return $cache_file; + } else { + // We need to use a temporary file because piping from cURL to tar is flaky + // on MinGW (and probably in other environments too). + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + + $headers = array('Accept' => 'application/json'); + $options = array( + 'timeout' => 600, // 10 minutes ought to be enough for everybody + 'filename' => $temp + ); + + Utils\get_request( $package, $headers, $options ); + $cache->import( $cache_key, $temp ); + unlink($temp); + return $cache->has( $cache_key ); + } + }; + add_filter( 'upgrader_pre_download', $defer_cached_file, 10, 3 ); $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); + remove_filter( 'upgrader_pre_download', $defer_cached_file ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); From 5fbcb26b8b1cca7aa29a1ac8b163b80aa9d96b2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 11:43:11 -0700 Subject: [PATCH 3128/4858] Copy cache to a temp file, so upgrader can later delete it --- php/commands/core.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index c8483cdb1b..cd411989bb 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -824,13 +824,16 @@ function update( $args, $assoc_args ) { if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists( $package ) ) //Local file or remote? return $reply; //must be a local file.. + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + $cache = WP_CLI::get_cache(); $cache_key = "core/{$update->locale}-{$update->version}.tar.gz"; $cache_file = $cache->has( $cache_key ); if ( $cache_file ) { WP_CLI::log( "Using cached file '$cache_file'..." ); - return $cache_file; + copy( $cache_file, $temp ); + return $temp; } else { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). @@ -844,8 +847,7 @@ function update( $args, $assoc_args ) { Utils\get_request( $package, $headers, $options ); $cache->import( $cache_key, $temp ); - unlink($temp); - return $cache->has( $cache_key ); + return $temp; } }; add_filter( 'upgrader_pre_download', $defer_cached_file, 10, 3 ); From 8359b62380c99bbc8aa9bd20a8178b45f070bf2e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 12:36:43 -0700 Subject: [PATCH 3129/4858] Subclass, because the filter we want to use isn't available until 3.7.1 --- php/WP_CLI/CoreUpgrader.php | 67 +++++++++++++++++++++++ php/WP_CLI/NonDestructiveCoreUpgrader.php | 2 +- php/commands/core.php | 37 +------------ 3 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 php/WP_CLI/CoreUpgrader.php diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php new file mode 100644 index 0000000000..37cc7f0d40 --- /dev/null +++ b/php/WP_CLI/CoreUpgrader.php @@ -0,0 +1,67 @@ +<?php + +namespace WP_CLI; + +use WP_CLI; + +/** + * A Core Upgrader class that caches the download, and uses cached if available + * + * @package wp-cli + */ +class CoreUpgrader extends \Core_Upgrader { + + function download_package( $package ) { + + /** + * Filter whether to return the package. + * + * @since 3.7.0 + * + * @param bool $reply Whether to bail without returning the package. Default is false. + * @param string $package The package file name. + * @param object $this The WP_Upgrader instance. + */ + $reply = apply_filters( 'upgrader_pre_download', false, $package, $this ); + if ( false !== $reply ) + return $reply; + + if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote? + return $package; //must be a local file.. + + if ( empty( $package ) ) + return new WP_Error( 'no_package', $this->strings['no_package'] ); + + $this->skin->feedback( 'downloading_package', $package ); + + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + + $cache = WP_CLI::get_cache(); + $update = $GLOBALS['wp_cli_update_obj']; + $cache_key = "core/{$update->locale}-{$update->version}.tar.gz"; + $cache_file = $cache->has( $cache_key ); + + if ( $cache_file ) { + WP_CLI::log( "Using cached file '$cache_file'..." ); + copy( $cache_file, $temp ); + return $temp; + } else { + // We need to use a temporary file because piping from cURL to tar is flaky + // on MinGW (and probably in other environments too). + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + + $headers = array('Accept' => 'application/json'); + $options = array( + 'timeout' => 600, // 10 minutes ought to be enough for everybody + 'filename' => $temp + ); + + Utils\get_request( $package, $headers, $options ); + $cache->import( $cache_key, $temp ); + return $temp; + } + + } + +} + diff --git a/php/WP_CLI/NonDestructiveCoreUpgrader.php b/php/WP_CLI/NonDestructiveCoreUpgrader.php index 41ba059493..ebad21cbd2 100644 --- a/php/WP_CLI/NonDestructiveCoreUpgrader.php +++ b/php/WP_CLI/NonDestructiveCoreUpgrader.php @@ -7,7 +7,7 @@ * * @package wp-cli */ -class NonDestructiveCoreUpgrader extends \Core_Upgrader { +class NonDestructiveCoreUpgrader extends CoreUpgrader { function unpack_package($package, $delete_package = false) { return parent::unpack_package( $package, $delete_package ); } diff --git a/php/commands/core.php b/php/commands/core.php index cd411989bb..f95e396e9d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -750,7 +750,7 @@ function update( $args, $assoc_args ) { global $wp_version; $update = $from_api = null; - $upgrader = 'Core_Upgrader'; + $upgrader = 'WP_CLI\\CoreUpgrader'; if ( ! empty( $args[0] ) ) { @@ -819,40 +819,9 @@ function update( $args, $assoc_args ) { WP_CLI::log( "Starting update..." ); } - $defer_cached_file = function( $reply, $package, $upgrader ) use ( $update ) { - - if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists( $package ) ) //Local file or remote? - return $reply; //must be a local file.. - - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; - - $cache = WP_CLI::get_cache(); - $cache_key = "core/{$update->locale}-{$update->version}.tar.gz"; - $cache_file = $cache->has( $cache_key ); - - if ( $cache_file ) { - WP_CLI::log( "Using cached file '$cache_file'..." ); - copy( $cache_file, $temp ); - return $temp; - } else { - // We need to use a temporary file because piping from cURL to tar is flaky - // on MinGW (and probably in other environments too). - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; - - $headers = array('Accept' => 'application/json'); - $options = array( - 'timeout' => 600, // 10 minutes ought to be enough for everybody - 'filename' => $temp - ); - - Utils\get_request( $package, $headers, $options ); - $cache->import( $cache_key, $temp ); - return $temp; - } - }; - add_filter( 'upgrader_pre_download', $defer_cached_file, 10, 3 ); + $GLOBALS['wp_cli_update_obj'] = $update; $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); - remove_filter( 'upgrader_pre_download', $defer_cached_file ); + unset( $GLOBALS['wp_cli_update_obj'] ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); From 8ec0370bdee7ca01db980ada68a397d3de055e34 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 12:40:36 -0700 Subject: [PATCH 3130/4858] Only indicate "Downloading" when we're actually downloading something --- features/core.feature | 8 ++++++++ php/WP_CLI/CoreUpgrader.php | 4 ++-- php/commands/core.php | 2 -- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index 4191bdb6fc..9be8d2686d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -308,6 +308,10 @@ Feature: Manage WordPress installation """ Using cached file """ + And STDOUT should contain: + """ + Downloading + """ When I run `wp core update --version=3.9 --force` Then STDOUT should not be empty @@ -317,6 +321,10 @@ Feature: Manage WordPress installation """ Using cached file '{SUITE_CACHE_DIR}/core/en_US-3.8.1.tar.gz'... """ + And STDOUT should not contain: + """ + Downloading + """ Scenario: User defined in wp-cli.yml diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index 37cc7f0d40..f30dfbdbb6 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -32,8 +32,6 @@ function download_package( $package ) { if ( empty( $package ) ) return new WP_Error( 'no_package', $this->strings['no_package'] ); - $this->skin->feedback( 'downloading_package', $package ); - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; $cache = WP_CLI::get_cache(); @@ -56,6 +54,8 @@ function download_package( $package ) { 'filename' => $temp ); + $this->skin->feedback( 'downloading_package', $package ); + Utils\get_request( $package, $headers, $options ); $cache->import( $cache_key, $temp ); return $temp; diff --git a/php/commands/core.php b/php/commands/core.php index f95e396e9d..fed6a8cc65 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -790,8 +790,6 @@ function update( $args, $assoc_args ) { $new_package = $this->get_download_url($version, $locale); - WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $assoc_args['version'], $locale ) ); - $update = (object) array( 'response' => 'upgrade', 'current' => $assoc_args['version'], From 3811d39e217b333b0dcf86428368f7a1cc02e6ef Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 12:44:46 -0700 Subject: [PATCH 3131/4858] Make this method generally more useful --- php/WP_CLI/CoreUpgrader.php | 2 +- php/commands/core.php | 8 ++++---- php/utils.php | 10 +++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index f30dfbdbb6..931fd4bbad 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -56,7 +56,7 @@ function download_package( $package ) { $this->skin->feedback( 'downloading_package', $package ); - Utils\get_request( $package, $headers, $options ); + Utils\http_request( 'GET', $package, $headers, $options ); $cache->import( $cache_key, $temp ); return $temp; } diff --git a/php/commands/core.php b/php/commands/core.php index fed6a8cc65..d88f3e6a0f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -75,7 +75,7 @@ public function download( $args, $assoc_args ) { 'filename' => $temp ); - Utils\get_request( $download_url, $headers, $options ); + Utils\http_request( 'GET', $download_url, $headers, $options ); self::_extract( $temp, ABSPATH ); $cache->import( $cache_key, $temp ); unlink($temp); @@ -136,7 +136,7 @@ private static function _rmdir( $dir ) { private static function _read( $url ) { $headers = array('Accept' => 'application/json'); - return Utils\get_request( $url, $headers )->body; + return Utils\http_request( 'GET', $url, $headers )->body; } private function get_download_offer( $locale ) { @@ -659,11 +659,11 @@ private static function get_core_checksums( $version, $locale ) { $headers = array( 'Accept' => 'application/json' ); - $response = Utils\get_request( $url, $headers, $options ); + $response = Utils\http_request( 'GET', $url, $headers, $options ); if ( $ssl && ! $response->success ) { WP_CLI::warning( 'wp-cli could not establish a secure connection to WordPress.org. Please contact your server administrator.' ); - $response = Utils\get_request( $http_url, $headers, $options ); + $response = Utils\http_request( 'GET', $http_url, $headers, $options ); } if ( ! $response->success || 200 != $response->status_code ) diff --git a/php/utils.php b/php/utils.php index 60362ad7b4..3b34f5360e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -403,13 +403,15 @@ function replace_path_consts( $source, $path ) { } /** - * Download a remote URL + * Make a HTTP request to a remote URL * + * @param string $method * @param string $url * @param array $headers * @param array $options + * @return object */ -function get_request( $url, $headers = array(), $options = array() ) { +function http_request( $method, $url, $headers = array(), $options = array() ) { $pem_copied = false; // cURL can't read Phar archives @@ -423,8 +425,10 @@ function get_request( $url, $headers = array(), $options = array() ) { $pem_copied = true; } + $method = strtolower( $method ); + try { - $request = \Requests::get( $url, $headers, $options ); + $request = \Requests::$method( $url, $headers, $options ); if ( $pem_copied ) { unlink( $options['verify'] ); } From b438af1924057350a7ab93b690b74c90ac0fc22e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 12:47:42 -0700 Subject: [PATCH 3132/4858] Validate methods --- php/utils.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index 3b34f5360e..96d6419393 100644 --- a/php/utils.php +++ b/php/utils.php @@ -414,6 +414,13 @@ function replace_path_consts( $source, $path ) { function http_request( $method, $url, $headers = array(), $options = array() ) { $pem_copied = false; + $method = strtolower( $method ); + + if ( ! in_array( $method, array( 'get', 'post', 'put', 'delete', 'head', 'patch' ) ) ) { + $method = strtoupper( $method ); + WP_CLI::error( "Invalid method: {$method}" ); + } + // cURL can't read Phar archives if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; @@ -425,8 +432,6 @@ function http_request( $method, $url, $headers = array(), $options = array() ) { $pem_copied = true; } - $method = strtolower( $method ); - try { $request = \Requests::$method( $url, $headers, $options ); if ( $pem_copied ) { From 494cc3e82c754496ac8fec1098839337dcceab72 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 15:15:19 -0700 Subject: [PATCH 3133/4858] Allow `\Requests` to validate method on its own --- php/utils.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/php/utils.php b/php/utils.php index 96d6419393..e9baef00e6 100644 --- a/php/utils.php +++ b/php/utils.php @@ -414,13 +414,6 @@ function replace_path_consts( $source, $path ) { function http_request( $method, $url, $headers = array(), $options = array() ) { $pem_copied = false; - $method = strtolower( $method ); - - if ( ! in_array( $method, array( 'get', 'post', 'put', 'delete', 'head', 'patch' ) ) ) { - $method = strtoupper( $method ); - WP_CLI::error( "Invalid method: {$method}" ); - } - // cURL can't read Phar archives if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; @@ -433,7 +426,7 @@ function http_request( $method, $url, $headers = array(), $options = array() ) { } try { - $request = \Requests::$method( $url, $headers, $options ); + $request = \Requests::request( $url, null, $method, $headers, $options ); if ( $pem_copied ) { unlink( $options['verify'] ); } @@ -446,7 +439,7 @@ function http_request( $method, $url, $headers = array(), $options = array() ) { } $options['verify'] = false; try { - return \Requests::get( $url, $headers, $options ); + return \Requests::request( $url, null, $method, $headers, $options ); } catch( \Requests_Exception $ex ) { \WP_CLI::error( $ex->getMessage() ); } From ec52a45ca1255dcafe46cfb0b30fc5a441a661fc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 21 Aug 2014 15:44:24 -0700 Subject: [PATCH 3134/4858] Pass args in expected order, and allow `$data` as an option too --- php/WP_CLI/CoreUpgrader.php | 2 +- php/commands/core.php | 8 ++++---- php/utils.php | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index 931fd4bbad..d3d3692e44 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -56,7 +56,7 @@ function download_package( $package ) { $this->skin->feedback( 'downloading_package', $package ); - Utils\http_request( 'GET', $package, $headers, $options ); + Utils\http_request( 'GET', $package, null, $headers, $options ); $cache->import( $cache_key, $temp ); return $temp; } diff --git a/php/commands/core.php b/php/commands/core.php index d88f3e6a0f..9466a3e6fe 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -75,7 +75,7 @@ public function download( $args, $assoc_args ) { 'filename' => $temp ); - Utils\http_request( 'GET', $download_url, $headers, $options ); + Utils\http_request( 'GET', $download_url, null, $headers, $options ); self::_extract( $temp, ABSPATH ); $cache->import( $cache_key, $temp ); unlink($temp); @@ -136,7 +136,7 @@ private static function _rmdir( $dir ) { private static function _read( $url ) { $headers = array('Accept' => 'application/json'); - return Utils\http_request( 'GET', $url, $headers )->body; + return Utils\http_request( 'GET', $url, null, $headers )->body; } private function get_download_offer( $locale ) { @@ -659,11 +659,11 @@ private static function get_core_checksums( $version, $locale ) { $headers = array( 'Accept' => 'application/json' ); - $response = Utils\http_request( 'GET', $url, $headers, $options ); + $response = Utils\http_request( 'GET', $url, null, $headers, $options ); if ( $ssl && ! $response->success ) { WP_CLI::warning( 'wp-cli could not establish a secure connection to WordPress.org. Please contact your server administrator.' ); - $response = Utils\http_request( 'GET', $http_url, $headers, $options ); + $response = Utils\http_request( 'GET', $http_url, null, $headers, $options ); } if ( ! $response->success || 200 != $response->status_code ) diff --git a/php/utils.php b/php/utils.php index e9baef00e6..fbee550acb 100644 --- a/php/utils.php +++ b/php/utils.php @@ -411,7 +411,7 @@ function replace_path_consts( $source, $path ) { * @param array $options * @return object */ -function http_request( $method, $url, $headers = array(), $options = array() ) { +function http_request( $method, $url, $data = null, $headers = array(), $options = array() ) { $pem_copied = false; // cURL can't read Phar archives @@ -426,7 +426,7 @@ function http_request( $method, $url, $headers = array(), $options = array() ) { } try { - $request = \Requests::request( $url, null, $method, $headers, $options ); + $request = \Requests::request( $url, $headers, $data, $method, $options ); if ( $pem_copied ) { unlink( $options['verify'] ); } @@ -439,7 +439,7 @@ function http_request( $method, $url, $headers = array(), $options = array() ) { } $options['verify'] = false; try { - return \Requests::request( $url, null, $method, $headers, $options ); + return \Requests::request( $url, $headers, $data, $method, $options ); } catch( \Requests_Exception $ex ) { \WP_CLI::error( $ex->getMessage() ); } From f8f6d71fac046d396b593e230506b82a619cefab Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 25 Aug 2014 21:01:02 +0100 Subject: [PATCH 3135/4858] Correct the grammar when executing or deleting cron events where there is only one instance. --- features/cron.feature | 4 ++-- php/commands/cron.php | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index dbce7c356e..0f638f6f6e 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -18,7 +18,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event delete wp_cli_test_event_1` Then STDOUT should contain: """ - Success: Deleted 1 instances of the cron event 'wp_cli_test_event_1' + Success: Deleted the cron event 'wp_cli_test_event_1' """ When I run `wp cron event list` @@ -141,7 +141,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event delete wp_cli_test_event_2` Then STDOUT should contain: """ - Success: Deleted 1 instances of the cron event 'wp_cli_test_event_2' + Success: Deleted the cron event 'wp_cli_test_event_2' """ When I run `wp cron event list` diff --git a/php/commands/cron.php b/php/commands/cron.php index 9e73d145d3..4bdf4904ce 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -170,7 +170,8 @@ public function run( $args, $assoc_args ) { } if ( $executed ) { - WP_CLI::success( sprintf( "Executed %d instances of the cron event '%s'", $executed, $hook ) ); + $message = ( 1 == $executed ) ? "Executed the cron event '%2\$s'" : "Executed %1\$d instances of the cron event '%2\$s'"; + WP_CLI::success( sprintf( $message, $executed, $hook ) ); } else { WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); } @@ -232,7 +233,8 @@ public function delete( $args, $assoc_args ) { } if ( $deleted ) { - WP_CLI::success( sprintf( "Deleted %d instances of the cron event '%s'", $deleted, $hook ) ); + $message = ( 1 == $deleted ) ? "Deleted the cron event '%2\$s'" : "Deleted %1\$d instances of the cron event '%2\$s'"; + WP_CLI::success( sprintf( $message, $deleted, $hook ) ); } else { WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); } From 680a08771dc6112e3ebffd411b12dec8333c6477 Mon Sep 17 00:00:00 2001 From: Joshua Eichorn <joshua.eichorn@pagely.com> Date: Wed, 27 Aug 2014 19:18:19 +0000 Subject: [PATCH 3136/4858] Fix WP_CLI::colorize warnings Passing an array to colorize causes warnings since the passed in value ends up being passed into md5 Warning was PHP Warning: md5() expects parameter 1 to be string, array given in git/wp-cli/vendor/wp-cli/php-cli-tools/lib/cli/Colors.php on line 118 --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 1bbe9ae56f..0ce9d34e96 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -104,7 +104,7 @@ private function show_legend( $items ) { if ( in_array( true, wp_list_pluck( $items, 'update' ) ) ) $legend_line[] = '%yU = Update Available%n'; - \WP_CLI::line( 'Legend: ' . implode( ', ', \WP_CLI::colorize( $legend_line ) ) ); + \WP_CLI::line( 'Legend: ' . \WP_CLI::colorize( implode( ', ', $legend_line ) ) ); } function install( $args, $assoc_args ) { From 6398db537750b233a810c689eb8c2e5fa63f8b10 Mon Sep 17 00:00:00 2001 From: Joshua Eichorn <joshua.eichorn@pagely.com> Date: Wed, 27 Aug 2014 20:54:34 +0000 Subject: [PATCH 3137/4858] Add a summary table to the output of plugin update Example: Enabling Maintenance mode... Downloading update from https://downloads.wordpress.org/plugin/akismet.3.0.2.zip... Using cached file '/home/jeichorn/.wp-cli/cache/plugin/akismet-3.0.2.zip'... Unpacking the update... Installing the latest version... Removing the old version of the plugin... Plugin updated successfully. Disabling Maintenance mode... Success: Updated 1/1 plugins. +---------+-------------+-------------+---------+ | name | old_version | new_version | status | +---------+-------------+-------------+---------+ | akismet | 3.0.0 | 3.0.2 | Updated | +---------+-------------+-------------+---------+ --- php/WP_CLI/CommandWithUpgrade.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 1bbe9ae56f..01b146f05f 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -252,6 +252,20 @@ protected function update_many( $args, $assoc_args ) { } else { \WP_CLI::error( $line ); } + + if ($num_to_update > 0) { + $status = array(); + foreach($items_to_update as $item_to_update => $info) { + $status[$item_to_update] = array( + 'name' => $info['name'], + 'old_version' => $info['version'], + 'new_version' => $info['update_version'], + 'status' => $result[$item_to_update] !== null ? 'Updated' : 'Error', + ); + } + \WP_CLI\Utils\format_items( 'table', $status, + array( 'name', 'old_version', 'new_version', 'status' ) ); + } } protected function _list( $_, $assoc_args ) { From b76388b2be29b535c1f1724c2cc9aafbb5f18f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 28 Aug 2014 21:47:55 +0200 Subject: [PATCH 3138/4858] param-dump dumps current values --- php/commands/cli.php | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index bfc3a91a3c..8964f6f028 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -70,12 +70,34 @@ function info( $_, $assoc_args ) { } /** - * Dump the list of global parameters, as JSON. + * Dump the list of global parameters, as JSON or by var_export. + * + * ## OPTIONS + * + * [--format=<format>] + * : Accepted values: var_export * * @subcommand param-dump */ - function param_dump() { - echo json_encode( \WP_CLI::get_configurator()->get_spec() ); + function param_dump( $_, $assoc_args ) { + $spec = \WP_CLI::get_configurator()->get_spec(); + $config = \WP_CLI::get_configurator()->to_array(); + + // copy current config values to $spec + foreach ( $spec as $key => $value ) { + if ( isset( $config[0][$key] ) ) { + $current = $config[0][$key]; + } else { + $current = NULL; + } + $spec[$key]['current'] = $current; + } + + if ( isset( $assoc_args['format'] ) && 'var_export' === $assoc_args['format'] ) { + var_export( $spec ); + } else { + echo json_encode( $spec ); + } } /** From 363fe0ef06709f9837bc856adf6007b53dbc62ff Mon Sep 17 00:00:00 2001 From: Joshua Eichorn <joshua.eichorn@pagely.com> Date: Thu, 28 Aug 2014 21:16:49 +0000 Subject: [PATCH 3139/4858] Convert spaces to hard tabs --- php/WP_CLI/CommandWithUpgrade.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 01b146f05f..cc89361399 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -253,19 +253,19 @@ protected function update_many( $args, $assoc_args ) { \WP_CLI::error( $line ); } - if ($num_to_update > 0) { - $status = array(); - foreach($items_to_update as $item_to_update => $info) { - $status[$item_to_update] = array( - 'name' => $info['name'], - 'old_version' => $info['version'], - 'new_version' => $info['update_version'], - 'status' => $result[$item_to_update] !== null ? 'Updated' : 'Error', - ); - } - \WP_CLI\Utils\format_items( 'table', $status, - array( 'name', 'old_version', 'new_version', 'status' ) ); - } + if ($num_to_update > 0) { + $status = array(); + foreach($items_to_update as $item_to_update => $info) { + $status[$item_to_update] = array( + 'name' => $info['name'], + 'old_version' => $info['version'], + 'new_version' => $info['update_version'], + 'status' => $result[$item_to_update] !== null ? 'Updated' : 'Error', + ); + } + \WP_CLI\Utils\format_items( 'table', $status, + array( 'name', 'old_version', 'new_version', 'status' ) ); + } } protected function _list( $_, $assoc_args ) { From b8ce086765e61bea52986cd6e7a95d10510c261e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 30 Aug 2014 00:44:17 +0200 Subject: [PATCH 3140/4858] core check-update --- php/commands/core.php | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 9466a3e6fe..be93ee0cf6 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -9,6 +9,59 @@ */ class Core_Command extends WP_CLI_Command { + /** + * Check for update via Version Check API. Returns latest version if there's an update, or empty if no update available. + * + * ## OPTIONS + * + * [--major] + * : Compare only the first two parts of the version numbers. + * + * @subcommand check-update + */ + function check_update( $_, $assoc_args ) { + $versions_path = ABSPATH . 'wp-includes/version.php'; + + if ( ! is_readable( $versions_path ) ) { + WP_CLI::error( + "This does not seem to be a WordPress install.\n" . + "Pass --path=`path/to/wordpress` or run `wp core download`." ); + } + + include $versions_path; + + $url = 'http://api.wordpress.org/core/version-check/1.7/'; + + $options = array( + 'timeout' => 30 + ); + + $headers = array( + 'Accept' => 'application/json' + ); + $response = Utils\request( 'GET', $url, $headers, $options ); + + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( "Failed to get latest version." ); + } + + $latest_data = json_decode( $response->body ); + + $latest = $latest_data->offers[0]->current; + + if ( isset( $assoc_args['major'] ) ) { + $latest_major = explode( '.', $latest ); + $current_major = explode( '.', $wp_version ); + if ( $latest_major[0] !== $current_major[0] + || $latest_major[1] !== $current_major[1] ) { + WP_CLI::line( $latest ); + } + + } else { + WP_CLI::line( $latest ); + } + } + /** * Download core WordPress files. * From 882d25ba05cfe7e3cdc12defab7c2f81c511bf9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 30 Aug 2014 00:55:03 +0200 Subject: [PATCH 3141/4858] http_request and elseif() --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index be93ee0cf6..8113710131 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -39,7 +39,7 @@ function check_update( $_, $assoc_args ) { $headers = array( 'Accept' => 'application/json' ); - $response = Utils\request( 'GET', $url, $headers, $options ); + $response = Utils\http_request( 'GET', $url, $headers, $options ); if ( ! $response->success || 200 !== $response->status_code ) { WP_CLI::error( "Failed to get latest version." ); @@ -57,7 +57,7 @@ function check_update( $_, $assoc_args ) { WP_CLI::line( $latest ); } - } else { + } elseif ( $wp_version !== $latest ) { WP_CLI::line( $latest ); } } From 0f53bd07ca5e49c27b384cd1ed3788a46883fa18 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 30 Aug 2014 11:50:14 -0700 Subject: [PATCH 3142/4858] Example: Update one option against multiple sites See #1367 --- php/commands/option.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/option.php b/php/commands/option.php index ded55ce2be..962ef03cef 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -96,6 +96,9 @@ public function add( $args, $assoc_args ) { * # Update an option by reading from a file * wp option update my_option < value.txt * + * # Update one option on multiple sites using xargs + * wp site list --field=url | xargs -n1 -I {} sh -c 'wp --url={} option update <key> <value>' + * * @alias set */ public function update( $args, $assoc_args ) { From 912169a00b6ca4e4a18990b8d2b1b90f85b94cc4 Mon Sep 17 00:00:00 2001 From: Pippin Williamson <pippin@pippinsplugins.com> Date: Tue, 2 Sep 2014 19:09:17 -0500 Subject: [PATCH 3143/4858] Better error message for update() Return error messages for both identical values and update failures. --- php/commands/option.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index 7b9bc80af4..ea5d17f7d6 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -107,8 +107,10 @@ public function update( $args, $assoc_args ) { $result = update_option( $key, $value ); // update_option() returns false if the value is the same - if ( !$result && $value != get_option( $key ) ) { - WP_CLI::error( "Option '$key' value is already set to '$value'." ); + if ( ! $result ) { + WP_CLI::error( "Could not update option '$key'." ); + } else if ( $value == get_option( $key ) ) { + WP_CLI::error( "Value passed for '$key' option is unchanged." ); } else { WP_CLI::success( "Updated '$key' option." ); } From 31b9a2feb04c673764328568f8bddc0ecf15dfa8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigosprimo@gmail.com> Date: Thu, 4 Sep 2014 23:36:51 -0300 Subject: [PATCH 3144/4858] test coverage for `wp scaffold _s` --- features/scaffold.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index a02d3d9f20..438e1842ee 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -187,3 +187,15 @@ Feature: WordPress code scaffolding """ Error: Invalid package directory. composer.json file must be present. """ + + Scenario: Scaffold starter code for a theme + Given I run `wp theme path` + And save STDOUT as {THEME_DIR} + + When I run `wp scaffold _s starter-theme` + Then STDOUT should contain: + """ + Success: Created theme 'Starter-theme'. + """ + And the {THEME_DIR}/starter-theme/style.css file should exist + From 5e905ca9e3c7b7a235754e9791ce953be71b653c Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigosprimo@gmail.com> Date: Fri, 5 Sep 2014 00:00:28 -0300 Subject: [PATCH 3145/4858] fix `wp scaffold _s` --- php/commands/scaffold.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 3fd04361d1..babe849e42 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -216,6 +216,7 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); + $this->init_wp_filesystem(); unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); From 27b23a8a085595dd0493233bc034b875e44ff8d5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 09:58:36 -0700 Subject: [PATCH 3146/4858] Denote all available fields for `wp comment list` --- php/commands/comment.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 6a014cefd6..b490c902cf 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -127,11 +127,34 @@ public function get( $args, $assoc_args ) { * : Prints the value of a single field for each comment. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to comment_ID,comment_post_ID,comment_date,comment_approved,comment_author,comment_author_email + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each comment: + * + * * comment_ID + * * comment_post_ID + * * comment_date + * * comment_approved + * * comment_author + * * comment_author_email + * + * These fields are optionally available: + * + * * comment_author_url + * * comment_author_IP + * * comment_date_gmt + * * comment_content + * * comment_karma + * * comment_agent + * * comment_type + * * comment_parent + * * user_id + * * ## EXAMPLES * * wp comment list --field=ID From 4b9d5c0e7d0d356de7cf8eab0a66139f063f62e2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:01:56 -0700 Subject: [PATCH 3147/4858] Denote available fields for `wp cron schedule list` --- php/commands/cron.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 4bdf4904ce..93a75ee125 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -396,11 +396,21 @@ class Cron_Schedule_Command extends WP_CLI_Command { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Available fields: name, display, interval. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, json, csv, ids. Default: table. * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each cron schedule: + * + * * name + * * display + * * interval + * + * There are no additional fields. + * * ## EXAMPLES * * wp cron schedule list From bb7c308c251758e92b4ef4bfcbf2a97ff5cd21d0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:05:13 -0700 Subject: [PATCH 3148/4858] Denote available fields for `wp menu list` --- php/commands/menu.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index adc6ab2f06..fe9739837b 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -94,11 +94,29 @@ public function delete( $args, $_ ) { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to term_id,name,slug,count + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each menu: + * + * * term_id + * * name + * * slug + * * count + * + * These fields are optionally available: + * + * * term_group + * * term_taxonomy_id + * * taxonomy + * * description + * * parent + * * locations + * * ## EXAMPLES * * wp menu list From 172e36bdf768a4095f8e17e83a69e32a2564d40f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:10:30 -0700 Subject: [PATCH 3149/4858] Denote relevant available fields for `wp menu item list` --- php/commands/menu.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index fe9739837b..8219df7aeb 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -190,11 +190,34 @@ class Menu_Item_Command extends WP_CLI_Command { * : The name, slug, or term ID for the menu * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to db_id,type,title,link + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each menu item: + * + * * db_id + * * type + * * title + * * link + * * position + * + * These fields are optionally available: + * + * * menu_item_parent + * * object_id + * * object + * * type + * * type_label + * * target + * * attr_title + * * description + * * classes + * * xfn + * * ## EXAMPLES * * wp menu item list <menu> From 639f884bdafec1a8b05a8d13838ddb1d61349d93 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:12:15 -0700 Subject: [PATCH 3150/4858] Fix display of menu item classes in list table --- php/commands/menu.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 8219df7aeb..ee679c77f5 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -233,9 +233,12 @@ public function list_( $args, $assoc_args ) { // Correct position inconsistency and // protected `url` param in WP-CLI - $items = array_map( function( $item ) { + $items = array_map( function( $item ) use ( $assoc_args ) { $item->position = $item->menu_order; $item->link = $item->url; + if ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'json' ) ) ) { + $item->classes = json_encode( $item->classes ); + } return $item; }, $items ); From 5f0b465c78e135d79782689b6ac7af22ba898fa4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:16:18 -0700 Subject: [PATCH 3151/4858] Denote available fields for `wp menu location list` --- php/commands/menu.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index ee679c77f5..f71f9dbda8 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -624,6 +624,13 @@ class Menu_Location_Command extends WP_CLI_Command { * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each location: + * + * * name + * * description + * * ## EXAMPLES * * wp menu location list From 5750ccd1c7318601739ee9cbe4da2102d8e8198a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:31:21 -0700 Subject: [PATCH 3152/4858] Denote available fields for `wp plugin list` --- php/commands/plugin.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 74af879cb6..e33d270977 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -506,11 +506,28 @@ function delete( $args, $assoc_args = array() ) { * : Prints the value of a single field for each plugin. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to name,status,update,version. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each plugin: + * + * * name + * * status + * * update + * * version + * + * These fields are optionally available: + * + * * update_version + * * update_package + * * update_id + * * title + * * description + * * ## EXAMPLES * * wp plugin list --status=active --format=json From db74d8da674906e6a083252632048a21a7a55c49 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:31:57 -0700 Subject: [PATCH 3153/4858] Denote available fields for `wp theme list` --- php/commands/theme.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 3fd58af36c..c7eee76e40 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -516,11 +516,28 @@ function delete( $args ) { * : Prints the value of a single field for each theme. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to name,status,update,version. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, json. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each theme: + * + * * name + * * status + * * update + * * version + * + * These fields are optionally available: + * + * * update_version + * * update_package + * * update_id + * * title + * * description + * * ## EXAMPLES * * wp theme list --status=inactive --format=csv From 6950c89cdffc21f3e9ee4631f7f167c39d7a4e1d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:33:34 -0700 Subject: [PATCH 3154/4858] Formatting --- php/commands/rewrite.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index ccaffbc2ba..4bc3dced56 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -144,6 +144,7 @@ public function structure( $args, $assoc_args ) { * ## EXAMPLES * * wp rewrite list --format=csv + * * @subcommand list */ public function list_( $args, $assoc_args ) { From 680b6dea126c718428e38e930e3b1b00b6f8e4a2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:36:29 -0700 Subject: [PATCH 3155/4858] Denote available fields for `wp post list` --- php/commands/post.php | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index 84fa861a47..fdd0203f0c 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -211,11 +211,43 @@ public function delete( $args, $assoc_args ) { * : Prints the value of a single field for each post. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to ID,post_title,post_name,post_date,post_status. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each post: + * + * * ID + * * post_title + * * post_name + * * post_date + * * post_status + * + * These fields are optionally available: + * + * * post_author + * * post_date_gmt + * * post_content + * * post_excerpt + * * comment_status + * * ping_status + * * post_password + * * to_ping + * * pinged + * * post_modified + * * post_modified_gmt + * * post_content_filtered + * * post_parent + * * guid + * * menu_order + * * post_type + * * post_mime_type + * * comment_count + * * filter + * * ## EXAMPLES * * wp post list --field=ID From 23120d184f5c5dfefc598fd4b7434d958a4f043a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:38:06 -0700 Subject: [PATCH 3156/4858] Denote available fields for `wp role list` --- php/commands/role.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index f11d99f501..88b46eab0e 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -18,11 +18,20 @@ class Role_Command extends WP_CLI_Command { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to name,role. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each role: + * + * * name + * * role + * + * There are no optional fields. + * * ## EXAMPLES * * wp role list --fields=role --format=csv From 0e345ace27f5461b44a8e3efab90f89affdaf2eb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:45:13 -0700 Subject: [PATCH 3157/4858] Denote available fields for `wp sidebar list` --- php/commands/sidebar.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 626476868e..0096d4a6c1 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -17,11 +17,27 @@ class Sidebar_Command extends WP_CLI_Command { * ## OPTIONS * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to name, id, description + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each sidebar: + * + * * name + * * id + * * description + * + * These fields are optionally available: + * + * * class + * * before_widget + * * after_widget + * * before_title + * * after_title + * * ## EXAMPLES * * wp sidebar list --fields=name,id --format=csv From aa4b55a5e75c93d860ad251b4d6e76d59695d5fc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:50:38 -0700 Subject: [PATCH 3158/4858] Denote available fields for `wp site list --- php/commands/site.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index 7aa6ab2efd..7f286e1677 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -345,6 +345,27 @@ private function _get_network( $network_id ) { * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each site: + * + * * blog_id + * * url + * * last_updated + * * registered + * + * These fields are optionally available: + * + * * site_id + * * domain + * * path + * * public + * * archived + * * mature + * * spam + * * deleted + * * lang_id + * * ## EXAMPLES * * # Output a simple list of site URLs From 964d75a15a718fedd3861a0b1fb406ea77b31249 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:52:41 -0700 Subject: [PATCH 3159/4858] Denote available fields for `wp term list` --- php/commands/term.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 503fb9dacf..2e3e22ccdc 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -25,17 +25,31 @@ class Term_Command extends WP_CLI_Command { * : List terms of one or more taxonomies * * [--<field>=<value>] - * : Filter by one or more fields. For accepted fields, see get_terms(). + * : Filter by one or more fields. * * [--field=<field>] * : Prints the value of a single field for each term. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to all of the term object fields. + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each term: + * + * * term_id + * * term_taxonomy_id + * * name + * * slug + * * description + * * parent + * * count + * + * There are no optionally available fields. + * * ## EXAMPLES * * wp term list category --format=csv From 08b5e4fd5b70dfddce741ab167ac467c50fe1571 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:57:11 -0700 Subject: [PATCH 3160/4858] Denote available fields for `wp user list` --- php/commands/user.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index a46378d183..f41ea4b839 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -36,11 +36,36 @@ public function __construct() { * : Prints the value of a single field for each user. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to ID,user_login,display_name,user_email,user_registered,roles + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each user: + * + * * ID + * * user_login + * * display_name + * * user_email + * * user_registered + * * roles + * + * These fields are optionally available: + * + * * user_pass + * * user_nicename + * * user_url + * * user_activation_key + * * user_status + * * spam + * * deleted + * * caps + * * cap_key + * * allcaps + * * filter + * * ## EXAMPLES * * wp user list --field=ID From 97518998dc69e060bc63dc6944814b63623ec6e3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 10:59:17 -0700 Subject: [PATCH 3161/4858] Denote available fields for `wp widget list` --- php/commands/widget.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index 32924b557b..19c9568d4a 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -34,11 +34,22 @@ class Widget_Command extends WP_CLI_Command { * : ID for the corresponding sidebar. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to name, id, description + * : Limit the output to specific object fields. * * [--format=<format>] * : Accepted values: table, csv, json, count, ids. Default: table * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each widget: + * + * * name + * * id + * * position + * * options + * + * There are no optionally available fields. + * * ## EXAMPLES * * wp sidebar widget list <sidebar-id> --fields=name --format=csv From e93617d5eed18db222ce9b2b91765662216f989a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 6 Sep 2014 11:16:12 -0700 Subject: [PATCH 3162/4858] Ensure all non-section header bodies are indented --- php/commands/help.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index f8c7d9d9ff..615089bbce 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -60,12 +60,15 @@ private static function show_help( $command ) { $out .= wordwrap( $longdesc, 90 ) . "\n"; } - // section headers - $out = preg_replace( '/^## ([A-Z ]+)/m', WP_CLI::colorize( '%9\1%n' ), $out ); - // definition lists $out = preg_replace_callback( '/([^\n]+)\n: (.+?)(\n\n|$)/s', array( __CLASS__, 'rewrap_param_desc' ), $out ); + // Ensure all non-section headers are indented + $out = preg_replace( '#^([^\s^\#])#m', "\t$1", $out ); + + // section headers + $out = preg_replace( '/^## ([A-Z ]+)/m', WP_CLI::colorize( '%9\1%n' ), $out ); + $out = str_replace( "\t", ' ', $out ); self::pass_through_pager( $out ); From b51ae3b126efc957f33164245126fa22b4cff8c3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 15:11:50 -0700 Subject: [PATCH 3163/4858] Switch php-cli-tools to latest release in preparation for 0.17.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 40ec7edf61..b02fa60933 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "0.10.0", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From 57d689c7e05cb720ddc2174070a1d9b7e0b890c4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 16:11:48 -0700 Subject: [PATCH 3164/4858] Tag syntax for requiring a specific min version of WP Looks like this `@require-wp-4.0` Currently non-functional. Something's wrong with my bash --- ci/test.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/ci/test.sh b/ci/test.sh index 9e14eacf90..309c70ea8f 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -5,8 +5,57 @@ set -ex # Run the unit tests vendor/bin/phpunit +# http://stackoverflow.com/questions/4023830/bash-how-compare-two-strings-in-version-format +function vercomp () { + echo $1 + echo $2 + if [[ $1 == $2 ]] + then + return 0 + fi + local IFS=. + local i ver1=($1) ver2=($2) + # fill empty fields in ver1 with zeros + for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) + do + ver1[i]=0 + done + for ((i=0; i<${#ver1[@]}; i++)) + do + if [[ -z ${ver2[i]} ]] + then + # fill empty fields in ver2 with zeros + ver2[i]=0 + fi + if ((10#${ver1[i]} > 10#${ver2[i]})) + then + return 1 + fi + if ((10#${ver1[i]} < 10#${ver2[i]})) + then + return 2 + fi + done + return 0 +} + +if [[ ! -z "$WP_VERSION" ]]; then + + skip_tags="--tags='" + requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) + for (( i = 0; i < ${#requires[@]}; i++ )); do + version=${requires[$i]:12} + comp=$(vercomp $version $WP_VERSION) + if [[ 1 == $comp ]]; then + skip_tags="$skip_tags~$tag," + fi + done + skip_tags="$skip_tags'" + +fi + # Run the functional tests -vendor/bin/behat --format progress +vendor/bin/behat --format progress $skip_tags # Run CodeSniffer ./codesniffer/scripts/phpcs --standard=./ci/ php/ From ac93efc82405e6018927070c82ff8ba6a5fc79f2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 20:26:27 -0700 Subject: [PATCH 3165/4858] Properly execute this bash function, and save our assigned data --- ci/test.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ci/test.sh b/ci/test.sh index 309c70ea8f..2ea7a134b8 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -6,9 +6,7 @@ set -ex vendor/bin/phpunit # http://stackoverflow.com/questions/4023830/bash-how-compare-two-strings-in-version-format -function vercomp () { - echo $1 - echo $2 +vercomp() { if [[ $1 == $2 ]] then return 0 @@ -44,13 +42,16 @@ if [[ ! -z "$WP_VERSION" ]]; then skip_tags="--tags='" requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) for (( i = 0; i < ${#requires[@]}; i++ )); do - version=${requires[$i]:12} - comp=$(vercomp $version $WP_VERSION) - if [[ 1 == $comp ]]; then - skip_tags="$skip_tags~$tag," + version=${requires[$i]:13} + require=${requires[$i]} + vercomp $version $WP_VERSION + compare="$?" + if [[ 1 == $compare ]]; then + skip_tags="$skip_tags~$require," fi done - skip_tags="$skip_tags'" + skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' + skip_tags="$skip_tags'" # close the argument fi From e3bffa71f57f9a7cef6614557b44317884048f03 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 21:01:55 -0700 Subject: [PATCH 3166/4858] List available core translations --- features/core.feature | 10 ++++ php/WP_CLI/CommandWithTranslation.php | 78 +++++++++++++++++++++++++++ php/commands/core.php | 7 +++ 3 files changed, 95 insertions(+) create mode 100644 php/WP_CLI/CommandWithTranslation.php diff --git a/features/core.feature b/features/core.feature index 9be8d2686d..f0c3f8387c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -345,3 +345,13 @@ Feature: Manage WordPress installation """ http://localhost:8001 """ + + @require-wp-4.0 + Scenario: Core translation CRUD + Given a WP install + + When I run `wp core i18n list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php new file mode 100644 index 0000000000..1c2c9ad4ac --- /dev/null +++ b/php/WP_CLI/CommandWithTranslation.php @@ -0,0 +1,78 @@ +<?php + +namespace WP_CLI; + +/** + * Base class for WP-CLI commands that deal with translations + * + * @package wp-cli + */ +abstract class CommandWithTranslation extends \WP_CLI_Command { + + protected $obj_type; + + protected $obj_fields = array( + 'language', + 'english_name', + 'native_name', + 'status', + 'updated', + ); + + /** + * List all languages available. + * + * [--keys=<keys>] + * : Limit output to metadata of specific keys. + * + * [--fields=<fields>] + * : Limit the output to specific fields. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each translation: + * + * * language + * * english_name + * * native_name + * * status + * * updated + * + * These fields are optionally available: + * + * * version + * * package + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + + require_once ABSPATH . '/wp-admin/includes/translation-install.php'; + + $response = translations_api( $this->object_type ); + $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); + $available = get_available_languages(); + $translations = array_map( function( $translation ) use ( $available ) { + $translation['status'] = ( in_array( $translation['language'], $available ) ) ? 'installed' : 'uninstalled'; + return $translation; + }, $translations ); + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $translations ); + + } + + /** + * Get Formatter object based on supplied parameters. + * + * @param array $assoc_args Parameters passed to command. Determines formatting. + * @return \WP_CLI\Formatter + */ + protected function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); + } + +} diff --git a/php/commands/core.php b/php/commands/core.php index 9466a3e6fe..a732f29a7a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -873,3 +873,10 @@ private function get_download_url($version, $locale = 'en_US', $file_type = 'zip WP_CLI::add_command( 'core', 'Core_Command' ); +class Core_i18n_Command extends WP_CLI\CommandWithTranslation { + + protected $object_type = 'core'; + +} + +WP_CLI::add_command( 'core i18n', 'Core_i18n_Command' ); From e2df73aa3742c432507f93cc3a00b20765db1256 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 21:13:24 -0700 Subject: [PATCH 3167/4858] Throw an error for the whole command if < WP 4.0 --- php/commands/core.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index a732f29a7a..43dff99e19 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -879,4 +879,10 @@ class Core_i18n_Command extends WP_CLI\CommandWithTranslation { } -WP_CLI::add_command( 'core i18n', 'Core_i18n_Command' ); +WP_CLI::add_command( 'core i18n', 'Core_i18n_Command', array( + 'before_invoke' => function() { + if ( version_compare( $GLOBALS['wp_version'], '4.0', '<' ) ) { + WP_CLI::error( "Requires WordPress 4.0 or greater." ); + } + }) +); From 8c3dc5b9b70843cb4a5b42c5eab11dcfeaf9136c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 21:28:53 -0700 Subject: [PATCH 3168/4858] Break into a separate file so it doesn't affect our verbosity --- ci/set-behat-tags.sh | 57 ++++++++++++++++++++++++++++++++++++++++++++ ci/test.sh | 52 ++-------------------------------------- 2 files changed, 59 insertions(+), 50 deletions(-) create mode 100755 ci/set-behat-tags.sh diff --git a/ci/set-behat-tags.sh b/ci/set-behat-tags.sh new file mode 100755 index 0000000000..043a71fdff --- /dev/null +++ b/ci/set-behat-tags.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# http://stackoverflow.com/questions/4023830/bash-how-compare-two-strings-in-version-format +vercomp() { + if [[ $1 == $2 ]] + then + return 0 + fi + local IFS=. + local i ver1=($1) ver2=($2) + # fill empty fields in ver1 with zeros + for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) + do + ver1[i]=0 + done + for ((i=0; i<${#ver1[@]}; i++)) + do + if [[ -z ${ver2[i]} ]] + then + # fill empty fields in ver2 with zeros + ver2[i]=0 + fi + if ((10#${ver1[i]} > 10#${ver2[i]})) + then + return 1 + fi + if ((10#${ver1[i]} < 10#${ver2[i]})) + then + return 2 + fi + done + return 0 +} + +if [[ ! -z "$WP_VERSION" ]]; then + + skip_tags="--tags='" + requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) + for (( i = 0; i < ${#requires[@]}; i++ )); do + version=${requires[$i]:12} + require=${requires[$i]} + vercomp $version $WP_VERSION + compare="$?" + if [[ 1 == $compare ]]; then + skip_tags="$skip_tags~$require," + fi + done + if [[ "--tags='" != $skip_tags ]]; then + skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' + skip_tags="$skip_tags'" # close the argument + else + skip_tags='' + fi + +fi + +echo export behat_tags=$skip_tags \ No newline at end of file diff --git a/ci/test.sh b/ci/test.sh index 2ea7a134b8..0972b3a341 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -5,58 +5,10 @@ set -ex # Run the unit tests vendor/bin/phpunit -# http://stackoverflow.com/questions/4023830/bash-how-compare-two-strings-in-version-format -vercomp() { - if [[ $1 == $2 ]] - then - return 0 - fi - local IFS=. - local i ver1=($1) ver2=($2) - # fill empty fields in ver1 with zeros - for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) - do - ver1[i]=0 - done - for ((i=0; i<${#ver1[@]}; i++)) - do - if [[ -z ${ver2[i]} ]] - then - # fill empty fields in ver2 with zeros - ver2[i]=0 - fi - if ((10#${ver1[i]} > 10#${ver2[i]})) - then - return 1 - fi - if ((10#${ver1[i]} < 10#${ver2[i]})) - then - return 2 - fi - done - return 0 -} - -if [[ ! -z "$WP_VERSION" ]]; then - - skip_tags="--tags='" - requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) - for (( i = 0; i < ${#requires[@]}; i++ )); do - version=${requires[$i]:13} - require=${requires[$i]} - vercomp $version $WP_VERSION - compare="$?" - if [[ 1 == $compare ]]; then - skip_tags="$skip_tags~$require," - fi - done - skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' - skip_tags="$skip_tags'" # close the argument - -fi +eval $(./ci/set-behat-tags.sh) # Run the functional tests -vendor/bin/behat --format progress $skip_tags +vendor/bin/behat --format progress $behat_tags # Run CodeSniffer ./codesniffer/scripts/phpcs --standard=./ci/ php/ From c6f49c294d2e956eda88a7de026c851cd8b0cb6e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 7 Sep 2014 21:40:58 -0700 Subject: [PATCH 3169/4858] Install a given language --- features/core.feature | 13 ++++++++++++ php/WP_CLI/CommandWithTranslation.php | 29 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/features/core.feature b/features/core.feature index f0c3f8387c..238e8695c3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -355,3 +355,16 @@ Feature: Manage WordPress installation | language | english_name | status | | ar | Arabic | uninstalled | | az | Azerbaijani | uninstalled | + | en_GB | English (UK) | uninstalled | + + When I run `wp core i18n install en_GB` + Then STDOUT should be: + """ + Success: Language installed. + """ + + When I run `wp core i18n install en_GB` + Then STDOUT should be: + """ + Warning: Language already installed. + """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 1c2c9ad4ac..65f9552f79 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -65,6 +65,35 @@ public function list_( $args, $assoc_args ) { } + /** + * Install a given language. + * + * <language> + * : Language code to install. + * + * @subcommand install + */ + public function install( $args, $assoc_args ) { + + list( $language_code ) = $args; + + $available = get_available_languages(); + if ( in_array( $language_code, $available ) ) { + \WP_CLI::warning( "Language already installed." ); + exit; + } + + require_once ABSPATH . '/wp-admin/includes/translation-install.php'; + + $response = wp_download_language_pack( $language_code ); + if ( $response == $language_code ) { + \WP_CLI::success( "Language installed." ); + } else { + \WP_CLI::error( "Couldn't install language." ); + } + + } + /** * Get Formatter object based on supplied parameters. * From a84903503a6cbe416acd0d4d348e4f90f3904ae9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Sep 2014 05:41:05 -0700 Subject: [PATCH 3170/4858] Switch to php-cli-tools v0.10.1 See https://github.com/wp-cli/php-cli-tools/releases/tag/v0.10.1 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b02fa60933..da62d1b490 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.10.0", + "wp-cli/php-cli-tools": "0.10.1", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From 96edff066daf4cad0d37d743a2fda31221d85172 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 05:45:43 -0700 Subject: [PATCH 3171/4858] Test latest version of WP, now 4.0 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3e6f78d2a4..b5b6e3185f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=3.9 + - WP_VERSION=4.0 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: From 5a9033fb76ba3868610d5d4cd1378d1c5d6ad33e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 05:55:59 -0700 Subject: [PATCH 3172/4858] Use `try` for `STDERR` --- features/core.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 238e8695c3..0571e7be14 100644 --- a/features/core.feature +++ b/features/core.feature @@ -363,8 +363,8 @@ Feature: Manage WordPress installation Success: Language installed. """ - When I run `wp core i18n install en_GB` - Then STDOUT should be: + When I try `wp core i18n install en_GB` + Then STDERR should be: """ Warning: Language already installed. """ From b6656b40fa071bef548e38bcd1c52fdd6f653e00 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 06:05:48 -0700 Subject: [PATCH 3173/4858] Another test --- features/core.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/core.feature b/features/core.feature index 0571e7be14..9da9cc810b 100644 --- a/features/core.feature +++ b/features/core.feature @@ -368,3 +368,11 @@ Feature: Manage WordPress installation """ Warning: Language already installed. """ + + When I run `wp core i18n list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | + | en_GB | English (UK) | installed | + From 0a455aec84705099ff333d54b6bde8606383a081 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 06:06:00 -0700 Subject: [PATCH 3174/4858] Standardize on `obj_type` for consistency --- php/WP_CLI/CommandWithTranslation.php | 2 +- php/commands/core.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 65f9552f79..b49b69435e 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -52,7 +52,7 @@ public function list_( $args, $assoc_args ) { require_once ABSPATH . '/wp-admin/includes/translation-install.php'; - $response = translations_api( $this->object_type ); + $response = translations_api( $this->obj_type ); $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); $available = get_available_languages(); $translations = array_map( function( $translation ) use ( $available ) { diff --git a/php/commands/core.php b/php/commands/core.php index 43dff99e19..6d46485605 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -875,7 +875,7 @@ private function get_download_url($version, $locale = 'en_US', $file_type = 'zip class Core_i18n_Command extends WP_CLI\CommandWithTranslation { - protected $object_type = 'core'; + protected $obj_type = 'core'; } From f4922c3b5de1c84d8aa36295c651efe2ae24aca0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 06:07:56 -0700 Subject: [PATCH 3175/4858] Use `wp_get_installed_translations()`, which allows us to pass the type --- php/WP_CLI/CommandWithTranslation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index b49b69435e..bbdcd7578a 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -54,7 +54,8 @@ public function list_( $args, $assoc_args ) { $response = translations_api( $this->obj_type ); $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); - $available = get_available_languages(); + $available = wp_get_installed_translations( $this->obj_type ); + $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); $translations = array_map( function( $translation ) use ( $available ) { $translation['status'] = ( in_array( $translation['language'], $available ) ) ? 'installed' : 'uninstalled'; return $translation; From b7272053c93e9becf91f51db314bfb1b289b4790 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 06:15:55 -0700 Subject: [PATCH 3176/4858] Defer to `wp_get_installed_translations()` --- php/WP_CLI/CommandWithTranslation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index bbdcd7578a..2476892d7c 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -78,7 +78,8 @@ public function install( $args, $assoc_args ) { list( $language_code ) = $args; - $available = get_available_languages(); + $available = wp_get_installed_translations( $this->obj_type ); + $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); if ( in_array( $language_code, $available ) ) { \WP_CLI::warning( "Language already installed." ); exit; From a24165930e9b4f7bdc4004f6de2154f9c09bd194 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 06:55:12 -0700 Subject: [PATCH 3177/4858] Uninstall command for core language --- features/core.feature | 17 +++++++++- php/WP_CLI/CommandWithTranslation.php | 48 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 9da9cc810b..787fbbdbc3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -358,7 +358,9 @@ Feature: Manage WordPress installation | en_GB | English (UK) | uninstalled | When I run `wp core i18n install en_GB` - Then STDOUT should be: + Then the wp-content/languages/admin-en_GB.po file should exist + And the wp-content/languages/en_GB.po file should exist + And STDOUT should be: """ Success: Language installed. """ @@ -376,3 +378,16 @@ Feature: Manage WordPress installation | az | Azerbaijani | uninstalled | | en_GB | English (UK) | installed | + When I run `wp core i18n uninstall en_GB` + Then the wp-content/languages/admin-en_GB.po file should not exist + And the wp-content/languages/en_GB.po file should not exist + And STDOUT should be: + """ + Success: Language uninstalled. + """ + + When I try `wp core i18n uninstall en_GB` + Then STDERR should be: + """ + Error: Language not installed. + """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 2476892d7c..1ec851910f 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -96,6 +96,54 @@ public function install( $args, $assoc_args ) { } + /** + * Uninstall a given language. + * + * <language> + * : Language code to uninstall. + * + * @subcommand uninstall + */ + public function uninstall( $args, $assoc_args ) { + global $wp_filesystem; + + list( $language_code ) = $args; + + $available = wp_get_installed_translations( $this->obj_type ); + $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); + if ( ! in_array( $language_code, $available ) ) { + \WP_CLI::error( "Language not installed." ); + } + + $dir = 'core' === $this->obj_type ? '' : "/$this->obj_type"; + $files = scandir( WP_LANG_DIR . $dir ); + if ( ! $files ) { + \WP_CLI::error( "No files found in language directory." ); + } + + // As of WP 4.0, no API for deleting a language pack + WP_Filesystem(); + $deleted = false; + foreach ( $files as $file ) { + if ( '.' === $file[0] || is_dir( $file ) ) { + continue; + } + $extension_length = strlen( $language_code ) + 4; + $ending = substr( $file, -$extension_length ); + if ( ! in_array( $file, array( $language_code . '.po', $language_code . '.mo' ) ) && ! in_array( $ending, array( '-' . $language_code . '.po', '-' . $language_code . '.mo' ) ) ) { + continue; + } + $deleted = $wp_filesystem->delete( WP_LANG_DIR . $dir . '/' . $file ); + } + + if ( $deleted ) { + \WP_CLI::success( "Language uninstalled." ); + } else { + \WP_CLI::error( "Couldn't uninstall language." ); + } + + } + /** * Get Formatter object based on supplied parameters. * From 4ae5c78e131ae9ed1ce424655773136e42bb3c88 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 06:56:34 -0700 Subject: [PATCH 3178/4858] Rename to `wp core language` --- features/core.feature | 12 ++++++------ php/commands/core.php | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/features/core.feature b/features/core.feature index 787fbbdbc3..5ced9955d2 100644 --- a/features/core.feature +++ b/features/core.feature @@ -350,14 +350,14 @@ Feature: Manage WordPress installation Scenario: Core translation CRUD Given a WP install - When I run `wp core i18n list --fields=language,english_name,status` + When I run `wp core language list --fields=language,english_name,status` Then STDOUT should be a table containing rows: | language | english_name | status | | ar | Arabic | uninstalled | | az | Azerbaijani | uninstalled | | en_GB | English (UK) | uninstalled | - When I run `wp core i18n install en_GB` + When I run `wp core language install en_GB` Then the wp-content/languages/admin-en_GB.po file should exist And the wp-content/languages/en_GB.po file should exist And STDOUT should be: @@ -365,20 +365,20 @@ Feature: Manage WordPress installation Success: Language installed. """ - When I try `wp core i18n install en_GB` + When I try `wp core language install en_GB` Then STDERR should be: """ Warning: Language already installed. """ - When I run `wp core i18n list --fields=language,english_name,status` + When I run `wp core language list --fields=language,english_name,status` Then STDOUT should be a table containing rows: | language | english_name | status | | ar | Arabic | uninstalled | | az | Azerbaijani | uninstalled | | en_GB | English (UK) | installed | - When I run `wp core i18n uninstall en_GB` + When I run `wp core language uninstall en_GB` Then the wp-content/languages/admin-en_GB.po file should not exist And the wp-content/languages/en_GB.po file should not exist And STDOUT should be: @@ -386,7 +386,7 @@ Feature: Manage WordPress installation Success: Language uninstalled. """ - When I try `wp core i18n uninstall en_GB` + When I try `wp core language uninstall en_GB` Then STDERR should be: """ Error: Language not installed. diff --git a/php/commands/core.php b/php/commands/core.php index 6d46485605..aa7f8e75ce 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -873,13 +873,13 @@ private function get_download_url($version, $locale = 'en_US', $file_type = 'zip WP_CLI::add_command( 'core', 'Core_Command' ); -class Core_i18n_Command extends WP_CLI\CommandWithTranslation { +class Core_Language_Command extends WP_CLI\CommandWithTranslation { protected $obj_type = 'core'; } -WP_CLI::add_command( 'core i18n', 'Core_i18n_Command', array( +WP_CLI::add_command( 'core language', 'Core_Language_Command', array( 'before_invoke' => function() { if ( version_compare( $GLOBALS['wp_version'], '4.0', '<' ) ) { WP_CLI::error( "Requires WordPress 4.0 or greater." ); From 56fa910582ccb3765cc74160079b75343464065e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 07:01:06 -0700 Subject: [PATCH 3179/4858] Remove some copy and paste --- php/WP_CLI/CommandWithTranslation.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 1ec851910f..ca1b8e63f9 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -22,14 +22,11 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { /** * List all languages available. * - * [--keys=<keys>] - * : Limit output to metadata of specific keys. - * * [--fields=<fields>] * : Limit the output to specific fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json. Default: table * * ## AVAILABLE FIELDS * From 0bc1eaf7097a8e46aa801947eb842c893b15ed4c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 07:13:38 -0700 Subject: [PATCH 3180/4858] Command to activate a core language --- features/core.feature | 19 ++++++++++++++++++ php/WP_CLI/CommandWithTranslation.php | 28 ++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 5ced9955d2..dac89c77bd 100644 --- a/features/core.feature +++ b/features/core.feature @@ -378,6 +378,25 @@ Feature: Manage WordPress installation | az | Azerbaijani | uninstalled | | en_GB | English (UK) | installed | + When I run `wp core language activate en_GB` + Then STDOUT should be: + """ + Success: Language activated. + """ + + When I run `wp core language list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | + | en_GB | English (UK) | active | + + When I try `wp core language activate invalid_lang` + Then STDERR should be: + """ + Error: Language not installed. + """ + When I run `wp core language uninstall en_GB` Then the wp-content/languages/admin-en_GB.po file should not exist And the wp-content/languages/en_GB.po file should not exist diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index ca1b8e63f9..36ca451a28 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -53,8 +53,12 @@ public function list_( $args, $assoc_args ) { $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); $available = wp_get_installed_translations( $this->obj_type ); $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); - $translations = array_map( function( $translation ) use ( $available ) { + $current_locale = get_locale(); + $translations = array_map( function( $translation ) use ( $available, $current_locale ) { $translation['status'] = ( in_array( $translation['language'], $available ) ) ? 'installed' : 'uninstalled'; + if ( $current_locale == $translation['language'] ) { + $translation['status'] = 'active'; + } return $translation; }, $translations ); @@ -93,6 +97,28 @@ public function install( $args, $assoc_args ) { } + /** + * Activate a given language. + * + * <language> + * : Language code to activate. + * + * @subcommand activate + */ + public function activate( $args, $assoc_args ) { + + list( $language_code ) = $args; + + $available = wp_get_installed_translations( $this->obj_type ); + $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); + if ( ! in_array( $language_code, $available ) ) { + \WP_CLI::error( "Language not installed." ); + } + + update_option( 'WPLANG', $language_code ); + \WP_CLI::success( "Language activated." ); + } + /** * Uninstall a given language. * From a57778faba65a58a104c45154f690751402191ca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 07:31:39 -0700 Subject: [PATCH 3181/4858] Mimic core's behavior of preventing orphaned terms for all versions --- features/term.feature | 7 +++++++ php/commands/term.php | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/features/term.feature b/features/term.feature index 90b2a0b076..2dc2d3d051 100644 --- a/features/term.feature +++ b/features/term.feature @@ -70,3 +70,10 @@ Feature: Manage WordPress terms """ 11 """ + + Scenario: Term with a non-existent parent + When I try `wp term create category Apple --parent=99 --porcelain` + Then STDERR should be: + """ + Error: Parent term does not exist. + """ diff --git a/php/commands/term.php b/php/commands/term.php index 2e3e22ccdc..d7a35e295b 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -110,7 +110,7 @@ public function create( $args, $assoc_args ) { $defaults = array( 'slug' => sanitize_title( $term ), 'description' => '', - 'parent' => '', + 'parent' => 0, ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); @@ -121,6 +121,11 @@ public function create( $args, $assoc_args ) { $porcelain = false; } + // Compatibility for < WP 4.0 + if ( $assoc_args['parent'] > 0 && ! term_exists( (int) $assoc_args['parent'] ) ) { + WP_CLI::error( 'Parent term does not exist.' ); + } + $ret = wp_insert_term( $term, $taxonomy, $assoc_args ); if ( is_wp_error( $ret ) ) { From 9aaed7ea2aeb146f4ad9056990b01c90582ab4a6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 07:35:00 -0700 Subject: [PATCH 3182/4858] Update orphan term test to get around core's new check for parent --- features/export.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/export.feature b/features/export.feature index b7878a96b4..8539e309c2 100644 --- a/features/export.feature +++ b/features/export.feature @@ -12,8 +12,12 @@ Feature: Export content. Scenario: Term with a non-existent parent Given a WP install - When I run `wp term create category Apple --parent=99 --porcelain` + When I run `wp term create category Apple --porcelain` Then STDOUT should be a number + And save STDOUT as {TERM_ID} + + When I run `wp term update category {TERM_ID} --parent=99` + Then STDOUT should not be empty When I try `wp export` Then STDERR should be: From 4663fce9e06c122696866b26cdb5f34dd0b125d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 18:26:12 +0200 Subject: [PATCH 3183/4858] major,minor and Formatter --- php/commands/cli.php | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index bfc3a91a3c..b0d26adb7f 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -69,6 +69,85 @@ function info( $_, $assoc_args ) { } } + /** + * Check for update via Github API. Returns the available versions if there are updates, or empty if no update available. + * + * ## OPTIONS + * + * [--minor] + * : Compare only the first two parts of the version number. + * + * [--major] + * : Compare only the first part of the version number. + * + * [--field=<field>] + * : Prints the value of a single field for each update. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to version,type,package_url. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * @subcommand check-update + */ + function check_update( $_, $assoc_args ) { + $url = 'https://api.github.com/repos/wp-cli/wp-cli/releases'; + + $options = array( + 'timeout' => 30 + ); + + $headers = array( + 'Accept' => 'application/json' + ); + $response = Utils\http_request( 'GET', $url, $headers, $options ); + + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( "Failed to get latest version." ); + } + + $release_data = json_decode( $response->body ); + $current_parts = explode( '.', WP_CLI_VERSION ); + $updates = array(); + + foreach ( $release_data as $release ) { + $release_version = $release->tag_name; + // get rid of leading "v" + if ( 'v' === substr( $release_version, 0, 1 ) ) { + $release_version = ltrim( $release_version, 'v' ); + } + // don't list the current version + if ( version_compare( $release_version, WP_CLI_VERSION, '<=' ) ) + continue; + $release_parts = explode( '.', $release_version ); + $release_type = 'major'; + + if ( $release_parts[0] === $current_parts[0] + && $release_parts[1] === $current_parts[1] ) { + $release_type = 'minor'; + } + + if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $release_type ) + && ! ( isset( $assoc_args['major'] ) && 'major' !== $release_type ) + ) { + $updates[] = array( + 'version' => $release_version, + 'type' => $release_type, + 'package_url' => $release->assets[0]->browser_download_url + ); + } + } + + if ( $updates ) { + $formatter = new \WP_CLI\Formatter( + $assoc_args, + array( 'version', 'type', 'package_url' ) + ); + $formatter->display_items( $updates ); + } + } + /** * Dump the list of global parameters, as JSON. * From 5a809b2bdc73f707341c6696f042b3ace6f334c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 18:49:37 +0200 Subject: [PATCH 3184/4858] WP.org announces only one version --- php/commands/core.php | 67 +++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 20682e65af..9287d0588a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -14,20 +14,25 @@ class Core_Command extends WP_CLI_Command { * * ## OPTIONS * + * [--minor] + * : Compare only the first two parts of the version number. + * * [--major] - * : Compare only the first two parts of the version numbers. + * : Compare only the first part of the version number. + * + * [--field=<field>] + * : Prints the value of a single field for each update. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to version,type,package_url. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table * * @subcommand check-update */ function check_update( $_, $assoc_args ) { $versions_path = ABSPATH . 'wp-includes/version.php'; - - if ( ! is_readable( $versions_path ) ) { - WP_CLI::error( - "This does not seem to be a WordPress install.\n" . - "Pass --path=`path/to/wordpress` or run `wp core download`." ); - } - include $versions_path; $url = 'http://api.wordpress.org/core/version-check/1.7/'; @@ -45,20 +50,46 @@ function check_update( $_, $assoc_args ) { WP_CLI::error( "Failed to get latest version." ); } - $latest_data = json_decode( $response->body ); + $release_data = json_decode( $response->body ); + + $current_parts = explode( '.', $wp_version ); + $updates = array(); + + foreach ( $release_data as $release ) { + $release_version = $release->tag_name; + // get rid of leading "v" + if ( 'v' === substr( $release_version, 0, 1 ) ) { + $release_version = ltrim( $release_version, 'v' ); + } + // don't list the current version + if ( version_compare( $release_version, $wp_version '<=' ) ) + continue; + $release_parts = explode( '.', $release_version ); + $release_type = 'major'; - $latest = $latest_data->offers[0]->current; + if ( $release_parts[0] === $current_parts[0] + && $release_parts[1] === $current_parts[1] ) { + $release_type = 'minor'; + } - if ( isset( $assoc_args['major'] ) ) { - $latest_major = explode( '.', $latest ); - $current_major = explode( '.', $wp_version ); - if ( $latest_major[0] !== $current_major[0] - || $latest_major[1] !== $current_major[1] ) { - WP_CLI::line( $latest ); + if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $release_type ) + && ! ( isset( $assoc_args['major'] ) && 'major' !== $release_type ) + ) { + $updates[] = array( + 'version' => $release_version, + 'type' => $release_type, + // there's onyl one version on WP.org + 'package_url' => $release->assets[0]->browser_download_url + ); } + } - } elseif ( $wp_version !== $latest ) { - WP_CLI::line( $latest ); + if ( $updates ) { + $formatter = new \WP_CLI\Formatter( + $assoc_args, + array( 'version', 'type', 'package_url' ) + ); + $formatter->display_items( $updates ); } } From 95a4f7006d960269879cb9c9e492fa882f7f0559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 18:51:51 +0200 Subject: [PATCH 3185/4858] Let's call this update_type to be specific. --- php/commands/cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index b0d26adb7f..d030fe74d0 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -121,19 +121,19 @@ function check_update( $_, $assoc_args ) { if ( version_compare( $release_version, WP_CLI_VERSION, '<=' ) ) continue; $release_parts = explode( '.', $release_version ); - $release_type = 'major'; + $update_type = 'major'; if ( $release_parts[0] === $current_parts[0] && $release_parts[1] === $current_parts[1] ) { - $release_type = 'minor'; + $update_type = 'minor'; } - if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $release_type ) - && ! ( isset( $assoc_args['major'] ) && 'major' !== $release_type ) + if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) + && ! ( isset( $assoc_args['major'] ) && 'major' !== $update_type ) ) { $updates[] = array( 'version' => $release_version, - 'type' => $release_type, + 'type' => $update_type, 'package_url' => $release->assets[0]->browser_download_url ); } From ef95444b292aff41a2e148644615f18420698df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 18:54:50 +0200 Subject: [PATCH 3186/4858] major -> minor, minor -> patch --- php/commands/cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index d030fe74d0..8aa4e6408e 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -74,10 +74,10 @@ function info( $_, $assoc_args ) { * * ## OPTIONS * - * [--minor] + * [--patch] * : Compare only the first two parts of the version number. * - * [--major] + * [--minor] * : Compare only the first part of the version number. * * [--field=<field>] @@ -121,15 +121,15 @@ function check_update( $_, $assoc_args ) { if ( version_compare( $release_version, WP_CLI_VERSION, '<=' ) ) continue; $release_parts = explode( '.', $release_version ); - $update_type = 'major'; + $update_type = 'minor'; if ( $release_parts[0] === $current_parts[0] && $release_parts[1] === $current_parts[1] ) { - $update_type = 'minor'; + $update_type = 'patch'; } - if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) - && ! ( isset( $assoc_args['major'] ) && 'major' !== $update_type ) + if ( ! ( isset( $assoc_args['patch'] ) && 'patch' !== $update_type ) + && ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) ) { $updates[] = array( 'version' => $release_version, From 69f13fb2c42332eb016675b6af339998dc41389f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 19:27:16 +0200 Subject: [PATCH 3187/4858] only show the latest version for each minor version --- php/commands/cli.php | 18 +++++++++++++++++- php/wp-cli.php | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 8aa4e6408e..9653b3d616 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -69,6 +69,21 @@ function info( $_, $assoc_args ) { } } + /** + * Compare the last processed release to the current one, return true if it's the same minor version. + * + */ + private function same_minor_release( $release_parts, $updates ) { + $previous = end( $updates ); + if ( false === $previous ) + return false; + + $previous_parts = explode( '.', $previous['version'] ); + + return ( $previous_parts[0] === $release_parts[0] + && $previous_parts[1] === $release_parts[1] ); + } + /** * Check for update via Github API. Returns the available versions if there are updates, or empty if no update available. * @@ -117,7 +132,7 @@ function check_update( $_, $assoc_args ) { if ( 'v' === substr( $release_version, 0, 1 ) ) { $release_version = ltrim( $release_version, 'v' ); } - // don't list the current version + // don't list earlier releases if ( version_compare( $release_version, WP_CLI_VERSION, '<=' ) ) continue; $release_parts = explode( '.', $release_version ); @@ -130,6 +145,7 @@ function check_update( $_, $assoc_args ) { if ( ! ( isset( $assoc_args['patch'] ) && 'patch' !== $update_type ) && ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) + && ! $this->same_minor_release( $release_parts, $updates ) ) { $updates[] = array( 'version' => $release_version, diff --git a/php/wp-cli.php b/php/wp-cli.php index c0a45246ee..e0acf8b284 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.16.0' ); +define( 'WP_CLI_VERSION', '0.13.0' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From d3a459e071c46ec7cf8d415a0dcb56d2203df139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 19:29:46 +0200 Subject: [PATCH 3188/4858] oops again --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index e0acf8b284..c0a45246ee 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.13.0' ); +define( 'WP_CLI_VERSION', '0.16.0' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From cd1ed9cd58cb4c4b0f238881bacd0f378c0d610f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 19:42:32 +0200 Subject: [PATCH 3189/4858] halfdone check-update --- php/commands/core.php | 59 ++++++++----------------------------------- 1 file changed, 11 insertions(+), 48 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9287d0588a..305578190d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -14,17 +14,11 @@ class Core_Command extends WP_CLI_Command { * * ## OPTIONS * - * [--minor] - * : Compare only the first two parts of the version number. - * - * [--major] - * : Compare only the first part of the version number. - * * [--field=<field>] * : Prints the value of a single field for each update. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to version,type,package_url. + * : Limit the output to specific object fields. Defaults to version,package_url. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table @@ -32,9 +26,7 @@ class Core_Command extends WP_CLI_Command { * @subcommand check-update */ function check_update( $_, $assoc_args ) { - $versions_path = ABSPATH . 'wp-includes/version.php'; - include $versions_path; - + //TODO all versions: http://api.wordpress.org/core/stable-check/1.0/ $url = 'http://api.wordpress.org/core/version-check/1.7/'; $options = array( @@ -52,45 +44,16 @@ function check_update( $_, $assoc_args ) { $release_data = json_decode( $response->body ); - $current_parts = explode( '.', $wp_version ); - $updates = array(); - - foreach ( $release_data as $release ) { - $release_version = $release->tag_name; - // get rid of leading "v" - if ( 'v' === substr( $release_version, 0, 1 ) ) { - $release_version = ltrim( $release_version, 'v' ); - } - // don't list the current version - if ( version_compare( $release_version, $wp_version '<=' ) ) - continue; - $release_parts = explode( '.', $release_version ); - $release_type = 'major'; - - if ( $release_parts[0] === $current_parts[0] - && $release_parts[1] === $current_parts[1] ) { - $release_type = 'minor'; - } - - if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $release_type ) - && ! ( isset( $assoc_args['major'] ) && 'major' !== $release_type ) - ) { - $updates[] = array( - 'version' => $release_version, - 'type' => $release_type, - // there's onyl one version on WP.org - 'package_url' => $release->assets[0]->browser_download_url - ); - } - } + $updates[] = array( + 'version' => $release_data->offers[0]->version, + 'package_url' => $release_data->offers[0]->packages->no_content + ); - if ( $updates ) { - $formatter = new \WP_CLI\Formatter( - $assoc_args, - array( 'version', 'type', 'package_url' ) - ); - $formatter->display_items( $updates ); - } + $formatter = new \WP_CLI\Formatter( + $assoc_args, + array( 'version', 'package_url' ) + ); + $formatter->display_items( $updates ); } /** From e938929303c205bdf339412cf36d911252008806 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 10:56:52 -0700 Subject: [PATCH 3190/4858] Clarify what this `type` refers to by calling it `update_type` See #1386 --- php/commands/cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 9653b3d616..31d8738f7a 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -149,7 +149,7 @@ function check_update( $_, $assoc_args ) { ) { $updates[] = array( 'version' => $release_version, - 'type' => $update_type, + 'update_type' => $update_type, 'package_url' => $release->assets[0]->browser_download_url ); } @@ -158,7 +158,7 @@ function check_update( $_, $assoc_args ) { if ( $updates ) { $formatter = new \WP_CLI\Formatter( $assoc_args, - array( 'version', 'type', 'package_url' ) + array( 'version', 'update_type', 'package_url' ) ); $formatter->display_items( $updates ); } From 40b233b88b9a29a0221e8963dedefb4c88e97c35 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 11:02:32 -0700 Subject: [PATCH 3191/4858] Success message when WP-CLI is up to date See #1386 --- php/commands/cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index 31d8738f7a..eead271f61 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -161,6 +161,8 @@ function check_update( $_, $assoc_args ) { array( 'version', 'update_type', 'package_url' ) ); $formatter->display_items( $updates ); + } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { + WP_CLI::success( "WP-CLI is at the latest version." ); } } From 9aa1975ed34e4d36656d6e587a51abd8febe37f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 20:27:22 +0200 Subject: [PATCH 3192/4858] list all releases --- php/commands/core.php | 48 +++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 9287d0588a..ce82d9e36b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -9,6 +9,28 @@ */ class Core_Command extends WP_CLI_Command { + /** + * Compare processed releases to the current one, and delete older one. Return remaining updates. + * + */ + private function remove_same_minor_releases( $release_parts, $updates ) { + if ( empty( $updates ) ) + return false; + + $differents = array(); + foreach ( $updates as $processed ) { + $processed_parts = explode( '.', $processed['version'] ); + + // later releases are always later in the array + if ( $processed_parts[0] !== $release_parts[0] + && $processed_parts[1] !== $release_parts[1] ) { + $differents[] = $processed; + } + } + + return $differents; + } + /** * Check for update via Version Check API. Returns latest version if there's an update, or empty if no update available. * @@ -35,12 +57,11 @@ function check_update( $_, $assoc_args ) { $versions_path = ABSPATH . 'wp-includes/version.php'; include $versions_path; - $url = 'http://api.wordpress.org/core/version-check/1.7/'; + $url = 'http://api.wordpress.org/core/stable-check/1.0/'; $options = array( 'timeout' => 30 ); - $headers = array( 'Accept' => 'application/json' ); @@ -51,35 +72,32 @@ function check_update( $_, $assoc_args ) { } $release_data = json_decode( $response->body ); + $locale = get_locale(); $current_parts = explode( '.', $wp_version ); $updates = array(); - foreach ( $release_data as $release ) { - $release_version = $release->tag_name; - // get rid of leading "v" - if ( 'v' === substr( $release_version, 0, 1 ) ) { - $release_version = ltrim( $release_version, 'v' ); - } - // don't list the current version - if ( version_compare( $release_version, $wp_version '<=' ) ) + foreach ( $release_data as $release_version => $release ) { + // don't list earliers versions + if ( version_compare( $release_version, $wp_version, '<=' ) ) continue; + $release_parts = explode( '.', $release_version ); - $release_type = 'major'; + $update_type = 'major'; if ( $release_parts[0] === $current_parts[0] && $release_parts[1] === $current_parts[1] ) { - $release_type = 'minor'; + $update_type = 'minor'; } if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $release_type ) && ! ( isset( $assoc_args['major'] ) && 'major' !== $release_type ) ) { + $updates = $this->remove_same_minor_releases( $release_parts, $updates ); $updates[] = array( 'version' => $release_version, - 'type' => $release_type, - // there's onyl one version on WP.org - 'package_url' => $release->assets[0]->browser_download_url + 'type' => $update_type, + 'package_url' => $this->get_download_url( $release_version, $locale ) ); } } From 49903dd349e8b111b53a7e1a11f3239b208c6605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 20:29:40 +0200 Subject: [PATCH 3193/4858] list all releases --- php/commands/core.php | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index b5141bc96c..ce82d9e36b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -36,11 +36,17 @@ private function remove_same_minor_releases( $release_parts, $updates ) { * * ## OPTIONS * + * [--minor] + * : Compare only the first two parts of the version number. + * + * [--major] + * : Compare only the first part of the version number. + * * [--field=<field>] * : Prints the value of a single field for each update. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to version,package_url. + * : Limit the output to specific object fields. Defaults to version,type,package_url. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table @@ -48,15 +54,10 @@ private function remove_same_minor_releases( $release_parts, $updates ) { * @subcommand check-update */ function check_update( $_, $assoc_args ) { -<<<<<<< HEAD $versions_path = ABSPATH . 'wp-includes/version.php'; include $versions_path; $url = 'http://api.wordpress.org/core/stable-check/1.0/'; -======= - //TODO all versions: http://api.wordpress.org/core/stable-check/1.0/ - $url = 'http://api.wordpress.org/core/version-check/1.7/'; ->>>>>>> cd1ed9cd58cb4c4b0f238881bacd0f378c0d610f $options = array( 'timeout' => 30 @@ -73,7 +74,6 @@ function check_update( $_, $assoc_args ) { $release_data = json_decode( $response->body ); $locale = get_locale(); -<<<<<<< HEAD $current_parts = explode( '.', $wp_version ); $updates = array(); @@ -101,18 +101,14 @@ function check_update( $_, $assoc_args ) { ); } } -======= - $updates[] = array( - 'version' => $release_data->offers[0]->version, - 'package_url' => $release_data->offers[0]->packages->no_content - ); ->>>>>>> cd1ed9cd58cb4c4b0f238881bacd0f378c0d610f - $formatter = new \WP_CLI\Formatter( - $assoc_args, - array( 'version', 'package_url' ) - ); - $formatter->display_items( $updates ); + if ( $updates ) { + $formatter = new \WP_CLI\Formatter( + $assoc_args, + array( 'version', 'type', 'package_url' ) + ); + $formatter->display_items( $updates ); + } } /** From cd99c897ce11560c264a92f6134432b9ba386fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 20:40:03 +0200 Subject: [PATCH 3194/4858] variable name --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index ce82d9e36b..4d26e9fa74 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -90,8 +90,8 @@ function check_update( $_, $assoc_args ) { $update_type = 'minor'; } - if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $release_type ) - && ! ( isset( $assoc_args['major'] ) && 'major' !== $release_type ) + if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) + && ! ( isset( $assoc_args['major'] ) && 'major' !== $update_type ) ) { $updates = $this->remove_same_minor_releases( $release_parts, $updates ); $updates[] = array( From 222b75b1f95ea1831242ddc0c4d47d56dd81ab2a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 11:40:10 -0700 Subject: [PATCH 3195/4858] One instance missed in e938929303c205bdf339412cf36d911252008806 --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index eead271f61..deb9b86f92 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -99,7 +99,7 @@ private function same_minor_release( $release_parts, $updates ) { * : Prints the value of a single field for each update. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to version,type,package_url. + * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table From 0e0d6fdc93b42275d7bacf1c1f592a834add22f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 10 Sep 2014 22:41:21 +0200 Subject: [PATCH 3196/4858] 3 tests for wp core check-update --- features/core.feature | 31 +++++++++++++++++++++++++++++++ php/commands/core.php | 12 +++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index dac89c77bd..e06bc15311 100644 --- a/features/core.feature +++ b/features/core.feature @@ -260,6 +260,37 @@ Feature: Manage WordPress installation 3.9 """ + @download + Scenario: Check for update via Version Check API + Given a WP install + + When I run `wp core download --version=3.8 --force` + Then STDOUT should not be empty + + When I run `wp core check-update` + Then STDOUT should be: + """ + version update_type package_url + 3.8.4 minor https://wordpress.org/wordpress-3.8.4.zip + 3.9.2 major https://wordpress.org/wordpress-3.9.2.zip + 4.0 major https://wordpress.org/wordpress-4.0.zip + """ + + When I run `wp core check-update --major` + Then STDOUT should be: + """ + version update_type package_url + 3.9.2 major https://wordpress.org/wordpress-3.9.2.zip + 4.0 major https://wordpress.org/wordpress-4.0.zip + """ + + When I run `wp core check-update --minor` + Then STDOUT should be: + """ + version update_type package_url + 3.8.4 minor https://wordpress.org/wordpress-3.8.4.zip + """ + Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory diff --git a/php/commands/core.php b/php/commands/core.php index 4d26e9fa74..f3b5eb3f06 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -23,7 +23,7 @@ private function remove_same_minor_releases( $release_parts, $updates ) { // later releases are always later in the array if ( $processed_parts[0] !== $release_parts[0] - && $processed_parts[1] !== $release_parts[1] ) { + || $processed_parts[1] !== $release_parts[1] ) { $differents[] = $processed; } } @@ -46,10 +46,10 @@ private function remove_same_minor_releases( $release_parts, $updates ) { * : Prints the value of a single field for each update. * * [--fields=<fields>] - * : Limit the output to specific object fields. Defaults to version,type,package_url. + * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json. Default: table * * @subcommand check-update */ @@ -96,7 +96,7 @@ function check_update( $_, $assoc_args ) { $updates = $this->remove_same_minor_releases( $release_parts, $updates ); $updates[] = array( 'version' => $release_version, - 'type' => $update_type, + 'update_type' => $update_type, 'package_url' => $this->get_download_url( $release_version, $locale ) ); } @@ -105,9 +105,11 @@ function check_update( $_, $assoc_args ) { if ( $updates ) { $formatter = new \WP_CLI\Formatter( $assoc_args, - array( 'version', 'type', 'package_url' ) + array( 'version', 'update_type', 'package_url' ) ); $formatter->display_items( $updates ); + } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { + WP_CLI::success( "WordPress is at the latest version." ); } } From 70952f2f369286b86e48f29c6b098eb80802856e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 16:48:16 -0700 Subject: [PATCH 3197/4858] Fix typo; move private method to the bottom of the class See #1365 --- php/commands/core.php | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index f3b5eb3f06..f6f82afec2 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -9,28 +9,6 @@ */ class Core_Command extends WP_CLI_Command { - /** - * Compare processed releases to the current one, and delete older one. Return remaining updates. - * - */ - private function remove_same_minor_releases( $release_parts, $updates ) { - if ( empty( $updates ) ) - return false; - - $differents = array(); - foreach ( $updates as $processed ) { - $processed_parts = explode( '.', $processed['version'] ); - - // later releases are always later in the array - if ( $processed_parts[0] !== $release_parts[0] - || $processed_parts[1] !== $release_parts[1] ) { - $differents[] = $processed; - } - } - - return $differents; - } - /** * Check for update via Version Check API. Returns latest version if there's an update, or empty if no update available. * @@ -973,6 +951,29 @@ private function get_download_url($version, $locale = 'en_US', $file_type = 'zip return $url; } } + + /** + * Compare processed releases to the current one, and delete older one. Return remaining updates. + * + */ + private function remove_same_minor_releases( $release_parts, $updates ) { + if ( empty( $updates ) ) + return false; + + $difference = array(); + foreach ( $updates as $processed ) { + $processed_parts = explode( '.', $processed['version'] ); + + // later releases are always later in the array + if ( $processed_parts[0] !== $release_parts[0] + || $processed_parts[1] !== $release_parts[1] ) { + $difference[] = $processed; + } + } + + return $difference; + } + } WP_CLI::add_command( 'core', 'Core_Command' ); From 8d34aff1e7fb68853cd768054227ea2a72f147bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 10 Sep 2014 16:59:01 -0700 Subject: [PATCH 3198/4858] Mirror behaviour of `wp cli check-update` by listing most recent atop See #1365 --- features/core.feature | 30 +++++++++++++++++++++--------- php/commands/core.php | 7 ++++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/features/core.feature b/features/core.feature index e06bc15311..3e59a8c5a8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -268,27 +268,39 @@ Feature: Manage WordPress installation Then STDOUT should not be empty When I run `wp core check-update` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 4.0 | major | https://wordpress.org/wordpress-4.0.zip | + | 3.9.2 | major | https://wordpress.org/wordpress-3.9.2.zip | + | 3.8.4 | minor | https://wordpress.org/wordpress-3.8.4.zip | + + When I run `wp core check-update --field=version | wc -l` Then STDOUT should be: """ - version update_type package_url - 3.8.4 minor https://wordpress.org/wordpress-3.8.4.zip - 3.9.2 major https://wordpress.org/wordpress-3.9.2.zip - 4.0 major https://wordpress.org/wordpress-4.0.zip + 3 """ When I run `wp core check-update --major` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 4.0 | major | https://wordpress.org/wordpress-4.0.zip | + | 3.9.2 | major | https://wordpress.org/wordpress-3.9.2.zip | + + When I run `wp core check-update --major --field=version | wc -l` Then STDOUT should be: """ - version update_type package_url - 3.9.2 major https://wordpress.org/wordpress-3.9.2.zip - 4.0 major https://wordpress.org/wordpress-4.0.zip + 2 """ When I run `wp core check-update --minor` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 3.8.4 | minor | https://wordpress.org/wordpress-3.8.4.zip | + + When I run `wp core check-update --minor --field=version | wc -l` Then STDOUT should be: """ - version update_type package_url - 3.8.4 minor https://wordpress.org/wordpress-3.8.4.zip + 1 """ Scenario: Custom wp-content directory diff --git a/php/commands/core.php b/php/commands/core.php index f6f82afec2..548476d90f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -50,12 +50,17 @@ function check_update( $_, $assoc_args ) { } $release_data = json_decode( $response->body ); + $release_versions = array_keys( (array) $release_data ); + usort( $release_versions, function( $a, $b ){ + return ! version_compare( $a, $b ); + }); + $locale = get_locale(); $current_parts = explode( '.', $wp_version ); $updates = array(); - foreach ( $release_data as $release_version => $release ) { + foreach ( $release_versions as $release_version ) { // don't list earliers versions if ( version_compare( $release_version, $wp_version, '<=' ) ) continue; From ebb46e33988c784431e391e0f65517665795ba86 Mon Sep 17 00:00:00 2001 From: Patrick Holberg Hesselberg <phh@peytz.dk> Date: Thu, 11 Sep 2014 18:47:20 +0000 Subject: [PATCH 3199/4858] removes like_escape deprecation notice and uses $wpdb->esc_like() if the method is available. Fallbacks to old like_escape() --- php/commands/search-replace.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7406eca9d8..efb8955e65 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -122,7 +122,7 @@ private static function get_table_list( $args, $network ) { return $args; $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; - $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", like_escape( $prefix ) . '%' ) ); + $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); $allowed_tables = array(); $allowed_table_types = array( 'tables', 'global_tables' ); @@ -166,7 +166,10 @@ private static function sql_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; if ( $dry_run ) { - return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . like_escape( esc_sql( $old ) ) . '%' ) ); + // Remove notices in 4.0 and support backwards compatibility + $old = method_exists( $wpdb, 'esc_like' ) ? $wpdb->esc_like( $old ) : like_escape( esc_sql( $old ) ); + + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . $old . '%' ) ); } else { return $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } @@ -181,10 +184,13 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $fields = $primary_keys; $fields[] = $col; + // Remove notices in 4.0 and support backwards compatibility + $old = method_exists( $wpdb, 'esc_like' ) ? $wpdb->esc_like( $old ) : like_escape( esc_sql( $old ) ); + $args = array( 'table' => $table, 'fields' => $fields, - 'where' => "`$col`" . ' LIKE "%' . like_escape( esc_sql( $old ) ) . '%"', + 'where' => "`$col`" . ' LIKE "%' . $old . '%"', 'chunk_size' => $chunk_size ); From 7c2bb438ab1fff65342a5dff287228fee5658e67 Mon Sep 17 00:00:00 2001 From: Patrick Holberg Hesselberg <phh@peytz.dk> Date: Thu, 11 Sep 2014 19:01:10 +0000 Subject: [PATCH 3200/4858] avoids using a one-liner and uses a static method instead --- php/commands/search-replace.php | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index efb8955e65..d62d54dcef 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -166,10 +166,7 @@ private static function sql_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; if ( $dry_run ) { - // Remove notices in 4.0 and support backwards compatibility - $old = method_exists( $wpdb, 'esc_like' ) ? $wpdb->esc_like( $old ) : like_escape( esc_sql( $old ) ); - - return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . $old . '%' ) ); + return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); } else { return $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } @@ -184,13 +181,10 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $fields = $primary_keys; $fields[] = $col; - // Remove notices in 4.0 and support backwards compatibility - $old = method_exists( $wpdb, 'esc_like' ) ? $wpdb->esc_like( $old ) : like_escape( esc_sql( $old ) ); - $args = array( 'table' => $table, 'fields' => $fields, - 'where' => "`$col`" . ' LIKE "%' . $old . '%"', + 'where' => "`$col`" . ' LIKE "%' . self::esc_like( $old ) . '%"', 'chunk_size' => $chunk_size ); @@ -252,6 +246,21 @@ private static function is_text_col( $type ) { return false; } + + private static function esc_like( $old ) { + global $wpdb; + + // Remove notices in 4.0 and support backwards compatibility + if( method_exists( $wpdb, 'esc_like' ) ) { + // 4.0 + $old = $wpdb->esc_like( $old ); + } else { + // 3.9 or less + $old = like_escape( esc_sql( $old ) ); + } + + return $old; + } } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); From edbcc1c0dc54a7dc943072d5151da60136459eba Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 11 Sep 2014 16:38:49 -0700 Subject: [PATCH 3201/4858] If no time supplied, `wp cron schedule` should default to "now" --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 93a75ee125..0b9854d5cf 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -101,7 +101,7 @@ public function list_( $args, $assoc_args ) { public function schedule( $args, $assoc_args ) { $hook = $args[0]; - $next_run = ( isset( $args[1] ) ) ? $args[1] : false; + $next_run = ( isset( $args[1] ) ) ? $args[1] : 'now'; $recurrence = ( isset( $args[2] ) ) ? $args[2] : false; if ( ! empty( $next_run ) ) { From 6a43a8f015ba0e839817dc45b591011a4a6a8f25 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 11 Sep 2014 16:41:01 -0700 Subject: [PATCH 3202/4858] Test for edbcc1c --- features/cron.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/cron.feature b/features/cron.feature index 0f638f6f6e..90f43ba157 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -34,6 +34,12 @@ Feature: Manage WP-Cron events and schedules Success: Scheduled event with hook 'wp_cli_test_event_3' """ + When I run `wp cron event schedule wp_cli_test_event_4` + Then STDOUT should contain: + """ + Success: Scheduled event with hook 'wp_cli_test_event_4' + """ + When I run `wp cron event list --format=csv --fields=hook,recurrence` Then STDOUT should be CSV containing: | hook | recurrence | From 1fb79c687c4b8afba082d586ae7c48bd71c1652b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 11 Sep 2014 17:07:48 -0700 Subject: [PATCH 3203/4858] Update .mailmap --- .mailmap | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.mailmap b/.mailmap index b2fd54a52b..9d78defad2 100644 --- a/.mailmap +++ b/.mailmap @@ -13,6 +13,7 @@ dangardner <dan@web.nearest.to> danielbachhuber <d@danielbachhuber.com> danielbachhuber <daniel@handbuilt.co> danielbachhuber <danielbachhuber@gmail.com> +dlh01 <david@alleyinteractive.com> dd32 <contact-atlassian@dd32.id.au> drrobotnik <B@Brandons-Mac-Pro-4.local> dwightjack <marco.solazzi@gmail.com> @@ -35,10 +36,13 @@ johnpbloch <johnpbloch@gmail.com> jonathanbardo <jonathanbardo@users.noreply.github.com> joshbetz <j@joshbetz.com> joshlevinson <joshalevinson@gmail.com> +jeichorn <joshua.eichorn@pagely.com> Kevinlearynet <info@kevinleary.net> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> +santagada <santagada@gmail.com> +lkwdwrd <woodward.lucas@gmail.com> marcoceppi <marco@ceppi.net> matiskay <matiskay@gmail.com> mattes <matthias.kadenbach@gmail.com> @@ -56,18 +60,22 @@ nb <nb@nikolay.bg> nickdaugherty <ndaugherty987@gmail.com> nikolay <nikolay@users.noreply.github.com> nikolay <nikolaynkolev@gmail.com> +nschoenholtz <noah@alleyinteractive.com> nullvariable <nullvariable@gmail.com> nyordanov <me@nyordanov.com> ocean90 <dominikschilling+git@gmail.com> oknoway <nate@oknoway.com> om4james <james@jamesc.id.au> om4james <james@om4.com.au> +phh <phh@peytz.dk> Rarst <contact@rarst.net> robertboloc <robertboloc@gmail.com> +rodrigoprimo <rodrigosprimo@gmail.com> rodrigoprimo <rodrigo@hacklab.com.br> roelven <roel@soundcloud.com> ryanduff <ryan@fusionized.com> sboisvert <stephane.boisvert@automattic.com> +scribu <mail@scribu.net> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> sibprogrammer <ayuzhakov@parallels.com> @@ -91,5 +99,6 @@ twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> +willmot <tom@humanmade.co.uk> wopr42 <john@zippykid.com> ziz <justin@crowdfavorite.com> From a17fa6f1ad9ba79446bada40abf00b521260f0ec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 11 Sep 2014 17:49:44 -0700 Subject: [PATCH 3204/4858] Version bump --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index c0a45246ee..28fe469ca1 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.16.0' ); +define( 'WP_CLI_VERSION', '0.17.0' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 366eb4e1ad4b5f23c6b57101deaa861a79103bfa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 17 Sep 2014 06:47:38 -0700 Subject: [PATCH 3205/4858] URL hacking to easily transform production to local See #1232 --- php/commands/search-replace.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index d62d54dcef..52ffbeaa1a 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -48,6 +48,9 @@ class Search_Replace_Command extends WP_CLI_Command { * 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; From 55b9731b902b03717ec64b2b4567d7aff2b26d70 Mon Sep 17 00:00:00 2001 From: William Turrell <william@wturrell.co.uk> Date: Fri, 12 Sep 2014 21:06:26 +0000 Subject: [PATCH 3206/4858] fix blank response for wp comment list --format-ids --- php/commands/comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index b490c902cf..b1ed1a6301 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -169,7 +169,7 @@ public function list_( $_, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); if ( 'ids' == $formatter->format ) - $assoc_args['fields'] = 'ids'; + $assoc_args['fields'] = 'comment_ID'; $query = new WP_Comment_Query(); $comments = $query->query( $assoc_args ); From f4701db287dee07958cb413661a7aaf49504038d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Tue, 16 Sep 2014 22:24:27 +0200 Subject: [PATCH 3207/4858] adding functional tests --- features/comment.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 1451e79063..8d2a445186 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -55,6 +55,12 @@ Feature: Manage WordPress comments 1 """ + When I run `wp comment list --format=ids` + Then STDOUT should be: + """ + 1 + """ + When I run `wp comment url 1` Then STDOUT should be: """ From 0456b68dfd63d887c23ae9ed19120add46bbfe95 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 17 Sep 2014 18:59:26 -0700 Subject: [PATCH 3208/4858] Force https when accessing WordPress.org WordPress.org started redirecting to https anyway. Sometimes WordPress.org APIs return http though. --- php/WP_CLI/CommandWithUpgrade.php | 4 ++++ php/commands/core.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 0ce9d34e96..982cbee279 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -167,6 +167,10 @@ protected static function alter_api_response( $response, $version ) { if ( $response->version == $version ) return; + // WordPress.org forces https, but still sometimes returns http + // See https://twitter.com/nacin/status/512362694205140992 + $response->download_link = str_replace( 'http://', 'https://', $response->download_link ); + list( $link ) = explode( $response->slug, $response->download_link ); if ( false !== strpos( $response->download_link, 'theme' ) ) diff --git a/php/commands/core.php b/php/commands/core.php index 548476d90f..aa3139a00b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -35,7 +35,7 @@ function check_update( $_, $assoc_args ) { $versions_path = ABSPATH . 'wp-includes/version.php'; include $versions_path; - $url = 'http://api.wordpress.org/core/stable-check/1.0/'; + $url = 'https://api.wordpress.org/core/stable-check/1.0/'; $options = array( 'timeout' => 30 From 87ae8886db79a38eb13a5585c57956d89a261fd9 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 19 Sep 2014 15:21:54 -0300 Subject: [PATCH 3209/4858] skip parameter check when calling help command --- features/help.feature | 7 +++++++ php/WP_CLI/Dispatcher/Subcommand.php | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/features/help.feature b/features/help.feature index 994358c3f2..5221c847f6 100644 --- a/features/help.feature +++ b/features/help.feature @@ -15,6 +15,13 @@ Feature: Get help about WP-CLI commands When I run `wp help help` Then STDOUT should not be empty + When I run `wp post list --post_type=post --posts_per_page=5 --help` + Then STDERR should be empty + And STDOUT should contain: + """ + wp post list + """ + Scenario: Help for nonexistent commands Given a WP install diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 373ee4e61e..83c87c7d2d 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -248,8 +248,10 @@ private function validate_args( $args, $assoc_args, $extra_args ) { array_merge( \WP_CLI::get_config(), $extra_args, $assoc_args ) ); - foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { - $errors['fatal'][] = "unknown --$key parameter"; + if ( $this->name != 'help' ) { + foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { + $errors['fatal'][] = "unknown --$key parameter"; + } } if ( !empty( $errors['fatal'] ) ) { From 468c57f3c369a45d962eaddd85a56a69ccf2253c Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 19 Sep 2014 22:41:02 -0300 Subject: [PATCH 3210/4858] add --activate param to `wp core language install --activate` --- features/core.feature | 9 +++++++++ php/WP_CLI/CommandWithTranslation.php | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/features/core.feature b/features/core.feature index 3e59a8c5a8..1c08fba6c6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -453,3 +453,12 @@ Feature: Manage WordPress installation """ Error: Language not installed. """ + + When I run `wp core language install --activate en_GB` + Then the wp-content/languages/admin-en_GB.po file should exist + And the wp-content/languages/en_GB.po file should exist + And STDOUT should be: + """ + Success: Language installed. + Success: Language activated. + """ \ No newline at end of file diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 36ca451a28..48c93d67bb 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -73,6 +73,9 @@ public function list_( $args, $assoc_args ) { * <language> * : Language code to install. * + * [--activate] + * : If set, the language will be activated immediately after install. + * * @subcommand install */ public function install( $args, $assoc_args ) { @@ -91,6 +94,10 @@ public function install( $args, $assoc_args ) { $response = wp_download_language_pack( $language_code ); if ( $response == $language_code ) { \WP_CLI::success( "Language installed." ); + + if ( isset( $assoc_args['activate'] ) ) { + $this->activate( array( $language_code ), array() ); + } } else { \WP_CLI::error( "Couldn't install language." ); } From 85d50bb63ceb62d9e01759c42b3ac4a146692326 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 19 Sep 2014 23:33:42 -0300 Subject: [PATCH 3211/4858] add en_US to the list of languages --- features/core.feature | 9 +++++---- php/WP_CLI/CommandWithTranslation.php | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index 3e59a8c5a8..4ca86a9d2e 100644 --- a/features/core.feature +++ b/features/core.feature @@ -395,10 +395,11 @@ Feature: Manage WordPress installation When I run `wp core language list --fields=language,english_name,status` Then STDOUT should be a table containing rows: - | language | english_name | status | - | ar | Arabic | uninstalled | - | az | Azerbaijani | uninstalled | - | en_GB | English (UK) | uninstalled | + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | + | en_US | English (United States) | active | + | en_GB | English (UK) | uninstalled | When I run `wp core language install en_GB` Then the wp-content/languages/admin-en_GB.po file should exist diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 36ca451a28..c8d5419a20 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -51,6 +51,17 @@ public function list_( $args, $assoc_args ) { $response = translations_api( $this->obj_type ); $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); + + $en_us = array( + 'language' => 'en_US', + 'english_name' => 'English (United States)', + 'native_name' => 'English (United States)', + 'status' => ( empty( $current_locale ) ) ? 'active' : 'installed', + ); + + array_push( $translations, $en_us ); + uasort( $translations, array( $this, '_sort_translations_callback' ) ); + $available = wp_get_installed_translations( $this->obj_type ); $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); $current_locale = get_locale(); @@ -67,6 +78,13 @@ public function list_( $args, $assoc_args ) { } + /** + * Callback to sort array by a 'language' key. + */ + protected function _sort_translations_callback( $a, $b ) { + return strnatcasecmp( $a['language'], $b['language'] ); + } + /** * Install a given language. * From 8b4d2b1e948413a53474e92635fcb65b6652d09d Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 19 Sep 2014 23:58:14 -0300 Subject: [PATCH 3212/4858] make it possible to activate en_US language --- features/core.feature | 14 ++++++ php/WP_CLI/CommandWithTranslation.php | 70 ++++++++++++++++++--------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/features/core.feature b/features/core.feature index 4ca86a9d2e..b2f1c68aa8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -435,6 +435,20 @@ Feature: Manage WordPress installation | az | Azerbaijani | uninstalled | | en_GB | English (UK) | active | + When I run `wp core language activate en_US` + Then STDOUT should be: + """ + Success: Language activated. + """ + + When I run `wp core language list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | en_US | English (United States) | active | + | en_GB | English (UK) | installed | + + When I try `wp core language activate invalid_lang` Then STDERR should be: """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index c8d5419a20..d4b7bc5ac1 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -47,23 +47,9 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { */ public function list_( $args, $assoc_args ) { - require_once ABSPATH . '/wp-admin/includes/translation-install.php'; - - $response = translations_api( $this->obj_type ); - $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); - - $en_us = array( - 'language' => 'en_US', - 'english_name' => 'English (United States)', - 'native_name' => 'English (United States)', - 'status' => ( empty( $current_locale ) ) ? 'active' : 'installed', - ); + $translations = $this->_get_all_languages(); + $available = $this->_get_installed_languages(); - array_push( $translations, $en_us ); - uasort( $translations, array( $this, '_sort_translations_callback' ) ); - - $available = wp_get_installed_translations( $this->obj_type ); - $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); $current_locale = get_locale(); $translations = array_map( function( $translation ) use ( $available, $current_locale ) { $translation['status'] = ( in_array( $translation['language'], $available ) ) ? 'installed' : 'uninstalled'; @@ -97,8 +83,8 @@ public function install( $args, $assoc_args ) { list( $language_code ) = $args; - $available = wp_get_installed_translations( $this->obj_type ); - $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); + $available = $this->_get_installed_languages(); + if ( in_array( $language_code, $available ) ) { \WP_CLI::warning( "Language already installed." ); exit; @@ -127,16 +113,56 @@ public function activate( $args, $assoc_args ) { list( $language_code ) = $args; - $available = wp_get_installed_translations( $this->obj_type ); - $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); + $available = $this->_get_installed_languages(); + if ( ! in_array( $language_code, $available ) ) { \WP_CLI::error( "Language not installed." ); } + if ( $language_code == 'en_US' ) { + $language_code = ''; + } + update_option( 'WPLANG', $language_code ); \WP_CLI::success( "Language activated." ); } + /** + * Return a list of installed languages. + * + * @return array + */ + protected function _get_installed_languages() { + $available = wp_get_installed_translations( $this->obj_type ); + $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); + $available[] = 'en_US'; + + return $available; + } + + /** + * Return a list of all languages + * + * @return array + */ + protected function _get_all_languages() { + require_once ABSPATH . '/wp-admin/includes/translation-install.php'; + + $response = translations_api( $this->obj_type ); + $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); + + $en_us = array( + 'language' => 'en_US', + 'english_name' => 'English (United States)', + 'native_name' => 'English (United States)', + ); + + array_push( $translations, $en_us ); + uasort( $translations, array( $this, '_sort_translations_callback' ) ); + + return $translations; + } + /** * Uninstall a given language. * @@ -150,8 +176,8 @@ public function uninstall( $args, $assoc_args ) { list( $language_code ) = $args; - $available = wp_get_installed_translations( $this->obj_type ); - $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); + $available = $this->_get_installed_languages(); + if ( ! in_array( $language_code, $available ) ) { \WP_CLI::error( "Language not installed." ); } From 489458a0f00a9ed2b5e53e92cf9c4558c7614b8f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Sat, 20 Sep 2014 12:34:44 -0300 Subject: [PATCH 3213/4858] Add functionality to filter list of languages --- features/core.feature | 9 +++++++++ php/WP_CLI/CommandWithTranslation.php | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index b2f1c68aa8..c9c55b24a1 100644 --- a/features/core.feature +++ b/features/core.feature @@ -468,3 +468,12 @@ Feature: Manage WordPress installation """ Error: Language not installed. """ + + When I run `wp core language list --fields=language,english_name,status --status=active` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | en_US | English (United States) | active | + And STDOUT should not contain: + """ + English (UK) + """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index d4b7bc5ac1..57fc3a503c 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -22,6 +22,9 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { /** * List all languages available. * + * [--<field>=<value>] + * : Filter results based on the value of a field. + * * [--fields=<fields>] * : Limit the output to specific fields. * @@ -56,12 +59,20 @@ public function list_( $args, $assoc_args ) { if ( $current_locale == $translation['language'] ) { $translation['status'] = 'active'; } + return $translation; }, $translations ); + foreach ( $translations as $key => $translation ) { + foreach ( $this->obj_fields as $field ) { + if ( isset( $assoc_args[$field] ) && $assoc_args[$field] != $translation[$field] ) { + unset( $translations[$key] ); + } + } + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $translations ); - } /** From 3e459a9d04b167e99cae65b0f702f60a925f5b90 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Sat, 20 Sep 2014 12:38:47 -0300 Subject: [PATCH 3214/4858] add missing new line at end of file --- features/core.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 1c08fba6c6..4d063f7de0 100644 --- a/features/core.feature +++ b/features/core.feature @@ -461,4 +461,5 @@ Feature: Manage WordPress installation """ Success: Language installed. Success: Language activated. - """ \ No newline at end of file + """ + From 1a571218f1a2a195b2311f5ff46d59176f9f74d7 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Sat, 20 Sep 2014 17:00:15 -0300 Subject: [PATCH 3215/4858] remove empty line added by mistake --- php/WP_CLI/CommandWithTranslation.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 57fc3a503c..810362161e 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -59,7 +59,6 @@ public function list_( $args, $assoc_args ) { if ( $current_locale == $translation['language'] ) { $translation['status'] = 'active'; } - return $translation; }, $translations ); From 6952bc4b859655afb46cd679ab60998180224aed Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Sep 2014 11:45:25 -0300 Subject: [PATCH 3216/4858] improve test for `wp core language --<field>=<value>` --- features/core.feature | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index c9c55b24a1..2ac94a4d73 100644 --- a/features/core.feature +++ b/features/core.feature @@ -473,7 +473,9 @@ Feature: Manage WordPress installation Then STDOUT should be a table containing rows: | language | english_name | status | | en_US | English (United States) | active | - And STDOUT should not contain: + + When I run `wp core language list --fields=language,english_name,status --status=active | wc -l` + Then STDOUT should be: """ - English (UK) + 2 """ From b4477a4bb05c6f0b58955cb81f3ba06fb8e31ad4 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Sep 2014 11:49:16 -0300 Subject: [PATCH 3217/4858] remove underscores from methods names --- php/WP_CLI/CommandWithTranslation.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 810362161e..a93361a52d 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -50,8 +50,8 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { */ public function list_( $args, $assoc_args ) { - $translations = $this->_get_all_languages(); - $available = $this->_get_installed_languages(); + $translations = $this->get_all_languages(); + $available = $this->get_installed_languages(); $current_locale = get_locale(); $translations = array_map( function( $translation ) use ( $available, $current_locale ) { @@ -77,7 +77,7 @@ public function list_( $args, $assoc_args ) { /** * Callback to sort array by a 'language' key. */ - protected function _sort_translations_callback( $a, $b ) { + protected function sort_translations_callback( $a, $b ) { return strnatcasecmp( $a['language'], $b['language'] ); } @@ -93,7 +93,7 @@ public function install( $args, $assoc_args ) { list( $language_code ) = $args; - $available = $this->_get_installed_languages(); + $available = $this->get_installed_languages(); if ( in_array( $language_code, $available ) ) { \WP_CLI::warning( "Language already installed." ); @@ -123,7 +123,7 @@ public function activate( $args, $assoc_args ) { list( $language_code ) = $args; - $available = $this->_get_installed_languages(); + $available = $this->get_installed_languages(); if ( ! in_array( $language_code, $available ) ) { \WP_CLI::error( "Language not installed." ); @@ -142,7 +142,7 @@ public function activate( $args, $assoc_args ) { * * @return array */ - protected function _get_installed_languages() { + protected function get_installed_languages() { $available = wp_get_installed_translations( $this->obj_type ); $available = ! empty( $available['default'] ) ? array_keys( $available['default'] ) : array(); $available[] = 'en_US'; @@ -155,7 +155,7 @@ protected function _get_installed_languages() { * * @return array */ - protected function _get_all_languages() { + protected function get_all_languages() { require_once ABSPATH . '/wp-admin/includes/translation-install.php'; $response = translations_api( $this->obj_type ); @@ -168,7 +168,7 @@ protected function _get_all_languages() { ); array_push( $translations, $en_us ); - uasort( $translations, array( $this, '_sort_translations_callback' ) ); + uasort( $translations, array( $this, 'sort_translations_callback' ) ); return $translations; } @@ -186,7 +186,7 @@ public function uninstall( $args, $assoc_args ) { list( $language_code ) = $args; - $available = $this->_get_installed_languages(); + $available = $this->get_installed_languages(); if ( ! in_array( $language_code, $available ) ) { \WP_CLI::error( "Language not installed." ); From 57ffd7afb9cf25c60060ffd03901953149b258c3 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Sep 2014 12:00:21 -0300 Subject: [PATCH 3218/4858] remove unecessary check --- features/help.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index 5221c847f6..dff1de5235 100644 --- a/features/help.feature +++ b/features/help.feature @@ -16,7 +16,6 @@ Feature: Get help about WP-CLI commands Then STDOUT should not be empty When I run `wp post list --post_type=post --posts_per_page=5 --help` - Then STDERR should be empty And STDOUT should contain: """ wp post list From 4d95eb6467234b2fe72bba82b976e4150683a29e Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Sep 2014 14:35:58 -0300 Subject: [PATCH 3219/4858] typo --- features/help.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index dff1de5235..4e48d26afc 100644 --- a/features/help.feature +++ b/features/help.feature @@ -16,7 +16,7 @@ Feature: Get help about WP-CLI commands Then STDOUT should not be empty When I run `wp post list --post_type=post --posts_per_page=5 --help` - And STDOUT should contain: + Then STDOUT should contain: """ wp post list """ From 1321638d324aa0be4759c4910d3acc0b08cea2ba Mon Sep 17 00:00:00 2001 From: Tiago Hillebrandt <tiagohillebrandt@ubuntu.com> Date: Mon, 22 Sep 2014 21:14:03 -0500 Subject: [PATCH 3220/4858] Implements the enable all plugins function. --- php/commands/plugin.php | 66 +++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e33d270977..d69180368c 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -132,29 +132,36 @@ protected function get_all_items() { * * ## OPTIONS * - * <plugin>... + * [<plugin>...] * : One or more plugins to activate. * + * [--all] + * : If set, all plugins will be activated. + * * [--network] * : If set, the plugin will be activated for the entire multisite network. */ function activate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); + $enable_all = isset( $assoc_args['all'] ); - foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - - $status = $this->get_status( $plugin->file ); - if ( ! $network_wide && 'active' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); - continue; - } else if ( $network_wide && 'active-network' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); - continue; - } + if ( $enable_all ) { + $this->update_plugins_status( "activate", $network_wide ); + } else { + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { + $status = $this->get_status( $plugin->file ); + if ( ! $network_wide && 'active' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); + continue; + } else if ( $network_wide && 'active-network' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); + continue; + } - activate_plugin( $plugin->file, '', $network_wide ); + activate_plugin( $plugin->file, '', $network_wide ); - $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); + $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); + } } } @@ -177,16 +184,7 @@ function deactivate( $args, $assoc_args = array() ) { $disable_all = isset( $assoc_args['all'] ); if ( $disable_all ) { - foreach ( get_plugins() as $file => $details ) { - if ( $this->get_status( $file ) == "inactive" ) - continue; - - $name = Utils\get_plugin_name( $file ); - - deactivate_plugins( $file, false, $network_wide ); - - $this->active_output( $name, $file, $network_wide, "deactivate" ); - } + $this->update_plugins_status( "deactivate", $network_wide ); } else { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { deactivate_plugins( $plugin->file, false, $network_wide ); @@ -357,7 +355,7 @@ protected function filter_item_list( $items, $args ) { * * [--activate] * : If set, the plugin will be activated immediately after install. - * + * * [--activate-network] * : If set, the plugin will be network activated immediately after install * @@ -561,6 +559,25 @@ private function active_output( $name, $file, $network_wide, $action ) { } } + /** + * Enable or disable all plugins. + */ + private function update_plugins_status( $action, $network_wide ) { + $status = ( $action == "activate" ) ? "active" : "inactive"; + foreach ( get_plugins() as $file => $details ) { + if ( $this->get_status( $file ) == $status ) + continue; + + if ( $action == "activate" ) + activate_plugins( $file, false, $network_wide ); + else + deactivate_plugins( $file, false, $network_wide ); + + $name = Utils\get_plugin_name( $file ); + $this->active_output( $name, $file, $network_wide, $action ); + } + } + protected function get_status( $file ) { if ( is_plugin_active_for_network( $file ) ) return 'active-network'; @@ -603,4 +620,3 @@ private function _delete( $plugin ) { } WP_CLI::add_command( 'plugin', 'Plugin_Command' ); - From 37f662a997ff416a48f29600e84291195b1c7e2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 25 Sep 2014 10:34:03 -0700 Subject: [PATCH 3221/4858] Wrap `new DateTime` with try{ } catch() {} It can trigger an Exception if `date.timezone` isn't set --- php/WP_CLI/FileCache.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/FileCache.php b/php/WP_CLI/FileCache.php index 6fb0af3d7f..6238070072 100644 --- a/php/WP_CLI/FileCache.php +++ b/php/WP_CLI/FileCache.php @@ -220,7 +220,11 @@ public function clean() { // unlink expired files if ( $ttl > 0 ) { - $expire = new \DateTime(); + try { + $expire = new \DateTime(); + } catch ( \Exception $e ) { + \WP_CLI::error( $e->getMessage() ); + } $expire->modify( '-' . $ttl . ' seconds' ); $finder = $this->get_finder()->date( 'until ' . $expire->format( 'Y-m-d H:i:s' ) ); From bf6bc5efcaf5b52c6f5bfaca18c148c382d88358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 25 Sep 2014 22:36:44 +0200 Subject: [PATCH 3222/4858] Add option list subcommand. --- php/commands/option.php | 75 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/php/commands/option.php b/php/commands/option.php index 962ef03cef..087d1d1e02 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -77,6 +77,81 @@ public function add( $args, $assoc_args ) { } } + /** + * List options. + * + * [--search=<sql-like-pattern>] + * : SQL pattern matching enables you to use "_" to match any single character and "%" to match an arbitrary number of characters. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. + * + * [--autoload] + * : Match only autoload options. + * + * [--total] + * : Display only the total size of matching options. + * + * [--format=<format>] + * : The serialization format for the value. Default is table. + * + * ## AVAILABLE FIELDS + * + * This field will be displayed by default for each matching option: + * + * * option_name + * + * These fields are optionally available: + * + * * option_name + * * autoload + * * size + * + * @subcommand list + * @synopsis [--search=<sql-like-pattern>] [--total] [--autoload] [--fields=<fields>] [--format=<format>] + */ + public function list_( $args, $assoc_args ) { + + global $wpdb; + $size_query = "LENGTH(option_value) AS size"; + $autoload_query = ''; + + if ( isset( $assoc_args['search'] ) ) { + $pattern = $assoc_args['search']; + } else { + $pattern = '%'; + } + + if ( isset( $assoc_args['fields'] ) ) { + $fields = explode( ',', $assoc_args['fields'] ); + } else { + $fields = array( 'option_name' ); + } + + if ( isset( $assoc_args['total'] ) ) { + $fields = array( 'size' ); + $size_query = "SUM(LENGTH(option_value)) AS size"; + } + + if ( isset( $assoc_args['autoload'] ) ) { + $autoload_query = " AND autoload='yes'"; + } + + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT option_name,option_value,autoload," . $size_query + . " FROM $wpdb->options WHERE option_name LIKE %s" . $autoload_query, + $pattern + ) + ); + + $formatter = new \WP_CLI\Formatter( + $assoc_args, + $fields + ); + $formatter->display_items( $results ); + } + /** * Update an option. * From 66ac9908c494ae0d192ea650decac8a18b64a416 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 06:06:16 -0700 Subject: [PATCH 3223/4858] WPorg API returns names with HTML entities. We can decode for CLI. --- features/plugin.feature | 9 +++++++++ php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 0d582808fa..41823ad307 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -233,3 +233,12 @@ Feature: Manage WordPress plugins """ Warning: Plugin 'akismet' is already network active. """ + + Scenario: Plugin name with HTML entities + Given a WP install + + When I run `wp plugin install debug-bar-list-dependencies` + Then STDOUT should contain: + """ + Installing Debug Bar List Script & Style Dependencies + """ diff --git a/php/commands/plugin.php b/php/commands/plugin.php index e33d270977..118d976e50 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -268,7 +268,7 @@ protected function install_from_repo( $slug, $assoc_args ) { return new WP_Error( 'already_installed', 'Plugin already installed.' ); } - WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name ), $api->version ) ); if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index c7eee76e40..94b73e54ba 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -283,7 +283,7 @@ protected function install_from_repo( $slug, $assoc_args ) { return new WP_Error( 'already_installed', 'Theme already installed.' ); } - WP_CLI::log( sprintf( 'Installing %s (%s)', $api->name, $api->version ) ); + WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name ), $api->version ) ); if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } From 9bd35fb54affda982d55146f1c922d4ea34b0262 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 06:16:23 -0700 Subject: [PATCH 3224/4858] Sniff out the custom vendor path if we're a part of a Composer project --- php/utils.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index fbee550acb..77d0d98172 100644 --- a/php/utils.php +++ b/php/utils.php @@ -30,10 +30,18 @@ function load_dependencies() { } function get_vendor_paths() { - return array( + $vendor_paths = array( WP_CLI_ROOT . '/../../../vendor', // part of a larger project / installed via Composer (preferred) WP_CLI_ROOT . '/vendor', // top-level project / installed as Git clone ); + $maybe_composer_json = WP_CLI_ROOT . '/../../../composer.json'; + if ( file_exists( $maybe_composer_json ) && is_readable( $maybe_composer_json ) ) { + $composer = json_decode( file_get_contents( $maybe_composer_json ) ); + if ( ! empty( $composer->{'vendor-dir'} ) ) { + array_unshift( $vendor_paths, WP_CLI_ROOT . '/../../../' . $composer->{'vendor-dir'} ); + } + } + return $vendor_paths; } // Using require() directly inside a class grants access to private methods to the loaded code From b5a2cd7d99616141e469fc4a72b8f7de12c03702 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 06:35:19 -0700 Subject: [PATCH 3225/4858] PHP magic methods, except `__invoke()`, aren't valid WP-CLI commands PHP reserves `__` prefix for magic methods. Don't use function names starting with `__` unless you're using magic methods. --- features/help.feature | 47 ++++++++++++++++++++++++ php/WP_CLI/Dispatcher/CommandFactory.php | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index 994358c3f2..d84be1c55a 100644 --- a/features/help.feature +++ b/features/help.feature @@ -70,3 +70,50 @@ Feature: Get help about WP-CLI commands """ usage: wp core """ + + Scenario: Help for commands with magic methods + Given a WP install + And a wp-content/plugins/test-cli/command.php file: + """ + <?php + // Plugin Name: Test CLI Help + + class Test_Magic_Methods extends WP_CLI_Command { + /** + * A dummy command. + * + * @subcommand my-command + */ + function my_command() {} + + /** + * Magic methods should not appear as commands + */ + function __construct() {} + function __destruct() {} + function __call( $name, $arguments ) {} + function __get( $key ) {} + function __set( $key, $value ) {} + function __isset( $key ) {} + function __unset( $key ) {} + function __sleep() {} + function __wakeup() {} + function __toString() {} + function __set_state() {} + function __clone() {} + function __debugInfo() {} + } + + WP_CLI::add_command( 'test-magic-methods', 'Test_Magic_Methods' ); + """ + And I run `wp plugin activate test-cli` + + When I run `wp test-magic-methods` + Then STDOUT should contain: + """ + usage: wp test-magic-methods my-command + """ + And STDOUT should not contain: + """ + __destruct + """ diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index 2bc884e013..b4f941dd03 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -88,7 +88,7 @@ private static function create_composite_command( $parent, $name, $reflection ) * @return bool */ private static function is_good_method( $method ) { - return $method->isPublic() && !$method->isConstructor() && !$method->isStatic(); + return $method->isPublic() && !$method->isStatic() && 0 !== strpos( $method->getName(), '__' ); } } From 1dcc78f3d43db09ad9a2e863133b814fdd3a58c3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 06:47:12 -0700 Subject: [PATCH 3226/4858] Limit `wp core language list` output by fields --- features/core.feature | 6 ++++++ php/WP_CLI/CommandWithTranslation.php | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/features/core.feature b/features/core.feature index 3e59a8c5a8..1f77dfcc68 100644 --- a/features/core.feature +++ b/features/core.feature @@ -427,6 +427,12 @@ Feature: Manage WordPress installation Success: Language activated. """ + When I run `wp core language list --field=language --status=active` + Then STDOUT should be: + """ + en_GB + """ + When I run `wp core language list --fields=language,english_name,status` Then STDOUT should be a table containing rows: | language | english_name | status | diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 36ca451a28..ba9192b918 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -22,6 +22,12 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { /** * List all languages available. * + * [--field=<field>] + * : Display the value of a single field + * + * [--<field>=<value>] + * : Filter results by key=value pairs. + * * [--fields=<fields>] * : Limit the output to specific fields. * @@ -62,6 +68,16 @@ public function list_( $args, $assoc_args ) { return $translation; }, $translations ); + foreach( $translations as $key => $translation ) { + + $fields = array_keys( $translation ); + foreach( $fields as $field ) { + if ( isset( $assoc_args[ $field ] ) && $assoc_args[ $field ] != $translation[ $field ] ) { + unset( $translations[ $key ] ); + } + } + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $translations ); From 401b9975743d2dff84b7825cf3e2c309aa68f7af Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 09:05:30 -0700 Subject: [PATCH 3227/4858] Formatter: Gracefully handle items with objects / arrays as values We've been preflighting the data to `json_encode()` each time. This is unnecessary. --- php/WP_CLI/CommandWithMeta.php | 4 ---- php/WP_CLI/Formatter.php | 22 +++++++++++++++++++++- php/commands/cron.php | 7 ------- php/commands/menu.php | 3 --- php/commands/widget.php | 6 ------ 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 2f3d7b49cf..7b54511a1b 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -51,10 +51,6 @@ public function list_( $args, $assoc_args ) { $item_value = maybe_unserialize( $item_value ); - if ( ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv' ) ) )&& ( is_object( $item_value ) || is_array( $item_value ) ) ) { - $item_value = json_encode( $item_value ); - } - $items[] = (object) array( "{$this->meta_type}_id" => $object_id, 'meta_key' => $key, diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index cd9717a7de..ac1bc24d28 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -72,6 +72,22 @@ public function display_items( $items ) { array_unshift( $items, $item ); } } + + if ( in_array( $this->args['format'], array( 'table', 'csv' ) ) ) { + $items = array_map( function( $item ){ + foreach( (array)$item as $key => $value ) { + if ( is_array( $value ) || is_object( $value ) ) { + if ( is_object( $item ) ) { + $item->$key = json_encode( $value ); + } else if ( is_array( $item ) ) { + $item[ $key ] = json_encode( $value ); + } + } + } + return $item; + }, $items ); + } + $this->format( $items ); } } @@ -85,7 +101,11 @@ public function display_item( $item ) { if ( isset( $this->args['field'] ) ) { $item = (object) $item; $key = $this->find_item_key( $item, $this->args['field'] ); - \WP_CLI::print_value( $item->$key, array( 'format' => $this->args['format'] ) ); + $value = $item->$key; + if ( in_array( $this->args['format'], array( 'table', 'csv' ) ) && ( is_object( $value ) || is_array( $value ) ) ) { + $value = json_encode( $value ); + } + \WP_CLI::print_value( $value, array( 'format' => $this->args['format'] ) ); } else { self::show_multiple_fields( $item, $this->args['format'] ); } diff --git a/php/commands/cron.php b/php/commands/cron.php index 0b9854d5cf..c340792289 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -58,13 +58,6 @@ public function list_( $args, $assoc_args ) { $events = array(); } - if ( in_array( $formatter->format, array( 'table', 'csv' ) ) ) { - $events = array_map( function( $event ){ - $event->args = json_encode( $event->args ); - return $event; - }, $events ); - } - if ( 'ids' == $formatter->format ) { echo implode( ' ', wp_list_pluck( $events, 'hook' ) ); } else { diff --git a/php/commands/menu.php b/php/commands/menu.php index f71f9dbda8..0277cbba06 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -236,9 +236,6 @@ public function list_( $args, $assoc_args ) { $items = array_map( function( $item ) use ( $assoc_args ) { $item->position = $item->menu_order; $item->link = $item->url; - if ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'json' ) ) ) { - $item->classes = json_encode( $item->classes ); - } return $item; }, $items ); diff --git a/php/commands/widget.php b/php/commands/widget.php index 19c9568d4a..af8a0a88d4 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -64,12 +64,6 @@ public function list_( $args, $assoc_args ) { $output_widgets = $this->get_sidebar_widgets( $sidebar_id ); - if ( empty( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'table', 'csv') ) ) { - foreach( $output_widgets as &$output_widget ) { - $output_widget->options = json_encode( $output_widget->options ); - } - } - if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) { $output_widgets = wp_list_pluck( $output_widgets, 'id' ); } From 0b729355e905cb561d2dd0d5ea80987f6b384142 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 10:13:55 -0700 Subject: [PATCH 3228/4858] `wp <object> get` should support limiting output based off `--fields` Adds support to `wp post`, `wp comment`, and `wp term`. `wp user` already had it. Unlike `wp <object> list`, `* get` defaults to all object fields. Adds `--format=csv` to `* get` as well. --- features/comment.feature | 6 ++++++ features/post.feature | 8 +++++++ features/term.feature | 8 ++++++- php/WP_CLI/CommandWithDBObject.php | 12 ++++++++++- php/WP_CLI/Formatter.php | 34 +++++++++++++++++++++++++----- php/commands/comment.php | 13 ++++++++++-- php/commands/post.php | 9 +++++++- php/commands/term.php | 15 ++++++++++--- php/commands/user.php | 2 +- 9 files changed, 93 insertions(+), 14 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 8d2a445186..94aeb9d9b1 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -44,6 +44,12 @@ Feature: Manage WordPress comments | Field | Value | | comment_author | Mr WordPress | + When I run `wp comment get 1 --fields=comment_author,comment_author_email --format=json` + Then STDOUT should be: + """ + {"comment_author":"Mr WordPress","comment_author_email":""} + """ + When I run `wp comment list --fields=comment_approved,comment_author` Then STDOUT should be a table containing rows: | comment_approved | comment_author | diff --git a/features/post.feature b/features/post.feature index 1ff2128fed..1d297a9ec9 100644 --- a/features/post.feature +++ b/features/post.feature @@ -60,6 +60,14 @@ Feature: Manage WordPress posts | Field | Value | | ID | {POST_ID} | | post_title | Test post | + | post_name | | + | post_type | post | + + When I run `wp post get {POST_ID} --format=csv --fields=post_title,type | wc -l` + Then STDOUT should be: + """ + 3 + """ When I run `wp post get --format=json {POST_ID}` Then STDOUT should be JSON containing: diff --git a/features/term.feature b/features/term.feature index 2dc2d3d051..6bcf637204 100644 --- a/features/term.feature +++ b/features/term.feature @@ -43,13 +43,19 @@ Feature: Manage WordPress terms | term_id | {TERM_ID} | | name | Test term | + When I run `wp term get post_tag {TERM_ID} --format=csv --fields=name,taxonomy` + Then STDOUT should be CSV containing: + | Field | Value | + | name | Test term | + | taxonomy | post_tag | + Scenario: Creating/deleting a term When I run `wp term create post_tag 'Test delete term' --slug=test-delete --description='This is a test term to be deleted' --porcelain` Then STDOUT should be a number And save STDOUT as {TERM_ID} When I run `wp term get post_tag {TERM_ID} --field=slug --format=json` - Then STDOUT should contain: + Then STDOUT should be: """ "test-delete" """ diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 90adb0933f..8a52bfc92f 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -134,7 +134,17 @@ protected function success_or_failure( $r ) { * @return \WP_CLI\Formatter */ protected function get_formatter( &$assoc_args ) { - return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); + + if ( ! empty( $assoc_args['fields'] ) ) { + if ( is_string( $assoc_args['fields'] ) ) { + $fields = explode( ',', $assoc_args['fields'] ); + } else { + $fields = $assoc_args['fields']; + } + } else { + $fields = $this->obj_fields; + } + return new \WP_CLI\Formatter( $assoc_args, $fields, $this->obj_type ); } /** diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index cd9717a7de..d38db2b8fc 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -87,7 +87,7 @@ public function display_item( $item ) { $key = $this->find_item_key( $item, $this->args['field'] ); \WP_CLI::print_value( $item->$key, array( 'format' => $this->args['format'] ) ); } else { - self::show_multiple_fields( $item, $this->args['format'] ); + $this->show_multiple_fields( $item, $this->args['format'] ); } } @@ -194,12 +194,34 @@ private function find_item_key( $item, $field ) { * @param object|array Data to display * @param string Format to display the data in */ - private static function show_multiple_fields( $data, $format ) { + private function show_multiple_fields( $data, $format ) { + + $true_fields = array(); + foreach( $this->args['fields'] as $field ) { + $true_fields[] = $this->find_item_key( $data, $field ); + } + + foreach( $data as $key => $value ) { + if ( ! in_array( $key, $true_fields ) ) { + if ( is_array( $data ) ) { + unset( $data[ $key ] ); + } else if ( is_object( $data ) ) { + unset( $data->$key ); + } + } + } switch ( $format ) { case 'table': - self::assoc_array_to_table( $data ); + case 'csv': + $rows = $this->assoc_array_to_rows( $data ); + $fields = array( 'Field', 'Value' ); + if ( 'table' == $format ) { + self::show_table( $rows, $fields ); + } else if ( 'csv' == $format ) { + \WP_CLI\Utils\write_csv( STDOUT, $rows, $fields ); + } break; case 'json': @@ -236,11 +258,13 @@ private static function show_table( $items, $fields ) { * Format an associative array as a table. * * @param array $fields Fields and values to format + * @return array $rows */ - private static function assoc_array_to_table( $fields ) { + private function assoc_array_to_rows( $fields ) { $rows = array(); foreach ( $fields as $field => $value ) { + if ( ! is_string( $value ) ) { $value = json_encode( $value ); } @@ -251,7 +275,7 @@ private static function assoc_array_to_table( $fields ) { ); } - self::show_table( $rows, array( 'Field', 'Value' ) ); + return $rows; } } diff --git a/php/commands/comment.php b/php/commands/comment.php index b1ed1a6301..cdf7641d45 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -98,8 +98,11 @@ public function update( $args, $assoc_args ) { * [--field=<field>] * : Instead of returning the whole comment, returns the value of a single field. * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv. Default: table * * ## EXAMPLES * @@ -108,8 +111,14 @@ public function update( $args, $assoc_args ) { public function get( $args, $assoc_args ) { $comment_id = (int)$args[0]; $comment = get_comment( $comment_id ); - if ( empty( $comment ) ) + if ( empty( $comment ) ) { WP_CLI::error( "Invalid comment ID." ); + } + + if ( empty( $assoc_args['fields'] ) ) { + $comment_array = get_object_vars( $comment ); + $assoc_args['fields'] = array_keys( $comment_array ); + } $formatter = $this->get_formatter( $assoc_args ); $formatter->display_item( $comment ); diff --git a/php/commands/post.php b/php/commands/post.php index fdd0203f0c..69784641f6 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -145,8 +145,11 @@ protected function _edit( $content, $title ) { * [--field=<field>] * : Instead of returning the whole post, returns the value of a single field. * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv. Default: table * * ## EXAMPLES * @@ -159,6 +162,10 @@ public function get( $args, $assoc_args ) { $post_arr = get_object_vars( $post ); unset( $post_arr['filter'] ); + if ( empty( $assoc_args['fields'] ) ) { + $assoc_args['fields'] = array_keys( $post_arr ); + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_item( $post_arr ); } diff --git a/php/commands/term.php b/php/commands/term.php index d7a35e295b..8aeae04bd2 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -152,21 +152,30 @@ public function create( $args, $assoc_args ) { * [--field=<field>] * : Instead of returning the whole term, returns the value of a single field. * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv. Default: table * * ## EXAMPLES * * wp term get category 1 --format=json */ public function get( $args, $assoc_args ) { - $formatter = $this->get_formatter( $assoc_args ); list( $taxonomy, $term_id ) = $args; $term = get_term_by( 'id', $term_id, $taxonomy ); - if ( ! $term ) + if ( ! $term ) { WP_CLI::error( "Term doesn't exist." ); + } + if ( empty( $assoc_args['fields'] ) ) { + $term_array = get_object_vars( $term ); + $assoc_args['fields'] = array_keys( $term_array ); + } + + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_item( $term ); } diff --git a/php/commands/user.php b/php/commands/user.php index f41ea4b839..816ff3c978 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -118,7 +118,7 @@ public function list_( $args, $assoc_args ) { * : Get a specific subset of the user's fields. * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv. Default: table * * ## EXAMPLES * From 671c6e0869d751189be89eec4254d32a3fdbbd81 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 10:29:45 -0700 Subject: [PATCH 3229/4858] Safely handle supplied iterators --- php/WP_CLI/Formatter.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index ac1bc24d28..6e58e297c7 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -74,7 +74,7 @@ public function display_items( $items ) { } if ( in_array( $this->args['format'], array( 'table', 'csv' ) ) ) { - $items = array_map( function( $item ){ + $callback = function( $item ){ foreach( (array)$item as $key => $value ) { if ( is_array( $value ) || is_object( $value ) ) { if ( is_object( $item ) ) { @@ -85,7 +85,12 @@ public function display_items( $items ) { } } return $item; - }, $items ); + }; + if ( is_object( $items ) && is_a( $items, 'Iterator' ) ) { + $items = \WP_CLI\Utils\iterator_map( $items, $callback ); + } else { + $items = array_map( $callback, $items ); + } } $this->format( $items ); From d7ae0c41ae9b1fcd3f9f577222e361d548f61d6c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 10:51:49 -0700 Subject: [PATCH 3230/4858] Update post_content from a file or `STDIN` --- features/post.feature | 51 +++++++++++++++++++++++++++++++++++++++++-- php/commands/post.php | 47 ++++++++++++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/features/post.feature b/features/post.feature index 1ff2128fed..aa0247284c 100644 --- a/features/post.feature +++ b/features/post.feature @@ -35,13 +35,13 @@ Feature: Manage WordPress posts alert('This should not be stripped.'); </script> """ - And a command.sh file: + And a create-post.sh file: """ cat content.html | wp post create --post_title='Test post' --post_excerpt="A multiline excerpt" --porcelain - """ - When I run `bash command.sh` + When I run `bash create-post.sh` Then STDOUT should be a number And save STDOUT as {POST_ID} @@ -97,6 +97,53 @@ Feature: Manage WordPress posts http://example.com/?p=3 """ + Scenario: Update a post from file or STDIN + Given a content.html file: + """ + Oh glorious CLI + """ + And a content-2.html file: + """ + Let it be the weekend + """ + + When I run `wp post create --post_title="Testing update via STDIN" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID} + + When I run `cat content.html | wp post update {POST_ID} -` + Then STDOUT should contain: + """ + Success: Updated post {POST_ID} + """ + + When I run `wp post get --field=post_content {POST_ID}` + Then STDOUT should be: + """ + Oh glorious CLI + """ + + When I run `wp post create --post_title="Testing update via STDIN. Again!" --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_TWO} + + When I run `wp post update {POST_ID} {POST_ID_TWO} content-2.html` + Then STDOUT should contain: + """ + Success: Updated post {POST_ID_TWO} + """ + + When I run `wp post get --field=post_content {POST_ID_TWO}` + Then STDOUT should be: + """ + Let it be the weekend + """ + + When I try `wp post update {POST_ID} invalid-file.html` + Then STDERR should be: + """ + Error: Unable to read content from invalid-file.html. + """ Scenario: Creating/listing posts When I run `wp post create --post_title='Publish post' --post_content='Publish post content' --post_status='publish' --porcelain` diff --git a/php/commands/post.php b/php/commands/post.php index fdd0203f0c..3e2d028a9a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -52,16 +52,7 @@ public function __construct() { */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { - if ( $args[0] !== '-' ) { - $readfile = $args[0]; - if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) { - \WP_CLI::error( "Unable to read content from $readfile." ); - } - } else { - $readfile = 'php://stdin'; - } - - $assoc_args['post_content'] = file_get_contents( $readfile ); + $assoc_args['post_content'] = $this->read_from_file_or_stdin( $args[0] ); } if ( isset( $assoc_args['edit'] ) ) { @@ -91,6 +82,13 @@ public function create( $args, $assoc_args ) { * <id>... * : One or more IDs of posts to update. * + * [<file>] + * : Read post content from <file>. If this value is present, the + * `--post_content` argument will be ignored. + * + * Passing `-` as the filename will cause post content to + * be read from STDIN. + * * --<field>=<value> * : One or more fields to update. See wp_update_post(). * @@ -99,6 +97,17 @@ public function create( $args, $assoc_args ) { * wp post update 123 --post_name=something --post_status=draft */ public function update( $args, $assoc_args ) { + + foreach( $args as $key => $arg ) { + if ( is_numeric( $arg ) ) { + continue; + } + + $assoc_args['post_content'] = $this->read_from_file_or_stdin( $arg ); + unset( $args[ $key ] ); + break; + } + parent::_update( $args, $assoc_args, function ( $params ) { return wp_update_post( $params, true ); } ); @@ -428,6 +437,24 @@ private function maybe_reset_depth() { // 10% chance of reseting to root depth return ( mt_rand(1, 10) == 7 ); } + + /** + * Read post content from file or STDIN + * + * @param string $arg Supplied argument + * @return string + */ + private function read_from_file_or_stdin( $arg ) { + if ( $arg !== '-' ) { + $readfile = $arg; + if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) { + \WP_CLI::error( "Unable to read content from $readfile." ); + } + } else { + $readfile = 'php://stdin'; + } + return file_get_contents( $readfile ); + } } /** From 445266dc04b1cb25b1ab49a93fee0fcd5cf7dee3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 11:06:46 -0700 Subject: [PATCH 3231/4858] Use https URLs --- features/upgradables.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 2bc9c2e06a..027668c83b 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -176,5 +176,5 @@ Feature: Manage WordPress themes and plugins Examples: | type | type_name | item | item_title | version | zip_file | file_to_check | - | theme | Theme | p2 | P2 | 1.0.1 | http://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css | - | plugin | Plugin | category-checklist-tree | Category Checklist Tree | 1.2 | http://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | + | theme | Theme | p2 | P2 | 1.0.1 | https://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css | + | plugin | Plugin | category-checklist-tree | Category Checklist Tree | 1.2 | https://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | From 0a1e8b39282c9b04c62195f5aa91144e992d6bbb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 11:19:35 -0700 Subject: [PATCH 3232/4858] `wp theme get` and `wp plugin get` should also benefit from 0b729355e905cb561d2dd0d5ea80987f6b384142 --- php/commands/plugin.php | 10 +++++++++- php/commands/theme.php | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 118d976e50..7b3fee466c 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -395,8 +395,11 @@ function install( $args, $assoc_args ) { * [--field=<field>] * : Instead of returning the whole plugin, returns the value of a single field. * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * * [--format=<format>] - * : Output list as table or JSON. Defaults to table. + * : Output list as table, json, CSV. Defaults to table. * * ## EXAMPLES * @@ -417,6 +420,11 @@ public function get( $args, $assoc_args ) { 'status' => $this->get_status( $file ), ); + if ( empty( $assoc_args['fields'] ) ) { + $plugin_array = get_object_vars( $plugin_obj ); + $assoc_args['fields'] = array_keys( $plugin_array ); + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_item( $plugin_obj ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index 94b73e54ba..aaef43c5db 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -397,8 +397,11 @@ function install( $args, $assoc_args ) { * [--field=<field>] * : Instead of returning the whole theme, returns the value of a single field. * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv. Default: table * * ## EXAMPLES * @@ -417,6 +420,10 @@ public function get( $args, $assoc_args ) { $theme_obj->description = wordwrap( $theme_obj->description ); + if ( empty( $assoc_args['fields'] ) ) { + $assoc_args['fields'] = $theme_vars; + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_item( $theme_obj ); } From d8488b4d3e271d6fef2dbaf524cd3200c79d0124 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 13:19:54 -0700 Subject: [PATCH 3233/4858] Test that should fail for #1437 --- features/user.feature | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/user.feature b/features/user.feature index ddbea8ab76..336d1cae41 100644 --- a/features/user.feature +++ b/features/user.feature @@ -23,6 +23,11 @@ Feature: Manage WordPress users test """ + When I run `wp user list --fields=user_login,roles` + Then STDOUT should be a table containing rows: + | user_login | roles | + | testuser2 | author | + When I run `wp user meta get {USER_ID} last_name` Then STDOUT should be: """ From 747a73898d9dd903d3180fa13a2208e79f0c6295 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 13:21:07 -0700 Subject: [PATCH 3234/4858] Fix mangling of `wp user list` 1. Only JSON encode fields that will be displayed on output. `WP_User`'s `data` attribute was getting JSON-encoded, which meant the magic getter no longer worked. 2. Using `isset()` for object properties, instead of `property_exists()`, means we can check if magic properties are available. --- php/WP_CLI/Formatter.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 23bd528ced..cb7cfcd521 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -74,13 +74,16 @@ public function display_items( $items ) { } if ( in_array( $this->args['format'], array( 'table', 'csv' ) ) ) { - $callback = function( $item ){ - foreach( (array)$item as $key => $value ) { + $fields = $this->args['fields']; + $callback = function( $item ) use ( $fields ) { + foreach( $fields as $field ) { + $true_field = $this->find_item_key( $item, $field ); + $value = is_object( $item ) ? $item->$true_field : $item[ $true_field ]; if ( is_array( $value ) || is_object( $value ) ) { if ( is_object( $item ) ) { - $item->$key = json_encode( $value ); + $item->$true_field = json_encode( $value ); } else if ( is_array( $item ) ) { - $item[ $key ] = json_encode( $value ); + $item[ $true_field ] = json_encode( $value ); } } } @@ -200,7 +203,7 @@ private function show_single_field( $items, $field ) { */ private function find_item_key( $item, $field ) { foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { - if ( ( is_object( $item ) && property_exists( $item, $maybe_key ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { + if ( ( is_object( $item ) && isset( $item->$maybe_key ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { $key = $maybe_key; break; } From 28dab1b46c480fccc0d852271eb0799aff2f5be7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 13:33:37 -0700 Subject: [PATCH 3235/4858] Increase timeout when getting download offer Helpful for low-bandwidth airplane connections --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index aa3139a00b..e2625d154a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -223,7 +223,7 @@ private static function _rmdir( $dir ) { private static function _read( $url ) { $headers = array('Accept' => 'application/json'); - return Utils\http_request( 'GET', $url, null, $headers )->body; + return Utils\http_request( 'GET', $url, null, $headers, array( 'timeout' => 30 ) )->body; } private function get_download_offer( $locale ) { From 12e0381053d765ac96487c09764c1e13852125e7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 14:26:59 -0700 Subject: [PATCH 3236/4858] Pre 5.5 backwards compat --- php/WP_CLI/Formatter.php | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index cb7cfcd521..5da9926b0a 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -74,25 +74,10 @@ public function display_items( $items ) { } if ( in_array( $this->args['format'], array( 'table', 'csv' ) ) ) { - $fields = $this->args['fields']; - $callback = function( $item ) use ( $fields ) { - foreach( $fields as $field ) { - $true_field = $this->find_item_key( $item, $field ); - $value = is_object( $item ) ? $item->$true_field : $item[ $true_field ]; - if ( is_array( $value ) || is_object( $value ) ) { - if ( is_object( $item ) ) { - $item->$true_field = json_encode( $value ); - } else if ( is_array( $item ) ) { - $item[ $true_field ] = json_encode( $value ); - } - } - } - return $item; - }; if ( is_object( $items ) && is_a( $items, 'Iterator' ) ) { - $items = \WP_CLI\Utils\iterator_map( $items, $callback ); + $items = \WP_CLI\Utils\iterator_map( $items, array( $this, 'transform_item_values_to_json' ) ); } else { - $items = array_map( $callback, $items ); + $items = array_map( array( $this, 'transform_item_values_to_json' ), $items ); } } @@ -306,4 +291,25 @@ private function assoc_array_to_rows( $fields ) { return $rows; } + /** + * Transforms objects and arrays to JSON as necessary + * + * @param mixed $item + * @return mixed + */ + public function transform_item_values_to_json( $item ) { + foreach( $this->args['fields'] as $field ) { + $true_field = $this->find_item_key( $item, $field ); + $value = is_object( $item ) ? $item->$true_field : $item[ $true_field ]; + if ( is_array( $value ) || is_object( $value ) ) { + if ( is_object( $item ) ) { + $item->$true_field = json_encode( $value ); + } else if ( is_array( $item ) ) { + $item[ $true_field ] = json_encode( $value ); + } + } + } + return $item; + } + } From a66640a4abf1fa5e43368b71a804ee50200433f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 15:13:16 -0700 Subject: [PATCH 3237/4858] Ensure mu-plugins conform to our established spec for plugins Fixes this error: https://travis-ci.org/wp-cli/wp-cli/jobs/37127895 --- php/commands/plugin.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 7b3fee466c..f9e675b457 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -118,9 +118,15 @@ protected function get_all_items() { foreach ( get_mu_plugins() as $file => $mu_plugin ) { $items[ $file ] = array( - 'name' => Utils\get_plugin_name( $file ), - 'status' => 'must-use', - 'update' => false + 'name' => Utils\get_plugin_name( $file ), + 'status' => 'must-use', + 'update' => false, + 'update_version' => NULL, + 'update_package' => NULL, + 'version' => '', + 'update_id' => '', + 'title' => '', + 'description' => '', ); } From ebf3a53abb83f77c49816d7bf18b4051e2099eb3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 15:29:50 -0700 Subject: [PATCH 3238/4858] PHP 5.3 compat --- php/WP_CLI/Iterators/Transform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Iterators/Transform.php b/php/WP_CLI/Iterators/Transform.php index 823e620b10..0c8e05590d 100644 --- a/php/WP_CLI/Iterators/Transform.php +++ b/php/WP_CLI/Iterators/Transform.php @@ -17,7 +17,7 @@ public function current() { $value = parent::current(); foreach ( $this->transformers as $fn ) { - $value = $fn( $value ); + $value = call_user_func( $fn, $value ); } return $value; From dbb357223030c2c0ba575aa22b3a82a283932d3e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 5 Oct 2014 15:56:53 -0700 Subject: [PATCH 3239/4858] `wp user import-csv` should support CSVs generated from `wp user list` Key change is acknowledging a "roles" column, which can include one or more roles. --- features/user.feature | 37 +++++++++++++++++++++++++++++++++++++ php/commands/user.php | 23 ++++++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/features/user.feature b/features/user.feature index 336d1cae41..5b6fc0175c 100644 --- a/features/user.feature +++ b/features/user.feature @@ -200,6 +200,43 @@ Feature: Manage WordPress users } """ + @daniel + Scenario: Import users from a CSV file generated by `wp user list` + Given a WP install + + When I run `wp user delete 1 --yes` + And I run `wp user create bobjones bobjones@domain.com --display_name="Bob Jones" --role=contributor` + And I run `wp user create billjones billjones@domain.com --display_name="Bill Jones" --role=administrator` + And I run `wp user add-role billjones author` + Then STDOUT should not be empty + + When I run `wp user list --field=user_login | wc -l` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp user list --format=csv > users.csv` + Then the users.csv file should exist + + When I run `wp user delete $(wp user list --format=ids) --yes` + Then STDOUT should not be empty + + When I run `wp user list --field=user_login | wc -l` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp user import-csv users.csv` + Then STDOUT should not be empty + + When I run `wp user list --fields=display_name,roles` + Then STDOUT should be a table containing rows: + | display_name | roles | + | Bob Jones | contributor | + | Bill Jones | administrator,author | + Scenario: Managing user roles Given a WP install diff --git a/php/commands/user.php b/php/commands/user.php index 816ff3c978..50c28b7568 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -622,7 +622,23 @@ public function import_csv( $args, $assoc_args ) { ); $new_user = array_merge( $defaults, $new_user ); - if ( 'none' === $new_user['role'] ) { + $secondary_roles = array(); + if ( ! empty( $new_user['roles'] ) ) { + $roles = array_map( 'trim', explode( ',', $new_user['roles'] ) ); + $invalid_role = false; + foreach( $roles as $role ) { + if ( is_null( get_role( $role ) ) ) { + WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); + $invalid_role = true; + break; + } + } + if ( $invalid_role ) { + continue; + } + $new_user['role'] = array_shift( $roles ); + $secondary_roles = $roles; + } else if ( 'none' === $new_user['role'] ) { $new_user['role'] = false; } elseif ( is_null( get_role( $new_user['role'] ) ) ) { WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); @@ -669,6 +685,11 @@ public function import_csv( $args, $assoc_args ) { delete_user_option( $user_id, 'user_level' ); } + $user = get_user_by( 'id', $user_id ); + foreach( $secondary_roles as $secondary_role ) { + $user->add_role( $secondary_role ); + } + if ( !empty( $existing_user ) ) { WP_CLI::success( $new_user['user_login'] . " updated" ); } else { From 1ce63ad1cca5e306997d320c7d42d29d44a0f5ab Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 6 Oct 2014 07:57:18 -0400 Subject: [PATCH 3240/4858] Remove temp tag --- features/user.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/user.feature b/features/user.feature index 5b6fc0175c..44bc1a2eb3 100644 --- a/features/user.feature +++ b/features/user.feature @@ -200,7 +200,6 @@ Feature: Manage WordPress users } """ - @daniel Scenario: Import users from a CSV file generated by `wp user list` Given a WP install From 1451c685b7e08742a0d18bd382ccb8eb0d244bc2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 6 Oct 2014 07:57:28 -0400 Subject: [PATCH 3241/4858] Fix indentation --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 50c28b7568..27ab5385ca 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -627,7 +627,7 @@ public function import_csv( $args, $assoc_args ) { $roles = array_map( 'trim', explode( ',', $new_user['roles'] ) ); $invalid_role = false; foreach( $roles as $role ) { - if ( is_null( get_role( $role ) ) ) { + if ( is_null( get_role( $role ) ) ) { WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); $invalid_role = true; break; From c73e5af4942899de8b84042e738a3d33ccdd55d2 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 6 Oct 2014 21:59:20 -0300 Subject: [PATCH 3242/4858] Revert "improve test for `wp core language --<field>=<value>`" This reverts commit 6952bc4b859655afb46cd679ab60998180224aed. --- features/core.feature | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/features/core.feature b/features/core.feature index 2ac94a4d73..c9c55b24a1 100644 --- a/features/core.feature +++ b/features/core.feature @@ -473,9 +473,7 @@ Feature: Manage WordPress installation Then STDOUT should be a table containing rows: | language | english_name | status | | en_US | English (United States) | active | - - When I run `wp core language list --fields=language,english_name,status --status=active | wc -l` - Then STDOUT should be: + And STDOUT should not contain: """ - 2 + English (UK) """ From 950077f31ba0299f938531a65c93a4038c7b2b7b Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 6 Oct 2014 22:00:07 -0300 Subject: [PATCH 3243/4858] Revert "remove empty line added by mistake" This reverts commit 1a571218f1a2a195b2311f5ff46d59176f9f74d7. --- php/WP_CLI/CommandWithTranslation.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index a93361a52d..d2d9ad63f2 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -59,6 +59,7 @@ public function list_( $args, $assoc_args ) { if ( $current_locale == $translation['language'] ) { $translation['status'] = 'active'; } + return $translation; }, $translations ); From 7f17a11bb3d3f9c24ca5bd73ad19b351870e8fcd Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 6 Oct 2014 22:00:21 -0300 Subject: [PATCH 3244/4858] Revert "Add functionality to filter list of languages" This reverts commit 489458a0f00a9ed2b5e53e92cf9c4558c7614b8f. --- features/core.feature | 9 --------- php/WP_CLI/CommandWithTranslation.php | 13 +------------ 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/features/core.feature b/features/core.feature index c9c55b24a1..b2f1c68aa8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -468,12 +468,3 @@ Feature: Manage WordPress installation """ Error: Language not installed. """ - - When I run `wp core language list --fields=language,english_name,status --status=active` - Then STDOUT should be a table containing rows: - | language | english_name | status | - | en_US | English (United States) | active | - And STDOUT should not contain: - """ - English (UK) - """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index d2d9ad63f2..5caa95fdd3 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -22,9 +22,6 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { /** * List all languages available. * - * [--<field>=<value>] - * : Filter results based on the value of a field. - * * [--fields=<fields>] * : Limit the output to specific fields. * @@ -59,20 +56,12 @@ public function list_( $args, $assoc_args ) { if ( $current_locale == $translation['language'] ) { $translation['status'] = 'active'; } - return $translation; }, $translations ); - foreach ( $translations as $key => $translation ) { - foreach ( $this->obj_fields as $field ) { - if ( isset( $assoc_args[$field] ) && $assoc_args[$field] != $translation[$field] ) { - unset( $translations[$key] ); - } - } - } - $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $translations ); + } /** From 4e882a9c3351a961a356dc1570f24ae9de8b386f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 7 Oct 2014 08:59:32 -0400 Subject: [PATCH 3245/4858] Prevent error caused by #1417 by ensuring item confirms to expected --- php/WP_CLI/CommandWithTranslation.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 1e93b99ffc..c7e544f5ec 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -178,6 +178,7 @@ protected function get_all_languages() { 'language' => 'en_US', 'english_name' => 'English (United States)', 'native_name' => 'English (United States)', + 'updated' => '', ); array_push( $translations, $en_us ); From ea168a6402c87b58b4264c2decdcb2f909a3a055 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 9 Oct 2014 13:29:25 -0300 Subject: [PATCH 3246/4858] fix `wp comment approve` and `wp comment unapprove` commands --- features/comment.feature | 18 ++++++++++++++++++ php/commands/comment.php | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/features/comment.feature b/features/comment.feature index 94aeb9d9b1..b1c930a1ed 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -95,3 +95,21 @@ Feature: Manage WordPress comments post-trashed: 0 total_comments: 1 """ + + Scenario: Approving/unapproving comments + Given I run `wp comment create --comment_post_ID=1 --comment_approved=0 --porcelain` + And save STDOUT as {COMMENT_ID} + + When I run `wp comment approve {COMMENT_ID}` + Then STDOUT should contain: + """ + Approved comment {COMMENT_ID} + """ + + When I run `wp comment unapprove {COMMENT_ID}` + Then STDOUT should contain: + """ + Unapproved comment {COMMENT_ID} + """ + + diff --git a/php/commands/comment.php b/php/commands/comment.php index cdf7641d45..fa19bad29e 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -234,7 +234,7 @@ private function call( $args, $status, $success, $failure ) { private function set_status( $args, $status, $success ) { $comment = $this->fetcher->get_check( $args[0] ); - $r = wp_set_comment_status( $comment->comment_ID, 'approve', true ); + $r = wp_set_comment_status( $comment->comment_ID, $status, true ); if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); From e19f55dd6d75b832ded8c5e3738448833fd8a13f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 9 Oct 2014 16:02:51 -0300 Subject: [PATCH 3247/4858] make sure comment approve and unapprove are changing comment status --- features/comment.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index b1c930a1ed..dd8ee017ad 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -106,10 +106,21 @@ Feature: Manage WordPress comments Approved comment {COMMENT_ID} """ + When I run `wp comment get --field=comment_approved {COMMENT_ID}` + Then STDOUT should be: + """ + 1 + """ + When I run `wp comment unapprove {COMMENT_ID}` Then STDOUT should contain: """ Unapproved comment {COMMENT_ID} """ + When I run `wp comment get --field=comment_approved {COMMENT_ID}` + Then STDOUT should be: + """ + 0 + """ From b3d6befa26b8c4fbfe645caace155523cea7817a Mon Sep 17 00:00:00 2001 From: Borek Bernard <borekb@gmail.com> Date: Thu, 23 Oct 2014 00:44:46 +0200 Subject: [PATCH 3248/4858] Fixed mkdir command in `wp core download` on Windows --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index e2625d154a..ede9536453 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -125,7 +125,8 @@ public function download( $args, $assoc_args ) { if ( !is_dir( ABSPATH ) ) { WP_CLI::log( sprintf( 'Creating directory %s', ABSPATH ) ); - WP_CLI::launch( Utils\esc_cmd( 'mkdir -p %s', ABSPATH ) ); + $mkdir = \WP_CLI\Utils\is_windows() ? 'mkdir %s' : 'mkdir -p %s'; + WP_CLI::launch( Utils\esc_cmd( $mkdir, ABSPATH ) ); } $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; From 06e5e84f0f5ba5122b88f53393ff9b6b8b75f630 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Oct 2014 06:51:07 -0700 Subject: [PATCH 3249/4858] Don't iterate when there aren't image sizes --- php/commands/media.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/media.php b/php/commands/media.php index 0db3794680..7d8c774e2d 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -237,6 +237,10 @@ private function remove_old_images( $att_id ) { $dir_path = $wud['basedir'] . '/' . dirname( $metadata['file'] ) . '/'; $original_path = $dir_path . basename( $metadata['file'] ); + if ( empty( $metadata['sizes'] ) ) { + return; + } + foreach ( $metadata['sizes'] as $size => $size_info ) { $intermediate_path = $dir_path . $size_info['file']; From 569a08eed0d11071f31b06a360eee8fcf0d449cf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 26 Oct 2014 11:48:05 -0700 Subject: [PATCH 3250/4858] Only set up testing suite if it doesn't exist --- templates/install-wp-tests.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 1e39064a59..f4ece0efc4 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -39,8 +39,13 @@ install_test_suite() { local ioption='-i' fi - # set up testing suite - mkdir -p $WP_TESTS_DIR + # set up testing suite if it doesn't yet exist + if [ ! "$(ls -A $WP_TESTS_DIR)" ]; then + # set up testing suite + mkdir -p $WP_TESTS_DIR + svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR + fi + cd $WP_TESTS_DIR svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ From 2cd2bee4610fbeba65036e7e46ed29096cc48325 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 26 Oct 2014 11:48:22 -0700 Subject: [PATCH 3251/4858] Only configure tests config if it doesn't exist --- templates/install-wp-tests.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index f4ece0efc4..336c22bbce 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -47,14 +47,15 @@ install_test_suite() { fi cd $WP_TESTS_DIR - svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ - - wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php + + if [ ! -f wp-tests-config.php ]; then + wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php + fi } install_db() { From 3d76824570da4a6e08ae67109afd7226b74407dd Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Sun, 26 Oct 2014 16:48:12 -0700 Subject: [PATCH 3252/4858] remove unused variables --- php/commands/core.php | 5 +++-- php/commands/cron.php | 4 ++-- php/commands/media.php | 2 +- php/commands/term.php | 7 ------- php/commands/user.php | 1 - 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index e2625d154a..c88ec74b01 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -539,8 +539,9 @@ private function _install( $assoc_args ) { // Support prompting for the `--url=<url>`, // which is normally a runtime argument - if ( isset( $assoc_args['url'] ) ) - $url_parts = WP_CLI::set_url( $assoc_args['url'] ); + if ( isset( $assoc_args['url'] ) ) { + WP_CLI::set_url( $assoc_args['url'] ); + } $public = true; diff --git a/php/commands/cron.php b/php/commands/cron.php index c340792289..32d1959503 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -151,7 +151,7 @@ public function run( $args, $assoc_args ) { } $executed = 0; - foreach ( $events as $id => $event ) { + foreach ( $events as $event ) { if ( $event->hook == $hook ) { $result = self::run_event( $event ); if ( $result ) { @@ -214,7 +214,7 @@ public function delete( $args, $assoc_args ) { } $deleted = 0; - foreach ( $events as $id => $event ) { + foreach ( $events as $event ) { if ( $event->hook == $hook ) { $result = self::delete_event( $event ); if ( $result ) { diff --git a/php/commands/media.php b/php/commands/media.php index 0db3794680..df54353145 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -237,7 +237,7 @@ private function remove_old_images( $att_id ) { $dir_path = $wud['basedir'] . '/' . dirname( $metadata['file'] ) . '/'; $original_path = $dir_path . basename( $metadata['file'] ); - foreach ( $metadata['sizes'] as $size => $size_info ) { + foreach ( $metadata['sizes'] as $size_info ) { $intermediate_path = $dir_path . $size_info['file']; if ( $intermediate_path == $original_path ) diff --git a/php/commands/term.php b/php/commands/term.php index 8aeae04bd2..e7befa0c2d 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -282,8 +282,6 @@ public function delete( $args ) { * wp term generate --count=10 */ public function generate( $args, $assoc_args ) { - global $wpdb; - list ( $taxonomy ) = $args; $defaults = array( @@ -304,11 +302,6 @@ public function generate( $args, $assoc_args ) { $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; diff --git a/php/commands/user.php b/php/commands/user.php index 27ab5385ca..b9575d3a48 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -559,7 +559,6 @@ public function list_caps( $args, $assoc_args ) { $user->get_role_caps(); $user_caps_list = $user->allcaps; - $cap_table_titles = array( 'capability', 'status' ); foreach ( $user_caps_list as $cap => $active ) { if ( $active ) { From 651d987ce2c6de2277bd28db29af0c2b1904ea4d Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Sun, 26 Oct 2014 17:09:05 -0700 Subject: [PATCH 3253/4858] add tests to `wp plugin activate --all` and `wp plugin deactivate --all` --- features/plugin.feature | 33 +++++++++++++++++++++++++++++++++ php/commands/plugin.php | 8 +++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 41823ad307..7f98233bbf 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -242,3 +242,36 @@ Feature: Manage WordPress plugins """ Installing Debug Bar List Script & Style Dependencies """ + + Scenario: Enable and disable all plugins + Given a WP install + + When I run `wp plugin activate --all` + Then STDOUT should be: + """ + Success: Plugin 'akismet' activated. + Success: Plugin 'hello' activated. + """ + + When I run `wp plugin list --field=status` + Then STDOUT should be: + """ + active + active + must-use + """ + + When I run `wp plugin deactivate --all` + Then STDOUT should be: + """ + Success: Plugin 'akismet' deactivated. + Success: Plugin 'hello' deactivated. + """ + + When I run `wp plugin list --field=status` + Then STDOUT should be: + """ + inactive + inactive + must-use + """ diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 13da512915..4977dffe83 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -579,13 +579,15 @@ private function active_output( $name, $file, $network_wide, $action ) { private function update_plugins_status( $action, $network_wide ) { $status = ( $action == "activate" ) ? "active" : "inactive"; foreach ( get_plugins() as $file => $details ) { - if ( $this->get_status( $file ) == $status ) + if ( $this->get_status( $file ) == $status ) { continue; + } - if ( $action == "activate" ) + if ( $action == "activate" ) { activate_plugins( $file, false, $network_wide ); - else + } else { deactivate_plugins( $file, false, $network_wide ); + } $name = Utils\get_plugin_name( $file ); $this->active_output( $name, $file, $network_wide, $action ); From c252c27c96aa720689721964ae38357d73aa282a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Fri, 31 Oct 2014 22:13:52 +0100 Subject: [PATCH 3254/4858] Added CHECK TABLE example --- php/commands/db.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/db.php b/php/commands/db.php index edaa20aa58..dae4537b29 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -95,6 +95,7 @@ function cli() { * * # execute a query stored in a file * wp db query < debug.sql + * wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" */ function query( $args ) { $assoc_args = array( From dcf415cbf71272c5782afb3840acca04a1b72b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Fri, 31 Oct 2014 22:16:06 +0100 Subject: [PATCH 3255/4858] Added comment --- php/commands/db.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/db.php b/php/commands/db.php index dae4537b29..491755dd3e 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -95,6 +95,7 @@ function cli() { * * # execute a query stored in a file * wp db query < debug.sql + * # check all tables in the database * wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" */ function query( $args ) { From 2e1770073d7e2358b475db27752f9b41868f0812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Fri, 31 Oct 2014 22:17:06 +0100 Subject: [PATCH 3256/4858] And an empty line too --- php/commands/db.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/db.php b/php/commands/db.php index 491755dd3e..bfd7e021fd 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -95,6 +95,7 @@ function cli() { * * # execute a query stored in a file * wp db query < debug.sql + * * # check all tables in the database * wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" */ From 04074c5696f96113deb496f72ee4604e55d1cee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 1 Nov 2014 14:01:36 +0100 Subject: [PATCH 3257/4858] fixed search+tests --- features/option.feature | 23 +++++++++++++++++ php/commands/option.php | 56 +++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/features/option.feature b/features/option.feature index ee9a7a509d..8db89c3af7 100644 --- a/features/option.feature +++ b/features/option.feature @@ -13,6 +13,29 @@ Feature: Manage WordPress options bar """ + When I run `wp option list --search='str_o*'` + Then STDOUT should be: + """ + option_name + str_opt + """ + + When I run `wp option list --search='str_o*' --total` + Then STDOUT should be: + """ + size + 3 + """ + + When I run `wp option add auto_opt --autoload=no 'bar'` + Then STDOUT should not be empty + + When I run `wp option list --search='auto_opt' --autoload` + Then STDOUT should not be empty + + When I run `wp option list | grep -q "str_opt"` + Then the return code should be 0 + When I run `wp option delete str_opt` Then STDOUT should not be empty diff --git a/php/commands/option.php b/php/commands/option.php index 087d1d1e02..137ffab190 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -80,21 +80,29 @@ public function add( $args, $assoc_args ) { /** * List options. * - * [--search=<sql-like-pattern>] - * : SQL pattern matching enables you to use "_" to match any single character and "%" to match an arbitrary number of characters. - * - * [--fields=<fields>] - * : Limit the output to specific object fields. + * [--search=<pattern>] + * : Use wildcards ( * and ? ) to match option name. * * [--autoload] * : Match only autoload options. * * [--total] - * : Display only the total size of matching options. + * : Display only the total size of matching options in bytes. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. * * [--format=<format>] * : The serialization format for the value. Default is table. * + * ## EXAMPLES + * + * # Get the total size of all autoload options + * wp option list --total --autoload + * + * # List all options begining with "i2f_" + * wp option list --search "i2f_*" + * * ## AVAILABLE FIELDS * * This field will be displayed by default for each matching option: @@ -103,7 +111,7 @@ public function add( $args, $assoc_args ) { * * These fields are optionally available: * - * * option_name + * * option_value * * autoload * * size * @@ -113,24 +121,25 @@ public function add( $args, $assoc_args ) { public function list_( $args, $assoc_args ) { global $wpdb; - $size_query = "LENGTH(option_value) AS size"; + $pattern = '%'; + $fields = array( 'option_name' ); + $size_query = ",LENGTH(option_value) AS size"; $autoload_query = ''; if ( isset( $assoc_args['search'] ) ) { - $pattern = $assoc_args['search']; - } else { - $pattern = '%'; + $pattern = self::esc_like( esc_sql( $assoc_args['search'] ) ); + // substitute wildcards + $pattern = str_replace( '*', '%', $pattern ); + $pattern = str_replace( '?', '_', $pattern ); } if ( isset( $assoc_args['fields'] ) ) { $fields = explode( ',', $assoc_args['fields'] ); - } else { - $fields = array( 'option_name' ); } if ( isset( $assoc_args['total'] ) ) { $fields = array( 'size' ); - $size_query = "SUM(LENGTH(option_value)) AS size"; + $size_query = ",SUM(LENGTH(option_value)) AS `size`"; } if ( isset( $assoc_args['autoload'] ) ) { @@ -139,8 +148,8 @@ public function list_( $args, $assoc_args ) { $results = $wpdb->get_results( $wpdb->prepare( - "SELECT option_name,option_value,autoload," . $size_query - . " FROM $wpdb->options WHERE option_name LIKE %s" . $autoload_query, + "SELECT `option_name`,`option_value`,`autoload`" . $size_query + . " FROM `$wpdb->options` WHERE `option_name` LIKE %s" . $autoload_query, $pattern ) ); @@ -206,6 +215,21 @@ public function delete( $args ) { WP_CLI::success( "Deleted '$key' option." ); } } + + private static function esc_like( $old ) { + global $wpdb; + + // Remove notices in 4.0 and support backwards compatibility + if( method_exists( $wpdb, 'esc_like' ) ) { + // 4.0 + $old = $wpdb->esc_like( $old ); + } else { + // 3.9 or less + $old = like_escape( esc_sql( $old ) ); + } + + return $old; + } } WP_CLI::add_command( 'option', 'Option_Command' ); From 01dd52e5f7822245a5fa06e27b8ff5b99248f4ed Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 1 Nov 2014 10:54:35 -0700 Subject: [PATCH 3258/4858] If core directory is already around, skip --- templates/install-wp-tests.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 336c22bbce..28c9320647 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -17,6 +17,11 @@ WP_CORE_DIR=/tmp/wordpress/ set -ex install_wp() { + + if [ -d $WP_CORE_DIR ]; then + return; + fi + mkdir -p $WP_CORE_DIR if [ $WP_VERSION == 'latest' ]; then From f9d597726ebcd5c5b15fc89ec6f30852b374c84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 1 Nov 2014 22:09:00 +0100 Subject: [PATCH 3259/4858] make total a format, and autoload=off --- features/option.feature | 8 +++++- php/commands/option.php | 54 +++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/features/option.feature b/features/option.feature index 8db89c3af7..4dd0616901 100644 --- a/features/option.feature +++ b/features/option.feature @@ -13,6 +13,12 @@ Feature: Manage WordPress options bar """ + When I run `wp option list + Then STDOUT should not be empty + + When I run `wp option list --autoload=on + Then STDOUT should not be empty + When I run `wp option list --search='str_o*'` Then STDOUT should be: """ @@ -20,7 +26,7 @@ Feature: Manage WordPress options str_opt """ - When I run `wp option list --search='str_o*' --total` + When I run `wp option list --search='str_o*' --format=total_bytes` Then STDOUT should be: """ size diff --git a/php/commands/option.php b/php/commands/option.php index 137ffab190..6cccab2b98 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -83,22 +83,24 @@ public function add( $args, $assoc_args ) { * [--search=<pattern>] * : Use wildcards ( * and ? ) to match option name. * - * [--autoload] - * : Match only autoload options. - * - * [--total] - * : Display only the total size of matching options in bytes. + * [--autoload=<value>] + * : Match only autoload options when value is on, and only not-autoload option when off. * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] - * : The serialization format for the value. Default is table. + * : The serialization format for the value. + * : total_bytes displays the total size of matching options in bytes. + * : Accepted values: table, json, csv, count, total_bytes. Default: table * * ## EXAMPLES * * # Get the total size of all autoload options - * wp option list --total --autoload + * wp option list --autoload=on --format=total_bytes + * + * # Find biggest transients + * wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail * * # List all options begining with "i2f_" * wp option list --search "i2f_*" @@ -108,22 +110,22 @@ public function add( $args, $assoc_args ) { * This field will be displayed by default for each matching option: * * * option_name + * * option_value * * These fields are optionally available: * - * * option_value * * autoload - * * size + * * size_bytes * * @subcommand list - * @synopsis [--search=<sql-like-pattern>] [--total] [--autoload] [--fields=<fields>] [--format=<format>] + * @synopsis [--search=<sql-like-pattern>] [--autoload=<value>] [--fields=<fields>] [--format=<format>] */ public function list_( $args, $assoc_args ) { global $wpdb; $pattern = '%'; - $fields = array( 'option_name' ); - $size_query = ",LENGTH(option_value) AS size"; + $fields = array( 'option_name', 'option_value' ); + $size_query = ",LENGTH(option_value) AS `size_bytes`"; $autoload_query = ''; if ( isset( $assoc_args['search'] ) ) { @@ -137,13 +139,19 @@ public function list_( $args, $assoc_args ) { $fields = explode( ',', $assoc_args['fields'] ); } - if ( isset( $assoc_args['total'] ) ) { - $fields = array( 'size' ); - $size_query = ",SUM(LENGTH(option_value)) AS `size`"; + if ( isset( $assoc_args['format'] ) && 'total_bytes' === $assoc_args['format'] ) { + $fields = array( 'size_bytes' ); + $size_query = ",SUM(LENGTH(option_value)) AS `size_bytes`"; } if ( isset( $assoc_args['autoload'] ) ) { - $autoload_query = " AND autoload='yes'"; + if ( 'on' === $assoc_args['autoload'] ) { + $autoload_query = " AND autoload='yes'"; + } elseif ( 'off' === $assoc_args['autoload'] ) { + $autoload_query = " AND autoload='no'"; + } else { + WP_CLI::error( "Value of '--autoload' should be on or off." ); + } } $results = $wpdb->get_results( @@ -154,11 +162,15 @@ public function list_( $args, $assoc_args ) { ) ); - $formatter = new \WP_CLI\Formatter( - $assoc_args, - $fields - ); - $formatter->display_items( $results ); + if ( isset( $assoc_args['format'] ) && 'total_bytes' === $assoc_args['format'] ) { + WP_CLI::line( $results[0]->size_bytes ); + } else { + $formatter = new \WP_CLI\Formatter( + $assoc_args, + $fields + ); + $formatter->display_items( $results ); + } } /** From f54ef85d658e05e194fe0707bbbabc003706dc7c Mon Sep 17 00:00:00 2001 From: Brad Parbs <brad@bradparbs.com> Date: Tue, 4 Nov 2014 12:29:33 -0600 Subject: [PATCH 3260/4858] Fix running as sudo error message to be consistent in how help files show place to run command --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e7e48a97e7..6fe89d0fee 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -547,7 +547,7 @@ private function check_root() { "If you'd like to run it as the user that this site is under, you can " . "run the following to become the respective user:\n" . "\n" . - " sudo -u USER -i -- wp ...\n" . + " sudo -u USER -i -- wp <command>\n" . "\n" ); } From 2a48ea09bc5c9fe634ed899ba10b04c8f90d6633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 6 Nov 2014 01:40:47 +0100 Subject: [PATCH 3261/4858] Show mu-plugin version too --- php/commands/plugin.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 4977dffe83..ca92ccd04e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -117,13 +117,17 @@ protected function get_all_items() { $items = $this->get_item_list(); foreach ( get_mu_plugins() as $file => $mu_plugin ) { + $mu_version = ''; + if ( ! empty( $mu_plugin['Version'] ) ) + $mu_version = $mu_plugin['Version']; + $items[ $file ] = array( 'name' => Utils\get_plugin_name( $file ), 'status' => 'must-use', 'update' => false, 'update_version' => NULL, 'update_package' => NULL, - 'version' => '', + 'version' => $mu_version, 'update_id' => '', 'title' => '', 'description' => '', From 48c730d3b3a655f2d1dd37e426a28c2747b2575a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 6 Nov 2014 02:04:41 +0100 Subject: [PATCH 3262/4858] WP coding standards --- php/commands/plugin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ca92ccd04e..3f2321f614 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -118,8 +118,9 @@ protected function get_all_items() { foreach ( get_mu_plugins() as $file => $mu_plugin ) { $mu_version = ''; - if ( ! empty( $mu_plugin['Version'] ) ) + if ( ! empty( $mu_plugin['Version'] ) ) { $mu_version = $mu_plugin['Version']; + } $items[ $file ] = array( 'name' => Utils\get_plugin_name( $file ), From 679ad873f88e7b29743bf799e474c5815ef87924 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 6 Nov 2014 16:10:57 -0800 Subject: [PATCH 3263/4858] Decode quotes too --- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 3f2321f614..68ffd51770 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -277,7 +277,7 @@ protected function install_from_repo( $slug, $assoc_args ) { return new WP_Error( 'already_installed', 'Plugin already installed.' ); } - WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name ), $api->version ) ); + WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } diff --git a/php/commands/theme.php b/php/commands/theme.php index aaef43c5db..adceda527d 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -283,7 +283,7 @@ protected function install_from_repo( $slug, $assoc_args ) { return new WP_Error( 'already_installed', 'Theme already installed.' ); } - WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name ), $api->version ) ); + WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } From f73d6011d11f866c22816aee6e0ea39addd49be1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 6 Nov 2014 16:23:31 -0800 Subject: [PATCH 3264/4858] Check response code in `::_read()` If WordPress.org returns a bad response, we want to know about it --- php/commands/core.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d87aed2ea5..dfdb15e289 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -224,7 +224,12 @@ private static function _rmdir( $dir ) { private static function _read( $url ) { $headers = array('Accept' => 'application/json'); - return Utils\http_request( 'GET', $url, null, $headers, array( 'timeout' => 30 ) )->body; + $response = Utils\http_request( 'GET', $url, null, $headers, array( 'timeout' => 30 ) ); + if ( 200 === $response->status_code ) { + return $response->body; + } else { + WP_CLI::error( "Couldn't fetch response from {$url} (HTTP code {$response->status_code})" ); + } } private function get_download_offer( $locale ) { From 325dfa01a0c56509f3c402c407cb104e288a005f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 07:37:04 -0800 Subject: [PATCH 3265/4858] Test for #1485 --- features/config.feature | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/features/config.feature b/features/config.feature index ad5f2e05e5..6c755d64ea 100644 --- a/features/config.feature +++ b/features/config.feature @@ -197,4 +197,19 @@ Feature: Have a config file """ When I run `WP_CLI_CONFIG_PATH=test-dir/config.yml wp help` - Then STDERR should be empty + Then STDERR should be empty + + Scenario: Missing required files should not fatal WP-CLI + Given an empty directory + And a wp-cli.yml file: + """ + require: + - missing-file.php + """ + + When I try `wp help` + Then STDERR should contain: + """ + Error: Required file 'missing-file.php' doesn't exist + """ + From 85c5d632fa0c2d056915ac314c6d50b0ccff61b6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 07:37:25 -0800 Subject: [PATCH 3266/4858] Throw a human-friendly error if required file is missing --- php/WP_CLI/Runner.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6fe89d0fee..de8122abfc 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -568,6 +568,9 @@ public function before_wp_load() { if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { + if ( ! file_exists( $path ) ) { + WP_CLI::error( sprintf( "Required file '%s' doesn't exist", basename( $path ) ) ); + } Utils\load_file( $path ); } } From 0efd4a736bfb7a64082755218b455474c4b1c918 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 07:52:37 -0800 Subject: [PATCH 3267/4858] Update php-cli-tools to 0.10.2 Release notes https://github.com/wp-cli/php-cli-tools/releases/tag/v0.10.2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index da62d1b490..f503e39061 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.10.1", + "wp-cli/php-cli-tools": "0.10.2", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From c1b6ae001edbdfdd981a2dd4b89f529f4d180c58 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 08:25:57 -0800 Subject: [PATCH 3268/4858] Fix editing post content in an editor `\WP_CLI::launch()` now uses the `Process` class, which pipes STDOUT to return the results. Because all we care about is running the process, it's simpler to just internalize that here. --- php/utils.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index fbee550acb..963a3a4636 100644 --- a/php/utils.php +++ b/php/utils.php @@ -279,7 +279,12 @@ function launch_editor_for_input( $input, $title = 'WP-CLI' ) { $editor = 'vi'; } - \WP_CLI::launch( "$editor " . escapeshellarg( $tmpfile ) ); + $descriptorspec = array( STDIN, STDOUT, STDERR ); + $process = proc_open( "$editor " . escapeshellarg( $tmpfile ), $descriptorspec, $pipes ); + $r = proc_close( $process ); + if ( $r ) { + exit( $r ); + } $output = file_get_contents( $tmpfile ); From b10bef5f0401e53c6c1644c86bf11ad0d448b57b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 09:01:06 -0800 Subject: [PATCH 3269/4858] More tests for #1485 --- features/config.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/config.feature b/features/config.feature index 6c755d64ea..2a2b3ae84e 100644 --- a/features/config.feature +++ b/features/config.feature @@ -213,3 +213,9 @@ Feature: Have a config file Error: Required file 'missing-file.php' doesn't exist """ + When I run `wp cli info` + Then STDOUT should not be empty + + When I run `wp --info` + Then STDOUT should not be empty + From cbeb521ef46b0bae040418ef87ede32c18022a86 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 09:08:11 -0800 Subject: [PATCH 3270/4858] Run `wp cli info` early to protect from runtime If a config file includes poor declarations, we still want `wp cli info` to work. --- php/WP_CLI/Runner.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index de8122abfc..787d4dd52c 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -562,6 +562,12 @@ public function before_wp_load() { if ( empty( $this->arguments ) ) $this->arguments[] = 'help'; + // Protect 'cli info' from most of the runtime + if ( 'cli' === $this->arguments[0] && ! empty( $this->arguments[1] ) && 'info' === $this->arguments[1] ) { + $this->_run_command(); + exit; + } + // Load bundled commands early, so that they're forced to use the same // APIs as non-bundled commands. Utils\load_command( $this->arguments[0] ); From 28cf2fac657196b2e03c15880b25c3398c499902 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 09:22:27 -0800 Subject: [PATCH 3271/4858] Failing test for #1489 --- features/plugin.feature | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 7f98233bbf..814ec42b3a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -274,4 +274,14 @@ Feature: Manage WordPress plugins inactive inactive must-use - """ + """ + + Scenario: Uninstall a plugin without deleting + Given a WP install + + When I run `wp plugin install akismet --version=2.5.7 --force` + Then STDOUT should not be empty + + When I run `wp plugin uninstall akismet --no-delete` + Then STDOUT should not be empty + From 894a35ced5edabf4502f34758e5107732cd76b34 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 09:30:25 -0800 Subject: [PATCH 3272/4858] Turn `plugin uninstall --no-delete` into `plugin uninstall --skip-delete` The `--no-delete` flag has been broken since a9adf7b78bcefe3b5db03e167f53c6263dab1549 (5 releases), so I'm not concerned about a backwards compat shim. Adds more verbosity too. --- features/plugin.feature | 8 ++++++-- php/commands/plugin.php | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 814ec42b3a..0ef5a21ac5 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -282,6 +282,10 @@ Feature: Manage WordPress plugins When I run `wp plugin install akismet --version=2.5.7 --force` Then STDOUT should not be empty - When I run `wp plugin uninstall akismet --no-delete` - Then STDOUT should not be empty + When I run `wp plugin uninstall akismet --skip-delete` + Then STDOUT should contain: + """ + Success: Ran uninstall procedure for + """ + diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 68ffd51770..214c78e8d0 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -446,7 +446,7 @@ public function get( $args, $assoc_args ) { * <plugin>... * : One or more plugins to uninstall. * - * [--no-delete] + * [--skip-delete] * : If set, the plugin files will not be deleted. Only the uninstall procedure * will be run. * @@ -463,8 +463,10 @@ function uninstall( $args, $assoc_args = array() ) { uninstall_plugin( $plugin->file ); - if ( !isset( $assoc_args['no-delete'] ) && $this->_delete( $plugin ) ) { - WP_CLI::success( "Uninstalled '$plugin->name' plugin." ); + if ( !isset( $assoc_args['skip-delete'] ) && $this->_delete( $plugin ) ) { + WP_CLI::success( "Uninstalled and deleted '$plugin->name' plugin." ); + } else { + WP_CLI::success( "Ran uninstall procedure for '$plugin->name' plugin without deleting." ); } } } From 2bcca7edf7c08e5103798a13b16f4ccff79f4a7f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 10:14:18 -0800 Subject: [PATCH 3273/4858] Failing test for #1432 --- features/core.feature | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index b0cc7b5d67..60d4f9e9c2 100644 --- a/features/core.feature +++ b/features/core.feature @@ -367,7 +367,20 @@ Feature: Manage WordPress installation And STDOUT should not contain: """ Downloading - """ + """ + + Scenario: Don't run update when up-to-date + Given a WP install + + When I run `wp core update` + Then STDOUT should contain: + """ + WordPress is at the latest version + """ + And STDOUT should not contain: + """ + Updating + """ Scenario: User defined in wp-cli.yml From 69a77e5fe14be009bc90eb3a7899bde5ac38f22e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 10:24:19 -0800 Subject: [PATCH 3274/4858] Don't attempt to update when `$update` isn't set Also, unless `--force` is specified, don't update when the versions are the same. Previously, an invalid conditional meant the update process executed even when `$update` wasn't set. --- features/core.feature | 9 +++++++-- php/commands/core.php | 43 ++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/features/core.feature b/features/core.feature index 60d4f9e9c2..3f84b643d0 100644 --- a/features/core.feature +++ b/features/core.feature @@ -375,13 +375,18 @@ Feature: Manage WordPress installation When I run `wp core update` Then STDOUT should contain: """ - WordPress is at the latest version + WordPress is up to date """ And STDOUT should not contain: """ - Updating + Updating """ + When I run `wp core update --force` + Then STDOUT should contain: + """ + Updating + """ Scenario: User defined in wp-cli.yml Given an empty directory diff --git a/php/commands/core.php b/php/commands/core.php index dfdb15e289..e3b2ace8cc 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -870,9 +870,7 @@ function update( $args, $assoc_args ) { wp_version_check(); $from_api = get_site_transient( 'update_core' ); - if ( empty( $from_api->updates ) ) { - $update = false; - } else { + if ( ! empty( $from_api->updates ) ) { list( $update ) = $from_api->updates; } @@ -898,32 +896,35 @@ function update( $args, $assoc_args ) { 'locale' => $locale ); - } else { - WP_CLI::success( 'WordPress is up to date.' ); - return; } + + if ( ! empty( $update ) && ( $update->version != $wp_version || isset( $assoc_args['force'] ) ) ) { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - if ( $update->version ) { - WP_CLI::log( "Updating to version {$update->version} ({$update->locale})..." ); - } else { - WP_CLI::log( "Starting update..." ); - } + if ( $update->version ) { + WP_CLI::log( "Updating to version {$update->version} ({$update->locale})..." ); + } else { + WP_CLI::log( "Starting update..." ); + } - $GLOBALS['wp_cli_update_obj'] = $update; - $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); - unset( $GLOBALS['wp_cli_update_obj'] ); + $GLOBALS['wp_cli_update_obj'] = $update; + $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); + unset( $GLOBALS['wp_cli_update_obj'] ); - if ( is_wp_error($result) ) { - $msg = WP_CLI::error_to_string( $result ); - if ( 'up_to_date' != $result->get_error_code() ) { - WP_CLI::error( $msg ); + if ( is_wp_error($result) ) { + $msg = WP_CLI::error_to_string( $result ); + if ( 'up_to_date' != $result->get_error_code() ) { + WP_CLI::error( $msg ); + } else { + WP_CLI::success( $msg ); + } } else { - WP_CLI::success( $msg ); + WP_CLI::success( 'WordPress updated successfully.' ); } + } else { - WP_CLI::success( 'WordPress updated successfully.' ); + WP_CLI::success( 'WordPress is up to date.' ); } } From 90f38f7200fe4d21e63cdd6d70cef1804cb1c025 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 11:28:22 -0800 Subject: [PATCH 3275/4858] Update existing test for 894a35ced5edabf4502f34758e5107732cd76b34 --- features/plugin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 0ef5a21ac5..fec30f86a9 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -76,7 +76,7 @@ Feature: Manage WordPress plugins When I run `wp plugin uninstall Zombieland` Then STDOUT should contain: """ - Success: Uninstalled 'Zombieland' plugin. + Success: Uninstalled and deleted 'Zombieland' plugin. """ And the {PLUGIN_DIR}/zombieland file should not exist From 7382430c1b3d3e55a44c8fb416668126913120eb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 11:32:35 -0800 Subject: [PATCH 3276/4858] Lock down permissions for bash completion --- utils/wp-completion.bash | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 utils/wp-completion.bash diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash old mode 100755 new mode 100644 From e04e7e934a48b0d47bf6ccd14ca684eb9d1f908d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 12:08:09 -0800 Subject: [PATCH 3277/4858] No indentation here --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index e3b2ace8cc..27723b6cb8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -897,7 +897,7 @@ function update( $args, $assoc_args ) { ); } - + if ( ! empty( $update ) && ( $update->version != $wp_version || isset( $assoc_args['force'] ) ) ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); From b72e32fc2ceb0598a655d238a41f24c9daf0285b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 12 Nov 2014 22:12:21 +0100 Subject: [PATCH 3278/4858] indent examples --- php/commands/option.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index 6cccab2b98..6309b6bdbf 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -96,14 +96,14 @@ public function add( $args, $assoc_args ) { * * ## EXAMPLES * - * # Get the total size of all autoload options - * wp option list --autoload=on --format=total_bytes + * # Get the total size of all autoload options + * wp option list --autoload=on --format=total_bytes * - * # Find biggest transients - * wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail + * # Find biggest transients + * wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail * - * # List all options begining with "i2f_" - * wp option list --search "i2f_*" + * # List all options begining with "i2f_" + * wp option list --search "i2f_*" * * ## AVAILABLE FIELDS * From 7e0d3ee461529c38392b737de7985aa242d7c5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 12 Nov 2014 22:40:27 +0100 Subject: [PATCH 3279/4858] wrapping up `wp option list` tests --- features/option.feature | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/features/option.feature b/features/option.feature index 4dd0616901..4e33f6ef58 100644 --- a/features/option.feature +++ b/features/option.feature @@ -13,23 +13,26 @@ Feature: Manage WordPress options bar """ - When I run `wp option list + When I run `wp option list` Then STDOUT should not be empty - When I run `wp option list --autoload=on + When I run `wp option list` + Then STDOUT should contain: + """ + bar + """ + + When I run `wp option list --autoload=on` Then STDOUT should not be empty When I run `wp option list --search='str_o*'` - Then STDOUT should be: - """ - option_name - str_opt - """ + Then STDOUT should be a table containing rows: + | option_name | option_value | + | str_opt | bar | When I run `wp option list --search='str_o*' --format=total_bytes` Then STDOUT should be: """ - size 3 """ @@ -45,10 +48,15 @@ Feature: Manage WordPress options When I run `wp option delete str_opt` Then STDOUT should not be empty + When I run `wp option list` + Then STDOUT should not contain: + """ + str_opt + """ + When I try `wp option get str_opt` Then the return code should be 1 - # Integer values When I run `wp option update blog_public 0` Then STDOUT should not be empty From 0261d6713cc268927461d4361840c061d365431b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 14:14:49 -0800 Subject: [PATCH 3280/4858] Disambiguate two plugins sharing the same directory --- features/plugin.feature | 18 ++++++++++++++++++ php/commands/plugin.php | 18 ++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index fec30f86a9..1d86171a8a 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -288,4 +288,22 @@ Feature: Manage WordPress plugins Success: Ran uninstall procedure for """ + Scenario: Two plugins, one directory + Given a WP install + And I run `svn co https://meta.svn.wordpress.org/sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook wp-content/plugins/handbook` + + When I run `wp plugin list --fields=name,status` + Then STDOUT should be a table containing rows: + | name | status | + | handbook/handbook | inactive | + | handbook/functionality-for-pages | inactive | + + When I run `wp plugin activate handbook/functionality-for-pages` + Then STDOUT should not be empty + + When I run `wp plugin list --fields=name,status` + Then STDOUT should be a table containing rows: + | name | status | + | handbook/handbook | inactive | + | handbook/functionality-for-pages | active | diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 214c78e8d0..95cd478b79 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -322,13 +322,18 @@ function update( $args, $assoc_args ) { } protected function get_item_list() { - $items = array(); + $items = $duplicate_names = array(); foreach ( get_plugins() as $file => $details ) { $update_info = $this->get_update_info( $file ); + $name = Utils\get_plugin_name( $file ); + if ( ! isset( $duplicate_names[ $name ] ) ) { + $duplicate_names[ $name ] = array(); + } + $duplicate_names[ $name ][] = $file; $items[ $file ] = array( - 'name' => Utils\get_plugin_name( $file ), + 'name' => $name, 'status' => $this->get_status( $file ), 'update' => (bool) $update_info, 'update_version' => $update_info['new_version'], @@ -340,6 +345,15 @@ protected function get_item_list() { ); } + foreach( $duplicate_names as $name => $files ) { + if ( count( $files ) <= 1 ) { + continue; + } + foreach( $files as $file ) { + $items[ $file ]['name'] = str_replace( '.' . pathinfo( $file, PATHINFO_EXTENSION ), '', $file ); + } + } + return $items; } From d500fb54d5166c1929efbe63a2c3bf6e1baedd38 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 14:18:45 -0800 Subject: [PATCH 3281/4858] Fix indentation --- features/plugin.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 1d86171a8a..3de6cfb293 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -296,7 +296,7 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | | handbook/handbook | inactive | - | handbook/functionality-for-pages | inactive | + | handbook/functionality-for-pages | inactive | When I run `wp plugin activate handbook/functionality-for-pages` Then STDOUT should not be empty @@ -305,5 +305,5 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | status | | handbook/handbook | inactive | - | handbook/functionality-for-pages | active | + | handbook/functionality-for-pages | active | From a53b49fddbebb7155a016b656c5aa126b388a779 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 12 Nov 2014 14:20:23 -0800 Subject: [PATCH 3282/4858] More indentation fixes --- features/plugin.feature | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 3de6cfb293..8b578fb8ec 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -274,34 +274,34 @@ Feature: Manage WordPress plugins inactive inactive must-use - """ + """ Scenario: Uninstall a plugin without deleting Given a WP install - When I run `wp plugin install akismet --version=2.5.7 --force` - Then STDOUT should not be empty + When I run `wp plugin install akismet --version=2.5.7 --force` + Then STDOUT should not be empty - When I run `wp plugin uninstall akismet --skip-delete` - Then STDOUT should contain: - """ - Success: Ran uninstall procedure for - """ + When I run `wp plugin uninstall akismet --skip-delete` + Then STDOUT should contain: + """ + Success: Ran uninstall procedure for + """ Scenario: Two plugins, one directory Given a WP install And I run `svn co https://meta.svn.wordpress.org/sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook wp-content/plugins/handbook` - When I run `wp plugin list --fields=name,status` + When I run `wp plugin list --fields=name,status` Then STDOUT should be a table containing rows: | name | status | | handbook/handbook | inactive | | handbook/functionality-for-pages | inactive | - When I run `wp plugin activate handbook/functionality-for-pages` - Then STDOUT should not be empty + When I run `wp plugin activate handbook/functionality-for-pages` + Then STDOUT should not be empty - When I run `wp plugin list --fields=name,status` + When I run `wp plugin list --fields=name,status` Then STDOUT should be a table containing rows: | name | status | | handbook/handbook | inactive | From f334c09f0096041eac254dfb5dddc8088cd6c2a4 Mon Sep 17 00:00:00 2001 From: borekb <borekb@gmail.com> Date: Thu, 13 Nov 2014 14:45:23 +0100 Subject: [PATCH 3283/4858] Update .gitattributes WP-CLI only works well with LF line endings (see e.g. comment parsing) and the original settings cause auto-translation to CRLF on Windows. The `eol=lf` bit fixes that so that the working copy files are LF on Windows too. --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 0fdf7ac9b9..a5666637cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ # Auto detect text files and perform EOL normalization -* text=auto +* text=auto eol=lf From 43c56556374dee00977e448a4fc3f400b33d2dd5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 18 Nov 2014 05:34:20 -0800 Subject: [PATCH 3284/4858] Internalize these files for performance --- features/plugin.feature | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 8b578fb8ec..530c217d79 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -290,7 +290,24 @@ Feature: Manage WordPress plugins Scenario: Two plugins, one directory Given a WP install - And I run `svn co https://meta.svn.wordpress.org/sites/trunk/wordpress.org/public_html/wp-content/plugins/handbook wp-content/plugins/handbook` + And a wp-content/plugins/handbook/handbook.php file: + """ + <?php + /** + * Plugin Name: Handbook + * Description: Features for a handbook, complete with glossary and table of contents + * Author: Nacin + */ + """ + And a wp-content/plugins/handbook/functionality-for-pages.php file: + """ + <?php + /** + * Plugin Name: Handbook Functionality for Pages + * Description: Adds handbook-like table of contents to all Pages for a site. Covers Table of Contents and the "watch this page" widget + * Author: Nacin + */ + """ When I run `wp plugin list --fields=name,status` Then STDOUT should be a table containing rows: From b6699b37f26ee2b23b04b0cfdb96081a0ff9860d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 18 Nov 2014 07:36:04 -0800 Subject: [PATCH 3285/4858] Version bump --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 28fe469ca1..2199b643da 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.17.0' ); +define( 'WP_CLI_VERSION', '0.17.1' ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From 2fba48c7a2da53a117f6ad48b2c3939982514f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 19 Nov 2014 01:24:44 +0100 Subject: [PATCH 3286/4858] Debian package builder --- utils/wp-cli-updatedeb.sh | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 utils/wp-cli-updatedeb.sh diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh new file mode 100644 index 0000000000..c4f34efb51 --- /dev/null +++ b/utils/wp-cli-updatedeb.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# +# Package wp-cli to be installed in Debian-compatible systems. +# Only the phar file is included. +# +# VERSION :0.2 +# DATE :2014-11-19 +# AUTHOR :Viktor Szépe <viktor@szepe.net> +# LICENSE :The MIT License (MIT) +# URL :https://github.com/wp-cli/wp-cli/tree/master/utils +# BASH-VERSION :4.2+ + +# packages source path +DIR="php-wpcli" +# phar URL +PHAR="https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli.phar" + +die() { + local RET="$1" + shift + + echo -e "$@" >&2 + exit "$RET" +} + +dump_control() { + cat > DEBIAN/control <<CTRL +Package: php-wpcli +Version: 0.0.0 +Architecture: all +Maintainer: Daniel Bachhuber <daniel@handbuilt.co> +Section: php +Priority: optional +Depends: php5-cli, php5-mysql | php5-mysqlnd, mysql-client +Homepage: http://wp-cli.org/ +Description: wp-cli is a set of command-line tools for managing + WordPress installations. You can update plugins, set up multisite + installs and much more, without using a web browser. + +CTRL +} + +# deb's dir +if ! [ -d "$DIR" ]; then + mkdir "$DIR" || die 1 "Cannot create directory here: ${PWD}" +fi + +pushd "$DIR" + +# control file +if ! [ -r DEBIAN/control ]; then + mkdir DEBIAN + dump_control +fi + +# content dirs +[ -d usr/bin ] || mkdir -p usr/bin + +# download current version +wget -nv -O usr/bin/wp "$PHAR" || die 3 "Phar download failure" +chmod +x usr/bin/wp || die 4 "chmod failure" + +# get version +WPCLI_VER="$(grep -ao "define.*WP_CLI_VERSION.*;" usr/bin/wp | cut -d"'" -f4)" +[ -z "$WPCLI_VER" ] && die 5 "Cannot get wp-cli version" +echo "Current version: ${WPCLI_VER}" + +# update version +sed -i "s/^Version: .*$/Version: ${WPCLI_VER}/" DEBIAN/control || die 6 "Version update failure" + +# update MD5-s +find usr -type f -exec md5sum \{\} \; > DEBIAN/md5sums || die 7 "md5sum creation failure" + +popd + +# build package in the current diretory +WPCLI_PKG="${PWD}/php-wpcli_${WPCLI_VER}_all.deb" +fakeroot dpkg-deb --build "$DIR" "$WPCLI_PKG" || die 8 "Packaging failed" + +# optional steps +echo "sign it: dpkg-sig -k <YOUR-KEY> -s builder \"$WPCLI_PKG\"" +echo "include in your repo: pushd /var/www/<REPO-DIR>" +echo "reprepro includedeb wheezy \"$WPCLI_PKG\" && popd" From 367fb6fe7f1972586cf7c6b84391cace00e525f0 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Fri, 21 Nov 2014 21:23:18 -0500 Subject: [PATCH 3287/4858] Better 'version' support for `wp [plugin|theme] update`. See #1488. --- php/commands/plugin.php | 7 ++++--- php/commands/theme.php | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 95cd478b79..1cdaadaae9 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -298,8 +298,7 @@ protected function install_from_repo( $slug, $assoc_args ) { * : If set, all plugins that have updates will be updated. * * [--version=<version>] - * : If set, the plugin will be updated to the latest development version, - * regardless of what version is currently installed. + * : If set, the plugin will be updated to the specified version. * * [--dry-run] * : Preview which plugins would be updated. @@ -311,9 +310,11 @@ protected function install_from_repo( $slug, $assoc_args ) { * wp plugin update --all */ function update( $args, $assoc_args ) { - if ( isset( $assoc_args['version'] ) && 'dev' == $assoc_args['version'] ) { + if ( isset( $assoc_args['version'] ) ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { $this->_delete( $plugin ); + + $assoc_args['force'] = 1; $this->install( array( $plugin->name ), $assoc_args ); } } else { diff --git a/php/commands/theme.php b/php/commands/theme.php index adceda527d..9a09e10f0f 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -440,8 +440,7 @@ public function get( $args, $assoc_args ) { * : If set, all themes that have updates will be updated. * * [--version=<version>] - * : If set, the theme will be updated to the latest development version, - * regardless of what version is currently installed. + * : If set, the plugin will be updated to the specified version. * * [--dry-run] * : Preview which themes would be updated. @@ -453,7 +452,19 @@ public function get( $args, $assoc_args ) { * wp theme update --all */ function update( $args, $assoc_args ) { - parent::update_many( $args, $assoc_args ); + if ( isset( $assoc_args['version'] ) ) { + foreach ( $this->fetcher->get_many( $args ) as $theme ) { + $r = delete_theme( $theme->stylesheet ); + if ( is_wp_error( $r ) ) { + WP_CLI::warning( $r ); + } else { + $assoc_args['force'] = 1; + $this->install( array( $theme->stylesheet ), $assoc_args ); + } + } + } else { + parent::update_many( $args, $assoc_args ); + } } /** From 0c3c34013493ae9782656f52006d7086b1549c4b Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sun, 23 Nov 2014 02:09:44 +0900 Subject: [PATCH 3288/4858] fix incorrect param for chmod --- php/commands/scaffold.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index babe849e42..050b812285 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -490,7 +490,7 @@ function plugin_tests( $args, $assoc_args ) { foreach ( $to_copy as $file => $dir ) { $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); if ( 'install-wp-tests.sh' === $file ) { - if ( ! $wp_filesystem->chmod( "$dir/$file", '0755' ) ) { + if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); } } @@ -632,4 +632,3 @@ private function init_wp_filesystem() { } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); - From 20017ec6ada642f28b51a840f06a971aaa59db12 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Nov 2014 07:26:27 -0800 Subject: [PATCH 3289/4858] Update version numbers to fix failing tests --- features/core.feature | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features/core.feature b/features/core.feature index b0cc7b5d67..7a4f8d4991 100644 --- a/features/core.feature +++ b/features/core.feature @@ -270,9 +270,9 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0 | major | https://wordpress.org/wordpress-4.0.zip | - | 3.9.2 | major | https://wordpress.org/wordpress-3.9.2.zip | - | 3.8.4 | minor | https://wordpress.org/wordpress-3.8.4.zip | + | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | + | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | + | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | When I run `wp core check-update --field=version | wc -l` Then STDOUT should be: @@ -283,8 +283,8 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0 | major | https://wordpress.org/wordpress-4.0.zip | - | 3.9.2 | major | https://wordpress.org/wordpress-3.9.2.zip | + | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | + | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | When I run `wp core check-update --major --field=version | wc -l` Then STDOUT should be: @@ -295,7 +295,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.4 | minor | https://wordpress.org/wordpress-3.8.4.zip | + | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | When I run `wp core check-update --minor --field=version | wc -l` Then STDOUT should be: From 4c4e0cfdab807193f2c710e73e6153fb8314770a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Nov 2014 07:42:37 -0800 Subject: [PATCH 3290/4858] Properly sort WordPress versions `version_compare()` can return `-1` or `0`, both of which are falsy. This caused inconsistent results when the WordPress API started returning versions out of order --- features/core.feature | 4 ++-- php/commands/core.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index 7a4f8d4991..0a9f5af4cc 100644 --- a/features/core.feature +++ b/features/core.feature @@ -272,7 +272,7 @@ Feature: Manage WordPress installation | version | update_type | package_url | | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | - | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | + | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | When I run `wp core check-update --field=version | wc -l` Then STDOUT should be: @@ -295,7 +295,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | + | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | When I run `wp core check-update --minor --field=version | wc -l` Then STDOUT should be: diff --git a/php/commands/core.php b/php/commands/core.php index dfdb15e289..85807ad809 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -52,7 +52,7 @@ function check_update( $_, $assoc_args ) { $release_data = json_decode( $response->body ); $release_versions = array_keys( (array) $release_data ); usort( $release_versions, function( $a, $b ){ - return ! version_compare( $a, $b ); + return 1 === version_compare( $a, $b ); }); $locale = get_locale(); @@ -86,6 +86,7 @@ function check_update( $_, $assoc_args ) { } if ( $updates ) { + $updates = array_reverse( $updates ); $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'version', 'update_type', 'package_url' ) From 1f7c7edc2462636a8725837508c1ea1353882618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 19 Nov 2014 01:24:44 +0100 Subject: [PATCH 3291/4858] Debian package builder --- utils/wp-cli-updatedeb.sh | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 utils/wp-cli-updatedeb.sh diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh new file mode 100644 index 0000000000..c4f34efb51 --- /dev/null +++ b/utils/wp-cli-updatedeb.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# +# Package wp-cli to be installed in Debian-compatible systems. +# Only the phar file is included. +# +# VERSION :0.2 +# DATE :2014-11-19 +# AUTHOR :Viktor Szépe <viktor@szepe.net> +# LICENSE :The MIT License (MIT) +# URL :https://github.com/wp-cli/wp-cli/tree/master/utils +# BASH-VERSION :4.2+ + +# packages source path +DIR="php-wpcli" +# phar URL +PHAR="https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli.phar" + +die() { + local RET="$1" + shift + + echo -e "$@" >&2 + exit "$RET" +} + +dump_control() { + cat > DEBIAN/control <<CTRL +Package: php-wpcli +Version: 0.0.0 +Architecture: all +Maintainer: Daniel Bachhuber <daniel@handbuilt.co> +Section: php +Priority: optional +Depends: php5-cli, php5-mysql | php5-mysqlnd, mysql-client +Homepage: http://wp-cli.org/ +Description: wp-cli is a set of command-line tools for managing + WordPress installations. You can update plugins, set up multisite + installs and much more, without using a web browser. + +CTRL +} + +# deb's dir +if ! [ -d "$DIR" ]; then + mkdir "$DIR" || die 1 "Cannot create directory here: ${PWD}" +fi + +pushd "$DIR" + +# control file +if ! [ -r DEBIAN/control ]; then + mkdir DEBIAN + dump_control +fi + +# content dirs +[ -d usr/bin ] || mkdir -p usr/bin + +# download current version +wget -nv -O usr/bin/wp "$PHAR" || die 3 "Phar download failure" +chmod +x usr/bin/wp || die 4 "chmod failure" + +# get version +WPCLI_VER="$(grep -ao "define.*WP_CLI_VERSION.*;" usr/bin/wp | cut -d"'" -f4)" +[ -z "$WPCLI_VER" ] && die 5 "Cannot get wp-cli version" +echo "Current version: ${WPCLI_VER}" + +# update version +sed -i "s/^Version: .*$/Version: ${WPCLI_VER}/" DEBIAN/control || die 6 "Version update failure" + +# update MD5-s +find usr -type f -exec md5sum \{\} \; > DEBIAN/md5sums || die 7 "md5sum creation failure" + +popd + +# build package in the current diretory +WPCLI_PKG="${PWD}/php-wpcli_${WPCLI_VER}_all.deb" +fakeroot dpkg-deb --build "$DIR" "$WPCLI_PKG" || die 8 "Packaging failed" + +# optional steps +echo "sign it: dpkg-sig -k <YOUR-KEY> -s builder \"$WPCLI_PKG\"" +echo "include in your repo: pushd /var/www/<REPO-DIR>" +echo "reprepro includedeb wheezy \"$WPCLI_PKG\" && popd" From 099f3227c5f3ab0a8174e57bd26be2f50c6bee30 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sun, 23 Nov 2014 02:09:44 +0900 Subject: [PATCH 3292/4858] fix incorrect param for chmod --- php/commands/scaffold.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index babe849e42..050b812285 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -490,7 +490,7 @@ function plugin_tests( $args, $assoc_args ) { foreach ( $to_copy as $file => $dir ) { $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); if ( 'install-wp-tests.sh' === $file ) { - if ( ! $wp_filesystem->chmod( "$dir/$file", '0755' ) ) { + if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); } } @@ -632,4 +632,3 @@ private function init_wp_filesystem() { } WP_CLI::add_command( 'scaffold', 'Scaffold_Command' ); - From 4bf792a679d621187d1c77ed6cc5b2361c4e5283 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Nov 2014 07:26:27 -0800 Subject: [PATCH 3293/4858] Update version numbers to fix failing tests --- features/core.feature | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features/core.feature b/features/core.feature index b0cc7b5d67..7a4f8d4991 100644 --- a/features/core.feature +++ b/features/core.feature @@ -270,9 +270,9 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0 | major | https://wordpress.org/wordpress-4.0.zip | - | 3.9.2 | major | https://wordpress.org/wordpress-3.9.2.zip | - | 3.8.4 | minor | https://wordpress.org/wordpress-3.8.4.zip | + | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | + | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | + | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | When I run `wp core check-update --field=version | wc -l` Then STDOUT should be: @@ -283,8 +283,8 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0 | major | https://wordpress.org/wordpress-4.0.zip | - | 3.9.2 | major | https://wordpress.org/wordpress-3.9.2.zip | + | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | + | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | When I run `wp core check-update --major --field=version | wc -l` Then STDOUT should be: @@ -295,7 +295,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.4 | minor | https://wordpress.org/wordpress-3.8.4.zip | + | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | When I run `wp core check-update --minor --field=version | wc -l` Then STDOUT should be: From 1ea6266d39ff9c3895d289f4e4ea060a6cb72928 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Nov 2014 07:42:37 -0800 Subject: [PATCH 3294/4858] Properly sort WordPress versions `version_compare()` can return `-1` or `0`, both of which are falsy. This caused inconsistent results when the WordPress API started returning versions out of order --- features/core.feature | 4 ++-- php/commands/core.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index 7a4f8d4991..0a9f5af4cc 100644 --- a/features/core.feature +++ b/features/core.feature @@ -272,7 +272,7 @@ Feature: Manage WordPress installation | version | update_type | package_url | | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | - | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | + | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | When I run `wp core check-update --field=version | wc -l` Then STDOUT should be: @@ -295,7 +295,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.1 | minor | https://wordpress.org/wordpress-3.8.1.zip | + | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | When I run `wp core check-update --minor --field=version | wc -l` Then STDOUT should be: diff --git a/php/commands/core.php b/php/commands/core.php index dfdb15e289..85807ad809 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -52,7 +52,7 @@ function check_update( $_, $assoc_args ) { $release_data = json_decode( $response->body ); $release_versions = array_keys( (array) $release_data ); usort( $release_versions, function( $a, $b ){ - return ! version_compare( $a, $b ); + return 1 === version_compare( $a, $b ); }); $locale = get_locale(); @@ -86,6 +86,7 @@ function check_update( $_, $assoc_args ) { } if ( $updates ) { + $updates = array_reverse( $updates ); $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'version', 'update_type', 'package_url' ) From 638014639f4eb3fea3089fed4973d5778ad54dff Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Mon, 24 Nov 2014 16:50:11 -0500 Subject: [PATCH 3295/4858] Behat test for `wp plugin update --version`. See #1510. --- features/plugin.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 530c217d79..c79aee297b 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -324,3 +324,16 @@ Feature: Manage WordPress plugins | handbook/handbook | inactive | | handbook/functionality-for-pages | active | + Scenario: Install a plugin, then update to a specific version of that plugin + Given a WP install + + When I run `wp plugin install akismet --version=2.5.7 --force` + Then STDOUT should not be empty + + When I run `wp plugin update akismet --version=2.6.0` + Then STDOUT should not be empty + + When I run `wp plugin list --fields=name,version` + Then STDOUT should be a table containing rows: + | name | version | + | akismet | 2.6.0 | From e492c44c2c5224a8dcedd8f77f4e5835688f1232 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Mon, 24 Nov 2014 16:50:36 -0500 Subject: [PATCH 3296/4858] Behat test for `wp theme update --version`. See #1510. --- features/theme.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 6ad011a7e2..fde24c9933 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -211,3 +211,17 @@ Feature: Manage WordPress themes """ Error: This is not a multisite install. """ + + Scenario: Install a theme, then update to a specific version of that theme + Given a WP install + + When I run `wp theme install p2 --version=1.4.1` + Then STDOUT should not be empty + + When I run `wp theme update p2 --version=1.4.2` + Then STDOUT should not be empty + + When I run `wp theme list --fields=name,version` + Then STDOUT should be a table containing rows: + | name | version | + | p2 | 1.4.2 | From dbf252bf338c7adf138b691fc60bcfeeac15e0bb Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 24 Nov 2014 22:27:40 -0200 Subject: [PATCH 3297/4858] add global parameters for all subcommands --- features/help.feature | 6 ++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 37 ++++++++++++++++++++++ php/WP_CLI/Dispatcher/RootCommand.php | 25 +-------------- templates/man-params.mustache | 8 ++++- 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/features/help.feature b/features/help.feature index b4551a60de..e94455d515 100644 --- a/features/help.feature +++ b/features/help.feature @@ -15,6 +15,12 @@ Feature: Get help about WP-CLI commands When I run `wp help help` Then STDOUT should not be empty + When I run `wp help help` + Then STDOUT should contain: + """ + GLOBAL PARAMETERS + """ + When I run `wp post list --post_type=post --posts_per_page=5 --help` Then STDOUT should contain: """ diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 7296652f7e..cc7258d03a 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -2,6 +2,8 @@ namespace WP_CLI\Dispatcher; +use \WP_CLI\Utils; + /** * A non-leaf node in the command tree. * Contains one or more Subcommands. @@ -28,6 +30,7 @@ public function __construct( $parent, $name, $docparser ) { $this->shortdesc = $docparser->get_shortdesc(); $this->longdesc = $docparser->get_longdesc(); + $this->longdesc .= $this->get_global_params(); $this->docparser = $docparser; $when_to_invoke = $docparser->get_tag( 'when' ); @@ -221,5 +224,39 @@ private static function get_aliases( $subcommands ) { public function get_alias() { return false; } + + /*** + * Get the list of global parameters + * + * @param string $root_command whether to include or not root command specific description + * @return string + */ + protected function get_global_params( $root_command = false ) { + $binding = array(); + $binding['root_command'] = $root_command; + + foreach ( \WP_CLI::get_configurator()->get_spec() as $key => $details ) { + if ( false === $details['runtime'] ) + continue; + + if ( isset( $details['deprecated'] ) ) + continue; + + if ( isset( $details['hidden'] ) ) + continue; + + if ( true === $details['runtime'] ) + $synopsis = "--[no-]$key"; + else + $synopsis = "--$key" . $details['runtime']; + + $binding['parameters'][] = array( + 'synopsis' => $synopsis, + 'desc' => $details['desc'] + ); + } + + return Utils\mustache_render( 'man-params.mustache', $binding ); + } } diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index d5c19826b5..fb730da07e 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -25,30 +25,7 @@ public function __construct() { * @return string */ public function get_longdesc() { - $binding = array(); - - foreach ( \WP_CLI::get_configurator()->get_spec() as $key => $details ) { - if ( false === $details['runtime'] ) - continue; - - if ( isset( $details['deprecated'] ) ) - continue; - - if ( isset( $details['hidden'] ) ) - continue; - - if ( true === $details['runtime'] ) - $synopsis = "--[no-]$key"; - else - $synopsis = "--$key" . $details['runtime']; - - $binding['parameters'][] = array( - 'synopsis' => $synopsis, - 'desc' => $details['desc'] - ); - } - - return Utils\mustache_render( 'man-params.mustache', $binding ); + return $this->get_global_params( true ); } /** diff --git a/templates/man-params.mustache b/templates/man-params.mustache index dd848d83f9..e1417bd7c5 100644 --- a/templates/man-params.mustache +++ b/templates/man-params.mustache @@ -1,3 +1,7 @@ +{{^root_command}} + + +{{/root_command}} ## GLOBAL PARAMETERS {{#parameters}} @@ -5,4 +9,6 @@ {{desc}} {{/parameters}} -Run 'wp help <command>' to get more information on a specific command. +{{#root_command}} + Run 'wp help <command>' to get more information on a specific command. +{{/root_command}} \ No newline at end of file From 16bf57219ca3e10be351aa8b293b06932d0c661d Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 24 Nov 2014 22:31:56 -0200 Subject: [PATCH 3298/4858] add missing new line --- templates/man-params.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/man-params.mustache b/templates/man-params.mustache index e1417bd7c5..a27f4d846a 100644 --- a/templates/man-params.mustache +++ b/templates/man-params.mustache @@ -11,4 +11,4 @@ {{/parameters}} {{#root_command}} Run 'wp help <command>' to get more information on a specific command. -{{/root_command}} \ No newline at end of file +{{/root_command}} From a74a434dd6d97efe0fafdde9bdbfdf8842e2c1ee Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 26 Nov 2014 11:45:11 -0200 Subject: [PATCH 3299/4858] define WPLANG only for WP < 4.0 --- php/commands/core.php | 9 +++++++++ templates/wp-config.mustache | 2 ++ 2 files changed, 11 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 85807ad809..a096dd690b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -311,6 +311,9 @@ public function config( $_, $assoc_args ) { WP_CLI::error( "The 'wp-config.php' file already exists." ); } + $versions_path = ABSPATH . 'wp-includes/version.php'; + include $versions_path; + $defaults = array( 'dbhost' => 'localhost', 'dbpass' => '', @@ -344,6 +347,12 @@ public function config( $_, $assoc_args ) { 'https://api.wordpress.org/secret-key/1.1/salt/' ); } + if ( version_compare( $wp_version, '4.0', '<' ) ) { + $assoc_args['add-wplang'] = true; + } else { + $assoc_args['add-wplang'] = false; + } + $out = Utils\mustache_render( 'wp-config.mustache', $assoc_args ); $bytes_written = file_put_contents( ABSPATH . 'wp-config.php', $out ); diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index 6951c9bb0c..104a379461 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -26,7 +26,9 @@ define('DB_COLLATE', '{{dbcollate}}'); $table_prefix = '{{dbprefix}}'; +{{#add-wplang}} define('WPLANG', '{{locale}}'); +{{/add-wplang}} {{extra-php}} From 3228254276ac4554a4b1739c723830007e6753c7 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 28 Nov 2014 08:54:20 -0200 Subject: [PATCH 3300/4858] add tests to check if WPLANG is defined only for WP < 4.0 --- features/core.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/core.feature b/features/core.feature index 0a9f5af4cc..47f385f924 100644 --- a/features/core.feature +++ b/features/core.feature @@ -67,6 +67,10 @@ Feature: Manage WordPress installation """ define( 'WP_DEBUG_LOG', true ); """ + And the wp-config.php file should not contain: + """ + define( 'WPLANG', '' ); + """ When I try the previous command again Then the return code should be 1 @@ -82,6 +86,16 @@ Feature: Manage WordPress installation define('AUTH_SALT', """ + Scenario: Define WPLANG when running WP < 4.0 + Given an empty directory + And I run `wp core download --version=3.9 --force` + + When I run `wp core config {CORE_CONFIG_SETTINGS}` + Then the wp-config.php file should contain: + """ + define('WPLANG', ''); + """ + Scenario: Database doesn't exist Given an empty directory And WP files From 27b4f78971d40462fbf1653f9cee2c0b0f009cd7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 28 Nov 2014 10:55:10 -0800 Subject: [PATCH 3301/4858] Don't allow active language to be uninstalled --- features/core.feature | 12 ++++++++++++ php/WP_CLI/CommandWithTranslation.php | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/features/core.feature b/features/core.feature index 0a9f5af4cc..6523036aa9 100644 --- a/features/core.feature +++ b/features/core.feature @@ -484,3 +484,15 @@ Feature: Manage WordPress installation Success: Language activated. """ + @require-wp-4.0 + Scenario: Don't allow active language to be uninstalled + Given a WP install + + When I run `wp core language install en_GB --activate` + Then STDOUT should not be empty + + When I try `wp core language uninstall en_GB` + Then STDERR should be: + """ + Warning: The 'en_GB' language is active. + """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index c7e544f5ec..06aa8c6ab6 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -212,6 +212,12 @@ public function uninstall( $args, $assoc_args ) { \WP_CLI::error( "No files found in language directory." ); } + $current_locale = get_locale(); + if ( $language_code === $current_locale ) { + \WP_CLI::warning( "The '{$language_code}' language is active." ); + exit; + } + // As of WP 4.0, no API for deleting a language pack WP_Filesystem(); $deleted = false; From 1098d4070e31f5d9dd2b28750fcef8ec0913df5d Mon Sep 17 00:00:00 2001 From: spacedmonkey <spacedmonkey2@gmail.com> Date: Sun, 30 Nov 2014 22:12:22 +0000 Subject: [PATCH 3302/4858] Added new subcommands wp user term and wp post term --- features/post-term.feature | 86 ++++++++++++ features/user-term.feature | 102 ++++++++++++++ php/WP_CLI/CommandWithTerms.php | 226 ++++++++++++++++++++++++++++++++ php/commands/post.php | 27 ++++ php/commands/user.php | 18 +++ 5 files changed, 459 insertions(+) create mode 100644 features/post-term.feature create mode 100644 features/user-term.feature create mode 100644 php/WP_CLI/CommandWithTerms.php diff --git a/features/post-term.feature b/features/post-term.feature new file mode 100644 index 0000000000..f23dd11df9 --- /dev/null +++ b/features/post-term.feature @@ -0,0 +1,86 @@ +Feature: Manage post term + + Scenario: Postterm CRUD + Given a WP install + + When I run `wp post term add 1 category foo` + Then STDOUT should be: + """ + Success: Added term. + """ + + When I run `wp post term list 1 category --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | foo | foo | category | + + When I run `wp post term add 1 category bar` + Then STDOUT should be: + """ + Success: Added term. + """ + + When I run `wp post term list 1 category --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | foo | foo | category | + | bar | bar | category | + + When I run `wp post term set 1 category new` + Then STDOUT should be: + """ + Success: Set terms. + """ + + When I run `wp post term list 1 category --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | new | new | category | + + When I run `wp post term remove 1 category new` + Then STDOUT should be: + """ + Success: Deleted term. + """ + + Scenario: Multiple post term + Given a WP install + + When I run `wp post term add 1 category apple` + And I run `wp post term add 1 category apple` + Then STDOUT should be: + """ + Success: Added term. + """ + + When I run `wp post term set 1 category 'apple1, apple2'` + Then STDOUT should be: + """ + Success: Set terms. + """ + + When I run `wp post term list 1 category --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | apple1 | apple1 | category | + | apple2 | apple2 | category | + + Scenario: Invalid Post ID + Given a WP install + + When I try `wp post term add 99999 category boo` + Then the return code should be 1 + And STDERR should be: + """ + Error: Could not find the post with ID 99999. + """ + + Scenario: Postterm Add invalid tax + Given a WP install + + When I try `wp post term add 1 foo2 boo` + Then the return code should be 1 + And STDERR should be: + """ + Error: Invalid taxonomy. + """ diff --git a/features/user-term.feature b/features/user-term.feature new file mode 100644 index 0000000000..8fd84eddcd --- /dev/null +++ b/features/user-term.feature @@ -0,0 +1,102 @@ +Feature: Manage user term + + Scenario: Userterm CRUD + Given a WP install + And a wp-content/plugins/test-add-tax/plugin.php file: + """ + <?php + // Plugin Name: Test Add Tax + + function add_cli_tax(){ + register_taxonomy( 'user_type', 'user' ); + } + + add_action('init','add_cli_tax'); + """ + And I run `wp plugin activate test-add-tax` + + + When I run `wp user term add 1 user_type foo` + Then STDOUT should be: + """ + Success: Added term. + """ + + When I run `wp user term list 1 user_type --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | foo | foo | user_type | + + When I run `wp user term add 1 user_type bar` + Then STDOUT should be: + """ + Success: Added term. + """ + + When I run `wp user term list 1 user_type --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | foo | foo | user_type | + | bar | bar | user_type | + + When I run `wp user term set 1 user_type new` + Then STDOUT should be: + """ + Success: Set terms. + """ + + When I run `wp user term list 1 user_type --fields=name,slug,taxonomy` + Then STDOUT should be a table containing rows: + | name | slug | taxonomy | + | new | new | user_type | + + When I run `wp user term remove 1 user_type new` + Then STDOUT should be: + """ + Success: Deleted term. + """ + + Scenario: Multiple user term + Given a WP install + + And a wp-content/plugins/test-add-tax/plugin.php file: + """ + <?php + // Plugin Name: Test Add Tax + + function add_cli_tax(){ + register_taxonomy( 'user_type', 'user' ); + } + + add_action('init','add_cli_tax'); + """ + And I run `wp plugin activate test-add-tax` + + When I run `wp user term add 1 user_type apple` + And I run `wp user term add 1 user_type apple` + Then STDOUT should contain: + """ + Success: Added term. + """ + + When I run `wp user term set 1 user_type 'apple1, apple2'` + Then STDOUT should contain: + """ + Success: Set terms. + """ + + When I run `wp user term list 1 user_type --format=json --fields=name,slug,taxonomy` + Then STDOUT should contain: + """ + [{"name":"apple1","slug":"apple1","taxonomy":"user_type"},{"name":"apple2","slug":"apple2","taxonomy":"user_type"}] + """ + + Scenario: Userterm Add invalid tax + Given a WP install + + When I try `wp user term add 1 boo foo2` + Then the return code should be 1 + And STDERR should be: + """ + Error: Invalid taxonomy. + """ \ No newline at end of file diff --git a/php/WP_CLI/CommandWithTerms.php b/php/WP_CLI/CommandWithTerms.php new file mode 100644 index 0000000000..4c8b0c8c52 --- /dev/null +++ b/php/WP_CLI/CommandWithTerms.php @@ -0,0 +1,226 @@ +<?php + +namespace WP_CLI; + +use WP_CLI; + +/** + * Base class for WP-CLI commands that deal with terms + * + * @package wp-cli + */ +abstract class CommandWithTerms extends \WP_CLI_Command { + + /** + * @var string $object_type WordPress' expected name for the object. + */ + protected $obj_type; + + /** + * @var string $object_id WordPress' object id. + */ + protected $obj_id; + + /** + * @var array $obj_fields Default fields to display for each object. + */ + protected $obj_fields = array( + "term_id", + "name", + "slug", + "taxonomy" + ); + + /** + * List all terms associated with an object. + * + * <id> + * : ID for the object. + * + * <taxonomy>... + * : One or more taxonomies to list. + * + * [--fields=<fields>] + * : Limit the output to specific row fields. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each term: + * + * * term_id + * * name + * * slug + * * taxonomy + * + * These fields are optionally available: + * + * * term_taxonomy_id + * * description + * * term_group + * * parent + * * count + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + + $object_id = array_shift( $args ); + $taxonomy_names = $args; + + $this->set_obj_id( $object_id ); + + $items = wp_get_object_terms( $object_id, $taxonomy_names ); + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $items ); + + } + + + /** + * Remove a term. + * + * <id> + * : The ID of the object. + * + * <taxonomy> + * : The name of the taxonomy type to deleted. + * + * <term> + * : The name of the term to deleted. + */ + public function remove( $args, $assoc_args ) { + list( $object_id, $taxonomy, $term ) = $args; + + $this->set_obj_id( $object_id ); + + $this->taxonomy_exists( $taxonomy ); + + $terms = explode( ",", $term ); + + $result = wp_remove_object_terms( $object_id, $terms, $taxonomy ); + + if ( ! is_wp_error( $result ) ) { + WP_CLI::success( "Deleted term." ); + } else { + WP_CLI::error( "Failed to delete term." ); + } + } + + /** + * Add a term. Appends to existed + * + * <id> + * : The ID of the object. + * + * <taxonomy> + * : The name of the taxonomy type to be added. + * + * <term> + * : The name of the term to be added. + */ + public function add( $args, $assoc_args ) { + list( $object_id, $taxonomy, $term ) = $args; + + $this->set_obj_id( $object_id ); + + $this->taxonomy_exists( $taxonomy ); + + $terms = explode( ",", $term ); + + $result = wp_set_object_terms( $object_id, $terms, $taxonomy, true ); + + if ( ! is_wp_error( $result ) ) { + WP_CLI::success( "Added term." ); + } else { + WP_CLI::error( "Failed to add term." ); + } + } + + /** + * Set terms. Replaces existing terms + * + * <id> + * : The ID of the object. + * + * <taxonomy> + * : The name of the taxonomy type to be updated. + * + * <term> + * : The name of the term to be updated. + */ + public function set( $args, $assoc_args ) { + list( $object_id, $taxonomy, $term ) = $args; + + $this->set_obj_id( $object_id ); + + $this->taxonomy_exists( $taxonomy ); + + $terms = explode( ",", $term ); + + $result = wp_set_object_terms( $object_id, $terms, $taxonomy, false ); + + if ( ! is_wp_error( $result ) ) { + WP_CLI::success( "Set terms." ); + } else { + WP_CLI::error( "Failed to set terms." ); + } + } + + /** + * Check if taxonomy exists + * + * @param $taxonomy + */ + protected function taxonomy_exists( $taxonomy ) { + + $taxonomy_names = get_object_taxonomies( $this->get_object_type() ); + + if ( ! in_array( $taxonomy, $taxonomy_names ) ) { + WP_CLI::error( 'Invalid taxonomy.' ); + } + } + + /** + * Set obj_id Class variable + * + * @param string $obj_id + */ + protected function set_obj_id( $obj_id ) { + $this->obj_id = $obj_id; + } + + /** + * Get obj_id Class variable + * + * @return string + */ + protected function get_obj_id() { + return $this->obj_id; + } + + + /** + * Get obj_type Class variable + * + * @return string $obj_type + */ + protected function get_object_type() { + return $this->obj_type; + } + + /** + * Get Formatter object based on supplied parameters. + * + * @param array $assoc_args Parameters passed to command. Determines formatting. + * + * @return WP_CLI\Formatter + */ + protected function get_formatter( &$assoc_args ) { + return new WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); + } +} + diff --git a/php/commands/post.php b/php/commands/post.php index 9547668041..2a9f50e140 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -480,6 +480,33 @@ class Post_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'post'; } +/** + * Manage post terms. + * + * ## OPTIONS + * + * [--format=json] + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp post term set 123 test category + */ +class Post_Term_Command extends \WP_CLI\CommandWithTerms { + protected $obj_type = 'post'; + + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\Post; + } + + protected function get_object_type() { + $post = $this->fetcher->get_check( $this->get_obj_id() ); + + return $post->post_type; + } +} + WP_CLI::add_command( 'post', 'Post_Command' ); WP_CLI::add_command( 'post meta', 'Post_Meta_Command' ); +WP_CLI::add_command( 'post term', 'Post_Term_Command' ); diff --git a/php/commands/user.php b/php/commands/user.php index b9575d3a48..698692bfcf 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -825,6 +825,24 @@ private function replace_login_with_user_id( $args ) { } +/** + * Manage user terms. + * + * ## OPTIONS + * + * [--format=json] + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp user term set 123 test category + */ +class User_Term_Command extends \WP_CLI\CommandWithTerms { + protected $obj_type = 'user'; +} + + WP_CLI::add_command( 'user', 'User_Command' ); WP_CLI::add_command( 'user meta', 'User_Meta_Command' ); +WP_CLI::add_command( 'user term', 'User_Term_Command' ); From 05d79b50cb64f0b26b85680f05997be8ec338327 Mon Sep 17 00:00:00 2001 From: spacedmonkey <spacedmonkey2@gmail.com> Date: Mon, 1 Dec 2014 01:29:34 +0000 Subject: [PATCH 3303/4858] Improved tests, formatting and backwards compatibility for post / user term --- features/post-term.feature | 21 ++++-- features/user-term.feature | 19 ++++-- php/WP_CLI/CommandWithTerms.php | 115 +++++++++++++++++++++++++++----- php/commands/post.php | 4 -- php/commands/user.php | 4 -- 5 files changed, 126 insertions(+), 37 deletions(-) diff --git a/features/post-term.feature b/features/post-term.feature index f23dd11df9..20ab616b23 100644 --- a/features/post-term.feature +++ b/features/post-term.feature @@ -32,10 +32,11 @@ Feature: Manage post term Success: Set terms. """ - When I run `wp post term list 1 category --fields=name,slug,taxonomy` - Then STDOUT should be a table containing rows: - | name | slug | taxonomy | - | new | new | category | + When I run `wp post term list 1 category --fields=name,slug,taxonomy --format=count` + Then STDOUT should be: + """ + 1 + """ When I run `wp post term remove 1 category new` Then STDOUT should be: @@ -43,6 +44,12 @@ Feature: Manage post term Success: Deleted term. """ + When I run `wp post term list 1 category --fields=name,slug,taxonomy --format=count` + Then STDOUT should be: + """ + 0 + """ + Scenario: Multiple post term Given a WP install @@ -53,7 +60,7 @@ Feature: Manage post term Success: Added term. """ - When I run `wp post term set 1 category 'apple1, apple2'` + When I run `wp post term set 1 category apple1 apple2` Then STDOUT should be: """ Success: Set terms. @@ -73,7 +80,7 @@ Feature: Manage post term And STDERR should be: """ Error: Could not find the post with ID 99999. - """ + """ Scenario: Postterm Add invalid tax Given a WP install @@ -83,4 +90,4 @@ Feature: Manage post term And STDERR should be: """ Error: Invalid taxonomy. - """ + """ diff --git a/features/user-term.feature b/features/user-term.feature index 8fd84eddcd..3895f20a2c 100644 --- a/features/user-term.feature +++ b/features/user-term.feature @@ -45,10 +45,11 @@ Feature: Manage user term Success: Set terms. """ - When I run `wp user term list 1 user_type --fields=name,slug,taxonomy` - Then STDOUT should be a table containing rows: - | name | slug | taxonomy | - | new | new | user_type | + When I run `wp user term list 1 user_type --fields=name,slug,taxonomy --format=count` + Then STDOUT should be: + """ + 1 + """ When I run `wp user term remove 1 user_type new` Then STDOUT should be: @@ -56,6 +57,12 @@ Feature: Manage user term Success: Deleted term. """ + When I run `wp user term list 1 user_type --fields=name,slug,taxonomy --format=count` + Then STDOUT should be: + """ + 0 + """ + Scenario: Multiple user term Given a WP install @@ -79,7 +86,7 @@ Feature: Manage user term Success: Added term. """ - When I run `wp user term set 1 user_type 'apple1, apple2'` + When I run `wp user term set 1 user_type apple1 apple2` Then STDOUT should contain: """ Success: Set terms. @@ -99,4 +106,4 @@ Feature: Manage user term And STDERR should be: """ Error: Invalid taxonomy. - """ \ No newline at end of file + """ \ No newline at end of file diff --git a/php/WP_CLI/CommandWithTerms.php b/php/WP_CLI/CommandWithTerms.php index 4c8b0c8c52..1ba36170fe 100644 --- a/php/WP_CLI/CommandWithTerms.php +++ b/php/WP_CLI/CommandWithTerms.php @@ -89,19 +89,19 @@ public function list_( $args, $assoc_args ) { * <taxonomy> * : The name of the taxonomy type to deleted. * - * <term> - * : The name of the term to deleted. + * <term>... + * : The name of the term or terms to deleted. */ public function remove( $args, $assoc_args ) { - list( $object_id, $taxonomy, $term ) = $args; + $object_id = array_shift( $args ); + $taxonomy = array_shift( $args ); + $terms = $args; $this->set_obj_id( $object_id ); $this->taxonomy_exists( $taxonomy ); - $terms = explode( ",", $term ); - - $result = wp_remove_object_terms( $object_id, $terms, $taxonomy ); + $result = self::wp_remove_object_terms( $object_id, $terms, $taxonomy ); if ( ! is_wp_error( $result ) ) { WP_CLI::success( "Deleted term." ); @@ -119,18 +119,18 @@ public function remove( $args, $assoc_args ) { * <taxonomy> * : The name of the taxonomy type to be added. * - * <term> - * : The name of the term to be added. + * <term>... + * : The name of the term or terms to be added. */ public function add( $args, $assoc_args ) { - list( $object_id, $taxonomy, $term ) = $args; + $object_id = array_shift( $args ); + $taxonomy = array_shift( $args ); + $terms = $args; $this->set_obj_id( $object_id ); $this->taxonomy_exists( $taxonomy ); - $terms = explode( ",", $term ); - $result = wp_set_object_terms( $object_id, $terms, $taxonomy, true ); if ( ! is_wp_error( $result ) ) { @@ -149,18 +149,18 @@ public function add( $args, $assoc_args ) { * <taxonomy> * : The name of the taxonomy type to be updated. * - * <term> - * : The name of the term to be updated. + * <term>... + * : The name of the term or terms to be updated. */ public function set( $args, $assoc_args ) { - list( $object_id, $taxonomy, $term ) = $args; + $object_id = array_shift( $args ); + $taxonomy = array_shift( $args ); + $terms = $args; $this->set_obj_id( $object_id ); $this->taxonomy_exists( $taxonomy ); - $terms = explode( ",", $term ); - $result = wp_set_object_terms( $object_id, $terms, $taxonomy, false ); if ( ! is_wp_error( $result ) ) { @@ -170,6 +170,89 @@ public function set( $args, $assoc_args ) { } } + + /** + * Remove term(s) associated with a given object. + * + * + * @global wpdb $wpdb WordPress database abstraction object. + * + * @param int $object_id The ID of the object from which the terms will be removed. + * @param array|int|string $terms The slug(s) or ID(s) of the term(s) to remove. + * @param array|string $taxonomy Taxonomy name. + * @return bool|WP_Error True on success, false or WP_Error on failure. + */ + private static function wp_remove_object_terms( $object_id, $terms, $taxonomy ) { + global $wpdb; + + // Remove notices in below 3.6 and support backwards compatibility + + if( function_exists( 'wp_remove_object_terms' ) ){ + return wp_remove_object_terms( $object_id, $terms, $taxonomy ); + } + + $object_id = (int) $object_id; + + if ( ! taxonomy_exists( $taxonomy ) ) { + return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy' ) ); + } + + if ( ! is_array( $terms ) ) { + $terms = array( $terms ); + } + + $tt_ids = array(); + + foreach ( (array) $terms as $term ) { + if ( ! strlen( trim( $term ) ) ) { + continue; + } + + if ( ! $term_info = term_exists( $term, $taxonomy ) ) { + // Skip if a non-existent term ID is passed. + if ( is_int( $term ) ) { + continue; + } + } + + if ( is_wp_error( $term_info ) ) { + return $term_info; + } + + $tt_ids[] = $term_info['term_taxonomy_id']; + } + + if ( $tt_ids ) { + $in_tt_ids = "'" . implode( "', '", $tt_ids ) . "'"; + + /** + * Fires immediately before an object-term relationship is deleted. + * + * @since 2.9.0 + * + * @param int $object_id Object ID. + * @param array $tt_ids An array of term taxonomy IDs. + */ + do_action( 'delete_term_relationships', $object_id, $tt_ids ); + $deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) ); + + /** + * Fires immediately after an object-term relationship is deleted. + * + * @since 2.9.0 + * + * @param int $object_id Object ID. + * @param array $tt_ids An array of term taxonomy IDs. + */ + do_action( 'deleted_term_relationships', $object_id, $tt_ids ); + wp_update_term_count( $tt_ids, $taxonomy ); + + return (bool) $deleted; + } + + return false; + } + /** * Check if taxonomy exists * diff --git a/php/commands/post.php b/php/commands/post.php index 2a9f50e140..a5977e565f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -483,10 +483,6 @@ class Post_Meta_Command extends \WP_CLI\CommandWithMeta { /** * Manage post terms. * - * ## OPTIONS - * - * [--format=json] - * : Encode/decode values as JSON. * * ## EXAMPLES * diff --git a/php/commands/user.php b/php/commands/user.php index 698692bfcf..76a347fac9 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -828,10 +828,6 @@ private function replace_login_with_user_id( $args ) { /** * Manage user terms. * - * ## OPTIONS - * - * [--format=json] - * : Encode/decode values as JSON. * * ## EXAMPLES * From 55ed9fd1bf9ab19696a0340e3769cb21b6ce2f59 Mon Sep 17 00:00:00 2001 From: mikey dubs <mike@herebox.org> Date: Sun, 30 Nov 2014 16:32:30 -0800 Subject: [PATCH 3304/4858] install-wp-tests.sh svn wget https wordpress.org Use https for requests to wordpress.org Fixes svn checkout currently failing using http like: svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ svn: E175002: Unable to connect to a repository at URL 'http://develop.svn.wordpress.org/trunk/tests/phpunit/includes' github issue wp-cli/wp-cli#1529 --- templates/install-wp-tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 1e39064a59..b9ddf1f066 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -25,7 +25,7 @@ install_wp() { local ARCHIVE_NAME="wordpress-$WP_VERSION" fi - wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz + wget -nv -O /tmp/wordpress.tar.gz https://wordpress.org/${ARCHIVE_NAME}.tar.gz tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR wget -nv -O $WP_CORE_DIR/wp-content/db.php https://raw.github.com/markoheijnen/wp-mysqli/master/db.php @@ -42,9 +42,9 @@ install_test_suite() { # set up testing suite mkdir -p $WP_TESTS_DIR cd $WP_TESTS_DIR - svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ + svn co --quiet https://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ - wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php + wget -nv -O wp-tests-config.php https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php From 3035f78d3e61762526d998a39e09f514e1fcb000 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 1 Dec 2014 16:07:39 -0800 Subject: [PATCH 3305/4858] Tests to establish errors in #1427 --- features/core.feature | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/features/core.feature b/features/core.feature index 8fbe329dba..dfd8d408a2 100644 --- a/features/core.feature +++ b/features/core.feature @@ -510,3 +510,59 @@ Feature: Manage WordPress installation """ Warning: The 'en_GB' language is active. """ + + Scenario: Ensure file cache isn't corrupted by core update, part one + Given a WP install + And an empty cache + + When I run `wp core update --version=4.0 --force` + Then STDOUT should contain: + """ + Success: WordPress updated successfully + """ + + When I run `wp core version` + Then STDOUT should be: + """ + 4.0 + """ + + When I run `wp core download --version=4.0 --force` + Then STDOUT should contain: + """ + Success: WordPress downloaded + """ + + When I run `wp core version` + Then STDOUT should be: + """ + 4.0 + """ + + Scenario: Ensure file cache isn't corrupted by core update, part two + Given a WP install + And an empty cache + + When I run `wp core download --version=4.0 --force` + Then STDOUT should contain: + """ + Success: WordPress downloaded + """ + + When I run `wp core version` + Then STDOUT should be: + """ + 4.0 + """ + + When I run `wp core update --version=4.0 --force` + Then STDOUT should contain: + """ + Success: WordPress updated successfully + """ + + When I run `wp core version` + Then STDOUT should be: + """ + 4.0 + """ From 07fc75513c29c19583e0ec5659e0e3db2ba4f4a1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 1 Dec 2014 16:18:22 -0800 Subject: [PATCH 3306/4858] If there's a bad cache, fall back to downloading fresh --- features/core.feature | 4 ++++ php/commands/core.php | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index dfd8d408a2..896ad52bf7 100644 --- a/features/core.feature +++ b/features/core.feature @@ -532,6 +532,10 @@ Feature: Manage WordPress installation """ Success: WordPress downloaded """ + And STDERR should contain: + """ + Warning: Extraction failed, downloading a new copy... + """ When I run `wp core version` Then STDOUT should be: diff --git a/php/commands/core.php b/php/commands/core.php index a096dd690b..73200db387 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -150,10 +150,18 @@ public function download( $args, $assoc_args ) { $cache_key = "core/$locale-$version.tar.gz"; $cache_file = $cache->has($cache_key); + $bad_cache = false; if ( $cache_file ) { WP_CLI::log( "Using cached file '$cache_file'..." ); - self::_extract( $cache_file, ABSPATH ); - } else { + try{ + self::_extract( $cache_file, ABSPATH ); + } catch ( Exception $e ) { + WP_CLI::warning( "Extraction failed, downloading a new copy..." ); + $bad_cache = true; + } + } + + if ( ! $cache_file || $bad_cache ) { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; From f16b0e6e2bf3f02e271380b7c23c0b75f5e7d156 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 1 Dec 2014 16:25:35 -0800 Subject: [PATCH 3307/4858] Persist package file extension in `WP_CLI\CoreUpgrader` `wp core update` uses ZIP files, while `wp core download` uses gzipped TAR files. Renaming ZIP files to `.tar.gz` causes nasty bugs. Let's keep them cached separately. --- features/core.feature | 15 ++------------- php/WP_CLI/CoreUpgrader.php | 8 +++++--- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/features/core.feature b/features/core.feature index 896ad52bf7..8ba517e5a3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -511,21 +511,10 @@ Feature: Manage WordPress installation Warning: The 'en_GB' language is active. """ - Scenario: Ensure file cache isn't corrupted by core update, part one + Scenario: Ensure file cache isn't corrupted by a ZIP masquerading as a gzipped TAR, part one Given a WP install And an empty cache - - When I run `wp core update --version=4.0 --force` - Then STDOUT should contain: - """ - Success: WordPress updated successfully - """ - - When I run `wp core version` - Then STDOUT should be: - """ - 4.0 - """ + And I run `mkdir -p {SUITE_CACHE_DIR}/core; wget -O {SUITE_CACHE_DIR}/core/en_US-4.0.tar.gz https://wordpress.org/wordpress-4.0.zip` When I run `wp core download --version=4.0 --force` Then STDOUT should contain: diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index d3d3692e44..e156649f54 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -32,11 +32,13 @@ function download_package( $package ) { if ( empty( $package ) ) return new WP_Error( 'no_package', $this->strings['no_package'] ); - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + $ext = pathinfo( $package, PATHINFO_EXTENSION ); + + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.' . $ext; $cache = WP_CLI::get_cache(); $update = $GLOBALS['wp_cli_update_obj']; - $cache_key = "core/{$update->locale}-{$update->version}.tar.gz"; + $cache_key = "core/{$update->locale}-{$update->version}.{$ext}"; $cache_file = $cache->has( $cache_key ); if ( $cache_file ) { @@ -46,7 +48,7 @@ function download_package( $package ) { } else { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.' . $ext; $headers = array('Accept' => 'application/json'); $options = array( From d348f0821d936e875c2274e612b4e6070fddf93b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 2 Dec 2014 07:22:30 -0800 Subject: [PATCH 3308/4858] Update cache was changed to ZIP --- features/core.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 8ba517e5a3..c68af4ba5d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -376,7 +376,7 @@ Feature: Manage WordPress installation When I run `wp core update --version=3.8.1 --force` Then STDOUT should contain: """ - Using cached file '{SUITE_CACHE_DIR}/core/en_US-3.8.1.tar.gz'... + Using cached file '{SUITE_CACHE_DIR}/core/en_US-3.8.1.zip'... """ And STDOUT should not contain: """ From 2d4aa021efb6dbe25a148078150babcd551312b3 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Tue, 2 Dec 2014 18:08:26 +0000 Subject: [PATCH 3309/4858] Implement #522 --- php/commands/cli.php | 101 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index deb9b86f92..d6fe428198 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -107,6 +107,97 @@ private function same_minor_release( $release_parts, $updates ) { * @subcommand check-update */ function check_update( $_, $assoc_args ) { + $updates = $this->get_updates( $assoc_args ); + + if ( $updates ) { + $formatter = new \WP_CLI\Formatter( + $assoc_args, + array( 'version', 'update_type', 'package_url' ) + ); + $formatter->display_items( $updates ); + } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { + WP_CLI::success( "WP-CLI is at the latest version." ); + } + } + + /** + * Fetch most recent update matching the requirements. Returns the available versions if there are updates, or empty if no update available. + * + * ## OPTIONS + * + * [--patch] + * : Compare only the first two parts of the version number. + * + * [--minor] + * : Compare only the first part of the version number. + * + * [--yes] + * : Do not prompt for confirmation + * + * @subcommand self-update + */ + function self_update( $_, $assoc_args ) { + if ( 0 !== strpos( WP_CLI_ROOT, 'phar://' ) ) { + WP_CLI::error( "You can only self-update PHARs" ); + } + + $old_phar = realpath( $_SERVER['argv'][0] ); + + if ( ! is_writable( $old_phar ) ) { + WP_CLI::error( sprintf( "%s is not writable by current user", $old_phar ) ); + } + + $updates = $this->get_updates( $assoc_args ); + + if ( $updates ) { + $newest = $updates[0]; + + WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); + + $download_url = $newest['package_url']; + + WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); + + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.phar'; + + $headers = array(); + $options = array( + 'timeout' => 600, // 10 minutes ought to be enough for everybody + 'filename' => $temp + ); + + Utils\http_request( 'GET', $download_url, null, $headers, $options ); + + exec( "php $temp --version", $output, $status ); + + if ( 0 !== $status ) { + WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli self-update again.' ); + } + + WP_CLI::log( 'New version works. Proceeding to replace.' ); + + $mode = fileperms( $old_phar ) & 511; + + if ( false === @chmod( $temp, $mode ) ) { + WP_CLI::error( sprintf( "Cannot chmod %s", $temp ) ); + } + + class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the file we no longer have access to this class + + if ( false === @rename( $temp, $old_phar ) ) { + WP_CLI::error( sprintf( "Cannot move %s to %s", $temp, $old_phar ) ); + } + + WP_CLI::success( sprintf( 'Successfully update WP-CLI to %s', $newest['version'] ) ); + } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { + WP_CLI::success( "WP-CLI is at the latest version." ); + } + } + + /** + * Returns update information + */ + private function get_updates( $assoc_args ) { $url = 'https://api.github.com/repos/wp-cli/wp-cli/releases'; $options = array( @@ -155,15 +246,7 @@ function check_update( $_, $assoc_args ) { } } - if ( $updates ) { - $formatter = new \WP_CLI\Formatter( - $assoc_args, - array( 'version', 'update_type', 'package_url' ) - ); - $formatter->display_items( $updates ); - } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { - WP_CLI::success( "WP-CLI is at the latest version." ); - } + return $updates; } /** From 777218040353a8c3b5bd002a47c6dd7c16b4beab Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Wed, 3 Dec 2014 09:55:52 +0000 Subject: [PATCH 3310/4858] Refactoring and better errors Changes to WP_CLI::error(): - can now take an array of lines, which will be printed in a red box, similar to Composer's exceptions - new boolean $exit param - if false will not exit(1); defaults to old behaviour Both loggers get a new error_box( $message_lines ) function `wp cli self-update` is now `wp cli update` --- php/WP_CLI/Loggers/Quiet.php | 11 ++++++ php/WP_CLI/Loggers/Regular.php | 26 ++++++++++++++ php/class-wp-cli.php | 15 +++++--- php/commands/cli.php | 62 ++++++++++++++++++---------------- 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 6ccbb4029b..44a86ca34b 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -43,4 +43,15 @@ public function error( $message ) { fwrite( STDERR, \WP_CLI::colorize( "%RError:%n $message\n" ) ); } + /** + * Similar to error( $message ), but outputs $message in a red box + * + * @param array $message Message to write. + */ + public function error_box( $message_lines ) { + $message = implode( "\n", $message_lines ); + + fwrite( STDERR, \WP_CLI::colorize( "%RError:%n\n$message\n" ) ); + fwrite( STDERR, \WP_CLI::colorize( "%R---------%n\n\n" ) ); + } } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index f5dda04fcb..32d4a772a5 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -73,4 +73,30 @@ public function error( $message ) { $this->_line( $message, 'Error', '%R', STDERR ); } + /** + * Similar to error( $message ), but outputs $message in a red box + * + * @param array $message Message to write. + */ + public function error_box( $message_lines ) { + // convert tabs to four spaces, as some shells will output the tabs as variable-length + $message_lines = array_map( function( $line ) { + return str_replace( "\t", ' ', $line ); + } , $message_lines ); + + $longest = max( array_map( 'strlen', $message_lines ) ); + + // write an empty line before the message + $empty_line = \cli\Colors::colorize( '%w%1 ' . str_repeat( ' ', $longest ) . ' %n' ); + $this->write( STDERR, "\n\t$empty_line\n" ); + + foreach ( $message_lines as $line ) { + $padding = str_repeat( ' ', $longest - strlen( $line ) ); + $line = \cli\Colors::colorize( "%w%1 $line $padding%n" ); + $this->write( STDERR, "\t$line\n" ); + } + + // write an empty line after the message + $this->write( STDERR, "\t$empty_line\n\n" ); + } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 63fb63f38a..9d83c2e6f3 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -240,14 +240,21 @@ public static function warning( $message ) { /** * Display an error in the CLI and end with a newline * - * @param string $message + * @param string|array|WP_Error $message + * @param bool $exit if true, the script will exit() */ - public static function error( $message ) { + public static function error( $message, $exit = true ) { if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) ) { - self::$logger->error( self::error_to_string( $message ) ); + if ( is_array( $message ) ) { + self::$logger->error_box( array_map( array( __CLASS__, 'error_to_string' ), $message ) ); + } else { + self::$logger->error( self::error_to_string( $message ) ); + } } - exit(1); + if ( $exit ) { + exit(1); + } } /** diff --git a/php/commands/cli.php b/php/commands/cli.php index d6fe428198..7bcc113c8e 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -134,9 +134,9 @@ function check_update( $_, $assoc_args ) { * [--yes] * : Do not prompt for confirmation * - * @subcommand self-update + * @subcommand update */ - function self_update( $_, $assoc_args ) { + function update( $_, $assoc_args ) { if ( 0 !== strpos( WP_CLI_ROOT, 'phar://' ) ) { WP_CLI::error( "You can only self-update PHARs" ); } @@ -149,49 +149,51 @@ function self_update( $_, $assoc_args ) { $updates = $this->get_updates( $assoc_args ); - if ( $updates ) { - $newest = $updates[0]; + if ( empty( $updates ) ) { + WP_CLI::success( "WP-CLI is at the latest version." ); + } - WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); + $newest = $updates[0]; - $download_url = $newest['package_url']; + WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); - WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); + $download_url = $newest['package_url']; - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.phar'; + WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); - $headers = array(); - $options = array( - 'timeout' => 600, // 10 minutes ought to be enough for everybody - 'filename' => $temp - ); + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.phar'; - Utils\http_request( 'GET', $download_url, null, $headers, $options ); + $headers = array(); + $options = array( + 'timeout' => 600, // 10 minutes ought to be enough for everybody + 'filename' => $temp + ); - exec( "php $temp --version", $output, $status ); + Utils\http_request( 'GET', $download_url, null, $headers, $options ); - if ( 0 !== $status ) { - WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli self-update again.' ); - } + exec( "php $temp --version", $output, $status ); - WP_CLI::log( 'New version works. Proceeding to replace.' ); + if ( 0 !== $status ) { + WP_CLI::error( $output, false ); - $mode = fileperms( $old_phar ) & 511; + WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli self-update again.' ); + } - if ( false === @chmod( $temp, $mode ) ) { - WP_CLI::error( sprintf( "Cannot chmod %s", $temp ) ); - } + WP_CLI::log( 'New version works. Proceeding to replace.' ); - class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the file we no longer have access to this class + $mode = fileperms( $old_phar ) & 511; - if ( false === @rename( $temp, $old_phar ) ) { - WP_CLI::error( sprintf( "Cannot move %s to %s", $temp, $old_phar ) ); - } + if ( false === @chmod( $temp, $mode ) ) { + WP_CLI::error( sprintf( "Cannot chmod %s", $temp ) ); + } - WP_CLI::success( sprintf( 'Successfully update WP-CLI to %s', $newest['version'] ) ); - } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { - WP_CLI::success( "WP-CLI is at the latest version." ); + class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the file we no longer have access to this class + + if ( false === @rename( $temp, $old_phar ) ) { + WP_CLI::error( sprintf( "Cannot move %s to %s", $temp, $old_phar ) ); } + + WP_CLI::success( sprintf( 'Successfully update WP-CLI to %s', $newest['version'] ) ); } /** From 456c5cc88307c6f7b960768c7e0a4ea39304cd15 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Wed, 3 Dec 2014 12:34:55 +0000 Subject: [PATCH 3311/4858] Extract WP_CLI_VERSION to a separate file - Implements #680 - It is now possibile to set the version at build time (required for #1535): --version=x.y.z - Keywords for incrementing the version number by one: --version=[patch|minor|major] - When no arguments are passed, the old behaviour is preverved - utils/update-phar takes an option argument: `update-phar [same|patch|minor|major|x.y.z]` --- VERSION | 1 + composer.json | 5 ++-- php/wp-cli.php | 2 +- utils/make-phar.php | 61 ++++++++++++++++++++++++++++++++++++++++++--- utils/update-phar | 4 ++- 5 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000..14a8c24575 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.17.1 \ No newline at end of file diff --git a/composer.json b/composer.json index f503e39061..ee4763449d 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "wp-cli/wp-cli", "description": "A command line interface for WordPress", - "keywords": [ "cli", "wordpress" ], + "keywords": [ "cli", "wordpress" ], "homepage": "http://wp-cli.org", "license": "MIT", "bin": [ @@ -18,7 +18,8 @@ }, "require-dev": { "phpunit/phpunit": "3.7.*", - "behat/behat": "2.5.*" + "behat/behat": "2.5.*", + "ulrichsg/getopt-php": "2.2.*" }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" diff --git a/php/wp-cli.php b/php/wp-cli.php index 2199b643da..46d7033363 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', '0.17.1' ); +define( 'WP_CLI_VERSION', file_get_contents( WP_CLI_ROOT . '/VERSION' ) ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; diff --git a/utils/make-phar.php b/utils/make-phar.php index 4558cfbfb9..687970ca6e 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -3,15 +3,67 @@ require './vendor/autoload.php'; use Symfony\Component\Finder\Finder; +use Ulrichsg\Getopt\Getopt; +use Ulrichsg\Getopt\Option; -if ( !isset( $argv[1] ) ) { - echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet]\n"; +$getopt = new Getopt( array( + new Option( null, 'version', Getopt::REQUIRED_ARGUMENT ), + new Option( null, 'quiet' ), + new Option( 'o', 'output', Getopt::REQUIRED_ARGUMENT ), +) ); + +$getopt->parse(); + +if ( ! $getopt['output'] && ! $getopt->getOperand(0) ) { + echo "usage: php -dphar.readonly=0 $argv[0] -o <path> [--quiet] [--version=same|patch|minor|major|x.y.z]\n"; exit(1); } -define( 'DEST_PATH', $argv[1] ); +define( 'DEST_PATH', $getopt['output'] ?: $getopt->getOperand(0) ); + +define( 'BE_QUIET', (bool) $getopt['quiet'] ); + +if ( $getopt['version'] ) { + // split version ussuming the format is x.y.z-pre + $current_version = explode( '-', file_get_contents( './VERSION' ), 2 ); + $current_version[0] = explode( '.', $current_version[0] ); + + switch ( $getopt['version'] ) { + case 'same': + // do nothing + break; + + case 'patch': + $current_version[0][2]++; + + $current_version = array( $current_version[0] ); // drop possible pre-release info + break; -define( 'BE_QUIET', in_array( '--quiet', $argv ) ); + case 'minor': + $current_version[0][1]++; + $current_version[0][2] = 0; + + $current_version = array( $current_version[0] ); // drop possible pre-release info + break; + + case 'major': + $current_version[0][0]++; + $current_version[0][1] = 0; + $current_version[0][2] = 0; + + $current_version = array( $current_version[0] ); // drop possible pre-release info + break; + + default: + $current_version = array( array( $getopt['version'] ) ); + break; + } + + // reconstruct version string + $current_version[0] = implode( '.', $current_version[0] ); + $current_version = implode( '-', $current_version ); + file_put_contents( './VERSION', $current_version ); +} function add_file( $phar, $path ) { $key = str_replace( './', '', $path ); @@ -67,6 +119,7 @@ function add_file( $phar, $path ) { add_file( $phar, './vendor/autoload.php' ); add_file( $phar, './utils/get-package-require-from-composer.php' ); add_file( $phar, './vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); +add_file( $phar, './VERSION' ); $phar->setStub( <<<EOB #!/usr/bin/env php diff --git a/utils/update-phar b/utils/update-phar index ea79bf1129..7eeb24f883 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -2,6 +2,8 @@ set -ex +version=${1-"same"} + current_rev=$(git rev-parse HEAD) current_rev=${current_rev:0:10} @@ -10,7 +12,7 @@ packages_repo=../wp-cli-packages fname="phar/wp-cli.phar" # generate archive -php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet +php -dphar.readonly=0 -o ./utils/make-phar.php $packages_repo/$fname --quiet --version=$version cd $packages_repo From 733d34f982b9524a98a8826ed4b471731a34599b Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Wed, 3 Dec 2014 16:00:30 +0000 Subject: [PATCH 3312/4858] wp cli update - fix success message --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 7bcc113c8e..fc3d4ccf9d 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -193,7 +193,7 @@ class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the WP_CLI::error( sprintf( "Cannot move %s to %s", $temp, $old_phar ) ); } - WP_CLI::success( sprintf( 'Successfully update WP-CLI to %s', $newest['version'] ) ); + WP_CLI::success( sprintf( 'Updated WP-CLI to %s', $newest['version'] ) ); } /** From a036ec39d8afedec11b8d5570c6a0eaf4222adf3 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Wed, 3 Dec 2014 16:50:02 +0000 Subject: [PATCH 3313/4858] update checker options - change description of --patch and --minor - introduce --ignore-patch and --ignore-minor --- php/commands/cli.php | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index fc3d4ccf9d..8779fd567e 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -90,10 +90,16 @@ private function same_minor_release( $release_parts, $updates ) { * ## OPTIONS * * [--patch] - * : Compare only the first two parts of the version number. + * : Only list patch updates + * + * [--ignore-patch] + * : Do not list patch updates * * [--minor] - * : Compare only the first part of the version number. + * : Only list minor updates + * + * [--ignore-minor] + * : Do not list minor updates * * [--field=<field>] * : Prints the value of a single field for each update. @@ -126,10 +132,16 @@ function check_update( $_, $assoc_args ) { * ## OPTIONS * * [--patch] - * : Compare only the first two parts of the version number. + * : Only list patch updates + * + * [--ignore-patch] + * : Do not list patch updates * * [--minor] - * : Compare only the first part of the version number. + * : Only list minor updates + * + * [--ignore-minor] + * : Do not list minor updates * * [--yes] * : Do not prompt for confirmation @@ -237,7 +249,9 @@ private function get_updates( $assoc_args ) { } if ( ! ( isset( $assoc_args['patch'] ) && 'patch' !== $update_type ) + && ! ( isset( $assoc_args['ignore-patch'] ) && 'patch' === $update_type ) && ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) + && ! ( isset( $assoc_args['ignore-minor'] ) && 'minor' === $update_type ) && ! $this->same_minor_release( $release_parts, $updates ) ) { $updates[] = array( From 6fd93c2fdd9813280b56e8e81a15fb17f06d1f75 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Wed, 3 Dec 2014 17:25:33 +0000 Subject: [PATCH 3314/4858] New function - WP_CLI::error_multi_line() --- php/WP_CLI/Loggers/Quiet.php | 2 +- php/WP_CLI/Loggers/Regular.php | 2 +- php/class-wp-cli.php | 23 ++++++++++++++--------- php/commands/cli.php | 3 ++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 44a86ca34b..f1140f8586 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -48,7 +48,7 @@ public function error( $message ) { * * @param array $message Message to write. */ - public function error_box( $message_lines ) { + public function error_multi_line( $message_lines ) { $message = implode( "\n", $message_lines ); fwrite( STDERR, \WP_CLI::colorize( "%RError:%n\n$message\n" ) ); diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index 32d4a772a5..d5358dee69 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -78,7 +78,7 @@ public function error( $message ) { * * @param array $message Message to write. */ - public function error_box( $message_lines ) { + public function error_multi_line( $message_lines ) { // convert tabs to four spaces, as some shells will output the tabs as variable-length $message_lines = array_map( function( $line ) { return str_replace( "\t", ' ', $line ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9d83c2e6f3..f0a5764071 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -240,20 +240,25 @@ public static function warning( $message ) { /** * Display an error in the CLI and end with a newline * - * @param string|array|WP_Error $message - * @param bool $exit if true, the script will exit() + * @param string|WP_Error $message + * @param bool $exit if true, the script will exit() */ public static function error( $message, $exit = true ) { if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) ) { - if ( is_array( $message ) ) { - self::$logger->error_box( array_map( array( __CLASS__, 'error_to_string' ), $message ) ); - } else { - self::$logger->error( self::error_to_string( $message ) ); - } + self::$logger->error( self::error_to_string( $message ) ); } - if ( $exit ) { - exit(1); + exit(1); + } + + /** + * Display an error in the CLI and end with a newline + * + * @param array $message each element from the array will be printed on its own line + */ + public static function error_multi_line( $message_lines ) { + if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) && is_array( $message_lines ) ) { + self::$logger->error_multi_line( array_map( array( __CLASS__, 'error_to_string' ), $message_lines ) ); } } diff --git a/php/commands/cli.php b/php/commands/cli.php index 8779fd567e..b1c8132d6f 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -163,6 +163,7 @@ function update( $_, $assoc_args ) { if ( empty( $updates ) ) { WP_CLI::success( "WP-CLI is at the latest version." ); + exit(0); } $newest = $updates[0]; @@ -186,7 +187,7 @@ function update( $_, $assoc_args ) { exec( "php $temp --version", $output, $status ); if ( 0 !== $status ) { - WP_CLI::error( $output, false ); + WP_CLI::error_multi_line( $output ); WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli self-update again.' ); } From 3270b1151111392bf4c9e658f5b27e6e406ef5d6 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Thu, 4 Dec 2014 11:48:43 +0000 Subject: [PATCH 3315/4858] WP_CLI\Utils\increment_version() and tests --- php/utils.php | 54 ++++++++++++++++++++++++++++++++++++++++++++ tests/test-utils.php | 37 ++++++++++++++++++++++++++++++ utils/make-phar.php | 43 ++++------------------------------- 3 files changed, 96 insertions(+), 38 deletions(-) create mode 100644 tests/test-utils.php diff --git a/php/utils.php b/php/utils.php index 963a3a4636..4b81cb8d0e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -450,3 +450,57 @@ function http_request( $method, $url, $data = null, $headers = array(), $options } } } + +/** + * Increments a version string using the "x.y.z-pre" format + * + * Can increment the major, minor or patch number by one + * If $new_version == "same" the version string is not changed + * If $new_version is not a known keyword, it will be used as the new version string directly + * + * @param string $current_version + * @param string $new_version + * @return string + */ +function increment_version( $current_version, $new_version ) { + // split version assuming the format is x.y.z-pre + $current_version = explode( '-', $current_version, 2 ); + $current_version[0] = explode( '.', $current_version[0] ); + + switch ( $new_version ) { + case 'same': + // do nothing + break; + + case 'patch': + $current_version[0][2]++; + + $current_version = array( $current_version[0] ); // drop possible pre-release info + break; + + case 'minor': + $current_version[0][1]++; + $current_version[0][2] = 0; + + $current_version = array( $current_version[0] ); // drop possible pre-release info + break; + + case 'major': + $current_version[0][0]++; + $current_version[0][1] = 0; + $current_version[0][2] = 0; + + $current_version = array( $current_version[0] ); // drop possible pre-release info + break; + + default: // not a keyword + $current_version = array( array( $new_version ) ); + break; + } + + // reconstruct version string + $current_version[0] = implode( '.', $current_version[0] ); + $current_version = implode( '-', $current_version ); + + return $current_version; +} \ No newline at end of file diff --git a/tests/test-utils.php b/tests/test-utils.php new file mode 100644 index 0000000000..005abedeb3 --- /dev/null +++ b/tests/test-utils.php @@ -0,0 +1,37 @@ +<?php + +use WP_CLI\Utils; + +class UtilsTest extends PHPUnit_Framework_TestCase { + + function testIncrementVersion() { + // keyword increments + $this->assertEquals( + Utils\increment_version( '1.2.3-pre', 'same' ), + '1.2.3-pre' + ); + + $this->assertEquals( + Utils\increment_version( '1.2.3-pre', 'patch' ), + '1.2.4' + ); + + $this->assertEquals( + Utils\increment_version( '1.2.3-pre', 'minor' ), + '1.3.0' + ); + + $this->assertEquals( + Utils\increment_version( '1.2.3-pre', 'major' ), + '2.0.0' + ); + + // custom version string + $this->assertEquals( + Utils\increment_version( '1.2.3-pre', '4.5.6-alpha1' ), + '4.5.6-alpha1' + ); + } + +} + diff --git a/utils/make-phar.php b/utils/make-phar.php index 687970ca6e..2459809fb5 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -1,10 +1,12 @@ <?php require './vendor/autoload.php'; +require './php/utils.php'; use Symfony\Component\Finder\Finder; use Ulrichsg\Getopt\Getopt; use Ulrichsg\Getopt\Option; +use WP_CLI\Utils; $getopt = new Getopt( array( new Option( null, 'version', Getopt::REQUIRED_ARGUMENT ), @@ -24,45 +26,10 @@ define( 'BE_QUIET', (bool) $getopt['quiet'] ); if ( $getopt['version'] ) { - // split version ussuming the format is x.y.z-pre - $current_version = explode( '-', file_get_contents( './VERSION' ), 2 ); - $current_version[0] = explode( '.', $current_version[0] ); + $current_version = file_get_contents( './VERSION' ); + $new_version = $getopt['version']; - switch ( $getopt['version'] ) { - case 'same': - // do nothing - break; - - case 'patch': - $current_version[0][2]++; - - $current_version = array( $current_version[0] ); // drop possible pre-release info - break; - - case 'minor': - $current_version[0][1]++; - $current_version[0][2] = 0; - - $current_version = array( $current_version[0] ); // drop possible pre-release info - break; - - case 'major': - $current_version[0][0]++; - $current_version[0][1] = 0; - $current_version[0][2] = 0; - - $current_version = array( $current_version[0] ); // drop possible pre-release info - break; - - default: - $current_version = array( array( $getopt['version'] ) ); - break; - } - - // reconstruct version string - $current_version[0] = implode( '.', $current_version[0] ); - $current_version = implode( '-', $current_version ); - file_put_contents( './VERSION', $current_version ); + file_put_contents( './VERSION', utils\increment_version( $current_version, $new_version ) ); } function add_file( $phar, $path ) { From fc41d0f938c664f90624b218f72b2f01e4d7c8ef Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Thu, 4 Dec 2014 13:07:30 +0000 Subject: [PATCH 3316/4858] add a new line at the end of php/utils.php --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 4b81cb8d0e..b80c0ea171 100644 --- a/php/utils.php +++ b/php/utils.php @@ -503,4 +503,4 @@ function increment_version( $current_version, $new_version ) { $current_version = implode( '-', $current_version ); return $current_version; -} \ No newline at end of file +} From 696dc1697057118c0a6853dd8b2de52fb14c4d1b Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Thu, 4 Dec 2014 13:34:43 +0000 Subject: [PATCH 3317/4858] Use WP_CLI\Configurator instead of Ulrichsg\Getopt\Getopt in utils/make-phar.php --- composer.json | 3 +-- utils/make-phar-spec.php | 23 +++++++++++++++++++++++ utils/make-phar.php | 23 +++++++++-------------- utils/update-phar | 2 +- 4 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 utils/make-phar-spec.php diff --git a/composer.json b/composer.json index ee4763449d..6c8a5ea5ee 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,7 @@ }, "require-dev": { "phpunit/phpunit": "3.7.*", - "behat/behat": "2.5.*", - "ulrichsg/getopt-php": "2.2.*" + "behat/behat": "2.5.*" }, "suggest": { "psy/psysh": "Enhanced `wp shell` functionality" diff --git a/utils/make-phar-spec.php b/utils/make-phar-spec.php new file mode 100644 index 0000000000..cc4fd4955f --- /dev/null +++ b/utils/make-phar-spec.php @@ -0,0 +1,23 @@ +<?php + +return array( + 'output' => array( + 'runtime' => '=<path>', + 'file' => '<path>', + 'desc' => 'Path to output file', + ), + + 'version' => array( + 'runtime' => '=<version>', + 'file' => '<version>', + 'desc' => 'New package version', + ), + + 'quiet' => array( + 'runtime' => '', + 'file' => '<bool>', + 'default' => false, + 'desc' => 'Suppress informational messages', + ), +); + diff --git a/utils/make-phar.php b/utils/make-phar.php index 2459809fb5..744e57be9d 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -4,30 +4,25 @@ require './php/utils.php'; use Symfony\Component\Finder\Finder; -use Ulrichsg\Getopt\Getopt; -use Ulrichsg\Getopt\Option; use WP_CLI\Utils; +use WP_CLI\Configurator; -$getopt = new Getopt( array( - new Option( null, 'version', Getopt::REQUIRED_ARGUMENT ), - new Option( null, 'quiet' ), - new Option( 'o', 'output', Getopt::REQUIRED_ARGUMENT ), -) ); +$configurator = new Configurator( './utils/make-phar-spec.php' ); -$getopt->parse(); +list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); -if ( ! $getopt['output'] && ! $getopt->getOperand(0) ) { - echo "usage: php -dphar.readonly=0 $argv[0] -o <path> [--quiet] [--version=same|patch|minor|major|x.y.z]\n"; +if ( ! isset( $args[0] ) || empty( $args[0] ) ) { + echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet] [--version=same|patch|minor|major|x.y.z]\n"; exit(1); } -define( 'DEST_PATH', $getopt['output'] ?: $getopt->getOperand(0) ); +define( 'DEST_PATH', $args[0] ); -define( 'BE_QUIET', (bool) $getopt['quiet'] ); +define( 'BE_QUIET', isset( $runtime_config['quiet'] ) && $runtime_config['quiet'] ); -if ( $getopt['version'] ) { +if ( isset( $runtime_config['version'] ) ) { $current_version = file_get_contents( './VERSION' ); - $new_version = $getopt['version']; + $new_version = $runtime_config['version']; file_put_contents( './VERSION', utils\increment_version( $current_version, $new_version ) ); } diff --git a/utils/update-phar b/utils/update-phar index 7eeb24f883..ee911f0a01 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -12,7 +12,7 @@ packages_repo=../wp-cli-packages fname="phar/wp-cli.phar" # generate archive -php -dphar.readonly=0 -o ./utils/make-phar.php $packages_repo/$fname --quiet --version=$version +php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet --version=$version cd $packages_repo From 02ed51480a974b1d86384d6e6393630359c03100 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 10:39:12 +0000 Subject: [PATCH 3318/4858] New behat feature for `wp cli` tasks features/cli.feature: - wp cli check-updates should return at least one update after version 0.0.0 - wp cli update should perform a successful update of version 0.0.0 --- features/bootstrap/FeatureContext.php | 29 +++++++++++++++++++++++++++ features/cli.feature | 26 ++++++++++++++++++++++++ features/steps/given.php | 5 +++++ 3 files changed, 60 insertions(+) create mode 100644 features/cli.feature diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index ae06d8eaa4..1680769694 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -91,6 +91,24 @@ public function afterScenario( $event ) { } } + /** + * @BeforeScenario @cli-update + */ + public function setLowVersion( $scope ) + { + $this->variables['TRUE_VERSION'] = file_get_contents( './VERSION' ); + file_put_contents( './VERSION', '0.0.0' ); + } + + /** + * @AfterScenario @cli-update + */ + public function restoreVersion( $scope ) + { + file_put_contents( './VERSION', $this->variables['TRUE_VERSION'] ); + unset( $this->variables['TRUE_VERSION'] ); + } + public static function create_cache_dir() { self::$suite_cache_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-suite-cache-", TRUE ); mkdir( self::$suite_cache_dir ); @@ -138,6 +156,17 @@ public function create_run_dir() { } } + public function build_phar() { + $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; + + Process::create( + Utils\esc_cmd( 'php -dphar.readonly=0 %s %2$s && chmod +x %2$s', __DIR__ . '/../../utils/make-phar.php', $this->variables['PHAR_PATH'] ), + null, + self::get_process_env_variables() + )->run_check(); + // passthru( 'php -dphar.readonly=0 ' . . $this->variables['PHAR_PATH'] . ' && chmod +x ' . $this->variables['PHAR_PATH'] ); + } + private function set_cache_dir() { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ), null, self::get_process_env_variables() )->run_check(); diff --git a/features/cli.feature b/features/cli.feature new file mode 100644 index 0000000000..4557f3b3ec --- /dev/null +++ b/features/cli.feature @@ -0,0 +1,26 @@ +Feature: `wp cli` tasks + + @cli-update + Scenario: Check for updates + Given an empty directory + And a new Phar + + When I run `{PHAR_PATH} cli check-update` + Then STDOUT should contain: + """ + package_url + """ + And STDERR should be empty + + @cli-update + Scenario: Do WP-CLI Update + Given an empty directory + And a new Phar + + When I run `{PHAR_PATH} cli update --yes` + Then STDOUT should contain: + """ + Success: + """ + And STDERR should be empty + And the return code should be 0 diff --git a/features/steps/given.php b/features/steps/given.php index 3e7a7b26d8..c2f783d6b8 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -119,3 +119,8 @@ function ( $world, $stream, $output_filter, $key ) { } ); +$steps->Given( '/^a new Phar$/', + function ( $world ) { + $world->build_phar(); + } +); \ No newline at end of file From 80978c4f057a9d76f1ef5e759dabc538ce52cd9b Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 10:46:47 +0000 Subject: [PATCH 3319/4858] Add a version param to "Given a new Phar" --- features/bootstrap/FeatureContext.php | 29 +++++++-------------------- features/cli.feature | 6 ++---- features/steps/given.php | 6 +++--- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 1680769694..7ae97d6b4d 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -91,24 +91,6 @@ public function afterScenario( $event ) { } } - /** - * @BeforeScenario @cli-update - */ - public function setLowVersion( $scope ) - { - $this->variables['TRUE_VERSION'] = file_get_contents( './VERSION' ); - file_put_contents( './VERSION', '0.0.0' ); - } - - /** - * @AfterScenario @cli-update - */ - public function restoreVersion( $scope ) - { - file_put_contents( './VERSION', $this->variables['TRUE_VERSION'] ); - unset( $this->variables['TRUE_VERSION'] ); - } - public static function create_cache_dir() { self::$suite_cache_dir = sys_get_temp_dir() . '/' . uniqid( "wp-cli-test-suite-cache-", TRUE ); mkdir( self::$suite_cache_dir ); @@ -156,15 +138,18 @@ public function create_run_dir() { } } - public function build_phar() { - $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; + public function build_phar( $version ) { + $this->variables['TRUE_VERSION'] = file_get_contents( './VERSION' ); + $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; Process::create( - Utils\esc_cmd( 'php -dphar.readonly=0 %s %2$s && chmod +x %2$s', __DIR__ . '/../../utils/make-phar.php', $this->variables['PHAR_PATH'] ), + Utils\esc_cmd( 'php -dphar.readonly=0 %s %2$s --version=%s && chmod +x %2$s', __DIR__ . '/../../utils/make-phar.php', $this->variables['PHAR_PATH'], $version ), null, self::get_process_env_variables() )->run_check(); - // passthru( 'php -dphar.readonly=0 ' . . $this->variables['PHAR_PATH'] . ' && chmod +x ' . $this->variables['PHAR_PATH'] ); + + file_put_contents( './VERSION', $this->variables['TRUE_VERSION'] ); + unset( $this->variables['TRUE_VERSION'] ); } private function set_cache_dir() { diff --git a/features/cli.feature b/features/cli.feature index 4557f3b3ec..b9b06f5be6 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -1,9 +1,8 @@ Feature: `wp cli` tasks - @cli-update Scenario: Check for updates Given an empty directory - And a new Phar + And a new Phar with version "0.0.0" When I run `{PHAR_PATH} cli check-update` Then STDOUT should contain: @@ -12,10 +11,9 @@ Feature: `wp cli` tasks """ And STDERR should be empty - @cli-update Scenario: Do WP-CLI Update Given an empty directory - And a new Phar + And a new Phar with version "0.0.0" When I run `{PHAR_PATH} cli update --yes` Then STDOUT should contain: diff --git a/features/steps/given.php b/features/steps/given.php index c2f783d6b8..3af6b32136 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -119,8 +119,8 @@ function ( $world, $stream, $output_filter, $key ) { } ); -$steps->Given( '/^a new Phar$/', - function ( $world ) { - $world->build_phar(); +$steps->Given( '/^a new Phar(?: with version "([^"]+)")$/', + function ( $world, $version ) { + $world->build_phar( $version ); } ); \ No newline at end of file From 47026a20a497552f8709559b1dcd608d7d310be3 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 11:31:22 +0000 Subject: [PATCH 3320/4858] Move version changes to make-phar.php - make-phar.php gains a new optional flag --store-version which defaults to false. The script will change the contents of VERSION only if this is true. This is false when building temporary Phars with custom versions for tests. - Because of that there is a new function set_file_contents() in make-phar.php This is similar to add_file(), but the contents of the new file are passed as an argument, instead of reading them via file_get_contents() - Behat test for building a temporary Phar with a fake version Also ensure that VERSION is not modified --- features/bootstrap/FeatureContext.php | 20 ++++++++++++++------ features/cli.feature | 15 +++++++++++++++ features/steps/given.php | 17 +++++++++++++++++ utils/make-phar-spec.php | 7 +++++++ utils/make-phar.php | 27 +++++++++++++++++++++------ utils/update-phar | 2 +- 6 files changed, 75 insertions(+), 13 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 7ae97d6b4d..a9f09a0ead 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -78,6 +78,13 @@ public static function afterSuite( SuiteEvent $event ) { } } + /** + * @BeforeScenario + */ + public function beforeScenario( $event ) { + $this->variables['SRC_DIR'] = realpath( __DIR__ . '/../..' ); + } + /** * @AfterScenario */ @@ -138,18 +145,19 @@ public function create_run_dir() { } } - public function build_phar( $version ) { - $this->variables['TRUE_VERSION'] = file_get_contents( './VERSION' ); + public function build_phar( $version = 'same' ) { $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; Process::create( - Utils\esc_cmd( 'php -dphar.readonly=0 %s %2$s --version=%s && chmod +x %2$s', __DIR__ . '/../../utils/make-phar.php', $this->variables['PHAR_PATH'], $version ), + Utils\esc_cmd( + 'php -dphar.readonly=0 %1$s %2$s --version=%3$s && chmod +x %2$s', + __DIR__ . '/../../utils/make-phar.php', + $this->variables['PHAR_PATH'], + $version + ), null, self::get_process_env_variables() )->run_check(); - - file_put_contents( './VERSION', $this->variables['TRUE_VERSION'] ); - unset( $this->variables['TRUE_VERSION'] ); } private function set_cache_dir() { diff --git a/features/cli.feature b/features/cli.feature index b9b06f5be6..7371efa28d 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -1,5 +1,20 @@ Feature: `wp cli` tasks + Scenario: Ability to set a custom version when building + Given an empty directory + And save the {SRC_DIR}/VERSION file as {TRUE_VERSION} + And a new Phar with version "1.2.3" + + When I run `{PHAR_PATH} cli version` + Then STDOUT should be: + """ + WP-CLI 1.2.3 + """ + And the {SRC_DIR}/VERSION file should be: + """ + {TRUE_VERSION} + """ + Scenario: Check for updates Given an empty directory And a new Phar with version "0.0.0" diff --git a/features/steps/given.php b/features/steps/given.php index 3af6b32136..a9f536a7c5 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -123,4 +123,21 @@ function ( $world, $stream, $output_filter, $key ) { function ( $world, $version ) { $world->build_phar( $version ); } +); + +$steps->Given( '/^save the (.+) file ([\'].+[^\'])?as \{(\w+)\}$/', + function ( $world, $filepath, $output_filter, $key ) { + $full_file = file_get_contents( $world->replace_variables( $filepath ) ); + + if ( $output_filter ) { + $output_filter = '/' . trim( str_replace( '%s', '(.+[^\b])', $output_filter ), "' " ) . '/'; + if ( false !== preg_match( $output_filter, $full_file, $matches ) ) + $output = array_pop( $matches ); + else + $output = ''; + } else { + $output = $full_file; + } + $world->variables[ $key ] = trim( $output, "\n" ); + } ); \ No newline at end of file diff --git a/utils/make-phar-spec.php b/utils/make-phar-spec.php index cc4fd4955f..d5f3165c43 100644 --- a/utils/make-phar-spec.php +++ b/utils/make-phar-spec.php @@ -13,6 +13,13 @@ 'desc' => 'New package version', ), + 'store-version' => array( + 'runtime' => '', + 'file' => '<bool>', + 'default' => false, + 'desc' => 'If true the contents of ./VERSION will be set to the value passed to --version', + ), + 'quiet' => array( 'runtime' => '', 'file' => '<bool>', diff --git a/utils/make-phar.php b/utils/make-phar.php index 744e57be9d..1841dcd34f 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -12,7 +12,7 @@ list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); if ( ! isset( $args[0] ) || empty( $args[0] ) ) { - echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet] [--version=same|patch|minor|major|x.y.z]\n"; + echo "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet] [--version=same|patch|minor|major|x.y.z] [--store-version]\n"; exit(1); } @@ -20,11 +20,17 @@ define( 'BE_QUIET', isset( $runtime_config['quiet'] ) && $runtime_config['quiet'] ); +$current_version = file_get_contents( './VERSION' ); + if ( isset( $runtime_config['version'] ) ) { - $current_version = file_get_contents( './VERSION' ); - $new_version = $runtime_config['version']; + $new_version = $runtime_config['version']; + $new_version = Utils\increment_version( $current_version, $new_version ); + + if ( isset( $runtime_config['store-version'] ) && $runtime_config['store-version'] ) { + file_put_contents( './VERSION', $new_version ); + } - file_put_contents( './VERSION', utils\increment_version( $current_version, $new_version ) ); + $current_version = $new_version; } function add_file( $phar, $path ) { @@ -36,6 +42,15 @@ function add_file( $phar, $path ) { $phar[ $key ] = file_get_contents( $path ); } +function set_file_contents( $phar, $path, $content ) { + $key = str_replace( './', '', $path ); + + if ( !BE_QUIET ) + echo "$key - $path\n"; + + $phar[ $key ] = $content; +} + $phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' ); $phar->startBuffering(); @@ -81,7 +96,8 @@ function add_file( $phar, $path ) { add_file( $phar, './vendor/autoload.php' ); add_file( $phar, './utils/get-package-require-from-composer.php' ); add_file( $phar, './vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); -add_file( $phar, './VERSION' ); + +set_file_contents( $phar, './VERSION', $current_version ); $phar->setStub( <<<EOB #!/usr/bin/env php @@ -96,4 +112,3 @@ function add_file( $phar, $path ) { $phar->stopBuffering(); echo "Generated " . DEST_PATH . "\n"; - diff --git a/utils/update-phar b/utils/update-phar index ee911f0a01..3c6a1b547b 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -12,7 +12,7 @@ packages_repo=../wp-cli-packages fname="phar/wp-cli.phar" # generate archive -php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet --version=$version +php -dphar.readonly=0 ./utils/make-phar.php $packages_repo/$fname --quiet --version=$version --store-version cd $packages_repo From fc548076b58bf4a02e9c267b288a56cd05f86ee7 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 12:05:26 +0000 Subject: [PATCH 3321/4858] fix whitespace --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index a9f09a0ead..c17d1842ba 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -146,7 +146,7 @@ public function create_run_dir() { } public function build_phar( $version = 'same' ) { - $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; + $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; Process::create( Utils\esc_cmd( From b76d88369696a1c58fa31cffb56fb9db762ff06d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 5 Dec 2014 14:26:18 -0800 Subject: [PATCH 3322/4858] Define wp_is_mobile() function It's normally defined in `vars.php`, and some plugins / themes expect it --- php/wp-settings-cli.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index d189f412f1..f2e2fc85e8 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -211,8 +211,11 @@ // Define and enforce our SSL constants wp_ssl_constants( ); -// Create common globals. +// Don't create common globals, but we still need wp_is_mobile() // require( ABSPATH . WPINC . '/vars.php' ); +function wp_is_mobile() { + return false; +} // Make taxonomies and posts available to plugins and themes. // @plugin authors: warning: these get registered again on the init hook. From 910e65012d05534174805b54f7e6c9fe44796142 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 22:50:24 +0000 Subject: [PATCH 3323/4858] `wp cli update/check-update` arguments --- php/commands/cli.php | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index b1c8132d6f..4c40336e07 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -92,15 +92,9 @@ private function same_minor_release( $release_parts, $updates ) { * [--patch] * : Only list patch updates * - * [--ignore-patch] - * : Do not list patch updates - * * [--minor] * : Only list minor updates * - * [--ignore-minor] - * : Do not list minor updates - * * [--field=<field>] * : Prints the value of a single field for each update. * @@ -132,16 +126,10 @@ function check_update( $_, $assoc_args ) { * ## OPTIONS * * [--patch] - * : Only list patch updates - * - * [--ignore-patch] - * : Do not list patch updates + * : Only perform patch updates * * [--minor] - * : Only list minor updates - * - * [--ignore-minor] - * : Do not list minor updates + * : Only perform minor updates * * [--yes] * : Do not prompt for confirmation @@ -249,10 +237,10 @@ private function get_updates( $assoc_args ) { $update_type = 'patch'; } - if ( ! ( isset( $assoc_args['patch'] ) && 'patch' !== $update_type ) - && ! ( isset( $assoc_args['ignore-patch'] ) && 'patch' === $update_type ) - && ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) - && ! ( isset( $assoc_args['ignore-minor'] ) && 'minor' === $update_type ) + if ( ! ( isset( $assoc_args['patch'] ) && $assoc_args['patch'] && 'patch' !== $update_type ) + && ! ( isset( $assoc_args['patch'] ) && ! $assoc_args['patch'] && 'patch' === $update_type ) + && ! ( isset( $assoc_args['minor'] ) && $assoc_args['minor'] && 'minor' !== $update_type ) + && ! ( isset( $assoc_args['minor'] ) && ! $assoc_args['minor'] && 'minor' === $update_type ) && ! $this->same_minor_release( $release_parts, $updates ) ) { $updates[] = array( From e02362b5ab8d6b05cc8301731975a098ea4b92c3 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 23:04:02 +0000 Subject: [PATCH 3324/4858] More Behat tests for `wp cli update` - from 0.14.0 with --patch - from 0.14.0 with --no-patch --- features/cli.feature | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/features/cli.feature b/features/cli.feature index 7371efa28d..37257dccd2 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -37,3 +37,31 @@ Feature: `wp cli` tasks """ And STDERR should be empty And the return code should be 0 + + Scenario: Patch update from 0.14.0 to 0.14.1 + Given an empty directory + And a new Phar with version "0.14.0" + + When I run `{PHAR_PATH} cli update --patch --yes` + Then STDOUT should contain: + """ + Success: Updated WP-CLI to 0.14.1 + """ + And STDERR should be empty + And the return code should be 0 + + Scenario: Not a patch update from 0.14.0 + Given an empty directory + And a new Phar with version "0.14.0" + + When I run `{PHAR_PATH} cli update --no-patch --yes` + Then STDOUT should contain: + """ + Success: + """ + And STDOUT should not contain: + """ + 0.14.1 + """ + And STDERR should be empty + And the return code should be 0 \ No newline at end of file From d2c900b61e78b5899729400f1512d5141d7dcfc4 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 5 Dec 2014 23:07:10 +0000 Subject: [PATCH 3325/4858] missing newline charater at the end of features/cli.feature --- features/cli.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/cli.feature b/features/cli.feature index 37257dccd2..d0cf96056d 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -64,4 +64,4 @@ Feature: `wp cli` tasks 0.14.1 """ And STDERR should be empty - And the return code should be 0 \ No newline at end of file + And the return code should be 0 From ccd3ece3700c6b14d588f701f2f893f0e394642f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 5 Dec 2014 15:16:01 -0800 Subject: [PATCH 3326/4858] Introduce `wp user list --network` shorthand This makes it easier to list all users in a network. --- features/user.feature | 33 +++++++++++++++++++++++++++++++++ php/commands/user.php | 10 ++++++++++ 2 files changed, 43 insertions(+) diff --git a/features/user.feature b/features/user.feature index 44bc1a2eb3..a1151b09b6 100644 --- a/features/user.feature +++ b/features/user.feature @@ -321,3 +321,36 @@ Feature: Manage WordPress users """ Password: """ + + Scenario: List network users + Given a WP multisite install + + When I run `wp user create testsubscriber testsubscriber@example.com` + Then STDOUT should contain: + """ + Success: Created user + """ + + When I run `wp user list --field=user_login` + Then STDOUT should contain: + """ + testsubscriber + """ + + When I run `wp user delete testsubscriber --yes` + Then STDOUT should contain: + """ + Success: Removed user + """ + + When I run `wp user list --field=user_login` + Then STDOUT should not contain: + """ + testsubscriber + """ + + When I run `wp user list --field=user_login --network` + Then STDOUT should contain: + """ + testsubscriber + """ diff --git a/php/commands/user.php b/php/commands/user.php index 76a347fac9..103b9e6594 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -32,6 +32,9 @@ public function __construct() { * [--<field>=<value>] * : Control output by one or more arguments of get_users(). * + * [--network] + * : List all users in the network for multisite. + * * [--field=<field>] * : Prints the value of a single field for each user. * @@ -85,6 +88,13 @@ public function list_( $args, $assoc_args ) { $assoc_args['fields'] = 'all_with_meta'; } + if ( isset( $assoc_args['network'] ) ) { + if ( ! is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + $assoc_args['blog_id'] = 0; + } + $users = get_users( $assoc_args ); if ( 'ids' == $formatter->format ) { From c0fe260e295061c6ea827ffb1df42f75c1c7ec87 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 5 Dec 2014 15:20:05 -0800 Subject: [PATCH 3327/4858] Roles shouldn't be exposed with `--network` --- php/commands/user.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 103b9e6594..fae201e42b 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -80,19 +80,26 @@ public function __construct() { * @subcommand list */ public function list_( $args, $assoc_args ) { - $formatter = $this->get_formatter( $assoc_args ); - - if ( 'ids' == $formatter->format ) { - $assoc_args['fields'] = 'ids'; - } else { - $assoc_args['fields'] = 'all_with_meta'; - } if ( isset( $assoc_args['network'] ) ) { if ( ! is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); } $assoc_args['blog_id'] = 0; + if ( isset( $assoc_args['fields'] ) ) { + $fields = explode( ',', $assoc_args['fields'] ); + $assoc_args['fields'] = array_diff( $fields, array( 'roles' ) ); + } else { + $assoc_args['fields'] = array_diff( $this->obj_fields, array( 'roles' ) ); + } + } + + $formatter = $this->get_formatter( $assoc_args ); + + if ( 'ids' == $formatter->format ) { + $assoc_args['fields'] = 'ids'; + } else { + $assoc_args['fields'] = 'all_with_meta'; } $users = get_users( $assoc_args ); From e98fa0f3c3520024396b01a7022ab9e6b2bac9b6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 5 Dec 2014 15:27:47 -0800 Subject: [PATCH 3328/4858] Test for #1548 --- features/menu.feature | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index b350f094dc..8c0f059bde 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -95,6 +95,9 @@ Feature: Manage WordPress menus | custom | WordPress | | 2 | http://wordpress.org | {POST_ITEM_ID} | | taxonomy | Test term | | 3 | {TERM_LINK} | 0 | + When I run `wp menu item list sidebar-menu --format=ids` + Then STDOUT should not be empty + When I run `wp menu item delete {CUSTOM_ITEM_ID}` And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: From 992e0ac120c1906243c7f97c99b76da67b5dcb00 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 5 Dec 2014 15:30:04 -0800 Subject: [PATCH 3329/4858] Use `db_id` as the id for `wp menu list item` --- php/commands/menu.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index 0277cbba06..136a6e4219 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -239,6 +239,12 @@ public function list_( $args, $assoc_args ) { return $item; }, $items ); + if ( ! empty( $assoc_args['format'] ) && 'ids' == $assoc_args['format'] ) { + $items = array_map( function( $item ) { + return $item->db_id; + }, $items ); + } + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $items ); From 59c9f77ed6427091b53dd8a48fcbe9c7e22373a7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 5 Dec 2014 15:40:46 -0800 Subject: [PATCH 3330/4858] Don't throw error, as this will change existing behavior More verbose tests --- features/option.feature | 13 +++++++++++-- php/commands/option.php | 15 +++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/features/option.feature b/features/option.feature index ee9a7a509d..ba1afb6927 100644 --- a/features/option.feature +++ b/features/option.feature @@ -21,11 +21,20 @@ Feature: Manage WordPress options # Integer values - When I run `wp option update blog_public 0` + When I run `wp option update blog_public 1` Then STDOUT should not be empty + When I run `wp option update blog_public 0` + Then STDOUT should contain: + """ + Success: Updated 'blog_public' option. + """ + When I run the previous command again - Then STDOUT should not be empty + Then STDOUT should contain: + """ + Success: Value passed for 'blog_public' option is unchanged. + """ When I run `wp option get blog_public` Then STDOUT should be: diff --git a/php/commands/option.php b/php/commands/option.php index ea5d17f7d6..7ab27d3ffa 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -104,15 +104,14 @@ public function update( $args, $assoc_args ) { $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); $value = WP_CLI::read_value( $value, $assoc_args ); - $result = update_option( $key, $value ); - - // update_option() returns false if the value is the same - if ( ! $result ) { - WP_CLI::error( "Could not update option '$key'." ); - } else if ( $value == get_option( $key ) ) { - WP_CLI::error( "Value passed for '$key' option is unchanged." ); + if ( $value === get_option( $key ) ) { + WP_CLI::success( "Value passed for '$key' option is unchanged." ); } else { - WP_CLI::success( "Updated '$key' option." ); + if ( update_option( $key, $value ) ) { + WP_CLI::success( "Updated '$key' option." ); + } else { + WP_CLI::error( "Could not update option '$key'." ); + } } } From d6756825ade291e0152289253e7446cfab29580d Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Mon, 8 Dec 2014 13:10:28 +0000 Subject: [PATCH 3331/4858] Force SHA-512 signature for Phars --- utils/make-phar.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 744e57be9d..bdae345006 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -38,6 +38,8 @@ function add_file( $phar, $path ) { $phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' ); +$phar->setSignatureAlgorithm( Phar::SHA512 ); + $phar->startBuffering(); // PHP files @@ -97,3 +99,5 @@ function add_file( $phar, $path ) { echo "Generated " . DEST_PATH . "\n"; +$signature = $phar->getSignature(); +echo "{$signature['hash_type']} signature: {$signature['hash']}\n"; \ No newline at end of file From 30c93ebb545a18c108bf65e99158a19fda5500a7 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Mon, 8 Dec 2014 15:12:21 +0000 Subject: [PATCH 3332/4858] checksums for nightly builds --- ci/deploy.sh | 11 ++++++++--- utils/test-phar-download | 5 +++++ utils/update-phar | 4 +++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index e3b17b39f0..8829599d53 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -30,10 +30,15 @@ git config user.name "Travis CI" git config user.email "travis@travis-ci.org" git config push.default "current" -mv $WP_CLI_BIN_DIR/wp phar/wp-cli-nightly.phar -chmod -x phar/wp-cli-nightly.phar +fname="phar/wp-cli-nightly.phar" -git add phar/wp-cli-nightly.phar +mv $WP_CLI_BIN_DIR/wp $fname +chmod -x $fname + +md5sum $fname | cut -d ' ' -f 1 > $fname.md5 +sha512sum $fname | cut -d ' ' -f 1 > $fname.sha512 + +git add $fname.phar $fname.md5 $fname.sha512 git commit -m "phar build: $TRAVIS_REPO_SLUG@$TRAVIS_COMMIT" git push diff --git a/utils/test-phar-download b/utils/test-phar-download index f1a47e5190..f4c9ad7f48 100755 --- a/utils/test-phar-download +++ b/utils/test-phar-download @@ -4,3 +4,8 @@ actual_checksum=$(curl http://wp-cli.org/packages/phar/wp-cli.phar | md5sum | cu echo "expected:" $(curl -s http://wp-cli.org/packages/phar/wp-cli.phar.md5) echo "actual: " $actual_checksum + +actual_checksum=$(curl http://wp-cli.org/packages/phar/wp-cli.phar | sha512sum | cut -d ' ' -f 1) + +echo "expected SHA-512:" $(curl -s http://wp-cli.org/packages/phar/wp-cli.phar.sha512) +echo "actual SHA-512: " $actual_checksum diff --git a/utils/update-phar b/utils/update-phar index ee911f0a01..009b5542d0 100755 --- a/utils/update-phar +++ b/utils/update-phar @@ -41,7 +41,9 @@ fi echo $md5hash | cut -d ' ' -f 1 > $fname.md5 -git add $fname $fname.md5 +sha512sum $fname | cut -d ' ' -f 1 > $fname.sha512 + +git add $fname $fname.md5 $fname.sha512 git commit -m "$new_commit_subj" From 4f852f6861cafa267e557fa36dceb54502b5bf14 Mon Sep 17 00:00:00 2001 From: Alex Mills <git@viper007bond.com> Date: Wed, 10 Dec 2014 18:07:53 -0800 Subject: [PATCH 3333/4858] Disable colors by default when being run under Windows. Colors don't render correctly. --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 787d4dd52c..c2e29132d7 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -453,7 +453,7 @@ public function in_color() { private function init_colorization() { if ( 'auto' === $this->config['color'] ) { - $this->colorize = !\cli\Shell::isPiped(); + $this->colorize = ( !\cli\Shell::isPiped() && !\WP_CLI\Utils\is_windows() ); } else { $this->colorize = $this->config['color']; } From 01190b6e8fe20629dd81095e350f958c7bcbf682 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 15 Dec 2014 12:12:55 -0200 Subject: [PATCH 3334/4858] add test scenario for exporting posts from a given category --- features/export.feature | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/features/export.feature b/features/export.feature index 8539e309c2..7f5de8997b 100644 --- a/features/export.feature +++ b/features/export.feature @@ -158,3 +158,50 @@ Feature: Export content. """ 10 """ + + Scenario: Export posts from a given category + Given a WP install + And these installed and active plugins: + """ + wordpress-importer + """ + + When I run `wp term create category Apple --porcelain` + Then STDOUT should be a number + And save STDOUT as {TERM_ID} + + When I run `wp site empty --yes` + And I run `wp post generate --post_type=post --count=10` + And I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 10 + """ + + When I run `for id in $(wp post list --posts_per_page=5 --ids); do wp post term add $id category Apple; done` + And I run `wp post list --post_type=post --cat={TERM_ID} --format=count` + Then STDOUT should be: + """ + 5 + """ + + When I run `wp export --post_type=post --category=apple` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 5 + """ From 058af9db07b194842c67ca9306b5f2f629f8a18f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 15 Dec 2014 12:35:45 -0200 Subject: [PATCH 3335/4858] category information should be included before posts on export file --- features/export.feature | 4 ++++ php/export/class-wp-export-query.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/features/export.feature b/features/export.feature index 7f5de8997b..196bca3359 100644 --- a/features/export.feature +++ b/features/export.feature @@ -187,6 +187,10 @@ Feature: Export content. When I run `wp export --post_type=post --category=apple` And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + Then the {EXPORT_FILE} file should contain: + """ + <wp:category_nicename>apple</wp:category_nicename> + """ When I run `wp site empty --yes` Then STDOUT should not be empty diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index d826d17f68..6f5bb9bf31 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -72,7 +72,7 @@ public function authors() { public function categories() { if ( $this->category ) { - return $this->category; + return array( $this->category ); } if ( $this->filters['post_type'] ) { return array(); From b3d7b1c5c3e65d9cbd69da0303308dc1206d29c9 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 16 Dec 2014 12:07:33 -0200 Subject: [PATCH 3336/4858] author_email is not always in the WXR file --- php/commands/import.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index a0fd39d54e..eca7db4c20 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -80,9 +80,11 @@ private function import_wxr( $file, $args ) { $author = new \stdClass; // Always in the WXR $author->user_login = $wxr_author['author_login']; - $author->user_email = $wxr_author['author_email']; // Should be in the WXR; no guarantees + if ( isset ( $wxr_author['author_email'] ) ) { + $author->user_email = $wxr_author['author_email']; + } if ( isset( $wxr_author['author_display_name'] ) ) $author->display_name = $wxr_author['author_display_name']; if ( isset( $wxr_author['author_first_name'] ) ) From 4606d3210f6932afd3b343a7b72580f6a209def7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 16 Dec 2014 11:54:45 -0800 Subject: [PATCH 3337/4858] Alias `wp theme uninstall` to `wp theme delete` Even though themes don't have an uninstall process, plugins do. This brings them to closer interface parity. --- php/commands/theme.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 9a09e10f0f..5843333d8e 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -502,6 +502,8 @@ function is_installed( $args, $assoc_args = array() ) { * ## EXAMPLES * * wp theme delete twentyeleven + * + * @alias uninstall */ function delete( $args ) { foreach ( $this->fetcher->get_many( $args ) as $theme ) { From dd03e18d79048c27f833e974bd3533fba740b68c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 16 Dec 2014 12:32:44 -0800 Subject: [PATCH 3338/4858] Report HTTP error code on failure to install This gives the end user more information as to why their command failed. --- php/WP_CLI/CommandWithUpgrade.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 982cbee279..b24f1c6fe5 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -187,10 +187,11 @@ protected static function alter_api_response( $response, $version ) { // check if the requested version exists $response = wp_remote_head( $response->download_link ); - if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { + $response_code = wp_remote_retrieve_response_code( $response ); + if ( 200 !== $response_code ) { \WP_CLI::error( sprintf( - "Can't find the requested %s's version %s in the WordPress.org %s repository.", - $download_type, $version, $download_type ) ); + "Can't find the requested %s's version %s in the WordPress.org %s repository (HTTP code %d).", + $download_type, $version, $download_type, $response_code ) ); } } } From 76e9d690bd6f1756f02a7996c4487683140eb716 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 16 Dec 2014 12:48:50 -0800 Subject: [PATCH 3339/4858] Update php-cli-tools to v0.10.3 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6c8a5ea5ee..8d35b340c9 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.10.2", + "wp-cli/php-cli-tools": "0.10.3", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From 4a1631d166376a8e7031238051eabf6bc2432ba4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 16 Dec 2014 13:16:09 -0800 Subject: [PATCH 3340/4858] Failing test condition for #1541 --- features/post-meta.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/post-meta.feature b/features/post-meta.feature index 19a92cb6f3..7fd2eba5c3 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -12,6 +12,12 @@ Feature: Manage post custom fields bar """ + When I try `wp post meta get 2 foo` + Then STDERR should be: + """ + Error: Could not find the post with ID 2. + """ + When I run `wp post-meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty From 292da5952b6b6fe6a95799eac9550fcb47fe3e45 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 16 Dec 2014 13:18:11 -0800 Subject: [PATCH 3341/4858] Also test user meta --- features/user-meta.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/user-meta.feature b/features/user-meta.feature index a7adffae60..8d96312b24 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -12,6 +12,12 @@ Feature: Manage user custom fields bar """ + When I try `wp user-meta get 2 foo` + Then STDERR should be: + """ + Error: Invalid user ID, email or login: '2' + """ + When I run `wp user-meta set admin foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty From d41d8fed8566f70370cb9084eab1f5c8e04678d7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 16 Dec 2014 13:28:23 -0800 Subject: [PATCH 3342/4858] Check that post ID exists before changing metadata --- features/post-meta.feature | 4 ++-- php/WP_CLI/CommandWithMeta.php | 20 ++++++++++++++++++++ php/commands/post.php | 11 +++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/features/post-meta.feature b/features/post-meta.feature index 7fd2eba5c3..821be2fad6 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -12,10 +12,10 @@ Feature: Manage post custom fields bar """ - When I try `wp post meta get 2 foo` + When I try `wp post meta get 999999 foo` Then STDERR should be: """ - Error: Could not find the post with ID 2. + Error: Could not find the post with ID 999999. """ When I run `wp post-meta set 1 foo '[ "1", "2" ]' --format=json` diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 7b54511a1b..1d1f72ecae 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -34,6 +34,8 @@ public function list_( $args, $assoc_args ) { $keys = ! empty( $assoc_args['keys'] ) ? explode( ',', $assoc_args['keys'] ) : array(); + $object_id = $this->check_object_id( $object_id ); + $metadata = get_metadata( $this->meta_type, $object_id ); if ( ! $metadata ) { $metadata = array(); @@ -80,6 +82,8 @@ public function list_( $args, $assoc_args ) { public function get( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; + $object_id = $this->check_object_id( $object_id ); + $value = \get_metadata( $this->meta_type, $object_id, $meta_key, true ); if ( '' === $value ) @@ -105,6 +109,8 @@ public function delete( $args, $assoc_args ) { $meta_value = ! empty( $args[2] ) ? $args[2] : ''; + $object_id = $this->check_object_id( $object_id ); + $success = \delete_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { @@ -137,6 +143,8 @@ public function add( $args, $assoc_args ) { $meta_value = \WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); $meta_value = \WP_CLI::read_value( $meta_value, $assoc_args ); + $object_id = $this->check_object_id( $object_id ); + $success = \add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { @@ -171,6 +179,8 @@ public function update( $args, $assoc_args ) { $meta_value = \WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); $meta_value = \WP_CLI::read_value( $meta_value, $assoc_args ); + $object_id = $this->check_object_id( $object_id ); + $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { @@ -193,5 +203,15 @@ private function get_fields() { ); } + /** + * Check that the object ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + // Needs to be set in subclass + return $object_id; + } + } diff --git a/php/commands/post.php b/php/commands/post.php index a5977e565f..edde22682f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -478,6 +478,17 @@ private function read_from_file_or_stdin( $arg ) { */ class Post_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'post'; + + /** + * Check that the post ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + $fetcher = new \WP_CLI\Fetchers\Post; + $post = $fetcher->get_check( $object_id ); + return $post->ID; + } } /** From f8e03be4a478762007058c179342440c84022426 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:13:43 -0800 Subject: [PATCH 3343/4858] Drop test for term with non-existent parent Core's term API has changed, and no longer will permit the pre-condition. Our code still works; we just don't need to test for it anymore. --- features/export.feature | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/features/export.feature b/features/export.feature index 196bca3359..40caccd2f7 100644 --- a/features/export.feature +++ b/features/export.feature @@ -9,22 +9,6 @@ Feature: Export content. All done with export """ - Scenario: Term with a non-existent parent - Given a WP install - - When I run `wp term create category Apple --porcelain` - Then STDOUT should be a number - And save STDOUT as {TERM_ID} - - When I run `wp term update category {TERM_ID} --parent=99` - Then STDOUT should not be empty - - When I try `wp export` - Then STDERR should be: - """ - Error: Term is missing a parent. - """ - Scenario: Export argument validator Given a WP install From 04a8a7168d00cebbf9719bf63b356efd086a5c2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:17:23 -0800 Subject: [PATCH 3344/4858] Explicitly install WordPress importer This will let us catch plugin installation failures, instead of letting the precondition pass and test fail later --- features/export.feature | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/features/export.feature b/features/export.feature index 40caccd2f7..a342d608cb 100644 --- a/features/export.feature +++ b/features/export.feature @@ -38,10 +38,9 @@ Feature: Export content. Scenario: Export with post_type and post_status argument Given a WP install - And these installed and active plugins: - """ - wordpress-importer - """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should not be empty When I run `wp site empty --yes` And I run `wp post generate --post_type=page --post_status=draft --count=10` @@ -74,10 +73,9 @@ Feature: Export content. Scenario: Export only one post Given a WP install - And these installed and active plugins: - """ - wordpress-importer - """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should not be empty When I run `wp post generate --count=10` And I run `wp post list --format=count` @@ -107,10 +105,9 @@ Feature: Export content. Scenario: Export posts within a given date range Given a WP install - And these installed and active plugins: - """ - wordpress-importer - """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should not be empty When I run `wp site empty --yes` And I run `wp post generate --post_type=post --post_date=2013-08-01 --count=10` @@ -145,10 +142,9 @@ Feature: Export content. Scenario: Export posts from a given category Given a WP install - And these installed and active plugins: - """ - wordpress-importer - """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should not be empty When I run `wp term create category Apple --porcelain` Then STDOUT should be a number From 9e1892baef2d94b5e2b04e5e36e6c4b8721999d3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:35:18 -0800 Subject: [PATCH 3345/4858] Test comment validation for comment meta --- features/comment-meta.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/comment-meta.feature b/features/comment-meta.feature index 5eedef6169..f6f779ecb0 100644 --- a/features/comment-meta.feature +++ b/features/comment-meta.feature @@ -12,6 +12,12 @@ Feature: Manage comment custom fields bar """ + When I try `wp comment meta get 999999 foo` + Then STDERR should be: + """ + Error: Invalid comment ID. + """ + When I run `wp comment-meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty From d247ec812251114b2a3310259a6a7273282e66be Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:37:58 -0800 Subject: [PATCH 3346/4858] Validate comment ID for comment meta --- php/commands/comment.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/php/commands/comment.php b/php/commands/comment.php index fa19bad29e..662f4f7340 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -440,6 +440,17 @@ public function url( $args ) { */ class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'comment'; + + /** + * Check that the comment ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + $fetcher = new \WP_CLI\Fetchers\Comment; + $comment = $fetcher->get_check( $object_id ); + return $comment->comment_ID; + } } WP_CLI::add_command( 'comment', 'Comment_Command' ); From d470978e9993352e48882c592254e0d2b944733f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:38:18 -0800 Subject: [PATCH 3347/4858] Fix error message used in test --- features/comment-meta.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/comment-meta.feature b/features/comment-meta.feature index f6f779ecb0..f1bb0abf3b 100644 --- a/features/comment-meta.feature +++ b/features/comment-meta.feature @@ -15,7 +15,7 @@ Feature: Manage comment custom fields When I try `wp comment meta get 999999 foo` Then STDERR should be: """ - Error: Invalid comment ID. + Error: Could not find the comment with ID 999999. """ When I run `wp comment-meta set 1 foo '[ "1", "2" ]' --format=json` From 012d934a99456b132a1cb529e83a38916a33411e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:49:45 -0800 Subject: [PATCH 3348/4858] Use our formatter, so we can catch errors --- features/core.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index c68af4ba5d..e6201b8b04 100644 --- a/features/core.feature +++ b/features/core.feature @@ -288,7 +288,7 @@ Feature: Manage WordPress installation | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | - When I run `wp core check-update --field=version | wc -l` + When I run `wp core check-update --format=count` Then STDOUT should be: """ 3 @@ -300,7 +300,7 @@ Feature: Manage WordPress installation | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | - When I run `wp core check-update --major --field=version | wc -l` + When I run `wp core check-update --major --format=count` Then STDOUT should be: """ 2 @@ -311,7 +311,7 @@ Feature: Manage WordPress installation | version | update_type | package_url | | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | - When I run `wp core check-update --minor --field=version | wc -l` + When I run `wp core check-update --minor --format=count` Then STDOUT should be: """ 1 From 7b6a9d28fc2ed28f6dc7ae8edcffc988f72fcd5c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 12:53:10 -0800 Subject: [PATCH 3349/4858] Update version check test to accommodate WP4.1 --- features/core.feature | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index e6201b8b04..b226393cb3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -284,6 +284,7 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | + | 4.1 | major | https://wordpress.org/wordpress-4.1.zip | | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | @@ -291,19 +292,20 @@ Feature: Manage WordPress installation When I run `wp core check-update --format=count` Then STDOUT should be: """ - 3 + 4 """ When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | + | 4.1 | major | https://wordpress.org/wordpress-4.1.zip | | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: """ - 2 + 3 """ When I run `wp core check-update --minor` From de73ef1dccece8477d729921483ae13bdc4572d1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 18 Dec 2014 13:22:46 -0800 Subject: [PATCH 3350/4858] Use Travis' nifty dependency caching --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b5b6e3185f..c78c12632c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,6 +46,10 @@ script: ./ci/test.sh after_success: ./ci/deploy.sh +cache: + directories: + - vendor + notifications: email: on_success: never From cc34083c3e968d40566d2b81b83ba40a7aad6cf6 Mon Sep 17 00:00:00 2001 From: Stephen Edgar <stephen@netweb.com.au> Date: Fri, 19 Dec 2014 12:21:54 +1100 Subject: [PATCH 3351/4858] Use new Travis container-based infrastructure for improved speed and cache http://docs.travis-ci.com/user/workers/container-based-infrastructure/ --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index c78c12632c..b6bf25ecae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +sudo: false + language: php php: From 61eeda1a240c9cdc27cf40514a5abe7e9e0d2b8f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 11:55:02 -0800 Subject: [PATCH 3352/4858] For performance, use a plugin we're already using --- features/plugin.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index c79aee297b..21a98e663d 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -164,13 +164,13 @@ Feature: Manage WordPress plugins Scenario: Network activate a plugin Given a WP multisite install - When I run `wp plugin install user-switching --activate-network` + When I run `wp plugin activate akismet --network` Then STDOUT should not be empty When I run `wp plugin list --fields=name,status` Then STDOUT should be a table containing rows: | name | status | - | user-switching | active-network | + | akismet | active-network | Scenario: List plugins Given a WP install From 779649b3f01ab91d686d4e6351611ccdad37ad86 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 12:06:02 -0800 Subject: [PATCH 3353/4858] More reliable behavior for network activating a plugin * If the plugin is already active, allow it to be network-activated. * If the plugin is already network-active, don't change status. --- features/plugin.feature | 28 +++++++++++++++++++++++++--- php/commands/plugin.php | 9 ++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 21a98e663d..df1b50b3c5 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -161,16 +161,38 @@ Feature: Manage WordPress plugins Status: Network Active """ + @daniel Scenario: Network activate a plugin Given a WP multisite install - When I run `wp plugin activate akismet --network` - Then STDOUT should not be empty + When I run `wp plugin activate akismet` + Then STDOUT should contain: + """ + Success: Plugin 'akismet' activated. + """ When I run `wp plugin list --fields=name,status` Then STDOUT should be a table containing rows: | name | status | - | akismet | active-network | + | akismet | active | + + When I run `wp plugin activate akismet` + Then STDERR should contain: + """ + Warning: Plugin 'akismet' is already active. + """ + + When I run `wp plugin activate akismet --network` + Then STDOUT should contain: + """ + Success: Plugin 'akismet' network activated. + """ + + When I run `wp plugin activate akismet --network` + Then STDERR should contain: + """ + Warning: Plugin 'akismet' is already network active. + """ Scenario: List plugins Given a WP install diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 1cdaadaae9..ce05cd800e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -161,12 +161,15 @@ function activate( $args, $assoc_args = array() ) { } else { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { $status = $this->get_status( $plugin->file ); + // Network-active is the highest level of activation status + if ( 'active-network' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); + continue; + } + // Don't reactivate active plugins, but do let them become network-active if ( ! $network_wide && 'active' === $status ) { WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); continue; - } else if ( $network_wide && 'active-network' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); - continue; } activate_plugin( $plugin->file, '', $network_wide ); From deb90bd4c5d29e23f1ab311d44678951863b4876 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 12:07:17 -0800 Subject: [PATCH 3354/4858] Drop tag used for local dev --- features/plugin.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index df1b50b3c5..dd04762d0f 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -161,7 +161,6 @@ Feature: Manage WordPress plugins Status: Network Active """ - @daniel Scenario: Network activate a plugin Given a WP multisite install From fbe94017020f04f57cf52dc0a2d2fe68839e972b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 12:08:02 -0800 Subject: [PATCH 3355/4858] Drop tests we no longer need --- features/plugin.feature | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index dd04762d0f..49811617b8 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -222,39 +222,6 @@ Feature: Manage WordPress plugins | name | status | | akismet | active | - Scenario: Activate a plugin which is already active - Given a WP multisite install - - When I run `wp plugin activate akismet` - Then STDOUT should be: - """ - Success: Plugin 'akismet' activated. - """ - - When I try `wp plugin activate akismet` - Then STDERR should be: - """ - Warning: Plugin 'akismet' is already active. - """ - - When I run `wp plugin deactivate akismet` - Then STDOUT should be: - """ - Success: Plugin 'akismet' deactivated. - """ - - When I run `wp plugin activate akismet --network` - Then STDOUT should be: - """ - Success: Plugin 'akismet' network activated. - """ - - When I try `wp plugin activate akismet --network` - Then STDERR should be: - """ - Warning: Plugin 'akismet' is already network active. - """ - Scenario: Plugin name with HTML entities Given a WP install From 80e50b9a47327d444f5f988c6f18d8d76626791b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 12:24:08 -0800 Subject: [PATCH 3356/4858] More consistent behavior for plugin deactivation * Network active plugins must be deactivated with `--network` flag * Throw a warning when an inactive plugin is attempted to be deactivated * Active plugins must be deactivated before network activating --- features/plugin.feature | 18 ++++++++++++++++++ php/commands/plugin.php | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 49811617b8..1436c23257 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -193,6 +193,24 @@ Feature: Manage WordPress plugins Warning: Plugin 'akismet' is already network active. """ + When I run `wp plugin deactivate akismet` + Then STDERR should contain: + """ + Warning: Plugin 'akismet' is network active and must be deactivated with --network flag. + """ + + When I run `wp plugin deactivate akismet --network` + Then STDOUT should contain: + """ + Success: Plugin 'akismet' network deactivated. + """ + + When I run `wp plugin deactivate akismet` + Then STDERR should contain: + """ + Warning: Plugin 'akismet' isn't active. + """ + Scenario: List plugins Given a WP install diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ce05cd800e..6cd60ff4cd 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -172,6 +172,11 @@ function activate( $args, $assoc_args = array() ) { continue; } + // Plugins need to be deactivated before being network activated + if ( $network_wide && 'active' === $status ) { + deactivate_plugins( $plugin->file, false, false ); + } + activate_plugin( $plugin->file, '', $network_wide ); $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); @@ -201,6 +206,19 @@ function deactivate( $args, $assoc_args = array() ) { $this->update_plugins_status( "deactivate", $network_wide ); } else { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { + + $status = $this->get_status( $plugin->file ); + // Network active plugins must be explicitly deactivated + if ( ! $network_wide && 'active-network' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is network active and must be deactivated with --network flag." ); + continue; + } + + if ( ! in_array( $status, array( 'active', 'active-network' ) ) ) { + WP_CLI::warning( "Plugin '{$plugin->name}' isn't active." ); + continue; + } + deactivate_plugins( $plugin->file, false, $network_wide ); $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); From 53776e5c64c09376a7eadfc98e96285bbcb2032e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 12:33:43 -0800 Subject: [PATCH 3357/4858] Update plugin fetcher to match on full path WordPress stores dirname/filename.php in the database, so this is a valid name to use --- php/WP_CLI/Fetchers/Plugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/WP_CLI/Fetchers/Plugin.php b/php/WP_CLI/Fetchers/Plugin.php index 5f29dfc31d..13ccfaf25f 100644 --- a/php/WP_CLI/Fetchers/Plugin.php +++ b/php/WP_CLI/Fetchers/Plugin.php @@ -21,6 +21,7 @@ class Plugin extends Base { public function get( $name ) { foreach ( get_plugins() as $file => $_ ) { if ( $file === "$name.php" || + ( $name && $file === $name ) || ( dirname( $file ) === $name && $name !== '.' ) ) { return (object) compact( 'name', 'file' ); } From 678593f338d0d257eb6b3e9075ff68e1e44fb449 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 19 Dec 2014 12:39:12 -0800 Subject: [PATCH 3358/4858] Drop unnecessary abstraction We're dropping duplicate code, and reusing our status checking logic --- php/commands/plugin.php | 109 +++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 63 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 6cd60ff4cd..349e13c94a 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -154,34 +154,36 @@ protected function get_all_items() { */ function activate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); - $enable_all = isset( $assoc_args['all'] ); - if ( $enable_all ) { - $this->update_plugins_status( "activate", $network_wide ); - } else { - foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - $status = $this->get_status( $plugin->file ); - // Network-active is the highest level of activation status - if ( 'active-network' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); - continue; - } - // Don't reactivate active plugins, but do let them become network-active - if ( ! $network_wide && 'active' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); - continue; - } - - // Plugins need to be deactivated before being network activated - if ( $network_wide && 'active' === $status ) { - deactivate_plugins( $plugin->file, false, false ); - } - - activate_plugin( $plugin->file, '', $network_wide ); - - $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); + if ( isset( $assoc_args['all'] ) ) { + $args = array_map( function( $file ){ + return Utils\get_plugin_name( $file ); + }, array_keys( get_plugins() ) ); + } + + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { + $status = $this->get_status( $plugin->file ); + // Network-active is the highest level of activation status + if ( 'active-network' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); + continue; + } + // Don't reactivate active plugins, but do let them become network-active + if ( ! $network_wide && 'active' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is already active." ); + continue; + } + + // Plugins need to be deactivated before being network activated + if ( $network_wide && 'active' === $status ) { + deactivate_plugins( $plugin->file, false, false ); } + + activate_plugin( $plugin->file, '', $network_wide ); + + $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); } + } /** @@ -202,27 +204,29 @@ function deactivate( $args, $assoc_args = array() ) { $network_wide = isset( $assoc_args['network'] ); $disable_all = isset( $assoc_args['all'] ); - if ( $disable_all ) { - $this->update_plugins_status( "deactivate", $network_wide ); - } else { - foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - - $status = $this->get_status( $plugin->file ); - // Network active plugins must be explicitly deactivated - if ( ! $network_wide && 'active-network' === $status ) { - WP_CLI::warning( "Plugin '{$plugin->name}' is network active and must be deactivated with --network flag." ); - continue; - } + if ( isset( $assoc_args['all'] ) ) { + $args = array_map( function( $file ){ + return Utils\get_plugin_name( $file ); + }, array_keys( get_plugins() ) ); + } - if ( ! in_array( $status, array( 'active', 'active-network' ) ) ) { - WP_CLI::warning( "Plugin '{$plugin->name}' isn't active." ); - continue; - } + foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - deactivate_plugins( $plugin->file, false, $network_wide ); + $status = $this->get_status( $plugin->file ); + // Network active plugins must be explicitly deactivated + if ( ! $network_wide && 'active-network' === $status ) { + WP_CLI::warning( "Plugin '{$plugin->name}' is network active and must be deactivated with --network flag." ); + continue; + } - $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); + if ( ! in_array( $status, array( 'active', 'active-network' ) ) ) { + WP_CLI::warning( "Plugin '{$plugin->name}' isn't active." ); + continue; } + + deactivate_plugins( $plugin->file, false, $network_wide ); + + $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); } } @@ -616,27 +620,6 @@ private function active_output( $name, $file, $network_wide, $action ) { } } - /** - * Enable or disable all plugins. - */ - private function update_plugins_status( $action, $network_wide ) { - $status = ( $action == "activate" ) ? "active" : "inactive"; - foreach ( get_plugins() as $file => $details ) { - if ( $this->get_status( $file ) == $status ) { - continue; - } - - if ( $action == "activate" ) { - activate_plugins( $file, false, $network_wide ); - } else { - deactivate_plugins( $file, false, $network_wide ); - } - - $name = Utils\get_plugin_name( $file ); - $this->active_output( $name, $file, $network_wide, $action ); - } - } - protected function get_status( $file ) { if ( is_plugin_active_for_network( $file ) ) return 'active-network'; From d59761f63f36c31a73d07d34269a9e7f9e03acee Mon Sep 17 00:00:00 2001 From: "Svetoslav Marinov (Slavi)" <slavi@orbisius.com> Date: Sun, 21 Dec 2014 14:48:14 +0200 Subject: [PATCH 3359/4858] Fix: handling the case where plugins that are not in own folders e.g. Hello Dolly -> plugins/hello.php --- php/commands/plugin.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 1cdaadaae9..6082ed770a 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -647,7 +647,13 @@ private function _delete( $plugin ) { $path = path_join( WP_PLUGIN_DIR, $plugin_dir ); if ( \WP_CLI\Utils\is_windows() ) { - $command = 'rd /s /q '; + // Handles plugins that are not in own folders + // e.g. Hello Dolly -> plugins/hello.php + if ( is_file( $path ) ) { + $command = 'del /f /q '; + } else { + $command = 'rd /s /q '; + } $path = str_replace( "/", "\\", $path ); } else { $command = 'rm -rf '; From 2b89a1584994aa1b1433bb995f65b4fe10603ea0 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 14:50:55 -0200 Subject: [PATCH 3360/4858] remove extra lines before global parameters when calling `wp post --help` --- php/WP_CLI/Dispatcher/CompositeCommand.php | 4 ++++ templates/man-params.mustache | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index cc7258d03a..7b01e02fe4 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -235,6 +235,10 @@ protected function get_global_params( $root_command = false ) { $binding = array(); $binding['root_command'] = $root_command; + if (! $this->can_have_subcommands() || ( is_object( $this->parent ) && get_class( $this->parent ) == 'WP_CLI\Dispatcher\CompositeCommand' )) { + $binding['is_subcommand'] = true; + } + foreach ( \WP_CLI::get_configurator()->get_spec() as $key => $details ) { if ( false === $details['runtime'] ) continue; diff --git a/templates/man-params.mustache b/templates/man-params.mustache index a27f4d846a..53ca9addcc 100644 --- a/templates/man-params.mustache +++ b/templates/man-params.mustache @@ -1,7 +1,7 @@ -{{^root_command}} +{{#is_subcommand}} -{{/root_command}} +{{/is_subcommand}} ## GLOBAL PARAMETERS {{#parameters}} From a2481164aec1510ea2f6240ff3a4043681c84e13 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 15:36:40 -0200 Subject: [PATCH 3361/4858] add `wp site archive` and `wp site unarchive` subcommands --- features/site.feature | 26 ++++++++++++++++++++++++ php/commands/site.php | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/features/site.feature b/features/site.feature index 3a03820079..3000943741 100644 --- a/features/site.feature +++ b/features/site.feature @@ -84,3 +84,29 @@ Feature: Manage sites in a multisite installation http://example.com/first """ + Scenario: Archive/unarchive a site + Given a WP multisite install + And I run `wp site create --slug=first --porcelain` + And save STDOUT as {SITE_ID} + + When I run `wp site archive {SITE_ID}` + Then STDOUT should be: + """ + Success: Site {SITE_ID} archived. + """ + + When I run `wp site list --fields=blog_id,archived` + Then STDOUT should be a table containing rows: + | blog_id | archived | + | {SITE_ID} | 1 | + + When I run `wp site unarchive {SITE_ID}` + Then STDOUT should be: + """ + Success: Site {SITE_ID} unarchived. + """ + + When I run `wp site list --fields=blog_id,archived` + Then STDOUT should be a table containing rows: + | blog_id | archived | + | {SITE_ID} | 0 | diff --git a/php/commands/site.php b/php/commands/site.php index 7f286e1677..b01f0dabbe 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -429,6 +429,52 @@ public function url( $args ) { parent::_url( $args, 'get_site_url' ); } + + /** + * Archive one or more sites + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of sites to archive. + * + * ## EXAMPLES + * + * wp site archive 123 + */ + public function archive( $args ) { + $this->update_site_status( $args, 'archived', 1 ); + } + + /** + * Unarchive one or more sites + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of sites to unarchive. + * + * ## EXAMPLES + * + * wp site unarchive 123 + */ + public function unarchive( $args ) { + $this->update_site_status( $args, 'archived', 0 ); + } + + private function update_site_status( $ids, $pref, $value ) { + if ( $pref == 'archived' && $value == 1 ) { + $action = 'archived'; + } else if ( $pref == 'archived' && $value == 0) { + $action = 'unarchived'; + } + + foreach ( $ids as $site_id ) { + $site = $this->fetcher->get_check( $site_id ); + update_blog_status( $site->blog_id, $pref, $value ); + WP_CLI::success( "Site {$site->blog_id} $action." ); + } + } } WP_CLI::add_command( 'site', 'Site_Command' ); From a865a1561411145329ea943cc009acd9fa404b6e Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 15:51:12 -0200 Subject: [PATCH 3362/4858] warning message when trying to archive a site that is already archived --- features/site.feature | 35 ++++++++++++++++++++++++++--------- php/commands/site.php | 7 +++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/features/site.feature b/features/site.feature index 3000943741..deeecc14ab 100644 --- a/features/site.feature +++ b/features/site.feature @@ -87,26 +87,43 @@ Feature: Manage sites in a multisite installation Scenario: Archive/unarchive a site Given a WP multisite install And I run `wp site create --slug=first --porcelain` - And save STDOUT as {SITE_ID} + And save STDOUT as {FIRST_SITE} + And I run `wp site create --slug=second --porcelain` + And save STDOUT as {SECOND_SITE} - When I run `wp site archive {SITE_ID}` + When I run `wp site archive {FIRST_SITE}` Then STDOUT should be: """ - Success: Site {SITE_ID} archived. + Success: Site {FIRST_SITE} archived. + """ + + When I run `wp site list --fields=blog_id,archived` + Then STDOUT should be a table containing rows: + | blog_id | archived | + | {FIRST_SITE} | 1 | + + When I run `wp site archive {FIRST_SITE} {SECOND_SITE}` + Then STDERR should be: + """ + Warning: Site {FIRST_SITE} already archived. + """ + And STDOUT should be: + """ + Success: Site {SECOND_SITE} archived. """ When I run `wp site list --fields=blog_id,archived` Then STDOUT should be a table containing rows: - | blog_id | archived | - | {SITE_ID} | 1 | + | blog_id | archived | + | {FIRST_SITE} | 1 | - When I run `wp site unarchive {SITE_ID}` + When I run `wp site unarchive {FIRST_SITE}` Then STDOUT should be: """ - Success: Site {SITE_ID} unarchived. + Success: Site {FIRST_SITE} unarchived. """ When I run `wp site list --fields=blog_id,archived` Then STDOUT should be a table containing rows: - | blog_id | archived | - | {SITE_ID} | 0 | + | blog_id | archived | + | {FIRST_SITE} | 0 | diff --git a/php/commands/site.php b/php/commands/site.php index b01f0dabbe..08687e66ec 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -471,6 +471,13 @@ private function update_site_status( $ids, $pref, $value ) { foreach ( $ids as $site_id ) { $site = $this->fetcher->get_check( $site_id ); + $old_value = get_blog_status( $site->blog_id, $pref ); + + if ( $value == $old_value ) { + WP_CLI::warning( "Site {$site->blog_id} already $action." ); + continue; + } + update_blog_status( $site->blog_id, $pref, $value ); WP_CLI::success( "Site {$site->blog_id} $action." ); } From 144fe62e61e292645cd9b48dd920f065cddc206f Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 16:03:38 -0200 Subject: [PATCH 3363/4858] warning when user tries to change the main site --- features/site.feature | 6 ++++++ php/commands/site.php | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/features/site.feature b/features/site.feature index deeecc14ab..fdb7d70e8c 100644 --- a/features/site.feature +++ b/features/site.feature @@ -127,3 +127,9 @@ Feature: Manage sites in a multisite installation Then STDOUT should be a table containing rows: | blog_id | archived | | {FIRST_SITE} | 0 | + + When I run `wp site archive 1` + Then STDERR should be: + """ + Warning: You are not allowed to change the main site. + """ \ No newline at end of file diff --git a/php/commands/site.php b/php/commands/site.php index 08687e66ec..a4a03ace67 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -471,6 +471,12 @@ private function update_site_status( $ids, $pref, $value ) { foreach ( $ids as $site_id ) { $site = $this->fetcher->get_check( $site_id ); + + if ( is_main_site( $site->blog_id ) ) { + WP_CLI::warning( "You are not allowed to change the main site." ); + continue; + } + $old_value = get_blog_status( $site->blog_id, $pref ); if ( $value == $old_value ) { From 6c8a700f3f85893e9c0f76add2db7b6cbe8902dd Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 16:16:25 -0200 Subject: [PATCH 3364/4858] add subcommands to activate and deactivate a site --- features/site.feature | 50 +++++++++++++++++++++++++++++++++++++++++++ php/commands/site.php | 36 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/features/site.feature b/features/site.feature index fdb7d70e8c..a7fd496c13 100644 --- a/features/site.feature +++ b/features/site.feature @@ -129,6 +129,56 @@ Feature: Manage sites in a multisite installation | {FIRST_SITE} | 0 | When I run `wp site archive 1` + Then STDERR should be: + """ + Warning: You are not allowed to change the main site. + """ + + Scenario: Activate/deactivate a site + Given a WP multisite install + And I run `wp site create --slug=first --porcelain` + And save STDOUT as {FIRST_SITE} + And I run `wp site create --slug=second --porcelain` + And save STDOUT as {SECOND_SITE} + + When I run `wp site deactivate {FIRST_SITE}` + Then STDOUT should be: + """ + Success: Site {FIRST_SITE} deactivated. + """ + + When I run `wp site list --fields=blog_id,deleted` + Then STDOUT should be a table containing rows: + | blog_id | deleted | + | {FIRST_SITE} | 1 | + + When I run `wp site deactivate {FIRST_SITE} {SECOND_SITE}` + Then STDERR should be: + """ + Warning: Site {FIRST_SITE} already deactivated. + """ + And STDOUT should be: + """ + Success: Site {SECOND_SITE} deactivated. + """ + + When I run `wp site list --fields=blog_id,deleted` + Then STDOUT should be a table containing rows: + | blog_id | deleted | + | {FIRST_SITE} | 1 | + + When I run `wp site activate {FIRST_SITE}` + Then STDOUT should be: + """ + Success: Site {FIRST_SITE} activated. + """ + + When I run `wp site list --fields=blog_id,deleted` + Then STDOUT should be a table containing rows: + | blog_id | deleted | + | {FIRST_SITE} | 0 | + + When I run `wp site deactivate 1` Then STDERR should be: """ Warning: You are not allowed to change the main site. diff --git a/php/commands/site.php b/php/commands/site.php index a4a03ace67..2eddda1640 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -462,11 +462,47 @@ public function unarchive( $args ) { $this->update_site_status( $args, 'archived', 0 ); } + /** + * Activate one or more sites + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of sites to activate. + * + * ## EXAMPLES + * + * wp site activate 123 + */ + public function activate( $args ) { + $this->update_site_status( $args, 'deleted', 0 ); + } + + /** + * Deactivate one or more sites + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of sites to deactivate. + * + * ## EXAMPLES + * + * wp site deactivate 123 + */ + public function deactivate( $args ) { + $this->update_site_status( $args, 'deleted', 1 ); + } + private function update_site_status( $ids, $pref, $value ) { if ( $pref == 'archived' && $value == 1 ) { $action = 'archived'; } else if ( $pref == 'archived' && $value == 0) { $action = 'unarchived'; + } else if ( $pref == 'deleted' && $value == 1 ) { + $action = 'deactivated'; + } else if ( $pref == 'deleted' && $value == 0 ) { + $action = 'activated'; } foreach ( $ids as $site_id ) { From 1e62ae3f1f9c15f0ec24b8b1ffe25434f46bed73 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 16:33:51 -0200 Subject: [PATCH 3365/4858] add subcommands to mark or remove a site from spam --- features/site.feature | 50 +++++++++++++++++++++++++++++++++++++++++++ php/commands/site.php | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/features/site.feature b/features/site.feature index a7fd496c13..87493ce666 100644 --- a/features/site.feature +++ b/features/site.feature @@ -179,6 +179,56 @@ Feature: Manage sites in a multisite installation | {FIRST_SITE} | 0 | When I run `wp site deactivate 1` + Then STDERR should be: + """ + Warning: You are not allowed to change the main site. + """ + + Scenario: Mark/remove a site from spam + Given a WP multisite install + And I run `wp site create --slug=first --porcelain` + And save STDOUT as {FIRST_SITE} + And I run `wp site create --slug=second --porcelain` + And save STDOUT as {SECOND_SITE} + + When I run `wp site spam {FIRST_SITE}` + Then STDOUT should be: + """ + Success: Site {FIRST_SITE} marked as spam. + """ + + When I run `wp site list --fields=blog_id,spam` + Then STDOUT should be a table containing rows: + | blog_id | spam | + | {FIRST_SITE} | 1 | + + When I run `wp site spam {FIRST_SITE} {SECOND_SITE}` + Then STDERR should be: + """ + Warning: Site {FIRST_SITE} already marked as spam. + """ + And STDOUT should be: + """ + Success: Site {SECOND_SITE} marked as spam. + """ + + When I run `wp site list --fields=blog_id,spam` + Then STDOUT should be a table containing rows: + | blog_id | spam | + | {FIRST_SITE} | 1 | + + When I run `wp site not-spam {FIRST_SITE}` + Then STDOUT should be: + """ + Success: Site {FIRST_SITE} removed from spam. + """ + + When I run `wp site list --fields=blog_id,spam` + Then STDOUT should be a table containing rows: + | blog_id | spam | + | {FIRST_SITE} | 0 | + + When I run `wp site spam 1` Then STDERR should be: """ Warning: You are not allowed to change the main site. diff --git a/php/commands/site.php b/php/commands/site.php index 2eddda1640..075ca2ba55 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -494,6 +494,40 @@ public function deactivate( $args ) { $this->update_site_status( $args, 'deleted', 1 ); } + /** + * Mark one or more sites as spam + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of sites to be marked as spam. + * + * ## EXAMPLES + * + * wp site spam 123 + */ + public function spam( $args ) { + $this->update_site_status( $args, 'spam', 1 ); + } + + /** + * Remove one or more sites from spam + * + * ## OPTIONS + * + * <id>... + * : One or more IDs of sites to remove from spam. + * + * ## EXAMPLES + * + * wp site not-spam 123 + * + * @subcommand not-spam + */ + public function not_spam( $args ) { + $this->update_site_status( $args, 'spam', 0 ); + } + private function update_site_status( $ids, $pref, $value ) { if ( $pref == 'archived' && $value == 1 ) { $action = 'archived'; @@ -503,6 +537,10 @@ private function update_site_status( $ids, $pref, $value ) { $action = 'deactivated'; } else if ( $pref == 'deleted' && $value == 0 ) { $action = 'activated'; + } else if ( $pref == 'spam' && $value == 1 ) { + $action = 'marked as spam'; + } else if ( $pref == 'spam' && $value == 0 ) { + $action = 'removed from spam'; } foreach ( $ids as $site_id ) { From f7bf2f87d4e31d4a4754c5e6e49a355b7e83c732 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 22 Dec 2014 16:35:58 -0200 Subject: [PATCH 3366/4858] add missing new line to the end of the file --- features/site.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/site.feature b/features/site.feature index 87493ce666..5b5767fda2 100644 --- a/features/site.feature +++ b/features/site.feature @@ -232,4 +232,4 @@ Feature: Manage sites in a multisite installation Then STDERR should be: """ Warning: You are not allowed to change the main site. - """ \ No newline at end of file + """ From 53378cc92897f8251fd566d805b1a454840c9d6e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 22 Dec 2014 12:42:17 -0800 Subject: [PATCH 3367/4858] Don't force update check on plugin install This reduces our dependency on WordPress.org API for installing. The genesis of this call appears to be a copy and paste error: 1. https://github.com/wp-cli/wp-cli/commit/1e2b9ee2384139c16aadb772ce0ccbcd7df52acb#diff-59ccae364a062cc72d61b0199f525e79R112 2. https://github.com/wp-cli/wp-cli/commit/1e2b9ee2384139c16aadb772ce0ccbcd7df52acb#diff-78c563be62d40fb1c0c180515eef9636L60 --- php/WP_CLI/CommandWithUpgrade.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index b24f1c6fe5..b3d7a35780 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -108,8 +108,6 @@ private function show_legend( $items ) { } function install( $args, $assoc_args ) { - // Force WordPress to check for updates - call_user_func( $this->upgrade_refresh ); foreach ( $args as $slug ) { $local_or_remote_zip_file = false; From 12a6de75c42dd52635c38ca7c069578484dceb02 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 22 Dec 2014 13:00:20 -0800 Subject: [PATCH 3368/4858] Throw error when converting multisite to subdomains with "localhost" Subdomains don't work at all when the domain is "localhost" --- features/core.feature | 12 ++++++++++++ php/commands/core.php | 10 +++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index b226393cb3..32d3210ce5 100644 --- a/features/core.feature +++ b/features/core.feature @@ -247,6 +247,18 @@ Feature: Manage WordPress installation example.com """ + Scenario: Install multisite with subdomains on localhost + Given an empty directory + And WP files + And wp-config.php + And a database + + When I try `wp core multisite-install --url=http://localhost/ --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1 --subdomains` + Then STDERR should contain: + """ + Error: Multisite with subdomains cannot be configured when domain is 'localhost'. + """ + Scenario: Update from a ZIP file Given a WP install diff --git a/php/commands/core.php b/php/commands/core.php index 73200db387..982b18ddc1 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -441,7 +441,7 @@ public function install( $args, $assoc_args ) { * Default: '/' * * [--subdomains] - * : If passed, the network will use subdomains, instead of subdirectories. + * : If passed, the network will use subdomains, instead of subdirectories. Doesn't work with 'localhost'. * * @subcommand multisite-convert * @alias install-network @@ -473,7 +473,7 @@ public function multisite_convert( $args, $assoc_args ) { * Default: '/' * * [--subdomains] - * : If passed, the network will use subdomains, instead of subdirectories. + * : If passed, the network will use subdomains, instead of subdirectories. Doesn't work with 'localhost'. * * --title=<site-title> * : The title of the new site. @@ -595,13 +595,17 @@ private function _multisite_convert( $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + $domain = self::get_clean_basedomain(); + if ( 'localhost' === $domain && ! empty( $assoc_args['subdomains'] ) ) { + WP_CLI::error( "Multisite with subdomains cannot be configured when domain is 'localhost'." ); + } + // need to register the multisite tables manually for some reason foreach ( $wpdb->tables( 'ms_global' ) as $table => $prefixed_table ) $wpdb->$table = $prefixed_table; install_network(); - $domain = self::get_clean_basedomain(); $result = populate_network( $assoc_args['site_id'], $domain, From f4472aa75d3064df42481d81dcceb79eb36bdfd5 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Tue, 23 Dec 2014 11:55:45 +0100 Subject: [PATCH 3369/4858] Add behat test for scaffolding post type with icon --- features/scaffold.feature | 11 +++++++++++ templates/post_type.mustache | 1 + 2 files changed, 12 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 438e1842ee..86b2f307b5 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -64,6 +64,10 @@ Feature: WordPress code scaffolding """ __( 'Zombies', 'zombieland' """ + And STDOUT should contain: + """ + 'menu_icon' => 'dashicons-admin-post', + """ Scenario: CPT slug is too long When I try `wp scaffold post-type slugiswaytoolonginfact` @@ -80,6 +84,13 @@ Feature: WordPress code scaffolding __( 'Brain eaters' """ + Scenario: Scaffold a Custom Post Type with icon + When I run `wp scaffold post-type zombie --icon="art"` + Then STDOUT should contain: + """ + 'menu_icon' => 'dashicons-art', + """ + Scenario: Scaffold a plugin Given I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 4cf479eb6c..d3ddf21bc3 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -22,4 +22,5 @@ 'has_archive' => true, 'rewrite' => true, 'query_var' => true, + 'menu_icon' => 'dashicons-admin-post', ) ); From 739126c5d2ff97344dae5eb0e7715165c20c3431 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Geus <sebastiaan@hoppinger.com> Date: Tue, 23 Dec 2014 11:56:50 +0100 Subject: [PATCH 3370/4858] implement icon argument for scaffold post type command --- php/commands/scaffold.php | 4 ++++ templates/post_type.mustache | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 050b812285..2f50a08677 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -24,6 +24,9 @@ class Scaffold_Command extends WP_CLI_Command { * [--textdomain=<textdomain>] * : The textdomain to use for the labels. * + * [--icon=<icon>] + * : The dashicon to use in the menu. + * * [--theme] * : Create a file in the active theme directory, instead of sending to * STDOUT. Specify a theme with `--theme=<theme>` to have the file placed in that theme. @@ -46,6 +49,7 @@ function post_type( $args, $assoc_args ) { $defaults = array( 'textdomain' => '', + 'icon' => 'admin-post', ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/post-types/', array( diff --git a/templates/post_type.mustache b/templates/post_type.mustache index d3ddf21bc3..f017dccafa 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -22,5 +22,5 @@ 'has_archive' => true, 'rewrite' => true, 'query_var' => true, - 'menu_icon' => 'dashicons-admin-post', + 'menu_icon' => 'dashicons-{{icon}}', ) ); From d4d19dd2edccf6183a9a748198cb3c0875d5f55b Mon Sep 17 00:00:00 2001 From: ozh <ozh@ozh.org> Date: Wed, 31 Dec 2014 11:06:50 +0100 Subject: [PATCH 3371/4858] Work around =~ operator for older Bash versions --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index b9ddf1f066..4238760adb 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -60,7 +60,7 @@ install_db() { local EXTRA="" if ! [ -z $DB_HOSTNAME ] ; then - if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then + if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" elif ! [ -z $DB_SOCK_OR_PORT ] ; then EXTRA=" --socket=$DB_SOCK_OR_PORT" From 9e4723feace69357fdc755f0399ca25d113c4c43 Mon Sep 17 00:00:00 2001 From: ozh <ozh@ozh.org> Date: Fri, 2 Jan 2015 22:13:30 +0100 Subject: [PATCH 3372/4858] Use env variable for WP_CORE_DIR if set --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 4238760adb..a3f1184df5 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -12,7 +12,7 @@ DB_HOST=${4-localhost} WP_VERSION=${5-latest} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} -WP_CORE_DIR=/tmp/wordpress/ +WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} set -ex From 235aaa1d305a5eadf61c3e5bbd0aeb4a574a2f66 Mon Sep 17 00:00:00 2001 From: oneumyvakin <oneumyvakin@gmail.com> Date: Wed, 7 Jan 2015 14:12:35 +0600 Subject: [PATCH 3373/4858] Add "skip-themes" command --- php/config-spec.php | 7 +++++++ php/utils-wp.php | 18 ++++++++++++++++++ php/wp-settings-cli.php | 10 ++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index 37f98fbf5e..1d67b11b8a 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -34,6 +34,13 @@ 'desc' => 'Skip loading all or some plugins', 'default' => '', ), + + 'skip-themes' => array( + 'runtime' => '[=<theme>]', + 'file' => '<list>', + 'desc' => 'Skip loading all or some themes', + 'default' => '', + ), 'require' => array( 'runtime' => '=<path>', diff --git a/php/utils-wp.php b/php/utils-wp.php index dba28dfc29..b9ee33c195 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -95,6 +95,24 @@ function is_plugin_skipped( $file ) { return in_array( $name, array_filter( $skipped_plugins ) ); } +function get_theme_name( $path ) { + return basename( $path ); +} + +function is_theme_skipped( $path ) { + $name = get_theme_name( $path ); + + $skipped_themes = \WP_CLI::get_runner()->config['skip-themes']; + if ( true === $skipped_themes ) + return true; + + if ( ! is_array( $skipped_themes ) ) { + $skipped_themes = explode( ',', $skipped_themes ); + } + + return in_array( $name, array_filter( $skipped_themes ) ); +} + /** * Register the sidebar for unused widgets * Core does this in /wp-admin/widgets.php, which isn't helpful diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index f2e2fc85e8..6944f37978 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -326,10 +326,12 @@ function wp_is_mobile() { // Load the functions for the active theme, for both parent and child theme if applicable. global $pagenow; if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) { - if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) - include( STYLESHEETPATH . '/functions.php' ); - if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) - include( TEMPLATEPATH . '/functions.php' ); + if ( !Utils\is_theme_skipped( TEMPLATEPATH ) ) { + if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) + include( STYLESHEETPATH . '/functions.php' ); + if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) + include( TEMPLATEPATH . '/functions.php' ); + } } do_action( 'after_setup_theme' ); From 2d31834d10db293ef48939ac1640b7137fa3fe57 Mon Sep 17 00:00:00 2001 From: oneumyvakin <oneumyvakin@gmail.com> Date: Thu, 8 Jan 2015 16:37:59 +0600 Subject: [PATCH 3374/4858] Add tests for "skip-themes" --- features/skip-themes.feature | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 features/skip-themes.feature diff --git a/features/skip-themes.feature b/features/skip-themes.feature new file mode 100644 index 0000000000..bd9cd2b41a --- /dev/null +++ b/features/skip-themes.feature @@ -0,0 +1,80 @@ +Feature: Skipping themes + + Scenario: Skipping themes via global flag + Given a WP install + And I run `wp theme install classic` + And I run `wp theme install default --activate` + + When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + true + """ + + # The specified theme should be skipped + When I run `wp --skip-themes=default eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ + + # All themes should be not skipped + When I run `wp --skip-themes eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ + + # Skip another theme + When I run `wp --skip-themes=classic eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + true + """ + + # The specified theme should still show up as an active theme + When I run `wp --skip-themes theme status default` + Then STDOUT should contain: + """ + Active + """ + + # Skip several themes + When I run `wp --skip-themes=classic,default eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ + + Scenario: Skipping multiple themes via config file + Given a WP install + And a wp-cli.yml file: + """ + skip-themes: + - classic + - default + """ + And I run `wp theme install classic --activate` + And I run `wp theme install default` + + # The classic theme should show up as an active theme + When I run `wp theme status` + Then STDOUT should contain: + """ + A classic + """ + + # The default theme should show up as an installed theme + When I run `wp theme status` + Then STDOUT should contain: + """ + I default + """ + + And I run `wp theme activate default` + # The specified theme should be skipped + When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ \ No newline at end of file From 37d9f4709738ca0c64a6edd31082643379f76371 Mon Sep 17 00:00:00 2001 From: oneumyvakin <oneumyvakin@gmail.com> Date: Thu, 8 Jan 2015 16:49:51 +0600 Subject: [PATCH 3375/4858] Revert "Add tests for "skip-themes"" This reverts commit 2d31834d10db293ef48939ac1640b7137fa3fe57. --- features/skip-themes.feature | 80 ------------------------------------ 1 file changed, 80 deletions(-) delete mode 100644 features/skip-themes.feature diff --git a/features/skip-themes.feature b/features/skip-themes.feature deleted file mode 100644 index bd9cd2b41a..0000000000 --- a/features/skip-themes.feature +++ /dev/null @@ -1,80 +0,0 @@ -Feature: Skipping themes - - Scenario: Skipping themes via global flag - Given a WP install - And I run `wp theme install classic` - And I run `wp theme install default --activate` - - When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` - Then STDOUT should be: - """ - true - """ - - # The specified theme should be skipped - When I run `wp --skip-themes=default eval 'var_export( function_exists( "kubrick_head" ) );'` - Then STDOUT should be: - """ - false - """ - - # All themes should be not skipped - When I run `wp --skip-themes eval 'var_export( function_exists( "kubrick_head" ) );'` - Then STDOUT should be: - """ - false - """ - - # Skip another theme - When I run `wp --skip-themes=classic eval 'var_export( function_exists( "kubrick_head" ) );'` - Then STDOUT should be: - """ - true - """ - - # The specified theme should still show up as an active theme - When I run `wp --skip-themes theme status default` - Then STDOUT should contain: - """ - Active - """ - - # Skip several themes - When I run `wp --skip-themes=classic,default eval 'var_export( function_exists( "kubrick_head" ) );'` - Then STDOUT should be: - """ - false - """ - - Scenario: Skipping multiple themes via config file - Given a WP install - And a wp-cli.yml file: - """ - skip-themes: - - classic - - default - """ - And I run `wp theme install classic --activate` - And I run `wp theme install default` - - # The classic theme should show up as an active theme - When I run `wp theme status` - Then STDOUT should contain: - """ - A classic - """ - - # The default theme should show up as an installed theme - When I run `wp theme status` - Then STDOUT should contain: - """ - I default - """ - - And I run `wp theme activate default` - # The specified theme should be skipped - When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` - Then STDOUT should be: - """ - false - """ \ No newline at end of file From d5f7177ccfdc3e555a9cf2d62b76eab7dbee9640 Mon Sep 17 00:00:00 2001 From: oneumyvakin <oneumyvakin@gmail.com> Date: Thu, 8 Jan 2015 17:17:01 +0600 Subject: [PATCH 3376/4858] Add skip-themes command with tests --- features/skip-themes.feature | 80 ++++++++++++++++++++++++++++++++++++ php/wp-settings-cli.php | 10 +++-- 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 features/skip-themes.feature diff --git a/features/skip-themes.feature b/features/skip-themes.feature new file mode 100644 index 0000000000..bd9cd2b41a --- /dev/null +++ b/features/skip-themes.feature @@ -0,0 +1,80 @@ +Feature: Skipping themes + + Scenario: Skipping themes via global flag + Given a WP install + And I run `wp theme install classic` + And I run `wp theme install default --activate` + + When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + true + """ + + # The specified theme should be skipped + When I run `wp --skip-themes=default eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ + + # All themes should be not skipped + When I run `wp --skip-themes eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ + + # Skip another theme + When I run `wp --skip-themes=classic eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + true + """ + + # The specified theme should still show up as an active theme + When I run `wp --skip-themes theme status default` + Then STDOUT should contain: + """ + Active + """ + + # Skip several themes + When I run `wp --skip-themes=classic,default eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ + + Scenario: Skipping multiple themes via config file + Given a WP install + And a wp-cli.yml file: + """ + skip-themes: + - classic + - default + """ + And I run `wp theme install classic --activate` + And I run `wp theme install default` + + # The classic theme should show up as an active theme + When I run `wp theme status` + Then STDOUT should contain: + """ + A classic + """ + + # The default theme should show up as an installed theme + When I run `wp theme status` + Then STDOUT should contain: + """ + I default + """ + + And I run `wp theme activate default` + # The specified theme should be skipped + When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` + Then STDOUT should be: + """ + false + """ \ No newline at end of file diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 6944f37978..21014a654a 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -327,10 +327,12 @@ function wp_is_mobile() { global $pagenow; if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) { if ( !Utils\is_theme_skipped( TEMPLATEPATH ) ) { - if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) - include( STYLESHEETPATH . '/functions.php' ); - if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) - include( TEMPLATEPATH . '/functions.php' ); + if ( !Utils\is_theme_skipped( TEMPLATEPATH ) ) { + if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) + include( STYLESHEETPATH . '/functions.php' ); + if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) + include( TEMPLATEPATH . '/functions.php' ); + } } } From 230ba53bd56148b703112caa13cf58238058568b Mon Sep 17 00:00:00 2001 From: oneumyvakin <oneumyvakin@gmail.com> Date: Thu, 8 Jan 2015 22:53:30 +0600 Subject: [PATCH 3377/4858] Remove unnecessary condition, fix formatting in tests --- features/skip-themes.feature | 23 ++++++++++++----------- php/wp-settings-cli.php | 10 ++++------ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/features/skip-themes.feature b/features/skip-themes.feature index bd9cd2b41a..a285eec796 100644 --- a/features/skip-themes.feature +++ b/features/skip-themes.feature @@ -3,7 +3,7 @@ Feature: Skipping themes Scenario: Skipping themes via global flag Given a WP install And I run `wp theme install classic` - And I run `wp theme install default --activate` + And I run `wp theme install default --activate` When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` Then STDOUT should be: @@ -17,14 +17,14 @@ Feature: Skipping themes """ false """ - - # All themes should be not skipped + + # All themes should be skipped When I run `wp --skip-themes eval 'var_export( function_exists( "kubrick_head" ) );'` Then STDOUT should be: """ false """ - + # Skip another theme When I run `wp --skip-themes=classic eval 'var_export( function_exists( "kubrick_head" ) );'` Then STDOUT should be: @@ -54,9 +54,9 @@ Feature: Skipping themes - classic - default """ - And I run `wp theme install classic --activate` - And I run `wp theme install default` - + And I run `wp theme install classic --activate` + And I run `wp theme install default` + # The classic theme should show up as an active theme When I run `wp theme status` Then STDOUT should contain: @@ -70,11 +70,12 @@ Feature: Skipping themes """ I default """ - - And I run `wp theme activate default` - # The specified theme should be skipped + + And I run `wp theme activate default` + + # The default theme should be skipped When I run `wp eval 'var_export( function_exists( "kubrick_head" ) );'` Then STDOUT should be: """ false - """ \ No newline at end of file + """ diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 21014a654a..6944f37978 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -327,12 +327,10 @@ function wp_is_mobile() { global $pagenow; if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) { if ( !Utils\is_theme_skipped( TEMPLATEPATH ) ) { - if ( !Utils\is_theme_skipped( TEMPLATEPATH ) ) { - if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) - include( STYLESHEETPATH . '/functions.php' ); - if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) - include( TEMPLATEPATH . '/functions.php' ); - } + if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) + include( STYLESHEETPATH . '/functions.php' ); + if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) + include( TEMPLATEPATH . '/functions.php' ); } } From 3155fbac809a51e24a8b8a68561027c3e58fff74 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 04:38:55 -0800 Subject: [PATCH 3378/4858] Indentation fixes again --- features/core.feature | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/features/core.feature b/features/core.feature index 3f84b643d0..afee37b215 100644 --- a/features/core.feature +++ b/features/core.feature @@ -370,23 +370,23 @@ Feature: Manage WordPress installation """ Scenario: Don't run update when up-to-date - Given a WP install + Given a WP install - When I run `wp core update` - Then STDOUT should contain: - """ - WordPress is up to date - """ - And STDOUT should not contain: - """ - Updating - """ + When I run `wp core update` + Then STDOUT should contain: + """ + WordPress is up to date + """ + And STDOUT should not contain: + """ + Updating + """ - When I run `wp core update --force` - Then STDOUT should contain: - """ - Updating - """ + When I run `wp core update --force` + Then STDOUT should contain: + """ + Updating + """ Scenario: User defined in wp-cli.yml Given an empty directory From 6406e8a13798fcf194ec14c2f5ddfd8f2be7d290 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 04:39:38 -0800 Subject: [PATCH 3379/4858] First make sure core is up to date; required for older versions --- features/core.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/core.feature b/features/core.feature index afee37b215..c993a315a8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -371,6 +371,7 @@ Feature: Manage WordPress installation Scenario: Don't run update when up-to-date Given a WP install + And I run `wp core update` When I run `wp core update` Then STDOUT should contain: From cf203804559a9428a998dfe25cb15921c2e8abda Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 04:42:23 -0800 Subject: [PATCH 3380/4858] Explicitly mark public --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 4c40336e07..b4809f4af0 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -106,7 +106,7 @@ private function same_minor_release( $release_parts, $updates ) { * * @subcommand check-update */ - function check_update( $_, $assoc_args ) { + public function check_update( $_, $assoc_args ) { $updates = $this->get_updates( $assoc_args ); if ( $updates ) { From ec7ed9c5470d169c7ce50682311088d3addbcaf4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 04:43:01 -0800 Subject: [PATCH 3381/4858] More methods to be marked public --- php/commands/cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index b4809f4af0..4cd16a8aa9 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -31,7 +31,7 @@ private function command_to_array( $command ) { /** * Print WP-CLI version. */ - function version() { + public function version() { WP_CLI::line( 'WP-CLI ' . WP_CLI_VERSION ); } @@ -43,7 +43,7 @@ function version() { * [--format=<format>] * : Accepted values: json */ - function info( $_, $assoc_args ) { + public function info( $_, $assoc_args ) { $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); $runner = WP_CLI::get_runner(); @@ -136,7 +136,7 @@ public function check_update( $_, $assoc_args ) { * * @subcommand update */ - function update( $_, $assoc_args ) { + public function update( $_, $assoc_args ) { if ( 0 !== strpos( WP_CLI_ROOT, 'phar://' ) ) { WP_CLI::error( "You can only self-update PHARs" ); } @@ -259,7 +259,7 @@ private function get_updates( $assoc_args ) { * * @subcommand param-dump */ - function param_dump() { + public function param_dump() { echo json_encode( \WP_CLI::get_configurator()->get_spec() ); } @@ -268,7 +268,7 @@ function param_dump() { * * @subcommand cmd-dump */ - function cmd_dump() { + public function cmd_dump() { echo json_encode( self::command_to_array( WP_CLI::get_root_command() ) ); } @@ -283,7 +283,7 @@ function cmd_dump() { * --point=<point> * : The index to the current cursor position relative to the beginning of the command */ - function completions( $_, $assoc_args ) { + public function completions( $_, $assoc_args ) { $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); $compl = new \WP_CLI\Completions( $line ); $compl->render(); From 53ade8583989a8fd70a5e6a5c948cda1b40a9558 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 04:45:36 -0800 Subject: [PATCH 3382/4858] When GH returns an error, give more visibility into the error --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 4cd16a8aa9..29239088d7 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -213,7 +213,7 @@ private function get_updates( $assoc_args ) { $response = Utils\http_request( 'GET', $url, $headers, $options ); if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( "Failed to get latest version." ); + WP_CLI::error( sprintf( "Failed to get latest version (HTTP code %d)", $response->status_code ) ); } $release_data = json_decode( $response->body ); From 6e0e7b2c9c87b5c616fb09d8e592e1cec8535de2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 05:37:34 -0800 Subject: [PATCH 3383/4858] Trim contents, so we don't have to worry about newline --- php/wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-cli.php b/php/wp-cli.php index 46d7033363..ab8bcf68b1 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -2,7 +2,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); -define( 'WP_CLI_VERSION', file_get_contents( WP_CLI_ROOT . '/VERSION' ) ); +define( 'WP_CLI_VERSION', trim( file_get_contents( WP_CLI_ROOT . '/VERSION' ) ) ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From d3ea18a17965f94d1498a607087e02594fc826f7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 06:10:29 -0800 Subject: [PATCH 3384/4858] Version bump --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 14a8c24575..66333910a4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.17.1 \ No newline at end of file +0.18.0 From b234659488568850d9e74b8af073a0740815a892 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 07:24:28 -0800 Subject: [PATCH 3385/4858] Update .mailmap for v0.18.0 --- .mailmap | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.mailmap b/.mailmap index 9d78defad2..78ecffe33c 100644 --- a/.mailmap +++ b/.mailmap @@ -1,8 +1,12 @@ +Alex Mills <git@viper007bond.com> andreascreten <andreas@madewithlove.be> bartaakos <akos@netpositive.hu> bendoh <ben@thinkoomph.com> BoiteAWeb <juliobosk@gmail.com> boonebgorges <boonebgorges@gmail.com> +Borek Bernard <borekb@gmail.com> +borekb <borekb@gmail.com> +Brad Parbs <brad@bradparbs.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> clemens-tolboom <clemens@build2be.com> @@ -13,8 +17,8 @@ dangardner <dan@web.nearest.to> danielbachhuber <d@danielbachhuber.com> danielbachhuber <daniel@handbuilt.co> danielbachhuber <danielbachhuber@gmail.com> -dlh01 <david@alleyinteractive.com> dd32 <contact-atlassian@dd32.id.au> +dlh01 <david@alleyinteractive.com> drrobotnik <B@Brandons-Mac-Pro-4.local> dwightjack <marco.solazzi@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> @@ -27,6 +31,7 @@ glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> +jeichorn <joshua.eichorn@pagely.com> jghazally <jeff@bigfish.co.uk> jghazally <jghazally@gmail.com> jmslbam <jmslbam@gmail.com> @@ -36,12 +41,10 @@ johnpbloch <johnpbloch@gmail.com> jonathanbardo <jonathanbardo@users.noreply.github.com> joshbetz <j@joshbetz.com> joshlevinson <joshalevinson@gmail.com> -jeichorn <joshua.eichorn@pagely.com> Kevinlearynet <info@kevinleary.net> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> -santagada <santagada@gmail.com> lkwdwrd <woodward.lucas@gmail.com> marcoceppi <marco@ceppi.net> matiskay <matiskay@gmail.com> @@ -50,8 +53,10 @@ mattheu <matthew@matth.eu> mboynes <mboynes@alleyinteractive.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> +mikey dubs <mike@herebox.org> milesj <mileswjohnson@gmail.com> MiteshShah <Mitesh.Shah@rtCamp.com> +miya0001 <miya@wpist.me> mwilliamson <michael.williamson@red-gate.com> mwilliamson <mike@zwobble.org> nacin <andrewnacin@gmail.com> @@ -67,13 +72,17 @@ ocean90 <dominikschilling+git@gmail.com> oknoway <nate@oknoway.com> om4james <james@jamesc.id.au> om4james <james@om4.com.au> +oneumyvakin <oneumyvakin@gmail.com> +ozh <ozh@ozh.org> phh <phh@peytz.dk> +Pippin Williamson <pippin@pippinsplugins.com> Rarst <contact@rarst.net> robertboloc <robertboloc@gmail.com> -rodrigoprimo <rodrigosprimo@gmail.com> rodrigoprimo <rodrigo@hacklab.com.br> +rodrigoprimo <rodrigosprimo@gmail.com> roelven <roel@soundcloud.com> ryanduff <ryan@fusionized.com> +santagada <santagada@gmail.com> sboisvert <stephane.boisvert@automattic.com> scribu <mail@scribu.net> scribu <scribu@gmail.com> @@ -81,10 +90,13 @@ sebastiaandegeus <sebastiaan@hoppinger.com> sibprogrammer <ayuzhakov@parallels.com> simonwheatley <simonw@codeforthepeople.com> soulou <leo@soulou.fr> +spacedmonkey <spacedmonkey2@gmail.com> SpikesDivZero <wesley.spikes@gmail.com> spuriousdata <spuriousdata@gmail.com> +Stephen Edgar <stephen@netweb.com.au> stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> +Svetoslav Marinov (Slavi) <slavi@orbisius.com> szepeviktor <viktor@szepe.net> taupecat <tracy@taupecat.com> tddewey <td@tddewey.com> @@ -99,6 +111,7 @@ twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> +William Turrell <william@wturrell.co.uk> willmot <tom@humanmade.co.uk> wopr42 <john@zippykid.com> ziz <justin@crowdfavorite.com> From 2005f210c100e836a6d3f5f446ceb02076b8d62c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Jan 2015 09:13:22 -0800 Subject: [PATCH 3386/4858] Make sure version is trimmed on build too --- utils/make-phar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index 1841dcd34f..1ce6f7b875 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -20,7 +20,7 @@ define( 'BE_QUIET', isset( $runtime_config['quiet'] ) && $runtime_config['quiet'] ); -$current_version = file_get_contents( './VERSION' ); +$current_version = trim( file_get_contents( './VERSION' ) ); if ( isset( $runtime_config['version'] ) ) { $new_version = $runtime_config['version']; From 6b52960318b6537ac76d29b49ec14e73651db872 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 15 Jan 2015 12:58:05 +0000 Subject: [PATCH 3387/4858] s/domain.com/example.com --- features/user.feature | 22 +++++++++++----------- php/commands/user.php | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/features/user.feature b/features/user.feature index a1151b09b6..30890875a3 100644 --- a/features/user.feature +++ b/features/user.feature @@ -130,9 +130,9 @@ Feature: Manage WordPress users And a users.csv file: """ user_login,user_email,display_name,role - bobjones,bobjones@domain.com,Bob Jones,contributor - newuser1,newuser1@domain.com,New User,author - admin,admin@domain.com,Existing User,administrator + bobjones,bobjones@example.com,Bob Jones,contributor + newuser1,newuser1@example.com,New User,author + admin,admin@example.com,Existing User,administrator """ When I try `wp user import-csv users-incorrect.csv --skip-update` @@ -162,7 +162,7 @@ Feature: Manage WordPress users [{ "user_login":"admin", "display_name":"Existing User", - "user_email":"admin@domain.com", + "user_email":"admin@example.com", "roles":"administrator" }] """ @@ -172,12 +172,12 @@ Feature: Manage WordPress users And a users.csv file: """ user_login,user_email,display_name,role - bobjones,bobjones@domain.com,Bob Jones,contributor - newuser1,newuser1@domain.com,New User,author - admin,admin@domain.com,Existing User,administrator + bobjones,bobjones@example.com,Bob Jones,contributor + newuser1,newuser1@example.com,New User,author + admin,admin@example.com,Existing User,administrator """ - When I run `wp user create bobjones bobjones@domain.com --display_name="Robert Jones" --role=administrator` + When I run `wp user create bobjones bobjones@example.com --display_name="Robert Jones" --role=administrator` Then STDOUT should not be empty When I run `wp user import-csv users.csv --skip-update` @@ -195,7 +195,7 @@ Feature: Manage WordPress users { "user_login":"bobjones", "display_name":"Robert Jones", - "user_email":"bobjones@domain.com", + "user_email":"bobjones@example.com", "roles":"administrator" } """ @@ -204,8 +204,8 @@ Feature: Manage WordPress users Given a WP install When I run `wp user delete 1 --yes` - And I run `wp user create bobjones bobjones@domain.com --display_name="Bob Jones" --role=contributor` - And I run `wp user create billjones billjones@domain.com --display_name="Bill Jones" --role=administrator` + And I run `wp user create bobjones bobjones@example.com --display_name="Bob Jones" --role=contributor` + And I run `wp user create billjones billjones@example.com --display_name="Bill Jones" --role=administrator` And I run `wp user add-role billjones author` Then STDOUT should not be empty diff --git a/php/commands/user.php b/php/commands/user.php index fae201e42b..d9597fca0a 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -607,9 +607,9 @@ public function list_caps( $args, $assoc_args ) { * Sample users.csv file: * * user_login,user_email,display_name,role - * bobjones,bobjones@domain.com,Bob Jones,contributor - * newuser1,newuser1@domain.com,New User,author - * existinguser,existinguser@domain.com,Existing User,administrator + * bobjones,bobjones@example.com,Bob Jones,contributor + * newuser1,newuser1@example.com,New User,author + * existinguser,existinguser@example.com,Existing User,administrator * * @subcommand import-csv */ From 82e2c14e05abdbc2f50e9830ae05326635ae4337 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 15 Jan 2015 05:39:28 -0800 Subject: [PATCH 3388/4858] Properly catch error when WordPress importer install fails Plugin install failure doesn't elevate exit code yet, so it's more subtle --- features/export.feature | 20 ++++++++++++++++---- features/import.feature | 12 ++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/features/export.feature b/features/export.feature index a342d608cb..ae0281bd42 100644 --- a/features/export.feature +++ b/features/export.feature @@ -40,7 +40,10 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDOUT should not be empty + Then STDERR should not contain: + """ + Warning: + """ When I run `wp site empty --yes` And I run `wp post generate --post_type=page --post_status=draft --count=10` @@ -75,7 +78,10 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDOUT should not be empty + Then STDERR should not contain: + """ + Warning: + """ When I run `wp post generate --count=10` And I run `wp post list --format=count` @@ -107,7 +113,10 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDOUT should not be empty + Then STDERR should not contain: + """ + Warning: + """ When I run `wp site empty --yes` And I run `wp post generate --post_type=post --post_date=2013-08-01 --count=10` @@ -144,7 +153,10 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDOUT should not be empty + Then STDERR should not contain: + """ + Warning: + """ When I run `wp term create category Apple --porcelain` Then STDOUT should be a number diff --git a/features/import.feature b/features/import.feature index b401e3164f..c975325b23 100644 --- a/features/import.feature +++ b/features/import.feature @@ -23,7 +23,10 @@ Feature: Import content. """ When I run `wp plugin install wordpress-importer --activate` - Then STDOUT should not be empty + Then STDERR should not contain: + """ + Warning: + """ When I run `wp import {EXPORT_FILE} --authors=skip` Then STDOUT should not be empty @@ -70,7 +73,12 @@ Feature: Import content. """ When I run `wp plugin install wordpress-importer --activate` - And I run `wp import export-posts --authors=skip --skip=image_resize` + Then STDERR should not contain: + """ + Warning: + """ + + When I run `wp import export-posts --authors=skip --skip=image_resize` And I run `wp import export-pages --authors=skip --skip=image_resize` Then STDOUT should not be empty From 6a2adbacd819c19ce1b2a0d0c1a0422a949e68de Mon Sep 17 00:00:00 2001 From: 2ndkauboy <bernhard@kau-boys.de> Date: Mon, 19 Jan 2015 02:31:15 +0100 Subject: [PATCH 3389/4858] implement the new best practice from the CODEX to enqueue the parent themes script through the functions.php file instead of importing it in the child themes style.css file --- php/commands/scaffold.php | 2 ++ templates/child_theme.mustache | 4 +--- templates/child_theme_functions.mustache | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 templates/child_theme_functions.mustache diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 050b812285..7f9ae4f59f 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -269,10 +269,12 @@ function child_theme( $args, $assoc_args ) { $theme_dir = WP_CONTENT_DIR . "/themes" . "/$theme_slug"; $theme_style_path = "$theme_dir/style.css"; + $theme_functions_path = "$theme_dir/functions.php"; $this->maybe_create_themes_dir(); $this->create_file( $theme_style_path, Utils\mustache_render( 'child_theme.mustache', $data ) ); + $this->create_file( $theme_functions_path, Utils\mustache_render( 'child_theme_functions.mustache', $data ) ); WP_CLI::success( "Created $theme_dir" ); diff --git a/templates/child_theme.mustache b/templates/child_theme.mustache index 6e96440f11..0ff54a109b 100644 --- a/templates/child_theme.mustache +++ b/templates/child_theme.mustache @@ -6,6 +6,4 @@ Author: {{author}} Author URI: {{author_uri}} Template: {{parent_theme}} Version: 0.1.0 -*/ - -@import '../{{parent_theme}}/style.css'; +*/ \ No newline at end of file diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache new file mode 100644 index 0000000000..da47ec199a --- /dev/null +++ b/templates/child_theme_functions.mustache @@ -0,0 +1,8 @@ +<?php + +add_action( 'wp_enqueue_scripts', '{{parent_theme}}_parent_theme_enqueue_styles' ); + +function {{parent_theme}}_parent_theme_enqueue_styles() { + wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); + +} \ No newline at end of file From 3c197e28627e6d768db3e4d9408ec6cfd6fa5694 Mon Sep 17 00:00:00 2001 From: 2ndkauboy <bernhard@kau-boys.de> Date: Tue, 20 Jan 2015 00:20:39 +0100 Subject: [PATCH 3390/4858] remove unnecessary newline in function --- templates/child_theme_functions.mustache | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache index da47ec199a..e6b8390e2a 100644 --- a/templates/child_theme_functions.mustache +++ b/templates/child_theme_functions.mustache @@ -4,5 +4,4 @@ add_action( 'wp_enqueue_scripts', '{{parent_theme}}_parent_theme_enqueue_styles' function {{parent_theme}}_parent_theme_enqueue_styles() { wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); - } \ No newline at end of file From 89972be4c7d04614e597047c08a664d4ad7e2a5e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Jan 2015 16:17:37 -0800 Subject: [PATCH 3391/4858] On Travis, serve Github update check requests from cache This will prevent us from hitting the API request rate-limiting. When `WP_CLI_REQUESTS_CACHE_DIR` environment variable is set, check to see if a cached version of the request is available from the static file cache. If the cached version is available, serve it. If it's not available, do the request and stash it in the cache. Ideally, we'd be injecting our own `Requests_Transport` class, but `Requests` doesn't easily support this. --- .travis.yml | 1 + ci/prepare.sh | 2 ++ ...a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 | 1 + features/bootstrap/FeatureContext.php | 5 +++-- php/utils.php | 16 ++++++++++++++++ 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 diff --git a/.travis.yml b/.travis.yml index b6bf25ecae..c1998eac3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ php: env: global: - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + - WP_CLI_REQUESTS_CACHE_DIR=/tmp/wp-cli-requests-cache-dir # Encripted deploy key. See https://gist.github.com/scribu/6241271 - secure: "U8gOPW2m9fkJW8omnPjFHFZutGIqAAfVs0H1izpSKJhclUfYAGjAGl1Cb6ZiUp3jZE11iWa+fAZ5mmmLAQ5L9ijta40igfFw0s+o/Vt3WBM4a3Vdqpg6civ0rDi9tJYuwtMaEi/kF/yuhKzUT80EAMqVix5xPnf963iIUPyarfY=" - secure: "W9t7pG5h/Khoi+TrxplpSeTWxaTr7r6cYRVJBsXgghZLDXsU/qn/OhGDdY+IMfSgzO49wjFyLh2EOs8zZSujY75fgFffK2+jd/882NUlpvpXoW9C3yEfZhLJVQZI/1idnpDe9f6zA0XlpBn3bQ2QeS3i2a/JwOGCD8BQjNobk1M=" diff --git a/ci/prepare.sh b/ci/prepare.sh index 611a068de1..0abf482c58 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -18,5 +18,7 @@ chmod +x $WP_CLI_BIN_DIR/wp ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' ./bin/wp core version --path='/tmp/wp-cli-test core-download-cache/' +cp -Rf ./ci/requests-cache $WP_CLI_REQUESTS_CACHE_DIR + mysql -e 'CREATE DATABASE wp_cli_test;' -uroot mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot diff --git a/ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 b/ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 new file mode 100644 index 0000000000..c15234fba2 --- /dev/null +++ b/ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 @@ -0,0 +1 @@ +{"body":"[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":83,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3322,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2945,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6232,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":180,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":21,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":480,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":45,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","raw":"HTTP\/1.1 200 OK\r\nServer: GitHub.com\r\nDate: Tue, 20 Jan 2015 00:06:54 GMT\r\nContent-Type: application\/json; charset=utf-8\r\nTransfer-Encoding: chunked\r\nStatus: 200 OK\r\nX-RateLimit-Limit: 60\r\nX-RateLimit-Remaining: 43\r\nX-RateLimit-Reset: 1421714966\r\nCache-Control: public, max-age=60, s-maxage=60\r\nETag: W\/\"431ba748cd115b111a96bdc64bd25c55\"\r\nVary: Accept\r\nX-GitHub-Media-Type: github.v3\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options: deny\r\nContent-Security-Policy: default-src 'none'\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\nAccess-Control-Allow-Origin: *\r\nX-GitHub-Request-Id: CFAD13E4:1D6D:1E0FBDD:54BD9C1E\r\nStrict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\nX-Content-Type-Options: nosniff\r\nVary: Accept-Encoding\r\nX-Served-By: d594a23ec74671eba905bf91ef329026\r\nContent-Encoding: gzip\r\n\r\n[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":83,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3322,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2945,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6232,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":180,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":21,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":480,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":45,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","headers":{},"status_code":200,"success":true,"redirects":0,"url":"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases","history":[],"cookies":{}} \ No newline at end of file diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index c17d1842ba..9d920a0328 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -41,8 +41,9 @@ private static function get_process_env_variables() { // Ensure we're using the expected `wp` binary $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); $env = array( - 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), - 'BEHAT_RUN' => 1 + 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), + 'BEHAT_RUN' => 1, + 'WP_CLI_REQUESTS_CACHE_DIR' => getenv( 'WP_CLI_REQUESTS_CACHE_DIR' ) ?: false, ); if ( $config_path = getenv( 'WP_CLI_CONFIG_PATH' ) ) { $env['WP_CLI_CONFIG_PATH'] = $config_path; diff --git a/php/utils.php b/php/utils.php index b80c0ea171..79b055b4ae 100644 --- a/php/utils.php +++ b/php/utils.php @@ -430,11 +430,27 @@ function http_request( $method, $url, $data = null, $headers = array(), $options $pem_copied = true; } + $cache_file = false; + if ( $cache_dir = getenv( 'WP_CLI_REQUESTS_CACHE_DIR' ) ) { + $cache_key = hash_hmac( 'sha256', 'requests_' . $url . serialize( $headers ) . serialize( $data ) . serialize( $options ), '' ); + $cache_file = rtrim( $cache_dir, '/' ) . '/' . $cache_key; + if ( file_exists( $cache_file ) && is_readable( $cache_file ) ) { + return json_decode( file_get_contents( $cache_file ) ); + } + } + try { $request = \Requests::request( $url, $headers, $data, $method, $options ); if ( $pem_copied ) { unlink( $options['verify'] ); } + if ( ! empty( $cache_file ) ) { + $cache_dir = dirname( $cache_file ); + if ( ! is_dir( $cache_dir ) ) { + mkdir( $cache_dir, 0755, true ); + } + file_put_contents( $cache_file, json_encode( $request ) ); + } return $request; } catch( \Requests_Exception $ex ) { // Handle SSL certificate issues gracefully From f4dac3bef26c57285ba898f8424ceb36ae80cf14 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 Jan 2015 07:00:37 -0800 Subject: [PATCH 3392/4858] Force isn't necessary If this is run twice, we'll get a duplicate subdirectory. But, it doesn't cause any problems --- ci/prepare.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index 0abf482c58..0b94367cd1 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -18,7 +18,7 @@ chmod +x $WP_CLI_BIN_DIR/wp ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' ./bin/wp core version --path='/tmp/wp-cli-test core-download-cache/' -cp -Rf ./ci/requests-cache $WP_CLI_REQUESTS_CACHE_DIR +cp -r ./ci/requests-cache $WP_CLI_REQUESTS_CACHE_DIR mysql -e 'CREATE DATABASE wp_cli_test;' -uroot mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot From 91670f46e8729c9045a148adb4e995c8728b7260 Mon Sep 17 00:00:00 2001 From: BA <kau@connecticum.de> Date: Wed, 21 Jan 2015 20:10:10 +0100 Subject: [PATCH 3393/4858] add newlines at end of changed mustache templates --- templates/child_theme.mustache | 2 +- templates/child_theme_functions.mustache | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/child_theme.mustache b/templates/child_theme.mustache index 0ff54a109b..3fda10143e 100644 --- a/templates/child_theme.mustache +++ b/templates/child_theme.mustache @@ -6,4 +6,4 @@ Author: {{author}} Author URI: {{author_uri}} Template: {{parent_theme}} Version: 0.1.0 -*/ \ No newline at end of file +*/ diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache index e6b8390e2a..c8f5417672 100644 --- a/templates/child_theme_functions.mustache +++ b/templates/child_theme_functions.mustache @@ -4,4 +4,4 @@ add_action( 'wp_enqueue_scripts', '{{parent_theme}}_parent_theme_enqueue_styles' function {{parent_theme}}_parent_theme_enqueue_styles() { wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); -} \ No newline at end of file +} From 1a3b677f2196e0b69ec0f089d01888dbe4e61d02 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 23 Jan 2015 07:10:25 -0800 Subject: [PATCH 3394/4858] Update cached Github request Somehow the key changed... --- ...6307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc | 1 + ...b3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc delete mode 100644 ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 diff --git a/ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc b/ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc new file mode 100644 index 0000000000..94235eb4df --- /dev/null +++ b/ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc @@ -0,0 +1 @@ +{"body":"[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":257,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3550,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2949,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6236,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":184,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":23,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":536,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":47,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","raw":"HTTP\/1.1 200 OK\r\nServer: GitHub.com\r\nDate: Fri, 23 Jan 2015 15:05:37 GMT\r\nContent-Type: application\/json; charset=utf-8\r\nTransfer-Encoding: chunked\r\nStatus: 200 OK\r\nX-RateLimit-Limit: 60\r\nX-RateLimit-Remaining: 58\r\nX-RateLimit-Reset: 1422029028\r\nCache-Control: public, max-age=60, s-maxage=60\r\nETag: W\/\"cc5da6bb9b75b9409843ff24258f0035\"\r\nVary: Accept\r\nX-GitHub-Media-Type: github.v3\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options: deny\r\nContent-Security-Policy: default-src 'none'\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\nAccess-Control-Allow-Origin: *\r\nX-GitHub-Request-Id: 49A4CEBC:1D6B:6DD46FA:54C26340\r\nStrict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\nX-Content-Type-Options: nosniff\r\nVary: Accept-Encoding\r\nX-Served-By: 13d09b732ebe76f892093130dc088652\r\nContent-Encoding: gzip\r\n\r\n[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":257,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3550,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2949,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6236,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":184,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":23,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":536,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":47,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","headers":{},"status_code":200,"success":true,"redirects":0,"url":"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases","history":[],"cookies":{}} \ No newline at end of file diff --git a/ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 b/ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 deleted file mode 100644 index c15234fba2..0000000000 --- a/ci/requests-cache/f0db3d31346d4a5c733a1fac25aa46ba8a454b1e403fd7447a0c2161f2d07f13 +++ /dev/null @@ -1 +0,0 @@ -{"body":"[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":83,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3322,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2945,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6232,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":180,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":21,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":480,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":45,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","raw":"HTTP\/1.1 200 OK\r\nServer: GitHub.com\r\nDate: Tue, 20 Jan 2015 00:06:54 GMT\r\nContent-Type: application\/json; charset=utf-8\r\nTransfer-Encoding: chunked\r\nStatus: 200 OK\r\nX-RateLimit-Limit: 60\r\nX-RateLimit-Remaining: 43\r\nX-RateLimit-Reset: 1421714966\r\nCache-Control: public, max-age=60, s-maxage=60\r\nETag: W\/\"431ba748cd115b111a96bdc64bd25c55\"\r\nVary: Accept\r\nX-GitHub-Media-Type: github.v3\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options: deny\r\nContent-Security-Policy: default-src 'none'\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\nAccess-Control-Allow-Origin: *\r\nX-GitHub-Request-Id: CFAD13E4:1D6D:1E0FBDD:54BD9C1E\r\nStrict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\nX-Content-Type-Options: nosniff\r\nVary: Accept-Encoding\r\nX-Served-By: d594a23ec74671eba905bf91ef329026\r\nContent-Encoding: gzip\r\n\r\n[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":83,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3322,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2945,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6232,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":180,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":21,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":480,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":45,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","headers":{},"status_code":200,"success":true,"redirects":0,"url":"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases","history":[],"cookies":{}} \ No newline at end of file From 1760511e32db3eaf92f42fffa32868be24f09e59 Mon Sep 17 00:00:00 2001 From: Francesco Laffi <francesco.laffi@gmail.com> Date: Fri, 30 Jan 2015 12:57:06 +0100 Subject: [PATCH 3395/4858] add flag to search-replace command to ignore wpdb table lists --- features/search-replace.feature | 10 ++++++++-- php/commands/search-replace.php | 11 +++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 43207edbec..de03518462 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -24,9 +24,9 @@ Feature: Do global search/replace | wp_2_posts | guid | 2 | SQL | | wp_blogs | path | 1 | SQL | - Scenario: Don't run on unregistered tables + Scenario: Don't run on unregistered tables by default Given a WP install - And I run `wp db query "CREATE TABLE wp_awesome ( id int(11) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"` + And I run `wp db query "CREATE TABLE wp_awesome ( id int(11) unsigned NOT NULL AUTO_INCREMENT, awesome_stuff TEXT, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"` When I run `wp search-replace foo bar` Then STDOUT should not contain: @@ -34,6 +34,12 @@ Feature: Do global search/replace wp_awesome """ + When I run `wp search-replace foo bar --all-tables` + Then STDOUT should contain: + """ + wp_awesome + """ + Scenario: Quiet search/replace Given a WP install diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 52ffbeaa1a..bd2985cf58 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -43,6 +43,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--recurse-objects] * : Enable recursing into objects to replace strings * + * [--all-tables] + * : Enable replacement on any tables that match the table prefix even if not registered on wpdb + * * ## EXAMPLES * * wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid @@ -70,7 +73,7 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; - $tables = self::get_table_list( $args, isset( $assoc_args['network'] ) ); + $tables = self::get_table_list( $args, isset( $assoc_args['network'] ), isset( $assoc_args['all-tables'] ) ); foreach ( $tables as $table ) { list( $primary_keys, $columns ) = self::get_columns( $table ); @@ -118,7 +121,7 @@ public function __invoke( $args, $assoc_args ) { } } - private static function get_table_list( $args, $network ) { + private static function get_table_list( $args, $network, $all ) { global $wpdb; if ( !empty( $args ) ) @@ -127,6 +130,10 @@ private static function get_table_list( $args, $network ) { $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); + if ( $all ) { + return $matching_tables; + } + $allowed_tables = array(); $allowed_table_types = array( 'tables', 'global_tables' ); if ( $network ) { From 7afa42ec60a69c1b4af12adb64c7e6508884f444 Mon Sep 17 00:00:00 2001 From: Andreas Heigl <andreas@heigl.org> Date: Wed, 4 Feb 2015 16:12:08 +0100 Subject: [PATCH 3396/4858] Adds possibility to download via curl This also removes the wget-call from install-package-tests as curl is already a requirement. --- templates/install-package-tests.sh | 2 +- templates/install-wp-tests.sh | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/templates/install-package-tests.sh b/templates/install-package-tests.sh index 74c76b5878..0df429c56f 100644 --- a/templates/install-package-tests.sh +++ b/templates/install-package-tests.sh @@ -8,7 +8,7 @@ install_wp_cli() { # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR mkdir -p $WP_CLI_BIN_DIR - wget https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli-nightly.phar + curl -s https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli-nightly.phar mv wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index a3f1184df5..ab6396707f 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -16,6 +16,14 @@ WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} set -ex +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + install_wp() { mkdir -p $WP_CORE_DIR @@ -25,10 +33,10 @@ install_wp() { local ARCHIVE_NAME="wordpress-$WP_VERSION" fi - wget -nv -O /tmp/wordpress.tar.gz https://wordpress.org/${ARCHIVE_NAME}.tar.gz + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - wget -nv -O $WP_CORE_DIR/wp-content/db.php https://raw.github.com/markoheijnen/wp-mysqli/master/db.php + download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php } install_test_suite() { @@ -44,7 +52,7 @@ install_test_suite() { cd $WP_TESTS_DIR svn co --quiet https://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ - wget -nv -O wp-tests-config.php https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php + download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php wp-tests-config.php sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php From 483887a3ac06ee7a517d1bd986e171e0d7892bbb Mon Sep 17 00:00:00 2001 From: Andreas Heigl <andreas@heigl.org> Date: Thu, 5 Feb 2015 07:22:09 +0100 Subject: [PATCH 3397/4858] Adds download-function to install-package-tests.sh --- templates/install-package-tests.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/templates/install-package-tests.sh b/templates/install-package-tests.sh index 0df429c56f..cbde91ef28 100644 --- a/templates/install-package-tests.sh +++ b/templates/install-package-tests.sh @@ -4,12 +4,19 @@ set -ex PACKAGE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../ && pwd )" +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + install_wp_cli() { # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR mkdir -p $WP_CLI_BIN_DIR - curl -s https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli-nightly.phar - mv wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp + download https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp } @@ -30,7 +37,8 @@ set_package_context() { download_behat() { cd $PACKAGE_DIR - curl -s https://getcomposer.org/installer | php + download https://getcomposer.org/installer installer + php installer php composer.phar require --dev behat/behat='~2.5' } From 66b7e6332e2a3ec934ace651b2040ea3135ebfb3 Mon Sep 17 00:00:00 2001 From: Andreas Heigl <andreas@heigl.org> Date: Thu, 5 Feb 2015 07:22:35 +0100 Subject: [PATCH 3398/4858] Fixes some indentation-issues --- templates/install-wp-tests.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index ab6396707f..56647cee9f 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -17,11 +17,11 @@ WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} set -ex download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; + if [ `which curl` ]; then + curl -s "$1" > "$2"; elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi + wget -nv -O "$2" "$1" + fi } install_wp() { From 72643760081926b37002fefed454c70f453e2208 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 9 Feb 2015 16:47:50 +0100 Subject: [PATCH 3399/4858] Correct the inline docs for `CommandWithUpgrade::_search()`. --- php/WP_CLI/CommandWithUpgrade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index b3d7a35780..39da96241d 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -351,8 +351,8 @@ private function get_color( $status ) { /** * Search wordpress.org repo. * - * @param object $api Data from WP plugin/theme API - * @param array $assoc_args Data passed in from command. + * @param array $args A arguments array containing the search term in the first element. + * @param array $assoc_args Data passed in from command. */ protected function _search( $args, $assoc_args ) { $term = $args[0]; From 7d5bb04a92445db08a7aa2c146d76c0b31bd2175 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 9 Feb 2015 10:41:12 -0800 Subject: [PATCH 3400/4858] Test against the latest version of WordPress --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c1998eac3f..fe4c4b6102 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=4.0 + - WP_VERSION=4.1 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: From 5344805cef642e989a87e752cfca784b3fd9e86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 12 Feb 2015 23:13:09 +0100 Subject: [PATCH 3401/4858] Check command class --- php/class-wp-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f0a5764071..01256b5064 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -166,6 +166,10 @@ public static function do_hook( $when ) { * 'before_invoke' => callback to execute before invoking the command */ public static function add_command( $name, $class, $args = array() ) { + if ( ! class_exists( $class ) ) { + WP_CLI::error( sprintf( "Class '%s' does not exist.", $class ) ); + } + if ( isset( $args['before_invoke'] ) ) { self::add_hook( "before_invoke:$name", $args['before_invoke'] ); } From dd6f717608e55d8b5eca1e68bf21818c88e2e244 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 12 Feb 2015 20:10:08 -0800 Subject: [PATCH 3402/4858] Fix builds by increasing the # of items per page WordPress.org API is giving us junk results for `per_page=1` See https://meta.trac.wordpress.org/ticket/866 --- features/upgradables.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 027668c83b..dc195e89ed 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -165,10 +165,10 @@ Feature: Manage WordPress themes and plugins """ And the <file_to_check> file should not exist - When I run `wp <type> search <item> --per-page=1 --fields=name,slug` + When I run `wp <type> search <item> --per-page=2 --fields=name,slug` Then STDOUT should contain: """ - Showing 1 of + Showing 2 of """ And STDOUT should end with a table containing rows: | name | slug | From 8ddc599ea1b1f1cd3822af1ba0fe641b20b714f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 14:10:55 -0800 Subject: [PATCH 3403/4858] Don't instantiate the `Import_Command` class when registering Proper use is to provide the class name as a string --- php/commands/import.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index eca7db4c20..d082d3797c 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -378,5 +378,5 @@ private function suggest_user( $author_user_login, $author_user_email = '' ) { } -WP_CLI::add_command( 'import', new Import_Command ); +WP_CLI::add_command( 'import', 'Import_Command' ); From b6439a7302b826ec2de2c6bbb84eb455ea3202ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Fri, 13 Feb 2015 23:16:10 +0100 Subject: [PATCH 3404/4858] Class-proof class_exists --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 01256b5064..cfe4ae30ae 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -166,7 +166,7 @@ public static function do_hook( $when ) { * 'before_invoke' => callback to execute before invoking the command */ public static function add_command( $name, $class, $args = array() ) { - if ( ! class_exists( $class ) ) { + if ( is_string( $class ) && ! class_exists( (string) $class ) ) { WP_CLI::error( sprintf( "Class '%s' does not exist.", $class ) ); } From daecd1427f95948203a7775b2b467e96e5c437a6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 14:24:58 -0800 Subject: [PATCH 3405/4858] Rename `--all-tables` to `--all-tables-with-prefix` for clarity --- features/search-replace.feature | 2 +- php/commands/search-replace.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index de03518462..f85ae7c246 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -34,7 +34,7 @@ Feature: Do global search/replace wp_awesome """ - When I run `wp search-replace foo bar --all-tables` + When I run `wp search-replace foo bar --all-tables-with-prefix` Then STDOUT should contain: """ wp_awesome diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index bd2985cf58..cd09e1861d 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -43,7 +43,7 @@ class Search_Replace_Command extends WP_CLI_Command { * [--recurse-objects] * : Enable recursing into objects to replace strings * - * [--all-tables] + * [--all-tables-with-prefix] * : Enable replacement on any tables that match the table prefix even if not registered on wpdb * * ## EXAMPLES @@ -73,7 +73,7 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; - $tables = self::get_table_list( $args, isset( $assoc_args['network'] ), isset( $assoc_args['all-tables'] ) ); + $tables = self::get_table_list( $args, isset( $assoc_args['network'] ), isset( $assoc_args['all-tables-with-prefix'] ) ); foreach ( $tables as $table ) { list( $primary_keys, $columns ) = self::get_columns( $table ); @@ -121,7 +121,7 @@ public function __invoke( $args, $assoc_args ) { } } - private static function get_table_list( $args, $network, $all ) { + private static function get_table_list( $args, $network, $all_with_prefix ) { global $wpdb; if ( !empty( $args ) ) @@ -130,7 +130,7 @@ private static function get_table_list( $args, $network, $all ) { $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); - if ( $all ) { + if ( $all_with_prefix ) { return $matching_tables; } From b8a092f2e959c3618f9be97ccdd1a69e2a79942d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 14:31:34 -0800 Subject: [PATCH 3406/4858] Rename `--icon` argument to `--dashicon` for clarity --- features/scaffold.feature | 4 ++-- php/commands/scaffold.php | 4 ++-- templates/post_type.mustache | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 86b2f307b5..1f3086bcd1 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -84,8 +84,8 @@ Feature: WordPress code scaffolding __( 'Brain eaters' """ - Scenario: Scaffold a Custom Post Type with icon - When I run `wp scaffold post-type zombie --icon="art"` + Scenario: Scaffold a Custom Post Type with dashicon + When I run `wp scaffold post-type zombie --dashicon="art"` Then STDOUT should contain: """ 'menu_icon' => 'dashicons-art', diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 8f4f6b91c5..c26f26c404 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -24,7 +24,7 @@ class Scaffold_Command extends WP_CLI_Command { * [--textdomain=<textdomain>] * : The textdomain to use for the labels. * - * [--icon=<icon>] + * [--dashicon=<dashicon>] * : The dashicon to use in the menu. * * [--theme] @@ -49,7 +49,7 @@ function post_type( $args, $assoc_args ) { $defaults = array( 'textdomain' => '', - 'icon' => 'admin-post', + 'dashicon' => 'admin-post', ); $this->_scaffold( $args[0], $assoc_args, $defaults, '/post-types/', array( diff --git a/templates/post_type.mustache b/templates/post_type.mustache index f017dccafa..68e0814b03 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -22,5 +22,5 @@ 'has_archive' => true, 'rewrite' => true, 'query_var' => true, - 'menu_icon' => 'dashicons-{{icon}}', + 'menu_icon' => 'dashicons-{{dashicon}}', ) ); From b982ae03ff84344c141ed90038c88994c45d78f6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 14:41:13 -0800 Subject: [PATCH 3407/4858] Add `--sassify` option to `wp scaffold _s` --- php/commands/scaffold.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 8f4f6b91c5..61a99a238b 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -181,6 +181,9 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * * [--author_uri=<uri>] * : What to put in the 'Author URI:' header in style.css + * + * [--sassify] + * : Include stylesheets as SASS */ function _s( $args, $assoc_args ) { @@ -205,6 +208,9 @@ function _s( $args, $assoc_args ) { $body['underscoresme_description'] = $theme_description; $body['underscoresme_generate_submit'] = "Generate"; $body['underscoresme_generate'] = "1"; + if ( isset( $assoc_args['sassify'] ) ) { + $body['underscoresme_sass'] = 1; + } $tmpfname = wp_tempnam($url); $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); From 725769d75c256dd012a992141d40d443f57167f2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 14:50:04 -0800 Subject: [PATCH 3408/4858] Test for `--sassify` optoin --- features/scaffold.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 86b2f307b5..adb946aea2 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -210,3 +210,13 @@ Feature: WordPress code scaffolding """ And the {THEME_DIR}/starter-theme/style.css file should exist + Scenario: Scaffold starter code for a theme with sass + Given I run `wp theme path` + And save STDOUT as {THEME_DIR} + + When I run `wp scaffold _s starter-theme --sassify` + Then STDOUT should contain: + """ + Success: Created theme 'Starter-theme'. + """ + And the {THEME_DIR}/starter-theme/sass directory should exist From 0816fa17ea26bd5baee55157ccb4db2ef2db88f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 15:25:37 -0800 Subject: [PATCH 3409/4858] Skip Github API tests by default Being rate-limited isn't a problem worth solving --- ci/set-behat-tags.sh | 13 ++++++------- features/cli.feature | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ci/set-behat-tags.sh b/ci/set-behat-tags.sh index 043a71fdff..86bb9cc624 100755 --- a/ci/set-behat-tags.sh +++ b/ci/set-behat-tags.sh @@ -32,6 +32,8 @@ vercomp() { return 0 } +# Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 +skip_tags="--tags='~github-api," if [[ ! -z "$WP_VERSION" ]]; then skip_tags="--tags='" @@ -45,13 +47,10 @@ if [[ ! -z "$WP_VERSION" ]]; then skip_tags="$skip_tags~$require," fi done - if [[ "--tags='" != $skip_tags ]]; then - skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' - skip_tags="$skip_tags'" # close the argument - else - skip_tags='' - fi fi -echo export behat_tags=$skip_tags \ No newline at end of file +skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' +skip_tags="$skip_tags'" # close the argument + +echo export behat_tags=$skip_tags,~github-api diff --git a/features/cli.feature b/features/cli.feature index d0cf96056d..d15e4888ed 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -1,3 +1,4 @@ +@github-api Feature: `wp cli` tasks Scenario: Ability to set a custom version when building From e3a04302f740b35caaaa82d59f09cd147387b5fa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 15:27:27 -0800 Subject: [PATCH 3410/4858] Revert "Merge pull request #1618 from wp-cli/1612-cache-requests" This reverts commit b28bde37be5e0fc8e8feb762b7d380c1ee958064, reversing changes made to aa15356fd208a07cd18d05b4062e5d18ca6f0591. --- .travis.yml | 1 - ci/prepare.sh | 2 -- features/bootstrap/FeatureContext.php | 5 ++--- php/utils.php | 16 ---------------- 4 files changed, 2 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index fe4c4b6102..9ab5b14b72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ php: env: global: - WP_CLI_BIN_DIR=/tmp/wp-cli-phar - - WP_CLI_REQUESTS_CACHE_DIR=/tmp/wp-cli-requests-cache-dir # Encripted deploy key. See https://gist.github.com/scribu/6241271 - secure: "U8gOPW2m9fkJW8omnPjFHFZutGIqAAfVs0H1izpSKJhclUfYAGjAGl1Cb6ZiUp3jZE11iWa+fAZ5mmmLAQ5L9ijta40igfFw0s+o/Vt3WBM4a3Vdqpg6civ0rDi9tJYuwtMaEi/kF/yuhKzUT80EAMqVix5xPnf963iIUPyarfY=" - secure: "W9t7pG5h/Khoi+TrxplpSeTWxaTr7r6cYRVJBsXgghZLDXsU/qn/OhGDdY+IMfSgzO49wjFyLh2EOs8zZSujY75fgFffK2+jd/882NUlpvpXoW9C3yEfZhLJVQZI/1idnpDe9f6zA0XlpBn3bQ2QeS3i2a/JwOGCD8BQjNobk1M=" diff --git a/ci/prepare.sh b/ci/prepare.sh index 0b94367cd1..611a068de1 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -18,7 +18,5 @@ chmod +x $WP_CLI_BIN_DIR/wp ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' ./bin/wp core version --path='/tmp/wp-cli-test core-download-cache/' -cp -r ./ci/requests-cache $WP_CLI_REQUESTS_CACHE_DIR - mysql -e 'CREATE DATABASE wp_cli_test;' -uroot mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 9d920a0328..c17d1842ba 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -41,9 +41,8 @@ private static function get_process_env_variables() { // Ensure we're using the expected `wp` binary $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); $env = array( - 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), - 'BEHAT_RUN' => 1, - 'WP_CLI_REQUESTS_CACHE_DIR' => getenv( 'WP_CLI_REQUESTS_CACHE_DIR' ) ?: false, + 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), + 'BEHAT_RUN' => 1 ); if ( $config_path = getenv( 'WP_CLI_CONFIG_PATH' ) ) { $env['WP_CLI_CONFIG_PATH'] = $config_path; diff --git a/php/utils.php b/php/utils.php index 79b055b4ae..b80c0ea171 100644 --- a/php/utils.php +++ b/php/utils.php @@ -430,27 +430,11 @@ function http_request( $method, $url, $data = null, $headers = array(), $options $pem_copied = true; } - $cache_file = false; - if ( $cache_dir = getenv( 'WP_CLI_REQUESTS_CACHE_DIR' ) ) { - $cache_key = hash_hmac( 'sha256', 'requests_' . $url . serialize( $headers ) . serialize( $data ) . serialize( $options ), '' ); - $cache_file = rtrim( $cache_dir, '/' ) . '/' . $cache_key; - if ( file_exists( $cache_file ) && is_readable( $cache_file ) ) { - return json_decode( file_get_contents( $cache_file ) ); - } - } - try { $request = \Requests::request( $url, $headers, $data, $method, $options ); if ( $pem_copied ) { unlink( $options['verify'] ); } - if ( ! empty( $cache_file ) ) { - $cache_dir = dirname( $cache_file ); - if ( ! is_dir( $cache_dir ) ) { - mkdir( $cache_dir, 0755, true ); - } - file_put_contents( $cache_file, json_encode( $request ) ); - } return $request; } catch( \Requests_Exception $ex ) { // Handle SSL certificate issues gracefully From bc565d7b9bcbdbf48cd9d66012a5549071a4a9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 14 Feb 2015 00:27:44 +0100 Subject: [PATCH 3411/4858] Test non-existent class in add_command() --- features/command.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 features/command.feature diff --git a/features/command.feature b/features/command.feature new file mode 100644 index 0000000000..e7b72e4791 --- /dev/null +++ b/features/command.feature @@ -0,0 +1,16 @@ +Feature: WP-CLI Commands + + Scenario: Invalid class is specified for a command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + + WP_CLI::add_command( 'command example', 'Non_Existent_Class' ); + """ + + When I run `wp --require=custom-cmd.php help` + Then STDOUT should contain: + """ + Error: Class 'Non_Existent_Class' does not exist. + """ From 659d3dce1183f82eaf902b0b0346262a9537ad84 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 15:28:37 -0800 Subject: [PATCH 3412/4858] Don't need this cache file anymore --- ...6307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc | 1 - 1 file changed, 1 deletion(-) delete mode 100644 ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc diff --git a/ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc b/ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc deleted file mode 100644 index 94235eb4df..0000000000 --- a/ci/requests-cache/7166307ee3b279227528edb0d3c10ee7308e00e6cbee2ffe7aed21b9273f4fcc +++ /dev/null @@ -1 +0,0 @@ -{"body":"[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":257,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3550,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2949,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6236,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":184,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":23,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":536,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":47,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","raw":"HTTP\/1.1 200 OK\r\nServer: GitHub.com\r\nDate: Fri, 23 Jan 2015 15:05:37 GMT\r\nContent-Type: application\/json; charset=utf-8\r\nTransfer-Encoding: chunked\r\nStatus: 200 OK\r\nX-RateLimit-Limit: 60\r\nX-RateLimit-Remaining: 58\r\nX-RateLimit-Reset: 1422029028\r\nCache-Control: public, max-age=60, s-maxage=60\r\nETag: W\/\"cc5da6bb9b75b9409843ff24258f0035\"\r\nVary: Accept\r\nX-GitHub-Media-Type: github.v3\r\nX-XSS-Protection: 1; mode=block\r\nX-Frame-Options: deny\r\nContent-Security-Policy: default-src 'none'\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\r\nAccess-Control-Allow-Origin: *\r\nX-GitHub-Request-Id: 49A4CEBC:1D6B:6DD46FA:54C26340\r\nStrict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\nX-Content-Type-Options: nosniff\r\nVary: Accept-Encoding\r\nX-Served-By: 13d09b732ebe76f892093130dc088652\r\nContent-Encoding: gzip\r\n\r\n[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/851681\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.18.0\",\"id\":851681,\"tag_name\":\"v0.18.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.18.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2015-01-14T14:10:29Z\",\"published_at\":\"2015-01-14T16:54:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/379372\",\"id\":379372,\"name\":\"wp-cli-0.18.0.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1342749,\"download_count\":257,\"created_at\":\"2015-01-14T16:53:08Z\",\"updated_at\":\"2015-01-14T16:54:37Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.18.0\/wp-cli-0.18.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.18.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.18.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.18.0.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/713614\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.1\",\"id\":713614,\"tag_name\":\"v0.17.1\",\"target_commitish\":\"release-0.17.1\",\"name\":\"Version 0.17.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-11-18T14:04:52Z\",\"published_at\":\"2014-11-18T14:56:27Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/310207\",\"id\":310207,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1317194,\"download_count\":3550,\"created_at\":\"2014-11-18T14:54:16Z\",\"updated_at\":\"2014-11-18T14:54:18Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.1\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/552464\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.17.0\",\"id\":552464,\"tag_name\":\"v0.17.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.17.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-09-12T00:49:44Z\",\"published_at\":\"2014-09-12T01:12:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/235975\",\"id\":235975,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1315849,\"download_count\":2949,\"created_at\":\"2014-09-12T01:12:02Z\",\"updated_at\":\"2014-09-12T01:12:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.17.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.17.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.17.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.17.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/403843\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.16.0\",\"id\":403843,\"tag_name\":\"v0.16.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.16.0\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-07-01T00:05:47Z\",\"published_at\":\"2014-07-01T00:48:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/172144\",\"id\":172144,\"name\":\"wp-cli.phar\",\"label\":null,\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1235702,\"download_count\":6236,\"created_at\":\"2014-07-01T00:34:43Z\",\"updated_at\":\"2014-07-01T00:34:50Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.16.0\/wp-cli.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.16.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.16.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.16.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/321103\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.1\",\"id\":321103,\"tag_name\":\"v0.15.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.1\",\"draft\":false,\"author\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-05-14T23:36:21Z\",\"published_at\":\"2014-05-14T23:53:00Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/135615\",\"id\":135615,\"name\":\"wp-cli-0.15.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"danielbachhuber\",\"id\":36432,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/36432?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/danielbachhuber\",\"html_url\":\"https:\/\/github.com\/danielbachhuber\",\"followers_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/danielbachhuber\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":2124218,\"download_count\":235,\"created_at\":\"2014-05-14T23:52:51Z\",\"updated_at\":\"2014-05-14T23:53:00Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.1\/wp-cli-0.15.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.1\",\"body\":\"Release notes http:\/\/wp-cli.org\/blog\/version-0.15.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/273283\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.15.0\",\"id\":273283,\"tag_name\":\"v0.15.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.15.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-04-15T16:16:50Z\",\"published_at\":\"2014-04-15T18:28:48Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/116905\",\"id\":116905,\"name\":\"wp-cli-0.15.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1195268,\"download_count\":184,\"created_at\":\"2014-04-17T17:19:40Z\",\"updated_at\":\"2014-04-17T17:19:55Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.15.0\/wp-cli-0.15.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.15.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.15.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.15.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244583\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.0\",\"id\":244583,\"tag_name\":\"v0.12.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-04T13:54:34Z\",\"published_at\":\"2014-03-27T22:35:13Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102407\",\"id\":102407,\"name\":\"wp-cli-0.12.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":669359,\"download_count\":7,\"created_at\":\"2014-03-27T22:35:08Z\",\"updated_at\":\"2014-03-27T22:35:13Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.0\/wp-cli-0.12.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/244580\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.12.1\",\"id\":244580,\"tag_name\":\"v0.12.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.12.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-10-11T12:36:09Z\",\"published_at\":\"2014-03-27T22:33:29Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102406\",\"id\":102406,\"name\":\"wp-cli-0.12.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":677814,\"download_count\":23,\"created_at\":\"2014-03-27T22:32:59Z\",\"updated_at\":\"2014-03-27T22:33:29Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.12.1\/wp-cli-0.12.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.12.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.12.1\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.12.1.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/204805\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.1\",\"id\":204805,\"tag_name\":\"v0.14.1\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.1\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-28T15:47:44Z\",\"published_at\":\"2014-02-28T18:22:18Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102398\",\"id\":102398,\"name\":\"wp-cli-0.14.1.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1106244,\"download_count\":536,\"created_at\":\"2014-03-27T22:24:59Z\",\"updated_at\":\"2014-03-27T22:25:09Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.1\/wp-cli-0.14.1.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.1\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.1\",\"body\":\"Resolved issues: https:\/\/github.com\/wp-cli\/wp-cli\/issues?labels=&milestone=22&page=1&state=closed\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/174903\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.14.0\",\"id\":174903,\"tag_name\":\"v0.14.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.14.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2014-02-06T00:02:26Z\",\"published_at\":\"2014-02-06T00:29:37Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102401\",\"id\":102401,\"name\":\"wp-cli-0.14.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1101392,\"download_count\":229,\"created_at\":\"2014-03-27T22:26:59Z\",\"updated_at\":\"2014-03-27T22:27:15Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.14.0\/wp-cli-0.14.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.14.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.14.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.14.html\"},{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\",\"assets_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets\",\"upload_url\":\"https:\/\/uploads.github.com\/repos\/wp-cli\/wp-cli\/releases\/114831\/assets{?name}\",\"html_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/tag\/v0.13.0\",\"id\":114831,\"tag_name\":\"v0.13.0\",\"target_commitish\":\"master\",\"name\":\"Version 0.13.0\",\"draft\":false,\"author\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"prerelease\":false,\"created_at\":\"2013-11-30T13:14:44Z\",\"published_at\":\"2013-12-06T22:31:35Z\",\"assets\":[{\"url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases\/assets\/102405\",\"id\":102405,\"name\":\"wp-cli-0.13.0.phar\",\"label\":\"\",\"uploader\":{\"login\":\"scribu\",\"id\":225715,\"avatar_url\":\"https:\/\/avatars.githubusercontent.com\/u\/225715?v=3\",\"gravatar_id\":\"\",\"url\":\"https:\/\/api.github.com\/users\/scribu\",\"html_url\":\"https:\/\/github.com\/scribu\",\"followers_url\":\"https:\/\/api.github.com\/users\/scribu\/followers\",\"following_url\":\"https:\/\/api.github.com\/users\/scribu\/following{\/other_user}\",\"gists_url\":\"https:\/\/api.github.com\/users\/scribu\/gists{\/gist_id}\",\"starred_url\":\"https:\/\/api.github.com\/users\/scribu\/starred{\/owner}{\/repo}\",\"subscriptions_url\":\"https:\/\/api.github.com\/users\/scribu\/subscriptions\",\"organizations_url\":\"https:\/\/api.github.com\/users\/scribu\/orgs\",\"repos_url\":\"https:\/\/api.github.com\/users\/scribu\/repos\",\"events_url\":\"https:\/\/api.github.com\/users\/scribu\/events{\/privacy}\",\"received_events_url\":\"https:\/\/api.github.com\/users\/scribu\/received_events\",\"type\":\"User\",\"site_admin\":false},\"content_type\":\"application\/octet-stream\",\"state\":\"uploaded\",\"size\":1043153,\"download_count\":47,\"created_at\":\"2014-03-27T22:30:36Z\",\"updated_at\":\"2014-03-27T22:30:43Z\",\"browser_download_url\":\"https:\/\/github.com\/wp-cli\/wp-cli\/releases\/download\/v0.13.0\/wp-cli-0.13.0.phar\"}],\"tarball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/tarball\/v0.13.0\",\"zipball_url\":\"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/zipball\/v0.13.0\",\"body\":\"Release notes: http:\/\/wp-cli.org\/blog\/version-0.13.html\"}]","headers":{},"status_code":200,"success":true,"redirects":0,"url":"https:\/\/api.github.com\/repos\/wp-cli\/wp-cli\/releases","history":[],"cookies":{}} \ No newline at end of file From 84cc9b172cf4edd15632116ddc5b1f67d488d86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 14 Feb 2015 00:49:36 +0100 Subject: [PATCH 3413/4858] Test fixed by "When I try" and STDERR --- features/command.feature | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/features/command.feature b/features/command.feature index e7b72e4791..6e034d6b28 100644 --- a/features/command.feature +++ b/features/command.feature @@ -9,8 +9,9 @@ Feature: WP-CLI Commands WP_CLI::add_command( 'command example', 'Non_Existent_Class' ); """ - When I run `wp --require=custom-cmd.php help` - Then STDOUT should contain: + When I try `wp --require=custom-cmd.php help` + Then the return code should be 1 + And STDERR should contain: """ - Error: Class 'Non_Existent_Class' does not exist. + Class 'Non_Existent_Class' does not exist. """ From a6124c15ba75331f428aeaed2fbebc96f54fba83 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 16:24:51 -0800 Subject: [PATCH 3414/4858] Properly format Behat tags --- ci/set-behat-tags.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ci/set-behat-tags.sh b/ci/set-behat-tags.sh index 86bb9cc624..f3ccb1fe91 100755 --- a/ci/set-behat-tags.sh +++ b/ci/set-behat-tags.sh @@ -33,10 +33,9 @@ vercomp() { } # Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 -skip_tags="--tags='~github-api," +skip_tags="--tags='~@github-api," if [[ ! -z "$WP_VERSION" ]]; then - skip_tags="--tags='" requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) for (( i = 0; i < ${#requires[@]}; i++ )); do version=${requires[$i]:12} @@ -53,4 +52,4 @@ fi skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' skip_tags="$skip_tags'" # close the argument -echo export behat_tags=$skip_tags,~github-api +echo export behat_tags=$skip_tags From e5f1927560c796f53c7ebb640350258aa288f800 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 13 Feb 2015 17:28:45 -0800 Subject: [PATCH 3415/4858] Comma means `OR`, `&&` means `AND` --- ci/set-behat-tags.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/set-behat-tags.sh b/ci/set-behat-tags.sh index f3ccb1fe91..ee5de21430 100755 --- a/ci/set-behat-tags.sh +++ b/ci/set-behat-tags.sh @@ -33,7 +33,7 @@ vercomp() { } # Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 -skip_tags="--tags='~@github-api," +skip_tags="--tags='~@github-api&&" if [[ ! -z "$WP_VERSION" ]]; then requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) @@ -43,13 +43,13 @@ if [[ ! -z "$WP_VERSION" ]]; then vercomp $version $WP_VERSION compare="$?" if [[ 1 == $compare ]]; then - skip_tags="$skip_tags~$require," + skip_tags="$skip_tags~$require&&" fi done fi -skip_tags=$(echo $skip_tags| sed 's/\,$//') # trim trailing ',' +skip_tags=$(echo $skip_tags| sed 's/&&$//') # trim trailing '&&' skip_tags="$skip_tags'" # close the argument echo export behat_tags=$skip_tags From 8760891fa7ec583c40f24321def434deb1d09800 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 15 Feb 2015 10:18:27 -0800 Subject: [PATCH 3416/4858] Clarify this is all tables in the database. See #1225 --- php/commands/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index bfd7e021fd..4b9eb07575 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -124,7 +124,7 @@ function query( $args ) { * : Extra arguments to pass to mysqldump * * [--tables=<tables>] - * : The comma separated list of specific tables to export. Excluding this parameter will export all tables + * : The comma separated list of specific tables to export. Excluding this parameter will export all tables in the database. * * ## EXAMPLES * From 0f172f0e96ed6044b5218c342d1681fe0cccd119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sun, 15 Feb 2015 21:49:33 +0100 Subject: [PATCH 3417/4858] The best I could do in the field of "tabular format" --- features/option.feature | 17 +++++++++++++---- php/commands/option.php | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/features/option.feature b/features/option.feature index 569d4da6d8..bc23bcf9f7 100644 --- a/features/option.feature +++ b/features/option.feature @@ -19,11 +19,14 @@ Feature: Manage WordPress options When I run `wp option list` Then STDOUT should contain: """ - bar + str_opt bar """ - When I run `wp option list --autoload=on` - Then STDOUT should not be empty + When I run `wp option list --autoload=off` + Then STDOUT should not contain: + """ + str_opt bar + """ When I run `wp option list --search='str_o*'` Then STDOUT should be a table containing rows: @@ -36,6 +39,12 @@ Feature: Manage WordPress options 3 """ + When I run `wp option list` + Then STDOUT should contain: + """ + home http://example.com + """ + When I run `wp option add auto_opt --autoload=no 'bar'` Then STDOUT should not be empty @@ -51,7 +60,7 @@ Feature: Manage WordPress options When I run `wp option list` Then STDOUT should not contain: """ - str_opt + str_opt bar """ When I try `wp option get str_opt` diff --git a/php/commands/option.php b/php/commands/option.php index cfaa0fba39..443bfaac5a 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -118,7 +118,7 @@ public function add( $args, $assoc_args ) { * * size_bytes * * @subcommand list - * @synopsis [--search=<sql-like-pattern>] [--autoload=<value>] [--fields=<fields>] [--format=<format>] + * @synopsis [--search=<glob-style-pattern>] [--autoload=<value>] [--fields=<fields>] [--format=<format>] */ public function list_( $args, $assoc_args ) { From 6d4daea55f87c320d1d8a18ea4ec7e02dddd85eb Mon Sep 17 00:00:00 2001 From: mwithheld <vhmark@gmail.com> Date: Thu, 19 Feb 2015 11:14:43 -0800 Subject: [PATCH 3418/4858] Update version check test to accommodate WP4.1.1 --- features/core.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 24c07cc83e..505b3caa95 100644 --- a/features/core.feature +++ b/features/core.feature @@ -296,7 +296,7 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.1 | major | https://wordpress.org/wordpress-4.1.zip | + | 4.1.1 | major | https://wordpress.org/wordpress-4.1.1.zip | | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | @@ -310,7 +310,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.1 | major | https://wordpress.org/wordpress-4.1.zip | + | 4.1.1 | major | https://wordpress.org/wordpress-4.1.1.zip | | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | From 15bc0fdfe26040fedc12b237b018e5a0355262bc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 19 Feb 2015 22:01:22 -0800 Subject: [PATCH 3419/4858] Use `mysql` with `--no-auto-rehash` for perf boost --- php/commands/db.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 4b9eb07575..e6f01bfa17 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -78,7 +78,7 @@ function repair() { * @alias connect */ function cli() { - self::run( 'mysql --no-defaults', array( + self::run( 'mysql --no-defaults --no-auto-rehash', array( 'database' => DB_NAME ) ); } @@ -109,7 +109,7 @@ function query( $args ) { $assoc_args['execute'] = $args[0]; } - self::run( 'mysql --no-defaults', $assoc_args ); + self::run( 'mysql --no-defaults --no-auto-rehash', $assoc_args ); } /** @@ -192,7 +192,7 @@ function import( $args, $assoc_args ) { ); } - self::run( 'mysql --no-defaults', array( + self::run( 'mysql --no-defaults --no-auto-rehash', array( 'database' => DB_NAME ), $descriptors ); @@ -244,7 +244,7 @@ private static function get_create_query() { } private static function run_query( $query ) { - self::run( 'mysql --no-defaults', array( 'execute' => $query ) ); + self::run( 'mysql --no-defaults --no-auto-rehash', array( 'execute' => $query ) ); } private static function run( $cmd, $assoc_args = array(), $descriptors = null ) { From c2b4a8bbb858a93ca5d4028dcd2e1a6c6891b295 Mon Sep 17 00:00:00 2001 From: Nikolay Yordanov <me@nyordanov.com> Date: Fri, 20 Feb 2015 22:45:06 +0000 Subject: [PATCH 3420/4858] do not force a SHA512 signature in make-phar.php --- utils/make-phar.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index 83e0e106fb..1ce6f7b875 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -53,8 +53,6 @@ function set_file_contents( $phar, $path, $content ) { $phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' ); -$phar->setSignatureAlgorithm( Phar::SHA512 ); - $phar->startBuffering(); // PHP files @@ -114,6 +112,3 @@ function set_file_contents( $phar, $path, $content ) { $phar->stopBuffering(); echo "Generated " . DEST_PATH . "\n"; - -$signature = $phar->getSignature(); -echo "{$signature['hash_type']} signature: {$signature['hash']}\n"; From 8b59d511034ff8313a7b9eb48043173fc7137a45 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 21 Feb 2015 10:23:38 -0800 Subject: [PATCH 3421/4858] Don't append `.phar` because it's already included in `$fname` See #1555 --- ci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 8829599d53..8939208368 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -38,7 +38,7 @@ chmod -x $fname md5sum $fname | cut -d ' ' -f 1 > $fname.md5 sha512sum $fname | cut -d ' ' -f 1 > $fname.sha512 -git add $fname.phar $fname.md5 $fname.sha512 +git add $fname $fname.md5 $fname.sha512 git commit -m "phar build: $TRAVIS_REPO_SLUG@$TRAVIS_COMMIT" git push From 9e4ee3f5a160f5ff12ca295ba62a36a5f65b11d0 Mon Sep 17 00:00:00 2001 From: Josh Betz <j@joshbetz.com> Date: Wed, 25 Feb 2015 22:35:05 -0600 Subject: [PATCH 3422/4858] Pad export filenames with zeros It's helpful in many cases to have these files automatically ordered correctly. Without padded zeros, they will be ordered something like: ``` *.1.xml *.10.xml *.2.xml *.3.xml ... ``` --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 4569d6d082..976901d7b7 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -100,7 +100,7 @@ private static function get_filename_template() { if ( ! empty( $sitename ) ) { $sitename .= '.'; } - return $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.%d.xml'; + return $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.%03d.xml'; } private static function load_export_api() { From 6fbb217e875e9cd7bb73a774bac98b1a95d50950 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 26 Feb 2015 13:36:34 +0000 Subject: [PATCH 3423/4858] When testing WP-Cron, correctly set the `sslverify `argument depending on the version of WordPress in use. --- php/commands/cron.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 32d1959503..527e427988 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -509,7 +509,9 @@ public function test() { * @return WP_Error|array The response or WP_Error on failure. */ protected static function get_cron_spawn() { + global $wp_version; + $sslverify = version_compare( $wp_version, 4.0, '<' ); $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); $cron_request = apply_filters( 'cron_request', array( @@ -518,7 +520,7 @@ protected static function get_cron_spawn() { 'args' => array( 'timeout' => 3, 'blocking' => true, - 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) + 'sslverify' => apply_filters( 'https_local_ssl_verify', $sslverify ) ) ) ); From 078585bfa30fd2759484bbc2e7cb3bc8dc1959f5 Mon Sep 17 00:00:00 2001 From: JQ <JeyKeu@users.noreply.github.com> Date: Tue, 3 Mar 2015 15:16:02 +0500 Subject: [PATCH 3424/4858] Elaborated error message This should fix #1434 When we download the `non-phar` version of `wp-cli` we have to run `composer install` to install it's dependencies. If we try to run `wp` when we haven't run `composer install`, we get this error: `Internal error: Can't find Composer autoloader.` which doesn't help. Instead I added: `Try running: composer install\n` Giving: `Internal error: Can't find Composer autoloader.\nTry running: composer install\n` Which makes more sense. --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index b80c0ea171..9581c164dc 100644 --- a/php/utils.php +++ b/php/utils.php @@ -24,7 +24,7 @@ function load_dependencies() { } if ( !$has_autoload ) { - fputs( STDERR, "Internal error: Can't find Composer autoloader.\n" ); + fputs( STDERR, "Internal error: Can't find Composer autoloader.\nTry running: composer install\n" ); exit(3); } } From 6f373e06c590abf8990e4ae19455905a2e75f604 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 3 Mar 2015 19:45:59 -0800 Subject: [PATCH 3425/4858] Throw hard error if importing a file returns WP_Error `create_author_mapping_file()` uses WP_Error to report that an author mapping file needs to be updated. However, when importing a directory of WXR files, only using `::warning()` means the second file will use the author mapping file of the first, which should've been edited. --- php/commands/import.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index d082d3797c..58668db4d4 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -55,7 +55,7 @@ public function __invoke( $args, $assoc_args ) { $ret = $this->import_wxr( $file, $assoc_args ); if ( is_wp_error( $ret ) ) { - WP_CLI::warning( $ret ); + WP_CLI::error( $ret ); } else { WP_CLI::line(); // WXR import ends with HTML, so make sure message is on next line WP_CLI::success( "Finished importing from $file file." ); From c81c3042855f109926d5cd8a948a29d6ca6b00e1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 3 Mar 2015 20:21:15 -0800 Subject: [PATCH 3426/4858] Ensure our fake cached WordPress download is considered fresh WPorg started serving WordPress downloads with a historic filemtime, meaning our cache gets cleared as soon as we try to use it. --- features/core.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 505b3caa95..fa783ea107 100644 --- a/features/core.feature +++ b/features/core.feature @@ -547,7 +547,7 @@ Feature: Manage WordPress installation Scenario: Ensure file cache isn't corrupted by a ZIP masquerading as a gzipped TAR, part one Given a WP install And an empty cache - And I run `mkdir -p {SUITE_CACHE_DIR}/core; wget -O {SUITE_CACHE_DIR}/core/en_US-4.0.tar.gz https://wordpress.org/wordpress-4.0.zip` + And I run `mkdir -p {SUITE_CACHE_DIR}/core; wget -O {SUITE_CACHE_DIR}/core/en_US-4.0.tar.gz https://wordpress.org/wordpress-4.0.zip; touch {SUITE_CACHE_DIR}/core/en_US-4.0.tar.gz` When I run `wp core download --version=4.0 --force` Then STDOUT should contain: From 8825b8b183a46bc5e2c4e503320130b03cd3f4b6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 3 Mar 2015 20:28:18 -0800 Subject: [PATCH 3427/4858] If a term is missing a parent, be more descriptive as to where it's missing --- php/export/class-wp-export-query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 6f5bb9bf31..95c176c75d 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -294,7 +294,7 @@ private function check_for_orphaned_terms( $terms ) { foreach ( $have_parent as $has_parent ) { if ( ! isset( $term_ids[ $has_parent->parent ] ) ) { $this->missing_parents = $has_parent; - throw new WP_Export_Term_Exception( __( 'Term is missing a parent.' ) ); + throw new WP_Export_Term_Exception( sprintf( __( 'Term is missing a parent: %s (%d)' ), $has_parent->slug, $has_parent->term_taxonomy_id ) ); } } } From 2818c2057b1d064f2257e6ea7821a3794f510041 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 4 Mar 2015 07:06:23 -0800 Subject: [PATCH 3428/4858] Update php-cli-tools to v0.10.4 See https://github.com/wp-cli/php-cli-tools/releases/tag/v0.10.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8d35b340c9..6b17472c77 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.10.3", + "wp-cli/php-cli-tools": "0.10.4", "mustache/mustache": "~2.4", "rhumsaa/array_column": "~1.1", "rmccue/requests": "~1.6", From 7bd1553d9a0fab8885384367c493a8272a9eff82 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 4 Mar 2015 07:14:49 -0800 Subject: [PATCH 3429/4858] Wrap comment meta values in CDATA on export --- php/export/class-wp-export-wxr-formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php index 5a99543a79..92c15f768c 100644 --- a/php/export/class-wp-export-wxr-formatter.php +++ b/php/export/class-wp-export-wxr-formatter.php @@ -252,7 +252,7 @@ protected function comment_meta( $comment ) { foreach( $metas as $meta ) { $oxymel->tag( 'wp:commentmeta' )->contains ->tag( 'wp:meta_key', $meta->meta_key ) - ->tag( 'wp:meta_value', $meta->meta_value ) + ->tag( 'wp:meta_value' )->contains->cdata( $meta->meta_value )->end ->end; } return $oxymel; From 71377a3b56c4196ddb7883441b0832b60acb89bb Mon Sep 17 00:00:00 2001 From: Keith Grennan <keith@nearlyfree.org> Date: Wed, 4 Mar 2015 13:39:51 -0800 Subject: [PATCH 3430/4858] sanitize option before checking value equality If a plugin defines a sanitize_option filter, the equality check in 'wp option update' may indicate that the the new option value is different from the original when in fact it is not. The result is a spurious error message on an unchanged option, instead of succeeding with 'Value passed for 'foo' option is unchanged'. I see this with the Yoast SEO plugin which defines this filter. --- php/commands/option.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index 443bfaac5a..6f8b8e888c 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -203,6 +203,8 @@ public function update( $args, $assoc_args ) { $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); $value = WP_CLI::read_value( $value, $assoc_args ); + $value = sanitize_option( $key, $value ); + if ( $value === get_option( $key ) ) { WP_CLI::success( "Value passed for '$key' option is unchanged." ); } else { @@ -246,4 +248,3 @@ private static function esc_like( $old ) { } WP_CLI::add_command( 'option', 'Option_Command' ); - From bfa7266d137a50a4d4ac50101398f5c3db9de25e Mon Sep 17 00:00:00 2001 From: Keith Grennan <keith@nearlyfree.org> Date: Thu, 5 Mar 2015 06:34:35 -0800 Subject: [PATCH 3431/4858] sanitize the value to compare as well The === comparison in 'wp option update' was breaking due to sanitize_option() turning the value of blog_public from a string to an integer. This comparison logic seems brittle but I understand the problem that WP's update_option returns false both on errors and when the option is unchanged, so we're trying to distinguish between them. --- php/commands/option.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index 6f8b8e888c..6575da1a36 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -204,8 +204,9 @@ public function update( $args, $assoc_args ) { $value = WP_CLI::read_value( $value, $assoc_args ); $value = sanitize_option( $key, $value ); + $old_value = sanitize_option( $key, get_option( $key ) ); - if ( $value === get_option( $key ) ) { + if ( $value === $old_value ) { WP_CLI::success( "Value passed for '$key' option is unchanged." ); } else { if ( update_option( $key, $value ) ) { From b79f7e31aac7c8251556bc267b7adc5f4a55ad05 Mon Sep 17 00:00:00 2001 From: Keith Grennan <keith@nearlyfree.org> Date: Thu, 5 Mar 2015 07:43:33 -0800 Subject: [PATCH 3432/4858] apply option unchanged logic to post meta --- features/post-meta.feature | 3 +++ php/WP_CLI/CommandWithMeta.php | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/features/post-meta.feature b/features/post-meta.feature index 821be2fad6..9e37fd5103 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -21,6 +21,9 @@ Feature: Manage post custom fields When I run `wp post-meta set 1 foo '[ "1", "2" ]' --format=json` Then STDOUT should not be empty + When I run the previous command again + Then STDOUT should not be empty + When I run `wp post-meta get 1 foo --format=json` Then STDOUT should be: """ diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 1d1f72ecae..9e9b07518f 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -181,13 +181,22 @@ public function update( $args, $assoc_args ) { $object_id = $this->check_object_id( $object_id ); - $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $meta_value = sanitize_meta( $meta_key, $meta_value, $this->meta_type ); + $old_value = sanitize_meta( $meta_key, get_metadata( $this->meta_type, $object_id, $meta_key, true ), $this->meta_type ); - if ( $success ) { - \WP_CLI::success( "Updated custom field." ); + if ( $meta_value === $old_value ) { + \WP_CLI::success( "Value passed for custom field '$meta_key' is unchanged." ); } else { - \WP_CLI::error( "Failed to update custom field." ); + $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + + if ( $success ) { + \WP_CLI::success( "Updated custom field '$meta_key'." ); + } else { + \WP_CLI::error( "Failed to update custom field '$meta_key'." ); + } + } + } /** @@ -214,4 +223,3 @@ protected function check_object_id( $object_id ) { } } - From 09c8208cd045f3125cc64309424a954a1d1212e4 Mon Sep 17 00:00:00 2001 From: Keith Grennan <keith@nearlyfree.org> Date: Thu, 5 Mar 2015 13:13:37 -0800 Subject: [PATCH 3433/4858] check for the specific message --- features/post-meta.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/post-meta.feature b/features/post-meta.feature index 9e37fd5103..74b30eabc6 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -22,7 +22,10 @@ Feature: Manage post custom fields Then STDOUT should not be empty When I run the previous command again - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: Value passed for custom field 'foo' is unchanged. + """ When I run `wp post-meta get 1 foo --format=json` Then STDOUT should be: From d91f39d77462ed58b098db123e47d9b552d675f8 Mon Sep 17 00:00:00 2001 From: Jim Reevior <jim@thinkoomph.com> Date: Thu, 5 Mar 2015 17:58:32 -0500 Subject: [PATCH 3434/4858] Added allow multisite constant to multisite install and convert. The multisite install and convert procedures do not include: define( 'WP_ALLOW_MULTISITE', true ); If this isn't present, the "Network Settings" and "Network Setup" menu items are not available in the network admin. --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index 9fbbb34cd7..c79c9ed5af 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -636,6 +636,7 @@ private function _multisite_convert( $assoc_args ) { if ( !is_multisite() ) { ob_start(); ?> +define( 'WP_ALLOW_MULTISITE', true ); define('MULTISITE', true); define('SUBDOMAIN_INSTALL', <?php var_export( $assoc_args['subdomains'] ); ?>); $base = '<?php echo $assoc_args['base']; ?>'; From 4e88a33d10794d0ddbdc8eb7714e056722a19bd4 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Thu, 5 Mar 2015 23:42:45 -0600 Subject: [PATCH 3435/4858] Add --all-tables flag to search-replace command --- php/commands/search-replace.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index cd09e1861d..20fbb7e764 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -46,6 +46,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--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. + * * ## EXAMPLES * * wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid @@ -64,6 +67,7 @@ public function __invoke( $args, $assoc_args ) { $dry_run = isset( $assoc_args['dry-run'] ); $php_only = isset( $assoc_args['precise'] ); $recurse_objects = isset( $assoc_args['recurse-objects'] ); + $all_tables = isset( $assoc_args['all-tables'] ); if ( isset( $assoc_args['skip-columns'] ) ) $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -73,7 +77,16 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; - $tables = self::get_table_list( $args, isset( $assoc_args['network'] ), isset( $assoc_args['all-tables-with-prefix'] ) ); + if ( $all_tables ) { + WP_CLI::confirm( "Will run against ALL tables in the database, not only WordPress tables. Continue?" ); + $tables = $wpdb->get_col( 'SHOW TABLES' ); + } else { + $tables = self::get_table_list( + $args, + isset( $assoc_args['network'] ), + isset( $assoc_args['all-tables-with-prefix'] ) + ); + } foreach ( $tables as $table ) { list( $primary_keys, $columns ) = self::get_columns( $table ); From aa783be40c36c477a6afbcd18c8545a14d646f55 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Thu, 5 Mar 2015 23:43:37 -0600 Subject: [PATCH 3436/4858] Add tests for --all-tables flag --- features/search-replace.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index f85ae7c246..d66b6bcef5 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -40,6 +40,22 @@ Feature: Do global search/replace wp_awesome """ + Scenario: Run on unregistered, unprefixed tables with --all-tables flag + Given a WP install + And I run `wp db query "CREATE TABLE awesome_table ( id int(11) unsigned NOT NULL AUTO_INCREMENT, awesome_stuff TEXT, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"` + + When I run `wp search-replace foo bar` + Then STDOUT should not contain: + """ + awesome_table + """ + + When I run `wp search-replace foo bar --all-tables` + Then STDOUT should contain: + """ + awesome_table + """ + Scenario: Quiet search/replace Given a WP install From f4b28dab4c4aadb774343532ce2a5a3b0e74782f Mon Sep 17 00:00:00 2001 From: yivi <ivan@ojiva.es> Date: Sat, 7 Mar 2015 11:52:27 +0100 Subject: [PATCH 3437/4858] Check to see if _s theme has actually been created, or if the unzip operation failed. --- php/commands/scaffold.php | 213 ++++++++++++++++++++------------------ 1 file changed, 115 insertions(+), 98 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index a4d239b72c..1b8d7485d9 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -39,7 +39,7 @@ class Scaffold_Command extends WP_CLI_Command { * * @subcommand post-type * - * @alias cpt + * @alias cpt */ function post_type( $args, $assoc_args ) { @@ -91,7 +91,7 @@ function post_type( $args, $assoc_args ) { * * @subcommand taxonomy * - * @alias tax + * @alias tax */ function taxonomy( $args, $assoc_args ) { $defaults = array( @@ -99,7 +99,7 @@ function taxonomy( $args, $assoc_args ) { 'post_types' => "'post'" ); - if( isset($assoc_args['post_types']) ) { + if ( isset( $assoc_args['post_types'] ) ) { $assoc_args['post_types'] = $this->quote_comma_list_elements( $assoc_args['post_types'] ); } @@ -114,9 +114,9 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $control_args = $this->extract_args( $assoc_args, array( 'label' => preg_replace( '/_|-/', ' ', strtolower( $slug ) ), - 'theme' => false, - 'plugin' => false, - 'raw' => false, + 'theme' => FALSE, + 'plugin' => FALSE, + 'raw' => FALSE, ) ); $vars = $this->extract_args( $assoc_args, $defaults ); @@ -132,7 +132,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $vars['label_plural_ucfirst'] = ucfirst( $vars['label_plural'] ); // We use the machine name for function declarations - $machine_name = preg_replace( '/-/', '_', $slug ); + $machine_name = preg_replace( '/-/', '_', $slug ); $machine_name_plural = $this->pluralize( $slug ); list( $raw_template, $extended_template ) = $templates; @@ -142,7 +142,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) if ( ! $control_args['raw'] ) { $vars = array_merge( $vars, array( 'machine_name' => $machine_name, - 'output' => $raw_output + 'output' => $raw_output ) ); $final_output = Utils\mustache_render( $extended_template, $vars ); @@ -151,7 +151,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) } if ( $path = $this->get_output_path( $control_args, $subdir ) ) { - $filename = $path . $slug .'.php'; + $filename = $path . $slug . '.php'; $this->create_file( $filename, $final_output ); @@ -189,31 +189,35 @@ function _s( $args, $assoc_args ) { $theme_slug = $args[0]; $theme_path = WP_CONTENT_DIR . "/themes"; - $url = "http://underscores.me"; - $timeout = 30; + $url = "http://underscores.me"; + $timeout = 30; $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), - 'author' => "Me", + 'author' => "Me", 'author_uri' => "", ) ); - $theme_description = "Custom theme: ".$data['theme_name']." developed by, ".$data['author']; + $theme_description = "Custom theme: " . $data['theme_name'] . " developed by, " . $data['author']; - $body = array(); - $body['underscoresme_name'] = $data['theme_name']; - $body['underscoresme_slug'] = $theme_slug; - $body['underscoresme_author'] = $data['author']; - $body['underscoresme_author_uri'] = $data['author_uri']; - $body['underscoresme_description'] = $theme_description; + $body = array(); + $body['underscoresme_name'] = $data['theme_name']; + $body['underscoresme_slug'] = $theme_slug; + $body['underscoresme_author'] = $data['author']; + $body['underscoresme_author_uri'] = $data['author_uri']; + $body['underscoresme_description'] = $theme_description; $body['underscoresme_generate_submit'] = "Generate"; - $body['underscoresme_generate'] = "1"; + $body['underscoresme_generate'] = "1"; if ( isset( $assoc_args['sassify'] ) ) { $body['underscoresme_sass'] = 1; } - $tmpfname = wp_tempnam($url); - $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, 'stream' => true, 'filename' => $tmpfname ) ); + $tmpfname = wp_tempnam( $url ); + $response = wp_remote_post( $url, array( 'timeout' => $timeout, + 'body' => $body, + 'stream' => TRUE, + 'filename' => $tmpfname + ) ); if ( is_wp_error( $response ) ) { WP_CLI::error( $response ); @@ -227,13 +231,19 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); $this->init_wp_filesystem(); - unzip_file( $tmpfname, $theme_path ); + $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); - WP_CLI::success( "Created theme '{$data['theme_name']}'." ); + if ( TRUE === $unzip_result ) { + WP_CLI::success( "Created theme '{$data['theme_name']}'." ); + } else { + WP_CLI::error( "Could not decompress your theme files ('$tmpfname') at '$theme_path': " . $unzip_result->get_error_message() ); + print_r( $unzip_result ); + } - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + } } @@ -270,15 +280,15 @@ function child_theme( $args, $assoc_args ) { $data = wp_parse_args( $assoc_args, array( 'theme_name' => ucfirst( $theme_slug ), - 'author' => "Me", + 'author' => "Me", 'author_uri' => "", - 'theme_uri' => "" + 'theme_uri' => "" ) ); $data['description'] = ucfirst( $data['parent_theme'] ) . " child theme."; - $theme_dir = WP_CONTENT_DIR . "/themes" . "/$theme_slug"; - $theme_style_path = "$theme_dir/style.css"; + $theme_dir = WP_CONTENT_DIR . "/themes" . "/$theme_slug"; + $theme_style_path = "$theme_dir/style.css"; $theme_functions_path = "$theme_dir/functions.php"; $this->maybe_create_themes_dir(); @@ -288,25 +298,27 @@ function child_theme( $args, $assoc_args ) { WP_CLI::success( "Created $theme_dir" ); - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + } } private function get_output_path( $assoc_args, $subdir ) { if ( $assoc_args['theme'] ) { $theme = $assoc_args['theme']; - if ( is_string( $theme ) ) + if ( is_string( $theme ) ) { $path = get_theme_root( $theme ) . '/' . $theme; - else + } else { $path = get_stylesheet_directory(); + } } elseif ( $assoc_args['plugin'] ) { $plugin = $assoc_args['plugin']; - $path = WP_PLUGIN_DIR . '/' . $plugin; - if ( !is_dir( $path ) ) { + $path = WP_PLUGIN_DIR . '/' . $plugin; + if ( ! is_dir( $path ) ) { WP_CLI::error( "Can't find '$plugin' plugin." ); } } else { - return false; + return FALSE; } $path .= $subdir; @@ -342,7 +354,7 @@ private function get_output_path( $assoc_args, $subdir ) { * * wp scaffold package-tests /path/to/command/dir/ * - * @when before_wp_load + * @when before_wp_load * @subcommand package-tests */ public function package_tests( $args, $assoc_args ) { @@ -360,39 +372,39 @@ public function package_tests( $args, $assoc_args ) { } $package_dir .= '/'; - $bin_dir = $package_dir . 'bin/'; - $utils_dir = $package_dir . 'utils/'; - $features_dir = $package_dir . 'features/'; + $bin_dir = $package_dir . 'bin/'; + $utils_dir = $package_dir . 'utils/'; + $features_dir = $package_dir . 'features/'; $bootstrap_dir = $features_dir . 'bootstrap/'; - $steps_dir = $features_dir . 'steps/'; - $extra_dir = $features_dir . 'extra/'; - foreach( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir, $utils_dir, $bin_dir ) as $dir ) { + $steps_dir = $features_dir . 'steps/'; + $extra_dir = $features_dir . 'extra/'; + foreach ( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir, $utils_dir, $bin_dir ) as $dir ) { if ( ! is_dir( $dir ) ) { Process::create( Utils\esc_cmd( 'mkdir %s', $dir ) )->run(); } } $to_copy = array( - 'templates/.travis.package.yml' => $package_dir, - 'templates/load-wp-cli.feature' => $features_dir, - 'templates/install-package-tests.sh' => $bin_dir, - 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, - 'features/bootstrap/support.php' => $bootstrap_dir, - 'php/WP_CLI/Process.php' => $bootstrap_dir, - 'php/utils.php' => $bootstrap_dir, + 'templates/.travis.package.yml' => $package_dir, + 'templates/load-wp-cli.feature' => $features_dir, + 'templates/install-package-tests.sh' => $bin_dir, + 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, + 'features/bootstrap/support.php' => $bootstrap_dir, + 'php/WP_CLI/Process.php' => $bootstrap_dir, + 'php/utils.php' => $bootstrap_dir, 'utils/get-package-require-from-composer.php' => $utils_dir, - 'features/steps/given.php' => $steps_dir, - 'features/steps/when.php' => $steps_dir, - 'features/steps/then.php' => $steps_dir, - 'features/extra/no-mail.php' => $extra_dir, + 'features/steps/given.php' => $steps_dir, + 'features/steps/when.php' => $steps_dir, + 'features/steps/then.php' => $steps_dir, + 'features/extra/no-mail.php' => $extra_dir, ); foreach ( $to_copy as $file => $dir ) { // file_get_contents() works with Phar-archived files - $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); + $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); $file_path = $dir . basename( $file ); - $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml'), $file_path ); - $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); + $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml' ), $file_path ); + $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); file_put_contents( $file_path, $contents ); if ( 'templates/install-package-tests.sh' === $file ) { Process::create( Utils\esc_cmd( 'chmod +x %s', $file_path ) )->run(); @@ -429,8 +441,8 @@ function plugin( $args, $assoc_args ) { $data['textdomain'] = $plugin_slug; - $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - $plugin_path = "$plugin_dir/$plugin_slug.php"; + $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + $plugin_path = "$plugin_dir/$plugin_slug.php"; $plugin_readme_path = "$plugin_dir/readme.txt"; $this->maybe_create_plugins_dir(); @@ -440,7 +452,7 @@ function plugin( $args, $assoc_args ) { WP_CLI::success( "Created $plugin_dir" ); - if ( !isset( $assoc_args['skip-tests'] ) ) { + if ( ! isset( $assoc_args['skip-tests'] ) ) { WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ) ); } @@ -483,8 +495,8 @@ function plugin_tests( $args, $assoc_args ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - $tests_dir = "$plugin_dir/tests"; - $bin_dir = "$plugin_dir/bin"; + $tests_dir = "$plugin_dir/tests"; + $bin_dir = "$plugin_dir/bin"; $wp_filesystem->mkdir( $tests_dir ); $wp_filesystem->mkdir( $bin_dir ); @@ -494,13 +506,13 @@ function plugin_tests( $args, $assoc_args ) { $to_copy = array( 'install-wp-tests.sh' => $bin_dir, - '.travis.yml' => $plugin_dir, - 'phpunit.xml' => $plugin_dir, - 'test-sample.php' => $tests_dir, + '.travis.yml' => $plugin_dir, + 'phpunit.xml' => $plugin_dir, + 'test-sample.php' => $tests_dir, ); foreach ( $to_copy as $file => $dir ) { - $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); + $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", TRUE ); if ( 'install-wp-tests.sh' === $file ) { if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); @@ -516,7 +528,7 @@ private function create_file( $filename, $contents ) { $wp_filesystem->mkdir( dirname( $filename ) ); - if ( !$wp_filesystem->put_contents( $filename, $contents ) ) { + if ( ! $wp_filesystem->put_contents( $filename, $contents ) ) { WP_CLI::error( "Error creating file: $filename" ); } } @@ -526,62 +538,65 @@ private function create_file( $filename, $contents ) { * Same goes for when plugin is being used. */ private function get_textdomain( $textdomain, $args ) { - if ( strlen( $textdomain ) ) + if ( strlen( $textdomain ) ) { return $textdomain; + } - if ( $args['theme'] ) + if ( $args['theme'] ) { return strtolower( wp_get_theme()->template ); + } - if ( $args['plugin'] && true !== $args['plugin'] ) + if ( $args['plugin'] && TRUE !== $args['plugin'] ) { return $args['plugin']; + } return 'YOUR-TEXTDOMAIN'; } private function pluralize( $word ) { $plural = array( - '/(quiz)$/i' => '\1zes', - '/^(ox)$/i' => '\1en', - '/([m|l])ouse$/i' => '\1ice', - '/(matr|vert|ind)ix|ex$/i' => '\1ices', - '/(x|ch|ss|sh)$/i' => '\1es', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive)$/i' => '\1s', - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(buffal|tomat)o$/i' => '\1oes', - '/(bu)s$/i' => '1ses', - '/(alias|status)/i' => '\1es', - '/(octop|vir)us$/i' => '1i', - '/(ax|test)is$/i' => '\1es', - '/s$/i' => 's', - '/$/' => 's' + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)ix|ex$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(buffal|tomat)o$/i' => '\1oes', + '/(bu)s$/i' => '1ses', + '/(alias|status)/i' => '\1es', + '/(octop|vir)us$/i' => '1i', + '/(ax|test)is$/i' => '\1es', + '/s$/i' => 's', + '/$/' => 's' ); $uncountable = array( 'equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep' ); $irregular = array( - 'person' => 'people', - 'man' => 'men', - 'woman' => 'women', - 'child' => 'children', - 'sex' => 'sexes', - 'move' => 'moves' + 'person' => 'people', + 'man' => 'men', + 'woman' => 'women', + 'child' => 'children', + 'sex' => 'sexes', + 'move' => 'moves' ); $lowercased_word = strtolower( $word ); foreach ( $uncountable as $_uncountable ) { - if ( substr( $lowercased_word, ( -1 * strlen( $_uncountable ) ) ) == $_uncountable ) { + if ( substr( $lowercased_word, ( - 1 * strlen( $_uncountable ) ) ) == $_uncountable ) { return $word; } } - foreach ( $irregular as $_plural=> $_singular ) { - if ( preg_match( '/('.$_plural.')$/i', $word, $arr ) ) { - return preg_replace( '/('.$_plural.')$/i', substr( $arr[0], 0, 1 ).substr( $_singular, 1 ), $word ); + foreach ( $irregular as $_plural => $_singular ) { + if ( preg_match( '/(' . $_plural . ')$/i', $word, $arr ) ) { + return preg_replace( '/(' . $_plural . ')$/i', substr( $arr[0], 0, 1 ) . substr( $_singular, 1 ), $word ); } } @@ -590,7 +605,8 @@ private function pluralize( $word ) { return preg_replace( $rule, $replacement, $word ); } } - return false; + + return FALSE; } protected function extract_args( $assoc_args, $defaults ) { @@ -638,6 +654,7 @@ protected function maybe_create_plugins_dir() { private function init_wp_filesystem() { global $wp_filesystem; WP_Filesystem(); + return $wp_filesystem; } From 286c49816061fd4a8e379ecd91ca0e8408ba1f0e Mon Sep 17 00:00:00 2001 From: yivi <ivan@ojiva.es> Date: Sat, 7 Mar 2015 12:13:49 +0100 Subject: [PATCH 3438/4858] changed spaces for tabs to pass travis tests --- php/commands/scaffold.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 1b8d7485d9..f43be21eb7 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -213,11 +213,12 @@ function _s( $args, $assoc_args ) { } $tmpfname = wp_tempnam( $url ); - $response = wp_remote_post( $url, array( 'timeout' => $timeout, - 'body' => $body, - 'stream' => TRUE, - 'filename' => $tmpfname - ) ); + $response = wp_remote_post( $url, array( + 'timeout' => $timeout, + 'body' => $body, + 'stream' => TRUE, + 'filename' => $tmpfname + ) ); if ( is_wp_error( $response ) ) { WP_CLI::error( $response ); From 589ca86392f7790e3446bcbf11c12295c35a9f24 Mon Sep 17 00:00:00 2001 From: Bobby Walters <bobbymwalters@gmail.com> Date: Sat, 7 Mar 2015 23:31:02 -0500 Subject: [PATCH 3439/4858] Honor https scheme on --url option When using the --url global option (or during core install), URLs with an https scheme were being treated as http. The WP is_ssl() function checks for the $_SERVER['HTTPS'] flag or port 443 being set. This change allows standard and non-standard ports to be used so is_ssl() will return true when the supplied URL has an https scheme. This helps with the wp_guess_url() call during wp_install() so the proper URL is used when populating the database. --- php/class-wp-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index cfe4ae30ae..f571c47a59 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -103,6 +103,10 @@ private static function set_url_params( $url_parts ) { }; if ( isset( $url_parts['host'] ) ) { + if ( isset( $url_parts['scheme'] ) && 'https' === strtolower( $url_parts['scheme'] ) ) { + $_SERVER['HTTPS'] = 'on'; + } + $_SERVER['HTTP_HOST'] = $url_parts['host']; if ( isset( $url_parts['port'] ) ) { $_SERVER['HTTP_HOST'] .= ':' . $url_parts['port']; From 29e345f5f945e1995fae5f465786155e94b5a078 Mon Sep 17 00:00:00 2001 From: Bobby Walters <bobbymwalters@gmail.com> Date: Sun, 8 Mar 2015 16:12:12 -0400 Subject: [PATCH 3440/4858] Added functional tests for --url=https://... --- features/core.feature | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/features/core.feature b/features/core.feature index fa783ea107..636989d600 100644 --- a/features/core.feature +++ b/features/core.feature @@ -53,7 +53,7 @@ Feature: Manage WordPress installation Error: wp-config.php not found. Either create one manually or use `wp core config`. """ - + Given a wp-config-extra.php file: """ define( 'WP_DEBUG_LOG', true ); @@ -162,6 +162,36 @@ Feature: Manage WordPress installation http://localhost:8001 """ + Scenario: Install WordPress with an https scheme + Given an empty directory + And WP files + And wp-config.php + And a database + + When I run `wp core install --url='https://localhost' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + Then the return code should be 0 + + When I run `wp eval 'echo home_url();'` + Then STDOUT should be: + """ + https://localhost + """ + + Scenario: Install WordPress with an https scheme and non-standard port + Given an empty directory + And WP files + And wp-config.php + And a database + + When I run `wp core install --url='https://localhost:8443' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + Then the return code should be 0 + + When I run `wp eval 'echo home_url();'` + Then STDOUT should be: + """ + https://localhost:8443 + """ + Scenario: Full install Given a WP install @@ -173,7 +203,7 @@ Feature: Manage WordPress installation Then STDOUT should be: """ false - """ + """ When I run `wp eval 'var_export( function_exists( 'media_handle_upload' ) );'` Then STDOUT should be: @@ -225,7 +255,7 @@ Feature: Manage WordPress installation Then STDOUT should be: """ foobar.org - """ + """ # Can complain that it's already installed, but don't exit with an error code When I try `wp core multisite-install --url=foobar.org --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` From 87dda00ffcae850b4c542b90b98611cce37832de Mon Sep 17 00:00:00 2001 From: yivi <ivan@ojiva.es> Date: Mon, 9 Mar 2015 11:53:53 +0100 Subject: [PATCH 3441/4858] uppercase booleans to lowercase braces for variables inside a string. --- php/commands/scaffold.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f43be21eb7..0e52489c71 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -114,9 +114,9 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $control_args = $this->extract_args( $assoc_args, array( 'label' => preg_replace( '/_|-/', ' ', strtolower( $slug ) ), - 'theme' => FALSE, - 'plugin' => FALSE, - 'raw' => FALSE, + 'theme' => false, + 'plugin' => false, + 'raw' => false, ) ); $vars = $this->extract_args( $assoc_args, $defaults ); @@ -216,7 +216,7 @@ function _s( $args, $assoc_args ) { $response = wp_remote_post( $url, array( 'timeout' => $timeout, 'body' => $body, - 'stream' => TRUE, + 'stream' => true, 'filename' => $tmpfname ) ); @@ -235,11 +235,10 @@ function _s( $args, $assoc_args ) { $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); - if ( TRUE === $unzip_result ) { + if ( true === $unzip_result ) { WP_CLI::success( "Created theme '{$data['theme_name']}'." ); } else { - WP_CLI::error( "Could not decompress your theme files ('$tmpfname') at '$theme_path': " . $unzip_result->get_error_message() ); - print_r( $unzip_result ); + WP_CLI::error( "Could not decompress your theme files ('{$tmpfname}') at '{$theme_path}': {$unzip_result->get_error_message()}" ); } if ( isset( $assoc_args['activate'] ) ) { @@ -319,7 +318,7 @@ private function get_output_path( $assoc_args, $subdir ) { WP_CLI::error( "Can't find '$plugin' plugin." ); } } else { - return FALSE; + return false; } $path .= $subdir; @@ -513,7 +512,7 @@ function plugin_tests( $args, $assoc_args ) { ); foreach ( $to_copy as $file => $dir ) { - $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", TRUE ); + $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); if ( 'install-wp-tests.sh' === $file ) { if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); @@ -547,7 +546,7 @@ private function get_textdomain( $textdomain, $args ) { return strtolower( wp_get_theme()->template ); } - if ( $args['plugin'] && TRUE !== $args['plugin'] ) { + if ( $args['plugin'] && true !== $args['plugin'] ) { return $args['plugin']; } @@ -607,7 +606,7 @@ private function pluralize( $word ) { } } - return FALSE; + return false; } protected function extract_args( $assoc_args, $defaults ) { From ad0dfddf558b24c379ed18d6036757d9e615a647 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 9 Mar 2015 12:26:09 -0300 Subject: [PATCH 3442/4858] `wp post term list` display error for invalid taxonomy --- features/post-term.feature | 8 +++++++- php/WP_CLI/CommandWithTerms.php | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/features/post-term.feature b/features/post-term.feature index 20ab616b23..d38f628c2d 100644 --- a/features/post-term.feature +++ b/features/post-term.feature @@ -26,6 +26,12 @@ Feature: Manage post term | foo | foo | category | | bar | bar | category | + When I try `wp post term list 1 foo2` + Then STDERR should be: + """ + Error: Invalid taxonomy foo2. + """ + When I run `wp post term set 1 category new` Then STDOUT should be: """ @@ -89,5 +95,5 @@ Feature: Manage post term Then the return code should be 1 And STDERR should be: """ - Error: Invalid taxonomy. + Error: Invalid taxonomy foo2. """ diff --git a/php/WP_CLI/CommandWithTerms.php b/php/WP_CLI/CommandWithTerms.php index 1ba36170fe..277fe4aed2 100644 --- a/php/WP_CLI/CommandWithTerms.php +++ b/php/WP_CLI/CommandWithTerms.php @@ -72,6 +72,10 @@ public function list_( $args, $assoc_args ) { $this->set_obj_id( $object_id ); + foreach ( $taxonomy_names as $taxonomy ) { + $this->taxonomy_exists( $taxonomy ); + } + $items = wp_get_object_terms( $object_id, $taxonomy_names ); $formatter = $this->get_formatter( $assoc_args ); @@ -263,7 +267,7 @@ protected function taxonomy_exists( $taxonomy ) { $taxonomy_names = get_object_taxonomies( $this->get_object_type() ); if ( ! in_array( $taxonomy, $taxonomy_names ) ) { - WP_CLI::error( 'Invalid taxonomy.' ); + WP_CLI::error( "Invalid taxonomy {$taxonomy}." ); } } From 32417605ff1fe16fb659266f3163548792b36437 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 9 Mar 2015 14:44:00 -0300 Subject: [PATCH 3443/4858] fix failing test --- features/user-term.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/user-term.feature b/features/user-term.feature index 3895f20a2c..0c83e2f7a8 100644 --- a/features/user-term.feature +++ b/features/user-term.feature @@ -105,5 +105,5 @@ Feature: Manage user term Then the return code should be 1 And STDERR should be: """ - Error: Invalid taxonomy. + Error: Invalid taxonomy boo. """ \ No newline at end of file From 2f6d0374ec589b483213f6d19e3b1439496f08d3 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 13:41:47 -0400 Subject: [PATCH 3444/4858] Create utility function for options. --- php/utils.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/php/utils.php b/php/utils.php index 9581c164dc..46143896fd 100644 --- a/php/utils.php +++ b/php/utils.php @@ -504,3 +504,18 @@ function increment_version( $current_version, $new_version ) { return $current_version; } + +/** + * Determine the boolean value of a flag in an array. + * + * Primarily useful for determining the status of a boolean flag for a command. This is needed because a flag can be + * prefixed with --no- to set it to false. Therefore it is not sufficient to only check whether a flag is set. + * + * @param array $array The array to check. + * @param string $key The key to check for. + * + * @return bool True if the key is set in the array and is truthy, false otherwise. + */ +function flag( $array, $key ) { + return isset( $array[ $key ] ) && $array[ $key ]; +} From 35e3fec28430c40ccf3d876a5fdb0c625d10ada5 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 13:49:08 -0400 Subject: [PATCH 3445/4858] Formatting updates --- php/commands/search-replace.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 20fbb7e764..d34c510ffd 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -69,10 +69,11 @@ public function __invoke( $args, $assoc_args ) { $recurse_objects = isset( $assoc_args['recurse-objects'] ); $all_tables = isset( $assoc_args['all-tables'] ); - if ( isset( $assoc_args['skip-columns'] ) ) + if ( isset( $assoc_args['skip-columns'] ) ) { $skip_columns = explode( ',', $assoc_args['skip-columns'] ); - else + } else { $skip_columns = array(); + } // never mess with hashed passwords $skip_columns[] = 'user_pass'; @@ -128,8 +129,9 @@ public function __invoke( $args, $assoc_args ) { $table->setRows( $report ); $table->display(); - if ( !$dry_run ) + if ( ! $dry_run ) { WP_CLI::success( "Made $total replacements." ); + } } } From ce2df83279f482a682f9b173a1b3591e4cd8c214 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 13:50:59 -0400 Subject: [PATCH 3446/4858] Update get_table_list to process assoc_args directly --- php/commands/search-replace.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index d34c510ffd..b8bd7bee8f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -136,11 +136,23 @@ public function __invoke( $args, $assoc_args ) { } } - private static function get_table_list( $args, $network, $all_with_prefix ) { + /** + * Retrieve a list of tables from the database. + * + * @param array $assoc_args Array of options passed to this command. + * + * @return array The array of table names. + */ + private static function get_table_list( $assoc_args ) { global $wpdb; - if ( !empty( $args ) ) - return $args; + $network = \WP_CLI\Utils\flag( $assoc_args, 'network' ); + $all_tables = \WP_CLI\Utils\flag( $assoc_args, 'all-tables' ); + $all_with_prefix = \WP_CLI\Utils\flag( $assoc_args, 'all-tables-with-prefix' ); + + if ( $all_tables ) { + return $wpdb->get_col( 'SHOW TABLES' ); + } $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); From a5ce331223173b84982a9d9937a3a5919b71c6ad Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 13:51:17 -0400 Subject: [PATCH 3447/4858] Use new utility function for flags --- php/commands/search-replace.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b8bd7bee8f..86d4bb4de1 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -64,10 +64,9 @@ public function __invoke( $args, $assoc_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'] ); - $all_tables = isset( $assoc_args['all-tables'] ); + $dry_run = \WP_CLI\Utils\flag( $assoc_args, 'dry-run' ); + $php_only = \WP_CLI\Utils\flag( $assoc_args, 'precise' ); + $recurse_objects = \WP_CLI\Utils\flag( $assoc_args, 'recurse-objects' ); if ( isset( $assoc_args['skip-columns'] ) ) { $skip_columns = explode( ',', $assoc_args['skip-columns'] ); From 53eec3e5640c79296cb82a0d2f01abd449822db6 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 13:51:38 -0400 Subject: [PATCH 3448/4858] Update call to get_table_list --- php/commands/search-replace.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 86d4bb4de1..372312d8bf 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -77,17 +77,8 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; - if ( $all_tables ) { - WP_CLI::confirm( "Will run against ALL tables in the database, not only WordPress tables. Continue?" ); - $tables = $wpdb->get_col( 'SHOW TABLES' ); - } else { - $tables = self::get_table_list( - $args, - isset( $assoc_args['network'] ), - isset( $assoc_args['all-tables-with-prefix'] ) - ); - } - + // 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( $args, $assoc_args ) : $args; foreach ( $tables as $table ) { list( $primary_keys, $columns ) = self::get_columns( $table ); From beae4842d3cbad76e5399749136599b141e64394 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 14:00:11 -0400 Subject: [PATCH 3449/4858] Align consecutive assignments --- php/commands/search-replace.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 372312d8bf..6035a2cd95 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -60,12 +60,12 @@ class Search_Replace_Command extends WP_CLI_Command { */ 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\flag( $assoc_args, 'dry-run' ); - $php_only = \WP_CLI\Utils\flag( $assoc_args, 'precise' ); + $old = array_shift( $args ); + $new = array_shift( $args ); + $total = 0; + $report = array(); + $dry_run = \WP_CLI\Utils\flag( $assoc_args, 'dry-run' ); + $php_only = \WP_CLI\Utils\flag( $assoc_args, 'precise' ); $recurse_objects = \WP_CLI\Utils\flag( $assoc_args, 'recurse-objects' ); if ( isset( $assoc_args['skip-columns'] ) ) { From 6741683cc556b04f09b5b1b4623d7f0a7b7214e0 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 14:00:22 -0400 Subject: [PATCH 3450/4858] Add global tag to docblock --- php/commands/search-replace.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 6035a2cd95..fcec229304 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -129,6 +129,8 @@ public function __invoke( $args, $assoc_args ) { /** * Retrieve a list of tables from the database. * + * @global wpdb $wpdb + * * @param array $assoc_args Array of options passed to this command. * * @return array The array of table names. From 968d0acaabe829c316a583e68cae50196682dbc6 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 18:01:46 -0400 Subject: [PATCH 3451/4858] Move helper into class method --- php/commands/search-replace.php | 27 +++++++++++++++++++++------ php/utils.php | 15 --------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index fcec229304..f1da256794 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -64,9 +64,9 @@ public function __invoke( $args, $assoc_args ) { $new = array_shift( $args ); $total = 0; $report = array(); - $dry_run = \WP_CLI\Utils\flag( $assoc_args, 'dry-run' ); - $php_only = \WP_CLI\Utils\flag( $assoc_args, 'precise' ); - $recurse_objects = \WP_CLI\Utils\flag( $assoc_args, 'recurse-objects' ); + $dry_run = self::check_flag( $assoc_args, 'dry-run' ); + $php_only = self::check_flag( $assoc_args, 'precise' ); + $recurse_objects = self::check_flag( $assoc_args, 'recurse-objects' ); if ( isset( $assoc_args['skip-columns'] ) ) { $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -138,9 +138,9 @@ public function __invoke( $args, $assoc_args ) { private static function get_table_list( $assoc_args ) { global $wpdb; - $network = \WP_CLI\Utils\flag( $assoc_args, 'network' ); - $all_tables = \WP_CLI\Utils\flag( $assoc_args, 'all-tables' ); - $all_with_prefix = \WP_CLI\Utils\flag( $assoc_args, 'all-tables-with-prefix' ); + $network = self::check_flag( $assoc_args, 'network' ); + $all_tables = self::check_flag( $assoc_args, 'all-tables' ); + $all_with_prefix = self::check_flag( $assoc_args, 'all-tables-with-prefix' ); if ( $all_tables ) { return $wpdb->get_col( 'SHOW TABLES' ); @@ -290,6 +290,21 @@ private static function esc_like( $old ) { return $old; } + + /** + * Determine the boolean value of a flag in an array. + * + * Primarily useful for determining the status of a boolean flag for a command. This is needed because a flag can be + * prefixed with --no- to set it to false. Therefore it is not sufficient to only check whether a flag is set. + * + * @param array $array The array to check. + * @param string $key The key to check for. + * + * @return bool True if the key is set in the array and is truthy, false otherwise. + */ + private static function check_flag( $array, $key ) { + return isset( $array[ $key ] ) && $array[ $key ]; + } } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); diff --git a/php/utils.php b/php/utils.php index 46143896fd..9581c164dc 100644 --- a/php/utils.php +++ b/php/utils.php @@ -504,18 +504,3 @@ function increment_version( $current_version, $new_version ) { return $current_version; } - -/** - * Determine the boolean value of a flag in an array. - * - * Primarily useful for determining the status of a boolean flag for a command. This is needed because a flag can be - * prefixed with --no- to set it to false. Therefore it is not sufficient to only check whether a flag is set. - * - * @param array $array The array to check. - * @param string $key The key to check for. - * - * @return bool True if the key is set in the array and is truthy, false otherwise. - */ -function flag( $array, $key ) { - return isset( $array[ $key ] ) && $array[ $key ]; -} From e83c082495f67131577586262dda6aa9f8e5bd61 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Tue, 10 Mar 2015 18:05:34 -0400 Subject: [PATCH 3452/4858] Pass correct arguments to get_table_list --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f1da256794..d9b8e3129c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -78,7 +78,7 @@ public function __invoke( $args, $assoc_args ) { $skip_columns[] = 'user_pass'; // 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( $args, $assoc_args ) : $args; + $tables = empty( $args ) ? self::get_table_list( $assoc_args ) : $args; foreach ( $tables as $table ) { list( $primary_keys, $columns ) = self::get_columns( $table ); From 42c9d4a59ec506f09a6c5545e8cacaf85b5c7027 Mon Sep 17 00:00:00 2001 From: Jeremy Pry <jeremy.pry@gmail.com> Date: Wed, 11 Mar 2015 10:47:55 -0400 Subject: [PATCH 3453/4858] Modify get_table_list This method now accepts a string as a parameter, and will function differently depending on which string is passed. --- php/commands/search-replace.php | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index d9b8e3129c..fe1cd8a22f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -77,8 +77,20 @@ public function __invoke( $args, $assoc_args ) { // never mess with hashed passwords $skip_columns[] = 'user_pass'; + // Determine how to limit the list of tables. Defaults to 'wordpress' + $table_type = 'wordpress'; + if ( self::check_flag( $assoc_args, 'network' ) ) { + $table_type = 'network'; + } + if ( self::check_flag( $assoc_args, 'all-tables-with-prefix' ) ) { + $table_type = 'all-tables-with-prefix'; + } + if ( self::check_flag( $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( $assoc_args ) : $args; + $tables = empty( $args ) ? self::get_table_list( $table_type ) : $args; foreach ( $tables as $table ) { list( $primary_keys, $columns ) = self::get_columns( $table ); @@ -131,25 +143,27 @@ public function __invoke( $args, $assoc_args ) { * * @global wpdb $wpdb * - * @param array $assoc_args Array of options passed to this command. + * @param string $limit_to Sting defining how to limit the list of tables to retrieve. Acceptable vales are: + * - 'wordpress' for default WordPress tables only + * - 'network' for default Multisite tables only + * - 'all-tables-with-prefix' for all tables using the WordPress DB prefix + * - 'all-tables' for all tables in the DB * * @return array The array of table names. */ - private static function get_table_list( $assoc_args ) { + private static function get_table_list( $limit_to ) { global $wpdb; - $network = self::check_flag( $assoc_args, 'network' ); - $all_tables = self::check_flag( $assoc_args, 'all-tables' ); - $all_with_prefix = self::check_flag( $assoc_args, 'all-tables-with-prefix' ); + $network = 'network' == $limit_to; - if ( $all_tables ) { + if ( 'all-tables' == $limit_to ) { return $wpdb->get_col( 'SHOW TABLES' ); } $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); - if ( $all_with_prefix ) { + if ( 'all-tables-with-prefix' == $limit_to ) { return $matching_tables; } From 8e9d127e2feb717cb88b527d0ccfb53a28de8416 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 11 Mar 2015 08:56:14 -0700 Subject: [PATCH 3454/4858] Fix PHP strict standards in importer ``` PHP Strict Standards: Only variables should be passed by reference in /home/vagrant/.wp-cli/php/commands/import.php on line 358 ``` --- php/commands/import.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/import.php b/php/commands/import.php index 58668db4d4..d31d36d598 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -355,7 +355,9 @@ private function suggest_user( $author_user_login, $author_user_email = '' ) { $levs[] = levenshtein( $author_user_login, $user->display_name ); $levs[] = levenshtein( $author_user_login, $user->user_login ); $levs[] = levenshtein( $author_user_login, $user->user_email ); - $levs[] = levenshtein( $author_user_login, array_shift( explode( "@", $user->user_email ) ) ); + $email_parts = explode( "@", $user->user_email ); + $email_login = array_shift( $email_parts ); + $levs[] = levenshtein( $author_user_login, $email_login ); rsort( $levs ); $lev = array_pop( $levs ); if ( 0 == $lev ) { From 0434117232844fb352d62092f246edb885ab4dae Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 12 Mar 2015 16:18:41 -0400 Subject: [PATCH 3455/4858] Add test for activate option of scaffold _s subcommand --- features/scaffold.feature | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index cecc110858..4d912e01fb 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -39,7 +39,7 @@ Feature: WordPress code scaffolding """ __( 'Zombie speeds', 'zombieland' """ - + @tax Scenario: Scaffold a Custom Taxonomy with label "Speed" When I run `wp scaffold taxonomy zombie-speed --label="Speed"` @@ -220,3 +220,10 @@ Feature: WordPress code scaffolding Success: Created theme 'Starter-theme'. """ And the {THEME_DIR}/starter-theme/sass directory should exist + + Scenario: Scaffold starter code for a theme and activate it + When I run `wp scaffold _s starter-theme --activate` + Then STDOUT should contain: + """ + Switched to 'Starter-theme' theme. + """ From 54694e142e09425efea76e6f98bbadcbc4cb4424 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 12 Mar 2015 17:01:28 -0400 Subject: [PATCH 3456/4858] Add test for activate option of scaffold plugin subcommand --- features/scaffold.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 4d912e01fb..cc8be4c130 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -100,6 +100,13 @@ Feature: WordPress code scaffolding And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist + Scenario: Scaffold a plugin and activate it + When I run `wp scaffold plugin hello-world --activate` + Then STDOUT should contain: + """ + Plugin 'hello-world' activated. + """ + Scenario: Scaffold plugin tests When I run `wp plugin path` Then save STDOUT as {PLUGIN_DIR} From 49abd64b396341dae60dcc40cd771390384891b5 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 12 Mar 2015 17:04:49 -0400 Subject: [PATCH 3457/4858] Failing test for new scaffold plugin option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let’s make it pass --- features/scaffold.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index cc8be4c130..8650dee106 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -107,6 +107,13 @@ Feature: WordPress code scaffolding Plugin 'hello-world' activated. """ + Scenario: Scaffold a plugin and network activate it + When I run `wp scaffold plugin hello-world --activate-network` + Then STDOUT should contain: + """ + Plugin 'hello-world' network activated. + """ + Scenario: Scaffold plugin tests When I run `wp plugin path` Then save STDOUT as {PLUGIN_DIR} From 797852b6825691850dc378ae6f0a7ca888575152 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 12 Mar 2015 17:43:47 -0400 Subject: [PATCH 3458/4858] Fix tests by removing WP install background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To test multisite, can’t have `Given a WP install` as background --- features/scaffold.feature | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 8650dee106..3a1b446a68 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -1,10 +1,8 @@ Feature: WordPress code scaffolding - Background: - Given a WP install - @theme Scenario: Scaffold a child theme + Given a WP install Given I run `wp theme path` And save STDOUT as {THEME_DIR} @@ -14,6 +12,7 @@ Feature: WordPress code scaffolding @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme + Given a WP install Given I run `wp eval 'echo STYLESHEETPATH;'` And save STDOUT as {STYLESHEETPATH} @@ -26,6 +25,7 @@ Feature: WordPress code scaffolding # Test for all flags but --label, --theme, --plugin and --raw @tax Scenario: Scaffold a Custom Taxonomy and attach it to CPTs including one that is prefixed and has a text domain + Given a WP install When I run `wp scaffold taxonomy zombie-speed --post_types="prefix-zombie,wraith" --textdomain=zombieland` Then STDOUT should contain: """ @@ -42,6 +42,7 @@ Feature: WordPress code scaffolding @tax Scenario: Scaffold a Custom Taxonomy with label "Speed" + Given a WP install When I run `wp scaffold taxonomy zombie-speed --label="Speed"` Then STDOUT should contain: """ @@ -55,6 +56,7 @@ Feature: WordPress code scaffolding # Test for all flags but --label, --theme, --plugin and --raw @cpt Scenario: Scaffold a Custom Post Type + Given a WP install When I run `wp scaffold post-type zombie --textdomain=zombieland` Then STDOUT should contain: """ @@ -70,6 +72,7 @@ Feature: WordPress code scaffolding """ Scenario: CPT slug is too long + Given a WP install When I try `wp scaffold post-type slugiswaytoolonginfact` Then STDERR should be: """ @@ -78,6 +81,7 @@ Feature: WordPress code scaffolding @cpt Scenario: Scaffold a Custom Post Type with label + Given a WP install When I run `wp scaffold post-type zombie --label="Brain eater"` Then STDOUT should contain: """ @@ -85,6 +89,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold a Custom Post Type with dashicon + Given a WP install When I run `wp scaffold post-type zombie --dashicon="art"` Then STDOUT should contain: """ @@ -92,6 +97,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold a plugin + Given a WP install Given I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} @@ -101,6 +107,7 @@ Feature: WordPress code scaffolding And the {PLUGIN_DIR}/hello-world/readme.txt file should exist Scenario: Scaffold a plugin and activate it + Given a WP install When I run `wp scaffold plugin hello-world --activate` Then STDOUT should contain: """ @@ -108,6 +115,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold a plugin and network activate it + Given a WP multisite install When I run `wp scaffold plugin hello-world --activate-network` Then STDOUT should contain: """ @@ -115,6 +123,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold plugin tests + Given a WP install When I run `wp plugin path` Then save STDOUT as {PLUGIN_DIR} @@ -145,6 +154,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold package tests + Given a WP install Given a community-command/command.php file: """ <?php @@ -214,6 +224,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold starter code for a theme + Given a WP install Given I run `wp theme path` And save STDOUT as {THEME_DIR} @@ -225,6 +236,7 @@ Feature: WordPress code scaffolding And the {THEME_DIR}/starter-theme/style.css file should exist Scenario: Scaffold starter code for a theme with sass + Given a WP install Given I run `wp theme path` And save STDOUT as {THEME_DIR} @@ -236,6 +248,7 @@ Feature: WordPress code scaffolding And the {THEME_DIR}/starter-theme/sass directory should exist Scenario: Scaffold starter code for a theme and activate it + Given a WP install When I run `wp scaffold _s starter-theme --activate` Then STDOUT should contain: """ From e77b13d95234b6acf9b49d9fa05240af6470dcc4 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 12 Mar 2015 17:48:25 -0400 Subject: [PATCH 3459/4858] Add activate-network option, fix wp-cli/wp-cli#1709 --- php/commands/scaffold.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index a4d239b72c..00da18bf37 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -419,6 +419,9 @@ public function package_tests( $args, $assoc_args ) { * * [--activate] * : Activate the newly generated plugin. + * + * [--activate-network] + * : Network activate the newly generated plugin. */ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; @@ -447,6 +450,10 @@ function plugin( $args, $assoc_args ) { if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); } + + if ( isset( $assoc_args['activate-network'] ) ) { + WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug), array( 'network' => true ) ); + } } /** From fe04feac18aa6c3880126b329108ac2e8a56af90 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 12 Mar 2015 18:09:10 -0400 Subject: [PATCH 3460/4858] Should be elsif (mutually exclusive options) --- php/commands/scaffold.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 00da18bf37..dffe4c9c68 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -449,9 +449,7 @@ function plugin( $args, $assoc_args ) { if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); - } - - if ( isset( $assoc_args['activate-network'] ) ) { + } else if ( isset( $assoc_args['activate-network'] ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug), array( 'network' => true ) ); } } From d2dafaa00180f1f94bc361862ca3d45da1c03785 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Fri, 13 Mar 2015 12:21:43 -0400 Subject: [PATCH 3461/4858] Add test for scaffold child-theme --enable-network option --- features/scaffold.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 3a1b446a68..221c11bb3c 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -10,6 +10,15 @@ Feature: WordPress code scaffolding Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist + Scenario: Scaffold a child theme and network enable it + Given a WP multisite install + + When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --enable-network` + Then STDOUT should contain: + """ + Success: Network enabled the 'Zombieland' theme. + """ + @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install From 8556cabcee8c78fb1b6ee7770c3c8e03d52fd6a8 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Fri, 13 Mar 2015 12:22:55 -0400 Subject: [PATCH 3462/4858] Add support for scaffold child-theme --enable-network Tests passing again --- php/commands/scaffold.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index dffe4c9c68..74e7f9ab00 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -263,6 +263,9 @@ function _s( $args, $assoc_args ) { * [--activate] * : Activate the newly created child theme. * + * [--enable-network] + * : Enable the newly created child theme for the entire network. + * * @subcommand child-theme */ function child_theme( $args, $assoc_args ) { @@ -288,8 +291,11 @@ function child_theme( $args, $assoc_args ) { WP_CLI::success( "Created $theme_dir" ); - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + } else if ( isset( $assoc_args['enable-network'] ) ) { + WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); + } } private function get_output_path( $assoc_args, $subdir ) { From 681f7be059b2b1e5d2fb5ca57d1d83e78e2bc55e Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Fri, 13 Mar 2015 12:27:06 -0400 Subject: [PATCH 3463/4858] Add test for scaffold _s --enable-network option --- features/scaffold.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 221c11bb3c..556b3006f6 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -263,3 +263,11 @@ Feature: WordPress code scaffolding """ Switched to 'Starter-theme' theme. """ + + Scenario: Scaffold starter code for a theme and network enable it + Given a WP multisite install + When I run `wp scaffold _s starter-theme --enable-network` + Then STDOUT should contain: + """ + Success: Network enabled the 'Starter-theme' theme. + """ From 508f98393bae5a536146394460dff307d63c1655 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Fri, 13 Mar 2015 14:04:57 -0400 Subject: [PATCH 3464/4858] Add --enable-network option to scaffold _s; fix #1711 --- php/commands/scaffold.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 74e7f9ab00..96e6ed054c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -173,6 +173,9 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * [--activate] * : Activate the newly downloaded theme. * + * [--enable-network] + * : Enable the newly downloaded theme for the entire network. + * * [--theme_name=<title>] * : What to put in the 'Theme Name:' header in style.css * @@ -232,9 +235,11 @@ function _s( $args, $assoc_args ) { WP_CLI::success( "Created theme '{$data['theme_name']}'." ); - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - + } else if ( isset( $assoc_args['enable-network'] ) ) { + WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); + } } /** From 15812c0b19b1293c58e2c40dbfe06b10f14a1fc0 Mon Sep 17 00:00:00 2001 From: Ross Hattori <rhattori@saymedia.com> Date: Sun, 15 Mar 2015 15:37:45 -0700 Subject: [PATCH 3465/4858] Change the properties for the author names https://github.com/WordPress/WordPress/blob/60b0cd7943b9150b5f69e3ebc9fd06828b9f1e75/wp-admin/includes/export.php#L272-273 --- php/export/class-wp-export-wxr-formatter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php index 92c15f768c..def92ac6e6 100644 --- a/php/export/class-wp-export-wxr-formatter.php +++ b/php/export/class-wp-export-wxr-formatter.php @@ -103,8 +103,8 @@ public function authors() { ->tag( 'wp:author_login', $author->user_login ) ->tag( 'wp:author_email', $author->user_email ) ->tag( 'wp:author_display_name' )->contains->cdata( $author->display_name )->end - ->tag( 'wp:author_first_name' )->contains->cdata( $author->user_first_name )->end - ->tag( 'wp:author_last_name' )->contains->cdata( $author->user_last_name )->end + ->tag( 'wp:author_first_name' )->contains->cdata( $author->user_firstname )->end + ->tag( 'wp:author_last_name' )->contains->cdata( $author->user_lastname )->end ->end; } return $oxymel->to_string(); From 8ab0c30a06fca35cb929d4110c52b6ecc3333b63 Mon Sep 17 00:00:00 2001 From: Ross Hattori <rhattori@saymedia.com> Date: Sun, 15 Mar 2015 15:51:53 -0700 Subject: [PATCH 3466/4858] Add wp:author_id tag to author export --- php/export/class-wp-export-wxr-formatter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php index def92ac6e6..d2bc4d5afe 100644 --- a/php/export/class-wp-export-wxr-formatter.php +++ b/php/export/class-wp-export-wxr-formatter.php @@ -100,6 +100,7 @@ public function authors() { foreach ( $authors as $author ) { $oxymel ->tag( 'wp:wp_author' )->contains + ->tag( 'wp:author_id', $author->ID ) ->tag( 'wp:author_login', $author->user_login ) ->tag( 'wp:author_email', $author->user_email ) ->tag( 'wp:author_display_name' )->contains->cdata( $author->display_name )->end From d3ddd49abc105b76eae45913da2ea78c6d1f282c Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Mon, 16 Mar 2015 11:41:19 -0400 Subject: [PATCH 3467/4858] Revert fe04fea..508f983 This rolls back to commit fe04feac18aa6c3880126b329108ac2e8a56af90. --- features/scaffold.feature | 17 ----------------- php/commands/scaffold.php | 17 +++-------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 556b3006f6..3a1b446a68 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -10,15 +10,6 @@ Feature: WordPress code scaffolding Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist - Scenario: Scaffold a child theme and network enable it - Given a WP multisite install - - When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --enable-network` - Then STDOUT should contain: - """ - Success: Network enabled the 'Zombieland' theme. - """ - @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install @@ -263,11 +254,3 @@ Feature: WordPress code scaffolding """ Switched to 'Starter-theme' theme. """ - - Scenario: Scaffold starter code for a theme and network enable it - Given a WP multisite install - When I run `wp scaffold _s starter-theme --enable-network` - Then STDOUT should contain: - """ - Success: Network enabled the 'Starter-theme' theme. - """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 96e6ed054c..dffe4c9c68 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -173,9 +173,6 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * [--activate] * : Activate the newly downloaded theme. * - * [--enable-network] - * : Enable the newly downloaded theme for the entire network. - * * [--theme_name=<title>] * : What to put in the 'Theme Name:' header in style.css * @@ -235,11 +232,9 @@ function _s( $args, $assoc_args ) { WP_CLI::success( "Created theme '{$data['theme_name']}'." ); - if ( isset( $assoc_args['activate'] ) ) { + if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } else if ( isset( $assoc_args['enable-network'] ) ) { - WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); - } + } /** @@ -268,9 +263,6 @@ function _s( $args, $assoc_args ) { * [--activate] * : Activate the newly created child theme. * - * [--enable-network] - * : Enable the newly created child theme for the entire network. - * * @subcommand child-theme */ function child_theme( $args, $assoc_args ) { @@ -296,11 +288,8 @@ function child_theme( $args, $assoc_args ) { WP_CLI::success( "Created $theme_dir" ); - if ( isset( $assoc_args['activate'] ) ) { + if ( isset( $assoc_args['activate'] ) ) WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } else if ( isset( $assoc_args['enable-network'] ) ) { - WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); - } } private function get_output_path( $assoc_args, $subdir ) { From d7f19908f6268f2358ec6e9ea3ff5d515b98b434 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 16 Mar 2015 15:23:11 -0300 Subject: [PATCH 3468/4858] fix author's xml node name --- php/export/class-wp-export-wxr-formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/class-wp-export-wxr-formatter.php b/php/export/class-wp-export-wxr-formatter.php index d2bc4d5afe..ca874c6ff3 100644 --- a/php/export/class-wp-export-wxr-formatter.php +++ b/php/export/class-wp-export-wxr-formatter.php @@ -99,7 +99,7 @@ public function authors() { $authors = $this->export->authors(); foreach ( $authors as $author ) { $oxymel - ->tag( 'wp:wp_author' )->contains + ->tag( 'wp:author' )->contains ->tag( 'wp:author_id', $author->ID ) ->tag( 'wp:author_login', $author->user_login ) ->tag( 'wp:author_email', $author->user_email ) From 5bbfe9eeff4e954f6b644297d9dc8bb0b2abef36 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 17 Mar 2015 12:11:42 -0300 Subject: [PATCH 3469/4858] add test to make sure that the users information is exported correctly --- features/export.feature | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/features/export.feature b/features/export.feature index ae0281bd42..ddc1626f76 100644 --- a/features/export.feature +++ b/features/export.feature @@ -201,3 +201,29 @@ Feature: Export content. """ 5 """ + + Scenario: Export posts should include user information + Given a WP install + And I run `wp plugin install wordpress-importer --activate` + And I run `wp user create user user@user.com --role=editor --display_name="Test User"` + And I run `wp post generate --post_type=post --count=10 --post_author=user` + + When I run `wp export` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + Then the {EXPORT_FILE} file should contain: + """ + <wp:author_display_name><![CDATA[Test User]]></wp:author_display_name> + """ + + When I run `wp site empty --yes` + And I run `wp user list --field=user_login | xargs -n 1 wp user delete --yes` + Then STDOUT should not be empty + + When I run `wp import {EXPORT_FILE} --authors=create` + Then STDOUT should not be empty + + When I run `wp user get user --field=display_name` + Then STDOUT should be: + """ + Test User + """ \ No newline at end of file From 2e2547f162e66ae7efbd017c4d108330f5e15df6 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 17 Mar 2015 12:20:24 -0300 Subject: [PATCH 3470/4858] add missing line to the end of the file --- features/export.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/export.feature b/features/export.feature index ddc1626f76..f7be508ced 100644 --- a/features/export.feature +++ b/features/export.feature @@ -226,4 +226,4 @@ Feature: Export content. Then STDOUT should be: """ Test User - """ \ No newline at end of file + """ From a3a6adea68a07a4d01454a0768d96ff31e99ff7b Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Tue, 17 Mar 2015 20:22:24 -0400 Subject: [PATCH 3471/4858] Consistent functional test assertions for scaffold command --- features/scaffold.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 3a1b446a68..e1f48aee1f 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -252,5 +252,5 @@ Feature: WordPress code scaffolding When I run `wp scaffold _s starter-theme --activate` Then STDOUT should contain: """ - Switched to 'Starter-theme' theme. + Success: Switched to 'Starter-theme' theme. """ From 399589c067a16438f7ef795dd2499f6e08f6c0b4 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 25 Mar 2015 14:30:42 -0300 Subject: [PATCH 3472/4858] add `--format=ids` to `wp post term list` --- features/post-term.feature | 6 ++++++ features/user-term.feature | 6 ++++++ php/WP_CLI/CommandWithTerms.php | 9 +++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/features/post-term.feature b/features/post-term.feature index d38f628c2d..94893c4275 100644 --- a/features/post-term.feature +++ b/features/post-term.feature @@ -26,6 +26,12 @@ Feature: Manage post term | foo | foo | category | | bar | bar | category | + When I run `wp post term list 1 category --format=ids` + Then STDOUT should be: + """ + 3 2 1 + """ + When I try `wp post term list 1 foo2` Then STDERR should be: """ diff --git a/features/user-term.feature b/features/user-term.feature index 0c83e2f7a8..c5c81939c2 100644 --- a/features/user-term.feature +++ b/features/user-term.feature @@ -39,6 +39,12 @@ Feature: Manage user term | foo | foo | user_type | | bar | bar | user_type | + When I run `wp user term list 1 user_type --format=ids` + Then STDOUT should be: + """ + 3 2 + """ + When I run `wp user term set 1 user_type new` Then STDOUT should be: """ diff --git a/php/WP_CLI/CommandWithTerms.php b/php/WP_CLI/CommandWithTerms.php index 277fe4aed2..f906f7b3cb 100644 --- a/php/WP_CLI/CommandWithTerms.php +++ b/php/WP_CLI/CommandWithTerms.php @@ -44,7 +44,7 @@ abstract class CommandWithTerms extends \WP_CLI_Command { * : Limit the output to specific row fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, ids. Default: table * * ## AVAILABLE FIELDS * @@ -69,6 +69,7 @@ public function list_( $args, $assoc_args ) { $object_id = array_shift( $args ); $taxonomy_names = $args; + $taxonomy_args = array(); $this->set_obj_id( $object_id ); @@ -76,7 +77,11 @@ public function list_( $args, $assoc_args ) { $this->taxonomy_exists( $taxonomy ); } - $items = wp_get_object_terms( $object_id, $taxonomy_names ); + if ( $assoc_args['format'] == 'ids' ) { + $taxonomy_args['fields'] = 'ids'; + } + + $items = wp_get_object_terms( $object_id, $taxonomy_names, $taxonomy_args ); $formatter = $this->get_formatter( $assoc_args ); $formatter->display_items( $items ); From 3dc3421c98ce3380fc4d6628dfa0d0fca349e9fe Mon Sep 17 00:00:00 2001 From: Morgan Estes <morgan.estes@gmail.com> Date: Wed, 25 Mar 2015 14:16:27 -0500 Subject: [PATCH 3473/4858] Switch from rhumsaa/array_column to ramsey/array_column, as the former isn't supported anymore. --- composer.json | 2 +- utils/make-phar.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6b17472c77..6cec94c7d4 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "php": ">=5.3.2", "wp-cli/php-cli-tools": "0.10.4", "mustache/mustache": "~2.4", - "rhumsaa/array_column": "~1.1", + "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", "symfony/finder": "~2.3", "nb/oxymel": "0.1.0" diff --git a/utils/make-phar.php b/utils/make-phar.php index 1ce6f7b875..69ae514ffd 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -69,7 +69,7 @@ function set_file_contents( $phar, $path, $content ) { ->in('./vendor/composer') ->in('./vendor/symfony/finder') ->in('./vendor/nb/oxymel') - ->in('./vendor/rhumsaa/array_column') + ->in('./vendor/ramsey/array_column') ->exclude('test') ->exclude('tests') ->exclude('Tests') From 5195b2319dc5e746d4a5d47b73fe034d349d4457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Sat, 28 Mar 2015 18:41:33 -0400 Subject: [PATCH 3474/4858] Add `wp core language update` command and Behat tests --- features/core.feature | 11 ++++ php/WP_CLI/CommandWithTranslation.php | 89 +++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/features/core.feature b/features/core.feature index 636989d600..60ef63791a 100644 --- a/features/core.feature +++ b/features/core.feature @@ -505,6 +505,17 @@ Feature: Manage WordPress installation Success: Language activated. """ + When I run `wp core language update --dry-run` + Then save STDOUT 'Available (\d+) translations updates' as {UPDATES} + + When I run `wp core language update` + Then STDOUT should contain: + """ + Success: Updated {UPDATES}/{UPDATES} translations. + """ + And the wp-content/languages/plugins directory should exist + And the wp-content/languages/themes directory should exist + When I run `wp core language list --field=language --status=active` Then STDOUT should be: """ diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 06aa8c6ab6..761b07b64c 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -124,6 +124,95 @@ public function install( $args, $assoc_args ) { } + /** + * Updates the active translation of core, plugins, and themes. + * + * [--dry-run] + * : Preview which translations would be updated. + * + * @subcommand update + */ + public function update( $args, $assoc_args ) { + + // Ignore updates for the default locale. + if ( 'en_US' == get_locale() ) { + \WP_CLI::line( "Translations updates are not needed for the default locale." ); + + return; + } + + wp_version_check(); // Check for Core updates. + wp_update_themes(); // Check for Theme updates. + wp_update_plugins(); // Check for Plugin updates. + + $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. + + if ( empty( $updates ) ) { + \WP_CLI::line( "No translations updates available." ); + + return; + } + + // Gets a list of all languages. + $all_languages = $this->get_all_languages(); + + // Formats the updates list. + foreach ( $updates as $update ) { + if ( 'plugin' == $update->type ) { + $plugin_data = array_shift( get_plugins( '/' . $update->slug ) ); + $name = $plugin_data['Name']; + } elseif ( 'theme' == $update->type ) { + $theme_data = wp_get_theme( $update->slug ); + $name = $theme_data['Name']; + } else { // Core + $name = 'WordPress'; + } + + // Gets the translation data. + $translation = (object) reset( wp_list_filter( $all_languages, array( + 'language' => $update->language + ) ) ); + + $update->Type = ucfirst( $update->type ); + $update->Name = $name; + $update->Version = $update->version; + $update->Language = $translation->english_name; + } + + // Only preview which translations would be updated. + if ( isset( $assoc_args['dry-run'] ) ) { + \WP_CLI::line( sprintf( 'Available %d translations updates:', count( $updates ) ) ); + \WP_CLI\Utils\format_items( 'table', $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); + + return; + } + + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + + $upgrader = new \Language_Pack_Upgrader( new \Automatic_Upgrader_Skin() ); + $results = array(); + + // Update translations. + foreach ( $updates as $update ) { + \WP_CLI::line( "Updating '{$update->Language}' translations for {$update->Name} {$update->Version}..." ); + $results[] = $upgrader->upgrade( $update ); + } + + $num_to_update = count( $updates ); + $num_updated = count( array_filter( $results ) ); + + $line = "Updated $num_updated/$num_to_update translations."; + + if ( $num_to_update == $num_updated ) { + \WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + \WP_CLI::warning( $line ); + } else { + \WP_CLI::error( $line ); + } + + } + /** * Activate a given language. * From eb55b068bfdae9a19d2c1cde4d60b341f26f6e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Sat, 28 Mar 2015 22:21:39 -0400 Subject: [PATCH 3475/4858] Fix `wp core language update` to check 'dry-run' arg value --- php/WP_CLI/CommandWithTranslation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 761b07b64c..0169e07609 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -180,7 +180,7 @@ public function update( $args, $assoc_args ) { } // Only preview which translations would be updated. - if ( isset( $assoc_args['dry-run'] ) ) { + if ( isset( $assoc_args['dry-run'] ) && $assoc_args['dry-run'] ) { \WP_CLI::line( sprintf( 'Available %d translations updates:', count( $updates ) ) ); \WP_CLI\Utils\format_items( 'table', $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); From 5402ea90ad08dddaf80f1bc706b354766ea69b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Sat, 28 Mar 2015 23:29:09 -0400 Subject: [PATCH 3476/4858] Add `WP_CLI::check_flag` function Function to check if a command flag is set and has the expected value. --- php/class-wp-cli.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f571c47a59..9e4e7ef9af 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -465,6 +465,18 @@ public static function run_command( $args, $assoc_args = array() ) { self::get_runner()->run_command( $args, $assoc_args ); } + /** + * Check if the flag is set and has the expected value. + * + * @param array $args The arguments array to check. + * @param string $flag The flag to check for. + * @param mixed $expected The expected value for the flag. Default: TRUE + * @return bool + */ + public static function check_flag( $args, $flag, $expected = true ) { + return isset( $args[ $flag ] ) && $args[ $flag ] == $expected; + } + // DEPRECATED STUFF From 61681173caa558dc530ea886ed4d5c54258bc8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 30 Mar 2015 14:32:29 -0400 Subject: [PATCH 3477/4858] Improves `wp core language update` messages --- php/WP_CLI/CommandWithTranslation.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 0169e07609..cdcc4a5e80 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -136,7 +136,7 @@ public function update( $args, $assoc_args ) { // Ignore updates for the default locale. if ( 'en_US' == get_locale() ) { - \WP_CLI::line( "Translations updates are not needed for the default locale." ); + \WP_CLI::success( "Translations updates are not needed for the 'English (US)' locale." ); return; } @@ -148,7 +148,7 @@ public function update( $args, $assoc_args ) { $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. if ( empty( $updates ) ) { - \WP_CLI::line( "No translations updates available." ); + \WP_CLI::success( 'Translations are up to date.' ); return; } @@ -194,8 +194,18 @@ public function update( $args, $assoc_args ) { // Update translations. foreach ( $updates as $update ) { - \WP_CLI::line( "Updating '{$update->Language}' translations for {$update->Name} {$update->Version}..." ); - $results[] = $upgrader->upgrade( $update ); + \WP_CLI::line( "Updating '{$update->Language}' translation for {$update->Name} {$update->Version}..." ); + \WP_CLI::line( "Downloading translation from {$update->package}..." ); + + $result = $upgrader->upgrade( $update ); + + if ( $result ) { + \WP_CLI::line( 'Translation updated successfully.' ); + } else { + \WP_CLI::line( 'Translation update failed.' ); + } + + $results[] = $result; } $num_to_update = count( $updates ); From fda3162469711b3048df6e7cb9b93bd78e3fb727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 30 Mar 2015 17:30:40 -0400 Subject: [PATCH 3478/4858] Indicates whether there is a new version in `wp core language list` --- php/WP_CLI/CommandWithTranslation.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index cdcc4a5e80..e9deb91037 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -16,7 +16,7 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { 'english_name', 'native_name', 'status', - 'updated', + 'update', ); /** @@ -42,7 +42,7 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { * * english_name * * native_name * * status - * * updated + * * update * * These fields are optionally available: * @@ -56,12 +56,27 @@ public function list_( $args, $assoc_args ) { $translations = $this->get_all_languages(); $available = $this->get_installed_languages(); + wp_version_check(); // Check for Core updates. + wp_update_themes(); // Check for Theme updates. + wp_update_plugins(); // Check for Plugin updates. + $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. + $current_locale = get_locale(); - $translations = array_map( function( $translation ) use ( $available, $current_locale ) { + $translations = array_map( function( $translation ) use ( $available, $current_locale, $updates ) { $translation['status'] = ( in_array( $translation['language'], $available ) ) ? 'installed' : 'uninstalled'; if ( $current_locale == $translation['language'] ) { $translation['status'] = 'active'; } + + $update = wp_list_filter( $updates, array( + 'language' => $translation['language'] + ) ); + if ( $update ) { + $translation['update'] = 'available'; + } else { + $translation['update'] = 'none'; + } + return $translation; }, $translations ); From 751003ae8e4f7a37f94a22bc04897ed1d0daa182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 30 Mar 2015 18:19:35 -0400 Subject: [PATCH 3479/4858] Add `--force` flag to `wp core language update` command --- features/core.feature | 2 +- php/WP_CLI/CommandWithTranslation.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 60ef63791a..86d0eab36f 100644 --- a/features/core.feature +++ b/features/core.feature @@ -505,7 +505,7 @@ Feature: Manage WordPress installation Success: Language activated. """ - When I run `wp core language update --dry-run` + When I run `wp core language update --dry-run --force` Then save STDOUT 'Available (\d+) translations updates' as {UPDATES} When I run `wp core language update` diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index e9deb91037..14b8fc029a 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -145,6 +145,9 @@ public function install( $args, $assoc_args ) { * [--dry-run] * : Preview which translations would be updated. * + * [--force] + * : Force the check for updates. + * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -156,6 +159,10 @@ public function update( $args, $assoc_args ) { return; } + if ( isset( $assoc_args['force'] ) && $assoc_args['force'] ) { + wp_clean_update_cache(); // Clear existing update caches. + } + wp_version_check(); // Check for Core updates. wp_update_themes(); // Check for Theme updates. wp_update_plugins(); // Check for Plugin updates. From 921c6572c447995dcd707e5d19899a99cf6adeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 30 Mar 2015 18:32:50 -0400 Subject: [PATCH 3480/4858] Do not check for translations updates after updating plugins/themes --- php/WP_CLI/CommandWithUpgrade.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 39da96241d..b4c505ec49 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -10,6 +10,13 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $upgrade_refresh; protected $upgrade_transient; + function __construct() { + // Do not automatically check translations updates after updating plugins/themes. + add_action( 'upgrader_process_complete', function() { + remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); + }, 1 ); + } + abstract protected function get_upgrader_class( $force ); abstract protected function get_item_list(); From 8fdeea3d1e311bc4f26848e971d545d2359d53a9 Mon Sep 17 00:00:00 2001 From: Brian MacKinney <brian@getpantheon.com> Date: Thu, 2 Apr 2015 11:40:48 -0700 Subject: [PATCH 3481/4858] Correctly enqueue parent and child themes Completes #1706 --- templates/child_theme_functions.mustache | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache index c8f5417672..09c74101ed 100644 --- a/templates/child_theme_functions.mustache +++ b/templates/child_theme_functions.mustache @@ -1,7 +1,12 @@ <?php -add_action( 'wp_enqueue_scripts', '{{parent_theme}}_parent_theme_enqueue_styles' ); +add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' ); -function {{parent_theme}}_parent_theme_enqueue_styles() { +function theme_enqueue_styles() { wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); + wp_enqueue_style( '{{slug}}-style', + get_stylesheet_directory_uri() . '/style.css', + array('{{parent_theme}}-style') + ); + } From b959d55f56b7221d7c96fdfac065a9fdf06b34cd Mon Sep 17 00:00:00 2001 From: Brian MacKinney <brian@getpantheon.com> Date: Thu, 2 Apr 2015 14:52:54 -0700 Subject: [PATCH 3482/4858] Revert function name change {{parent_theme}}_parent_theme_enque_styles matches wp-cli function naming conventions. --- templates/child_theme_functions.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache index 09c74101ed..1c08099394 100644 --- a/templates/child_theme_functions.mustache +++ b/templates/child_theme_functions.mustache @@ -1,8 +1,8 @@ <?php -add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' ); +add_action( 'wp_enqueue_scripts', '{{parent_theme}}_parent_theme_enqueue_styles' ); -function theme_enqueue_styles() { +function {{parent_theme}}_parent_theme_enqueue_styles() { wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); wp_enqueue_style( '{{slug}}-style', get_stylesheet_directory_uri() . '/style.css', From 7788937a750b0cd023d9e65290ca344057232535 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 2 Apr 2015 20:41:53 -0400 Subject: [PATCH 3483/4858] Add test for scaffold child-theme --enable-network --- features/scaffold.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index e1f48aee1f..eb6e509586 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -10,6 +10,15 @@ Feature: WordPress code scaffolding Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist + Scenario: Scaffold a child theme and network enable it + Given a WP multisite install + + When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --enable-network` + Then STDOUT should contain: + """ + Success: Network enabled the 'Zombieland' theme. + """ + @tax @cpt Scenario: Scaffold a Custom Taxonomy and Custom Post Type and write it to active theme Given a WP install From 4c4654bbb66b1a460b32fbed58e388bcbfef1901 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 2 Apr 2015 20:42:06 -0400 Subject: [PATCH 3484/4858] Add test for scaffold _s --enable-network --- features/scaffold.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index eb6e509586..ba218c24a6 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -263,3 +263,11 @@ Feature: WordPress code scaffolding """ Success: Switched to 'Starter-theme' theme. """ + + Scenario: Scaffold starter code for a theme and network enable it + Given a WP multisite install + When I run `wp scaffold _s starter-theme --enable-network` + Then STDOUT should contain: + """ + Success: Network enabled the 'Starter-theme' theme. + """ From be859e3530032dfac45441ae5280b8453902a6a5 Mon Sep 17 00:00:00 2001 From: Andrew Patton <andrew@acusti.ca> Date: Thu, 2 Apr 2015 20:44:50 -0400 Subject: [PATCH 3485/4858] Add --enable-network for scaffold theme commands, fix #1711 --- php/commands/scaffold.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index dffe4c9c68..96e6ed054c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -173,6 +173,9 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * [--activate] * : Activate the newly downloaded theme. * + * [--enable-network] + * : Enable the newly downloaded theme for the entire network. + * * [--theme_name=<title>] * : What to put in the 'Theme Name:' header in style.css * @@ -232,9 +235,11 @@ function _s( $args, $assoc_args ) { WP_CLI::success( "Created theme '{$data['theme_name']}'." ); - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - + } else if ( isset( $assoc_args['enable-network'] ) ) { + WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); + } } /** @@ -263,6 +268,9 @@ function _s( $args, $assoc_args ) { * [--activate] * : Activate the newly created child theme. * + * [--enable-network] + * : Enable the newly created child theme for the entire network. + * * @subcommand child-theme */ function child_theme( $args, $assoc_args ) { @@ -288,8 +296,11 @@ function child_theme( $args, $assoc_args ) { WP_CLI::success( "Created $theme_dir" ); - if ( isset( $assoc_args['activate'] ) ) + if ( isset( $assoc_args['activate'] ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); + } else if ( isset( $assoc_args['enable-network'] ) ) { + WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); + } } private function get_output_path( $assoc_args, $subdir ) { From 19515799b5785054f2e283534c28055015e14e60 Mon Sep 17 00:00:00 2001 From: yivi <ivan@yivoff.com> Date: Sat, 4 Apr 2015 11:44:34 +0200 Subject: [PATCH 3486/4858] functional test: _s scaffolding check for failure when wp_content_dir it's not set properly --- features/scaffold.feature | 9 +++++++++ features/steps/given.php | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index e1f48aee1f..bc5cbc1ae7 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -254,3 +254,12 @@ Feature: WordPress code scaffolding """ Success: Switched to 'Starter-theme' theme. """ + + Scenario: Scaffold starter code for a theme, but can't unzip theme files + Given a WP install + And a misconfigured WP_CONTENT_DIR constant directory + When I try `wp scaffold _s starter-theme` + Then STDERR should contain: + """ + Error: Could not decompress your theme files + """ diff --git a/features/steps/given.php b/features/steps/given.php index a9f536a7c5..0d6509876a 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -140,4 +140,17 @@ function ( $world, $filepath, $output_filter, $key ) { } $world->variables[ $key ] = trim( $output, "\n" ); } +); + +$steps->Given('/^a misconfigured WP_CONTENT_DIR constant directory$/', + function($world) { + $wp_config_path = $world->variables['RUN_DIR'] . "/wp-config.php"; + + $wp_config_code = file_get_contents( $wp_config_path ); + + $world->add_line_to_wp_config( $wp_config_code, + "define( 'WP_CONTENT_DIR', '' );" ); + + file_put_contents( $wp_config_path, $wp_config_code ); + } ); \ No newline at end of file From 911c494fb975a7c3823847f58c380f91a766f989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 01:00:59 -0400 Subject: [PATCH 3487/4858] Clear update caches by default when checking for updates in `wp core language` --- php/WP_CLI/CommandWithTranslation.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 14b8fc029a..3dd0a93a0c 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -56,6 +56,7 @@ public function list_( $args, $assoc_args ) { $translations = $this->get_all_languages(); $available = $this->get_installed_languages(); + wp_clean_update_cache(); // Clear existing update caches. wp_version_check(); // Check for Core updates. wp_update_themes(); // Check for Theme updates. wp_update_plugins(); // Check for Plugin updates. @@ -145,9 +146,6 @@ public function install( $args, $assoc_args ) { * [--dry-run] * : Preview which translations would be updated. * - * [--force] - * : Force the check for updates. - * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -159,10 +157,7 @@ public function update( $args, $assoc_args ) { return; } - if ( isset( $assoc_args['force'] ) && $assoc_args['force'] ) { - wp_clean_update_cache(); // Clear existing update caches. - } - + wp_clean_update_cache(); // Clear existing update caches. wp_version_check(); // Check for Core updates. wp_update_themes(); // Check for Theme updates. wp_update_plugins(); // Check for Plugin updates. From 4d8fb256b3bc9eb7416845a2bd569180a938ba6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 01:04:22 -0400 Subject: [PATCH 3488/4858] Run the `wp core language update` command after updating plugin/themes Instead of running the default translations updates from WordPress, which returns HTML tags to the standard output, runs the command `wp core language update` after updating plugin or themes. --- php/WP_CLI/CommandWithUpgrade.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index b4c505ec49..9f57669f81 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -11,9 +11,10 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $upgrade_transient; function __construct() { - // Do not automatically check translations updates after updating plugins/themes. + // After updating plugins/themes also update translations by running the `core language update` command. add_action( 'upgrader_process_complete', function() { remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); + \WP_CLI::run_command( array( 'core', 'language', 'update' ), array( 'dry-run' => false ) ); }, 1 ); } From 58dcb46c8899ea5aa9664a389dd84b19d13e036d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 01:21:43 -0400 Subject: [PATCH 3489/4858] Adds back the 'updated' column to the `wp core language list` command --- php/WP_CLI/CommandWithTranslation.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 3dd0a93a0c..8bed161acd 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -17,6 +17,7 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { 'native_name', 'status', 'update', + 'updated', ); /** @@ -43,6 +44,7 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { * * native_name * * status * * update + * * updated * * These fields are optionally available: * From 6757d94f3662755b11b458bb09beddc3718a61ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 02:12:53 -0400 Subject: [PATCH 3490/4858] Fix `wp core language update` Behat tests --- features/core.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 86d0eab36f..60ef63791a 100644 --- a/features/core.feature +++ b/features/core.feature @@ -505,7 +505,7 @@ Feature: Manage WordPress installation Success: Language activated. """ - When I run `wp core language update --dry-run --force` + When I run `wp core language update --dry-run` Then save STDOUT 'Available (\d+) translations updates' as {UPDATES} When I run `wp core language update` From 6b95e929a009324c20ccf3fa8d961e72e8131864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 15:40:21 -0400 Subject: [PATCH 3491/4858] Add Behat tests for the `update` field in `wp core language list` --- features/core.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/core.feature b/features/core.feature index 60ef63791a..779b83501b 100644 --- a/features/core.feature +++ b/features/core.feature @@ -505,6 +505,14 @@ Feature: Manage WordPress installation Success: Language activated. """ + When I run `wp core language list --fields=language,english_name,update` + Then STDOUT should be a table containing rows: + | language | english_name | update | + | ar | Arabic | none | + | az | Azerbaijani | none | + | en_US | English (United States) | none | + | en_GB | English (UK) | available | + When I run `wp core language update --dry-run` Then save STDOUT 'Available (\d+) translations updates' as {UPDATES} From 89a9cc46a64098a2a053a3e48c39971ab1ef6d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 16:54:17 -0400 Subject: [PATCH 3492/4858] Changes `\WP_CLI::check_flag` function to `\WP_CLI\Utils\check_flag` --- php/class-wp-cli.php | 12 ------------ php/utils.php | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9e4e7ef9af..f571c47a59 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -465,18 +465,6 @@ public static function run_command( $args, $assoc_args = array() ) { self::get_runner()->run_command( $args, $assoc_args ); } - /** - * Check if the flag is set and has the expected value. - * - * @param array $args The arguments array to check. - * @param string $flag The flag to check for. - * @param mixed $expected The expected value for the flag. Default: TRUE - * @return bool - */ - public static function check_flag( $args, $flag, $expected = true ) { - return isset( $args[ $flag ] ) && $args[ $flag ] == $expected; - } - // DEPRECATED STUFF diff --git a/php/utils.php b/php/utils.php index 9581c164dc..45b36ee99d 100644 --- a/php/utils.php +++ b/php/utils.php @@ -504,3 +504,15 @@ function increment_version( $current_version, $new_version ) { return $current_version; } + +/** + * Check if the flag is set and has the expected value. + * + * @param array $args The arguments array to check. + * @param string $flag The flag to check for. + * @param mixed $expected The expected value for the flag. Default: TRUE + * @return bool + */ +function check_flag( $args, $flag, $expected = true ) { + return isset( $args[ $flag ] ) && ( $args[ $flag ] === $expected ); +} From 4b5f91353d0167a12e79bd646336d05120bf5e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 6 Apr 2015 19:46:15 -0400 Subject: [PATCH 3493/4858] Small fix in comments --- php/WP_CLI/CommandWithTranslation.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 8bed161acd..507c4dd523 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -59,9 +59,9 @@ public function list_( $args, $assoc_args ) { $available = $this->get_installed_languages(); wp_clean_update_cache(); // Clear existing update caches. - wp_version_check(); // Check for Core updates. - wp_update_themes(); // Check for Theme updates. - wp_update_plugins(); // Check for Plugin updates. + wp_version_check(); // Check for Core translation updates. + wp_update_themes(); // Check for Theme translation updates. + wp_update_plugins(); // Check for Plugin translation updates. $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. $current_locale = get_locale(); @@ -160,9 +160,9 @@ public function update( $args, $assoc_args ) { } wp_clean_update_cache(); // Clear existing update caches. - wp_version_check(); // Check for Core updates. - wp_update_themes(); // Check for Theme updates. - wp_update_plugins(); // Check for Plugin updates. + wp_version_check(); // Check for Core translation updates. + wp_update_themes(); // Check for Theme translation updates. + wp_update_plugins(); // Check for Plugin translation updates. $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. From 83a0bc471e5f4172703eaef3b85992caaf3f87ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 13 Apr 2015 00:10:25 -0400 Subject: [PATCH 3494/4858] Refactor code to use the `\WP_CLI\Utils\check_flag` function --- php/WP_CLI/CommandWithDBObject.php | 2 +- php/WP_CLI/CommandWithTranslation.php | 4 ++-- php/WP_CLI/CommandWithUpgrade.php | 12 ++++++------ php/class-wp-cli.php | 6 +++--- php/commands/cli.php | 10 +++++----- php/commands/comment.php | 2 +- php/commands/core.php | 20 ++++++++++---------- php/commands/media.php | 6 +++--- php/commands/menu.php | 2 +- php/commands/option.php | 6 +++--- php/commands/plugin.php | 20 ++++++++++---------- php/commands/post.php | 4 ++-- php/commands/rewrite.php | 6 +++--- php/commands/role.php | 4 ++-- php/commands/scaffold.php | 16 ++++++++-------- php/commands/search-replace.php | 26 ++++++-------------------- php/commands/shell.php | 2 +- php/commands/site.php | 6 +++--- php/commands/term.php | 8 ++------ php/commands/theme.php | 14 +++++++------- php/commands/user.php | 12 ++++++------ 21 files changed, 85 insertions(+), 103 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index 8a52bfc92f..dcd2be9b41 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -41,7 +41,7 @@ protected function _create( $args, $assoc_args, $callback ) { \WP_CLI::error( $obj_id ); } - if ( isset( $assoc_args['porcelain'] ) ) + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) \WP_CLI::line( $obj_id ); else \WP_CLI::success( "Created $this->obj_type $obj_id." ); diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 507c4dd523..c78b326c4a 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -133,7 +133,7 @@ public function install( $args, $assoc_args ) { if ( $response == $language_code ) { \WP_CLI::success( "Language installed." ); - if ( isset( $assoc_args['activate'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { $this->activate( array( $language_code ), array() ); } } else { @@ -199,7 +199,7 @@ public function update( $args, $assoc_args ) { } // Only preview which translations would be updated. - if ( isset( $assoc_args['dry-run'] ) && $assoc_args['dry-run'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'dry-run' ) ) { \WP_CLI::line( sprintf( 'Available %d translations updates:', count( $updates ) ) ); \WP_CLI\Utils\format_items( 'table', $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 9f57669f81..0b3c592ceb 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -150,12 +150,12 @@ function install( $args, $assoc_args ) { } if ( $result ) { - if ( isset( $assoc_args['activate-network'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate-network' ) ) { \WP_CLI::log( "Network-activating '$slug'..." ); $this->activate( array( $slug ), array( 'network' => true ) ); } - if ( isset( $assoc_args['activate'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { \WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } @@ -203,20 +203,20 @@ protected static function alter_api_response( $response, $version ) { } protected function get_upgrader( $assoc_args ) { - $upgrader_class = $this->get_upgrader_class( isset( $assoc_args['force'] ) ); + $upgrader_class = $this->get_upgrader_class( \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ); return \WP_CLI\Utils\get_upgrader( $upgrader_class ); } protected function update_many( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); - if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) { \WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." ); } $items = $this->get_item_list(); - if ( !isset( $assoc_args['all'] ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { $items = $this->filter_item_list( $items, $args ); } @@ -224,7 +224,7 @@ protected function update_many( $args, $assoc_args ) { 'update' => true ) ); - if ( isset( $assoc_args['dry-run'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'dry-run' ) ) { if ( empty( $items_to_update ) ) { \WP_CLI::line( "No {$this->item_type} updates available." ); return; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f571c47a59..897781a49c 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -274,7 +274,7 @@ public static function error_multi_line( $message_lines ) { * Ask for confirmation before running a destructive operation. */ public static function confirm( $question, $assoc_args = array() ) { - if ( !isset( $assoc_args['yes'] ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'yes' ) ) { fwrite( STDOUT, $question . " [y/n] " ); $answer = trim( fgets( STDIN ) ); @@ -314,7 +314,7 @@ public static function get_value_from_arg_or_stdin( $args, $index ) { * @param array $assoc_args */ public static function read_value( $raw_value, $assoc_args = array() ) { - if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'json' ) ) { $value = json_decode( $raw_value, true ); if ( null === $value ) { WP_CLI::error( sprintf( 'Invalid JSON: %s', $raw_value ) ); @@ -333,7 +333,7 @@ public static function read_value( $raw_value, $assoc_args = array() ) { * @param array $assoc_args */ public static function print_value( $value, $assoc_args = array() ) { - if ( isset( $assoc_args['format'] ) && 'json' == $assoc_args['format'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'json' ) ) { $value = json_encode( $value ); } elseif ( is_array( $value ) || is_object( $value ) ) { $value = var_export( $value ); diff --git a/php/commands/cli.php b/php/commands/cli.php index 29239088d7..e1355bdf54 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -48,7 +48,7 @@ public function info( $_, $assoc_args ) { $runner = WP_CLI::get_runner(); - if ( isset( $assoc_args['format'] ) && 'json' === $assoc_args['format'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'json' ) ) { $info = array( 'php_binary_path' => $php_bin, 'global_config_path' => $runner->global_config_path, @@ -237,10 +237,10 @@ private function get_updates( $assoc_args ) { $update_type = 'patch'; } - if ( ! ( isset( $assoc_args['patch'] ) && $assoc_args['patch'] && 'patch' !== $update_type ) - && ! ( isset( $assoc_args['patch'] ) && ! $assoc_args['patch'] && 'patch' === $update_type ) - && ! ( isset( $assoc_args['minor'] ) && $assoc_args['minor'] && 'minor' !== $update_type ) - && ! ( isset( $assoc_args['minor'] ) && ! $assoc_args['minor'] && 'minor' === $update_type ) + if ( ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'patch' ) && 'patch' !== $update_type ) + && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'patch', false ) && 'patch' === $update_type ) + && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'minor' ) && 'minor' !== $update_type ) + && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'minor', false ) && 'minor' === $update_type ) && ! $this->same_minor_release( $release_parts, $updates ) ) { $updates[] = array( diff --git a/php/commands/comment.php b/php/commands/comment.php index 662f4f7340..824f974a50 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -209,7 +209,7 @@ public function list_( $_, $assoc_args ) { */ public function delete( $args, $assoc_args ) { parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { - $r = wp_delete_comment( $comment_id, isset( $assoc_args['force'] ) ); + $r = wp_delete_comment( $comment_id, \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ); if ( $r ) { return array( 'success', "Deleted comment $comment_id." ); diff --git a/php/commands/core.php b/php/commands/core.php index c79c9ed5af..a74be9d14d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -73,8 +73,8 @@ function check_update( $_, $assoc_args ) { $update_type = 'minor'; } - if ( ! ( isset( $assoc_args['minor'] ) && 'minor' !== $update_type ) - && ! ( isset( $assoc_args['major'] ) && 'major' !== $update_type ) + if ( ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'minor' ) && 'minor' !== $update_type ) + && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'major' ) && 'major' !== $update_type ) ) { $updates = $this->remove_same_minor_releases( $release_parts, $updates ); $updates[] = array( @@ -121,7 +121,7 @@ function check_update( $_, $assoc_args ) { * @when before_wp_load */ public function download( $args, $assoc_args ) { - if ( !isset( $assoc_args['force'] ) && is_readable( ABSPATH . 'wp-load.php' ) ) + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) && is_readable( ABSPATH . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); if ( !is_dir( ABSPATH ) ) { @@ -336,7 +336,7 @@ public function config( $_, $assoc_args ) { WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); // Check DB connection - if ( !isset( $assoc_args['skip-check'] ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-check' ) ) { Utils\run_mysql_command( 'mysql --no-defaults', array( 'execute' => ';', 'host' => $assoc_args['dbhost'], @@ -345,12 +345,12 @@ public function config( $_, $assoc_args ) { ) ); } - if ( isset( $assoc_args['extra-php'] ) && $assoc_args['extra-php'] === true ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'extra-php' ) ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); } // TODO: adapt more resilient code from wp-admin/setup-config.php - if ( ! isset( $assoc_args['skip-salts'] ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-salts' ) ) { $assoc_args['keys-and-salts'] = self::_read( 'https://api.wordpress.org/secret-key/1.1/salt/' ); } @@ -387,7 +387,7 @@ public function config( $_, $assoc_args ) { */ public function is_installed( $_, $assoc_args ) { - if ( isset( $assoc_args['network'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) ) { if ( is_blog_installed() && is_multisite() ) { exit( 0 ); } else { @@ -735,7 +735,7 @@ public function version( $args = array(), $assoc_args = array() ) { include $versions_path; // @codingStandardsIgnoreStart - if ( isset( $assoc_args['extra'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'extra' ) ) { if ( preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ) ) { $human_readable_tiny_mce = $match[1] . '.' . $match[2]; } else { @@ -898,7 +898,7 @@ function update( $args, $assoc_args ) { } } else if ( version_compare( $wp_version, $assoc_args['version'], '<' ) - || isset( $assoc_args['force'] ) ) { + || \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ) { $version = $assoc_args['version']; $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : get_locale(); @@ -921,7 +921,7 @@ function update( $args, $assoc_args ) { } - if ( ! empty( $update ) && ( $update->version != $wp_version || isset( $assoc_args['force'] ) ) ) { + if ( ! empty( $update ) && ( $update->version != $wp_version || \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ) ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); diff --git a/php/commands/media.php b/php/commands/media.php index 9f73deca5a..5228ff2a69 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -162,18 +162,18 @@ function import( $args, $assoc_args = array() ) { } // Set as featured image, if --post_id and --featured_image are set - if ( $assoc_args['post_id'] && isset( $assoc_args['featured_image'] ) ) { + if ( $assoc_args['post_id'] && \WP_CLI\Utils\check_flag( $assoc_args, 'featured_image' ) ) { update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); } $attachment_success_text = ''; if ( $assoc_args['post_id'] ) { $attachment_success_text = " and attached to post {$assoc_args['post_id']}"; - if ( isset($assoc_args['featured_image']) ) + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'featured_image' ) ) $attachment_success_text .= ' as featured image'; } - if ( isset( $assoc_args['porcelain'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $success ); } else { WP_CLI::success( sprintf( diff --git a/php/commands/menu.php b/php/commands/menu.php index 136a6e4219..afab17d3e7 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -51,7 +51,7 @@ public function create( $args, $assoc_args ) { } else { - if ( isset( $assoc_args['porcelain'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $menu_id ); } else { WP_CLI::success( "Created menu $menu_id." ); diff --git a/php/commands/option.php b/php/commands/option.php index 6575da1a36..142847ab1e 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -64,7 +64,7 @@ public function add( $args, $assoc_args ) { $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); $value = WP_CLI::read_value( $value, $assoc_args ); - if ( isset( $assoc_args['autoload'] ) && $assoc_args['autoload'] == 'no' ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'autoload', 'no' ) ) { $autoload = 'no'; } else { $autoload = 'yes'; @@ -139,7 +139,7 @@ public function list_( $args, $assoc_args ) { $fields = explode( ',', $assoc_args['fields'] ); } - if ( isset( $assoc_args['format'] ) && 'total_bytes' === $assoc_args['format'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'total_bytes' ) ) { $fields = array( 'size_bytes' ); $size_query = ",SUM(LENGTH(option_value)) AS `size_bytes`"; } @@ -162,7 +162,7 @@ public function list_( $args, $assoc_args ) { ) ); - if ( isset( $assoc_args['format'] ) && 'total_bytes' === $assoc_args['format'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'total_bytes' ) ) { WP_CLI::line( $results[0]->size_bytes ); } else { $formatter = new \WP_CLI\Formatter( diff --git a/php/commands/plugin.php b/php/commands/plugin.php index c5352befe3..bafdb8ad23 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -153,9 +153,9 @@ protected function get_all_items() { * : If set, the plugin will be activated for the entire multisite network. */ function activate( $args, $assoc_args = array() ) { - $network_wide = isset( $assoc_args['network'] ); + $network_wide = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ); - if ( isset( $assoc_args['all'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { $args = array_map( function( $file ){ return Utils\get_plugin_name( $file ); }, array_keys( get_plugins() ) ); @@ -201,10 +201,10 @@ function activate( $args, $assoc_args = array() ) { * : If set, the plugin will be deactivated for the entire multisite network. */ function deactivate( $args, $assoc_args = array() ) { - $network_wide = isset( $assoc_args['network'] ); - $disable_all = isset( $assoc_args['all'] ); + $network_wide = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ); + $disable_all = \WP_CLI\Utils\check_flag( $assoc_args, 'all' ); - if ( isset( $assoc_args['all'] ) ) { + if ( $disable_all ) { $args = array_map( function( $file ){ return Utils\get_plugin_name( $file ); }, array_keys( get_plugins() ) ); @@ -242,7 +242,7 @@ function deactivate( $args, $assoc_args = array() ) { * : If set, the plugin will be toggled for the entire multisite network. */ function toggle( $args, $assoc_args = array() ) { - $network_wide = isset( $assoc_args['network'] ); + $network_wide = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { if ( $this->check_active( $plugin->file, $network_wide ) ) { @@ -277,7 +277,7 @@ function path( $args, $assoc_args ) { $plugin = $this->fetcher->get_check( $args[0] ); $path .= '/' . $plugin->file; - if ( isset( $assoc_args['dir'] ) ) + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'dir' ) ) $path = dirname( $path ); } @@ -297,13 +297,13 @@ protected function install_from_repo( $slug, $assoc_args ) { $status = install_plugin_install_status( $api ); - if ( !isset( $assoc_args['force'] ) && 'install' != $status['status'] ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) && 'install' != $status['status'] ) { // We know this will fail, so avoid a needless download of the package. return new WP_Error( 'already_installed', 'Plugin already installed.' ); } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); - if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'version', 'dev' ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); @@ -503,7 +503,7 @@ function uninstall( $args, $assoc_args = array() ) { uninstall_plugin( $plugin->file ); - if ( !isset( $assoc_args['skip-delete'] ) && $this->_delete( $plugin ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-delete' ) && $this->_delete( $plugin ) ) { WP_CLI::success( "Uninstalled and deleted '$plugin->name' plugin." ); } else { WP_CLI::success( "Ran uninstall procedure for '$plugin->name' plugin without deleting." ); diff --git a/php/commands/post.php b/php/commands/post.php index edde22682f..dd80cda149 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -55,7 +55,7 @@ public function create( $args, $assoc_args ) { $assoc_args['post_content'] = $this->read_from_file_or_stdin( $args[0] ); } - if ( isset( $assoc_args['edit'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'edit' ) ) { $input = isset( $assoc_args['post_content'] ) ? $assoc_args['post_content'] : ''; @@ -357,7 +357,7 @@ public function generate( $args, $assoc_args ) { $post_author = $user_fetcher->get_check( $post_author )->ID; } - if ( isset( $assoc_args['post_content'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'post_content' ) ) { $post_content = file_get_contents( 'php://stdin' ); } diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 4bc3dced56..bea5dfd5fd 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -28,10 +28,10 @@ class Rewrite_Command extends WP_CLI_Command { public function flush( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config self::apache_modules(); - if ( isset( $assoc_args['hard'] ) && ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'hard' ) && ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); } - flush_rewrite_rules( isset( $assoc_args['hard'] ) ); + flush_rewrite_rules( \WP_CLI\Utils\check_flag( $assoc_args, 'hard' ) ); if ( ! get_option( 'rewrite_rules' ) ) { WP_CLI::warning( "Rewrite rules are empty, possibly because of a missing permalink_structure option. Use 'wp rewrite list' to verify, or 'wp rewrite structure' to update permalink_structure." ); } @@ -115,7 +115,7 @@ public function structure( $args, $assoc_args ) { // Launch a new process to flush rewrites because core expects flush // to happen after rewrites are set $new_assoc_args = array(); - if ( isset( $assoc_args['hard'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'hard' ) ) { $new_assoc_args['hard'] = true; if ( ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); diff --git a/php/commands/role.php b/php/commands/role.php index 88b46eab0e..b12ed8ad09 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -169,7 +169,7 @@ public function reset( $args, $assoc_args ) { self::persistence_check(); - if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) WP_CLI::error( "Role key not provided, or is invalid." ); if ( ! function_exists( 'populate_roles' ) ) { @@ -179,7 +179,7 @@ public function reset( $args, $assoc_args ) { // get our default roles $default_roles = $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); - if ( isset( $assoc_args['all'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { foreach( $default_roles as $role ) { remove_role( $role ); } diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 96e6ed054c..e78cc59d03 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -211,7 +211,7 @@ function _s( $args, $assoc_args ) { $body['underscoresme_description'] = $theme_description; $body['underscoresme_generate_submit'] = "Generate"; $body['underscoresme_generate'] = "1"; - if ( isset( $assoc_args['sassify'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'sassify' ) ) { $body['underscoresme_sass'] = 1; } @@ -235,9 +235,9 @@ function _s( $args, $assoc_args ) { WP_CLI::success( "Created theme '{$data['theme_name']}'." ); - if ( isset( $assoc_args['activate'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } else if ( isset( $assoc_args['enable-network'] ) ) { + } else if ( \WP_CLI\Utils\check_flag( $assoc_args, 'enable-network' ) ) { WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); } } @@ -296,9 +296,9 @@ function child_theme( $args, $assoc_args ) { WP_CLI::success( "Created $theme_dir" ); - if ( isset( $assoc_args['activate'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } else if ( isset( $assoc_args['enable-network'] ) ) { + } else if ( \WP_CLI\Utils\check_flag( $assoc_args, 'enable-network' ) ) { WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); } } @@ -454,13 +454,13 @@ function plugin( $args, $assoc_args ) { WP_CLI::success( "Created $plugin_dir" ); - if ( !isset( $assoc_args['skip-tests'] ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-tests' ) ) { WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ) ); } - if ( isset( $assoc_args['activate'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); - } else if ( isset( $assoc_args['activate-network'] ) ) { + } else if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate-network' ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug), array( 'network' => true ) ); } } diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index fe1cd8a22f..195cb0a7ac 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -64,9 +64,9 @@ public function __invoke( $args, $assoc_args ) { $new = array_shift( $args ); $total = 0; $report = array(); - $dry_run = self::check_flag( $assoc_args, 'dry-run' ); - $php_only = self::check_flag( $assoc_args, 'precise' ); - $recurse_objects = self::check_flag( $assoc_args, 'recurse-objects' ); + $dry_run = \WP_CLI\Utils\check_flag( $assoc_args, 'dry-run' ); + $php_only = \WP_CLI\Utils\check_flag( $assoc_args, 'precise' ); + $recurse_objects = \WP_CLI\Utils\check_flag( $assoc_args, 'recurse-objects' ); if ( isset( $assoc_args['skip-columns'] ) ) { $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -79,13 +79,13 @@ public function __invoke( $args, $assoc_args ) { // Determine how to limit the list of tables. Defaults to 'wordpress' $table_type = 'wordpress'; - if ( self::check_flag( $assoc_args, 'network' ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) ) { $table_type = 'network'; } - if ( self::check_flag( $assoc_args, 'all-tables-with-prefix' ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all-tables-with-prefix' ) ) { $table_type = 'all-tables-with-prefix'; } - if ( self::check_flag( $assoc_args, 'all-tables' ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all-tables' ) ) { $table_type = 'all-tables'; } @@ -305,20 +305,6 @@ private static function esc_like( $old ) { return $old; } - /** - * Determine the boolean value of a flag in an array. - * - * Primarily useful for determining the status of a boolean flag for a command. This is needed because a flag can be - * prefixed with --no- to set it to false. Therefore it is not sufficient to only check whether a flag is set. - * - * @param array $array The array to check. - * @param string $key The key to check for. - * - * @return bool True if the key is set in the array and is truthy, false otherwise. - */ - private static function check_flag( $array, $key ) { - return isset( $array[ $key ] ) && $array[ $key ]; - } } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); diff --git a/php/commands/shell.php b/php/commands/shell.php index 82b96484d0..d805a2d8ed 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -21,7 +21,7 @@ public function __invoke( $_, $assoc_args ) { '\\WP_CLI\\REPL', ); - if ( isset( $assoc_args['basic'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'basic' ) ) { $class = '\\WP_CLI\\REPL'; } else { foreach ( $implementations as $candidate ) { diff --git a/php/commands/site.php b/php/commands/site.php index 7f286e1677..c292f53c62 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -178,7 +178,7 @@ function delete( $args, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl site?", $assoc_args ); - wpmu_delete_blog( $blog->blog_id, !isset( $assoc_args['keep-tables'] ) ); + wpmu_delete_blog( $blog->blog_id, ! \WP_CLI\Utils\check_flag( $assoc_args, 'keep-tables' ) ); WP_CLI::success( "The site at $blog->siteurl was deleted." ); } @@ -231,7 +231,7 @@ public function create( $_, $assoc_args ) { $network = $current_site; } - $public = !isset( $assoc_args['private'] ); + $public = ! \WP_CLI\Utils\check_flag( $assoc_args, 'private' ); // Sanitize if ( preg_match( '|^([a-zA-Z0-9-])+$|', $base ) ) { @@ -301,7 +301,7 @@ public function create( $_, $assoc_args ) { WP_CLI::error( $id->get_error_message() ); } - if ( isset( $assoc_args['porcelain'] ) ) + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) WP_CLI::line( $id ); else WP_CLI::success( "Site $id created: $url" ); diff --git a/php/commands/term.php b/php/commands/term.php index e7befa0c2d..46a005e636 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -114,12 +114,8 @@ public function create( $args, $assoc_args ) { ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); - if ( isset( $assoc_args['porcelain'] ) ) { - $porcelain = true; - unset( $assoc_args['porcelain'] ); - } else { - $porcelain = false; - } + $porcelain = \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ); + unset( $assoc_args['porcelain'] ); // Compatibility for < WP 4.0 if ( $assoc_args['parent'] > 0 && ! term_exists( (int) $assoc_args['parent'] ) ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 5843333d8e..79dc55c767 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -260,7 +260,7 @@ public function path( $args, $assoc_args ) { $path = $theme->get_stylesheet_directory(); - if ( !isset( $assoc_args['dir'] ) ) + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'dir' ) ) $path .= '/style.css'; } @@ -278,13 +278,13 @@ protected function install_from_repo( $slug, $assoc_args ) { self::alter_api_response( $api, $assoc_args['version'] ); } - if ( !isset( $assoc_args['force'] ) && wp_get_theme( $slug )->exists() ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) && wp_get_theme( $slug )->exists() ) { // We know this will fail, so avoid a needless download of the package. return new WP_Error( 'already_installed', 'Theme already installed.' ); } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); - if ( !isset( $assoc_args['version'] ) || 'dev' !== $assoc_args['version'] ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'version', 'dev' ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); @@ -597,11 +597,11 @@ class Theme_Mod_command extends WP_CLI_Command { */ public function get( $args = array(), $assoc_args = array() ) { - if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) { WP_CLI::error( "You must specify at least one mod or use --all." ); } - if ( isset( $assoc_args['all'] ) && $assoc_args['all'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { $args = array(); } @@ -657,11 +657,11 @@ public function get( $args = array(), $assoc_args = array() ) { */ public function remove( $args = array(), $assoc_args = array() ) { - if ( ! isset( $assoc_args['all'] ) && empty( $args ) ) { + if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) { WP_CLI::error( "You must specify at least one mod or use --all." ); } - if ( isset( $assoc_args['all'] ) && $assoc_args['all'] ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { remove_theme_mods(); WP_CLI::success( 'Theme mods removed.' ); return; diff --git a/php/commands/user.php b/php/commands/user.php index d9597fca0a..580a0c5fdd 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -81,7 +81,7 @@ public function __construct() { */ public function list_( $args, $assoc_args ) { - if ( isset( $assoc_args['network'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) ) { if ( ! is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); } @@ -175,7 +175,7 @@ public function get( $args, $assoc_args ) { * wp user delete 123 --reassign=567 */ public function delete( $args, $assoc_args ) { - $network = isset( $assoc_args['network'] ) && is_multisite(); + $network = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) && is_multisite(); $reassign = isset( $assoc_args['reassign'] ) ? $assoc_args['reassign'] : null; if ( $network && $reassign ) { @@ -287,7 +287,7 @@ public function create( $args, $assoc_args ) { $user->role = $role; $user_id = wp_insert_user( $user ); - if ( isset( $assoc_args['send-email'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'send-email' ) ) { wp_new_user_notification( $user_id, $user->user_pass ); } @@ -300,7 +300,7 @@ public function create( $args, $assoc_args ) { } } - if ( isset( $assoc_args['porcelain'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $user_id ); } else { WP_CLI::success( "Created user $user_id." ); @@ -668,7 +668,7 @@ public function import_csv( $args, $assoc_args ) { $existing_user = get_user_by( 'login', $new_user['user_login'] ); } - if ( $existing_user && isset( $assoc_args['skip-update'] ) ) { + if ( $existing_user && \WP_CLI\Utils\check_flag( $assoc_args, 'skip-update' ) ) { WP_CLI::log( "{$existing_user->user_login} exists and has been skipped" ); continue; @@ -687,7 +687,7 @@ public function import_csv( $args, $assoc_args ) { } else { unset( $new_user['ID'] ); // Unset else it will just return the ID $user_id = wp_insert_user( $new_user ); - if ( isset( $assoc_args['send-email'] ) ) { + if ( \WP_CLI\Utils\check_flag( $assoc_args, 'send-email' ) ) { wp_new_user_notification( $user_id, $new_user['user_pass'] ); } } From b00ea2237acf70939b10a6b4c20dac5cdce82f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Mon, 13 Apr 2015 00:41:05 -0400 Subject: [PATCH 3495/4858] Fix incorrect type of value When set, flags must be strictly boolean values. --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 79dc55c767..4ef1ced63d 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -458,7 +458,7 @@ function update( $args, $assoc_args ) { if ( is_wp_error( $r ) ) { WP_CLI::warning( $r ); } else { - $assoc_args['force'] = 1; + $assoc_args['force'] = true; $this->install( array( $theme->stylesheet ), $assoc_args ); } } From a604b83d03a86187cdb02a82f3e80c82403a3a5e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 16 Apr 2015 11:58:56 -0700 Subject: [PATCH 3496/4858] Scaffold plugin and plugin tests to arbitrary directory mu-plugins is one use case, and plugins within themes is another --- features/scaffold.feature | 21 +++++++++++++++++++++ php/commands/scaffold.php | 36 +++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index e1f48aee1f..86039c9feb 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -254,3 +254,24 @@ Feature: WordPress code scaffolding """ Success: Switched to 'Starter-theme' theme. """ + + Scenario: Scaffold plugin and tests for non-standard plugin directory + Given a WP install + + When I run `wp scaffold plugin custom-plugin --dir=wp-content/mu-plugins --skip-tests` + Then STDOUT should not be empty + And the wp-content/mu-plugins/custom-plugin/custom-plugin.php file should exist + And the wp-content/mu-plugins/custom-plugin/tests directory should not exist + + When I try `wp scaffold plugin-tests --dir=wp-content/mu-plugins/incorrect-custom-plugin` + Then STDERR should contain: + """ + Error: Invalid plugin specified. + """ + + When I run `wp scaffold plugin-tests --dir=wp-content/mu-plugins/custom-plugin` + Then STDOUT should contain: + """ + Success: Created test files. + """ + And the wp-content/mu-plugins/custom-plugin/tests directory should exist diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index dffe4c9c68..768781f70c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -411,6 +411,9 @@ public function package_tests( $args, $assoc_args ) { * <slug> * : The internal name of the plugin. * + * [--dir=<dirname>] + * : Put the new plugin in some arbitrary directory path. Plugin directory will be path plus supplied slug. + * * [--plugin_name=<title>] * : What to put in the 'Plugin Name:' header * @@ -432,19 +435,26 @@ function plugin( $args, $assoc_args ) { $data['textdomain'] = $plugin_slug; - $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + if ( ! empty( $assoc_args['dir'] ) ) { + if ( ! is_dir( $assoc_args['dir'] ) ) { + WP_CLI::error( "Cannot create plugin in directory that doesn't exist." ); + } + $plugin_dir = $assoc_args['dir'] . "/$plugin_slug"; + } else { + $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + $this->maybe_create_plugins_dir(); + } + $plugin_path = "$plugin_dir/$plugin_slug.php"; $plugin_readme_path = "$plugin_dir/readme.txt"; - $this->maybe_create_plugins_dir(); - $this->create_file( $plugin_path, Utils\mustache_render( 'plugin.mustache', $data ) ); $this->create_file( $plugin_readme_path, Utils\mustache_render( 'plugin-readme.mustache', $data ) ); WP_CLI::success( "Created $plugin_dir" ); if ( !isset( $assoc_args['skip-tests'] ) ) { - WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ) ); + WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ), array( 'dir' => $plugin_dir ) ); } if ( isset( $assoc_args['activate'] ) ) { @@ -473,9 +483,12 @@ function plugin( $args, $assoc_args ) { * * ## OPTIONS * - * <plugin> + * [<plugin>] * : The name of the plugin to generate test files for. * + * [--dir=<dirname>] + * : Generate test files for a non-standard plugin path. + * * ## EXAMPLE * * wp scaffold plugin-tests hello @@ -485,9 +498,18 @@ function plugin( $args, $assoc_args ) { function plugin_tests( $args, $assoc_args ) { $wp_filesystem = $this->init_wp_filesystem(); - $plugin_slug = $args[0]; + if ( ! empty( $assoc_args['dir'] ) ) { + $plugin_dir = $assoc_args['dir']; + if ( ! is_dir( $plugin_dir ) ) { + WP_CLI::error( 'Invalid plugin specified.' ); + } + } else if ( ! empty( $args[0] ) ) { + $plugin_slug = $args[0]; + $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + } else { + WP_CLI::error( 'Invalid plugin specified.' ); + } - $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; $tests_dir = "$plugin_dir/tests"; $bin_dir = "$plugin_dir/bin"; From 7511f519e870a7e2a92e1afa1d5cd94671aa0fdf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 17 Apr 2015 07:06:37 -0700 Subject: [PATCH 3497/4858] Document how to delete all posts in the trash --- php/commands/post.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/post.php b/php/commands/post.php index edde22682f..a9bdd70a54 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -195,6 +195,9 @@ public function get( $args, $assoc_args ) { * wp post delete 123 --force * * wp post delete $(wp post list --post_type='page' --format=ids) + * + * # delete all posts in the trash + * wp post delete $(wp post list --post_status=trash --format=ids) */ public function delete( $args, $assoc_args ) { $defaults = array( From 4b4113a81f7cebd44246489b8c3e83236f63317d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 17 Apr 2015 07:08:59 -0700 Subject: [PATCH 3498/4858] Failing test case for incorrect language when deleting trashed post --- features/post.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/post.feature b/features/post.feature index daec7467a2..4969598dcb 100644 --- a/features/post.feature +++ b/features/post.feature @@ -21,7 +21,10 @@ Feature: Manage WordPress posts """ When I run the previous command again - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: Deleted post {POST_ID} + """ When I try the previous command again Then the return code should be 1 From 3f410275e190bfcb76fadb016414d81090766ed6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 17 Apr 2015 07:13:09 -0700 Subject: [PATCH 3499/4858] If the post is already trashed, clarify success language --- features/post.feature | 2 +- php/commands/post.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/features/post.feature b/features/post.feature index 4969598dcb..012c61f02a 100644 --- a/features/post.feature +++ b/features/post.feature @@ -23,7 +23,7 @@ Feature: Manage WordPress posts When I run the previous command again Then STDOUT should be: """ - Success: Deleted post {POST_ID} + Success: Deleted post {POST_ID}. """ When I try the previous command again diff --git a/php/commands/post.php b/php/commands/post.php index edde22682f..964e8e5cd6 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -203,10 +203,11 @@ public function delete( $args, $assoc_args ) { $assoc_args = array_merge( $defaults, $assoc_args ); parent::_delete( $args, $assoc_args, function ( $post_id, $assoc_args ) { + $status = get_post_status( $post_id ); $r = wp_delete_post( $post_id, $assoc_args['force'] ); if ( $r ) { - $action = $assoc_args['force'] ? 'Deleted' : 'Trashed'; + $action = $assoc_args['force'] || 'trash' === $status ? 'Deleted' : 'Trashed'; return array( 'success', "$action post $post_id." ); } else { From 19ba6160695ecc74cbc5816d63c19f5b44f31dc4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 17 Apr 2015 09:52:33 -0700 Subject: [PATCH 3500/4858] Add `after_invoke` hook for any post-execution tasks --- php/WP_CLI/Dispatcher/Subcommand.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 83c87c7d2d..dd601c34e9 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -293,6 +293,8 @@ public function invoke( $args, $assoc_args, $extra_args ) { \WP_CLI::do_hook( 'before_invoke:' . implode( ' ', array_slice( $path, 1 ) ) ); call_user_func( $this->when_invoked, $args, array_merge( $extra_args, $assoc_args ) ); + + \WP_CLI::do_hook( 'after_invoke:' . implode( ' ', array_slice( $path, 1 ) ) ); } } From 4532e1d5223c1e79bdd16f22cdad2da0ae31f1c7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 17 Apr 2015 10:08:18 -0700 Subject: [PATCH 3501/4858] Respect `$exit` argument in `WP_CLI::error()` --- php/class-wp-cli.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f571c47a59..aa73f8cee9 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -256,7 +256,9 @@ public static function error( $message, $exit = true ) { self::$logger->error( self::error_to_string( $message ) ); } - exit(1); + if ( $exit ) { + exit(1); + } } /** From 74dd4231cc1763c29a667502a449678ea15473e6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 13:49:00 -0700 Subject: [PATCH 3502/4858] Add default Gruntfile to plugin scaffold with two helpful tasks --- features/scaffold.feature | 2 ++ php/commands/scaffold.php | 3 ++ templates/plugin-gruntfile.mustache | 54 +++++++++++++++++++++++++++++ templates/plugin-packages.mustache | 12 +++++++ 4 files changed, 71 insertions(+) create mode 100644 templates/plugin-gruntfile.mustache create mode 100644 templates/plugin-packages.mustache diff --git a/features/scaffold.feature b/features/scaffold.feature index 346b0e08c4..59e6ebb040 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -114,6 +114,8 @@ Feature: WordPress code scaffolding Then STDOUT should not be empty And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist + And the {PLUGIN_DIR}/hello-world/package.json file should exist + And the {PLUGIN_DIR}/hello-world/Gruntfile.js file should exist Scenario: Scaffold a plugin and activate it Given a WP install diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f61ad2cec4..d06109c190 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -441,6 +441,7 @@ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; $data = wp_parse_args( $assoc_args, array( + 'plugin_slug' => $plugin_slug, 'plugin_name' => ucfirst( $plugin_slug ), ) ); @@ -461,6 +462,8 @@ function plugin( $args, $assoc_args ) { $this->create_file( $plugin_path, Utils\mustache_render( 'plugin.mustache', $data ) ); $this->create_file( $plugin_readme_path, Utils\mustache_render( 'plugin-readme.mustache', $data ) ); + $this->create_file( "$plugin_dir/package.json", Utils\mustache_render( 'plugin-packages.mustache', $data ) ); + $this->create_file( "$plugin_dir/Gruntfile.js", Utils\mustache_render( 'plugin-gruntfile.mustache', $data ) ); WP_CLI::success( "Created $plugin_dir" ); diff --git a/templates/plugin-gruntfile.mustache b/templates/plugin-gruntfile.mustache new file mode 100644 index 0000000000..96dba5e2d0 --- /dev/null +++ b/templates/plugin-gruntfile.mustache @@ -0,0 +1,54 @@ +module.exports = function( grunt ) { + + 'use strict'; + var remapify = require('remapify'); + var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; + // Project configuration + grunt.initConfig( { + + pkg: grunt.file.readJSON( 'package.json' ), + + addtextdomain: { + options: { + textdomain: '{{textdomain}}', + }, + target: { + files: { + src: [ '*.php', '**/*.php', '!node_modules/**', '!php-tests/**', '!bin/**' ] + } + } + }, + + wp_readme_to_markdown: { + your_target: { + files: { + 'README.md': 'readme.txt' + } + }, + }, + + makepot: { + target: { + options: { + domainPath: '/languages', + mainFile: '{{plugin_slug}}.php', + potFilename: '{{plugin_slug}}.pot', + potHeaders: { + poedit: true, + 'x-poedit-keywordslist': true + }, + type: 'wp-plugin', + updateTimestamp: true + } + } + }, + } ); + + grunt.loadNpmTasks( 'grunt-wp-i18n' ); + grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' ); + grunt.registerTask( 'i18n', ['addtextdomain', 'makepot'] ); + grunt.registerTask( 'readme', ['wp_readme_to_markdown']); + + grunt.util.linefeed = '\n'; + +}; diff --git a/templates/plugin-packages.mustache b/templates/plugin-packages.mustache new file mode 100644 index 0000000000..ef736af278 --- /dev/null +++ b/templates/plugin-packages.mustache @@ -0,0 +1,12 @@ + +{ + "name": "{{plugin_name}}", + "version": "0.0.0", + "main": "Gruntfile.js", + "author": "YOUR NAME HERE", + "devDependencies": { + "grunt": "^0.4.5", + "grunt-wp-i18n": "^0.5.0", + "grunt-wp-readme-to-markdown": "~0.9.0" + } +} From ce7154ecbbf55fb697b8d480c197ed9833b18ea6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 14:05:12 -0700 Subject: [PATCH 3503/4858] Don't permit child themes to be activated without their parent If a child theme is dependent on parent functions, WP can fatal. --- features/theme.feature | 9 +++++++++ php/commands/theme.php | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index fde24c9933..040d4e6bcc 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -225,3 +225,12 @@ Feature: Manage WordPress themes Then STDOUT should be a table containing rows: | name | version | | p2 | 1.4.2 | + + Scenario: Install and attempt to activate a child theme without its parent + Given a WP install + + When I try `wp theme install biker --activate` + Then STDERR should contain: + """ + Error: The 'biker' theme cannot be activated without its parent, 'jolene'. + """ diff --git a/php/commands/theme.php b/php/commands/theme.php index 5843333d8e..34e5fec526 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -128,6 +128,10 @@ public function activate( $args = array() ) { exit; } + if ( $theme->get_stylesheet() != $theme->get_template() && ! $this->fetcher->get( $theme->get_template() ) ) { + WP_CLI::error( "The '{$theme->get_stylesheet()}' theme cannot be activated without its parent, '{$theme->get_template()}'." ); + } + switch_theme( $theme->get_template(), $theme->get_stylesheet() ); if ( $this->is_active_theme( $theme ) ) { From 666c12e6b4307bc5f3a80ba71bab9c0457b7cb6b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 14:15:36 -0700 Subject: [PATCH 3504/4858] Failing test case for #1728 --- features/cron.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 90f43ba157..e8d0513db5 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -4,16 +4,16 @@ Feature: Manage WP-Cron events and schedules Given a WP install Scenario: Scheduling and then deleting an event - When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour' --apple=banana` + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 2 minutes' --apple=banana` Then STDOUT should contain: """ Success: Scheduled event with hook 'wp_cli_test_event_1' """ - When I run `wp cron event list --format=csv --fields=hook,recurrence,args` + When I run `wp cron event list --format=csv --fields=hook,recurrence,next_run_relative,args` Then STDOUT should be CSV containing: - | hook | recurrence | args | - | wp_cli_test_event_1 | Non-repeating | {"apple":"banana"} | + | hook | recurrence | next_run_relative | args | + | wp_cli_test_event_1 | Non-repeating | 1 hour 1 minute | {"apple":"banana"} | When I run `wp cron event delete wp_cli_test_event_1` Then STDOUT should contain: From 25bdcbefb7f01e18193467e22f9667a0be9ba4df Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 14:16:36 -0700 Subject: [PATCH 3505/4858] Fix broken conditional for `<next-run>` argument --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 527e427988..b9b4ed0cb7 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -97,7 +97,7 @@ public function schedule( $args, $assoc_args ) { $next_run = ( isset( $args[1] ) ) ? $args[1] : 'now'; $recurrence = ( isset( $args[2] ) ) ? $args[2] : false; - if ( ! empty( $next_run ) ) { + if ( empty( $next_run ) ) { $timestamp = time(); } else if ( is_numeric( $next_run ) ) { $timestamp = absint( $next_run ); From 5ba7cdbbb8bb6e5c8e5df1e2b5c427dd8053dfbb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 14:26:44 -0700 Subject: [PATCH 3506/4858] Support filtering by site value in `wp site list` --- features/site.feature | 19 +++++++++++++++++++ php/commands/site.php | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/features/site.feature b/features/site.feature index 3a03820079..989177cfd1 100644 --- a/features/site.feature +++ b/features/site.feature @@ -35,6 +35,25 @@ Feature: Manage sites in a multisite installation When I try the previous command again Then the return code should be 1 + Scenario: Filter site list + Given a WP multisite install + + When I run `wp site create --slug=first --porcelain` + Then STDOUT should be a number + And save STDOUT as {SITE_ID} + + When I run `wp site list --fields=blog_id,url` + Then STDOUT should be a table containing rows: + | blog_id | url | + | 1 | example.com/ | + | 2 | example.com/first/ | + + When I run `wp site list --field=url --blog_id=2` + Then STDOUT should be: + """ + example.com/first/ + """ + Scenario: Delete a site by slug Given a WP multisite install diff --git a/php/commands/site.php b/php/commands/site.php index 7f286e1677..a5992ce859 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -336,6 +336,9 @@ private function _get_network( $network_id ) { * [--network=<id>] * : The network to which the sites belong. * + * [--<field>=<value>] + * : Filter by one or more fields. + * * [--field=<field>] * : Prints the value of a single field for each site. * @@ -391,6 +394,14 @@ public function list_( $_, $assoc_args ) { $assoc_args = array_merge( $defaults, $assoc_args ); $where = array(); + + $site_cols = array( 'blog_id', 'url', 'last_updated', 'registered', 'site_id', 'domain', 'path', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' ); + foreach( $site_cols as $col ) { + if ( isset( $assoc_args[ $col ] ) ) { + $where[ $col ] = $assoc_args[ $col ]; + } + } + if ( isset( $assoc_args['network'] ) ) { $where['site_id'] = $assoc_args['network']; } From 59b123642117315196ed120c7c3f66c04a90dbad Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 14:29:32 -0700 Subject: [PATCH 3507/4858] Don't attempt to activate a child without a parent --- features/scaffold.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 346b0e08c4..4b4452db3b 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -6,7 +6,7 @@ Feature: WordPress code scaffolding Given I run `wp theme path` And save STDOUT as {THEME_DIR} - When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com --activate` + When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com` Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist From a221fa4d60a26aedeb7eb57f10264aed0fd434dc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 14:58:35 -0700 Subject: [PATCH 3508/4858] On multisite, run user creation through validation rules --- features/user.feature | 46 +++++++++++++++++++++++++++++++++++++++++++ php/commands/user.php | 45 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index 30890875a3..f35d936a92 100644 --- a/features/user.feature +++ b/features/user.feature @@ -167,6 +167,52 @@ Feature: Manage WordPress users }] """ + Scenario: Import new users on multisite + Given a WP multisite install + And a user-invalid.csv file: + """ + user_login,user_email,display_name,role + bob-jones,bobjones@example.com,Bob Jones,contributor + """ + And a user-valid.csv file: + """ + user_login,user_email,display_name,role + bobjones,bobjones@example.com,Bob Jones,contributor + """ + + When I try `wp user import-csv user-invalid.csv` + Then STDERR should contain: + """ + Warning: Only lowercase letters (a-z) and numbers are allowed. + """ + + When I run `wp user import-csv user-valid.csv` + Then STDOUT should not be empty + + When I run `wp user get bobjones --field=display_name` + Then STDOUT should be: + """ + Bob Jones + """ + + Scenario: Create new users on multisite + Given a WP multisite install + + When I try `wp user create bob-jones bobjones@example.com` + Then STDERR should contain: + """ + Warning: Only lowercase letters (a-z) and numbers are allowed. + """ + + When I run `wp user create bobjones bobjones@example.com --display_name="Bob Jones"` + Then STDOUT should not be empty + + When I run `wp user get bobjones --field=display_name` + Then STDOUT should be: + """ + Bob Jones + """ + Scenario: Import new users but don't update existing Given a WP install And a users.csv file: diff --git a/php/commands/user.php b/php/commands/user.php index d9597fca0a..c77f7085a6 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -286,7 +286,27 @@ public function create( $args, $assoc_args ) { } $user->role = $role; - $user_id = wp_insert_user( $user ); + if ( is_multisite() ) { + $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); + if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) { + WP_CLI::warning( $ret['errors'] ); + continue; + } + $user_id = wpmu_create_user( $user->user_login, $user->user_email, $user->user_login, $user->user_pass ); + if ( ! $user_id ) { + WP_CLI::warning( "Unknown error creating new user" ); + continue; + } + $user->ID = $user_id; + $user_id = wp_update_user( $user ); + if ( is_wp_error( $user_id ) ) { + WP_CLI::warning( $user_id ); + continue; + } + } else { + $user_id = wp_insert_user( $user ); + } + if ( isset( $assoc_args['send-email'] ) ) { wp_new_user_notification( $user_id, $user->user_pass ); } @@ -686,7 +706,28 @@ public function import_csv( $args, $assoc_args ) { // Create the user } else { unset( $new_user['ID'] ); // Unset else it will just return the ID - $user_id = wp_insert_user( $new_user ); + + if ( is_multisite() ) { + $ret = wpmu_validate_user_signup( $new_user['user_login'], $new_user['user_email'] ); + if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) { + WP_CLI::warning( $ret['errors'] ); + continue; + } + $user_id = wpmu_create_user( $new_user['user_login'], $new_user['user_email'], $new_user['user_pass'] ); + if ( ! $user_id ) { + WP_CLI::warning( "Unknown error creating new user" ); + continue; + } + $new_user['ID'] = $user_id; + $user_id = wp_update_user( $new_user ); + if ( is_wp_error( $user_id ) ) { + WP_CLI::warning( $user_id ); + continue; + } + } else { + $user_id = wp_insert_user( $new_user ); + } + if ( isset( $assoc_args['send-email'] ) ) { wp_new_user_notification( $user_id, $new_user['user_pass'] ); } From 02fca9a4131969b541b36f7a32cbcb15a740bff6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 15:02:15 -0700 Subject: [PATCH 3509/4858] Be more fault tolerant with timing in CI --- features/cron.feature | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index e8d0513db5..73b46d3931 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -4,16 +4,22 @@ Feature: Manage WP-Cron events and schedules Given a WP install Scenario: Scheduling and then deleting an event - When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 2 minutes' --apple=banana` + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 5 minutes' --apple=banana` Then STDOUT should contain: """ Success: Scheduled event with hook 'wp_cli_test_event_1' """ - When I run `wp cron event list --format=csv --fields=hook,recurrence,next_run_relative,args` + When I run `wp cron event list --format=csv --fields=hook,recurrence,args` Then STDOUT should be CSV containing: - | hook | recurrence | next_run_relative | args | - | wp_cli_test_event_1 | Non-repeating | 1 hour 1 minute | {"apple":"banana"} | + | hook | recurrence | args | + | wp_cli_test_event_1 | Non-repeating | {"apple":"banana"} | + + When I run `wp cron event list --fields=hook,next_run_relative | grep wp_cli_test_event_1` + Then STDOUT should contain: + """ + 1 hour + """ When I run `wp cron event delete wp_cli_test_event_1` Then STDOUT should contain: From ae4a6edb88512ab5cc26fb233b64e5b4180cf24f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 15:07:52 -0700 Subject: [PATCH 3510/4858] Rename `wp site not-spam` to `wp site unspam` --- features/site.feature | 2 +- php/commands/site.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/site.feature b/features/site.feature index 5b5767fda2..7edd3ec1b5 100644 --- a/features/site.feature +++ b/features/site.feature @@ -217,7 +217,7 @@ Feature: Manage sites in a multisite installation | blog_id | spam | | {FIRST_SITE} | 1 | - When I run `wp site not-spam {FIRST_SITE}` + When I run `wp site unspam {FIRST_SITE}` Then STDOUT should be: """ Success: Site {FIRST_SITE} removed from spam. diff --git a/php/commands/site.php b/php/commands/site.php index 075ca2ba55..189f95e65a 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -520,11 +520,11 @@ public function spam( $args ) { * * ## EXAMPLES * - * wp site not-spam 123 + * wp site unspam 123 * - * @subcommand not-spam + * @subcommand unspam */ - public function not_spam( $args ) { + public function unspam( $args ) { $this->update_site_status( $args, 'spam', 0 ); } From cff2b5d496989cc11f7e59859c19c21a98d16c3b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 15:08:42 -0700 Subject: [PATCH 3511/4858] Wrap actions in brackets --- php/commands/site.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 189f95e65a..376652f480 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -554,12 +554,12 @@ private function update_site_status( $ids, $pref, $value ) { $old_value = get_blog_status( $site->blog_id, $pref ); if ( $value == $old_value ) { - WP_CLI::warning( "Site {$site->blog_id} already $action." ); + WP_CLI::warning( "Site {$site->blog_id} already {$action}." ); continue; } update_blog_status( $site->blog_id, $pref, $value ); - WP_CLI::success( "Site {$site->blog_id} $action." ); + WP_CLI::success( "Site {$site->blog_id} {$action}." ); } } } From df5cf19d64e2f50e316acac61353127b2f608887 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 15:21:11 -0700 Subject: [PATCH 3512/4858] Helpful error message when user provides invalid version or locale --- features/core.feature | 9 +++++++++ php/commands/core.php | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 779b83501b..d733c63fd4 100644 --- a/features/core.feature +++ b/features/core.feature @@ -641,3 +641,12 @@ Feature: Manage WordPress installation """ 4.0 """ + + Scenario: Catch download of non-existent WP version + Given an empty directory + + When I try `wp core download --version=4.1.0 --force` + Then STDERR should contain: + """ + Error: Release not found. + """ diff --git a/php/commands/core.php b/php/commands/core.php index c79c9ed5af..b95b729b5f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -172,7 +172,12 @@ public function download( $args, $assoc_args ) { 'filename' => $temp ); - Utils\http_request( 'GET', $download_url, null, $headers, $options ); + $response = Utils\http_request( 'GET', $download_url, null, $headers, $options ); + if ( 404 == $response->status_code ) { + WP_CLI::error( "Release not found. Double-check locale or version." ); + } else if ( 20 != substr( $response->status_code, 0, 2 ) ) { + WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})" ); + } self::_extract( $temp, ABSPATH ); $cache->import( $cache_key, $temp ); unlink($temp); From 5b3dda9463ece12690f3c50a9d8cd4d7d356cff1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 17:40:12 -0700 Subject: [PATCH 3513/4858] Hard error, because it's not looped --- php/commands/user.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index c77f7085a6..11aa5829d1 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -289,19 +289,16 @@ public function create( $args, $assoc_args ) { if ( is_multisite() ) { $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) { - WP_CLI::warning( $ret['errors'] ); - continue; + WP_CLI::error( $ret['errors'] ); } $user_id = wpmu_create_user( $user->user_login, $user->user_email, $user->user_login, $user->user_pass ); if ( ! $user_id ) { - WP_CLI::warning( "Unknown error creating new user" ); - continue; + WP_CLI::error( "Unknown error creating new user" ); } $user->ID = $user_id; $user_id = wp_update_user( $user ); if ( is_wp_error( $user_id ) ) { - WP_CLI::warning( $user_id ); - continue; + WP_CLI::error( $user_id ); } } else { $user_id = wp_insert_user( $user ); From a09fbc98f221ea2da1c517dfea2ae8c2fd25df4f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 17:42:50 -0700 Subject: [PATCH 3514/4858] Update tests for multisite --- features/user.feature | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/features/user.feature b/features/user.feature index f35d936a92..d65b246d71 100644 --- a/features/user.feature +++ b/features/user.feature @@ -67,20 +67,20 @@ Feature: Manage WordPress users Scenario: Reassigning user posts Given a WP multisite install - When I run `wp user create bob bob@example.com --role=author --porcelain` + When I run `wp user create bobjones bob@example.com --role=author --porcelain` And save STDOUT as {BOB_ID} And I run `wp user create sally sally@example.com --role=editor --porcelain` And save STDOUT as {SALLY_ID} - When I run `wp post generate --count=3 --post_author=bob` + When I run `wp post generate --count=3 --post_author=bobjones` And I run `wp post list --author={BOB_ID} --format=count` Then STDOUT should be: """ 3 """ - When I run `wp user delete bob --reassign={SALLY_ID}` + When I run `wp user delete bobjones --reassign={SALLY_ID}` And I run `wp post list --author={SALLY_ID} --format=count` Then STDOUT should be: """ @@ -90,16 +90,16 @@ Feature: Manage WordPress users Scenario: Deleting user from the whole network Given a WP multisite install - When I run `wp user create bob bob@example.com --role=author --porcelain` + When I run `wp user create bobjones bob@example.com --role=author --porcelain` And save STDOUT as {BOB_ID} - When I run `wp user get bob` + When I run `wp user get bobjones` Then STDOUT should not be empty - When I run `wp user delete bob --network --yes` + When I run `wp user delete bobjones --network --yes` Then STDOUT should not be empty - When I try `wp user get bob` + When I try `wp user get bobjones` Then STDERR should not be empty Scenario: Generating and deleting users @@ -201,7 +201,7 @@ Feature: Manage WordPress users When I try `wp user create bob-jones bobjones@example.com` Then STDERR should contain: """ - Warning: Only lowercase letters (a-z) and numbers are allowed. + Error: Only lowercase letters (a-z) and numbers are allowed. """ When I run `wp user create bobjones bobjones@example.com --display_name="Bob Jones"` From b9f82017af69fd146d7be4def86cce27166e7932 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 19 Apr 2015 18:08:14 -0700 Subject: [PATCH 3515/4858] Fix indentation --- php/commands/user.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 11aa5829d1..e9b326e4d0 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -298,7 +298,7 @@ public function create( $args, $assoc_args ) { $user->ID = $user_id; $user_id = wp_update_user( $user ); if ( is_wp_error( $user_id ) ) { - WP_CLI::error( $user_id ); + WP_CLI::error( $user_id ); } } else { $user_id = wp_insert_user( $user ); @@ -718,8 +718,8 @@ public function import_csv( $args, $assoc_args ) { $new_user['ID'] = $user_id; $user_id = wp_update_user( $new_user ); if ( is_wp_error( $user_id ) ) { - WP_CLI::warning( $user_id ); - continue; + WP_CLI::warning( $user_id ); + continue; } } else { $user_id = wp_insert_user( $new_user ); From 3b4cc5fac86b29b7d212b19b94d7cead61ec6b4f Mon Sep 17 00:00:00 2001 From: yivi <ivan@ojiva.es> Date: Mon, 20 Apr 2015 13:00:13 +0200 Subject: [PATCH 3516/4858] removed .idea files --- .idea/php.xml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .idea/php.xml diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index b06e40b214..0000000000 --- a/.idea/php.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="Behat"> - <behat_settings> - <BehatSettings behat_path="$PROJECT_DIR$/vendor/behat/behat/bin/behat" /> - </behat_settings> - </component> - <component name="PhpProjectSharedConfiguration" php_language_level="5.5.0" /> -</project> - From 976cf9134fd62693e595294f89366f2b43a50d95 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 20 Apr 2015 17:03:30 -0700 Subject: [PATCH 3517/4858] Bail early if there's no `file` set We need it to continue with the operation --- php/commands/media.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/media.php b/php/commands/media.php index 9f73deca5a..901b1e0a24 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -234,6 +234,10 @@ private function remove_old_images( $att_id ) { $metadata = wp_get_attachment_metadata( $att_id ); + if ( empty( $metadata['file'] ) ) { + return; + } + $dir_path = $wud['basedir'] . '/' . dirname( $metadata['file'] ) . '/'; $original_path = $dir_path . basename( $metadata['file'] ); From 31f1f0e023754adedab460ca5afbee3ff7a8126c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Apr 2015 10:31:55 -0700 Subject: [PATCH 3518/4858] Increase max PHP tested version for plugins to 5.5 --- templates/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 64be0af086..8b561acd35 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -2,7 +2,7 @@ language: php php: - 5.3 - - 5.4 + - 5.5 env: - WP_VERSION=latest WP_MULTISITE=0 From 7f273e6711f525ed77678008eb7223db8c600568 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Apr 2015 10:41:52 -0700 Subject: [PATCH 3519/4858] Use plugin slug in plugin's packages.json `npm install` fails on the name --- templates/plugin-packages.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/plugin-packages.mustache b/templates/plugin-packages.mustache index ef736af278..657df46087 100644 --- a/templates/plugin-packages.mustache +++ b/templates/plugin-packages.mustache @@ -1,6 +1,6 @@ { - "name": "{{plugin_name}}", + "name": "{{plugin_slug}}", "version": "0.0.0", "main": "Gruntfile.js", "author": "YOUR NAME HERE", From e73d44ad14cbcbfed6e672487c8f34eb92eb2b39 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Apr 2015 10:44:29 -0700 Subject: [PATCH 3520/4858] Scaffolded unit tests should follow coding standards --- templates/bootstrap.mustache | 8 +++++--- templates/test-sample.php | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index c18a7fe3ee..e2802af053 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -1,12 +1,14 @@ <?php -$_tests_dir = getenv('WP_TESTS_DIR'); -if ( !$_tests_dir ) $_tests_dir = '/tmp/wordpress-tests-lib'; +$_tests_dir = getenv( 'WP_TESTS_DIR' ); +if ( ! $_tests_dir ) { + $_tests_dir = '/tmp/wordpress-tests-lib'; +} require_once $_tests_dir . '/includes/functions.php'; function _manually_load_plugin() { - require dirname( __FILE__ ) . '/../{{plugin_slug}}.php'; + require dirname( __FILE__ ) . '/../.php'; } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); diff --git a/templates/test-sample.php b/templates/test-sample.php index 1a23460d39..79ba8f9a2e 100644 --- a/templates/test-sample.php +++ b/templates/test-sample.php @@ -2,7 +2,7 @@ class SampleTest extends WP_UnitTestCase { - function testSample() { + function test_sample() { // replace this with some actual testing code $this->assertTrue( true ); } From 04c7b00445b5c1045199ecc744d453f96dd866c8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Apr 2015 12:07:53 -0700 Subject: [PATCH 3521/4858] Update tested WordPress versions to reflect new stable --- features/core.feature | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/features/core.feature b/features/core.feature index d733c63fd4..046eca25d8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,10 +326,10 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.1.1 | major | https://wordpress.org/wordpress-4.1.1.zip | - | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | - | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | - | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | + | 4.1.2 | major | https://wordpress.org/wordpress-4.1.2.zip | + | 4.0.2 | major | https://wordpress.org/wordpress-4.0.2.zip | + | 3.9.4 | major | https://wordpress.org/wordpress-3.9.4.zip | + | 3.8.6 | minor | https://wordpress.org/wordpress-3.8.6.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -340,9 +340,9 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.1.1 | major | https://wordpress.org/wordpress-4.1.1.zip | - | 4.0.1 | major | https://wordpress.org/wordpress-4.0.1.zip | - | 3.9.3 | major | https://wordpress.org/wordpress-3.9.3.zip | + | 4.1.2 | major | https://wordpress.org/wordpress-4.1.2.zip | + | 4.0.2 | major | https://wordpress.org/wordpress-4.0.2.zip | + | 3.9.4 | major | https://wordpress.org/wordpress-3.9.4.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -353,7 +353,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.5 | minor | https://wordpress.org/wordpress-3.8.5.zip | + | 3.8.6 | minor | https://wordpress.org/wordpress-3.8.6.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From 2e84fa50f985e55670567eaecaf289d5f806c560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Tue, 21 Apr 2015 17:52:00 -0400 Subject: [PATCH 3522/4858] Change `\WP_CLI\Utils\check_flag` function name and operation `\WP_CLI\Utils\check_flag` -> `\WP_CLI\Utils\get_flag_value` The operation was changed to fit in other cases. --- php/WP_CLI/CommandWithDBObject.php | 2 +- php/WP_CLI/CommandWithTranslation.php | 4 ++-- php/WP_CLI/CommandWithUpgrade.php | 12 ++++++------ php/class-wp-cli.php | 6 +++--- php/commands/cli.php | 10 +++++----- php/commands/comment.php | 2 +- php/commands/core.php | 20 ++++++++++---------- php/commands/media.php | 6 +++--- php/commands/menu.php | 2 +- php/commands/option.php | 6 +++--- php/commands/plugin.php | 18 +++++++++--------- php/commands/post.php | 4 ++-- php/commands/rewrite.php | 6 +++--- php/commands/role.php | 4 ++-- php/commands/scaffold.php | 16 ++++++++-------- php/commands/search-replace.php | 12 ++++++------ php/commands/shell.php | 2 +- php/commands/site.php | 6 +++--- php/commands/term.php | 2 +- php/commands/theme.php | 14 +++++++------- php/commands/user.php | 12 ++++++------ php/utils.php | 16 ++++++++-------- 22 files changed, 91 insertions(+), 91 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index dcd2be9b41..ef32e35864 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -41,7 +41,7 @@ protected function _create( $args, $assoc_args, $callback ) { \WP_CLI::error( $obj_id ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) \WP_CLI::line( $obj_id ); else \WP_CLI::success( "Created $this->obj_type $obj_id." ); diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index c78b326c4a..b46ed12747 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -133,7 +133,7 @@ public function install( $args, $assoc_args ) { if ( $response == $language_code ) { \WP_CLI::success( "Language installed." ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { $this->activate( array( $language_code ), array() ); } } else { @@ -199,7 +199,7 @@ public function update( $args, $assoc_args ) { } // Only preview which translations would be updated. - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'dry-run' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run' ) ) { \WP_CLI::line( sprintf( 'Available %d translations updates:', count( $updates ) ) ); \WP_CLI\Utils\format_items( 'table', $updates, array( 'Type', 'Name', 'Version', 'Language' ) ); diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 0b3c592ceb..ed1d7214bf 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -150,12 +150,12 @@ function install( $args, $assoc_args ) { } if ( $result ) { - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate-network' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate-network' ) ) { \WP_CLI::log( "Network-activating '$slug'..." ); $this->activate( array( $slug ), array( 'network' => true ) ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { \WP_CLI::log( "Activating '$slug'..." ); $this->activate( array( $slug ) ); } @@ -203,20 +203,20 @@ protected static function alter_api_response( $response, $version ) { } protected function get_upgrader( $assoc_args ) { - $upgrader_class = $this->get_upgrader_class( \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ); + $upgrader_class = $this->get_upgrader_class( \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ); return \WP_CLI\Utils\get_upgrader( $upgrader_class ); } protected function update_many( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { \WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." ); } $items = $this->get_item_list(); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { $items = $this->filter_item_list( $items, $args ); } @@ -224,7 +224,7 @@ protected function update_many( $args, $assoc_args ) { 'update' => true ) ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'dry-run' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run' ) ) { if ( empty( $items_to_update ) ) { \WP_CLI::line( "No {$this->item_type} updates available." ); return; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0dd7345d87..2dcd966806 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -276,7 +276,7 @@ public static function error_multi_line( $message_lines ) { * Ask for confirmation before running a destructive operation. */ public static function confirm( $question, $assoc_args = array() ) { - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'yes' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'yes' ) ) { fwrite( STDOUT, $question . " [y/n] " ); $answer = trim( fgets( STDIN ) ); @@ -316,7 +316,7 @@ public static function get_value_from_arg_or_stdin( $args, $index ) { * @param array $assoc_args */ public static function read_value( $raw_value, $assoc_args = array() ) { - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'json' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { $value = json_decode( $raw_value, true ); if ( null === $value ) { WP_CLI::error( sprintf( 'Invalid JSON: %s', $raw_value ) ); @@ -335,7 +335,7 @@ public static function read_value( $raw_value, $assoc_args = array() ) { * @param array $assoc_args */ public static function print_value( $value, $assoc_args = array() ) { - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'json' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { $value = json_encode( $value ); } elseif ( is_array( $value ) || is_object( $value ) ) { $value = var_export( $value ); diff --git a/php/commands/cli.php b/php/commands/cli.php index e1355bdf54..5553335a03 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -48,7 +48,7 @@ public function info( $_, $assoc_args ) { $runner = WP_CLI::get_runner(); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'json' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { $info = array( 'php_binary_path' => $php_bin, 'global_config_path' => $runner->global_config_path, @@ -237,10 +237,10 @@ private function get_updates( $assoc_args ) { $update_type = 'patch'; } - if ( ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'patch' ) && 'patch' !== $update_type ) - && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'patch', false ) && 'patch' === $update_type ) - && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'minor' ) && 'minor' !== $update_type ) - && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'minor', false ) && 'minor' === $update_type ) + if ( ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'patch' ) && 'patch' !== $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'patch' ) === false && 'patch' === $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) && 'minor' !== $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) === false && 'minor' === $update_type ) && ! $this->same_minor_release( $release_parts, $updates ) ) { $updates[] = array( diff --git a/php/commands/comment.php b/php/commands/comment.php index 824f974a50..2aac405a48 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -209,7 +209,7 @@ public function list_( $_, $assoc_args ) { */ public function delete( $args, $assoc_args ) { parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { - $r = wp_delete_comment( $comment_id, \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ); + $r = wp_delete_comment( $comment_id, \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ); if ( $r ) { return array( 'success', "Deleted comment $comment_id." ); diff --git a/php/commands/core.php b/php/commands/core.php index ae7c9ea7fc..43a040c22b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -73,8 +73,8 @@ function check_update( $_, $assoc_args ) { $update_type = 'minor'; } - if ( ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'minor' ) && 'minor' !== $update_type ) - && ! ( \WP_CLI\Utils\check_flag( $assoc_args, 'major' ) && 'major' !== $update_type ) + if ( ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) && 'minor' !== $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'major' ) && 'major' !== $update_type ) ) { $updates = $this->remove_same_minor_releases( $release_parts, $updates ); $updates[] = array( @@ -121,7 +121,7 @@ function check_update( $_, $assoc_args ) { * @when before_wp_load */ public function download( $args, $assoc_args ) { - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) && is_readable( ABSPATH . 'wp-load.php' ) ) + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && is_readable( ABSPATH . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); if ( !is_dir( ABSPATH ) ) { @@ -341,7 +341,7 @@ public function config( $_, $assoc_args ) { WP_CLI::error( '--dbprefix can only contain numbers, letters, and underscores.' ); // Check DB connection - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-check' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-check' ) ) { Utils\run_mysql_command( 'mysql --no-defaults', array( 'execute' => ';', 'host' => $assoc_args['dbhost'], @@ -350,12 +350,12 @@ public function config( $_, $assoc_args ) { ) ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'extra-php' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra-php' ) ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); } // TODO: adapt more resilient code from wp-admin/setup-config.php - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-salts' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-salts' ) ) { $assoc_args['keys-and-salts'] = self::_read( 'https://api.wordpress.org/secret-key/1.1/salt/' ); } @@ -392,7 +392,7 @@ public function config( $_, $assoc_args ) { */ public function is_installed( $_, $assoc_args ) { - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ) { if ( is_blog_installed() && is_multisite() ) { exit( 0 ); } else { @@ -740,7 +740,7 @@ public function version( $args = array(), $assoc_args = array() ) { include $versions_path; // @codingStandardsIgnoreStart - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'extra' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra' ) ) { if ( preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ) ) { $human_readable_tiny_mce = $match[1] . '.' . $match[2]; } else { @@ -903,7 +903,7 @@ function update( $args, $assoc_args ) { } } else if ( version_compare( $wp_version, $assoc_args['version'], '<' ) - || \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ) { + || \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) { $version = $assoc_args['version']; $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : get_locale(); @@ -926,7 +926,7 @@ function update( $args, $assoc_args ) { } - if ( ! empty( $update ) && ( $update->version != $wp_version || \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) ) ) { + if ( ! empty( $update ) && ( $update->version != $wp_version || \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); diff --git a/php/commands/media.php b/php/commands/media.php index 5228ff2a69..a3e856c19b 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -162,18 +162,18 @@ function import( $args, $assoc_args = array() ) { } // Set as featured image, if --post_id and --featured_image are set - if ( $assoc_args['post_id'] && \WP_CLI\Utils\check_flag( $assoc_args, 'featured_image' ) ) { + if ( $assoc_args['post_id'] && \WP_CLI\Utils\get_flag_value( $assoc_args, 'featured_image' ) ) { update_post_meta( $assoc_args['post_id'], '_thumbnail_id', $success ); } $attachment_success_text = ''; if ( $assoc_args['post_id'] ) { $attachment_success_text = " and attached to post {$assoc_args['post_id']}"; - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'featured_image' ) ) + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'featured_image' ) ) $attachment_success_text .= ' as featured image'; } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $success ); } else { WP_CLI::success( sprintf( diff --git a/php/commands/menu.php b/php/commands/menu.php index afab17d3e7..e214711041 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -51,7 +51,7 @@ public function create( $args, $assoc_args ) { } else { - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $menu_id ); } else { WP_CLI::success( "Created menu $menu_id." ); diff --git a/php/commands/option.php b/php/commands/option.php index 142847ab1e..ff6cadc63e 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -64,7 +64,7 @@ public function add( $args, $assoc_args ) { $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); $value = WP_CLI::read_value( $value, $assoc_args ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'autoload', 'no' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'autoload' ) === 'no' ) { $autoload = 'no'; } else { $autoload = 'yes'; @@ -139,7 +139,7 @@ public function list_( $args, $assoc_args ) { $fields = explode( ',', $assoc_args['fields'] ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'total_bytes' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'total_bytes' ) { $fields = array( 'size_bytes' ); $size_query = ",SUM(LENGTH(option_value)) AS `size_bytes`"; } @@ -162,7 +162,7 @@ public function list_( $args, $assoc_args ) { ) ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'format', 'total_bytes' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'total_bytes' ) { WP_CLI::line( $results[0]->size_bytes ); } else { $formatter = new \WP_CLI\Formatter( diff --git a/php/commands/plugin.php b/php/commands/plugin.php index bafdb8ad23..ebf37da0a2 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -153,9 +153,9 @@ protected function get_all_items() { * : If set, the plugin will be activated for the entire multisite network. */ function activate( $args, $assoc_args = array() ) { - $network_wide = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ); + $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { $args = array_map( function( $file ){ return Utils\get_plugin_name( $file ); }, array_keys( get_plugins() ) ); @@ -201,8 +201,8 @@ function activate( $args, $assoc_args = array() ) { * : If set, the plugin will be deactivated for the entire multisite network. */ function deactivate( $args, $assoc_args = array() ) { - $network_wide = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ); - $disable_all = \WP_CLI\Utils\check_flag( $assoc_args, 'all' ); + $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); + $disable_all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ); if ( $disable_all ) { $args = array_map( function( $file ){ @@ -242,7 +242,7 @@ function deactivate( $args, $assoc_args = array() ) { * : If set, the plugin will be toggled for the entire multisite network. */ function toggle( $args, $assoc_args = array() ) { - $network_wide = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ); + $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { if ( $this->check_active( $plugin->file, $network_wide ) ) { @@ -277,7 +277,7 @@ function path( $args, $assoc_args ) { $plugin = $this->fetcher->get_check( $args[0] ); $path .= '/' . $plugin->file; - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'dir' ) ) + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dir' ) ) $path = dirname( $path ); } @@ -297,13 +297,13 @@ protected function install_from_repo( $slug, $assoc_args ) { $status = install_plugin_install_status( $api ); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) && 'install' != $status['status'] ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && 'install' != $status['status'] ) { // We know this will fail, so avoid a needless download of the package. return new WP_Error( 'already_installed', 'Plugin already installed.' ); } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'version', 'dev' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) === 'dev' ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); @@ -503,7 +503,7 @@ function uninstall( $args, $assoc_args = array() ) { uninstall_plugin( $plugin->file ); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-delete' ) && $this->_delete( $plugin ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-delete' ) && $this->_delete( $plugin ) ) { WP_CLI::success( "Uninstalled and deleted '$plugin->name' plugin." ); } else { WP_CLI::success( "Ran uninstall procedure for '$plugin->name' plugin without deleting." ); diff --git a/php/commands/post.php b/php/commands/post.php index f4e286c28d..7a149bcd52 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -55,7 +55,7 @@ public function create( $args, $assoc_args ) { $assoc_args['post_content'] = $this->read_from_file_or_stdin( $args[0] ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'edit' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'edit' ) ) { $input = isset( $assoc_args['post_content'] ) ? $assoc_args['post_content'] : ''; @@ -361,7 +361,7 @@ public function generate( $args, $assoc_args ) { $post_author = $user_fetcher->get_check( $post_author )->ID; } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'post_content' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'post_content' ) ) { $post_content = file_get_contents( 'php://stdin' ); } diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index bea5dfd5fd..f7df4ff5a0 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -28,10 +28,10 @@ class Rewrite_Command extends WP_CLI_Command { public function flush( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config self::apache_modules(); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'hard' ) && ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) && ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); } - flush_rewrite_rules( \WP_CLI\Utils\check_flag( $assoc_args, 'hard' ) ); + flush_rewrite_rules( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) ); if ( ! get_option( 'rewrite_rules' ) ) { WP_CLI::warning( "Rewrite rules are empty, possibly because of a missing permalink_structure option. Use 'wp rewrite list' to verify, or 'wp rewrite structure' to update permalink_structure." ); } @@ -115,7 +115,7 @@ public function structure( $args, $assoc_args ) { // Launch a new process to flush rewrites because core expects flush // to happen after rewrites are set $new_assoc_args = array(); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'hard' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) ) { $new_assoc_args['hard'] = true; if ( ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); diff --git a/php/commands/role.php b/php/commands/role.php index b12ed8ad09..436fb689a4 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -169,7 +169,7 @@ public function reset( $args, $assoc_args ) { self::persistence_check(); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) WP_CLI::error( "Role key not provided, or is invalid." ); if ( ! function_exists( 'populate_roles' ) ) { @@ -179,7 +179,7 @@ public function reset( $args, $assoc_args ) { // get our default roles $default_roles = $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { foreach( $default_roles as $role ) { remove_role( $role ); } diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 85ffba8ff4..a6d6a4e837 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -211,7 +211,7 @@ function _s( $args, $assoc_args ) { $body['underscoresme_description'] = $theme_description; $body['underscoresme_generate_submit'] = "Generate"; $body['underscoresme_generate'] = "1"; - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'sassify' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'sassify' ) ) { $body['underscoresme_sass'] = 1; } @@ -244,9 +244,9 @@ function _s( $args, $assoc_args ) { WP_CLI::error( "Could not decompress your theme files ('{$tmpfname}') at '{$theme_path}': {$unzip_result->get_error_message()}" ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } else if ( \WP_CLI\Utils\check_flag( $assoc_args, 'enable-network' ) ) { + } else if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'enable-network' ) ) { WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); } } @@ -305,9 +305,9 @@ function child_theme( $args, $assoc_args ) { WP_CLI::success( "Created $theme_dir" ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); - } else if ( \WP_CLI\Utils\check_flag( $assoc_args, 'enable-network' ) ) { + } else if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'enable-network' ) ) { WP_CLI::run_command( array( 'theme', 'enable', $theme_slug ), array( 'network' => true ) ); } } @@ -477,13 +477,13 @@ function plugin( $args, $assoc_args ) { WP_CLI::success( "Created $plugin_dir" ); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'skip-tests' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-tests' ) ) { WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ), array( 'dir' => $plugin_dir ) ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug ) ); - } else if ( \WP_CLI\Utils\check_flag( $assoc_args, 'activate-network' ) ) { + } else if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate-network' ) ) { WP_CLI::run_command( array( 'plugin', 'activate', $plugin_slug), array( 'network' => true ) ); } } diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 195cb0a7ac..6307674397 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -64,9 +64,9 @@ public function __invoke( $args, $assoc_args ) { $new = array_shift( $args ); $total = 0; $report = array(); - $dry_run = \WP_CLI\Utils\check_flag( $assoc_args, 'dry-run' ); - $php_only = \WP_CLI\Utils\check_flag( $assoc_args, 'precise' ); - $recurse_objects = \WP_CLI\Utils\check_flag( $assoc_args, 'recurse-objects' ); + $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' ); if ( isset( $assoc_args['skip-columns'] ) ) { $skip_columns = explode( ',', $assoc_args['skip-columns'] ); @@ -79,13 +79,13 @@ public function __invoke( $args, $assoc_args ) { // Determine how to limit the list of tables. Defaults to 'wordpress' $table_type = 'wordpress'; - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ) { $table_type = 'network'; } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all-tables-with-prefix' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all-tables-with-prefix' ) ) { $table_type = 'all-tables-with-prefix'; } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all-tables' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all-tables' ) ) { $table_type = 'all-tables'; } diff --git a/php/commands/shell.php b/php/commands/shell.php index d805a2d8ed..0bb052ff57 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -21,7 +21,7 @@ public function __invoke( $_, $assoc_args ) { '\\WP_CLI\\REPL', ); - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'basic' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'basic' ) ) { $class = '\\WP_CLI\\REPL'; } else { foreach ( $implementations as $candidate ) { diff --git a/php/commands/site.php b/php/commands/site.php index e42e9c5777..545f33b9c7 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -178,7 +178,7 @@ function delete( $args, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl site?", $assoc_args ); - wpmu_delete_blog( $blog->blog_id, ! \WP_CLI\Utils\check_flag( $assoc_args, 'keep-tables' ) ); + wpmu_delete_blog( $blog->blog_id, ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'keep-tables' ) ); WP_CLI::success( "The site at $blog->siteurl was deleted." ); } @@ -231,7 +231,7 @@ public function create( $_, $assoc_args ) { $network = $current_site; } - $public = ! \WP_CLI\Utils\check_flag( $assoc_args, 'private' ); + $public = ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'private' ); // Sanitize if ( preg_match( '|^([a-zA-Z0-9-])+$|', $base ) ) { @@ -301,7 +301,7 @@ public function create( $_, $assoc_args ) { WP_CLI::error( $id->get_error_message() ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) WP_CLI::line( $id ); else WP_CLI::success( "Site $id created: $url" ); diff --git a/php/commands/term.php b/php/commands/term.php index 46a005e636..31cedcec9c 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -114,7 +114,7 @@ public function create( $args, $assoc_args ) { ); $assoc_args = wp_parse_args( $assoc_args, $defaults ); - $porcelain = \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ); + $porcelain = \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ); unset( $assoc_args['porcelain'] ); // Compatibility for < WP 4.0 diff --git a/php/commands/theme.php b/php/commands/theme.php index 4ef1ced63d..b074d5e6eb 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -260,7 +260,7 @@ public function path( $args, $assoc_args ) { $path = $theme->get_stylesheet_directory(); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'dir' ) ) + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'dir' ) ) $path .= '/style.css'; } @@ -278,13 +278,13 @@ protected function install_from_repo( $slug, $assoc_args ) { self::alter_api_response( $api, $assoc_args['version'] ); } - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'force' ) && wp_get_theme( $slug )->exists() ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && wp_get_theme( $slug )->exists() ) { // We know this will fail, so avoid a needless download of the package. return new WP_Error( 'already_installed', 'Theme already installed.' ); } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'version', 'dev' ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) === 'dev' ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); @@ -597,11 +597,11 @@ class Theme_Mod_command extends WP_CLI_Command { */ public function get( $args = array(), $assoc_args = array() ) { - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { WP_CLI::error( "You must specify at least one mod or use --all." ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { $args = array(); } @@ -657,11 +657,11 @@ public function get( $args = array(), $assoc_args = array() ) { */ public function remove( $args = array(), $assoc_args = array() ) { - if ( ! \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) && empty( $args ) ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { WP_CLI::error( "You must specify at least one mod or use --all." ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'all' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { remove_theme_mods(); WP_CLI::success( 'Theme mods removed.' ); return; diff --git a/php/commands/user.php b/php/commands/user.php index 9d1ecb8d0a..d4fdd39fb2 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -81,7 +81,7 @@ public function __construct() { */ public function list_( $args, $assoc_args ) { - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ) { if ( ! is_multisite() ) { WP_CLI::error( 'This is not a multisite install.' ); } @@ -175,7 +175,7 @@ public function get( $args, $assoc_args ) { * wp user delete 123 --reassign=567 */ public function delete( $args, $assoc_args ) { - $network = \WP_CLI\Utils\check_flag( $assoc_args, 'network' ) && is_multisite(); + $network = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) && is_multisite(); $reassign = isset( $assoc_args['reassign'] ) ? $assoc_args['reassign'] : null; if ( $network && $reassign ) { @@ -304,7 +304,7 @@ public function create( $args, $assoc_args ) { $user_id = wp_insert_user( $user ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'send-email' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'send-email' ) ) { wp_new_user_notification( $user_id, $user->user_pass ); } @@ -317,7 +317,7 @@ public function create( $args, $assoc_args ) { } } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'porcelain' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $user_id ); } else { WP_CLI::success( "Created user $user_id." ); @@ -685,7 +685,7 @@ public function import_csv( $args, $assoc_args ) { $existing_user = get_user_by( 'login', $new_user['user_login'] ); } - if ( $existing_user && \WP_CLI\Utils\check_flag( $assoc_args, 'skip-update' ) ) { + if ( $existing_user && \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-update' ) ) { WP_CLI::log( "{$existing_user->user_login} exists and has been skipped" ); continue; @@ -725,7 +725,7 @@ public function import_csv( $args, $assoc_args ) { $user_id = wp_insert_user( $new_user ); } - if ( \WP_CLI\Utils\check_flag( $assoc_args, 'send-email' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'send-email' ) ) { wp_new_user_notification( $user_id, $new_user['user_pass'] ); } } diff --git a/php/utils.php b/php/utils.php index 45b36ee99d..21bad5bb97 100644 --- a/php/utils.php +++ b/php/utils.php @@ -506,13 +506,13 @@ function increment_version( $current_version, $new_version ) { } /** - * Check if the flag is set and has the expected value. + * Return the flag value or, if it's not set, the $default value. * - * @param array $args The arguments array to check. - * @param string $flag The flag to check for. - * @param mixed $expected The expected value for the flag. Default: TRUE - * @return bool + * @param array $args Arguments array. + * @param string $flag Flag to get the value. + * @param mixed $default Default value for the flag. Default: NULL + * @return mixed */ -function check_flag( $args, $flag, $expected = true ) { - return isset( $args[ $flag ] ) && ( $args[ $flag ] === $expected ); -} +function get_flag_value( $args, $flag, $default = null ) { + return isset( $args[ $flag ] ) ? $args[ $flag ] : $default; +} \ No newline at end of file From 47d3f61911e5ad890149accc7d9bf366f46782b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Tue, 21 Apr 2015 19:26:41 -0400 Subject: [PATCH 3523/4858] Refactor additional entries to use the `\WP_CLI\Utils\get_flag_value` function --- php/Spyc.php | 2 +- php/WP_CLI/CommandWithUpgrade.php | 2 +- php/class-wp-cli.php | 19 ++++++++---------- php/commands/cache.php | 24 +++++++++++------------ php/commands/comment.php | 2 +- php/commands/core.php | 6 +++--- php/commands/cron.php | 6 +++--- php/commands/db.php | 2 +- php/commands/menu.php | 10 ++++------ php/commands/post.php | 3 +-- php/commands/scaffold.php | 4 +--- php/commands/search-replace.php | 6 +----- php/commands/site.php | 2 +- php/commands/transient.php | 2 +- php/commands/user.php | 29 ++++++++++++---------------- php/commands/widget.php | 2 +- php/export/class-wp-export-query.php | 2 +- 17 files changed, 53 insertions(+), 70 deletions(-) diff --git a/php/Spyc.php b/php/Spyc.php index 4227b3ed96..7a0c282846 100644 --- a/php/Spyc.php +++ b/php/Spyc.php @@ -755,7 +755,7 @@ private function addArray ($incoming_data, $incoming_indent) { return $this->addArrayInline ($incoming_data, $incoming_indent); $key = key ($incoming_data); - $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; + $value = \WP_CLI\Utils\get_flag_value( $incoming_data, $key ); if ($key === '__!YAMLZero') $key = '0'; if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index ed1d7214bf..ee113cfa0b 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -394,7 +394,7 @@ protected function _search( $args, $assoc_args ) { $items = $api->$plural; - $count = isset( $api->info['results'] ) ? $api->info['results'] : 'unknown'; + $count = \WP_CLI\Utils\get_flag_value( $api->info, 'results', 'unknown' ); \WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) ); $formatter->display_items( $items ); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 2dcd966806..e721c63275 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -99,7 +99,7 @@ public static function set_url( $url ) { private static function set_url_params( $url_parts ) { $f = function( $key ) use ( $url_parts ) { - return isset( $url_parts[ $key ] ) ? $url_parts[ $key ] : ''; + return \WP_CLI\Utils\get_flag_value( $url_parts, $key, '' ); }; if ( isset( $url_parts['host'] ) ) { @@ -116,7 +116,7 @@ private static function set_url_params( $url_parts ) { } $_SERVER['REQUEST_URI'] = $f('path') . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' ); - $_SERVER['SERVER_PORT'] = isset( $url_parts['port'] ) ? $url_parts['port'] : '80'; + $_SERVER['SERVER_PORT'] = \WP_CLI\Utils\get_flag_value( $url_parts, 'port', '80' ); $_SERVER['QUERY_STRING'] = $f('query'); } @@ -295,15 +295,12 @@ public static function confirm( $question, $assoc_args = array() ) { * @return string */ public static function get_value_from_arg_or_stdin( $args, $index ) { - if ( isset( $args[ $index ] ) ) { - $raw_value = $args[ $index ]; - } else { - // We don't use file_get_contents() here because it doesn't handle - // Ctrl-D properly, when typing in the value interactively. - $raw_value = ''; - while ( ( $line = fgets( STDIN ) ) !== false ) { - $raw_value .= $line; - } + $raw_value = \WP_CLI\Utils\get_flag_value( $args, $index, '' ); + + // We don't use file_get_contents() here because it doesn't handle + // Ctrl-D properly, when typing in the value interactively. + while ( ( $line = fgets( STDIN ) ) !== false ) { + $raw_value .= $line; } return $raw_value; diff --git a/php/commands/cache.php b/php/commands/cache.php index 0c9274811b..c78ce1ce4f 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -19,9 +19,9 @@ class Cache_Command extends WP_CLI_Command { public function add( $args, $assoc_args ) { list( $key, $value ) = $args; - $group = ( isset( $args[2] ) ) ? $args[2] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 2, '' ); - $expiration = ( isset( $args[3] ) ) ? $args[3] : 0; + $expiration = \WP_CLI\Utils\get_flag_value( $args, 3, 0 ); if ( ! wp_cache_add( $key, $value, $group, $expiration ) ) { WP_CLI::error( "Could not add object '$key' in group '$group'. Does it already exist?" ); @@ -38,9 +38,9 @@ public function add( $args, $assoc_args ) { public function decr( $args, $assoc_args ) { $key = $args[0]; - $offset = ( isset( $args[1] ) ) ? $args[1] : 1; + $offset = \WP_CLI\Utils\get_flag_value( $args, 1, 1 ); - $group = ( isset( $args[2] ) ) ? $args[2] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 2, '' ); $value = wp_cache_decr( $key, $offset, $group ); @@ -59,7 +59,7 @@ public function decr( $args, $assoc_args ) { public function delete( $args, $assoc_args ) { $key = $args[0]; - $group = ( isset( $args[1] ) ) ? $args[1] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 1, '' ); $result = wp_cache_delete( $key, $group ); @@ -91,7 +91,7 @@ public function flush( $args, $assoc_args ) { public function get( $args, $assoc_args ) { $key = $args[0]; - $group = ( isset( $args[1] ) ) ? $args[1] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 1, '' ); $value = wp_cache_get( $key, $group ); @@ -110,9 +110,9 @@ public function get( $args, $assoc_args ) { public function incr( $args, $assoc_args ) { $key = $args[0]; - $offset = ( isset( $args[1] ) ) ? $args[1] : 1; + $offset = \WP_CLI\Utils\get_flag_value( $args, 1, 1 ); - $group = ( isset( $args[2] ) ) ? $args[2] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 2, '' ); $value = wp_cache_incr( $key, $offset, $group ); @@ -131,9 +131,9 @@ public function incr( $args, $assoc_args ) { public function replace( $args, $assoc_args ) { list( $key, $value ) = $args; - $group = ( isset( $args[2] ) ) ? $args[2] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 2, '' ); - $expiration = ( isset( $args[3] ) ) ? $args[3] : 0; + $expiration = \WP_CLI\Utils\get_flag_value( $args, 3, 0 ); $result = wp_cache_replace( $key, $value, $group, $expiration ); @@ -152,9 +152,9 @@ public function replace( $args, $assoc_args ) { public function set( $args, $assoc_args ) { list( $key, $value ) = $args; - $group = ( isset( $args[2] ) ) ? $args[2] : ''; + $group = \WP_CLI\Utils\get_flag_value( $args, 2, '' ); - $expiration = ( isset( $args[3] ) ) ? $args[3] : 0; + $expiration = \WP_CLI\Utils\get_flag_value( $args, 3, 0 ); $result = wp_cache_set( $key, $value, $group, $expiration ); diff --git a/php/commands/comment.php b/php/commands/comment.php index 2aac405a48..4b16eca071 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -353,7 +353,7 @@ public function unapprove( $args, $assoc_args ) { * wp comment count 42 */ public function count( $args, $assoc_args ) { - $post_id = isset( $args[0] ) ? $args[0] : 0; + $post_id = \WP_CLI\Utils\get_flag_value( $args, 0, 0 ); $count = wp_count_comments( $post_id ); diff --git a/php/commands/core.php b/php/commands/core.php index 43a040c22b..fc3d791cf9 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -130,7 +130,7 @@ public function download( $args, $assoc_args ) { WP_CLI::launch( Utils\esc_cmd( $mkdir, ABSPATH ) ); } - $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : 'en_US'; + $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', 'en_US' ); if ( isset( $assoc_args['version'] ) ) { $version = $assoc_args['version']; @@ -877,7 +877,7 @@ function update( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; - $version = ! empty( $assoc_args['version'] ) ? $assoc_args['version'] : null; + $version = \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ); $update = (object) array( 'response' => 'upgrade', @@ -906,7 +906,7 @@ function update( $args, $assoc_args ) { || \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) { $version = $assoc_args['version']; - $locale = isset( $assoc_args['locale'] ) ? $assoc_args['locale'] : get_locale(); + $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); $new_package = $this->get_download_url($version, $locale); diff --git a/php/commands/cron.php b/php/commands/cron.php index b9b4ed0cb7..7025c26b2b 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -94,8 +94,8 @@ public function list_( $args, $assoc_args ) { public function schedule( $args, $assoc_args ) { $hook = $args[0]; - $next_run = ( isset( $args[1] ) ) ? $args[1] : 'now'; - $recurrence = ( isset( $args[2] ) ) ? $args[2] : false; + $next_run = \WP_CLI\Utils\get_flag_value( $args, 1, 'now' ); + $recurrence = \WP_CLI\Utils\get_flag_value( $args, 2, false ); if ( empty( $next_run ) ) { $timestamp = time(); @@ -294,7 +294,7 @@ protected static function get_cron_events() { 'sig' => $sig, 'args' => $data['args'], 'schedule' => $data['schedule'], - 'interval' => isset( $data['interval'] ) ? $data['interval'] : null, + 'interval' => \WP_CLI\Utils\get_flag_value( $data, 'interval' ), ); } diff --git a/php/commands/db.php b/php/commands/db.php index e6f01bfa17..956c9647cd 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -215,7 +215,7 @@ function import( $args, $assoc_args ) { function tables( $args, $assoc_args ) { global $wpdb; - $scope = isset( $assoc_args['scope'] ) ? $assoc_args['scope'] : 'all'; + $scope = \WP_CLI\Utils\get_flag_value( $assoc_args, 'scope', 'all' ); $tables = $wpdb->tables( $scope ); diff --git a/php/commands/menu.php b/php/commands/menu.php index e214711041..240427580f 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -495,7 +495,7 @@ public function delete( $args, $_ ) { private function add_or_update_item( $method, $type, $args, $assoc_args ) { $menu = $args[0]; - $menu_item_db_id = ( isset( $args[1] ) ) ? $args[1] : 0; + $menu_item_db_id = \WP_CLI\Utils\get_flag_value( $args, 1, 0 ); $menu = wp_get_nav_menu_object( $menu ); if ( ! $menu || is_wp_error( $menu ) ) { @@ -503,9 +503,7 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { } // `url` is protected in WP-CLI, so we use `link` instead - if ( isset( $assoc_args['link'] ) ) { - $assoc_args['url'] = $assoc_args['link']; - } + $assoc_args['url'] = \WP_CLI\Utils\get_flag_value( $assoc_args, 'link' ); // Need to persist the menu item data. See https://core.trac.wordpress.org/ticket/28138 if ( 'update' == $method ) { @@ -557,7 +555,7 @@ private function add_or_update_item( $method, $type, $args, $assoc_args ) { foreach( $default_args as $key => $default_value ) { // wp_update_nav_menu_item() has a weird argument prefix $new_key = 'menu-item-' . $key; - $menu_item_args[ $new_key ] = isset( $assoc_args[ $key ] ) ? $assoc_args[ $key ] : $default_value; + $menu_item_args[ $new_key ] = \WP_CLI\Utils\get_flag_value( $assoc_args, $key, $default_value ); } $menu_item_args['menu-item-type'] = $type; @@ -717,7 +715,7 @@ public function remove( $args, $_ ) { } $locations = get_nav_menu_locations(); - if ( ! isset( $locations[ $location ] ) || $locations[ $location ] != $menu->term_id ) { + if ( \WP_CLI\Utils\get_flag_value( $locations, $location ) != $menu->term_id ) { WP_CLI::error( "Menu isn't assigned to location." ); } diff --git a/php/commands/post.php b/php/commands/post.php index 7a149bcd52..e0ae7a8559 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -56,8 +56,7 @@ public function create( $args, $assoc_args ) { } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'edit' ) ) { - $input = isset( $assoc_args['post_content'] ) ? - $assoc_args['post_content'] : ''; + $input = \WP_CLI\Utils\get_flag_value( $assoc_args, 'post_content', '' ); if ( $output = $this->_edit( $input, 'WP-CLI: New Post' ) ) $assoc_args['post_content'] = $output; diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index a6d6a4e837..b51a9b8b4d 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -652,9 +652,7 @@ protected function extract_args( $assoc_args, $defaults ) { $out = array(); foreach ( $defaults as $key => $value ) { - $out[ $key ] = isset( $assoc_args[ $key ] ) - ? $assoc_args[ $key ] - : $value; + $out[ $key ] = \WP_CLI\Utils\get_flag_value( $assoc_args, $key, $value ); } return $out; diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 6307674397..54008e9844 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -68,11 +68,7 @@ public function __invoke( $args, $assoc_args ) { $php_only = \WP_CLI\Utils\get_flag_value( $assoc_args, 'precise' ); $recurse_objects = \WP_CLI\Utils\get_flag_value( $assoc_args, 'recurse-objects' ); - if ( isset( $assoc_args['skip-columns'] ) ) { - $skip_columns = explode( ',', $assoc_args['skip-columns'] ); - } else { - $skip_columns = array(); - } + $skip_columns = explode( ',', \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-columns' ) ); // never mess with hashed passwords $skip_columns[] = 'user_pass'; diff --git a/php/commands/site.php b/php/commands/site.php index 545f33b9c7..cbdf6ac18e 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -216,7 +216,7 @@ public function create( $_, $assoc_args ) { global $wpdb, $current_site; $base = $assoc_args['slug']; - $title = isset( $assoc_args['title'] ) ? $assoc_args['title'] : ucfirst( $base ); + $title = \WP_CLI\Utils\get_flag_value( $assoc_args, 'title', ucfirst( $base ) ); $email = empty( $assoc_args['email'] ) ? '' : $assoc_args['email']; diff --git a/php/commands/transient.php b/php/commands/transient.php index 16248d4548..3ea4b19b0e 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -35,7 +35,7 @@ public function get( $args, $assoc_args ) { public function set( $args ) { list( $key, $value ) = $args; - $expiration = isset( $args[2] ) ? $args[2] : 0; + $expiration = \WP_CLI\Utils\get_flag_value( $args, 2, 0 ); if ( set_transient( $key, $value, $expiration ) ) WP_CLI::success( 'Transient added.' ); diff --git a/php/commands/user.php b/php/commands/user.php index d4fdd39fb2..52a73d49bc 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -176,7 +176,7 @@ public function get( $args, $assoc_args ) { */ public function delete( $args, $assoc_args ) { $network = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) && is_multisite(); - $reassign = isset( $assoc_args['reassign'] ) ? $assoc_args['reassign'] : null; + $reassign = \WP_CLI\Utils\get_flag_value( $assoc_args, 'reassign' ); if ( $network && $reassign ) { WP_CLI::error('Reassigning content to a different user is not supported on multisite.'); @@ -259,17 +259,17 @@ public function create( $args, $assoc_args ) { WP_CLI::error( "The '{$user->user_email}' email address is invalid." ); } - $user->user_registered = isset( $assoc_args['user_registered'] ) - ? $assoc_args['user_registered'] : strftime( "%F %T", current_time('timestamp') ); + $user->user_registered = \WP_CLI\Utils\get_flag_value( + $assoc_args, + 'user_registered', + strftime( "%F %T", current_time('timestamp') ) + ); - $user->display_name = isset( $assoc_args['display_name'] ) - ? $assoc_args['display_name'] : false; + $user->display_name = \WP_CLI\Utils\get_flag_value( $assoc_args, 'display_name', false ); - $user->first_name = isset( $assoc_args['first_name'] ) - ? $assoc_args['first_name'] : false; + $user->first_name = \WP_CLI\Utils\get_flag_value( $assoc_args, 'first_name', false ); - $user->last_name = isset( $assoc_args['last_name'] ) - ? $assoc_args['last_name'] : false; + $user->last_name = \WP_CLI\Utils\get_flag_value( $assoc_args, 'last_name', false ); if ( isset( $assoc_args['user_pass'] ) ) { $user->user_pass = $assoc_args['user_pass']; @@ -278,13 +278,8 @@ public function create( $args, $assoc_args ) { $generated_pass = true; } - if ( isset( $assoc_args['role'] ) ) { - $role = $assoc_args['role']; - self::validate_role( $role ); - } else { - $role = get_option('default_role'); - } - $user->role = $role; + $user->role = \WP_CLI\Utils\get_flag_value( $assoc_args, 'role', get_option('default_role') ); + self::validate_role( $user->role ); if ( is_multisite() ) { $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); @@ -432,7 +427,7 @@ public function generate( $args, $assoc_args ) { public function set_role( $args, $assoc_args ) { $user = $this->fetcher->get_check( $args[0] ); - $role = isset( $args[1] ) ? $args[1] : get_option( 'default_role' ); + $role = \WP_CLI\Utils\get_flag_value( $args, 1, get_option('default_role') ); self::validate_role( $role ); diff --git a/php/commands/widget.php b/php/commands/widget.php index af8a0a88d4..81064269b3 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -97,7 +97,7 @@ public function list_( $args, $assoc_args ) { public function add( $args, $assoc_args ) { list( $name, $sidebar_id ) = $args; - $position = ( isset( $args[2] ) ) ? (int) $args[2] - 1 : 0; + $position = \WP_CLI\Utils\get_flag_value( $args, 2, 1 ) - 1; $this->validate_sidebar( $sidebar_id ); if ( false == ( $widget = $this->get_widget_obj( $name ) ) ) { diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 95c176c75d..381b7bfdcc 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -118,7 +118,7 @@ public function nav_menu_terms() { public function exportify_post( $post ) { $GLOBALS['wp_query']->in_the_loop = true; - $previous_global_post = isset( $GLOBALS['post'] )? $GLOBALS['post'] : null; + $previous_global_post = \WP_CLI\Utils\get_flag_value( $GLOBALS, 'post' ); $GLOBALS['post'] = $post; setup_postdata( $post ); $post->post_content = apply_filters( 'the_content_export', $post->post_content ); From b6a57ede3c5b1d3f8baec7e74fff23ba95cd2ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wendell=20J=C3=BAnior?= <wrnx00@gmail.com> Date: Tue, 21 Apr 2015 21:53:59 -0400 Subject: [PATCH 3524/4858] Reverse incorrect changes and fix some --- php/class-wp-cli.php | 15 +++++++++------ php/commands/core.php | 2 +- php/commands/plugin.php | 2 +- php/commands/theme.php | 2 +- php/utils.php | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e721c63275..44bf9ace53 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -295,12 +295,15 @@ public static function confirm( $question, $assoc_args = array() ) { * @return string */ public static function get_value_from_arg_or_stdin( $args, $index ) { - $raw_value = \WP_CLI\Utils\get_flag_value( $args, $index, '' ); - - // We don't use file_get_contents() here because it doesn't handle - // Ctrl-D properly, when typing in the value interactively. - while ( ( $line = fgets( STDIN ) ) !== false ) { - $raw_value .= $line; + if ( isset( $args[ $index ] ) ) { + $raw_value = $args[ $index ]; + } else { + // We don't use file_get_contents() here because it doesn't handle + // Ctrl-D properly, when typing in the value interactively. + $raw_value = ''; + while ( ( $line = fgets( STDIN ) ) !== false ) { + $raw_value .= $line; + } } return $raw_value; diff --git a/php/commands/core.php b/php/commands/core.php index fc3d791cf9..d5f5d3c5dd 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -350,7 +350,7 @@ public function config( $_, $assoc_args ) { ) ); } - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra-php' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra-php' ) === true ) { $assoc_args['extra-php'] = file_get_contents( 'php://stdin' ); } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index ebf37da0a2..568eaa3dba 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -303,7 +303,7 @@ protected function install_from_repo( $slug, $assoc_args ) { } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) === 'dev' ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) != 'dev' ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); diff --git a/php/commands/theme.php b/php/commands/theme.php index b074d5e6eb..4786a8dece 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -284,7 +284,7 @@ protected function install_from_repo( $slug, $assoc_args ) { } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) === 'dev' ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'version' ) != 'dev' ) { WP_CLI::get_http_cache_manager()->whitelist_package( $api->download_link, $this->item_type, $api->slug, $api->version ); } $result = $this->get_upgrader( $assoc_args )->install( $api->download_link ); diff --git a/php/utils.php b/php/utils.php index 21bad5bb97..a16a7a6698 100644 --- a/php/utils.php +++ b/php/utils.php @@ -514,5 +514,5 @@ function increment_version( $current_version, $new_version ) { * @return mixed */ function get_flag_value( $args, $flag, $default = null ) { - return isset( $args[ $flag ] ) ? $args[ $flag ] : $default; -} \ No newline at end of file + return isset( $args[ $flag ] ) ? $args[ $flag ] : $default; +} From 352d3c4883da6572ccfadd8aab80498d971af629 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 05:57:21 -0700 Subject: [PATCH 3525/4858] Periodically clear object cache on import WordPress' internal object cache can grow until all memory is consumed because cache invalidation is disabled. On large imports, this can fatal the import. --- php/commands/import.php | 12 ++++++++++-- php/utils-wp.php | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index d31d36d598..f63df2f5ce 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -171,10 +171,18 @@ private function add_wxr_filters() { } ); add_action( 'wp_import_insert_post', function( $post_id, $original_post_ID, $post, $postdata ) { - if ( is_wp_error( $post_id ) ) + global $wpcli_import_counts; + if ( is_wp_error( $post_id ) ) { WP_CLI::warning( "-- Error importing post: " . $post_id->get_error_code() ); - else + } else { WP_CLI::line( "-- Imported post as post_id #{$post_id}" ); + } + + if ( $wpcli_import_counts['current_post'] % 500 === 0 ) { + WP_CLI\Utils\wp_clear_object_cache(); + WP_CLI::line( "-- Cleared object cache." ); + } + }, 10, 4 ); add_action( 'wp_import_insert_term', function( $t, $import_term, $post_id, $post ) { diff --git a/php/utils-wp.php b/php/utils-wp.php index b9ee33c195..8501ce7ad4 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -131,3 +131,25 @@ function wp_register_unused_sidebar() { )); } + +/** + * Clear all of the caches for memory management + */ +function wp_clear_object_cache() { + global $wpdb, $wp_object_cache; + + $wpdb->queries = array(); // or define( 'WP_IMPORTING', true ); + + if ( ! is_object( $wp_object_cache ) ) { + return; + } + + $wp_object_cache->group_ops = array(); + $wp_object_cache->stats = array(); + $wp_object_cache->memcache_debug = array(); + $wp_object_cache->cache = array(); + + if ( is_callable( $wp_object_cache, '__remoteset' ) ) { + $wp_object_cache->__remoteset(); // important + } +} From 8a838b1750e1f59c76173aa281f50d570370f4f7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 06:33:18 -0700 Subject: [PATCH 3526/4858] Ensure the parent doesn't actually exist Sometimes WordPress installs the parent for us --- features/theme.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/theme.feature b/features/theme.feature index 040d4e6bcc..a40800555c 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -228,8 +228,10 @@ Feature: Manage WordPress themes Scenario: Install and attempt to activate a child theme without its parent Given a WP install + And I run `wp theme install biker` + And I run `rm -rf wp-content/themes/jolene` - When I try `wp theme install biker --activate` + When I try `wp theme activate biker` Then STDERR should contain: """ Error: The 'biker' theme cannot be activated without its parent, 'jolene'. From 57c45a5a2eda5098280653e519e5775890f80080 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 07:15:24 -0700 Subject: [PATCH 3527/4858] Deactivate and uninstall a plugin in one go Adds `--uninstall` flag to `wp plugin deactivate` --- features/plugin.feature | 22 ++++++++++++++++++++++ php/commands/plugin.php | 9 +++++++++ 2 files changed, 31 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index 1436c23257..abaa0ba530 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -282,6 +282,28 @@ Feature: Manage WordPress plugins must-use """ + Scenario: Deactivate and uninstall a plugin + Given a WP install + And these installed and active plugins: + """ + akismet + """ + + When I run `wp plugin deactivate akismet --uninstall` + Then STDOUT should contain: + """ + Success: Plugin 'akismet' deactivated. + Uninstalling 'akismet'... + Success: Uninstalled and deleted 'akismet' plugin. + """ + + When I try `wp plugin get akismet` + Then STDERR should be: + """ + Error: The 'akismet' plugin could not be found. + """ + + Scenario: Uninstall a plugin without deleting Given a WP install diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 568eaa3dba..b94a2d11ea 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -194,6 +194,9 @@ function activate( $args, $assoc_args = array() ) { * [<plugin>...] * : One or more plugins to deactivate. * + * [--uninstall] + * : Uninstall the plugin after deactivation. + * * [--all] * : If set, all plugins will be deactivated. * @@ -227,6 +230,12 @@ function deactivate( $args, $assoc_args = array() ) { deactivate_plugins( $plugin->file, false, $network_wide ); $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'uninstall' ) ) { + WP_CLI::log( "Uninstalling '{$plugin->name}'..." ); + $this->uninstall( array( $plugin->name ) ); + } + } } From 91357037c69e14662804e77e3eeb67e7ed18b584 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 07:29:02 -0700 Subject: [PATCH 3528/4858] Support uninstalling with `--deactivate` flag --- features/plugin.feature | 23 ++++++++++++++++++++++- php/commands/plugin.php | 10 +++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index abaa0ba530..cee0eb4a75 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -282,7 +282,7 @@ Feature: Manage WordPress plugins must-use """ - Scenario: Deactivate and uninstall a plugin + Scenario: Deactivate and uninstall a plugin, part one Given a WP install And these installed and active plugins: """ @@ -303,6 +303,27 @@ Feature: Manage WordPress plugins Error: The 'akismet' plugin could not be found. """ + Scenario: Deactivate and uninstall a plugin, part two + Given a WP install + And these installed and active plugins: + """ + akismet + """ + + When I run `wp plugin uninstall akismet --deactivate` + Then STDOUT should contain: + """ + Deactivating 'akismet'... + Success: Plugin 'akismet' deactivated. + Success: Uninstalled and deleted 'akismet' plugin. + """ + + When I try `wp plugin get akismet` + Then STDERR should be: + """ + Error: The 'akismet' plugin could not be found. + """ + Scenario: Uninstall a plugin without deleting Given a WP install diff --git a/php/commands/plugin.php b/php/commands/plugin.php index b94a2d11ea..2a941cba63 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -495,6 +495,9 @@ public function get( $args, $assoc_args ) { * <plugin>... * : One or more plugins to uninstall. * + * [--deactivate] + * : Deactivate the plugin before uninstalling. Default behavior is to warn and skip if the plugin is active. + * * [--skip-delete] * : If set, the plugin files will not be deleted. Only the uninstall procedure * will be run. @@ -505,11 +508,16 @@ public function get( $args, $assoc_args ) { */ function uninstall( $args, $assoc_args = array() ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - if ( is_plugin_active( $plugin->file ) ) { + if ( is_plugin_active( $plugin->file ) && ! WP_CLI\Utils\get_flag_value( $assoc_args, 'deactivate' ) ) { WP_CLI::warning( "The '{$plugin->name}' plugin is active." ); continue; } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'deactivate' ) ) { + WP_CLI::log( "Deactivating '{$plugin->name}'..." ); + $this->deactivate( array( $plugin->name ) ); + } + uninstall_plugin( $plugin->file ); if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-delete' ) && $this->_delete( $plugin ) ) { From fc8c25349d77e8db61aa180d947035cb7896aee0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 08:20:24 -0700 Subject: [PATCH 3529/4858] Add `--skip-delete` flag to `wp media regenerate` This allows old thumbnails to remain around afterwards, which can be important on many sites. --- features/media.feature | 61 +++++++++++++++++++++++++++++++++++++++++- php/commands/media.php | 13 ++++++--- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/features/media.feature b/features/media.feature index fa28cff858..d0d0207a5b 100644 --- a/features/media.feature +++ b/features/media.feature @@ -52,4 +52,63 @@ Feature: Manage WordPress attachments Then STDOUT should be: """ My imported attachment - """ \ No newline at end of file + """ + + Scenario: Delete existing thumbnails when media is regenerated + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + And a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 100, 100, true ); + }); + """ + And I run `wp option update uploads_use_yearmonth_folders 0` + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + And the wp-content/uploads/large-image-100x100.jpg file should exist + + Given a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 200, 200, true ); + }); + """ + When I run `wp media regenerate --yes` + Then STDOUT should not be empty + And the wp-content/uploads/large-image-100x100.jpg file should not exist + And the wp-content/uploads/large-image-200x200.jpg file should exist + + Scenario: Skip deletion of existing thumbnails when media is regenerated + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + And a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 100, 100, true ); + }); + """ + And I run `wp option update uploads_use_yearmonth_folders 0` + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + And the wp-content/uploads/large-image-100x100.jpg file should exist + + Given a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 200, 200, true ); + }); + """ + When I run `wp media regenerate --skip-delete --yes` + Then STDOUT should not be empty + And the wp-content/uploads/large-image-100x100.jpg file should exist + And the wp-content/uploads/large-image-200x200.jpg file should exist + diff --git a/php/commands/media.php b/php/commands/media.php index a3e856c19b..2c391dcd33 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -15,6 +15,9 @@ class Media_Command extends WP_CLI_Command { * [<attachment-id>...] * : One or more IDs of the attachments to regenerate. * + * [--skip-delete] + * : Skip deletion of the original thumbnails. If your thumbnails are linked from sources outside your control, it's likely best to leave them around. Defaults to false. + * * [--yes] * : Answer yes to the confirmation message. * @@ -31,6 +34,8 @@ function regenerate( $args, $assoc_args = array() ) { WP_CLI::confirm( 'Do you realy want to regenerate all images?', $assoc_args ); } + $skip_delete = \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-delete' ); + $query_args = array( 'post_type' => 'attachment', 'post__in' => $args, @@ -53,7 +58,7 @@ function regenerate( $args, $assoc_args = array() ) { _n( 'image', 'images', $count ) ) ); foreach ( $images->posts as $id ) { - $this->_process_regeneration( $id ); + $this->_process_regeneration( $id, $skip_delete ); } WP_CLI::success( sprintf( @@ -198,7 +203,7 @@ private function _make_copy( $path ) { return $filename; } - private function _process_regeneration( $id ) { + private function _process_regeneration( $id, $skip_delete = false ) { $image = get_post( $id ); $fullsizepath = get_attached_file( $image->ID ); @@ -210,7 +215,9 @@ private function _process_regeneration( $id ) { return; } - $this->remove_old_images( $image->ID ); + if ( ! $skip_delete ) { + $this->remove_old_images( $image->ID ); + } $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); if ( is_wp_error( $metadata ) ) { From 08d25c5567439924b34b07ff364ecabf02e22a20 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 10:15:55 -0700 Subject: [PATCH 3530/4858] Update tests to acknowledge WordPress 4.2 --- features/core.feature | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 046eca25d8..e0f351cac8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,6 +326,7 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | + | 4.2 | major | https://wordpress.org/wordpress-4.2.zip | | 4.1.2 | major | https://wordpress.org/wordpress-4.1.2.zip | | 4.0.2 | major | https://wordpress.org/wordpress-4.0.2.zip | | 3.9.4 | major | https://wordpress.org/wordpress-3.9.4.zip | @@ -334,12 +335,13 @@ Feature: Manage WordPress installation When I run `wp core check-update --format=count` Then STDOUT should be: """ - 4 + 5 """ When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | + | 4.2 | major | https://wordpress.org/wordpress-4.2.zip | | 4.1.2 | major | https://wordpress.org/wordpress-4.1.2.zip | | 4.0.2 | major | https://wordpress.org/wordpress-4.0.2.zip | | 3.9.4 | major | https://wordpress.org/wordpress-3.9.4.zip | @@ -347,7 +349,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --major --format=count` Then STDOUT should be: """ - 3 + 4 """ When I run `wp core check-update --minor` From cb90a740a22cf63b724109e608c603e8166c4f2d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 14:37:36 -0700 Subject: [PATCH 3531/4858] Update test cases to fail for child themes --- features/theme.feature | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index a40800555c..c8557e4683 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -128,73 +128,72 @@ Feature: Manage WordPress themes Scenario: Enabling and disabling a theme Given a WP multisite install - - When I run `wp theme install p2` - Then STDOUT should not be empty + And I run `wp theme install jolene` + And I run `wp theme install biker` When I try `wp option get allowedthemes` Then the return code should be 1 And STDERR should be empty - When I run `wp theme enable p2` + When I run `wp theme enable biker` Then STDOUT should contain: """ - Success: Enabled the 'P2' theme. + Success: Enabled the 'Biker' theme. """ When I run `wp option get allowedthemes` Then STDOUT should contain: """ - 'p2' => true + 'biker' => true """ - When I run `wp theme disable p2` + When I run `wp theme disable biker` Then STDOUT should contain: """ - Success: Disabled the 'P2' theme. + Success: Disabled the 'Biker' theme. """ When I run `wp option get allowedthemes` Then STDOUT should not contain: """ - 'p2' => true + 'biker' => true """ - When I run `wp theme enable p2 --activate` + When I run `wp theme enable biker --activate` Then STDOUT should contain: """ - Success: Enabled the 'P2' theme. - Success: Switched to 'P2' theme. + Success: Enabled the 'Biker' theme. + Success: Switched to 'Biker' theme. """ When I run `wp network-meta get 1 allowedthemes` Then STDOUT should not contain: """ - 'p2' => true + 'biker' => true """ - When I run `wp theme enable p2 --network` + When I run `wp theme enable biker --network` Then STDOUT should contain: """ - Success: Network enabled the 'P2' theme. + Success: Network enabled the 'Biker' theme. """ When I run `wp network-meta get 1 allowedthemes` Then STDOUT should contain: """ - 'p2' => true + 'biker' => true """ - When I run `wp theme disable p2 --network` + When I run `wp theme disable biker --network` Then STDOUT should contain: """ - Success: Network disabled the 'P2' theme. + Success: Network disabled the 'Biker' theme. """ When I run `wp network-meta get 1 allowedthemes` Then STDOUT should not contain: """ - 'p2' => true + 'biker' => true """ Scenario: Enabling and disabling a theme without multisite From 5712d571054a2052e635d7a040e1ccbb58c4842e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 14:38:06 -0700 Subject: [PATCH 3532/4858] Use `stylesheet` to track enabled themes `template` is shared by parent and child themes, which means the child theme couldn't ever be enabled --- php/commands/theme.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index f4cfc9917b..254afc9491 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -179,7 +179,7 @@ public function enable( $args, $assoc_args ) { $allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' ); if ( empty( $allowed_themes ) ) $allowed_themes = array(); - $allowed_themes[ $theme->get_template() ] = true; + $allowed_themes[ $theme->get_stylesheet() ] = true; call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes ); if ( ! empty( $assoc_args['network'] ) ) @@ -225,8 +225,8 @@ public function disable( $args, $assoc_args ) { # Add the current theme to the allowed themes option or site option $allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' ); - if ( ! empty( $allowed_themes[ $theme->get_template() ] ) ) - unset( $allowed_themes[ $theme->get_template() ] ); + if ( ! empty( $allowed_themes[ $theme->get_stylesheet() ] ) ) + unset( $allowed_themes[ $theme->get_stylesheet() ] ); call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes ); if ( ! empty( $assoc_args['network'] ) ) From dea90c52b3f7eca4d3b75a22f8b46ae7f6ce2c89 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 23 Apr 2015 15:23:22 -0700 Subject: [PATCH 3533/4858] Update tests to accommodate yet another core minor release --- features/core.feature | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/features/core.feature b/features/core.feature index e0f351cac8..8c142b580c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -327,10 +327,10 @@ Feature: Manage WordPress installation Then STDOUT should be a table containing rows: | version | update_type | package_url | | 4.2 | major | https://wordpress.org/wordpress-4.2.zip | - | 4.1.2 | major | https://wordpress.org/wordpress-4.1.2.zip | - | 4.0.2 | major | https://wordpress.org/wordpress-4.0.2.zip | - | 3.9.4 | major | https://wordpress.org/wordpress-3.9.4.zip | - | 3.8.6 | minor | https://wordpress.org/wordpress-3.8.6.zip | + | 4.1.3 | major | https://wordpress.org/wordpress-4.1.3.zip | + | 4.0.3 | major | https://wordpress.org/wordpress-4.0.3.zip | + | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | + | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -342,9 +342,9 @@ Feature: Manage WordPress installation Then STDOUT should be a table containing rows: | version | update_type | package_url | | 4.2 | major | https://wordpress.org/wordpress-4.2.zip | - | 4.1.2 | major | https://wordpress.org/wordpress-4.1.2.zip | - | 4.0.2 | major | https://wordpress.org/wordpress-4.0.2.zip | - | 3.9.4 | major | https://wordpress.org/wordpress-3.9.4.zip | + | 4.1.3 | major | https://wordpress.org/wordpress-4.1.3.zip | + | 4.0.3 | major | https://wordpress.org/wordpress-4.0.3.zip | + | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -355,7 +355,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.6 | minor | https://wordpress.org/wordpress-3.8.6.zip | + | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From 9f0c9ec312057fe411f8370c52775146e6230572 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 24 Apr 2015 06:39:06 -0700 Subject: [PATCH 3534/4858] Don't require remapify in default plugin Gruntfile It's copy-paste leftovers --- templates/plugin-gruntfile.mustache | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/plugin-gruntfile.mustache b/templates/plugin-gruntfile.mustache index 96dba5e2d0..661d0e309f 100644 --- a/templates/plugin-gruntfile.mustache +++ b/templates/plugin-gruntfile.mustache @@ -1,7 +1,6 @@ module.exports = function( grunt ) { 'use strict'; - var remapify = require('remapify'); var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; // Project configuration grunt.initConfig( { From 9c7b1235322d2ae061f5e513ce4aba48e3aeb27e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 24 Apr 2015 13:38:51 -0700 Subject: [PATCH 3535/4858] Switch indentation to two spaces instead of four --- templates/.travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 8b561acd35..6476f89ba3 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -1,16 +1,16 @@ language: php php: - - 5.3 - - 5.5 + - 5.3 + - 5.5 env: - - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.8 WP_MULTISITE=0 - - WP_VERSION=3.8 WP_MULTISITE=1 + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=latest WP_MULTISITE=1 + - WP_VERSION=3.8 WP_MULTISITE=0 + - WP_VERSION=3.8 WP_MULTISITE=1 before_script: - - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION + - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION script: phpunit From fa2dbff87b2270dcf6dca86b6bba6954c91e09d9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 24 Apr 2015 13:44:53 -0700 Subject: [PATCH 3536/4858] Only notify developers on build failure --- templates/.travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/.travis.yml b/templates/.travis.yml index 6476f89ba3..25a3edb533 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -1,5 +1,9 @@ language: php +notifications: + on_success: never + on_failure: change + php: - 5.3 - 5.5 From 6b9260d6cbec904bfe280367fcd0f6b7ae409652 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 24 Apr 2015 13:51:01 -0700 Subject: [PATCH 3537/4858] Make the matrix smarter about the builds it spawns --- templates/.travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index 25a3edb533..b4393cc7da 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -10,9 +10,11 @@ php: env: - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=latest WP_MULTISITE=1 - - WP_VERSION=3.8 WP_MULTISITE=0 - - WP_VERSION=3.8 WP_MULTISITE=1 + +matrix: + include: + - php: 5.3 + env: WP_VERSION=latest WP_MULTISITE=1 before_script: - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION From 966e380584f3b42a746310f16ae15abd231e5743 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 25 Apr 2015 13:54:44 -0700 Subject: [PATCH 3538/4858] Update mailmap --- .mailmap | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.mailmap b/.mailmap index 78ecffe33c..23d32791fc 100644 --- a/.mailmap +++ b/.mailmap @@ -1,12 +1,18 @@ +2ndkauboy <bernhard@kau-boys.de> Alex Mills <git@viper007bond.com> +Andreas Heigl <andreas@heigl.org> andreascreten <andreas@madewithlove.be> +Andrew Patton <andrew@acusti.ca> +BA <kau@connecticum.de> bartaakos <akos@netpositive.hu> bendoh <ben@thinkoomph.com> +Bobby Walters <bobbymwalters@gmail.com> BoiteAWeb <juliobosk@gmail.com> boonebgorges <boonebgorges@gmail.com> Borek Bernard <borekb@gmail.com> borekb <borekb@gmail.com> Brad Parbs <brad@bradparbs.com> +Brian MacKinney <brian@getpantheon.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> clemens-tolboom <clemens@build2be.com> @@ -14,6 +20,7 @@ conatus <alex@recordsonribs.com> ctayloroomphinc <ctaylor@thinkoomph.com> cyberhobo <dylan.k.kuhn@gmail.com> dangardner <dan@web.nearest.to> +Daniel Bachhuber <daniel.bachhuber@fusion.net> danielbachhuber <d@danielbachhuber.com> danielbachhuber <daniel@handbuilt.co> danielbachhuber <danielbachhuber@gmail.com> @@ -32,8 +39,10 @@ goldenapples <ntaintor@janrain.com> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> jeichorn <joshua.eichorn@pagely.com> +Jeremy Pry <jeremy.pry@gmail.com> jghazally <jeff@bigfish.co.uk> jghazally <jghazally@gmail.com> +Jim Reevior <jim@thinkoomph.com> jmslbam <jmslbam@gmail.com> johnbillion <johnbillion@gmail.com> johnpbloch <jbloch@John-Blochs-iMac.local> @@ -41,6 +50,8 @@ johnpbloch <johnpbloch@gmail.com> jonathanbardo <jonathanbardo@users.noreply.github.com> joshbetz <j@joshbetz.com> joshlevinson <joshalevinson@gmail.com> +JQ <JeyKeu@users.noreply.github.com> +Keith Grennan <keith@nearlyfree.org> Kevinlearynet <info@kevinleary.net> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> @@ -57,8 +68,10 @@ mikey dubs <mike@herebox.org> milesj <mileswjohnson@gmail.com> MiteshShah <Mitesh.Shah@rtCamp.com> miya0001 <miya@wpist.me> +Morgan Estes <morgan.estes@gmail.com> mwilliamson <michael.williamson@red-gate.com> mwilliamson <mike@zwobble.org> +mwithheld <vhmark@gmail.com> nacin <andrewnacin@gmail.com> navitronic <adrian@navitronic.co.uk> nb <nb@nikolay.bg> @@ -81,6 +94,7 @@ robertboloc <robertboloc@gmail.com> rodrigoprimo <rodrigo@hacklab.com.br> rodrigoprimo <rodrigosprimo@gmail.com> roelven <roel@soundcloud.com> +Ross Hattori <rhattori@saymedia.com> ryanduff <ryan@fusionized.com> santagada <santagada@gmail.com> sboisvert <stephane.boisvert@automattic.com> @@ -109,9 +123,12 @@ tott <tott@automattic.com> trepmal <trepmal@gmail.com> twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> +Wendell Júnior <wrnx00@gmail.com> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> William Turrell <william@wturrell.co.uk> willmot <tom@humanmade.co.uk> wopr42 <john@zippykid.com> +yivi <ivan@ojiva.es> +yivi <ivan@yivoff.com> ziz <justin@crowdfavorite.com> From 8c54240ec1c9fee352f7c74d8ef151275b1f3d39 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 25 Apr 2015 14:04:29 -0700 Subject: [PATCH 3539/4858] Bump stable to v0.19.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 66333910a4..1cf0537c34 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.18.0 +0.19.0 From 419ac2b00a27e3756fbdcfb1f92a573824df2d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sun, 26 Apr 2015 19:56:41 +0200 Subject: [PATCH 3540/4858] With the new VERSION file version string detection is only possible by running wp-cli --- utils/wp-cli-updatedeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 utils/wp-cli-updatedeb.sh diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh old mode 100644 new mode 100755 index c4f34efb51..7f1aefe336 --- a/utils/wp-cli-updatedeb.sh +++ b/utils/wp-cli-updatedeb.sh @@ -61,7 +61,7 @@ wget -nv -O usr/bin/wp "$PHAR" || die 3 "Phar download failure" chmod +x usr/bin/wp || die 4 "chmod failure" # get version -WPCLI_VER="$(grep -ao "define.*WP_CLI_VERSION.*;" usr/bin/wp | cut -d"'" -f4)" +WPCLI_VER="$(usr/bin/wp cli version|cut -d" " -f2)" [ -z "$WPCLI_VER" ] && die 5 "Cannot get wp-cli version" echo "Current version: ${WPCLI_VER}" From 9149e7da41340f5fd63d1db993e5741dc2a57a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Vor=C3=A1=C4=8Dek?= <jan@voracek.net> Date: Mon, 27 Apr 2015 14:25:09 +0200 Subject: [PATCH 3541/4858] Fixed user role checking --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 52a73d49bc..1a255792a0 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -306,7 +306,7 @@ public function create( $args, $assoc_args ) { if ( is_wp_error( $user_id ) ) { WP_CLI::error( $user_id ); } else { - if ( false === $role ) { + if ( false === $user->role ) { delete_user_option( $user_id, 'capabilities' ); delete_user_option( $user_id, 'user_level' ); } From 3dbf6223dca50f81014cde3de35c758e3aa4cd62 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 1 May 2015 04:27:52 -0700 Subject: [PATCH 3542/4858] Update core tests for WP 4.2.1 --- features/core.feature | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/features/core.feature b/features/core.feature index 8c142b580c..3886fbd0a1 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,9 +326,9 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2 | major | https://wordpress.org/wordpress-4.2.zip | - | 4.1.3 | major | https://wordpress.org/wordpress-4.1.3.zip | - | 4.0.3 | major | https://wordpress.org/wordpress-4.0.3.zip | + | 4.2.1 | major | https://wordpress.org/wordpress-4.2.1.zip | + | 4.1.4 | major | https://wordpress.org/wordpress-4.1.4.zip | + | 4.0.4 | major | https://wordpress.org/wordpress-4.0.4.zip | | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | @@ -341,9 +341,9 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2 | major | https://wordpress.org/wordpress-4.2.zip | - | 4.1.3 | major | https://wordpress.org/wordpress-4.1.3.zip | - | 4.0.3 | major | https://wordpress.org/wordpress-4.0.3.zip | + | 4.2.1 | major | https://wordpress.org/wordpress-4.2.1.zip | + | 4.1.4 | major | https://wordpress.org/wordpress-4.1.4.zip | + | 4.0.4 | major | https://wordpress.org/wordpress-4.0.4.zip | | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | When I run `wp core check-update --major --format=count` From 97a0d042ecd7fc7afc2951e452e3c9bdb8b94467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sun, 3 May 2015 20:00:59 +0200 Subject: [PATCH 3543/4858] Reworked parm-dump with current values --- php/commands/cli.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 8964f6f028..0a85ae75d2 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -70,27 +70,32 @@ function info( $_, $assoc_args ) { } /** - * Dump the list of global parameters, as JSON or by var_export. + * Dump the list of global parameters, as JSON or in var_export format. * * ## OPTIONS * + * [--with-values] + * : Display current values also. + * * [--format=<format>] - * : Accepted values: var_export + * : Accepted values: var_export, json. Default: var_export. * * @subcommand param-dump */ function param_dump( $_, $assoc_args ) { $spec = \WP_CLI::get_configurator()->get_spec(); - $config = \WP_CLI::get_configurator()->to_array(); - - // copy current config values to $spec - foreach ( $spec as $key => $value ) { - if ( isset( $config[0][$key] ) ) { - $current = $config[0][$key]; - } else { - $current = NULL; + + if ( isset( $assoc_args['with-values'] ) ) { + $config = \WP_CLI::get_configurator()->to_array(); + // Copy current config values to $spec + foreach ( $spec as $key => $value ) { + if ( isset( $config[0][$key] ) ) { + $current = $config[0][$key]; + } else { + $current = NULL; + } + $spec[$key]['current'] = $current; } - $spec[$key]['current'] = $current; } if ( isset( $assoc_args['format'] ) && 'var_export' === $assoc_args['format'] ) { From 4519b9ef36f7a0ec3a65f4117a8e9a2e2a4bf872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sun, 3 May 2015 20:24:03 +0200 Subject: [PATCH 3544/4858] Test for param-dump with current values --- features/cli.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/cli.feature b/features/cli.feature index d15e4888ed..34d6d48be6 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -66,3 +66,14 @@ Feature: `wp cli` tasks """ And STDERR should be empty And the return code should be 0 + + Scenario: Dump the list of global parameters with values + Given a WP install + + When I run `wp cli param-dump --with-values | grep -o '"current":' | uniq -c` + Then STDOUT should be: + """ + 15 "current": + """ + And STDERR should be empty + And the return code should be 0 From 69f55923b65568b9456cd473a4a05076251cabc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sun, 3 May 2015 20:28:15 +0200 Subject: [PATCH 3545/4858] Revert removed functions in cli.php --- php/commands/cli.php | 185 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index fccab59d67..918c462415 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -69,6 +69,191 @@ public function info( $_, $assoc_args ) { } } + /** + * Compare the last processed release to the current one, return true if it's the same minor version. + * + */ + private function same_minor_release( $release_parts, $updates ) { + $previous = end( $updates ); + if ( false === $previous ) + return false; + + $previous_parts = explode( '.', $previous['version'] ); + + return ( $previous_parts[0] === $release_parts[0] + && $previous_parts[1] === $release_parts[1] ); + } + + /** + * Check for update via Github API. Returns the available versions if there are updates, or empty if no update available. + * + * ## OPTIONS + * + * [--patch] + * : Only list patch updates + * + * [--minor] + * : Only list minor updates + * + * [--field=<field>] + * : Prints the value of a single field for each update. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. Defaults to version,update_type,package_url. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * @subcommand check-update + */ + public function check_update( $_, $assoc_args ) { + $updates = $this->get_updates( $assoc_args ); + + if ( $updates ) { + $formatter = new \WP_CLI\Formatter( + $assoc_args, + array( 'version', 'update_type', 'package_url' ) + ); + $formatter->display_items( $updates ); + } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { + WP_CLI::success( "WP-CLI is at the latest version." ); + } + } + + /** + * Fetch most recent update matching the requirements. Returns the available versions if there are updates, or empty if no update available. + * + * ## OPTIONS + * + * [--patch] + * : Only perform patch updates + * + * [--minor] + * : Only perform minor updates + * + * [--yes] + * : Do not prompt for confirmation + * + * @subcommand update + */ + public function update( $_, $assoc_args ) { + if ( 0 !== strpos( WP_CLI_ROOT, 'phar://' ) ) { + WP_CLI::error( "You can only self-update PHARs" ); + } + + $old_phar = realpath( $_SERVER['argv'][0] ); + + if ( ! is_writable( $old_phar ) ) { + WP_CLI::error( sprintf( "%s is not writable by current user", $old_phar ) ); + } + + $updates = $this->get_updates( $assoc_args ); + + if ( empty( $updates ) ) { + WP_CLI::success( "WP-CLI is at the latest version." ); + exit(0); + } + + $newest = $updates[0]; + + WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); + + $download_url = $newest['package_url']; + + WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); + + $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.phar'; + + $headers = array(); + $options = array( + 'timeout' => 600, // 10 minutes ought to be enough for everybody + 'filename' => $temp + ); + + Utils\http_request( 'GET', $download_url, null, $headers, $options ); + + exec( "php $temp --version", $output, $status ); + + if ( 0 !== $status ) { + WP_CLI::error_multi_line( $output ); + + WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli self-update again.' ); + } + + WP_CLI::log( 'New version works. Proceeding to replace.' ); + + $mode = fileperms( $old_phar ) & 511; + + if ( false === @chmod( $temp, $mode ) ) { + WP_CLI::error( sprintf( "Cannot chmod %s", $temp ) ); + } + + class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the file we no longer have access to this class + + if ( false === @rename( $temp, $old_phar ) ) { + WP_CLI::error( sprintf( "Cannot move %s to %s", $temp, $old_phar ) ); + } + + WP_CLI::success( sprintf( 'Updated WP-CLI to %s', $newest['version'] ) ); + } + + /** + * Returns update information + */ + private function get_updates( $assoc_args ) { + $url = 'https://api.github.com/repos/wp-cli/wp-cli/releases'; + + $options = array( + 'timeout' => 30 + ); + + $headers = array( + 'Accept' => 'application/json' + ); + $response = Utils\http_request( 'GET', $url, $headers, $options ); + + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( sprintf( "Failed to get latest version (HTTP code %d)", $response->status_code ) ); + } + + $release_data = json_decode( $response->body ); + $current_parts = explode( '.', WP_CLI_VERSION ); + $updates = array(); + + foreach ( $release_data as $release ) { + $release_version = $release->tag_name; + // get rid of leading "v" + if ( 'v' === substr( $release_version, 0, 1 ) ) { + $release_version = ltrim( $release_version, 'v' ); + } + // don't list earlier releases + if ( version_compare( $release_version, WP_CLI_VERSION, '<=' ) ) + continue; + $release_parts = explode( '.', $release_version ); + $update_type = 'minor'; + + if ( $release_parts[0] === $current_parts[0] + && $release_parts[1] === $current_parts[1] ) { + $update_type = 'patch'; + } + + if ( ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'patch' ) && 'patch' !== $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'patch' ) === false && 'patch' === $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) && 'minor' !== $update_type ) + && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) === false && 'minor' === $update_type ) + && ! $this->same_minor_release( $release_parts, $updates ) + ) { + $updates[] = array( + 'version' => $release_version, + 'update_type' => $update_type, + 'package_url' => $release->assets[0]->browser_download_url + ); + } + } + + return $updates; + } + /** * Dump the list of global parameters, as JSON or in var_export format. * From 42372ef33ba3523a61cab87aad0f49f10381b023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Mon, 4 May 2015 09:53:02 +0200 Subject: [PATCH 3546/4858] Use get_flag_value() --- php/commands/cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 918c462415..9592131ada 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -270,7 +270,7 @@ private function get_updates( $assoc_args ) { function param_dump( $_, $assoc_args ) { $spec = \WP_CLI::get_configurator()->get_spec(); - if ( isset( $assoc_args['with-values'] ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'with-values' ) ) { $config = \WP_CLI::get_configurator()->to_array(); // Copy current config values to $spec foreach ( $spec as $key => $value ) { @@ -283,7 +283,7 @@ function param_dump( $_, $assoc_args ) { } } - if ( isset( $assoc_args['format'] ) && 'var_export' === $assoc_args['format'] ) { + if ( 'var_export' === \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) ) { var_export( $spec ); } else { echo json_encode( $spec ); From cf6f5bfb4d63d11ca451086b14aa9bac4b60faa8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Mon, 4 May 2015 05:48:22 -0700 Subject: [PATCH 3547/4858] Fix documentation: the default is json See #1363 --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 9592131ada..ddc4d05301 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -263,7 +263,7 @@ private function get_updates( $assoc_args ) { * : Display current values also. * * [--format=<format>] - * : Accepted values: var_export, json. Default: var_export. + * : Accepted values: var_export, json. Default: json. * * @subcommand param-dump */ From 78b2e470096b389313ea07e278d2bcdd2490174b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 6 May 2015 12:42:03 -0700 Subject: [PATCH 3548/4858] Simple `wp comment generate` command Supports `--count` to start --- features/comment.feature | 7 +++++++ php/commands/comment.php | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index dd8ee017ad..293936ab24 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -124,3 +124,10 @@ Feature: Manage WordPress comments 0 """ + Scenario: Generate comments + When I run `wp comment generate --count=20` + And I run `wp comment list --format=count` + Then STDOUT should be: + """ + 21 + """ diff --git a/php/commands/comment.php b/php/commands/comment.php index 4b16eca071..a10248f018 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -87,6 +87,37 @@ public function update( $args, $assoc_args ) { } ); } + /** + * 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(); + + } + /** * Get a single comment. * From 71a130cc574b4d2f31e8eaf78edcf9abb8d07964 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Thu, 7 May 2015 15:45:20 -0400 Subject: [PATCH 3549/4858] In `wp term generate`, try to generate unique term names. --- features/term.feature | 9 +++++++++ php/commands/term.php | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/features/term.feature b/features/term.feature index 6bcf637204..2ee4447dd9 100644 --- a/features/term.feature +++ b/features/term.feature @@ -77,6 +77,15 @@ Feature: Manage WordPress terms 11 """ + Scenario: Generating terms when terms already exist + When I run `wp term generate category --count=10` + And I run `wp term generate category --count=10` + And I run `wp term list category --format=count` + Then STDOUT should be: + """ + 21 + """ + Scenario: Term with a non-existent parent When I try `wp term create category Apple --parent=99 --porcelain` Then STDERR should be: diff --git a/php/commands/term.php b/php/commands/term.php index 31cedcec9c..7b0c0762d6 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -278,6 +278,8 @@ public function delete( $args ) { * wp term generate --count=10 */ public function generate( $args, $assoc_args ) { + global $wpdb; + list ( $taxonomy ) = $args; $defaults = array( @@ -302,6 +304,8 @@ public function generate( $args, $assoc_args ) { $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" ); + for ( $i = 0; $i < $count; $i++ ) { if ( $hierarchical ) { @@ -325,7 +329,9 @@ public function generate( $args, $assoc_args ) { 'slug' => $slug . "-$i", ); - $term = wp_insert_term( "$label $i", $taxonomy, $args ); + // Try to generate a unique term name. + $name = $label . ' ' . ( $max_id + $i + 1 ); + $term = wp_insert_term( $name, $taxonomy, $args ); if ( is_wp_error( $term ) ) { WP_CLI::warning( $term ); } else { From 496df802d8eb19c31374474199d247bf679cda39 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 7 May 2015 16:11:07 -0700 Subject: [PATCH 3550/4858] Update core tests for WP 4.2.2 --- features/core.feature | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/features/core.feature b/features/core.feature index 3886fbd0a1..3fa82fe65c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,11 +326,11 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2.1 | major | https://wordpress.org/wordpress-4.2.1.zip | - | 4.1.4 | major | https://wordpress.org/wordpress-4.1.4.zip | - | 4.0.4 | major | https://wordpress.org/wordpress-4.0.4.zip | - | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | - | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | + | 4.2.2 | major | https://wordpress.org/wordpress-4.2.2.zip | + | 4.1.5 | major | https://wordpress.org/wordpress-4.1.5.zip | + | 4.0.5 | major | https://wordpress.org/wordpress-4.0.5.zip | + | 3.9.6 | major | https://wordpress.org/wordpress-3.9.6.zip | + | 3.8.8 | minor | https://wordpress.org/wordpress-3.8.8.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -341,10 +341,10 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2.1 | major | https://wordpress.org/wordpress-4.2.1.zip | - | 4.1.4 | major | https://wordpress.org/wordpress-4.1.4.zip | - | 4.0.4 | major | https://wordpress.org/wordpress-4.0.4.zip | - | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | + | 4.2.2 | major | https://wordpress.org/wordpress-4.2.2.zip | + | 4.1.5 | major | https://wordpress.org/wordpress-4.1.5.zip | + | 4.0.5 | major | https://wordpress.org/wordpress-4.0.5.zip | + | 3.9.6 | major | https://wordpress.org/wordpress-3.9.6.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -355,7 +355,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | + | 3.8.8 | minor | https://wordpress.org/wordpress-3.8.8.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From f66c49649cf86ad2060041bae238a66ba36eb619 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 7 May 2015 16:11:07 -0700 Subject: [PATCH 3551/4858] Update core tests for WP 4.2.2 --- features/core.feature | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/features/core.feature b/features/core.feature index 3886fbd0a1..3fa82fe65c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,11 +326,11 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2.1 | major | https://wordpress.org/wordpress-4.2.1.zip | - | 4.1.4 | major | https://wordpress.org/wordpress-4.1.4.zip | - | 4.0.4 | major | https://wordpress.org/wordpress-4.0.4.zip | - | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | - | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | + | 4.2.2 | major | https://wordpress.org/wordpress-4.2.2.zip | + | 4.1.5 | major | https://wordpress.org/wordpress-4.1.5.zip | + | 4.0.5 | major | https://wordpress.org/wordpress-4.0.5.zip | + | 3.9.6 | major | https://wordpress.org/wordpress-3.9.6.zip | + | 3.8.8 | minor | https://wordpress.org/wordpress-3.8.8.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -341,10 +341,10 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2.1 | major | https://wordpress.org/wordpress-4.2.1.zip | - | 4.1.4 | major | https://wordpress.org/wordpress-4.1.4.zip | - | 4.0.4 | major | https://wordpress.org/wordpress-4.0.4.zip | - | 3.9.5 | major | https://wordpress.org/wordpress-3.9.5.zip | + | 4.2.2 | major | https://wordpress.org/wordpress-4.2.2.zip | + | 4.1.5 | major | https://wordpress.org/wordpress-4.1.5.zip | + | 4.0.5 | major | https://wordpress.org/wordpress-4.0.5.zip | + | 3.9.6 | major | https://wordpress.org/wordpress-3.9.6.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -355,7 +355,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.7 | minor | https://wordpress.org/wordpress-3.8.7.zip | + | 3.8.8 | minor | https://wordpress.org/wordpress-3.8.8.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From 5b3d3b64677f3e3e791f0ee341ae47985e017813 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Thu, 7 May 2015 20:40:25 -0400 Subject: [PATCH 3552/4858] Simplify logic for ensuring unique term slug/name. --- php/commands/term.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 7b0c0762d6..b858ea3b0d 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -306,7 +306,7 @@ public function generate( $args, $assoc_args ) { $max_id = (int) $wpdb->get_var( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy ORDER BY term_taxonomy_id DESC LIMIT 1" ); - for ( $i = 0; $i < $count; $i++ ) { + for ( $i = $max_id; $i <= $max_id + $count; $i++ ) { if ( $hierarchical ) { @@ -329,8 +329,7 @@ public function generate( $args, $assoc_args ) { 'slug' => $slug . "-$i", ); - // Try to generate a unique term name. - $name = $label . ' ' . ( $max_id + $i + 1 ); + $name = "$label $i"; $term = wp_insert_term( $name, $taxonomy, $args ); if ( is_wp_error( $term ) ) { WP_CLI::warning( $term ); From a27b92e608eb13f370d76261604a33d75213b461 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Thu, 7 May 2015 20:43:30 -0400 Subject: [PATCH 3553/4858] Counting is fun. --- php/commands/term.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index b858ea3b0d..f9c93b9c8d 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -306,7 +306,7 @@ public function generate( $args, $assoc_args ) { $max_id = (int) $wpdb->get_var( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy ORDER BY term_taxonomy_id DESC LIMIT 1" ); - for ( $i = $max_id; $i <= $max_id + $count; $i++ ) { + for ( $i = $max_id + 1; $i <= $max_id + $count; $i++ ) { if ( $hierarchical ) { From 49e9a59f5c47513a1581a3f5260a70c0350c27c1 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sat, 9 May 2015 00:57:46 +0900 Subject: [PATCH 3554/4858] fix install-wp-tests.sh problem --- templates/install-wp-tests.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 6bb7fcd2fd..25fb88e5e8 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -11,7 +11,7 @@ DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-latest} -WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} +WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib/includes} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} set -ex @@ -62,12 +62,12 @@ install_test_suite() { cd $WP_TESTS_DIR if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php wp-tests-config.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php + download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php ${WP_TESTS_DIR}/../wp-tests-config.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" ${WP_TESTS_DIR}/../wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" ${WP_TESTS_DIR}/../wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" ${WP_TESTS_DIR}/../wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" ${WP_TESTS_DIR}/../wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" ${WP_TESTS_DIR}/../wp-tests-config.php fi } From d8c449b2b863b73b2a17c53d3db7b03057c6265e Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sat, 9 May 2015 11:23:35 +0900 Subject: [PATCH 3555/4858] missing plugin slug in tests/bootstrap.php --- features/scaffold.feature | 4 ++++ php/commands/scaffold.php | 8 ++++++-- templates/bootstrap.mustache | 5 ++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 35104a1081..2b908b182d 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -151,6 +151,10 @@ Feature: WordPress code scaffolding bootstrap.php test-sample.php """ + And the {PLUGIN_DIR}/hello-world/tests/bootstrap.php file should contain: + """ + hello-world.php + """ And the {PLUGIN_DIR}/hello-world/bin directory should contain: """ install-wp-tests.sh diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index b51a9b8b4d..e824ad803b 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -527,10 +527,14 @@ function plugin_tests( $args, $assoc_args ) { if ( ! is_dir( $plugin_dir ) ) { WP_CLI::error( 'Invalid plugin specified.' ); } - } else if ( ! empty( $args[0] ) ) { + } + + if ( ! empty( $args[0] ) ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - } else { + } + + if ( empty( $assoc_args['dir'] ) && empty( $args[0] ) ) { WP_CLI::error( 'Invalid plugin specified.' ); } diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index e2802af053..4628e2d3f5 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -8,9 +8,8 @@ if ( ! $_tests_dir ) { require_once $_tests_dir . '/includes/functions.php'; function _manually_load_plugin() { - require dirname( __FILE__ ) . '/../.php'; + require dirname( __FILE__ ) . '/../{{plugin_slug}}.php'; } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); -require $_tests_dir . '/includes/bootstrap.php'; - +require $_tests_dir . '/includes/bootstrap.php'; \ No newline at end of file From 64147e80a844bb324c66986e443b70b280016ef9 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sat, 9 May 2015 11:46:10 +0900 Subject: [PATCH 3556/4858] add new line --- templates/bootstrap.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index 4628e2d3f5..0f7a5391fa 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -12,4 +12,4 @@ function _manually_load_plugin() { } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); -require $_tests_dir . '/includes/bootstrap.php'; \ No newline at end of file +require $_tests_dir . '/includes/bootstrap.php'; From 1924c718a1683866351c3bad78b730f46106719e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sat, 9 May 2015 14:56:33 -0700 Subject: [PATCH 3557/4858] Correct spelling --- php/config-spec.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/config-spec.php b/php/config-spec.php index 1d67b11b8a..501a806b65 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -91,7 +91,7 @@ 'default' => array(), ), - # --allow-root => (NOT RECCOMENDED) Allow wp-cli to run as root. This poses + # --allow-root => (NOT RECOMMENDED) Allow wp-cli to run as root. This poses # a security risk, so you probably do not want to do this. 'allow-root' => array( 'file' => false, # Explicit. Just in case the default changes. From 95f8b30fd45433fb82738323a6393da378f5cd83 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sun, 10 May 2015 11:06:46 +0900 Subject: [PATCH 3558/4858] update to test whole line --- features/scaffold.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 2b908b182d..07e9d716b2 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -153,7 +153,7 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/tests/bootstrap.php file should contain: """ - hello-world.php + require dirname( __FILE__ ) . '/../hello-world.php'; """ And the {PLUGIN_DIR}/hello-world/bin directory should contain: """ From f442684744f64e09d5a2aaaa14e086c3c883eaef Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Mon, 11 May 2015 15:23:37 +0900 Subject: [PATCH 3559/4858] fix problem when --dir=path/to/directory --- features/scaffold.feature | 5 +++++ php/commands/scaffold.php | 9 +++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 07e9d716b2..5d6df90914 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -290,6 +290,11 @@ Feature: WordPress code scaffolding Success: Created test files. """ And the wp-content/mu-plugins/custom-plugin/tests directory should exist + And the wp-content/mu-plugins/custom-plugin/tests/bootstrap.php file should exist + And the wp-content/mu-plugins/custom-plugin/tests/bootstrap.php file should contain: + """ + require dirname( __FILE__ ) . '/../custom-plugin.php'; + """ Scenario: Scaffold starter code for a theme and network enable it Given a WP multisite install diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index e824ad803b..001c53b561 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -527,14 +527,11 @@ function plugin_tests( $args, $assoc_args ) { if ( ! is_dir( $plugin_dir ) ) { WP_CLI::error( 'Invalid plugin specified.' ); } - } - - if ( ! empty( $args[0] ) ) { + $plugin_slug = basename( $plugin_dir ); + } elseif ( ! empty( $args[0] ) ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - } - - if ( empty( $assoc_args['dir'] ) && empty( $args[0] ) ) { + } else { WP_CLI::error( 'Invalid plugin specified.' ); } From f2c31cf28a59cb07a4006aba61904361726a9950 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Mon, 11 May 2015 15:27:01 +0900 Subject: [PATCH 3560/4858] elseif to elseif :) --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 001c53b561..358859a4ee 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -528,7 +528,7 @@ function plugin_tests( $args, $assoc_args ) { WP_CLI::error( 'Invalid plugin specified.' ); } $plugin_slug = basename( $plugin_dir ); - } elseif ( ! empty( $args[0] ) ) { + } else if ( ! empty( $args[0] ) ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; } else { From dd3dfecdae782c92b6d996b0dd08b8eac683989e Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Tue, 12 May 2015 05:16:06 +0900 Subject: [PATCH 3561/4858] change `...` to `dirname()` --- features/scaffold.feature | 4 ++-- templates/bootstrap.mustache | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 5d6df90914..edae7ba196 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -153,7 +153,7 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/tests/bootstrap.php file should contain: """ - require dirname( __FILE__ ) . '/../hello-world.php'; + require dirname( dirname( __FILE__ ) ) . '/hello-world.php'; """ And the {PLUGIN_DIR}/hello-world/bin directory should contain: """ @@ -293,7 +293,7 @@ Feature: WordPress code scaffolding And the wp-content/mu-plugins/custom-plugin/tests/bootstrap.php file should exist And the wp-content/mu-plugins/custom-plugin/tests/bootstrap.php file should contain: """ - require dirname( __FILE__ ) . '/../custom-plugin.php'; + require dirname( dirname( __FILE__ ) ) . '/custom-plugin.php'; """ Scenario: Scaffold starter code for a theme and network enable it diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index 0f7a5391fa..be86eeaeac 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -8,7 +8,7 @@ if ( ! $_tests_dir ) { require_once $_tests_dir . '/includes/functions.php'; function _manually_load_plugin() { - require dirname( __FILE__ ) . '/../{{plugin_slug}}.php'; + require dirname( dirname( __FILE__ ) ) . '/{{plugin_slug}}.php'; } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); From 8f5f50ee41bd814faebf016895821a5385e8b873 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Tue, 12 May 2015 05:55:27 +0900 Subject: [PATCH 3562/4858] change `...` to `dirname` in install-wp-tests.sh --- templates/install-wp-tests.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 25fb88e5e8..6b2d4aefdc 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -32,7 +32,7 @@ install_wp() { mkdir -p $WP_CORE_DIR - if [ $WP_VERSION == 'latest' ]; then + if [ $WP_VERSION == 'latest' ]; then local ARCHIVE_NAME='latest' else local ARCHIVE_NAME="wordpress-$WP_VERSION" @@ -62,12 +62,12 @@ install_test_suite() { cd $WP_TESTS_DIR if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php ${WP_TESTS_DIR}/../wp-tests-config.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" ${WP_TESTS_DIR}/../wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" ${WP_TESTS_DIR}/../wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" ${WP_TESTS_DIR}/../wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" ${WP_TESTS_DIR}/../wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" ${WP_TESTS_DIR}/../wp-tests-config.php + download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php $(dirname ${WP_TESTS_DIR})/wp-tests-config.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php fi } From fc2d3b53d5f3e6c55bb07b38ed4ca78261c84eee Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Mon, 11 May 2015 19:55:04 -0500 Subject: [PATCH 3563/4858] adds tests for verbose search-replace flag --- features/search-replace.feature | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index d66b6bcef5..fc544a8ac1 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,6 +15,7 @@ Feature: Do global search/replace guid """ + Scenario: Multisite search/replace Given a WP multisite install And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` @@ -62,6 +63,29 @@ Feature: Do global search/replace When I run `wp search-replace foo bar --quiet` Then STDOUT should be empty + Scenario: Verbose search/replace + Given a WP install + And I run `wp post create --post_title='Replace this text' --porcelain` + And save STDOUT as {POSTID} + + When I run `wp search-replace 'Replace' 'Replaced' --verbose` + Then STDOUT should contain: + """ + Updating wp_posts.post_title from 'Replace' to 'Replaced' + """ + + When I run `wp search-replace 'Replace' 'Replaced' --verbose --dry-run` + Then STDOUT should contain: + """ + This would update wp_posts.post_title from 'Replace' to 'Replaced' + """ + + When I run `wp search-replace 'Replace' 'Replaced' --verbose --precise` + Then STDOUT should contain: + """ + Updating wp_posts.post_title from 'Replace' to 'Replaced' + """ + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install And I run `wp option get siteurl` From dd162887790455fa9b677005260e447160873c76 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Mon, 11 May 2015 19:55:21 -0500 Subject: [PATCH 3564/4858] handles --verbose flag added to searchreplace --- php/commands/search-replace.php | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 54008e9844..1b9e69ca43 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -49,6 +49,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--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. + * * ## EXAMPLES * * wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid @@ -67,6 +70,7 @@ public function __invoke( $args, $assoc_args ) { $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' ); $skip_columns = explode( ',', \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-columns' ) ); @@ -108,10 +112,10 @@ public function __invoke( $args, $assoc_args ) { if ( $php_only || NULL !== $serialRow ) { $type = 'PHP'; - $count = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ); + $count = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose ); } else { $type = 'SQL'; - $count = self::sql_handle_col( $col, $table, $old, $new, $dry_run ); + $count = self::sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ); } $report[] = array( $table, $col, $count, $type ); @@ -201,17 +205,21 @@ private static function get_table_list( $limit_to ) { } - private static function sql_handle_col( $col, $table, $old, $new, $dry_run ) { + private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) { global $wpdb; if ( $dry_run ) { - return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); + $result = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); } else { - return $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); + $result = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); + } + if ( $result && $verbose ) { + self::log_verbose_details( $table, $col, $old, $new, $dry_run ); } + return $result; } - private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects ) { + private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite @@ -252,6 +260,10 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, } } + if ( $count && $verbose ) { + self::log_verbose_details( $table, $col, $old, $new, $dry_run ); + } + return $count; } @@ -301,6 +313,12 @@ private static function esc_like( $old ) { return $old; } + private static function log_verbose_details( $table, $col, $old, $new, $dry_run ) { + $action = $dry_run ? 'This would update' : 'Updating'; + $verbose_output = "$action $table.$col from '$old' to '$new'\r\n"; + WP_CLI::log( $verbose_output ); + } + } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); From 0c82f831b972e9ae168f1ce4269cf8be01d6f761 Mon Sep 17 00:00:00 2001 From: Boone B Gorges <boonebgorges@gmail.com> Date: Tue, 12 May 2015 16:14:46 -0400 Subject: [PATCH 3565/4858] Skip cache invalidation when generating terms. When generating terms in a hierarchical category, `clean_term_cache()` triggers a rebuild of the taxonomy hierarchy with every call to `wp_insert_term()`. This is extremely slow when the taxonomy has many terms. We only need to bust the cache once, after all terms have been generated. See https://core.trac.wordpress.org/changeset/32498. --- php/commands/term.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index f9c93b9c8d..fe155ea030 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -306,6 +306,9 @@ public function generate( $args, $assoc_args ) { $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 ) { @@ -334,13 +337,15 @@ public function generate( $args, $assoc_args ) { if ( is_wp_error( $term ) ) { WP_CLI::warning( $term ); } else { + $created[] = $term['term_id']; $previous_term_id = $term['term_id']; } $notify->tick(); } - delete_option( $taxonomy . '_children' ); + wp_suspend_cache_invalidation( $suspend_cache_invalidation ); + clean_term_cache( $created, $taxonomy ); $notify->finish(); } From 3ce55ba6f953a5dc1e67a4c965c14aedb8c2bbf6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 13 May 2015 11:02:34 -0700 Subject: [PATCH 3566/4858] More sensible behavior for scaffolding plugin tests with `--dir=<dir>` arg If a plugin slug is provided, use that instead of the directory basename. But, if no slug is provided, use directory basename. --- features/scaffold.feature | 26 +++++++++++++++++++++++++- php/commands/scaffold.php | 20 +++++++++++++------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index edae7ba196..699b255132 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -281,7 +281,7 @@ Feature: WordPress code scaffolding When I try `wp scaffold plugin-tests --dir=wp-content/mu-plugins/incorrect-custom-plugin` Then STDERR should contain: """ - Error: Invalid plugin specified. + Error: Invalid plugin directory specified. """ When I run `wp scaffold plugin-tests --dir=wp-content/mu-plugins/custom-plugin` @@ -296,6 +296,30 @@ Feature: WordPress code scaffolding require dirname( dirname( __FILE__ ) ) . '/custom-plugin.php'; """ + Scenario: Scaffold tests for a plugin with a different slug than plugin directory + Given a WP install + And a wp-content/mu-plugins/custom-plugin2/custom-plugin-slug.php file: + """ + <?php + /** + * Plugin Name: Handbook + * Description: Features for a handbook, complete with glossary and table of contents + * Author: Nacin + */ + """ + + When I run `wp scaffold plugin-tests custom-plugin-slug --dir=wp-content/mu-plugins/custom-plugin2` + Then STDOUT should contain: + """ + Success: Created test files. + """ + And the wp-content/mu-plugins/custom-plugin2/tests directory should exist + And the wp-content/mu-plugins/custom-plugin2/tests/bootstrap.php file should exist + And the wp-content/mu-plugins/custom-plugin2/tests/bootstrap.php file should contain: + """ + require dirname( dirname( __FILE__ ) ) . '/custom-plugin-slug.php'; + """ + Scenario: Scaffold starter code for a theme and network enable it Given a WP multisite install When I run `wp scaffold _s starter-theme --enable-network` diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 358859a4ee..33060e4b22 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -511,7 +511,7 @@ function plugin( $args, $assoc_args ) { * : The name of the plugin to generate test files for. * * [--dir=<dirname>] - * : Generate test files for a non-standard plugin path. + * : Generate test files for a non-standard plugin path. If no plugin slug is specified, the directory name is used. * * ## EXAMPLE * @@ -522,16 +522,22 @@ function plugin( $args, $assoc_args ) { function plugin_tests( $args, $assoc_args ) { $wp_filesystem = $this->init_wp_filesystem(); + if ( ! empty( $args[0] ) ) { + $plugin_slug = $args[0]; + $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + } + if ( ! empty( $assoc_args['dir'] ) ) { $plugin_dir = $assoc_args['dir']; if ( ! is_dir( $plugin_dir ) ) { - WP_CLI::error( 'Invalid plugin specified.' ); + WP_CLI::error( 'Invalid plugin directory specified.' ); } - $plugin_slug = basename( $plugin_dir ); - } else if ( ! empty( $args[0] ) ) { - $plugin_slug = $args[0]; - $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - } else { + if ( empty( $plugin_slug ) ) { + $plugin_slug = basename( $plugin_dir ); + } + } + + if ( empty( $plugin_slug ) || empty( $plugin_dir ) ) { WP_CLI::error( 'Invalid plugin specified.' ); } From fa4fe115818f5311d2d8f5125bdb40f257935b5a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 13 May 2015 12:38:06 -0700 Subject: [PATCH 3567/4858] Version bump for master --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1cf0537c34..41915c7994 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.19.0 +0.19.1 From 3a8f83aff623d2d9de539026ac489df5ffec8ffa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 15 May 2015 13:08:35 -0700 Subject: [PATCH 3568/4858] Filter taxonomy terms by `term_id` It's a bit hacky, but that's alright. We can work around WP core. --- features/term.feature | 11 +++++++++++ php/commands/term.php | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/features/term.feature b/features/term.feature index 2ee4447dd9..fa85f1f8b0 100644 --- a/features/term.feature +++ b/features/term.feature @@ -92,3 +92,14 @@ Feature: Manage WordPress terms """ Error: Parent term does not exist. """ + + Scenario: Filter terms by term_id + When I run `wp term generate category --count=10` + And I run `wp term create category "My Test Category" --porcelain` + And save STDOUT as {TERM_ID} + + When I run `wp term list category --term_id={TERM_ID} --field=name` + Then STDOUT should be: + """ + My Test Category + """ diff --git a/php/commands/term.php b/php/commands/term.php index fe155ea030..66d7bcceda 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -66,7 +66,12 @@ public function list_( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); - $terms = get_terms( $args, $assoc_args ); + if ( ! empty( $assoc_args['term_id'] ) ) { + $term = get_term_by( 'id', $assoc_args['term_id'], $args[0] ); + $terms = array( $term ); + } else { + $terms = get_terms( $args, $assoc_args ); + } if ( 'ids' == $formatter->format ) { $terms = wp_list_pluck( $terms, 'term_id' ); From 0cf22cc2c4a965a3fea8854538151b0d6b712a35 Mon Sep 17 00:00:00 2001 From: KDoole <dev@Kevins-iMac.local> Date: Fri, 15 May 2015 16:10:33 -0500 Subject: [PATCH 3569/4858] updated the verbose message --- features/search-replace.feature | 12 ++++-------- php/commands/search-replace.php | 18 ++++++++---------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index fc544a8ac1..5649cd84c7 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -71,19 +71,15 @@ Feature: Do global search/replace When I run `wp search-replace 'Replace' 'Replaced' --verbose` Then STDOUT should contain: """ - Updating wp_posts.post_title from 'Replace' to 'Replaced' - """ - - When I run `wp search-replace 'Replace' 'Replaced' --verbose --dry-run` - Then STDOUT should contain: - """ - This would update wp_posts.post_title from 'Replace' to 'Replaced' + Checking wp_posts.post_title + 1 rows affected """ When I run `wp search-replace 'Replace' 'Replaced' --verbose --precise` Then STDOUT should contain: """ - Updating wp_posts.post_title from 'Replace' to 'Replaced' + Checking wp_posts.post_title + 1 rows affected """ Scenario Outline: Large guid search/replace where replacement contains search (or not) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 1b9e69ca43..023b2b9b2d 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -209,14 +209,14 @@ private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $ver global $wpdb; if ( $dry_run ) { - $result = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); + $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); } else { - $result = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); + $count = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } - if ( $result && $verbose ) { - self::log_verbose_details( $table, $col, $old, $new, $dry_run ); + if ( $count && $verbose ) { + self::log_verbose_details( $table, $col, $count ); } - return $result; + return $count; } private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose ) { @@ -261,7 +261,7 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, } if ( $count && $verbose ) { - self::log_verbose_details( $table, $col, $old, $new, $dry_run ); + self::log_verbose_details( $table, $col, $count ); } return $count; @@ -313,10 +313,8 @@ private static function esc_like( $old ) { return $old; } - private static function log_verbose_details( $table, $col, $old, $new, $dry_run ) { - $action = $dry_run ? 'This would update' : 'Updating'; - $verbose_output = "$action $table.$col from '$old' to '$new'\r\n"; - WP_CLI::log( $verbose_output ); + private static function log_verbose_details( $table, $col, $count ) { + WP_CLI::log( sprintf( 'Checking: %s.%s' . PHP_EOL . '%d rows affected', $table, $col, $count ) ); } } From 6a2abcca83b9e5d4c1cce3029940dee271c158a6 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Fri, 15 May 2015 16:17:23 -0500 Subject: [PATCH 3570/4858] includes verbose messages for unaffected rows --- features/search-replace.feature | 4 ++-- php/commands/search-replace.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 5649cd84c7..cba391557f 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -71,14 +71,14 @@ Feature: Do global search/replace When I run `wp search-replace 'Replace' 'Replaced' --verbose` Then STDOUT should contain: """ - Checking wp_posts.post_title + Checking: wp_posts.post_title 1 rows affected """ When I run `wp search-replace 'Replace' 'Replaced' --verbose --precise` Then STDOUT should contain: """ - Checking wp_posts.post_title + Checking: wp_posts.post_title 1 rows affected """ diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 023b2b9b2d..f0d0c433d6 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -213,7 +213,7 @@ private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $ver } else { $count = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } - if ( $count && $verbose ) { + if ( $verbose ) { self::log_verbose_details( $table, $col, $count ); } return $count; @@ -260,7 +260,7 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, } } - if ( $count && $verbose ) { + if ( $verbose ) { self::log_verbose_details( $table, $col, $count ); } From a824c6b542698b1f3afa9bfc6e65ce70ba2bfba0 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Thu, 28 May 2015 09:54:21 -0400 Subject: [PATCH 3571/4858] Added the --start_id argument to the `wp export` command to specify a starting post ID --- php/commands/export.php | 17 +++++++++++++++++ php/export/class-wp-export-query.php | 12 ++++++++++++ 2 files changed, 29 insertions(+) diff --git a/php/commands/export.php b/php/commands/export.php index 976901d7b7..b4125f6cbc 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -37,6 +37,9 @@ class Export_Command extends WP_CLI_Command { * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. * + * [--start_id=<pid>] + * : Export only posts with IDs greater than or equal to this post ID. + * * [--author=<author>] * : Export only posts by this author. Can be either user login or user ID. * @@ -62,6 +65,7 @@ public function __invoke( $_, $assoc_args ) { 'category' => NULL, 'post_status' => NULL, 'post__in' => NULL, + 'start_id' => NULL, 'skip_comments' => NULL, 'max_file_size' => 15, ); @@ -202,6 +206,19 @@ private function check_post__in( $post__in ) { return true; } + private function check_start_id( $start_id ) { + $start_id = intval( $start_id ); + + // Post IDs must be greater than 0 + if ( 0 >= $start_id ) { + WP_CLI::warning( sprintf( __( 'Invalid start ID: %d' ), $start_id ) ); + return false; + } + + $this->export_args['start_id'] = $start_id; + return true; + } + private function check_author( $author ) { if ( is_null( $author ) ) return true; diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 381b7bfdcc..c970eb17f7 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -14,6 +14,7 @@ class WP_Export_Query { 'author' => null, 'start_date' => null, 'end_date' => null, + 'start_id' => null, 'category' => null, ); @@ -146,6 +147,7 @@ private function calculate_post_ids() { $this->author_where(); $this->start_date_where(); $this->end_date_where(); + $this->start_id_where(); $this->category_where(); $where = implode( ' AND ', array_filter( $this->wheres ) ); @@ -212,6 +214,16 @@ private function end_date_where() { $this->wheres[] = $wpdb->prepare( 'p.post_date <= %s', date( 'Y-m-d 23:59:59', $timestamp ) ); } + private function start_id_where() { + global $wpdb; + + $start_id = absint( $this->filters['start_id'] ); + if ( 0 === $start_id ) { + return; + } + $this->wheres[] = $wpdb->prepare( 'p.ID >= %d', $start_id ); + } + private function get_timestamp_for_the_last_day_of_a_month( $yyyy_mm ) { return strtotime( "$yyyy_mm +1month -1day" ); } From 1107b9cc7726214e6b8f0b60eb1dde025903f362 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Thu, 28 May 2015 10:21:01 -0400 Subject: [PATCH 3572/4858] Bail early from check_start_id if one isn't set --- php/commands/export.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/export.php b/php/commands/export.php index b4125f6cbc..e3a6ee5889 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -207,6 +207,10 @@ private function check_post__in( $post__in ) { } private function check_start_id( $start_id ) { + if ( is_null( $start_id ) ) { + return true; + } + $start_id = intval( $start_id ); // Post IDs must be greater than 0 From 2b8709ce1b96de9f67bfec83eea65951bfea1458 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <steve@stevegrunwell.com> Date: Thu, 28 May 2015 17:08:25 +0000 Subject: [PATCH 3573/4858] Enable the --post_type argument of `wp export` to accept multiple, comma-separated post types --- php/commands/export.php | 17 +++++++++++++---- php/export/class-wp-export-query.php | 26 ++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index 976901d7b7..6adc6800da 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -32,7 +32,8 @@ class Export_Command extends WP_CLI_Command { * : Export only posts published before this date, in format YYYY-MM-DD. * * [--post_type=<post-type>] - * : Export only posts with this post_type. Defaults to all. + * : Export only posts with this post_type. Separate multiple post types with a + * comma. Defaults to all. * * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. @@ -179,10 +180,18 @@ private function check_post_type( $post_type ) { if ( is_null( $post_type ) ) return true; + $post_type = array_unique( array_filter( explode( ',', $post_type ) ) ); $post_types = get_post_types(); - if ( !in_array( $post_type, $post_types ) ) { - WP_CLI::warning( sprintf( 'The post type %s does not exist. Choose "all" or any of these existing post types instead: %s', $post_type, implode( ", ", $post_types ) ) ); - return false; + + foreach ( $post_type as $type ) { + if ( ! in_array( $type, $post_types ) ) { + WP_CLI::warning( sprintf( + 'The post type %s does not exist. Choose "all" or any of these existing post types instead: %s', + $type, + implode( ", ", $post_types ) + ) ); + return false; + } } $this->export_args['post_type'] = $post_type; return true; diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 381b7bfdcc..f1e2422a78 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -159,12 +159,30 @@ private function calculate_post_ids() { private function post_type_where() { global $wpdb; - $post_types_filters = array( 'can_export' => true ); + $post_types_filters = array( 'can_export' => true, 'name' => null ); if ( $this->filters['post_type'] ) { - $post_types_filters = array_merge( $post_types_filters, array( 'name' => $this->filters['post_type'] ) ); + $post_types = $this->filters['post_type']; + + // Flatten single post types + if ( is_array( $post_types ) && 1 === count( $post_types ) ) { + $post_types = array_shift( $post_types ); + } + $post_types_filters = array_merge( $post_types_filters, array( 'name' => $post_types ) ); } - $post_types = get_post_types( $post_types_filters ); - if ( !$post_types ) { + + // Multiple post types + if ( is_array( $post_types_filters['name'] ) ) { + $post_types = array(); + foreach ( $post_types_filters['name'] as $post_type ) { + if ( post_type_exists( $post_type ) ) { + $post_types[] = $post_type; + } + } + } else { + $post_types = get_post_types( $post_types_filters ); + } + + if ( ! $post_types ) { $this->wheres[] = 'p.post_type IS NULL'; return; } From a233803633a1e74ace3a1aace073340858f28591 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 8 May 2015 14:59:34 +0300 Subject: [PATCH 3574/4858] behat: be consistent about dbhost --- features/bootstrap/FeatureContext.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index c17d1842ba..87085229cf 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -28,7 +28,8 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { private static $db_settings = array( 'dbname' => 'wp_cli_test', 'dbuser' => 'wp_cli_test', - 'dbpass' => 'password1' + 'dbpass' => 'password1', + 'dbhost' => '127.0.0.1', ); public $variables = array(); @@ -169,7 +170,7 @@ private function set_cache_dir() { private static function run_sql( $sql ) { Utils\run_mysql_command( 'mysql --no-defaults', array( 'execute' => $sql, - 'host' => 'localhost', + 'host' => self::$db_settings['dbhost'], 'user' => self::$db_settings['dbuser'], 'pass' => self::$db_settings['dbpass'], ) ); From 65e8bf4c06415e18f8390a342e3396c6a0bd1b40 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 May 2015 22:40:06 +0300 Subject: [PATCH 3575/4858] add `wp server` command --- features/bootstrap/FeatureContext.php | 55 ++++++++++++++++++ features/server.feature | 13 +++++ features/steps/when.php | 6 ++ php/commands/server.php | 60 ++++++++++++++++++++ php/router-lib.php | 81 +++++++++++++++++++++++++++ php/router.php | 27 +++++++++ 6 files changed, 242 insertions(+) create mode 100644 features/server.feature create mode 100644 php/commands/server.php create mode 100644 php/router-lib.php create mode 100644 php/router.php diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 87085229cf..02d22011cc 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -32,6 +32,8 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface { 'dbhost' => '127.0.0.1', ); + private $running_procs = array(); + public $variables = array(); /** @@ -97,6 +99,36 @@ public function afterScenario( $event ) { if ( $event->getResult() < 4 ) { Process::create( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ), null, self::get_process_env_variables() )->run(); } + + foreach ( $this->running_procs as $proc ) { + self::terminate_proc( $proc ); + } + } + + /** + * Terminate a process and any of its children. + */ + private static function terminate_proc( $proc ) { + $status = proc_get_status( $proc ); + + $master_pid = $status['pid']; + + $output = `ps -o ppid,pid,command | grep ^$master_pid`; + + foreach ( explode( "\n", $output ) as $line ) { + if ( preg_match( '/^(\d+)\s+(\d+)/', $line, $matches ) ) { + $parent = $matches[1]; + $child = $matches[2]; + + if ( $parent == $master_pid ) { + if ( ! posix_kill( $child, 9 ) ) { + throw new RuntimeException( posix_strerror( posix_get_last_error() ) ); + } + } + } + } + + proc_close( $proc ); } public static function create_cache_dir() { @@ -199,6 +231,29 @@ public function proc( $command, $assoc_args = array(), $path = '' ) { return Process::create( $command, $path, $env ); } + /** + * Start a background process. Will automatically be closed when the tests finish. + */ + public function background_proc( $cmd ) { + $descriptors = array( + 0 => STDIN, + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ); + + $proc = proc_open( $cmd, $descriptors, $pipes, $this->variables['RUN_DIR'], self::get_process_env_variables() ); + + sleep(1); + + $status = proc_get_status( $proc ); + + if ( !$status['running'] ) { + throw new RuntimeException( stream_get_contents( $pipes[2] ) ); + } else { + $this->running_procs[] = $proc; + } + } + public function move_files( $src, $dest ) { rename( $this->variables['RUN_DIR'] . "/$src", $this->variables['RUN_DIR'] . "/$dest" ); } diff --git a/features/server.feature b/features/server.feature new file mode 100644 index 0000000000..ad9ff53bd1 --- /dev/null +++ b/features/server.feature @@ -0,0 +1,13 @@ +Feature: Serve WordPress locally + + Scenario: Vanilla install + Given a WP install + And I start `wp server --host=localhost --port=8181` + + When I run `curl -sS localhost:8181` + Then STDOUT should contain: + """ + Just another WordPress site + """ + + When I run `test "$(curl -sS localhost:8181/license.txt)" == "$(cat license.txt)"` diff --git a/features/steps/when.php b/features/steps/when.php index 55651d9b39..b1ad614455 100644 --- a/features/steps/when.php +++ b/features/steps/when.php @@ -14,6 +14,12 @@ function invoke_proc( $proc, $mode ) { return $proc->$method(); } +$steps->When( '/^I start `([^`]+)`$/', + function ( $world, $cmd ) { + $world->background_proc( $cmd ); + } +); + $steps->When( '/^I (run|try) `([^`]+)`$/', function ( $world, $mode, $cmd ) { $cmd = $world->replace_variables( $cmd ); diff --git a/php/commands/server.php b/php/commands/server.php new file mode 100644 index 0000000000..5af14a50e8 --- /dev/null +++ b/php/commands/server.php @@ -0,0 +1,60 @@ +<?php + +class Server_Command extends WP_CLI_Command { + + /** + * Start a development server. + * + * ## OPTIONS + * + * --host=<host> + * : The hostname to bind the server to. Default: localhost + * + * --port=<port> + * : The port number to bind the server to. Default: 8080 + * + * ## EXAMPLES + * + * # Make the instance available on any address (with port 8080) + * wp server --host=0.0.0.0 + * + * # Run on port 80 (for multisite) + * sudo wp server --host=localhost.localdomain --port=80 + * + * @when before_wp_load + * @synopsis [--host=<host>] [--port=<port>] + */ + function __invoke( $_, $assoc_args ) { + $min_version = '5.4'; + if ( version_compare( PHP_VERSION, $min_version, '<' ) ) { + WP_CLI::error( "The `wp server` command requires PHP $min_version or newer." ); + } + + $defaults = array( + 'host' => 'localhost', + 'port' => 8080 + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $config_path = WP_CLI::get_runner()->project_config_path; + + if ( !$config_path ) { + $docroot = ABSPATH; + } else { + $docroot = dirname( $config_path ); + } + + $cmd = \WP_CLI\Utils\esc_cmd( PHP_BINARY . ' -S %s -t %s %s', + $assoc_args['host'] . ':' . $assoc_args['port'], + $docroot, + WP_CLI_ROOT . '/php/router.php' + ); + + $descriptors = array( STDIN, STDOUT, STDERR ); + + exit( proc_close( proc_open( $cmd, $descriptors, $pipes ) ) ); + } +} + +WP_CLI::add_command( 'server', 'Server_Command' ); + diff --git a/php/router-lib.php b/php/router-lib.php new file mode 100644 index 0000000000..08a400d410 --- /dev/null +++ b/php/router-lib.php @@ -0,0 +1,81 @@ +<?php + +namespace WP_CLI\Router; + +function get_full_host( $url ) { + $parsed_url = parse_url( $url ); + + $host = $parsed_url['host']; + if ( isset( $parsed_url['port'] ) && $parsed_url['port'] != 80 ) + $host .= ':' . $parsed_url['port']; + + return $host; +} + +function option_home( $url ) { + $GLOBALS['_wp_cli_original_url'] = $url; + + return 'http://' . $_SERVER['HTTP_HOST']; +} + +function option_siteurl( $url ) { + if ( !isset( $GLOBALS['_wp_cli_original_url'] ) ) + get_option('home'); + + $home_url_host = get_full_host( $GLOBALS['_wp_cli_original_url'] ); + $site_url_host = get_full_host( $url ); + + if ( $site_url_host == $home_url_host ) { + $url = str_replace( $site_url_host, $_SERVER['HTTP_HOST'], $url ); + } + + return $url; +} + +function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + global $wp_filter, $merged_filters; + + $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); + $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); + unset( $merged_filters[ $tag ] ); + return true; +} + +function _wp_filter_build_unique_id($tag, $function, $priority) { + global $wp_filter; + static $filter_id_count = 0; + + if ( is_string($function) ) + return $function; + + if ( is_object($function) ) { + // Closures are currently implemented as objects + $function = array( $function, '' ); + } else { + $function = (array) $function; + } + + if (is_object($function[0]) ) { + // Object Class Calling + if ( function_exists('spl_object_hash') ) { + return spl_object_hash($function[0]) . $function[1]; + } else { + $obj_idx = get_class($function[0]).$function[1]; + if ( !isset($function[0]->wp_filter_id) ) { + if ( false === $priority ) + return false; + $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; + $function[0]->wp_filter_id = $filter_id_count; + ++$filter_id_count; + } else { + $obj_idx .= $function[0]->wp_filter_id; + } + + return $obj_idx; + } + } else if ( is_string($function[0]) ) { + // Static Calling + return $function[0] . '::' . $function[1]; + } +} + diff --git a/php/router.php b/php/router.php new file mode 100644 index 0000000000..613be42c46 --- /dev/null +++ b/php/router.php @@ -0,0 +1,27 @@ +<?php +// Used by `wp server` to route requests. + +require_once __DIR__ . '/router-lib.php'; + +WP_CLI\Router\add_filter( 'option_home', '\\WP_CLI\\Router\\option_home', 20 ); +WP_CLI\Router\add_filter( 'option_siteurl', '\\WP_CLI\\Router\\option_siteurl', 20 ); + +$root = $_SERVER['DOCUMENT_ROOT']; +$path = '/'. ltrim( parse_url( urldecode( $_SERVER['REQUEST_URI'] ) )['path'], '/' ); + +if ( file_exists( $root.$path ) ) { + if ( is_dir( $root.$path ) && substr( $path, -1 ) !== '/' ) { + header( "Location: $path/" ); + exit; + } + + if ( strpos( $path, '.php' ) !== false ) { + chdir( dirname( $root.$path ) ); + require_once $root.$path; + } else { + return false; + } +} else { + chdir( $root ); + require_once 'index.php'; +} From 9878b947ca87c291165cfc88fe9a7edd9b37e8c0 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Fri, 29 May 2015 23:50:09 +0300 Subject: [PATCH 3576/4858] port Behat tag script to PHP --- ci/behat-tags.php | 22 ++++++++++++++++++ ci/set-behat-tags.sh | 55 -------------------------------------------- ci/test.sh | 4 ++-- 3 files changed, 24 insertions(+), 57 deletions(-) create mode 100644 ci/behat-tags.php delete mode 100755 ci/set-behat-tags.sh diff --git a/ci/behat-tags.php b/ci/behat-tags.php new file mode 100644 index 0000000000..ec573189e0 --- /dev/null +++ b/ci/behat-tags.php @@ -0,0 +1,22 @@ +<?php + +# Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 +$skip_tags = array('@github-api'); + +exec( 'grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq', $existing_tags ); + +$WP_VERSION = getenv( 'WP_VERSION' ); + +if ( $WP_VERSION ) { + foreach ( $existing_tags as $tag ) { + $version = str_replace( '@require-wp-', '', $tag ); + if ( version_compare( $version, $WP_VERSION, '>' ) ) { + $skip_tags[] = $tag; + } + } +} + +if ( !empty( $skip_tags ) ) { + echo '--tags=~' . implode( '&&~', $skip_tags ); +} + diff --git a/ci/set-behat-tags.sh b/ci/set-behat-tags.sh deleted file mode 100755 index ee5de21430..0000000000 --- a/ci/set-behat-tags.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -# http://stackoverflow.com/questions/4023830/bash-how-compare-two-strings-in-version-format -vercomp() { - if [[ $1 == $2 ]] - then - return 0 - fi - local IFS=. - local i ver1=($1) ver2=($2) - # fill empty fields in ver1 with zeros - for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) - do - ver1[i]=0 - done - for ((i=0; i<${#ver1[@]}; i++)) - do - if [[ -z ${ver2[i]} ]] - then - # fill empty fields in ver2 with zeros - ver2[i]=0 - fi - if ((10#${ver1[i]} > 10#${ver2[i]})) - then - return 1 - fi - if ((10#${ver1[i]} < 10#${ver2[i]})) - then - return 2 - fi - done - return 0 -} - -# Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 -skip_tags="--tags='~@github-api&&" -if [[ ! -z "$WP_VERSION" ]]; then - - requires=($(grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq)) - for (( i = 0; i < ${#requires[@]}; i++ )); do - version=${requires[$i]:12} - require=${requires[$i]} - vercomp $version $WP_VERSION - compare="$?" - if [[ 1 == $compare ]]; then - skip_tags="$skip_tags~$require&&" - fi - done - -fi - -skip_tags=$(echo $skip_tags| sed 's/&&$//') # trim trailing '&&' -skip_tags="$skip_tags'" # close the argument - -echo export behat_tags=$skip_tags diff --git a/ci/test.sh b/ci/test.sh index 0972b3a341..930f2b4a53 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -5,10 +5,10 @@ set -ex # Run the unit tests vendor/bin/phpunit -eval $(./ci/set-behat-tags.sh) +BEHAT_TAGS=$(php ci/behat-tags.php) # Run the functional tests -vendor/bin/behat --format progress $behat_tags +vendor/bin/behat --format progress $BEHAT_TAGS # Run CodeSniffer ./codesniffer/scripts/phpcs --standard=./ci/ php/ From 06120ce0362b2540f3a815cee6d6f194091d9f0c Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 May 2015 00:04:17 +0300 Subject: [PATCH 3577/4858] behat: check environment before running tests that require a specific PHP version --- ci/behat-tags.php | 31 ++++++++++++++++++++++++------- features/server.feature | 1 + 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ci/behat-tags.php b/ci/behat-tags.php index ec573189e0..145d90f88d 100644 --- a/ci/behat-tags.php +++ b/ci/behat-tags.php @@ -1,21 +1,38 @@ <?php -# Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 -$skip_tags = array('@github-api'); +error_reporting(E_ALL); +ini_set('display_errors', 1); + +function php_version_tags() { + exec( 'grep "@require-php-[0-9\.]*" -h -o features/*.feature | uniq', $existing_tags ); +} + +function version_tags( $prefix, $current ) { + if ( ! $current ) + return; -exec( 'grep "@require-wp-[0-9\.]*" -h -o features/*.feature | uniq', $existing_tags ); + exec( "grep '@{$prefix}-[0-9\.]*' -h -o features/*.feature | uniq", $existing_tags ); -$WP_VERSION = getenv( 'WP_VERSION' ); + $skip_tags = array(); -if ( $WP_VERSION ) { foreach ( $existing_tags as $tag ) { - $version = str_replace( '@require-wp-', '', $tag ); - if ( version_compare( $version, $WP_VERSION, '>' ) ) { + $required = str_replace( "@{$prefix}-", '', $tag ); + if ( version_compare( $current, $required, '<' ) ) { $skip_tags[] = $tag; } } + + return $skip_tags; } +$skip_tags = array_merge( + version_tags( 'require-wp', getenv( 'WP_VERSION' ) ), + version_tags( 'require-php', PHP_VERSION ) +); + +# Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 +$skip_tags[] = '@github-api'; + if ( !empty( $skip_tags ) ) { echo '--tags=~' . implode( '&&~', $skip_tags ); } diff --git a/features/server.feature b/features/server.feature index ad9ff53bd1..f9be1bcdb1 100644 --- a/features/server.feature +++ b/features/server.feature @@ -1,3 +1,4 @@ +@require-php-5.4 Feature: Serve WordPress locally Scenario: Vanilla install From b4beeb10fc416cc15ea7b4c78c4dc2579bf6a165 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 May 2015 01:30:54 +0300 Subject: [PATCH 3578/4858] extract router.php from phar, before starting the server --- php/commands/server.php | 2 +- php/router-lib.php | 81 --------------------------------------- php/router.php | 84 +++++++++++++++++++++++++++++++++++++++-- php/utils.php | 44 ++++++++++++--------- 4 files changed, 108 insertions(+), 103 deletions(-) delete mode 100644 php/router-lib.php diff --git a/php/commands/server.php b/php/commands/server.php index 5af14a50e8..e050fa4b6d 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -47,7 +47,7 @@ function __invoke( $_, $assoc_args ) { $cmd = \WP_CLI\Utils\esc_cmd( PHP_BINARY . ' -S %s -t %s %s', $assoc_args['host'] . ':' . $assoc_args['port'], $docroot, - WP_CLI_ROOT . '/php/router.php' + \WP_CLI\Utils\extract_from_phar( WP_CLI_ROOT . '/php/router.php' ) ); $descriptors = array( STDIN, STDOUT, STDERR ); diff --git a/php/router-lib.php b/php/router-lib.php deleted file mode 100644 index 08a400d410..0000000000 --- a/php/router-lib.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -namespace WP_CLI\Router; - -function get_full_host( $url ) { - $parsed_url = parse_url( $url ); - - $host = $parsed_url['host']; - if ( isset( $parsed_url['port'] ) && $parsed_url['port'] != 80 ) - $host .= ':' . $parsed_url['port']; - - return $host; -} - -function option_home( $url ) { - $GLOBALS['_wp_cli_original_url'] = $url; - - return 'http://' . $_SERVER['HTTP_HOST']; -} - -function option_siteurl( $url ) { - if ( !isset( $GLOBALS['_wp_cli_original_url'] ) ) - get_option('home'); - - $home_url_host = get_full_host( $GLOBALS['_wp_cli_original_url'] ); - $site_url_host = get_full_host( $url ); - - if ( $site_url_host == $home_url_host ) { - $url = str_replace( $site_url_host, $_SERVER['HTTP_HOST'], $url ); - } - - return $url; -} - -function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { - global $wp_filter, $merged_filters; - - $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); - $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); - unset( $merged_filters[ $tag ] ); - return true; -} - -function _wp_filter_build_unique_id($tag, $function, $priority) { - global $wp_filter; - static $filter_id_count = 0; - - if ( is_string($function) ) - return $function; - - if ( is_object($function) ) { - // Closures are currently implemented as objects - $function = array( $function, '' ); - } else { - $function = (array) $function; - } - - if (is_object($function[0]) ) { - // Object Class Calling - if ( function_exists('spl_object_hash') ) { - return spl_object_hash($function[0]) . $function[1]; - } else { - $obj_idx = get_class($function[0]).$function[1]; - if ( !isset($function[0]->wp_filter_id) ) { - if ( false === $priority ) - return false; - $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; - $function[0]->wp_filter_id = $filter_id_count; - ++$filter_id_count; - } else { - $obj_idx .= $function[0]->wp_filter_id; - } - - return $obj_idx; - } - } else if ( is_string($function[0]) ) { - // Static Calling - return $function[0] . '::' . $function[1]; - } -} - diff --git a/php/router.php b/php/router.php index 613be42c46..869129630e 100644 --- a/php/router.php +++ b/php/router.php @@ -1,10 +1,88 @@ <?php // Used by `wp server` to route requests. -require_once __DIR__ . '/router-lib.php'; +namespace WP_CLI\Router; -WP_CLI\Router\add_filter( 'option_home', '\\WP_CLI\\Router\\option_home', 20 ); -WP_CLI\Router\add_filter( 'option_siteurl', '\\WP_CLI\\Router\\option_siteurl', 20 ); +function get_full_host( $url ) { + $parsed_url = parse_url( $url ); + + $host = $parsed_url['host']; + if ( isset( $parsed_url['port'] ) && $parsed_url['port'] != 80 ) + $host .= ':' . $parsed_url['port']; + + return $host; +} + +function option_home( $url ) { + $GLOBALS['_wp_cli_original_url'] = $url; + + return 'http://' . $_SERVER['HTTP_HOST']; +} + +function option_siteurl( $url ) { + if ( !isset( $GLOBALS['_wp_cli_original_url'] ) ) + get_option('home'); + + $home_url_host = get_full_host( $GLOBALS['_wp_cli_original_url'] ); + $site_url_host = get_full_host( $url ); + + if ( $site_url_host == $home_url_host ) { + $url = str_replace( $site_url_host, $_SERVER['HTTP_HOST'], $url ); + } + + return $url; +} + +// This should be identical to the normal WordPress add_filter() function. +function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + global $wp_filter, $merged_filters; + + $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); + $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); + unset( $merged_filters[ $tag ] ); + return true; +} + +function _wp_filter_build_unique_id($tag, $function, $priority) { + global $wp_filter; + static $filter_id_count = 0; + + if ( is_string($function) ) + return $function; + + if ( is_object($function) ) { + // Closures are currently implemented as objects + $function = array( $function, '' ); + } else { + $function = (array) $function; + } + + if (is_object($function[0]) ) { + // Object Class Calling + if ( function_exists('spl_object_hash') ) { + return spl_object_hash($function[0]) . $function[1]; + } else { + $obj_idx = get_class($function[0]).$function[1]; + if ( !isset($function[0]->wp_filter_id) ) { + if ( false === $priority ) + return false; + $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; + $function[0]->wp_filter_id = $filter_id_count; + ++$filter_id_count; + } else { + $obj_idx .= $function[0]->wp_filter_id; + } + + return $obj_idx; + } + } else if ( is_string($function[0]) ) { + // Static Calling + return $function[0] . '::' . $function[1]; + } +} + +add_filter( 'option_home', '\\WP_CLI\\Router\\option_home', 20 ); +add_filter( 'option_siteurl', '\\WP_CLI\\Router\\option_siteurl', 20 ); $root = $_SERVER['DOCUMENT_ROOT']; $path = '/'. ltrim( parse_url( urldecode( $_SERVER['REQUEST_URI'] ) )['path'], '/' ); diff --git a/php/utils.php b/php/utils.php index a16a7a6698..1dd6bd2b6f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -7,8 +7,31 @@ use \WP_CLI\Dispatcher; use \WP_CLI\Iterators\Transform; +function inside_phar() { + return 0 === strpos( WP_CLI_ROOT, 'phar://' ); +} + +// Files that need to be read by external programs have to be extracted from the Phar archive. +function extract_from_phar( $path ) { + if ( ! inside_phar() ) { + return $path; + } + + $fname = basename( $path ); + + $tmp_path = sys_get_temp_dir() . "/wp-cli-$fname"; + + copy( $path, $tmp_path ); + + register_shutdown_function( function() use ( $tmp_path ) { + unlink( $tmp_path ); + } ); + + return $tmp_path; +} + function load_dependencies() { - if ( 0 === strpos( WP_CLI_ROOT, 'phar:' ) ) { + if ( inside_phar() ) { require WP_CLI_ROOT . '/vendor/autoload.php'; return; } @@ -417,31 +440,16 @@ function replace_path_consts( $source, $path ) { * @return object */ function http_request( $method, $url, $data = null, $headers = array(), $options = array() ) { - $pem_copied = false; - // cURL can't read Phar archives - if ( 0 === strpos( WP_CLI_ROOT, 'phar://' ) ) { - $options['verify'] = sys_get_temp_dir() . '/wp-cli-cacert.pem'; - - copy( - WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem', - $options['verify'] - ); - $pem_copied = true; - } + $options['verify'] = extract_from_phar( + WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); try { $request = \Requests::request( $url, $headers, $data, $method, $options ); - if ( $pem_copied ) { - unlink( $options['verify'] ); - } return $request; } catch( \Requests_Exception $ex ) { // Handle SSL certificate issues gracefully \WP_CLI::warning( $ex->getMessage() ); - if ( $pem_copied ) { - unlink( $options['verify'] ); - } $options['verify'] = false; try { return \Requests::request( $url, $headers, $data, $method, $options ); From c661d6076785b1c884040507350c153a13894ec9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 May 2015 02:40:34 +0300 Subject: [PATCH 3579/4858] behat: use cmp instead of test --- features/server.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/server.feature b/features/server.feature index f9be1bcdb1..fc1a716639 100644 --- a/features/server.feature +++ b/features/server.feature @@ -11,4 +11,6 @@ Feature: Serve WordPress locally Just another WordPress site """ - When I run `test "$(curl -sS localhost:8181/license.txt)" == "$(cat license.txt)"` + When I run `curl -sS localhost:8181/license.txt > /tmp/license.txt` + And I run `cmp /tmp/license.txt license.txt` + Then STDOUT should be empty From 7c1f9d20cb0157c1c554df8433fdc0188632ec1b Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 May 2015 04:58:08 +0300 Subject: [PATCH 3580/4858] behat: use proc helper method wherever possible --- features/bootstrap/FeatureContext.php | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 02d22011cc..22b9a78e04 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -92,12 +92,11 @@ public function beforeScenario( $event ) { * @AfterScenario */ public function afterScenario( $event ) { - if ( !isset( $this->variables['RUN_DIR'] ) ) - return; - - // remove altered WP install, unless there's an error - if ( $event->getResult() < 4 ) { - Process::create( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ), null, self::get_process_env_variables() )->run(); + if ( isset( $this->variables['RUN_DIR'] ) ) { + // remove altered WP install, unless there's an error + if ( $event->getResult() < 4 ) { + $this->proc( Utils\esc_cmd( 'rm -r %s', $this->variables['RUN_DIR'] ) )->run(); + } } foreach ( $this->running_procs as $proc ) { @@ -181,21 +180,17 @@ public function create_run_dir() { public function build_phar( $version = 'same' ) { $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid( "wp-cli-build-", TRUE ) . '.phar'; - Process::create( - Utils\esc_cmd( - 'php -dphar.readonly=0 %1$s %2$s --version=%3$s && chmod +x %2$s', - __DIR__ . '/../../utils/make-phar.php', - $this->variables['PHAR_PATH'], - $version - ), - null, - self::get_process_env_variables() - )->run_check(); + $this->proc( Utils\esc_cmd( + 'php -dphar.readonly=0 %1$s %2$s --version=%3$s && chmod +x %2$s', + __DIR__ . '/../../utils/make-phar.php', + $this->variables['PHAR_PATH'], + $version + ) )->run_check(); } private function set_cache_dir() { $path = sys_get_temp_dir() . '/wp-cli-test-cache'; - Process::create( Utils\esc_cmd( 'mkdir -p %s', $path ), null, self::get_process_env_variables() )->run_check(); + $this->proc( Utils\esc_cmd( 'mkdir -p %s', $path ) )->run_check(); $this->variables['CACHE_DIR'] = $path; } @@ -227,8 +222,13 @@ public function proc( $command, $assoc_args = array(), $path = '' ) { $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; } - $path = "{$this->variables['RUN_DIR']}/{$path}"; - return Process::create( $command, $path, $env ); + if ( isset( $this->variables['RUN_DIR'] ) ) { + $cwd = "{$this->variables['RUN_DIR']}/{$path}"; + } else { + $cwd = null; + } + + return Process::create( $command, $cwd, $env ); } /** @@ -271,7 +271,7 @@ public function download_wp( $subdir = '' ) { mkdir( $dest_dir ); } - Process::create( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ), null, self::get_process_env_variables() )->run_check(); + $this->proc( Utils\esc_cmd( "cp -r %s/* %s", self::$cache_dir, $dest_dir ) )->run_check(); // disable emailing mkdir( $dest_dir . '/wp-content/mu-plugins' ); From 06ab8fd20e155a678bb33fc94a3265d7582b0b64 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Sat, 30 May 2015 05:29:11 +0300 Subject: [PATCH 3581/4858] behat: prevent stalled builds by using posix_kill() instead of proc_close() --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 22b9a78e04..75e0e6fe4b 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -127,7 +127,7 @@ private static function terminate_proc( $proc ) { } } - proc_close( $proc ); + posix_kill( $master_pid, 9 ); } public static function create_cache_dir() { From 9addcdaab8b237f3c1b7bb1a8fe080023097ab8b Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Sat, 30 May 2015 01:01:36 -0400 Subject: [PATCH 3582/4858] Add a feature test for `wp export --start_id=<id>` --- features/export.feature | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/features/export.feature b/features/export.feature index f7be508ced..59d9c8f416 100644 --- a/features/export.feature +++ b/features/export.feature @@ -227,3 +227,41 @@ Feature: Export content. """ Test User """ + + Scenario: Export posts from a given starting post ID + Given a WP install + + When I run `wp plugin install wordpress-importer --activate` + Then STDERR should not contain: + """ + Warning: + """ + + When I run `wp site empty --yes` + And I run `wp post generate --post_type=post --count=10` + And I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 10 + """ + + When I run `wp export --start_id=6` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 5 + """ \ No newline at end of file From 9431cb1c70b770677304f6d11ff8b453662b7128 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Sat, 30 May 2015 01:30:15 -0400 Subject: [PATCH 3583/4858] Add functional tests for comma-separated --post_type arguments on `wp export` --- features/export.feature | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/features/export.feature b/features/export.feature index f7be508ced..05d389e32a 100644 --- a/features/export.feature +++ b/features/export.feature @@ -74,6 +74,58 @@ Feature: Export content. 10 """ + Scenario: Export a comma-separated list of post types + Given a WP install + + When I run `wp plugin install wordpress-importer --activate` + Then STDERR should not contain: + """ + Warning: + """ + + When I run `wp site empty --yes` + And I run `wp post generate --post_type=page --count=10` + And I run `wp post generate --post_type=post --count=10` + And I run `wp post generate --post_type=attachment --count=10` + And I run `wp post list --post_type=page,post,attachment --format=count` + Then STDOUT should be: + """ + 30 + """ + + When I run `wp export --post_type=page,post` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page,post --format=count` + Then STDOUT should be: + """ + 20 + """ + + When I run `wp post list --post_type=page --format=count` + Then STDOUT should be: + """ + 10 + """ + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 10 + """ + Scenario: Export only one post Given a WP install From dbc97f28873e0f8b9a9e9fbed897f19ce41cbf3f Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Sun, 31 May 2015 14:11:36 -0500 Subject: [PATCH 3584/4858] initial stab at adding regex to search-replace --- features/search-replace.feature | 14 ++++++++++++++ php/WP_CLI/Iterators/Query.php | 2 +- php/WP_CLI/Iterators/Table.php | 1 - php/WP_CLI/SearchReplacer.php | 13 +++++++++++-- php/commands/search-replace.php | 14 +++++++++----- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index cba391557f..4f950768ac 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -81,6 +81,20 @@ Feature: Do global search/replace Checking: wp_posts.post_title 1 rows affected """ + @wip + Scenario: Regex search/replace + Given a WP install + When I run `wp search-replace '(Hello)\s(world)' '$2, $1' --regex` + Then STDOUT should contain: + """ + wp_posts + """ + When I run `wp post list --fields=post_title` + Then STDOUT should contain: + """ + world, Hello + """ + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install diff --git a/php/WP_CLI/Iterators/Query.php b/php/WP_CLI/Iterators/Query.php index 03e7fbe40c..a5fdec554e 100644 --- a/php/WP_CLI/Iterators/Query.php +++ b/php/WP_CLI/Iterators/Query.php @@ -36,7 +36,7 @@ class Query implements \Iterator { */ public function __construct( $query, $chunk_size = 500 ) { $this->query = $query; - + $this->count_query = preg_replace( '/^.*? FROM /', 'SELECT COUNT(*) FROM ', $query, 1, $replacements ); if ( $replacements != 1 ) $this->count_query = ''; diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index eb7d1d60fd..71807f710a 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -51,7 +51,6 @@ function __construct( $args = array() ) { $conditions = self::build_where_conditions( $args['where'] ); $where_sql = $conditions ? " WHERE $conditions" : ''; $query = "SELECT $fields FROM $table $where_sql"; - parent::__construct( $query, $args['chunk_size'] ); } diff --git a/php/WP_CLI/SearchReplacer.php b/php/WP_CLI/SearchReplacer.php index e3910b20b3..d888eb81a8 100644 --- a/php/WP_CLI/SearchReplacer.php +++ b/php/WP_CLI/SearchReplacer.php @@ -13,10 +13,11 @@ class SearchReplacer { * @param string $to What we want it to be replaced with. * @param bool $recurse_objects Should objects be recursively replaced? */ - function __construct( $from, $to, $recurse_objects = false ) { + function __construct( $from, $to, $recurse_objects = false, $regex = false ) { $this->from = $from; $this->to = $to; $this->recurse_objects = $recurse_objects; + $this->regex = $regex; // Get the XDebug nesting level. Will be zero (no limit) if no value is set $this->max_recursion = intval( ini_get( 'xdebug.max_nesting_level' ) ); @@ -80,7 +81,7 @@ private function _run( $data, $serialised, $recursion_level = 0, &$visited_data } else if ( is_string( $data ) ) { - $data = str_replace( $this->from, $this->to, $data ); + $data = $this->str_replace( $this->from, $this->to, $data ); } if ( $serialised ) @@ -92,5 +93,13 @@ private function _run( $data, $serialised, $recursion_level = 0, &$visited_data return $data; } + + private function str_replace( $from, $to, $data ) { + if ( $this->regex ) { + return preg_replace( "/$from/", $to, $data ); + } else { + return str_replace( $from, $to, $data ); + } + } } diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f0d0c433d6..9e0767fd7c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -52,6 +52,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--verbose] * : Prints rows to the console as they're updated. * + * [--regex] + * : Runs the search using a regular expression. Using --regex slows the search-replace down significantly. + * * ## EXAMPLES * * wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid @@ -71,6 +74,7 @@ public function __invoke( $args, $assoc_args ) { $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' ) ); @@ -110,9 +114,9 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } - if ( $php_only || NULL !== $serialRow ) { + if ( $php_only || $regex || NULL !== $serialRow ) { $type = 'PHP'; - $count = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose ); + $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 ); @@ -219,7 +223,7 @@ private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $ver return $count; } - private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose ) { + private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite @@ -231,7 +235,7 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $args = array( 'table' => $table, 'fields' => $fields, - 'where' => "`$col`" . ' LIKE "%' . self::esc_like( $old ) . '%"', + 'where' => $regex ? '' : "`$col`" . ' LIKE "%' . self::esc_like( $old ) . '%"', 'chunk_size' => $chunk_size ); @@ -239,7 +243,7 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $count = 0; - $replacer = new \WP_CLI\SearchReplacer( $old, $new, $recurse_objects ); + $replacer = new \WP_CLI\SearchReplacer( $old, $new, $recurse_objects, $regex ); foreach ( $it as $row ) { if ( '' === $row->$col ) From 443359e563c6a81902e8714670e4a3d22c6da886 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Sun, 31 May 2015 14:59:02 -0500 Subject: [PATCH 3585/4858] adds a basic confirm message when scaffold will overwrite an existing file --- php/commands/scaffold.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 33060e4b22..50bcf8ce72 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -574,6 +574,9 @@ private function create_file( $filename, $contents ) { $wp_filesystem->mkdir( dirname( $filename ) ); + if ( file_exists( $filename ) ) { + WP_CLI::confirm( 'Scaffold will overwrite "' . $filename . '". Continue?' ); + } if ( ! $wp_filesystem->put_contents( $filename, $contents ) ) { WP_CLI::error( "Error creating file: $filename" ); } From 599536d40a7d58be9cc39a51a3c7881bed270306 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Sun, 31 May 2015 21:41:23 -0500 Subject: [PATCH 3586/4858] create_file accepts an array, wp-cli warns when fules will be overriden --- php/commands/scaffold.php | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 50bcf8ce72..d26e52c976 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -153,7 +153,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) if ( $path = $this->get_output_path( $control_args, $subdir ) ) { $filename = $path . $slug . '.php'; - $this->create_file( $filename, $final_output ); + $this->create_files( array( $filename => $final_output ) ); WP_CLI::success( "Created $filename" ); } else { @@ -300,8 +300,10 @@ function child_theme( $args, $assoc_args ) { $this->maybe_create_themes_dir(); - $this->create_file( $theme_style_path, Utils\mustache_render( 'child_theme.mustache', $data ) ); - $this->create_file( $theme_functions_path, Utils\mustache_render( 'child_theme_functions.mustache', $data ) ); + $this->create_files( array( + $theme_style_path => Utils\mustache_render( 'child_theme.mustache', $data ), + $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) + ) ); WP_CLI::success( "Created $theme_dir" ); @@ -470,11 +472,12 @@ function plugin( $args, $assoc_args ) { $plugin_path = "$plugin_dir/$plugin_slug.php"; $plugin_readme_path = "$plugin_dir/readme.txt"; - $this->create_file( $plugin_path, Utils\mustache_render( 'plugin.mustache', $data ) ); - $this->create_file( $plugin_readme_path, Utils\mustache_render( 'plugin-readme.mustache', $data ) ); - $this->create_file( "$plugin_dir/package.json", Utils\mustache_render( 'plugin-packages.mustache', $data ) ); - $this->create_file( "$plugin_dir/Gruntfile.js", Utils\mustache_render( 'plugin-gruntfile.mustache', $data ) ); - + $this->create_files( array( + $plugin_path => Utils\mustache_render( 'plugin.mustache', $data ), + $plugin_readme_path => Utils\mustache_render( 'plugin-readme.mustache', $data ), + "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), + "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), + ) ); WP_CLI::success( "Created $plugin_dir" ); if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-tests' ) ) { @@ -547,8 +550,8 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->mkdir( $tests_dir ); $wp_filesystem->mkdir( $bin_dir ); - $this->create_file( "$tests_dir/bootstrap.php", - Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ); + $this->create_files( array( "$tests_dir/bootstrap.php" => + Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ) ); $to_copy = array( 'install-wp-tests.sh' => $bin_dir, @@ -569,16 +572,21 @@ function plugin_tests( $args, $assoc_args ) { WP_CLI::success( "Created test files." ); } - private function create_file( $filename, $contents ) { + private function create_files( $files_and_contents ) { $wp_filesystem = $this->init_wp_filesystem(); - $wp_filesystem->mkdir( dirname( $filename ) ); - - if ( file_exists( $filename ) ) { - WP_CLI::confirm( 'Scaffold will overwrite "' . $filename . '". Continue?' ); + $pre_existing_files = array_filter( array_keys( $files_and_contents ), 'file_exists' ); + if ( ! empty( $pre_existing_files ) ) { + WP_CLI::warning( 'Scaffold will overwrite: ' . PHP_EOL . implode( PHP_EOL, $pre_existing_files ) ); + WP_CLI::confirm( 'Overwrite files and continue?' ); } - if ( ! $wp_filesystem->put_contents( $filename, $contents ) ) { - WP_CLI::error( "Error creating file: $filename" ); + + foreach ( $files_and_contents as $filename => $contents ) { + $wp_filesystem->mkdir( dirname( $filename ) ); + + if ( ! $wp_filesystem->put_contents( $filename, $contents ) ) { + WP_CLI::error( "Error creating file: $filename" ); + } } } From 5abfd5680c98f21332fb5c594b4a25c0cb084e61 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 00:23:29 +0300 Subject: [PATCH 3587/4858] use inside_phar() in one more place --- php/commands/cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index ddc4d05301..2c2d078a66 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -137,8 +137,8 @@ public function check_update( $_, $assoc_args ) { * @subcommand update */ public function update( $_, $assoc_args ) { - if ( 0 !== strpos( WP_CLI_ROOT, 'phar://' ) ) { - WP_CLI::error( "You can only self-update PHARs" ); + if ( ! Utils\inside_phar() ) { + WP_CLI::error( "You can only self-update Phar files." ); } $old_phar = realpath( $_SERVER['argv'][0] ); From 890f43f62973bc06765adf2d223c8d5637434b6f Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 00:39:06 +0300 Subject: [PATCH 3588/4858] clarify command description --- php/commands/server.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/server.php b/php/commands/server.php index e050fa4b6d..47dea0f5bd 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -3,7 +3,9 @@ class Server_Command extends WP_CLI_Command { /** - * Start a development server. + * Launch PHP's built-in web server for this specific WordPress installation. + * + * <http://php.net/manual/en/features.commandline.webserver.php> * * ## OPTIONS * From 9433772e164c100f01c589a1b5e346d622afb2ad Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 00:44:02 +0300 Subject: [PATCH 3589/4858] behat: s/start/launch in the background/ --- features/server.feature | 2 +- features/steps/when.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/server.feature b/features/server.feature index fc1a716639..0a01006859 100644 --- a/features/server.feature +++ b/features/server.feature @@ -3,7 +3,7 @@ Feature: Serve WordPress locally Scenario: Vanilla install Given a WP install - And I start `wp server --host=localhost --port=8181` + And I launch in the background `wp server --host=localhost --port=8181` When I run `curl -sS localhost:8181` Then STDOUT should contain: diff --git a/features/steps/when.php b/features/steps/when.php index b1ad614455..b0832493ed 100644 --- a/features/steps/when.php +++ b/features/steps/when.php @@ -14,7 +14,7 @@ function invoke_proc( $proc, $mode ) { return $proc->$method(); } -$steps->When( '/^I start `([^`]+)`$/', +$steps->When( '/^I launch in the background `([^`]+)`$/', function ( $world, $cmd ) { $world->background_proc( $cmd ); } From a5fac0214872d2a3e8e8c9aa39b2ae56a3141406 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 00:45:50 +0300 Subject: [PATCH 3590/4858] ci: remove error reporting re-config it's up to the developer to change his php.ini file --- ci/behat-tags.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/ci/behat-tags.php b/ci/behat-tags.php index 145d90f88d..18943e3800 100644 --- a/ci/behat-tags.php +++ b/ci/behat-tags.php @@ -1,8 +1,5 @@ <?php -error_reporting(E_ALL); -ini_set('display_errors', 1); - function php_version_tags() { exec( 'grep "@require-php-[0-9\.]*" -h -o features/*.feature | uniq', $existing_tags ); } From 59931910afe61b8ed7e421bd82c73561daac2c00 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 00:50:49 +0300 Subject: [PATCH 3591/4858] add --docroot option fixes https://github.com/wp-cli/server-command/issues/3 --- php/commands/server.php | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/php/commands/server.php b/php/commands/server.php index 47dea0f5bd..cd88e98a0f 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -9,12 +9,15 @@ class Server_Command extends WP_CLI_Command { * * ## OPTIONS * - * --host=<host> + * [--host=<host>] * : The hostname to bind the server to. Default: localhost * - * --port=<port> + * [--port=<port>] * : The port number to bind the server to. Default: 8080 * + * [--docroot=<path>] + * : The path to use as the document root. + * * ## EXAMPLES * * # Make the instance available on any address (with port 8080) @@ -34,16 +37,21 @@ function __invoke( $_, $assoc_args ) { $defaults = array( 'host' => 'localhost', - 'port' => 8080 + 'port' => 8080, + 'docroot' => false ); $assoc_args = array_merge( $defaults, $assoc_args ); - $config_path = WP_CLI::get_runner()->project_config_path; + $docroot = $assoc_args['docroot']; + + if ( !$docroot ) { + $config_path = WP_CLI::get_runner()->project_config_path; - if ( !$config_path ) { - $docroot = ABSPATH; - } else { - $docroot = dirname( $config_path ); + if ( !$config_path ) { + $docroot = ABSPATH; + } else { + $docroot = dirname( $config_path ); + } } $cmd = \WP_CLI\Utils\esc_cmd( PHP_BINARY . ' -S %s -t %s %s', From e23b2400cb56a28d8d44ef8bd516790e8773c7e9 Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 01:51:46 +0300 Subject: [PATCH 3592/4858] reorganize router functions --- php/router.php | 72 +++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/php/router.php b/php/router.php index 869129630e..9e524e4b02 100644 --- a/php/router.php +++ b/php/router.php @@ -3,37 +3,11 @@ namespace WP_CLI\Router; -function get_full_host( $url ) { - $parsed_url = parse_url( $url ); - - $host = $parsed_url['host']; - if ( isset( $parsed_url['port'] ) && $parsed_url['port'] != 80 ) - $host .= ':' . $parsed_url['port']; - - return $host; -} - -function option_home( $url ) { - $GLOBALS['_wp_cli_original_url'] = $url; - - return 'http://' . $_SERVER['HTTP_HOST']; -} - -function option_siteurl( $url ) { - if ( !isset( $GLOBALS['_wp_cli_original_url'] ) ) - get_option('home'); - - $home_url_host = get_full_host( $GLOBALS['_wp_cli_original_url'] ); - $site_url_host = get_full_host( $url ); - - if ( $site_url_host == $home_url_host ) { - $url = str_replace( $site_url_host, $_SERVER['HTTP_HOST'], $url ); - } - - return $url; -} - -// This should be identical to the normal WordPress add_filter() function. +/** + * This is a copy of WordPress's add_filter() function. + * + * We duplicate it because WordPress is not loaded yet. + */ function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { global $wp_filter, $merged_filters; @@ -43,6 +17,11 @@ function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) return true; } +/** + * This is a copy of WordPress's _wp_filter_build_unique_id() function. + * + * We duplicate it because WordPress is not loaded yet. + */ function _wp_filter_build_unique_id($tag, $function, $priority) { global $wp_filter; static $filter_id_count = 0; @@ -81,8 +60,35 @@ function _wp_filter_build_unique_id($tag, $function, $priority) { } } -add_filter( 'option_home', '\\WP_CLI\\Router\\option_home', 20 ); -add_filter( 'option_siteurl', '\\WP_CLI\\Router\\option_siteurl', 20 ); +function _get_full_host( $url ) { + $parsed_url = parse_url( $url ); + + $host = $parsed_url['host']; + if ( isset( $parsed_url['port'] ) && $parsed_url['port'] != 80 ) + $host .= ':' . $parsed_url['port']; + + return $host; +} + +add_filter( 'option_home', function ( $url ) { + $GLOBALS['_wp_cli_original_url'] = $url; + + return 'http://' . $_SERVER['HTTP_HOST']; +}, 20 ); + +add_filter( 'option_siteurl', function ( $url ) { + if ( !isset( $GLOBALS['_wp_cli_original_url'] ) ) + get_option('home'); + + $home_url_host = _get_full_host( $GLOBALS['_wp_cli_original_url'] ); + $site_url_host = _get_full_host( $url ); + + if ( $site_url_host == $home_url_host ) { + $url = str_replace( $site_url_host, $_SERVER['HTTP_HOST'], $url ); + } + + return $url; +}, 20 ); $root = $_SERVER['DOCUMENT_ROOT']; $path = '/'. ltrim( parse_url( urldecode( $_SERVER['REQUEST_URI'] ) )['path'], '/' ); From 92e0cbf82b2819e0b02c5c5701855d1a57fbb4da Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 1 Jun 2015 15:56:10 -0700 Subject: [PATCH 3593/4858] Switch php-cli-tools to `dev-master` so we can dogfood changes --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6cec94c7d4..7d9ab3cb46 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.10.4", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", From c5d5d240e976e779ee5b8502ce45f8c224f265cf Mon Sep 17 00:00:00 2001 From: scribu <mail@scribu.net> Date: Tue, 2 Jun 2015 02:00:16 +0300 Subject: [PATCH 3594/4858] add a few more comments --- php/router.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/router.php b/php/router.php index 9e524e4b02..2898402279 100644 --- a/php/router.php +++ b/php/router.php @@ -70,6 +70,7 @@ function _get_full_host( $url ) { return $host; } +// We need to trick WordPress into using the URL set by `wp server`, especially on multisite. add_filter( 'option_home', function ( $url ) { $GLOBALS['_wp_cli_original_url'] = $url; @@ -78,7 +79,7 @@ function _get_full_host( $url ) { add_filter( 'option_siteurl', function ( $url ) { if ( !isset( $GLOBALS['_wp_cli_original_url'] ) ) - get_option('home'); + get_option('home'); // trigger the option_home filter $home_url_host = _get_full_host( $GLOBALS['_wp_cli_original_url'] ); $site_url_host = _get_full_host( $url ); From 3fb5f393f26d246246e1feec464e452ba6054fb6 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Mon, 1 Jun 2015 22:38:03 -0500 Subject: [PATCH 3595/4858] added a WP_CLI@prompt --- php/class-wp-cli.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 44bf9ace53..d77e5269e8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -286,6 +286,19 @@ public static function confirm( $question, $assoc_args = array() ) { } } + /** + * Prompt before continuing. + */ + public static function prompt( $question, $assoc_args = array() ) { + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) { + fwrite( STDOUT, $question . " [s/r] " ); + + $answer = trim( fgets( STDIN ) ); + + return ( 'r' == $answer ); + } + } + /** * Read value from a positional argument or from STDIN. * From 1e27028f13a8bb345a8d2b22d24b53e33ae4e396 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Mon, 1 Jun 2015 22:38:47 -0500 Subject: [PATCH 3596/4858] WIP; playing around with log message formats --- php/commands/scaffold.php | 44 ++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d26e52c976..f708158faf 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -472,13 +472,20 @@ function plugin( $args, $assoc_args ) { $plugin_path = "$plugin_dir/$plugin_slug.php"; $plugin_readme_path = "$plugin_dir/readme.txt"; - $this->create_files( array( + $files_written = $this->create_files( array( $plugin_path => Utils\mustache_render( 'plugin.mustache', $data ), $plugin_readme_path => Utils\mustache_render( 'plugin-readme.mustache', $data ), "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), ) ); - WP_CLI::success( "Created $plugin_dir" ); + + if ( empty( $files_written ) ) { + WP_CLI::log( 'All files skipped' ); + } else { + WP_CLI::log( PHP_EOL ); + WP_CLI::success( "Created plugin files:" ); + WP_CLI::log( implode( PHP_EOL, $files_written ) ); + } if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-tests' ) ) { WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ), array( 'dir' => $plugin_dir ) ); @@ -550,7 +557,7 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->mkdir( $tests_dir ); $wp_filesystem->mkdir( $bin_dir ); - $this->create_files( array( "$tests_dir/bootstrap.php" => + $files_written = $this->create_files( array( "$tests_dir/bootstrap.php" => Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ) ); $to_copy = array( @@ -569,25 +576,42 @@ function plugin_tests( $args, $assoc_args ) { } } + if ( empty( $files_written ) ) { + WP_CLI::log( 'All files skipped' ); + } else { + WP_CLI::log( PHP_EOL ); + WP_CLI::success( "Created plugin files:" ); + WP_CLI::log( implode( PHP_EOL, $files_written ) ); + } + WP_CLI::success( "Created test files." ); } private function create_files( $files_and_contents ) { $wp_filesystem = $this->init_wp_filesystem(); - - $pre_existing_files = array_filter( array_keys( $files_and_contents ), 'file_exists' ); - if ( ! empty( $pre_existing_files ) ) { - WP_CLI::warning( 'Scaffold will overwrite: ' . PHP_EOL . implode( PHP_EOL, $pre_existing_files ) ); - WP_CLI::confirm( 'Overwrite files and continue?' ); - } + $wrote_files = array(); foreach ( $files_and_contents as $filename => $contents ) { - $wp_filesystem->mkdir( dirname( $filename ) ); + $should_write_file = true; + + if ( file_exists( $filename ) ) { + WP_CLI::log( PHP_EOL ); + WP_CLI::warning( 'File already exists:' ); + WP_CLI::log( $filename ); + $should_write_file = WP_CLI::prompt( 'Skip this file, or replace it with scaffolding?' ); + } + + if ( $should_write_file ) { + $wp_filesystem->mkdir( dirname( $filename ) ); + } if ( ! $wp_filesystem->put_contents( $filename, $contents ) ) { WP_CLI::error( "Error creating file: $filename" ); + } elseif ( $should_write_file ) { + $wrote_files[] = $filename; } } + return $wrote_files; } /** From c668e24e5abaeb553c0dcb5594cf43add7b7689f Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Tue, 2 Jun 2015 10:15:57 -0500 Subject: [PATCH 3597/4858] adds a warning message to regex help text --- php/WP_CLI/Iterators/Table.php | 1 + php/commands/search-replace.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 71807f710a..eb7d1d60fd 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -51,6 +51,7 @@ function __construct( $args = array() ) { $conditions = self::build_where_conditions( $args['where'] ); $where_sql = $conditions ? " WHERE $conditions" : ''; $query = "SELECT $fields FROM $table $where_sql"; + parent::__construct( $query, $args['chunk_size'] ); } diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 9e0767fd7c..889a7923e8 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -53,7 +53,7 @@ class Search_Replace_Command extends WP_CLI_Command { * : Prints rows to the console as they're updated. * * [--regex] - * : Runs the search using a regular expression. Using --regex slows the search-replace down significantly. + * : Runs the search using a regular expression. Warning: search-replace will take about 15-20x longer when using --regex. * * ## EXAMPLES * From e3c833d856248638de4414f4eba6157dd660f727 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Tue, 2 Jun 2015 18:22:31 -0500 Subject: [PATCH 3598/4858] no longer logs every single file which gets created. prompts for additional files not originally covered --- php/commands/scaffold.php | 48 +++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f708158faf..5da178f08e 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -201,6 +201,13 @@ function _s( $args, $assoc_args ) { 'author_uri' => "", ) ); + $_s_theme_path = "$theme_path/$data[theme_name]"; + $should_write_file = $this->prompt_if_files_will_be_overwritten( $_s_theme_path ); + if ( ! $should_write_file ) { + WP_CLI::log( 'No files created' ); + die; + } + $theme_description = "Custom theme: " . $data['theme_name'] . " developed by, " . $data['author']; $body = array(); @@ -235,6 +242,7 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); $this->init_wp_filesystem(); + $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); @@ -415,6 +423,10 @@ public function package_tests( $args, $assoc_args ) { $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); $file_path = $dir . basename( $file ); $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml' ), $file_path ); + + $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path ); + if ( ! $should_write_file ) continue; + $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); file_put_contents( $file_path, $contents ); if ( 'templates/install-package-tests.sh' === $file ) { @@ -483,8 +495,7 @@ function plugin( $args, $assoc_args ) { WP_CLI::log( 'All files skipped' ); } else { WP_CLI::log( PHP_EOL ); - WP_CLI::success( "Created plugin files:" ); - WP_CLI::log( implode( PHP_EOL, $files_written ) ); + WP_CLI::success( "Created plugin files." ); } if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-tests' ) ) { @@ -568,7 +579,13 @@ function plugin_tests( $args, $assoc_args ) { ); foreach ( $to_copy as $file => $dir ) { - $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", "$dir/$file", true ); + $file_name = "$dir/$file"; + + $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_name ); + if ( ! $should_write_file ) continue; + $files_written[] = $file_name; + + $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", $file_name, true ); if ( 'install-wp-tests.sh' === $file ) { if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); @@ -580,11 +597,8 @@ function plugin_tests( $args, $assoc_args ) { WP_CLI::log( 'All files skipped' ); } else { WP_CLI::log( PHP_EOL ); - WP_CLI::success( "Created plugin files:" ); - WP_CLI::log( implode( PHP_EOL, $files_written ) ); + WP_CLI::success( "Created test files." ); } - - WP_CLI::success( "Created test files." ); } private function create_files( $files_and_contents ) { @@ -592,14 +606,7 @@ private function create_files( $files_and_contents ) { $wrote_files = array(); foreach ( $files_and_contents as $filename => $contents ) { - $should_write_file = true; - - if ( file_exists( $filename ) ) { - WP_CLI::log( PHP_EOL ); - WP_CLI::warning( 'File already exists:' ); - WP_CLI::log( $filename ); - $should_write_file = WP_CLI::prompt( 'Skip this file, or replace it with scaffolding?' ); - } + $should_write_file = $this->prompt_if_files_will_be_overwritten( $filename ); if ( $should_write_file ) { $wp_filesystem->mkdir( dirname( $filename ) ); @@ -614,6 +621,17 @@ private function create_files( $files_and_contents ) { return $wrote_files; } + private function prompt_if_files_will_be_overwritten( $filename ) { + $should_write_file = true; + if ( file_exists( $filename ) ) { + WP_CLI::log( PHP_EOL ); + WP_CLI::warning( 'File already exists:' ); + WP_CLI::log( $filename ); + $should_write_file = WP_CLI::prompt( 'Skip this file, or replace it with scaffolding?' ); + } + return $should_write_file; + } + /** * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. * Same goes for when plugin is being used. From 0a45e331d53cf5d75f306b89da3b9af803a7f323 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Tue, 2 Jun 2015 18:56:44 -0500 Subject: [PATCH 3599/4858] pulled out a method for logging whether files were crearted --- php/commands/scaffold.php | 59 +++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5da178f08e..f42939403e 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -153,9 +153,13 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) if ( $path = $this->get_output_path( $control_args, $subdir ) ) { $filename = $path . $slug . '.php'; - $this->create_files( array( $filename => $final_output ) ); + $files_written = $this->create_files( array( $filename => $final_output ) ); + log_whether_files_written( + $files_written, + $skip_message = "Skipped creating $filename", + $success_message = "Created $filename" + ); - WP_CLI::success( "Created $filename" ); } else { // STDOUT echo $final_output; @@ -308,12 +312,15 @@ function child_theme( $args, $assoc_args ) { $this->maybe_create_themes_dir(); - $this->create_files( array( + $files_written = $this->create_files( array( $theme_style_path => Utils\mustache_render( 'child_theme.mustache', $data ), $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) ) ); - - WP_CLI::success( "Created $theme_dir" ); + log_whether_files_written( + $files_written, + $skip_message = 'All theme files were skipped.', + $success_message = "Created $theme_dir." + ); if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { WP_CLI::run_command( array( 'theme', 'activate', $theme_slug ) ); @@ -418,6 +425,7 @@ public function package_tests( $args, $assoc_args ) { 'features/extra/no-mail.php' => $extra_dir, ); + $files_written = array(); foreach ( $to_copy as $file => $dir ) { // file_get_contents() works with Phar-archived files $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); @@ -426,6 +434,7 @@ public function package_tests( $args, $assoc_args ) { $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path ); if ( ! $should_write_file ) continue; + $files_written[] = $file_path; $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); file_put_contents( $file_path, $contents ); @@ -433,8 +442,11 @@ public function package_tests( $args, $assoc_args ) { Process::create( Utils\esc_cmd( 'chmod +x %s', $file_path ) )->run(); } } - - WP_CLI::success( "Created test files." ); + log_whether_files_written( + $files_written, + $skip_message = 'All package tests were skipped.', + $success_message = 'Created test files.' + ); } @@ -491,12 +503,11 @@ function plugin( $args, $assoc_args ) { "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), ) ); - if ( empty( $files_written ) ) { - WP_CLI::log( 'All files skipped' ); - } else { - WP_CLI::log( PHP_EOL ); - WP_CLI::success( "Created plugin files." ); - } + log_whether_files_written( + $files_written, + $skip_message = 'All plugin files were skipped.', + $success_message = 'Created plugin files.' + ); if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-tests' ) ) { WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ), array( 'dir' => $plugin_dir ) ); @@ -592,13 +603,11 @@ function plugin_tests( $args, $assoc_args ) { } } } - - if ( empty( $files_written ) ) { - WP_CLI::log( 'All files skipped' ); - } else { - WP_CLI::log( PHP_EOL ); - WP_CLI::success( "Created test files." ); - } + log_whether_files_written( + $files_written, + $skip_message = 'All test files were skipped.', + $success_message = 'Created test files.' + ); } private function create_files( $files_and_contents ) { @@ -624,14 +633,22 @@ private function create_files( $files_and_contents ) { private function prompt_if_files_will_be_overwritten( $filename ) { $should_write_file = true; if ( file_exists( $filename ) ) { - WP_CLI::log( PHP_EOL ); WP_CLI::warning( 'File already exists:' ); WP_CLI::log( $filename ); $should_write_file = WP_CLI::prompt( 'Skip this file, or replace it with scaffolding?' ); + WP_CLI::log( PHP_EOL ); } return $should_write_file; } + private function log_whether_files_written( $files_written, $skip_message, $success_message ) { + if ( empty( $files_written ) ) { + WP_CLI::log( $skip_message ); + } else { + WP_CLI::success( $success_message ); + } + } + /** * If you're writing your files to your theme directory your textdomain also needs to be the same as your theme. * Same goes for when plugin is being used. From ad42a504e22e52ec34760306c961c9899f28fe6d Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Tue, 2 Jun 2015 18:57:58 -0500 Subject: [PATCH 3600/4858] fixes my last commit --- php/commands/scaffold.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index f42939403e..a6f4e9632c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -154,7 +154,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $filename = $path . $slug . '.php'; $files_written = $this->create_files( array( $filename => $final_output ) ); - log_whether_files_written( + $this->log_whether_files_written( $files_written, $skip_message = "Skipped creating $filename", $success_message = "Created $filename" @@ -316,7 +316,7 @@ function child_theme( $args, $assoc_args ) { $theme_style_path => Utils\mustache_render( 'child_theme.mustache', $data ), $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) ) ); - log_whether_files_written( + $this->log_whether_files_written( $files_written, $skip_message = 'All theme files were skipped.', $success_message = "Created $theme_dir." @@ -442,7 +442,7 @@ public function package_tests( $args, $assoc_args ) { Process::create( Utils\esc_cmd( 'chmod +x %s', $file_path ) )->run(); } } - log_whether_files_written( + $this->log_whether_files_written( $files_written, $skip_message = 'All package tests were skipped.', $success_message = 'Created test files.' @@ -503,7 +503,7 @@ function plugin( $args, $assoc_args ) { "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), ) ); - log_whether_files_written( + $this->log_whether_files_written( $files_written, $skip_message = 'All plugin files were skipped.', $success_message = 'Created plugin files.' @@ -603,7 +603,7 @@ function plugin_tests( $args, $assoc_args ) { } } } - log_whether_files_written( + $this->log_whether_files_written( $files_written, $skip_message = 'All test files were skipped.', $success_message = 'Created test files.' From 03abffc532b9ad19194c51c6fdbb337d9674e6e2 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Wed, 3 Jun 2015 09:49:32 -0500 Subject: [PATCH 3601/4858] adds behat tests for --force overwriting files with scaffold --- features/scaffold.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 699b255132..db258777f1 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -336,3 +336,17 @@ Feature: WordPress code scaffolding """ Error: Could not decompress your theme files """ + + @wip + Scenario: Overwrite existing files + Given a WP install + When I run `wp scaffold plugin test` + And I run `wp scaffold plugin test --force` + Then STDERR should contain: + """ + already exists + """ + And STDOUT should contain: + """ + Replaced + """ \ No newline at end of file From d49b4fed6988669bfef5ef344554f40568de66c7 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Wed, 3 Jun 2015 09:51:20 -0500 Subject: [PATCH 3602/4858] refactored WP_CLI::prompt --- php/class-wp-cli.php | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d77e5269e8..dce06ca232 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -286,17 +286,23 @@ public static function confirm( $question, $assoc_args = array() ) { } } - /** - * Prompt before continuing. - */ - public static function prompt( $question, $assoc_args = array() ) { - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) { - fwrite( STDOUT, $question . " [s/r] " ); - - $answer = trim( fgets( STDIN ) ); - - return ( 'r' == $answer ); - } + /** + * Prompt before continuing. + * + * @param string $question The question to pose + * @param bool $default The default response + * @param array $answers when the users responds with $answers[0] return false, with $answers[1] return true + * @param bool $hide Hide the user's response + * @return bool + */ + public static function prompt( $question, $default = false, $answers = array( 'no', 'yes' ), $hide = false ) { + $marker = '[' . implode( '/', $answers ) . ']: '; + + do { + $answer = cli\prompt( $question, $default, $marker, $hide ); + } while ( ! in_array( $answer, $answers ) ); + + return $answers[ 1 ] === $answer; } /** From e6eb2365a623bef60e1e1fe5dd1a74fd76e032af Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Wed, 3 Jun 2015 09:52:13 -0500 Subject: [PATCH 3603/4858] implements --force to overwrite existing files when scaffolding --- php/commands/scaffold.php | 72 ++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index a6f4e9632c..18f44ffd51 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -37,6 +37,9 @@ class Scaffold_Command extends WP_CLI_Command { * [--raw] * : Just generate the `register_post_type()` call and nothing else. * + * [--force] + * : Overwrite files that already exist. + * * @subcommand post-type * * @alias cpt @@ -85,6 +88,9 @@ function post_type( $args, $assoc_args ) { * [--raw] * : Just generate the `register_taxonomy()` call and nothing else. * + * [--force] + * : Overwrite files that already exist. + * * ## EXAMPLES * * wp scaffold taxonomy venue --post_types=event,presentation @@ -153,7 +159,8 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) if ( $path = $this->get_output_path( $control_args, $subdir ) ) { $filename = $path . $slug . '.php'; - $files_written = $this->create_files( array( $filename => $final_output ) ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + $files_written = $this->create_files( array( $filename => $final_output ), $force ); $this->log_whether_files_written( $files_written, $skip_message = "Skipped creating $filename", @@ -191,6 +198,10 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * * [--sassify] * : Include stylesheets as SASS + * + * [--force] + * : Overwrite files that already exist. + * */ function _s( $args, $assoc_args ) { @@ -206,7 +217,8 @@ function _s( $args, $assoc_args ) { ) ); $_s_theme_path = "$theme_path/$data[theme_name]"; - $should_write_file = $this->prompt_if_files_will_be_overwritten( $_s_theme_path ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + $should_write_file = $this->prompt_if_files_will_be_overwritten( $_s_theme_path, $force ); if ( ! $should_write_file ) { WP_CLI::log( 'No files created' ); die; @@ -292,6 +304,9 @@ function _s( $args, $assoc_args ) { * [--enable-network] * : Enable the newly created child theme for the entire network. * + * [--force] + * : Overwrite files that already exist. + * * @subcommand child-theme */ function child_theme( $args, $assoc_args ) { @@ -312,10 +327,11 @@ function child_theme( $args, $assoc_args ) { $this->maybe_create_themes_dir(); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( $theme_style_path => Utils\mustache_render( 'child_theme.mustache', $data ), $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) - ) ); + ), $force ); $this->log_whether_files_written( $files_written, $skip_message = 'All theme files were skipped.', @@ -376,6 +392,9 @@ private function get_output_path( $assoc_args, $subdir ) { * <dir> * : The package directory to generate tests for. * + * [--force] + * : Overwrite files that already exist. + * * ## EXAMPLE * * wp scaffold package-tests /path/to/command/dir/ @@ -432,7 +451,8 @@ public function package_tests( $args, $assoc_args ) { $file_path = $dir . basename( $file ); $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml' ), $file_path ); - $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path, $force ); if ( ! $should_write_file ) continue; $files_written[] = $file_path; @@ -472,6 +492,10 @@ public function package_tests( $args, $assoc_args ) { * * [--activate-network] * : Network activate the newly generated plugin. + * + * [--force] + * : Overwrite files that already exist. + * */ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; @@ -496,12 +520,13 @@ function plugin( $args, $assoc_args ) { $plugin_path = "$plugin_dir/$plugin_slug.php"; $plugin_readme_path = "$plugin_dir/readme.txt"; + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( $plugin_path => Utils\mustache_render( 'plugin.mustache', $data ), $plugin_readme_path => Utils\mustache_render( 'plugin-readme.mustache', $data ), "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), - ) ); + ), $force ); $this->log_whether_files_written( $files_written, @@ -510,7 +535,7 @@ function plugin( $args, $assoc_args ) { ); if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-tests' ) ) { - WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ), array( 'dir' => $plugin_dir ) ); + WP_CLI::run_command( array( 'scaffold', 'plugin-tests', $plugin_slug ), array( 'dir' => $plugin_dir, 'force' => $force ) ); } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { @@ -545,6 +570,9 @@ function plugin( $args, $assoc_args ) { * [--dir=<dirname>] * : Generate test files for a non-standard plugin path. If no plugin slug is specified, the directory name is used. * + * [--force] + * : Overwrite files that already exist. + * * ## EXAMPLE * * wp scaffold plugin-tests hello @@ -579,8 +607,9 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->mkdir( $tests_dir ); $wp_filesystem->mkdir( $bin_dir ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( "$tests_dir/bootstrap.php" => - Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ) ); + Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ), $force ); $to_copy = array( 'install-wp-tests.sh' => $bin_dir, @@ -591,8 +620,8 @@ function plugin_tests( $args, $assoc_args ) { foreach ( $to_copy as $file => $dir ) { $file_name = "$dir/$file"; - - $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_name ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_name, $force ); if ( ! $should_write_file ) continue; $files_written[] = $file_name; @@ -610,12 +639,12 @@ function plugin_tests( $args, $assoc_args ) { ); } - private function create_files( $files_and_contents ) { + private function create_files( $files_and_contents, $force ) { $wp_filesystem = $this->init_wp_filesystem(); $wrote_files = array(); foreach ( $files_and_contents as $filename => $contents ) { - $should_write_file = $this->prompt_if_files_will_be_overwritten( $filename ); + $should_write_file = $this->prompt_if_files_will_be_overwritten( $filename, $force ); if ( $should_write_file ) { $wp_filesystem->mkdir( dirname( $filename ) ); @@ -630,14 +659,23 @@ private function create_files( $files_and_contents ) { return $wrote_files; } - private function prompt_if_files_will_be_overwritten( $filename ) { + private function prompt_if_files_will_be_overwritten( $filename, $force ) { $should_write_file = true; - if ( file_exists( $filename ) ) { - WP_CLI::warning( 'File already exists:' ); - WP_CLI::log( $filename ); - $should_write_file = WP_CLI::prompt( 'Skip this file, or replace it with scaffolding?' ); - WP_CLI::log( PHP_EOL ); + if ( ! file_exists( $filename ) ) { + return true; } + + WP_CLI::warning( $filename . ' already exists.' ); + if ( ! $force ) { + $should_write_file = WP_CLI::prompt( + $question = 'Skip this file, or replace it with scaffolding?', + $default = false, + $answers = array( 's', 'r' ), + $hide = false + ); + } + WP_CLI::log( $should_write_file ? 'Replaced' : 'Skipped' ); + return $should_write_file; } From 998883c02363b2b82b8f25af5320ed1ad6a9726c Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Wed, 3 Jun 2015 13:42:59 -0500 Subject: [PATCH 3604/4858] removes @wip from behat test --- features/search-replace.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 4f950768ac..f684f9ed4d 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -81,7 +81,7 @@ Feature: Do global search/replace Checking: wp_posts.post_title 1 rows affected """ - @wip + Scenario: Regex search/replace Given a WP install When I run `wp search-replace '(Hello)\s(world)' '$2, $1' --regex` From 1505c7d4d8f3e61dd8b1ba5d03728cc81c2b77fa Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Wed, 3 Jun 2015 14:09:28 -0500 Subject: [PATCH 3605/4858] pulls SearchReplacer->str_replace() into SearchReplacer->_run() --- php/WP_CLI/SearchReplacer.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/php/WP_CLI/SearchReplacer.php b/php/WP_CLI/SearchReplacer.php index d888eb81a8..45181703ba 100644 --- a/php/WP_CLI/SearchReplacer.php +++ b/php/WP_CLI/SearchReplacer.php @@ -81,7 +81,11 @@ private function _run( $data, $serialised, $recursion_level = 0, &$visited_data } else if ( is_string( $data ) ) { - $data = $this->str_replace( $this->from, $this->to, $data ); + if ( $this->regex ) { + $data = preg_replace( "/$from/", $to, $data ); + } else { + $data = str_replace( $from, $to, $data ); + } } if ( $serialised ) @@ -93,13 +97,5 @@ private function _run( $data, $serialised, $recursion_level = 0, &$visited_data return $data; } - - private function str_replace( $from, $to, $data ) { - if ( $this->regex ) { - return preg_replace( "/$from/", $to, $data ); - } else { - return str_replace( $from, $to, $data ); - } - } } From 59d6036f168b3b0cf33b225b1d79aa75387652c5 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Thu, 4 Jun 2015 00:20:12 -0500 Subject: [PATCH 3606/4858] converted spaces to tabs --- php/class-wp-cli.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index dce06ca232..0f4ef5c840 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -286,21 +286,21 @@ public static function confirm( $question, $assoc_args = array() ) { } } - /** - * Prompt before continuing. - * - * @param string $question The question to pose - * @param bool $default The default response - * @param array $answers when the users responds with $answers[0] return false, with $answers[1] return true - * @param bool $hide Hide the user's response - * @return bool - */ + /** + * Prompt before continuing. + * + * @param string $question The question to pose + * @param bool $default The default response + * @param array $answers when the users responds with $answers[0] return false, with $answers[1] return true + * @param bool $hide Hide the user's response + * @return bool + */ public static function prompt( $question, $default = false, $answers = array( 'no', 'yes' ), $hide = false ) { - $marker = '[' . implode( '/', $answers ) . ']: '; + $marker = '[' . implode( '/', $answers ) . ']: '; - do { - $answer = cli\prompt( $question, $default, $marker, $hide ); - } while ( ! in_array( $answer, $answers ) ); + do { + $answer = cli\prompt( $question, $default, $marker, $hide ); + } while ( ! in_array( $answer, $answers ) ); return $answers[ 1 ] === $answer; } From 796ca695a1625889248f8b1e8215d9f0e363f8ca Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Thu, 4 Jun 2015 00:26:36 -0500 Subject: [PATCH 3607/4858] improves file overwrite prompt output --- php/commands/scaffold.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 18f44ffd51..9422c443b5 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -665,7 +665,8 @@ private function prompt_if_files_will_be_overwritten( $filename, $force ) { return true; } - WP_CLI::warning( $filename . ' already exists.' ); + WP_CLI::warning( 'File already exists' ); + WP_CLI::log( $filename ); if ( ! $force ) { $should_write_file = WP_CLI::prompt( $question = 'Skip this file, or replace it with scaffolding?', @@ -674,7 +675,8 @@ private function prompt_if_files_will_be_overwritten( $filename, $force ) { $hide = false ); } - WP_CLI::log( $should_write_file ? 'Replaced' : 'Skipped' ); + $outcome = $should_write_file ? 'Replaced' : 'Skipped'; + WP_CLI::log( $outcome . PHP_EOL ); return $should_write_file; } From 8e16143b4da654dd402d24ddafb136acc5dff47a Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Thu, 4 Jun 2015 00:30:06 -0500 Subject: [PATCH 3608/4858] fixes my last commit... --- php/WP_CLI/SearchReplacer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/SearchReplacer.php b/php/WP_CLI/SearchReplacer.php index 45181703ba..d832ed2b3c 100644 --- a/php/WP_CLI/SearchReplacer.php +++ b/php/WP_CLI/SearchReplacer.php @@ -82,9 +82,9 @@ private function _run( $data, $serialised, $recursion_level = 0, &$visited_data else if ( is_string( $data ) ) { if ( $this->regex ) { - $data = preg_replace( "/$from/", $to, $data ); + $data = preg_replace( "/$this->from/", $this->to, $data ); } else { - $data = str_replace( $from, $to, $data ); + $data = str_replace( $this->from, $this->to, $data ); } } From 49c79ce17b1cc2f78acb43432ace2e5e5088c417 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Thu, 4 Jun 2015 15:15:10 -0500 Subject: [PATCH 3609/4858] fixes formatting issues --- features/scaffold.feature | 3 +-- php/commands/scaffold.php | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index db258777f1..01e5aab284 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -337,7 +337,6 @@ Feature: WordPress code scaffolding Error: Could not decompress your theme files """ - @wip Scenario: Overwrite existing files Given a WP install When I run `wp scaffold plugin test` @@ -349,4 +348,4 @@ Feature: WordPress code scaffolding And STDOUT should contain: """ Replaced - """ \ No newline at end of file + """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 9422c443b5..d7675dc459 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -453,7 +453,9 @@ public function package_tests( $args, $assoc_args ) { $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path, $force ); - if ( ! $should_write_file ) continue; + if ( ! $should_write_file ) { + continue; + } $files_written[] = $file_path; $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); From 77498838ddd07aecb83c015c9a384c85f9649b4c Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Thu, 4 Jun 2015 15:30:13 -0500 Subject: [PATCH 3610/4858] moved prompt method into scaffold command. fixed a logic error in prompt_if_files_will_be_overwritten --- php/class-wp-cli.php | 19 ------------------- php/commands/scaffold.php | 22 +++++++++++++--------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0f4ef5c840..44bf9ace53 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -286,25 +286,6 @@ public static function confirm( $question, $assoc_args = array() ) { } } - /** - * Prompt before continuing. - * - * @param string $question The question to pose - * @param bool $default The default response - * @param array $answers when the users responds with $answers[0] return false, with $answers[1] return true - * @param bool $hide Hide the user's response - * @return bool - */ - public static function prompt( $question, $default = false, $answers = array( 'no', 'yes' ), $hide = false ) { - $marker = '[' . implode( '/', $answers ) . ']: '; - - do { - $answer = cli\prompt( $question, $default, $marker, $hide ); - } while ( ! in_array( $answer, $answers ) ); - - return $answers[ 1 ] === $answer; - } - /** * Read value from a positional argument or from STDIN. * diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d7675dc459..6044380548 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -647,11 +647,12 @@ private function create_files( $files_and_contents, $force ) { foreach ( $files_and_contents as $filename => $contents ) { $should_write_file = $this->prompt_if_files_will_be_overwritten( $filename, $force ); - - if ( $should_write_file ) { - $wp_filesystem->mkdir( dirname( $filename ) ); + if ( ! $should_write_file ) { + continue; } + $wp_filesystem->mkdir( dirname( $filename ) ); + if ( ! $wp_filesystem->put_contents( $filename, $contents ) ) { WP_CLI::error( "Error creating file: $filename" ); } elseif ( $should_write_file ) { @@ -670,13 +671,16 @@ private function prompt_if_files_will_be_overwritten( $filename, $force ) { WP_CLI::warning( 'File already exists' ); WP_CLI::log( $filename ); if ( ! $force ) { - $should_write_file = WP_CLI::prompt( - $question = 'Skip this file, or replace it with scaffolding?', - $default = false, - $answers = array( 's', 'r' ), - $hide = false - ); + do { + $answer = cli\prompt( + 'Skip this file, or replace it with scaffolding?', + $default = false, + $marker = '[s/r]: ' + ); + } while ( ! in_array( $answer, array( 's', 'r' ) ) ); + $should_write_file = 'r' === $answer; } + $outcome = $should_write_file ? 'Replaced' : 'Skipped'; WP_CLI::log( $outcome . PHP_EOL ); From eb7ae1f7017e5d217cb1d6fd3dd75fbc105a33d4 Mon Sep 17 00:00:00 2001 From: Kevin Doole <kdoole@farmmedia.com> Date: Thu, 4 Jun 2015 15:39:02 -0500 Subject: [PATCH 3611/4858] for accuracy, changed copy in logged outcome of skip/replace prompt --- features/scaffold.feature | 2 +- php/commands/scaffold.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 01e5aab284..fc7aeea934 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -347,5 +347,5 @@ Feature: WordPress code scaffolding """ And STDOUT should contain: """ - Replaced + Replacing """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 6044380548..1db452d185 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -681,7 +681,7 @@ private function prompt_if_files_will_be_overwritten( $filename, $force ) { $should_write_file = 'r' === $answer; } - $outcome = $should_write_file ? 'Replaced' : 'Skipped'; + $outcome = $should_write_file ? 'Replacing' : 'Skipping'; WP_CLI::log( $outcome . PHP_EOL ); return $should_write_file; From f149f0dde7050c514350287e1dea0c4974dbb9bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 8 Jun 2015 14:35:02 -0700 Subject: [PATCH 3612/4858] Internalize `wp_clean_update_cache()` to prevent fatals in WP 4.0 The function was introduced in WP 4.1 --- php/WP_CLI/CommandWithTranslation.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index b46ed12747..e83e393421 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -58,7 +58,7 @@ public function list_( $args, $assoc_args ) { $translations = $this->get_all_languages(); $available = $this->get_installed_languages(); - wp_clean_update_cache(); // Clear existing update caches. + $this->wp_clean_update_cache(); // Clear existing update caches. wp_version_check(); // Check for Core translation updates. wp_update_themes(); // Check for Theme translation updates. wp_update_plugins(); // Check for Plugin translation updates. @@ -159,7 +159,7 @@ public function update( $args, $assoc_args ) { return; } - wp_clean_update_cache(); // Clear existing update caches. + $this->wp_clean_update_cache(); // Clear existing update caches. wp_version_check(); // Check for Core translation updates. wp_update_themes(); // Check for Theme translation updates. wp_update_plugins(); // Check for Plugin translation updates. @@ -369,4 +369,17 @@ protected function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields, $this->obj_type ); } + /** + * Replicates wp_clean_update_cache() for use in WP 4.0 + */ + private static function wp_clean_update_cache() { + if ( function_exists( 'wp_clean_plugins_cache' ) ) { + wp_clean_plugins_cache(); + } else { + delete_site_transient( 'update_plugins' ); + } + wp_clean_themes_cache(); + delete_site_transient( 'update_core' ); + } + } From 429d4e590ebb70fa7b7e5d8bfedfd5cd21805e66 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 8 Jun 2015 14:58:33 -0700 Subject: [PATCH 3613/4858] Switch tests to WP 4.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9ab5b14b72..58b187c0d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=4.1 + - WP_VERSION=4.2 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: From 4242406c71100559064a7ed2113088f2d5549ea9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 8 Jun 2015 15:56:27 -0700 Subject: [PATCH 3614/4858] Only run `help` early when WordPress isn't loaded When WordPress is loaded, we may have a plugin adding commands to a namespace --- features/help.feature | 28 ++++++++++++++++++++++++++++ php/WP_CLI/Runner.php | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index e94455d515..d73cde31ed 100644 --- a/features/help.feature +++ b/features/help.feature @@ -129,3 +129,31 @@ Feature: Get help about WP-CLI commands """ __destruct """ + + Scenario: Help for commands loaded into existing namespaces + Given a WP install + And a wp-content/plugins/test-cli/command.php file: + """ + <?php + // Plugin Name: Test CLI Extra Site Command + + class Test_CLI_Extra_Site_Command extends WP_CLI_Command { + + /** + * A dummy command. + * + * @subcommand my-command + */ + function my_command() {} + + } + + WP_CLI::add_command( 'site test-extra', 'Test_CLI_Extra_Site_Command' ); + """ + And I run `wp plugin activate test-cli` + + When I run `wp help site` + Then STDOUT should contain: + """ + test-extra + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c2e29132d7..218a72a13f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -596,7 +596,7 @@ public function before_wp_load() { self::set_wp_root( $this->find_wp_root() ); // First try at showing man page - if ( 'help' === $this->arguments[0] && ( isset( $this->arguments[1] ) || !$this->wp_exists() ) ) { + if ( 'help' === $this->arguments[0] && ! $this->wp_exists() ) { $this->_run_command(); } From 5cd6baeede34a3b47a908e16b262b8a0e6dad782 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Tue, 9 Jun 2015 18:47:40 +0100 Subject: [PATCH 3615/4858] Correct the error message text in `wp cli update` If the `wp cli update` command errors, it tells you to attempt `wp cli self-update` again, which is incorrect. --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 2c2d078a66..e578e4b04d 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -177,7 +177,7 @@ public function update( $_, $assoc_args ) { if ( 0 !== $status ) { WP_CLI::error_multi_line( $output ); - WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli self-update again.' ); + WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli update again.' ); } WP_CLI::log( 'New version works. Proceeding to replace.' ); From d015fa84cfcb1211cabd7b530e59e2db91623c0a Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Sat, 20 Jun 2015 16:08:42 +0100 Subject: [PATCH 3616/4858] Update the Travis notification syntax The [Travis linter](http://lint.travis-ci.org/) complains about the `notifications` syntax as it is currently. This fixes that. --- templates/.travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index b4393cc7da..cd4bc26e79 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -1,8 +1,9 @@ language: php notifications: - on_success: never - on_failure: change + email: + on_success: never + on_failure: change php: - 5.3 From 3d115990b19cc416194c2946b3da5a1d88b9213c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Jun 2015 13:04:36 -0700 Subject: [PATCH 3617/4858] Restore expected behavior of `WP_TESTS_DIR` environment variable In 49e9a59f5c47513a1581a3f5260a70c0350c27c1, the default value was changed to include `includes` in the path. Because this change broke compatibility with existing use of `WP_TESTS_DIR`, and broke scaffolding generally, we should restore the expected behavior. --- templates/install-wp-tests.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 6b2d4aefdc..c96a09f17d 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -11,7 +11,7 @@ DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-latest} -WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib/includes} +WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} set -ex @@ -53,21 +53,21 @@ install_test_suite() { fi # set up testing suite if it doesn't yet exist - if [ ! "$(ls -A $WP_TESTS_DIR)" ]; then + if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR - svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR + svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR/includes fi cd $WP_TESTS_DIR if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php $(dirname ${WP_TESTS_DIR})/wp-tests-config.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" $(dirname ${WP_TESTS_DIR})/wp-tests-config.php + download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php fi } From e20d953b4321c99a746e9291baf4364ceb4cd9fd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Jun 2015 14:06:51 -0700 Subject: [PATCH 3618/4858] Bump to latest version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 41915c7994..61e6e92d91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.19.1 +0.19.2 From f83b66637c264ee5599897d772131d5fcbb40ee0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Jun 2015 14:15:25 -0700 Subject: [PATCH 3619/4858] Backtick `wp rewrite flush` snippet, so it gets formatted in docs --- php/commands/rewrite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index f7df4ff5a0..d2d8e59425 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -17,8 +17,8 @@ class Rewrite_Command extends WP_CLI_Command { * To regenerate a .htaccess file with WP-CLI, you'll need to add the mod_rewrite module * to your wp-cli.yml or config.yml. For example: * - * apache_modules: - * - mod_rewrite + * `apache_modules: + * - mod_rewrite` * * ## OPTIONS * From b315fca810fce7307fa94c952cb7dc125708fd86 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 20 Jun 2015 14:24:12 -0700 Subject: [PATCH 3620/4858] Support `Requests` installed to parent project in `http_request()` --- php/utils.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/php/utils.php b/php/utils.php index 1dd6bd2b6f..88d504657a 100644 --- a/php/utils.php +++ b/php/utils.php @@ -440,6 +440,24 @@ function replace_path_consts( $source, $path ) { * @return object */ function http_request( $method, $url, $data = null, $headers = array(), $options = array() ) { + + $cert_path = '/rmccue/requests/library/Requests/Transport/cacert.pem'; + if ( inside_phar() ) { + // cURL can't read Phar archives + $options['verify'] = extract_from_phar( + WP_CLI_ROOT . '/vendor' . $cert_path ); + } else { + foreach( get_vendor_paths() as $vendor_path ) { + if ( file_exists( $vendor_path . $cert_path ) ) { + $options['verify'] = $vendor_path . $cert_path; + break; + } + } + if ( empty( $options['verify'] ) ){ + WP_CLI::error_log( "Cannot find SSL certificate." ); + } + } + // cURL can't read Phar archives $options['verify'] = extract_from_phar( WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); From 4d789c09f637fa55a6529a4d3f2fb3419cc882e4 Mon Sep 17 00:00:00 2001 From: Morgan Estes <morgan.estes@gmail.com> Date: Tue, 23 Jun 2015 21:19:06 -0500 Subject: [PATCH 3621/4858] Fixed the 'realy' typo that annoyed me. --- php/commands/media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 0f6117b2cd..dc83e9050d 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -31,7 +31,7 @@ class Media_Command extends WP_CLI_Command { */ function regenerate( $args, $assoc_args = array() ) { if ( empty( $args ) ) { - WP_CLI::confirm( 'Do you realy want to regenerate all images?', $assoc_args ); + WP_CLI::confirm( 'Do you really want to regenerate all images?', $assoc_args ); } $skip_delete = \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-delete' ); From e2adbe4722413036b8f81548f1437ff2ac4b1918 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 24 Jun 2015 03:49:47 -0700 Subject: [PATCH 3622/4858] Catch failure to extract WordPress archive file And provide a helpful error message --- php/commands/core.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d5f5d3c5dd..0a82e617c0 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -178,7 +178,12 @@ public function download( $args, $assoc_args ) { } else if ( 20 != substr( $response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})" ); } - self::_extract( $temp, ABSPATH ); + + try { + self::_extract( $temp, ABSPATH ); + } catch ( Exception $e ) { + WP_CLI::error( "Couldn't extract WordPress archive. " . $e->getMessage() ); + } $cache->import( $cache_key, $temp ); unlink($temp); } From d293c04506a05d1cc705b0723eaddb71f26b6a5c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 24 Jun 2015 03:54:17 -0700 Subject: [PATCH 3623/4858] Remove code missed in b315fca810fce7307fa94c952cb7dc125708fd86 --- php/utils.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/utils.php b/php/utils.php index 88d504657a..78cda6bdcc 100644 --- a/php/utils.php +++ b/php/utils.php @@ -458,10 +458,6 @@ function http_request( $method, $url, $data = null, $headers = array(), $options } } - // cURL can't read Phar archives - $options['verify'] = extract_from_phar( - WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); - try { $request = \Requests::request( $url, $headers, $data, $method, $options ); return $request; From e2bc7220cddaa3833045385d1171869849c77d22 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 24 Jun 2015 04:45:42 -0700 Subject: [PATCH 3624/4858] Document one-liner for listing all plugins in a network --- php/commands/plugin.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 2a941cba63..3a6e27fbdc 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -608,6 +608,9 @@ function delete( $args, $assoc_args = array() ) { * * wp plugin list --status=active --format=json * + * # List plugins on each site in a network + * wp site list --field=url | xargs -n 1 -I % wp plugin list --url=% + * * @subcommand list */ public function list_( $_, $assoc_args ) { From bdf63466bd8258faeafc587ff9eca036274b4585 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 24 Jun 2015 04:56:09 -0700 Subject: [PATCH 3625/4858] Failing test case for checking cached partial upgrades --- features/core.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/core.feature b/features/core.feature index 3fa82fe65c..f8769736c6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -652,3 +652,19 @@ Feature: Manage WordPress installation """ Error: Release not found. """ + + Scenario: Ensure cached partial upgrades aren't used in full upgrade + Given a WP install + And an empty cache + + When I run `wp core download --version=4.2.1 --force` + And I run `wp core update` + Then STDOUT should not be empty + + When I run `wp core download --version=4.1.1 --force` + And I run `wp core update` + And I run `wp core verify-checksums` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ From 10305edbbe636a96a46ec323142c336a3bb6864b Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Wed, 24 Jun 2015 20:05:45 -0700 Subject: [PATCH 3626/4858] accept associative args with no right-side data --- php/WP_CLI/Configurator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index f8120926ff..21ae2ad3f1 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -89,7 +89,7 @@ public static function extract_assoc( $arguments ) { $assoc_args[] = array( $matches[1], false ); } elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { $assoc_args[] = array( $matches[1], true ); - } elseif ( preg_match( '|^--([^=]+)=(.+)|s', $arg, $matches ) ) { + } elseif ( preg_match( '|^--([^=]+)=(.*)|s', $arg, $matches ) ) { $assoc_args[] = array( $matches[1], $matches[2] ); } else { $positional_args[] = $arg; From e5a12ee02234a5cd14d887f87f8705e84cbe6dbe Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Fri, 26 Jun 2015 13:23:36 -0700 Subject: [PATCH 3627/4858] add configurator::extract_assoc unit tests --- tests/test-configurator.php | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tests/test-configurator.php diff --git a/tests/test-configurator.php b/tests/test-configurator.php new file mode 100644 index 0000000000..55c291acbd --- /dev/null +++ b/tests/test-configurator.php @@ -0,0 +1,51 @@ +<?php + +use WP_CLI\Configurator; + +class ConfiguratorTest extends PHPUnit_Framework_TestCase { + + function testExtractAssoc() { + $args = Configurator::extract_assoc( array( 'foo', '--bar', '--baz=text' ) ); + + $this->assertCount( 1, $args[0] ); + $this->assertCount( 2, $args[1] ); + + $this->assertEquals( 'foo', $args[0][0] ); + + $this->assertEquals( 'bar', $args[1][0][0] ); + $this->assertTrue( $args[1][0][1] ); + + $this->assertEquals( 'baz', $args[1][1][0] ); + $this->assertEquals( 'text', $args[1][1][1] ); + + } + + function testExtractAssocNoValue() { + $args = Configurator::extract_assoc( array( 'foo', '--bar=', '--baz=text' ) ); + + $this->assertCount( 1, $args[0] ); + $this->assertCount( 2, $args[1] ); + + $this->assertEquals( 'foo', $args[0][0] ); + + $this->assertEquals( 'bar', $args[1][0][0] ); + $this->assertEmpty( $args[1][0][1] ); + + $this->assertEquals( 'baz', $args[1][1][0] ); + $this->assertEquals( 'text', $args[1][1][1] ); + + } + + function testExtractAssocDoubleDashInValue() { + $args = Configurator::extract_assoc( array( '--test=text--text' ) ); + + $this->assertCount( 0, $args[0] ); + $this->assertCount( 1, $args[1] ); + + $this->assertEquals( 'test', $args[1][0][0] ); + $this->assertEquals( 'text--text', $args[1][0][1] ); + + } + + +} \ No newline at end of file From 0b8a45d78e0f24c9bf12fb1ebd7943860027c716 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 29 Jun 2015 09:47:01 -0300 Subject: [PATCH 3628/4858] exit with a message when --url parameter is used with a unexistent site url --- features/flags.feature | 9 +++++++++ php/wp-settings-cli.php | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index 064648099e..912c1ab6ae 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -13,6 +13,15 @@ Feature: Global flags } """ + Scenario: Invalid URL + Given a WP multisite install + + When I try `wp post list --url=invalid.example.com` + Then STDERR should be: + """ + Error: Site invalid.example.com not found. + """ + Scenario: Quiet run Given a WP install diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 6944f37978..f942830257 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -76,6 +76,13 @@ unset( $values, $key, $value ); } +// In a multisite install, die if unable to find site given in --url parameter +if ( is_multisite() ) { + add_action( 'ms_site_not_found', function( $current_site, $domain, $path ) { + WP_CLI::error( "Site {$domain}{$path} not found." ); + }, 10, 3 ); +} + // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); From 5d136aea03cd6b28f682edece6119a58606354de Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 29 Jun 2015 14:55:48 -0300 Subject: [PATCH 3629/4858] run test only if wp_version >= 3.9 the hook ms_site_not_found was introduced in version 3.9 --- features/flags.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/flags.feature b/features/flags.feature index 912c1ab6ae..b50006f240 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -13,6 +13,7 @@ Feature: Global flags } """ + @require-wp-3.9 Scenario: Invalid URL Given a WP multisite install From c3eb7391b86239fd9f40a1ae28c6539c5ea4a5f7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 6 Jul 2015 09:25:24 -0700 Subject: [PATCH 3630/4858] Remove redundant `@subcommand` tag --- php/commands/cli.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index e578e4b04d..71053c4a33 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -133,8 +133,6 @@ public function check_update( $_, $assoc_args ) { * * [--yes] * : Do not prompt for confirmation - * - * @subcommand update */ public function update( $_, $assoc_args ) { if ( ! Utils\inside_phar() ) { From fa1d278121d7fbe614d55746e10f2b8bfd9abbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 16 Jul 2015 20:59:53 +0200 Subject: [PATCH 3631/4858] Fixing bash completion for now, closes #1919 --- utils/wp-completion.bash | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/wp-completion.bash b/utils/wp-completion.bash index 94896ca524..9df572b6d6 100644 --- a/utils/wp-completion.bash +++ b/utils/wp-completion.bash @@ -1,6 +1,7 @@ # bash completion for the `wp` command _wp_complete() { + local OLD_IFS="$IFS" local cur=${COMP_WORDS[COMP_CWORD]} IFS=$'\n'; # want to preserve spaces at the end @@ -15,5 +16,8 @@ _wp_complete() { else COMPREPLY=( ${opts[*]} ) fi + + IFS="$OLD_IFS" + return 0 } complete -o nospace -F _wp_complete wp From ca6348caf7fb085cdaf424a653dae4de4e03da83 Mon Sep 17 00:00:00 2001 From: Akeda Bagus <admin@gedex.web.id> Date: Sun, 19 Jul 2015 00:29:14 +0700 Subject: [PATCH 3632/4858] Fix delete user help message. It should 'delete' instead of 'update'. --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 1a255792a0..08b173be50 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -158,7 +158,7 @@ public function get( $args, $assoc_args ) { * ## OPTIONS * * <user>... - * : The user login, user email, or user ID of the user(s) to update. + * : The user login, user email, or user ID of the user(s) to delete. * * [--network] * : On multisite, delete the user from the entire network. From 204079e246a4362f66ade613fbb42c45658f0006 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Jul 2015 07:44:06 -0700 Subject: [PATCH 3633/4858] Properly pass error message to `error_multi_line()` in `cli update` `exec()` only _returns_ the last line, and renders the rest. `WP_CLI\Process` is more versatile for our needs --- php/commands/cli.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 71053c4a33..ee7114e07f 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -170,11 +170,11 @@ public function update( $_, $assoc_args ) { Utils\http_request( 'GET', $download_url, null, $headers, $options ); - exec( "php $temp --version", $output, $status ); - - if ( 0 !== $status ) { - WP_CLI::error_multi_line( $output ); - + $process = WP_CLI\Process::create( "php $temp --version" ); + $result = $process->run(); + if ( 0 !== $result->return_code ) { + $multi_line = explode( PHP_EOL, $result->stderr ); + WP_CLI::error_multi_line( $multi_line ); WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli update again.' ); } From 366d60274647e40537a5b0509ece60c1f2732030 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Jul 2015 08:00:34 -0700 Subject: [PATCH 3634/4858] Pass thru `--allow-root` in `cli update` This will let root update WP-CLI when it errored previously --- php/commands/cli.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index ee7114e07f..837ee4b8d8 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -170,7 +170,8 @@ public function update( $_, $assoc_args ) { Utils\http_request( 'GET', $download_url, null, $headers, $options ); - $process = WP_CLI\Process::create( "php $temp --version" ); + $allow_root = WP_CLI::get_runner()->config['allow-root'] ? '--allow-root' : ''; + $process = WP_CLI\Process::create( "php $temp --version {$allow_root}" ); $result = $process->run(); if ( 0 !== $result->return_code ) { $multi_line = explode( PHP_EOL, $result->stderr ); From dbb358d6978266bd9581a593d824f5e95cd01379 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Jul 2015 08:09:59 -0700 Subject: [PATCH 3635/4858] Prevent error notice in `cli update` ``` PHP Warning: unlink(/tmp/wp-cli-cacert.pem): No such file or directory in phar:///home/vagrant/.wp-cli/test.phar/php/utils.php on line 28 ``` Because we make a remote request against Github twice, the shutdown function is registered (and called) twice. The file is deleted the first time. --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 78cda6bdcc..2bfa71d787 100644 --- a/php/utils.php +++ b/php/utils.php @@ -24,7 +24,7 @@ function extract_from_phar( $path ) { copy( $path, $tmp_path ); register_shutdown_function( function() use ( $tmp_path ) { - unlink( $tmp_path ); + @unlink( $tmp_path ); } ); return $tmp_path; From d8895b6ad3c8fd3706b4c7f528d3f3df2d6a1252 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 21 Jul 2015 08:55:29 -0700 Subject: [PATCH 3636/4858] Use `wp (plugin|theme) update --format=summary` for one-liner messages --- features/plugin.feature | 7 +++++-- features/theme.feature | 7 +++++-- php/WP_CLI/CommandWithUpgrade.php | 28 +++++++++++++++++----------- php/commands/plugin.php | 3 +++ php/commands/theme.php | 3 +++ 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index cee0eb4a75..0eb663708e 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -118,8 +118,11 @@ Feature: Manage WordPress plugins Error: Please specify one or more plugins, or use --all. """ - When I run `wp plugin update --all` - Then STDOUT should not be empty + When I run `wp plugin update --all --format=summary | grep 'updated successfully from'` + Then STDOUT should contain: + """ + Akismet updated successfully from version 2.5.6 to version + """ Scenario: Activate a network-only plugin on single site Given a WP install diff --git a/features/theme.feature b/features/theme.feature index c8557e4683..cf8143185b 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -78,8 +78,11 @@ Feature: Manage WordPress themes Error: Please specify one or more themes, or use --all. """ - When I run `wp theme update --all` - Then STDOUT should not be empty + When I run `wp theme update --all --format=summary | grep 'updated successfully from'` + Then STDOUT should contain: + """ + P2 updated successfully from version 1.4.1 to version + """ Scenario: Get the path of an installed theme Given a WP install diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 6119b8b01f..d4c526ddf7 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -264,18 +264,24 @@ protected function update_many( $args, $assoc_args ) { \WP_CLI::error( $line ); } - if ($num_to_update > 0) { - $status = array(); - foreach($items_to_update as $item_to_update => $info) { - $status[$item_to_update] = array( - 'name' => $info['name'], - 'old_version' => $info['version'], - 'new_version' => $info['update_version'], - 'status' => $result[$item_to_update] !== null ? 'Updated' : 'Error', - ); + if ( $num_to_update > 0 ) { + if ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) { + foreach( $items_to_update as $item_to_update => $info ) { + $message = $result[$item_to_update] !== null ? 'updated successfully' : 'did not update'; + \WP_CLI::log( "{$info['title']} {$message} from version {$info['version']} to version {$info['update_version']}" ); + } + } else { + $status = array(); + foreach($items_to_update as $item_to_update => $info) { + $status[$item_to_update] = array( + 'name' => $info['name'], + 'old_version' => $info['version'], + 'new_version' => $info['update_version'], + 'status' => $result[$item_to_update] !== null ? 'Updated' : 'Error', + ); + } + \WP_CLI\Utils\format_items( 'table', $status, array( 'name', 'old_version', 'new_version', 'status' ) ); } - \WP_CLI\Utils\format_items( 'table', $status, - array( 'name', 'old_version', 'new_version', 'status' ) ); } } diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 3a6e27fbdc..5b3860fadb 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -331,6 +331,9 @@ protected function install_from_repo( $slug, $assoc_args ) { * [--all] * : If set, all plugins that have updates will be updated. * + * [--format=<format>] + * : Output summary as table or summary. Defaults to table. + * * [--version=<version>] * : If set, the plugin will be updated to the specified version. * diff --git a/php/commands/theme.php b/php/commands/theme.php index 254afc9491..0cebcebfa4 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -443,6 +443,9 @@ public function get( $args, $assoc_args ) { * [--all] * : If set, all themes that have updates will be updated. * + * [--format=<format>] + * : Output summary as table or summary. Defaults to table. + * * [--version=<version>] * : If set, the plugin will be updated to the specified version. * From 7b2e1e7382a4ef15bce249d95ac6f678192adbe9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 26 Jul 2015 19:01:05 -0700 Subject: [PATCH 3637/4858] Update core tests to reflect new minor WP version --- features/core.feature | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/features/core.feature b/features/core.feature index 3fa82fe65c..d54e48b726 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,11 +326,11 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2.2 | major | https://wordpress.org/wordpress-4.2.2.zip | - | 4.1.5 | major | https://wordpress.org/wordpress-4.1.5.zip | - | 4.0.5 | major | https://wordpress.org/wordpress-4.0.5.zip | - | 3.9.6 | major | https://wordpress.org/wordpress-3.9.6.zip | - | 3.8.8 | minor | https://wordpress.org/wordpress-3.8.8.zip | + | 4.2.3 | major | https://wordpress.org/wordpress-4.2.3.zip | + | 4.1.6 | major | https://wordpress.org/wordpress-4.1.6.zip | + | 4.0.6 | major | https://wordpress.org/wordpress-4.0.6.zip | + | 3.9.7 | major | https://wordpress.org/wordpress-3.9.7.zip | + | 3.8.9 | minor | https://wordpress.org/wordpress-3.8.9.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -341,10 +341,10 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.2.2 | major | https://wordpress.org/wordpress-4.2.2.zip | - | 4.1.5 | major | https://wordpress.org/wordpress-4.1.5.zip | - | 4.0.5 | major | https://wordpress.org/wordpress-4.0.5.zip | - | 3.9.6 | major | https://wordpress.org/wordpress-3.9.6.zip | + | 4.2.3 | major | https://wordpress.org/wordpress-4.2.3.zip | + | 4.1.6 | major | https://wordpress.org/wordpress-4.1.6.zip | + | 4.0.6 | major | https://wordpress.org/wordpress-4.0.6.zip | + | 3.9.7 | major | https://wordpress.org/wordpress-3.9.7.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -355,7 +355,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.8 | minor | https://wordpress.org/wordpress-3.8.8.zip | + | 3.8.9 | minor | https://wordpress.org/wordpress-3.8.9.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From 06e9d1f27942db745d77980c3702e5c5d3f3d375 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 27 Jul 2015 14:47:50 -0700 Subject: [PATCH 3638/4858] Prevent undefined notice when no `--format=<format>` is supplied ``` PHP Notice: Undefined index: format in /home/vagrant/.wp-cli/php/WP_CLI/CommandWithTerms.php on line 80 ``` --- php/WP_CLI/CommandWithTerms.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/WP_CLI/CommandWithTerms.php b/php/WP_CLI/CommandWithTerms.php index f906f7b3cb..285ae29945 100644 --- a/php/WP_CLI/CommandWithTerms.php +++ b/php/WP_CLI/CommandWithTerms.php @@ -67,6 +67,11 @@ abstract class CommandWithTerms extends \WP_CLI_Command { */ public function list_( $args, $assoc_args ) { + $defaults = array( + 'format' => 'table', + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + $object_id = array_shift( $args ); $taxonomy_names = $args; $taxonomy_args = array(); From 5424174f46faef1bd6894f7a09e5bea8519f3eb6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 27 Jul 2015 15:02:04 -0700 Subject: [PATCH 3639/4858] Failing test case for #1944 --- features/post.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/post.feature b/features/post.feature index 012c61f02a..31d9093061 100644 --- a/features/post.feature +++ b/features/post.feature @@ -216,3 +216,14 @@ Feature: Manage WordPress posts """ 1 """ + + Scenario: Update categories on a post + When I run `wp term create category "Test Category" --porcelain` + Then save STDOUT as {TERM_ID} + + When I run `wp post update 1 --post_category={TERM_ID}` + And I run `wp post term list 1 category --format=json --fields=name` + Then STDOUT should be: + """ + [{"name":"Test Category"}] + """ From e79934b64c6906e3fa8f0316644d82e0a2044016 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 27 Jul 2015 15:04:48 -0700 Subject: [PATCH 3640/4858] Properly handle `post_category` for `wp post update` --- php/commands/post.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/post.php b/php/commands/post.php index e0ae7a8559..3d5fa4557c 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -107,6 +107,10 @@ public function update( $args, $assoc_args ) { break; } + if ( isset( $assoc_args['post_category'] ) ) { + $assoc_args['post_category'] = explode( ',', $assoc_args['post_category'] ); + } + parent::_update( $args, $assoc_args, function ( $params ) { return wp_update_post( $params, true ); } ); From 10167ce3695f450e00184f0db5988578a782eebf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 27 Jul 2015 15:28:58 -0700 Subject: [PATCH 3641/4858] Create a new role from another role with `--clone=<role>` --- features/roles.feature | 41 ++++++++++++++++++++++++++++++++++++++++- php/commands/role.php | 34 +++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index bf62c1c2b0..53ac7046ab 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -10,6 +10,12 @@ Feature: Manage WordPress roles | Subscriber | subscriber | | Editor | editor | + When I run `wp role create reporter Reporter` + Then STDOUT should be: + """ + Success: Role with key reporter created. + """ + Scenario: Resetting a role When I run `wp role reset author` Then STDOUT should be: @@ -41,4 +47,37 @@ Feature: Manage WordPress roles Then STDOUT should be: """ Success: All default roles reset. - """ \ No newline at end of file + """ + + Scenario: Cloning a role + When I try `wp role create reporter Reporter --clone=no-role` + Then STDERR should be: + """ + Error: 'no-role' role not found. + """ + + When I run `wp role create reporter Reporter --clone=author` + Then STDOUT should be: + """ + Success: Role with key reporter created. Cloned capabilities from author. + """ + + When I run `wp role list` + Then STDOUT should be a table containing rows: + | name | role | + | Reporter | reporter | + + When I run `wp cap list reporter` + Then STDOUT should be: + """ + upload_files + edit_posts + edit_published_posts + publish_posts + read + level_2 + level_1 + level_0 + delete_posts + delete_published_posts + """ diff --git a/php/commands/role.php b/php/commands/role.php index 436fb689a4..31b76cf954 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -92,25 +92,49 @@ public function exists( $args ) { * <role-name> * : The publicly visible name of the role. * + * [--clone=<role>] + * : Clone capabilities from an existing role. + * * ## EXAMPLES * * wp role create approver Approver * * wp role create productadmin "Product Administrator" */ - public function create( $args ) { + public function create( $args, $assoc_args ) { + global $wp_roles; + self::persistence_check(); $role_key = array_shift( $args ); $role_name = array_shift( $args ); - if ( empty( $role_key ) || empty( $role_name ) ) + if ( empty( $role_key ) || empty( $role_name ) ) { WP_CLI::error( "Can't create role, insufficient information provided."); + } - if ( ! add_role( $role_key, $role_name ) ) + $capabilities = false; + if ( ! empty( $assoc_args['clone'] ) ) { + $role_obj = $wp_roles->get_role( $assoc_args['clone'] ); + if ( ! $role_obj ) { + WP_CLI::error( "'{$assoc_args['clone']}' role not found." ); + } + $capabilities = array_keys( $role_obj->capabilities ); + } + + if ( add_role( $role_key, $role_name ) ) { + if ( ! empty( $capabilities ) ) { + $role_obj = $wp_roles->get_role( $role_key ); + foreach( $capabilities as $cap ) { + $role_obj->add_cap( $cap ); + } + WP_CLI::success( sprintf( "Role with key %s created. Cloned capabilities from %s.", $role_key, $assoc_args['clone'] ) ); + } else { + WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); + } + } else { WP_CLI::error( "Role couldn't be created." ); - else - WP_CLI::success( sprintf( "Role with key %s created.", $role_key ) ); + } } /** From d4cd2b97087d419c330896efb61751562f49f986 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 27 Jul 2015 16:00:03 -0700 Subject: [PATCH 3642/4858] Designate version in-progress with `-alpha` --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 61e6e92d91..4863f59c36 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.19.2 +0.20.0-alpha From 5ef1cbd413cc20778bb8bf66f8eb9828672fad5e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 31 Jul 2015 09:08:31 -0700 Subject: [PATCH 3643/4858] Document how to delete inactive plugins --- php/commands/plugin.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 3a6e27fbdc..ccf69eb4f6 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -561,6 +561,9 @@ function is_installed( $args, $assoc_args = array() ) { * ## EXAMPLES * * wp plugin delete hello + * + * # Delete inactive plugins + * wp plugin delete $(wp plugin list --status=inactive --field=name) */ function delete( $args, $assoc_args = array() ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { From 2156c86cee6784d3fc7707320f06ce78b9015d20 Mon Sep 17 00:00:00 2001 From: Chris Montgomery <chris@montchr.io> Date: Mon, 3 Aug 2015 23:03:39 -0400 Subject: [PATCH 3644/4858] add doc for CommandWithMeta->get() --- php/WP_CLI/CommandWithMeta.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 9e9b07518f..c2010277b5 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -77,6 +77,12 @@ public function list_( $args, $assoc_args ) { /** * Get meta field value. * + * <id> + * : The ID of the object. + * + * <key> + * : The name of the meta field to get. + * * @synopsis <id> <key> [--format=<format>] */ public function get( $args, $assoc_args ) { From 8ce9199e5938fab754cf1ae482274611195a8431 Mon Sep 17 00:00:00 2001 From: Chris Montgomery <chris@montchr.io> Date: Mon, 3 Aug 2015 23:04:26 -0400 Subject: [PATCH 3645/4858] correct typo in CommandWithMeta->delete() --- php/WP_CLI/CommandWithMeta.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index c2010277b5..97d0c74a20 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -105,7 +105,7 @@ public function get( $args, $assoc_args ) { * : The ID of the object. * * <key> - * : The name of the meta field to create. + * : The name of the meta field to delete. * * [<value>] * : The value to delete. If omitted, all rows with key will deleted. From d9dcff5297e5be2340da4ad7197501d8eb0fa10a Mon Sep 17 00:00:00 2001 From: Chris Montgomery <chris@montchr.io> Date: Mon, 3 Aug 2015 23:13:09 -0400 Subject: [PATCH 3646/4858] add CommandWithMeta->get() format option to docs --- php/WP_CLI/CommandWithMeta.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 97d0c74a20..73f86458e9 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -83,6 +83,9 @@ public function list_( $args, $assoc_args ) { * <key> * : The name of the meta field to get. * + * [--format=<format>] + * : Accepted values: table, json. Default: table + * * @synopsis <id> <key> [--format=<format>] */ public function get( $args, $assoc_args ) { From e122de344402b4a3c5736c70f635696ff48adaca Mon Sep 17 00:00:00 2001 From: Ryan McCue <me@ryanmccue.info> Date: Tue, 4 Aug 2015 11:48:45 +0200 Subject: [PATCH 3647/4858] Unset things we don't need during import With large imports, this can cause memory issues due to parsing the data twice and keeping it loaded in memory. --- php/commands/import.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/php/commands/import.php b/php/commands/import.php index f63df2f5ce..815d137dfe 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -75,6 +75,11 @@ private function import_wxr( $file, $args ) { // Prepare the data to be used in process_author_mapping(); $wp_import->get_authors_from_import( $import_data ); + + // We no longer need the original data, so unset to avoid using excess + // memory. + unset( $import_data ); + $author_data = array(); foreach ( $wp_import->authors as $wxr_author ) { $author = new \stdClass; @@ -102,6 +107,8 @@ private function import_wxr( $file, $args ) { $author_in = wp_list_pluck( $author_mapping, 'old_user_login' ); $author_out = wp_list_pluck( $author_mapping, 'new_user_login' ); + unset( $author_mapping, $author_data ); + // $user_select needs to be an array of user IDs $user_select = array(); $invalid_user_select = array(); @@ -115,6 +122,8 @@ private function import_wxr( $file, $args ) { if ( ! empty( $invalid_user_select ) ) return new WP_Error( 'invalid-author-mapping', sprintf( "These user_logins are invalid: %s", implode( ',', $invalid_user_select ) ) ); + unset( $author_out ); + // Drive the import $wp_import->fetch_attachments = !in_array( 'attachment', $args['skip'] ); $_GET = array( 'import' => 'wordpress', 'step' => 2 ); From dbbb417d4cb0a2c879d9b07ef9b9f6a9210bf08a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Aug 2015 07:50:46 -0700 Subject: [PATCH 3648/4858] Update tests for WordPress 4.2.4 and related point releases --- features/core.feature | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/features/core.feature b/features/core.feature index d54e48b726..872771ac96 100644 --- a/features/core.feature +++ b/features/core.feature @@ -325,12 +325,12 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 4.2.3 | major | https://wordpress.org/wordpress-4.2.3.zip | - | 4.1.6 | major | https://wordpress.org/wordpress-4.1.6.zip | - | 4.0.6 | major | https://wordpress.org/wordpress-4.0.6.zip | - | 3.9.7 | major | https://wordpress.org/wordpress-3.9.7.zip | - | 3.8.9 | minor | https://wordpress.org/wordpress-3.8.9.zip | + | version | update_type | package_url | + | 4.2.4 | major | https://wordpress.org/wordpress-4.2.4.zip | + | 4.1.7 | major | https://wordpress.org/wordpress-4.1.7.zip | + | 4.0.7 | major | https://wordpress.org/wordpress-4.0.7.zip | + | 3.9.8 | major | https://wordpress.org/wordpress-3.9.8.zip | + | 3.8.10 | minor | https://wordpress.org/wordpress-3.8.10.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -340,11 +340,11 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 4.2.3 | major | https://wordpress.org/wordpress-4.2.3.zip | - | 4.1.6 | major | https://wordpress.org/wordpress-4.1.6.zip | - | 4.0.6 | major | https://wordpress.org/wordpress-4.0.6.zip | - | 3.9.7 | major | https://wordpress.org/wordpress-3.9.7.zip | + | version | update_type | package_url | + | 4.2.4 | major | https://wordpress.org/wordpress-4.2.4.zip | + | 4.1.7 | major | https://wordpress.org/wordpress-4.1.7.zip | + | 4.0.7 | major | https://wordpress.org/wordpress-4.0.7.zip | + | 3.9.8 | major | https://wordpress.org/wordpress-3.9.8.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -354,8 +354,8 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 3.8.9 | minor | https://wordpress.org/wordpress-3.8.9.zip | + | version | update_type | package_url | + | 3.8.10 | minor | https://wordpress.org/wordpress-3.8.10.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From 867e57b5e7384ba81eebe23184a95c02ab818592 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 4 Aug 2015 09:08:19 -0700 Subject: [PATCH 3649/4858] Remove unnecessary backslashes from `CommandWithMeta` --- php/WP_CLI/CommandWithMeta.php | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 9e9b07518f..25a0d363db 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -2,6 +2,8 @@ namespace WP_CLI; +use WP_CLI; + /** * Base class for WP-CLI commands that deal with metadata * @@ -84,12 +86,12 @@ public function get( $args, $assoc_args ) { $object_id = $this->check_object_id( $object_id ); - $value = \get_metadata( $this->meta_type, $object_id, $meta_key, true ); + $value = get_metadata( $this->meta_type, $object_id, $meta_key, true ); if ( '' === $value ) die(1); - \WP_CLI::print_value( $value, $assoc_args ); + WP_CLI::print_value( $value, $assoc_args ); } /** @@ -111,12 +113,12 @@ public function delete( $args, $assoc_args ) { $object_id = $this->check_object_id( $object_id ); - $success = \delete_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $success = delete_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { - \WP_CLI::success( "Deleted custom field." ); + WP_CLI::success( "Deleted custom field." ); } else { - \WP_CLI::error( "Failed to delete custom field." ); + WP_CLI::error( "Failed to delete custom field." ); } } @@ -140,17 +142,17 @@ public function delete( $args, $assoc_args ) { public function add( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $meta_value = \WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); - $meta_value = \WP_CLI::read_value( $meta_value, $assoc_args ); + $meta_value = WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); + $meta_value = WP_CLI::read_value( $meta_value, $assoc_args ); $object_id = $this->check_object_id( $object_id ); - $success = \add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $success = add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { - \WP_CLI::success( "Added custom field." ); + WP_CLI::success( "Added custom field." ); } else { - \WP_CLI::error( "Failed to add custom field." ); + WP_CLI::error( "Failed to add custom field." ); } } @@ -176,8 +178,8 @@ public function add( $args, $assoc_args ) { public function update( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; - $meta_value = \WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); - $meta_value = \WP_CLI::read_value( $meta_value, $assoc_args ); + $meta_value = WP_CLI::get_value_from_arg_or_stdin( $args, 2 ); + $meta_value = WP_CLI::read_value( $meta_value, $assoc_args ); $object_id = $this->check_object_id( $object_id ); @@ -185,14 +187,14 @@ public function update( $args, $assoc_args ) { $old_value = sanitize_meta( $meta_key, get_metadata( $this->meta_type, $object_id, $meta_key, true ), $this->meta_type ); if ( $meta_value === $old_value ) { - \WP_CLI::success( "Value passed for custom field '$meta_key' is unchanged." ); + WP_CLI::success( "Value passed for custom field '$meta_key' is unchanged." ); } else { - $success = \update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $success = update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { - \WP_CLI::success( "Updated custom field '$meta_key'." ); + WP_CLI::success( "Updated custom field '$meta_key'." ); } else { - \WP_CLI::error( "Failed to update custom field '$meta_key'." ); + WP_CLI::error( "Failed to update custom field '$meta_key'." ); } } From c7d97fb93936282fb9a9d36b830e24961f453405 Mon Sep 17 00:00:00 2001 From: Chris Montgomery <chris@montchr.io> Date: Tue, 4 Aug 2015 12:27:26 -0400 Subject: [PATCH 3650/4858] remove @synopsis from CommandWithMeta->get() --- php/WP_CLI/CommandWithMeta.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 73f86458e9..dd348b5c69 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -85,8 +85,6 @@ public function list_( $args, $assoc_args ) { * * [--format=<format>] * : Accepted values: table, json. Default: table - * - * @synopsis <id> <key> [--format=<format>] */ public function get( $args, $assoc_args ) { list( $object_id, $meta_key ) = $args; From 6f31197280806e73572cd386d5c252edd6501e3a Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Sat, 15 Aug 2015 11:27:29 -0400 Subject: [PATCH 3651/4858] Change the default argument for 'post_type' from 'all' to 'any' --- php/commands/export.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index f790e4c7d8..8b60c22ecb 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -33,7 +33,7 @@ class Export_Command extends WP_CLI_Command { * * [--post_type=<post-type>] * : Export only posts with this post_type. Separate multiple post types with a - * comma. Defaults to all. + * comma. Defaults to "any". * * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. @@ -181,7 +181,7 @@ private function check_end_date( $date ) { } private function check_post_type( $post_type ) { - if ( is_null( $post_type ) ) + if ( is_null( $post_type ) || 'any' === $post_type ) return true; $post_type = array_unique( array_filter( explode( ',', $post_type ) ) ); @@ -190,7 +190,7 @@ private function check_post_type( $post_type ) { foreach ( $post_type as $type ) { if ( ! in_array( $type, $post_types ) ) { WP_CLI::warning( sprintf( - 'The post type %s does not exist. Choose "all" or any of these existing post types instead: %s', + 'The post type %s does not exist. Choose "any" or any of these existing post types instead: %s', $type, implode( ", ", $post_types ) ) ); From db7ed2ed2a512c96aaf20f671cb5a4d26d782e6a Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Sat, 15 Aug 2015 11:36:04 -0400 Subject: [PATCH 3652/4858] Good advice: test against what you're expecting, not what you're expecting *not* to see --- features/export.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/export.feature b/features/export.feature index e86546cd66..27a470c1a3 100644 --- a/features/export.feature +++ b/features/export.feature @@ -130,9 +130,9 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDERR should not contain: + Then STDERR should contain: """ - Warning: + Success: """ When I run `wp post generate --count=10` From 505023389cac7bdda02bc1b4b097563a7facf2a5 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Sat, 15 Aug 2015 11:37:31 -0400 Subject: [PATCH 3653/4858] Stick closer to the original language, since 'any' isn't truly the default value --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 8b60c22ecb..de8ab40639 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -33,7 +33,7 @@ class Export_Command extends WP_CLI_Command { * * [--post_type=<post-type>] * : Export only posts with this post_type. Separate multiple post types with a - * comma. Defaults to "any". + * comma. Defaults to all. * * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. From 6bee93886bf0435cde7d194b27ac87226ae2d902 Mon Sep 17 00:00:00 2001 From: Steve Grunwell <steve.grunwell@10up.com> Date: Sat, 15 Aug 2015 16:00:24 +0000 Subject: [PATCH 3654/4858] Fix some broken feature tests with odd expectations --- features/export.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/export.feature b/features/export.feature index 27a470c1a3..58d183546b 100644 --- a/features/export.feature +++ b/features/export.feature @@ -78,9 +78,9 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDERR should not contain: + Then STDOUT should contain: """ - Warning: + Success: """ When I run `wp site empty --yes` @@ -130,7 +130,7 @@ Feature: Export content. Given a WP install When I run `wp plugin install wordpress-importer --activate` - Then STDERR should contain: + Then STDOUT should contain: """ Success: """ @@ -233,7 +233,7 @@ Feature: Export content. And save STDOUT 'Writing to file %s' as {EXPORT_FILE} Then the {EXPORT_FILE} file should contain: """ - <wp:category_nicename>apple</wp:category_nicename> + <category domain="category" nicename="apple"><![CDATA[Apple]]></category> """ When I run `wp site empty --yes` From 7d9a1ee8022e583c413bd9efe92126fa9e59f37f Mon Sep 17 00:00:00 2001 From: Steve Grunwell <stevegrunwell@gmail.com> Date: Sat, 15 Aug 2015 13:21:44 -0400 Subject: [PATCH 3655/4858] Ensure that the comma-separated --post_type changes won't affect the rest of the exporter --- php/export/class-wp-export-query.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 2b7c2f4ae1..4d271b48fb 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -161,7 +161,7 @@ private function calculate_post_ids() { private function post_type_where() { global $wpdb; - $post_types_filters = array( 'can_export' => true, 'name' => null ); + $post_types_filters = array( 'can_export' => true ); if ( $this->filters['post_type'] ) { $post_types = $this->filters['post_type']; @@ -248,7 +248,7 @@ private function get_timestamp_for_the_last_day_of_a_month( $yyyy_mm ) { private function category_where() { global $wpdb; - if ( 'post' != $this->filters['post_type'] ) { + if ( 'post' != $this->filters['post_type'] && ! in_array( 'post', (array) $this->filters['post_type'] ) ) { return; } $category = $this->find_category_from_any_object( $this->filters['category'] ); From 1aab880df588d3a400ed4f169580722f22872bdb Mon Sep 17 00:00:00 2001 From: Marc Addeo <marcaddeo@gmail.com> Date: Mon, 17 Aug 2015 11:12:24 -0400 Subject: [PATCH 3656/4858] Add the docroot option to the synopsis so wp-cli parses it as a valid option --- php/commands/server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/server.php b/php/commands/server.php index cd88e98a0f..a4be4a9e45 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -27,7 +27,7 @@ class Server_Command extends WP_CLI_Command { * sudo wp server --host=localhost.localdomain --port=80 * * @when before_wp_load - * @synopsis [--host=<host>] [--port=<port>] + * @synopsis [--host=<host>] [--port=<port>] [--docroot=<docroot>] */ function __invoke( $_, $assoc_args ) { $min_version = '5.4'; From bb5196c4d5f5fb8e2aaa26f00854e73b6984e617 Mon Sep 17 00:00:00 2001 From: Marc Addeo <marcaddeo@gmail.com> Date: Mon, 17 Aug 2015 11:51:10 -0400 Subject: [PATCH 3657/4858] Remove the `@synopsis` annotation completely, as it is deprecated --- php/commands/server.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/server.php b/php/commands/server.php index a4be4a9e45..d82fc7be66 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -27,7 +27,6 @@ class Server_Command extends WP_CLI_Command { * sudo wp server --host=localhost.localdomain --port=80 * * @when before_wp_load - * @synopsis [--host=<host>] [--port=<port>] [--docroot=<docroot>] */ function __invoke( $_, $assoc_args ) { $min_version = '5.4'; From dc8502de2d5fb39fe2430b4447633a171628adbb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 18 Aug 2015 16:25:57 -0700 Subject: [PATCH 3658/4858] Ensure `$pagenow` global is always set Core sets the variable in `wp-includes/vars.php` --- php/wp-settings-cli.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index f942830257..41e8b79df1 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -218,8 +218,9 @@ // Define and enforce our SSL constants wp_ssl_constants( ); -// Don't create common globals, but we still need wp_is_mobile() +// Don't create common globals, but we still need wp_is_mobile() and $pagenow // require( ABSPATH . WPINC . '/vars.php' ); +$GLOBALS['pagenow'] = null; function wp_is_mobile() { return false; } From 63a8987cbd8c698ba5ad5c652ff49c007623f467 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 20 Aug 2015 05:53:38 -0700 Subject: [PATCH 3659/4858] Update tests for WordPress 4.3 --- features/core.feature | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 872771ac96..a9882c81d6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -326,6 +326,7 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | + | 4.3 | major | https://wordpress.org/wordpress-4.3.zip | | 4.2.4 | major | https://wordpress.org/wordpress-4.2.4.zip | | 4.1.7 | major | https://wordpress.org/wordpress-4.1.7.zip | | 4.0.7 | major | https://wordpress.org/wordpress-4.0.7.zip | @@ -335,12 +336,13 @@ Feature: Manage WordPress installation When I run `wp core check-update --format=count` Then STDOUT should be: """ - 5 + 6 """ When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | + | 4.3 | major | https://wordpress.org/wordpress-4.3.zip | | 4.2.4 | major | https://wordpress.org/wordpress-4.2.4.zip | | 4.1.7 | major | https://wordpress.org/wordpress-4.1.7.zip | | 4.0.7 | major | https://wordpress.org/wordpress-4.0.7.zip | @@ -349,7 +351,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --major --format=count` Then STDOUT should be: """ - 4 + 5 """ When I run `wp core check-update --minor` From d12c64285e646c3c63eff87c14eaea664bec8206 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 20 Aug 2015 06:28:25 -0700 Subject: [PATCH 3660/4858] Fix typo in `apache_modules()` PHPdoc --- php/commands/rewrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index d2d8e59425..4fabc7d695 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -222,7 +222,7 @@ public function list_( $args, $assoc_args ) { * to see: * * 1. if the $is_apache variable is set. - * 2. if the mod_rewrite module is returned from the apche_get_modules + * 2. if the mod_rewrite module is returned from the apache_get_modules * function. * * To get this to work with wp-cli you'll need to add the mod_rewrite module From 3d018a5b70ced75926d5db83f137fba8f8b68c33 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 20 Aug 2015 13:15:35 -0700 Subject: [PATCH 3661/4858] Clarify `wp post term` documentation --- php/WP_CLI/CommandWithTerms.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithTerms.php b/php/WP_CLI/CommandWithTerms.php index 285ae29945..bfae4653a1 100644 --- a/php/WP_CLI/CommandWithTerms.php +++ b/php/WP_CLI/CommandWithTerms.php @@ -125,7 +125,7 @@ public function remove( $args, $assoc_args ) { } /** - * Add a term. Appends to existed + * Add a term. Appends to existing set of terms on the object. * * <id> * : The ID of the object. @@ -134,7 +134,7 @@ public function remove( $args, $assoc_args ) { * : The name of the taxonomy type to be added. * * <term>... - * : The name of the term or terms to be added. + * : The slug of the term or terms to be added. */ public function add( $args, $assoc_args ) { $object_id = array_shift( $args ); @@ -155,7 +155,7 @@ public function add( $args, $assoc_args ) { } /** - * Set terms. Replaces existing terms + * Set terms. Replaces existing terms on the object. * * <id> * : The ID of the object. @@ -164,7 +164,7 @@ public function add( $args, $assoc_args ) { * : The name of the taxonomy type to be updated. * * <term>... - * : The name of the term or terms to be updated. + * : The slug of the term or terms to be updated. */ public function set( $args, $assoc_args ) { $object_id = array_shift( $args ); From 92075fe75b63bb78b84b529e26067c469a7d677d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 22 Aug 2015 07:32:16 -0700 Subject: [PATCH 3662/4858] Try against the next major release --- features/core.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 40cbfe3daf..59e487978d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -660,11 +660,11 @@ Feature: Manage WordPress installation And an empty cache When I run `wp core download --version=4.2.1 --force` - And I run `wp core update` + And I run `wp core update --version=4.2.2` Then STDOUT should not be empty When I run `wp core download --version=4.1.1 --force` - And I run `wp core update` + And I run `wp core update --version=4.2.2` And I run `wp core verify-checksums` Then STDOUT should be: """ From e3b779d70da410b93368cebe248ffff2caeb731e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 22 Aug 2015 07:52:03 -0700 Subject: [PATCH 3663/4858] Use the proper key for the result array `$item_to_update` is some arbitrary string that only works for plugins --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index d4c526ddf7..47d4250665 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -267,7 +267,7 @@ protected function update_many( $args, $assoc_args ) { if ( $num_to_update > 0 ) { if ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) { foreach( $items_to_update as $item_to_update => $info ) { - $message = $result[$item_to_update] !== null ? 'updated successfully' : 'did not update'; + $message = $result[ $info['update_id'] ] !== null ? 'updated successfully' : 'did not update'; \WP_CLI::log( "{$info['title']} {$message} from version {$info['version']} to version {$info['update_version']}" ); } } else { From 11523591385a9c97a5caa6190bd1af4078034c1f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 22 Aug 2015 08:17:09 -0700 Subject: [PATCH 3664/4858] Use absolute file paths for `make-phar.php` This makes it possible to call the script from the Behat context --- utils/make-phar.php | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index 69ae514ffd..69445c7f88 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -1,13 +1,15 @@ <?php -require './vendor/autoload.php'; -require './php/utils.php'; +define( 'WP_CLI_ROOT', dirname( dirname( __FILE__ ) ) ); + +require WP_CLI_ROOT . '/vendor/autoload.php'; +require WP_CLI_ROOT . '/php/utils.php'; use Symfony\Component\Finder\Finder; use WP_CLI\Utils; use WP_CLI\Configurator; -$configurator = new Configurator( './utils/make-phar-spec.php' ); +$configurator = new Configurator( WP_CLI_ROOT . '/utils/make-phar-spec.php' ); list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) ); @@ -20,21 +22,21 @@ define( 'BE_QUIET', isset( $runtime_config['quiet'] ) && $runtime_config['quiet'] ); -$current_version = trim( file_get_contents( './VERSION' ) ); +$current_version = trim( file_get_contents( WP_CLI_ROOT . '/VERSION' ) ); if ( isset( $runtime_config['version'] ) ) { $new_version = $runtime_config['version']; $new_version = Utils\increment_version( $current_version, $new_version ); if ( isset( $runtime_config['store-version'] ) && $runtime_config['store-version'] ) { - file_put_contents( './VERSION', $new_version ); + file_put_contents( WP_CLI_ROOT . '/VERSION', $new_version ); } $current_version = $new_version; } function add_file( $phar, $path ) { - $key = str_replace( './', '', $path ); + $key = str_replace( WP_CLI_ROOT, '', $path ); if ( !BE_QUIET ) echo "$key - $path\n"; @@ -43,7 +45,7 @@ function add_file( $phar, $path ) { } function set_file_contents( $phar, $path, $content ) { - $key = str_replace( './', '', $path ); + $key = str_replace( WP_CLI_ROOT, '', $path ); if ( !BE_QUIET ) echo "$key - $path\n"; @@ -61,15 +63,15 @@ function set_file_contents( $phar, $path, $content ) { ->files() ->ignoreVCS(true) ->name('*.php') - ->in('./php') - ->in('./features') - ->in('./vendor/wp-cli') - ->in('./vendor/mustache') - ->in('./vendor/rmccue/requests') - ->in('./vendor/composer') - ->in('./vendor/symfony/finder') - ->in('./vendor/nb/oxymel') - ->in('./vendor/ramsey/array_column') + ->in(WP_CLI_ROOT . '/php') + ->in(WP_CLI_ROOT . '/features') + ->in(WP_CLI_ROOT . '/vendor/wp-cli') + ->in(WP_CLI_ROOT . '/vendor/mustache') + ->in(WP_CLI_ROOT . '/vendor/rmccue/requests') + ->in(WP_CLI_ROOT . '/vendor/composer') + ->in(WP_CLI_ROOT . '/vendor/symfony/finder') + ->in(WP_CLI_ROOT . '/vendor/nb/oxymel') + ->in(WP_CLI_ROOT . '/vendor/ramsey/array_column') ->exclude('test') ->exclude('tests') ->exclude('Tests') @@ -86,18 +88,18 @@ function set_file_contents( $phar, $path, $content ) { ->files() ->ignoreVCS(true) ->ignoreDotFiles(false) - ->in('./templates') + ->in( WP_CLI_ROOT . '/templates') ; foreach ( $finder as $file ) { add_file( $phar, $file ); } -add_file( $phar, './vendor/autoload.php' ); -add_file( $phar, './utils/get-package-require-from-composer.php' ); -add_file( $phar, './vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); +add_file( $phar, WP_CLI_ROOT . '/vendor/autoload.php' ); +add_file( $phar, WP_CLI_ROOT . '/utils/get-package-require-from-composer.php' ); +add_file( $phar, WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); -set_file_contents( $phar, './VERSION', $current_version ); +set_file_contents( $phar, WP_CLI_ROOT . '/VERSION', $current_version ); $phar->setStub( <<<EOB #!/usr/bin/env php From 53db8d7b64dd7740d3586c29e965d8cab17dab68 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 22 Aug 2015 08:18:47 -0700 Subject: [PATCH 3665/4858] Introduce `wp cli update --nightly` for updating to nightly release --- features/cli.feature | 13 +++++++++++++ php/commands/cli.php | 36 +++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/features/cli.feature b/features/cli.feature index 34d6d48be6..83c0f2ea52 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -67,6 +67,19 @@ Feature: `wp cli` tasks And STDERR should be empty And the return code should be 0 + Scenario: Install WP-CLI nightly + Given an empty directory + And a new Phar with version "0.14.0" + + When I run `{PHAR_PATH} cli update --nightly --yes` + Then STDOUT should contain: + """ + Success: Updated WP-CLI to the latest nightly release + """ + + And STDERR should be empty + And the return code should be 0 + Scenario: Dump the list of global parameters with values Given a WP install diff --git a/php/commands/cli.php b/php/commands/cli.php index 837ee4b8d8..fd8c11eded 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -131,6 +131,9 @@ public function check_update( $_, $assoc_args ) { * [--minor] * : Only perform minor updates * + * [--nightly] + * : Update to the latest built version of the master branch. Potentially unstable. + * * [--yes] * : Do not prompt for confirmation */ @@ -145,18 +148,28 @@ public function update( $_, $assoc_args ) { WP_CLI::error( sprintf( "%s is not writable by current user", $old_phar ) ); } - $updates = $this->get_updates( $assoc_args ); + if ( isset( $assoc_args['nightly'] ) ) { - if ( empty( $updates ) ) { - WP_CLI::success( "WP-CLI is at the latest version." ); - exit(0); - } + WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to the latest nightly?', WP_CLI_VERSION ), $assoc_args ); + + $download_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar'; + + } else { - $newest = $updates[0]; + $updates = $this->get_updates( $assoc_args ); - WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); + if ( empty( $updates ) ) { + WP_CLI::success( "WP-CLI is at the latest version." ); + exit(0); + } + + $newest = $updates[0]; - $download_url = $newest['package_url']; + WP_CLI::confirm( sprintf( 'You have version %s. Would you like to update to %s?', WP_CLI_VERSION, $newest['version'] ), $assoc_args ); + + $download_url = $newest['package_url']; + + } WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); @@ -193,7 +206,12 @@ class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the WP_CLI::error( sprintf( "Cannot move %s to %s", $temp, $old_phar ) ); } - WP_CLI::success( sprintf( 'Updated WP-CLI to %s', $newest['version'] ) ); + if ( isset( $assoc_args['nightly'] ) ) { + $updated_version = 'the latest nightly release'; + } else { + $updated_version = $newest['version']; + } + WP_CLI::success( sprintf( 'Updated WP-CLI to %s', $updated_version ) ); } /** From d3ed4c6e2fc27f98f8e12ced66ebe61afee190b1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sat, 22 Aug 2015 08:38:31 -0700 Subject: [PATCH 3666/4858] Append git short hash to alpha versions When using `wp cli update --nightly`, the short hash will be helpful for keeping track of which version you're running. --- ci/prepare.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index 611a068de1..0baee0dc88 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -6,9 +6,17 @@ set -ex composer install --no-interaction --prefer-source +CLI_VERSION=$(head -n 1 VERSION) +if [[ $CLI_VERSION == *"-alpha"* ]] +then + GIT_HASH=$(git rev-parse HEAD) + GIT_SHORT_HASH=${GIT_HASH:0:7} + CLI_VERSION="$CLI_VERSION-$GIT_SHORT_HASH" +fi + # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR mkdir -p $WP_CLI_BIN_DIR -php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet +php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet --version=$CLI_VERSION mv wp-cli.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp From 69009b8f34f03ca22f1e249e286c219fee625532 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Aug 2015 07:03:41 -0700 Subject: [PATCH 3667/4858] Mock API response to get a failing build for partial update again See https://github.com/wp-cli/wp-cli/issues/1898#issuecomment-134206853 --- features/core.feature | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 59e487978d..28b55e0f4b 100644 --- a/features/core.feature +++ b/features/core.feature @@ -658,13 +658,43 @@ Feature: Manage WordPress installation Scenario: Ensure cached partial upgrades aren't used in full upgrade Given a WP install And an empty cache + And a wp-content/mu-plugins/upgrade-override.php file: + """ + <?php + add_filter( 'pre_site_transient_update_core', function(){ + return (object) array( + 'updates' => array( + (object) array( + 'response' => 'autoupdate', + 'download' => 'https://downloads.wordpress.org/release/wordpress-4.2.4.zip', + 'locale' => 'en_US', + 'packages' => (object) array( + 'full' => 'https://downloads.wordpress.org/release/wordpress-4.2.4.zip', + 'no_content' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-no-content.zip', + 'new_bundled' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-new-bundled.zip', + 'partial' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-partial-1.zip', + 'rollback' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-rollback-1.zip', + ), + 'current' => '4.2.4', + 'version' => '4.2.4', + 'php_version' => '5.2.4', + 'mysql_version' => '5.0', + 'new_bundled' => '4.1', + 'partial_version' => '4.2.1', + 'support_email' => 'updatehelp42@wordpress.org', + 'new_files' => '', + ), + ), + ); + }); + """ When I run `wp core download --version=4.2.1 --force` - And I run `wp core update --version=4.2.2` + And I run `wp core update` Then STDOUT should not be empty When I run `wp core download --version=4.1.1 --force` - And I run `wp core update --version=4.2.2` + And I run `wp core update` And I run `wp core verify-checksums` Then STDOUT should be: """ From 392aba67ebb58d6a6568f4065a808807d0992903 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 24 Aug 2015 07:41:28 -0700 Subject: [PATCH 3668/4858] Use WPorg API filename in our cache key to accommodate for partials WordPress can actually return a variety of files, and we want to make sure our cache properly handles each. Cache key is renamed for all WordPress core archive files, so no longer need to worry about mismatched extensions. --- features/core.feature | 69 +++++++++---------------------------- php/WP_CLI/CoreUpgrader.php | 3 +- php/commands/core.php | 2 +- 3 files changed, 19 insertions(+), 55 deletions(-) diff --git a/features/core.feature b/features/core.feature index 28b55e0f4b..465fc47f97 100644 --- a/features/core.feature +++ b/features/core.feature @@ -12,7 +12,7 @@ Feature: Manage WordPress installation When I run `wp core download` And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/en_US-{VERSION}.tar.gz file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-en_US.tar.gz file should exist When I run `mkdir inner` And I run `cd inner && wp core download` @@ -23,7 +23,7 @@ Feature: Manage WordPress installation Then the wp-settings.php file should exist And STDOUT should contain: """ - Using cached file '{SUITE_CACHE_DIR}/core/en_US-{VERSION}.tar.gz'... + Using cached file '{SUITE_CACHE_DIR}/core/wordpress-{VERSION}-en_US.tar.gz'... """ @download @@ -33,7 +33,7 @@ Feature: Manage WordPress installation When I run `wp core download --locale=de_DE` And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/de_DE-{VERSION}.tar.gz file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-de_DE.tar.gz file should exist Scenario: No wp-config.php Given an empty directory @@ -424,7 +424,7 @@ Feature: Manage WordPress installation When I run `wp core update --version=3.8.1 --force` Then STDOUT should contain: """ - Using cached file '{SUITE_CACHE_DIR}/core/en_US-3.8.1.zip'... + Using cached file '{SUITE_CACHE_DIR}/core/wordpress-3.8.1-en_US.zip'... """ And STDOUT should not contain: """ @@ -597,55 +597,6 @@ Feature: Manage WordPress installation Warning: The 'en_GB' language is active. """ - Scenario: Ensure file cache isn't corrupted by a ZIP masquerading as a gzipped TAR, part one - Given a WP install - And an empty cache - And I run `mkdir -p {SUITE_CACHE_DIR}/core; wget -O {SUITE_CACHE_DIR}/core/en_US-4.0.tar.gz https://wordpress.org/wordpress-4.0.zip; touch {SUITE_CACHE_DIR}/core/en_US-4.0.tar.gz` - - When I run `wp core download --version=4.0 --force` - Then STDOUT should contain: - """ - Success: WordPress downloaded - """ - And STDERR should contain: - """ - Warning: Extraction failed, downloading a new copy... - """ - - When I run `wp core version` - Then STDOUT should be: - """ - 4.0 - """ - - Scenario: Ensure file cache isn't corrupted by core update, part two - Given a WP install - And an empty cache - - When I run `wp core download --version=4.0 --force` - Then STDOUT should contain: - """ - Success: WordPress downloaded - """ - - When I run `wp core version` - Then STDOUT should be: - """ - 4.0 - """ - - When I run `wp core update --version=4.0 --force` - Then STDOUT should contain: - """ - Success: WordPress updated successfully - """ - - When I run `wp core version` - Then STDOUT should be: - """ - 4.0 - """ - Scenario: Catch download of non-existent WP version Given an empty directory @@ -692,6 +643,11 @@ Feature: Manage WordPress installation When I run `wp core download --version=4.2.1 --force` And I run `wp core update` Then STDOUT should not be empty + And the {SUITE_CACHE_DIR}/core directory should contain: + """ + wordpress-4.2.1-en_US.tar.gz + wordpress-4.2.4-partial-1-en_US.zip + """ When I run `wp core download --version=4.1.1 --force` And I run `wp core update` @@ -700,3 +656,10 @@ Feature: Manage WordPress installation """ Success: WordPress install verifies against checksums. """ + And the {SUITE_CACHE_DIR}/core directory should contain: + """ + wordpress-4.1.1-en_US.tar.gz + wordpress-4.2.1-en_US.tar.gz + wordpress-4.2.4-no-content-en_US.zip + wordpress-4.2.4-partial-1-en_US.zip + """ diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index e156649f54..25dc2335a6 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -32,13 +32,14 @@ function download_package( $package ) { if ( empty( $package ) ) return new WP_Error( 'no_package', $this->strings['no_package'] ); + $filename = pathinfo( $package, PATHINFO_FILENAME ); $ext = pathinfo( $package, PATHINFO_EXTENSION ); $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.' . $ext; $cache = WP_CLI::get_cache(); $update = $GLOBALS['wp_cli_update_obj']; - $cache_key = "core/{$update->locale}-{$update->version}.{$ext}"; + $cache_key = "core/{$filename}-{$update->locale}.{$ext}"; $cache_file = $cache->has( $cache_key ); if ( $cache_file ) { diff --git a/php/commands/core.php b/php/commands/core.php index 0a82e617c0..ccbcfa5b80 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -147,7 +147,7 @@ public function download( $args, $assoc_args ) { WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $version, $locale ) ); $cache = WP_CLI::get_cache(); - $cache_key = "core/$locale-$version.tar.gz"; + $cache_key = "core/wordpress-{$version}-{$locale}.tar.gz"; $cache_file = $cache->has($cache_key); $bad_cache = false; From 218742209476748d1b4ebfcd4157a689ef059b88 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Mon, 24 Aug 2015 18:24:58 +0200 Subject: [PATCH 3669/4858] Switch away from `wp_download_language_pack()` so it's possible to install language packs when, for example, the `DISALLOW_FILE_MODS` constant is defined and set to true. See #1879. --- features/core.feature | 6 ++++ php/WP_CLI/CommandWithTranslation.php | 47 ++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index a9882c81d6..488a66555c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -584,6 +584,12 @@ Feature: Manage WordPress installation Success: Language activated. """ + When I try `wp core language install invalid_lang` + Then STDERR should be: + """ + Error: Language 'invalid_lang' not found. + """ + @require-wp-4.0 Scenario: Don't allow active language to be uninstalled Given a WP install diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index e83e393421..368655568c 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -127,17 +127,15 @@ public function install( $args, $assoc_args ) { exit; } - require_once ABSPATH . '/wp-admin/includes/translation-install.php'; - - $response = wp_download_language_pack( $language_code ); - if ( $response == $language_code ) { + $response = $this->download_language_pack( $language_code ); + if ( ! is_wp_error( $response ) ) { \WP_CLI::success( "Language installed." ); if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { $this->activate( array( $language_code ), array() ); } } else { - \WP_CLI::error( "Couldn't install language." ); + \WP_CLI::error( $response ); } } @@ -268,6 +266,45 @@ public function activate( $args, $assoc_args ) { \WP_CLI::success( "Language activated." ); } + /** + * Download a language pack. + * + * @see wp_download_language_pack() + * + * @param string $download Language code to download. + * @return string|WP_Error Returns the language code if successfully downloaded, or a WP_Error object on failure. + */ + protected function download_language_pack( $download ) { + + $translations = $this->get_all_languages(); + + foreach ( $translations as $translation ) { + if ( $translation['language'] === $download ) { + $translation_to_load = true; + break; + } + } + + if ( empty( $translation_to_load ) ) { + return new \WP_Error( 'not_found', "Language '{$download}' not found." ); + } + $translation = (object) $translation; + + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + $skin = new \Automatic_Upgrader_Skin; + $upgrader = new \Language_Pack_Upgrader( $skin ); + $translation->type = 'core'; + $result = $upgrader->upgrade( $translation, array( 'clear_update_cache' => false ) ); + + if ( is_wp_error( $result ) ) { + return $result; + } else if ( ! $result ) { + return new \WP_Error( 'not_installed', "Could not install language '{$download}'." ); + } + + return $translation->language; + } + /** * Return a list of installed languages. * From c74120ed673755dc6ab2d1f2185343381906159a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Mon, 24 Aug 2015 10:20:26 -0700 Subject: [PATCH 3670/4858] Change to `private` so we don't have to worry about bc --- php/WP_CLI/CommandWithTranslation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 368655568c..74d3537b46 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -274,7 +274,7 @@ public function activate( $args, $assoc_args ) { * @param string $download Language code to download. * @return string|WP_Error Returns the language code if successfully downloaded, or a WP_Error object on failure. */ - protected function download_language_pack( $download ) { + private function download_language_pack( $download ) { $translations = $this->get_all_languages(); From bd5ecd48d116e341730927e9c6460b79e5024c47 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Aug 2015 10:57:05 -0700 Subject: [PATCH 3671/4858] Warn on cli update when directory isn't writeable `rename()` requires both the file and directory to be writeable. Erroring earlier is more helpful to the end user. --- php/commands/cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index fd8c11eded..718979abe9 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -146,6 +146,8 @@ public function update( $_, $assoc_args ) { if ( ! is_writable( $old_phar ) ) { WP_CLI::error( sprintf( "%s is not writable by current user", $old_phar ) ); + } else if ( ! is_writeable( dirname( $old_phar ) ) ) { + WP_CLI::error( sprintf( "%s is not writable by current user", dirname( $old_phar ) ) ); } if ( isset( $assoc_args['nightly'] ) ) { From 9e480000ad068cd1c64f3927adabeb3687ed6209 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Aug 2015 15:10:39 -0700 Subject: [PATCH 3672/4858] Deliberately flag specific scenarios dependent on Github API The other `cli.feature` scenarios are fine to run each Travis build --- features/cli.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/cli.feature b/features/cli.feature index 83c0f2ea52..68ed68fde3 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -1,4 +1,3 @@ -@github-api Feature: `wp cli` tasks Scenario: Ability to set a custom version when building @@ -16,6 +15,7 @@ Feature: `wp cli` tasks {TRUE_VERSION} """ + @github-api Scenario: Check for updates Given an empty directory And a new Phar with version "0.0.0" @@ -27,6 +27,7 @@ Feature: `wp cli` tasks """ And STDERR should be empty + @github-api Scenario: Do WP-CLI Update Given an empty directory And a new Phar with version "0.0.0" @@ -39,6 +40,7 @@ Feature: `wp cli` tasks And STDERR should be empty And the return code should be 0 + @github-api Scenario: Patch update from 0.14.0 to 0.14.1 Given an empty directory And a new Phar with version "0.14.0" @@ -51,6 +53,7 @@ Feature: `wp cli` tasks And STDERR should be empty And the return code should be 0 + @github-api Scenario: Not a patch update from 0.14.0 Given an empty directory And a new Phar with version "0.14.0" @@ -80,6 +83,7 @@ Feature: `wp cli` tasks And STDERR should be empty And the return code should be 0 + @github-api Scenario: Dump the list of global parameters with values Given a WP install From ad63ed626b7107c364dc55fde15bf82c04c1ece7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Aug 2015 15:32:18 -0700 Subject: [PATCH 3673/4858] Deprecate `@synopsis` for `wp cache` in favor of better docs --- php/commands/cache.php | 72 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/php/commands/cache.php b/php/commands/cache.php index c78ce1ce4f..dcc729d570 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -14,7 +14,19 @@ class Cache_Command extends WP_CLI_Command { /** * Add a value to the object cache. * - * @synopsis <key> <value> [<group>] [<expiration>] + * If a value already exists for the key, the value isn't added. + * + * <key> + * : Cache key. + * + * <value> + * : Value to add to the key. + * + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. + * + * [<expiration>] + * : Define how long to keep the value, in seconds. Defaults to 0 (as long as possible). */ public function add( $args, $assoc_args ) { list( $key, $value ) = $args; @@ -33,7 +45,14 @@ public function add( $args, $assoc_args ) { /** * Decrement a value in the object cache. * - * @synopsis <key> [<offset>] [<group>] + * <key> + * : Cache key. + * + * [<offset>] + * : The amount by which to decrement the item's value. Default is 1. + * + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. */ public function decr( $args, $assoc_args ) { $key = $args[0]; @@ -54,7 +73,11 @@ public function decr( $args, $assoc_args ) { /** * Remove a value from the object cache. * - * @synopsis <key> [<group>] + * <key> + * : Cache key. + * + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. */ public function delete( $args, $assoc_args ) { $key = $args[0]; @@ -86,7 +109,11 @@ public function flush( $args, $assoc_args ) { /** * Get a value from the object cache. * - * @synopsis <key> [<group>] + * <key> + * : Cache key. + * + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. */ public function get( $args, $assoc_args ) { $key = $args[0]; @@ -105,7 +132,14 @@ public function get( $args, $assoc_args ) { /** * Increment a value in the object cache. * - * @synopsis <key> [<offset>] [<group>] + * <key> + * : Cache key. + * + * [<offset>] + * : The amount by which to increment the item's value. Default is 1. + * + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. */ public function incr( $args, $assoc_args ) { $key = $args[0]; @@ -124,9 +158,19 @@ public function incr( $args, $assoc_args ) { } /** - * Replace an existing value in the object cache. + * Replace a value in the object cache, if the value already exists. + * + * <key> + * : Cache key. + * + * <value> + * : Value to replace. * - * @synopsis <key> <value> [<group>] [<expiration>] + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. + * + * [<expiration>] + * : Define how long to keep the value, in seconds. Defaults to 0 (as long as possible). */ public function replace( $args, $assoc_args ) { list( $key, $value ) = $args; @@ -145,9 +189,19 @@ public function replace( $args, $assoc_args ) { } /** - * Set a value to the object cache. + * Set a value to the object cache, regardless of whether it already exists. + * + * <key> + * : Cache key. + * + * <value> + * : Value to set on the key. + * + * [<group>] + * : Method for grouping data within the cache which allows the same key to be used across groups. * - * @synopsis <key> <value> [<group>] [<expiration>] + * [<expiration>] + * : Define how long to keep the value, in seconds. Defaults to 0 (as long as possible). */ public function set( $args, $assoc_args ) { list( $key, $value ) = $args; From d087648838db1f32472ed20a3e6ed9c5d94e9936 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 25 Aug 2015 20:29:20 -0700 Subject: [PATCH 3674/4858] Lock php-cli-tools to v0.10.5 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7d9ab3cb46..26dcc72c22 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "0.10.5", "mustache/mustache": "~2.4", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", From dedf06cc3b66215f27015ee0f075de710202bcdc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Wed, 26 Aug 2015 06:59:45 -0700 Subject: [PATCH 3675/4858] Load WP_HTTP with require_once because core now loads in http.php r33748 --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 41e8b79df1..28cc2380b2 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -167,7 +167,7 @@ Utils\maybe_require( '3.5-alpha-22024', ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); -require( ABSPATH . WPINC . '/class-http.php' ); +require_once( ABSPATH . WPINC . '/class-http.php' ); require( ABSPATH . WPINC . '/widgets.php' ); require( ABSPATH . WPINC . '/nav-menu.php' ); require( ABSPATH . WPINC . '/nav-menu-template.php' ); From 1db2f8143d8f54e5bb7f50a6595e2d2a3a28d3e4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Wed, 26 Aug 2015 07:01:41 -0700 Subject: [PATCH 3676/4858] Test against the latest version of WordPress --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 58b187c0d5..28e3bdd2bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=4.2 + - WP_VERSION=4.3 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: From 096af51ba82381ab1243353010c410a462cf0264 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 26 Aug 2015 08:30:10 -0700 Subject: [PATCH 3677/4858] Update `.mailmap` with contributors to v0.20.0 --- .mailmap | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.mailmap b/.mailmap index 23d32791fc..c5b31ad862 100644 --- a/.mailmap +++ b/.mailmap @@ -1,4 +1,5 @@ 2ndkauboy <bernhard@kau-boys.de> +Akeda Bagus <admin@gedex.web.id> Alex Mills <git@viper007bond.com> Andreas Heigl <andreas@heigl.org> andreascreten <andreas@madewithlove.be> @@ -15,6 +16,7 @@ Brad Parbs <brad@bradparbs.com> Brian MacKinney <brian@getpantheon.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> +Chris Montgomery <chris@montchr.io> clemens-tolboom <clemens@build2be.com> conatus <alex@recordsonribs.com> ctayloroomphinc <ctaylor@thinkoomph.com> @@ -38,6 +40,7 @@ glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> +Jan Voráček <jan@voracek.net> jeichorn <joshua.eichorn@pagely.com> Jeremy Pry <jeremy.pry@gmail.com> jghazally <jeff@bigfish.co.uk> @@ -51,12 +54,15 @@ jonathanbardo <jonathanbardo@users.noreply.github.com> joshbetz <j@joshbetz.com> joshlevinson <joshalevinson@gmail.com> JQ <JeyKeu@users.noreply.github.com> +KDoole <dev@Kevins-iMac.local> Keith Grennan <keith@nearlyfree.org> +Kevin Doole <kdoole@farmmedia.com> Kevinlearynet <info@kevinleary.net> kidfiction <ejdanderson@gmail.com> lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> lkwdwrd <woodward.lucas@gmail.com> +Marc Addeo <marcaddeo@gmail.com> marcoceppi <marco@ceppi.net> matiskay <matiskay@gmail.com> mattes <matthias.kadenbach@gmail.com> @@ -95,6 +101,7 @@ rodrigoprimo <rodrigo@hacklab.com.br> rodrigoprimo <rodrigosprimo@gmail.com> roelven <roel@soundcloud.com> Ross Hattori <rhattori@saymedia.com> +Ryan McCue <me@ryanmccue.info> ryanduff <ryan@fusionized.com> santagada <santagada@gmail.com> sboisvert <stephane.boisvert@automattic.com> @@ -108,6 +115,9 @@ spacedmonkey <spacedmonkey2@gmail.com> SpikesDivZero <wesley.spikes@gmail.com> spuriousdata <spuriousdata@gmail.com> Stephen Edgar <stephen@netweb.com.au> +Steve Grunwell <steve.grunwell@10up.com> +Steve Grunwell <steve@stevegrunwell.com> +Steve Grunwell <stevegrunwell@gmail.com> stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> Svetoslav Marinov (Slavi) <slavi@orbisius.com> From 284a1aa6df81c95017656a17b4298e72e123035b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Wed, 26 Aug 2015 09:19:25 -0700 Subject: [PATCH 3678/4858] Correct wording in theme documentation --- php/commands/theme.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 0cebcebfa4..c3879282e1 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -55,7 +55,7 @@ function status( $args ) { * : Optional number of results to display. Defaults to 10. * * [--field=<field>] - * : Prints the value of a single field for each plugin. + * : Prints the value of a single field for each theme. * * [--fields=<fields>] * : Ask for specific fields from the API. Defaults to name,slug,author,rating. Acceptable values: @@ -447,7 +447,7 @@ public function get( $args, $assoc_args ) { * : Output summary as table or summary. Defaults to table. * * [--version=<version>] - * : If set, the plugin will be updated to the specified version. + * : If set, the theme will be updated to the specified version. * * [--dry-run] * : Preview which themes would be updated. From 58317fce36e34a10473bbd397b42a185edd10438 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 26 Aug 2015 10:38:02 -0700 Subject: [PATCH 3679/4858] Bump version to 0.20.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4863f59c36..5a03fb737b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.20.0-alpha +0.20.0 From 5307f30b6e901c23a27e7bc58b4525e0ce080eec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 26 Aug 2015 16:48:30 -0700 Subject: [PATCH 3680/4858] Bump to new working version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5a03fb737b..217292ece3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.20.0 +0.21.0-alpha From f076bfa02b664ad5c7ad4f7893979571a2b763cc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 27 Aug 2015 16:15:50 -0700 Subject: [PATCH 3681/4858] Failing test case for #2015 --- features/upgradables.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index dc195e89ed..bc1576597e 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -76,7 +76,11 @@ Feature: Manage WordPress themes and plugins When I run `wp <type> update <item>` And save STDOUT 'Downloading update from .*\/<item>\.%s\.zip' as {NEW_VERSION} - Then STDOUT should not be empty + And STDOUT should not be empty + Then STDOUT should not contain: + """ + Error + """ And the {SUITE_CACHE_DIR}/<type>/<item>-{NEW_VERSION}.zip file should exist When I run `wp <type> update --all` From cab23b21c5301db525c54a53a4e006344753544c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 27 Aug 2015 16:17:10 -0700 Subject: [PATCH 3682/4858] Use proper key identified in e3b779d70da410b93368cebe248ffff2caeb731e --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 47d4250665..20e347faca 100644 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -277,7 +277,7 @@ protected function update_many( $args, $assoc_args ) { 'name' => $info['name'], 'old_version' => $info['version'], 'new_version' => $info['update_version'], - 'status' => $result[$item_to_update] !== null ? 'Updated' : 'Error', + 'status' => $result[ $info['update_id'] ] !== null ? 'Updated' : 'Error', ); } \WP_CLI\Utils\format_items( 'table', $status, array( 'name', 'old_version', 'new_version', 'status' ) ); From 86e925396c2d2b2f98fae4147792ab93377cc4e0 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 28 Aug 2015 14:37:19 -0300 Subject: [PATCH 3683/4858] add error message when trying to use `wp rewrite flush --hard` on a ms install --- features/rewrite.feature | 13 +++++++++++++ php/commands/rewrite.php | 9 ++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index 6ab22a61ed..d1fcacfbf8 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -62,3 +62,16 @@ Feature: Manage WordPress rewrites When I run `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/` And I run `wp rewrite flush --hard` Then the .htaccess file should exist + + Scenario: Error when trying to generate .htaccess on a multisite install + Given a WP multisite install + And a wp-cli.yml file: + """ + apache_modules: [mod_rewrite] + """ + + When I try `wp rewrite flush --hard` + Then STDERR should be: + """ + Error: WordPress can't generate .htaccess file for a multisite install. + """ diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 4fabc7d695..0096a6b6e5 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -23,15 +23,22 @@ class Rewrite_Command extends WP_CLI_Command { * ## OPTIONS * * [--hard] - * : Perform a hard flush - update `.htaccess` rules as well as rewrite rules in database. + * : Perform a hard flush - update `.htaccess` rules as well as rewrite rules in database. Works only on single site installs. */ public function flush( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config self::apache_modules(); + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) && ! in_array( 'mod_rewrite', (array) WP_CLI::get_config( 'apache_modules' ) ) ) { WP_CLI::warning( "Regenerating a .htaccess file requires special configuration. See usage docs." ); } + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) && is_multisite() ) { + WP_CLI::error( "WordPress can't generate .htaccess file for a multisite install." ); + } + flush_rewrite_rules( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) ); + if ( ! get_option( 'rewrite_rules' ) ) { WP_CLI::warning( "Rewrite rules are empty, possibly because of a missing permalink_structure option. Use 'wp rewrite list' to verify, or 'wp rewrite structure' to update permalink_structure." ); } From 818f28de5c0911276aae36c466c9636954644788 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 28 Aug 2015 15:08:40 -0300 Subject: [PATCH 3684/4858] replace error with warning --- features/rewrite.feature | 2 +- php/commands/rewrite.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index d1fcacfbf8..25fe482e1a 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -73,5 +73,5 @@ Feature: Manage WordPress rewrites When I try `wp rewrite flush --hard` Then STDERR should be: """ - Error: WordPress can't generate .htaccess file for a multisite install. + Warning: WordPress can't generate .htaccess file for a multisite install. """ diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 0096a6b6e5..58c5ff26c6 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -34,7 +34,7 @@ public function flush( $args, $assoc_args ) { } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) && is_multisite() ) { - WP_CLI::error( "WordPress can't generate .htaccess file for a multisite install." ); + WP_CLI::warning( "WordPress can't generate .htaccess file for a multisite install." ); } flush_rewrite_rules( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) ); From 684b3c94427c7053e608d7ffdf8772baf97772ae Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Tue, 1 Sep 2015 13:29:44 +0200 Subject: [PATCH 3685/4858] s/propmts/prompts --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 08b173be50..6db4b15ac1 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -167,7 +167,7 @@ public function get( $args, $assoc_args ) { * : User ID to reassign the posts to. * * [--yes] - * : Answer yes to any confirmation propmts. + * : Answer yes to any confirmation prompts. * * ## EXAMPLES * From b559f2f76f0b43e1f48d762d60cffd1ca3eece27 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Sep 2015 12:35:47 -0700 Subject: [PATCH 3686/4858] Failing tests for #2019 --- features/config.feature | 103 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/features/config.feature b/features/config.feature index 2a2b3ae84e..d324ac20d2 100644 --- a/features/config.feature +++ b/features/config.feature @@ -219,3 +219,106 @@ Feature: Have a config file When I run `wp --info` Then STDOUT should not be empty + Scenario: WordPress install with commented out DOMAIN_CURRENT_SITE, first style + Given a WP multisite install + And a wp-config.php file: + """ +<?php +// ** MySQL settings ** // +/** The name of the database for WordPress */ +define('DB_NAME', 'wp_cli_test'); + +/** MySQL database username */ +define('DB_USER', 'wp_cli_test'); + +/** MySQL database password */ +define('DB_PASSWORD', 'password1'); + +/** MySQL hostname */ +define('DB_HOST', '127.0.0.1'); + +/** Database Charset to use in creating database tables. */ +define('DB_CHARSET', 'utf8'); + +/** The Database Collate type. Don't change this if in doubt. */ +define('DB_COLLATE', ''); + +$table_prefix = 'wp_'; + +define( 'WP_ALLOW_MULTISITE', true ); +define('MULTISITE', true); +define('SUBDOMAIN_INSTALL', false); +$base = '/'; +define('DOMAIN_CURRENT_SITE', 'example.com'); +# define('DOMAIN_CURRENT_SITE', 'bta.example.com'); +define('PATH_CURRENT_SITE', '/'); +define('SITE_ID_CURRENT_SITE', 1); +define('BLOG_ID_CURRENT_SITE', 1); + +/* That's all, stop editing! Happy blogging. */ + +/** Absolute path to the WordPress directory. */ +if ( !defined('ABSPATH') ) + define('ABSPATH', dirname(__FILE__) . '/'); + +/** Sets up WordPress vars and included files. */ +require_once(ABSPATH . 'wp-settings.php'); + """ + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ + + Scenario: WordPress install with commented out DOMAIN_CURRENT_SITE, second style + Given a WP multisite install + And a wp-config.php file: + """ +<?php +// ** MySQL settings ** // +/** The name of the database for WordPress */ +define('DB_NAME', 'wp_cli_test'); + +/** MySQL database username */ +define('DB_USER', 'wp_cli_test'); + +/** MySQL database password */ +define('DB_PASSWORD', 'password1'); + +/** MySQL hostname */ +define('DB_HOST', '127.0.0.1'); + +/** Database Charset to use in creating database tables. */ +define('DB_CHARSET', 'utf8'); + +/** The Database Collate type. Don't change this if in doubt. */ +define('DB_COLLATE', ''); + +$table_prefix = 'wp_'; + +define( 'WP_ALLOW_MULTISITE', true ); +define('MULTISITE', true); +define('SUBDOMAIN_INSTALL', false); +$base = '/'; +define('DOMAIN_CURRENT_SITE', 'example.com'); +//define('DOMAIN_CURRENT_SITE', 'bta.example.com'); +define('PATH_CURRENT_SITE', '/'); +define('SITE_ID_CURRENT_SITE', 1); +define('BLOG_ID_CURRENT_SITE', 1); + +/* That's all, stop editing! Happy blogging. */ + +/** Absolute path to the WordPress directory. */ +if ( !defined('ABSPATH') ) + define('ABSPATH', dirname(__FILE__) . '/'); + +/** Sets up WordPress vars and included files. */ +require_once(ABSPATH . 'wp-settings.php'); + """ + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ From d4d67de8e73c61fc494ca577ba0ef7267a7853a8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Sep 2015 12:52:46 -0700 Subject: [PATCH 3687/4858] Ignore commented `define('DOMAIN_CURRENT_SITE')` statements in wp-config --- php/WP_CLI/Runner.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 218a72a13f..3e36d818db 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -211,14 +211,17 @@ private static function guess_url( $assoc_args ) { $wp_config_file = file_get_contents( $wp_config_path ); $hit = array(); - $re_define = "#.*define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;#iU"; + $re_define = "~(.*)define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;~iU"; if ( preg_match_all( $re_define, $wp_config_file, $matches ) ) { - foreach ( $matches[2] as $def_key => $def_name ) { + foreach ( $matches[3] as $def_key => $def_name ) { + if ( false !== strpos( $matches[1][$def_key], '#' ) || false !== strpos( $matches[1][$def_key], '//' ) ) { + continue; + } if ( 'DOMAIN_CURRENT_SITE' == $def_name ) - $hit['domain'] = $matches[5][$def_key]; + $hit['domain'] = $matches[6][$def_key]; if ( 'PATH_CURRENT_SITE' == $def_name ) - $hit['path'] = $matches[5][$def_key]; + $hit['path'] = $matches[6][$def_key]; } } From ff0085738f5a374203b853fdb4baf5ff2956c849 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Sep 2015 13:43:38 -0700 Subject: [PATCH 3688/4858] Break core language tests into dedicated file --- features/core-language.feature | 134 +++++++++++++++++++++++++++++++++ features/core.feature | 133 -------------------------------- 2 files changed, 134 insertions(+), 133 deletions(-) create mode 100644 features/core-language.feature diff --git a/features/core-language.feature b/features/core-language.feature new file mode 100644 index 0000000000..3e6501c41f --- /dev/null +++ b/features/core-language.feature @@ -0,0 +1,134 @@ +Feature: Manage translation files for a WordPress install + + @require-wp-4.0 + Scenario: Core translation CRUD + Given a WP install + + When I run `wp core language list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | + | en_US | English (United States) | active | + | en_GB | English (UK) | uninstalled | + + When I run `wp core language install en_GB` + Then the wp-content/languages/admin-en_GB.po file should exist + And the wp-content/languages/en_GB.po file should exist + And STDOUT should be: + """ + Success: Language installed. + """ + + When I try `wp core language install en_GB` + Then STDERR should be: + """ + Warning: Language already installed. + """ + + When I run `wp core language list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | + | en_GB | English (UK) | installed | + + When I run `wp core language activate en_GB` + Then STDOUT should be: + """ + Success: Language activated. + """ + + When I run `wp core language list --fields=language,english_name,update` + Then STDOUT should be a table containing rows: + | language | english_name | update | + | ar | Arabic | none | + | az | Azerbaijani | none | + | en_US | English (United States) | none | + | en_GB | English (UK) | available | + + When I run `wp core language update --dry-run` + Then save STDOUT 'Available (\d+) translations updates' as {UPDATES} + + When I run `wp core language update` + Then STDOUT should contain: + """ + Success: Updated {UPDATES}/{UPDATES} translations. + """ + And the wp-content/languages/plugins directory should exist + And the wp-content/languages/themes directory should exist + + When I run `wp core language list --field=language --status=active` + Then STDOUT should be: + """ + en_GB + """ + + When I run `wp core language list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | az | Azerbaijani | uninstalled | + | en_GB | English (UK) | active | + + When I run `wp core language activate en_US` + Then STDOUT should be: + """ + Success: Language activated. + """ + + When I run `wp core language list --fields=language,english_name,status` + Then STDOUT should be a table containing rows: + | language | english_name | status | + | ar | Arabic | uninstalled | + | en_US | English (United States) | active | + | en_GB | English (UK) | installed | + + + When I try `wp core language activate invalid_lang` + Then STDERR should be: + """ + Error: Language not installed. + """ + + When I run `wp core language uninstall en_GB` + Then the wp-content/languages/admin-en_GB.po file should not exist + And the wp-content/languages/en_GB.po file should not exist + And STDOUT should be: + """ + Success: Language uninstalled. + """ + + When I try `wp core language uninstall en_GB` + Then STDERR should be: + """ + Error: Language not installed. + """ + + When I run `wp core language install --activate en_GB` + Then the wp-content/languages/admin-en_GB.po file should exist + And the wp-content/languages/en_GB.po file should exist + And STDOUT should be: + """ + Success: Language installed. + Success: Language activated. + """ + + When I try `wp core language install invalid_lang` + Then STDERR should be: + """ + Error: Language 'invalid_lang' not found. + """ + + @require-wp-4.0 + Scenario: Don't allow active language to be uninstalled + Given a WP install + + When I run `wp core language install en_GB --activate` + Then STDOUT should not be empty + + When I try `wp core language uninstall en_GB` + Then STDERR should be: + """ + Warning: The 'en_GB' language is active. + """ diff --git a/features/core.feature b/features/core.feature index 90a2910f20..558fcb70f4 100644 --- a/features/core.feature +++ b/features/core.feature @@ -470,139 +470,6 @@ Feature: Manage WordPress installation http://localhost:8001 """ - @require-wp-4.0 - Scenario: Core translation CRUD - Given a WP install - - When I run `wp core language list --fields=language,english_name,status` - Then STDOUT should be a table containing rows: - | language | english_name | status | - | ar | Arabic | uninstalled | - | az | Azerbaijani | uninstalled | - | en_US | English (United States) | active | - | en_GB | English (UK) | uninstalled | - - When I run `wp core language install en_GB` - Then the wp-content/languages/admin-en_GB.po file should exist - And the wp-content/languages/en_GB.po file should exist - And STDOUT should be: - """ - Success: Language installed. - """ - - When I try `wp core language install en_GB` - Then STDERR should be: - """ - Warning: Language already installed. - """ - - When I run `wp core language list --fields=language,english_name,status` - Then STDOUT should be a table containing rows: - | language | english_name | status | - | ar | Arabic | uninstalled | - | az | Azerbaijani | uninstalled | - | en_GB | English (UK) | installed | - - When I run `wp core language activate en_GB` - Then STDOUT should be: - """ - Success: Language activated. - """ - - When I run `wp core language list --fields=language,english_name,update` - Then STDOUT should be a table containing rows: - | language | english_name | update | - | ar | Arabic | none | - | az | Azerbaijani | none | - | en_US | English (United States) | none | - | en_GB | English (UK) | available | - - When I run `wp core language update --dry-run` - Then save STDOUT 'Available (\d+) translations updates' as {UPDATES} - - When I run `wp core language update` - Then STDOUT should contain: - """ - Success: Updated {UPDATES}/{UPDATES} translations. - """ - And the wp-content/languages/plugins directory should exist - And the wp-content/languages/themes directory should exist - - When I run `wp core language list --field=language --status=active` - Then STDOUT should be: - """ - en_GB - """ - - When I run `wp core language list --fields=language,english_name,status` - Then STDOUT should be a table containing rows: - | language | english_name | status | - | ar | Arabic | uninstalled | - | az | Azerbaijani | uninstalled | - | en_GB | English (UK) | active | - - When I run `wp core language activate en_US` - Then STDOUT should be: - """ - Success: Language activated. - """ - - When I run `wp core language list --fields=language,english_name,status` - Then STDOUT should be a table containing rows: - | language | english_name | status | - | ar | Arabic | uninstalled | - | en_US | English (United States) | active | - | en_GB | English (UK) | installed | - - - When I try `wp core language activate invalid_lang` - Then STDERR should be: - """ - Error: Language not installed. - """ - - When I run `wp core language uninstall en_GB` - Then the wp-content/languages/admin-en_GB.po file should not exist - And the wp-content/languages/en_GB.po file should not exist - And STDOUT should be: - """ - Success: Language uninstalled. - """ - - When I try `wp core language uninstall en_GB` - Then STDERR should be: - """ - Error: Language not installed. - """ - - When I run `wp core language install --activate en_GB` - Then the wp-content/languages/admin-en_GB.po file should exist - And the wp-content/languages/en_GB.po file should exist - And STDOUT should be: - """ - Success: Language installed. - Success: Language activated. - """ - - When I try `wp core language install invalid_lang` - Then STDERR should be: - """ - Error: Language 'invalid_lang' not found. - """ - - @require-wp-4.0 - Scenario: Don't allow active language to be uninstalled - Given a WP install - - When I run `wp core language install en_GB --activate` - Then STDOUT should not be empty - - When I try `wp core language uninstall en_GB` - Then STDERR should be: - """ - Warning: The 'en_GB' language is active. - """ - Scenario: Catch download of non-existent WP version Given an empty directory From 1debfdf2f389697db0dc3d05d848b16e3235f2cb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 1 Sep 2015 14:01:08 -0700 Subject: [PATCH 3689/4858] Get all available translation updates, not just the current locale Currently only works for themes and plugins, because the core filter only accepts a single locale. --- features/core-language.feature | 2 ++ php/WP_CLI/CommandWithTranslation.php | 39 ++++++++++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/features/core-language.feature b/features/core-language.feature index 3e6501c41f..e975c921c1 100644 --- a/features/core-language.feature +++ b/features/core-language.feature @@ -13,6 +13,7 @@ Feature: Manage translation files for a WordPress install | en_GB | English (UK) | uninstalled | When I run `wp core language install en_GB` + And I run `wp core language install en_AU` Then the wp-content/languages/admin-en_GB.po file should exist And the wp-content/languages/en_GB.po file should exist And STDOUT should be: @@ -44,6 +45,7 @@ Feature: Manage translation files for a WordPress install | language | english_name | update | | ar | Arabic | none | | az | Azerbaijani | none | + | en_AU | English (Australia) | available | | en_US | English (United States) | none | | en_GB | English (UK) | available | diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 74d3537b46..277fb630e8 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -58,11 +58,7 @@ public function list_( $args, $assoc_args ) { $translations = $this->get_all_languages(); $available = $this->get_installed_languages(); - $this->wp_clean_update_cache(); // Clear existing update caches. - wp_version_check(); // Check for Core translation updates. - wp_update_themes(); // Check for Theme translation updates. - wp_update_plugins(); // Check for Plugin translation updates. - $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. + $updates = $this->get_translation_updates(); $current_locale = get_locale(); $translations = array_map( function( $translation ) use ( $available, $current_locale, $updates ) { @@ -157,13 +153,7 @@ public function update( $args, $assoc_args ) { return; } - $this->wp_clean_update_cache(); // Clear existing update caches. - wp_version_check(); // Check for Core translation updates. - wp_update_themes(); // Check for Theme translation updates. - wp_update_plugins(); // Check for Plugin translation updates. - - $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. - + $updates = $this->get_translation_updates(); if ( empty( $updates ) ) { \WP_CLI::success( 'Translations are up to date.' ); @@ -266,6 +256,31 @@ public function activate( $args, $assoc_args ) { \WP_CLI::success( "Language activated." ); } + /** + * Get all updates available for all translations + * + * @return array + */ + private function get_translation_updates() { + $available = $this->get_installed_languages(); + $func = function() use ( $available ) { + return $available; + }; + $filters = array( 'plugins_update_check_locales', 'themes_update_check_locales' ); + foreach( $filters as $filter ) { + add_filter( $filter, $func ); + } + $this->wp_clean_update_cache(); // Clear existing update caches. + wp_version_check(); // Check for Core translation updates. + wp_update_themes(); // Check for Theme translation updates. + wp_update_plugins(); // Check for Plugin translation updates. + foreach( $filters as $filter ) { + remove_filter( $filter, $func ); + } + $updates = wp_get_translation_updates(); // Retrieves a list of all translations updates available. + return $updates; + } + /** * Download a language pack. * From 9eccb492aeb49a088c4e0d455bb9ac69bcf22576 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 2 Sep 2015 07:31:45 -0700 Subject: [PATCH 3690/4858] Introduce `wp comment recount` for recalculating `comment_count` --- features/comment.feature | 22 ++++++++++++++++++++++ php/commands/comment.php | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 293936ab24..f79a2ac230 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -131,3 +131,25 @@ Feature: Manage WordPress comments """ 21 """ + + Scenario: Recounting comments + When I run `wp comment create --comment_post_ID=1 --comment_approved=1 --porcelain` + And I run `wp comment create --comment_post_ID=1 --comment_approved=1 --porcelain` + And I run `wp post get 1 --field=comment_count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp eval 'global $wpdb; $wpdb->update( $wpdb->posts, array( "comment_count" => 1 ), array( "ID" => 1 ) );'` + And I run `wp post get 1 --field=comment_count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp comment recount 1` + Then STDOUT should be: + """ + Updated post 1 comment count to 3 + """ diff --git a/php/commands/comment.php b/php/commands/comment.php index a10248f018..e27d30647a 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -398,6 +398,24 @@ public function count( $args, $assoc_args ) { } } + /** + * Recount the comment_count value for one or more posts. + * + * <id>... + * : IDs for one or more posts to update. + */ + public function recount( $args ) { + foreach( $args as $id ) { + wp_update_comment_count( $id ); + $post = get_post( $id ); + if ( $post ) { + WP_CLI::log( sprintf( "Updated post %d comment count to %d", $post->ID, $post->comment_count ) ); + } else { + WP_CLI::warning( sprintf( "Post %d doesn't exist", $post->ID ) ); + } + } + } + /** * Get status of a comment. * From 6213a3906644252f2f1d9882f597b05a7dd6070e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 2 Sep 2015 12:13:14 -0700 Subject: [PATCH 3691/4858] Clarify expected behavior for `WP_CLI::run_command()` See https://wordpress.slack.com/archives/cli/p1441220169000129 --- php/class-wp-cli.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 44bf9ace53..6204574338 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -458,7 +458,10 @@ public static function get_config( $key = null ) { } /** - * Run a given command. + * Run a given command within the current process using the same global parameters. + * + * To run a command using a new process with the same global parameters, use WP_CLI::launch_self() + * To run a command using a new process with different global parameters, use WP_CLI::launch() * * @param array * @param array From 5063ec6be418b0aee94b638dd5c6c5667fc0d484 Mon Sep 17 00:00:00 2001 From: John Blackbourn <johnbillion@gmail.com> Date: Thu, 3 Sep 2015 12:36:43 +0200 Subject: [PATCH 3692/4858] Return a more useful error message when running `wp scaffold plugin-tests` with an invalid plugin slug. --- features/scaffold.feature | 8 ++++++++ php/commands/scaffold.php | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index fc7aeea934..a691bb8fb2 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -349,3 +349,11 @@ Feature: WordPress code scaffolding """ Replacing """ + Scenario: Scaffold tests for invalid plugin directory + Given a WP install + + When I try `wp scaffold plugin-tests incorrect-custom-plugin` + Then STDERR should contain: + """ + Error: Invalid plugin directory specified. + """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 1db452d185..e58b7f5ef6 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -603,6 +603,10 @@ function plugin_tests( $args, $assoc_args ) { WP_CLI::error( 'Invalid plugin specified.' ); } + if ( ! is_dir( $plugin_dir ) ) { + WP_CLI::error( 'Invalid plugin directory specified.' ); + } + $tests_dir = "$plugin_dir/tests"; $bin_dir = "$plugin_dir/bin"; From 8867542e28a97c12f7ca9109029088997331395a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 3 Sep 2015 05:57:42 -0700 Subject: [PATCH 3693/4858] Clarify it's an invalid plugin slug; `--dir` is checked elsewhere --- features/scaffold.feature | 2 +- php/commands/scaffold.php | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index a691bb8fb2..777403f37b 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -355,5 +355,5 @@ Feature: WordPress code scaffolding When I try `wp scaffold plugin-tests incorrect-custom-plugin` Then STDERR should contain: """ - Error: Invalid plugin directory specified. + Error: Invalid plugin slug specified. """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index e58b7f5ef6..ba197763dd 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -587,6 +587,9 @@ function plugin_tests( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; + if ( ! is_dir( $plugin_dir ) ) { + WP_CLI::error( 'Invalid plugin slug specified.' ); + } } if ( ! empty( $assoc_args['dir'] ) ) { @@ -603,10 +606,6 @@ function plugin_tests( $args, $assoc_args ) { WP_CLI::error( 'Invalid plugin specified.' ); } - if ( ! is_dir( $plugin_dir ) ) { - WP_CLI::error( 'Invalid plugin directory specified.' ); - } - $tests_dir = "$plugin_dir/tests"; $bin_dir = "$plugin_dir/bin"; From 41b56158a2cfa908958565cdd8ad81d6c4e51a6f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 3 Sep 2015 06:32:15 -0700 Subject: [PATCH 3694/4858] Permit custom directories to be specified with slugs --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ba197763dd..5591b98a8e 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -587,7 +587,7 @@ function plugin_tests( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { $plugin_slug = $args[0]; $plugin_dir = WP_PLUGIN_DIR . "/$plugin_slug"; - if ( ! is_dir( $plugin_dir ) ) { + if ( empty( $assoc_args['dir'] ) && ! is_dir( $plugin_dir ) ) { WP_CLI::error( 'Invalid plugin slug specified.' ); } } From cacca9b9b40eabadc7386f36d337cb38d215ba4f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 3 Sep 2015 14:06:26 -0700 Subject: [PATCH 3695/4858] In `wp theme list`, indicate a parent theme with `status=parent` This will more clearly distinguish between a genuinely inactive theme vs. an "inactive" theme being used as a parent theme. --- features/theme.feature | 11 +++++++++++ php/commands/theme.php | 8 +++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/features/theme.feature b/features/theme.feature index cf8143185b..42144d0cd4 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -238,3 +238,14 @@ Feature: Manage WordPress themes """ Error: The 'biker' theme cannot be activated without its parent, 'jolene'. """ + + Scenario: List an active theme with its parent + Given a WP install + And I run `wp theme install jolene` + And I run `wp theme install --activate biker` + + When I run `wp theme list --fields=name,status` + Then STDOUT should be a table containing rows: + | name | status | + | biker | active | + | jolene | parent | diff --git a/php/commands/theme.php b/php/commands/theme.php index c3879282e1..380a4fadd4 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -107,7 +107,13 @@ protected function get_all_items() { } protected function get_status( $theme ) { - return ( $this->is_active_theme( $theme ) ) ? 'active' : 'inactive'; + if ( $this->is_active_theme( $theme ) ) { + return 'active'; + } else if ( $theme->get_stylesheet_directory() === get_template_directory() ) { + return 'parent'; + } else { + return 'inactive'; + } } /** From f42e7d17256af2035aac79bda37f1d5e5cf5097b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 4 Sep 2015 10:53:52 -0700 Subject: [PATCH 3696/4858] Fix example in `wp menu item delete` See https://github.com/wp-cli/wp-cli.github.com/pull/63 --- php/commands/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 240427580f..fd1a5428e9 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -471,7 +471,7 @@ public function update( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu item remove 45 + * wp menu item delete 45 * * @subcommand delete */ From f57298898b6d85a962e1ecbf9376b0400eecee58 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 7 Sep 2015 07:17:52 -0700 Subject: [PATCH 3697/4858] Warn user when `wp-config.php` isn't writable for multisite convert WordPress multisite needs extra constants in `wp-config.php`. If WP-CLI can't add them, we should let the user know instead of failing silently. --- php/commands/core.php | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index ccbcfa5b80..939a78f930 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -644,22 +644,26 @@ private function _multisite_convert( $assoc_args ) { } if ( !is_multisite() ) { - ob_start(); -?> + $subdomain_export = Utils\get_flag_value( $assoc_args, 'subdomains' ) ? 'true' : 'false'; + $ms_config = <<<EOT define( 'WP_ALLOW_MULTISITE', true ); -define('MULTISITE', true); -define('SUBDOMAIN_INSTALL', <?php var_export( $assoc_args['subdomains'] ); ?>); -$base = '<?php echo $assoc_args['base']; ?>'; -define('DOMAIN_CURRENT_SITE', '<?php echo $domain; ?>'); -define('PATH_CURRENT_SITE', '<?php echo $assoc_args['base']; ?>'); -define('SITE_ID_CURRENT_SITE', 1); -define('BLOG_ID_CURRENT_SITE', 1); - -<?php - $ms_config = ob_get_clean(); - - self::modify_wp_config( $ms_config ); - WP_CLI::log( 'Added multisite constants to wp-config.php.' ); +define( 'MULTISITE', true ); +define( 'SUBDOMAIN_INSTALL', {$subdomain_export} ); +\$base = '{$assoc_args['base']}'; +define( 'DOMAIN_CURRENT_SITE', '{$domain}' ); +define( 'PATH_CURRENT_SITE', '{$assoc_args['base']}' ); +define( 'SITE_ID_CURRENT_SITE', 1 ); +define( 'BLOG_ID_CURRENT_SITE', 1 ); +EOT; + + $wp_config_path = Utils\locate_wp_config(); + if ( is_writable( $wp_config_path ) ) { + self::modify_wp_config( $ms_config ); + WP_CLI::log( 'Added multisite constants to wp-config.php.' ); + } else { + WP_CLI::warning( 'Multisite constants could not be written to wp-config.php:' ); + WP_CLI::log( $ms_config ); + } } return true; From 2e570c809fe197e58425bc2dc57542feb30865c0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 7 Sep 2015 07:19:57 -0700 Subject: [PATCH 3698/4858] Clarify the end user may need to add the constants manually --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 939a78f930..d654100431 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -661,7 +661,7 @@ private function _multisite_convert( $assoc_args ) { self::modify_wp_config( $ms_config ); WP_CLI::log( 'Added multisite constants to wp-config.php.' ); } else { - WP_CLI::warning( 'Multisite constants could not be written to wp-config.php:' ); + WP_CLI::warning( 'Multisite constants could not be written to wp-config.php. You may need to add them manually:' ); WP_CLI::log( $ms_config ); } } From d7abd6c7d8e9c3063f3bff98a899364bb8d06045 Mon Sep 17 00:00:00 2001 From: Grant McInnes <grant.mcinnes@eyesopen.ca> Date: Fri, 11 Sep 2015 13:15:38 -0400 Subject: [PATCH 3699/4858] Improve description of search-replace behavior This description used to emphasize that search-replace worked on all tables. That's not true. If plugins create tables and don't register the tables on the $wpdb object, search-replace will ignore them in the default configuration. This clarifies it I hope. Hopefully also clarifies that --all-tables ignores the wpdb registry. --- php/commands/search-replace.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 889a7923e8..b6e93a71bb 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -12,8 +12,10 @@ class Search_Replace_Command extends WP_CLI_Command { * * ## DESCRIPTION * - * This command will go through all rows in all tables and will replace all - * appearances of the old string with the new one. + * 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. * @@ -47,7 +49,7 @@ class Search_Replace_Command extends WP_CLI_Command { * : 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. + * : 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. From eb0f8670d034f324babb8cf43030a144baaab7c3 Mon Sep 17 00:00:00 2001 From: Grant McInnes <grant.mcinnes@eyesopen.ca> Date: Fri, 11 Sep 2015 13:56:53 -0400 Subject: [PATCH 3700/4858] Update search-replace.php --- php/commands/search-replace.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b6e93a71bb..5e2df5649f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -14,8 +14,8 @@ class Search_Replace_Command extends WP_CLI_Command { * * 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). + * 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. * From 380a5862a9af3c5b3d80ad72bbd5ee22a3b73e78 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Fri, 11 Sep 2015 11:26:55 -0700 Subject: [PATCH 3701/4858] capital P See #2045 --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 5e2df5649f..f3c1b2f001 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -15,7 +15,7 @@ class Search_Replace_Command extends WP_CLI_Command { * 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). + * just WordPress core tables). * * It will correctly handle serialized values, and will not change primary key values. * From 031c531072013686a12e04a83dc3626d9d7a83d6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 13 Sep 2015 06:38:39 -0700 Subject: [PATCH 3702/4858] Generic args for `wp comment create` should always be optional ... including setting a post ID --- php/commands/comment.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index e27d30647a..38d0bdb12d 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -32,7 +32,7 @@ public function __construct() { * * ## OPTIONS * - * --<field>=<value> + * [--<field>=<value>] * : Associative args for the new comment. See wp_insert_comment(). * * [--porcelain] @@ -44,10 +44,12 @@ public function __construct() { */ public function create( $args, $assoc_args ) { parent::_create( $args, $assoc_args, function ( $params ) { - $post_id = $params['comment_post_ID']; - $post = get_post( $post_id ); - if ( !$post ) { - return new WP_Error( 'no_post', "Can't find post $post_id." ); + if ( isset( $params['comment_post_ID'] ) ) { + $post_id = $params['comment_post_ID']; + $post = get_post( $post_id ); + if ( !$post ) { + return new WP_Error( 'no_post', "Can't find post $post_id." ); + } } // We use wp_insert_comment() instead of wp_new_comment() to stay at a low level and From bf1f0297661c384e90634c46dbeb5e3766c59225 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 13 Sep 2015 07:20:46 -0700 Subject: [PATCH 3703/4858] Add `--post_type__not_in` argument to `wp export` This argument makes it easier to generate an export with all post types _except_ those identified. --- features/export.feature | 62 ++++++++++++++++++++++++++++++++++++++++- php/commands/export.php | 50 +++++++++++++++++++++++++-------- 2 files changed, 100 insertions(+), 12 deletions(-) diff --git a/features/export.feature b/features/export.feature index 58d183546b..ab8c51b40e 100644 --- a/features/export.feature +++ b/features/export.feature @@ -316,4 +316,64 @@ Feature: Export content. Then STDOUT should be: """ 5 - """ \ No newline at end of file + """ + + Scenario: Exclude a specific post type from export + Given a WP install + And I run `wp post generate --post_type=post --count=10` + And I run `wp plugin install wordpress-importer --activate` + + When I run `wp post list --post_type=any --format=count` + Then STDOUT should be: + """ + 12 + """ + + When I run `wp export --post_type__not_in=post` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp post generate --post_type=post --count=10` + And I run `wp post list --post_type=any --format=count` + Then STDOUT should be: + """ + 11 + """ + + When I run `wp export --post_type__not_in=post,page` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=any --format=count` + Then STDOUT should be: + """ + 0 + """ diff --git a/php/commands/export.php b/php/commands/export.php index de8ab40639..230548afd6 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -35,6 +35,10 @@ class Export_Command extends WP_CLI_Command { * : Export only posts with this post_type. Separate multiple post types with a * comma. Defaults to all. * + * [--post_type__not_in=<post-type>] + * : Export all post types except those identified. Seperate multiple post types + * with a comma. Defaults to none. + * * [--post__in=<pid>] * : Export all posts specified as a comma-separated list of IDs. * @@ -58,17 +62,18 @@ class Export_Command extends WP_CLI_Command { */ public function __invoke( $_, $assoc_args ) { $defaults = array( - 'dir' => NULL, - 'start_date' => NULL, - 'end_date' => NULL, - 'post_type' => NULL, - 'author' => NULL, - 'category' => NULL, - 'post_status' => NULL, - 'post__in' => NULL, - 'start_id' => NULL, - 'skip_comments' => NULL, - 'max_file_size' => 15, + 'dir' => NULL, + 'start_date' => NULL, + 'end_date' => NULL, + 'post_type' => NULL, + 'post_type__not_in' => NULL, + 'author' => NULL, + 'category' => NULL, + 'post_status' => NULL, + 'post__in' => NULL, + 'start_id' => NULL, + 'skip_comments' => NULL, + 'max_file_size' => 15, ); $this->validate_args( wp_parse_args( $assoc_args, $defaults ) ); @@ -201,6 +206,29 @@ private function check_post_type( $post_type ) { return true; } + private function check_post_type__not_in( $post_type ) { + if ( is_null( $post_type ) ) { + return true; + } + + $post_type = array_unique( array_filter( explode( ',', $post_type ) ) ); + $post_types = get_post_types(); + + $keep_post_types = array(); + foreach ( $post_type as $type ) { + if ( ! in_array( $type, $post_types ) ) { + WP_CLI::warning( sprintf( + 'The post type %s does not exist. Use any of these existing post types instead: %s', + $type, + implode( ", ", $post_types ) + ) ); + return false; + } + } + $this->export_args['post_type'] = array_diff( $post_types, $post_type ); + return true; + } + private function check_post__in( $post__in ) { if ( is_null( $post__in ) ) return true; From deb904f024c0ff307bdc662fb888534916a1c136 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 13 Sep 2015 07:50:57 -0700 Subject: [PATCH 3704/4858] Use `wp core update-db --network` to upgrade databases across network --- features/core.feature | 11 +++++++++++ php/class-wp-cli.php | 7 +++++-- php/commands/core.php | 38 ++++++++++++++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/features/core.feature b/features/core.feature index 558fcb70f4..7d508c7d1a 100644 --- a/features/core.feature +++ b/features/core.feature @@ -289,6 +289,17 @@ Feature: Manage WordPress installation Error: Multisite with subdomains cannot be configured when domain is 'localhost'. """ + Scenario: Update db across network + Given a WP multisite install + And I run `wp site create --slug=foo` + And I run `wp site create --slug=bar` + + When I run `wp core update-db --network` + Then STDOUT should contain: + """ + Success: WordPress database upgraded on 3/3 sites. + """ + Scenario: Update from a ZIP file Given a WP install diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 6204574338..c4255ac683 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -397,10 +397,11 @@ public static function launch( $command, $exit_on_error = true, $return_detailed * @param array $assoc_args Associative arguments to use * @param bool Whether to exit if the command returns an error status * @param bool Whether to return an exit status (default) or detailed execution results + * @param array $runtime_args Override one or more global args (path,url,user,allow-root) * * @return int|ProcessRun The command exit status, or a ProcessRun instance */ - public static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false ) { + public static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false, $runtime_args = array() ) { $reused_runtime_args = array( 'path', 'url', @@ -409,7 +410,9 @@ public static function launch_self( $command, $args = array(), $assoc_args = arr ); foreach ( $reused_runtime_args as $key ) { - if ( $value = self::get_runner()->config[ $key ] ) + if ( isset( $runtime_args[ $key ] ) ) { + $assoc_args[ $key ] = $runtime_args[ $key ]; + } else if ( $value = self::get_runner()->config[ $key ] ) $assoc_args[ $key ] = $value; } diff --git a/php/commands/core.php b/php/commands/core.php index d654100431..fae093dcc7 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -968,12 +968,42 @@ function update( $args, $assoc_args ) { /** * Update the WordPress database. * + * [--network] + * : Update databases for all sites on a network + * * @subcommand update-db */ - function update_db() { - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - wp_upgrade(); - WP_CLI::success( 'WordPress database upgraded successfully.' ); + function update_db( $_, $assoc_args ) { + global $wpdb; + + $network = Utils\get_flag_value( $assoc_args, 'network' ); + if ( $network && ! is_multisite() ) { + WP_CLI::error( 'This is not a multisite install.' ); + } + + if ( $network ) { + $iterator_args = array( + 'table' => $wpdb->blogs, + ); + $it = new \WP_CLI\Iterators\Table( $iterator_args ); + $success = $total = 0; + foreach( $it as $blog ) { + $total++; + $url = $blog->domain . $blog->path; + $process = WP_CLI::launch_self( 'core update-db', array(), array(), false, true, array( 'url' => $url ) ); + if ( 0 == $process->return_code ) { + WP_CLI::log( "Database upgraded successfully on {$url}" ); + $success++; + } else { + WP_CLI::warning( "Database failed to upgrade on {$url}" ); + } + } + WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites.', $success, $total ) ); + } else { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + wp_upgrade(); + WP_CLI::success( 'WordPress database upgraded successfully.' ); + } } /** From ea6ee604fa54e6de7c1f247ad0bf7deb136a2361 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Tue, 15 Sep 2015 16:33:55 -0700 Subject: [PATCH 3705/4858] Failing test case for wp-includes/session.php not loading See #2049 --- features/framework.feature | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 features/framework.feature diff --git a/features/framework.feature b/features/framework.feature new file mode 100644 index 0000000000..438471e254 --- /dev/null +++ b/features/framework.feature @@ -0,0 +1,15 @@ +Feature: Load WP-CLI + + Scenario: A plugin calling wp_signon() shouldn't fatal + Given a WP install + And I run `wp user create testuser test@example.org --user_pass=testuser` + And a wp-content/mu-plugins/test.php file: + """ + <?php + add_action( 'plugins_loaded', function(){ + wp_signon( array( 'user_login' => 'testuser', 'user_password' => 'testuser' ) ); + }); + """ + + When I run `wp option get home` + Then STDOUT should not be empty From 519ad782bf7e370f19eb81f4dcc5b8b8bac1bcc3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Tue, 15 Sep 2015 16:35:01 -0700 Subject: [PATCH 3706/4858] Ensure wp-includes/session.php is loaded in bootstrap --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 28cc2380b2..720ef44af2 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -139,6 +139,7 @@ require( ABSPATH . WPINC . '/class-wp-theme.php' ); require( ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); +require( ABSPATH . WPINC . '/session.php' ); require( ABSPATH . WPINC . '/meta.php' ); require( ABSPATH . WPINC . '/general-template.php' ); require( ABSPATH . WPINC . '/link-template.php' ); From 1a947094432c7e4bf10508c9444ae3144eee9b3d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Tue, 15 Sep 2015 16:43:11 -0700 Subject: [PATCH 3707/4858] Dismiss admin notice if all upgrades were successful --- php/commands/core.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index fae093dcc7..2fd10be8df 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -974,7 +974,7 @@ function update( $args, $assoc_args ) { * @subcommand update-db */ function update_db( $_, $assoc_args ) { - global $wpdb; + global $wpdb, $wp_db_version; $network = Utils\get_flag_value( $assoc_args, 'network' ); if ( $network && ! is_multisite() ) { @@ -998,6 +998,9 @@ function update_db( $_, $assoc_args ) { WP_CLI::warning( "Database failed to upgrade on {$url}" ); } } + if ( $total && $success == $total ) { + update_site_option( 'wpmu_upgrade_site', $wp_db_version ); + } WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites.', $success, $total ) ); } else { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); From ff2c2522c031a51df535dde4324eebcf257e9862 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Tue, 15 Sep 2015 16:50:25 -0700 Subject: [PATCH 3708/4858] Update tests for WP 4.3.1 and associated security releases --- features/core.feature | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/features/core.feature b/features/core.feature index 558fcb70f4..2cae7ea1a6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -316,7 +316,7 @@ Feature: Manage WordPress installation 3.9 """ - @download + @download @update-check Scenario: Check for update via Version Check API Given a WP install @@ -326,12 +326,12 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.3 | major | https://wordpress.org/wordpress-4.3.zip | - | 4.2.4 | major | https://wordpress.org/wordpress-4.2.4.zip | - | 4.1.7 | major | https://wordpress.org/wordpress-4.1.7.zip | - | 4.0.7 | major | https://wordpress.org/wordpress-4.0.7.zip | - | 3.9.8 | major | https://wordpress.org/wordpress-3.9.8.zip | - | 3.8.10 | minor | https://wordpress.org/wordpress-3.8.10.zip | + | 4.3.1 | major | https://wordpress.org/wordpress-4.3.1.zip | + | 4.2.5 | major | https://wordpress.org/wordpress-4.2.5.zip | + | 4.1.8 | major | https://wordpress.org/wordpress-4.1.8.zip | + | 4.0.8 | major | https://wordpress.org/wordpress-4.0.8.zip | + | 3.9.9 | major | https://wordpress.org/wordpress-3.9.9.zip | + | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -342,11 +342,11 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.3 | major | https://wordpress.org/wordpress-4.3.zip | - | 4.2.4 | major | https://wordpress.org/wordpress-4.2.4.zip | - | 4.1.7 | major | https://wordpress.org/wordpress-4.1.7.zip | - | 4.0.7 | major | https://wordpress.org/wordpress-4.0.7.zip | - | 3.9.8 | major | https://wordpress.org/wordpress-3.9.8.zip | + | 4.3.1 | major | https://wordpress.org/wordpress-4.3.1.zip | + | 4.2.5 | major | https://wordpress.org/wordpress-4.2.5.zip | + | 4.1.8 | major | https://wordpress.org/wordpress-4.1.8.zip | + | 4.0.8 | major | https://wordpress.org/wordpress-4.0.8.zip | + | 3.9.9 | major | https://wordpress.org/wordpress-3.9.9.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -357,7 +357,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.10 | minor | https://wordpress.org/wordpress-3.8.10.zip | + | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: From ff176910ee47290f1593206264ca4d7f679056f1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Wed, 16 Sep 2015 06:21:57 -0700 Subject: [PATCH 3709/4858] `session.php` was introduced in WP 4.0 --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 720ef44af2..c52034c159 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -139,7 +139,7 @@ require( ABSPATH . WPINC . '/class-wp-theme.php' ); require( ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); -require( ABSPATH . WPINC . '/session.php' ); +Utils\maybe_require( '4.0', ABSPATH . WPINC . '/session.php' ); require( ABSPATH . WPINC . '/meta.php' ); require( ABSPATH . WPINC . '/general-template.php' ); require( ABSPATH . WPINC . '/link-template.php' ); From b1b6c0dbc920abc4a6a53713005d3393d1e9165a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 19 Sep 2015 15:06:53 +0200 Subject: [PATCH 3710/4858] Fixed deb creator script: added changelog, man page, copyright --- utils/wp-cli-updatedeb.sh | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh index 7f1aefe336..fe40b73e4a 100755 --- a/utils/wp-cli-updatedeb.sh +++ b/utils/wp-cli-updatedeb.sh @@ -24,7 +24,7 @@ die() { } dump_control() { - cat > DEBIAN/control <<CTRL + cat > DEBIAN/control <<EOF Package: php-wpcli Version: 0.0.0 Architecture: all @@ -37,7 +37,7 @@ Description: wp-cli is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs and much more, without using a web browser. -CTRL +EOF } # deb's dir @@ -53,6 +53,31 @@ if ! [ -r DEBIAN/control ]; then dump_control fi +# copyright +if ! [ -r usr/share/doc/php-wpcli/copyright ];then + mkdir -p usr/share/doc/php-wpcli &> /dev/null + wget -nv -O usr/share/doc/php-wpcli/copyright https://github.com/wp-cli/wp-cli/raw/master/LICENSE.txt +fi + +# changelog +if ! [ -r usr/share/doc/php-wpcli/changelog.gz ];then + mkdir -p usr/share/doc/php-wpcli &> /dev/null + echo "Changelog can be found in the blog: http://wp-cli.org/blog/" \ + | gzip -9 > usr/share/doc/php-wpcli/changelog.gz +fi + +# minimal man page +if ! [ -r usr/share/man/man1/wp.1.gz ];then + mkdir -p usr/share/man/man1 &> /dev/null + { + echo '.TH "WP" "1"' + wp --help + } \ + | sed 's/^\([A-Z ]\+\)$/.SH "\1"/' \ + | sed 's/^ wp$/wp \\- A command line interface for WordPress/' \ + | gzip -9 > usr/share/man/man1/wp.1.gz +fi + # content dirs [ -d usr/bin ] || mkdir -p usr/bin @@ -78,6 +103,6 @@ WPCLI_PKG="${PWD}/php-wpcli_${WPCLI_VER}_all.deb" fakeroot dpkg-deb --build "$DIR" "$WPCLI_PKG" || die 8 "Packaging failed" # optional steps -echo "sign it: dpkg-sig -k <YOUR-KEY> -s builder \"$WPCLI_PKG\"" -echo "include in your repo: pushd /var/www/<REPO-DIR>" -echo "reprepro includedeb wheezy \"$WPCLI_PKG\" && popd" +echo "sign it: dpkg-sig -k YOUR-KEY -s builder \"${WPCLI_PKG}\"" +echo "include in your repo: pushd /var/www/REPO-DIR" +echo " reprepro includedeb jessie \"${WPCLI_PKG}\" && popd" From f71b4c1c6fcbd65bac0d45272b5e01afe204afac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sat, 19 Sep 2015 11:02:21 -0700 Subject: [PATCH 3711/4858] Let user know when invalid subcommand has a valid parent command --- features/command.feature | 24 ++++++++++++++++++++++++ php/WP_CLI/Runner.php | 19 +++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/features/command.feature b/features/command.feature index 6e034d6b28..2039cc1232 100644 --- a/features/command.feature +++ b/features/command.feature @@ -15,3 +15,27 @@ Feature: WP-CLI Commands """ Class 'Non_Existent_Class' does not exist. """ + + Scenario: Invalid subcommand of valid command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + /** + * @when before_wp_load + */ + class Custom_Command_Class extends WP_CLI_Command { + + public function valid() { + WP_CLI::success( 'Hello world' ); + } + + } + WP_CLI::add_command( 'command', 'Custom_Command_Class' ); + """ + + When I try `wp --require=custom-cmd.php command invalid` + Then STDERR should be: + """ + Error: 'invalid' is not a registered subcommand of 'command'. See 'wp help command'. + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3e36d818db..7a6b02715a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -261,10 +261,21 @@ public function find_command_to_run( $args ) { $subcommand = $command->find_subcommand( $args ); if ( !$subcommand ) { - return sprintf( - "'%s' is not a registered wp command. See 'wp help'.", - $full_name - ); + if ( count( $cmd_path ) > 1 ) { + $child = array_pop( $cmd_path ); + $parent_name = implode( ' ', $cmd_path ); + return sprintf( + "'%s' is not a registered subcommand of '%s'. See 'wp help %s'.", + $child, + $parent_name, + $parent_name + ); + } else { + return sprintf( + "'%s' is not a registered wp command. See 'wp help'.", + $full_name + ); + } } if ( $this->is_command_disabled( $subcommand ) ) { From 6b54e61a793f8d8b78014863f6c0f07199ed8761 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sat, 19 Sep 2015 11:26:30 -0700 Subject: [PATCH 3712/4858] Permit `--path` for `wp core download`, even when WP is detected This lets a custom WP-CLI command download WP to a different directory, when loaded from the scope of an existing WP install. --- features/core.feature | 26 ++++++++++++++++++++++++++ php/commands/core.php | 15 +++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/features/core.feature b/features/core.feature index a731cf6f6f..d0e3b16bdb 100644 --- a/features/core.feature +++ b/features/core.feature @@ -490,6 +490,32 @@ Feature: Manage WordPress installation Error: Release not found. """ + Scenario: Core download to a directory specified by `--path` in custom command + Given a WP install + And a download-command.php file: + """ + <?php + class Download_Command extends WP_CLI_Command { + public function __invoke() { + WP_CLI::run_command( array( 'core', 'download' ), array( 'path' => 'src/' ) ); + } + } + WP_CLI::add_command( 'custom-download', 'Download_Command' ); + """ + + When I run `wp --require=download-command.php custom-download` + Then STDOUT should not be empty + And the src directory should contain: + """ + wp-load.php + """ + + When I try `wp --require=download-command.php custom-download` + Then STDERR should be: + """ + Error: WordPress files seem to already be present here. + """ + Scenario: Ensure cached partial upgrades aren't used in full upgrade Given a WP install And an empty cache diff --git a/php/commands/core.php b/php/commands/core.php index 2fd10be8df..81694a7074 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -121,13 +121,16 @@ function check_update( $_, $assoc_args ) { * @when before_wp_load */ public function download( $args, $assoc_args ) { - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && is_readable( ABSPATH . 'wp-load.php' ) ) + + $download_dir = ! empty( $assoc_args['path'] ) ? $assoc_args['path'] : ABSPATH; + + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && is_readable( $download_dir . 'wp-load.php' ) ) WP_CLI::error( 'WordPress files seem to already be present here.' ); - if ( !is_dir( ABSPATH ) ) { - WP_CLI::log( sprintf( 'Creating directory %s', ABSPATH ) ); + if ( !is_dir( $download_dir ) ) { + WP_CLI::log( sprintf( 'Creating directory %s', $download_dir ) ); $mkdir = \WP_CLI\Utils\is_windows() ? 'mkdir %s' : 'mkdir -p %s'; - WP_CLI::launch( Utils\esc_cmd( $mkdir, ABSPATH ) ); + WP_CLI::launch( Utils\esc_cmd( $mkdir, $download_dir ) ); } $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', 'en_US' ); @@ -154,7 +157,7 @@ public function download( $args, $assoc_args ) { if ( $cache_file ) { WP_CLI::log( "Using cached file '$cache_file'..." ); try{ - self::_extract( $cache_file, ABSPATH ); + self::_extract( $cache_file, $download_dir ); } catch ( Exception $e ) { WP_CLI::warning( "Extraction failed, downloading a new copy..." ); $bad_cache = true; @@ -180,7 +183,7 @@ public function download( $args, $assoc_args ) { } try { - self::_extract( $temp, ABSPATH ); + self::_extract( $temp, $download_dir ); } catch ( Exception $e ) { WP_CLI::error( "Couldn't extract WordPress archive. " . $e->getMessage() ); } From 5f677bcedf829738ab66d6963354ff4904ac7b66 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sat, 19 Sep 2015 11:50:07 -0700 Subject: [PATCH 3713/4858] Pass any `rewrite flush` warnings when using `rewrite structure` --- features/rewrite.feature | 6 ++++++ php/commands/rewrite.php | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index 25fe482e1a..3c49c4843f 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -75,3 +75,9 @@ Feature: Manage WordPress rewrites """ Warning: WordPress can't generate .htaccess file for a multisite install. """ + + When I try `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/ --hard` + Then STDERR should contain: + """ + Warning: WordPress can't generate .htaccess file for a multisite install. + """ diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 58c5ff26c6..5a6f4ab0b6 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -129,7 +129,11 @@ public function structure( $args, $assoc_args ) { } } - \WP_CLI::launch_self( 'rewrite flush', array(), $new_assoc_args ); + $process_run = WP_CLI::launch_self( 'rewrite flush', array(), $new_assoc_args, true, true, array( 'apache_modules', WP_CLI::get_config( 'apache_modules' ) ) ); + if ( ! empty( $process_run->stderr ) ) { + // Strip "Warning: " + WP_CLI::warning( substr( $process_run->stderr, 9 ) ); + } WP_CLI::success( "Rewrite structure set." ); } From 8a3af834b43f34d998f79a426370ffb5b3b41de5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sat, 19 Sep 2015 11:56:24 -0700 Subject: [PATCH 3714/4858] Run test suite against PHP 5.6, instead of PHP 5.5 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 28e3bdd2bb..8f37b55a47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ language: php php: - 5.3 - - 5.5 + - 5.6 env: global: @@ -34,12 +34,12 @@ env: - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: - - WP_VERSION=4.3 + - WP_VERSION=4.3.1 - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: exclude: - - php: 5.5 + - php: 5.6 env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master before_script: ./ci/prepare.sh From a77a9df6c3106cef756b087d07cd776efbcf30f4 Mon Sep 17 00:00:00 2001 From: Stephen Edgar <stephen@netweb.com.au> Date: Sun, 20 Sep 2015 10:00:24 +1000 Subject: [PATCH 3715/4858] Use HTTPS for w.org SVN checkout --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index c96a09f17d..80ba41649c 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -56,7 +56,7 @@ install_test_suite() { if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR - svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR/includes fi cd $WP_TESTS_DIR From 9f597261f0f7d60f50e6e1e1b86d6ee41d18abd9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 05:45:27 -0700 Subject: [PATCH 3716/4858] Deprecate `wp post url` in favor of `wp post list --field=url` --- php/WP_CLI/Runner.php | 11 +++++++++++ php/commands/post.php | 25 ++++++------------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7a6b02715a..33ef848ee6 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -453,6 +453,17 @@ private static function back_compat_conversions( $args, $assoc_args ) { } } + // post url --> post list --post__in --field=url + if ( count( $args ) >= 2 && 'post' === $args[0] && 'url' === $args[1] ) { + $post_ids = array_slice( $args, 2 ); + $args = array( 'post', 'list' ); + $assoc_args['post__in'] = implode( ',', $post_ids ); + $assoc_args['post_type'] = 'any'; + $assoc_args['orderby'] = 'post__in'; + $assoc_args['field'] = 'url'; + break; + } + return array( $args, $assoc_args ); } diff --git a/php/commands/post.php b/php/commands/post.php index 3d5fa4557c..38dd7d2c61 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -270,6 +270,7 @@ public function delete( $args, $assoc_args ) { * * post_mime_type * * comment_count * * filter + * * url * * ## EXAMPLES * @@ -305,7 +306,11 @@ public function list_( $_, $assoc_args ) { echo implode( ' ', $query->posts ); } else { $query = new WP_Query( $query_args ); - $formatter->display_items( $query->posts ); + $posts = array_map( function( $post ) { + $post->url = get_permalink( $post->ID ); + return $post; + }, $query->posts ); + $formatter->display_items( $posts ); } } @@ -424,24 +429,6 @@ public function generate( $args, $assoc_args ) { // @codingStandardsIgnoreEnd } - /** - * Get post url - * - * ## OPTIONS - * - * <id>... - * : One or more IDs of posts get the URL. - * - * ## EXAMPLES - * - * wp post url 123 - * - * wp post url 123 324 - */ - public function url( $args ) { - parent::_url( $args, 'get_permalink' ); - } - private function maybe_make_child() { // 50% chance of making child post return ( mt_rand(1, 2) == 1 ); From 6b7bbe7690183c2d1daf82e6fa595a9ac1e74bea Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 06:01:27 -0700 Subject: [PATCH 3717/4858] Attempt two at seeing what fails in PHP 7 --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8f37b55a47..46b1adf308 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ language: php php: - 5.3 - 5.6 + - '7' env: global: @@ -41,6 +42,8 @@ matrix: exclude: - php: 5.6 env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master + - php: '7' + env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master before_script: ./ci/prepare.sh From aa74d5ecd0a7e674a30968ea60ba8bf7df16332b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 06:08:09 -0700 Subject: [PATCH 3718/4858] Remove errant `break` --- php/WP_CLI/Runner.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 33ef848ee6..e84a9a177f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -461,7 +461,6 @@ private static function back_compat_conversions( $args, $assoc_args ) { $assoc_args['post_type'] = 'any'; $assoc_args['orderby'] = 'post__in'; $assoc_args['field'] = 'url'; - break; } return array( $args, $assoc_args ); From 5e5733803c0d8e79f997b4de951e5c722f4650b5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 07:01:51 -0700 Subject: [PATCH 3719/4858] Deprecate `wp site url` in favor of `wp site list --field=url` Also uses `get_site_url()` to produce `url` in `wp site list` for consistency with other resources --- features/site.feature | 31 +++++++++++++++++++++---------- php/WP_CLI/Iterators/Table.php | 11 ++++++++--- php/WP_CLI/Runner.php | 26 ++++++++++++++++++-------- php/commands/site.php | 29 ++++++++--------------------- 4 files changed, 55 insertions(+), 42 deletions(-) diff --git a/features/site.feature b/features/site.feature index 58eb137f86..f46478da93 100644 --- a/features/site.feature +++ b/features/site.feature @@ -18,15 +18,15 @@ Feature: Manage sites in a multisite installation When I run `wp site list --fields=blog_id,url` Then STDOUT should be a table containing rows: - | blog_id | url | - | 1 | example.com/ | - | 2 | example.com/first/ | + | blog_id | url | + | 1 | http://example.com/ | + | 2 | http://example.com/first/ | When I run `wp site list --field=url` Then STDOUT should be: """ - example.com/ - example.com/first/ + http://example.com/ + http://example.com/first/ """ When I run `wp site delete {SITE_ID} --yes` @@ -44,14 +44,14 @@ Feature: Manage sites in a multisite installation When I run `wp site list --fields=blog_id,url` Then STDOUT should be a table containing rows: - | blog_id | url | - | 1 | example.com/ | - | 2 | example.com/first/ | + | blog_id | url | + | 1 | http://example.com/ | + | 2 | http://example.com/first/ | When I run `wp site list --field=url --blog_id=2` Then STDOUT should be: """ - example.com/first/ + http://example.com/first/ """ Scenario: Delete a site by slug @@ -100,7 +100,18 @@ Feature: Manage sites in a multisite installation When I run `wp site url {SITE_ID}` Then STDOUT should be: """ - http://example.com/first + http://example.com/first/ + """ + + When I run `wp site create --slug=second --porcelain` + Then STDOUT should be a number + And save STDOUT as {SECOND_ID} + + When I run `wp site url {SECOND_ID} {SITE_ID}` + Then STDOUT should be: + """ + http://example.com/second/ + http://example.com/first/ """ Scenario: Archive/unarchive a site diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index eb7d1d60fd..cebb812bd7 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -36,11 +36,13 @@ class Table extends Query { * = string – this will be the where clause * = array – each element is treated as a condition if it's positional, or as column => value if * it's a key/value pair. In the latter case the value is automatically quoted and escaped + * append - add arbitrary extra SQL */ function __construct( $args = array() ) { $defaults = array( 'fields' => '*', 'where' => array(), + 'append' => '', 'table' => null, 'chunk_size' => 500 ); @@ -50,7 +52,7 @@ function __construct( $args = array() ) { $fields = self::build_fields( $args['fields'] ); $conditions = self::build_where_conditions( $args['where'] ); $where_sql = $conditions ? " WHERE $conditions" : ''; - $query = "SELECT $fields FROM $table $where_sql"; + $query = "SELECT $fields FROM $table $where_sql {$args['append']}"; parent::__construct( $query, $args['chunk_size'] ); } @@ -67,10 +69,13 @@ private static function build_where_conditions( $where ) { if ( is_array( $where ) ) { $conditions = array(); foreach( $where as $key => $value ) { - if ( is_numeric( $key ) ) + if ( is_array( $value ) ) { + $conditions[] = $key . ' IN (' . $wpdb->escape( implode( ',', $value ) ) . ')'; + } else if ( is_numeric( $key ) ) { $conditions[] = $value; - else + } else { $conditions[] = $key . ' = "' . $wpdb->escape( $value ) .'"'; + } } $where = implode( ' AND ', $conditions ); } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e84a9a177f..5a3927f46d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -453,14 +453,24 @@ private static function back_compat_conversions( $args, $assoc_args ) { } } - // post url --> post list --post__in --field=url - if ( count( $args ) >= 2 && 'post' === $args[0] && 'url' === $args[1] ) { - $post_ids = array_slice( $args, 2 ); - $args = array( 'post', 'list' ); - $assoc_args['post__in'] = implode( ',', $post_ids ); - $assoc_args['post_type'] = 'any'; - $assoc_args['orderby'] = 'post__in'; - $assoc_args['field'] = 'url'; + // (post|site) url --> (post|site) list --*__in --field=url + if ( count( $args ) >= 2 && in_array( $args[0], array( 'post', 'site' ) ) && 'url' === $args[1] ) { + switch ( $args[0] ) { + case 'post': + $post_ids = array_slice( $args, 2 ); + $args = array( 'post', 'list' ); + $assoc_args['post__in'] = implode( ',', $post_ids ); + $assoc_args['post_type'] = 'any'; + $assoc_args['orderby'] = 'post__in'; + $assoc_args['field'] = 'url'; + break; + case 'site': + $site_ids = array_slice( $args, 2 ); + $args = array( 'site', 'list' ); + $assoc_args['site__in'] = implode( ',', $site_ids ); + $assoc_args['field'] = 'url'; + break; + } } return array( $args, $assoc_args ); diff --git a/php/commands/site.php b/php/commands/site.php index cbdf6ac18e..d9faf3e9ab 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -394,6 +394,7 @@ public function list_( $_, $assoc_args ) { $assoc_args = array_merge( $defaults, $assoc_args ); $where = array(); + $append = ''; $site_cols = array( 'blog_id', 'url', 'last_updated', 'registered', 'site_id', 'domain', 'path', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' ); foreach( $site_cols as $col ) { @@ -402,6 +403,11 @@ public function list_( $_, $assoc_args ) { } } + if ( isset( $assoc_args['site__in'] ) ) { + $where['blog_id'] = explode( ',', $assoc_args['site__in'] ); + $append = "ORDER BY FIELD( blog_id, " . implode( ',', array_map( 'intval', $where['blog_id'] ) ) . " )"; + } + if ( isset( $assoc_args['network'] ) ) { $where['site_id'] = $assoc_args['network']; } @@ -409,11 +415,12 @@ public function list_( $_, $assoc_args ) { $iterator_args = array( 'table' => $wpdb->blogs, 'where' => $where, + 'append' => $append, ); $it = new \WP_CLI\Iterators\Table( $iterator_args ); $it = \WP_CLI\Utils\iterator_map( $it, function( $blog ) { - $blog->url = $blog->domain . $blog->path; + $blog->url = trailingslashit( get_site_url( $blog->blog_id ) ); return $blog; } ); @@ -421,26 +428,6 @@ public function list_( $_, $assoc_args ) { $formatter->display_items( $it ); } - /** - * Get site url - * - * ## OPTIONS - * - * <id>... - * : One or more IDs of sites to get the URL. - * - * ## EXAMPLES - * - * wp site url 123 - */ - public function url( $args ) { - if ( !is_multisite() ) { - WP_CLI::error( 'This is not a multisite install.' ); - } - - parent::_url( $args, 'get_site_url' ); - } - /** * Archive one or more sites * From 69bb3694663a32455a22fe5e8336cb5ebb624760 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 07:07:44 -0700 Subject: [PATCH 3720/4858] Add test case for custom base path for multisite --- features/core.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/core.feature b/features/core.feature index d0e3b16bdb..4eb71f8eb8 100644 --- a/features/core.feature +++ b/features/core.feature @@ -490,6 +490,16 @@ Feature: Manage WordPress installation Error: Release not found. """ + Scenario: Test output in a multisite install with custom base path + Given a WP install + + When I run `wp core multisite-convert --title=Test --base=/test/` + And I run `wp post list` + Then STDOUT should contain: + """ + Hello world! + """ + Scenario: Core download to a directory specified by `--path` in custom command Given a WP install And a download-command.php file: From ce7b969cd8571eaed6c996cb3f0d096c5bad96f9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 07:36:50 -0700 Subject: [PATCH 3721/4858] Update db tests to use empty `DB_CHARSET` instead of file mod hack --- features/db.feature | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/features/db.feature b/features/db.feature index 2fc9b71e55..3734989519 100644 --- a/features/db.feature +++ b/features/db.feature @@ -73,17 +73,19 @@ Feature: Perform database operations """ Scenario: DB export no charset - Given a WP install - And a replace-script.php file: + Given an empty directory + And WP files + + When I run `wp core config {CORE_CONFIG_SETTINGS} --dbcharset=""` + Then STDOUT should not be empty + + When I run `cat wp-config.php` + Then STDOUT should contain: """ - <?php - $wp_config = file_get_contents( 'wp-config.php' ); - $wp_config = str_replace( 'utf8', '', $wp_config ); - file_put_contents( 'wp-config.php', $wp_config ); - WP_CLI::success( "Replaced charset" ); + define('DB_CHARSET', ''); """ - When I run `wp eval-file replace-script.php` + When I run `wp db create` Then STDOUT should not be empty When I run `wp db export /tmp/wp-cli-behat.sql` From e1c5db0b383979bce60734b0cf6a499af9850c5d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 07:48:09 -0700 Subject: [PATCH 3722/4858] Support APC cache with WP-CLI, but only after warning with confirmation --- php/wp-settings-cli.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index c52034c159..a72c3d50de 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -102,7 +102,8 @@ // WP-CLI: the APC cache is not available on the command-line, so bail, to prevent cache poisoning if ( $GLOBALS['_wp_using_ext_object_cache'] && class_exists( 'APC_Object_Cache' ) ) { - WP_CLI::error( 'WP-CLI is not compatible with the APC object cache.' ); + WP_CLI::warning( 'Running WP-CLI while the APC object cache is activated can result in cache corruption.' ); + WP_CLI::confirm( 'Given the consequences, do you wish to continue?' ); } // Attach the default filters. From e430b6228a52b4c0215b3cf2698ec2d216806190 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 14:06:41 -0700 Subject: [PATCH 3723/4858] Deprecate `@synopsis` for `cap`, `eval`, `help`, `option`, and others --- php/commands/cap.php | 16 +++++++++++++--- php/commands/eval.php | 5 +++-- php/commands/help.php | 7 ++++--- php/commands/option.php | 10 +++++++--- php/commands/site.php | 12 +++++------- php/commands/transient.php | 18 +++++++++++++++--- php/commands/user.php | 5 ----- 7 files changed, 47 insertions(+), 26 deletions(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index afeee5d54c..9330c2c9a7 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -19,13 +19,15 @@ class Capabilities_Command extends WP_CLI_Command { /** * List capabilities for a given role. * + * <role> + * : Key for the role. + * * ## EXAMPLES * * # Display alphabetical list of bbPress moderator capabilities * wp cap list 'bbp_moderator' | sort * * @subcommand list - * @synopsis <role> */ public function list_( $args ) { $role_obj = self::get_role( $args[0] ); @@ -37,7 +39,11 @@ public function list_( $args ) { /** * Add capabilities to a given role. * - * @synopsis <role> <cap>... + * <role> + * : Key for the role. + * + * <cap>... + * : One or more capabilities to add. */ public function add( $args ) { self::persistence_check(); @@ -63,7 +69,11 @@ public function add( $args ) { /** * Remove capabilities from a given role. * - * @synopsis <role> <cap>... + * <role> + * : Key for the role. + * + * <cap>... + * : One or more capabilities to remove. */ public function remove( $args ) { self::persistence_check(); diff --git a/php/commands/eval.php b/php/commands/eval.php index 782752b76e..cce2ca4b28 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -5,11 +5,12 @@ class Eval_Command extends WP_CLI_Command { /** * Execute arbitrary PHP code after loading WordPress. * + * <php-code> + * : The code to execute, as a string. + * * ## EXAMPLES * * wp eval 'echo WP_CONTENT_DIR;' - * - * @synopsis <php-code> */ public function __invoke( $args, $assoc_args ) { eval( $args[0] ); diff --git a/php/commands/help.php b/php/commands/help.php index 615089bbce..ec2dcce53f 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -6,7 +6,10 @@ class Help_Command extends WP_CLI_Command { /** - * Get help on a certain command. + * Get help on WP-CLI, or on a specific. command. + * + * [<command>...] + * : Get help on a specific command. * * ## EXAMPLES * @@ -15,8 +18,6 @@ class Help_Command extends WP_CLI_Command { * * # get help for `core download` subcommand * wp help core download - * - * @synopsis [<command>...] */ function __invoke( $args, $assoc_args ) { $command = self::find_subcommand( $args ); diff --git a/php/commands/option.php b/php/commands/option.php index ff6cadc63e..979a53b28f 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -23,7 +23,11 @@ class Option_Command extends WP_CLI_Command { /** * Get an option. * - * @synopsis <key> [--format=<format>] + * <key> + * : Key for the option + * + * [--format=<format>] + * : Get value as var_export() or JSON. Default: var_export() */ public function get( $args, $assoc_args ) { list( $key ) = $args; @@ -118,7 +122,6 @@ public function add( $args, $assoc_args ) { * * size_bytes * * @subcommand list - * @synopsis [--search=<glob-style-pattern>] [--autoload=<value>] [--fields=<fields>] [--format=<format>] */ public function list_( $args, $assoc_args ) { @@ -220,7 +223,8 @@ public function update( $args, $assoc_args ) { /** * Delete an option. * - * @synopsis <key> + * <key> + * : Key for the option. */ public function delete( $args ) { list( $key ) = $args; diff --git a/php/commands/site.php b/php/commands/site.php index d9faf3e9ab..d21d1c3615 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -191,22 +191,20 @@ function delete( $args, $assoc_args ) { * --slug=<slug> * : Path for the new site. Subdomain on subdomain installs, directory on subdirectory installs. * - * --title=<title> + * [--title=<title>] * : Title of the new site. Default: prettified slug. * - * --email=<email> + * [--email=<email>] * : Email for Admin user. User will be created if none exists. Assignement to Super Admin if not included. * - * --network_id=<network-id> + * [--network_id=<network-id>] * : Network to associate new site with. Defaults to current network (typically 1). * - * --private + * [--private] * : If set, the new site will be non-public (not indexed) * - * --porcelain + * [--porcelain] * : If set, only the site id will be output on success. - * - * @synopsis --slug=<slug> [--title=<title>] [--email=<email>] [--network_id=<network-id>] [--private] [--porcelain] */ public function create( $_, $assoc_args ) { if ( !is_multisite() ) { diff --git a/php/commands/transient.php b/php/commands/transient.php index 3ea4b19b0e..4b6de95b0e 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -12,7 +12,11 @@ class Transient_Command extends WP_CLI_Command { /** * Get a transient value. * - * @synopsis <key> [--json] + * <key> + * : Key for the transient. + * + * [--json] + * : Format output as JSON. */ public function get( $args, $assoc_args ) { list( $key ) = $args; @@ -30,7 +34,14 @@ public function get( $args, $assoc_args ) { /** * Set a transient value. <expiration> is the time until expiration, in seconds. * - * @synopsis <key> <value> [<expiration>] + * <key> + * : Key for the transient. + * + * <value> + * : Value to be set for the transient. + * + * [<expiration] + * : Time until expiration, in seconds. */ public function set( $args ) { list( $key, $value ) = $args; @@ -46,7 +57,8 @@ public function set( $args ) { /** * Delete a transient value. * - * @synopsis <key> + * <key> + * : Key for the transient. */ public function delete( $args ) { list( $key ) = $args; diff --git a/php/commands/user.php b/php/commands/user.php index 6db4b15ac1..09eda770f3 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -796,8 +796,6 @@ public function __construct() { * * [--format=<format>] * : Accepted values: table, json. Default: table - * - * @synopsis <user> <key> [--format=<format>] */ public function get( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); @@ -832,8 +830,6 @@ public function delete( $args, $assoc_args ) { * * <value> * : The new metadata value. - * - * @synopsis <user> <key> <value> [--format=<format>] */ public function add( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); @@ -853,7 +849,6 @@ public function add( $args, $assoc_args ) { * : The new metadata value. * * @alias set - * @synopsis <user> <key> <value> [--format=<format>] */ public function update( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); From 10bcfefc560e12097bea16ead3457f17f3e171c1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 14:37:01 -0700 Subject: [PATCH 3724/4858] Let eval'd `DOMAIN_CURRENT_SITE` set URL, unless `--url` is passed. Props @mboynes --- features/config.feature | 86 ++++++++++++----------------------------- php/WP_CLI/Runner.php | 41 ++++++++------------ php/wp-cli.php | 2 + 3 files changed, 44 insertions(+), 85 deletions(-) diff --git a/features/config.feature b/features/config.feature index d324ac20d2..0959c9983b 100644 --- a/features/config.feature +++ b/features/config.feature @@ -197,7 +197,7 @@ Feature: Have a config file """ When I run `WP_CLI_CONFIG_PATH=test-dir/config.yml wp help` - Then STDERR should be empty + Then STDERR should be empty Scenario: Missing required files should not fatal WP-CLI Given an empty directory @@ -207,23 +207,32 @@ Feature: Have a config file - missing-file.php """ - When I try `wp help` - Then STDERR should contain: - """ - Error: Required file 'missing-file.php' doesn't exist - """ + When I try `wp help` + Then STDERR should contain: + """ + Error: Required file 'missing-file.php' doesn't exist + """ When I run `wp cli info` - Then STDOUT should not be empty + Then STDOUT should not be empty When I run `wp --info` - Then STDOUT should not be empty + Then STDOUT should not be empty - Scenario: WordPress install with commented out DOMAIN_CURRENT_SITE, first style + Scenario: WordPress install with local dev DOMAIN_CURRENT_SITE Given a WP multisite install + And a local-dev.php file: + """ + <?php + define( 'DOMAIN_CURRENT_SITE', 'example.dev' ); + """ And a wp-config.php file: """ <?php +if ( file_exists( __DIR__ . '/local-dev.php' ) ) { + require_once __DIR__ . '/local-dev.php'; +} + // ** MySQL settings ** // /** The name of the database for WordPress */ define('DB_NAME', 'wp_cli_test'); @@ -249,8 +258,9 @@ define( 'WP_ALLOW_MULTISITE', true ); define('MULTISITE', true); define('SUBDOMAIN_INSTALL', false); $base = '/'; -define('DOMAIN_CURRENT_SITE', 'example.com'); -# define('DOMAIN_CURRENT_SITE', 'bta.example.com'); +if ( ! defined( 'DOMAIN_CURRENT_SITE' ) ) { + define('DOMAIN_CURRENT_SITE', 'example.com'); +} define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); @@ -265,59 +275,13 @@ if ( !defined('ABSPATH') ) require_once(ABSPATH . 'wp-settings.php'); """ - When I run `wp option get home` - Then STDOUT should be: - """ - http://example.com - """ - - Scenario: WordPress install with commented out DOMAIN_CURRENT_SITE, second style - Given a WP multisite install - And a wp-config.php file: + When I try `wp option get home` + Then STDERR should be: """ -<?php -// ** MySQL settings ** // -/** The name of the database for WordPress */ -define('DB_NAME', 'wp_cli_test'); - -/** MySQL database username */ -define('DB_USER', 'wp_cli_test'); - -/** MySQL database password */ -define('DB_PASSWORD', 'password1'); - -/** MySQL hostname */ -define('DB_HOST', '127.0.0.1'); - -/** Database Charset to use in creating database tables. */ -define('DB_CHARSET', 'utf8'); - -/** The Database Collate type. Don't change this if in doubt. */ -define('DB_COLLATE', ''); - -$table_prefix = 'wp_'; - -define( 'WP_ALLOW_MULTISITE', true ); -define('MULTISITE', true); -define('SUBDOMAIN_INSTALL', false); -$base = '/'; -define('DOMAIN_CURRENT_SITE', 'example.com'); -//define('DOMAIN_CURRENT_SITE', 'bta.example.com'); -define('PATH_CURRENT_SITE', '/'); -define('SITE_ID_CURRENT_SITE', 1); -define('BLOG_ID_CURRENT_SITE', 1); - -/* That's all, stop editing! Happy blogging. */ - -/** Absolute path to the WordPress directory. */ -if ( !defined('ABSPATH') ) - define('ABSPATH', dirname(__FILE__) . '/'); - -/** Sets up WordPress vars and included files. */ -require_once(ABSPATH . 'wp-settings.php'); + Error: Site example.dev/ not found. """ - When I run `wp option get home` + When I run `wp option get home --url=example.com` Then STDOUT should be: """ http://example.com diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 5a3927f46d..87e435b471 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -206,30 +206,6 @@ private static function guess_url( $assoc_args ) { if ( true === $url ) { WP_CLI::warning( 'The --url parameter expects a value.' ); } - } elseif ( $wp_config_path = Utils\locate_wp_config() ) { - // Try to find the blog parameter in the wp-config file - $wp_config_file = file_get_contents( $wp_config_path ); - $hit = array(); - - $re_define = "~(.*)define\s*\(\s*(['|\"]{1})(.+)(['|\"]{1})\s*,\s*(['|\"]{1})(.+)(['|\"]{1})\s*\)\s*;~iU"; - - if ( preg_match_all( $re_define, $wp_config_file, $matches ) ) { - foreach ( $matches[3] as $def_key => $def_name ) { - if ( false !== strpos( $matches[1][$def_key], '#' ) || false !== strpos( $matches[1][$def_key], '//' ) ) { - continue; - } - if ( 'DOMAIN_CURRENT_SITE' == $def_name ) - $hit['domain'] = $matches[6][$def_key]; - if ( 'PATH_CURRENT_SITE' == $def_name ) - $hit['path'] = $matches[6][$def_key]; - } - } - - if ( !empty( $hit ) && isset( $hit['domain'] ) ) { - $url = $hit['domain']; - if ( isset( $hit['path'] ) ) - $url .= $hit['path']; - } } if ( isset( $url ) ) { @@ -728,6 +704,23 @@ private static function fake_current_site_blog( $url_parts ) { ); } + /** + * Called after wp-config.php is eval'd, to potentially reset `--url` + */ + public function maybe_update_url_from_domain_constant() { + if ( ! empty( $this->config['url'] ) || ! empty( $this->config['blog'] ) ) { + return; + } + + if ( defined( 'DOMAIN_CURRENT_SITE' ) ) { + $url = DOMAIN_CURRENT_SITE; + if ( defined( 'PATH_CURRENT_SITE' ) ) { + $url .= PATH_CURRENT_SITE; + } + \WP_CLI::set_url( $url ); + } + } + public function after_wp_load() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); diff --git a/php/wp-cli.php b/php/wp-cli.php index ab8bcf68b1..3d1df759a3 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -22,6 +22,8 @@ // Load wp-config.php code, in the global scope eval( WP_CLI::get_runner()->get_wp_config_code() ); +WP_CLI::get_runner()->maybe_update_url_from_domain_constant(); + // Load Core, mu-plugins, plugins, themes etc. require WP_CLI_ROOT . '/php/wp-settings-cli.php'; From b151bf82044c4e5ae01d27a08ad49d8477a4fddd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 14:51:12 -0700 Subject: [PATCH 3725/4858] Restore use of `--format` for `user meta (add|update)` --- php/commands/user.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index 09eda770f3..cb5d35afe7 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -830,6 +830,9 @@ public function delete( $args, $assoc_args ) { * * <value> * : The new metadata value. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. */ public function add( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); @@ -848,6 +851,9 @@ public function add( $args, $assoc_args ) { * <value> * : The new metadata value. * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. + * * @alias set */ public function update( $args, $assoc_args ) { From aa951dd14fcbbda606c75c0bfac70ecaa7e28bed Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 14:58:11 -0700 Subject: [PATCH 3726/4858] Compatibility with a different error in WP 3.5 --- features/config.feature | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/features/config.feature b/features/config.feature index 0959c9983b..cc22badef2 100644 --- a/features/config.feature +++ b/features/config.feature @@ -276,10 +276,7 @@ require_once(ABSPATH . 'wp-settings.php'); """ When I try `wp option get home` - Then STDERR should be: - """ - Error: Site example.dev/ not found. - """ + Then STDERR should not be empty When I run `wp option get home --url=example.com` Then STDOUT should be: From 9f5467bebec8d74ddc40f46f835812a258ac3fe8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 15:24:17 -0700 Subject: [PATCH 3727/4858] Use `--defer-term-counting` to recalculate term count in batch for perf --- php/WP_CLI/CommandWithDBObject.php | 8 ++++++++ php/commands/post.php | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index ef32e35864..b72a648f8e 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -71,6 +71,10 @@ protected function _update( $args, $assoc_args, $callback ) { ) ); } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { + wp_defer_term_counting( false ); + } + exit( $status ); } @@ -90,6 +94,10 @@ protected function _delete( $args, $assoc_args, $callback ) { $status = $this->success_or_failure( $r ); } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { + wp_defer_term_counting( false ); + } + exit( $status ); } diff --git a/php/commands/post.php b/php/commands/post.php index 38dd7d2c61..c2bf43b3e0 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -91,6 +91,9 @@ public function create( $args, $assoc_args ) { * --<field>=<value> * : One or more fields to update. See wp_update_post(). * + * [--defer-term-counting] + * : Recalculate term count in batch, for a performance boost. + * * ## EXAMPLES * * wp post update 123 --post_name=something --post_status=draft @@ -111,6 +114,10 @@ public function update( $args, $assoc_args ) { $assoc_args['post_category'] = explode( ',', $assoc_args['post_category'] ); } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { + wp_defer_term_counting( true ); + } + parent::_update( $args, $assoc_args, function ( $params ) { return wp_update_post( $params, true ); } ); @@ -193,6 +200,9 @@ public function get( $args, $assoc_args ) { * [--force] * : Skip the trash bin. * + * [--defer-term-counting] + * : Recalculate term count in batch, for a performance boost. + * * ## EXAMPLES * * wp post delete 123 --force @@ -208,6 +218,10 @@ public function delete( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { + wp_defer_term_counting( true ); + } + parent::_delete( $args, $assoc_args, function ( $post_id, $assoc_args ) { $status = get_post_status( $post_id ); $r = wp_delete_post( $post_id, $assoc_args['force'] ); From 6865afe64cb906a5bcbc0b80b1aae725c3576766 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 15:25:47 -0700 Subject: [PATCH 3728/4858] Move all deferred term counting logic to parent method --- php/WP_CLI/CommandWithDBObject.php | 8 ++++++++ php/commands/post.php | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/CommandWithDBObject.php b/php/WP_CLI/CommandWithDBObject.php index b72a648f8e..0702956a4e 100644 --- a/php/WP_CLI/CommandWithDBObject.php +++ b/php/WP_CLI/CommandWithDBObject.php @@ -62,6 +62,10 @@ protected function _update( $args, $assoc_args, $callback ) { \WP_CLI::error( "Need some fields to update." ); } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { + wp_defer_term_counting( true ); + } + foreach ( $args as $obj_id ) { $params = array_merge( $assoc_args, array( $this->obj_id_key => $obj_id ) ); @@ -89,6 +93,10 @@ protected function _update( $args, $assoc_args, $callback ) { protected function _delete( $args, $assoc_args, $callback ) { $status = 0; + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { + wp_defer_term_counting( true ); + } + foreach ( $args as $obj_id ) { $r = $callback( $obj_id, $assoc_args ); $status = $this->success_or_failure( $r ); diff --git a/php/commands/post.php b/php/commands/post.php index c2bf43b3e0..5a5198ce57 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -114,10 +114,6 @@ public function update( $args, $assoc_args ) { $assoc_args['post_category'] = explode( ',', $assoc_args['post_category'] ); } - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { - wp_defer_term_counting( true ); - } - parent::_update( $args, $assoc_args, function ( $params ) { return wp_update_post( $params, true ); } ); @@ -218,10 +214,6 @@ public function delete( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'defer-term-counting' ) ) { - wp_defer_term_counting( true ); - } - parent::_delete( $args, $assoc_args, function ( $post_id, $assoc_args ) { $status = get_post_status( $post_id ); $r = wp_delete_post( $post_id, $assoc_args['force'] ); From 2f4d6695fdec0f9da54684bf5a9825a536099061 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 15:30:34 -0700 Subject: [PATCH 3729/4858] Revert "Compatibility with a different error in WP 3.5" This reverts commit aa951dd14fcbbda606c75c0bfac70ecaa7e28bed. --- features/config.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/config.feature b/features/config.feature index cc22badef2..0959c9983b 100644 --- a/features/config.feature +++ b/features/config.feature @@ -276,7 +276,10 @@ require_once(ABSPATH . 'wp-settings.php'); """ When I try `wp option get home` - Then STDERR should not be empty + Then STDERR should be: + """ + Error: Site example.dev/ not found. + """ When I run `wp option get home --url=example.com` Then STDOUT should be: From 93d45ddedcc2572e02fbdfec2814a441b6396387 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Sun, 20 Sep 2015 15:31:00 -0700 Subject: [PATCH 3730/4858] Increase minimum requirement for this test --- features/config.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/config.feature b/features/config.feature index 0959c9983b..f5d16ad292 100644 --- a/features/config.feature +++ b/features/config.feature @@ -219,6 +219,7 @@ Feature: Have a config file When I run `wp --info` Then STDOUT should not be empty + @require-wp-3.9 Scenario: WordPress install with local dev DOMAIN_CURRENT_SITE Given a WP multisite install And a local-dev.php file: From e184e69844a55701f81bb5068f42653d2b4fa02b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Mon, 21 Sep 2015 06:17:40 -0700 Subject: [PATCH 3731/4858] `--autoload=(yes|no)` support for `update option` --- features/option.feature | 20 ++++++++++++++++++++ php/commands/option.php | 12 ++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/features/option.feature b/features/option.feature index bc23bcf9f7..8a44855f37 100644 --- a/features/option.feature +++ b/features/option.feature @@ -120,3 +120,23 @@ Feature: Manage WordPress options "list": [1, 2, 3] } """ + + Scenario: Update autoload value for custom option + Given a WP install + And I run `wp option add hello world --autoload=no` + + When I run `wp option update hello universe` + Then STDOUT should not be empty + + When I run `wp option list --search='hello' --fields=option_name,option_value,autoload` + Then STDOUT should be a table containing rows: + | option_name | option_value | autoload | + | hello | universe | no | + + When I run `wp option update hello island --autoload=yes` + Then STDOUT should not be empty + + When I run `wp option list --search='hello' --fields=option_name,option_value,autoload` + Then STDOUT should be a table containing rows: + | option_name | option_value | autoload | + | hello | island | yes | diff --git a/php/commands/option.php b/php/commands/option.php index 979a53b28f..5cfdcd37a3 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -187,6 +187,9 @@ public function list_( $args, $assoc_args ) { * [<value>] * : The new value. If ommited, the value is read from STDIN. * + * [--autoload=<autoload>] + * : Should this option be automatically loaded. Accepted values: yes, no. Default: yes + * * [--format=<format>] * : The serialization format for the value. Default is plaintext. * @@ -206,13 +209,18 @@ public function update( $args, $assoc_args ) { $value = WP_CLI::get_value_from_arg_or_stdin( $args, 1 ); $value = WP_CLI::read_value( $value, $assoc_args ); + $autoload = \WP_CLI\Utils\get_flag_value( $assoc_args, 'autoload' ); + if ( ! in_array( $autoload, array( 'yes', 'no' ) ) ) { + $autoload = null; + } + $value = sanitize_option( $key, $value ); $old_value = sanitize_option( $key, get_option( $key ) ); - if ( $value === $old_value ) { + if ( $value === $old_value && is_null( $autoload ) ) { WP_CLI::success( "Value passed for '$key' option is unchanged." ); } else { - if ( update_option( $key, $value ) ) { + if ( update_option( $key, $value, $autoload ) ) { WP_CLI::success( "Updated '$key' option." ); } else { WP_CLI::error( "Could not update option '$key'." ); From e7b71e8c28dc3e572d968a0f1fd83f5a15408383 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Mon, 21 Sep 2015 06:21:16 -0700 Subject: [PATCH 3732/4858] Fix invalid synopsis part for `wp option list` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` salty-wordpress ➜ wordpress-test.dev wp option list --search="apple" Warning: The `wp option list` command has an invalid synopsis part: The Warning: The `wp option list` command has an invalid synopsis part: serialization Warning: The `wp option list` command has an invalid synopsis part: format Warning: The `wp option list` command has an invalid synopsis part: for Warning: The `wp option list` command has an invalid synopsis part: the Warning: The `wp option list` command has an invalid synopsis part: value. Warning: The `wp option list` command has an invalid synopsis part: total_bytes Warning: The `wp option list` command has an invalid synopsis part: displays Warning: The `wp option list` command has an invalid synopsis part: the Warning: The `wp option list` command has an invalid synopsis part: total Warning: The `wp option list` command has an invalid synopsis part: size Warning: The `wp option list` command has an invalid synopsis part: of Warning: The `wp option list` command has an invalid synopsis part: matching Warning: The `wp option list` command has an invalid synopsis part: options Warning: The `wp option list` command has an invalid synopsis part: in Warning: The `wp option list` command has an invalid synopsis part: bytes. ``` --- php/commands/option.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index 979a53b28f..a4bf9251b2 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -94,9 +94,7 @@ public function add( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : The serialization format for the value. - * : total_bytes displays the total size of matching options in bytes. - * : Accepted values: table, json, csv, count, total_bytes. Default: table + * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. Accepted values: table, json, csv, count, total_bytes. Default: table * * ## EXAMPLES * From 4e96b943257b16b98547ca26d247e50f7bc36f5d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Mon, 21 Sep 2015 06:45:43 -0700 Subject: [PATCH 3733/4858] `--autoload` requires WP 4.2 --- features/option.feature | 1 + php/commands/option.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/features/option.feature b/features/option.feature index 8a44855f37..cd44b4596a 100644 --- a/features/option.feature +++ b/features/option.feature @@ -121,6 +121,7 @@ Feature: Manage WordPress options } """ + @require-wp-4.2 Scenario: Update autoload value for custom option Given a WP install And I run `wp option add hello world --autoload=no` diff --git a/php/commands/option.php b/php/commands/option.php index 5cfdcd37a3..9e05f30b53 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -188,7 +188,7 @@ public function list_( $args, $assoc_args ) { * : The new value. If ommited, the value is read from STDIN. * * [--autoload=<autoload>] - * : Should this option be automatically loaded. Accepted values: yes, no. Default: yes + * : Requires WP 4.2. Should this option be automatically loaded. Accepted values: yes, no. Default: yes * * [--format=<format>] * : The serialization format for the value. Default is plaintext. From 05d5553083730ab70f12b0f223da17964acaf26a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 21 Sep 2015 14:24:24 -0700 Subject: [PATCH 3734/4858] Exhaust all possible options when finding PHP binary --- php/class-wp-cli.php | 2 +- php/commands/cli.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index c4255ac683..4f1e645411 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -434,7 +434,7 @@ public static function launch_self( $command, $args = array(), $assoc_args = arr * * @return string */ - private static function get_php_binary() { + public static function get_php_binary() { if ( defined( 'PHP_BINARY' ) ) return PHP_BINARY; diff --git a/php/commands/cli.php b/php/commands/cli.php index 718979abe9..ffb83ff897 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -44,7 +44,7 @@ public function version() { * : Accepted values: json */ public function info( $_, $assoc_args ) { - $php_bin = defined( 'PHP_BINARY' ) ? PHP_BINARY : getenv( 'WP_CLI_PHP_USED' ); + $php_bin = WP_CLI::get_php_binary(); $runner = WP_CLI::get_runner(); @@ -186,7 +186,8 @@ public function update( $_, $assoc_args ) { Utils\http_request( 'GET', $download_url, null, $headers, $options ); $allow_root = WP_CLI::get_runner()->config['allow-root'] ? '--allow-root' : ''; - $process = WP_CLI\Process::create( "php $temp --version {$allow_root}" ); + $php_binary = WP_CLI::get_php_binary(); + $process = WP_CLI\Process::create( "{$php_binary} $temp --version {$allow_root}" ); $result = $process->run(); if ( 0 !== $result->return_code ) { $multi_line = explode( PHP_EOL, $result->stderr ); From e664ca96923d3bbf088dff2e66f427ec68e6bf05 Mon Sep 17 00:00:00 2001 From: Hiroshi Urabe <mail@torounit.com> Date: Thu, 24 Sep 2015 18:21:12 +0900 Subject: [PATCH 3735/4858] Use WP_VERSION when checkout wordpress tests. #2050 --- templates/install-wp-tests.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 80ba41649c..9cd88e16d4 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -14,6 +14,12 @@ WP_VERSION=${5-latest} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} +if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then + WP_TESTS_TAG="tags/$WP_VERSION" +else + WP_TESTS_TAG='trunk' +fi + set -ex download() { @@ -56,13 +62,13 @@ install_test_suite() { if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR - svn co --quiet https://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes fi cd $WP_TESTS_DIR if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php From a5152d73f86bb6e5de07be3b47998999257478ac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 24 Sep 2015 16:52:30 -0700 Subject: [PATCH 3736/4858] Support multiple comment ids for `comment (spam|trash|approve)` et al From https://wordpress.slack.com/archives/cli/p1443138041000281 --- php/commands/comment.php | 48 +++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 38d0bdb12d..372a5e4287 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -281,15 +281,17 @@ private function set_status( $args, $status, $success ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to trash. + * <id>... + * : The IDs of the comments to trash. * * ## EXAMPLES * * wp comment trash 1337 */ public function trash( $args, $assoc_args ) { - $this->call( $args, __FUNCTION__, 'Trashed', 'Failed trashing' ); + foreach( $args as $id ) { + $this->call( $id, __FUNCTION__, 'Trashed', 'Failed trashing' ); + } } /** @@ -297,15 +299,17 @@ public function trash( $args, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to untrash. + * <id>... + * : The IDs of the comments to untrash. * * ## EXAMPLES * * wp comment untrash 1337 */ public function untrash( $args, $assoc_args ) { - $this->call( $args, __FUNCTION__, 'Untrashed', 'Failed untrashing' ); + foreach( $args as $id ) { + $this->call( $id, __FUNCTION__, 'Untrashed', 'Failed untrashing' ); + } } /** @@ -313,15 +317,17 @@ public function untrash( $args, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to mark as spam. + * <id>... + * : The IDs of the comments to mark as spam. * * ## EXAMPLES * * wp comment spam 1337 */ public function spam( $args, $assoc_args ) { - $this->call( $args, __FUNCTION__, 'Marked as spam', 'Failed marking as spam' ); + foreach( $args as $id ) { + $this->call( $id, __FUNCTION__, 'Marked as spam', 'Failed marking as spam' ); + } } /** @@ -329,15 +335,17 @@ public function spam( $args, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to unmark as spam. + * <id>... + * : The IDs of the comments to unmark as spam. * * ## EXAMPLES * * wp comment unspam 1337 */ public function unspam( $args, $assoc_args ) { - $this->call( $args, __FUNCTION__, 'Unspammed', 'Failed unspamming' ); + foreach( $args as $id ) { + $this->call( $args, __FUNCTION__, 'Unspammed', 'Failed unspamming' ); + } } /** @@ -345,15 +353,17 @@ public function unspam( $args, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to approve. + * <id>... + * : The IDs of the comments to approve. * * ## EXAMPLES * * wp comment approve 1337 */ public function approve( $args, $assoc_args ) { - $this->set_status( $args, 'approve', "Approved" ); + foreach( $args as $id ) { + $this->set_status( $id, 'approve', "Approved" ); + } } /** @@ -361,15 +371,17 @@ public function approve( $args, $assoc_args ) { * * ## OPTIONS * - * <id> - * : The ID of the comment to unapprove. + * <id>... + * : The IDs of the comments to unapprove. * * ## EXAMPLES * * wp comment unapprove 1337 */ public function unapprove( $args, $assoc_args ) { - $this->set_status( $args, 'hold', "Unapproved" ); + foreach( $args as $id ) { + $this->set_status( $id, 'hold', "Unapproved" ); + } } /** From 1028f8a7627de7c5b0fff3802543080be5aee788 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 28 Sep 2015 16:47:36 -0700 Subject: [PATCH 3737/4858] Only run `wp core update-db --network` on active sites --- features/core.feature | 9 +++++++++ php/commands/core.php | 1 + 2 files changed, 10 insertions(+) diff --git a/features/core.feature b/features/core.feature index 4eb71f8eb8..29a96bc9c0 100644 --- a/features/core.feature +++ b/features/core.feature @@ -293,6 +293,15 @@ Feature: Manage WordPress installation Given a WP multisite install And I run `wp site create --slug=foo` And I run `wp site create --slug=bar` + And I run `wp site create --slug=burrito --porcelain` + And save STDOUT as {BURRITO_ID} + And I run `wp site create --slug=taco --porcelain` + And save STDOUT as {TACO_ID} + And I run `wp site create --slug=pizza --porcelain` + And save STDOUT as {PIZZA_ID} + And I run `wp site archive {BURRITO_ID}` + And I run `wp site spam {TACO_ID}` + And I run `wp site delete {PIZZA_ID} --yes` When I run `wp core update-db --network` Then STDOUT should contain: diff --git a/php/commands/core.php b/php/commands/core.php index 81694a7074..892611fa20 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -987,6 +987,7 @@ function update_db( $_, $assoc_args ) { if ( $network ) { $iterator_args = array( 'table' => $wpdb->blogs, + 'where' => array( 'spam' => 0, 'deleted' => 0, 'archived' => 0 ), ); $it = new \WP_CLI\Iterators\Table( $iterator_args ); $success = $total = 0; From d2dfb216bed4fe15ea4ac2da28f89e853f02f873 Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Mon, 28 Sep 2015 21:16:03 -0400 Subject: [PATCH 3738/4858] alias update as upgrade --- php/commands/plugin.php | 2 ++ php/commands/theme.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index bb26cd5c4d..d266aae993 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -345,6 +345,8 @@ protected function install_from_repo( $slug, $assoc_args ) { * wp plugin update bbpress --version=dev * * wp plugin update --all + * + * @alias upgrade */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { diff --git a/php/commands/theme.php b/php/commands/theme.php index 380a4fadd4..59f5fd20ec 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -463,6 +463,8 @@ public function get( $args, $assoc_args ) { * wp theme update twentyeleven twentytwelve * * wp theme update --all + * + * @alias upgrade */ function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { From e578f4059edd2a01ce566209966b5f448d0814b8 Mon Sep 17 00:00:00 2001 From: Borek Bernard <borekb@gmail.com> Date: Wed, 30 Sep 2015 16:54:56 +0200 Subject: [PATCH 3739/4858] Paginate help output on Windows using `more` --- php/commands/help.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/php/commands/help.php b/php/commands/help.php index ec2dcce53f..5b2c3cf5eb 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -90,11 +90,8 @@ private static function indent( $whitespace, $text ) { } private static function pass_through_pager( $out ) { - if ( Utils\is_windows() ) { - // no paging for Windows cmd.exe; sorry - echo $out; - return 0; - } + + $pager = Utils\is_windows() ? 'more' : 'less -r'; // convert string to file handle $fd = fopen( "php://temp", "r+" ); @@ -107,7 +104,7 @@ private static function pass_through_pager( $out ) { 2 => STDERR ); - return proc_close( proc_open( 'less -r', $descriptorspec, $pipes ) ); + return proc_close( proc_open( $pager, $descriptorspec, $pipes ) ); } private static function get_initial_markdown( $command ) { From ec701315c9001bd9565bf44f70abd09a008d0591 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 2 Oct 2015 13:27:18 -0700 Subject: [PATCH 3740/4858] Clarify expected output for `wp core check-update` [ci-skip] --- php/commands/core.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 81694a7074..30cf9dc5b8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -10,7 +10,9 @@ class Core_Command extends WP_CLI_Command { /** - * Check for update via Version Check API. Returns latest version if there's an update, or empty if no update available. + * Check for update via Version Check API. + * + * Lists the most recent versions when there are updates available, or success message when up to date. * * ## OPTIONS * From 0d5c9319532368f41a9e2e7593ef3d599b359fa1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 2 Oct 2015 15:02:48 -0700 Subject: [PATCH 3741/4858] Permit space-delimited IDs for `wp export --post__in` This makes it easier to pass IDs returned by one command into export. --- features/export.feature | 32 ++++++++++++++++++++++++++++++++ php/commands/export.php | 5 +++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/features/export.feature b/features/export.feature index ab8c51b40e..cb2720ef68 100644 --- a/features/export.feature +++ b/features/export.feature @@ -161,6 +161,38 @@ Feature: Export content. 1 """ + Scenario: Export multiple posts, separated by spaces + Given a WP install + + When I run `wp plugin install wordpress-importer --activate` + Then STDOUT should contain: + """ + Success: + """ + + When I run `wp post create --post_title='Test post' --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID} + + When I run `wp post create --post_title='Test post 2' --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID_TWO} + + When I run `wp export --post__in="{POST_ID} {POST_ID_TWO}"` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --post_type=post --format=count` + Then STDOUT should be: + """ + 2 + """ + Scenario: Export posts within a given date range Given a WP install diff --git a/php/commands/export.php b/php/commands/export.php index 230548afd6..50b077c457 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -40,7 +40,7 @@ class Export_Command extends WP_CLI_Command { * with a comma. Defaults to none. * * [--post__in=<pid>] - * : Export all posts specified as a comma-separated list of IDs. + * : Export all posts specified as a comma- or space-separated list of IDs. * * [--start_id=<pid>] * : Export only posts with IDs greater than or equal to this post ID. @@ -233,7 +233,8 @@ private function check_post__in( $post__in ) { if ( is_null( $post__in ) ) return true; - $post__in = array_unique( array_map( 'intval', explode( ',', $post__in ) ) ); + $separator = false !== stripos( $post__in, ' ' ) ? ' ' : ','; + $post__in = array_unique( array_map( 'intval', explode( $separator, $post__in ) ) ); if ( empty( $post__in ) ) { WP_CLI::warning( "post__in should be comma-separated post IDs" ); return false; From 68bf55ae6a4584d09b3d5e320b6874a59700e577 Mon Sep 17 00:00:00 2001 From: voldemortensen <voldemortensen@users.noreply.github.com> Date: Fri, 2 Oct 2015 16:05:04 -0600 Subject: [PATCH 3742/4858] check if file is writable before copying and don't report success if file isn't copied to current directory --- php/commands/core.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 892611fa20..368e04b14c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -219,6 +219,8 @@ private static function _copy_overwrite_files( $source, $dest ) { new RecursiveDirectoryIterator( $source, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::SELF_FIRST); + $error = 0; + foreach ( $iterator as $item ) { if ( $item->isDir() ) { $dest_path = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); @@ -226,9 +228,18 @@ private static function _copy_overwrite_files( $source, $dest ) { mkdir( $dest_path ); } } else { - copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ); + if ( ! $item->isWritable() ) { + copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ) ) { + } else { + $error = 1; + WP_CLI::warning( 'Unable to copy ' . $iterator->getSubPathName() . ' to current directory.' ); + } } } + + if ( $error ) { + WP_CLI::error( 'There was an error downloading all WordPress files.' ); + } } private static function _rmdir( $dir ) { From 3fb770288a8f44d20bc87220eb64c3db7dfd1ab9 Mon Sep 17 00:00:00 2001 From: voldemortensen <voldemortensen@users.noreply.github.com> Date: Fri, 2 Oct 2015 16:08:27 -0600 Subject: [PATCH 3743/4858] fix garbage I missed from troubleshooting. --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 368e04b14c..bf0babc9b2 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -229,7 +229,7 @@ private static function _copy_overwrite_files( $source, $dest ) { } } else { if ( ! $item->isWritable() ) { - copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ) ) { + copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ); } else { $error = 1; WP_CLI::warning( 'Unable to copy ' . $iterator->getSubPathName() . ' to current directory.' ); From 28f26688944cd00fa1306b4c6a37196d92781520 Mon Sep 17 00:00:00 2001 From: voldemortensen <voldemortensen@users.noreply.github.com> Date: Fri, 2 Oct 2015 16:09:56 -0600 Subject: [PATCH 3744/4858] its friday... remove an erroneous not check --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index bf0babc9b2..bf5206876e 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -228,7 +228,7 @@ private static function _copy_overwrite_files( $source, $dest ) { mkdir( $dest_path ); } } else { - if ( ! $item->isWritable() ) { + if ( $item->isWritable() ) { copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ); } else { $error = 1; From d0fdb9a789520a4d523059ca1cc7bb4dd5172c01 Mon Sep 17 00:00:00 2001 From: voldemortensen <voldemortensen@users.noreply.github.com> Date: Fri, 2 Oct 2015 16:17:17 -0600 Subject: [PATCH 3745/4858] check the right file for writability --- php/commands/core.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index bf5206876e..fe880e4649 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -222,14 +222,16 @@ private static function _copy_overwrite_files( $source, $dest ) { $error = 0; foreach ( $iterator as $item ) { + + $dest_path = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); + if ( $item->isDir() ) { - $dest_path = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); if ( !is_dir( $dest_path ) ) { mkdir( $dest_path ); } } else { - if ( $item->isWritable() ) { - copy( $item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName() ); + if ( is_writable( $dest_path ) ) { + copy( $item, $dest_path ); } else { $error = 1; WP_CLI::warning( 'Unable to copy ' . $iterator->getSubPathName() . ' to current directory.' ); From 786628eda71c5b874579aabc72e54c71a0cd760a Mon Sep 17 00:00:00 2001 From: voldemortensen <voldemortensen@users.noreply.github.com> Date: Fri, 2 Oct 2015 16:40:11 -0600 Subject: [PATCH 3746/4858] check if file exists and is writable. files that don't exist aren't writable --- php/commands/core.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index fe880e4649..aff297f7bd 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -230,7 +230,9 @@ private static function _copy_overwrite_files( $source, $dest ) { mkdir( $dest_path ); } } else { - if ( is_writable( $dest_path ) ) { + if ( file_exists( $dest_path ) && is_writable( $dest_path ) ) { + copy( $item, $dest_path ); + } elseif ( ! file_exists( $dest_path ) ) { copy( $item, $dest_path ); } else { $error = 1; From f3ad656ee73dadd8e89d2e2cc54b8fd9b747ce0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Mon, 5 Oct 2015 15:38:17 +0200 Subject: [PATCH 3747/4858] Added syntax highlight --- CONTRIBUTING.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 001b2400e2..4063c75926 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,9 @@ The unit test files are in the `tests/` directory. To run the unit tests, just execute: - ./vendor/bin/phpunit +```bash +./vendor/bin/phpunit +``` ### Functional tests @@ -48,15 +50,21 @@ The functional test files are in the `features/` directory. Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: - GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; +```sql +GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; +``` Then, to run the entire test suite: - ./vendor/bin/behat --expand +```bash +./vendor/bin/behat --expand +``` Or to test a single feature: - ./vendor/bin/behat features/core.feature +```bash +./vendor/bin/behat features/core.feature +``` More info can be found by using `./vendor/bin/behat --help`. From c60adb7f777183eb390f368eeb0b7c81eae458ab Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 5 Oct 2015 23:34:35 -0300 Subject: [PATCH 3748/4858] add `wp taxonomy list` command --- features/taxonomy.feature | 16 +++++++++ php/commands/taxonomy.php | 71 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 features/taxonomy.feature create mode 100644 php/commands/taxonomy.php diff --git a/features/taxonomy.feature b/features/taxonomy.feature new file mode 100644 index 0000000000..ece9b7327b --- /dev/null +++ b/features/taxonomy.feature @@ -0,0 +1,16 @@ +Feature: Manage WordPress taxonomies + + Background: + Given a WP install + + Scenario: Listing taxonomies + When I run `wp taxonomy list --format=csv` + Then STDOUT should be CSV containing: + | name | label | description | public | hierarchical | + | category | Categories | | 1 | 1 | + | post_tag | Tags | | 1 | | + + When I run `wp taxonomy list --object_type=link --format=csv` + Then STDOUT should be CSV containing: + | name | label | description | public | hierarchical | + | link_category | Link Categories | | | | diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php new file mode 100644 index 0000000000..aef6c17a16 --- /dev/null +++ b/php/commands/taxonomy.php @@ -0,0 +1,71 @@ +<?php +/** + * Manage taxonomies. + * + * @package wp-cli + */ +class Taxonomy_Command extends WP_CLI_Command { + + private $fields = array( + 'name', + 'label', + 'description', + 'public', + 'hierarchical' + ); + + /** + * List taxonomies. + * + * ## OPTIONS + * + * [--<field>=<value>] + * : Filter by one or more fields (see get_taxonomies() first parameter for a list of available fields). + * + * [--field=<field>] + * : Prints the value of a single field for each taxonomy. + * + * [--fields=<fields>] + * : Limit the output to specific taxonomy fields. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each term: + * + * * name + * * label + * * description + * * public + * * hierarchical + * + * There are no optionally available fields. + * + * ## EXAMPLES + * + * wp taxonomy list --format=csv + * + * wp taxonomy list --object-type=post --fields=name,public + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); + + if ( isset( $assoc_args['object_type'] ) ) { + $assoc_args['object_type'] = array( $assoc_args['object_type'] ); + } + + $taxonomies = get_taxonomies( $assoc_args, 'objects' ); + + $formatter->display_items( $taxonomies ); + } + + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'taxonomy' ); + } +} + +WP_CLI::add_command( 'taxonomy', 'Taxonomy_Command' ); From 47aa5229c8b860849a2f0d9a054008891874be53 Mon Sep 17 00:00:00 2001 From: Brandon Kraft <public@brandonkraft.com> Date: Tue, 6 Oct 2015 16:08:59 -0500 Subject: [PATCH 3749/4858] Include new WP file https://core.trac.wordpress.org/changeset/34851 added WPINC/embed-functions.php This'll work for the build svn repo. Develop will need a version bump. --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index a72c3d50de..24c376a1ab 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -168,6 +168,7 @@ require( ABSPATH . WPINC . '/shortcodes.php' ); Utils\maybe_require( '3.5-alpha-22024', ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); +Utils\maybe_require( '4.4-alpha-34851', ABSPATH . WPINC . '/embed-functions.php' ); require( ABSPATH . WPINC . '/http.php' ); require_once( ABSPATH . WPINC . '/class-http.php' ); require( ABSPATH . WPINC . '/widgets.php' ); From ef2f66ecc12c5c4a87a7fd741c67c63ae20eefc4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Oct 2015 06:24:06 -0700 Subject: [PATCH 3750/4858] Load WordPress with `WP_CLI\Runner::load_wordpress()` This also lets other commands running before WordPress loads to load WordPress on their own. --- features/framework.feature | 34 ++++++++++++++++++++++ php/WP_CLI/Runner.php | 58 ++++++++++++++++++++++++++++++-------- php/wp-cli.php | 19 +------------ 3 files changed, 81 insertions(+), 30 deletions(-) diff --git a/features/framework.feature b/features/framework.feature index 438471e254..6a1e370cec 100644 --- a/features/framework.feature +++ b/features/framework.feature @@ -13,3 +13,37 @@ Feature: Load WP-CLI When I run `wp option get home` Then STDOUT should not be empty + + Scenario: A command loaded before WordPress then calls WordPress to load + Given a WP install + And a custom-cmd.php file: + """ + <?php + class Load_WordPress_Command_Class extends WP_CLI_Command { + + /** + * @when before_wp_load + */ + public function __invoke() { + if ( ! function_exists( 'update_option' ) ) { + WP_CLI::log( 'WordPress not loaded.' ); + } + WP_CLI::get_runner()->load_wordpress(); + if ( function_exists( 'update_option' ) ) { + WP_CLI::log( 'WordPress loaded!' ); + } + WP_CLI::get_runner()->load_wordpress(); + WP_CLI::log( 'load_wordpress() can safely be called twice.' ); + } + + } + WP_CLI::add_command( 'load-wordpress', 'Load_WordPress_Command_Class' ); + """ + + When I run `wp --require=custom-cmd.php load-wordpress` + Then STDOUT should be: + """ + WordPress not loaded. + WordPress loaded! + load_wordpress() can safely be called twice. + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 87e435b471..9aa22e949e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -562,7 +562,7 @@ private function check_root() { ); } - public function before_wp_load() { + public function start() { $this->init_config(); $this->init_colorization(); $this->init_logger(); @@ -672,6 +672,50 @@ public function before_wp_load() { if ( $this->cmd_starts_with( array( 'plugin' ) ) ) { $GLOBALS['pagenow'] = 'plugins.php'; } + + $this->load_wordpress(); + + $this->_run_command(); + + } + + /** + * Load WordPress, if it hasn't already been loaded + */ + public function load_wordpress() { + static $wp_cli_is_loaded; + // Globals not explicitly globalized in WordPress + global $wpdb, $wp, $wp_rewrite, $wp_version, $wp_db_version, + $current_site, $current_blog, $tinymce_version, $required_php_version, + $shortcode_tags, $required_mysql_version, $wp_local_package; + + if ( ! empty( $wp_cli_is_loaded ) ) { + return; + } + + $wp_cli_is_loaded = true; + + // Load wp-config.php code, in the global scope + eval( $this->get_wp_config_code() ); + + $this->maybe_update_url_from_domain_constant(); + + // Load Core, mu-plugins, plugins, themes etc. + require WP_CLI_ROOT . '/php/wp-settings-cli.php'; + + // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 + @ini_set( 'memory_limit', -1 ); + + // Load all the admin APIs, for convenience + require ABSPATH . 'wp-admin/includes/admin.php'; + + add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); + + // Handle --user parameter + if ( ! defined( 'WP_INSTALLING' ) ) { + self::set_user( $this->config ); + } + } private static function fake_current_site_blog( $url_parts ) { @@ -707,7 +751,7 @@ private static function fake_current_site_blog( $url_parts ) { /** * Called after wp-config.php is eval'd, to potentially reset `--url` */ - public function maybe_update_url_from_domain_constant() { + private function maybe_update_url_from_domain_constant() { if ( ! empty( $this->config['url'] ) || ! empty( $this->config['blog'] ) ) { return; } @@ -721,15 +765,5 @@ public function maybe_update_url_from_domain_constant() { } } - public function after_wp_load() { - add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - - // Handle --user parameter - if ( ! defined( 'WP_INSTALLING' ) ) { - self::set_user( $this->config ); - } - - $this->_run_command(); - } } diff --git a/php/wp-cli.php b/php/wp-cli.php index 3d1df759a3..0d0e499e6d 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -17,21 +17,4 @@ \WP_CLI\Utils\load_dependencies(); -WP_CLI::get_runner()->before_wp_load(); - -// Load wp-config.php code, in the global scope -eval( WP_CLI::get_runner()->get_wp_config_code() ); - -WP_CLI::get_runner()->maybe_update_url_from_domain_constant(); - -// Load Core, mu-plugins, plugins, themes etc. -require WP_CLI_ROOT . '/php/wp-settings-cli.php'; - -// Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 -@ini_set( 'memory_limit', -1 ); - -// Load all the admin APIs, for convenience -require ABSPATH . 'wp-admin/includes/admin.php'; - -WP_CLI::get_runner()->after_wp_load(); - +WP_CLI::get_runner()->start(); From 742e11d669ca21b7bc8a92a620d2911d9a65063e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Oct 2015 06:47:48 -0700 Subject: [PATCH 3751/4858] Globalize as core now does in `wp-settings.php` --- php/WP_CLI/Runner.php | 4 +--- php/wp-settings-cli.php | 15 +++++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9aa22e949e..95dc29aaa6 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -685,9 +685,7 @@ public function start() { public function load_wordpress() { static $wp_cli_is_loaded; // Globals not explicitly globalized in WordPress - global $wpdb, $wp, $wp_rewrite, $wp_version, $wp_db_version, - $current_site, $current_blog, $tinymce_version, $required_php_version, - $shortcode_tags, $required_mysql_version, $wp_local_package; + global $current_site, $current_blog, $shortcode_tags; if ( ! empty( $wp_cli_is_loaded ) ) { return; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index a72c3d50de..deb51f1aff 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -15,6 +15,13 @@ // Include files required for initialization. require( ABSPATH . WPINC . '/load.php' ); require( ABSPATH . WPINC . '/default-constants.php' ); + +/* + * These can't be directly globalized in version.php. When updating, + * we're including version.php from another install and don't want + * these values to be overridden if already set. + */ +global $wp_version, $wp_db_version, $tinymce_version, $required_php_version, $required_mysql_version; require( ABSPATH . WPINC . '/version.php' ); // Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, WP_CONTENT_DIR and WP_CACHE. @@ -271,7 +278,7 @@ function wp_is_mobile() { * @global object $wp_the_query * @since 2.0.0 */ -$wp_the_query = new WP_Query(); +$GLOBALS['wp_the_query'] = new WP_Query(); /** * Holds the reference to @see $wp_the_query @@ -279,7 +286,7 @@ function wp_is_mobile() { * @global object $wp_query * @since 1.5.0 */ -$wp_query = $wp_the_query; +$GLOBALS['wp_query'] = $wp_the_query; /** * Holds the WordPress Rewrite object for creating pretty URLs @@ -293,7 +300,7 @@ function wp_is_mobile() { * @global object $wp * @since 2.0.0 */ -$wp = new WP(); +$GLOBALS['wp'] = new WP(); /** * WordPress Widget Factory Object @@ -347,7 +354,7 @@ function wp_is_mobile() { do_action( 'after_setup_theme' ); // Set up current user. -$wp->init(); +$GLOBALS['wp']->init(); /** * Most of WP is loaded at this stage, and the user is authenticated. WP continues From 36001b73a7eaa650766bc93c04d8142490bcd9b6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Oct 2015 07:00:34 -0700 Subject: [PATCH 3752/4858] Use global version of the variable because it doesn't exist in local scope --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index deb51f1aff..5fe61d7c01 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -286,7 +286,7 @@ function wp_is_mobile() { * @global object $wp_query * @since 1.5.0 */ -$GLOBALS['wp_query'] = $wp_the_query; +$GLOBALS['wp_query'] = $GLOBALS['wp_the_query']; /** * Holds the WordPress Rewrite object for creating pretty URLs From fe642e4d26fe3452b7f558ad1a16f329f8151123 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Oct 2015 09:08:11 -0700 Subject: [PATCH 3753/4858] Check for version and wp-config.php inside of `Runner::load_wordpress()` Because commands can call this method directly, we want to make sure everything is set up as expected. --- features/framework.feature | 36 ++++++++++++++++++++++++++++++++++++ php/WP_CLI/Runner.php | 8 ++++++++ 2 files changed, 44 insertions(+) diff --git a/features/framework.feature b/features/framework.feature index 6a1e370cec..ea69fcc5fa 100644 --- a/features/framework.feature +++ b/features/framework.feature @@ -47,3 +47,39 @@ Feature: Load WP-CLI WordPress loaded! load_wordpress() can safely be called twice. """ + + Scenario: A command loaded before WordPress then calls WordPress to load, but WP doesn't exist + Given an empty directory + And a custom-cmd.php file: + """ + <?php + class Load_WordPress_Command_Class extends WP_CLI_Command { + + /** + * @when before_wp_load + */ + public function __invoke() { + if ( ! function_exists( 'update_option' ) ) { + WP_CLI::log( 'WordPress not loaded.' ); + } + WP_CLI::get_runner()->load_wordpress(); + if ( function_exists( 'update_option' ) ) { + WP_CLI::log( 'WordPress loaded!' ); + } + WP_CLI::get_runner()->load_wordpress(); + WP_CLI::log( 'load_wordpress() can safely be called twice.' ); + } + + } + WP_CLI::add_command( 'load-wordpress', 'Load_WordPress_Command_Class' ); + """ + + When I try `wp --require=custom-cmd.php load-wordpress` + Then STDOUT should be: + """ + WordPress not loaded. + """ + And STDERR should contain: + """ + Error: This does not seem to be a WordPress install. + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 95dc29aaa6..f106ca68db 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -693,6 +693,14 @@ public function load_wordpress() { $wp_cli_is_loaded = true; + $this->check_wp_version(); + + if ( !Utils\locate_wp_config() ) { + WP_CLI::error( + "wp-config.php not found.\n" . + "Either create one manually or use `wp core config`." ); + } + // Load wp-config.php code, in the global scope eval( $this->get_wp_config_code() ); From 095773b6ae125675ad16e56eed54251c87c132ae Mon Sep 17 00:00:00 2001 From: Robin Schneider <ypid@riseup.net> Date: Thu, 8 Oct 2015 00:15:16 +0200 Subject: [PATCH 3754/4858] Support MariaDB client library. When mariadb-client is already installed on a system, installing wpcli currently requires to remove mariadb-client because mariadb-client and mysql-client are in conflict. --- utils/wp-cli-updatedeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh index fe40b73e4a..9558295641 100755 --- a/utils/wp-cli-updatedeb.sh +++ b/utils/wp-cli-updatedeb.sh @@ -31,7 +31,7 @@ Architecture: all Maintainer: Daniel Bachhuber <daniel@handbuilt.co> Section: php Priority: optional -Depends: php5-cli, php5-mysql | php5-mysqlnd, mysql-client +Depends: php5-cli, php5-mysql | php5-mysqlnd, mysql-client | mariadb-client Homepage: http://wp-cli.org/ Description: wp-cli is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite From b6c7eeff9736c6e54ac2942507247648ddd51494 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 7 Oct 2015 16:05:33 -0700 Subject: [PATCH 3755/4858] Remove string match on upgradeable list search Every time WordPress.org changes their algorithm, this breaks. I'd rather not keep fixing it. --- features/upgradables.feature | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index bc1576597e..49c40a05f3 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -174,9 +174,6 @@ Feature: Manage WordPress themes and plugins """ Showing 2 of """ - And STDOUT should end with a table containing rows: - | name | slug | - | <item_title> | <item> | Examples: | type | type_name | item | item_title | version | zip_file | file_to_check | From 4cbdef7870595680b2bd4dbc7fd8186fea57f527 Mon Sep 17 00:00:00 2001 From: Ryan McCue <me@ryanmccue.info> Date: Thu, 8 Oct 2015 12:47:24 +1000 Subject: [PATCH 3756/4858] Load the REST API in wp-settings --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 50d216ae25..38f08aba5f 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -182,6 +182,7 @@ require( ABSPATH . WPINC . '/nav-menu.php' ); require( ABSPATH . WPINC . '/nav-menu-template.php' ); require( ABSPATH . WPINC . '/admin-bar.php' ); +Utils\maybe_require( '4.4-alpha-34928', ABSPATH . WPINC . '/rest-api.php' ); // Load multisite-specific files. if ( is_multisite() ) { From 36e41f1a7cfb8fc89fb3f70974cd5af17af1860a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 8 Oct 2015 07:40:37 -0700 Subject: [PATCH 3757/4858] `eval` or `eval-file` without WordPress via `--skip-wordpress` --- features/eval.feature | 35 +++++++++++++++++++++++++++++++++++ php/commands/eval-file.php | 13 +++++++++++-- php/commands/eval.php | 12 +++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/features/eval.feature b/features/eval.feature index 1e3e2bdf08..b78a5ad6c0 100644 --- a/features/eval.feature +++ b/features/eval.feature @@ -20,3 +20,38 @@ Feature: Evaluating PHP code and files. """ foo bar """ + + Scenario: Eval without WordPress install + Given an empty directory + + When I try `wp eval 'var_dump(defined("WP_CONTENT_DIR"));'` + Then STDERR should contain: + """ + Error: This does not seem to be a WordPress install. + """ + + When I run `wp eval 'var_dump(defined("WP_CONTENT_DIR"));' --skip-wordpress` + Then STDOUT should be: + """ + bool(false) + """ + + Scenario: Eval file without WordPress install + Given an empty directory + And a script.php file: + """ + <?php + var_dump(defined("WP_CONTENT_DIR")); + """ + + When I try `wp eval-file script.php` + Then STDERR should contain: + """ + Error: This does not seem to be a WordPress install. + """ + + When I run `wp eval-file script.php --skip-wordpress` + Then STDOUT should be: + """ + bool(false) + """ diff --git a/php/commands/eval-file.php b/php/commands/eval-file.php index 92798f5447..d42391c939 100644 --- a/php/commands/eval-file.php +++ b/php/commands/eval-file.php @@ -3,7 +3,7 @@ class EvalFile_Command extends WP_CLI_Command { /** - * Load and execute a PHP file after loading WordPress. + * Load and execute a PHP file. * * ## OPTIONS * @@ -13,17 +13,26 @@ class EvalFile_Command extends WP_CLI_Command { * [<arg>...] * : One or more arguments to pass to the file. They are placed in the $args variable. * + * [--skip-wordpress] + * : Load and execute file without loading WordPress. + * + * @when before_wp_load + * * ## EXAMPLES * * wp eval-file my-code.php value1 value2 */ - public function __invoke( $args ) { + public function __invoke( $args, $assoc_args ) { $file = array_shift( $args ); if ( !file_exists( $file ) ) { WP_CLI::error( "'$file' does not exist." ); } + if ( null === \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-wordpress' ) ) { + WP_CLI::get_runner()->load_wordpress(); + } + self::_eval( $file, $args ); } diff --git a/php/commands/eval.php b/php/commands/eval.php index cce2ca4b28..f81a626dab 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -3,16 +3,26 @@ class Eval_Command extends WP_CLI_Command { /** - * Execute arbitrary PHP code after loading WordPress. + * Execute arbitrary PHP code. * * <php-code> * : The code to execute, as a string. * + * [--skip-wordpress] + * : Execute code without loading WordPress. + * + * @when before_wp_load + * * ## EXAMPLES * * wp eval 'echo WP_CONTENT_DIR;' */ public function __invoke( $args, $assoc_args ) { + + if ( null === \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-wordpress' ) ) { + WP_CLI::get_runner()->load_wordpress(); + } + eval( $args[0] ); } } From 1624d1294b35c64ee90fc24734f7a32033077e16 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 8 Oct 2015 09:06:54 -0700 Subject: [PATCH 3758/4858] Globalize `$blog_id` before loading WordPress Without `$blog_id` globalized, users with persistent object cache drop-ins experience cache pollution. ``` vagrant@vip:/srv/www$ wp option get home http://vip.local vagrant@vip:/srv/www$ sudo service memcached restart Restarting memcached: memcached. vagrant@vip:/srv/www$ wp option get home http://vip.local/fusion vagrant@vip:/srv/www$ wp option get home --url=vip.local http://vip.local/fusion vagrant@vip:/srv/www$ sudo service memcached restart Restarting memcached: memcached. vagrant@vip:/srv/www$ wp option get home --url=vip.local http://vip.local ``` Somewhere, there's usage of `$blog_id` in WordPress that should be explicitly globalized, but isn't. --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index f106ca68db..3785c6c62e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -685,7 +685,7 @@ public function start() { public function load_wordpress() { static $wp_cli_is_loaded; // Globals not explicitly globalized in WordPress - global $current_site, $current_blog, $shortcode_tags; + global $blog_id, $current_site, $current_blog, $shortcode_tags; if ( ! empty( $wp_cli_is_loaded ) ) { return; From b728d757e0e38e0073262c7237f44ab781b02006 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel.bachhuber@fusion.net> Date: Thu, 8 Oct 2015 09:45:04 -0700 Subject: [PATCH 3759/4858] More core variables that need to be explicitly globalized Props @jeremyfelt --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3785c6c62e..a196c1cc46 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -685,7 +685,7 @@ public function start() { public function load_wordpress() { static $wp_cli_is_loaded; // Globals not explicitly globalized in WordPress - global $blog_id, $current_site, $current_blog, $shortcode_tags; + global $blog_id, $site_id, $public, $current_site, $current_blog, $shortcode_tags; if ( ! empty( $wp_cli_is_loaded ) ) { return; From 92dac0f1b95d248ac11ddee095911557005547eb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Fri, 9 Oct 2015 05:51:53 -0700 Subject: [PATCH 3760/4858] Use proper tests checkout for WP_VERSION=latest --- templates/install-wp-tests.sh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 9cd88e16d4..0aaf09f3cc 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -14,14 +14,6 @@ WP_VERSION=${5-latest} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} -if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then - WP_TESTS_TAG="tags/$WP_VERSION" -else - WP_TESTS_TAG='trunk' -fi - -set -ex - download() { if [ `which curl` ]; then curl -s "$1" > "$2"; @@ -30,6 +22,22 @@ download() { fi } +if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then + WP_TESTS_TAG="tags/$WP_VERSION" +else + # http serves a single offer, whereas https serves multiple. we only want one + download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json + grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json + LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') + if [[ -z "$LATEST_VERSION" ]]; then + echo "Latest WordPress version could not be found" + exit 1 + fi + WP_TESTS_TAG="tags/$LATEST_VERSION" +fi + +set -ex + install_wp() { if [ -d $WP_CORE_DIR ]; then From 3f2aa3771667c13f327661b1e12a26f8127ebcfc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 07:22:35 -0700 Subject: [PATCH 3761/4858] Globalize `$blog_id` as core does See https://core.trac.wordpress.org/changeset/34961 --- php/WP_CLI/Runner.php | 2 +- php/wp-settings-cli.php | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a196c1cc46..13d29a0366 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -685,7 +685,7 @@ public function start() { public function load_wordpress() { static $wp_cli_is_loaded; // Globals not explicitly globalized in WordPress - global $blog_id, $site_id, $public, $current_site, $current_blog, $shortcode_tags; + global $site_id, $public, $current_site, $current_blog, $shortcode_tags; if ( ! empty( $wp_cli_is_loaded ) ) { return; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 38f08aba5f..caaebf4fca 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -24,6 +24,15 @@ global $wp_version, $wp_db_version, $tinymce_version, $required_php_version, $required_mysql_version; require( ABSPATH . WPINC . '/version.php' ); +/** + * If not already configured, `$blog_id` will default to 1 in a single site + * configuration. In multisite, it will be overridden by default in ms-settings.php. + * + * @global int $blog_id + * @since 2.0.0 + */ +global $blog_id; + // Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, WP_CONTENT_DIR and WP_CACHE. wp_initial_constants(); From 0ab7662046fd3d958f1caf53a11e8686c5cd02d3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 08:22:05 -0700 Subject: [PATCH 3762/4858] Use `--debug` for more verbosity during WP-CLI bootstrap process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` salty-wordpress ➜ wordpress-test.dev wp option get home --debug Debug: Using default global config: /home/vagrant/.wp-cli/config.yml (0.057s) Debug: Using project config: /srv/www/wordpress-test.dev/wp-cli.yml (0.061s) Debug: Required file from config: /srv/www/wp-rest-cli/wp-rest-cli.php (0.144s) Debug: ABSPATH defined: /srv/www/wordpress-test.dev/ (0.145s) Debug: Begin WordPress load (0.148s) Debug: wp-config.php path: /srv/www/wordpress-test.dev/wp-config.php (0.15s) Debug: Set URL: wordpress-test.dev/ (0.152s) Debug: Loaded WordPress (0.925s) http://wordpress-test.dev ``` --- features/config.feature | 25 ++++++++++++++++ php/WP_CLI/Loggers/Quiet.php | 12 ++++++++ php/WP_CLI/Loggers/Regular.php | 12 ++++++++ php/WP_CLI/Runner.php | 53 +++++++++++++++++++++++++--------- php/class-wp-cli.php | 10 +++++++ php/config-spec.php | 2 +- php/wp-cli.php | 1 + 7 files changed, 101 insertions(+), 14 deletions(-) diff --git a/features/config.feature b/features/config.feature index f5d16ad292..729140a044 100644 --- a/features/config.feature +++ b/features/config.feature @@ -199,6 +199,31 @@ Feature: Have a config file When I run `WP_CLI_CONFIG_PATH=test-dir/config.yml wp help` Then STDERR should be empty + Scenario: Load WordPress with `--debug` + Given a WP install + + When I run `wp option get home --debug` + Then STDERR should contain: + """ + No readable global config found + """ + Then STDERR should contain: + """ + No project config found + """ + And STDERR should contain: + """ + Begin WordPress load + """ + And STDERR should contain: + """ + wp-config.php path: + """ + And STDERR should contain: + """ + Loaded WordPress + """ + Scenario: Missing required files should not fatal WP-CLI Given an empty directory And a wp-cli.yml file: diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index f1140f8586..130c2ff9be 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -25,6 +25,18 @@ public function success( $message ) { // nothing } + /** + * Write a message to STDERR, prefixed with "Debug: ". + * + * @param string $message Message to write. + */ + public function debug( $message ) { + if ( \WP_CLI::get_runner()->config['debug'] ) { + $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); + $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); + } + } + /** * Warning messages aren't logged. * diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index d5358dee69..20eb869b2f 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -55,6 +55,18 @@ public function success( $message ) { $this->_line( $message, 'Success', '%G' ); } + /** + * Write a message to STDERR, prefixed with "Debug: ". + * + * @param string $message Message to write. + */ + public function debug( $message ) { + if ( \WP_CLI::get_runner()->config['debug'] ) { + $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); + $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); + } + } + /** * Write a warning message to STDERR, prefixed with "Warning: ". * diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a196c1cc46..3672545c89 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -21,6 +21,10 @@ class Runner { private $_early_invoke = array(); + private $_global_config_path_debug; + + private $_project_config_path_debug; + public function __get( $key ) { if ( '_' === $key[0] ) return null; @@ -60,20 +64,25 @@ private function do_early_invoke( $when ) { * * @return string|false */ - private static function get_global_config_path() { - $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + private function get_global_config_path() { + if ( isset( $runtime_config['config'] ) ) { $config_path = $runtime_config['config']; - } - - if ( !$config_path ) { + $this->_global_config_path_debug = 'Using global config from config runtime arg: ' . $config_path; + } else if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) { + $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + $this->_global_config_path_debug = 'Using global config from WP_CLI_CONFIG_PATH env var: ' . $config_path; + } else { $config_path = getenv( 'HOME' ) . '/.wp-cli/config.yml'; + $this->_global_config_path_debug = 'Using default global config: ' . $config_path; } - if ( !is_readable( $config_path ) ) + if ( is_readable( $config_path ) ) { + return $config_path; + } else { + $this->_global_config_path_debug = 'No readable global config found'; return false; - - return $config_path; + } } /** @@ -83,7 +92,7 @@ private static function get_global_config_path() { * * @return string|false */ - private static function get_project_config_path() { + private function get_project_config_path() { $config_files = array( 'wp-cli.local.yml', 'wp-cli.yml' @@ -91,7 +100,7 @@ private static function get_project_config_path() { // Stop looking upward when we find we have emerged from a subdirectory // install into a parent install - return Utils\find_file_upward( $config_files, getcwd(), function ( $dir ) { + $project_config_path = Utils\find_file_upward( $config_files, getcwd(), function ( $dir ) { static $wp_load_count = 0; $wp_load_path = $dir . DIRECTORY_SEPARATOR . 'wp-load.php'; if ( file_exists( $wp_load_path ) ) { @@ -99,6 +108,12 @@ private static function get_project_config_path() { } return $wp_load_count > 1; } ); + if ( ! empty( $project_config_path ) ) { + $this->_project_config_path_debug = 'Using project config: ' . $project_config_path; + } else { + $this->_project_config_path_debug = 'No project config found'; + } + return $project_config_path; } /** @@ -171,6 +186,7 @@ private function find_wp_root() { */ private static function set_wp_root( $path ) { define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); + WP_CLI::debug( 'ABSPATH defined: ' . ABSPATH ); $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); } @@ -514,8 +530,8 @@ private function init_config() { // File config { - $this->global_config_path = self::get_global_config_path(); - $this->project_config_path = self::get_project_config_path(); + $this->global_config_path = $this->get_global_config_path(); + $this->project_config_path = $this->get_project_config_path(); $configurator->merge_yml( $this->global_config_path ); $configurator->merge_yml( $this->project_config_path ); @@ -567,6 +583,9 @@ public function start() { $this->init_colorization(); $this->init_logger(); + WP_CLI::debug( $this->_global_config_path_debug ); + WP_CLI::debug( $this->_project_config_path_debug ); + $this->check_root(); if ( empty( $this->arguments ) ) @@ -588,6 +607,7 @@ public function start() { WP_CLI::error( sprintf( "Required file '%s' doesn't exist", basename( $path ) ) ); } Utils\load_file( $path ); + WP_CLI::debug( 'Required file from config: ' . $path ); } } @@ -693,14 +713,19 @@ public function load_wordpress() { $wp_cli_is_loaded = true; + WP_CLI::debug( 'Begin WordPress load' ); + $this->check_wp_version(); - if ( !Utils\locate_wp_config() ) { + $wp_config_path = Utils\locate_wp_config(); + if ( ! $wp_config_path ) { WP_CLI::error( "wp-config.php not found.\n" . "Either create one manually or use `wp core config`." ); } + WP_CLI::debug( 'wp-config.php path: ' . $wp_config_path ); + // Load wp-config.php code, in the global scope eval( $this->get_wp_config_code() ); @@ -722,6 +747,8 @@ public function load_wordpress() { self::set_user( $this->config ); } + WP_CLI::debug( 'Loaded WordPress' ); + } private static function fake_current_site_blog( $url_parts ) { diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 4f1e645411..74839ceefb 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -93,6 +93,7 @@ public static function get_cache() { * Set the context in which WP-CLI should be run */ public static function set_url( $url ) { + WP_CLI::debug( 'Set URL: ' . $url ); $url_parts = Utils\parse_url( $url ); self::set_url_params( $url_parts ); } @@ -236,6 +237,15 @@ public static function success( $message ) { self::$logger->success( $message ); } + /** + * Log debug information + * + * @param string $message + */ + public static function debug( $message ) { + self::$logger->debug( self::error_to_string( $message ) ); + } + /** * Display a warning in the CLI and end with a newline * diff --git a/php/config-spec.php b/php/config-spec.php index 501a806b65..4e6622b0e7 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -67,7 +67,7 @@ 'runtime' => '', 'file' => '<bool>', 'default' => false, - 'desc' => 'Show all PHP errors', + 'desc' => 'Show all PHP errors; add verbosity to WP-CLI bootstrap', ), 'prompt' => array( diff --git a/php/wp-cli.php b/php/wp-cli.php index 0d0e499e6d..7aa32bb465 100644 --- a/php/wp-cli.php +++ b/php/wp-cli.php @@ -3,6 +3,7 @@ // Can be used by plugins/themes to check if WP-CLI is running or not define( 'WP_CLI', true ); define( 'WP_CLI_VERSION', trim( file_get_contents( WP_CLI_ROOT . '/VERSION' ) ) ); +define( 'WP_CLI_START_MICROTIME', microtime( true ) ); // Set common headers, to prevent warnings from plugins $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; From eaddd49dc72ff9f3bc9818dc87bd126e973f94b3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 08:28:51 -0700 Subject: [PATCH 3763/4858] Abstract common methods to a base logger class --- php/WP_CLI/Loggers/Base.php | 51 ++++++++++++++++++++++++++++++++++ php/WP_CLI/Loggers/Quiet.php | 20 +++---------- php/WP_CLI/Loggers/Regular.php | 37 +----------------------- 3 files changed, 56 insertions(+), 52 deletions(-) create mode 100644 php/WP_CLI/Loggers/Base.php diff --git a/php/WP_CLI/Loggers/Base.php b/php/WP_CLI/Loggers/Base.php new file mode 100644 index 0000000000..ef6fab1967 --- /dev/null +++ b/php/WP_CLI/Loggers/Base.php @@ -0,0 +1,51 @@ +<?php + +namespace WP_CLI\Loggers; + +/** + * Base logger class + */ +abstract class Base { + + abstract public function info( $message ); + + abstract public function success( $message ); + + abstract public function warning( $message ); + + /** + * Write a message to STDERR, prefixed with "Debug: ". + * + * @param string $message Message to write. + */ + public function debug( $message ) { + if ( \WP_CLI::get_runner()->config['debug'] ) { + $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); + $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); + } + } + + /** + * Write a string to a resource. + * + * @param resource $handle Commonly STDOUT or STDERR. + * @param string $str Message to write. + */ + protected function write( $handle, $str ) { + fwrite( $handle, $str ); + } + + /** + * Output one line of message to a resource. + * + * @param string $message Message to write. + * @param string $label Prefix message with a label. + * @param string $color Colorize label with a given color. + * @param resource $handle Resource to write to. Defaults to STDOUT. + */ + protected function _line( $message, $label, $color, $handle = STDOUT ) { + $label = \cli\Colors::colorize( "$color$label:%n", $this->in_color ); + $this->write( $handle, "$label $message\n" ); + } + +} diff --git a/php/WP_CLI/Loggers/Quiet.php b/php/WP_CLI/Loggers/Quiet.php index 130c2ff9be..e8de7be82f 100644 --- a/php/WP_CLI/Loggers/Quiet.php +++ b/php/WP_CLI/Loggers/Quiet.php @@ -5,7 +5,7 @@ /** * Quiet logger only logs errors. */ -class Quiet { +class Quiet extends Base { /** * Informational messages aren't logged. @@ -25,18 +25,6 @@ public function success( $message ) { // nothing } - /** - * Write a message to STDERR, prefixed with "Debug: ". - * - * @param string $message Message to write. - */ - public function debug( $message ) { - if ( \WP_CLI::get_runner()->config['debug'] ) { - $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); - $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); - } - } - /** * Warning messages aren't logged. * @@ -52,7 +40,7 @@ public function warning( $message ) { * @param string $message Message to write. */ public function error( $message ) { - fwrite( STDERR, \WP_CLI::colorize( "%RError:%n $message\n" ) ); + $this->write( STDERR, \WP_CLI::colorize( "%RError:%n $message\n" ) ); } /** @@ -63,7 +51,7 @@ public function error( $message ) { public function error_multi_line( $message_lines ) { $message = implode( "\n", $message_lines ); - fwrite( STDERR, \WP_CLI::colorize( "%RError:%n\n$message\n" ) ); - fwrite( STDERR, \WP_CLI::colorize( "%R---------%n\n\n" ) ); + $this->write( STDERR, \WP_CLI::colorize( "%RError:%n\n$message\n" ) ); + $this->write( STDERR, \WP_CLI::colorize( "%R---------%n\n\n" ) ); } } diff --git a/php/WP_CLI/Loggers/Regular.php b/php/WP_CLI/Loggers/Regular.php index 20eb869b2f..eeb3920474 100644 --- a/php/WP_CLI/Loggers/Regular.php +++ b/php/WP_CLI/Loggers/Regular.php @@ -5,7 +5,7 @@ /** * Default logger for success, warning, error, and standard messages. */ -class Regular { +class Regular extends Base { /** * @param bool $in_color Whether or not to Colorize strings. @@ -14,29 +14,6 @@ function __construct( $in_color ) { $this->in_color = $in_color; } - /** - * Write a string to a resource. - * - * @param resource $handle Commonly STDOUT or STDERR. - * @param string $str Message to write. - */ - protected function write( $handle, $str ) { - fwrite( $handle, $str ); - } - - /** - * Output one line of message to a resource. - * - * @param string $message Message to write. - * @param string $label Prefix message with a label. - * @param string $color Colorize label with a given color. - * @param resource $handle Resource to write to. Defaults to STDOUT. - */ - private function _line( $message, $label, $color, $handle = STDOUT ) { - $label = \cli\Colors::colorize( "$color$label:%n", $this->in_color ); - $this->write( $handle, "$label $message\n" ); - } - /** * Write an informational message to STDOUT. * @@ -55,18 +32,6 @@ public function success( $message ) { $this->_line( $message, 'Success', '%G' ); } - /** - * Write a message to STDERR, prefixed with "Debug: ". - * - * @param string $message Message to write. - */ - public function debug( $message ) { - if ( \WP_CLI::get_runner()->config['debug'] ) { - $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); - $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); - } - } - /** * Write a warning message to STDERR, prefixed with "Warning: ". * From 7b5bf21bcc3cbc0d680388924ae9afbc0a1acf2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 08:35:49 -0700 Subject: [PATCH 3764/4858] Remove test because it fails sporadically This part of the codebase is pretty mature. We don't really need to worry about this breaking. --- features/user.feature | 6 ------ 1 file changed, 6 deletions(-) diff --git a/features/user.feature b/features/user.feature index d65b246d71..11c0a08118 100644 --- a/features/user.feature +++ b/features/user.feature @@ -141,12 +141,6 @@ Feature: Manage WordPress users Error: Missing file: users-incorrect.csv """ - When I try `wp user import-csv http://example.com/users.csv --skip-update` - Then STDERR should be: - """ - Error: Couldn't access remote CSV file (HTTP 404 response). - """ - When I run `wp user import-csv users.csv` Then STDOUT should not be empty From c539a57ce1cfeae32ee1141a9b061a1573e2a124 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 08:46:54 -0700 Subject: [PATCH 3765/4858] Update test to account for `WP_CLI::debug()`, which always gets called --- features/flags.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/flags.feature b/features/flags.feature index b50006f240..0ecbf1bd80 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -97,7 +97,7 @@ Feature: Global flags """ When I try `wp --require=custom-logger.php is-installed` - Then STDOUT should be: + Then STDOUT should contain: """ log: called 'error' method """ From 3d72acea6d0995704d0c70a52eba73c5a3effaeb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 08:52:19 -0700 Subject: [PATCH 3766/4858] Log the command being run --- features/config.feature | 4 ++++ php/WP_CLI/Runner.php | 1 + 2 files changed, 5 insertions(+) diff --git a/features/config.feature b/features/config.feature index 729140a044..b56b58f24f 100644 --- a/features/config.feature +++ b/features/config.feature @@ -223,6 +223,10 @@ Feature: Have a config file """ Loaded WordPress """ + And STDERR should contain: + """ + Running command: option get + """ Scenario: Missing required files should not fatal WP-CLI Given an empty directory diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3672545c89..be25d7d949 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -306,6 +306,7 @@ public function run_command( $args, $assoc_args = array() ) { $extra_args = array(); } + WP_CLI::debug( 'Running command: ' . $name ); try { $command->invoke( $final_args, $assoc_args, $extra_args ); } catch ( WP_CLI\Iterators\Exception $e ) { From e26bfbfa0c588b893f7db84d6d7d4051598cf812 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 09:06:17 -0700 Subject: [PATCH 3767/4858] In PHP 7, `substr()` returns empty string when string === # start char Because we're checking to see if there's any value beyond the flag string, updating our check is functionally equivalent --- php/WP_CLI/SynopsisParser.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index 43b89cc80f..d4ba779240 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -59,7 +59,8 @@ private static function classify_token( $token ) { $value = substr( $token, strlen( $matches[0] ) ); - if ( false === $value ) { + // substr returns false <= PHP 5.6, and '' PHP 7+ + if ( false === $value || '' === $value ) { $param['type'] = 'flag'; } else { $param['type'] = 'assoc'; From 36e2a1d05386591edb80aaacf608006b7096b54a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 10:24:05 -0700 Subject: [PATCH 3768/4858] Update `wp cli check-update` to accommodate major releases Also, if `--major`, `--minor` or `--patch` is specified in a check, then success message will parrot the supplied flag. --- composer.json | 1 + php/commands/cli.php | 123 ++++++++++++++++++++++++++++--------------- utils/make-phar.php | 1 + 3 files changed, 84 insertions(+), 41 deletions(-) diff --git a/composer.json b/composer.json index 26dcc72c22..1fe600e046 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "php": ">=5.3.2", "wp-cli/php-cli-tools": "0.10.5", "mustache/mustache": "~2.4", + "composer/semver": "1.0.0", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", "symfony/finder": "~2.3", diff --git a/php/commands/cli.php b/php/commands/cli.php index ffb83ff897..ee1841bddf 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -1,7 +1,9 @@ <?php -use \WP_CLI\Dispatcher, - \WP_CLI\Utils; +use \Composer\Semver\Comparator; +use \Composer\Semver\Semver; +use \WP_CLI\Dispatcher; +use \WP_CLI\Utils; /** * Get information about WP-CLI itself. @@ -69,21 +71,6 @@ public function info( $_, $assoc_args ) { } } - /** - * Compare the last processed release to the current one, return true if it's the same minor version. - * - */ - private function same_minor_release( $release_parts, $updates ) { - $previous = end( $updates ); - if ( false === $previous ) - return false; - - $previous_parts = explode( '.', $previous['version'] ); - - return ( $previous_parts[0] === $release_parts[0] - && $previous_parts[1] === $release_parts[1] ); - } - /** * Check for update via Github API. Returns the available versions if there are updates, or empty if no update available. * @@ -95,6 +82,9 @@ private function same_minor_release( $release_parts, $updates ) { * [--minor] * : Only list minor updates * + * [--major] + * : Only list major updates + * * [--field=<field>] * : Prints the value of a single field for each update. * @@ -116,7 +106,8 @@ public function check_update( $_, $assoc_args ) { ); $formatter->display_items( $updates ); } else if ( empty( $assoc_args['format'] ) || 'table' == $assoc_args['format'] ) { - WP_CLI::success( "WP-CLI is at the latest version." ); + $update_type = $this->get_update_type_str( $assoc_args ); + WP_CLI::success( "WP-CLI is at the latest{$update_type}version." ); } } @@ -131,6 +122,9 @@ public function check_update( $_, $assoc_args ) { * [--minor] * : Only perform minor updates * + * [--major] + * : Only perform major updates + * * [--nightly] * : Update to the latest built version of the master branch. Potentially unstable. * @@ -161,7 +155,8 @@ public function update( $_, $assoc_args ) { $updates = $this->get_updates( $assoc_args ); if ( empty( $updates ) ) { - WP_CLI::success( "WP-CLI is at the latest version." ); + $update_type = $this->get_update_type_str( $assoc_args ); + WP_CLI::success( "WP-CLI is at the latest{$update_type}version." ); exit(0); } @@ -237,41 +232,48 @@ private function get_updates( $assoc_args ) { } $release_data = json_decode( $response->body ); - $current_parts = explode( '.', WP_CLI_VERSION ); - $updates = array(); + $updates = array( + 'major' => false, + 'minor' => false, + 'patch' => false, + ); foreach ( $release_data as $release ) { + + // get rid of leading "v" if there is one set $release_version = $release->tag_name; - // get rid of leading "v" if ( 'v' === substr( $release_version, 0, 1 ) ) { $release_version = ltrim( $release_version, 'v' ); } - // don't list earlier releases - if ( version_compare( $release_version, WP_CLI_VERSION, '<=' ) ) + + $update_type = $this->get_named_sem_ver( $release_version ); + if ( ! $update_type ) { continue; - $release_parts = explode( '.', $release_version ); - $update_type = 'minor'; + } - if ( $release_parts[0] === $current_parts[0] - && $release_parts[1] === $current_parts[1] ) { - $update_type = 'patch'; + if ( ! empty( $updates[ $update_type ] ) && ! Comparator::greaterThan( $release_version, $updates[ $update_type ]['version'] ) ) { + continue; } - if ( ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'patch' ) && 'patch' !== $update_type ) - && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'patch' ) === false && 'patch' === $update_type ) - && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) && 'minor' !== $update_type ) - && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) === false && 'minor' === $update_type ) - && ! $this->same_minor_release( $release_parts, $updates ) - ) { - $updates[] = array( - 'version' => $release_version, - 'update_type' => $update_type, - 'package_url' => $release->assets[0]->browser_download_url - ); + $updates[ $update_type ] = array( + 'version' => $release_version, + 'update_type' => $update_type, + 'package_url' => $release->assets[0]->browser_download_url + ); + } + + foreach( $updates as $type => $value ) { + if ( empty( $value ) ) { + unset( $updates[ $type ] ); } } - return $updates; + foreach( array( 'major', 'minor', 'patch' ) as $type ) { + if ( true === \WP_CLI\Utils\get_flag_value( $assoc_args, $type ) ) { + return ! empty( $updates[ $type ] ) ? array( $updates[ $type ] ) : false; + } + } + return array_values( $updates ); } /** @@ -335,6 +337,45 @@ public function completions( $_, $assoc_args ) { $compl = new \WP_CLI\Completions( $line ); $compl->render(); } + + /** + * Get the named semantic version + * + * @param string $version + * @return string $name 'major', 'minor', 'patch' + */ + private function get_named_sem_ver( $version ) { + + if ( ! Comparator::greaterThan( $version, WP_CLI_VERSION ) ) { + return ''; + } + + $parts = explode( '-', WP_CLI_VERSION ); + list( $major, $minor, $patch ) = explode( '.', $parts[0] ); + + if ( Semver::satisfies( $version, "{$major}.{$minor}.x" ) ) { + return 'patch'; + } else if ( Semver::satisfies( $version, "{$major}.x.x" ) ) { + return 'minor'; + } else { + return 'major'; + } + } + + /** + * Get a string representing the type of update being checked for + */ + private function get_update_type_str( $assoc_args ) { + $update_type = ' '; + foreach( array( 'major', 'minor', 'patch' ) as $type ) { + if ( true === \WP_CLI\Utils\get_flag_value( $assoc_args, $type ) ) { + $update_type = ' ' . $type . ' '; + break; + } + } + return $update_type; + } + } WP_CLI::add_command( 'cli', 'CLI_Command' ); diff --git a/utils/make-phar.php b/utils/make-phar.php index 69445c7f88..7e2432bee2 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -72,6 +72,7 @@ function set_file_contents( $phar, $path, $content ) { ->in(WP_CLI_ROOT . '/vendor/symfony/finder') ->in(WP_CLI_ROOT . '/vendor/nb/oxymel') ->in(WP_CLI_ROOT . '/vendor/ramsey/array_column') + ->in(WP_CLI_ROOT . '/vendor/composer/semver') ->exclude('test') ->exclude('tests') ->exclude('Tests') From 84feba8e00672e7e8a76880b8d62364d53f37aaa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 12 Oct 2015 10:48:33 -0700 Subject: [PATCH 3769/4858] Abstract to a utility to add test coverage around it --- php/commands/cli.php | 27 +-------------------------- php/utils.php | 27 +++++++++++++++++++++++++++ tests/test-utils.php | 11 +++++++++++ 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index ee1841bddf..30baa3237e 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -1,7 +1,6 @@ <?php use \Composer\Semver\Comparator; -use \Composer\Semver\Semver; use \WP_CLI\Dispatcher; use \WP_CLI\Utils; @@ -246,7 +245,7 @@ private function get_updates( $assoc_args ) { $release_version = ltrim( $release_version, 'v' ); } - $update_type = $this->get_named_sem_ver( $release_version ); + $update_type = Utils\get_named_sem_ver( $release_version, WP_CLI_VERSION ); if ( ! $update_type ) { continue; } @@ -338,30 +337,6 @@ public function completions( $_, $assoc_args ) { $compl->render(); } - /** - * Get the named semantic version - * - * @param string $version - * @return string $name 'major', 'minor', 'patch' - */ - private function get_named_sem_ver( $version ) { - - if ( ! Comparator::greaterThan( $version, WP_CLI_VERSION ) ) { - return ''; - } - - $parts = explode( '-', WP_CLI_VERSION ); - list( $major, $minor, $patch ) = explode( '.', $parts[0] ); - - if ( Semver::satisfies( $version, "{$major}.{$minor}.x" ) ) { - return 'patch'; - } else if ( Semver::satisfies( $version, "{$major}.x.x" ) ) { - return 'minor'; - } else { - return 'major'; - } - } - /** * Get a string representing the type of update being checked for */ diff --git a/php/utils.php b/php/utils.php index 62bfe7cae1..22e3281a4f 100644 --- a/php/utils.php +++ b/php/utils.php @@ -4,6 +4,8 @@ namespace WP_CLI\Utils; +use \Composer\Semver\Comparator; +use \Composer\Semver\Semver; use \WP_CLI\Dispatcher; use \WP_CLI\Iterators\Transform; @@ -535,6 +537,31 @@ function increment_version( $current_version, $new_version ) { return $current_version; } +/** + * Compare two version strings to get the named semantic version + * + * @param string $new_version + * @param string $original_version + * @return string $name 'major', 'minor', 'patch' + */ +function get_named_sem_ver( $new_version, $original_version ) { + + if ( ! Comparator::greaterThan( $new_version, $original_version ) ) { + return ''; + } + + $parts = explode( '-', $original_version ); + list( $major, $minor, $patch ) = explode( '.', $parts[0] ); + + if ( Semver::satisfies( $new_version, "{$major}.{$minor}.x" ) ) { + return 'patch'; + } else if ( Semver::satisfies( $new_version, "{$major}.x.x" ) ) { + return 'minor'; + } else { + return 'major'; + } +} + /** * Return the flag value or, if it's not set, the $default value. * diff --git a/tests/test-utils.php b/tests/test-utils.php index 005abedeb3..01bbc5101e 100644 --- a/tests/test-utils.php +++ b/tests/test-utils.php @@ -33,5 +33,16 @@ function testIncrementVersion() { ); } + public function testGetSemVer() { + $original_version = '0.19.1'; + $this->assertEmpty( Utils\get_named_sem_ver( '0.18.0', $original_version ) ); + $this->assertEmpty( Utils\get_named_sem_ver( '0.19.1', $original_version ) ); + $this->assertEquals( 'patch', Utils\get_named_sem_ver( '0.19.2', $original_version ) ); + $this->assertEquals( 'minor', Utils\get_named_sem_ver( '0.20.0', $original_version ) ); + $this->assertEquals( 'minor', Utils\get_named_sem_ver( '0.20.3', $original_version ) ); + $this->assertEquals( 'major', Utils\get_named_sem_ver( '1.0.0', $original_version ) ); + $this->assertEquals( 'major', Utils\get_named_sem_ver( '1.1.1', $original_version ) ); + } + } From 9c527a3cc2803124cdefcafb3ecd64bf85c2d694 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Tue, 13 Oct 2015 19:34:42 +0900 Subject: [PATCH 3770/4858] Add .editorconfig to scaffold plugin, plugin-tests and package-tests. --- features/scaffold.feature | 4 +++- php/commands/scaffold.php | 14 ++++++++------ templates/.editorconfig | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 templates/.editorconfig diff --git a/features/scaffold.feature b/features/scaffold.feature index 777403f37b..9695021e1d 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -161,6 +161,7 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/phpunit.xml file should exist And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist + And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-wp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` Then STDOUT should be: @@ -199,6 +200,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold package-tests community-command` Then STDOUT should not be empty And the community-command/.travis.yml file should exist + And the community-command/.editorconfig file should exist And the community-command/bin/install-package-tests.sh file should exist And the community-command/utils/get-package-require-from-composer.php file should exist And the community-command/features directory should contain: @@ -351,7 +353,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold tests for invalid plugin directory Given a WP install - + When I try `wp scaffold plugin-tests incorrect-custom-plugin` Then STDERR should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5591b98a8e..c7208bc3d3 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -162,7 +162,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( $filename => $final_output ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = "Skipped creating $filename", $success_message = "Created $filename" ); @@ -258,7 +258,7 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); $this->init_wp_filesystem(); - + $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); @@ -333,7 +333,7 @@ function child_theme( $args, $assoc_args ) { $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All theme files were skipped.', $success_message = "Created $theme_dir." ); @@ -431,6 +431,7 @@ public function package_tests( $args, $assoc_args ) { $to_copy = array( 'templates/.travis.package.yml' => $package_dir, + 'templates/.editorconfig' => $package_dir, 'templates/load-wp-cli.feature' => $features_dir, 'templates/install-package-tests.sh' => $bin_dir, 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, @@ -465,7 +466,7 @@ public function package_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All package tests were skipped.', $success_message = 'Created test files.' ); @@ -531,7 +532,7 @@ function plugin( $args, $assoc_args ) { ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All plugin files were skipped.', $success_message = 'Created plugin files.' ); @@ -621,6 +622,7 @@ function plugin_tests( $args, $assoc_args ) { '.travis.yml' => $plugin_dir, 'phpunit.xml' => $plugin_dir, 'test-sample.php' => $tests_dir, + '.editorconfig' => $plugin_dir, ); foreach ( $to_copy as $file => $dir ) { @@ -638,7 +640,7 @@ function plugin_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All test files were skipped.', $success_message = 'Created test files.' ); diff --git a/templates/.editorconfig b/templates/.editorconfig new file mode 100644 index 0000000000..e1cc194ebc --- /dev/null +++ b/templates/.editorconfig @@ -0,0 +1,21 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab + +[{.jshintrc,*.json,*.yml}] +indent_style = space +indent_size = 2 + +[{*.txt,wp-config-sample.php}] +end_of_line = crlf From 518522344910420e93b526cc81a1c057db7700ee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 13 Oct 2015 07:16:23 -0700 Subject: [PATCH 3771/4858] Break `core verify-checksums` tests into separate file --- features/core-checksums.feature | 33 +++++++++++++++++++++++++++++++++ features/core.feature | 32 -------------------------------- 2 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 features/core-checksums.feature diff --git a/features/core-checksums.feature b/features/core-checksums.feature new file mode 100644 index 0000000000..11bd61438c --- /dev/null +++ b/features/core-checksums.feature @@ -0,0 +1,33 @@ +Feature: Validate checksums for WordPress install + + Scenario: Verify core checksums + Given a WP install + + When I run `wp core update` + Then STDOUT should not be empty + + When I run `wp core verify-checksums` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ + + When I run `sed -i.bak s/WordPress/Wordpress/g readme.html` + Then STDERR should be empty + + When I try `wp core verify-checksums` + Then STDERR should be: + """ + Warning: File doesn't verify against checksum: readme.html + Error: WordPress install doesn't verify against checksums. + """ + + When I run `rm readme.html` + Then STDERR should be empty + + When I try `wp core verify-checksums` + Then STDERR should be: + """ + Warning: File doesn't exist: readme.html + Error: WordPress install doesn't verify against checksums. + """ diff --git a/features/core.feature b/features/core.feature index 29a96bc9c0..b9adda9804 100644 --- a/features/core.feature +++ b/features/core.feature @@ -392,38 +392,6 @@ Feature: Manage WordPress installation When I run `wp plugin status hello` Then STDOUT should not be empty - Scenario: Verify core checksums - Given a WP install - - When I run `wp core update` - Then STDOUT should not be empty - - When I run `wp core verify-checksums` - Then STDOUT should be: - """ - Success: WordPress install verifies against checksums. - """ - - When I run `sed -i.bak s/WordPress/Wordpress/g readme.html` - Then STDERR should be empty - - When I try `wp core verify-checksums` - Then STDERR should be: - """ - Warning: File doesn't verify against checksum: readme.html - Error: WordPress install doesn't verify against checksums. - """ - - When I run `rm readme.html` - Then STDERR should be empty - - When I try `wp core verify-checksums` - Then STDERR should be: - """ - Warning: File doesn't exist: readme.html - Error: WordPress install doesn't verify against checksums. - """ - Scenario: Core update from cache Given a WP install And an empty cache From 0ecd899c769bbb7341ae9f717e3fcefdbd5fe47f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 13 Oct 2015 07:35:06 -0700 Subject: [PATCH 3772/4858] Support for verifying checksums without loading WordPress --- features/core-checksums.feature | 22 ++++++++++++++++++++++ php/commands/core.php | 32 +++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/features/core-checksums.feature b/features/core-checksums.feature index 11bd61438c..9c622976b1 100644 --- a/features/core-checksums.feature +++ b/features/core-checksums.feature @@ -31,3 +31,25 @@ Feature: Validate checksums for WordPress install Warning: File doesn't exist: readme.html Error: WordPress install doesn't verify against checksums. """ + + Scenario: Verify core checksums without loading WordPress + Given an empty directory + And I run `wp core download --version=4.3` + + When I try `wp core verify-checksums` + Then STDERR should contain: + """ + Error: wp-config.php not found. + """ + + When I run `wp core verify-checksums --version=4.3 --locale=en_US` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ + + When I try `wp core verify-checksums --version=4.2 --locale=en_US` + Then STDERR should contain: + """ + Error: WordPress install doesn't verify against checksums. + """ diff --git a/php/commands/core.php b/php/commands/core.php index 433b0f8469..d35b055ac8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -798,10 +798,7 @@ public function version( $args = array(), $assoc_args = array() ) { * @return bool|array False on failure. An array of checksums on success. */ private static function get_core_checksums( $version, $locale ) { - $url = $http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); - - if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) - $url = 'https' . substr( $url, 4 ); + $url = 'https://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); $options = array( 'timeout' => 30 @@ -812,11 +809,6 @@ private static function get_core_checksums( $version, $locale ) { ); $response = Utils\http_request( 'GET', $url, null, $headers, $options ); - if ( $ssl && ! $response->success ) { - WP_CLI::warning( 'wp-cli could not establish a secure connection to WordPress.org. Please contact your server administrator.' ); - $response = Utils\http_request( 'GET', $http_url, null, $headers, $options ); - } - if ( ! $response->success || 200 != $response->status_code ) return false; @@ -832,11 +824,33 @@ private static function get_core_checksums( $version, $locale ) { /** * Verify WordPress files against WordPress.org's checksums. * + * Specify version to verify checksums without loading WordPress. + * + * [--version=<version>] + * : Verify checksums against a specific version of WordPress. + * + * [--locale=<locale>] + * : Verify checksums against a specific locale of WordPress. + * + * @when before_wp_load + * * @subcommand verify-checksums */ public function verify_checksums( $args, $assoc_args ) { global $wp_version, $wp_local_package; + if ( ! empty( $assoc_args['version'] ) ) { + $wp_version = $assoc_args['version']; + } + + if ( ! empty( $assoc_args['locale'] ) ) { + $wp_local_package = $assoc_args['locale']; + } + + if ( empty( $wp_version ) ) { + WP_CLI::get_runner()->load_wordpress(); + } + $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); if ( ! is_array( $checksums ) ) { From 0671d55c3f46aea4b022a7bec6ecb1615020aba4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 13 Oct 2015 08:22:13 -0700 Subject: [PATCH 3773/4858] Explicitly identify jobs for clarity --- .travis.yml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 46b1adf308..aa680e987c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,6 @@ sudo: false language: php -php: - - 5.3 - - 5.6 - - '7' - env: global: - WP_CLI_BIN_DIR=/tmp/wp-cli-phar @@ -34,16 +29,17 @@ env: - secure: "XS4lJJSZ2+4rB+zkt9lsdhG+pZEQ6nUjRSdLcVAgS7f7yvFCOjJYWRXlQ5zP/Gl3/XVe/L8EuGLYZsztauLSd6Ob7nEwnb5vIegLaqzbZd7Yizp9TnBj0AFCqo/ZPY+ZhnURY9OLFqknfQMWhrTeVvGRT94nhnnIF+sxokQgv0M=" - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" - matrix: - - WP_VERSION=4.3.1 - - WP_VERSION=3.5.2 DEPLOY_BRANCH=master matrix: - exclude: - - php: 5.6 - env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master - - php: '7' - env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master + include: + - php: 5.3 + env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master + - php: 5.6 + env: WP_VERSION=3.5.2 + - php: 5.6 + env: WP_VERSION=4.3.1 + - php: 7.0 + env: WP_VERSION=4.3.1 before_script: ./ci/prepare.sh From f1d27fb807c7804ea28dad0eeab0ba719f066a79 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 13 Oct 2015 08:29:39 -0700 Subject: [PATCH 3774/4858] Allow PHP7 to fail --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index aa680e987c..b1c87df12e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,8 @@ matrix: env: WP_VERSION=4.3.1 - php: 7.0 env: WP_VERSION=4.3.1 + allow_failures: + - php: 7.0 before_script: ./ci/prepare.sh From 2c3d1cf9a36a6fe540bf5b43c5a5c431da93ccb3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 13 Oct 2015 08:30:07 -0700 Subject: [PATCH 3775/4858] Formatting --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1c87df12e..7f9acd4048 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,16 +32,16 @@ env: matrix: include: - - php: 5.3 - env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master - - php: 5.6 - env: WP_VERSION=3.5.2 - - php: 5.6 - env: WP_VERSION=4.3.1 - - php: 7.0 - env: WP_VERSION=4.3.1 + - php: 5.3 + env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master + - php: 5.6 + env: WP_VERSION=3.5.2 + - php: 5.6 + env: WP_VERSION=4.3.1 + - php: 7.0 + env: WP_VERSION=4.3.1 allow_failures: - - php: 7.0 + - php: 7.0 before_script: ./ci/prepare.sh From af56d4ac8c6b9f42f56ad0e18960489b0efd5881 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 14 Oct 2015 12:08:19 -0300 Subject: [PATCH 3776/4858] improve `wp term list --<field>=<value>` documentation --- php/commands/term.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index 66d7bcceda..4367506bd0 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -25,7 +25,7 @@ class Term_Command extends WP_CLI_Command { * : List terms of one or more taxonomies * * [--<field>=<value>] - * : Filter by one or more fields. + * : Filter by one or more fields (see get_terms() $args parameter for a list of fields). * * [--field=<field>] * : Prints the value of a single field for each term. From ca404a8268069bcc0ba0fe1ba63f1cbfbb34f9d3 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 14 Oct 2015 15:23:59 -0300 Subject: [PATCH 3777/4858] remove description field from `wp taxonomy list` as it was added after wp 3.5.2 --- features/taxonomy.feature | 10 +++++----- php/commands/taxonomy.php | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/features/taxonomy.feature b/features/taxonomy.feature index ece9b7327b..f31eddfd33 100644 --- a/features/taxonomy.feature +++ b/features/taxonomy.feature @@ -6,11 +6,11 @@ Feature: Manage WordPress taxonomies Scenario: Listing taxonomies When I run `wp taxonomy list --format=csv` Then STDOUT should be CSV containing: - | name | label | description | public | hierarchical | - | category | Categories | | 1 | 1 | - | post_tag | Tags | | 1 | | + | name | label | public | hierarchical | + | category | Categories | 1 | 1 | + | post_tag | Tags | 1 | | When I run `wp taxonomy list --object_type=link --format=csv` Then STDOUT should be CSV containing: - | name | label | description | public | hierarchical | - | link_category | Link Categories | | | | + | name | label | public | hierarchical | + | link_category | Link Categories | | | diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index aef6c17a16..e7762fc4bf 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -9,7 +9,6 @@ class Taxonomy_Command extends WP_CLI_Command { private $fields = array( 'name', 'label', - 'description', 'public', 'hierarchical' ); From 3641d0efd02e797d0b8871de3027df8d1a618cd1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 14 Oct 2015 14:17:36 -0700 Subject: [PATCH 3778/4858] Test PHP 7 and 5.6 against WordPress trunk It'll be helpful to see what our compatibility is like --- .travis.yml | 7 +++++-- ci/prepare.sh | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f9acd4048..fb932211e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,11 +37,14 @@ matrix: - php: 5.6 env: WP_VERSION=3.5.2 - php: 5.6 - env: WP_VERSION=4.3.1 + env: WP_VERSION=latest + - php: 5.6 + env: WP_VERSION=trunk - php: 7.0 - env: WP_VERSION=4.3.1 + env: WP_VERSION=trunk allow_failures: - php: 7.0 + - env: WP_VERSION=trunk before_script: ./ci/prepare.sh diff --git a/ci/prepare.sh b/ci/prepare.sh index 0baee0dc88..a279e31585 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -23,7 +23,15 @@ chmod +x $WP_CLI_BIN_DIR/wp # Install CodeSniffer things ./ci/prepare-codesniffer.sh -./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' +if [[ $WP_VERSION == "trunk" ]] +then + wget https://wordpress.org/nightly-builds/wordpress-latest.zip + unzip wordpress-latest.zip + mv wordpress '/tmp/wp-cli-test core-download-cache/' +else + ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' +fi + ./bin/wp core version --path='/tmp/wp-cli-test core-download-cache/' mysql -e 'CREATE DATABASE wp_cli_test;' -uroot From 6b206234373449777f6bedd3a857af6a90ca95a4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 15 Oct 2015 06:17:02 -0700 Subject: [PATCH 3779/4858] Ensure oEmbed controller is loaded in bootstrap --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index caaebf4fca..6a7f4b58e5 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -185,6 +185,7 @@ Utils\maybe_require( '3.5-alpha-22024', ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); Utils\maybe_require( '4.4-alpha-34851', ABSPATH . WPINC . '/embed-functions.php' ); +Utils\maybe_require( '4.4-alpha-34903', ABSPATH . WPINC . '/class-wp-oembed-controller.php' ); require( ABSPATH . WPINC . '/http.php' ); require_once( ABSPATH . WPINC . '/class-http.php' ); require( ABSPATH . WPINC . '/widgets.php' ); From 7220ea0f869537afbbed1c2b01e4fe64dcf70ca8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 15 Oct 2015 22:30:28 -0300 Subject: [PATCH 3780/4858] make `wp taxonomy list` expose the same fields WP-API exposes --- features/taxonomy.feature | 10 +++++----- php/commands/taxonomy.php | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/features/taxonomy.feature b/features/taxonomy.feature index f31eddfd33..823262fd23 100644 --- a/features/taxonomy.feature +++ b/features/taxonomy.feature @@ -6,11 +6,11 @@ Feature: Manage WordPress taxonomies Scenario: Listing taxonomies When I run `wp taxonomy list --format=csv` Then STDOUT should be CSV containing: - | name | label | public | hierarchical | - | category | Categories | 1 | 1 | - | post_tag | Tags | 1 | | + | name | label | description | object_type | show_tagcloud | hierarchical | public | + | category | Categories | | post | 1 | 1 | 1 | + | post_tag | Tags | | post | 1 | | 1 | When I run `wp taxonomy list --object_type=link --format=csv` Then STDOUT should be CSV containing: - | name | label | public | hierarchical | - | link_category | Link Categories | | | + | name | label | description | object_type | show_tagcloud | hierarchical | public | + | link_category | Link Categories | | link | | | | diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index e7762fc4bf..0bd7d60765 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -9,10 +9,24 @@ class Taxonomy_Command extends WP_CLI_Command { private $fields = array( 'name', 'label', + 'description', + 'object_type', + 'show_tagcloud', + 'hierarchical', 'public', - 'hierarchical' ); + public function __construct() { + global $wp_version; + + if ( version_compare( $wp_version, 3.7, '<' ) ) { + // remove description for wp <= 3.7 + $this->fields = array_values( array_diff( $this->fields, array( 'description' ) ) ); + } + + parent::__construct(); + } + /** * List taxonomies. * @@ -59,6 +73,11 @@ public function list_( $args, $assoc_args ) { $taxonomies = get_taxonomies( $assoc_args, 'objects' ); + $taxonomies = array_map( function( $taxonomy ) { + $taxonomy->object_type = implode( ', ', $taxonomy->object_type ); + return $taxonomy; + }, $taxonomies ); + $formatter->display_items( $taxonomies ); } From 535bd15f2f49e108693a3f4cd2aac580352dd72a Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Thu, 15 Oct 2015 23:14:44 -0300 Subject: [PATCH 3781/4858] run taxonomy tests only on wp >= 3.7 --- features/taxonomy.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/taxonomy.feature b/features/taxonomy.feature index 823262fd23..79ff76aac6 100644 --- a/features/taxonomy.feature +++ b/features/taxonomy.feature @@ -3,6 +3,7 @@ Feature: Manage WordPress taxonomies Background: Given a WP install + @require-wp-3.7 Scenario: Listing taxonomies When I run `wp taxonomy list --format=csv` Then STDOUT should be CSV containing: From 877fad19ebf935a9c7b9918b69b8814c733ba616 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 16 Oct 2015 14:18:21 +0900 Subject: [PATCH 3782/4858] Revert "Add .editorconfig to scaffold plugin, plugin-tests and package-tests." This reverts commit 9c527a3cc2803124cdefcafb3ecd64bf85c2d694. --- features/scaffold.feature | 4 +--- php/commands/scaffold.php | 14 ++++++-------- templates/.editorconfig | 21 --------------------- 3 files changed, 7 insertions(+), 32 deletions(-) delete mode 100644 templates/.editorconfig diff --git a/features/scaffold.feature b/features/scaffold.feature index 9695021e1d..777403f37b 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -161,7 +161,6 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/phpunit.xml file should exist And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist - And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-wp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` Then STDOUT should be: @@ -200,7 +199,6 @@ Feature: WordPress code scaffolding When I run `wp scaffold package-tests community-command` Then STDOUT should not be empty And the community-command/.travis.yml file should exist - And the community-command/.editorconfig file should exist And the community-command/bin/install-package-tests.sh file should exist And the community-command/utils/get-package-require-from-composer.php file should exist And the community-command/features directory should contain: @@ -353,7 +351,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold tests for invalid plugin directory Given a WP install - + When I try `wp scaffold plugin-tests incorrect-custom-plugin` Then STDERR should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c7208bc3d3..5591b98a8e 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -162,7 +162,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( $filename => $final_output ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = "Skipped creating $filename", $success_message = "Created $filename" ); @@ -258,7 +258,7 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); $this->init_wp_filesystem(); - + $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); @@ -333,7 +333,7 @@ function child_theme( $args, $assoc_args ) { $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All theme files were skipped.', $success_message = "Created $theme_dir." ); @@ -431,7 +431,6 @@ public function package_tests( $args, $assoc_args ) { $to_copy = array( 'templates/.travis.package.yml' => $package_dir, - 'templates/.editorconfig' => $package_dir, 'templates/load-wp-cli.feature' => $features_dir, 'templates/install-package-tests.sh' => $bin_dir, 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, @@ -466,7 +465,7 @@ public function package_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All package tests were skipped.', $success_message = 'Created test files.' ); @@ -532,7 +531,7 @@ function plugin( $args, $assoc_args ) { ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All plugin files were skipped.', $success_message = 'Created plugin files.' ); @@ -622,7 +621,6 @@ function plugin_tests( $args, $assoc_args ) { '.travis.yml' => $plugin_dir, 'phpunit.xml' => $plugin_dir, 'test-sample.php' => $tests_dir, - '.editorconfig' => $plugin_dir, ); foreach ( $to_copy as $file => $dir ) { @@ -640,7 +638,7 @@ function plugin_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All test files were skipped.', $success_message = 'Created test files.' ); diff --git a/templates/.editorconfig b/templates/.editorconfig deleted file mode 100644 index e1cc194ebc..0000000000 --- a/templates/.editorconfig +++ /dev/null @@ -1,21 +0,0 @@ -# This file is for unifying the coding style for different editors and IDEs -# editorconfig.org - -# WordPress Coding Standards -# https://make.wordpress.org/core/handbook/coding-standards/ - -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -indent_style = tab - -[{.jshintrc,*.json,*.yml}] -indent_style = space -indent_size = 2 - -[{*.txt,wp-config-sample.php}] -end_of_line = crlf From f60a61681ec343760e789056b20b2d7e85b5f278 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 16 Oct 2015 14:43:15 +0900 Subject: [PATCH 3783/4858] add .editorconfig to --- features/scaffold.feature | 4 +++- php/commands/scaffold.php | 15 +++++++++------ templates/.editorconfig | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 templates/.editorconfig diff --git a/features/scaffold.feature b/features/scaffold.feature index 777403f37b..4fdb964475 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -112,6 +112,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world` Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist And the {PLUGIN_DIR}/hello-world/package.json file should exist @@ -140,6 +141,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world --skip-tests` Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist And the {PLUGIN_DIR}/hello-world/tests directory should not exist @@ -351,7 +353,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold tests for invalid plugin directory Given a WP install - + When I try `wp scaffold plugin-tests incorrect-custom-plugin` Then STDERR should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5591b98a8e..c123927efb 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -162,7 +162,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( $filename => $final_output ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = "Skipped creating $filename", $success_message = "Created $filename" ); @@ -258,7 +258,7 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); $this->init_wp_filesystem(); - + $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); @@ -333,7 +333,7 @@ function child_theme( $args, $assoc_args ) { $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All theme files were skipped.', $success_message = "Created $theme_dir." ); @@ -465,7 +465,7 @@ public function package_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All package tests were skipped.', $success_message = 'Created test files.' ); @@ -530,8 +530,11 @@ function plugin( $args, $assoc_args ) { "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), ), $force ); + $wp_filesystem = $this->init_wp_filesystem(); + $wp_filesystem->copy( WP_CLI_ROOT . "/templates/.editorconfig", "$plugin_dir/.editorconfig", true ); + $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All plugin files were skipped.', $success_message = 'Created plugin files.' ); @@ -638,7 +641,7 @@ function plugin_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All test files were skipped.', $success_message = 'Created test files.' ); diff --git a/templates/.editorconfig b/templates/.editorconfig new file mode 100644 index 0000000000..e1cc194ebc --- /dev/null +++ b/templates/.editorconfig @@ -0,0 +1,21 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab + +[{.jshintrc,*.json,*.yml}] +indent_style = space +indent_size = 2 + +[{*.txt,wp-config-sample.php}] +end_of_line = crlf From 1fa452a5538d1a5b5af646ada73edeabdbb9e115 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 16 Oct 2015 14:43:15 +0900 Subject: [PATCH 3784/4858] add .editorconfig to `wp scaffold plugin` --- features/scaffold.feature | 4 +++- php/commands/scaffold.php | 15 +++++++++------ templates/.editorconfig | 21 +++++++++++++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 templates/.editorconfig diff --git a/features/scaffold.feature b/features/scaffold.feature index 777403f37b..4fdb964475 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -112,6 +112,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world` Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist And the {PLUGIN_DIR}/hello-world/package.json file should exist @@ -140,6 +141,7 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world --skip-tests` Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist And the {PLUGIN_DIR}/hello-world/tests directory should not exist @@ -351,7 +353,7 @@ Feature: WordPress code scaffolding """ Scenario: Scaffold tests for invalid plugin directory Given a WP install - + When I try `wp scaffold plugin-tests incorrect-custom-plugin` Then STDERR should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5591b98a8e..c123927efb 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -162,7 +162,7 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( $filename => $final_output ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = "Skipped creating $filename", $success_message = "Created $filename" ); @@ -258,7 +258,7 @@ function _s( $args, $assoc_args ) { $this->maybe_create_themes_dir(); $this->init_wp_filesystem(); - + $unzip_result = unzip_file( $tmpfname, $theme_path ); unlink( $tmpfname ); @@ -333,7 +333,7 @@ function child_theme( $args, $assoc_args ) { $theme_functions_path => Utils\mustache_render( 'child_theme_functions.mustache', $data ) ), $force ); $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All theme files were skipped.', $success_message = "Created $theme_dir." ); @@ -465,7 +465,7 @@ public function package_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All package tests were skipped.', $success_message = 'Created test files.' ); @@ -530,8 +530,11 @@ function plugin( $args, $assoc_args ) { "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), ), $force ); + $wp_filesystem = $this->init_wp_filesystem(); + $wp_filesystem->copy( WP_CLI_ROOT . "/templates/.editorconfig", "$plugin_dir/.editorconfig", true ); + $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All plugin files were skipped.', $success_message = 'Created plugin files.' ); @@ -638,7 +641,7 @@ function plugin_tests( $args, $assoc_args ) { } } $this->log_whether_files_written( - $files_written, + $files_written, $skip_message = 'All test files were skipped.', $success_message = 'Created test files.' ); diff --git a/templates/.editorconfig b/templates/.editorconfig new file mode 100644 index 0000000000..e1cc194ebc --- /dev/null +++ b/templates/.editorconfig @@ -0,0 +1,21 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab + +[{.jshintrc,*.json,*.yml}] +indent_style = space +indent_size = 2 + +[{*.txt,wp-config-sample.php}] +end_of_line = crlf From b72ec0a66a547eac57728839f0a1faf3da367841 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Mon, 19 Oct 2015 00:51:09 +0900 Subject: [PATCH 3785/4858] move into create_files() --- php/commands/scaffold.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c123927efb..873a7faa1d 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -528,11 +528,9 @@ function plugin( $args, $assoc_args ) { $plugin_readme_path => Utils\mustache_render( 'plugin-readme.mustache', $data ), "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), + "$plugin_dir/.editorconfig" => file_get_contents( WP_CLI_ROOT . "/templates/.editorconfig" ), ), $force ); - $wp_filesystem = $this->init_wp_filesystem(); - $wp_filesystem->copy( WP_CLI_ROOT . "/templates/.editorconfig", "$plugin_dir/.editorconfig", true ); - $this->log_whether_files_written( $files_written, $skip_message = 'All plugin files were skipped.', From dd0e4c770450dce55c316f9acf6826620ff6b204 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 19 Oct 2015 06:34:29 -0700 Subject: [PATCH 3786/4858] Remove unnecessary `get_post()` from `_process_regeneration()` Because we're passing `$id`, and only ever using the `ID` attribute from `$image`, we don't need to assign `$image` --- php/commands/media.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index dc83e9050d..997d670148 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -204,11 +204,10 @@ private function _make_copy( $path ) { } private function _process_regeneration( $id, $skip_delete = false ) { - $image = get_post( $id ); - $fullsizepath = get_attached_file( $image->ID ); + $fullsizepath = get_attached_file( $id ); - $att_desc = sprintf( '"%1$s" (ID %2$d).', get_the_title( $image->ID ), $image->ID ); + $att_desc = sprintf( '"%1$s" (ID %2$d).', get_the_title( $id ), $id ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { WP_CLI::warning( "Can't find $att_desc" ); @@ -216,10 +215,10 @@ private function _process_regeneration( $id, $skip_delete = false ) { } if ( ! $skip_delete ) { - $this->remove_old_images( $image->ID ); + $this->remove_old_images( $id ); } - $metadata = wp_generate_attachment_metadata( $image->ID, $fullsizepath ); + $metadata = wp_generate_attachment_metadata( $id, $fullsizepath ); if ( is_wp_error( $metadata ) ) { WP_CLI::warning( $metadata->get_error_message() ); return; @@ -230,7 +229,7 @@ private function _process_regeneration( $id, $skip_delete = false ) { return; } - wp_update_attachment_metadata( $image->ID, $metadata ); + wp_update_attachment_metadata( $id, $metadata ); WP_CLI::log( "Regenerated thumbnails for $att_desc" ); From 94707b052c535c31df8487ff8ff2a8e1d5bab15d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Tue, 20 Oct 2015 15:50:58 -0700 Subject: [PATCH 3787/4858] Accommodate `wp_new_user_notification()`'s deprecated second argument --- php/commands/user.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index cb5d35afe7..fb9292173a 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -300,7 +300,7 @@ public function create( $args, $assoc_args ) { } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'send-email' ) ) { - wp_new_user_notification( $user_id, $user->user_pass ); + self::wp_new_user_notification( $user_id, $user->user_pass ); } if ( is_wp_error( $user_id ) ) { @@ -721,7 +721,7 @@ public function import_csv( $args, $assoc_args ) { } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'send-email' ) ) { - wp_new_user_notification( $user_id, $new_user['user_pass'] ); + self::wp_new_user_notification( $user_id, $new_user['user_pass'] ); } } @@ -760,6 +760,27 @@ private static function validate_role( $role ) { } + /** + * Acommodate three different behaviors for wp_new_user_notification() + * - 4.3.1 and above: expect second argument to be deprecated + * - 4.3: Second argument was repurposed as $notify + * - Below 4.3: Send the password in the notification + * + * @param string $user_id + * @param string $password + */ + private static function wp_new_user_notification( $user_id, $password ) { + global $wp_version; + $version = str_replace( '-src', '', $wp_version ); + if ( version_compare( $version, '4.3.1', '>=' ) ) { + wp_new_user_notification( $user_id, null, 'both' ); + } else if ( version_compare( $version, '4.3', '>' ) ) { + wp_new_user_notification( $user_id, 'both' ); + } else { + wp_new_user_notification( $user_id, $password ); + } + } + } /** From ab17e5a201c083516ea9c22cc3af1e6e9e145e09 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 21 Oct 2015 06:05:17 -0700 Subject: [PATCH 3788/4858] Properly match on WP 4.3 --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index fb9292173a..4d11b1bdb9 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -774,7 +774,7 @@ private static function wp_new_user_notification( $user_id, $password ) { $version = str_replace( '-src', '', $wp_version ); if ( version_compare( $version, '4.3.1', '>=' ) ) { wp_new_user_notification( $user_id, null, 'both' ); - } else if ( version_compare( $version, '4.3', '>' ) ) { + } else if ( version_compare( $version, '4.3', '>=' ) ) { wp_new_user_notification( $user_id, 'both' ); } else { wp_new_user_notification( $user_id, $password ); From 51d692f3d3d572b772c717280ea5dc1a894d7128 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Oct 2015 10:09:42 -0700 Subject: [PATCH 3789/4858] Break `core update-db` tests to a separate features file --- features/core-update-db.feature | 21 +++++++++++++++++++++ features/core.feature | 20 -------------------- 2 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 features/core-update-db.feature diff --git a/features/core-update-db.feature b/features/core-update-db.feature new file mode 100644 index 0000000000..3d5075efeb --- /dev/null +++ b/features/core-update-db.feature @@ -0,0 +1,21 @@ +Feature: Update core's database + + Scenario: Update db across network + Given a WP multisite install + And I run `wp site create --slug=foo` + And I run `wp site create --slug=bar` + And I run `wp site create --slug=burrito --porcelain` + And save STDOUT as {BURRITO_ID} + And I run `wp site create --slug=taco --porcelain` + And save STDOUT as {TACO_ID} + And I run `wp site create --slug=pizza --porcelain` + And save STDOUT as {PIZZA_ID} + And I run `wp site archive {BURRITO_ID}` + And I run `wp site spam {TACO_ID}` + And I run `wp site delete {PIZZA_ID} --yes` + + When I run `wp core update-db --network` + Then STDOUT should contain: + """ + Success: WordPress database upgraded on 3/3 sites. + """ diff --git a/features/core.feature b/features/core.feature index b9adda9804..bdedea78af 100644 --- a/features/core.feature +++ b/features/core.feature @@ -289,26 +289,6 @@ Feature: Manage WordPress installation Error: Multisite with subdomains cannot be configured when domain is 'localhost'. """ - Scenario: Update db across network - Given a WP multisite install - And I run `wp site create --slug=foo` - And I run `wp site create --slug=bar` - And I run `wp site create --slug=burrito --porcelain` - And save STDOUT as {BURRITO_ID} - And I run `wp site create --slug=taco --porcelain` - And save STDOUT as {TACO_ID} - And I run `wp site create --slug=pizza --porcelain` - And save STDOUT as {PIZZA_ID} - And I run `wp site archive {BURRITO_ID}` - And I run `wp site spam {TACO_ID}` - And I run `wp site delete {PIZZA_ID} --yes` - - When I run `wp core update-db --network` - Then STDOUT should contain: - """ - Success: WordPress database upgraded on 3/3 sites. - """ - Scenario: Update from a ZIP file Given a WP install From d3a6c8336f6765fda59bc923a6f2cec519d40130 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Oct 2015 10:28:49 -0700 Subject: [PATCH 3790/4858] Provide more verbosity when updating core database schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be helpful to know what version we were at, and what we updated to. ``` salty-wordpress ➜ wordpress-test.dev wp core update-db --network WordPress database already at latest db version 30135 on wordpress-test.dev/ WordPress database upgraded successfully from db version 33056 to 30135 on wordpress-test.dev/foo/ WordPress database upgraded successfully from db version 33056 to 30135 on wordpress-test.dev/bar/ Success: WordPress database upgraded on 3/3 sites ``` --- features/core-update-db.feature | 19 ++++++++++++++++++- php/commands/core.php | 21 ++++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/features/core-update-db.feature b/features/core-update-db.feature index 3d5075efeb..eec53c0268 100644 --- a/features/core-update-db.feature +++ b/features/core-update-db.feature @@ -1,5 +1,22 @@ Feature: Update core's database + Scenario: Update db on a single site + Given a WP install + And I run `wp core download --version=4.1 --force` + And I run `wp option update db_version 29630` + + When I run `wp core update-db` + Then STDOUT should contain: + """ + Success: WordPress database upgraded successfully from 29630 to 30133 + """ + + When I run `wp core update-db` + Then STDOUT should contain: + """ + Success: WordPress database already at latest version 30133 + """ + Scenario: Update db across network Given a WP multisite install And I run `wp site create --slug=foo` @@ -17,5 +34,5 @@ Feature: Update core's database When I run `wp core update-db --network` Then STDOUT should contain: """ - Success: WordPress database upgraded on 3/3 sites. + Success: WordPress database upgraded on 3/3 sites """ diff --git a/php/commands/core.php b/php/commands/core.php index d35b055ac8..3520bf7c04 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1008,7 +1008,7 @@ function update( $args, $assoc_args ) { * @subcommand update-db */ function update_db( $_, $assoc_args ) { - global $wpdb, $wp_db_version; + global $wpdb, $wp_db_version, $wp_current_db_version; $network = Utils\get_flag_value( $assoc_args, 'network' ); if ( $network && ! is_multisite() ) { @@ -1027,7 +1027,13 @@ function update_db( $_, $assoc_args ) { $url = $blog->domain . $blog->path; $process = WP_CLI::launch_self( 'core update-db', array(), array(), false, true, array( 'url' => $url ) ); if ( 0 == $process->return_code ) { - WP_CLI::log( "Database upgraded successfully on {$url}" ); + // See if we can parse the stdout + if ( preg_match( '#Success: (.+)#', $process->stdout, $matches ) ) { + $message = "{$matches[1]} on {$url}"; + } else { + $message = "Database upgraded successfully on {$url}"; + } + WP_CLI::log( $message ); $success++; } else { WP_CLI::warning( "Database failed to upgrade on {$url}" ); @@ -1036,11 +1042,16 @@ function update_db( $_, $assoc_args ) { if ( $total && $success == $total ) { update_site_option( 'wpmu_upgrade_site', $wp_db_version ); } - WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites.', $success, $total ) ); + WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites', $success, $total ) ); } else { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - wp_upgrade(); - WP_CLI::success( 'WordPress database upgraded successfully.' ); + $wp_current_db_version = __get_option( 'db_version' ); + if ( $wp_db_version != $wp_current_db_version ) { + wp_upgrade(); + WP_CLI::success( "WordPress database upgraded successfully from db version {$wp_current_db_version} to {$wp_db_version}" ); + } else { + WP_CLI::success( "WordPress database already at latest db version {$wp_db_version}" ); + } } } From d3360668bda1198972a5d74d68f8aa378340b920 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 25 Oct 2015 11:21:42 -0700 Subject: [PATCH 3791/4858] Update tests to accommodate new messages --- features/core-update-db.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core-update-db.feature b/features/core-update-db.feature index eec53c0268..b26e596e67 100644 --- a/features/core-update-db.feature +++ b/features/core-update-db.feature @@ -8,13 +8,13 @@ Feature: Update core's database When I run `wp core update-db` Then STDOUT should contain: """ - Success: WordPress database upgraded successfully from 29630 to 30133 + Success: WordPress database upgraded successfully from db version 29630 to 30133 """ When I run `wp core update-db` Then STDOUT should contain: """ - Success: WordPress database already at latest version 30133 + Success: WordPress database already at latest db version 30133 """ Scenario: Update db across network From a8501bdb782797a42e71448579264386f4e47410 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 26 Oct 2015 16:15:08 -0200 Subject: [PATCH 3792/4858] add subcommand `wp taxonomy get` --- features/taxonomy.feature | 14 +++++++++++ php/commands/taxonomy.php | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/features/taxonomy.feature b/features/taxonomy.feature index 79ff76aac6..35605a47c4 100644 --- a/features/taxonomy.feature +++ b/features/taxonomy.feature @@ -15,3 +15,17 @@ Feature: Manage WordPress taxonomies Then STDOUT should be CSV containing: | name | label | description | object_type | show_tagcloud | hierarchical | public | | link_category | Link Categories | | link | | | | + + Scenario: Get taxonomy + When I try `wp taxonomy get invalid-taxonomy` + Then STDERR should be: + """ + Error: Taxonomy invalid-taxonomy doesn't exist. + """ + + When I run `wp taxonomy get category` + Then STDOUT should be a table containing rows: + | Field | Value | + | name | category | + | object_type | ["post"] | + | label | Categories | \ No newline at end of file diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index 0bd7d60765..be26a0f163 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -81,6 +81,59 @@ public function list_( $args, $assoc_args ) { $formatter->display_items( $taxonomies ); } + /** + * Get a taxonomy + * + * ## OPTIONS + * + * <taxonomy> + * : Taxonomy slug + * + * [--field=<field>] + * : Instead of returning the whole taxonomy, returns the value of a single field. + * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * + * [--format=<format>] + * : Accepted values: table, json, csv. Default: table + * + * ## EXAMPLES + * + * wp taxonomy get post_tag --format=json + */ + public function get( $args, $assoc_args ) { + $taxonomy = get_taxonomy( $args[0] ); + + if ( ! $taxonomy ) { + WP_CLI::error( "Taxonomy {$args[0]} doesn't exist." ); + } + + if ( empty( $assoc_args['fields'] ) ) { + $default_fields = array_merge( $this->fields, array( + 'labels', + 'cap' + ) ); + + $assoc_args['fields'] = $default_fields; + } + + $data = array( + 'name' => $taxonomy->name, + 'label' => $taxonomy->label, + 'description' => $taxonomy->description, + 'object_type' => $taxonomy->object_type, + 'show_tagcloud' => $taxonomy->show_tagcloud, + 'hierarchical' => $taxonomy->hierarchical, + 'public' => $taxonomy->public, + 'labels' => $taxonomy->labels, + 'cap' => $taxonomy->cap, + ); + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $data ); + } + private function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'taxonomy' ); } From 23dc7b30cb3f05d2e0ad58865c01bf08e4d70dd6 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Mon, 26 Oct 2015 16:16:50 -0200 Subject: [PATCH 3793/4858] add missing new line at the end of the file --- features/taxonomy.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/taxonomy.feature b/features/taxonomy.feature index 35605a47c4..e2d75c3169 100644 --- a/features/taxonomy.feature +++ b/features/taxonomy.feature @@ -28,4 +28,4 @@ Feature: Manage WordPress taxonomies | Field | Value | | name | category | | object_type | ["post"] | - | label | Categories | \ No newline at end of file + | label | Categories | From 64fd82fff1463d1160eea59773467651e7495783 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 26 Oct 2015 11:39:35 -0700 Subject: [PATCH 3794/4858] Remove unnecessary `esc_sql()` from `wp option list --search=` The query is run through `$wpdb->prepare()` later on --- php/commands/option.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index 9f2f66f844..6fd5274295 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -130,7 +130,7 @@ public function list_( $args, $assoc_args ) { $autoload_query = ''; if ( isset( $assoc_args['search'] ) ) { - $pattern = self::esc_like( esc_sql( $assoc_args['search'] ) ); + $pattern = self::esc_like( $assoc_args['search'] ); // substitute wildcards $pattern = str_replace( '*', '%', $pattern ); $pattern = str_replace( '?', '_', $pattern ); From abeb6ad84d8be35f58803cecd579c027338f98c4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 26 Oct 2015 11:44:56 -0700 Subject: [PATCH 3795/4858] Use `esc_sql()` and `$wpdb->prepare()` instead of deprecated method --- php/WP_CLI/Iterators/Table.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index cebb812bd7..143dbcc675 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -65,16 +65,15 @@ private static function build_fields( $fields ) { } private static function build_where_conditions( $where ) { - global $wpdb; if ( is_array( $where ) ) { $conditions = array(); foreach( $where as $key => $value ) { if ( is_array( $value ) ) { - $conditions[] = $key . ' IN (' . $wpdb->escape( implode( ',', $value ) ) . ')'; + $conditions[] = $key . ' IN (' . esc_sql( implode( ',', $value ) ) . ')'; } else if ( is_numeric( $key ) ) { $conditions[] = $value; } else { - $conditions[] = $key . ' = "' . $wpdb->escape( $value ) .'"'; + $conditions[] = $key . $wpdb->prepare( ' = %s', $value ); } } $where = implode( ' AND ', $conditions ); From 493ad29e433a3bcf7a6189faa4fe0a19a7788427 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 26 Oct 2015 12:29:01 -0700 Subject: [PATCH 3796/4858] Restore `$wpdb` global --- php/WP_CLI/Iterators/Table.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 143dbcc675..472129ef8e 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -65,6 +65,7 @@ private static function build_fields( $fields ) { } private static function build_where_conditions( $where ) { + global $wpdb; if ( is_array( $where ) ) { $conditions = array(); foreach( $where as $key => $value ) { From 55282c8aac32139ac188a2ebd15c9bf4a54cb4e8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 27 Oct 2015 08:13:00 -0200 Subject: [PATCH 3797/4858] add `wp post-type` command --- features/post-type.feature | 11 ++++++ php/commands/post-type.php | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 features/post-type.feature create mode 100644 php/commands/post-type.php diff --git a/features/post-type.feature b/features/post-type.feature new file mode 100644 index 0000000000..fb98b0173e --- /dev/null +++ b/features/post-type.feature @@ -0,0 +1,11 @@ +Feature: Manage WordPress post types + + Background: + Given a WP install + + Scenario: Listing post types + When I run `wp post-type list --format=csv` + Then STDOUT should be CSV containing: + | name | label | description | hierarchical | public | capability_type | + | post | Posts | | | 1 | post | + | page | Pages | | 1 | 1 | page | diff --git a/php/commands/post-type.php b/php/commands/post-type.php new file mode 100644 index 0000000000..3b6f671783 --- /dev/null +++ b/php/commands/post-type.php @@ -0,0 +1,69 @@ +<?php +/** + * Manage post types. + * + * @package wp-cli + */ +class Post_Type_Command extends WP_CLI_Command { + + private $fields = array( + 'name', + 'label', + 'description', + 'hierarchical', + 'public', + 'capability_type', + ); + + /** + * List post types. + * + * ## OPTIONS + * + * [--<field>=<value>] + * : Filter by one or more fields (see get_post_types() first parameter for a list of available fields). + * + * [--field=<field>] + * : Prints the value of a single field for each post type. + * + * [--fields=<fields>] + * : Limit the output to specific post type fields. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each term: + * + * * name + * * label + * * description + * * hierarchical + * * public + * * capability_type + * + * There are no optionally available fields. + * + * ## EXAMPLES + * + * wp post-type list --format=csv + * + * wp post-type list --object-type=post --fields=name,public + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); + + $types = get_post_types( $assoc_args, 'objects' ); + + $formatter->display_items( $types ); + } + + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'post-type' ); + } +} + +WP_CLI::add_command( 'post-type', 'Post_Type_Command' ); From 0d5afaab128a6a541f9992b8b8dae9cf59c1b63d Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 27 Oct 2015 08:35:09 -0200 Subject: [PATCH 3798/4858] add subcommand `wp post-type get <post-type>` --- features/post-type.feature | 13 ++++++++++ php/commands/post-type.php | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/features/post-type.feature b/features/post-type.feature index fb98b0173e..08f2a1f615 100644 --- a/features/post-type.feature +++ b/features/post-type.feature @@ -9,3 +9,16 @@ Feature: Manage WordPress post types | name | label | description | hierarchical | public | capability_type | | post | Posts | | | 1 | post | | page | Pages | | 1 | 1 | page | + + Scenario: Get a post type + When I try `wp post-type get invalid-post-type` + Then STDERR should be: + """ + Error: Post type invalid-post-type doesn't exist. + """ + + When I run `wp post-type get page` + Then STDOUT should be a table containing rows: + | Field | Value | + | name | page | + | label | Pages | diff --git a/php/commands/post-type.php b/php/commands/post-type.php index 3b6f671783..d83ec398fb 100644 --- a/php/commands/post-type.php +++ b/php/commands/post-type.php @@ -61,6 +61,58 @@ public function list_( $args, $assoc_args ) { $formatter->display_items( $types ); } + /** + * Get a post type + * + * ## OPTIONS + * + * <post-type> + * : Post type slug + * + * [--field=<field>] + * : Instead of returning the whole taxonomy, returns the value of a single field. + * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to all fields. + * + * [--format=<format>] + * : Accepted values: table, json, csv. Default: table + * + * ## EXAMPLES + * + * wp post-type get page --format=json + */ + public function get( $args, $assoc_args ) { + $post_type = get_post_type_object( $args[0] ); + + if ( ! $post_type ) { + WP_CLI::error( "Post type {$args[0]} doesn't exist." ); + } + + if ( empty( $assoc_args['fields'] ) ) { + $default_fields = array_merge( $this->fields, array( + 'labels', + 'cap' + ) ); + + $assoc_args['fields'] = $default_fields; + } + + $data = array( + 'name' => $post_type->name, + 'label' => $post_type->label, + 'description' => $post_type->description, + 'hierarchical' => $post_type->hierarchical, + 'public' => $post_type->public, + 'capability_type' => $post_type->capability_type, + 'labels' => $post_type->labels, + 'cap' => $post_type->cap, + ); + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_item( $data ); + } + private function get_formatter( &$assoc_args ) { return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'post-type' ); } From e0b43d7dff6b30fba3144948c191b2b0d9ed22ed Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 05:19:58 -0700 Subject: [PATCH 3799/4858] Don't allow failures against WordPress trunk We need to make sure WP-CLI is fully-compatible with WP 4.4 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fb932211e2..b714914cbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,6 @@ matrix: env: WP_VERSION=trunk allow_failures: - php: 7.0 - - env: WP_VERSION=trunk before_script: ./ci/prepare.sh From aa4068f35bf10b7312e1d2e0845dcf98020561ca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 05:32:33 -0700 Subject: [PATCH 3800/4858] Pick another rewrite rule to match Core changed the regex for this one in 4.4 See https://core.trac.wordpress.org/ticket/11694#comment:39 --- features/rewrite.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index 3c49c4843f..7e86f16baa 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -25,7 +25,7 @@ Feature: Manage WordPress rewrites When I run `wp rewrite list --format=csv` Then STDOUT should be CSV containing: | match | query | source | - | blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)(/[0-9]+)?/?$ | index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&name=$matches[4]&page=$matches[5] | post | + | blog/[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/[^/]+/attachment/([^/]+)/trackback/?$ | index.php?attachment=$matches[1]&tb=1 | post | | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | | section/(.+?)/?$ | index.php?category_name=$matches[1] | category | From 94db54d1c8decf9c095c038d78239db82cda2a73 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 05:36:02 -0700 Subject: [PATCH 3801/4858] Make this a lower-fidelity test, because core changed the retval --- features/comment.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index f79a2ac230..ff970332c8 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -68,9 +68,9 @@ Feature: Manage WordPress comments """ When I run `wp comment url 1` - Then STDOUT should be: + Then STDOUT should contain: """ - http://example.com/?p=1#comment-1 + #comment-1 """ Scenario: Count comments From 41db5ec515c5f9b745c51173d55768636322bc10 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 05:39:29 -0700 Subject: [PATCH 3802/4858] Update `wp comment count` tests for WP 4.4 WordPress returns a new `all` value, which fails the original tests. --- features/comment.feature | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index ff970332c8..8e368e244d 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -75,24 +75,30 @@ Feature: Manage WordPress comments Scenario: Count comments When I run `wp comment count 1` - Then STDOUT should be: + Then STDOUT should contain: """ approved: 1 + """ + And STDOUT should contain: + """ moderated: 0 - spam: 0 - trash: 0 - post-trashed: 0 + """ + And STDOUT should contain: + """ total_comments: 1 """ When I run `wp comment count` - Then STDOUT should be: + Then STDOUT should contain: """ approved: 1 + """ + And STDOUT should contain: + """ moderated: 0 - spam: 0 - trash: 0 - post-trashed: 0 + """ + And STDOUT should contain: + """ total_comments: 1 """ From 676afbbcb764aef1f476cb5ac549333e0d76675e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 05:56:13 -0700 Subject: [PATCH 3803/4858] Use functionally-equivalent empty strings instead of `null` Something changed deep in the bowels of `wp_insert_post()` that causes SQL failures when `null` is provided. --- php/commands/media.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 997d670148..e2f4599439 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -111,10 +111,10 @@ function regenerate( $args, $assoc_args = array() ) { */ function import( $args, $assoc_args = array() ) { $assoc_args = wp_parse_args( $assoc_args, array( - 'title' => null, - 'caption' => null, - 'alt' => null, - 'desc' => null + 'title' => '', + 'caption' => '', + 'alt' => '', + 'desc' => '', ) ); if ( isset( $assoc_args['post_id'] ) ) { From ffe2d0d5d36f882e5e74f8a456bf9262055b9223 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 06:19:47 -0700 Subject: [PATCH 3804/4858] Cast `parent` and `count` on terms as `int` Core began doing this in 4.4, and we should do it too --- features/term.feature | 4 ++-- php/commands/term.php | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/features/term.feature b/features/term.feature index fa85f1f8b0..03f2bbbb60 100644 --- a/features/term.feature +++ b/features/term.feature @@ -18,8 +18,8 @@ Feature: Manage WordPress terms "name": "Test term", "slug":"test", "description":"This is a test term", - "parent":"0", - "count":"0" + "parent":0, + "count":0 }] """ diff --git a/php/commands/term.php b/php/commands/term.php index 4367506bd0..f5ddfb3e53 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -73,6 +73,12 @@ public function list_( $args, $assoc_args ) { $terms = get_terms( $args, $assoc_args ); } + $terms = array_map( function( $term ){ + $term->count = (int)$term->count; + $term->parent = (int)$term->parent; + return $term; + }, $terms ); + if ( 'ids' == $formatter->format ) { $terms = wp_list_pluck( $terms, 'term_id' ); echo implode( ' ', $terms ); From e9b7f8ed7e1ae2a37ced0b258e2b9e04a63db1fb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 06:21:05 -0700 Subject: [PATCH 3805/4858] Cast as int, see ffe2d0d --- php/commands/term.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index f5ddfb3e53..113a6620c3 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -182,6 +182,9 @@ public function get( $args, $assoc_args ) { $assoc_args['fields'] = array_keys( $term_array ); } + $term->count = (int) $term->count; + $term->parent = (int) $term->parent; + $formatter = $this->get_formatter( $assoc_args ); $formatter->display_item( $term ); } From 51f2e16f11013931c65c73b55675442be7d4f1b8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 06:24:58 -0700 Subject: [PATCH 3806/4858] Make test strings less precise, to work with 4.3 and 4.4 --- features/user.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/user.feature b/features/user.feature index 11c0a08118..62ed3fe2b8 100644 --- a/features/user.feature +++ b/features/user.feature @@ -177,7 +177,7 @@ Feature: Manage WordPress users When I try `wp user import-csv user-invalid.csv` Then STDERR should contain: """ - Warning: Only lowercase letters (a-z) and numbers are allowed. + lowercase letters (a-z) and numbers """ When I run `wp user import-csv user-valid.csv` @@ -195,7 +195,7 @@ Feature: Manage WordPress users When I try `wp user create bob-jones bobjones@example.com` Then STDERR should contain: """ - Error: Only lowercase letters (a-z) and numbers are allowed. + lowercase letters (a-z) and numbers """ When I run `wp user create bobjones bobjones@example.com --display_name="Bob Jones"` From d478ce3e470676fd9baa2a2b3f63c5f852f31fd0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 29 Oct 2015 06:47:29 -0700 Subject: [PATCH 3807/4858] Support `$WP_VERSION=trunk` or `$WP_VERSION=nightly` in WP test install While technically `trunk` is different than `nightly`, pragmatically they're the same, and I'd like to use a built archive instead of SVN checkout. --- templates/install-wp-tests.sh | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 0aaf09f3cc..5baa6cb56c 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -24,6 +24,8 @@ download() { if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then WP_TESTS_TAG="tags/$WP_VERSION" +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" else # http serves a single offer, whereas https serves multiple. we only want one download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json @@ -46,15 +48,21 @@ install_wp() { mkdir -p $WP_CORE_DIR - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p /tmp/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip + unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ + mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR else - local ARCHIVE_NAME="wordpress-$WP_VERSION" + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR fi - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php } From cc8aa8001bc439a6403874cac3bc8802ae10efad Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Sun, 1 Nov 2015 14:32:44 -0800 Subject: [PATCH 3808/4858] Provide human-friendly output when rewrite rules successfully flush This makes `wp rewrite flush` more consistent with other commands. --- features/rewrite.feature | 5 ++++- php/commands/rewrite.php | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index 7e86f16baa..d2908d4f5b 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -50,7 +50,10 @@ Feature: Manage WordPress rewrites When I run `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/` Then I run `wp rewrite flush` - Then STDOUT should be empty + Then STDOUT should be: + """ + Success: Rewrite rules flushed. + """ Scenario: Generate .htaccess on hard flush Given a WP install diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 5a6f4ab0b6..db5eba43ed 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -41,6 +41,8 @@ public function flush( $args, $assoc_args ) { if ( ! get_option( 'rewrite_rules' ) ) { WP_CLI::warning( "Rewrite rules are empty, possibly because of a missing permalink_structure option. Use 'wp rewrite list' to verify, or 'wp rewrite structure' to update permalink_structure." ); + } else { + WP_CLI::success( 'Rewrite rules flushed.' ); } } From 8702c14a199f11180accb2b22e68593e160a9af5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 2 Nov 2015 08:03:00 -0800 Subject: [PATCH 3809/4858] Add syntax highlighting to `wp rewrite structure` docs --- php/commands/rewrite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index db5eba43ed..ed0e046cd5 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -56,8 +56,8 @@ public function flush( $args, $assoc_args ) { * To regenerate a .htaccess file with WP-CLI, you'll need to add the mod_rewrite module * to your wp-cli.yml or config.yml. For example: * - * apache_modules: - * - mod_rewrite + * `apache_modules: + * - mod_rewrite` * * ## OPTIONS * From c7e4a2a91550711386ba9130d86ebf6af024054e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 2 Nov 2015 08:05:08 -0800 Subject: [PATCH 3810/4858] Test PHP 5.6 instead of 5.5 in plugin tests .travis.yml --- templates/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index cd4bc26e79..eeb11ff8c0 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -7,7 +7,7 @@ notifications: php: - 5.3 - - 5.5 + - 5.6 env: - WP_VERSION=latest WP_MULTISITE=0 From 2e09584f2c387fc6776723673aa12474f9ec67df Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Mon, 2 Nov 2015 08:05:44 -0800 Subject: [PATCH 3811/4858] Remove trailing space --- templates/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.travis.yml b/templates/.travis.yml index eeb11ff8c0..375e59ed2d 100644 --- a/templates/.travis.yml +++ b/templates/.travis.yml @@ -18,6 +18,6 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=1 before_script: - - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION + - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION script: phpunit From 7ac800b0bbcc539df4e0f47c785e33cc6277d7c6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 4 Nov 2015 14:55:27 -0800 Subject: [PATCH 3812/4858] Update mailmap with latest contributors --- .mailmap | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.mailmap b/.mailmap index c5b31ad862..080fcc238f 100644 --- a/.mailmap +++ b/.mailmap @@ -13,6 +13,7 @@ boonebgorges <boonebgorges@gmail.com> Borek Bernard <borekb@gmail.com> borekb <borekb@gmail.com> Brad Parbs <brad@bradparbs.com> +Brandon Kraft <public@brandonkraft.com> Brian MacKinney <brian@getpantheon.com> builtbylane <lanegoldberg@gmail.com> c10b10 <alex.ciobica@gmail.com> @@ -33,14 +34,18 @@ dwightjack <marco.solazzi@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> eugeneware <eugene@noblesamurai.com> +Evan Mattson <me@aaemnnost.tv> francescolaffi <francesco.laffi@gmail.com> future500 <ramon@future500.nl> getsource <mike.schroder@dreamhost.com> glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> +Grant McInnes <grant.mcinnes@eyesopen.ca> +Hiroshi Urabe <mail@torounit.com> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> Jan Voráček <jan@voracek.net> +Jeff Gould <jrgould@gmail.com> jeichorn <joshua.eichorn@pagely.com> Jeremy Pry <jeremy.pry@gmail.com> jghazally <jeff@bigfish.co.uk> @@ -97,6 +102,7 @@ phh <phh@peytz.dk> Pippin Williamson <pippin@pippinsplugins.com> Rarst <contact@rarst.net> robertboloc <robertboloc@gmail.com> +Robin Schneider <ypid@riseup.net> rodrigoprimo <rodrigo@hacklab.com.br> rodrigoprimo <rodrigosprimo@gmail.com> roelven <roel@soundcloud.com> @@ -133,6 +139,7 @@ tott <tott@automattic.com> trepmal <trepmal@gmail.com> twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> +voldemortensen <voldemortensen@users.noreply.github.com> Wendell Júnior <wrnx00@gmail.com> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> From a1154ef06a6ce67c7d7ccd62fc8ecba26b9a4855 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Wed, 4 Nov 2015 15:40:56 -0800 Subject: [PATCH 3813/4858] Version bump --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 217292ece3..885415662f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.21.0-alpha +0.21.0 From 4f99ec616f328349b6f4ab632e4e7f202710408f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <d@danielbachhuber.com> Date: Thu, 5 Nov 2015 06:32:19 -0800 Subject: [PATCH 3814/4858] Back to work --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 885415662f..3941605750 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.21.0 +0.22.0-alpha From fe8da658c5d9c3e071c609e1c6c40b8e73be60a8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 5 Nov 2015 13:49:23 -0800 Subject: [PATCH 3815/4858] Failing test case for running `wp help core config` --- features/help.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/help.feature b/features/help.feature index d73cde31ed..fb066f603c 100644 --- a/features/help.feature +++ b/features/help.feature @@ -27,6 +27,16 @@ Feature: Get help about WP-CLI commands wp post list """ + Scenario: Help when WordPress is downloaded but not installed + Given an empty directory + + When I run `wp core download` + And I run `wp help core config` + Then STDOUT should contain: + """ + wp core config + """ + Scenario: Help for nonexistent commands Given a WP install From 573ab9220a69506ec1d76c60000261b62109a7f1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 5 Nov 2015 13:58:27 -0800 Subject: [PATCH 3816/4858] Display help early when WordPress is downloaded, but not configured --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b227d7caa4..799518ed32 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -627,7 +627,7 @@ public function start() { self::set_wp_root( $this->find_wp_root() ); // First try at showing man page - if ( 'help' === $this->arguments[0] && ! $this->wp_exists() ) { + if ( 'help' === $this->arguments[0] && ( ! $this->wp_exists() || ! Utils\locate_wp_config() ) ) { $this->_run_command(); } From 9bb4e5ee6b47a711ac4a56cbc1fa5f8eb99882b2 Mon Sep 17 00:00:00 2001 From: Corey Worrell <proskater55@gmail.com> Date: Fri, 6 Nov 2015 15:30:17 -0800 Subject: [PATCH 3817/4858] Allowing remote plugin files without `.zip` in filename Fixes #2170 --- php/WP_CLI/CommandWithUpgrade.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) mode change 100644 => 100755 php/WP_CLI/CommandWithUpgrade.php diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php old mode 100644 new mode 100755 index 20e347faca..7db521842a --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -121,15 +121,9 @@ function install( $args, $assoc_args ) { $local_or_remote_zip_file = false; $result = false; - // Check if a URL to a remote zip file has been specified - $url_path = parse_url( $slug, PHP_URL_PATH ); - if ( ! empty( $url_path ) && '.zip' === substr( $url_path, - 4 ) ) { + // Check if a URL to a remote or local zip has been specified + if ( strpos( $slug, '://' ) || ( pathinfo( $slug, PATHINFO_EXTENSION ) === 'zip' && is_file( $slug ) ) ) { $local_or_remote_zip_file = $slug; - } else { - // Check if a local zip file has been specified - if ( 'zip' === pathinfo( $slug, PATHINFO_EXTENSION ) && file_exists( $slug ) ) { - $local_or_remote_zip_file = $slug; - } } if ( $local_or_remote_zip_file ) { From b4dadf39f28da753bb4562a3cada65492db8f713 Mon Sep 17 00:00:00 2001 From: Corey Worrell <proskater55@gmail.com> Date: Fri, 6 Nov 2015 15:36:49 -0800 Subject: [PATCH 3818/4858] Adding tighter check to `strpos` --- php/WP_CLI/CommandWithUpgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 7db521842a..e037242182 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -122,7 +122,7 @@ function install( $args, $assoc_args ) { $result = false; // Check if a URL to a remote or local zip has been specified - if ( strpos( $slug, '://' ) || ( pathinfo( $slug, PATHINFO_EXTENSION ) === 'zip' && is_file( $slug ) ) ) { + if ( strpos( $slug, '://' ) !== false || ( pathinfo( $slug, PATHINFO_EXTENSION ) === 'zip' && is_file( $slug ) ) ) { $local_or_remote_zip_file = $slug; } From 044f59602b417b01bceeae2e314c3d4e73b2898d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 9 Nov 2015 07:31:51 -0800 Subject: [PATCH 3819/4858] Have Travis only send email notifications on initial failure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b714914cbe..c058d4068a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,3 +58,4 @@ cache: notifications: email: on_success: never + on_failure: change From cbe9fa4cf50319f79e3de96c5bf6e8eda0c0f44f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 9 Nov 2015 16:23:39 -0800 Subject: [PATCH 3820/4858] Include `not_found` label when scaffolding a custom taxonomy --- templates/taxonomy.mustache | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index 911a6881c6..e47807605b 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -27,6 +27,7 @@ 'separate_items_with_commas' => __( '{{label_plural_ucfirst}} separated by comma', '{{textdomain}}' ), 'add_or_remove_items' => __( 'Add or remove {{label_plural}}', '{{textdomain}}' ), 'choose_from_most_used' => __( 'Choose from the most used {{label_plural}}', '{{textdomain}}' ), + 'not_found' => __( 'No {{label_plural}} found.', '{{textdomain}}' ), 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), ), ) ); From ba20cd35662468493cc212a2b3dbcbcc89b545db Mon Sep 17 00:00:00 2001 From: Josh Eaton <josh@josheaton.org> Date: Mon, 9 Nov 2015 20:54:16 -0500 Subject: [PATCH 3821/4858] Fix scaffolded plugin header so it passes WPCS. * Add @package tag * Use correct comment type. --- templates/plugin.mustache | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/templates/plugin.mustache b/templates/plugin.mustache index d992cd094e..29aded1f7f 100644 --- a/templates/plugin.mustache +++ b/templates/plugin.mustache @@ -1,12 +1,12 @@ <?php -/* -Plugin Name: {{plugin_name}} -Version: 0.1-alpha -Description: PLUGIN DESCRIPTION HERE -Author: YOUR NAME HERE -Author URI: YOUR SITE HERE -Plugin URI: PLUGIN SITE HERE -Text Domain: {{textdomain}} -Domain Path: /languages -*/ - +/** + * Plugin Name: {{plugin_name}} + * Version: 0.1-alpha + * Description: PLUGIN DESCRIPTION HERE + * Author: YOUR NAME HERE + * Author URI: YOUR SITE HERE + * Plugin URI: PLUGIN SITE HERE + * Text Domain: {{textdomain}} + * Domain Path: /languages + * @package {{plugin_name}} + */ From 8c2ddda14a202de50cdec44b20fd5e3c5a29a2b7 Mon Sep 17 00:00:00 2001 From: Josh Eaton <josh@josheaton.org> Date: Mon, 9 Nov 2015 20:56:02 -0500 Subject: [PATCH 3822/4858] Fix minor spacing issues with scaffolded Gruntfile. --- templates/plugin-gruntfile.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/plugin-gruntfile.mustache b/templates/plugin-gruntfile.mustache index 661d0e309f..86a021bfb0 100644 --- a/templates/plugin-gruntfile.mustache +++ b/templates/plugin-gruntfile.mustache @@ -5,7 +5,7 @@ module.exports = function( grunt ) { // Project configuration grunt.initConfig( { - pkg: grunt.file.readJSON( 'package.json' ), + pkg: grunt.file.readJSON( 'package.json' ), addtextdomain: { options: { @@ -46,7 +46,7 @@ module.exports = function( grunt ) { grunt.loadNpmTasks( 'grunt-wp-i18n' ); grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' ); grunt.registerTask( 'i18n', ['addtextdomain', 'makepot'] ); - grunt.registerTask( 'readme', ['wp_readme_to_markdown']); + grunt.registerTask( 'readme', ['wp_readme_to_markdown'] ); grunt.util.linefeed = '\n'; From 3bc3adc1775b46c6e126eedc5cc400d6a85931f1 Mon Sep 17 00:00:00 2001 From: Ryan Williams <ryrowi@gmail.com> Date: Fri, 13 Nov 2015 11:14:02 -0500 Subject: [PATCH 3823/4858] prevent duplicate super-admin grants --- php/commands/super-admin.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 4410f345cd..6dc47baeec 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -35,11 +35,18 @@ public function add( $args, $_ ) { foreach ( $user_logins as $user_login ) { $user = get_user_by( 'login', $user_login ); + if ( !$user ) { WP_CLI::warning( "Couldn't find {$user_login} user." ); - } else { - $super_admins[] = $user->user_login; + continue; + } + + if ( in_array( $user->user_login, $super_admins ) ) { + WP_CLI::warning( "User {$user_login} already has super-admin capabilities." ); + continue; } + + $super_admins[] = $user->user_login; } update_site_option( 'site_admins' , $super_admins ); From 636042f9a994b4c45fd0e61ad22b9f92402741fc Mon Sep 17 00:00:00 2001 From: Ryan Williams <ryrowi@gmail.com> Date: Fri, 13 Nov 2015 11:14:55 -0500 Subject: [PATCH 3824/4858] super-admin add: only output success message if option update succeeds --- php/commands/super-admin.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 6dc47baeec..9d52fed9da 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -49,8 +49,9 @@ public function add( $args, $_ ) { $super_admins[] = $user->user_login; } - update_site_option( 'site_admins' , $super_admins ); - WP_CLI::success( 'Granted super-admin capabilities.' ); + if ( update_site_option( 'site_admins' , $super_admins ) ) { + WP_CLI::success( 'Granted super-admin capabilities.' ); + } } /** From 5c7295aa1b4f47f0a7a388d4e801aac1aa2e7eb6 Mon Sep 17 00:00:00 2001 From: Ryan Williams <ryrowi@gmail.com> Date: Fri, 13 Nov 2015 14:56:55 -0500 Subject: [PATCH 3825/4858] add error & nochange states for super-admin add --- php/commands/super-admin.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 9d52fed9da..c57d6be30d 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -32,6 +32,7 @@ public function add( $args, $_ ) { $users = $this->fetcher->get_many( $args ); $user_logins = wp_list_pluck( $users, 'user_login' ); $super_admins = self::get_admins(); + $num_super_admins = count( $super_admins ); foreach ( $user_logins as $user_login ) { $user = get_user_by( 'login', $user_login ); @@ -49,8 +50,14 @@ public function add( $args, $_ ) { $super_admins[] = $user->user_login; } - if ( update_site_option( 'site_admins' , $super_admins ) ) { - WP_CLI::success( 'Granted super-admin capabilities.' ); + if ( $num_super_admins === count( $super_admins ) ) { + WP_CLI::log( 'No changes.' ); + } else { + if ( update_site_option( 'site_admins' , $super_admins ) ) { + WP_CLI::success( 'Granted super-admin capabilities.' ); + } else { + WP_CLI::error( 'Site options update failed!' ); + } } } From fce03bbf541dcab1b82411814b5b511bdc0c314e Mon Sep 17 00:00:00 2001 From: Ryan Williams <ryrowi@gmail.com> Date: Fri, 13 Nov 2015 14:57:14 -0500 Subject: [PATCH 3826/4858] add duplicate prevention feature test for super-admin add --- features/super-admin.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/super-admin.feature b/features/super-admin.feature index a7a5ea1e40..f53b2ba355 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -17,6 +17,14 @@ Feature: Manage super admins associated with a multisite instance superadmin """ + When I run `wp super-admin add superadmin` + And I run `wp super-admin list` + Then STDOUT should be: + """ + admin + superadmin + """ + When I run `wp super-admin remove admin` And I run `wp super-admin list` Then STDOUT should be: From 22a7aa6a09b8b0a1dc75855ae8f7479572e66893 Mon Sep 17 00:00:00 2001 From: Ryan Williams <ryrowi@gmail.com> Date: Fri, 13 Nov 2015 14:58:27 -0500 Subject: [PATCH 3827/4858] whitespace --- features/super-admin.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/super-admin.feature b/features/super-admin.feature index f53b2ba355..b4d523858f 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -21,8 +21,8 @@ Feature: Manage super admins associated with a multisite instance And I run `wp super-admin list` Then STDOUT should be: """ - admin - superadmin + admin + superadmin """ When I run `wp super-admin remove admin` From e97a67975be0e8a693474940b9a870cdb69c65af Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 13 Nov 2015 12:53:22 -0800 Subject: [PATCH 3828/4858] Use safe version of parent theme slug for child enequeue function A parent theme can include dashes, which aren't safe for a function. Also passes `slug` to the template, so the ID for the child theme stylesheet is populated. --- php/commands/scaffold.php | 2 ++ templates/child_theme_functions.mustache | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 873a7faa1d..100b621e02 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -318,6 +318,8 @@ function child_theme( $args, $assoc_args ) { 'author_uri' => "", 'theme_uri' => "" ) ); + $data['slug'] = $theme_slug; + $data['parent_theme_function_safe'] = str_replace( '-', '_', $data['parent_theme'] ); $data['description'] = ucfirst( $data['parent_theme'] ) . " child theme."; diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache index 1c08099394..395cf0deff 100644 --- a/templates/child_theme_functions.mustache +++ b/templates/child_theme_functions.mustache @@ -1,8 +1,8 @@ <?php -add_action( 'wp_enqueue_scripts', '{{parent_theme}}_parent_theme_enqueue_styles' ); +add_action( 'wp_enqueue_scripts', '{{parent_theme_function_safe}}_parent_theme_enqueue_styles' ); -function {{parent_theme}}_parent_theme_enqueue_styles() { +function {{parent_theme_function_safe}}_parent_theme_enqueue_styles() { wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); wp_enqueue_style( '{{slug}}-style', get_stylesheet_directory_uri() . '/style.css', From 336d529d2dfa8b095fae97d85b47cc80bf81ddb1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 14 Nov 2015 12:04:34 -0800 Subject: [PATCH 3829/4858] Clarify documentation for `wp cache flush` When using a persistent object cache with Multisite, flushing is typically a global operation. --- php/commands/cache.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/cache.php b/php/commands/cache.php index dcc729d570..6fe77130db 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -95,6 +95,9 @@ public function delete( $args, $assoc_args ) { /** * Flush the object cache. + * + * For sites using a persistent object cache, because WordPress Multisite simply adds a blog id + * to the cache key, flushing cache is typically a global operation. */ public function flush( $args, $assoc_args ) { $value = wp_cache_flush(); From 27ee1df363fad6e0e8f47638b74d63c783606229 Mon Sep 17 00:00:00 2001 From: Dave Leach <dave@dmleach.com> Date: Sun, 15 Nov 2015 12:17:30 -0500 Subject: [PATCH 3830/4858] 2209: Added in_color property to base logger; added relevant unit tests --- php/WP_CLI/Loggers/Base.php | 14 +++++++++++++- tests/test-logging.php | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Loggers/Base.php b/php/WP_CLI/Loggers/Base.php index ef6fab1967..4354e87a46 100644 --- a/php/WP_CLI/Loggers/Base.php +++ b/php/WP_CLI/Loggers/Base.php @@ -7,19 +7,31 @@ */ abstract class Base { + protected $in_color = false; + abstract public function info( $message ); abstract public function success( $message ); abstract public function warning( $message ); + /** + * Retrieve the runner instance from the base CLI object. This facilitates + * unit testing, where the WP_CLI instance isn't available + * + * @return Runner Instance of the runner class + */ + protected function getRunner() { + return \WP_CLI::get_runner(); + } + /** * Write a message to STDERR, prefixed with "Debug: ". * * @param string $message Message to write. */ public function debug( $message ) { - if ( \WP_CLI::get_runner()->config['debug'] ) { + if ( $this->getRunner()->config['debug'] ) { $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); } diff --git a/tests/test-logging.php b/tests/test-logging.php index 02899d9a8e..c047943e6b 100644 --- a/tests/test-logging.php +++ b/tests/test-logging.php @@ -1,17 +1,48 @@ <?php -class LoggerMock extends WP_CLI\Loggers\Regular { +class MockRegularLogger extends WP_CLI\Loggers\Regular { + + protected function getRunner() { + return (object) array ( + 'config' => array ( + 'debug' => true + ) + ); + } protected function write( $handle, $str ) { echo $str; } } +class MockQuietLogger extends WP_CLI\Loggers\Quiet { + + protected function getRunner() { + return (object) array ( + 'config' => array ( + 'debug' => true + ) + ); + } +} class LoggingTests extends PHPUnit_Framework_TestCase { + function testLogDebug() { + define( 'WP_CLI_START_MICROTIME', microtime( true ) ); + $message = 'This is a test message.'; + + $regularLogger = new MockRegularLogger( false ); + $this->expectOutputRegex( "/Debug: {$message} \(\d+\.*\d*s\)/" ); + $regularLogger->debug( $message ); + + $quietLogger = new MockQuietLogger(); + $this->expectOutputRegex( "/Debug: {$message} \(\d+\.*\d*s\)/" ); + $quietLogger->debug( $message ); + } + function testLogEscaping() { - $logger = new LoggerMock( false ); + $logger = new MockRegularLogger( false ); $message = 'foo%20bar'; @@ -19,4 +50,3 @@ function testLogEscaping() { $logger->success( $message ); } } - From 0dacfc831c67d9ce08ee933b923ad2f147384063 Mon Sep 17 00:00:00 2001 From: Ryan Williams <ryrowi@gmail.com> Date: Mon, 16 Nov 2015 10:09:33 -0500 Subject: [PATCH 3831/4858] update super-admin tests to include warning message check --- features/super-admin.feature | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/super-admin.feature b/features/super-admin.feature index b4d523858f..ac6a5b7a63 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -18,7 +18,12 @@ Feature: Manage super admins associated with a multisite instance """ When I run `wp super-admin add superadmin` - And I run `wp super-admin list` + Then STDERR should contain: + """ + Warning: User superadmin already has super-admin capabilities. + """ + + When I run `wp super-admin list` Then STDOUT should be: """ admin From b2e8eddc6a45bdfa79b28de3487c34dba8e4c472 Mon Sep 17 00:00:00 2001 From: Dave Leach <dave@dmleach.com> Date: Mon, 16 Nov 2015 10:40:17 -0500 Subject: [PATCH 3832/4858] 2209: Renamed getRunner to get_runner to fit naming convention --- php/WP_CLI/Loggers/Base.php | 4 ++-- tests/test-logging.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Loggers/Base.php b/php/WP_CLI/Loggers/Base.php index 4354e87a46..2f36446ced 100644 --- a/php/WP_CLI/Loggers/Base.php +++ b/php/WP_CLI/Loggers/Base.php @@ -21,7 +21,7 @@ abstract public function warning( $message ); * * @return Runner Instance of the runner class */ - protected function getRunner() { + protected function get_runner() { return \WP_CLI::get_runner(); } @@ -31,7 +31,7 @@ protected function getRunner() { * @param string $message Message to write. */ public function debug( $message ) { - if ( $this->getRunner()->config['debug'] ) { + if ( $this->get_runner()->config['debug'] ) { $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); } diff --git a/tests/test-logging.php b/tests/test-logging.php index c047943e6b..98604965f2 100644 --- a/tests/test-logging.php +++ b/tests/test-logging.php @@ -2,7 +2,7 @@ class MockRegularLogger extends WP_CLI\Loggers\Regular { - protected function getRunner() { + protected function get_runner() { return (object) array ( 'config' => array ( 'debug' => true @@ -17,7 +17,7 @@ protected function write( $handle, $str ) { class MockQuietLogger extends WP_CLI\Loggers\Quiet { - protected function getRunner() { + protected function get_runner() { return (object) array ( 'config' => array ( 'debug' => true From ee935ba2c810afc1472298e50e9628a74e8cd452 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 16 Nov 2015 07:50:13 -0800 Subject: [PATCH 3833/4858] Fix test indentation --- features/super-admin.feature | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/features/super-admin.feature b/features/super-admin.feature index ac6a5b7a63..656499e23a 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -5,34 +5,34 @@ Feature: Manage super admins associated with a multisite instance When I run `wp user create superadmin superadmin@example.com` And I run `wp super-admin list` Then STDOUT should be: - """ - admin - """ + """ + admin + """ When I run `wp super-admin add superadmin` And I run `wp super-admin list` Then STDOUT should be: - """ - admin - superadmin - """ + """ + admin + superadmin + """ When I run `wp super-admin add superadmin` Then STDERR should contain: - """ - Warning: User superadmin already has super-admin capabilities. - """ + """ + Warning: User superadmin already has super-admin capabilities. + """ When I run `wp super-admin list` Then STDOUT should be: - """ - admin - superadmin - """ + """ + admin + superadmin + """ When I run `wp super-admin remove admin` And I run `wp super-admin list` Then STDOUT should be: - """ - superadmin - """ + """ + superadmin + """ From 55b23591b88c2f517948a2bb9285a2028b5b12cb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 16 Nov 2015 10:30:12 -0800 Subject: [PATCH 3834/4858] Suppress notices when using `is_readable()` If `open_basedir` is in effect, PHP will throw a notice when `is_readable()` is used on an unreadable directory. We _could_ have some more complicated check to see if the path being checked is within `open_basedir` defined paths, but checking the return value of `is_readable()` is sufficient for our needs. --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 22e3281a4f..7d1f9afad1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -142,7 +142,7 @@ function find_file_upward( $files, $dir = null, $stop_check = null ) { if ( is_null( $dir ) ) { $dir = getcwd(); } - while ( is_readable( $dir ) ) { + while ( @is_readable( $dir ) ) { // Stop walking up when the supplied callable returns true being passed the $dir if ( is_callable( $stop_check ) && call_user_func( $stop_check, $dir ) ) { return null; From 39bcee6f9a3bc270e1c8211e1c0070d5c7d34015 Mon Sep 17 00:00:00 2001 From: 2ndkauboy <bernhard@kau-boys.de> Date: Tue, 17 Nov 2015 18:05:13 +0100 Subject: [PATCH 3835/4858] prepend `all_items` label with `All `, as it is the default for CPTs --- templates/post_type.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index 68e0814b03..a86f731310 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -2,7 +2,7 @@ 'labels' => array( 'name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), 'singular_name' => __( '{{label_ucfirst}}', '{{textdomain}}' ), - 'all_items' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), + 'all_items' => __( 'All {{label_plural_ucfirst}}', '{{textdomain}}' ), 'new_item' => __( 'New {{label}}', '{{textdomain}}' ), 'add_new' => __( 'Add New', '{{textdomain}}' ), 'add_new_item' => __( 'Add New {{label}}', '{{textdomain}}' ), From 3d40b4a4f8a67634c0f4cbfd0bdc9f8ce654f162 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 17 Nov 2015 10:13:47 -0800 Subject: [PATCH 3836/4858] Make sure we download redirected version of nightly Otherwise, we'll just download the redirect --- templates/install-package-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-package-tests.sh b/templates/install-package-tests.sh index cbde91ef28..37fa695251 100644 --- a/templates/install-package-tests.sh +++ b/templates/install-package-tests.sh @@ -16,7 +16,7 @@ install_wp_cli() { # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR mkdir -p $WP_CLI_BIN_DIR - download https://github.com/wp-cli/builds/raw/gh-pages/phar/wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp + download https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp chmod +x $WP_CLI_BIN_DIR/wp } From a3f54a26d9a15cf91f7a6921ee3338591d60afc1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 06:06:51 -0800 Subject: [PATCH 3837/4858] Include more files in `wp-settings-cli.php` in prep for WP 4.4 See https://core.trac.wordpress.org/changeset/35718#file17 Also updates `Utils\maybe_require()` to handle `$wp_version` with `-src` in the value. --- php/utils-wp.php | 5 ++--- php/wp-settings-cli.php | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index 8501ce7ad4..934c324b56 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -56,10 +56,9 @@ function wp_redirect_handler( $url ) { } function maybe_require( $since, $path ) { - global $wp_version; - - if ( version_compare( $wp_version, $since, '>=' ) ) + if ( version_compare( str_replace( array( '-src' ), '', $GLOBALS['wp_version'] ), $since, '>=' ) ) { require $path; + } } function get_upgrader( $class ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 6a7f4b58e5..544f2cfb52 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -150,27 +150,41 @@ require( ABSPATH . WPINC . '/class-wp-ajax-response.php' ); require( ABSPATH . WPINC . '/formatting.php' ); require( ABSPATH . WPINC . '/capabilities.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-roles.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-role.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-user.php' ); require( ABSPATH . WPINC . '/query.php' ); Utils\maybe_require( '3.7-alpha-25139', ABSPATH . WPINC . '/date.php' ); require( ABSPATH . WPINC . '/theme.php' ); require( ABSPATH . WPINC . '/class-wp-theme.php' ); require( ABSPATH . WPINC . '/template.php' ); require( ABSPATH . WPINC . '/user.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-user-query.php' ); Utils\maybe_require( '4.0', ABSPATH . WPINC . '/session.php' ); require( ABSPATH . WPINC . '/meta.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-meta-query.php' ); require( ABSPATH . WPINC . '/general-template.php' ); require( ABSPATH . WPINC . '/link-template.php' ); require( ABSPATH . WPINC . '/author-template.php' ); require( ABSPATH . WPINC . '/post.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-page.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-page-dropdown.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-post.php' ); require( ABSPATH . WPINC . '/post-template.php' ); Utils\maybe_require( '3.6-alpha-23451', ABSPATH . WPINC . '/revision.php' ); Utils\maybe_require( '3.6-alpha-23451', ABSPATH . WPINC . '/post-formats.php' ); require( ABSPATH . WPINC . '/post-thumbnail-template.php' ); require( ABSPATH . WPINC . '/category.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-category.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-category-dropdown.php' ); require( ABSPATH . WPINC . '/category-template.php' ); require( ABSPATH . WPINC . '/comment.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-comment.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-comment-query.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-comment.php' ); require( ABSPATH . WPINC . '/comment-template.php' ); require( ABSPATH . WPINC . '/rewrite.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-rewrite.php' ); require( ABSPATH . WPINC . '/feed.php' ); require( ABSPATH . WPINC . '/bookmark.php' ); require( ABSPATH . WPINC . '/bookmark-template.php' ); @@ -179,20 +193,33 @@ require( ABSPATH . WPINC . '/deprecated.php' ); require( ABSPATH . WPINC . '/script-loader.php' ); require( ABSPATH . WPINC . '/taxonomy.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-term.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-tax-query.php' ); require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/embed.php' ); Utils\maybe_require( '3.5-alpha-22024', ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); -Utils\maybe_require( '4.4-alpha-34851', ABSPATH . WPINC . '/embed-functions.php' ); Utils\maybe_require( '4.4-alpha-34903', ABSPATH . WPINC . '/class-wp-oembed-controller.php' ); require( ABSPATH . WPINC . '/http.php' ); require_once( ABSPATH . WPINC . '/class-http.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-streams.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-curl.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-proxy.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-cookie.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-encoding.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-response.php' ); require( ABSPATH . WPINC . '/widgets.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-widget.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-widget-factory.php' ); require( ABSPATH . WPINC . '/nav-menu.php' ); require( ABSPATH . WPINC . '/nav-menu-template.php' ); require( ABSPATH . WPINC . '/admin-bar.php' ); Utils\maybe_require( '4.4-alpha-34928', ABSPATH . WPINC . '/rest-api.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/rest-api/class-wp-rest-server.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/rest-api/class-wp-rest-response.php' ); +Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/rest-api/class-wp-rest-request.php' ); // Load multisite-specific files. if ( is_multisite() ) { From 72d36c714ecc3050944824fdf447aa64a4af3fec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 07:09:36 -0800 Subject: [PATCH 3838/4858] Switch to git clone of trunk The nightly build is always later than we want it to be --- ci/prepare.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index a279e31585..b02a1e94e5 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -25,8 +25,8 @@ chmod +x $WP_CLI_BIN_DIR/wp if [[ $WP_VERSION == "trunk" ]] then - wget https://wordpress.org/nightly-builds/wordpress-latest.zip - unzip wordpress-latest.zip + git clone --depth 1 git@github.com:WordPress/WordPress.git wordpress + rm -rf wordpress/.git mv wordpress '/tmp/wp-cli-test core-download-cache/' else ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' From f4d5c98d5a12c2a06750bc9111598168326230e5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 07:28:20 -0800 Subject: [PATCH 3839/4858] Even easier: use the Github version of WP nightly --- ci/prepare.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index b02a1e94e5..6a9f00279c 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -25,9 +25,9 @@ chmod +x $WP_CLI_BIN_DIR/wp if [[ $WP_VERSION == "trunk" ]] then - git clone --depth 1 git@github.com:WordPress/WordPress.git wordpress - rm -rf wordpress/.git - mv wordpress '/tmp/wp-cli-test core-download-cache/' + wget https://github.com/WordPress/WordPress/archive/master.zip + unzip -q master.zip + mv WordPress-master '/tmp/wp-cli-test core-download-cache/' else ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' fi From deb0af97a525efacbe81dbba1309e5642bf2f16e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 07:54:06 -0800 Subject: [PATCH 3840/4858] Revert "Switch to git clone of trunk" Akismet isn't packaged with the Github version of WordPress This reverts commit 72d36c714ecc3050944824fdf447aa64a4af3fec. --- ci/prepare.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index 6a9f00279c..a279e31585 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -25,9 +25,9 @@ chmod +x $WP_CLI_BIN_DIR/wp if [[ $WP_VERSION == "trunk" ]] then - wget https://github.com/WordPress/WordPress/archive/master.zip - unzip -q master.zip - mv WordPress-master '/tmp/wp-cli-test core-download-cache/' + wget https://wordpress.org/nightly-builds/wordpress-latest.zip + unzip wordpress-latest.zip + mv wordpress '/tmp/wp-cli-test core-download-cache/' else ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' fi From c4ec8439183cdc0f25761cead532c487e817513e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 09:12:29 -0800 Subject: [PATCH 3841/4858] Failing test case for #1719 --- features/search-replace.feature | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index f684f9ed4d..f3f943f1b1 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -95,6 +95,30 @@ Feature: Do global search/replace world, Hello """ + Scenario: Search and replace within theme mods + Given a WP install + And a setup-theme-mod.php file: + """ + <?php + set_theme_mod( 'header_image_data', (object) array( 'url' => 'http://subdomain.example.com/foo.jpg' ) ); + """ + And I run `wp eval-file setup-theme-mod.php` + + When I run `wp theme mod get header_image_data` + Then STDOUT should be a table containing rows: + | key | value | + | header_image_data | {"url":"http:\/\/subdomain.example.com\/foo.jpg"} | + + When I run `wp search-replace subdomain.example.com example.com` + Then STDERR should be empty + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_options | option_value | 1 | PHP | + + When I run `wp theme mod get header_image_data` + Then STDOUT should be a table containing rows: + | key | value | + | header_image_data | {"url":"http:\/\/example.com\/foo.jpg"} | Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install From eff58d25b6b6252bcc9b5b512386831531d1786c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 09:18:07 -0800 Subject: [PATCH 3842/4858] Recurse objects by default when replacing inside of serialized data However, if `--no-recurse-objects` is provided, respect that flag too. --- features/search-replace.feature | 6 +++++- php/commands/search-replace.php | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index f3f943f1b1..fce6723615 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -109,8 +109,12 @@ Feature: Do global search/replace | key | value | | header_image_data | {"url":"http:\/\/subdomain.example.com\/foo.jpg"} | + When I run `wp search-replace subdomain.example.com example.com --no-recurse-objects` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_options | option_value | 0 | PHP | + When I run `wp search-replace subdomain.example.com example.com` - Then STDERR should be empty Then STDOUT should be a table containing rows: | Table | Column | Replacements | Type | | wp_options | option_value | 1 | PHP | diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f3c1b2f001..c23d72c26a 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -118,6 +118,9 @@ public function __invoke( $args, $assoc_args ) { if ( $php_only || $regex || NULL !== $serialRow ) { $type = 'PHP'; + if ( ! empty( $serialRow ) && null === $recurse_objects ) { + $recurse_objects = true; + } $count = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ); } else { $type = 'SQL'; From a6ce33e5d13893c8574243bedb2157432f6803f8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 10:18:11 -0800 Subject: [PATCH 3843/4858] Actually default to recursing objects in a bc way We shouldn't blindly recurse objects *just* when we've detected serialized data. --- php/commands/search-replace.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c23d72c26a..ed491cbd76 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -74,7 +74,7 @@ public function __invoke( $args, $assoc_args ) { $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' ); + $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' ); @@ -118,9 +118,6 @@ public function __invoke( $args, $assoc_args ) { if ( $php_only || $regex || NULL !== $serialRow ) { $type = 'PHP'; - if ( ! empty( $serialRow ) && null === $recurse_objects ) { - $recurse_objects = true; - } $count = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ); } else { $type = 'SQL'; From 72499dac5f7193668e75d3b1e816494d532b5d10 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 20 Nov 2015 10:21:56 -0800 Subject: [PATCH 3844/4858] Clarify default behavior for `--recurse-objects` --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index ed491cbd76..8d7e5373f4 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -43,7 +43,7 @@ class Search_Replace_Command extends WP_CLI_Command { * : 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 + * : 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 From bbba16dc24b53f3a5a9992edfdb80e9d0f614c05 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 05:14:27 -0800 Subject: [PATCH 3845/4858] Failing test case for #1613 --- features/search-replace.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index fce6723615..99d174240a 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -124,6 +124,29 @@ Feature: Do global search/replace | key | value | | header_image_data | {"url":"http:\/\/example.com\/foo.jpg"} | + Scenario: Search and replace with quoted strings + Given a WP install + + When I run `wp post create --post_content='<a href="http://apple.com">Apple</a>' --porcelain` + Then save STDOUT as {POST_ID} + + When I run `wp post get {POST_ID} --field=content` + Then STDOUT should be: + """ + <a href="http://apple.com">Apple</a> + """ + + When I run `wp search-replace '<a href="http://apple.com">Apple</a>' '<a href="http://google.com">Google</a>'` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_posts | post_content | 1 | PHP | + + When I run `wp post get {POST_ID} --field=content` + Then STDOUT should be: + """ + <a href="http://google.com">Google</a> + """ + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install And I run `wp option get siteurl` From 02755f06851a85afeed68a2058b4e6816700a0ff Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 05:29:06 -0800 Subject: [PATCH 3846/4858] Correct test to specify `SQL` --- features/search-replace.feature | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 99d174240a..65d135a618 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -136,10 +136,15 @@ Feature: Do global search/replace <a href="http://apple.com">Apple</a> """ + When I run `wp search-replace '<a href="http://apple.com">Apple</a>' '<a href="http://google.com">Google</a>' --dry-run` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_posts | post_content | 1 | SQL | + When I run `wp search-replace '<a href="http://apple.com">Apple</a>' '<a href="http://google.com">Google</a>'` Then STDOUT should be a table containing rows: | Table | Column | Replacements | Type | - | wp_posts | post_content | 1 | PHP | + | wp_posts | post_content | 1 | SQL | When I run `wp post get {POST_ID} --field=content` Then STDOUT should be: From 23e40059b2d35ff9d3a370e01d5480a0967736bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 05:29:50 -0800 Subject: [PATCH 3847/4858] Properly prepare value passed to search / replace Ensures quotes, etc. are properly escaped --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 8d7e5373f4..0022419a58 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -237,7 +237,7 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $args = array( 'table' => $table, 'fields' => $fields, - 'where' => $regex ? '' : "`$col`" . ' LIKE "%' . self::esc_like( $old ) . '%"', + 'where' => $regex ? '' : "`$col`" . $wpdb->prepare( ' LIKE %s', '%' . self::esc_like( $old ) . '%' ), 'chunk_size' => $chunk_size ); From da293006e6d9a1ab0b18eaace11f0e3846278c87 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 05:34:40 -0800 Subject: [PATCH 3848/4858] Break out `wp post generate` tests to `features/post-generate.feature` --- features/post-generate.feature | 33 +++++++++++++++++++++++++++++++++ features/post.feature | 29 ----------------------------- 2 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 features/post-generate.feature diff --git a/features/post-generate.feature b/features/post-generate.feature new file mode 100644 index 0000000000..9a3e039c53 --- /dev/null +++ b/features/post-generate.feature @@ -0,0 +1,33 @@ +Feature: Generate new WordPress posts + + Background: + Given a WP install + + Scenario: Generating posts + When I run `echo "Content generated by wp post generate" | wp post generate --count=1 --post_content` + And I run `wp post list --field=post_content` + Then STDOUT should contain: + """ + Content generated by wp post generate + """ + And STDERR should be empty + + Scenario: Generating posts by a specific author + + When I run `wp user create dummyuser dummy@example.com --porcelain` + Then save STDOUT as {AUTHOR_ID} + + When I run `wp post generate --post_author={AUTHOR_ID} --post_type=post --count=16` + And I run `wp post list --post_type=post --author={AUTHOR_ID} --format=count` + Then STDOUT should contain: + """ + 16 + """ + + Scenario: Generating pages + When I run `wp post generate --post_type=page --max_depth=10` + And I run `wp post list --post_type=page --field=post_parent` + Then STDOUT should contain: + """ + 1 + """ diff --git a/features/post.feature b/features/post.feature index 31d9093061..d9e5e07933 100644 --- a/features/post.feature +++ b/features/post.feature @@ -188,35 +188,6 @@ Feature: Manage WordPress posts Sample Page """ - Scenario: Generating posts - When I run `echo "Content generated by wp post generate" | wp post generate --count=1 --post_content` - And I run `wp post list --field=post_content` - Then STDOUT should contain: - """ - Content generated by wp post generate - """ - And STDERR should be empty - - Scenario: Generating posts by a specific author - - When I run `wp user create dummyuser dummy@example.com --porcelain` - Then save STDOUT as {AUTHOR_ID} - - When I run `wp post generate --post_author={AUTHOR_ID} --post_type=post --count=16` - And I run `wp post list --post_type=post --author={AUTHOR_ID} --format=count` - Then STDOUT should contain: - """ - 16 - """ - - Scenario: Generating pages - When I run `wp post generate --post_type=page --max_depth=10` - And I run `wp post list --post_type=page --field=post_parent` - Then STDOUT should contain: - """ - 1 - """ - Scenario: Update categories on a post When I run `wp term create category "Test Category" --porcelain` Then save STDOUT as {TERM_ID} From cb455dfc2c2c865d8c01e1fe1e51a00e0e4ffbc2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 09:01:07 -0800 Subject: [PATCH 3849/4858] Support wildcards / globs in table names with `wp search-replace` --- features/search-replace.feature | 72 +++++++++++++++++++++++++++++++++ php/commands/search-replace.php | 45 ++++++++++++++++++++- 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 65d135a618..4120480561 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -57,6 +57,78 @@ Feature: Do global search/replace awesome_table """ + @daniel + Scenario: Run on all tables matching string with wildcard + Given a WP install + + When I run `wp option set bar foo` + And I run `wp option get bar` + Then STDOUT should be: + """ + foo + """ + + When I run `wp post create --post_title=bar --porcelain` + Then save STDOUT as {POST_ID} + + When I run `wp post meta add {POST_ID} foo bar` + Then STDOUT should not be empty + + When I run `wp search-replace bar burrito wp_post\?` + And STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_posts | post_title | 1 | SQL | + And STDOUT should not contain: + """ + wp_options + """ + + When I run `wp post get {POST_ID} --field=title` + Then STDOUT should be: + """ + burrito + """ + + When I run `wp post meta get {POST_ID} foo` + Then STDOUT should be: + """ + bar + """ + + When I run `wp option get bar` + Then STDOUT should be: + """ + foo + """ + + When I try `wp search-replace foo burrito wp_opt\*on` + Then STDERR should be: + """ + Error: Couldn't find any tables matching: wp_opt*on + """ + + When I run `wp search-replace foo burrito wp_opt\* wp_postme\*` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_options | option_value | 1 | PHP | + | wp_postmeta | meta_key | 1 | SQL | + And STDOUT should not contain: + """ + wp_posts + """ + + When I run `wp option get bar` + Then STDOUT should be: + """ + burrito + """ + + When I run `wp post meta get {POST_ID} burrito` + Then STDOUT should be: + """ + bar + """ + Scenario: Quiet search/replace Given a WP install diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0022419a58..47926894a7 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -28,7 +28,7 @@ class Search_Replace_Command extends WP_CLI_Command { * : The new string. * * [<table>...] - * : List of database tables to restrict the replacement to. + * : 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. @@ -64,7 +64,7 @@ class Search_Replace_Command extends WP_CLI_Command { * 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 search-replace --url=example.com example.com example.dev wp_\*_options */ public function __invoke( $args, $assoc_args ) { global $wpdb; @@ -95,6 +95,22 @@ public function __invoke( $args, $assoc_args ) { $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 ) { @@ -295,6 +311,31 @@ private static function get_columns( $table ) { return array( $primary_keys, $columns ); } + /** + * Get all the tables that match a glob pattern + * + * @param string $glob + * @return array + */ + private static function get_tables_for_glob( $glob ) { + + static $all_tables = array(); + + if ( ! $all_tables ) { + $all_tables = self::get_table_list( 'all-tables' ); + } + + $tables = array(); + + foreach ( $all_tables as $table) { + if ( fnmatch( $glob, $table ) ) { + $tables[] = $table; + } + } + + return $tables; + } + private static function is_text_col( $type ) { foreach ( array( 'text', 'varchar' ) as $token ) { if ( false !== strpos( $type, $token ) ) From cc0b05db6223fd90a6d765227fdfb75e147ccfa1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 09:09:45 -0800 Subject: [PATCH 3850/4858] In `wp import`, use `WP_CLI::log()` instead of `WP_CLI::line()` The former gives us more control over verbosity. --- php/commands/import.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index 815d137dfe..40b9c31bf6 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -57,7 +57,7 @@ public function __invoke( $args, $assoc_args ) { if ( is_wp_error( $ret ) ) { WP_CLI::error( $ret ); } else { - WP_CLI::line(); // WXR import ends with HTML, so make sure message is on next line + WP_CLI::log(''); // WXR import ends with HTML, so make sure message is on next line WP_CLI::success( "Finished importing from $file file." ); } } @@ -170,11 +170,11 @@ private function add_wxr_filters() { global $wpcli_import_counts; $wpcli_import_counts['current_post']++; - WP_CLI::line(); - WP_CLI::line(); - WP_CLI::line( sprintf( 'Processing post #%d ("%s") (post_type: %s)', $post['post_id'], $post['post_title'], $post['post_type'] ) ); - WP_CLI::line( sprintf( '-- %s of %s', number_format( $wpcli_import_counts['current_post'] ), number_format( $wpcli_import_counts['total_posts'] ) ) ); - WP_CLI::line( '-- ' . date( 'r' ) ); + WP_CLI::log(''); + WP_CLI::log(''); + WP_CLI::log( sprintf( 'Processing post #%d ("%s") (post_type: %s)', $post['post_id'], $post['post_title'], $post['post_type'] ) ); + WP_CLI::log( sprintf( '-- %s of %s', number_format( $wpcli_import_counts['current_post'] ), number_format( $wpcli_import_counts['total_posts'] ) ) ); + WP_CLI::log( '-- ' . date( 'r' ) ); return $post; } ); @@ -184,32 +184,32 @@ private function add_wxr_filters() { if ( is_wp_error( $post_id ) ) { WP_CLI::warning( "-- Error importing post: " . $post_id->get_error_code() ); } else { - WP_CLI::line( "-- Imported post as post_id #{$post_id}" ); + WP_CLI::log( "-- Imported post as post_id #{$post_id}" ); } if ( $wpcli_import_counts['current_post'] % 500 === 0 ) { WP_CLI\Utils\wp_clear_object_cache(); - WP_CLI::line( "-- Cleared object cache." ); + WP_CLI::log( "-- Cleared object cache." ); } }, 10, 4 ); add_action( 'wp_import_insert_term', function( $t, $import_term, $post_id, $post ) { - WP_CLI::line( "-- Created term \"{$import_term['name']}\"" ); + WP_CLI::log( "-- Created term \"{$import_term['name']}\"" ); }, 10, 4 ); add_action( 'wp_import_set_post_terms', function( $tt_ids, $term_ids, $taxonomy, $post_id, $post ) { - WP_CLI::line( "-- Added terms (" . implode( ',', $term_ids ) .") for taxonomy \"{$taxonomy}\"" ); + WP_CLI::log( "-- Added terms (" . implode( ',', $term_ids ) .") for taxonomy \"{$taxonomy}\"" ); }, 10, 5 ); add_action( 'wp_import_insert_comment', function( $comment_id, $comment, $comment_post_ID, $post ) { global $wpcli_import_counts; $wpcli_import_counts['current_comment']++; - WP_CLI::line( sprintf( '-- Added comment #%d (%s of %s)', $comment_id, number_format( $wpcli_import_counts['current_comment'] ), number_format( $wpcli_import_counts['total_comments'] ) ) ); + WP_CLI::log( sprintf( '-- Added comment #%d (%s of %s)', $comment_id, number_format( $wpcli_import_counts['current_comment'] ), number_format( $wpcli_import_counts['total_comments'] ) ) ); }, 10, 4 ); add_action( 'import_post_meta', function( $post_id, $key, $value ) { - WP_CLI::line( "-- Added post_meta $key" ); + WP_CLI::log( "-- Added post_meta $key" ); }, 10, 3 ); } From c95e1e60f381f7d5249470a10b5d15dcc4422f5a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 09:28:28 -0800 Subject: [PATCH 3851/4858] Bail early on search-replace when terms are the same Let's help save developers from themselves. --- features/search-replace.feature | 10 ++++++++++ php/commands/search-replace.php | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index 65d135a618..9c0240136d 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -152,6 +152,16 @@ Feature: Do global search/replace <a href="http://google.com">Google</a> """ + Scenario: Search and replace with the same terms + Given a WP install + + When I run `wp search-replace foo foo` + Then STDERR should be: + """ + Warning: Replacement value 'foo' is identical to search value 'foo'. Skipping operation. + """ + And STDOUT should be empty + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install And I run `wp option get siteurl` diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0022419a58..12407c9616 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -80,6 +80,11 @@ public function __invoke( $args, $assoc_args ) { $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'; From dc5d690a5df0591ab9308f763749517fdbbcc10c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 09:34:49 -0800 Subject: [PATCH 3852/4858] Abstract cache type to helper utility --- php/commands/cache.php | 42 +-------------------------------- php/utils-wp.php | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/php/commands/cache.php b/php/commands/cache.php index 6fe77130db..51df60802a 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -230,47 +230,7 @@ public function set( $args, $assoc_args ) { * problems with this function's ability to determine which object cache is being used. */ public function type( $args, $assoc_args ) { - global $_wp_using_ext_object_cache, $wp_object_cache; - - if ( false !== $_wp_using_ext_object_cache ) { - // Test for Memcached PECL extension memcached object cache (https://github.com/tollmanz/wordpress-memcached-backend) - if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) { - $message = 'Memcached'; - - // Test for Memcache PECL extension memcached object cache (http://wordpress.org/extend/plugins/memcached/) - } elseif ( isset( $wp_object_cache->mc ) ) { - $is_memcache = true; - foreach ( $wp_object_cache->mc as $bucket ) { - if ( ! is_a( $bucket, 'Memcache' ) ) - $is_memcache = false; - } - - if ( $is_memcache ) - $message = 'Memcache'; - - // Test for Xcache object cache (http://plugins.svn.wordpress.org/xcache/trunk/object-cache.php) - } elseif ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) { - $message = 'Xcache'; - - // Test for WinCache object cache (http://wordpress.org/extend/plugins/wincache-object-cache-backend/) - } elseif ( class_exists( 'WinCache_Object_Cache' ) ) { - $message = 'WinCache'; - - // Test for APC object cache (http://wordpress.org/extend/plugins/apc/) - } elseif ( class_exists( 'APC_Object_Cache' ) ) { - $message = 'APC'; - - // Test for Redis Object Cache (https://github.com/alleyinteractive/wp-redis) - } elseif ( isset( $wp_object_cache->redis ) && is_a( $wp_object_cache->redis, 'Redis' ) ) { - $message = 'Redis'; - - } else { - $message = 'Unknown'; - } - } else { - $message = 'Default'; - } - + $message = WP_CLI\Utils\wp_get_cache_type(); WP_CLI::line( $message ); } } diff --git a/php/utils-wp.php b/php/utils-wp.php index 934c324b56..5d2c82d0fe 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -131,6 +131,59 @@ function wp_register_unused_sidebar() { } +/** + * Attempts to determine which object cache is being used. + * + * Note that the guesses made by this function are based on the WP_Object_Cache classes + * that define the 3rd party object cache extension. Changes to those classes could render + * problems with this function's ability to determine which object cache is being used. + * + * @return string + */ +function wp_get_cache_type() { + global $_wp_using_ext_object_cache, $wp_object_cache; + + if ( ! empty( $_wp_using_ext_object_cache ) ) { + // Test for Memcached PECL extension memcached object cache (https://github.com/tollmanz/wordpress-memcached-backend) + if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) { + $message = 'Memcached'; + + // Test for Memcache PECL extension memcached object cache (http://wordpress.org/extend/plugins/memcached/) + } elseif ( isset( $wp_object_cache->mc ) ) { + $is_memcache = true; + foreach ( $wp_object_cache->mc as $bucket ) { + if ( ! is_a( $bucket, 'Memcache' ) ) + $is_memcache = false; + } + + if ( $is_memcache ) + $message = 'Memcache'; + + // Test for Xcache object cache (http://plugins.svn.wordpress.org/xcache/trunk/object-cache.php) + } elseif ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) { + $message = 'Xcache'; + + // Test for WinCache object cache (http://wordpress.org/extend/plugins/wincache-object-cache-backend/) + } elseif ( class_exists( 'WinCache_Object_Cache' ) ) { + $message = 'WinCache'; + + // Test for APC object cache (http://wordpress.org/extend/plugins/apc/) + } elseif ( class_exists( 'APC_Object_Cache' ) ) { + $message = 'APC'; + + // Test for Redis Object Cache (https://github.com/alleyinteractive/wp-redis) + } elseif ( isset( $wp_object_cache->redis ) && is_a( $wp_object_cache->redis, 'Redis' ) ) { + $message = 'Redis'; + + } else { + $message = 'Unknown'; + } + } else { + $message = 'Default'; + } + return $message; +} + /** * Clear all of the caches for memory management */ From 880c66699ee8bc0eeb27b81074e647bd122b114f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 09:39:00 -0800 Subject: [PATCH 3853/4858] Let users know to flush their persistent object cache after s/r --- php/commands/search-replace.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0022419a58..590bb495be 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -138,7 +138,11 @@ public function __invoke( $args, $assoc_args ) { $table->display(); if ( ! $dry_run ) { - WP_CLI::success( "Made $total replacements." ); + $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 ); } } From f1be82a47708dcfc36ead84ee88865b1c9bef022 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 10:00:36 -0800 Subject: [PATCH 3854/4858] Introduce `wp_version_compare()` for comparing WP versions Tagged WordPress releases include `-src` in `$wp_version`, which `version_compare()` doesn't like. We need to make sure to strip it to get an accurate result. --- php/commands/core.php | 8 ++++---- php/commands/cron.php | 3 +-- php/commands/taxonomy.php | 3 +-- php/commands/user.php | 6 ++---- php/utils-wp.php | 6 +++++- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 3520bf7c04..531866b64a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -64,7 +64,7 @@ function check_update( $_, $assoc_args ) { foreach ( $release_versions as $release_version ) { // don't list earliers versions - if ( version_compare( $release_version, $wp_version, '<=' ) ) + if ( \WP_CLI\Utils\wp_version_compare( $release_version, '>=' ) ) continue; $release_parts = explode( '.', $release_version ); @@ -385,7 +385,7 @@ public function config( $_, $assoc_args ) { 'https://api.wordpress.org/secret-key/1.1/salt/' ); } - if ( version_compare( $wp_version, '4.0', '<' ) ) { + if ( \WP_CLI\Utils\wp_version_compare( '4.0', '<' ) ) { $assoc_args['add-wplang'] = true; } else { $assoc_args['add-wplang'] = false; @@ -945,7 +945,7 @@ function update( $args, $assoc_args ) { list( $update ) = $from_api->updates; } - } else if ( version_compare( $wp_version, $assoc_args['version'], '<' ) + } else if ( \WP_CLI\Utils\wp_version_compare( $assoc_args['version'], '<' ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) { $version = $assoc_args['version']; @@ -1115,7 +1115,7 @@ class Core_Language_Command extends WP_CLI\CommandWithTranslation { WP_CLI::add_command( 'core language', 'Core_Language_Command', array( 'before_invoke' => function() { - if ( version_compare( $GLOBALS['wp_version'], '4.0', '<' ) ) { + if ( \WP_CLI\Utils\wp_version_compare( '4.0', '<' ) ) { WP_CLI::error( "Requires WordPress 4.0 or greater." ); } }) diff --git a/php/commands/cron.php b/php/commands/cron.php index 7025c26b2b..9dacd26563 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -509,9 +509,8 @@ public function test() { * @return WP_Error|array The response or WP_Error on failure. */ protected static function get_cron_spawn() { - global $wp_version; - $sslverify = version_compare( $wp_version, 4.0, '<' ); + $sslverify = \WP_CLI\Utils\wp_version_compare( 4.0, '<' ); $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); $cron_request = apply_filters( 'cron_request', array( diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index be26a0f163..7d34abe7e4 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -17,9 +17,8 @@ class Taxonomy_Command extends WP_CLI_Command { ); public function __construct() { - global $wp_version; - if ( version_compare( $wp_version, 3.7, '<' ) ) { + if ( \WP_CLI\Utils\wp_version_compare( 3.7, '<' ) ) { // remove description for wp <= 3.7 $this->fields = array_values( array_diff( $this->fields, array( 'description' ) ) ); } diff --git a/php/commands/user.php b/php/commands/user.php index 4d11b1bdb9..d3fd69bb98 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -770,11 +770,9 @@ private static function validate_role( $role ) { * @param string $password */ private static function wp_new_user_notification( $user_id, $password ) { - global $wp_version; - $version = str_replace( '-src', '', $wp_version ); - if ( version_compare( $version, '4.3.1', '>=' ) ) { + if ( \WP_CLI\Utils\wp_version_compare( '4.3.1', '>=' ) ) { wp_new_user_notification( $user_id, null, 'both' ); - } else if ( version_compare( $version, '4.3', '>=' ) ) { + } else if ( \WP_CLI\Utils\wp_version_compare( '4.3', '>=' ) ) { wp_new_user_notification( $user_id, 'both' ); } else { wp_new_user_notification( $user_id, $password ); diff --git a/php/utils-wp.php b/php/utils-wp.php index 934c324b56..a7414f42e2 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -56,11 +56,15 @@ function wp_redirect_handler( $url ) { } function maybe_require( $since, $path ) { - if ( version_compare( str_replace( array( '-src' ), '', $GLOBALS['wp_version'] ), $since, '>=' ) ) { + if ( wp_version_compare( $since, '>=' ) ) { require $path; } } +function wp_version_compare( $since, $operator ) { + return version_compare( str_replace( array( '-src' ), '', $GLOBALS['wp_version'] ), $since, $operator ); +} + function get_upgrader( $class ) { if ( !class_exists( '\WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; From 59d2ca9c76e579e4fe0a4c9387f610b889b61a32 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 10:52:07 -0800 Subject: [PATCH 3855/4858] Ensure `upload_space_check_disabled=>1` when installing multisite Because of how core executes `populate_network()`, this option is erroneously set to an empty value when WP-CLI installs multisite. The correct behavior is to disable multisite quotas by default on new installs. See https://core.trac.wordpress.org/ticket/21513 --- features/core.feature | 12 ++++++++++++ php/commands/core.php | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/features/core.feature b/features/core.feature index bdedea78af..c9d18e77bd 100644 --- a/features/core.feature +++ b/features/core.feature @@ -242,6 +242,12 @@ Feature: Manage WordPress installation When I try `wp core install-network --title='test network'` Then the return code should be 1 + When I run `wp network meta get 1 upload_space_check_disabled` + Then STDOUT should be: + """ + 1 + """ + Scenario: Install multisite from scratch Given an empty directory And WP files @@ -261,6 +267,12 @@ Feature: Manage WordPress installation When I try `wp core multisite-install --url=foobar.org --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` Then the return code should be 0 + When I run `wp network meta get 1 upload_space_check_disabled` + Then STDOUT should be: + """ + 1 + """ + Scenario: Install multisite from scratch, with MULTISITE already set in wp-config.php Given a WP multisite install And I run `wp db reset --yes` diff --git a/php/commands/core.php b/php/commands/core.php index 3520bf7c04..37eb975ecb 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -663,6 +663,10 @@ private function _multisite_convert( $assoc_args ) { } } + // delete_site_option() cleans the alloptions cache to prevent dupe option + delete_site_option( 'upload_space_check_disabled' ); + update_site_option( 'upload_space_check_disabled', 1 ); + if ( !is_multisite() ) { $subdomain_export = Utils\get_flag_value( $assoc_args, 'subdomains' ) ? 'true' : 'false'; $ms_config = <<<EOT From 03de8042351530cdfc2e40f01432d0718fc34cc9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 12:18:28 -0800 Subject: [PATCH 3856/4858] Provide a more helpful message when image regeneration fails If only a single image was regenerated, the message will be: > An error occurred with image regeneration. If multiple images were regenerated, the message will be: > An error occurred regenerating one or more images. --- php/commands/media.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index e2f4599439..9d9ff7a536 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -57,14 +57,21 @@ function regenerate( $args, $assoc_args = array() ) { WP_CLI::log( sprintf( 'Found %1$d %2$s to regenerate.', $count, _n( 'image', 'images', $count ) ) ); + $errored = false; foreach ( $images->posts as $id ) { - $this->_process_regeneration( $id, $skip_delete ); + if ( ! $this->_process_regeneration( $id, $skip_delete ) ) { + $errored = true; + } } - WP_CLI::success( sprintf( - 'Finished regenerating %1$s.', - _n('the image', 'all images', $count) - ) ); + if ( $errored ) { + WP_CLI::log( _n( 'An error occurred with image regeneration.', 'An error occurred regenerating one or more images.', $count ) ); + } else { + WP_CLI::success( sprintf( + 'Finished regenerating %1$s.', + _n('the image', 'all images', $count) + ) ); + } } /** @@ -211,7 +218,7 @@ private function _process_regeneration( $id, $skip_delete = false ) { if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { WP_CLI::warning( "Can't find $att_desc" ); - return; + return false; } if ( ! $skip_delete ) { @@ -221,18 +228,18 @@ private function _process_regeneration( $id, $skip_delete = false ) { $metadata = wp_generate_attachment_metadata( $id, $fullsizepath ); if ( is_wp_error( $metadata ) ) { WP_CLI::warning( $metadata->get_error_message() ); - return; + return false; } if ( empty( $metadata ) ) { WP_CLI::warning( "Couldn't regenerate thumbnails for $att_desc." ); - return; + return false; } wp_update_attachment_metadata( $id, $metadata ); WP_CLI::log( "Regenerated thumbnails for $att_desc" ); - + return true; } private function remove_old_images( $att_id ) { From 3d527829fc020354dc51fc277e1edfd976adc8d3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 12:26:19 -0800 Subject: [PATCH 3857/4858] Add tests for error state --- features/media.feature | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/features/media.feature b/features/media.feature index d0d0207a5b..c753624e27 100644 --- a/features/media.feature +++ b/features/media.feature @@ -79,7 +79,10 @@ Feature: Manage WordPress attachments }); """ When I run `wp media regenerate --yes` - Then STDOUT should not be empty + Then STDOUT should contain: + """ + Success: Finished regenerating the image. + """ And the wp-content/uploads/large-image-100x100.jpg file should not exist And the wp-content/uploads/large-image-200x200.jpg file should exist @@ -108,7 +111,39 @@ Feature: Manage WordPress attachments }); """ When I run `wp media regenerate --skip-delete --yes` - Then STDOUT should not be empty + Then STDOUT should contain: + """ + Success: Finished regenerating the image. + """ And the wp-content/uploads/large-image-100x100.jpg file should exist And the wp-content/uploads/large-image-200x200.jpg file should exist + Scenario: Provide helpful error messages when media can't be regenerated + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + And a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 100, 100, true ); + }); + """ + And I run `wp option update uploads_use_yearmonth_folders 0` + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + And the wp-content/uploads/large-image-100x100.jpg file should exist + + When I run `rm wp-content/uploads/large-image.jpg` + Then STDOUT should be empty + + When I run `wp media regenerate --yes` + Then STDOUT should contain: + """ + An error occurred with image regeneration. + """ + And STDERR should contain: + """ + Warning: Can't find + """ From 9b891d82a9f03519c086fd4bee9062630ecfe731 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 Nov 2015 14:05:22 -0800 Subject: [PATCH 3858/4858] Move `wp_version_compare()` to `utils.php`, so it's aways available --- php/utils-wp.php | 4 ---- php/utils.php | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index e39cd11de6..e3519af487 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -61,10 +61,6 @@ function maybe_require( $since, $path ) { } } -function wp_version_compare( $since, $operator ) { - return version_compare( str_replace( array( '-src' ), '', $GLOBALS['wp_version'] ), $since, $operator ); -} - function get_upgrader( $class ) { if ( !class_exists( '\WP_Upgrader' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; diff --git a/php/utils.php b/php/utils.php index 7d1f9afad1..69ad1c355e 100644 --- a/php/utils.php +++ b/php/utils.php @@ -234,6 +234,10 @@ function locate_wp_config() { return $path; } +function wp_version_compare( $since, $operator ) { + return version_compare( str_replace( array( '-src' ), '', $GLOBALS['wp_version'] ), $since, $operator ); +} + /** * Output items in a table, JSON, CSV, ids, or the total count * From f9e61c1373a1e07bc5319293c5683993875c79a7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 24 Nov 2015 12:25:46 -0800 Subject: [PATCH 3859/4858] Indicate execution time when running search/replace with `--verbose` ``` Checking: wp_users.user_email 0 rows affected (0.002s) Checking: wp_users.user_url 0 rows affected (0.001s) Checking: wp_users.user_activation_key 0 rows affected (0.001s) Checking: wp_users.display_name 0 rows affected (0.002s) ``` This can be helpful for better understanding where bottlenecks are --- php/commands/search-replace.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 3059aa8ffa..39c4299006 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -239,13 +239,20 @@ private static function get_table_list( $limit_to ) { private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) { global $wpdb; + if ( $verbose ) { + $time = microtime( true ); + WP_CLI::log( sprintf( 'Checking: %s.%s', $table, $col ) ); + } + if ( $dry_run ) { $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); } else { $count = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } + if ( $verbose ) { - self::log_verbose_details( $table, $col, $count ); + $time = round( microtime( true ) - $time, 3 ); + WP_CLI::log( sprintf( '%d rows affected (%ss)', $count, $time ) ); } return $count; } @@ -259,6 +266,11 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $fields = $primary_keys; $fields[] = $col; + if ( $verbose ) { + $time = microtime( true ); + WP_CLI::log( sprintf( 'Checking: %s.%s', $table, $col ) ); + } + $args = array( 'table' => $table, 'fields' => $fields, @@ -292,7 +304,8 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, } if ( $verbose ) { - self::log_verbose_details( $table, $col, $count ); + $time = round( microtime( true ) - $time, 3 ); + WP_CLI::log( sprintf( '%d rows affected (%ss)', $count, $time ) ); } return $count; @@ -369,10 +382,6 @@ private static function esc_like( $old ) { return $old; } - private static function log_verbose_details( $table, $col, $count ) { - WP_CLI::log( sprintf( 'Checking: %s.%s' . PHP_EOL . '%d rows affected', $table, $col, $count ) ); - } - } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); From 354d4f4e412237894da8f4fcd1cd6451d82b3a77 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 24 Nov 2015 12:37:10 -0800 Subject: [PATCH 3860/4858] Globalize `$wp_version` in a couple places we need it as a global --- php/commands/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 08450fa4c1..b4ee483c6f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -34,6 +34,7 @@ class Core_Command extends WP_CLI_Command { * @subcommand check-update */ function check_update( $_, $assoc_args ) { + global $wp_version; $versions_path = ABSPATH . 'wp-includes/version.php'; include $versions_path; @@ -345,6 +346,7 @@ private static function get_initial_locale() { * PHP */ public function config( $_, $assoc_args ) { + global $wp_version; if ( Utils\locate_wp_config() ) { WP_CLI::error( "The 'wp-config.php' file already exists." ); } From 1feb73e9ad1cd84efd5250f1c9d057e6c77b08bc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 24 Nov 2015 15:03:03 -0800 Subject: [PATCH 3861/4858] Start time tracking earlier, to get serialization check --- php/commands/search-replace.php | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 39c4299006..76e1c2f21e 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -133,16 +133,21 @@ public function __invoke( $args, $assoc_args ) { 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 = self::php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ); + $count = $this->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 ); + $count = $this->sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ); } $report[] = array( $table, $col, $count, $type ); @@ -236,14 +241,9 @@ private static function get_table_list( $limit_to ) { } - private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) { + private function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) { global $wpdb; - if ( $verbose ) { - $time = microtime( true ); - WP_CLI::log( sprintf( 'Checking: %s.%s', $table, $col ) ); - } - if ( $dry_run ) { $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); } else { @@ -251,13 +251,13 @@ private static function sql_handle_col( $col, $table, $old, $new, $dry_run, $ver } if ( $verbose ) { - $time = round( microtime( true ) - $time, 3 ); + $time = round( microtime( true ) - $this->start_time, 3 ); WP_CLI::log( sprintf( '%d rows affected (%ss)', $count, $time ) ); } return $count; } - private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ) { + private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite @@ -266,11 +266,6 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, $fields = $primary_keys; $fields[] = $col; - if ( $verbose ) { - $time = microtime( true ); - WP_CLI::log( sprintf( 'Checking: %s.%s', $table, $col ) ); - } - $args = array( 'table' => $table, 'fields' => $fields, @@ -304,7 +299,7 @@ private static function php_handle_col( $col, $primary_keys, $table, $old, $new, } if ( $verbose ) { - $time = round( microtime( true ) - $time, 3 ); + $time = round( microtime( true ) - $this->start_time, 3 ); WP_CLI::log( sprintf( '%d rows affected (%ss)', $count, $time ) ); } From 995ea29c1393a48ee57c7916911b023a848944af Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 24 Nov 2015 15:04:22 -0800 Subject: [PATCH 3862/4858] Clarify what this means --- php/commands/search-replace.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 76e1c2f21e..6777eb57c9 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -252,7 +252,7 @@ private function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) if ( $verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d rows affected (%ss)', $count, $time ) ); + WP_CLI::log( sprintf( '%d rows affected (in %ss)', $count, $time ) ); } return $count; } @@ -300,7 +300,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r if ( $verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d rows affected (%ss)', $count, $time ) ); + WP_CLI::log( sprintf( '%d rows affected (in %ss)', $count, $time ) ); } return $count; From 0bf3a5771f8bd9d7c37bea54fba4ad3b480d9c7d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 24 Nov 2015 15:05:10 -0800 Subject: [PATCH 3863/4858] Clarify type too --- php/commands/search-replace.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 6777eb57c9..7fb2592779 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -252,7 +252,7 @@ private function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) if ( $verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d rows affected (in %ss)', $count, $time ) ); + WP_CLI::log( sprintf( '%d rows affected using SQL (in %ss)', $count, $time ) ); } return $count; } @@ -300,7 +300,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r if ( $verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d rows affected (in %ss)', $count, $time ) ); + WP_CLI::log( sprintf( '%d rows affected using PHP (in %ss)', $count, $time ) ); } return $count; From 70cf30bd4e954d496cfe8e5c572fa97483974372 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 24 Nov 2015 17:54:32 -0800 Subject: [PATCH 3864/4858] Prevent unnecessary calls to `$wpdb->update()` when no replacements If the replacement value is the same as the original value, we don't need to perform an update --- php/commands/search-replace.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7fb2592779..3a6a506522 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -285,6 +285,10 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r $value = $replacer->run( $row->$col ); + if ( $value === $row->$col ) { + continue; + } + if ( $dry_run ) { if ( $value != $row->$col ) $count++; From a249578ae2053b88c3174b15378266c9c65a9dfe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 1 Dec 2015 07:21:03 -0800 Subject: [PATCH 3865/4858] Lock symfony to v2.7.x There's something broken in v2.8.0 --- composer.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1fe600e046..ba6f9d758c 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,14 @@ "composer/semver": "1.0.0", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", - "symfony/finder": "~2.3", + "symfony/finder": "2.7.*", + "symfony/yaml": "2.7.*", + "symfony/filesystem": "2.7.*", + "symfony/config": "2.7.*", + "symfony/console": "2.7.*", + "symfony/dependency-injection": "2.7.*", + "symfony/event-dispatcher": "2.7.*", + "symfony/translation": "2.7.*", "nb/oxymel": "0.1.0" }, "require-dev": { From 2915ba7167e5945efa1e06362021c6cc2a0d7da2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 1 Dec 2015 07:54:45 -0800 Subject: [PATCH 3866/4858] Abstract s/r table preparation to `WP_CLI\Utils\wp_get_table_names()` This will let us reuse it in other contexts (e.g. db export) --- php/commands/search-replace.php | 124 +------------------------------- php/utils-wp.php | 105 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 122 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 3a6a506522..bbaa7a50d4 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -88,36 +88,8 @@ public function __invoke( $args, $assoc_args ) { // 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; + // 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 ); @@ -174,73 +146,6 @@ public function __invoke( $args, $assoc_args ) { } } - /** - * Retrieve a list of tables from the database. - * - * @global wpdb $wpdb - * - * @param string $limit_to Sting defining how to limit the list of tables to retrieve. Acceptable vales are: - * - 'wordpress' for default WordPress tables only - * - 'network' for default Multisite tables only - * - 'all-tables-with-prefix' for all tables using the WordPress DB prefix - * - 'all-tables' for all tables in the DB - * - * @return array The array of table names. - */ - private static function get_table_list( $limit_to ) { - global $wpdb; - - $network = 'network' == $limit_to; - - if ( 'all-tables' == $limit_to ) { - return $wpdb->get_col( 'SHOW TABLES' ); - } - - $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; - $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); - - if ( 'all-tables-with-prefix' == $limit_to ) { - return $matching_tables; - } - - $allowed_tables = array(); - $allowed_table_types = array( 'tables', 'global_tables' ); - if ( $network ) { - $allowed_table_types[] = 'ms_global_tables'; - } - foreach( $allowed_table_types as $table_type ) { - foreach( $wpdb->$table_type as $table ) { - $allowed_tables[] = $prefix . $table; - } - } - - // Given our matching tables, also allow site-specific tables on the network - foreach( $matching_tables as $key => $matched_table ) { - - if ( in_array( $matched_table, $allowed_tables ) ) { - continue; - } - - if ( $network ) { - $valid_table = false; - foreach( array_merge( $wpdb->tables, $wpdb->old_tables ) as $maybe_site_table ) { - if ( preg_match( "#{$prefix}([\d]+)_{$maybe_site_table}#", $matched_table ) ) { - $valid_table = true; - } - } - if ( $valid_table ) { - continue; - } - } - - unset( $matching_tables[ $key ] ); - - } - - return array_values( $matching_tables ); - - } - private function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) { global $wpdb; @@ -332,31 +237,6 @@ private static function get_columns( $table ) { return array( $primary_keys, $columns ); } - /** - * Get all the tables that match a glob pattern - * - * @param string $glob - * @return array - */ - private static function get_tables_for_glob( $glob ) { - - static $all_tables = array(); - - if ( ! $all_tables ) { - $all_tables = self::get_table_list( 'all-tables' ); - } - - $tables = array(); - - foreach ( $all_tables as $table) { - if ( fnmatch( $glob, $table ) ) { - $tables[] = $table; - } - } - - return $tables; - } - private static function is_text_col( $type ) { foreach ( array( 'text', 'varchar' ) as $token ) { if ( false !== strpos( $type, $token ) ) diff --git a/php/utils-wp.php b/php/utils-wp.php index e3519af487..470ab39976 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -205,3 +205,108 @@ function wp_clear_object_cache() { $wp_object_cache->__remoteset(); // important } } + +/** + * Get a set of tables in the database. + * + * Interprets common command-line options into a resolved set of table names. + * + * @param array $args Provided table names, or tables with wildcards. + * @param array $assoc_args Optional flags for groups of tables (e.g. --network) + * @return array $tables + */ +function wp_get_table_names( $args, $assoc_args = array() ) { + global $wpdb; + + // Prioritize any supplied $args as tables + if ( ! empty( $args ) ) { + $new_tables = array(); + $get_tables_for_glob = function( $glob ) { + global $wpdb; + static $all_tables = array(); + if ( ! $all_tables ) { + $all_tables = $wpdb->get_col( 'SHOW TABLES' ); + } + $tables = array(); + foreach ( $all_tables as $table) { + if ( fnmatch( $glob, $table ) ) { + $tables[] = $table; + } + } + return $tables; + }; + foreach( $args as $key => $table ) { + if ( false !== strpos( $table, '*' ) || false !== strpos( $table, '?' ) ) { + $expanded_tables = $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; + } + } + return $new_tables; + } + + // Fall back to flag if no tables were passed + $table_type = 'wordpress'; + if ( get_flag_value( $assoc_args, 'network' ) ) { + $table_type = 'network'; + } + if ( get_flag_value( $assoc_args, 'all-tables-with-prefix' ) ) { + $table_type = 'all-tables-with-prefix'; + } + if ( get_flag_value( $assoc_args, 'all-tables' ) ) { + $table_type = 'all-tables'; + } + + $network = 'network' == $table_type; + + if ( 'all-tables' == $table_type ) { + return $wpdb->get_col( 'SHOW TABLES' ); + } + + $prefix = $network ? $wpdb->base_prefix : $wpdb->prefix; + $matching_tables = $wpdb->get_col( $wpdb->prepare( "SHOW TABLES LIKE %s", $prefix . '%' ) ); + + if ( 'all-tables-with-prefix' == $table_type ) { + return $matching_tables; + } + + $allowed_tables = array(); + $allowed_table_types = array( 'tables', 'global_tables' ); + if ( $network ) { + $allowed_table_types[] = 'ms_global_tables'; + } + foreach( $allowed_table_types as $table_type ) { + foreach( $wpdb->$table_type as $table ) { + $allowed_tables[] = $prefix . $table; + } + } + + // Given our matching tables, also allow site-specific tables on the network + foreach( $matching_tables as $key => $matched_table ) { + + if ( in_array( $matched_table, $allowed_tables ) ) { + continue; + } + + if ( $network ) { + $valid_table = false; + foreach( array_merge( $wpdb->tables, $wpdb->old_tables ) as $maybe_site_table ) { + if ( preg_match( "#{$prefix}([\d]+)_{$maybe_site_table}#", $matched_table ) ) { + $valid_table = true; + } + } + if ( $valid_table ) { + continue; + } + } + + unset( $matching_tables[ $key ] ); + + } + + return array_values( $matching_tables ); +} From fd32e4ede5d2ea3983fb576c740e11112ae27f6b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 1 Dec 2015 07:56:12 -0800 Subject: [PATCH 3867/4858] Remove flag I didn't mean to commit long ago --- features/search-replace.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index f8590a1230..fb526766a7 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -57,7 +57,6 @@ Feature: Do global search/replace awesome_table """ - @daniel Scenario: Run on all tables matching string with wildcard Given a WP install From 7845a67b97c162573212b6bcf6aff62bfad2957c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 1 Dec 2015 08:22:28 -0800 Subject: [PATCH 3868/4858] Use `WP_CLI\Utils\wp_get_table_names()` in `wp db tables` --- features/db-table.feature | 92 +++++++++++++++++++++++++++++++++++++++ php/commands/db.php | 18 ++++++-- php/utils-wp.php | 4 ++ 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 features/db-table.feature diff --git a/features/db-table.feature b/features/db-table.feature new file mode 100644 index 0000000000..4aedecaf31 --- /dev/null +++ b/features/db-table.feature @@ -0,0 +1,92 @@ +Feature: List database tables + + Scenario: List database tables on a single WordPress install + Given a WP install + + When I run `wp db tables` + Then STDOUT should contain: + """ + wp_users + wp_usermeta + wp_posts + wp_comments + wp_links + wp_options + wp_postmeta + wp_terms + wp_term_taxonomy + wp_term_relationships + """ + + Scenario: List database tables on a multisite WordPress install + Given a WP multisite install + + When I run `wp db tables` + Then STDOUT should contain: + """ + wp_users + wp_usermeta + wp_posts + wp_comments + wp_links + wp_options + wp_postmeta + wp_terms + wp_term_taxonomy + wp_term_relationships + """ + And STDOUT should contain: + """ + wp_blogs + wp_signups + wp_site + wp_sitemeta + wp_sitecategories + wp_registration_log + wp_blog_versions + """ + + When I run `wp site create --slug=foo` + And I run `wp db tables --url=example.com/foo` + Then STDOUT should contain: + """ + wp_users + wp_usermeta + wp_2_posts + """ + + When I run `wp db tables --url=example.com/foo --scope=global` + Then STDOUT should not contain: + """ + wp_2_posts + """ + + When I run `wp db tables --all-tables-with-prefix` + Then STDOUT should contain: + """ + wp_2_posts + """ + And STDOUT should contain: + """ + wp_posts + """ + + When I run `wp db tables --url=example.com/foo --all-tables-with-prefix` + Then STDOUT should contain: + """ + wp_2_posts + """ + And STDOUT should not contain: + """ + wp_posts + """ + + When I run `wp db tables --url=example.com/foo --network` + Then STDOUT should contain: + """ + wp_2_posts + """ + And STDOUT should contain: + """ + wp_posts + """ diff --git a/php/commands/db.php b/php/commands/db.php index 956c9647cd..e2f3a4bc7b 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -202,22 +202,34 @@ function import( $args, $assoc_args ) { /** * List the database tables. * + * Defaults to all tables registered to $wpdb. + * * ## OPTIONS * * [--scope=<scope>] * : Can be all, global, ms_global, blog, or old tables. Defaults to all. * + * [--network] + * : List all the tables in a multisite install. Overrides --scope=<scope>. + * + * [--all-tables-with-prefix] + * : List all tables that match the table prefix even if not registered on $wpdb. Overrides --network. + * + * [--all-tables] + * : List all tables in the database, regardless of the prefix, and even if not registered on $wpdb. Overrides --all-tables-with-prefix. + * * ## EXAMPLES * * # Export only tables for a single site * wp db export --tables=$(wp db tables --url=sub.example.com | tr '\n' ',') */ function tables( $args, $assoc_args ) { - global $wpdb; - $scope = \WP_CLI\Utils\get_flag_value( $assoc_args, 'scope', 'all' ); + if ( empty( $assoc_args ) ) { + $assoc_args['scope'] = 'all'; + } - $tables = $wpdb->tables( $scope ); + $tables = WP_CLI\Utils\wp_get_table_names( $args, $assoc_args ); foreach ( $tables as $table ) { WP_CLI::line( $table ); diff --git a/php/utils-wp.php b/php/utils-wp.php index 470ab39976..b4202dd847 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -274,6 +274,10 @@ function wp_get_table_names( $args, $assoc_args = array() ) { return $matching_tables; } + if ( $scope = get_flag_value( $assoc_args, 'scope' ) ) { + return $wpdb->tables( $scope ); + } + $allowed_tables = array(); $allowed_table_types = array( 'tables', 'global_tables' ); if ( $network ) { From 5880e442c1e79ecacbac54048d96260f7bed61ec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 1 Dec 2015 09:00:06 -0800 Subject: [PATCH 3869/4858] Add wildcard table searching and `--format=csv` for easier composing --- features/db-table.feature | 12 ++++++++++++ php/commands/db.php | 27 +++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/features/db-table.feature b/features/db-table.feature index 4aedecaf31..e0b6a907da 100644 --- a/features/db-table.feature +++ b/features/db-table.feature @@ -18,6 +18,18 @@ Feature: List database tables wp_term_relationships """ + When I run `wp db tables --format=csv` + Then STDOUT should contain: + """ + wp_terms,wp_usermeta,wp_users + """ + + When I run `wp db tables 'wp_post*' --format=csv` + Then STDOUT should be: + """ + wp_postmeta,wp_posts + """ + Scenario: List database tables on a multisite WordPress install Given a WP multisite install diff --git a/php/commands/db.php b/php/commands/db.php index e2f3a4bc7b..f8a7a281a5 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -131,6 +131,12 @@ function query( $args ) { * wp db export --add-drop-table * wp db export --tables=wp_options,wp_users * + * # Export all tables matching a wildcard + * wp db export --tables=$(wp db tables 'wp_user*' --format=csv) + * + * # Export all tables matching prefix + * wp db export --tables=$(wp db tables --all-tables-with-prefix --format=csv) + * * @alias dump */ function export( $args, $assoc_args ) { @@ -206,6 +212,9 @@ function import( $args, $assoc_args ) { * * ## OPTIONS * + * [<table>...] + * : List tables based on wildcard search, e.g. 'wp_*_options' or 'wp_post?'. + * * [--scope=<scope>] * : Can be all, global, ms_global, blog, or old tables. Defaults to all. * @@ -218,21 +227,31 @@ function import( $args, $assoc_args ) { * [--all-tables] * : List all tables in the database, regardless of the prefix, and even if not registered on $wpdb. Overrides --all-tables-with-prefix. * + * [--format=<format>] + * : Accepted values: list, csv. Default: list + * * ## EXAMPLES * * # Export only tables for a single site - * wp db export --tables=$(wp db tables --url=sub.example.com | tr '\n' ',') + * wp db export --tables=$(wp db tables --url=sub.example.com --format=csv) + * + * # Export all tables matching prefix + * wp db export --tables=$(wp db tables --all-tables-with-prefix --format=csv) */ function tables( $args, $assoc_args ) { - if ( empty( $assoc_args ) ) { + if ( empty( $args ) && empty( $assoc_args ) ) { $assoc_args['scope'] = 'all'; } $tables = WP_CLI\Utils\wp_get_table_names( $args, $assoc_args ); - foreach ( $tables as $table ) { - WP_CLI::line( $table ); + if ( ! empty( $assoc_args['format'] ) && 'csv' === $assoc_args['format'] ) { + WP_CLI::line( implode( ',', $tables ) ); + } else { + foreach ( $tables as $table ) { + WP_CLI::line( $table ); + } } } From c4a6385ee3fed63df3700b82bca01d90f81e2589 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 1 Dec 2015 09:23:44 -0800 Subject: [PATCH 3870/4858] Set to the version WordPress began incrementing blog tables --- features/db-table.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/db-table.feature b/features/db-table.feature index e0b6a907da..8c8ab1bc0d 100644 --- a/features/db-table.feature +++ b/features/db-table.feature @@ -30,6 +30,7 @@ Feature: List database tables wp_postmeta,wp_posts """ + @require-wp-3.9 Scenario: List database tables on a multisite WordPress install Given a WP multisite install From da9167d1d4b49cf5cb9d83f4e45d4bfa1ebc57d1 Mon Sep 17 00:00:00 2001 From: Ian Dunn <ian@iandunn.name> Date: Mon, 30 Nov 2015 11:26:03 -0800 Subject: [PATCH 3871/4858] Add .dist extension to PHPUnit configuration file in plugin-tests. Naming the file `phpunit.xml.dist` instead of `phpunit.xml` is considered a best practice because it allows other developers working on a project to override the configuration without messing with extra command line parameters or dirtying their local version control state. See http://www.testically.org/2010/08/24/best-practice-how-to-ship-phpunit-configuration/ --- .gitignore | 2 +- features/plugin.feature | 4 ++-- features/scaffold.feature | 2 +- php/commands/scaffold.php | 4 ++-- templates/{phpunit.xml => phpunit.xml.dist} | 0 5 files changed, 6 insertions(+), 6 deletions(-) rename templates/{phpunit.xml => phpunit.xml.dist} (100%) diff --git a/.gitignore b/.gitignore index ee37a1d64c..665e3e8afa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ config.yml /cache /vendor /*.phar -/phpunit.xml +/phpunit.xml.dist diff --git a/features/plugin.feature b/features/plugin.feature index 0eb663708e..65da74df61 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -8,7 +8,7 @@ Feature: Manage WordPress plugins When I run `wp plugin scaffold --skip-tests plugin1` Then STDOUT should not be empty And the {PLUGIN_DIR}/plugin1/plugin1.php file should exist - And the {PLUGIN_DIR}/zombieland/phpunit.xml file should not exist + And the {PLUGIN_DIR}/zombieland/phpunit.xml.dist file should not exist When I run `wp plugin path plugin1` Then STDOUT should be: @@ -25,7 +25,7 @@ Feature: Manage WordPress plugins When I run `wp plugin scaffold Zombieland` Then STDOUT should not be empty And the {PLUGIN_DIR}/Zombieland/Zombieland.php file should exist - And the {PLUGIN_DIR}/Zombieland/phpunit.xml file should exist + And the {PLUGIN_DIR}/Zombieland/phpunit.xml.dist file should exist # Ensure case sensitivity When I try `wp plugin status zombieLand` diff --git a/features/scaffold.feature b/features/scaffold.feature index 4fdb964475..6814597d0b 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -161,7 +161,7 @@ Feature: WordPress code scaffolding """ install-wp-tests.sh """ - And the {PLUGIN_DIR}/hello-world/phpunit.xml file should exist + And the {PLUGIN_DIR}/hello-world/phpunit.xml.dist file should exist And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-wp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 100b621e02..5672e79ab1 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -557,7 +557,7 @@ function plugin( $args, $assoc_args ) { * * These are the files that are generated: * - * * `phpunit.xml` is the configuration file for PHPUnit + * * `phpunit.xml.dist` is the configuration file for PHPUnit * * `.travis.yml` is the configuration file for Travis CI * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite * * `tests/test-sample.php` is a sample file containing the actual tests @@ -622,7 +622,7 @@ function plugin_tests( $args, $assoc_args ) { $to_copy = array( 'install-wp-tests.sh' => $bin_dir, '.travis.yml' => $plugin_dir, - 'phpunit.xml' => $plugin_dir, + 'phpunit.xml.dist' => $plugin_dir, 'test-sample.php' => $tests_dir, ); diff --git a/templates/phpunit.xml b/templates/phpunit.xml.dist similarity index 100% rename from templates/phpunit.xml rename to templates/phpunit.xml.dist From 7b9643c8b3f3ec4c1eaf7e1856d5281915264732 Mon Sep 17 00:00:00 2001 From: Tristan Penman <tristan@tristanpenman.com> Date: Thu, 3 Dec 2015 00:09:39 +0000 Subject: [PATCH 3872/4858] Improve plugin vs. theme detection for the error generated when the requested version of a plugin or theme does not exist Previously, the alter_api_response function would check for the substring 'theme' in the URL returned by the WordPress repository API. When requesting a non-existant version of a plugin such as Easy Updates Manager (which has the slug 'stops-core-theme-and-plugin-updates'), this would incorrectly report that the requested version of the _theme_ could not be found. This change makes the substring test stricter, by expecting the URL to contain the string '/theme/' for themes. It also performs a similar check for plugins ('/plugin/'), and if both checks fail, it will produce a more generic response (e.g. Can't find the requested plugin/theme's version...) --- php/WP_CLI/CommandWithUpgrade.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e037242182..8d988e2ce5 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -173,10 +173,12 @@ protected static function alter_api_response( $response, $version ) { list( $link ) = explode( $response->slug, $response->download_link ); - if ( false !== strpos( $response->download_link, 'theme' ) ) + if ( false !== strpos( $response->download_link, '/theme/' ) ) $download_type = 'theme'; - else + else if ( false !== strpos( $response->download_link, '/plugin/' ) ) $download_type = 'plugin'; + else + $download_type = 'plugin/theme'; if ( 'dev' == $version ) { $response->download_link = $link . $response->slug . '.zip'; From 018711fb1a95c1704f13e8371c891fbb49eaed39 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 3 Dec 2015 16:11:58 -0800 Subject: [PATCH 3873/4858] Use `--export=<file>` to `search-replace` to a saved file Props @westonruter for much of the original code --- features/search-replace.feature | 25 ++++++++++++++++++++++++ php/commands/search-replace.php | 34 ++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index fb526766a7..29d25ac430 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,6 +15,31 @@ Feature: Do global search/replace guid """ + Scenario: Search/replace with export + Given a WP install + + When I run `wp search-replace example.com example.net --export` + Then STDOUT should contain: + """ + DROP TABLE IF EXISTS `wp_commentmeta`; + CREATE TABLE `wp_commentmeta` + """ + And STDOUT should contain: + """ + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.org', 'yes'); + """ + + When I run `wp search-replace example.com example.org --skip-columns=option_value --export` + Then STDOUT should contain: + """ + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.com', 'yes'); + """ + + When I run `wp search-replace foo bar --export | tail -n 1` + Then STDOUT should not contain: + """ + Success: Made + """ Scenario: Multisite search/replace Given a WP multisite install diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index bbaa7a50d4..e8fcb92f70 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -7,6 +7,8 @@ */ class Search_Replace_Command extends WP_CLI_Command { + private $export_handle = false; + /** * Search/replace strings in the database. * @@ -57,6 +59,9 @@ class Search_Replace_Command extends WP_CLI_Command { * [--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 @@ -85,12 +90,35 @@ public function __invoke( $args, $assoc_args ) { exit; } + if ( null !== ( $export = \WP_CLI\Utils\get_flag_value( $assoc_args, 'export' ) ) ) { + if ( $dry_run ) { + WP_CLI::error( 'You cannot supply --dry-run and --export at the same time.' ); + } + if ( true === $export ) { + $this->export_handle = STDOUT; + $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 $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( $primary_keys, $columns ) = self::get_columns( $table ); // since we'll be updating one row at a time, @@ -128,7 +156,11 @@ public function __invoke( $args, $assoc_args ) { } } - if ( ! WP_CLI::get_config( 'quiet' ) ) { + if ( $this->export_handle && STDOUT !== $this->export_handle ) { + fclose( $this->export_handle ); + } + + if ( ! WP_CLI::get_config( 'quiet' ) && STDOUT !== $this->export_handle ) { $table = new \cli\Table(); $table->setHeaders( array( 'Table', 'Column', 'Replacements', 'Type' ) ); From f06605cf0c530ce1b5bec17d0e138ff58c281f55 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 4 Dec 2015 12:32:31 +0000 Subject: [PATCH 3874/4858] Convert .travis.yml into mustache template --- templates/{.travis.yml => .travis.mustache} | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename templates/{.travis.yml => .travis.mustache} (77%) diff --git a/templates/.travis.yml b/templates/.travis.mustache similarity index 77% rename from templates/.travis.yml rename to templates/.travis.mustache index 375e59ed2d..5a77b81b65 100644 --- a/templates/.travis.yml +++ b/templates/.travis.mustache @@ -10,7 +10,9 @@ php: - 5.6 env: - - WP_VERSION=latest WP_MULTISITE=0 +{{#wp_versions_to_test}} + - WP_VERSION={{.}} WP_MULTISITE=0 +{{/wp_versions_to_test}} matrix: include: From f87d1c8ed5af7c5222af87739b9fb878ceba634d Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 4 Dec 2015 12:33:15 +0000 Subject: [PATCH 3875/4858] Parse plugin readme.txt to find WP versions to test --- php/commands/scaffold.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 5672e79ab1..b7c1ad0caa 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -615,13 +615,29 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->mkdir( $tests_dir ); $wp_filesystem->mkdir( $bin_dir ); + $wp_versions_to_test = array('latest'); + // Parse plugin readme.txt + if ( file_exists( $plugin_dir . '/readme.txt' ) ) { + $readme_content = file_get_contents( $plugin_dir . '/readme.txt' ); + + preg_match( '/Requires at least\:(.*)\n/m', $readme_content, $matches ); + if ( isset( $matches[1] ) && $matches[1] ) { + $wp_versions_to_test[] = trim( $matches[1] ); + } + preg_match( '/Tested up to\:(.*)\n/m', $readme_content, $matches ); + if ( isset( $matches[1] ) && $matches[1] ) { + $wp_versions_to_test[] = trim( $matches[1] ); + } + } + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); - $files_written = $this->create_files( array( "$tests_dir/bootstrap.php" => - Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ) ), $force ); + $files_written = $this->create_files( array( + "$tests_dir/bootstrap.php" => Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ), + "$plugin_dir/.travis.yml" => Utils\mustache_render( '.travis.mustache', compact( 'wp_versions_to_test' ) ) + ), $force ); $to_copy = array( 'install-wp-tests.sh' => $bin_dir, - '.travis.yml' => $plugin_dir, 'phpunit.xml.dist' => $plugin_dir, 'test-sample.php' => $tests_dir, ); From 7284bf48bd132fbbf49e25fef1c5aaeaac84f617 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 4 Dec 2015 14:52:05 +0000 Subject: [PATCH 3876/4858] Add functional test --- features/scaffold.feature | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 6814597d0b..377b9666b2 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -322,6 +322,23 @@ Feature: WordPress code scaffolding require dirname( dirname( __FILE__ ) ) . '/custom-plugin-slug.php'; """ + Scenario: Scaffold tests parses plugin readme.txt + Given a WP install + When I run `wp plugin path` + Then save STDOUT as {PLUGIN_DIR} + + When I run `wp scaffold plugin hello-world` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/readme.txt file should exist + And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist + And the {PLUGIN_DIR}/hello-world/.travis.yml file should contain: + """ + env: + - WP_VERSION=latest WP_MULTISITE=0 + - WP_VERSION=3.0.1 WP_MULTISITE=0 + - WP_VERSION=3.4 WP_MULTISITE=0 + """ + Scenario: Scaffold starter code for a theme and network enable it Given a WP multisite install When I run `wp scaffold _s starter-theme --enable-network` From cd41122b91a7f287e6a252d08bcd24c5eac8ce3c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 06:52:55 -0800 Subject: [PATCH 3877/4858] Bail early, to prevent nested conditional --- php/commands/search-replace.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index e8fcb92f70..7433e35469 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -160,21 +160,22 @@ public function __invoke( $args, $assoc_args ) { fclose( $this->export_handle ); } - if ( ! WP_CLI::get_config( 'quiet' ) && STDOUT !== $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(); + $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 ); + 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 ); } } From c3a859c8a67936c0f9933a0fe13b651cebe6091f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 09:14:56 -0800 Subject: [PATCH 3878/4858] Write each row of data to export file Abstracts some arguments to class variables for better reusability throughout --- features/search-replace-export.feature | 146 +++++++++++++++++++++++++ features/search-replace.feature | 26 ----- php/commands/search-replace.php | 133 ++++++++++++++++------ 3 files changed, 246 insertions(+), 59 deletions(-) create mode 100644 features/search-replace-export.feature diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature new file mode 100644 index 0000000000..4727ae785b --- /dev/null +++ b/features/search-replace-export.feature @@ -0,0 +1,146 @@ +Feature: Search / replace with file export + + Scenario: Search / replace export to STDOUT + Given a WP install + + When I run `wp search-replace example.com example.net --export` + Then STDOUT should contain: + """ + DROP TABLE IF EXISTS `wp_commentmeta`; + CREATE TABLE `wp_commentmeta` + """ + And STDOUT should contain: + """ + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.net', 'yes'); + """ + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ + + When I run `wp search-replace example.com example.net --skip-columns=option_value --export` + Then STDOUT should contain: + """ + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.com', 'yes'); + """ + + When I run `wp search-replace foo bar --export | tail -n 1` + Then STDOUT should not contain: + """ + Success: Made + """ + + When I run `wp search-replace example.com example.net --export > wordpress.sql` + And I run `wp db import wordpress.sql` + Then STDOUT should not be empty + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.net + """ + + Scenario: Search / replace export to file + Given a WP install + And I run `wp post generate --count=30` + + When I run `wp search-replace example.com example.net --export=wordpress.sql` + Then STDOUT should contain: + """ + Success: Made 39 replacements and exported to wordpress.sql + """ + And STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_options | option_value | 5 | PHP | + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ + + When I run `wp site empty --yes` + And I run `wp post list --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp db import wordpress.sql` + Then STDOUT should not be empty + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.net + """ + + When I run `wp post list --format=count` + Then STDOUT should be: + """ + 31 + """ + + Scenario: Search / replace export to file with verbosity + Given a WP install + + When I run `wp search-replace example.com example.net --export=wordpress.sql --verbose` + Then STDOUT should contain: + """ + Checking: wp_posts + """ + And STDOUT should contain: + """ + Checking: wp_options + """ + + Scenario: Search / replace export with dry-run + Given a WP install + + When I try `wp search-replace example.com example.net --export --dry-run` + Then STDERR should be: + """ + Error: You cannot supply --dry-run and --export at the same time. + """ + + Scenario: Search / replace shouldn't affect primary key + Given a WP install + And I run `wp post create --post_title=foo --porcelain` + Then save STDOUT as {POST_ID} + + When I run `wp option update {POST_ID} foo` + And I run `wp option get {POST_ID}` + Then STDOUT should be: + """ + foo + """ + + When I run `wp search-replace {POST_ID} 99999999 --export=wordpress.sql` + And I run `wp db import wordpress.sql` + Then STDOUT should not be empty + + When I run `wp post get {POST_ID} --field=title` + Then STDOUT should be: + """ + foo + """ + + When I try `wp option get {POST_ID}` + Then STDOUT should be empty + + When I run `wp option get 99999999` + Then STDOUT should be: + """ + foo + """ + + Scenario: Search / replace export invalid file + Given a WP install + + When I try `wp search-replace example.com example.net --export=foo/bar.sql` + Then STDERR should contain: + """ + Error: Unable to open "foo/bar.sql" for writing. + """ diff --git a/features/search-replace.feature b/features/search-replace.feature index 29d25ac430..eb0783361d 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,32 +15,6 @@ Feature: Do global search/replace guid """ - Scenario: Search/replace with export - Given a WP install - - When I run `wp search-replace example.com example.net --export` - Then STDOUT should contain: - """ - DROP TABLE IF EXISTS `wp_commentmeta`; - CREATE TABLE `wp_commentmeta` - """ - And STDOUT should contain: - """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.org', 'yes'); - """ - - When I run `wp search-replace example.com example.org --skip-columns=option_value --export` - Then STDOUT should contain: - """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.com', 'yes'); - """ - - When I run `wp search-replace foo bar --export | tail -n 1` - Then STDOUT should not contain: - """ - Success: Made - """ - Scenario: Multisite search/replace Given a WP multisite install And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7433e35469..94698e6f0c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -8,6 +8,9 @@ class Search_Replace_Command extends WP_CLI_Command { private $export_handle = false; + private $recurse_objects; + private $regex; + private $skip_columns; /** * Search/replace strings in the database. @@ -79,13 +82,13 @@ public function __invoke( $args, $assoc_args ) { $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' ); + $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' ); - $skip_columns = explode( ',', \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-columns' ) ); + $this->skip_columns = explode( ',', \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-columns' ) ); - if ( $old === $new && ! $regex ) { + if ( $old === $new && ! $this->regex ) { WP_CLI::warning( "Replacement value '{$old}' is identical to search value '{$new}'. Skipping operation." ); exit; } @@ -96,18 +99,18 @@ public function __invoke( $args, $assoc_args ) { } if ( true === $export ) { $this->export_handle = STDOUT; - $verbose = false; + $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'] ) ); + WP_CLI::error( sprintf( 'Unable to open "%s" for writing.', $assoc_args['export'] ) ); } } $php_only = true; } // never mess with hashed passwords - $skip_columns[] = 'user_pass'; + $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 ); @@ -117,9 +120,14 @@ public function __invoke( $args, $assoc_args ) { 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 ) = self::get_columns( $table ); + 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 @@ -129,11 +137,11 @@ public function __invoke( $args, $assoc_args ) { } foreach ( $columns as $col ) { - if ( in_array( $col, $skip_columns ) ) { + if ( in_array( $col, $this->skip_columns ) ) { continue; } - if ( $verbose ) { + if ( $this->verbose ) { $this->start_time = microtime( true ); WP_CLI::log( sprintf( 'Checking: %s.%s', $table, $col ) ); } @@ -142,12 +150,12 @@ public function __invoke( $args, $assoc_args ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } - if ( $php_only || $regex || NULL !== $serialRow ) { + if ( $php_only || $this->regex || NULL !== $serialRow ) { $type = 'PHP'; - $count = $this->php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ); + $count = $this->php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run ); } else { $type = 'SQL'; - $count = $this->sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ); + $count = $this->sql_handle_col( $col, $table, $old, $new, $dry_run ); } $report[] = array( $table, $col, $count, $type ); @@ -171,7 +179,7 @@ public function __invoke( $args, $assoc_args ) { $table->display(); if ( ! $dry_run ) { - $success_message = "Made $total replacements."; + $success_message = ! empty( $assoc_args['export'] ) ? "Made {$total} replacements and exported to {$assoc_args['export']}." : "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`.'; } @@ -179,7 +187,56 @@ public function __invoke( $args, $assoc_args ) { } } - private function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) { + private function php_export_table( $table, $old, $new ) { + list( $primary_keys, $columns, $all_columns ) = self::get_columns( $table ); + $chunk_size = getenv( 'BEHAT_RUN' ) ? 10 : 1000; + $args = array( + 'table' => $table, + 'fields' => $all_columns, + 'chunk_size' => $chunk_size + ); + + $replacer = new \WP_CLI\SearchReplacer( $old, $new, $this->recurse_objects, $this->regex ); + $col_counts = array_fill_keys( $all_columns, 0 ); + if ( $this->verbose ) { + $this->start_time = microtime( true ); + WP_CLI::log( sprintf( 'Checking: %s', $table ) ); + } + foreach ( new \WP_CLI\Iterators\Table( $args ) as $i => $row ) { + $row_fields = array(); + foreach( $all_columns as $col ) { + $value = $row->$col; + if ( $value && ! in_array( $col, $primary_keys ) && ! in_array( $col, $this->skip_columns ) ) { + $new_value = $replacer->run( $value ); + if ( $new_value !== $value ) { + $col_counts[ $col ]++; + $value = $new_value; + } + } + $row_fields[ $col ] = $value; + } + $this->write_sql_row_fields( $table, $row_fields ); + } + + $table_report = array(); + $total_rows = $total_cols = 0; + foreach ( $col_counts as $col => $col_count ) { + $table_report[] = array( $table, $col, $col_count, 'PHP' ); + if ( $col_count ) { + $total_cols++; + $total_rows += $col_count; + } + } + + if ( $this->verbose ) { + $time = round( microtime( true ) - $this->start_time, 3 ); + WP_CLI::log( sprintf( '%d columns and %d total rows affected using PHP (in %ss)', $total_cols, $total_rows, $time ) ); + } + + return array( $table_report, $total_rows ); + } + + private function sql_handle_col( $col, $table, $old, $new, $dry_run ) { global $wpdb; if ( $dry_run ) { @@ -188,14 +245,14 @@ private function sql_handle_col( $col, $table, $old, $new, $dry_run, $verbose ) $count = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); } - if ( $verbose ) { + if ( $this->verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); WP_CLI::log( sprintf( '%d rows affected using SQL (in %ss)', $count, $time ) ); } return $count; } - private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run, $recurse_objects, $verbose, $regex ) { + private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite @@ -207,7 +264,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r $args = array( 'table' => $table, 'fields' => $fields, - 'where' => $regex ? '' : "`$col`" . $wpdb->prepare( ' LIKE %s', '%' . self::esc_like( $old ) . '%' ), + 'where' => $this->regex ? '' : "`$col`" . $wpdb->prepare( ' LIKE %s', '%' . self::esc_like( $old ) . '%' ), 'chunk_size' => $chunk_size ); @@ -215,7 +272,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r $count = 0; - $replacer = new \WP_CLI\SearchReplacer( $old, $new, $recurse_objects, $regex ); + $replacer = new \WP_CLI\SearchReplacer( $old, $new, $this->recurse_objects, $this->regex ); foreach ( $it as $row ) { if ( '' === $row->$col ) @@ -240,7 +297,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r } } - if ( $verbose ) { + if ( $this->verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); WP_CLI::log( sprintf( '%d rows affected using PHP (in %ss)', $count, $time ) ); } @@ -248,26 +305,36 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r return $count; } - private static function get_columns( $table ) { + private function write_sql_row_fields( $table, $row_fields ) { global $wpdb; + $sql = "INSERT INTO `$table` ("; + $sql .= join( ', ', array_map( + function ( $field ) { + return "`$field`"; + }, + array_keys( $row_fields ) + ) ); + $sql .= ') VALUES ('; + $sql .= join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ); + $sql .= ");\n"; + $sql = $wpdb->prepare( $sql, array_values( $row_fields ) ); + fwrite( $this->export_handle, $sql ); + } - $primary_keys = array(); - - $columns = array(); + private static function get_columns( $table ) { + global $wpdb; + $primary_keys = $text_columns = $all_columns = array(); foreach ( $wpdb->get_results( "DESCRIBE $table" ) as $col ) { if ( 'PRI' === $col->Key ) { $primary_keys[] = $col->Field; - continue; } - - if ( !self::is_text_col( $col->Type ) ) - continue; - - $columns[] = $col->Field; + if ( self::is_text_col( $col->Type ) ) { + $text_columns[] = $col->Field; + } + $all_columns[] = $col->Field; } - - return array( $primary_keys, $columns ); + return array( $primary_keys, $text_columns, $all_columns ); } private static function is_text_col( $type ) { From 04099b93fbafc5812cc46e6b011b1353539ed6a3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 09:23:07 -0800 Subject: [PATCH 3879/4858] Include a test for search / replace export on a specific table --- features/search-replace-export.feature | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index 4727ae785b..e50bde0cc0 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -144,3 +144,37 @@ Feature: Search / replace with file export """ Error: Unable to open "foo/bar.sql" for writing. """ + + Scenario: Search / replace specific table + Given a WP install + + When I run `wp post create --post_title=foo --porcelain` + Then save STDOUT as {POST_ID} + + When I run `wp option update bar foo` + Then STDOUT should not be empty + + When I run `wp search-replace foo burrito wp_posts --export=wordpress.sql --verbose` + Then STDOUT should contain: + """ + Checking: wp_posts + """ + And STDOUT should contain: + """ + Success: Made 1 replacements and exported to wordpress.sql. + """ + + When I run `wp db import wordpress.sql` + Then STDOUT should not be empty + + When I run `wp post get {POST_ID} --field=title` + Then STDOUT should be: + """ + burrito + """ + + When I run `wp option get bar` + Then STDOUT should be: + """ + foo + """ From 37a9208d6e9fc3bdd711777fd95e960bdba63ff6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 09:25:49 -0800 Subject: [PATCH 3880/4858] Abstract `$dry_run` to class variable for better reusability --- php/commands/search-replace.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 94698e6f0c..35f6d6d445 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -7,6 +7,7 @@ */ class Search_Replace_Command extends WP_CLI_Command { + private $dry_run; private $export_handle = false; private $recurse_objects; private $regex; @@ -80,7 +81,7 @@ public function __invoke( $args, $assoc_args ) { $new = array_shift( $args ); $total = 0; $report = array(); - $dry_run = \WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run' ); + $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' ); @@ -94,7 +95,7 @@ public function __invoke( $args, $assoc_args ) { } if ( null !== ( $export = \WP_CLI\Utils\get_flag_value( $assoc_args, 'export' ) ) ) { - if ( $dry_run ) { + if ( $this->dry_run ) { WP_CLI::error( 'You cannot supply --dry-run and --export at the same time.' ); } if ( true === $export ) { @@ -152,10 +153,10 @@ public function __invoke( $args, $assoc_args ) { if ( $php_only || $this->regex || NULL !== $serialRow ) { $type = 'PHP'; - $count = $this->php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run ); + $count = $this->php_handle_col( $col, $primary_keys, $table, $old, $new ); } else { $type = 'SQL'; - $count = $this->sql_handle_col( $col, $table, $old, $new, $dry_run ); + $count = $this->sql_handle_col( $col, $table, $old, $new ); } $report[] = array( $table, $col, $count, $type ); @@ -178,7 +179,7 @@ public function __invoke( $args, $assoc_args ) { $table->setRows( $report ); $table->display(); - if ( ! $dry_run ) { + if ( ! $this->dry_run ) { $success_message = ! empty( $assoc_args['export'] ) ? "Made {$total} replacements and exported to {$assoc_args['export']}." : "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`.'; @@ -236,10 +237,10 @@ private function php_export_table( $table, $old, $new ) { return array( $table_report, $total_rows ); } - private function sql_handle_col( $col, $table, $old, $new, $dry_run ) { + private function sql_handle_col( $col, $table, $old, $new ) { global $wpdb; - if ( $dry_run ) { + if ( $this->dry_run ) { $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(`$col`) FROM `$table` WHERE `$col` LIKE %s;", '%' . self::esc_like( $old ) . '%' ) ); } else { $count = $wpdb->query( $wpdb->prepare( "UPDATE `$table` SET `$col` = REPLACE(`$col`, %s, %s);", $old, $new ) ); @@ -252,7 +253,7 @@ private function sql_handle_col( $col, $table, $old, $new, $dry_run ) { return $count; } - private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_run ) { + private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { global $wpdb; // We don't want to have to generate thousands of rows when running the test suite @@ -284,7 +285,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new, $dry_r continue; } - if ( $dry_run ) { + if ( $this->dry_run ) { if ( $value != $row->$col ) $count++; } else { From 4af2fdd58420aa65637bff2075605d97bbc79f13 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 09:32:10 -0800 Subject: [PATCH 3881/4858] Add helpful example for this new feature --- php/commands/search-replace.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 35f6d6d445..ada5cf46dc 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -74,6 +74,9 @@ class Search_Replace_Command extends WP_CLI_Command { * * # 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; From b6a5ed763ffefe90487891067e4b650fdd48039d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 09:50:16 -0800 Subject: [PATCH 3882/4858] We don't need to include the object cache flush message with `--export` --- php/commands/search-replace.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index ada5cf46dc..d2f705e6a5 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -183,9 +183,13 @@ public function __invoke( $args, $assoc_args ) { $table->display(); if ( ! $this->dry_run ) { - $success_message = ! empty( $assoc_args['export'] ) ? "Made {$total} replacements and exported to {$assoc_args['export']}." : "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`.'; + 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 ); } From 5c7eb3f22345eec1ee3114f7bd818f38e139f4fb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 15:03:11 -0800 Subject: [PATCH 3883/4858] Abstract update getter, so we can use it with `wp core update` This changes the behavior of `wp core check-upate` to only list one major update. Users should be updating to the latest major release, not an intermediate one. --- features/core.feature | 12 +--- php/commands/core.php | 133 +++++++++++++++++++++--------------------- 2 files changed, 69 insertions(+), 76 deletions(-) diff --git a/features/core.feature b/features/core.feature index c9d18e77bd..74e45feaa3 100644 --- a/features/core.feature +++ b/features/core.feature @@ -339,31 +339,23 @@ Feature: Manage WordPress installation Then STDOUT should be a table containing rows: | version | update_type | package_url | | 4.3.1 | major | https://wordpress.org/wordpress-4.3.1.zip | - | 4.2.5 | major | https://wordpress.org/wordpress-4.2.5.zip | - | 4.1.8 | major | https://wordpress.org/wordpress-4.1.8.zip | - | 4.0.8 | major | https://wordpress.org/wordpress-4.0.8.zip | - | 3.9.9 | major | https://wordpress.org/wordpress-3.9.9.zip | | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | When I run `wp core check-update --format=count` Then STDOUT should be: """ - 6 + 2 """ When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | | 4.3.1 | major | https://wordpress.org/wordpress-4.3.1.zip | - | 4.2.5 | major | https://wordpress.org/wordpress-4.2.5.zip | - | 4.1.8 | major | https://wordpress.org/wordpress-4.1.8.zip | - | 4.0.8 | major | https://wordpress.org/wordpress-4.0.8.zip | - | 3.9.9 | major | https://wordpress.org/wordpress-3.9.9.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: """ - 5 + 1 """ When I run `wp core check-update --minor` diff --git a/php/commands/core.php b/php/commands/core.php index b4ee483c6f..59b784cb1b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1,5 +1,6 @@ <?php +use \Composer\Semver\Comparator; use \WP_CLI\Utils; /** @@ -34,60 +35,8 @@ class Core_Command extends WP_CLI_Command { * @subcommand check-update */ function check_update( $_, $assoc_args ) { - global $wp_version; - $versions_path = ABSPATH . 'wp-includes/version.php'; - include $versions_path; - - $url = 'https://api.wordpress.org/core/stable-check/1.0/'; - - $options = array( - 'timeout' => 30 - ); - $headers = array( - 'Accept' => 'application/json' - ); - $response = Utils\http_request( 'GET', $url, $headers, $options ); - - if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( "Failed to get latest version." ); - } - - $release_data = json_decode( $response->body ); - $release_versions = array_keys( (array) $release_data ); - usort( $release_versions, function( $a, $b ){ - return 1 === version_compare( $a, $b ); - }); - - $locale = get_locale(); - - $current_parts = explode( '.', $wp_version ); - $updates = array(); - - foreach ( $release_versions as $release_version ) { - // don't list earliers versions - if ( \WP_CLI\Utils\wp_version_compare( $release_version, '>=' ) ) - continue; - - $release_parts = explode( '.', $release_version ); - $update_type = 'major'; - - if ( $release_parts[0] === $current_parts[0] - && $release_parts[1] === $current_parts[1] ) { - $update_type = 'minor'; - } - - if ( ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) && 'minor' !== $update_type ) - && ! ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'major' ) && 'major' !== $update_type ) - ) { - $updates = $this->remove_same_minor_releases( $release_parts, $updates ); - $updates[] = array( - 'version' => $release_version, - 'update_type' => $update_type, - 'package_url' => $this->get_download_url( $release_version, $locale ) - ); - } - } + $updates = $this->get_updates( $assoc_args ); if ( $updates ) { $updates = array_reverse( $updates ); $formatter = new \WP_CLI\Formatter( @@ -1088,25 +1037,77 @@ private function get_download_url($version, $locale = 'en_US', $file_type = 'zip } /** - * Compare processed releases to the current one, and delete older one. Return remaining updates. - * + * Returns update information */ - private function remove_same_minor_releases( $release_parts, $updates ) { - if ( empty( $updates ) ) - return false; + private function get_updates( $assoc_args ) { + global $wp_version; + $versions_path = ABSPATH . 'wp-includes/version.php'; + include $versions_path; + + $url = 'https://api.wordpress.org/core/stable-check/1.0/'; + + $options = array( + 'timeout' => 30 + ); + $headers = array( + 'Accept' => 'application/json' + ); + $response = Utils\http_request( 'GET', $url, $headers, $options ); + + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( "Failed to get latest version list." ); + } + + $release_data = json_decode( $response->body ); + $release_versions = array_keys( (array) $release_data ); + usort( $release_versions, function( $a, $b ){ + return 1 === version_compare( $a, $b ); + }); + + $locale = get_locale(); + $compare_version = str_replace( '-src', '', $GLOBALS['wp_version'] ); + + $updates = array( + 'major' => false, + 'minor' => false, + ); + foreach ( $release_versions as $release_version ) { - $difference = array(); - foreach ( $updates as $processed ) { - $processed_parts = explode( '.', $processed['version'] ); + $update_type = Utils\get_named_sem_ver( $release_version, $compare_version ); + if ( ! $update_type ) { + continue; + } - // later releases are always later in the array - if ( $processed_parts[0] !== $release_parts[0] - || $processed_parts[1] !== $release_parts[1] ) { - $difference[] = $processed; + // WordPress follow its own versioning which is roughly equivalent to semver + if ( 'minor' === $update_type ) { + $update_type = 'major'; + } else if ( 'patch' === $update_type ) { + $update_type = 'minor'; } + + if ( ! empty( $updates[ $update_type ] ) && ! Comparator::greaterThan( $release_version, $updates[ $update_type ]['version'] ) ) { + continue; + } + + $updates[ $update_type ] = array( + 'version' => $release_version, + 'update_type' => $update_type, + 'package_url' => $this->get_download_url( $release_version, $locale ) + ); } - return $difference; + foreach( $updates as $type => $value ) { + if ( empty( $value ) ) { + unset( $updates[ $type ] ); + } + } + + foreach( array( 'major', 'minor' ) as $type ) { + if ( true === \WP_CLI\Utils\get_flag_value( $assoc_args, $type ) ) { + return ! empty( $updates[ $type ] ) ? array( $updates[ $type ] ) : false; + } + } + return array_values( $updates ); } } From ebf9b59de75fd365b8a4a25703450ebcd61457b3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 4 Dec 2015 15:22:30 -0800 Subject: [PATCH 3884/4858] Use `--minor` flag with `wp core update` to update to latest minor --- features/core.feature | 19 +++++++++++++++++++ php/commands/core.php | 15 ++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 74e45feaa3..24f61c1c55 100644 --- a/features/core.feature +++ b/features/core.feature @@ -369,6 +369,25 @@ Feature: Manage WordPress installation 1 """ + @download + Scenario: Update to the latest minor release + Given a WP install + + When I run `wp core download --version=3.8 --force` + Then STDOUT should not be empty + + When I run `wp core update --minor` + Then STDOUT should contain: + """ + Downloading update + """ + + When I run `wp core update --minor` + Then STDOUT should be: + """ + Success: WordPress is at the latest minor release. + """ + Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory diff --git a/php/commands/core.php b/php/commands/core.php index 59b784cb1b..91ab75080e 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -847,8 +847,11 @@ public function verify_checksums( $args, $assoc_args ) { * [<zip>] * : Path to zip file to use, instead of downloading from wordpress.org. * + * [--minor] + * : Only perform updates for minor releases. + * * [--version=<version>] - * : Update to this version, instead of to the latest version. + * : Update to a specific version, instead of to the latest version. * * [--force] * : Update even when installed WP version is greater than the requested version. @@ -872,6 +875,16 @@ function update( $args, $assoc_args ) { $update = $from_api = null; $upgrader = 'WP_CLI\\CoreUpgrader'; + if ( empty( $args[0] ) && empty( $assoc_args['version'] ) && \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) ) { + $updates = $this->get_updates( array( 'minor' => true ) ); + if ( ! empty( $updates ) ) { + $assoc_args['version'] = $updates['version']; + } else { + WP_CLI::success( 'WordPress is at the latest minor release.' ); + return; + } + } + if ( ! empty( $args[0] ) ) { $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; From 6450d322020a4f8fee372844b29b601236623670 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 08:08:05 -0800 Subject: [PATCH 3885/4858] Increase minimum supported WP version to 3.7.11 --- .travis.yml | 4 ++-- php/WP_CLI/Runner.php | 2 +- php/wp-settings-cli.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c058d4068a..90ef902217 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,9 +33,9 @@ env: matrix: include: - php: 5.3 - env: WP_VERSION=3.5.2 DEPLOY_BRANCH=master + env: WP_VERSION=3.7.11 DEPLOY_BRANCH=master - php: 5.6 - env: WP_VERSION=3.5.2 + env: WP_VERSION=3.7.11 - php: 5.6 env: WP_VERSION=latest - php: 5.6 diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 799518ed32..1de58f5735 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -513,7 +513,7 @@ private function check_wp_version() { include ABSPATH . 'wp-includes/version.php'; - $minimum_version = '3.5.2'; + $minimum_version = '3.7'; // @codingStandardsIgnoreStart if ( version_compare( $wp_version, $minimum_version, '<' ) ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 544f2cfb52..f4f23c4bab 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -199,7 +199,7 @@ require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/embed.php' ); -Utils\maybe_require( '3.5-alpha-22024', ABSPATH . WPINC . '/class-wp-embed.php' ); +require( ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); Utils\maybe_require( '4.4-alpha-34903', ABSPATH . WPINC . '/class-wp-oembed-controller.php' ); require( ABSPATH . WPINC . '/http.php' ); From 1a2a438b960669360e83fd7c88e666d14642c866 Mon Sep 17 00:00:00 2001 From: Steve Persch <steve.persch@pantheon.io> Date: Sun, 6 Dec 2015 14:48:41 -0500 Subject: [PATCH 3886/4858] Writing a behat test to cover https://github.com/wp-cli/wp-cli/issues/2246 --- features/menu.feature | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index 8c0f059bde..f2b554d6b1 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -111,3 +111,32 @@ Feature: Manage WordPress menus """ 0 """ + + Scenario: Preserve grandparent item as ancestor of child item when parent item is removed. + + When I run `wp menu create "Grandparent Test"` + Then STDOUT should not be empty + + When I run `wp menu item add-custom grandparent-test Grandparent http://example.com/grandparent --porcelain` + Then save STDOUT as {GRANDPARENT_ID} + + When I run `wp menu item add-custom grandparent-test Parent http://example.com/parent --porcelain --parent-id={GRANDPARENT_ID}` + Then save STDOUT as {PARENT_ID} + + When I run `wp menu item add-custom grandparent-test Child http://example.com/child --porcelain --parent-id={PARENT_ID}` + Then save STDOUT as {CHILD_ID} + + When I run `wp menu item list grandparent-test --fields=title,db_id,menu_item_parent` + Then STDOUT should be a table containing rows: + | title | db_id | menu_item_parent | + | Grandparent | {GRANDPARENT_ID} | 0 | + | Parent | {PARENT_ID} | {GRANDPARENT_ID} | + | Child | {CHILD_ID} | {PARENT_ID} | + + When I run `wp menu item delete {PARENT_ID}` + + When I run `wp menu item list grandparent-test --fields=title,db_id,menu_item_parent` + Then STDOUT should be a table containing rows: + | title | db_id | menu_item_parent | + | Grandparent | {GRANDPARENT_ID} | 0 | + | Child | {CHILD_ID} | {GRANDPARENT_ID} | From 667d6e67a26765278f901c34c5ef39494ee13c5d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 08:42:20 -0800 Subject: [PATCH 3887/4858] Properly update menu sub-item parent when parent is deleted --- php/commands/menu.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index fd1a5428e9..33cfcf0fa3 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -476,12 +476,23 @@ public function update( $args, $assoc_args ) { * @subcommand delete */ public function delete( $args, $_ ) { + global $wpdb; foreach( $args as $arg ) { + $parent_menu_id = (int) get_post_meta( $arg, '_menu_item_menu_item_parent', true ); $ret = wp_delete_post( $arg, true ); if ( ! $ret ) { WP_CLI::warning( "Couldn't delete menu item." ); + } else if ( $parent_menu_id ) { + $children = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value=%s", (int) $arg ) ); + if ( $children ) { + $children_query = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = %d WHERE meta_key = '_menu_item_menu_item_parent' AND meta_value=%s", $parent_menu_id, (int) $arg ); + $wpdb->query( $children_query ); + foreach( $children as $child ) { + clean_post_cache( $child ); + } + } } } From 52541f32f74870e182763b1253b5ae56d19d8a8e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 09:10:47 -0800 Subject: [PATCH 3888/4858] Only call `wp core language update` when WP >= 4.0 The utility isn't available before then. --- php/WP_CLI/CommandWithUpgrade.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 8d988e2ce5..b265e370b9 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -14,7 +14,9 @@ function __construct() { // After updating plugins/themes also update translations by running the `core language update` command. add_action( 'upgrader_process_complete', function() { remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); - \WP_CLI::run_command( array( 'core', 'language', 'update' ), array( 'dry-run' => false ) ); + if ( Utils\wp_version_compare( '4.0', '>=' ) ) { + \WP_CLI::run_command( array( 'core', 'language', 'update' ), array( 'dry-run' => false ) ); + } }, 1 ); } From 17e2877090b999bc65cc6dca215421fd677cfd1d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 10:58:10 -0800 Subject: [PATCH 3889/4858] Defer to `$PAGER` environment variable when set Doing so gives more control to the end user on how their output will be presented. --- php/commands/help.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 5b2c3cf5eb..4894c54f3e 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -91,7 +91,9 @@ private static function indent( $whitespace, $text ) { private static function pass_through_pager( $out ) { - $pager = Utils\is_windows() ? 'more' : 'less -r'; + if ( false === ( $pager = getenv( 'PAGER' ) ) ) { + $pager = Utils\is_windows() ? 'more' : 'less -r'; + } // convert string to file handle $fd = fopen( "php://temp", "r+" ); From fabbf7b75050ccda7b458ee6784fd90d4eb3b255 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 11:35:35 -0800 Subject: [PATCH 3890/4858] Delete all post or user meta with `--all` flag --- features/post-meta.feature | 33 ++++++++++++++++++++++++++++ php/WP_CLI/CommandWithMeta.php | 39 ++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/features/post-meta.feature b/features/post-meta.feature index 74b30eabc6..307edf060e 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -62,3 +62,36 @@ Feature: Manage post custom fields | 1 | apple | banana | | 1 | apple | banana | | 1 | banana | ["apple","apple"] | + + Scenario: Delete all post meta + Given a WP install + + When I run `wp post meta add 1 apple banana` + And I run `wp post meta add 1 _foo banana` + Then STDOUT should not be empty + + When I run `wp post meta list 1 --format=count` + Then STDOUT should be: + """ + 2 + """ + + When I try `wp post meta delete 1` + Then STDERR should be: + """ + Error: Please specify a meta key, or use the --all flag. + """ + + When I run `wp post meta delete 1 --all` + Then STDOUT should contain: + """ + Deleted 'apple' custom field. + Deleted '_foo' custom field. + Success: Deleted all custom fields. + """ + + When I run `wp post meta list 1 --format=count` + Then STDOUT should be: + """ + 0 + """ diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 15824298d2..0e8a07a39a 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -107,25 +107,50 @@ public function get( $args, $assoc_args ) { * <id> * : The ID of the object. * - * <key> + * [<key>] * : The name of the meta field to delete. * * [<value>] * : The value to delete. If omitted, all rows with key will deleted. + * + * [--all] + * : Delete all meta for the object. */ public function delete( $args, $assoc_args ) { - list( $object_id, $meta_key ) = $args; + list( $object_id ) = $args; + $meta_key = ! empty( $args[1] ) ? $args[1] : ''; $meta_value = ! empty( $args[2] ) ? $args[2] : ''; - $object_id = $this->check_object_id( $object_id ); + if ( empty( $meta_key ) && ! Utils\get_flag_value( $assoc_args, 'all' ) ) { + WP_CLI::error( 'Please specify a meta key, or use the --all flag.' ); + } - $success = delete_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + $object_id = $this->check_object_id( $object_id ); - if ( $success ) { - WP_CLI::success( "Deleted custom field." ); + if ( Utils\get_flag_value( $assoc_args, 'all' ) ) { + $errors = false; + foreach( get_metadata( $this->meta_type, $object_id ) as $meta_key => $values ) { + $success = delete_metadata( $this->meta_type, $object_id, $meta_key ); + if ( $success ) { + WP_CLI::log( "Deleted '{$meta_key}' custom field." ); + } else { + WP_CLI::warning( "Failed to delete '{$meta_key}' custom field." ); + $errors = true; + } + } + if ( $errors ) { + WP_CLI::error( 'Failed to delete all custom fields.' ); + } else { + WP_CLI::success( 'Deleted all custom fields.' ); + } } else { - WP_CLI::error( "Failed to delete custom field." ); + $success = delete_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); + if ( $success ) { + WP_CLI::success( "Deleted custom field." ); + } else { + WP_CLI::error( "Failed to delete custom field." ); + } } } From 5d5c702434c653a58e63ce9f3b6b843ec8884a05 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 11:45:52 -0800 Subject: [PATCH 3891/4858] Document CSV values for `wp post list --post__in=<ids>` --- php/commands/post.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/post.php b/php/commands/post.php index 5a5198ce57..b0e9fadf8c 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -288,6 +288,8 @@ public function delete( $args, $assoc_args ) { * * wp post list --post_type=page,post --format=ids * + * wp post list --post__in=1,3 + * * @subcommand list */ public function list_( $_, $assoc_args ) { From cf8631cb6d800ae4dfd32221735a93f5667406c0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 12:54:08 -0800 Subject: [PATCH 3892/4858] A more helpful error message when a plugin or theme slug doesn't exist We can, more or less, safely interpret this `WP_Error` response to mean no matching plugins or themes. --- features/upgradables.feature | 6 ++++++ php/WP_CLI/CommandWithUpgrade.php | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 49c40a05f3..fd66e585db 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -175,6 +175,12 @@ Feature: Manage WordPress themes and plugins Showing 2 of """ + When I try `wp <type> install an-impossible-slug-because-abc3fr` + Then STDERR should contain: + """ + Warning: Couldn't find 'an-impossible-slug-because-abc3fr' in the WordPress.org <type> directory. + """ + Examples: | type | type_name | item | item_title | version | zip_file | file_to_check | | theme | Theme | p2 | P2 | 1.0.1 | https://wordpress.org/themes/download/p2.1.0.1.zip | {CONTENT_DIR}/p2/style.css | diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index b265e370b9..9b71ea1c7d 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -141,7 +141,14 @@ function install( $args, $assoc_args ) { $result = $this->install_from_repo( $slug, $assoc_args ); if ( is_wp_error( $result ) ) { - \WP_CLI::warning( "$slug: " . $result->get_error_message() ); + + $key = $result->get_error_code(); + if ( in_array( $result->get_error_code(), array( 'plugins_api_failed', 'themes_api_failed' ) ) + && ! empty( $result->error_data[ $key ] ) && in_array( $result->error_data[ $key ], array( 'N;', 'b:0;' ) ) ) { + \WP_CLI::warning( "Couldn't find '$slug' in the WordPress.org {$this->item_type} directory." ); + } else { + \WP_CLI::warning( "$slug: " . $result->get_error_message() ); + } } } From 45ad777d3ae7d193d4c53d4324d997bac9863708 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 12:58:57 -0800 Subject: [PATCH 3893/4858] Split `media import` and `media regenerate` into separate test files --- features/media-import.feature | 48 +++++++++++++++++++ ...media.feature => media-regenerate.feature} | 48 +------------------ 2 files changed, 50 insertions(+), 46 deletions(-) create mode 100644 features/media-import.feature rename features/{media.feature => media-regenerate.feature} (69%) diff --git a/features/media-import.feature b/features/media-import.feature new file mode 100644 index 0000000000..adc20bcafc --- /dev/null +++ b/features/media-import.feature @@ -0,0 +1,48 @@ +Feature: Manage WordPress attachments + + Background: + Given a WP install + + Scenario: Import image from remote URL + When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1` + Then STDOUT should contain: + """ + Success: Imported file http://wp-cli.org/behat-data/codeispoetry.png + """ + + Scenario: Fail to import missing image + When I try `wp media import gobbledygook.png` + Then STDERR should contain: + """ + Unable to import file gobbledygook.png. Reason: File doesn't exist. + """ + + Scenario: Import a file as attachment from a local image + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1 --featured_image` + Then STDOUT should contain: + """ + Success: Imported file + """ + And STDOUT should contain: + """ + and attached to post 1 as featured image + """ + And the {CACHE_DIR}/large-image.jpg file should exist + + Scenario: Import a file as an attachment but porcelain style + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + + When I run `wp post get {ATTACHMENT_ID} --field=title` + Then STDOUT should be: + """ + My imported attachment + """ diff --git a/features/media.feature b/features/media-regenerate.feature similarity index 69% rename from features/media.feature rename to features/media-regenerate.feature index c753624e27..a589b334e0 100644 --- a/features/media.feature +++ b/features/media-regenerate.feature @@ -1,5 +1,5 @@ -Feature: Manage WordPress attachments - +Feature: Regenerate WordPress attachments + Background: Given a WP install @@ -10,50 +10,6 @@ Feature: Manage WordPress attachments No images found. """ - Scenario: Import image from remote URL - When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1` - Then STDOUT should contain: - """ - Success: Imported file http://wp-cli.org/behat-data/codeispoetry.png - """ - - Scenario: Fail to import missing image - When I try `wp media import gobbledygook.png` - Then STDERR should contain: - """ - Unable to import file gobbledygook.png. Reason: File doesn't exist. - """ - - Scenario: Import a file as attachment from a local image - Given download: - | path | url | - | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | - - When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1 --featured_image` - Then STDOUT should contain: - """ - Success: Imported file - """ - And STDOUT should contain: - """ - and attached to post 1 as featured image - """ - And the {CACHE_DIR}/large-image.jpg file should exist - - Scenario: Import a file as an attachment but porcelain style - Given download: - | path | url | - | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | - - When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` - Then save STDOUT as {ATTACHMENT_ID} - - When I run `wp post get {ATTACHMENT_ID} --field=title` - Then STDOUT should be: - """ - My imported attachment - """ - Scenario: Delete existing thumbnails when media is regenerated Given download: | path | url | From 2e4c10d7eb3eb80ba5503f4ed04a115e9bd4b4ef Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Dec 2015 15:30:43 -0800 Subject: [PATCH 3894/4858] Support `--fields=<fields>` for `wp rewrite list` --- features/rewrite.feature | 10 +++++++--- php/commands/rewrite.php | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index d2908d4f5b..f5c22050d5 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -29,10 +29,14 @@ Feature: Manage WordPress rewrites | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | | section/(.+?)/?$ | index.php?category_name=$matches[1] | category | - When I run `wp rewrite list --match=/topic/apple/ --format=csv` + When I run `wp rewrite list --match=/topic/apple/ --format=csv --fields=match,query` Then STDOUT should be CSV containing: - | match | query | source | - | topic/([^/]+)/?$ | index.php?tag=$matches[1] | post_tag | + | match | query | + | topic/([^/]+)/?$ | index.php?tag=$matches[1] | + And STDOUT should not contain: + """ + source + """ Scenario: Missing permalink_structure Given a WP install diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index ed0e046cd5..db2c9946fb 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -151,6 +151,9 @@ public function structure( $args, $assoc_args ) { * [--source=<source>] * : Show rewrite rules from a particular source. * + * [--fields=<fields>] + * : Limit the output to specific fields. Defaults to match,query,source. + * * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * @@ -172,7 +175,8 @@ public function list_( $args, $assoc_args ) { $defaults = array( 'source' => '', 'match' => '', - 'format' => 'table' + 'format' => 'table', + 'fields' => 'match,query,source', ); $assoc_args = array_merge( $defaults, $assoc_args ); @@ -221,7 +225,7 @@ public function list_( $args, $assoc_args ) { $rule_list[] = compact( 'match', 'query', 'source' ); } - WP_CLI\Utils\format_items( $assoc_args['format'], $rule_list, array('match', 'query', 'source' ) ); + WP_CLI\Utils\format_items( $assoc_args['format'], $rule_list, explode( ',', $assoc_args['fields'] ) ); } /** From a0c795fd593c5bd5cdad5aea1904d9b16e319e02 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <ernilambar@users.noreply.github.com> Date: Wed, 9 Dec 2015 10:21:09 +0545 Subject: [PATCH 3895/4858] Fixing spacing around parenthesis --- templates/child_theme_functions.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/child_theme_functions.mustache b/templates/child_theme_functions.mustache index 395cf0deff..d654c23db1 100644 --- a/templates/child_theme_functions.mustache +++ b/templates/child_theme_functions.mustache @@ -6,7 +6,7 @@ function {{parent_theme_function_safe}}_parent_theme_enqueue_styles() { wp_enqueue_style( '{{parent_theme}}-style', get_template_directory_uri() . '/style.css' ); wp_enqueue_style( '{{slug}}-style', get_stylesheet_directory_uri() . '/style.css', - array('{{parent_theme}}-style') + array( '{{parent_theme}}-style' ) ); } From db0f3249ce0f05c96eb732e967e8e3dc39fe05a4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 05:13:03 -0800 Subject: [PATCH 3896/4858] Update tests for WordPress 4.4 --- features/core.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core.feature b/features/core.feature index 24f61c1c55..db1d4403bf 100644 --- a/features/core.feature +++ b/features/core.feature @@ -338,7 +338,7 @@ Feature: Manage WordPress installation When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.3.1 | major | https://wordpress.org/wordpress-4.3.1.zip | + | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | When I run `wp core check-update --format=count` @@ -350,7 +350,7 @@ Feature: Manage WordPress installation When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.3.1 | major | https://wordpress.org/wordpress-4.3.1.zip | + | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: From ff2e5b30a5746d25a2ba9001d0fbc4b71331e48e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 05:16:48 -0800 Subject: [PATCH 3897/4858] Split `core download` tests into a separate feature file --- features/core-download.feature | 69 +++++++++++++++++++++++++++++++++ features/core.feature | 70 ---------------------------------- 2 files changed, 69 insertions(+), 70 deletions(-) create mode 100644 features/core-download.feature diff --git a/features/core-download.feature b/features/core-download.feature new file mode 100644 index 0000000000..c36801b825 --- /dev/null +++ b/features/core-download.feature @@ -0,0 +1,69 @@ +Feature: Download WordPress + + Scenario: Empty dir + Given an empty directory + And an empty cache + + When I try `wp core is-installed` + Then the return code should be 1 + And STDERR should not be empty + + When I run `wp core download` + And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} + Then the wp-settings.php file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-en_US.tar.gz file should exist + + When I run `mkdir inner` + And I run `cd inner && wp core download` + Then the inner/wp-settings.php file should exist + + # test core tarball cache + When I run `wp core download --force` + Then the wp-settings.php file should exist + And STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/core/wordpress-{VERSION}-en_US.tar.gz'... + """ + + Scenario: Localized install + Given an empty directory + And an empty cache + When I run `wp core download --locale=de_DE` + And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} + Then the wp-settings.php file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-de_DE.tar.gz file should exist + + Scenario: Catch download of non-existent WP version + Given an empty directory + + When I try `wp core download --version=4.1.0 --force` + Then STDERR should contain: + """ + Error: Release not found. + """ + + Scenario: Core download to a directory specified by `--path` in custom command + Given a WP install + And a download-command.php file: + """ + <?php + class Download_Command extends WP_CLI_Command { + public function __invoke() { + WP_CLI::run_command( array( 'core', 'download' ), array( 'path' => 'src/' ) ); + } + } + WP_CLI::add_command( 'custom-download', 'Download_Command' ); + """ + + When I run `wp --require=download-command.php custom-download` + Then STDOUT should not be empty + And the src directory should contain: + """ + wp-load.php + """ + + When I try `wp --require=download-command.php custom-download` + Then STDERR should be: + """ + Error: WordPress files seem to already be present here. + """ diff --git a/features/core.feature b/features/core.feature index db1d4403bf..079581e65c 100644 --- a/features/core.feature +++ b/features/core.feature @@ -1,40 +1,5 @@ Feature: Manage WordPress installation - @download - Scenario: Empty dir - Given an empty directory - And an empty cache - - When I try `wp core is-installed` - Then the return code should be 1 - And STDERR should not be empty - - When I run `wp core download` - And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} - Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-en_US.tar.gz file should exist - - When I run `mkdir inner` - And I run `cd inner && wp core download` - Then the inner/wp-settings.php file should exist - - # test core tarball cache - When I run `wp core download --force` - Then the wp-settings.php file should exist - And STDOUT should contain: - """ - Using cached file '{SUITE_CACHE_DIR}/core/wordpress-{VERSION}-en_US.tar.gz'... - """ - - @download - Scenario: Localized install - Given an empty directory - And an empty cache - When I run `wp core download --locale=de_DE` - And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} - Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-de_DE.tar.gz file should exist - Scenario: No wp-config.php Given an empty directory And WP files @@ -461,15 +426,6 @@ Feature: Manage WordPress installation http://localhost:8001 """ - Scenario: Catch download of non-existent WP version - Given an empty directory - - When I try `wp core download --version=4.1.0 --force` - Then STDERR should contain: - """ - Error: Release not found. - """ - Scenario: Test output in a multisite install with custom base path Given a WP install @@ -480,32 +436,6 @@ Feature: Manage WordPress installation Hello world! """ - Scenario: Core download to a directory specified by `--path` in custom command - Given a WP install - And a download-command.php file: - """ - <?php - class Download_Command extends WP_CLI_Command { - public function __invoke() { - WP_CLI::run_command( array( 'core', 'download' ), array( 'path' => 'src/' ) ); - } - } - WP_CLI::add_command( 'custom-download', 'Download_Command' ); - """ - - When I run `wp --require=download-command.php custom-download` - Then STDOUT should not be empty - And the src directory should contain: - """ - wp-load.php - """ - - When I try `wp --require=download-command.php custom-download` - Then STDERR should be: - """ - Error: WordPress files seem to already be present here. - """ - Scenario: Ensure cached partial upgrades aren't used in full upgrade Given a WP install And an empty cache From 4cc8b046d6abc97d2467cbf673eafcd627fba2ce Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 05:19:41 -0800 Subject: [PATCH 3898/4858] Split `core config` tests into a separate feature file --- features/core-config.feature | 62 ++++++++++++++++++++++++++++++++++++ features/core.feature | 61 ----------------------------------- 2 files changed, 62 insertions(+), 61 deletions(-) create mode 100644 features/core-config.feature diff --git a/features/core-config.feature b/features/core-config.feature new file mode 100644 index 0000000000..d940433e53 --- /dev/null +++ b/features/core-config.feature @@ -0,0 +1,62 @@ +Feature: Manage wp-config + + Scenario: No wp-config.php + Given an empty directory + And WP files + + When I try `wp core is-installed` + Then the return code should be 1 + And STDERR should not be empty + + When I run `wp core version` + Then STDOUT should not be empty + + When I try `wp core install` + Then the return code should be 1 + And STDERR should be: + """ + Error: wp-config.php not found. + Either create one manually or use `wp core config`. + """ + + Given a wp-config-extra.php file: + """ + define( 'WP_DEBUG_LOG', true ); + """ + When I run `wp core config {CORE_CONFIG_SETTINGS} --extra-php < wp-config-extra.php` + Then the wp-config.php file should contain: + """ + define('AUTH_SALT', + """ + And the wp-config.php file should contain: + """ + define( 'WP_DEBUG_LOG', true ); + """ + And the wp-config.php file should not contain: + """ + define( 'WPLANG', '' ); + """ + + When I try the previous command again + Then the return code should be 1 + And STDERR should not be empty + + Scenario: Configure with existing salts + Given an empty directory + And WP files + + When I run `wp core config {CORE_CONFIG_SETTINGS} --skip-salts --extra-php < /dev/null` + Then the wp-config.php file should not contain: + """ + define('AUTH_SALT', + """ + + Scenario: Define WPLANG when running WP < 4.0 + Given an empty directory + And I run `wp core download --version=3.9 --force` + + When I run `wp core config {CORE_CONFIG_SETTINGS}` + Then the wp-config.php file should contain: + """ + define('WPLANG', ''); + """ diff --git a/features/core.feature b/features/core.feature index 079581e65c..3c04a4826b 100644 --- a/features/core.feature +++ b/features/core.feature @@ -1,66 +1,5 @@ Feature: Manage WordPress installation - Scenario: No wp-config.php - Given an empty directory - And WP files - - When I try `wp core is-installed` - Then the return code should be 1 - And STDERR should not be empty - - When I run `wp core version` - Then STDOUT should not be empty - - When I try `wp core install` - Then the return code should be 1 - And STDERR should be: - """ - Error: wp-config.php not found. - Either create one manually or use `wp core config`. - """ - - Given a wp-config-extra.php file: - """ - define( 'WP_DEBUG_LOG', true ); - """ - When I run `wp core config {CORE_CONFIG_SETTINGS} --extra-php < wp-config-extra.php` - Then the wp-config.php file should contain: - """ - define('AUTH_SALT', - """ - And the wp-config.php file should contain: - """ - define( 'WP_DEBUG_LOG', true ); - """ - And the wp-config.php file should not contain: - """ - define( 'WPLANG', '' ); - """ - - When I try the previous command again - Then the return code should be 1 - And STDERR should not be empty - - Scenario: Configure with existing salts - Given an empty directory - And WP files - - When I run `wp core config {CORE_CONFIG_SETTINGS} --skip-salts --extra-php < /dev/null` - Then the wp-config.php file should not contain: - """ - define('AUTH_SALT', - """ - - Scenario: Define WPLANG when running WP < 4.0 - Given an empty directory - And I run `wp core download --version=3.9 --force` - - When I run `wp core config {CORE_CONFIG_SETTINGS}` - Then the wp-config.php file should contain: - """ - define('WPLANG', ''); - """ - Scenario: Database doesn't exist Given an empty directory And WP files From 270734e50d4aff9654b10b76c495b9db0e42a73d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 05:22:27 -0800 Subject: [PATCH 3899/4858] Split `core check-update` features into a separate file --- features/core-check-update.feature | 41 ++++++++++++++++++++++++++++++ features/core.feature | 41 ------------------------------ 2 files changed, 41 insertions(+), 41 deletions(-) create mode 100644 features/core-check-update.feature diff --git a/features/core-check-update.feature b/features/core-check-update.feature new file mode 100644 index 0000000000..4d6acc2360 --- /dev/null +++ b/features/core-check-update.feature @@ -0,0 +1,41 @@ +Feature: Check for more recent versions + + Scenario: Check for update via Version Check API + Given a WP install + + When I run `wp core download --version=3.8 --force` + Then STDOUT should not be empty + + When I run `wp core check-update` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | + | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | + + When I run `wp core check-update --format=count` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp core check-update --major` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | + + When I run `wp core check-update --major --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp core check-update --minor` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | + + When I run `wp core check-update --minor --format=count` + Then STDOUT should be: + """ + 1 + """ diff --git a/features/core.feature b/features/core.feature index 3c04a4826b..2749168b83 100644 --- a/features/core.feature +++ b/features/core.feature @@ -232,47 +232,6 @@ Feature: Manage WordPress installation 3.9 """ - @download @update-check - Scenario: Check for update via Version Check API - Given a WP install - - When I run `wp core download --version=3.8 --force` - Then STDOUT should not be empty - - When I run `wp core check-update` - Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | - | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | - - When I run `wp core check-update --format=count` - Then STDOUT should be: - """ - 2 - """ - - When I run `wp core check-update --major` - Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | - - When I run `wp core check-update --major --format=count` - Then STDOUT should be: - """ - 1 - """ - - When I run `wp core check-update --minor` - Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | - - When I run `wp core check-update --minor --format=count` - Then STDOUT should be: - """ - 1 - """ - @download Scenario: Update to the latest minor release Given a WP install From b51bac798186ce61c474734efae2094555cc5ec5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 05:25:33 -0800 Subject: [PATCH 3900/4858] Split `core update` tests into a separate file --- features/core-update.feature | 151 +++++++++++++++++++++++++++++++++++ features/core.feature | 151 ----------------------------------- 2 files changed, 151 insertions(+), 151 deletions(-) create mode 100644 features/core-update.feature diff --git a/features/core-update.feature b/features/core-update.feature new file mode 100644 index 0000000000..0604fdb6e6 --- /dev/null +++ b/features/core-update.feature @@ -0,0 +1,151 @@ +Feature: Update WordPress core + + Scenario: Update from a ZIP file + Given a WP install + + When I run `wp core download --version=3.8 --force` + Then STDOUT should not be empty + + When I run `wp eval 'echo $GLOBALS["wp_version"];'` + Then STDOUT should be: + """ + 3.8 + """ + + When I run `wget http://wordpress.org/wordpress-3.9.zip --quiet` + And I run `wp core update wordpress-3.9.zip` + Then STDOUT should be: + """ + Starting update... + Unpacking the update... + Success: WordPress updated successfully. + """ + + When I run `wp eval 'echo $GLOBALS["wp_version"];'` + Then STDOUT should be: + """ + 3.9 + """ + + Scenario: Update to the latest minor release + Given a WP install + + When I run `wp core download --version=3.8 --force` + Then STDOUT should not be empty + + When I run `wp core update --minor` + Then STDOUT should contain: + """ + Downloading update + """ + + When I run `wp core update --minor` + Then STDOUT should be: + """ + Success: WordPress is at the latest minor release. + """ + + Scenario: Core update from cache + Given a WP install + And an empty cache + + When I run `wp core update --version=3.8.1 --force` + Then STDOUT should not contain: + """ + Using cached file + """ + And STDOUT should contain: + """ + Downloading + """ + + When I run `wp core update --version=3.9 --force` + Then STDOUT should not be empty + + When I run `wp core update --version=3.8.1 --force` + Then STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/core/wordpress-3.8.1-en_US.zip'... + """ + And STDOUT should not contain: + """ + Downloading + """ + + Scenario: Don't run update when up-to-date + Given a WP install + And I run `wp core update` + + When I run `wp core update` + Then STDOUT should contain: + """ + WordPress is up to date + """ + And STDOUT should not contain: + """ + Updating + """ + + When I run `wp core update --force` + Then STDOUT should contain: + """ + Updating + """ + + Scenario: Ensure cached partial upgrades aren't used in full upgrade + Given a WP install + And an empty cache + And a wp-content/mu-plugins/upgrade-override.php file: + """ + <?php + add_filter( 'pre_site_transient_update_core', function(){ + return (object) array( + 'updates' => array( + (object) array( + 'response' => 'autoupdate', + 'download' => 'https://downloads.wordpress.org/release/wordpress-4.2.4.zip', + 'locale' => 'en_US', + 'packages' => (object) array( + 'full' => 'https://downloads.wordpress.org/release/wordpress-4.2.4.zip', + 'no_content' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-no-content.zip', + 'new_bundled' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-new-bundled.zip', + 'partial' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-partial-1.zip', + 'rollback' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-rollback-1.zip', + ), + 'current' => '4.2.4', + 'version' => '4.2.4', + 'php_version' => '5.2.4', + 'mysql_version' => '5.0', + 'new_bundled' => '4.1', + 'partial_version' => '4.2.1', + 'support_email' => 'updatehelp42@wordpress.org', + 'new_files' => '', + ), + ), + ); + }); + """ + + When I run `wp core download --version=4.2.1 --force` + And I run `wp core update` + Then STDOUT should not be empty + And the {SUITE_CACHE_DIR}/core directory should contain: + """ + wordpress-4.2.1-en_US.tar.gz + wordpress-4.2.4-partial-1-en_US.zip + """ + + When I run `wp core download --version=4.1.1 --force` + And I run `wp core update` + And I run `wp core verify-checksums` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ + And the {SUITE_CACHE_DIR}/core directory should contain: + """ + wordpress-4.1.1-en_US.tar.gz + wordpress-4.2.1-en_US.tar.gz + wordpress-4.2.4-no-content-en_US.zip + wordpress-4.2.4-partial-1-en_US.zip + """ diff --git a/features/core.feature b/features/core.feature index 2749168b83..13331c1c5d 100644 --- a/features/core.feature +++ b/features/core.feature @@ -205,52 +205,6 @@ Feature: Manage WordPress installation Error: Multisite with subdomains cannot be configured when domain is 'localhost'. """ - Scenario: Update from a ZIP file - Given a WP install - - When I run `wp core download --version=3.8 --force` - Then STDOUT should not be empty - - When I run `wp eval 'echo $GLOBALS["wp_version"];'` - Then STDOUT should be: - """ - 3.8 - """ - - When I run `wget http://wordpress.org/wordpress-3.9.zip --quiet` - And I run `wp core update wordpress-3.9.zip` - Then STDOUT should be: - """ - Starting update... - Unpacking the update... - Success: WordPress updated successfully. - """ - - When I run `wp eval 'echo $GLOBALS["wp_version"];'` - Then STDOUT should be: - """ - 3.9 - """ - - @download - Scenario: Update to the latest minor release - Given a WP install - - When I run `wp core download --version=3.8 --force` - Then STDOUT should not be empty - - When I run `wp core update --minor` - Then STDOUT should contain: - """ - Downloading update - """ - - When I run `wp core update --minor` - Then STDOUT should be: - """ - Success: WordPress is at the latest minor release. - """ - Scenario: Custom wp-content directory Given a WP install And a custom wp-content directory @@ -258,53 +212,6 @@ Feature: Manage WordPress installation When I run `wp plugin status hello` Then STDOUT should not be empty - Scenario: Core update from cache - Given a WP install - And an empty cache - - When I run `wp core update --version=3.8.1 --force` - Then STDOUT should not contain: - """ - Using cached file - """ - And STDOUT should contain: - """ - Downloading - """ - - When I run `wp core update --version=3.9 --force` - Then STDOUT should not be empty - - When I run `wp core update --version=3.8.1 --force` - Then STDOUT should contain: - """ - Using cached file '{SUITE_CACHE_DIR}/core/wordpress-3.8.1-en_US.zip'... - """ - And STDOUT should not contain: - """ - Downloading - """ - - Scenario: Don't run update when up-to-date - Given a WP install - And I run `wp core update` - - When I run `wp core update` - Then STDOUT should contain: - """ - WordPress is up to date - """ - And STDOUT should not contain: - """ - Updating - """ - - When I run `wp core update --force` - Then STDOUT should contain: - """ - Updating - """ - Scenario: User defined in wp-cli.yml Given an empty directory And WP files @@ -333,61 +240,3 @@ Feature: Manage WordPress installation """ Hello world! """ - - Scenario: Ensure cached partial upgrades aren't used in full upgrade - Given a WP install - And an empty cache - And a wp-content/mu-plugins/upgrade-override.php file: - """ - <?php - add_filter( 'pre_site_transient_update_core', function(){ - return (object) array( - 'updates' => array( - (object) array( - 'response' => 'autoupdate', - 'download' => 'https://downloads.wordpress.org/release/wordpress-4.2.4.zip', - 'locale' => 'en_US', - 'packages' => (object) array( - 'full' => 'https://downloads.wordpress.org/release/wordpress-4.2.4.zip', - 'no_content' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-no-content.zip', - 'new_bundled' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-new-bundled.zip', - 'partial' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-partial-1.zip', - 'rollback' => 'https://downloads.wordpress.org/release/wordpress-4.2.4-rollback-1.zip', - ), - 'current' => '4.2.4', - 'version' => '4.2.4', - 'php_version' => '5.2.4', - 'mysql_version' => '5.0', - 'new_bundled' => '4.1', - 'partial_version' => '4.2.1', - 'support_email' => 'updatehelp42@wordpress.org', - 'new_files' => '', - ), - ), - ); - }); - """ - - When I run `wp core download --version=4.2.1 --force` - And I run `wp core update` - Then STDOUT should not be empty - And the {SUITE_CACHE_DIR}/core directory should contain: - """ - wordpress-4.2.1-en_US.tar.gz - wordpress-4.2.4-partial-1-en_US.zip - """ - - When I run `wp core download --version=4.1.1 --force` - And I run `wp core update` - And I run `wp core verify-checksums` - Then STDOUT should be: - """ - Success: WordPress install verifies against checksums. - """ - And the {SUITE_CACHE_DIR}/core directory should contain: - """ - wordpress-4.1.1-en_US.tar.gz - wordpress-4.2.1-en_US.tar.gz - wordpress-4.2.4-no-content-en_US.zip - wordpress-4.2.4-partial-1-en_US.zip - """ From d3837e2023ffb9fcd051927b44a726bd38d1c864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 9 Dec 2015 16:38:25 +0100 Subject: [PATCH 3901/4858] Directing "issue openers" to wiki/How-to-solve-an-issue --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4063c75926..ae19809443 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ Submitting patches Whether you want to fix a bug or implement a new feature, the process is pretty much the same: -0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, open a new issue so that you can get some initial feedback. +0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, [open a new issue](https://github.com/wp-cli/wp-cli/wiki/How-to-solve-an-issue) so that you can get some initial feedback. 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. 2. Create a branch for each issue you'd like to address. Commit your changes. 3. Push the code changes from your local clone to your fork. From 0fdb6eaed1a04d16b42574df607bbd7a3e2d0e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Wed, 9 Dec 2015 16:50:46 +0100 Subject: [PATCH 3902/4858] Rename of my rude Wiki page --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae19809443..292dd1b8e0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ Submitting patches Whether you want to fix a bug or implement a new feature, the process is pretty much the same: -0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, [open a new issue](https://github.com/wp-cli/wp-cli/wiki/How-to-solve-an-issue) so that you can get some initial feedback. +0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, [open a new issue](https://github.com/wp-cli/wp-cli/wiki/Creating-Helpful-Bug-Reports) so that you can get some initial feedback. 1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. 2. Create a branch for each issue you'd like to address. Commit your changes. 3. Push the code changes from your local clone to your fork. From e2e234fa9495ee13704a622e7621737b17f136f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 07:53:15 -0800 Subject: [PATCH 3903/4858] Load `utils-wp.php` right before `wp-settings-cli.php` is called This helps to reduce the difference between `wp-settings-cli.php` and `wp-settings.php`. It has no functional differences. --- php/WP_CLI/Runner.php | 3 +++ php/wp-settings-cli.php | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 1de58f5735..444ebc2c05 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -732,6 +732,9 @@ public function load_wordpress() { $this->maybe_update_url_from_domain_constant(); + // Load WP-CLI utilities + require WP_CLI_ROOT . '/php/utils-wp.php'; + // Load Core, mu-plugins, plugins, themes etc. require WP_CLI_ROOT . '/php/wp-settings-cli.php'; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index f4f23c4bab..953cd04ba3 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -55,9 +55,6 @@ // Start loading timer. timer_start(); -// Load WP-CLI utilities -require WP_CLI_ROOT . '/php/utils-wp.php'; - // Check if we're in WP_DEBUG mode. Utils\wp_debug_mode(); From d13bff6bbf1fc0375f69b43855fe5f8e6d4155c9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 9 Dec 2015 09:07:31 -0800 Subject: [PATCH 3904/4858] Don't ever prefix rewrite rules with `index.php` Core does some fancy logic to determine whether `index.php` needs to be prepended to rewrite rules. `got_url_rewrite()` returns true if mod rewrite is available or `$GLOBALS['is_nginx']` is set. However, php-cli doesn't easily have access to these values. Instead, let's assume the developer knows the value they're passing, and that rewrites are configured for the site. --- php/commands/rewrite.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index db2c9946fb..f0b9ca09bd 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -81,12 +81,8 @@ public function structure( $args, $assoc_args ) { global $wp_rewrite; // copypasta from /wp-admin/options-permalink.php - $home_path = get_home_path(); - $iis7_permalinks = iis7_supports_permalinks(); $prefix = $blog_prefix = ''; - if ( ! got_mod_rewrite() && ! $iis7_permalinks ) - $prefix = '/index.php'; if ( is_multisite() && !is_subdomain_install() && is_main_site() ) $blog_prefix = '/blog'; From 1806acc122944ff1a0dc08cde20d65b81798ae9f Mon Sep 17 00:00:00 2001 From: Greg Anderson <greg.1.anderson@greenknowe.org> Date: Wed, 9 Dec 2015 09:30:58 -0800 Subject: [PATCH 3905/4858] Commit composer.lock to repository. --- .gitignore | 1 - composer.lock | 1240 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1240 insertions(+), 1 deletion(-) create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 665e3e8afa..27990f8353 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -composer.lock config.yml /cache /vendor diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..7c51a4dda1 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1240 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "7359993f535213af66c2148ea27369b3", + "content-hash": "da7f9e8dee2ffe0f76e5ed64233ecda9", + "packages": [ + { + "name": "composer/semver", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com" + }, + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2015-09-21 09:42:36" + }, + { + "name": "mustache/mustache", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/mustache.php.git", + "reference": "c745b01956caf27d26b55a72a90aff56bc169cd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/c745b01956caf27d26b55a72a90aff56bc169cd6", + "reference": "c745b01956caf27d26b55a72a90aff56bc169cd6", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "require-dev": { + "fabpot/php-cs-fixer": "~1.6", + "phpunit/phpunit": "~3.7|~4.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Mustache": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "A Mustache implementation in PHP.", + "homepage": "https://github.com/bobthecow/mustache.php", + "keywords": [ + "mustache", + "templating" + ], + "time": "2015-08-15 19:23:13" + }, + { + "name": "nb/oxymel", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/nb/oxymel.git", + "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nb/oxymel/zipball/cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", + "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "type": "library", + "autoload": { + "psr-0": { + "Oxymel": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nikolay Bachiyski", + "email": "nb@nikolay.bg", + "homepage": "http://extrapolate.me/" + } + ], + "description": "A sweet XML builder", + "homepage": "https://github.com/nb/oxymel", + "keywords": [ + "xml" + ], + "time": "2013-02-24 15:01:54" + }, + { + "name": "ramsey/array_column", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/ramsey/array_column.git", + "reference": "f8e52eb28e67eb50e613b451dd916abcf783c1db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/array_column/zipball/f8e52eb28e67eb50e613b451dd916abcf783c1db", + "reference": "f8e52eb28e67eb50e613b451dd916abcf783c1db", + "shasum": "" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.8.*", + "phpunit/phpunit": "~4.5", + "satooshi/php-coveralls": "0.6.*", + "squizlabs/php_codesniffer": "~2.2" + }, + "type": "library", + "autoload": { + "files": [ + "src/array_column.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "homepage": "http://benramsey.com" + } + ], + "description": "Provides functionality for array_column() to projects using PHP earlier than version 5.5.", + "homepage": "https://github.com/ramsey/array_column", + "keywords": [ + "array", + "array_column", + "column" + ], + "time": "2015-03-20 22:07:39" + }, + { + "name": "rmccue/requests", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/rmccue/Requests.git", + "reference": "6aac485666c2955077d77b796bbdd25f0013a4ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rmccue/Requests/zipball/6aac485666c2955077d77b796bbdd25f0013a4ea", + "reference": "6aac485666c2955077d77b796bbdd25f0013a4ea", + "shasum": "" + }, + "require": { + "php": ">=5.2" + }, + "require-dev": { + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "psr-0": { + "Requests": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Ryan McCue", + "homepage": "http://ryanmccue.info" + } + ], + "description": "A HTTP library written in PHP, for human beings.", + "homepage": "http://github.com/rmccue/Requests", + "keywords": [ + "curl", + "fsockopen", + "http", + "idna", + "ipv6", + "iri", + "sockets" + ], + "time": "2014-05-18 04:59:02" + }, + { + "name": "symfony/config", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "61973327bfb054f6f470de7be033a28b76c1dc20" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/61973327bfb054f6f470de7be033a28b76c1dc20", + "reference": "61973327bfb054f6f470de7be033a28b76c1dc20", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/filesystem": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2015-11-02 20:20:53" + }, + { + "name": "symfony/console", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "16bb1cb86df43c90931df65f529e7ebd79636750" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/16bb1cb86df43c90931df65f529e7ebd79636750", + "reference": "16bb1cb86df43c90931df65f529e7ebd79636750", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-11-18 09:54:26" + }, + { + "name": "symfony/dependency-injection", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "7a201bf08c29e47075047cbb378724ad46dfe217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7a201bf08c29e47075047cbb378724ad46dfe217", + "reference": "7a201bf08c29e47075047cbb378724ad46dfe217", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/expression-language": "<2.6" + }, + "require-dev": { + "symfony/config": "~2.2", + "symfony/expression-language": "~2.6", + "symfony/yaml": "~2.1" + }, + "suggest": { + "symfony/config": "", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2015-11-23 10:17:36" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "7e2f9c31645680026c2372edf66f863fc7757af5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7e2f9c31645680026c2372edf66f863fc7757af5", + "reference": "7e2f9c31645680026c2372edf66f863fc7757af5", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", + "symfony/stopwatch": "~2.3" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2015-10-30 20:10:21" + }, + { + "name": "symfony/filesystem", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "8e173509d7fdbbba3cf34d6d072f2073c0210c1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/8e173509d7fdbbba3cf34d6d072f2073c0210c1d", + "reference": "8e173509d7fdbbba3cf34d6d072f2073c0210c1d", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2015-11-18 13:41:01" + }, + { + "name": "symfony/finder", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/a06a0c0ff7db3736a50d530c908cca547bf13da9", + "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2015-10-30 20:10:21" + }, + { + "name": "symfony/translation", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", + "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.7", + "symfony/intl": "~2.4", + "symfony/yaml": "~2.2" + }, + "suggest": { + "psr/log": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2015-11-18 13:41:01" + }, + { + "name": "symfony/yaml", + "version": "v2.7.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "4cfcd7a9fceba662b3c036b7d9a91f6197af046c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4cfcd7a9fceba662b3c036b7d9a91f6197af046c", + "reference": "4cfcd7a9fceba662b3c036b7d9a91f6197af046c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2015-11-18 13:41:01" + }, + { + "name": "wp-cli/php-cli-tools", + "version": "v0.10.5", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/php-cli-tools.git", + "reference": "037a010441a5c220cd1df26cdc9b20ad73408356" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/037a010441a5c220cd1df26cdc9b20ad73408356", + "reference": "037a010441a5c220cd1df26cdc9b20ad73408356", + "shasum": "" + }, + "require": { + "php": ">= 5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "cli": "lib/" + }, + "files": [ + "lib/cli/cli.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Logsdon", + "email": "jlogsdon@php.net", + "role": "Developer" + }, + { + "name": "Daniel Bachhuber", + "email": "daniel@handbuilt.co", + "role": "Maintainer" + } + ], + "description": "Console utilities for PHP", + "homepage": "http://github.com/wp-cli/php-cli-tools", + "keywords": [ + "cli", + "console" + ], + "time": "2015-08-10 12:46:19" + } + ], + "packages-dev": [ + { + "name": "behat/behat", + "version": "v2.5.5", + "source": { + "type": "git", + "url": "https://github.com/Behat/Behat.git", + "reference": "c1e48826b84669c97a1efa78459aedfdcdcf2120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Behat/zipball/c1e48826b84669c97a1efa78459aedfdcdcf2120", + "reference": "c1e48826b84669c97a1efa78459aedfdcdcf2120", + "shasum": "" + }, + "require": { + "behat/gherkin": "~2.3.0", + "php": ">=5.3.1", + "symfony/config": "~2.3", + "symfony/console": "~2.0", + "symfony/dependency-injection": "~2.0", + "symfony/event-dispatcher": "~2.0", + "symfony/finder": "~2.0", + "symfony/translation": "~2.3", + "symfony/yaml": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.19" + }, + "suggest": { + "behat/mink-extension": "for integration with Mink testing framework", + "behat/symfony2-extension": "for integration with Symfony2 web framework", + "behat/yii-extension": "for integration with Yii web framework" + }, + "bin": [ + "bin/behat" + ], + "type": "library", + "autoload": { + "psr-0": { + "Behat\\Behat": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Scenario-oriented BDD framework for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Symfony2" + ], + "time": "2015-06-01 09:37:55" + }, + { + "name": "behat/gherkin", + "version": "v2.3.5", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "2b33963da5525400573560c173ab5c9c057e1852" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/2b33963da5525400573560c173ab5c9c057e1852", + "reference": "2b33963da5525400573560c173ab5c9c057e1852", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/finder": "~2.0" + }, + "require-dev": { + "symfony/config": "~2.0", + "symfony/translation": "~2.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "symfony/config": "If you want to use Config component to manage resources", + "symfony/translation": "If you want to use Symfony2 translations adapter", + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "DSL", + "Symfony2", + "parser" + ], + "time": "2013-10-15 11:22:17" + }, + { + "name": "phpunit/php-code-coverage", + "version": "1.2.18", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", + "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": ">=1.3.0@stable", + "phpunit/php-text-template": ">=1.2.0@stable", + "phpunit/php-token-stream": ">=1.1.3,<1.3.0" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*@dev" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.0.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2014-09-02 10:13:14" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2015-06-21 08:01:12" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2014-03-03 05:10:30" + }, + { + "name": "phpunit/phpunit", + "version": "3.7.38", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/38709dc22d519a3d1be46849868aa2ddf822bcf6", + "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": "~1.2", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.1", + "phpunit/php-timer": "~1.0", + "phpunit/phpunit-mock-objects": "~1.2", + "symfony/yaml": "~2.0" + }, + "require-dev": { + "pear-pear.php.net/pear": "1.9.4" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "composer/bin/phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2014-10-17 09:04:17" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875", + "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-text-template": ">=1.1.1@stable" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2013-01-13 10:24:48" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.2" + }, + "platform-dev": [] +} From 45a70610bf14f8e0be1ae588e3d6969242bd3e71 Mon Sep 17 00:00:00 2001 From: Ryan Hoover <ryanshoover@gmail.com> Date: Wed, 9 Dec 2015 14:46:45 -0600 Subject: [PATCH 3906/4858] Fix typo in function synopsis There's a typo in the synopsis for `set`. That typo is causing fatal errors in commands like `wp transient set "51ecb1f884" "Cache rules everything around me." "2592001"` Adding in the missing **>** fixes the problem. --- php/commands/transient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 4b6de95b0e..6331f633f8 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -40,7 +40,7 @@ public function get( $args, $assoc_args ) { * <value> * : Value to be set for the transient. * - * [<expiration] + * [<expiration>] * : Time until expiration, in seconds. */ public function set( $args ) { From 25418ce02e5337f311b19425ea377b5749ea2072 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 06:05:11 -0800 Subject: [PATCH 3907/4858] Failing test case for #2286 --- features/core-checksums.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/core-checksums.feature b/features/core-checksums.feature index 9c622976b1..055639275e 100644 --- a/features/core-checksums.feature +++ b/features/core-checksums.feature @@ -53,3 +53,13 @@ Feature: Validate checksums for WordPress install """ Error: WordPress install doesn't verify against checksums. """ + + Scenario: Verify core checksums for a non US local + Given a WP install + And I run `wp core download --locale=en_GB --version=4.3.1 --force` + + When I run `wp core verify-checksums` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ From 8fda3f656161fa5cf3b7b1f0db71963016beddfe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 06:08:28 -0800 Subject: [PATCH 3908/4858] Explicitly globalize `$wp_locale_package` This variable is included in non-US English locales --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 953cd04ba3..000db74a5f 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -21,7 +21,7 @@ * we're including version.php from another install and don't want * these values to be overridden if already set. */ -global $wp_version, $wp_db_version, $tinymce_version, $required_php_version, $required_mysql_version; +global $wp_version, $wp_db_version, $tinymce_version, $required_php_version, $required_mysql_version, $wp_local_package; require( ABSPATH . WPINC . '/version.php' ); /** From 666d9f91e88d7d2d9098977279fa779e8f1904aa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 06:10:26 -0800 Subject: [PATCH 3909/4858] Rename test file for consistency with command --- .../{core-checksums.feature => core-verify-checksums.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename features/{core-checksums.feature => core-verify-checksums.feature} (100%) diff --git a/features/core-checksums.feature b/features/core-verify-checksums.feature similarity index 100% rename from features/core-checksums.feature rename to features/core-verify-checksums.feature From 5c65b1e5460ae62829e622cfe12d4f0fa7d17f49 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 13:52:22 -0800 Subject: [PATCH 3910/4858] Use `--only-missing` to only regenerate images missing sizes This flag is helpful on sites with lots of images where only a small number of images are missing sizes. Props @michalkleiner for much of the original code --- features/media-regenerate.feature | 42 +++++++++++++++++++ php/commands/media.php | 70 ++++++++++++++++++++++++------- 2 files changed, 98 insertions(+), 14 deletions(-) diff --git a/features/media-regenerate.feature b/features/media-regenerate.feature index a589b334e0..a9048a1ff6 100644 --- a/features/media-regenerate.feature +++ b/features/media-regenerate.feature @@ -103,3 +103,45 @@ Feature: Regenerate WordPress attachments """ Warning: Can't find """ + + Scenario: Only regenerate images which are missing sizes + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + And a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 100, 100, true ); + }); + """ + And I run `wp option update uploads_use_yearmonth_folders 0` + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + And the wp-content/uploads/large-image-100x100.jpg file should exist + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My second imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID2} + And the wp-content/uploads/large-image-1-100x100.jpg file should exist + + When I run `rm wp-content/uploads/large-image-100x100.jpg` + Then the wp-content/uploads/large-image-100x100.jpg file should not exist + + When I run `wp media regenerate --only-missing --yes` + Then STDOUT should contain: + """ + Found 2 images to regenerate. + """ + And STDOUT should contain: + """ + No thumbnail regeneration needed for "My second imported attachment" + """ + And STDOUT should contain: + """ + Regenerated thumbnails for "My imported attachment" + """ + And STDOUT should contain: + """ + Success: Finished regenerating all images. + """ diff --git a/php/commands/media.php b/php/commands/media.php index 9d9ff7a536..3bb2becee3 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -18,6 +18,9 @@ class Media_Command extends WP_CLI_Command { * [--skip-delete] * : Skip deletion of the original thumbnails. If your thumbnails are linked from sources outside your control, it's likely best to leave them around. Defaults to false. * + * [--only-missing] + * : Only generate thumbnails for images missing image sizes. + * * [--yes] * : Answer yes to the confirmation message. * @@ -35,6 +38,10 @@ function regenerate( $args, $assoc_args = array() ) { } $skip_delete = \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-delete' ); + $only_missing = \WP_CLI\Utils\get_flag_value( $assoc_args, 'only-missing' ); + if ( $only_missing ) { + $skip_delete = true; + } $query_args = array( 'post_type' => 'attachment', @@ -59,7 +66,7 @@ function regenerate( $args, $assoc_args = array() ) { $errored = false; foreach ( $images->posts as $id ) { - if ( ! $this->_process_regeneration( $id, $skip_delete ) ) { + if ( ! $this->_process_regeneration( $id, $skip_delete, $only_missing ) ) { $errored = true; } } @@ -210,7 +217,7 @@ private function _make_copy( $path ) { return $filename; } - private function _process_regeneration( $id, $skip_delete = false ) { + private function _process_regeneration( $id, $skip_delete = false, $only_missing = false ) { $fullsizepath = get_attached_file( $id ); @@ -225,21 +232,27 @@ private function _process_regeneration( $id, $skip_delete = false ) { $this->remove_old_images( $id ); } - $metadata = wp_generate_attachment_metadata( $id, $fullsizepath ); - if ( is_wp_error( $metadata ) ) { - WP_CLI::warning( $metadata->get_error_message() ); - return false; - } + if ( ! $only_missing || $this->needs_regeneration( $id ) ) { - if ( empty( $metadata ) ) { - WP_CLI::warning( "Couldn't regenerate thumbnails for $att_desc." ); - return false; - } + $metadata = wp_generate_attachment_metadata( $id, $fullsizepath ); + if ( is_wp_error( $metadata ) ) { + WP_CLI::warning( $metadata->get_error_message() ); + return false; + } + + if ( empty( $metadata ) ) { + WP_CLI::warning( "Couldn't regenerate thumbnails for $att_desc." ); + return false; + } - wp_update_attachment_metadata( $id, $metadata ); + wp_update_attachment_metadata( $id, $metadata ); - WP_CLI::log( "Regenerated thumbnails for $att_desc" ); - return true; + WP_CLI::log( "Regenerated thumbnails for $att_desc" ); + return true; + } else { + WP_CLI::log( "No thumbnail regeneration needed for $att_desc" ); + return true; + } } private function remove_old_images( $att_id ) { @@ -268,6 +281,35 @@ private function remove_old_images( $att_id ) { unlink( $intermediate_path ); } } + + private function needs_regeneration( $att_id ) { + $wud = wp_upload_dir(); + + $metadata = wp_get_attachment_metadata($att_id); + + if ( empty($metadata['file'] ) ) { + return false; + } + + $dir_path = $wud['basedir'] . '/' . dirname( $metadata['file'] ) . '/'; + $original_path = $dir_path . basename( $metadata['file'] ); + + if ( empty( $metadata['sizes'] ) ) { + return false; + } + + foreach( $metadata['sizes'] as $size_info ) { + $intermediate_path = $dir_path . $size_info['file']; + + if ( $intermediate_path == $original_path ) + continue; + + if ( ! file_exists( $intermediate_path ) ) { + return true; + } + } + return false; + } } WP_CLI::add_command( 'media', 'Media_Command', array( From 2baf7c2e6cdc120cdc6cfa1b91eb8f8f615b1747 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 14:07:04 -0800 Subject: [PATCH 3911/4858] Use `wp core update-db --dry-run` to see if database needs update This can be helpful for determining whether a backup should be made, without incurring a backup each time `wp core update-db` is run. --- features/core-update-db.feature | 36 +++++++++++++++++++++++++++++++++ php/commands/core.php | 16 ++++++++++++--- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/features/core-update-db.feature b/features/core-update-db.feature index b26e596e67..140616e39d 100644 --- a/features/core-update-db.feature +++ b/features/core-update-db.feature @@ -17,6 +17,18 @@ Feature: Update core's database Success: WordPress database already at latest db version 30133 """ + Scenario: Dry run update db on a single site + Given a WP install + And I run `wp core download --version=4.1 --force` + And I run `wp option update db_version 29630` + + When I run `wp core update-db --dry-run` + Then STDOUT should be: + """ + Performing a dry run, with no database modification. + Success: WordPress database upgraded successfully from db version 29630 to 30133 + """ + Scenario: Update db across network Given a WP multisite install And I run `wp site create --slug=foo` @@ -36,3 +48,27 @@ Feature: Update core's database """ Success: WordPress database upgraded on 3/3 sites """ + + Scenario: Update db across network + Given a WP multisite install + And I run `wp site create --slug=foo` + And I run `wp site create --slug=bar` + And I run `wp site create --slug=burrito --porcelain` + And save STDOUT as {BURRITO_ID} + And I run `wp site create --slug=taco --porcelain` + And save STDOUT as {TACO_ID} + And I run `wp site create --slug=pizza --porcelain` + And save STDOUT as {PIZZA_ID} + And I run `wp site archive {BURRITO_ID}` + And I run `wp site spam {TACO_ID}` + And I run `wp site delete {PIZZA_ID} --yes` + + When I run `wp core update-db --network --dry-run` + Then STDOUT should contain: + """ + Performing a dry run, with no database modification. + """ + And STDOUT should contain: + """ + Success: WordPress database upgraded on 3/3 sites + """ diff --git a/php/commands/core.php b/php/commands/core.php index 91ab75080e..2045dabffa 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -973,6 +973,9 @@ function update( $args, $assoc_args ) { * [--network] * : Update databases for all sites on a network * + * [--dry-run] + * : Compare database versions without performing the update. + * * @subcommand update-db */ function update_db( $_, $assoc_args ) { @@ -983,6 +986,11 @@ function update_db( $_, $assoc_args ) { WP_CLI::error( 'This is not a multisite install.' ); } + $dry_run = Utils\get_flag_value( $assoc_args, 'dry-run' ); + if ( $dry_run ) { + WP_CLI::log( 'Performing a dry run, with no database modification.' ); + } + if ( $network ) { $iterator_args = array( 'table' => $wpdb->blogs, @@ -993,7 +1001,7 @@ function update_db( $_, $assoc_args ) { foreach( $it as $blog ) { $total++; $url = $blog->domain . $blog->path; - $process = WP_CLI::launch_self( 'core update-db', array(), array(), false, true, array( 'url' => $url ) ); + $process = WP_CLI::launch_self( 'core update-db', array(), array(), false, true, array( 'url' => $url, 'dry-run' => $dry_run ) ); if ( 0 == $process->return_code ) { // See if we can parse the stdout if ( preg_match( '#Success: (.+)#', $process->stdout, $matches ) ) { @@ -1007,7 +1015,7 @@ function update_db( $_, $assoc_args ) { WP_CLI::warning( "Database failed to upgrade on {$url}" ); } } - if ( $total && $success == $total ) { + if ( ! $dry_run && $total && $success == $total ) { update_site_option( 'wpmu_upgrade_site', $wp_db_version ); } WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites', $success, $total ) ); @@ -1015,7 +1023,9 @@ function update_db( $_, $assoc_args ) { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); $wp_current_db_version = __get_option( 'db_version' ); if ( $wp_db_version != $wp_current_db_version ) { - wp_upgrade(); + if ( ! $dry_run ) { + wp_upgrade(); + } WP_CLI::success( "WordPress database upgraded successfully from db version {$wp_current_db_version} to {$wp_db_version}" ); } else { WP_CLI::success( "WordPress database already at latest db version {$wp_db_version}" ); From 7b6321ab059dbcc940f8edd499b8e68967d30d89 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 14:35:40 -0800 Subject: [PATCH 3912/4858] Dashed image names were introduced in WP 4.4 We can remove this assertion without affecting the integrity of the test --- features/media-regenerate.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/media-regenerate.feature b/features/media-regenerate.feature index a9048a1ff6..fb4f99be60 100644 --- a/features/media-regenerate.feature +++ b/features/media-regenerate.feature @@ -123,7 +123,6 @@ Feature: Regenerate WordPress attachments When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My second imported attachment" --porcelain` Then save STDOUT as {ATTACHMENT_ID2} - And the wp-content/uploads/large-image-1-100x100.jpg file should exist When I run `rm wp-content/uploads/large-image-100x100.jpg` Then the wp-content/uploads/large-image-100x100.jpg file should not exist From 0062ddd7744cc44f4659ade9581f3a9a48e69562 Mon Sep 17 00:00:00 2001 From: Mihail Minkov <Mihail.Minkov.BG@gmail.com> Date: Fri, 11 Dec 2015 01:01:16 +0200 Subject: [PATCH 3913/4858] Fixed grammatical error. --- php/commands/scaffold.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index b7c1ad0caa..969295fd68 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -224,7 +224,7 @@ function _s( $args, $assoc_args ) { die; } - $theme_description = "Custom theme: " . $data['theme_name'] . " developed by, " . $data['author']; + $theme_description = "Custom theme: " . $data['theme_name'] . ", developed by " . $data['author']; $body = array(); $body['underscoresme_name'] = $data['theme_name']; From be7fee0059ff74b2ee7520cecde65ee1366ae76c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Dec 2015 16:13:33 -0800 Subject: [PATCH 3914/4858] Add one last sanity check test --- features/core-update-db.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/core-update-db.feature b/features/core-update-db.feature index 140616e39d..f3abbe1ea4 100644 --- a/features/core-update-db.feature +++ b/features/core-update-db.feature @@ -29,6 +29,12 @@ Feature: Update core's database Success: WordPress database upgraded successfully from db version 29630 to 30133 """ + When I run `wp option get db_version` + Then STDOUT should be: + """ + 29630 + """ + Scenario: Update db across network Given a WP multisite install And I run `wp site create --slug=foo` From 95ab7ddd2dcc1c0e29a361f145f798d03fc61c85 Mon Sep 17 00:00:00 2001 From: Duncan Brown <duncanjbrown@gmail.com> Date: Fri, 11 Dec 2015 18:02:54 +0000 Subject: [PATCH 3915/4858] Failing test for plugin gitignore --- features/scaffold.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 377b9666b2..4ab5c271fb 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -112,11 +112,17 @@ Feature: WordPress code scaffolding When I run `wp scaffold plugin hello-world` Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/.gitignore file should exist And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist And the {PLUGIN_DIR}/hello-world/hello-world.php file should exist And the {PLUGIN_DIR}/hello-world/readme.txt file should exist And the {PLUGIN_DIR}/hello-world/package.json file should exist And the {PLUGIN_DIR}/hello-world/Gruntfile.js file should exist + And the {PLUGIN_DIR}/hello-world/.gitignore file should contain: + """ + .DS_Store + node_modules/ + """ Scenario: Scaffold a plugin and activate it Given a WP install From e4b12812e0c08c6a377e953435cff7ac4b7b2da1 Mon Sep 17 00:00:00 2001 From: Duncan Brown <duncanjbrown@gmail.com> Date: Fri, 11 Dec 2015 18:07:26 +0000 Subject: [PATCH 3916/4858] Add .gitignore to plugin scaffold --- php/commands/scaffold.php | 1 + templates/plugin-gitignore.mustache | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 templates/plugin-gitignore.mustache diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 969295fd68..a9d863d4fa 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -530,6 +530,7 @@ function plugin( $args, $assoc_args ) { $plugin_readme_path => Utils\mustache_render( 'plugin-readme.mustache', $data ), "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), + "$plugin_dir/.gitignore" => Utils\mustache_render( 'plugin-gitignore.mustache', $data ), "$plugin_dir/.editorconfig" => file_get_contents( WP_CLI_ROOT . "/templates/.editorconfig" ), ), $force ); diff --git a/templates/plugin-gitignore.mustache b/templates/plugin-gitignore.mustache new file mode 100644 index 0000000000..646ac519ef --- /dev/null +++ b/templates/plugin-gitignore.mustache @@ -0,0 +1,2 @@ +.DS_Store +node_modules/ From 3266e1c9dbf811b8e2fd217e4152c29434964afe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 13 Dec 2015 16:15:11 -0800 Subject: [PATCH 3917/4858] Support custom export filename formats with `--filename_format=` --- features/export.feature | 13 +++++++++++++ php/commands/export.php | 17 +++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/features/export.feature b/features/export.feature index cb2720ef68..3f201eea25 100644 --- a/features/export.feature +++ b/features/export.feature @@ -409,3 +409,16 @@ Feature: Export content. """ 0 """ + + Scenario: Export a site with a custom filename format + Given a WP install + + When I run `wp export --filename_format='foo-bar.{date}.{n}.xml'` + Then STDOUT should contain: + """ + foo-bar. + """ + And STDOUT should contain: + """ + 000.xml + """ diff --git a/php/commands/export.php b/php/commands/export.php index 50b077c457..6fc6dfba3e 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -54,6 +54,9 @@ class Export_Command extends WP_CLI_Command { * [--post_status=<status>] * : Export only posts with this status. * + * [--filename_format=<format>] + * : Use a custom format for export filenames. Defaults to '{site}.wordpress.{date}.{n}.xml'. + * * ## EXAMPLES * * wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 @@ -74,9 +77,11 @@ public function __invoke( $_, $assoc_args ) { 'start_id' => NULL, 'skip_comments' => NULL, 'max_file_size' => 15, + 'filename_format' => '{site}.wordpress.{date}.{n}.xml', ); - $this->validate_args( wp_parse_args( $assoc_args, $defaults ) ); + $assoc_args = wp_parse_args( $assoc_args, $defaults ); + $this->validate_args( $assoc_args ); if ( !function_exists( 'wp_export' ) ) { self::load_export_api(); @@ -95,7 +100,7 @@ public function __invoke( $_, $assoc_args ) { 'writer_args' => array( 'max_file_size' => $this->max_file_size * MB_IN_BYTES, 'destination_directory' => $this->wxr_path, - 'filename_template' => self::get_filename_template() + 'filename_template' => self::get_filename_template( $assoc_args['filename_format'] ), ) ) ); } catch ( Exception $e ) { @@ -105,12 +110,12 @@ public function __invoke( $_, $assoc_args ) { WP_CLI::success( 'All done with export.' ); } - private static function get_filename_template() { + private static function get_filename_template( $filename_format ) { $sitename = sanitize_key( get_bloginfo( 'name' ) ); - if ( ! empty( $sitename ) ) { - $sitename .= '.'; + if ( empty( $sitename ) ) { + $sitename = 'site'; } - return $sitename . 'wordpress.' . date( 'Y-m-d' ) . '.%03d.xml'; + return str_replace( array( '{site}', '{date}', '{n}' ), array( $sitename, date( 'Y-m-d' ), '%03d' ), $filename_format ); } private static function load_export_api() { From 89aae167023651ea8e2a007ac885997fec090332 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 13 Dec 2015 16:37:00 -0800 Subject: [PATCH 3918/4858] Consistently use periods in global param docs --- php/config-spec.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index 4e6622b0e7..3fda4edff9 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -4,7 +4,7 @@ 'path' => array( 'runtime' => '=<path>', 'file' => '<path>', - 'desc' => 'Path to the WordPress files', + 'desc' => 'Path to the WordPress files.', ), 'url' => array( @@ -25,27 +25,27 @@ 'user' => array( 'runtime' => '=<id|login|email>', 'file' => '<id|login|email>', - 'desc' => 'Set the WordPress user', + 'desc' => 'Set the WordPress user.', ), 'skip-plugins' => array( 'runtime' => '[=<plugin>]', 'file' => '<list>', - 'desc' => 'Skip loading all or some plugins', + 'desc' => 'Skip loading all or some plugins.', 'default' => '', ), 'skip-themes' => array( 'runtime' => '[=<theme>]', 'file' => '<list>', - 'desc' => 'Skip loading all or some themes', + 'desc' => 'Skip loading all or some themes.', 'default' => '', ), 'require' => array( 'runtime' => '=<path>', 'file' => '<path>', - 'desc' => 'Load PHP file before running the command (may be used more than once)', + 'desc' => 'Load PHP file before running the command (may be used more than once).', 'multiple' => true, 'default' => array(), ), @@ -53,40 +53,40 @@ 'disabled_commands' => array( 'file' => '<list>', 'default' => array(), - 'desc' => '(Sub)commands to disable', + 'desc' => '(Sub)commands to disable.', ), 'color' => array( 'runtime' => true, 'file' => '<bool>', 'default' => 'auto', - 'desc' => 'Whether to colorize the output', + 'desc' => 'Whether to colorize the output.', ), 'debug' => array( 'runtime' => '', 'file' => '<bool>', 'default' => false, - 'desc' => 'Show all PHP errors; add verbosity to WP-CLI bootstrap', + 'desc' => 'Show all PHP errors; add verbosity to WP-CLI bootstrap.', ), 'prompt' => array( 'runtime' => '', 'file' => false, 'default' => false, - 'desc' => 'Prompt the user to enter values for all command arguments', + 'desc' => 'Prompt the user to enter values for all command arguments.', ), 'quiet' => array( 'runtime' => '', 'file' => '<bool>', 'default' => false, - 'desc' => 'Suppress informational messages', + 'desc' => 'Suppress informational messages.', ), 'apache_modules' => array( 'file' => '<list>', - 'desc' => 'List of Apache Modules that are to be reported as loaded', + 'desc' => 'List of Apache Modules that are to be reported as loaded.', 'multiple' => true, 'default' => array(), ), From 24e9917452c0a591fe9e6405683459c08e497f9b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 13 Dec 2015 16:53:15 -0800 Subject: [PATCH 3919/4858] Split out tests for comment generate and comment recount --- features/comment-generate.feature | 11 +++++++++++ features/comment-recount.feature | 25 +++++++++++++++++++++++++ features/comment.feature | 30 ------------------------------ 3 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 features/comment-generate.feature create mode 100644 features/comment-recount.feature diff --git a/features/comment-generate.feature b/features/comment-generate.feature new file mode 100644 index 0000000000..609fc257d2 --- /dev/null +++ b/features/comment-generate.feature @@ -0,0 +1,11 @@ +Feature: Generate comments + + Scenario: Generate a specific number of comments + Given a WP install + + When I run `wp comment generate --count=20` + And I run `wp comment list --format=count` + Then STDOUT should be: + """ + 21 + """ diff --git a/features/comment-recount.feature b/features/comment-recount.feature new file mode 100644 index 0000000000..5de768a0fe --- /dev/null +++ b/features/comment-recount.feature @@ -0,0 +1,25 @@ +Feature: Recount comments on a post + + Scenario: Recount comments on a post + Given a WP install + + When I run `wp comment create --comment_post_ID=1 --comment_approved=1 --porcelain` + And I run `wp comment create --comment_post_ID=1 --comment_approved=1 --porcelain` + And I run `wp post get 1 --field=comment_count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp eval 'global $wpdb; $wpdb->update( $wpdb->posts, array( "comment_count" => 1 ), array( "ID" => 1 ) );'` + And I run `wp post get 1 --field=comment_count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp comment recount 1` + Then STDOUT should be: + """ + Updated post 1 comment count to 3 + """ diff --git a/features/comment.feature b/features/comment.feature index 8e368e244d..f636f60874 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -129,33 +129,3 @@ Feature: Manage WordPress comments """ 0 """ - - Scenario: Generate comments - When I run `wp comment generate --count=20` - And I run `wp comment list --format=count` - Then STDOUT should be: - """ - 21 - """ - - Scenario: Recounting comments - When I run `wp comment create --comment_post_ID=1 --comment_approved=1 --porcelain` - And I run `wp comment create --comment_post_ID=1 --comment_approved=1 --porcelain` - And I run `wp post get 1 --field=comment_count` - Then STDOUT should be: - """ - 3 - """ - - When I run `wp eval 'global $wpdb; $wpdb->update( $wpdb->posts, array( "comment_count" => 1 ), array( "ID" => 1 ) );'` - And I run `wp post get 1 --field=comment_count` - Then STDOUT should be: - """ - 1 - """ - - When I run `wp comment recount 1` - Then STDOUT should be: - """ - Updated post 1 comment count to 3 - """ From c1edf396ceef8f68a89abea17c2cd4f821234356 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 14 Dec 2015 06:42:36 -0800 Subject: [PATCH 3920/4858] Permit failures on trunk Trunk has a fatal right now --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 90ef902217..8f7e5b5533 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,7 @@ matrix: env: WP_VERSION=trunk allow_failures: - php: 7.0 + - env: WP_VERSION=trunk before_script: ./ci/prepare.sh From 138ab6ec00209c2b0f637f36d21ace522dbbe362 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 14 Dec 2015 09:56:55 -0800 Subject: [PATCH 3921/4858] Don't use table iterator when running search / replace with PHP On large datasets, running `LIKE` twice per 1000 rows is far less efficient than running `LIKE` once to get keys for all rows to operate on, and `SELECT` to get the corresponding values for each row. On small datasets, this change will have a negligible impact. For a post meta table of ~3.5 million rows with 75610 affected records, this change improves execution time from 734.926s to 225.509s --- php/commands/search-replace.php | 40 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index d2f705e6a5..4ef2f3b262 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -263,42 +263,36 @@ private function sql_handle_col( $col, $table, $old, $new ) { private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { global $wpdb; - // We don't want to have to generate thousands of rows when running the test suite - $chunk_size = getenv( 'BEHAT_RUN' ) ? 10 : 1000; - - $fields = $primary_keys; - $fields[] = $col; - - $args = array( - 'table' => $table, - 'fields' => $fields, - 'where' => $this->regex ? '' : "`$col`" . $wpdb->prepare( ' LIKE %s', '%' . self::esc_like( $old ) . '%' ), - 'chunk_size' => $chunk_size - ); - - $it = new \WP_CLI\Iterators\Table( $args ); - $count = 0; - $replacer = new \WP_CLI\SearchReplacer( $old, $new, $this->recurse_objects, $this->regex ); - foreach ( $it as $row ) { - if ( '' === $row->$col ) + $where = $this->regex ? '' : " WHERE `$col`" . $wpdb->prepare( ' LIKE %s', '%' . self::esc_like( $old ) . '%' ); + $primary_keys_sql = esc_sql( implode( ',', $primary_keys ) ); + $col_sql = esc_sql( $col ); + $table_sql = esc_sql( $table ); + $rows = $wpdb->get_results( "SELECT {$primary_keys_sql} FROM {$table_sql}{$where}" ); + foreach ( $rows as $keys ) { + $where_sql = ''; + foreach( (array) $keys as $k => $v ) { + $where_sql .= "{$k}={$v}"; + } + $col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" ); + if ( '' === $col_value ) continue; - $value = $replacer->run( $row->$col ); + $value = $replacer->run( $col_value ); - if ( $value === $row->$col ) { + if ( $value === $col_value ) { continue; } if ( $this->dry_run ) { - if ( $value != $row->$col ) + if ( $value != $col_value ) $count++; } else { $where = array(); - foreach ( $primary_keys as $primary_key ) { - $where[ $primary_key ] = $row->$primary_key; + foreach( (array) $keys as $k => $v ) { + $where[ $k ] = $v; } $count += $wpdb->update( $table, array( $col => $value ), $where ); From e3c71cc72218ecf6abaf900ed892e8be3e1af045 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 14 Dec 2015 10:11:56 -0800 Subject: [PATCH 3922/4858] search-replace: Drop unneeded `REGEXP` when in regex mode We'll be using PHP mode in this context anyway --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index d2f705e6a5..dfa03e2643 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -150,7 +150,7 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::log( sprintf( 'Checking: %s.%s', $table, $col ) ); } - if ( ! $php_only ) { + if ( ! $php_only && ! $this->regex ) { $serialRow = $wpdb->get_row( "SELECT * FROM `$table` WHERE `$col` REGEXP '^[aiO]:[1-9]' LIMIT 1" ); } From e23ad5950dadb99b5b5ddc7cef7e5f6567953458 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 21 Dec 2015 07:36:44 -0800 Subject: [PATCH 3923/4858] Clarify behavior of `wp plugin delete` It's different than deactivating + uninstalling. --- php/commands/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index d266aae993..37181d3c03 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -556,7 +556,7 @@ function is_installed( $args, $assoc_args = array() ) { } /** - * Delete plugin files. + * Delete plugin files without deactivating or uninstalling. * * ## OPTIONS * From b129b84824ed8e12c7b79b65e74d6a77a1ce9bc4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 21 Dec 2015 08:13:29 -0800 Subject: [PATCH 3924/4858] Magically globalize any new variables defined in wp-config.php They're expected to be global, so we should explicitly make it so. --- features/framework.feature | 24 ++++++++++++++++++++++++ php/WP_CLI/Runner.php | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/features/framework.feature b/features/framework.feature index ea69fcc5fa..0772cfb213 100644 --- a/features/framework.feature +++ b/features/framework.feature @@ -83,3 +83,27 @@ Feature: Load WP-CLI """ Error: This does not seem to be a WordPress install. """ + + Scenario: Globalize global variables in wp-config.php + Given an empty directory + And WP files + And a wp-config-extra.php file: + """ + $redis_server = 'foo'; + """ + + When I run `wp core config {CORE_CONFIG_SETTINGS} --extra-php < wp-config-extra.php` + Then the wp-config.php file should contain: + """ + $redis_server = 'foo'; + """ + + When I run `wp db create` + And I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` + Then STDOUT should not be empty + + When I run `wp eval 'echo $GLOBALS["redis_server"];'` + Then STDOUT should be: + """ + foo + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 444ebc2c05..9da535565e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -728,7 +728,14 @@ public function load_wordpress() { WP_CLI::debug( 'wp-config.php path: ' . $wp_config_path ); // Load wp-config.php code, in the global scope + $wp_cli_original_defined_vars = get_defined_vars(); eval( $this->get_wp_config_code() ); + foreach( get_defined_vars() as $key => $var ) { + if ( array_key_exists( $key, $wp_cli_original_defined_vars ) || 'wp_cli_original_defined_vars' === $key ) { + continue; + } + $GLOBALS[ $key ] = $var; + } $this->maybe_update_url_from_domain_constant(); From e86e4a11465bf7b04d43c7f27876b245a12b8b03 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 21 Dec 2015 08:59:39 -0800 Subject: [PATCH 3925/4858] Revert "Permit failures on trunk" This reverts commit c1edf396ceef8f68a89abea17c2cd4f821234356. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8f7e5b5533..90ef902217 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,6 @@ matrix: env: WP_VERSION=trunk allow_failures: - php: 7.0 - - env: WP_VERSION=trunk before_script: ./ci/prepare.sh From cdd1c2f6585a8ca9b2ab926ffe99b1d8eba8fed5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 06:52:54 -0800 Subject: [PATCH 3926/4858] Failing test case for #2308 --- features/post-meta.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/post-meta.feature b/features/post-meta.feature index 307edf060e..a7eacd135f 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -95,3 +95,17 @@ Feature: Manage post custom fields """ 0 """ + + Scenario: List post meta with a null value + Given a WP install + And a setup.php file: + """ + <?php + update_post_meta( 1, 'foo', NULL ); + """ + And I run `wp eval-file setup.php` + + When I run `wp post meta list 1` + Then STDOUT should be a table containing rows: + | post_id | meta_key | meta_value | + | 1 | foo | | From d9f8412fb131952ee0cc9fb53f59fca28a6a6d24 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 06:53:53 -0800 Subject: [PATCH 3927/4858] Properly check for null values on objects --- php/WP_CLI/Formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 5da9926b0a..56616835eb 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -188,7 +188,7 @@ private function show_single_field( $items, $field ) { */ private function find_item_key( $item, $field ) { foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { - if ( ( is_object( $item ) && isset( $item->$maybe_key ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { + if ( ( is_object( $item ) && property_exists( $item, $maybe_key ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { $key = $maybe_key; break; } From b32fe69166cc4b7202c40d47ef668ab529ec7ba9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 07:14:49 -0800 Subject: [PATCH 3928/4858] Run multiple cron events, or use `--all` to run all of them Note: `wp cron event run` ignores the scheduled time for the event. If you need to run a specific event on a specific schedule, you'll need to replicate said schedule with system cron. --- features/cron.feature | 43 ++++++++++++++++++++++++++++++++++++++++++- php/commands/cron.php | 36 ++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 73b46d3931..10dcf99dcd 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -74,7 +74,9 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event run wp_cli_test_event_5` Then STDOUT should be: """ - Success: Executed 2 instances of the cron event 'wp_cli_test_event_5' + Executed the cron event 'wp_cli_test_event_5'. + Executed the cron event 'wp_cli_test_event_5'. + Success: Executed a total of 2 cron event(s). """ When I run `wp cron event list` @@ -174,3 +176,42 @@ Feature: Manage WP-Cron events and schedules """ Error: """ + + Scenario: Run multiple cron events + When I try `wp cron event run` + Then STDERR should be: + """ + Error: Please specify one or more cron events, or use --all. + """ + + When I run `wp cron event run wp_version_check wp_update_plugins` + Then STDOUT should contain: + """ + Executed the cron event 'wp_version_check'. + """ + And STDOUT should contain: + """ + Executed the cron event 'wp_update_plugins'. + """ + And STDOUT should contain: + """ + Success: Executed a total of 2 cron event(s). + """ + + When I run `wp cron event run --all` + Then STDOUT should contain: + """ + Executed the cron event 'wp_version_check'. + """ + And STDOUT should contain: + """ + Executed the cron event 'wp_update_plugins'. + """ + And STDOUT should contain: + """ + Executed the cron event 'wp_update_themes'. + """ + And STDOUT should contain: + """ + Success: Executed a total of + """ diff --git a/php/commands/cron.php b/php/commands/cron.php index 9dacd26563..ec04b6b78c 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -138,37 +138,49 @@ public function schedule( $args, $assoc_args ) { * * ## OPTIONS * - * <hook> - * : The hook name + * [<hook>...] + * : One or more hooks to run. + * + * [--all] + * : Run all hooks. */ public function run( $args, $assoc_args ) { - $hook = $args[0]; + if ( empty( $args ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + WP_CLI::error( 'Please specify one or more cron events, or use --all.' ); + } + $events = self::get_cron_events(); if ( is_wp_error( $events ) ) { WP_CLI::error( $events ); } + + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + $hooks = wp_list_pluck( $events, 'hook' ); + foreach( $args as $hook ) { + if ( ! in_array( $hook, $hooks ) ) { + WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); + } + } + } + $executed = 0; foreach ( $events as $event ) { - if ( $event->hook == $hook ) { + if ( in_array( $event->hook, $args ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { $result = self::run_event( $event ); if ( $result ) { $executed++; + WP_CLI::log( sprintf( "Executed the cron event '%s'.", $event->hook ) ); } else { - WP_CLI::warning( sprintf( "Failed to the execute the cron event '%s'", $hook ) ); + WP_CLI::warning( sprintf( "Failed to the execute the cron event '%s'.", $event->hook ) ); } } } - if ( $executed ) { - $message = ( 1 == $executed ) ? "Executed the cron event '%2\$s'" : "Executed %1\$d instances of the cron event '%2\$s'"; - WP_CLI::success( sprintf( $message, $executed, $hook ) ); - } else { - WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); - } - + $message = 'Executed a total of %d cron event(s).'; + WP_CLI::success( sprintf( $message, $executed ) ); } /** From be3694a20a9eaa50ba13509365232ae2986afe4d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 07:34:14 -0800 Subject: [PATCH 3929/4858] Failing test case for #1722 --- features/media-import.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/media-import.feature b/features/media-import.feature index adc20bcafc..4f971b0d67 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -17,6 +17,13 @@ Feature: Manage WordPress attachments Unable to import file gobbledygook.png. Reason: File doesn't exist. """ + Scenario: Fail to import missing image on Windows + When I try `wp media import c:/path/gobbledygook.png` + Then STDERR should contain: + """ + Unable to import file c:/path/gobbledygook.png. Reason: File doesn't exist. + """ + Scenario: Import a file as attachment from a local image Given download: | path | url | From 4d56828a1eec620af0b5e2dc143ae3555df29a72 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 07:41:13 -0800 Subject: [PATCH 3930/4858] Use host instead of scheme to determine whether a file is remote or local Local files can have schemes on Windows, but local files never have hosts --- php/commands/media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index 3bb2becee3..877fed9a64 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -141,7 +141,7 @@ function import( $args, $assoc_args = array() ) { } foreach ( $args as $file ) { - $is_file_remote = parse_url( $file, PHP_URL_SCHEME ); + $is_file_remote = parse_url( $file, PHP_URL_HOST ); $orig_filename = $file; if ( empty( $is_file_remote ) ) { From 7f695c548b1b90c33a47e3a76f293cbdde3e52f2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 08:08:31 -0800 Subject: [PATCH 3931/4858] Use readline for `--prompt`, which properly supports arrow keys --- php/WP_CLI/Dispatcher/Subcommand.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index dd601c34e9..19ecbc3abc 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -101,14 +101,13 @@ function get_usage( $prefix ) { */ private function prompt( $question, $default ) { - try { - $response = \cli\prompt( $question, $default ); - } catch( \Exception $e ) { - \WP_CLI::line(); - return false; + $question .= ': '; + if ( function_exists( 'readline' ) ) { + return readline( $question ); + } else { + echo $question; + return stream_get_line( STDIN, 1024, PHP_EOL ); } - - return $response; } /** From 3c9dff91022f43ad7d87886e180a43c53f4b436d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Dec 2015 08:12:56 -0800 Subject: [PATCH 3932/4858] Use `property_exists()` *and* `isset()` because WP has magic getters --- php/WP_CLI/Formatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 56616835eb..31c4a169eb 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -188,7 +188,7 @@ private function show_single_field( $items, $field ) { */ private function find_item_key( $item, $field ) { foreach ( array( $field, $this->prefix . '_' . $field ) as $maybe_key ) { - if ( ( is_object( $item ) && property_exists( $item, $maybe_key ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { + if ( ( is_object( $item ) && ( property_exists( $item, $maybe_key ) || isset( $item->$maybe_key ) ) ) || ( is_array( $item ) && array_key_exists( $maybe_key, $item ) ) ) { $key = $maybe_key; break; } From aa19a9d36a6d5c07cdc9f316569ab64cb48587c2 Mon Sep 17 00:00:00 2001 From: Frankie Jarrett <fjarrett@godaddy.com> Date: Wed, 23 Dec 2015 23:57:49 -0600 Subject: [PATCH 3933/4858] Fix widget list command example --- php/commands/widget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index 81064269b3..3976272c9e 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -52,7 +52,7 @@ class Widget_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp sidebar widget list <sidebar-id> --fields=name --format=csv + * wp widget list sidebar-1 --fields=name --format=csv * * @subcommand list */ From c76fc69bd75a8a3cf079f3787cc469f77c54f8a7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Dec 2015 07:48:24 -0800 Subject: [PATCH 3934/4858] Remove unused `php_version_tags()` function --- ci/behat-tags.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ci/behat-tags.php b/ci/behat-tags.php index 18943e3800..cca8ebf410 100644 --- a/ci/behat-tags.php +++ b/ci/behat-tags.php @@ -1,9 +1,5 @@ <?php -function php_version_tags() { - exec( 'grep "@require-php-[0-9\.]*" -h -o features/*.feature | uniq', $existing_tags ); -} - function version_tags( $prefix, $current ) { if ( ! $current ) return; From f1d46049eb1a468491cc041d9823a09cb9ff51a7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Dec 2015 08:02:39 -0800 Subject: [PATCH 3935/4858] Officially support PHP 7 Skip tests which download versions of WordPress earlier than 4.4, as they throw error notices in PHP 7. --- .travis.yml | 4 +--- ci/behat-tags.php | 11 ++++++----- features/core-check-update.feature | 1 + features/core-update.feature | 3 +++ 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 90ef902217..5fb2dfcfd9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,9 +41,7 @@ matrix: - php: 5.6 env: WP_VERSION=trunk - php: 7.0 - env: WP_VERSION=trunk - allow_failures: - - php: 7.0 + env: WP_VERSION=latest before_script: ./ci/prepare.sh diff --git a/ci/behat-tags.php b/ci/behat-tags.php index 18943e3800..ee10b40066 100644 --- a/ci/behat-tags.php +++ b/ci/behat-tags.php @@ -4,7 +4,7 @@ function php_version_tags() { exec( 'grep "@require-php-[0-9\.]*" -h -o features/*.feature | uniq', $existing_tags ); } -function version_tags( $prefix, $current ) { +function version_tags( $prefix, $current, $operator = '<' ) { if ( ! $current ) return; @@ -13,8 +13,8 @@ function version_tags( $prefix, $current ) { $skip_tags = array(); foreach ( $existing_tags as $tag ) { - $required = str_replace( "@{$prefix}-", '', $tag ); - if ( version_compare( $current, $required, '<' ) ) { + $compare = str_replace( "@{$prefix}-", '', $tag ); + if ( version_compare( $current, $compare, $operator ) ) { $skip_tags[] = $tag; } } @@ -23,8 +23,9 @@ function version_tags( $prefix, $current ) { } $skip_tags = array_merge( - version_tags( 'require-wp', getenv( 'WP_VERSION' ) ), - version_tags( 'require-php', PHP_VERSION ) + version_tags( 'require-wp', getenv( 'WP_VERSION' ), '<' ), + version_tags( 'require-php', PHP_VERSION, '<' ), + version_tags( 'less-than-php', PHP_VERSION, '>' ) ); # Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 4d6acc2360..f35d28a1ad 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -1,5 +1,6 @@ Feature: Check for more recent versions + @less-than-php-7 Scenario: Check for update via Version Check API Given a WP install diff --git a/features/core-update.feature b/features/core-update.feature index 0604fdb6e6..ee2065a3db 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -1,5 +1,6 @@ Feature: Update WordPress core + @less-than-php-7 Scenario: Update from a ZIP file Given a WP install @@ -27,6 +28,7 @@ Feature: Update WordPress core 3.9 """ + @less-than-php-7 Scenario: Update to the latest minor release Given a WP install @@ -45,6 +47,7 @@ Feature: Update WordPress core Success: WordPress is at the latest minor release. """ + @less-than-php-7 Scenario: Core update from cache Given a WP install And an empty cache From 9cd571e8dc63161e39137ef414ddc8bd027d517f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Dec 2015 09:08:04 -0800 Subject: [PATCH 3936/4858] Explicitly set menu position for term WordPress doesn't do this inherently, so we end up with two posts of the same menu order. --- features/menu.feature | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index f2b554d6b1..194829d178 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -77,7 +77,10 @@ Feature: Manage WordPress menus Then save STDOUT as {POST_ITEM_ID} When I run `wp menu item update {POST_ITEM_ID} --description="Washington Apples"` - Then STDERR should be empty + Then STDOUT should be: + """ + Success: Menu item updated. + """ When I run `wp menu item add-term sidebar-menu post_tag {TERM_ID} --porcelain` Then save STDOUT as {TERM_ITEM_ID} @@ -86,7 +89,16 @@ Feature: Manage WordPress menus Then save STDOUT as {CUSTOM_ITEM_ID} When I run `wp menu item update {CUSTOM_ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` - Then STDERR should be empty + Then STDOUT should be: + """ + Success: Menu item updated. + """ + + When I run `wp menu item update {TERM_ITEM_ID} --position=3` + Then STDOUT should be: + """ + Success: Menu item updated. + """ When I run `wp menu item list sidebar-menu --fields=type,title,description,position,link,menu_item_parent` Then STDOUT should be a table containing rows: From a13e5862cf9e44c1cfbb8e93e2eec689b8530e22 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Dec 2015 09:09:45 -0800 Subject: [PATCH 3937/4858] Use "should contain" instead of "should be" PHP 7.0.0 is producing unexpected output which is already fixed in 7.0.1. While it would be nice to be explicit, it's not wholly necessary. --- features/eval.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/eval.feature b/features/eval.feature index b78a5ad6c0..c8308b67b4 100644 --- a/features/eval.feature +++ b/features/eval.feature @@ -4,7 +4,7 @@ Feature: Evaluating PHP code and files. Given a WP install When I run `wp eval 'var_dump(defined("WP_CONTENT_DIR"));'` - Then STDOUT should be: + Then STDOUT should contain: """ bool(true) """ @@ -16,7 +16,7 @@ Feature: Evaluating PHP code and files. """ When I run `wp eval-file script.php foo bar` - Then STDOUT should be: + Then STDOUT should contain: """ foo bar """ @@ -31,7 +31,7 @@ Feature: Evaluating PHP code and files. """ When I run `wp eval 'var_dump(defined("WP_CONTENT_DIR"));' --skip-wordpress` - Then STDOUT should be: + Then STDOUT should contain: """ bool(false) """ @@ -51,7 +51,7 @@ Feature: Evaluating PHP code and files. """ When I run `wp eval-file script.php --skip-wordpress` - Then STDOUT should be: + Then STDOUT should contain: """ bool(false) """ From be9b601ff1bcb20b19562a08d432ce47870c25fa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Dec 2015 16:09:25 -0800 Subject: [PATCH 3938/4858] Less precise, because PHP 7 produces more output See a13e5862cf9e44c1cfbb8e93e2eec689b8530e22 --- features/shell.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/shell.feature b/features/shell.feature index d415c6c4ed..03dd6cb3e4 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -35,7 +35,7 @@ Feature: WordPress REPL """ When I run `wp shell --basic < session` - Then STDOUT should be: + Then STDOUT should contain: """ bool(true) """ From 19099b9c51573cdf1ecc2832c94b4a08539cddc6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 07:03:07 -0800 Subject: [PATCH 3939/4858] Switch php-cli-tools to `dev-master` --- composer.json | 2 +- composer.lock | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index ba6f9d758c..d4bee10814 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.10.5", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "composer/semver": "1.0.0", "ramsey/array_column": "~1.1", diff --git a/composer.lock b/composer.lock index 7c51a4dda1..d568185770 100644 --- a/composer.lock +++ b/composer.lock @@ -692,16 +692,16 @@ }, { "name": "wp-cli/php-cli-tools", - "version": "v0.10.5", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "037a010441a5c220cd1df26cdc9b20ad73408356" + "reference": "c6f72ea088518ffda711634e46589c2dbc0036cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/037a010441a5c220cd1df26cdc9b20ad73408356", - "reference": "037a010441a5c220cd1df26cdc9b20ad73408356", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/c6f72ea088518ffda711634e46589c2dbc0036cb", + "reference": "c6f72ea088518ffda711634e46589c2dbc0036cb", "shasum": "" }, "require": { @@ -1230,7 +1230,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "wp-cli/php-cli-tools": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From 5f7cd8793c567c3339014ae9d7a2005746c76700 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 10:22:04 -0800 Subject: [PATCH 3940/4858] Clean up search-replace documentation * Expand description to clarify on default behavior. * Order arguments based on priority. * Format argument descriptions within 80 character width. --- php/commands/search-replace.php | 64 ++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 36cd267f84..c4088216b0 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -18,53 +18,67 @@ class Search_Replace_Command extends WP_CLI_Command { * * ## 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). + * This command will searches through all rows in a selection of tables + * and replaces appearances of the first string with the second string. * - * It will correctly handle serialized values, and will not change primary key values. + * By default, the command uses tables registered to the $wpdb object. On + * multisite, this will just be the tables for the current site unless + * --network is specified. + * + * Search/replace intelligently handles PHP serialized data, and does not + * change primary key values. * * ## OPTIONS * * <old> - * : The old string. + * : A string to search for within the database. * * <new> - * : The new string. + * : Replace instances of the first string with this new string. * * [<table>...] - * : List of database tables to restrict the replacement to. Wildcards are supported, e.g. wp_\*_options or wp_post\?. + * : List of database tables to restrict the replacement to. Wildcards are + * supported, e.g. 'wp_*_options' or 'wp_post*'. + * + * [--dry-run] + * : Run the entire search/replace operation and show report, but don't save + * changes to the database. * * [--network] - * : Search/replace through all the tables in a multisite install. + * : Search/replace through all the tables registered to $wpdb in a + * multisite install. * - * [--skip-columns=<columns>] - * : Do not perform the replacement in the comma-separated columns. + * [--all-tables-with-prefix] + * : Enable replacement on any tables that match the table prefix even if + * not registered on $wpdb. * - * [--dry-run] - * : Show report, but don't perform the changes. + * [--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. * - * [--precise] - * : Force the use of PHP (instead of SQL) which is more thorough, but slower. Use if you see issues with serialized data. + * [--export[=<file>]] + * : Write transformed data as SQL file instead of saving replacements to + * the database. If <file> is not supplied, will output to STDOUT. * - * [--recurse-objects] - * : Enable recursing into objects to replace strings. Defaults to true; pass --no-recurse-objects to disable. + * [--skip-columns=<columns>] + * : Do not perform the replacement on specific columns. Use commas to + * specify multiple columns. 'guid' is skipped by default. * - * [--all-tables-with-prefix] - * : Enable replacement on any tables that match the table prefix even if not registered on wpdb + * [--precise] + * : Force the use of PHP (instead of SQL) which is more thorough, + * but slower. * - * [--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. + * [--recurse-objects] + * : Enable recursing into objects to replace strings. Defaults to true; + * pass --no-recurse-objects to disable. * * [--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. + * : Runs the search using a regular expression. Warning: search-replace + * will take about 15-20x longer when using --regex. * * ## EXAMPLES * From 03bdf9641f5eeb214f551fe9b7872d01aace413f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 10:57:55 -0800 Subject: [PATCH 3941/4858] Specify context for missing required files ``` Error: Required file 'missing-file.php' doesn't exist (from project's wp-cli.yml). ``` ``` Error: Required file 'baz.php' doesn't exist (from global config.yml). ``` --- features/config.feature | 45 +++++++++++++++++++++++++++++++---------- php/WP_CLI/Runner.php | 26 +++++++++++++++++++++++- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/features/config.feature b/features/config.feature index b56b58f24f..9702f8da7e 100644 --- a/features/config.feature +++ b/features/config.feature @@ -231,22 +231,45 @@ Feature: Have a config file Scenario: Missing required files should not fatal WP-CLI Given an empty directory And a wp-cli.yml file: - """ - require: - - missing-file.php - """ + """ + require: + - missing-file.php + """ - When I try `wp help` - Then STDERR should contain: - """ - Error: Required file 'missing-file.php' doesn't exist - """ + When I try `wp help` + Then STDERR should contain: + """ + Error: Required file 'missing-file.php' doesn't exist (from project's wp-cli.yml). + """ When I run `wp cli info` - Then STDOUT should not be empty + Then STDOUT should not be empty When I run `wp --info` - Then STDOUT should not be empty + Then STDOUT should not be empty + + Scenario: Missing required file in global config + Given an empty directory + And a config.yml file: + """ + require: + - /foo/baz.php + """ + + When I try `WP_CLI_CONFIG_PATH=config.yml wp help` + Then STDERR should contain: + """ + Error: Required file 'baz.php' doesn't exist (from global config.yml). + """ + + Scenario: Missing required file as runtime argument + Given an empty directory + + When I try `wp help --require=foo.php` + Then STDERR should contain: + """ + Error: Required file 'foo.php' doesn't exist (from runtime argument). + """ @require-wp-3.9 Scenario: WordPress install with local dev DOMAIN_CURRENT_SITE diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 9da535565e..d33094c7e9 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -25,6 +25,8 @@ class Runner { private $_project_config_path_debug; + private $_required_files; + public function __get( $key ) { if ( '_' === $key[0] ) return null; @@ -535,7 +537,11 @@ private function init_config() { $this->project_config_path = $this->get_project_config_path(); $configurator->merge_yml( $this->global_config_path ); + $config = $configurator->to_array(); + $this->_required_files['global'] = $config[0]['require']; $configurator->merge_yml( $this->project_config_path ); + $config = $configurator->to_array(); + $this->_required_files['project'] = $config[0]['require']; } // Runtime config and args @@ -550,6 +556,7 @@ private function init_config() { } list( $this->config, $this->extra_config ) = $configurator->to_array(); + $this->_required_files['runtime'] = $this->config['require']; } private function check_root() { @@ -605,7 +612,24 @@ public function start() { if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { if ( ! file_exists( $path ) ) { - WP_CLI::error( sprintf( "Required file '%s' doesn't exist", basename( $path ) ) ); + $context = ''; + foreach( array( 'global', 'project', 'runtime' ) as $scope ) { + if ( in_array( $path, $this->_required_files[ $scope ] ) ) { + switch ( $scope ) { + case 'global': + $context = ' (from global ' . basename( $this->global_config_path ) . ')'; + break; + case 'project': + $context = ' (from project\'s ' . basename( $this->project_config_path ) . ')'; + break; + case 'runtime': + $context = ' (from runtime argument)'; + break; + } + break; + } + } + WP_CLI::error( sprintf( "Required file '%s' doesn't exist%s.", basename( $path ), $context ) ); } Utils\load_file( $path ); WP_CLI::debug( 'Required file from config: ' . $path ); From 253ca656d82afb8606859ed2b91cda325940215d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 13:12:44 -0800 Subject: [PATCH 3942/4858] Assume db errors during `wp_install()` to be installation failure If database errors occur, let the user know with: ``` Error: Installation produced database errors, and may have partially or completely failed. ``` We should only show a success message when there aren't database errors. --- php/commands/core.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 2045dabffa..440a8fd2ca 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -562,6 +562,10 @@ private function _install( $assoc_args ) { } // @codingStandardsIgnoreEnd + if ( ! empty( $GLOBALS['wpdb']->last_error ) ) { + WP_CLI::error( 'Installation produced database errors, and may have partially or completely failed.' ); + } + // Confirm the uploads directory exists $upload_dir = wp_upload_dir(); if ( ! empty( $upload_dir['error'] ) ) { From aff7ef10ad31b15f823536526f4634b1f8f2afb5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 13:53:43 -0800 Subject: [PATCH 3943/4858] Provide plugin header details at runtime for `wp scaffold plugin` This makes it possible to expose them with `--prompt` --- php/commands/scaffold.php | 20 ++++++++++++++++++-- templates/plugin.mustache | 8 ++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index a9d863d4fa..4f302782ea 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -488,6 +488,18 @@ public function package_tests( $args, $assoc_args ) { * [--plugin_name=<title>] * : What to put in the 'Plugin Name:' header * + * [--plugin_description=<description>] + * : What to put in the 'Description:' header. + * + * [--plugin_author=<author>] + * : What to put in the 'Author:' header. + * + * [--plugin_author_uri=<url>] + * : What to put in the 'Author URI:' header. + * + * [--plugin_uri=<url>] + * : What to put in the 'Plugin URI:' header. + * * [--skip-tests] * : Don't generate files for unit testing. * @@ -505,8 +517,12 @@ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; $data = wp_parse_args( $assoc_args, array( - 'plugin_slug' => $plugin_slug, - 'plugin_name' => ucfirst( $plugin_slug ), + 'plugin_slug' => $plugin_slug, + 'plugin_name' => ucfirst( $plugin_slug ), + 'plugin_description' => 'PLUGIN DESCRIPTION HERE', + 'plugin_author' => 'YOUR NAME HERE', + 'plugin_author_uri' => 'YOUR SITE HERE', + 'plugin_uri' => 'PLUGIN SITE HERE', ) ); $data['textdomain'] = $plugin_slug; diff --git a/templates/plugin.mustache b/templates/plugin.mustache index 29aded1f7f..1673f7357e 100644 --- a/templates/plugin.mustache +++ b/templates/plugin.mustache @@ -2,10 +2,10 @@ /** * Plugin Name: {{plugin_name}} * Version: 0.1-alpha - * Description: PLUGIN DESCRIPTION HERE - * Author: YOUR NAME HERE - * Author URI: YOUR SITE HERE - * Plugin URI: PLUGIN SITE HERE + * Description: {{plugin_description}} + * Author: {{plugin_author}} + * Author URI: {{plugin_author_uri}} + * Plugin URI: {{plugin_uri}} * Text Domain: {{textdomain}} * Domain Path: /languages * @package {{plugin_name}} From f93a4b7d443410f9e103c279dff800296c16ce24 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 14:33:53 -0800 Subject: [PATCH 3944/4858] Use `--uploads` with `wp site empty` to delete the uploads dir too --- features/site.feature | 33 +++++++++++++++++++++++++++++++++ php/commands/site.php | 29 ++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/features/site.feature b/features/site.feature index f46478da93..db90fa7de3 100644 --- a/features/site.feature +++ b/features/site.feature @@ -68,6 +68,13 @@ Feature: Manage sites in a multisite installation Scenario: Empty a site Given a WP install + And I run `wp option update uploads_use_yearmonth_folders 0` + And download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1` + Then the wp-content/uploads/large-image.jpg file should exist When I try `wp site url 1` Then STDERR should be: @@ -83,6 +90,7 @@ Feature: Manage sites in a multisite installation When I run `wp site empty --yes` Then STDOUT should not be empty + And the wp-content/uploads/large-image.jpg file should exist When I run `wp post list --format=ids` Then STDOUT should be empty @@ -90,6 +98,31 @@ Feature: Manage sites in a multisite installation When I run `wp term list post_tag --format=ids` Then STDOUT should be empty + Scenario: Empty a site and its uploads directory + Given a WP multisite install + And I run `wp site create --slug=foo` + And I run `wp --url=example.com/foo option update uploads_use_yearmonth_folders 0` + And download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp --url=example.com/foo media import {CACHE_DIR}/large-image.jpg --post_id=1` + Then the wp-content/uploads/sites/2/large-image.jpg file should exist + + When I run `wp site empty --uploads --yes` + Then STDOUT should not be empty + And the wp-content/uploads/sites/2/large-image.jpg file should exist + + When I run `wp post list --format=ids` + Then STDOUT should be empty + + When I run `wp --url=example.com/foo site empty --uploads --yes` + Then STDOUT should not be empty + And the wp-content/uploads/sites/2/large-image.jpg file should not exist + + When I run `wp --url=example.com/foo post list --format=ids` + Then STDOUT should be empty + Scenario: Get site info Given a WP multisite install diff --git a/php/commands/site.php b/php/commands/site.php index d21d1c3615..923abc5806 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -121,6 +121,9 @@ private function _insert_default_terms() { * * ## OPTIONS * + * [--uploads] + * : Also delete *all* files in the site's in the uploads directory. + * * [--yes] * : Proceed to empty the site without a confirmation prompt. * @@ -128,13 +131,37 @@ private function _insert_default_terms() { */ public function _empty( $args, $assoc_args ) { - WP_CLI::confirm( 'Are you sure you want to empty the site at ' . site_url() . ' of all posts, comments, and terms?', $assoc_args ); + $upload_message = ''; + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'uploads' ) ) { + $upload_message = ', and delete its uploads directory'; + } + + WP_CLI::confirm( 'Are you sure you want to empty the site at ' . site_url() . ' of all posts, comments, and terms' . $upload_message . '?', $assoc_args ); $this->_empty_posts(); $this->_empty_comments(); $this->_empty_taxonomies(); $this->_insert_default_terms(); + if ( ! empty( $upload_message ) ) { + $upload_dir = wp_upload_dir(); + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( $upload_dir['basedir'], RecursiveDirectoryIterator::SKIP_DOTS ), + RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ( $files as $fileinfo ) { + $realpath = $fileinfo->getRealPath(); + // Don't clobber subsites when operating on the main site + if ( is_main_site() && false !== stripos( $realpath, '/sites/' ) ) { + continue; + } + $todo = $fileinfo->isDir() ? 'rmdir' : 'unlink'; + $todo( $realpath ); + } + rmdir( $upload_dir['basedir'] ); + } + WP_CLI::success( 'The site at ' . site_url() . ' was emptied.' ); } From c82dfeae61ace3f2306cfa705486f274bd160d92 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 14:35:36 -0800 Subject: [PATCH 3945/4858] Move `site empty` tests into their own file --- features/site-empty.feature | 58 +++++++++++++++++++++++++++++++++++++ features/site.feature | 57 ------------------------------------ 2 files changed, 58 insertions(+), 57 deletions(-) create mode 100644 features/site-empty.feature diff --git a/features/site-empty.feature b/features/site-empty.feature new file mode 100644 index 0000000000..873dfdb22b --- /dev/null +++ b/features/site-empty.feature @@ -0,0 +1,58 @@ +Feature: Empty a WordPress site of its data + + Scenario: Empty a site + Given a WP install + And I run `wp option update uploads_use_yearmonth_folders 0` + And download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1` + Then the wp-content/uploads/large-image.jpg file should exist + + When I try `wp site url 1` + Then STDERR should be: + """ + Error: This is not a multisite install. + """ + + When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` + Then STDOUT should not be empty + + When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term'` + Then STDOUT should not be empty + + When I run `wp site empty --yes` + Then STDOUT should not be empty + And the wp-content/uploads/large-image.jpg file should exist + + When I run `wp post list --format=ids` + Then STDOUT should be empty + + When I run `wp term list post_tag --format=ids` + Then STDOUT should be empty + + Scenario: Empty a site and its uploads directory + Given a WP multisite install + And I run `wp site create --slug=foo` + And I run `wp --url=example.com/foo option update uploads_use_yearmonth_folders 0` + And download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp --url=example.com/foo media import {CACHE_DIR}/large-image.jpg --post_id=1` + Then the wp-content/uploads/sites/2/large-image.jpg file should exist + + When I run `wp site empty --uploads --yes` + Then STDOUT should not be empty + And the wp-content/uploads/sites/2/large-image.jpg file should exist + + When I run `wp post list --format=ids` + Then STDOUT should be empty + + When I run `wp --url=example.com/foo site empty --uploads --yes` + Then STDOUT should not be empty + And the wp-content/uploads/sites/2/large-image.jpg file should not exist + + When I run `wp --url=example.com/foo post list --format=ids` + Then STDOUT should be empty diff --git a/features/site.feature b/features/site.feature index db90fa7de3..9f80f1cb6c 100644 --- a/features/site.feature +++ b/features/site.feature @@ -66,63 +66,6 @@ Feature: Manage sites in a multisite installation When I try the previous command again Then the return code should be 1 - Scenario: Empty a site - Given a WP install - And I run `wp option update uploads_use_yearmonth_folders 0` - And download: - | path | url | - | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | - - When I run `wp media import {CACHE_DIR}/large-image.jpg --post_id=1` - Then the wp-content/uploads/large-image.jpg file should exist - - When I try `wp site url 1` - Then STDERR should be: - """ - Error: This is not a multisite install. - """ - - When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` - Then STDOUT should not be empty - - When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term'` - Then STDOUT should not be empty - - When I run `wp site empty --yes` - Then STDOUT should not be empty - And the wp-content/uploads/large-image.jpg file should exist - - When I run `wp post list --format=ids` - Then STDOUT should be empty - - When I run `wp term list post_tag --format=ids` - Then STDOUT should be empty - - Scenario: Empty a site and its uploads directory - Given a WP multisite install - And I run `wp site create --slug=foo` - And I run `wp --url=example.com/foo option update uploads_use_yearmonth_folders 0` - And download: - | path | url | - | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | - - When I run `wp --url=example.com/foo media import {CACHE_DIR}/large-image.jpg --post_id=1` - Then the wp-content/uploads/sites/2/large-image.jpg file should exist - - When I run `wp site empty --uploads --yes` - Then STDOUT should not be empty - And the wp-content/uploads/sites/2/large-image.jpg file should exist - - When I run `wp post list --format=ids` - Then STDOUT should be empty - - When I run `wp --url=example.com/foo site empty --uploads --yes` - Then STDOUT should not be empty - And the wp-content/uploads/sites/2/large-image.jpg file should not exist - - When I run `wp --url=example.com/foo post list --format=ids` - Then STDOUT should be empty - Scenario: Get site info Given a WP multisite install From d513302d882a91b23107130b6bbd7f15b68f5813 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 15:33:22 -0800 Subject: [PATCH 3946/4858] Failing test case for `wp core update --minor` It updates to the latest major release, which it shouldn't --- features/core-update.feature | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/features/core-update.feature b/features/core-update.feature index ee2065a3db..058e880d06 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -32,13 +32,13 @@ Feature: Update WordPress core Scenario: Update to the latest minor release Given a WP install - When I run `wp core download --version=3.8 --force` + When I run `wp core download --version=3.7.9 --force` Then STDOUT should not be empty When I run `wp core update --minor` Then STDOUT should contain: """ - Downloading update + Updating to version 3.7.11 """ When I run `wp core update --minor` @@ -47,6 +47,12 @@ Feature: Update WordPress core Success: WordPress is at the latest minor release. """ + When I run `wp core version` + Then STDOUT should be: + """ + 3.7.11 + """ + @less-than-php-7 Scenario: Core update from cache Given a WP install From 2d3950c4591b49d54566a78cddfb6ffecafadc77 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 15:35:05 -0800 Subject: [PATCH 3947/4858] Fix `wp core update --minor` by using the proper return value --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 440a8fd2ca..c8d841246c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -882,7 +882,7 @@ function update( $args, $assoc_args ) { if ( empty( $args[0] ) && empty( $assoc_args['version'] ) && \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) ) { $updates = $this->get_updates( array( 'minor' => true ) ); if ( ! empty( $updates ) ) { - $assoc_args['version'] = $updates['version']; + $assoc_args['version'] = $updates[0]['version']; } else { WP_CLI::success( 'WordPress is at the latest minor release.' ); return; From b701632fb552c6c370366bd1a153bb29ddfcf29c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 15:41:47 -0800 Subject: [PATCH 3948/4858] Failing testcase for using `--url` with multisite in WP < 3.9 --- features/flags.feature | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index 0ecbf1bd80..b521a65f1e 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -13,6 +13,16 @@ Feature: Global flags } """ + Scenario: Setting the URL on multisite + Given a WP multisite install + And I run `wp site create --slug=foo` + + When I run `wp --url=example.com/foo option get home` + Then STDOUT should be: + """ + http://example.com/foo + """ + @require-wp-3.9 Scenario: Invalid URL Given a WP multisite install From f08fbf9b173bf2f1baf94585b025789043747f04 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 29 Dec 2015 15:50:28 -0800 Subject: [PATCH 3949/4858] Globalize `$path`, used until WP 3.9 for determining subsites in MS --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index d33094c7e9..af6932e2d2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -730,7 +730,7 @@ public function start() { public function load_wordpress() { static $wp_cli_is_loaded; // Globals not explicitly globalized in WordPress - global $site_id, $public, $current_site, $current_blog, $shortcode_tags; + global $site_id, $public, $current_site, $current_blog, $path, $shortcode_tags; if ( ! empty( $wp_cli_is_loaded ) ) { return; From 4f8eed42b20451e2980ed03e97213988daae7036 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 07:17:35 -0800 Subject: [PATCH 3950/4858] Include ci/behat-tags.php in `scaffold package-tests` --- ci/behat-tags.php | 13 +++++++++++++ features/scaffold.feature | 4 ++++ php/commands/scaffold.php | 1 + 3 files changed, 18 insertions(+) diff --git a/ci/behat-tags.php b/ci/behat-tags.php index 7595af15b6..14e52e3e81 100644 --- a/ci/behat-tags.php +++ b/ci/behat-tags.php @@ -1,4 +1,17 @@ <?php +/** + * Generate a list of tags to skip during the test run. + * + * Require a minimum version of WordPress: + * + * @require-wp-4.0 + * Scenario: Core translation CRUD + * + * Then use in bash script: + * + * BEHAT_TAGS=$(php behat-tags.php) + * vendor/bin/behat --format progress $BEHAT_TAGS + */ function version_tags( $prefix, $current, $operator = '<' ) { if ( ! $current ) diff --git a/features/scaffold.feature b/features/scaffold.feature index 4ab5c271fb..f2653bec21 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -208,6 +208,10 @@ Feature: WordPress code scaffolding Then STDOUT should not be empty And the community-command/.travis.yml file should exist And the community-command/bin/install-package-tests.sh file should exist + And the community-command/utils/behat-tags.php file should contain: + """ + require-wp + """ And the community-command/utils/get-package-require-from-composer.php file should exist And the community-command/features directory should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 4f302782ea..1df51eb1b0 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -439,6 +439,7 @@ public function package_tests( $args, $assoc_args ) { 'features/bootstrap/support.php' => $bootstrap_dir, 'php/WP_CLI/Process.php' => $bootstrap_dir, 'php/utils.php' => $bootstrap_dir, + 'ci/behat-tags.php' => $utils_dir, 'utils/get-package-require-from-composer.php' => $utils_dir, 'features/steps/given.php' => $steps_dir, 'features/steps/when.php' => $steps_dir, From de34d7f78276c4c6808670f42752e97b447ba2bc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 07:39:21 -0800 Subject: [PATCH 3951/4858] Support for testing multisite with subdomains --- features/site.feature | 20 +++++++++++++++++++- features/steps/given.php | 7 ++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/features/site.feature b/features/site.feature index 9f80f1cb6c..a6980b1638 100644 --- a/features/site.feature +++ b/features/site.feature @@ -9,8 +9,26 @@ Feature: Manage sites in a multisite installation Network with id 1000 does not exist. """ + Scenario: Create a subdomain site + Given a WP multisite subdomain install + + When I run `wp site create --slug=first` + Then STDOUT should not be empty + + When I run `wp site list --fields=blog_id,url` + Then STDOUT should be a table containing rows: + | blog_id | url | + | 1 | http://example.com/ | + | 2 | http://first.example.com/ | + + When I run `wp --url=first.example.com option get home` + Then STDOUT should be: + """ + http://first.example.com + """ + Scenario: Delete a site by id - Given a WP multisite install + Given a WP multisite subdirectory install When I run `wp site create --slug=first --porcelain` Then STDOUT should be a number diff --git a/features/steps/given.php b/features/steps/given.php index 0d6509876a..017d1a5d82 100644 --- a/features/steps/given.php +++ b/features/steps/given.php @@ -55,10 +55,11 @@ function ( $world, $subdir ) { } ); -$steps->Given( '/^a WP multisite install$/', - function ( $world ) { +$steps->Given( '/^a WP multisite (subdirectory|subdomain)?\s?install$/', + function ( $world, $type = 'subdirectory' ) { $world->install_wp(); - $world->proc( 'wp core install-network', array( 'title' => 'WP CLI Network' ) )->run_check(); + $subdomains = ! empty( $type ) && 'subdomain' === $type ? 1 : 0; + $world->proc( 'wp core install-network', array( 'title' => 'WP CLI Network', 'subdomains' => $subdomains ) )->run_check(); } ); From 485a346fd4ec4270b172f706564cd1f86c1d0e7e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 08:04:08 -0800 Subject: [PATCH 3952/4858] Make sure to include `behat-tags.php` in the Phar build --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 7e2432bee2..6e7924e6a1 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -97,6 +97,7 @@ function set_file_contents( $phar, $path, $content ) { } add_file( $phar, WP_CLI_ROOT . '/vendor/autoload.php' ); +add_file( $phar, WP_CLI_ROOT . '/ci/behat-tags.php' ); add_file( $phar, WP_CLI_ROOT . '/utils/get-package-require-from-composer.php' ); add_file( $phar, WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); From 1ae891308e94b75c233f26eff6ba4c646eaac0bc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 08:34:07 -0800 Subject: [PATCH 3953/4858] Use `--skip-email` to disable email notif on `core install` --- php/commands/core.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index c8d841246c..4e901c0d91 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -400,6 +400,9 @@ public function is_installed( $_, $assoc_args ) { * * --admin_email=<email> * : The email address for the admin user. + * + * [--skip-email] + * : Don't send an email notification to the new admin user. */ public function install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -468,6 +471,9 @@ public function multisite_convert( $args, $assoc_args ) { * --admin_email=<email> * : The email address for the admin user. * + * [--skip-email] + * : Don't send an email notification to the new admin user. + * * @subcommand multisite-install */ public function multisite_install( $args, $assoc_args ) { @@ -533,6 +539,12 @@ private function _install( $assoc_args ) { return false; } + if ( true === \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-email' ) ) { + function wp_new_blog_notification() { + // Silence is golden + } + } + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); extract( wp_parse_args( $assoc_args, array( From 1d7adbc5f8dbf21934f6e015c488f1aa5c86ae8b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 08:58:17 -0800 Subject: [PATCH 3954/4858] Failing test case for #1950 --- features/plugin-update.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 features/plugin-update.feature diff --git a/features/plugin-update.feature b/features/plugin-update.feature new file mode 100644 index 0000000000..818430cb40 --- /dev/null +++ b/features/plugin-update.feature @@ -0,0 +1,23 @@ +Feature: Update WordPress plugins + + Scenario: Updating plugin with invalid version shouldn't remove the old version + Given a WP install + + When I run `wp plugin install akismet --version=2.5.6 --force` + Then STDOUT should not be empty + + When I run `wp plugin list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | akismet | inactive | available | 2.5.6 | + + When I try `wp plugin update akismet --version=2.9.0` + Then STDERR should be: + """ + Error: Can't find the requested plugin's version 2.9.0 in the WordPress.org plugin repository (HTTP code 404). + """ + + When I run `wp plugin list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | akismet | inactive | available | 2.5.6 | From abd3a1dcb9d48c30fd2a88ab397a226a84773277 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 09:03:03 -0800 Subject: [PATCH 3955/4858] Updating plugin with invalid version shouldn't delete the plugin `install --force` does the trick for us, so we don't need to delete --- features/plugin-update.feature | 12 ++++++++++++ php/commands/plugin.php | 2 -- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/features/plugin-update.feature b/features/plugin-update.feature index 818430cb40..7144cccaea 100644 --- a/features/plugin-update.feature +++ b/features/plugin-update.feature @@ -6,6 +6,10 @@ Feature: Update WordPress plugins When I run `wp plugin install akismet --version=2.5.6 --force` Then STDOUT should not be empty + When I run `wp plugin list --name=akismet --field=update_version` + Then STDOUT should not be empty + And save STDOUT as {UPDATE_VERSION} + When I run `wp plugin list` Then STDOUT should be a table containing rows: | name | status | update | version | @@ -21,3 +25,11 @@ Feature: Update WordPress plugins Then STDOUT should be a table containing rows: | name | status | update | version | | akismet | inactive | available | 2.5.6 | + + When I run `wp plugin update akismet` + Then STDOUT should not be empty + + When I run `wp plugin list` + Then STDOUT should be a table containing rows: + | name | status | update | version | + | akismet | inactive | none | {UPDATE_VERSION} | diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 37181d3c03..885f69fb96 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -351,8 +351,6 @@ protected function install_from_repo( $slug, $assoc_args ) { function update( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { - $this->_delete( $plugin ); - $assoc_args['force'] = 1; $this->install( array( $plugin->name ), $assoc_args ); } From 0b53f0e46b9fbe716e21bee4b8732b5e91c6bda7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 09:13:50 -0800 Subject: [PATCH 3956/4858] Indicate error when `wp_insert_user()` returns 0 It shouldn't, but in some cases it does. Also prevents email notification from being sent when a user isn't created. --- php/commands/user.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index d3fd69bb98..130a4ff348 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -299,11 +299,10 @@ public function create( $args, $assoc_args ) { $user_id = wp_insert_user( $user ); } - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'send-email' ) ) { - self::wp_new_user_notification( $user_id, $user->user_pass ); - } - - if ( is_wp_error( $user_id ) ) { + if ( ! $user_id || is_wp_error( $user_id ) ) { + if ( ! $user_id ) { + $user_id = 'Unknown error creating new user.'; + } WP_CLI::error( $user_id ); } else { if ( false === $user->role ) { @@ -312,6 +311,10 @@ public function create( $args, $assoc_args ) { } } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'send-email' ) ) { + self::wp_new_user_notification( $user_id, $user->user_pass ); + } + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ) ) { WP_CLI::line( $user_id ); } else { From 6c87033f52dd97d14e995e208f66f4e2f9a52d84 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 10:00:23 -0800 Subject: [PATCH 3957/4858] Document how users can export a random subset of their content --- php/commands/export.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/export.php b/php/commands/export.php index 6fc6dfba3e..8d5731df0f 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -62,6 +62,9 @@ class Export_Command extends WP_CLI_Command { * wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 * * wp export --dir=/tmp/ --post__in=123,124,125 + * + * # Export a random subset of content + * wp export --post__in=$(wp post list --post_type=post --orderby=rand --posts_per_page=8 --format=ids) */ public function __invoke( $_, $assoc_args ) { $defaults = array( From e78b2471950e7dcff8eca49127bfb651af8e7ddc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 15:18:40 -0800 Subject: [PATCH 3958/4858] Ensure `wp_new_blog_notification()` isn't defined before we do so While it wouldn't realistically ever be defined in this scope, a PHP script calling `install()` twice would fatal on the second time. Better safe than sorry. --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 4e901c0d91..a754c7fdd2 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -539,7 +539,8 @@ private function _install( $assoc_args ) { return false; } - if ( true === \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-email' ) ) { + if ( true === \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-email' ) + && ! function_exists( 'wp_new_blog_notification' ) ) { function wp_new_blog_notification() { // Silence is golden } From 7028b1c32ff9333efff93336f240f1fb746d39ec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 15:45:54 -0800 Subject: [PATCH 3959/4858] Use `mustangostang/spyc` instead of bundling our own copy --- composer.json | 2 +- composer.lock | 47 ++ php/Spyc.php | 1035 ------------------------------------------- utils/make-phar.php | 1 + 4 files changed, 49 insertions(+), 1036 deletions(-) delete mode 100644 php/Spyc.php diff --git a/composer.json b/composer.json index d4bee10814..d8d6c5246d 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "php": ">=5.3.2", "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", + "mustangostang/spyc": "0.5.1", "composer/semver": "1.0.0", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", @@ -33,7 +34,6 @@ }, "autoload": { "psr-0": { "WP_CLI": "php" }, - "files": [ "php/Spyc.php" ], "classmap": [ "php/export" ] } } diff --git a/composer.lock b/composer.lock index d568185770..5dc2673cb9 100644 --- a/composer.lock +++ b/composer.lock @@ -114,6 +114,53 @@ ], "time": "2015-08-15 19:23:13" }, + { + "name": "mustangostang/spyc", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/mustangostang/spyc.git", + "reference": "dc4785b4d7227fd9905e086d499fb8abfadf9977" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/dc4785b4d7227fd9905e086d499fb8abfadf9977", + "reference": "dc4785b4d7227fd9905e086d499fb8abfadf9977", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT License" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2013-02-21 10:52:01" + }, { "name": "nb/oxymel", "version": "v0.1.0", diff --git a/php/Spyc.php b/php/Spyc.php deleted file mode 100644 index 7a0c282846..0000000000 --- a/php/Spyc.php +++ /dev/null @@ -1,1035 +0,0 @@ -<?php -/** - * Spyc -- A Simple PHP YAML Class - * @version 0.5 - * @author Vlad Andersen <vlad.andersen@gmail.com> - * @author Chris Wanstrath <chris@ozmm.org> - * @link http://code.google.com/p/spyc/ - * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen - * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @package Spyc - */ - -if (!function_exists('spyc_load')) : - /** - * Parses YAML to array. - * @param string $string YAML string. - * @return array - */ - function spyc_load ($string) { - return Spyc::YAMLLoadString($string); - } -endif; - -if (!function_exists('spyc_load_file')) : - /** - * Parses YAML to array. - * @param string $file Path to YAML file. - * @return array - */ - function spyc_load_file ($file) { - return Spyc::YAMLLoad($file); - } -endif; - -if ( ! class_exists( 'Spyc' ) ) : -/** - * The Simple PHP YAML Class. - * - * This class can be used to read a YAML file and convert its contents - * into a PHP array. It currently supports a very limited subsection of - * the YAML spec. - * - * Usage: - * <code> - * $Spyc = new Spyc; - * $array = $Spyc->load($file); - * </code> - * or: - * <code> - * $array = Spyc::YAMLLoad($file); - * </code> - * or: - * <code> - * $array = spyc_load_file($file); - * </code> - * @package Spyc - */ -class Spyc { - - // SETTINGS - - const REMPTY = "\0\0\0\0\0"; - - /** - * Setting this to true will force YAMLDump to enclose any string value in - * quotes. False by default. - * - * @var bool - */ - public $setting_dump_force_quotes = false; - - /** - * Setting this to true will forse YAMLLoad to use syck_load function when - * possible. False by default. - * @var bool - */ - public $setting_use_syck_is_possible = false; - - - - /**#@+ - * @access private - * @var mixed - */ - private $_dumpIndent; - private $_dumpWordWrap; - private $_containsGroupAnchor = false; - private $_containsGroupAlias = false; - private $path; - private $result; - private $LiteralPlaceHolder = '___YAML_Literal_Block___'; - private $SavedGroups = array(); - private $indent; - /** - * Path modifier that should be applied after adding current element. - * @var array - */ - private $delayedPath = array(); - - /**#@+ - * @access public - * @var mixed - */ - public $_nodeId; - -/** - * Load a valid YAML string to Spyc. - * @param string $input - * @return array - */ - public function load ($input) { - return $this->__loadString($input); - } - - /** - * Load a valid YAML file to Spyc. - * @param string $file - * @return array - */ - public function loadFile ($file) { - return $this->__load($file); - } - - /** - * Load YAML into a PHP array statically - * - * The load method, when supplied with a YAML stream (string or file), - * will do its best to convert YAML in a file into a PHP array. Pretty - * simple. - * Usage: - * <code> - * $array = Spyc::YAMLLoad('lucky.yaml'); - * print_r($array); - * </code> - * @access public - * @return array - * @param string $input Path of YAML file or string containing YAML - */ - public static function YAMLLoad($input) { - $Spyc = new Spyc; - return $Spyc->__load($input); - } - - /** - * Load a string of YAML into a PHP array statically - * - * The load method, when supplied with a YAML string, will do its best - * to convert YAML in a string into a PHP array. Pretty simple. - * - * Note: use this function if you don't want files from the file system - * loaded and processed as YAML. This is of interest to people concerned - * about security whose input is from a string. - * - * Usage: - * <code> - * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); - * print_r($array); - * </code> - * @access public - * @return array - * @param string $input String containing YAML - */ - public static function YAMLLoadString($input) { - $Spyc = new Spyc; - return $Spyc->__loadString($input); - } - - /** - * Dump YAML from PHP array statically - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as nothing.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public static function YAMLDump($array,$indent = false,$wordwrap = false) { - $spyc = new Spyc; - return $spyc->dump($array,$indent,$wordwrap); - } - - - /** - * Dump PHP array to YAML - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. Pretty simple. Feel free to - * save the returned string as tasteful.yaml and pass it around. - * - * Oh, and you can decide how big the indent is and what the wordwrap - * for folding is. Pretty cool -- just pass in 'false' for either if - * you want to use the default. - * - * Indent's default is 2 spaces, wordwrap's default is 40 characters. And - * you can turn off wordwrap by passing in 0. - * - * @access public - * @return string - * @param array $array PHP array - * @param int $indent Pass in false to use the default, which is 2 - * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) - */ - public function dump($array,$indent = false,$wordwrap = false) { - // Dumps to some very clean YAML. We'll have to add some more features - // and options soon. And better support for folding. - - // New features and options. - if ($indent === false or !is_numeric($indent)) { - $this->_dumpIndent = 2; - } else { - $this->_dumpIndent = $indent; - } - - if ($wordwrap === false or !is_numeric($wordwrap)) { - $this->_dumpWordWrap = 40; - } else { - $this->_dumpWordWrap = $wordwrap; - } - - // New YAML document - $string = "---\n"; - - // Start at the base of the array and move through it. - if ($array) { - $array = (array)$array; - $previous_key = -1; - foreach ($array as $key => $value) { - if (!isset($first_key)) $first_key = $key; - $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array); - $previous_key = $key; - } - } - return $string; - } - - /** - * Attempts to convert a key / value array item to YAML - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { - if (is_array($value)) { - if (empty ($value)) - return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); - // It has children. What to do? - // Make it the right kind of item - $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array); - // Add the indent - $indent += $this->_dumpIndent; - // Yamlize the array - $string .= $this->_yamlizeArray($value,$indent); - } elseif (!is_array($value)) { - // It doesn't have children. Yip. - $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array); - } - return $string; - } - - /** - * Attempts to convert an array to YAML - * @access private - * @return string - * @param $array The array you want to convert - * @param $indent The indent of the current level - */ - private function _yamlizeArray($array,$indent) { - if (is_array($array)) { - $string = ''; - $previous_key = -1; - foreach ($array as $key => $value) { - if (!isset($first_key)) $first_key = $key; - $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array); - $previous_key = $key; - } - return $string; - } else { - return false; - } - } - - /** - * Returns YAML from a key and a value - * @access private - * @return string - * @param $key The name of the key - * @param $value The value of the item - * @param $indent The indent of the current node - */ - private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) { - // do some folding here, for blocks - if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || - strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false || - strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 || - substr ($value, -1, 1) == ':') - ) { - $value = $this->_doLiteralBlock($value,$indent); - } else { - $value = $this->_doFolding($value,$indent); - } - - if ($value === array()) $value = '[ ]'; - if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) { - $value = $this->_doLiteralBlock($value,$indent); - } - if (trim ($value) != $value) - $value = $this->_doLiteralBlock($value,$indent); - - if (is_bool($value)) { - $value = ($value) ? "true" : "false"; - } - - if ($value === null) $value = 'null'; - if ($value === "'" . self::REMPTY . "'") $value = null; - - $spaces = str_repeat(' ',$indent); - - //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { - if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) { - // It's a sequence - $string = $spaces.'- '.$value."\n"; - } else { - // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); - // It's mapped - if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; } - $string = rtrim ($spaces.$key.': '.$value)."\n"; - } - return $string; - } - - /** - * Creates a literal block for dumping - * @access private - * @return string - * @param $value - * @param $indent int The value of the indent - */ - private function _doLiteralBlock($value,$indent) { - if ($value === "\n") return '\n'; - if (strpos($value, "\n") === false && strpos($value, "'") === false) { - return sprintf ("'%s'", $value); - } - if (strpos($value, "\n") === false && strpos($value, '"') === false) { - return sprintf ('"%s"', $value); - } - $exploded = explode("\n",$value); - $newValue = '|'; - $indent += $this->_dumpIndent; - $spaces = str_repeat(' ',$indent); - foreach ($exploded as $line) { - $newValue .= "\n" . $spaces . ($line); - } - return $newValue; - } - - /** - * Folds a string of text, if necessary - * @access private - * @return string - * @param $value The string you wish to fold - */ - private function _doFolding($value,$indent) { - // Don't do anything if wordwrap is set to 0 - - if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { - $indent += $this->_dumpIndent; - $indent = str_repeat(' ',$indent); - $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); - $value = ">\n".$indent.$wrapped; - } else { - if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY) - $value = '"' . $value . '"'; - } - - - return $value; - } - -// LOADING FUNCTIONS - - private function __load($input) { - $Source = $this->loadFromSource($input); - return $this->loadWithSource($Source); - } - - private function __loadString($input) { - $Source = $this->loadFromString($input); - return $this->loadWithSource($Source); - } - - private function loadWithSource($Source) { - if (empty ($Source)) return array(); - if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { - $array = syck_load (implode ('', $Source)); - return is_array($array) ? $array : array(); - } - - $this->path = array(); - $this->result = array(); - - $cnt = count($Source); - for ($i = 0; $i < $cnt; $i++) { - $line = $Source[$i]; - - $this->indent = strlen($line) - strlen(ltrim($line)); - $tempPath = $this->getParentPathByIndent($this->indent); - $line = self::stripIndent($line, $this->indent); - if (self::isComment($line)) continue; - if (self::isEmpty($line)) continue; - $this->path = $tempPath; - - $literalBlockStyle = self::startsLiteralBlock($line); - if ($literalBlockStyle) { - $line = rtrim ($line, $literalBlockStyle . " \n"); - $literalBlock = ''; - $line .= $this->LiteralPlaceHolder; - $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1])); - while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { - $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent); - } - $i--; - } - - while (++$i < $cnt && self::greedilyNeedNextLine($line)) { - $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); - } - $i--; - - - - if (strpos ($line, '#')) { - if (strpos ($line, '"') === false && strpos ($line, "'") === false) - $line = preg_replace('/\s+#(.+)$/','',$line); - } - - $lineArray = $this->_parseLine($line); - - if ($literalBlockStyle) - $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); - - $this->addArray($lineArray, $this->indent); - - foreach ($this->delayedPath as $indent => $delayedPath) - $this->path[$indent] = $delayedPath; - - $this->delayedPath = array(); - - } - return $this->result; - } - - private function loadFromSource ($input) { - if (!empty($input) && strpos($input, "\n") === false && file_exists($input)) - return file($input); - - return $this->loadFromString($input); - } - - private function loadFromString ($input) { - $lines = explode("\n",$input); - foreach ($lines as $k => $_) { - $lines[$k] = rtrim ($_, "\r"); - } - return $lines; - } - - /** - * Parses YAML code and returns an array for a node - * @access private - * @return array - * @param string $line A line from the YAML file - */ - private function _parseLine($line) { - if (!$line) return array(); - $line = trim($line); - if (!$line) return array(); - - $array = array(); - - $group = $this->nodeContainsGroup($line); - if ($group) { - $this->addGroup($line, $group); - $line = $this->stripGroup ($line, $group); - } - - if ($this->startsMappedSequence($line)) - return $this->returnMappedSequence($line); - - if ($this->startsMappedValue($line)) - return $this->returnMappedValue($line); - - if ($this->isArrayElement($line)) - return $this->returnArrayElement($line); - - if ($this->isPlainArray($line)) - return $this->returnPlainArray($line); - - - return $this->returnKeyValuePair($line); - - } - - /** - * Finds the type of the passed value, returns the value as the new type. - * @access private - * @param string $value - * @return mixed - */ - private function _toType($value) { - if ($value === '') return null; - $first_character = $value[0]; - $last_character = substr($value, -1, 1); - - $is_quoted = false; - do { - if (!$value) break; - if ($first_character != '"' && $first_character != "'") break; - if ($last_character != '"' && $last_character != "'") break; - $is_quoted = true; - } while (0); - - if ($is_quoted) - return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\'')); - - if (strpos($value, ' #') !== false && !$is_quoted) - $value = preg_replace('/\s+#(.+)$/','',$value); - - if (!$is_quoted) $value = str_replace('\n', "\n", $value); - - if ($first_character == '[' && $last_character == ']') { - // Take out strings sequences and mappings - $innerValue = trim(substr ($value, 1, -1)); - if ($innerValue === '') return array(); - $explode = $this->_inlineEscape($innerValue); - // Propagate value array - $value = array(); - foreach ($explode as $v) { - $value[] = $this->_toType($v); - } - return $value; - } - - if (strpos($value,': ')!==false && $first_character != '{') { - $array = explode(': ',$value); - $key = trim($array[0]); - array_shift($array); - $value = trim(implode(': ',$array)); - $value = $this->_toType($value); - return array($key => $value); - } - - if ($first_character == '{' && $last_character == '}') { - $innerValue = trim(substr ($value, 1, -1)); - if ($innerValue === '') return array(); - // Inline Mapping - // Take out strings sequences and mappings - $explode = $this->_inlineEscape($innerValue); - // Propagate value array - $array = array(); - foreach ($explode as $v) { - $SubArr = $this->_toType($v); - if (empty($SubArr)) continue; - if (is_array ($SubArr)) { - $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; - } - $array[] = $SubArr; - } - return $array; - } - - if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { - return null; - } - - if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){ - $intvalue = (int)$value; - if ($intvalue != PHP_INT_MAX) - $value = $intvalue; - return $value; - } - - if (in_array($value, - array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) { - return true; - } - - if (in_array(strtolower($value), - array('false', 'off', '-', 'no', 'n'))) { - return false; - } - - if (is_numeric($value)) { - if ($value === '0') return 0; - if (rtrim ($value, 0) === $value) - $value = (float)$value; - return $value; - } - - return $value; - } - - /** - * Used in inlines to check for more inlines or quoted strings - * @access private - * @return array - */ - private function _inlineEscape($inline) { - // There's gotta be a cleaner way to do this... - // While pure sequences seem to be nesting just fine, - // pure mappings and mappings with sequences inside can't go very - // deep. This needs to be fixed. - - $seqs = array(); - $maps = array(); - $saved_strings = array(); - - // Check for strings - $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; - if (preg_match_all($regex,$inline,$strings)) { - $saved_strings = $strings[0]; - $inline = preg_replace($regex,'YAMLString',$inline); - } - unset($regex); - - $i = 0; - do { - - // Check for sequences - while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { - $seqs[] = $matchseqs[0]; - $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); - } - - // Check for mappings - while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { - $maps[] = $matchmaps[0]; - $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); - } - - if ($i++ >= 10) break; - - } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); - - $explode = explode(', ',$inline); - $stringi = 0; $i = 0; - - while (1) { - - // Re-add the sequences - if (!empty($seqs)) { - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - foreach ($seqs as $seqk => $seq) { - $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); - $value = $explode[$key]; - } - } - } - } - - // Re-add the mappings - if (!empty($maps)) { - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLMap') !== false) { - foreach ($maps as $mapk => $map) { - $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); - $value = $explode[$key]; - } - } - } - } - - - // Re-add the strings - if (!empty($saved_strings)) { - foreach ($explode as $key => $value) { - while (strpos($value,'YAMLString') !== false) { - $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); - unset($saved_strings[$stringi]); - ++$stringi; - $value = $explode[$key]; - } - } - } - - $finished = true; - foreach ($explode as $key => $value) { - if (strpos($value,'YAMLSeq') !== false) { - $finished = false; break; - } - if (strpos($value,'YAMLMap') !== false) { - $finished = false; break; - } - if (strpos($value,'YAMLString') !== false) { - $finished = false; break; - } - } - if ($finished) break; - - $i++; - if ($i > 10) - break; // Prevent infinite loops. - } - - return $explode; - } - - private function literalBlockContinues ($line, $lineIndent) { - if (!trim($line)) return true; - if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true; - return false; - } - - private function referenceContentsByAlias ($alias) { - do { - if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } - $groupPath = $this->SavedGroups[$alias]; - $value = $this->result; - foreach ($groupPath as $k) { - $value = $value[$k]; - } - } while (false); - return $value; - } - - private function addArrayInline ($array, $indent) { - $CommonGroupPath = $this->path; - if (empty ($array)) return false; - - foreach ($array as $k => $_) { - $this->addArray(array($k => $_), $indent); - $this->path = $CommonGroupPath; - } - return true; - } - - private function addArray ($incoming_data, $incoming_indent) { - - // print_r ($incoming_data); - - if (count ($incoming_data) > 1) - return $this->addArrayInline ($incoming_data, $incoming_indent); - - $key = key ($incoming_data); - $value = \WP_CLI\Utils\get_flag_value( $incoming_data, $key ); - if ($key === '__!YAMLZero') $key = '0'; - - if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. - if ($key || $key === '' || $key === '0') { - $this->result[$key] = $value; - } else { - $this->result[] = $value; end ($this->result); $key = key ($this->result); - } - $this->path[$incoming_indent] = $key; - return; - } - - - - $history = array(); - // Unfolding inner array tree. - $history[] = $_arr = $this->result; - foreach ($this->path as $k) { - $history[] = $_arr = $_arr[$k]; - } - - if ($this->_containsGroupAlias) { - $value = $this->referenceContentsByAlias($this->_containsGroupAlias); - $this->_containsGroupAlias = false; - } - - - // Adding string or numeric key to the innermost level or $this->arr. - if (is_string($key) && $key == '<<') { - if (!is_array ($_arr)) { $_arr = array (); } - - $_arr = array_merge ($_arr, $value); - } else if ($key || $key === '' || $key === '0') { - if (!is_array ($_arr)) - $_arr = array ($key=>$value); - else - $_arr[$key] = $value; - } else { - if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } - else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } - } - - $reverse_path = array_reverse($this->path); - $reverse_history = array_reverse ($history); - $reverse_history[0] = $_arr; - $cnt = count($reverse_history) - 1; - for ($i = 0; $i < $cnt; $i++) { - $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; - } - $this->result = $reverse_history[$cnt]; - - $this->path[$incoming_indent] = $key; - - if ($this->_containsGroupAnchor) { - $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; - if (is_array ($value)) { - $k = key ($value); - if (!is_int ($k)) { - $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; - } - } - $this->_containsGroupAnchor = false; - } - - } - - private static function startsLiteralBlock ($line) { - $lastChar = substr (trim($line), -1); - if ($lastChar != '>' && $lastChar != '|') return false; - if ($lastChar == '|') return $lastChar; - // HTML tags should not be counted as literal blocks. - if (preg_match ('#<.*?>$#', $line)) return false; - return $lastChar; - } - - private static function greedilyNeedNextLine($line) { - $line = trim ($line); - if (!strlen($line)) return false; - if (substr ($line, -1, 1) == ']') return false; - if ($line[0] == '[') return true; - if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true; - return false; - } - - private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) { - $line = self::stripIndent($line, $indent); - if ($literalBlockStyle !== '|') { - $line = self::stripIndent($line); - } - $line = rtrim ($line, "\r\n\t ") . "\n"; - if ($literalBlockStyle == '|') { - return $literalBlock . $line; - } - if (strlen($line) == 0) - return rtrim($literalBlock, ' ') . "\n"; - if ($line == "\n" && $literalBlockStyle == '>') { - return rtrim ($literalBlock, " \t") . "\n"; - } - if ($line != "\n") - $line = trim ($line, "\r\n ") . " "; - return $literalBlock . $line; - } - - function revertLiteralPlaceHolder ($lineArray, $literalBlock) { - foreach ($lineArray as $k => $_) { - if (is_array($_)) - $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); - else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) - $lineArray[$k] = rtrim ($literalBlock, " \r\n"); - } - return $lineArray; - } - - private static function stripIndent ($line, $indent = -1) { - if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line)); - return substr ($line, $indent); - } - - private function getParentPathByIndent ($indent) { - if ($indent == 0) return array(); - $linePath = $this->path; - do { - end($linePath); $lastIndentInParentPath = key($linePath); - if ($indent <= $lastIndentInParentPath) array_pop ($linePath); - } while ($indent <= $lastIndentInParentPath); - return $linePath; - } - - - private function clearBiggerPathValues ($indent) { - - - if ($indent == 0) $this->path = array(); - if (empty ($this->path)) return true; - - foreach ($this->path as $k => $_) { - if ($k > $indent) unset ($this->path[$k]); - } - - return true; - } - - - private static function isComment ($line) { - if (!$line) return false; - if ($line[0] == '#') return true; - if (trim($line, " \r\n\t") == '---') return true; - return false; - } - - private static function isEmpty ($line) { - return (trim ($line) === ''); - } - - - private function isArrayElement ($line) { - if (!$line) return false; - if ($line[0] != '-') return false; - if (strlen ($line) > 3) - if (substr($line,0,3) == '---') return false; - - return true; - } - - private function isHashElement ($line) { - return strpos($line, ':'); - } - - private function isLiteral ($line) { - if ($this->isArrayElement($line)) return false; - if ($this->isHashElement($line)) return false; - return true; - } - - - private static function unquote ($value) { - if (!$value) return $value; - if (!is_string($value)) return $value; - if ($value[0] == '\'') return trim ($value, '\''); - if ($value[0] == '"') return trim ($value, '"'); - return $value; - } - - private function startsMappedSequence ($line) { - return ($line[0] == '-' && substr ($line, -1, 1) == ':'); - } - - private function returnMappedSequence ($line) { - $array = array(); - $key = self::unquote(trim(substr($line,1,-1))); - $array[$key] = array(); - $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); - return array($array); - } - - private function returnMappedValue ($line) { - $array = array(); - $key = self::unquote (trim(substr($line,0,-1))); - $array[$key] = ''; - return $array; - } - - private function startsMappedValue ($line) { - return (substr ($line, -1, 1) == ':'); - } - - private function isPlainArray ($line) { - return ($line[0] == '[' && substr ($line, -1, 1) == ']'); - } - - private function returnPlainArray ($line) { - return $this->_toType($line); - } - - private function returnKeyValuePair ($line) { - $array = array(); - $key = ''; - if (strpos ($line, ':')) { - // It's a key/value pair most likely - // If the key is in double quotes pull it out - if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { - $value = trim(str_replace($matches[1],'',$line)); - $key = $matches[2]; - } else { - // Do some guesswork as to the key and the value - $explode = explode(':',$line); - $key = trim($explode[0]); - array_shift($explode); - $value = trim(implode(':',$explode)); - } - // Set the type of the value. Int, string, etc - $value = $this->_toType($value); - if ($key === '0') $key = '__!YAMLZero'; - $array[$key] = $value; - } else { - $array = array ($line); - } - return $array; - - } - - - private function returnArrayElement ($line) { - if (strlen($line) <= 1) return array(array()); // Weird %) - $array = array(); - $value = trim(substr($line,1)); - $value = $this->_toType($value); - $array[] = $value; - return $array; - } - - - private function nodeContainsGroup ($line) { - $symbolsForReference = 'A-z0-9_\-'; - if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-) - if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; - if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; - if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1]; - if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1]; - if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1]; - return false; - - } - - private function addGroup ($line, $group) { - if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1); - if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1); - //print_r ($this->path); - } - - private function stripGroup ($line, $group) { - $line = trim(str_replace($group, '', $line)); - return $line; - } -} - -endif; diff --git a/utils/make-phar.php b/utils/make-phar.php index 6e7924e6a1..95e89f38ed 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -73,6 +73,7 @@ function set_file_contents( $phar, $path, $content ) { ->in(WP_CLI_ROOT . '/vendor/nb/oxymel') ->in(WP_CLI_ROOT . '/vendor/ramsey/array_column') ->in(WP_CLI_ROOT . '/vendor/composer/semver') + ->in(WP_CLI_ROOT . '/vendor/mustangostang') ->exclude('test') ->exclude('tests') ->exclude('Tests') From d93fb7d78837d3dca08ac8b16b3b33ca777b013c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 16:33:32 -0800 Subject: [PATCH 3960/4858] Use `--network` flag for `wp transient *` to manage site transients --- features/transient.feature | 56 ++++++++++++++++++++++++++++++++++++++ php/commands/transient.php | 28 ++++++++++++++----- 2 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 features/transient.feature diff --git a/features/transient.feature b/features/transient.feature new file mode 100644 index 0000000000..fcbd9d8ead --- /dev/null +++ b/features/transient.feature @@ -0,0 +1,56 @@ +Feature: Manage WordPress transient cache + + Scenario: Transient CRUD + Given a WP install + + When I try `wp transient get foo` + Then STDERR should be: + """ + Warning: Transient with key "foo" is not set. + """ + + When I run `wp transient set foo bar` + Then STDOUT should be: + """ + Success: Transient added. + """ + + When I run `wp transient get foo` + Then STDOUT should be: + """ + bar + """ + + When I run `wp transient delete foo` + Then STDOUT should be: + """ + Success: Transient deleted. + """ + + Scenario: Network transient CRUD + Given a WP multisite install + And I run `wp site create --slug=foo` + + When I run `wp transient set foo bar --network` + Then STDOUT should be: + """ + Success: Transient added. + """ + + When I run `wp --url=example.com/foo transient get foo --network` + Then STDOUT should be: + """ + bar + """ + + When I try `wp transient get foo` + Then STDERR should be: + """ + Warning: Transient with key "foo" is not set. + """ + + When I run `wp transient delete foo --network` + Then STDOUT should be: + """ + Success: Transient deleted. + """ diff --git a/php/commands/transient.php b/php/commands/transient.php index 6331f633f8..09d05eb1ce 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -17,11 +17,15 @@ class Transient_Command extends WP_CLI_Command { * * [--json] * : Format output as JSON. + * + * [--network] + * : Get the value of the network transient, instead of the single site. */ public function get( $args, $assoc_args ) { list( $key ) = $args; - $value = get_transient( $key ); + $func = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient'; + $value = $func( $key ); if ( false === $value ) { WP_CLI::warning( 'Transient with key "' . $key . '" is not set.' ); @@ -42,16 +46,21 @@ public function get( $args, $assoc_args ) { * * [<expiration>] * : Time until expiration, in seconds. + * + * [--network] + * : Set the transient value on the network, instead of single site. */ - public function set( $args ) { + public function set( $args, $assoc_args ) { list( $key, $value ) = $args; $expiration = \WP_CLI\Utils\get_flag_value( $args, 2, 0 ); - if ( set_transient( $key, $value, $expiration ) ) + $func = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ? 'set_site_transient' : 'set_transient'; + if ( $func( $key, $value, $expiration ) ) { WP_CLI::success( 'Transient added.' ); - else + } else { WP_CLI::error( 'Transient could not be set.' ); + } } /** @@ -59,14 +68,19 @@ public function set( $args ) { * * <key> * : Key for the transient. + * + * [--network] + * : Delete the value of a network transient, instead of that on a single site. */ - public function delete( $args ) { + public function delete( $args, $assoc_args ) { list( $key ) = $args; - if ( delete_transient( $key ) ) { + $func = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ? 'delete_site_transient' : 'delete_transient'; + if ( $func( $key ) ) { WP_CLI::success( 'Transient deleted.' ); } else { - if ( get_transient( $key ) ) + $func = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient'; + if ( $func( $key ) ) WP_CLI::error( 'Transient was not deleted even though the transient appears to exist.' ); else WP_CLI::warning( 'Transient was not deleted; however, the transient does not appear to exist.' ); From 5c78610488c73af3451efacf283d15597b826522 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 16:43:20 -0800 Subject: [PATCH 3961/4858] Move `user import-csv` tests to their own file --- features/user-import-csv.feature | 134 +++++++++++++++++++++++++++++++ features/user.feature | 133 ------------------------------ 2 files changed, 134 insertions(+), 133 deletions(-) create mode 100644 features/user-import-csv.feature diff --git a/features/user-import-csv.feature b/features/user-import-csv.feature new file mode 100644 index 0000000000..990d292436 --- /dev/null +++ b/features/user-import-csv.feature @@ -0,0 +1,134 @@ +Feature: Import users from CSV + + Scenario: Importing users from a CSV file + Given a WP install + And a users.csv file: + """ + user_login,user_email,display_name,role + bobjones,bobjones@example.com,Bob Jones,contributor + newuser1,newuser1@example.com,New User,author + admin,admin@example.com,Existing User,administrator + """ + + When I try `wp user import-csv users-incorrect.csv --skip-update` + Then STDERR should be: + """ + Error: Missing file: users-incorrect.csv + """ + + When I run `wp user import-csv users.csv` + Then STDOUT should not be empty + + When I run `wp user list --format=count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp user list --format=json` + Then STDOUT should be JSON containing: + """ + [{ + "user_login":"admin", + "display_name":"Existing User", + "user_email":"admin@example.com", + "roles":"administrator" + }] + """ + + Scenario: Import new users on multisite + Given a WP multisite install + And a user-invalid.csv file: + """ + user_login,user_email,display_name,role + bob-jones,bobjones@example.com,Bob Jones,contributor + """ + And a user-valid.csv file: + """ + user_login,user_email,display_name,role + bobjones,bobjones@example.com,Bob Jones,contributor + """ + + When I try `wp user import-csv user-invalid.csv` + Then STDERR should contain: + """ + lowercase letters (a-z) and numbers + """ + + When I run `wp user import-csv user-valid.csv` + Then STDOUT should not be empty + + When I run `wp user get bobjones --field=display_name` + Then STDOUT should be: + """ + Bob Jones + """ + + Scenario: Import new users but don't update existing + Given a WP install + And a users.csv file: + """ + user_login,user_email,display_name,role + bobjones,bobjones@example.com,Bob Jones,contributor + newuser1,newuser1@example.com,New User,author + admin,admin@example.com,Existing User,administrator + """ + + When I run `wp user create bobjones bobjones@example.com --display_name="Robert Jones" --role=administrator` + Then STDOUT should not be empty + + When I run `wp user import-csv users.csv --skip-update` + Then STDOUT should not be empty + + When I run `wp user list --format=count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp user get bobjones --fields=user_login,display_name,user_email,roles --format=json` + Then STDOUT should be JSON containing: + """ + { + "user_login":"bobjones", + "display_name":"Robert Jones", + "user_email":"bobjones@example.com", + "roles":"administrator" + } + """ + + Scenario: Import users from a CSV file generated by `wp user list` + Given a WP install + + When I run `wp user delete 1 --yes` + And I run `wp user create bobjones bobjones@example.com --display_name="Bob Jones" --role=contributor` + And I run `wp user create billjones billjones@example.com --display_name="Bill Jones" --role=administrator` + And I run `wp user add-role billjones author` + Then STDOUT should not be empty + + When I run `wp user list --field=user_login | wc -l` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp user list --format=csv > users.csv` + Then the users.csv file should exist + + When I run `wp user delete $(wp user list --format=ids) --yes` + Then STDOUT should not be empty + + When I run `wp user list --field=user_login | wc -l` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp user import-csv users.csv` + Then STDOUT should not be empty + + When I run `wp user list --fields=display_name,roles` + Then STDOUT should be a table containing rows: + | display_name | roles | + | Bob Jones | contributor | + | Bill Jones | administrator,author | diff --git a/features/user.feature b/features/user.feature index 62ed3fe2b8..93a012bb15 100644 --- a/features/user.feature +++ b/features/user.feature @@ -125,70 +125,6 @@ Feature: Manage WordPress users 0 """ - Scenario: Importing users from a CSV file - Given a WP install - And a users.csv file: - """ - user_login,user_email,display_name,role - bobjones,bobjones@example.com,Bob Jones,contributor - newuser1,newuser1@example.com,New User,author - admin,admin@example.com,Existing User,administrator - """ - - When I try `wp user import-csv users-incorrect.csv --skip-update` - Then STDERR should be: - """ - Error: Missing file: users-incorrect.csv - """ - - When I run `wp user import-csv users.csv` - Then STDOUT should not be empty - - When I run `wp user list --format=count` - Then STDOUT should be: - """ - 3 - """ - - When I run `wp user list --format=json` - Then STDOUT should be JSON containing: - """ - [{ - "user_login":"admin", - "display_name":"Existing User", - "user_email":"admin@example.com", - "roles":"administrator" - }] - """ - - Scenario: Import new users on multisite - Given a WP multisite install - And a user-invalid.csv file: - """ - user_login,user_email,display_name,role - bob-jones,bobjones@example.com,Bob Jones,contributor - """ - And a user-valid.csv file: - """ - user_login,user_email,display_name,role - bobjones,bobjones@example.com,Bob Jones,contributor - """ - - When I try `wp user import-csv user-invalid.csv` - Then STDERR should contain: - """ - lowercase letters (a-z) and numbers - """ - - When I run `wp user import-csv user-valid.csv` - Then STDOUT should not be empty - - When I run `wp user get bobjones --field=display_name` - Then STDOUT should be: - """ - Bob Jones - """ - Scenario: Create new users on multisite Given a WP multisite install @@ -207,75 +143,6 @@ Feature: Manage WordPress users Bob Jones """ - Scenario: Import new users but don't update existing - Given a WP install - And a users.csv file: - """ - user_login,user_email,display_name,role - bobjones,bobjones@example.com,Bob Jones,contributor - newuser1,newuser1@example.com,New User,author - admin,admin@example.com,Existing User,administrator - """ - - When I run `wp user create bobjones bobjones@example.com --display_name="Robert Jones" --role=administrator` - Then STDOUT should not be empty - - When I run `wp user import-csv users.csv --skip-update` - Then STDOUT should not be empty - - When I run `wp user list --format=count` - Then STDOUT should be: - """ - 3 - """ - - When I run `wp user get bobjones --fields=user_login,display_name,user_email,roles --format=json` - Then STDOUT should be JSON containing: - """ - { - "user_login":"bobjones", - "display_name":"Robert Jones", - "user_email":"bobjones@example.com", - "roles":"administrator" - } - """ - - Scenario: Import users from a CSV file generated by `wp user list` - Given a WP install - - When I run `wp user delete 1 --yes` - And I run `wp user create bobjones bobjones@example.com --display_name="Bob Jones" --role=contributor` - And I run `wp user create billjones billjones@example.com --display_name="Bill Jones" --role=administrator` - And I run `wp user add-role billjones author` - Then STDOUT should not be empty - - When I run `wp user list --field=user_login | wc -l` - Then STDOUT should be: - """ - 2 - """ - - When I run `wp user list --format=csv > users.csv` - Then the users.csv file should exist - - When I run `wp user delete $(wp user list --format=ids) --yes` - Then STDOUT should not be empty - - When I run `wp user list --field=user_login | wc -l` - Then STDOUT should be: - """ - 0 - """ - - When I run `wp user import-csv users.csv` - Then STDOUT should not be empty - - When I run `wp user list --fields=display_name,roles` - Then STDOUT should be a table containing rows: - | display_name | roles | - | Bob Jones | contributor | - | Bill Jones | administrator,author | - Scenario: Managing user roles Given a WP install From ae443b9a31123ddae1c5b6e5d724209447ee8ee3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 16:59:11 -0800 Subject: [PATCH 3962/4858] Introduce `WP_CLI\Utils\get_temp_dir()` for safer temp directories Also warns end user when the temp directory isn't writable. --- php/WP_CLI/CoreUpgrader.php | 2 +- php/WP_CLI/REPL.php | 2 +- php/commands/cli.php | 2 +- php/commands/core.php | 2 +- php/utils.php | 32 +++++++++++++++++++++++++++++++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index 25dc2335a6..1b9bf62933 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -35,7 +35,7 @@ function download_package( $package ) { $filename = pathinfo( $package, PATHINFO_FILENAME ); $ext = pathinfo( $package, PATHINFO_EXTENSION ); - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.' . $ext; + $temp = \WP_CLI\Utils\get_temp_dir() . uniqid('wp_') . '.' . $ext; $cache = WP_CLI::get_cache(); $update = $GLOBALS['wp_cli_update_obj']; diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index b3f902316a..576359ecc0 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -99,7 +99,7 @@ private static function create_prompt_cmd( $prompt, $history_path ) { private function set_history_file() { $data = getcwd() . get_current_user(); - $this->history_file = sys_get_temp_dir() . '/wp-cli-history-' . md5( $data ); + $this->history_file = \WP_CLI\Utils\get_temp_dir() . 'wp-cli-history-' . md5( $data ); } private static function starts_with( $tokens, $line ) { diff --git a/php/commands/cli.php b/php/commands/cli.php index 30baa3237e..a021f6acdc 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -169,7 +169,7 @@ public function update( $_, $assoc_args ) { WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.phar'; + $temp = \WP_CLI\Utils\get_temp_dir() . uniqid('wp_') . '.phar'; $headers = array(); $options = array( diff --git a/php/commands/core.php b/php/commands/core.php index 4e901c0d91..55055b7b7a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -119,7 +119,7 @@ public function download( $args, $assoc_args ) { if ( ! $cache_file || $bad_cache ) { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). - $temp = sys_get_temp_dir() . '/' . uniqid('wp_') . '.tar.gz'; + $temp = \WP_CLI\Utils\get_temp_dir() . uniqid('wp_') . '.tar.gz'; $headers = array('Accept' => 'application/json'); $options = array( diff --git a/php/utils.php b/php/utils.php index 69ad1c355e..8cdc5dbe92 100644 --- a/php/utils.php +++ b/php/utils.php @@ -21,7 +21,7 @@ function extract_from_phar( $path ) { $fname = basename( $path ); - $tmp_path = sys_get_temp_dir() . "/wp-cli-$fname"; + $tmp_path = get_temp_dir() . "wp-cli-$fname"; copy( $path, $tmp_path ); @@ -577,3 +577,33 @@ function get_named_sem_ver( $new_version, $original_version ) { function get_flag_value( $args, $flag, $default = null ) { return isset( $args[ $flag ] ) ? $args[ $flag ] : $default; } + +/** + * Get the temp directory, and let the user know if it isn't writable. + * + * @return string + */ +function get_temp_dir() { + static $temp = ''; + + $trailingslashit = function( $path ) { + return rtrim( $path ) . '/'; + }; + + if ( $temp ) + return $trailingslashit( $temp ); + + if ( function_exists( 'sys_get_temp_dir' ) ) { + $temp = sys_get_temp_dir(); + } else if ( ini_get( 'upload_tmp_dir' ) ) { + $temp = ini_get( 'upload_tmp_dir' ); + } else { + $temp = '/tmp/'; + } + + if ( ! @is_writable( $temp ) ) { + WP_CLI::warning( "Temp directory isn't writable: {$temp}" ); + } + + return $trailingslashit( $temp ); +} From cc1a58b78eeb68ca435dc0c8906156d2d37ae700 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Dec 2015 17:02:33 -0800 Subject: [PATCH 3963/4858] php-cli-tools: a more impossible placeholder pattern See https://github.com/wp-cli/php-cli-tools/pull/93 --- composer.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.lock b/composer.lock index d568185770..c54b3c3f52 100644 --- a/composer.lock +++ b/composer.lock @@ -696,12 +696,12 @@ "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "c6f72ea088518ffda711634e46589c2dbc0036cb" + "reference": "d0564da283585c7289e18877ed2f9c35c1b67013" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/c6f72ea088518ffda711634e46589c2dbc0036cb", - "reference": "c6f72ea088518ffda711634e46589c2dbc0036cb", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/d0564da283585c7289e18877ed2f9c35c1b67013", + "reference": "d0564da283585c7289e18877ed2f9c35c1b67013", "shasum": "" }, "require": { From 816564344eea06e8c9156b61424241665d59bc6d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Jan 2016 20:10:26 -0800 Subject: [PATCH 3964/4858] Update WordPress versions for 4.4.1 and brethren, attempt two --- features/core-check-update.feature | 8 ++++---- features/core-update.feature | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index f35d28a1ad..7d9a3d2d5b 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -10,8 +10,8 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | - | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | + | 4.4.1 | major | https://wordpress.org/wordpress-4.4.1.zip | + | 3.8.12 | minor | https://wordpress.org/wordpress-3.8.12.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -22,7 +22,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.4 | major | https://wordpress.org/wordpress-4.4.zip | + | 4.4.1 | major | https://wordpress.org/wordpress-4.4.1.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -33,7 +33,7 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.11 | minor | https://wordpress.org/wordpress-3.8.11.zip | + | 3.8.12 | minor | https://wordpress.org/wordpress-3.8.12.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: diff --git a/features/core-update.feature b/features/core-update.feature index 058e880d06..7a4c45e270 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -38,7 +38,7 @@ Feature: Update WordPress core When I run `wp core update --minor` Then STDOUT should contain: """ - Updating to version 3.7.11 + Updating to version 3.7.12 """ When I run `wp core update --minor` @@ -50,7 +50,7 @@ Feature: Update WordPress core When I run `wp core version` Then STDOUT should be: """ - 3.7.11 + 3.7.12 """ @less-than-php-7 From 7a4908a0090693c6ca7d6aba52b18182955256d9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jan 2016 07:17:48 -0800 Subject: [PATCH 3965/4858] Lock `php-cli-tools` to 0.11.0 --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d8d6c5246d..cfa9066eac 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "0.11.0", "mustache/mustache": "~2.4", "mustangostang/spyc": "0.5.1", "composer/semver": "1.0.0", diff --git a/composer.lock b/composer.lock index c24b9ebcda..3968ddb0c7 100644 --- a/composer.lock +++ b/composer.lock @@ -739,7 +739,7 @@ }, { "name": "wp-cli/php-cli-tools", - "version": "dev-master", + "version": "0.11.0", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", From 19641b8a5a64769824b1e457500f07cdbf6c4a69 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jan 2016 08:03:03 -0800 Subject: [PATCH 3966/4858] Update `.mailmap` for v0.22.0 --- .mailmap | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.mailmap b/.mailmap index 080fcc238f..9f24a1a943 100644 --- a/.mailmap +++ b/.mailmap @@ -20,6 +20,7 @@ c10b10 <alex.ciobica@gmail.com> Chris Montgomery <chris@montchr.io> clemens-tolboom <clemens@build2be.com> conatus <alex@recordsonribs.com> +Corey Worrell <proskater55@gmail.com> ctayloroomphinc <ctaylor@thinkoomph.com> cyberhobo <dylan.k.kuhn@gmail.com> dangardner <dan@web.nearest.to> @@ -27,21 +28,27 @@ Daniel Bachhuber <daniel.bachhuber@fusion.net> danielbachhuber <d@danielbachhuber.com> danielbachhuber <daniel@handbuilt.co> danielbachhuber <danielbachhuber@gmail.com> +Dave Leach <dave@dmleach.com> dd32 <contact-atlassian@dd32.id.au> dlh01 <david@alleyinteractive.com> drrobotnik <B@Brandons-Mac-Pro-4.local> +Duncan Brown <duncanjbrown@gmail.com> dwightjack <marco.solazzi@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> eugeneware <eugene@noblesamurai.com> Evan Mattson <me@aaemnnost.tv> francescolaffi <francesco.laffi@gmail.com> +Frankie Jarrett <fjarrett@godaddy.com> future500 <ramon@future500.nl> getsource <mike.schroder@dreamhost.com> +Gilbert Pellegrom <gilbert@pellegrom.me> glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> Grant McInnes <grant.mcinnes@eyesopen.ca> +Greg Anderson <greg.1.anderson@greenknowe.org> Hiroshi Urabe <mail@torounit.com> +Ian Dunn <ian@iandunn.name> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> Jan Voráček <jan@voracek.net> @@ -56,6 +63,7 @@ johnbillion <johnbillion@gmail.com> johnpbloch <jbloch@John-Blochs-iMac.local> johnpbloch <johnpbloch@gmail.com> jonathanbardo <jonathanbardo@users.noreply.github.com> +Josh Eaton <josh@josheaton.org> joshbetz <j@joshbetz.com> joshlevinson <joshalevinson@gmail.com> JQ <JeyKeu@users.noreply.github.com> @@ -75,6 +83,7 @@ mattheu <matthew@matth.eu> mboynes <mboynes@alleyinteractive.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> +Mihail Minkov <Mihail.Minkov.BG@gmail.com> mikey dubs <mike@herebox.org> milesj <mileswjohnson@gmail.com> MiteshShah <Mitesh.Shah@rtCamp.com> @@ -89,6 +98,7 @@ nb <nb@nikolay.bg> nickdaugherty <ndaugherty987@gmail.com> nikolay <nikolay@users.noreply.github.com> nikolay <nikolaynkolev@gmail.com> +Nilambar Sharma <ernilambar@users.noreply.github.com> nschoenholtz <noah@alleyinteractive.com> nullvariable <nullvariable@gmail.com> nyordanov <me@nyordanov.com> @@ -107,7 +117,9 @@ rodrigoprimo <rodrigo@hacklab.com.br> rodrigoprimo <rodrigosprimo@gmail.com> roelven <roel@soundcloud.com> Ross Hattori <rhattori@saymedia.com> +Ryan Hoover <ryanshoover@gmail.com> Ryan McCue <me@ryanmccue.info> +Ryan Williams <ryrowi@gmail.com> ryanduff <ryan@fusionized.com> santagada <santagada@gmail.com> sboisvert <stephane.boisvert@automattic.com> @@ -124,6 +136,7 @@ Stephen Edgar <stephen@netweb.com.au> Steve Grunwell <steve.grunwell@10up.com> Steve Grunwell <steve@stevegrunwell.com> Steve Grunwell <stevegrunwell@gmail.com> +Steve Persch <steve.persch@pantheon.io> stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> Svetoslav Marinov (Slavi) <slavi@orbisius.com> @@ -137,6 +150,7 @@ tollmanz <zack@zackdev.com> toszcze <toszcze@gmail.com> tott <tott@automattic.com> trepmal <trepmal@gmail.com> +Tristan Penman <tristan@tristanpenman.com> twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> voldemortensen <voldemortensen@users.noreply.github.com> From e52a853016ef34e3b36e5862e373f77289218e5a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jan 2016 08:10:01 -0800 Subject: [PATCH 3967/4858] Cut Travis' workload down on PRs --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5fb2dfcfd9..aa03bd705f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,6 +53,10 @@ cache: directories: - vendor +branches: + only: + - master + notifications: email: on_success: never From 45460a55328db9952e0c93023c8b79a2432332d9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jan 2016 08:36:32 -0800 Subject: [PATCH 3968/4858] Version bump --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3941605750..2157409059 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22.0-alpha +0.22.0 From 25e773a860a12debd7be3530e1d87793ba7e2211 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jan 2016 10:01:55 -0800 Subject: [PATCH 3969/4858] Bump version to 0.23.0-alpha --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 2157409059..c648a65ef2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22.0 +0.23.0-alpha From a63a08af529e80aefdf0edc3fa7dcba5315d8bb5 Mon Sep 17 00:00:00 2001 From: Anant Shrivastava <anant@anantshri.info> Date: Sat, 9 Jan 2016 12:16:00 +0530 Subject: [PATCH 3970/4858] Switched response to auto lower case Switching response to auto lower case allows us to use Y or y as yes --- php/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 74839ceefb..299622f65d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -289,7 +289,7 @@ public static function confirm( $question, $assoc_args = array() ) { if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'yes' ) ) { fwrite( STDOUT, $question . " [y/n] " ); - $answer = trim( fgets( STDIN ) ); + $answer = strtolower( trim( fgets( STDIN ) ) ); if ( 'y' != $answer ) exit; From 73393ee80f3762d6dab7e4b482bc7997d0e99658 Mon Sep 17 00:00:00 2001 From: hina <hina@hinaloe.net> Date: Mon, 11 Jan 2016 11:06:57 +0900 Subject: [PATCH 3971/4858] Check update file response status --- php/WP_CLI/CoreUpgrader.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CoreUpgrader.php b/php/WP_CLI/CoreUpgrader.php index 1b9bf62933..9e18c1f64f 100644 --- a/php/WP_CLI/CoreUpgrader.php +++ b/php/WP_CLI/CoreUpgrader.php @@ -59,7 +59,11 @@ function download_package( $package ) { $this->skin->feedback( 'downloading_package', $package ); - Utils\http_request( 'GET', $package, null, $headers, $options ); + /** @var \Requests_Response|null $req */ + $req = Utils\http_request( 'GET', $package, null, $headers, $options ); + if ( ! is_null( $req ) && $req->status_code !== 200 ) { + return new \WP_Error( 'download_failed', $this->strings['download_failed'] ); + } $cache->import( $cache_key, $temp ); return $temp; } @@ -67,4 +71,3 @@ function download_package( $package ) { } } - From bb8c85e984ea5bffafebde03dc9469ab6ef4de40 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 11 Jan 2016 04:45:19 -0800 Subject: [PATCH 3972/4858] Improve performance of `wp user list --format=count` * Only fetch user IDs, to avoid join with user meta table. * Skip unnecessary `SQL_CALC_FOUND_ROWS` --- php/commands/user.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 130a4ff348..a65b986ba3 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -96,16 +96,19 @@ public function list_( $args, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); - if ( 'ids' == $formatter->format ) { + if ( in_array( $formatter->format, array( 'ids', 'count' ) ) ) { $assoc_args['fields'] = 'ids'; } else { $assoc_args['fields'] = 'all_with_meta'; } + $assoc_args['count_total'] = false; $users = get_users( $assoc_args ); if ( 'ids' == $formatter->format ) { echo implode( ' ', $users ); + } else if ( 'count' === $formatter->format ) { + $formatter->display_items( $users ); } else { $it = WP_CLI\Utils\iterator_map( $users, function ( $user ) { if ( !is_object( $user ) ) From 7466d6b80f4703dc4e0701b26de18daf699bff5c Mon Sep 17 00:00:00 2001 From: Marco <mcastelluccio@mozilla.com> Date: Tue, 12 Jan 2016 16:03:32 +0100 Subject: [PATCH 3973/4858] Don't cd in WP_TESTS_DIR before dowloading and setting up wp-tests-config.php The paths in the remaining of the function are relative to the main directory, so the script shouldn't cd in WP_TESTS_DIR. --- templates/install-wp-tests.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 5baa6cb56c..4f5335586f 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -81,8 +81,6 @@ install_test_suite() { svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes fi - cd $WP_TESTS_DIR - if [ ! -f wp-tests-config.php ]; then download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php From 290edcb252a8134322bbdcff2a038fd97317a16d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Jan 2016 06:55:33 -0800 Subject: [PATCH 3974/4858] Register an arbitrary function, closure, or method as a command --- features/command.feature | 162 ++++++++++++++++++++++- php/WP_CLI/Dispatcher/CommandFactory.php | 54 +++++--- php/class-wp-cli.php | 25 +++- 3 files changed, 216 insertions(+), 25 deletions(-) diff --git a/features/command.feature b/features/command.feature index 2039cc1232..525eded94a 100644 --- a/features/command.feature +++ b/features/command.feature @@ -13,7 +13,7 @@ Feature: WP-CLI Commands Then the return code should be 1 And STDERR should contain: """ - Class 'Non_Existent_Class' does not exist. + Callable "Non_Existent_Class" does not exist, and cannot be registered as `wp command example`. """ Scenario: Invalid subcommand of valid command @@ -39,3 +39,163 @@ Feature: WP-CLI Commands """ Error: 'invalid' is not a registered subcommand of 'command'. See 'wp help command'. """ + + Scenario: Use a closure as a command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + /** + * My awesome closure command + * + * <message> + * : An awesome message to display + * + * @when before_wp_load + */ + $foo = function( $args ) { + WP_CLI::success( $args[0] ); + }; + WP_CLI::add_command( 'foo', $foo ); + """ + + When I run `wp --require=custom-cmd.php help` + Then STDOUT should contain: + """ + foo + """ + + When I run `wp --require=custom-cmd.php help foo` + Then STDOUT should contain: + """ + My awesome closure command + """ + + When I try `wp --require=custom-cmd.php foo bar --burrito` + Then STDERR should contain: + """ + unknown --burrito parameter + """ + + When I run `wp --require=custom-cmd.php foo bar` + Then STDOUT should contain: + """ + Success: bar + """ + + Scenario: Use a function as a command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + /** + * My awesome function command + * + * <message> + * : An awesome message to display + * + * @when before_wp_load + */ + function foo( $args ) { + WP_CLI::success( $args[0] ); + } + WP_CLI::add_command( 'foo', 'foo' ); + """ + + When I run `wp --require=custom-cmd.php help` + Then STDOUT should contain: + """ + foo + """ + + When I run `wp --require=custom-cmd.php help foo` + Then STDOUT should contain: + """ + My awesome function command + """ + + When I try `wp --require=custom-cmd.php foo bar --burrito` + Then STDERR should contain: + """ + unknown --burrito parameter + """ + + When I run `wp --require=custom-cmd.php foo bar` + Then STDOUT should contain: + """ + Success: bar + """ + + Scenario: Use a class method as a command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + class Foo_Class extends WP_CLI_Command { + /** + * My awesome class method command + * + * <message> + * : An awesome message to display + * + * @when before_wp_load + */ + function foo( $args ) { + WP_CLI::success( $args[0] ); + } + } + $foo = new Foo_Class; + WP_CLI::add_command( 'foo', array( $foo, 'foo' ) ); + """ + + When I run `wp --require=custom-cmd.php help` + Then STDOUT should contain: + """ + foo + """ + + When I run `wp --require=custom-cmd.php help foo` + Then STDOUT should contain: + """ + My awesome class method command + """ + + When I try `wp --require=custom-cmd.php foo bar --burrito` + Then STDERR should contain: + """ + unknown --burrito parameter + """ + + When I run `wp --require=custom-cmd.php foo bar` + Then STDOUT should contain: + """ + Success: bar + """ + + Scenario: Use an invalid class method as a command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + class Foo_Class extends WP_CLI_Command { + /** + * My awesome class method command + * + * <message> + * : An awesome message to display + * + * @when before_wp_load + */ + function foo( $args ) { + WP_CLI::success( $args[0] ); + } + } + $foo = new Foo_Class; + WP_CLI::add_command( 'bar', array( $foo, 'bar' ) ); + """ + + When I try `wp --require=custom-cmd.php bar` + Then STDERR should contain: + """ + Error: Callable ["Foo_Class","bar"] does not exist, and cannot be registered as `wp bar`. + """ diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index b4f941dd03..274d53201c 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -13,17 +13,27 @@ class CommandFactory { * Create a new CompositeCommand (or Subcommand if class has __invoke()) * * @param string $name Represents how the command should be invoked - * @param string $class A subclass of WP_CLI_Command + * @param string $callable A subclass of WP_CLI_Command, a function, or a closure * @param mixed $parent The new command's parent Composite (or Root) command */ - public static function create( $name, $class, $parent ) { - $reflection = new \ReflectionClass( $class ); - - if ( $reflection->hasMethod( '__invoke' ) ) { - $command = self::create_subcommand( $parent, $name, $reflection->name, - $reflection->getMethod( '__invoke' ) ); + public static function create( $name, $callable, $parent ) { + + if ( ( is_object( $callable ) && ( $callable instanceof \Closure ) ) + || ( is_string( $callable ) && function_exists( $callable ) ) ) { + $reflection = new \ReflectionFunction( $callable ); + $command = self::create_subcommand( $parent, $name, $callable, $reflection ); + } else if ( is_array( $callable ) && is_callable( $callable ) ) { + $reflection = new \ReflectionClass( $callable[0] ); + $command = self::create_subcommand( $parent, $name, array( $reflection->name, $callable[1] ), + $reflection->getMethod( $callable[1] ) ); } else { - $command = self::create_composite_command( $parent, $name, $reflection ); + $reflection = new \ReflectionClass( $callable ); + if ( $reflection->hasMethod( '__invoke' ) ) { + $command = self::create_subcommand( $parent, $name, array( $reflection->name, '__invoke' ), + $reflection->getMethod( '__invoke' ) ); + } else { + $command = self::create_composite_command( $parent, $name, $reflection ); + } } return $command; @@ -34,22 +44,28 @@ public static function create( $name, $class, $parent ) { * * @param mixed $parent The new command's parent Composite command * @param string $name Represents how the command should be invoked + * @param mixed $callable A callable function or closure, or class name and method + * @param object $reflection Reflection instance, for doc parsing * @param string $class A subclass of WP_CLI_Command * @param string $method Class method to be called upon invocation. */ - private static function create_subcommand( $parent, $name, $class_name, $method ) { - $docparser = new \WP_CLI\DocParser( $method->getDocComment() ); - - if ( !$name ) - $name = $docparser->get_tag( 'subcommand' ); + private static function create_subcommand( $parent, $name, $callable, $reflection ) { + $docparser = new \WP_CLI\DocParser( $reflection->getDocComment() ); - if ( !$name ) - $name = $method->name; + if ( is_array( $callable ) ) { + if ( !$name ) + $name = $docparser->get_tag( 'subcommand' ); - $method_name = $method->name; + if ( !$name ) + $name = $reflection->name; + } - $when_invoked = function ( $args, $assoc_args ) use ( $class_name, $method_name ) { - call_user_func( array( new $class_name, $method_name ), $args, $assoc_args ); + $when_invoked = function ( $args, $assoc_args ) use ( $callable ) { + if ( is_array( $callable ) ) { + call_user_func( array( new $callable[0], $callable[1] ), $args, $assoc_args ); + } else { + call_user_func( $callable, $args, $assoc_args ); + } }; return new Subcommand( $parent, $name, $docparser, $when_invoked ); @@ -71,7 +87,7 @@ private static function create_composite_command( $parent, $name, $reflection ) if ( !self::is_good_method( $method ) ) continue; - $subcommand = self::create_subcommand( $container, false, $reflection->name, $method ); + $subcommand = self::create_subcommand( $container, false, array( $reflection->name, $method->name ), $method ); $subcommand_name = $subcommand->get_name(); diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 299622f65d..df0785e73c 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -166,13 +166,28 @@ public static function do_hook( $when ) { * Add a command to the wp-cli list of commands * * @param string $name The name of the command that will be used in the CLI - * @param string $class The command implementation + * @param string $callable The command implementation as a class, function or closure * @param array $args An associative array with additional parameters: * 'before_invoke' => callback to execute before invoking the command */ - public static function add_command( $name, $class, $args = array() ) { - if ( is_string( $class ) && ! class_exists( (string) $class ) ) { - WP_CLI::error( sprintf( "Class '%s' does not exist.", $class ) ); + public static function add_command( $name, $callable, $args = array() ) { + $valid = false; + if ( is_object( $callable ) && ( $callable instanceof \Closure ) ) { + $valid = true; + } else if ( is_string( $callable ) && function_exists( $callable ) ) { + $valid = true; + } else if ( is_string( $callable ) && class_exists( (string) $callable ) ) { + $valid = true; + } else if ( is_object( $callable ) ) { + $valid = true; + } else if ( is_array( $callable ) && is_callable( $callable ) ) { + $valid = true; + } + if ( ! $valid ) { + if ( is_array( $callable ) ) { + $callable = array( get_class( $callable[0] ), $callable[1] ); + } + WP_CLI::error( sprintf( "Callable %s does not exist, and cannot be registered as `wp %s`.", json_encode( $callable ), $name ) ); } if ( isset( $args['before_invoke'] ) ) { @@ -200,7 +215,7 @@ public static function add_command( $name, $class, $args = array() ) { $command = $subcommand; } - $leaf_command = Dispatcher\CommandFactory::create( $leaf_name, $class, $command ); + $leaf_command = Dispatcher\CommandFactory::create( $leaf_name, $callable, $command ); if ( ! $command->can_have_subcommands() ) { throw new Exception( sprintf( "'%s' can't have subcommands.", From 2c9a3dca58b86663769c39da8bff5437e8925ca4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Jan 2016 07:25:43 -0800 Subject: [PATCH 3975/4858] Add `(before|after)_wp(_config)_load` hooks in WP load process This enables code injected via `--require` to make modifications at runtime. --- php/WP_CLI/Runner.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index af6932e2d2..5c48e329ba 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -739,6 +739,7 @@ public function load_wordpress() { $wp_cli_is_loaded = true; WP_CLI::debug( 'Begin WordPress load' ); + WP_CLI::do_hook( 'before_wp_load' ); $this->check_wp_version(); @@ -750,6 +751,7 @@ public function load_wordpress() { } WP_CLI::debug( 'wp-config.php path: ' . $wp_config_path ); + WP_CLI::do_hook( 'before_wp_config_load' ); // Load wp-config.php code, in the global scope $wp_cli_original_defined_vars = get_defined_vars(); @@ -762,6 +764,7 @@ public function load_wordpress() { } $this->maybe_update_url_from_domain_constant(); + WP_CLI::do_hook( 'after_wp_config_load' ); // Load WP-CLI utilities require WP_CLI_ROOT . '/php/utils-wp.php'; @@ -783,6 +786,7 @@ public function load_wordpress() { } WP_CLI::debug( 'Loaded WordPress' ); + WP_CLI::do_hook( 'after_wp_load' ); } From 2190333ed9eaff4777b9f6e2adeae080d36714e1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 14 Jan 2016 06:26:33 -0800 Subject: [PATCH 3976/4858] Prevent dupe builds with Travis defaults in `scaffold plugin-tests` --- templates/.travis.mustache | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/.travis.mustache b/templates/.travis.mustache index 5a77b81b65..38a8ae25a6 100644 --- a/templates/.travis.mustache +++ b/templates/.travis.mustache @@ -5,6 +5,10 @@ notifications: on_success: never on_failure: change +branches: + only: + - master + php: - 5.3 - 5.6 From 4bebf622b455c14d327ce57af81149250c37bac6 Mon Sep 17 00:00:00 2001 From: Eduardo Alencar <ealencar10@gmail.com> Date: Thu, 14 Jan 2016 14:11:07 -0200 Subject: [PATCH 3977/4858] Remove whitespace on rewrite command --- php/commands/rewrite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 3f33c1c92b..dc3bb68b67 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -218,5 +218,5 @@ function apache_get_modules() { } } -WP_CLI:: add_command( 'rewrite', 'Rewrite_Command' ); +WP_CLI::add_command( 'rewrite', 'Rewrite_Command' ); From 04b82e1bd1719a6a2a9d42f5101ad39c3f41114d Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 12:03:24 +0000 Subject: [PATCH 3978/4858] Make `wp core download --force` and `wp core update --force` clean up files when downgrading from 4.4 --- php/commands/core.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index fdaadb1862..40c7d03e42 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -99,6 +99,14 @@ public function download( $args, $assoc_args ) { $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); } + $from_version = ''; + $includes_folder = defined( 'WPINC' ) ? WPINC : '/wp-includes'; + if ( file_exists( $download_dir . $includes_folder . '/version.php' ) ) { + global $wp_version; + require_once( $download_dir . $includes_folder . '/version.php' ); + $from_version = $wp_version; + } + WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $version, $locale ) ); $cache = WP_CLI::get_cache(); @@ -143,6 +151,8 @@ public function download( $args, $assoc_args ) { unlink($temp); } + $this->_maybe_remove_unused_files( $from_version, $assoc_args['version'] ); + WP_CLI::success( 'WordPress downloaded.' ); } @@ -964,10 +974,14 @@ function update( $args, $assoc_args ) { WP_CLI::log( "Starting update..." ); } + $from_version = $wp_version; + $GLOBALS['wp_cli_update_obj'] = $update; $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); unset( $GLOBALS['wp_cli_update_obj'] ); + $this->_maybe_remove_unused_files( $from_version, $update->version ); + if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); if ( 'up_to_date' != $result->get_error_code() ) { @@ -1150,6 +1164,29 @@ private function get_updates( $assoc_args ) { return array_values( $updates ); } + private function _maybe_remove_unused_files( $version_from, $version_to) { + if ( ! $version_from || ! $version_to ) { + return; + } + + $files_to_remove = array(); + $includes_folder = defined( 'WPINC' ) ? WPINC : '/wp-includes'; + + if ( version_compare( $version_from, '4.4', '>=' ) && version_compare( $version_to, '4.4', '<' ) ) { + $files_to_remove[] = ABSPATH . $includes_folder . '/embed-functions.php'; + $files_to_remove[] = ABSPATH . $includes_folder . '/class-wp-oembed-controller.php'; + $files_to_remove[] = ABSPATH . $includes_folder . '/rest-api.php'; + } + + if ( ! empty( $files_to_remove ) ) { + foreach ( $files_to_remove as $file ) { + if ( file_exists( $file ) ) { + unlink( $file ); + } + } + } + } + } WP_CLI::add_command( 'core', 'Core_Command' ); From 5c605c0d6c6e622884443727c4297518af98db47 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 12:28:28 +0000 Subject: [PATCH 3979/4858] Add functional tests --- features/core-download.feature | 8 ++++++++ features/core-update.feature | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/features/core-download.feature b/features/core-download.feature index c36801b825..ec2a496953 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -67,3 +67,11 @@ Feature: Download WordPress """ Error: WordPress files seem to already be present here. """ + + Scenario: Downgrade from 4.4 to 4.3.2 cleans up files + Given an empty directory + When I run `wp core download --version=4.4` + Then the wp-includes/rest-api.php file should exist + + When I run `wp core download --version=4.3.2 --force` + Then the wp-includes/rest-api.php file should not exist diff --git a/features/core-update.feature b/features/core-update.feature index 7a4c45e270..72992fcd58 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -158,3 +158,11 @@ Feature: Update WordPress core wordpress-4.2.4-no-content-en_US.zip wordpress-4.2.4-partial-1-en_US.zip """ + + Scenario: Downgrade from 4.4 to 4.3.2 cleans up files + Given a WP install + When I run `wp core update --version=4.4 --force` + Then the wp-includes/rest-api.php file should exist + + When I run `wp core update --version=4.3.2 --force` + Then the wp-includes/rest-api.php file should not exist From f0471d8738adea63d165a62f5ebfdcb83a0b2480 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 14:58:50 +0000 Subject: [PATCH 3980/4858] Remove underscore --- php/commands/core.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 40c7d03e42..aa32f7e936 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -151,7 +151,7 @@ public function download( $args, $assoc_args ) { unlink($temp); } - $this->_maybe_remove_unused_files( $from_version, $assoc_args['version'] ); + $this->maybe_remove_unused_files( $from_version, $assoc_args['version'] ); WP_CLI::success( 'WordPress downloaded.' ); } @@ -980,7 +980,7 @@ function update( $args, $assoc_args ) { $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); unset( $GLOBALS['wp_cli_update_obj'] ); - $this->_maybe_remove_unused_files( $from_version, $update->version ); + $this->maybe_remove_unused_files( $from_version, $update->version ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); @@ -1164,7 +1164,7 @@ private function get_updates( $assoc_args ) { return array_values( $updates ); } - private function _maybe_remove_unused_files( $version_from, $version_to) { + private function maybe_remove_unused_files( $version_from, $version_to) { if ( ! $version_from || ! $version_to ) { return; } From 4a11410d6f7f0026548ffc5e02730ad66f6f1ed9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 15 Jan 2016 07:27:52 -0800 Subject: [PATCH 3981/4858] Improve .travis.yml for package tests * Disable noisy email notifications by default. * Prevent duplicate builds on pull requests. * Use two space indentation instead of four. --- templates/.travis.package.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/templates/.travis.package.yml b/templates/.travis.package.yml index 737aea1227..bb11edec43 100644 --- a/templates/.travis.package.yml +++ b/templates/.travis.package.yml @@ -1,15 +1,24 @@ language: php +notifications: + email: + on_success: never + on_failure: change + +branches: + only: + - master + php: - - 5.3 - - 5.5 + - 5.3 + - 5.6 env: - global: - - WP_CLI_BIN_DIR=/tmp/wp-cli-phar - - WP_CLI_CONFIG_PATH=/tmp/wp-cli-phar/config.yml + global: + - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + - WP_CLI_CONFIG_PATH=/tmp/wp-cli-phar/config.yml before_script: - - bash bin/install-package-tests.sh + - bash bin/install-package-tests.sh script: ./vendor/bin/behat From cad1153b735aeb665c2ca5920174c3b30ae9bf73 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 15:42:10 +0000 Subject: [PATCH 3982/4858] Fix includes folder path --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index aa32f7e936..dd221d8b6c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -100,7 +100,7 @@ public function download( $args, $assoc_args ) { } $from_version = ''; - $includes_folder = defined( 'WPINC' ) ? WPINC : '/wp-includes'; + $includes_folder = defined( 'WPINC' ) ? WPINC : 'wp-includes'; if ( file_exists( $download_dir . $includes_folder . '/version.php' ) ) { global $wp_version; require_once( $download_dir . $includes_folder . '/version.php' ); From 342a07b080a6992e0072fb5ba4f703376b35d4fa Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 15:43:35 +0000 Subject: [PATCH 3983/4858] Move version comparison outside the method and pass locale --- php/commands/core.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index dd221d8b6c..3bc0a42266 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -151,7 +151,9 @@ public function download( $args, $assoc_args ) { unlink($temp); } - $this->maybe_remove_unused_files( $from_version, $assoc_args['version'] ); + if ( version_compare( $from_version, '4.4', '>=' ) && version_compare( $assoc_args['version'], '4.4', '<' ) ) { + $this->remove_unused_files( $from_version, $assoc_args['version'], $locale ); + } WP_CLI::success( 'WordPress downloaded.' ); } @@ -980,7 +982,10 @@ function update( $args, $assoc_args ) { $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); unset( $GLOBALS['wp_cli_update_obj'] ); - $this->maybe_remove_unused_files( $from_version, $update->version ); + if ( version_compare( $from_version, '4.4', '>=' ) && version_compare( $update->version, '4.4', '<' ) ) { + $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); + $this->remove_unused_files( $from_version, $update->version, $locale ); + } if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); @@ -1164,7 +1169,7 @@ private function get_updates( $assoc_args ) { return array_values( $updates ); } - private function maybe_remove_unused_files( $version_from, $version_to) { + private function remove_unused_files( $version_from, $version_to, $locale ) { if ( ! $version_from || ! $version_to ) { return; } From a41899790a5be8b256383e2eee8dec530e4d7d8c Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 15:44:06 +0000 Subject: [PATCH 3984/4858] Use get_core_checksums to calculate files to remove --- php/commands/core.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 3bc0a42266..0957a7f445 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1174,19 +1174,19 @@ private function remove_unused_files( $version_from, $version_to, $locale ) { return; } - $files_to_remove = array(); - $includes_folder = defined( 'WPINC' ) ? WPINC : '/wp-includes'; + $old_checksums = self::get_core_checksums( $version_from, $locale ? $locale : 'en_US' ); + $new_checksums = self::get_core_checksums( $version_to, $locale ? $locale : 'en_US' ); - if ( version_compare( $version_from, '4.4', '>=' ) && version_compare( $version_to, '4.4', '<' ) ) { - $files_to_remove[] = ABSPATH . $includes_folder . '/embed-functions.php'; - $files_to_remove[] = ABSPATH . $includes_folder . '/class-wp-oembed-controller.php'; - $files_to_remove[] = ABSPATH . $includes_folder . '/rest-api.php'; + if ( empty( $old_checksums ) || empty( $new_checksums ) ) { + return; } + $files_to_remove = array_diff( array_keys( $old_checksums ), array_keys( $new_checksums ) ); + if ( ! empty( $files_to_remove ) ) { foreach ( $files_to_remove as $file ) { - if ( file_exists( $file ) ) { - unlink( $file ); + if ( file_exists( ABSPATH . $file ) ) { + unlink( ABSPATH . $file ); } } } From a23fbf25e52a73200fd87d9a057c47c96edacf52 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 15:44:22 +0000 Subject: [PATCH 3985/4858] Output count of files deleted --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index 0957a7f445..db02aa8a28 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1189,6 +1189,7 @@ private function remove_unused_files( $version_from, $version_to, $locale ) { unlink( ABSPATH . $file ); } } + WP_CLI::log( count($files_to_remove) . ' files cleaned up' ); } } From 05db2eb716491923dd4666ac62f0c345f97b7575 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 16:06:35 +0000 Subject: [PATCH 3986/4858] Remove version comparison checks --- php/commands/core.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index db02aa8a28..d95bedf546 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -151,9 +151,7 @@ public function download( $args, $assoc_args ) { unlink($temp); } - if ( version_compare( $from_version, '4.4', '>=' ) && version_compare( $assoc_args['version'], '4.4', '<' ) ) { - $this->remove_unused_files( $from_version, $assoc_args['version'], $locale ); - } + $this->remove_unused_files( $from_version, $assoc_args['version'], $locale ); WP_CLI::success( 'WordPress downloaded.' ); } @@ -982,10 +980,8 @@ function update( $args, $assoc_args ) { $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); unset( $GLOBALS['wp_cli_update_obj'] ); - if ( version_compare( $from_version, '4.4', '>=' ) && version_compare( $update->version, '4.4', '<' ) ) { - $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); - $this->remove_unused_files( $from_version, $update->version, $locale ); - } + $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); + $this->remove_unused_files( $from_version, $update->version, $locale ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); From 1a4714548196cc33b3af87a0afd3a543c8f24701 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 16:06:48 +0000 Subject: [PATCH 3987/4858] Better logging --- php/commands/core.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d95bedf546..10ad848381 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1167,6 +1167,7 @@ private function get_updates( $assoc_args ) { private function remove_unused_files( $version_from, $version_to, $locale ) { if ( ! $version_from || ! $version_to ) { + WP_CLI::warning( 'Failed to find WordPress version. Please cleanup unused files manually.' ); return; } @@ -1174,18 +1175,23 @@ private function remove_unused_files( $version_from, $version_to, $locale ) { $new_checksums = self::get_core_checksums( $version_to, $locale ? $locale : 'en_US' ); if ( empty( $old_checksums ) || empty( $new_checksums ) ) { + WP_CLI::warning( 'Failed to fetch checksums. Please cleanup unused files manually.' ); return; } $files_to_remove = array_diff( array_keys( $old_checksums ), array_keys( $new_checksums ) ); if ( ! empty( $files_to_remove ) ) { + WP_CLI::log( 'Cleaning up unused files...' ); + foreach ( $files_to_remove as $file ) { if ( file_exists( ABSPATH . $file ) ) { unlink( ABSPATH . $file ); + WP_CLI::log( 'File removed: ' . $file ); } } - WP_CLI::log( count($files_to_remove) . ' files cleaned up' ); + + WP_CLI::success( count( $files_to_remove ) . ' unused files cleaned up' ); } } From 958f98ed4c4fcf0731489108bd4ee89937515d86 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 16:11:43 +0000 Subject: [PATCH 3988/4858] Count actual files deleted --- php/commands/core.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 10ad848381..87bc9904db 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1184,14 +1184,18 @@ private function remove_unused_files( $version_from, $version_to, $locale ) { if ( ! empty( $files_to_remove ) ) { WP_CLI::log( 'Cleaning up unused files...' ); + $count = 0; foreach ( $files_to_remove as $file ) { if ( file_exists( ABSPATH . $file ) ) { unlink( ABSPATH . $file ); WP_CLI::log( 'File removed: ' . $file ); + $count++; } } - WP_CLI::success( count( $files_to_remove ) . ' unused files cleaned up' ); + if ( $count ) { + WP_CLI::success( number_format( $count ) . ' unused files cleaned up' ); + } } } From 4ca2925c8938771e2c8bf2499e9503c5df4ecd47 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 15 Jan 2016 16:18:34 +0000 Subject: [PATCH 3989/4858] Update tests --- features/core-download.feature | 2 +- features/core-update.feature | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/features/core-download.feature b/features/core-download.feature index ec2a496953..429125f58a 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -68,7 +68,7 @@ Feature: Download WordPress Error: WordPress files seem to already be present here. """ - Scenario: Downgrade from 4.4 to 4.3.2 cleans up files + Scenario: Make sure unused files are cleaned up Given an empty directory When I run `wp core download --version=4.4` Then the wp-includes/rest-api.php file should exist diff --git a/features/core-update.feature b/features/core-update.feature index 72992fcd58..0c13e5c2fd 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -159,10 +159,15 @@ Feature: Update WordPress core wordpress-4.2.4-partial-1-en_US.zip """ - Scenario: Downgrade from 4.4 to 4.3.2 cleans up files + Scenario: Make sure unused files are cleaned up Given a WP install When I run `wp core update --version=4.4 --force` Then the wp-includes/rest-api.php file should exist When I run `wp core update --version=4.3.2 --force` Then the wp-includes/rest-api.php file should not exist + + When I run `wp option add str_opt 'bar'` + Then STDOUT should not be empty + When I run `wp post create --post_title='Test post' --porcelain` + Then STDOUT should be a number From c01e19c997d4e8aadd0d1e70e6b128caec7889b8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 18 Jan 2016 05:31:41 -0800 Subject: [PATCH 3990/4858] Faster performance for `wp post list --format=count` When we only want the sum total, we don't need to fetch all data for each post. --- php/commands/post.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/post.php b/php/commands/post.php index b0e9fadf8c..1fdafec57a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -312,6 +312,10 @@ public function list_( $_, $assoc_args ) { $query_args['fields'] = 'ids'; $query = new WP_Query( $query_args ); echo implode( ' ', $query->posts ); + } else if ( 'count' === $formatter->format ) { + $query_args['fields'] = 'ids'; + $query = new WP_Query( $query_args ); + $formatter->display_items( $query->posts ); } else { $query = new WP_Query( $query_args ); $posts = array_map( function( $post ) { From e02f7cd76baa135beb5e9c2bd0bc9ff9d0102c2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 18 Jan 2016 07:43:14 -0800 Subject: [PATCH 3991/4858] Generate comments for a specific post with `--post_id=<post-id>` --- features/comment-generate.feature | 16 ++++++++++++++++ php/commands/comment.php | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/features/comment-generate.feature b/features/comment-generate.feature index 609fc257d2..e3742ee9a2 100644 --- a/features/comment-generate.feature +++ b/features/comment-generate.feature @@ -9,3 +9,19 @@ Feature: Generate comments """ 21 """ + + Scenario: Generate comments assigned to a specific post + Given a WP install + + When I run `wp comment generate --count=4 --post_id=2` + And I run `wp comment list --post_id=2 --format=count` + Then STDOUT should be: + """ + 4 + """ + + When I run `wp comment list --post_id=1 --format=count` + Then STDOUT should be: + """ + 1 + """ diff --git a/php/commands/comment.php b/php/commands/comment.php index 372a5e4287..9524d92526 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -96,11 +96,15 @@ public function update( $args, $assoc_args ) { * * [--count=<number>] * : How many comments to generate. Default: 100 + * + * [--post_id=<post-id>] + * : Assign comments to a specific post. */ public function generate( $args, $assoc_args ) { $defaults = array( - 'count' => 100, + 'count' => 100, + 'post_id' => null, ); $assoc_args = array_merge( $defaults, $assoc_args ); @@ -112,6 +116,7 @@ public function generate( $args, $assoc_args ) { for ( $i = $total; $i < $limit; $i++ ) { wp_insert_comment( array( 'comment_content' => "Comment {$i}", + 'comment_post_ID' => $assoc_args['post_id'], ) ); $notify->tick(); } From 937c4a623d2a0ffec07b6b5fc054467f5cc7e64f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 18 Jan 2016 09:55:02 -0800 Subject: [PATCH 3992/4858] Use `shortdesc`, `synopsis`, and `when` with `::add_subcommand()` Permits registration of these command attributes through variable, instead of PHPDoc --- features/command.feature | 53 ++++++++++++++++++++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 9 ++++ php/WP_CLI/Dispatcher/Subcommand.php | 9 ++++ php/WP_CLI/SynopsisParser.php | 41 +++++++++++++++++ php/class-wp-cli.php | 21 ++++++++- 5 files changed, 132 insertions(+), 1 deletion(-) diff --git a/features/command.feature b/features/command.feature index 525eded94a..503fc14070 100644 --- a/features/command.feature +++ b/features/command.feature @@ -199,3 +199,56 @@ Feature: WP-CLI Commands """ Error: Callable ["Foo_Class","bar"] does not exist, and cannot be registered as `wp bar`. """ + + Scenario: Register a synopsis for a given command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + function foo( $args ) { + $message = array_shift( $args ); + WP_CLI::log( 'Message is: ' . $message ); + WP_CLI::success( $args[0] ); + } + WP_CLI::add_command( 'foo', 'foo', array( + 'shortdesc' => 'My awesome function command', + 'when' => 'before_wp_load', + 'synopsis' => array( + array( + 'type' => 'positional', + 'name' => 'message', + 'description' => 'An awesome message to display', + 'optional' => false, + ), + array( + 'type' => 'assoc', + 'name' => 'apple', + 'description' => 'A type of fruit.', + 'optional' => false, + ), + array( + 'type' => 'assoc', + 'name' => 'meal', + 'description' => 'A type of meal.', + 'optional' => true, + ), + ), + ) ); + """ + And a wp-cli.yml file: + """ + require: + - custom-cmd.php + """ + + When I try `wp foo` + Then STDOUT should contain: + """ + usage: wp foo <message> --apple=<apple> [--meal=<meal>] + """ + + When I run `wp help foo` + Then STDOUT should contain: + """ + My awesome function command + """ diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 7b01e02fe4..8ec1f51523 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -99,6 +99,15 @@ public function get_shortdesc() { return $this->shortdesc; } + /** + * Set the short description for this composite command. + * + * @param string + */ + public function set_shortdesc( $shortdesc ) { + $this->shortdesc = $shortdesc; + } + /** * Get the long description for this composite * command. diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 19ecbc3abc..1bba0b6058 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -58,6 +58,15 @@ function get_synopsis() { return $this->synopsis; } + /** + * Set the synopsis string for this subcommand. + * + * @param string + */ + public function set_synopsis( $synopsis ) { + $this->synopsis = $synopsis; + } + /** * If an alias is set, grant access to it. * Aliases permit subcommands to be instantiated diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index d4ba779240..f825cc4efa 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -34,6 +34,47 @@ public static function parse( $synopsis ) { return $params; } + /** + * @param array A structured synopsis + * @return string Rendered synopsis + */ + public static function render( $synopsis ) { + if ( ! is_array( $synopsis ) ) { + return ''; + } + $bits = array( 'positional' => '', 'assoc' => '', 'flag' => '' ); + foreach( $bits as $key => &$value ) { + foreach( $synopsis as $arg ) { + if ( empty( $arg['type'] ) + || empty( $arg['name'] ) + || $key !== $arg['type'] ) { + continue; + } + if ( 'positional' === $key ) { + $rendered_arg = "<{$arg['name']}>"; + } else if ( 'assoc' === $key ) { + $rendered_arg = "--{$arg['name']}=<{$arg['name']}>"; + } else if ( 'flag' === $key ) { + $rendered_arg = "--{$arg['name']}"; + } + if ( ! empty( $arg['repeating'] ) ) { + $rendered_arg = "{$rendered_arg}..."; + } + if ( ! empty( $arg['optional'] ) ) { + $rendered_arg = "[{$rendered_arg}]"; + } + $value .= "{$rendered_arg} "; + } + } + $rendered = ''; + foreach( $bits as $v ) { + if ( ! empty( $v ) ) { + $rendered .= $v; + } + } + return rtrim( $rendered, ' ' ); + } + /** * Classify argument attributes based on its syntax. * diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index df0785e73c..81ab4a9455 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -168,7 +168,10 @@ public static function do_hook( $when ) { * @param string $name The name of the command that will be used in the CLI * @param string $callable The command implementation as a class, function or closure * @param array $args An associative array with additional parameters: - * 'before_invoke' => callback to execute before invoking the command + * 'before_invoke' => callback to execute before invoking the command, + * 'shortdesc' => short description (80 char or less) for the command, + * 'synopsis' => the synopsis for the command (string or array) + * 'when' => execute callback on a named WP-CLI hook (e.g. before_wp_load) */ public static function add_command( $name, $callable, $args = array() ) { $valid = false; @@ -222,6 +225,22 @@ public static function add_command( $name, $callable, $args = array() ) { implode( ' ' , Dispatcher\get_path( $command ) ) ) ); } + if ( isset( $args['shortdesc'] ) ) { + $leaf_command->set_shortdesc( $args['shortdesc'] ); + } + + if ( isset( $args['synopsis'] ) ) { + if ( is_string( $args['synopsis'] ) ) { + $leaf_command->set_synopsis( $args['synopsis'] ); + } else if ( is_array( $args['synopsis'] ) ) { + $leaf_command->set_synopsis( \WP_CLI\SynopsisParser::render( $args['synopsis'] ) ); + } + } + + if ( isset( $args['when'] ) ) { + self::get_runner()->register_early_invoke( $args['when'], $leaf_command ); + } + $command->add_subcommand( $leaf_name, $leaf_command ); } From 16546dbe9f6c4198b8e06783fa15186a11204d17 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 19 Jan 2016 07:39:33 -0800 Subject: [PATCH 3993/4858] Support for generic args; add tests for `::render()` --- php/WP_CLI/SynopsisParser.php | 11 +++++++--- tests/test-synopsis.php | 38 ++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/SynopsisParser.php b/php/WP_CLI/SynopsisParser.php index f825cc4efa..b79f8a3ffd 100644 --- a/php/WP_CLI/SynopsisParser.php +++ b/php/WP_CLI/SynopsisParser.php @@ -42,18 +42,24 @@ public static function render( $synopsis ) { if ( ! is_array( $synopsis ) ) { return ''; } - $bits = array( 'positional' => '', 'assoc' => '', 'flag' => '' ); + $bits = array( 'positional' => '', 'assoc' => '', 'generic' => '', 'flag' => '' ); foreach( $bits as $key => &$value ) { foreach( $synopsis as $arg ) { if ( empty( $arg['type'] ) - || empty( $arg['name'] ) || $key !== $arg['type'] ) { continue; } + + if ( empty( $arg['name'] ) && 'generic' !== $arg['type'] ) { + continue; + } + if ( 'positional' === $key ) { $rendered_arg = "<{$arg['name']}>"; } else if ( 'assoc' === $key ) { $rendered_arg = "--{$arg['name']}=<{$arg['name']}>"; + } else if ( 'generic' === $key ) { + $rendered_arg = "--<field>=<value>"; } else if ( 'flag' === $key ) { $rendered_arg = "--{$arg['name']}"; } @@ -149,4 +155,3 @@ private static function is_repeating( $token ) { } } } - diff --git a/tests/test-synopsis.php b/tests/test-synopsis.php index 427e2ab9b3..919227d9ea 100644 --- a/tests/test-synopsis.php +++ b/tests/test-synopsis.php @@ -135,5 +135,41 @@ function testAllowedValueCharacters() { $this->assertEquals( 'unknown', $r[3]['type'] ); } -} + function testRender() { + $a = array( + array( + 'name' => 'message', + 'type' => 'positional', + 'description' => 'A short message to display to the user.', + ), + array( + 'name' => 'secrets', + 'type' => 'positional', + 'description' => 'You may tell secrets, or you may not', + 'optional' => true, + 'repeating' => true, + ), + array( + 'name' => 'meal', + 'type' => 'assoc', + 'description' => 'A meal during the day or night.', + ), + array( + 'name' => 'snack', + 'type' => 'assoc', + 'description' => 'If you are hungry between meals, you should snack.', + 'optional' => true, + ) + ); + $this->assertEquals( '<message> [<secrets>...] --meal=<meal> [--snack=<snack>]', SynopsisParser::render( $a ) ); + } + + function testParseThenRender() { + $o = '<positional> --assoc=<assoc> --<field>=<value> [--flag]'; + $a = SynopsisParser::parse( $o ); + $r = SynopsisParser::render( $a ); + $this->assertEquals( $o, $r ); + } + +} From 8d03857a6649072a87a8a1b5b9f698f4591741e4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 19 Jan 2016 07:44:00 -0800 Subject: [PATCH 3994/4858] Add `.editorconfig` to project root based on WPCS --- .editorconfig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..71f819ca14 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# http://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab + +[*.json,*.yml,*.feature] +indent_style = space +indent_size = 2 + From 71fc0927270d2de2ecd6a85ec62ca4a789a3fdea Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 19 Jan 2016 09:17:21 -0800 Subject: [PATCH 3995/4858] Use Travis' native file encryption --- .travis.yml | 28 ++++------------------------ ci/deploy.sh | 5 ----- ci/id_rsa.enc | Bin 0 -> 3248 bytes 3 files changed, 4 insertions(+), 29 deletions(-) create mode 100644 ci/id_rsa.enc diff --git a/.travis.yml b/.travis.yml index aa03bd705f..80673fcde5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,30 +5,6 @@ language: php env: global: - WP_CLI_BIN_DIR=/tmp/wp-cli-phar - # Encripted deploy key. See https://gist.github.com/scribu/6241271 - - secure: "U8gOPW2m9fkJW8omnPjFHFZutGIqAAfVs0H1izpSKJhclUfYAGjAGl1Cb6ZiUp3jZE11iWa+fAZ5mmmLAQ5L9ijta40igfFw0s+o/Vt3WBM4a3Vdqpg6civ0rDi9tJYuwtMaEi/kF/yuhKzUT80EAMqVix5xPnf963iIUPyarfY=" - - secure: "W9t7pG5h/Khoi+TrxplpSeTWxaTr7r6cYRVJBsXgghZLDXsU/qn/OhGDdY+IMfSgzO49wjFyLh2EOs8zZSujY75fgFffK2+jd/882NUlpvpXoW9C3yEfZhLJVQZI/1idnpDe9f6zA0XlpBn3bQ2QeS3i2a/JwOGCD8BQjNobk1M=" - - secure: "YsVv3AKeHyr6nwkjhB+VingCdWIzfNP2VYMMHf841rnH6HsAXNw8PJcinnVYeMd15kgjA3Yk8PbITOmzZkf9yjAmbgJTvNempEElF/KG42FkoCACtZ2Wc/jIL9zEi5o47qUicwiS6LLWYx1uQa6vActpE4KdrcDLJ6pQHp/s7ss=" - - secure: "Qsx9+R7VBSdk3st1yVyRMYgAHV58lUUSqXJjvxAkUFXsumCEVFiNpuKepvA5+EZHHnpo7zQOK6EzrIDgUBHGfwEvVumI5eur8G1RKdHnvotuz4D7YCdoRnnrzbhJkAPnVcGrIBIHd5GlDHPTVBij77JwMq5kg2tfKoKcW3RuQTc=" - - secure: "NY3grWJVgnRcA7jQW0/DbPrSkIHVkGxfhdmVSVuSfhsRq5j4kA8/zhWTIwuQ4RtkE88GWye6NarJfjFYnz2KgnCUeaFPFdnB0VE3C3OUeWIsbitjYeqycUd1+JOikPREDZaXjBb79Ve6PGTHv7CUQ+R8vBYSR7eXGqNF9SBDTEw=" - - secure: "XuKAHb35W5vN/JX8iV4FipVdxUH8GbrfheOpOAwgZ0WS5+ua79farr6q73BIPzW8AMAg3p+p1UWNoKLFEaszKuW/mT7dQExsQO04aZ7ESeLbaoKS28EMUCVeOJl0Vo+AxNSruUAIbanvggyAcxq1ILGqH9iaHLpb9BgPei3LdEc=" - - secure: "GSPAeXVhSz5MQ/FRoGFQ7As6a3w/hsq5CslpSCvNz3q7jXUjK+HPzhq3MpWF8sBd6j5IS5YUn1Pl383BDfWj/RYhIzruzIwZhgD+M7VaFFHXcS7y6i9ritXKaw2g4u+16DYQC0zg0jBODXd5NspzyeB6IA5RSecqZeuPW7z/kJc=" - - secure: "BneSPyRBtN8BPNU//rAqFmma0HfVW2GXTgRf/vuTWDnkQ9aE3Uz4S8mlA4lcVpNigvVgRop7MltLVvpWNPDk4tVPu19CkhzKXIEj6Ny6UgD6f4ZHXid/T7I6T50dtJOfcj6leDih92M2JMNaBLPRxOvAUv6yN5FrSV2LNE/0XOw=" - - secure: "URrY5IoJxf40PX+UAldnJK5HZgL5EhJ/n+ildhltyFxDu3E29Ic8Unx89M4Cb09buv1sFBFMC59q3jxck9XOWBsxiRct9y/lvnzI1R1GmVoNiTssg7wLqL6MuD2iy/4fFHFgne2mg7DVDtujCUwTQgtdz7yoh8fQeF/6lBmge1U=" - - secure: "AlNVx6gd7x7lBgrk1Dcna3yfUgdx0wZEdH8V/5NaGirfGMnO7x7ZB1pQ2LVS4EIDCZSELqUCWirFzloJtxOyUJ5AZWCu2YSGzn0cxsHkZDdBsQ1J/oPYpO8PZ9bRBDhGqqqq96F4bPxav1e8G4TH165wBB6MsR1M/He0gPrL57g=" - - secure: "JOvovCe2mKyX6/Ihvqzu93px0RdE/RsNnyDJ6EYTJjFMOhpTP/GTQQcLhMVYq62pM6Ng9/jCQl5VMWEk0f7SGL7X/RW6Rz8HaL1KWy2U9/z67FQPMz+WlJMLTP77PXJouqVemG7Om8Mheg8vMUcgXV1W/vgoljzgeBf1zseQODg=" - - secure: "H7caXIeMS7r6mLuD2aombGuGskD3VwdptcPaY2X/natpMtvHHjbyonUFE26prTWsxFc29wT9Ot705w+yo0DK42SNGaqACpy1tjq6v6xwTCjIIYeGenfnb4FiFjOROCfCXdigJ9ANDS9ufvEd2pgB12BChyLvDVX8pn3FqVzO/wQ=" - - secure: "HbyEWzWOK/dtyYY4J6BcwwCy5EWKzRI1K51Qgsc7nyN6ZlQ4P7vvFmQuLX79zTX9k3PJb58/7Ahl0xQe2mhnpK3awAEuW4ZyqL9CFQnsn7FXAAm7DWcnD8WZvOR0BitiVOEAziuh9dM7FQYBkaq6vSU+Og7NC48osDX/y4PkmG8=" - - secure: "OtXKQFf7ef/1R67U+923TJwx8uafHkhIT3wUmw3QQFkimUDHAH3tPmEk5Qy6a59aMDEO0ESIZdTfwUcMcmfgqhAxNlvmDFSnfOgJmRxzeCD036/sU/8td8VNwRW93iCu48LoGcBfVcP3lM7EJVPK2NGjneBKjna8ekLMcSx8tmE=" - - secure: "G1+MwEPgBswGI3CGtvpwV6ELauqBgBo5b5QLDd44ijqhTOYiUZz5tzU2iKR+5sMm1TqVQjGpSNC/+Hpi4WTKnKCPfKnJh/Z4/859a90GlBytsEGLGK9kAduVeLiJ1T5aOA5lHAhHsWe+CL5+d4LVlFdzBeggcXjJj5+DHHZe7+s=" - - secure: "Z6jHEwZCotrkAvIbj7/fY2fNFvDK6CTZgkpRp+VRdTk8/krWBIBGpTXgSOPXxcx+yNWooRw/mS3sazFQzZ0cv2kqGFtKxTThfAHnWNf2wMlxXvk+FGGGlIOpwt6sB5Eh3N7sF/ZkfioYE66jIVWZg4AiXJ+iEH+DKNFKVrSkwk0=" - - secure: "BzGrbJOSRsuvPrHsSY3zwOn05G9qYq/l8mBltGikRgjMGLEJpH+9+vO5YyCSgS4tDsihSw+SFpNQojS3wDUyNFT7pe0IRnCukletOVp+gwPHdqD8NoEw1gKlWFhgFZNRrc/Ma6bQqPgaQmTV+HKbSM/oAIyW5NKA/+66WTESCrg=" - - secure: "JWzwwyjbZqrCki9ijj75+X2xRS7eLJDahiAS9x87GDz8wbCMuTpWzkA+lbrj5Za3wTRUe5S4wcAELhal2x0CTRO8wUQkxSo2cATN9Bk2p00SJtCBxRJrq2H5QmmYaLIluOmyIQNDpaNS/O+TQGgUCpVg2x8KzqgiCYYGXewgJ1g=" - - secure: "g1QgDqGFAYJqxv3qyT2tQplT62o/3xA19SAjO4sAzgEp8t/h6J9K+ehbyz3tlsGJhOP/b7VGyjvnUKLZ+4BlaRhSsS1TND753+YhWGD2PKhIZ58hdW4m4ARY0yrRkVFMQqEyyIj8D+TBC713yDc58L/tmehf8ZljZpFG2PICidE=" - - secure: "Gj9fw1wM3dfgZab0XqULeR9loDj9Gsa99z8bPgfAEWS7cWqoTitF2Y9SolUX1WZyOJUZ+5Shrl7jnihl8EOlm13wxt680Kmt7jTVX5DUH+NvzWVwkYDrZV7zSFayYZJTdx3FjEvSs+GIVrpzBeBvVFvCTQUuIphPkbxwR0JHonI=" - - secure: "XS4lJJSZ2+4rB+zkt9lsdhG+pZEQ6nUjRSdLcVAgS7f7yvFCOjJYWRXlQ5zP/Gl3/XVe/L8EuGLYZsztauLSd6Ob7nEwnb5vIegLaqzbZd7Yizp9TnBj0AFCqo/ZPY+ZhnURY9OLFqknfQMWhrTeVvGRT94nhnnIF+sxokQgv0M=" - - secure: "TVMYSuxuZojZUHn3R9me8FCA1V6RaOTNE6A5gta7LSTtqZFLAQOer6tfLVof5fB3SHh2ANcOYPpjO729Mcrg195p1I/0nS18WZ0BVYvsN0Dob1I79rqYvsaW8syxCd/6TZvr7XZYdd1fDtt7kxsv74SljkliYwI2mTniQDxMONE=" - - secure: "OqbgLy6Rn+NvhjpYygNZDWf6rj8sVejRZJBmssNi5fHRXopEtfIHids2FjSXZUVPs3ShqNuczo1jzgt7N3JHbcSaiedHlc7ONqDK0SyyOcsv1oKOR81bvYcL/KIoGiMRvkQI5IW01YWfSZlS0wgL2NYdJvYanCnSUUv6nNZAF7E=" matrix: include: @@ -43,6 +19,10 @@ matrix: - php: 7.0 env: WP_VERSION=latest +before_install: + - openssl aes-256-cbc -K $encrypted_a8125246a581_key -iv $encrypted_a8125246a581_iv -in ci/id_rsa.enc -out ~/.ssh/id_rsa -d + - chmod 600 ~/.ssh/id_rsa + before_script: ./ci/prepare.sh script: ./ci/test.sh diff --git a/ci/deploy.sh b/ci/deploy.sh index 8939208368..7e74e0299a 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -12,11 +12,6 @@ if [[ "$TRAVIS_BRANCH" != "$DEPLOY_BRANCH" ]]; then exit fi -# extract private key from decrypted environment variables stored in .travis.yml -echo -n $id_rsa_{00..30} >> ~/.ssh/id_rsa_base64 -base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa -chmod 600 ~/.ssh/id_rsa - # anyone can read the build log, so it MUST NOT contain any sensitive data set -x diff --git a/ci/id_rsa.enc b/ci/id_rsa.enc new file mode 100644 index 0000000000000000000000000000000000000000..dc8ca5344be0d6a3492af863046de37e7f9f0db5 GIT binary patch literal 3248 zcmV;h3{Ufn&B$YxQhT5yUa!Tbn-L%Boi&hD-pD{=!p6OkNE^*m-Z&Nk@;ZX??lv|Q z%J-}A-?QmB@P8Kvc?-v|xNX56-^jJ``yFusQZng9){=cRK=C+N&RGG<w$gx+37WY9 z=YFnG;O$?ZfNy$K<DAirsm!3=2X2=ubp{Q<pPc@(bkd@bFyhn5rb60{h7`ZFN^f7| zV@EzRiW?p$|71Flhpthrc{Mt{h{6bT$AjC(^Br?n>Ea?oc7Moe)t;7ZtzJO7(f>(W zQ`7;Sk^=~n?TRiZ+*iUa-5k!vI9L`Hy7hBqQ-8`2sbYK#S;&3gi<q&3gkkh?Gu?^V zCi{SDOt#6OM6PoYQSd-B0eNfm7FhSo)Nj^sX9Y*Fr2>SW#h!+jQy&#}=BpG3xxW`` zWo}50PS_h-Vs|+N_joDm|I+*w8G_TQuq1#!3(0zj<j9VAPjr?-na4AFdty+eJg9e4 zY#M-E-&tFXcvr{_>xVlS)<fWXldtIT9fh*4C|1GCdb58r0UC1PT`0a>u%}U40la)T z`__K)x!btEOLLx62&X~J#&x9)aO6n7_Q(yl3(n~KzK;c}0~xm8-JB6QTc}uGwkQRX z-ws<Op*@~U@g6*QseeM&<UV<{T27hW!yI0V+^kW>^(xdW&9%Rf!c7LgA$(wVGXNk( z(}wa4W#x}I?lg8krb<($x<I>=5(y4JQoQR|9%G(iI!%($n=hCsjA;@nt<os$cO_@X z6*LXD8RPS4PaC<N!gRygC$n>vQ?!zxz*m4|Lt3yaH1B}Ph!HGeWwTp&-l}Tiac{xn zg-qjet)Z%75$9596tZ0(ICXd|mY=H{otu);Yz&U9W>(VG@#lU&>d*zRcp0^4#5acB zs_Q}XBj@PB-aNZpl4X$zFTNK;0Py%abdFF*U!jqT{g?7890bCmUtt0lNv8q<c>ZqO zQ*+^eh{m9ht%%t)mB24gO?oAsDxU&EeAoHsizoedugP!&GKYxIgxg2TE0pX0_-S(} zy;DX=u`_PCgNn~NshcRU&VER5sLo4viDUD{V(v&pmN4g^YkaI_jy9Xl-etM_J($D7 z(W`NWM^qc4^X?^J(@)oKGOfw}j8gRX=cJMyWZuH_{2&!(O3W8JQ19NCdg`U<-2eHf zK*C(88`*9hctpP%!*^`!Gd~~V%zzLQq*;j!#4}1Bm6xs*WKnIshKebcW36N9mhv&N zCKmJ1{OFt#Jh@&5FuF@_e<enb2HzUig<|kaAST%e4Y6jUOUQ32PL5+7e}C*W&5*CZ zVwVgoA?_4+jV1O&$Zt-Z4LAk*?U#E_Lm+52P65w4T^DPsfio|8Y^l47l(GEJL{v!v z&E_iaKU&&)L?mXXEn-2%KYnoHX;2O_&VqWcpxF<7;%T6s|EODs$j}<coPJX;CvpF3 z@gZD_y2SXe&AgT`7M`l3dt%oVDQb9&Mk=Ed?n&}YmXwZ)aLD@JgMK|;E&_HTk`%Sw zCOJdks-w5nisR}4n8EscjsV;jhQrY>oc)uf1zUSbWOkjvKAZ1=hB<xgcJ>`fFKj81 z<<-qF98`&_C=Nr*$RY6u$w+@00E|og$5yU+kA{?UBMdn+j8nS0#<IK9kl87HQ4E$( zsU=f8?3Eu|JathRfnzNEYT25X`?1h5-xG`oNMPpH&UL?2ccRNfnh$6&2#UXhWx}4n zigJ@rDuJb+Yp-kUEWgF{XtG83F_UFDL^4+(*6?;pb-JRgA6E7H0+^bEb1j57tBI}T zjWGvG(&n093589sYV#DJJ&oz>ToUtuB$1VjUHX8=E_8*)9-M-TRCe_w3h4f;U&g=R zTmlZ!2TiI%f#tb&z8f^7d<7;M91!XJ+zl(bb+Nyen}Ief0ZsnTR+d1@UzW2@_Ck?b zq0?m0EFqV+;#dUt+Joh+0<THjy`31)v@|f6ddHfa9swl6(*1>O&dbLfdu#i~7lUfX zqH5YH2=PNp==o}Yruv4+X>Qxp1QQfd^Q$77i97n1TLTZQ49H$bPJ7UU?5E@ViCBA_ z-{Q?x($Lbr{kU@2aG6Kp6~(3IQW9N$+PGr<dt?27u@oiU$%HH&4&2N_`8+8pX}|KP zluf0TNyERk09!!G7vMPIXL2CFX_jfo&04lhXFho1KDHvazcqvtxSQeEm>d+SAyJF~ ze$m2%Vn+RmK~`Xc3s&KZ{jf?tAJAlYw(IaEmDC*9LX2Wat_?jfpgY7}4(dBP<;9`` zV|RqR{!yvpjWaJ=@3RaZ9HHmU&SdnF2v2t;rYK}B(|`js!do(9;TooFdk9~Ap(6%r zr9SLnTurWyW#ifQH2JAAZ#Sk7F#^v!l1?;eYQ+H}qh+s2)sLmJ-Kg(6fUU+e#?}J{ zG(P9rym2i|fbgBwocfF%`b}C>!@GBv7t>cyv@6QsW}2>#h}Hg>nDvwx_7n#?&wczC z?U`Gv=EqMfP&#OUA}5$tJv{zCuw<L+ww&TqEO1O_|CdF&JXx?8&u*;V@RSIMi)zDQ za-g15|1nXJt~d&J#z@v&W#P>2_wPz`@voOen4#AbC+r0E`lW|ESP$4j_j!S(>6&7E z258^vVw%SBa)hF41R;x2Fji`bJugL3?tppx<m$4pf)kN0Xej_l<DZPI!fAY3=VyOT ze?Fb|p3SkTOijl*e34i04D=|Pisk$p1W$0)doCsol5KTlL=-7G?_n(mJn8IJClHK* z6Y3_Nm~G{E!0#&TmK4EwM$E)oKp}7QU#C;#R+Bv)@=vM-k~RLER5R*AP@2xhf)vrP zXmG3uE$Tf6n{ni=5;*4EyQ52tywpu<2aZJJW&NDgpZumoEB38|ASIA?)t{N{E?_t( zr-vomgDs8ZVQU?UE4vPM^~%eK?{-1+2T~|x74`2M)|k1=Rpx3|Y7MPTqw2px#|lsi zf6c@jMV}ydBMWD=ZbE~Jkbaz@4mnT-kFP$a+ht?A`3A4Ec3PCxp07J<HdhJzSmw6x zOTc?rREJK30*f~tnMh(h<Ikzkc?VL(j2`~jNR%8jj%KBy9+jqvL@=-q@&754(bF^o zm(tl*`9+_ev~q)rpPKwI8KXe=rX44FV6nV+Cr<i{suDp+0Z-TiGSZ_5lr=cgdz6h$ zqyPP`k2fF#4}T#b;+ZuE9(kzZd6!g$nJeD+LR#rQJYouUrwTv3w^6&maMRs3E%fdE z#)5*B7Aot8_QSJ+fkgboq)3qbVPQ0=ef@?>p|5i>Wff_vMO^0izYYykLrjkaO0< z{QdO#++21_d^+j3$5`fm-f>J`ZfJe`G|rD7p-}T%98J>AZSvuq?vnvw+~8N(<ZsPi zvxx%K@`7f0=SAQCkuD^)j>C1h3#3a8>rkPTulj@$%@Hmz(uB=mKW%TTu3%}wa#J^P zPFifyt*gJ7cafU5sR=f=xTl;LG%hg>H{R|@`GR#}U-QUpdl8o4=B=QgXA?~F=TQv* zZs-Z;3@%&SK`eAG5MW_~k>vZ4kwF$d1)lyhd<pc4&{pYb(IGHEUSGlck!D3BHolz( zsm%6Gu&Mo`i#!3CCiY`D(_h=c$1<Q%?=b8`sUwV6n=Mg3FCtshpQ<kXJUAAm-d{b| zPV<jg(10tzxEwE|Q6&<(6_M6<qb8n#SG&a4hVlpf7M-KvK9EgeZDuFc{w{ieQ}s7+ z`C8?5L<0%hZry+{M-<UkH_{<1{{XYHgpw>onkO0QLB=ms2HmH*#e(FyD+^W*q=4M* z8BU8~td8NjCBF@k@oOFqi@bf5^YApVx*LR03s|o9Y;1=v`NYJDP;NtD^_;U~<Y#>{ zArwMUa(BHj)8q%bj@7o+0Q#bakYmq}zKxEwon$_aLo==<6G=@xpj#C?_y<>QQSd(N zXsa3>y;W*IDy705-d5&bsW-=m5PW#;c&1UgUg))Ze<jR<SiAquKZ8e#8rrfkv;a;m z(a=c`YFi#7&(~9`&j7J;O9t^f6Sk*sb$upa)=k}*Z<Ie6+xP!;!z-_S^^<~q-$F{k zupe!&`K)x@%`N2Qsp@PUUtVI6IEkDkDYS&A^QexFyWqg`+MLE9fA}?F4D!wEKRc%4 zqK!0pD+5RMjx2knF*rTm#va6nR`j_Ck~fCyIDxG#O5~Zkg}!h673`yjxNH)tuv(^| zmT0J^iB(!Rn=RlWUG9OlZ0K@5tp%0fA?WL0RtPvHj~!s3k!-r#J5H>(O|ZOsyLQQc iBGT$y^M*Jdj#$oo>AL9zZL$4BtMaF|@s2JZIh$gQs$-A< literal 0 HcmV?d00001 From 35e6ade79b3dff7a023407ef56f1643b2ebd48a9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 19 Jan 2016 12:38:07 -0800 Subject: [PATCH 3996/4858] In `WP_CLI::error_to_string()`, `json_encode()` `WP_Error` data Data is typically an array. Giving us a flattened array is more helpful than indicating "Array" --- php/class-wp-cli.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 81ab4a9455..536ee0621d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -401,10 +401,11 @@ public static function error_to_string( $errors ) { if ( is_object( $errors ) && is_a( $errors, 'WP_Error' ) ) { foreach ( $errors->get_error_messages() as $message ) { - if ( $errors->get_error_data() ) - return $message . ' ' . $errors->get_error_data(); - else + if ( $errors->get_error_data() ) { + return $message . ' ' . json_encode( $errors->get_error_data() ); + } else { return $message; + } } } } From ccb66073ab6203422b9ea5ea0e864f04fe4b7427 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 19 Jan 2016 12:52:15 -0800 Subject: [PATCH 3997/4858] Persist object when using `WP_CLI::add_command()` with class method This permits an instance to be shared between commands, or be instantiated with additional data. --- php/WP_CLI/Dispatcher/CommandFactory.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index 274d53201c..bd3874117a 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -24,7 +24,7 @@ public static function create( $name, $callable, $parent ) { $command = self::create_subcommand( $parent, $name, $callable, $reflection ); } else if ( is_array( $callable ) && is_callable( $callable ) ) { $reflection = new \ReflectionClass( $callable[0] ); - $command = self::create_subcommand( $parent, $name, array( $reflection->name, $callable[1] ), + $command = self::create_subcommand( $parent, $name, array( $callable[0], $callable[1] ), $reflection->getMethod( $callable[1] ) ); } else { $reflection = new \ReflectionClass( $callable ); @@ -62,7 +62,8 @@ private static function create_subcommand( $parent, $name, $callable, $reflectio $when_invoked = function ( $args, $assoc_args ) use ( $callable ) { if ( is_array( $callable ) ) { - call_user_func( array( new $callable[0], $callable[1] ), $args, $assoc_args ); + $callable[0] = is_object( $callable[0] ) ? $callable[0] : new $callable[0]; + call_user_func( array( $callable[0], $callable[1] ), $args, $assoc_args ); } else { call_user_func( $callable, $args, $assoc_args ); } From 034170ce528e3f7dd5989a004e23e6bea18c9146 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 19 Jan 2016 13:00:17 -0800 Subject: [PATCH 3998/4858] Add a test to cover two different types of passing classes --- features/command.feature | 53 ++++++++++++++++++++++++++++++++++++++-- php/class-wp-cli.php | 3 ++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/features/command.feature b/features/command.feature index 503fc14070..c73f906226 100644 --- a/features/command.feature +++ b/features/command.feature @@ -132,6 +132,10 @@ Feature: WP-CLI Commands """ <?php class Foo_Class extends WP_CLI_Command { + + public function __construct( $prefix ) { + $this->prefix = $prefix; + } /** * My awesome class method command * @@ -141,10 +145,10 @@ Feature: WP-CLI Commands * @when before_wp_load */ function foo( $args ) { - WP_CLI::success( $args[0] ); + WP_CLI::success( $this->prefix . ':' . $args[0] ); } } - $foo = new Foo_Class; + $foo = new Foo_Class( 'boo' ); WP_CLI::add_command( 'foo', array( $foo, 'foo' ) ); """ @@ -166,6 +170,51 @@ Feature: WP-CLI Commands unknown --burrito parameter """ + When I run `wp --require=custom-cmd.php foo bar` + Then STDOUT should contain: + """ + Success: boo:bar + """ + + Scenario: Use a class method as a command + Given an empty directory + And a custom-cmd.php file: + """ + <?php + class Foo_Class extends WP_CLI_Command { + /** + * My awesome class method command + * + * <message> + * : An awesome message to display + * + * @when before_wp_load + */ + function foo( $args ) { + WP_CLI::success( $args[0] ); + } + } + WP_CLI::add_command( 'foo', array( 'Foo_Class', 'foo' ) ); + """ + + When I run `wp --require=custom-cmd.php help` + Then STDOUT should contain: + """ + foo + """ + + When I run `wp --require=custom-cmd.php help foo` + Then STDOUT should contain: + """ + My awesome class method command + """ + + When I try `wp --require=custom-cmd.php foo bar --burrito` + Then STDERR should contain: + """ + unknown --burrito parameter + """ + When I run `wp --require=custom-cmd.php foo bar` Then STDOUT should contain: """ diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 81ab4a9455..1c2f84e8f1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -188,7 +188,8 @@ public static function add_command( $name, $callable, $args = array() ) { } if ( ! $valid ) { if ( is_array( $callable ) ) { - $callable = array( get_class( $callable[0] ), $callable[1] ); + $callable[0] = is_object( $callable[0] ) ? get_class( $callable[0] ) : $callable[0]; + $callable = array( $callable[0], $callable[1] ); } WP_CLI::error( sprintf( "Callable %s does not exist, and cannot be registered as `wp %s`.", json_encode( $callable ), $name ) ); } From cba6d73fe0ff5e299c4536d72f29c4cc0d448845 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Wed, 20 Jan 2016 10:05:46 +0000 Subject: [PATCH 3999/4858] Remove WPINC check --- php/commands/core.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 87bc9904db..6b715deb85 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -100,10 +100,9 @@ public function download( $args, $assoc_args ) { } $from_version = ''; - $includes_folder = defined( 'WPINC' ) ? WPINC : 'wp-includes'; - if ( file_exists( $download_dir . $includes_folder . '/version.php' ) ) { + if ( file_exists( $download_dir . 'wp-includes/version.php' ) ) { global $wp_version; - require_once( $download_dir . $includes_folder . '/version.php' ); + require_once( $download_dir . 'wp-includes/version.php' ); $from_version = $wp_version; } From 99e6488e496c82c1248138abdb690f02efabec9b Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Wed, 20 Jan 2016 10:06:00 +0000 Subject: [PATCH 4000/4858] Rename method --- php/commands/core.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 6b715deb85..726c8581f6 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -150,7 +150,7 @@ public function download( $args, $assoc_args ) { unlink($temp); } - $this->remove_unused_files( $from_version, $assoc_args['version'], $locale ); + $this->cleanup_extra_files( $from_version, $assoc_args['version'], $locale ); WP_CLI::success( 'WordPress downloaded.' ); } @@ -980,7 +980,7 @@ function update( $args, $assoc_args ) { unset( $GLOBALS['wp_cli_update_obj'] ); $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); - $this->remove_unused_files( $from_version, $update->version, $locale ); + $this->cleanup_extra_files( $from_version, $update->version, $locale ); if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); @@ -1164,7 +1164,7 @@ private function get_updates( $assoc_args ) { return array_values( $updates ); } - private function remove_unused_files( $version_from, $version_to, $locale ) { + private function cleanup_extra_files( $version_from, $version_to, $locale ) { if ( ! $version_from || ! $version_to ) { WP_CLI::warning( 'Failed to find WordPress version. Please cleanup unused files manually.' ); return; From 2e49124bb5ab27aa7aa501e764cbd576fedd51c9 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Wed, 20 Jan 2016 10:06:24 +0000 Subject: [PATCH 4001/4858] Cleanup language --- php/commands/core.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 726c8581f6..5ca76bdf22 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1166,7 +1166,7 @@ private function get_updates( $assoc_args ) { private function cleanup_extra_files( $version_from, $version_to, $locale ) { if ( ! $version_from || ! $version_to ) { - WP_CLI::warning( 'Failed to find WordPress version. Please cleanup unused files manually.' ); + WP_CLI::warning( 'Failed to find WordPress version. Please cleanup files manually.' ); return; } @@ -1174,14 +1174,14 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { $new_checksums = self::get_core_checksums( $version_to, $locale ? $locale : 'en_US' ); if ( empty( $old_checksums ) || empty( $new_checksums ) ) { - WP_CLI::warning( 'Failed to fetch checksums. Please cleanup unused files manually.' ); + WP_CLI::warning( 'Failed to fetch checksums. Please cleanup files manually.' ); return; } $files_to_remove = array_diff( array_keys( $old_checksums ), array_keys( $new_checksums ) ); if ( ! empty( $files_to_remove ) ) { - WP_CLI::log( 'Cleaning up unused files...' ); + WP_CLI::log( 'Cleaning up files...' ); $count = 0; foreach ( $files_to_remove as $file ) { @@ -1193,7 +1193,7 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { } if ( $count ) { - WP_CLI::success( number_format( $count ) . ' unused files cleaned up' ); + WP_CLI::log( number_format( $count ) . ' files cleaned up' ); } } } From 439427c323c41f1a5014450bf12f8042f0d87786 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Wed, 20 Jan 2016 10:07:03 +0000 Subject: [PATCH 4002/4858] Add message when no files found --- php/commands/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 5ca76bdf22..21bb1ec277 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1194,6 +1194,8 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { if ( $count ) { WP_CLI::log( number_format( $count ) . ' files cleaned up' ); + } else { + WP_CLI::log( 'No files found that need cleaned up' ); } } } From 196c8f30adca70a04e3c52c3af2b490200b461e3 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Wed, 20 Jan 2016 10:07:12 +0000 Subject: [PATCH 4003/4858] Update tests --- features/core-download.feature | 4 +++- features/core-update.feature | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/features/core-download.feature b/features/core-download.feature index 429125f58a..9e3eaace6f 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -68,10 +68,12 @@ Feature: Download WordPress Error: WordPress files seem to already be present here. """ - Scenario: Make sure unused files are cleaned up + Scenario: Make sure files are cleaned up Given an empty directory When I run `wp core download --version=4.4` Then the wp-includes/rest-api.php file should exist + Then the wp-includes/class-wp-comment.php file should exist When I run `wp core download --version=4.3.2 --force` Then the wp-includes/rest-api.php file should not exist + Then the wp-includes/class-wp-comment.php file should not exist diff --git a/features/core-update.feature b/features/core-update.feature index 0c13e5c2fd..2b97dd73c5 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -159,13 +159,26 @@ Feature: Update WordPress core wordpress-4.2.4-partial-1-en_US.zip """ - Scenario: Make sure unused files are cleaned up + Scenario: Make sure files are cleaned up Given a WP install When I run `wp core update --version=4.4 --force` Then the wp-includes/rest-api.php file should exist + Then the wp-includes/class-wp-comment.php file should exist When I run `wp core update --version=4.3.2 --force` Then the wp-includes/rest-api.php file should not exist + Then the wp-includes/class-wp-comment.php file should not exist + Then STDOUT should contain: + """ + File removed: wp-includes/class-walker-comment.php + File removed: wp-includes/class-wp-network.php + File removed: wp-includes/embed-template.php + File removed: wp-includes/class-wp-comment.php + File removed: wp-includes/class-wp-http-response.php + File removed: wp-includes/class-walker-category-dropdown.php + File removed: wp-includes/rest-api.php + 150 files cleaned up + """ When I run `wp option add str_opt 'bar'` Then STDOUT should not be empty From 8524ed20d25ac68a6955b1774a832a3a1cda5cd8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jan 2016 06:51:54 -0800 Subject: [PATCH 4004/4858] Only decrypt on deploys, when the key is present --- .travis.yml | 4 ---- ci/deploy.sh | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 80673fcde5..7d2d6bba5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,6 @@ matrix: - php: 7.0 env: WP_VERSION=latest -before_install: - - openssl aes-256-cbc -K $encrypted_a8125246a581_key -iv $encrypted_a8125246a581_iv -in ci/id_rsa.enc -out ~/.ssh/id_rsa -d - - chmod 600 ~/.ssh/id_rsa - before_script: ./ci/prepare.sh script: ./ci/test.sh diff --git a/ci/deploy.sh b/ci/deploy.sh index 7e74e0299a..b289940fd4 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -12,6 +12,9 @@ if [[ "$TRAVIS_BRANCH" != "$DEPLOY_BRANCH" ]]; then exit fi +openssl aes-256-cbc -K $encrypted_a8125246a581_key -iv $encrypted_a8125246a581_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d +chmod 600 ~/.ssh/id_rsa + # anyone can read the build log, so it MUST NOT contain any sensitive data set -x From b361f359a2a1e5be693b3715f35fafd829138cbf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jan 2016 07:22:56 -0800 Subject: [PATCH 4005/4858] Script is run from project root --- ci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index b289940fd4..9f942dffc3 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -12,7 +12,7 @@ if [[ "$TRAVIS_BRANCH" != "$DEPLOY_BRANCH" ]]; then exit fi -openssl aes-256-cbc -K $encrypted_a8125246a581_key -iv $encrypted_a8125246a581_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d +openssl aes-256-cbc -K $encrypted_a8125246a581_key -iv $encrypted_a8125246a581_iv -in ci/id_rsa.enc -out ~/.ssh/id_rsa -d chmod 600 ~/.ssh/id_rsa # anyone can read the build log, so it MUST NOT contain any sensitive data From e0b593e3135ce3bcb3594b2820be274b8078f151 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jan 2016 08:05:46 -0800 Subject: [PATCH 4006/4858] Revert "Revert "Permit failures on trunk"" This reverts commit e86e4a11465bf7b04d43c7f27876b245a12b8b03. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7d2d6bba5f..ab26ba81ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,8 @@ matrix: env: WP_VERSION=trunk - php: 7.0 env: WP_VERSION=latest + allow_failures: + - env: WP_VERSION=trunk before_script: ./ci/prepare.sh From 1d86cb6879cd42fd03ac6371251cbe1844f1da38 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jan 2016 14:02:38 -0800 Subject: [PATCH 4007/4858] Failing test case for scaffolding a plugin with prompting --- features/scaffold.feature | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index f2653bec21..635cd4144b 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -124,6 +124,43 @@ Feature: WordPress code scaffolding node_modules/ """ + Scenario: Scaffold a plugin by prompting + Given a WP install + And a session file: + """ + hello-world + + Hello World + An awesome introductory plugin for WordPress + WP-CLI + http://wp-cli.org + http://wp-cli.org + n + Y + n + n + """ + + When I run `wp scaffold plugin --prompt < session` + Then STDOUT should not be empty + And the wp-content/plugins/hello-world/hello-world.php file should exist + And the wp-content/plugins/hello-world/readme.txt file should exist + And the wp-content/plugins/hello-world/tests directory should exist + + When I run `wp plugin status hello-world` + Then STDOUT should contain: + """ + Status: Active + """ + And STDOUT should contain: + """ + Name: Hello World + """ + And STDOUT should contain: + """ + Description: An awesome introductory plugin for WordPress + """ + Scenario: Scaffold a plugin and activate it Given a WP install When I run `wp scaffold plugin hello-world --activate` From 9874ecc5070c613cb596a7c8991bda02e363f9ad Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jan 2016 14:03:13 -0800 Subject: [PATCH 4008/4858] Only prompt for the first command in the execution thread Some WP-CLI commands call other WP-CLI commands, and can produce erroneous results when they prompt a second time. --- php/WP_CLI/Dispatcher/Subcommand.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 1bba0b6058..202d51e736 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -288,8 +288,11 @@ private function validate_args( $args, $assoc_args, $extra_args ) { * @param array $assoc_args */ public function invoke( $args, $assoc_args, $extra_args ) { - if ( \WP_CLI::get_config( 'prompt' ) ) + 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; + } $to_unset = $this->validate_args( $args, $assoc_args, $extra_args ); From a9b2021b622a15ffe248d94a04a28f9ea25a9546 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Thu, 21 Jan 2016 16:31:15 +0000 Subject: [PATCH 4009/4858] Remove file count --- features/core-update.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/core-update.feature b/features/core-update.feature index 2b97dd73c5..a1ac048b1b 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -177,7 +177,6 @@ Feature: Update WordPress core File removed: wp-includes/class-wp-http-response.php File removed: wp-includes/class-walker-category-dropdown.php File removed: wp-includes/rest-api.php - 150 files cleaned up """ When I run `wp option add str_opt 'bar'` From 326c3bb2b86ea2639c38d1585fc09dc8d1c06d35 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 21 Jan 2016 10:31:51 -0800 Subject: [PATCH 4010/4858] Introduce a dedicated job for testing Git clone installation --- .travis.yml | 6 ++---- ci/prepare.sh | 15 +++++++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index ab26ba81ae..e0174c6cd5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,6 @@ sudo: false language: php -env: - global: - - WP_CLI_BIN_DIR=/tmp/wp-cli-phar - matrix: include: - php: 5.3 @@ -14,6 +10,8 @@ matrix: env: WP_VERSION=3.7.11 - php: 5.6 env: WP_VERSION=latest + - php: 5.6 + env: WP_VERSION=latest BUILD=git - php: 5.6 env: WP_VERSION=trunk - php: 7.0 diff --git a/ci/prepare.sh b/ci/prepare.sh index a279e31585..a64af0f673 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -15,10 +15,17 @@ then fi # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR -mkdir -p $WP_CLI_BIN_DIR -php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet --version=$CLI_VERSION -mv wp-cli.phar $WP_CLI_BIN_DIR/wp -chmod +x $WP_CLI_BIN_DIR/wp +if [[ $BUILD == 'git' ]] +then + export WP_CLI_BIN_DIR=bin/wp + echo $CLI_VERSION > VERSION +else + export WP_CLI_BIN_DIR=/tmp/wp-cli-phar + mkdir -p $WP_CLI_BIN_DIR + php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet --version=$CLI_VERSION + mv wp-cli.phar $WP_CLI_BIN_DIR/wp + chmod +x $WP_CLI_BIN_DIR/wp +fi # Install CodeSniffer things ./ci/prepare-codesniffer.sh From 23c2dbae64640a38bea7d6e78935c77de5f38e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= <otto@seravo.fi> Date: Fri, 22 Jan 2016 15:23:48 +0200 Subject: [PATCH 4011/4858] Mention MariaDB in docs to clarify that WP-CLI works with it too --- CONTRIBUTING.md | 4 ++-- features/search-replace.feature | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 292dd1b8e0..415dc8c24a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ To run the unit tests, just execute: The functional test files are in the `features/` directory. -Before running the functional tests, you'll need a MySQL user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: +Before running the functional tests, you'll need a MySQL (or MariaDB) user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: ```sql GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; @@ -62,7 +62,7 @@ Then, to run the entire test suite: Or to test a single feature: -```bash +```bash ./vendor/bin/behat features/core.feature ``` diff --git a/features/search-replace.feature b/features/search-replace.feature index eb0783361d..0f98c95dc8 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -249,7 +249,7 @@ Feature: Do global search/replace | http://newdomain.com | | | http://newdomain.com | --dry-run | - Scenario Outline: Choose replacement method (PHP or MySQL) given proper flags or data. + Scenario Outline: Choose replacement method (PHP or MySQL/MariaDB) given proper flags or data. Given a WP install And I run `wp option get siteurl` And save STDOUT as {SITEURL} From b1f3e820c45451e42dab1988c9ec1cbde5bb36c3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 22 Jan 2016 09:38:21 -0800 Subject: [PATCH 4012/4858] Failing test case for not cleaning up wp-content --- features/core-download.feature | 8 ++++++++ features/core-update.feature | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/features/core-download.feature b/features/core-download.feature index 9e3eaace6f..38ebaa5bfb 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -73,7 +73,15 @@ Feature: Download WordPress When I run `wp core download --version=4.4` Then the wp-includes/rest-api.php file should exist Then the wp-includes/class-wp-comment.php file should exist + And STDOUT should not contain: + """ + File removed: wp-content + """ When I run `wp core download --version=4.3.2 --force` Then the wp-includes/rest-api.php file should not exist Then the wp-includes/class-wp-comment.php file should not exist + And STDOUT should not contain: + """ + File removed: wp-content + """ diff --git a/features/core-update.feature b/features/core-update.feature index a1ac048b1b..6565f026b0 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -164,6 +164,10 @@ Feature: Update WordPress core When I run `wp core update --version=4.4 --force` Then the wp-includes/rest-api.php file should exist Then the wp-includes/class-wp-comment.php file should exist + And STDOUT should not contain: + """ + File removed: wp-content + """ When I run `wp core update --version=4.3.2 --force` Then the wp-includes/rest-api.php file should not exist @@ -178,6 +182,10 @@ Feature: Update WordPress core File removed: wp-includes/class-walker-category-dropdown.php File removed: wp-includes/rest-api.php """ + And STDOUT should not contain: + """ + File removed: wp-content + """ When I run `wp option add str_opt 'bar'` Then STDOUT should not be empty From f616e58315eec91512de8b5a2fd00b99147fafac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 22 Jan 2016 09:40:19 -0800 Subject: [PATCH 4013/4858] Don't ever clean up wp-content with `wp core update` or `wp core download` --- php/commands/core.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 21bb1ec277..efcd6875cc 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1185,6 +1185,12 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { $count = 0; foreach ( $files_to_remove as $file ) { + + // wp-content should be considered user data + if ( 0 === stripos( $file, 'wp-content' ) ) { + continue; + } + if ( file_exists( ABSPATH . $file ) ) { unlink( ABSPATH . $file ); WP_CLI::log( 'File removed: ' . $file ); From 82532c01b2cca1da1ecd15abee03062a2b264e10 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 24 Jan 2016 13:33:58 -0800 Subject: [PATCH 4014/4858] Only display `$shortdesc` in man doc when present. Sometimes there may not be a short description available. --- templates/man.mustache | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/man.mustache b/templates/man.mustache index a42acbcc35..ea1ec7b93b 100644 --- a/templates/man.mustache +++ b/templates/man.mustache @@ -2,10 +2,12 @@ {{name}} +{{#shortdesc}} ## DESCRIPTION {{shortdesc}} +{{/shortdesc}} ## SYNOPSIS {{synopsis}} From 515bb24012cdaecbc1b4253d59c9e424c3fe5eb3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 25 Jan 2016 11:27:48 -0800 Subject: [PATCH 4015/4858] Don't `exit` on premature success for `wp theme activate` This can kill other scripts calling the method directly. `return` is fine for our needs to stop command execution. --- php/commands/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 59f5fd20ec..3f78830c1f 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -131,7 +131,7 @@ public function activate( $args = array() ) { if ( 'active' === $this->get_status( $theme ) ) { WP_CLI::success( "The '$name' theme is already active." ); - exit; + return; } if ( $theme->get_stylesheet() != $theme->get_template() && ! $this->fetcher->get( $theme->get_template() ) ) { From db2c514421a0e3554b76f2846345fd2324f44e36 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 25 Jan 2016 16:49:36 -0800 Subject: [PATCH 4016/4858] Only clean up `wp core download` when WP was already present If we're downloading to an empty directory, skip the operation. --- features/core-download.feature | 4 ++-- php/commands/core.php | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/features/core-download.feature b/features/core-download.feature index 38ebaa5bfb..f35c49f561 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -73,9 +73,9 @@ Feature: Download WordPress When I run `wp core download --version=4.4` Then the wp-includes/rest-api.php file should exist Then the wp-includes/class-wp-comment.php file should exist - And STDOUT should not contain: + And STDERR should not contain: """ - File removed: wp-content + Warning: Failed to find WordPress version. Please cleanup files manually. """ When I run `wp core download --version=4.3.2 --force` diff --git a/php/commands/core.php b/php/commands/core.php index efcd6875cc..c8659f5057 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -75,8 +75,9 @@ function check_update( $_, $assoc_args ) { public function download( $args, $assoc_args ) { $download_dir = ! empty( $assoc_args['path'] ) ? $assoc_args['path'] : ABSPATH; + $wordpress_present = is_readable( $download_dir . 'wp-load.php' ); - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && is_readable( $download_dir . 'wp-load.php' ) ) + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && $wordpress_present ) WP_CLI::error( 'WordPress files seem to already be present here.' ); if ( !is_dir( $download_dir ) ) { @@ -150,7 +151,9 @@ public function download( $args, $assoc_args ) { unlink($temp); } - $this->cleanup_extra_files( $from_version, $assoc_args['version'], $locale ); + if ( $wordpress_present ) { + $this->cleanup_extra_files( $from_version, $version, $locale ); + } WP_CLI::success( 'WordPress downloaded.' ); } From 7a75432280b668b9bc2fac26724e5d37914a8993 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Tue, 26 Jan 2016 10:01:41 -0200 Subject: [PATCH 4017/4858] Check if taxonomy exists before listing its terms --- features/term.feature | 6 ++++++ php/commands/term.php | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/features/term.feature b/features/term.feature index 03f2bbbb60..5efcc7c7f5 100644 --- a/features/term.feature +++ b/features/term.feature @@ -49,6 +49,12 @@ Feature: Manage WordPress terms | name | Test term | | taxonomy | post_tag | + When I try `wp term list nonexistent_taxonomy` + Then STDERR should be: + """ + Error: Taxonomy nonexistent_taxonomy doesn't exist. + """ + Scenario: Creating/deleting a term When I run `wp term create post_tag 'Test delete term' --slug=test-delete --description='This is a test term to be deleted' --porcelain` Then STDOUT should be a number diff --git a/php/commands/term.php b/php/commands/term.php index 113a6620c3..c54c7aa28c 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -59,6 +59,12 @@ class Term_Command extends WP_CLI_Command { * @subcommand list */ public function list_( $args, $assoc_args ) { + foreach ( $args as $taxonomy ) { + if ( ! taxonomy_exists( $taxonomy ) ) { + WP_CLI::error( "Taxonomy $taxonomy doesn't exist." ); + } + } + $formatter = $this->get_formatter( $assoc_args ); $defaults = array( From 8a866fbae50af41b8b04c77fba056d4bddb61cfc Mon Sep 17 00:00:00 2001 From: Radu Dan <za_creature@yahoo.com> Date: Fri, 29 Jan 2016 22:41:38 +0200 Subject: [PATCH 4018/4858] PHP_BINARY may contain spaces --- php/commands/server.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/php/commands/server.php b/php/commands/server.php index d82fc7be66..45a1f13c0e 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -53,15 +53,21 @@ function __invoke( $_, $assoc_args ) { } } - $cmd = \WP_CLI\Utils\esc_cmd( PHP_BINARY . ' -S %s -t %s %s', + $cmd = \WP_CLI\Utils\esc_cmd( '%s -S %s -t %s %s', + PHP_BINARY, $assoc_args['host'] . ':' . $assoc_args['port'], $docroot, \WP_CLI\Utils\extract_from_phar( WP_CLI_ROOT . '/php/router.php' ) ); $descriptors = array( STDIN, STDOUT, STDERR ); + + // https://bugs.php.net/bug.php?id=60181 + $options = array(); + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') + $options["bypass_shell"] = TRUE; - exit( proc_close( proc_open( $cmd, $descriptors, $pipes ) ) ); + exit( proc_close( proc_open( $cmd, $descriptors, $pipes, NULL, NULL, $options ) ) ); } } From 370f50fdb5f2598939fea3a604ca2f934ffc1286 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 30 Jan 2016 01:49:41 -0800 Subject: [PATCH 4019/4858] Use `\WP_CLI\Utils\is_windows()` instead of dupe abstraction --- php/commands/server.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/server.php b/php/commands/server.php index 45a1f13c0e..c13e917a42 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -61,11 +61,12 @@ function __invoke( $_, $assoc_args ) { ); $descriptors = array( STDIN, STDOUT, STDERR ); - + // https://bugs.php.net/bug.php?id=60181 $options = array(); - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') + if ( \WP_CLI\Utils\is_windows() ) { $options["bypass_shell"] = TRUE; + } exit( proc_close( proc_open( $cmd, $descriptors, $pipes, NULL, NULL, $options ) ) ); } From 2ad7b8e21faa9718a10052834320d31a04ee47ef Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 30 Jan 2016 10:38:27 -0800 Subject: [PATCH 4020/4858] Fix `--skip_comments` flag for `wp export` --- features/export.feature | 57 ++++++++++++++++++++++++++++ php/export/class-wp-export-query.php | 9 ++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/features/export.feature b/features/export.feature index 3f201eea25..461ee86b88 100644 --- a/features/export.feature +++ b/features/export.feature @@ -146,6 +146,13 @@ Feature: Export content. Then STDOUT should be a number And save STDOUT as {POST_ID} + When I run `wp comment generate --count=2 --post_id={POST_ID}` + And I run `wp comment list --format=count` + Then STDOUT should contain: + """ + 3 + """ + When I run `wp export --post__in={POST_ID}` And save STDOUT 'Writing to file %s' as {EXPORT_FILE} @@ -161,6 +168,12 @@ Feature: Export content. 1 """ + When I run `wp comment list --format=count` + Then STDOUT should be: + """ + 2 + """ + Scenario: Export multiple posts, separated by spaces Given a WP install @@ -422,3 +435,47 @@ Feature: Export content. """ 000.xml """ + + Scenario: Export a site and skip the comments + Given a WP install + And I run `wp comment generate --post_id=1 --count=2` + And I run `wp plugin install wordpress-importer --activate` + + When I run `wp comment list --format=count` + Then STDOUT should contain: + """ + 3 + """ + + When I run `wp export --skip_comments` + And save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --format=count` + Then STDOUT should contain: + """ + 0 + """ + + When I run `wp comment list --format=count` + Then STDOUT should contain: + """ + 0 + """ + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should not be empty + + When I run `wp post list --format=count` + Then STDOUT should contain: + """ + 1 + """ + + When I run `wp comment list --format=count` + Then STDOUT should contain: + """ + 0 + """ diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 4d271b48fb..8cbbb89d13 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -127,7 +127,7 @@ public function exportify_post( $post ) { $post->is_sticky = is_sticky( $post->ID ) ? 1 : 0; $post->terms = self::get_terms_for_post( $post ); $post->meta = self::get_meta_for_post( $post ); - $post->comments = self::get_comments_for_post( $post ); + $post->comments = $this->get_comments_for_post( $post ); $GLOBALS['post'] = $previous_global_post; return $post; } @@ -353,8 +353,13 @@ private static function get_meta_for_post( $post ) { return $meta_for_export; } - private static function get_comments_for_post( $post ) { + private function get_comments_for_post( $post ) { global $wpdb; + + if ( $this->filters['skip_comments'] ) { + return array(); + } + $comments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); foreach( $comments as $comment ) { $meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $comment->comment_ID ) ); From c2fe1a8c1ee5ee72dcf54e30dbaa3ad1a08eee06 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 1 Feb 2016 13:01:39 -0800 Subject: [PATCH 4021/4858] Add example of how to run all due cron events Props @fjarrett --- php/commands/cron.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index ec04b6b78c..af420e4e0b 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -143,6 +143,11 @@ public function schedule( $args, $assoc_args ) { * * [--all] * : Run all hooks. + * + * ## EXAMPLES + * + * # Run all cron events due right now + * wp cron event run $( wp cron event list --fields=hook,next_run_relative --format=csv | awk -F, '$2=="now" {print $1}' ) */ public function run( $args, $assoc_args ) { From 2a4bfa9b4aefa0aad40d4fa5ce5e20fd0c5bce0e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 2 Feb 2016 10:06:00 -0800 Subject: [PATCH 4022/4858] Support for cleaning up files when ZIP is provided to `core update` Also bumps WP version in tests for latest release. --- features/core-check-update.feature | 8 ++++---- features/core-update.feature | 6 ++++-- php/commands/core.php | 12 +++++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 7d9a3d2d5b..10a6508845 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -10,8 +10,8 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.4.1 | major | https://wordpress.org/wordpress-4.4.1.zip | - | 3.8.12 | minor | https://wordpress.org/wordpress-3.8.12.zip | + | 4.4.2 | major | https://wordpress.org/wordpress-4.4.2.zip | + | 3.8.13 | minor | https://wordpress.org/wordpress-3.8.13.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -22,7 +22,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.4.1 | major | https://wordpress.org/wordpress-4.4.1.zip | + | 4.4.2 | major | https://wordpress.org/wordpress-4.4.2.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -33,7 +33,7 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.12 | minor | https://wordpress.org/wordpress-3.8.12.zip | + | 3.8.13 | minor | https://wordpress.org/wordpress-3.8.13.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: diff --git a/features/core-update.feature b/features/core-update.feature index 6565f026b0..ef52aa8ea2 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -19,6 +19,8 @@ Feature: Update WordPress core """ Starting update... Unpacking the update... + Cleaning up files... + No files found that need cleaned up Success: WordPress updated successfully. """ @@ -38,7 +40,7 @@ Feature: Update WordPress core When I run `wp core update --minor` Then STDOUT should contain: """ - Updating to version 3.7.12 + Updating to version 3.7.13 """ When I run `wp core update --minor` @@ -50,7 +52,7 @@ Feature: Update WordPress core When I run `wp core version` Then STDOUT should be: """ - 3.7.12 + 3.7.13 """ @less-than-php-7 diff --git a/php/commands/core.php b/php/commands/core.php index c8659f5057..a2b341c81d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -982,9 +982,6 @@ function update( $args, $assoc_args ) { $result = Utils\get_upgrader( $upgrader )->upgrade( $update ); unset( $GLOBALS['wp_cli_update_obj'] ); - $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); - $this->cleanup_extra_files( $from_version, $update->version, $locale ); - if ( is_wp_error($result) ) { $msg = WP_CLI::error_to_string( $result ); if ( 'up_to_date' != $result->get_error_code() ) { @@ -993,6 +990,15 @@ function update( $args, $assoc_args ) { WP_CLI::success( $msg ); } } else { + + if ( file_exists( ABSPATH . 'wp-includes/version.php' ) ) { + include( ABSPATH . 'wp-includes/version.php' ); + $to_version = $wp_version; + } + + $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', get_locale() ); + $this->cleanup_extra_files( $from_version, $to_version, $locale ); + WP_CLI::success( 'WordPress updated successfully.' ); } From 29b3aa05fd079e14c4894c8e4a20b8a553d64aa5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 04:57:07 -0800 Subject: [PATCH 4023/4858] Add a timer to individual events in `wp cron event run` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running multiple events at once, this makes it easier to see which are taking a long time. ``` salty-wordpress ➜ wordpress-develop.dev wp cron event run --all Executed the cron event 'wp_update_plugins' in 0.421s. Executed the cron event 'wp_update_themes' in 0.287s. Executed the cron event 'wp_version_check' in 1.315s. Executed the cron event 'update_network_counts' in 0.004s. Executed the cron event 'wp_scheduled_auto_draft_delete' in 0.004s. Success: Executed a total of 5 cron event(s). ``` --- features/cron.feature | 22 ++++++++++++++-------- php/commands/cron.php | 4 +++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 10dcf99dcd..c545908518 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -72,10 +72,16 @@ Feature: Manage WP-Cron events and schedules | wp_cli_test_event_5 | Non-repeating | {"foo":"bar"} | When I run `wp cron event run wp_cli_test_event_5` - Then STDOUT should be: + Then STDOUT should contain: + """ + Executed the cron event 'wp_cli_test_event_5' + """ + And STDOUT should contain: + """ + Executed the cron event 'wp_cli_test_event_5' + """ + And STDOUT should contain: """ - Executed the cron event 'wp_cli_test_event_5'. - Executed the cron event 'wp_cli_test_event_5'. Success: Executed a total of 2 cron event(s). """ @@ -187,11 +193,11 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event run wp_version_check wp_update_plugins` Then STDOUT should contain: """ - Executed the cron event 'wp_version_check'. + Executed the cron event 'wp_version_check' """ And STDOUT should contain: """ - Executed the cron event 'wp_update_plugins'. + Executed the cron event 'wp_update_plugins' """ And STDOUT should contain: """ @@ -201,15 +207,15 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event run --all` Then STDOUT should contain: """ - Executed the cron event 'wp_version_check'. + Executed the cron event 'wp_version_check' """ And STDOUT should contain: """ - Executed the cron event 'wp_update_plugins'. + Executed the cron event 'wp_update_plugins' """ And STDOUT should contain: """ - Executed the cron event 'wp_update_themes'. + Executed the cron event 'wp_update_themes' """ And STDOUT should contain: """ diff --git a/php/commands/cron.php b/php/commands/cron.php index af420e4e0b..0cf9342fdd 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -174,10 +174,12 @@ public function run( $args, $assoc_args ) { $executed = 0; foreach ( $events as $event ) { if ( in_array( $event->hook, $args ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + $start = microtime( true ); $result = self::run_event( $event ); + $total = round( microtime( true ) - $start, 3 ); if ( $result ) { $executed++; - WP_CLI::log( sprintf( "Executed the cron event '%s'.", $event->hook ) ); + WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); } else { WP_CLI::warning( sprintf( "Failed to the execute the cron event '%s'.", $event->hook ) ); } From 4ef41759e799e4d58a81fdf4feae1bb285564ace Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 05:18:21 -0800 Subject: [PATCH 4024/4858] Persist IPTC data in `wp media import` when missing title/caption --- features/media-import.feature | 28 +++++++++++++++++++++++++++- php/commands/media.php | 17 +++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/features/media-import.feature b/features/media-import.feature index 4f971b0d67..51a96b6fcc 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -45,7 +45,7 @@ Feature: Manage WordPress attachments | path | url | | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | - When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --caption="My fabulous caption" --porcelain` Then save STDOUT as {ATTACHMENT_ID} When I run `wp post get {ATTACHMENT_ID} --field=title` @@ -53,3 +53,29 @@ Feature: Manage WordPress attachments """ My imported attachment """ + + When I run `wp post get {ATTACHMENT_ID} --field=excerpt` + Then STDOUT should be: + """ + My fabulous caption + """ + + Scenario: Import a file and persist its original metadata + Given download: + | path | url | + | {CACHE_DIR}/canola.jpg | http://wp-cli.org/behat-data/canola.jpg | + + When I run `wp media import {CACHE_DIR}/canola.jpg --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + + When I run `wp post get {ATTACHMENT_ID} --field=title` + Then STDOUT should be: + """ + A field of amazing canola + """ + + When I run `wp post get {ATTACHMENT_ID} --field=excerpt` + Then STDOUT should be: + """ + The description for the image + """ diff --git a/php/commands/media.php b/php/commands/media.php index 877fed9a64..fdd905bf2d 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -165,6 +165,23 @@ function import( $args, $assoc_args = array() ) { 'post_content' => $assoc_args['desc'] ); + // use image exif/iptc data for title and caption defaults if possible + if ( empty( $post_array['post_title'] ) || empty( $post_array['post_excerpt'] ) ) { + // @codingStandardsIgnoreStart + $image_meta = @wp_read_image_metadata( $tempfile ); + error_log( var_export( $image_meta, true ) ); + // @codingStandardsIgnoreEnd + if ( ! empty( $image_meta ) ) { + if ( empty( $post_array['post_title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { + $post_array['post_title'] = $image_meta['title']; + } + + if ( empty( $post_array['post_excerpt'] ) && trim( $image_meta['caption'] ) ) { + $post_array['post_excerpt'] = $image_meta['caption']; + } + } + } + // Deletes the temporary file. $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); if ( is_wp_error( $success ) ) { From 82402216d4cc1f5b43172acbad011f591dc0bbcd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 05:19:54 -0800 Subject: [PATCH 4025/4858] Remove `error_log()` --- php/commands/media.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index fdd905bf2d..1aa0d7730b 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -169,7 +169,6 @@ function import( $args, $assoc_args = array() ) { if ( empty( $post_array['post_title'] ) || empty( $post_array['post_excerpt'] ) ) { // @codingStandardsIgnoreStart $image_meta = @wp_read_image_metadata( $tempfile ); - error_log( var_export( $image_meta, true ) ); // @codingStandardsIgnoreEnd if ( ! empty( $image_meta ) ) { if ( empty( $post_array['post_title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { From 80f75be8b28596d4d26bae3ec75cd86c1a03b5c8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 05:23:39 -0800 Subject: [PATCH 4026/4858] If no IPTC data is present, use filename as title --- features/media-import.feature | 14 ++++++++++++++ php/commands/media.php | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/features/media-import.feature b/features/media-import.feature index 51a96b6fcc..81a05db281 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -60,6 +60,20 @@ Feature: Manage WordPress attachments My fabulous caption """ + Scenario: Import a file and use its filename as the title + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + + When I run `wp media import {CACHE_DIR}/large-image.jpg --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + + When I run `wp post get {ATTACHMENT_ID} --field=title` + Then STDOUT should be: + """ + large-image.jpg + """ + Scenario: Import a file and persist its original metadata Given download: | path | url | diff --git a/php/commands/media.php b/php/commands/media.php index 1aa0d7730b..15cf3a80d1 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -181,6 +181,10 @@ function import( $args, $assoc_args = array() ) { } } + if ( empty( $post_array['post_title'] ) ) { + $post_array['post_title'] = $file_array['name']; + } + // Deletes the temporary file. $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); if ( is_wp_error( $success ) ) { From a22c1d62c18d988b531b3485c1c6cb69b862ecb0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 05:34:29 -0800 Subject: [PATCH 4027/4858] Don't check translation updates when updating themes or plugins WP-CLI intends to be precise and atomic; this behavior is neither. --- php/WP_CLI/CommandWithUpgrade.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 9b71ea1c7d..f7da95183c 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -11,12 +11,9 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $upgrade_transient; function __construct() { - // After updating plugins/themes also update translations by running the `core language update` command. + // Do not automatically check translations updates after updating plugins/themes. add_action( 'upgrader_process_complete', function() { remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); - if ( Utils\wp_version_compare( '4.0', '>=' ) ) { - \WP_CLI::run_command( array( 'core', 'language', 'update' ), array( 'dry-run' => false ) ); - } }, 1 ); } From d0fdf80fc37947c035bb3bbb5809e53ea6c9f4b8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 05:45:12 -0800 Subject: [PATCH 4028/4858] Support custom exit codes in `WP_CLI::error()` For instance: ``` WP_CLI::error( 'This is return code 5.', 5 ); ``` --- features/framework.feature | 41 ++++++++++++++++++++++++++++++++++++++ php/class-wp-cli.php | 6 ++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/features/framework.feature b/features/framework.feature index 0772cfb213..d79936e0db 100644 --- a/features/framework.feature +++ b/features/framework.feature @@ -107,3 +107,44 @@ Feature: Load WP-CLI """ foo """ + + Scenario: Use a custom error code with WP_CLI::error() + Given an empty directory + And a exit-normal.php file: + """ + <?php + WP_CLI::error( 'This is return code 1.' ); + """ + And a exit-higher.php file: + """ + <?php + WP_CLI::error( 'This is return code 5.', 5 ); + """ + And a no-exit.php file: + """ + <?php + WP_CLI::error( 'This has no exit.', false ); + WP_CLI::error( 'So I can use multiple lines.', false ); + """ + + When I try `wp --require=exit-normal.php` + Then the return code should be 1 + And STDERR should be: + """ + Error: This is return code 1. + """ + + When I try `wp --require=exit-higher.php` + Then the return code should be 5 + And STDERR should be: + """ + Error: This is return code 5. + """ + + When I try `wp --require=no-exit.php` + Then the return code should be 0 + And STDERR should be: + """ + Error: This has no exit. + Error: So I can use multiple lines. + """ diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9ca92e1044..9db24d88c8 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -301,8 +301,10 @@ public static function error( $message, $exit = true ) { self::$logger->error( self::error_to_string( $message ) ); } - if ( $exit ) { - exit(1); + if ( true === $exit ) { + exit( 1 ); + } elseif ( is_int( $exit ) && $exit >= 1 ) { + exit( $exit ); } } From 375c56cbaff2fc68a0663d020df54c978eebac95 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 07:48:10 -0800 Subject: [PATCH 4029/4858] Introduce `wp package` for managing WP-CLI community commands Use `wp package browse` to view all available community commands. Install a specific command with `wp package install <namespace/package-name>`. List all installed packages with `wp package list`. Or, uninstall a package with `wp package uninstall` Packages are installed to their own Composer project in `~/.wp-cli/packages`. This can be changed by setting a `WP_CLI_PACKAGES_DIR` environment variable. --- .gitignore | 1 + composer.json | 3 +- composer.lock | 474 +++++++++++++++++-- features/bootstrap/FeatureContext.php | 3 +- features/package.feature | 31 ++ php/WP_CLI/ComposerIO.php | 27 ++ php/WP_CLI/PackageManagerEventSubscriber.php | 52 ++ php/WP_CLI/Runner.php | 10 + php/commands/package.php | 416 ++++++++++++++++ utils/make-phar.php | 6 +- 10 files changed, 976 insertions(+), 47 deletions(-) create mode 100644 features/package.feature create mode 100644 php/WP_CLI/ComposerIO.php create mode 100644 php/WP_CLI/PackageManagerEventSubscriber.php create mode 100644 php/commands/package.php diff --git a/.gitignore b/.gitignore index 27990f8353..0d5a442ae4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ config.yml /cache +/packages /vendor /*.phar /phpunit.xml.dist diff --git a/composer.json b/composer.json index cfa9066eac..982a41a8da 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "symfony/dependency-injection": "2.7.*", "symfony/event-dispatcher": "2.7.*", "symfony/translation": "2.7.*", - "nb/oxymel": "0.1.0" + "nb/oxymel": "0.1.0", + "composer/composer": "1.0.0-alpha11" }, "require-dev": { "phpunit/phpunit": "3.7.*", diff --git a/composer.lock b/composer.lock index 3968ddb0c7..725ba48a55 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,83 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7359993f535213af66c2148ea27369b3", - "content-hash": "da7f9e8dee2ffe0f76e5ed64233ecda9", + "hash": "73c38df6a0ba5a0690655b528fadb0f3", + "content-hash": "c201c938374a2ff19d8f0388a49475ff", "packages": [ + { + "name": "composer/composer", + "version": "1.0.0-alpha11", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "cd9054ce2abd1d06ed0eb1244eba1b2c2af633b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/cd9054ce2abd1d06ed0eb1244eba1b2c2af633b6", + "reference": "cd9054ce2abd1d06ed0eb1244eba1b2c2af633b6", + "shasum": "" + }, + "require": { + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.0", + "justinrainbow/json-schema": "^1.4.4", + "php": "^5.3.2 || ^7.0", + "seld/cli-prompt": "^1.0", + "seld/jsonlint": "^1.0", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.5 || ^3.0", + "symfony/filesystem": "^2.5 || ^3.0", + "symfony/finder": "^2.2 || ^3.0", + "symfony/process": "^2.1 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2015-11-14 16:21:07" + }, { "name": "composer/semver", "version": "1.0.0", @@ -68,6 +142,133 @@ ], "time": "2015-09-21 09:42:36" }, + { + "name": "composer/spdx-licenses", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "9e1c3926bb0842812967213d7c92827bc5883671" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/9e1c3926bb0842812967213d7c92827bc5883671", + "reference": "9e1c3926bb0842812967213d7c92827bc5883671", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2015-10-05 11:27:42" + }, + { + "name": "justinrainbow/json-schema", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/cc84765fb7317f6b07bd8ac78364747f95b86341", + "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341", + "shasum": "" + }, + "require": { + "php": ">=5.3.29" + }, + "require-dev": { + "json-schema/json-schema-test-suite": "1.1.0", + "phpdocumentor/phpdocumentor": "~2", + "phpunit/phpunit": "~3.7" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2016-01-25 15:43:01" + }, { "name": "mustache/mustache", "version": "v2.9.0", @@ -296,18 +497,156 @@ ], "time": "2014-05-18 04:59:02" }, + { + "name": "seld/cli-prompt", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "b27db1514f7d7bb7a366ad95d4eb2b17140a0691" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b27db1514f7d7bb7a366ad95d4eb2b17140a0691", + "reference": "b27db1514f7d7bb7a366ad95d4eb2b17140a0691", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2016-01-09 17:55:27" + }, + { + "name": "seld/jsonlint", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "66834d3e3566bb5798db7294619388786ae99394" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/66834d3e3566bb5798db7294619388786ae99394", + "reference": "66834d3e3566bb5798db7294619388786ae99394", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2015-11-21 02:21:41" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13 18:44:15" + }, { "name": "symfony/config", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "61973327bfb054f6f470de7be033a28b76c1dc20" + "reference": "fbd0083cd9dac06556bd1096deaa0295c18a7584" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/61973327bfb054f6f470de7be033a28b76c1dc20", - "reference": "61973327bfb054f6f470de7be033a28b76c1dc20", + "url": "https://api.github.com/repos/symfony/config/zipball/fbd0083cd9dac06556bd1096deaa0295c18a7584", + "reference": "fbd0083cd9dac06556bd1096deaa0295c18a7584", "shasum": "" }, "require": { @@ -344,20 +683,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2015-11-02 20:20:53" + "time": "2016-01-03 15:32:00" }, { "name": "symfony/console", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "16bb1cb86df43c90931df65f529e7ebd79636750" + "reference": "d3fc138b6ed8f8074591821d3416d8f9c04d6ca6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/16bb1cb86df43c90931df65f529e7ebd79636750", - "reference": "16bb1cb86df43c90931df65f529e7ebd79636750", + "url": "https://api.github.com/repos/symfony/console/zipball/d3fc138b6ed8f8074591821d3416d8f9c04d6ca6", + "reference": "d3fc138b6ed8f8074591821d3416d8f9c04d6ca6", "shasum": "" }, "require": { @@ -403,20 +742,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2015-11-18 09:54:26" + "time": "2016-01-14 08:26:43" }, { "name": "symfony/dependency-injection", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "7a201bf08c29e47075047cbb378724ad46dfe217" + "reference": "37dfddbf3791d79b46b11f610b39e90d622e7183" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7a201bf08c29e47075047cbb378724ad46dfe217", - "reference": "7a201bf08c29e47075047cbb378724ad46dfe217", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/37dfddbf3791d79b46b11f610b39e90d622e7183", + "reference": "37dfddbf3791d79b46b11f610b39e90d622e7183", "shasum": "" }, "require": { @@ -465,20 +804,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2015-11-23 10:17:36" + "time": "2016-01-12 17:44:11" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "7e2f9c31645680026c2372edf66f863fc7757af5" + "reference": "79493b6421786e5a0fc2d161410aa86f400bcaea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7e2f9c31645680026c2372edf66f863fc7757af5", - "reference": "7e2f9c31645680026c2372edf66f863fc7757af5", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/79493b6421786e5a0fc2d161410aa86f400bcaea", + "reference": "79493b6421786e5a0fc2d161410aa86f400bcaea", "shasum": "" }, "require": { @@ -525,20 +864,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:10:21" + "time": "2016-01-13 10:26:43" }, { "name": "symfony/filesystem", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "8e173509d7fdbbba3cf34d6d072f2073c0210c1d" + "reference": "78188c6971053ff8eaa00fa180c0747c296152f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/8e173509d7fdbbba3cf34d6d072f2073c0210c1d", - "reference": "8e173509d7fdbbba3cf34d6d072f2073c0210c1d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/78188c6971053ff8eaa00fa180c0747c296152f6", + "reference": "78188c6971053ff8eaa00fa180c0747c296152f6", "shasum": "" }, "require": { @@ -574,20 +913,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2015-11-18 13:41:01" + "time": "2016-01-13 07:57:33" }, { "name": "symfony/finder", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9" + "reference": "d20ac81c81a67ab898b0c0afa435f3e9a7d460cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a06a0c0ff7db3736a50d530c908cca547bf13da9", - "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9", + "url": "https://api.github.com/repos/symfony/finder/zipball/d20ac81c81a67ab898b0c0afa435f3e9a7d460cf", + "reference": "d20ac81c81a67ab898b0c0afa435f3e9a7d460cf", "shasum": "" }, "require": { @@ -623,20 +962,69 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:10:21" + "time": "2016-01-14 08:26:43" + }, + { + "name": "symfony/process", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "dfecef47506179db2501430e732adbf3793099c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/dfecef47506179db2501430e732adbf3793099c8", + "reference": "dfecef47506179db2501430e732adbf3793099c8", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2016-02-02 13:44:19" }, { "name": "symfony/translation", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f" + "reference": "8cbab8445ad4269427077ba02fff8718cb397e22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", - "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", + "url": "https://api.github.com/repos/symfony/translation/zipball/8cbab8445ad4269427077ba02fff8718cb397e22", + "reference": "8cbab8445ad4269427077ba02fff8718cb397e22", "shasum": "" }, "require": { @@ -686,20 +1074,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2015-11-18 13:41:01" + "time": "2016-01-03 15:32:00" }, { "name": "symfony/yaml", - "version": "v2.7.7", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4cfcd7a9fceba662b3c036b7d9a91f6197af046c" + "reference": "a91e8af3dcde226e00be2e1c068764eef7b4c153" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4cfcd7a9fceba662b3c036b7d9a91f6197af046c", - "reference": "4cfcd7a9fceba662b3c036b7d9a91f6197af046c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a91e8af3dcde226e00be2e1c068764eef7b4c153", + "reference": "a91e8af3dcde226e00be2e1c068764eef7b4c153", "shasum": "" }, "require": { @@ -735,7 +1123,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2015-11-18 13:41:01" + "time": "2016-01-13 10:26:43" }, { "name": "wp-cli/php-cli-tools", @@ -1278,7 +1666,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "wp-cli/php-cli-tools": 20 + "composer/composer": 15 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 75e0e6fe4b..4ca743bf81 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -45,7 +45,8 @@ private static function get_process_env_variables() { $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ?: realpath( __DIR__ . "/../../bin" ); $env = array( 'PATH' => $bin_dir . ':' . getenv( 'PATH' ), - 'BEHAT_RUN' => 1 + 'BEHAT_RUN' => 1, + 'HOME' => '/tmp/wp-cli-home', ); if ( $config_path = getenv( 'WP_CLI_CONFIG_PATH' ) ) { $env['WP_CLI_CONFIG_PATH'] = $config_path; diff --git a/features/package.feature b/features/package.feature new file mode 100644 index 0000000000..ec40ebf7cc --- /dev/null +++ b/features/package.feature @@ -0,0 +1,31 @@ +Feature: Manage WP-CLI packages + + Scenario: Package CRUD + Given an empty directory + + When I run `wp package browse` + Then STDOUT should contain: + """ + danielbachhuber/wp-cli-reset-post-date-command + """ + + When I run `wp package install danielbachhuber/wp-cli-reset-post-date-command` + Then STDERR should be empty + + When I run `wp help reset-post-date` + Then STDERR should be empty + + When I run `wp package list` + Then STDOUT should contain: + """ + danielbachhuber/wp-cli-reset-post-date-command + """ + + When I run `wp package uninstall danielbachhuber/wp-cli-reset-post-date-command` + Then STDERR should be empty + + When I run `wp package list` + Then STDOUT should not contain: + """ + danielbachhuber/wp-cli-reset-post-date-command + """ diff --git a/php/WP_CLI/ComposerIO.php b/php/WP_CLI/ComposerIO.php new file mode 100644 index 0000000000..b4df56a7b2 --- /dev/null +++ b/php/WP_CLI/ComposerIO.php @@ -0,0 +1,27 @@ +<?php + +namespace WP_CLI; + +use \Composer\IO\NullIO; +use \WP_CLI; + +/** + * A Composer IO class so we can provide some level of interactivity from WP-CLI + */ +class ComposerIO extends NullIO { + + /** + * {@inheritDoc} + */ + public function isVerbose() { + return true; + } + + /** + * {@inheritDoc} + */ + public function write( $messages, $newline = true ) { + WP_CLI::log( " - " . strip_tags( $messages ) ); + } + +} diff --git a/php/WP_CLI/PackageManagerEventSubscriber.php b/php/WP_CLI/PackageManagerEventSubscriber.php new file mode 100644 index 0000000000..a4b3798e34 --- /dev/null +++ b/php/WP_CLI/PackageManagerEventSubscriber.php @@ -0,0 +1,52 @@ +<?php + +namespace WP_CLI; + +use \Composer\DependencyResolver\Rule; +use \Composer\EventDispatcher\Event; +use \Composer\EventDispatcher\EventSubscriberInterface; +use \Composer\Script\PackageEvent; +use \Composer\Script\ScriptEvents; +use \WP_CLI; + +/** + * A Composer Event subscriber so we can keep track of what's happening inside Composer + */ +class PackageManagerEventSubscriber implements EventSubscriberInterface { + + public static function getSubscribedEvents() { + + return array( + ScriptEvents::PRE_PACKAGE_INSTALL => 'pre_install', + ScriptEvents::POST_PACKAGE_INSTALL => 'post_install', + ); + } + + public static function pre_install( PackageEvent $event ) { + WP_CLI::log( ' - Installing package' ); + } + + public static function post_install( PackageEvent $event ) { + + $operation = $event->getOperation(); + $reason = $operation->getReason(); + if ( $reason instanceof Rule ) { + + switch ( $reason->getReason() ) { + + case Rule::RULE_PACKAGE_CONFLICT; + case Rule::RULE_PACKAGE_SAME_NAME: + case Rule::RULE_PACKAGE_REQUIRES: + $composer_error = $reason->getPrettyString(); + break; + + } + + if ( ! empty( $composer_error ) ) { + WP_CLI::log( sprintf( " - Error: %s", $composer_error ) ); + } + } + + } + +} diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 5c48e329ba..2055cee955 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -609,6 +609,16 @@ public function start() { // APIs as non-bundled commands. Utils\load_command( $this->arguments[0] ); + if ( getenv( 'WP_CLI_PACKAGES_DIR' ) ) { + $package_autoload = rtrim( getenv( 'WP_CLI_PACKAGES_DIR' ), '/' ) . '/vendor/autoload.php'; + } else { + $package_autoload = getenv( 'HOME' ) . '/.wp-cli/packages/vendor/autoload.php'; + } + + if ( file_exists( $package_autoload ) ) { + require_once $package_autoload; + } + if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { if ( ! file_exists( $path ) ) { diff --git a/php/commands/package.php b/php/commands/package.php new file mode 100644 index 0000000000..6ebcb23b9d --- /dev/null +++ b/php/commands/package.php @@ -0,0 +1,416 @@ +<?php +use \Composer\Config; +use \Composer\Config\JsonConfigSource; +use \Composer\EventDispatcher\Event; +use \Composer\Factory; +use \Composer\IO\NullIO; +use \Composer\Installer; +use \Composer\Json\JsonFile; +use \Composer\Json\JsonManipulator; +use \Composer\Package; +use \Composer\Package\Version\VersionParser; +use \Composer\Repository; +use \Composer\Repository\CompositeRepository; +use \Composer\Repository\ComposerRepository; +use \Composer\Repository\RepositoryManager; +use \Composer\Util\Filesystem; +use \WP_CLI\ComposerIO; + +/** + * Manage WP-CLI community packages. + * + * @package WP-CLI + * + * @when before_wp_load + */ +class Package_Command extends WP_CLI_Command { + + // TODO: read from composer.json + const PACKAGE_INDEX_URL = 'http://wp-cli.org/package-index/'; + + private $fields = array( + 'name', + 'description', + 'authors', + 'version', + ); + + /** + * Browse available WP-CLI community packages. + * + * ## OPTIONS + * + * [--format=<format>] + * : Accepted values: table, json. Default: table + */ + public function browse( $_, $assoc_args ) { + $this->show_packages( $this->get_community_packages(), $assoc_args ); + } + + /** + * Install a WP-CLI community package. + * + * ## OPTIONS + * + * <package> + * : The name of the package to install. Can optionally contain a version constraint. + * + * ## EXAMPLES + * + * # install the latest development version + * wp package install wp-cli/server-command + * + * # install the latest stable version + * wp package install wp-cli/server-command:@stable + */ + public function install( $args, $assoc_args ) { + list( $package_name ) = $args; + + if ( false !== strpos( $package_name, ':' ) ) { + list( $package_name, $version ) = explode( ':', $package_name ); + } else { + $version = 'dev-master'; + } + + $package = $this->get_community_package_by_name( $package_name ); + if ( ! $package ) { + WP_CLI::error( "Invalid package." ); + } else { + WP_CLI::log( sprintf( "Installing %s (%s)", $package_name, $version ) ); + } + + $composer = $this->get_composer(); + $composer_json_obj = $this->get_composer_json(); + + // Add the 'require' to composer.json + WP_CLI::log( sprintf( "Updating %s to require the package...", $composer_json_obj->getPath() ) ); + $composer_backup = file_get_contents( $composer_json_obj->getPath() ); + $json_manipulator = new JsonManipulator( $composer_backup ); + $json_manipulator->addLink( 'require', $package_name, $version ); + file_put_contents( $composer_json_obj->getPath(), $json_manipulator->getContents() ); + $composer = $this->get_composer(); + + // Set up the EventSubscriber + $event_subscriber = new \WP_CLI\PackageManagerEventSubscriber; + $composer->getEventDispatcher()->addSubscriber( $event_subscriber ); + + // Set up the installer + $install = Installer::create( new ComposerIO, $composer ); + $install->setUpdate( true ); // Installer class will only override composer.lock with this flag + + // Try running the installer, but revert composer.json if failed + WP_CLI::log( 'Using Composer to install the package...' ); + try { + $res = $install->run(); + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + + if ( 0 === $res ) { + WP_CLI::success( "Package installed successfully." ); + } else { + file_put_contents( $composer_json_obj->getPath(), $composer_backup ); + WP_CLI::error( "Package installation failed. Reverted composer.json" ); + } + } + + /** + * List installed WP-CLI community packages. + * + * ## OPTIONS + * + * [--format=<format>] + * : Accepted values: table, json. Default: table + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $this->show_packages( $this->get_installed_packages(), $assoc_args ); + } + + /** + * Uninstall a WP-CLI community package. + * + * ## OPTIONS + * + * <package> + * : The name of the package to uninstall. + */ + public function uninstall( $args ) { + list( $package_name ) = $args; + + $composer = $this->get_composer(); + if ( false === ( $package = $this->get_installed_package_by_name( $package_name ) ) ) { + WP_CLI::error( "Package not installed." ); + } + + $composer_json_obj = $this->get_composer_json(); + + // Remove the 'require' from composer.json + $json_path = $composer_json_obj->getPath(); + WP_CLI::log( sprintf( 'Removing require statement from %s', $json_path ) ); + $contents = file_get_contents( $json_path ); + $manipulator = new JsonManipulator( $contents ); + $manipulator->removeSubNode( 'require', $package_name ); + file_put_contents( $composer_json_obj->getPath(), $manipulator->getContents() ); + + // Delete the directory + $package_path = $composer->getConfig()->get( 'vendor-dir' ) . '/' . $package->getName(); + WP_CLI::log( sprintf( 'Deleting package directory %s', $package_path ) ); + $filesystem = new Filesystem; + $filesystem->removeDirectory( $package_path ); + + // Reset Composer and regenerate the auto-loader + $composer = $this->get_composer(); + WP_CLI::log( 'Regenerating Composer autoload.' ); + $this->regenerate_autoloader(); + + WP_CLI::success( "Uninstalled package." ); + } + + /** + * Check whether a package is a WP-CLI community package based + * on membership in our package index. + * + * @param object $package A package object + * @return bool + */ + private function is_community_package( $package ) { + return $this->package_index()->hasPackage( $package ); + } + + /** + * Get a Composer instance. + */ + private function get_composer() { + $composer_path = $this->get_composer_json_path(); + + // Composer's auto-load generating code makes some assumptions about where + // the 'vendor-dir' is, and where Composer is running from. + // Best to just pretend we're installing a package from ~/.wp-cli or similar + chdir( pathinfo( $composer_path, PATHINFO_DIRNAME ) ); + + try { + $composer = Factory::create( new NullIO, $composer_path ); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + + $this->composer = $composer; + return $this->composer; + } + + /** + * Get all of the community packages. + * + * @return array + */ + private function get_community_packages() { + static $community_packages; + + if ( null === $community_packages ) { + $community_packages = $this->package_index()->getPackages(); + } + + return $community_packages; + } + + /** + * Get the package index instance + * + * We need to construct the instance manually, because there's no way to select + * a particular instance using $composer->getRepositoryManager() + * + * @return ComposerRepository + */ + private function package_index() { + static $package_index; + + if ( !$package_index ) { + $config = new Config(); + $config->merge(array('config' => array( + 'home' => dirname( $this->get_composer_json_path() ), + /* 'cache-dir' => $cacheDir */ + ))); + $config->setConfigSource( new JsonConfigSource( $this->get_composer_json() ) ); + + $package_index = new ComposerRepository( array( 'url' => self::PACKAGE_INDEX_URL ), new NullIO, $config ); + } + + return $package_index; + } + + /** + * Display a set of packages + * + * @param array + * @param array + */ + private function show_packages( $packages, $assoc_args ) { + $defaults = array( + 'fields' => implode( ',', $this->fields ), + 'format' => 'table' + ); + $assoc_args = array_merge( $defaults, $assoc_args ); + + $list = array(); + foreach ( $packages as $package ) { + $package_output = new stdClass; + $package_output->name = $package->getName(); + $package_output->description = $package->getDescription(); + $package_output->authors = implode( ',', array_column( (array) $package->getAuthors(), 'name' ) ); + $package_output->version = $package->getPrettyVersion(); + $list[$package_output->name] = $package_output; + } + + WP_CLI\Utils\format_items( $assoc_args['format'], $list, $assoc_args['fields'] ); + } + + /** + * Get a community package by its name. + */ + private function get_community_package_by_name( $package_name ) { + foreach( $this->get_community_packages() as $package ) { + if ( $package_name == $package->getName() ) + return $package; + } + return false; + } + + /** + * Get the installed community packages. + */ + private function get_installed_packages() { + $composer = $this->get_composer(); + $repo = $composer->getRepositoryManager()->getLocalRepository(); + + $installed_packages = array(); + foreach( $repo->getPackages() as $package ) { + + if ( ! $this->is_community_package( $package ) ) + continue; + + $installed_packages[] = $package; + } + + return $installed_packages; + } + + /** + * Get an installed package by its name. + */ + private function get_installed_package_by_name( $package_name ) { + foreach( $this->get_installed_packages() as $package ) { + if ( $package_name == $package->getName() ) + return $package; + } + return false; + } + + /** + * Check if the package name provided is already installed. + */ + private function is_package_installed( $package_name ) { + if ( $this->get_installed_package_by_name( $package_name ) ) + return true; + else + return false; + } + + /** + * Get the composer.json object + */ + private function get_composer_json() { + return new JsonFile( $this->get_composer_json_path() ); + } + + /** + * Get the path to composer.json + */ + private function get_composer_json_path() { + static $composer_path; + + if ( null === $composer_path ) { + + if ( getenv( 'WP_CLI_PACKAGES_DIR' ) ) { + $composer_path = rtrim( getenv( 'WP_CLI_PACKAGES_DIR' ), '/' ) . '/composer.json'; + } else { + $composer_path = getenv( 'HOME' ) . '/.wp-cli/packages/composer.json'; + } + + // `composer.json` and its directory might need to be created + if ( ! file_exists( $composer_path ) ) { + $this->create_default_composer_json( $composer_path ); + } + } + + return $composer_path; + } + + /** + * Create a default composer.json, should one not already exist + * + * @param string $composer_path Where the composer.json should be created + * @return true|WP_Error + */ + private function create_default_composer_json( $composer_path ) { + + $composer_dir = pathinfo( $composer_path, PATHINFO_DIRNAME ); + if ( ! is_dir( $composer_dir ) ) { + \WP_CLI\Process::create( WP_CLI\Utils\esc_cmd( 'mkdir -p %s', $composer_dir ) )->run(); + } + + if ( ! is_dir( $composer_dir ) ) { + WP_CLI::error( "Composer directory for packages couldn't be created." ); + } + + $json_file = new JsonFile( $composer_path ); + + $author = (object)array( + 'name' => 'WP-CLI', + 'email' => 'noreply@wpcli.org' + ); + + $repositories = (object)array( + 'wp-cli' => (object)array( + 'type' => 'composer', + 'url' => self::PACKAGE_INDEX_URL, + ), + ); + + $options = array( + 'name' => 'wp-cli/wp-cli-community-packages', + 'description' => 'Installed community packages used by WP-CLI', + 'authors' => array( $author ), + 'homepage' => self::PACKAGE_INDEX_URL, + 'require' => new stdClass, + 'require-dev' => new stdClass, + 'minimum-stability' => 'dev', + 'license' => 'MIT', + 'repositories' => $repositories, + ); + + try { + $json_file->write( $options ); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + + return true; + } + + /** + * Regenerate the Composer autoloader + */ + private function regenerate_autoloader() { + $this->composer->getAutoloadGenerator()->dump( + $this->composer->getConfig(), + $this->composer->getRepositoryManager()->getLocalRepository(), + $this->composer->getPackage(), + $this->composer->getInstallationManager(), + 'composer' + ); + } +} + +WP_CLI::add_command( 'package', 'Package_Command' ); diff --git a/utils/make-phar.php b/utils/make-phar.php index 95e89f38ed..3c32064164 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -69,11 +69,11 @@ function set_file_contents( $phar, $path, $content ) { ->in(WP_CLI_ROOT . '/vendor/mustache') ->in(WP_CLI_ROOT . '/vendor/rmccue/requests') ->in(WP_CLI_ROOT . '/vendor/composer') - ->in(WP_CLI_ROOT . '/vendor/symfony/finder') + ->in(WP_CLI_ROOT . '/vendor/symfony') ->in(WP_CLI_ROOT . '/vendor/nb/oxymel') ->in(WP_CLI_ROOT . '/vendor/ramsey/array_column') - ->in(WP_CLI_ROOT . '/vendor/composer/semver') ->in(WP_CLI_ROOT . '/vendor/mustangostang') + ->in(WP_CLI_ROOT . '/vendor/justinrainbow/json-schema') ->exclude('test') ->exclude('tests') ->exclude('Tests') @@ -99,6 +99,8 @@ function set_file_contents( $phar, $path, $content ) { add_file( $phar, WP_CLI_ROOT . '/vendor/autoload.php' ); add_file( $phar, WP_CLI_ROOT . '/ci/behat-tags.php' ); +add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/LICENSE' ); +add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/res/composer-schema.json' ); add_file( $phar, WP_CLI_ROOT . '/utils/get-package-require-from-composer.php' ); add_file( $phar, WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); From 767d20af958f1f7481c1c2d1e181c5f56241780a Mon Sep 17 00:00:00 2001 From: Frank Staude <frank@staude.net> Date: Wed, 3 Feb 2016 17:23:41 +0100 Subject: [PATCH 4030/4858] Parameter sequence corrected for wp_create_user. We have a plugin in application that listens to the Hook wpmu_new_user. Here we noticed that the new user at the time still has no email. The problem was that the parameters are passed in the wrong order on wpmu_create_user. --- php/commands/user.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index a65b986ba3..5d027f69fa 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -289,7 +289,7 @@ public function create( $args, $assoc_args ) { if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) { WP_CLI::error( $ret['errors'] ); } - $user_id = wpmu_create_user( $user->user_login, $user->user_email, $user->user_login, $user->user_pass ); + $user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email ); if ( ! $user_id ) { WP_CLI::error( "Unknown error creating new user" ); } @@ -711,7 +711,7 @@ public function import_csv( $args, $assoc_args ) { WP_CLI::warning( $ret['errors'] ); continue; } - $user_id = wpmu_create_user( $new_user['user_login'], $new_user['user_email'], $new_user['user_pass'] ); + $user_id = wpmu_create_user( $new_user['user_login'], $new_user['user_pass'], $new_user['user_email'] ); if ( ! $user_id ) { WP_CLI::warning( "Unknown error creating new user" ); continue; From 05d7ec26c5e3ff6d98c97427f4fc244b08e8bbad Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 08:53:54 -0800 Subject: [PATCH 4031/4858] Use symfony/process ~2.1 for compat with PHP 5.3 --- composer.json | 1 + composer.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 982a41a8da..a27fe7819d 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ "symfony/console": "2.7.*", "symfony/dependency-injection": "2.7.*", "symfony/event-dispatcher": "2.7.*", + "symfony/process": "~2.1", "symfony/translation": "2.7.*", "nb/oxymel": "0.1.0", "composer/composer": "1.0.0-alpha11" diff --git a/composer.lock b/composer.lock index 725ba48a55..75bb6618c7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "73c38df6a0ba5a0690655b528fadb0f3", - "content-hash": "c201c938374a2ff19d8f0388a49475ff", + "hash": "be16eacf74b49e94af4974a9c8c2460e", + "content-hash": "5045f45078e9ea1cfb8087b858d377ac", "packages": [ { "name": "composer/composer", @@ -966,25 +966,25 @@ }, { "name": "symfony/process", - "version": "v3.0.2", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "dfecef47506179db2501430e732adbf3793099c8" + "reference": "6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/dfecef47506179db2501430e732adbf3793099c8", - "reference": "dfecef47506179db2501430e732adbf3793099c8", + "url": "https://api.github.com/repos/symfony/process/zipball/6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac", + "reference": "6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=5.3.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -1011,7 +1011,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-02-02 13:44:19" + "time": "2016-01-06 09:59:23" }, { "name": "symfony/translation", From b4e6f3ab88eda66cf0b55d9df829da1d30a668ce Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 09:14:38 -0800 Subject: [PATCH 4032/4858] Remove commented code --- php/commands/package.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 6ebcb23b9d..86bedc5dd5 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -25,7 +25,6 @@ */ class Package_Command extends WP_CLI_Command { - // TODO: read from composer.json const PACKAGE_INDEX_URL = 'http://wp-cli.org/package-index/'; private $fields = array( @@ -230,7 +229,6 @@ private function package_index() { $config = new Config(); $config->merge(array('config' => array( 'home' => dirname( $this->get_composer_json_path() ), - /* 'cache-dir' => $cacheDir */ ))); $config->setConfigSource( new JsonConfigSource( $this->get_composer_json() ) ); From 0d92faad1bf50338024dc064c149db14596d466e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 09:17:03 -0800 Subject: [PATCH 4033/4858] Add braces for coding standards --- php/commands/package.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 86bedc5dd5..a63fe7e506 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -162,7 +162,7 @@ public function uninstall( $args ) { // Reset Composer and regenerate the auto-loader $composer = $this->get_composer(); WP_CLI::log( 'Regenerating Composer autoload.' ); - $this->regenerate_autoloader(); + $this->regenerate_autoloader( $composer ); WP_CLI::success( "Uninstalled package." ); } @@ -195,8 +195,7 @@ private function get_composer() { WP_CLI::error( $e->getMessage() ); } - $this->composer = $composer; - return $this->composer; + return $composer; } /** @@ -285,8 +284,9 @@ private function get_installed_packages() { $installed_packages = array(); foreach( $repo->getPackages() as $package ) { - if ( ! $this->is_community_package( $package ) ) + if ( ! $this->is_community_package( $package ) ) { continue; + } $installed_packages[] = $package; } @@ -299,8 +299,9 @@ private function get_installed_packages() { */ private function get_installed_package_by_name( $package_name ) { foreach( $this->get_installed_packages() as $package ) { - if ( $package_name == $package->getName() ) + if ( $package_name == $package->getName() ) { return $package; + } } return false; } @@ -309,10 +310,11 @@ private function get_installed_package_by_name( $package_name ) { * Check if the package name provided is already installed. */ private function is_package_installed( $package_name ) { - if ( $this->get_installed_package_by_name( $package_name ) ) + if ( $this->get_installed_package_by_name( $package_name ) ) { return true; - else + } else { return false; + } } /** @@ -400,12 +402,12 @@ private function create_default_composer_json( $composer_path ) { /** * Regenerate the Composer autoloader */ - private function regenerate_autoloader() { - $this->composer->getAutoloadGenerator()->dump( - $this->composer->getConfig(), - $this->composer->getRepositoryManager()->getLocalRepository(), - $this->composer->getPackage(), - $this->composer->getInstallationManager(), + private function regenerate_autoloader( $composer ) { + $composer->getAutoloadGenerator()->dump( + $composer->getConfig(), + $composer->getRepositoryManager()->getLocalRepository(), + $composer->getPackage(), + $composer->getInstallationManager(), 'composer' ); } From 029d6e1b087a484a48029891cbed548160fad3d2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 09:17:43 -0800 Subject: [PATCH 4034/4858] More braces --- php/commands/package.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/package.php b/php/commands/package.php index a63fe7e506..17d7a47e45 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -268,8 +268,9 @@ private function show_packages( $packages, $assoc_args ) { */ private function get_community_package_by_name( $package_name ) { foreach( $this->get_community_packages() as $package ) { - if ( $package_name == $package->getName() ) + if ( $package_name == $package->getName() ) { return $package; + } } return false; } From 781ed1135eec2df5d9ea33dde606b062bc2b1275 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 09:18:28 -0800 Subject: [PATCH 4035/4858] Warn if installation fails, so `composer.json` is reverted --- php/commands/package.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/package.php b/php/commands/package.php index 17d7a47e45..b4e801f11c 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -102,7 +102,7 @@ public function install( $args, $assoc_args ) { try { $res = $install->run(); } catch ( Exception $e ) { - WP_CLI::error( $e->getMessage() ); + WP_CLI::warning( $e->getMessage() ); } if ( 0 === $res ) { From 9e8e0a5b31706474664abacef06ac1ee7d81a947 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 09:29:41 -0800 Subject: [PATCH 4036/4858] Retool `get_composer()` so we can warn when autoload isn't regenerated If the autoload isn't regenerated, it can brick someone's WP-CLI instance. At the very least, we should let them know they'll need to manually regenerate. --- php/commands/package.php | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index b4e801f11c..5b951a22b8 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -78,7 +78,11 @@ public function install( $args, $assoc_args ) { WP_CLI::log( sprintf( "Installing %s (%s)", $package_name, $version ) ); } - $composer = $this->get_composer(); + try { + $composer = $this->get_composer(); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } $composer_json_obj = $this->get_composer_json(); // Add the 'require' to composer.json @@ -87,7 +91,11 @@ public function install( $args, $assoc_args ) { $json_manipulator = new JsonManipulator( $composer_backup ); $json_manipulator->addLink( 'require', $package_name, $version ); file_put_contents( $composer_json_obj->getPath(), $json_manipulator->getContents() ); - $composer = $this->get_composer(); + try { + $composer = $this->get_composer(); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } // Set up the EventSubscriber $event_subscriber = new \WP_CLI\PackageManagerEventSubscriber; @@ -138,7 +146,11 @@ public function list_( $args, $assoc_args ) { public function uninstall( $args ) { list( $package_name ) = $args; - $composer = $this->get_composer(); + try { + $composer = $this->get_composer(); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } if ( false === ( $package = $this->get_installed_package_by_name( $package_name ) ) ) { WP_CLI::error( "Package not installed." ); } @@ -160,8 +172,13 @@ public function uninstall( $args ) { $filesystem->removeDirectory( $package_path ); // Reset Composer and regenerate the auto-loader - $composer = $this->get_composer(); WP_CLI::log( 'Regenerating Composer autoload.' ); + try { + $composer = $this->get_composer(); + } catch( Exception $e ) { + WP_CLI::warning( $e->getMessage() ); + WP_CLI::error( 'Composer autoload will need to be manually regenerated.' ); + } $this->regenerate_autoloader( $composer ); WP_CLI::success( "Uninstalled package." ); @@ -188,14 +205,7 @@ private function get_composer() { // the 'vendor-dir' is, and where Composer is running from. // Best to just pretend we're installing a package from ~/.wp-cli or similar chdir( pathinfo( $composer_path, PATHINFO_DIRNAME ) ); - - try { - $composer = Factory::create( new NullIO, $composer_path ); - } catch( Exception $e ) { - WP_CLI::error( $e->getMessage() ); - } - - return $composer; + return Factory::create( new NullIO, $composer_path ); } /** @@ -279,7 +289,11 @@ private function get_community_package_by_name( $package_name ) { * Get the installed community packages. */ private function get_installed_packages() { - $composer = $this->get_composer(); + try { + $composer = $this->get_composer(); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } $repo = $composer->getRepositoryManager()->getLocalRepository(); $installed_packages = array(); From 8660b7d54c15462952424ac82fc27ba9767b952d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 10:00:49 -0800 Subject: [PATCH 4037/4858] Manage term meta with `wp term meta` --- features/term-meta.feature | 35 +++++++++++++++++++++++++++++++++++ php/commands/term.php | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 features/term-meta.feature diff --git a/features/term-meta.feature b/features/term-meta.feature new file mode 100644 index 0000000000..fcc7b65813 --- /dev/null +++ b/features/term-meta.feature @@ -0,0 +1,35 @@ +Feature: Manage term custom fields + + @require-wp-4.4 + Scenario: Term meta CRUD + Given a WP install + + When I run `wp term meta add 1 foo 'bar'` + Then STDOUT should not be empty + + When I run `wp term meta get 1 foo` + Then STDOUT should be: + """ + bar + """ + + When I try `wp term meta get 999999 foo` + Then STDERR should be: + """ + Error: Could not find the term with ID 999999. + """ + + When I run `wp term meta set 1 foo '[ "1", "2" ]' --format=json` + Then STDOUT should not be empty + + When I run `wp term meta get 1 foo --format=json` + Then STDOUT should be: + """ + ["1","2"] + """ + + When I run `wp term meta delete 1 foo` + Then STDOUT should not be empty + + When I try `wp term meta get 1 foo` + Then the return code should be 1 diff --git a/php/commands/term.php b/php/commands/term.php index c54c7aa28c..07061fc0f5 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -411,5 +411,42 @@ private function get_formatter( &$assoc_args ) { } } +/** + * Manage term custom fields. + * + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * wp term meta set category 123 description "Mary is a WordPress developer." + */ +class Term_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'term'; + + /** + * Check that the term ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + $term = get_term( $object_id ); + if ( ! $term ) { + WP_CLI::error( "Could not find the term with ID {$object_id}." ); + } + return $term->term_id; + } + +} + WP_CLI::add_command( 'term', 'Term_Command' ); +WP_CLI::add_command( 'term meta', 'Term_Meta_Command', array( + 'before_invoke' => function() { + if ( \WP_CLI\Utils\wp_version_compare( '4.4', '<' ) ) { + WP_CLI::error( "Requires WordPress 4.4 or greater." ); + } + }) +); From 0d29675d2d8e9181b8ae5bf531efe57c42c61ed3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 11:02:18 -0800 Subject: [PATCH 4038/4858] Fix deploys; `WP_CLI_BIN_DIR` is no longer set --- ci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 9f942dffc3..45de26a955 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -30,7 +30,7 @@ git config push.default "current" fname="phar/wp-cli-nightly.phar" -mv $WP_CLI_BIN_DIR/wp $fname +mv /tmp/wp-cli-phar/wp $fname chmod -x $fname md5sum $fname | cut -d ' ' -f 1 > $fname.md5 From e4a53e45604b2cec1967249ca330fd3f99f18675 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 12:02:55 -0800 Subject: [PATCH 4039/4858] Explain nuances of `wp core update --minor` WordPress doesn't follow semver, so `--minor` would take you from WP 4.3 to WP 4.3.3 instead of WP 4.4.2 --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index a2b341c81d..6f589ff1db 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -877,7 +877,7 @@ public function verify_checksums( $args, $assoc_args ) { * : Path to zip file to use, instead of downloading from wordpress.org. * * [--minor] - * : Only perform updates for minor releases. + * : Only perform updates for minor releases (e.g. update from WP 4.3 to 4.3.3 instead of 4.4.2). * * [--version=<version>] * : Update to a specific version, instead of to the latest version. From 2be9d54ebee5fd93962b98fee7c386f311a20716 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 12:07:03 -0800 Subject: [PATCH 4040/4858] Remove dead code in `Cron_Event_Command->run()` `Cron_Event_Command::run_event()` always returns true --- php/commands/cron.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 0cf9342fdd..b369ad0593 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -177,12 +177,8 @@ public function run( $args, $assoc_args ) { $start = microtime( true ); $result = self::run_event( $event ); $total = round( microtime( true ) - $start, 3 ); - if ( $result ) { - $executed++; - WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); - } else { - WP_CLI::warning( sprintf( "Failed to the execute the cron event '%s'.", $event->hook ) ); - } + $executed++; + WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); } } From c9c8dca23f6b71b24f4610a770b9d332195ee8b2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 3 Feb 2016 13:11:29 -0800 Subject: [PATCH 4041/4858] Revert "Revert "Revert "Permit failures on trunk""" This reverts commit e0b593e3135ce3bcb3594b2820be274b8078f151. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e0174c6cd5..81b0e2b1da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,6 @@ matrix: env: WP_VERSION=trunk - php: 7.0 env: WP_VERSION=latest - allow_failures: - - env: WP_VERSION=trunk before_script: ./ci/prepare.sh From 9090cf837b1982cd197e3d3a621b63b5a53b7d05 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 4 Feb 2016 15:29:34 -0800 Subject: [PATCH 4042/4858] Explain exit codes for `wp (theme|plugin) is-installed` --- php/commands/plugin.php | 3 +++ php/commands/theme.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 885f69fb96..c9a92fb851 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -534,6 +534,8 @@ function uninstall( $args, $assoc_args = array() ) { /** * Check if the plugin is installed. * + * Returns exit code 0 when installed, 1 when uninstalled. + * * ## OPTIONS * * <plugin> @@ -542,6 +544,7 @@ function uninstall( $args, $assoc_args = array() ) { * ## EXAMPLES * * wp plugin is-installed hello + * echo $? # displays 0 or 1 * * @subcommand is-installed */ diff --git a/php/commands/theme.php b/php/commands/theme.php index 3f78830c1f..79d6c08170 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -485,6 +485,8 @@ function update( $args, $assoc_args ) { /** * Check if the theme is installed. * + * Returns exit code 0 when installed, 1 when uninstalled. + * * ## OPTIONS * * <theme> @@ -493,6 +495,7 @@ function update( $args, $assoc_args ) { * ## EXAMPLES * * wp theme is-installed twentytwelve + * echo $? # displays 0 or 1 * * @subcommand is-installed */ From 827fe5c546f5cc0e038f08bfe4de2eeb458a3425 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 10:54:29 +0000 Subject: [PATCH 4043/4858] Add json and csv formats to upgrade output --- php/WP_CLI/CommandWithUpgrade.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index f7da95183c..9bee857de6 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -282,7 +282,13 @@ protected function update_many( $args, $assoc_args ) { 'status' => $result[ $info['update_id'] ] !== null ? 'Updated' : 'Error', ); } - \WP_CLI\Utils\format_items( 'table', $status, array( 'name', 'old_version', 'new_version', 'status' ) ); + + $format = 'table'; + if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) { + $format = $assoc_args['format']; + } + + \WP_CLI\Utils\format_items( $format, $status, array( 'name', 'old_version', 'new_version', 'status' ) ); } } } From 760bc9e6ae7546af4cd7107d1c585da87ef3dccf Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 10:54:38 +0000 Subject: [PATCH 4044/4858] Add tests --- features/theme.feature | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 42144d0cd4..3b0239b244 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -249,3 +249,25 @@ Feature: Manage WordPress themes | name | status | | biker | active | | jolene | parent | + + Scenario: Check json and csv formats when updating a theme + Given a WP install + + When I run `wp theme update twentyfifteen --version=1.0` + Then STDOUT should not be empty + + When I run `wp theme update twentyfifteen --format=json` + Then STDOUT should contain: + """ + [{"name":"twentyfifteen","old_version":"1.0", + """ + + When I run `wp theme update twentyfifteen --version=1.0` + Then STDOUT should not be empty + + When I run `wp theme update twentyfifteen --format=csv` + Then STDOUT should contain: + """ + name,old_version,new_version,status + twentyfifteen,1.0, + """ From 07c1094b3ed8b3134dda46cefdd7f00370a00715 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 5 Feb 2016 05:27:23 -0800 Subject: [PATCH 4045/4858] Support `--format=yaml` when displaying structured data --- features/bootstrap/support.php | 22 +++++++++++++++ features/formatter.feature | 51 ++++++++++++++++++++++++++++++++++ features/steps/then.php | 10 +++++++ php/WP_CLI/Formatter.php | 5 ++++ php/class-wp-cli.php | 2 ++ php/commands/comment.php | 4 +-- php/commands/core.php | 2 +- php/commands/cron.php | 4 +-- php/commands/menu.php | 6 ++-- php/commands/package.php | 4 +-- php/commands/plugin.php | 6 ++-- php/commands/post-type.php | 4 +-- php/commands/post.php | 4 +-- php/commands/rewrite.php | 2 +- php/commands/role.php | 2 +- php/commands/sidebar.php | 2 +- php/commands/site.php | 2 +- php/commands/taxonomy.php | 4 +-- php/commands/term.php | 4 +-- php/commands/theme.php | 6 ++-- php/commands/user.php | 6 ++-- php/commands/widget.php | 2 +- 22 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 features/formatter.feature diff --git a/features/bootstrap/support.php b/features/bootstrap/support.php index 9df27c18aa..d5cc221e4a 100644 --- a/features/bootstrap/support.php +++ b/features/bootstrap/support.php @@ -164,3 +164,25 @@ function checkThatCsvStringContainsValues( $actualCSV, $expectedCSV ) { return $expectedResult >= count( $expectedCSV ); } +/** + * Compare two strings containing YAML to ensure that @a $actualYaml contains at + * least what the YAML string @a $expectedYaml contains. + * + * @return whether or not @a $actualYaml contains @a $expectedJson + * @retval true @a $actualYaml contains @a $expectedJson + * @retval false @a $actualYaml does not contain @a $expectedJson + * + * @param[in] $actualYaml the YAML string to be tested + * @param[in] $expectedYaml the expected YAML string + */ +function checkThatYamlStringContainsYamlString( $actualYaml, $expectedYaml ) { + $actualValue = spyc_load( $actualYaml ); + $expectedValue = spyc_load( $expectedYaml ); + + if ( !$actualValue ) { + return false; + } + + return compareContents( $expectedValue, $actualValue ); +} + diff --git a/features/formatter.feature b/features/formatter.feature new file mode 100644 index 0000000000..a34551b056 --- /dev/null +++ b/features/formatter.feature @@ -0,0 +1,51 @@ +Feature: Format output + + Scenario: Format output as YAML + Given an empty directory + And a output-yaml.php file: + """ + <?php + /** + * @when before_wp_load + */ + $output_yaml = function( $args ) { + $items = array( + array( + 'label' => 'Foo', + 'slug' => 'foo', + ), + array( + 'label' => 'Bar', + 'slug' => 'bar', + ), + ); + $assoc_args = array( 'format' => 'yaml', 'fields' => array( 'label', 'slug' ) ); + $formatter = new \WP_CLI\Formatter( $assoc_args ); + if ( 'all' === $args[0] ) { + $formatter->display_items( $items ); + } else if ( 'single' === $args[0] ) { + $formatter->display_item( $items[0] ); + } + }; + WP_CLI::add_command( 'yaml', $output_yaml ); + """ + + When I run `wp --require=output-yaml.php yaml all` + Then STDOUT should be YAML containing: + """ + --- + - + label: Foo + slug: foo + - + label: Bar + slug: bar + """ + + When I run `wp --require=output-yaml.php yaml single` + Then STDOUT should be YAML containing: + """ + --- + label: Foo + slug: foo + """ diff --git a/features/steps/then.php b/features/steps/then.php index f2e15fb323..f2889f5bf9 100644 --- a/features/steps/then.php +++ b/features/steps/then.php @@ -113,6 +113,16 @@ function ( $world, TableNode $expected ) { } ); +$steps->Then( '/^STDOUT should be YAML containing:$/', + function ( $world, PyStringNode $expected ) { + $output = $world->result->stdout; + $expected = $world->replace_variables( (string) $expected ); + + if ( !checkThatYamlStringContainsYamlString( $output, $expected ) ) { + throw new \Exception( $world->result ); + } +}); + $steps->Then( '/^(STDOUT|STDERR) should be empty$/', function ( $world, $stream ) { diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 31c4a169eb..0a3cd49781 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -144,6 +144,10 @@ private function format( $items ) { echo json_encode( $out ); break; + case 'yaml': + echo \Spyc::YAMLDump( $items, 2, 0 ); + break; + default: \WP_CLI::error( 'Invalid format: ' . $this->args['format'] ); } @@ -237,6 +241,7 @@ private function show_multiple_fields( $data, $format ) { } break; + case 'yaml': case 'json': \WP_CLI::print_value( $data, array( 'format' => $format ) ); break; diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9db24d88c8..1e360a40e4 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -384,6 +384,8 @@ public static function read_value( $raw_value, $assoc_args = array() ) { public static function print_value( $value, $assoc_args = array() ) { if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { $value = json_encode( $value ); + } elseif ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'yaml' ) { + $value = Spyc::YAMLDump( $value, 2, 0 ); } elseif ( is_array( $value ) || is_object( $value ) ) { $value = var_export( $value ); } diff --git a/php/commands/comment.php b/php/commands/comment.php index 9524d92526..45a01d86f9 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -140,7 +140,7 @@ public function generate( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * @@ -177,7 +177,7 @@ public function get( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/core.php b/php/commands/core.php index 6f589ff1db..541161cd5f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -30,7 +30,7 @@ class Core_Command extends WP_CLI_Command { * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] - * : Accepted values: table, csv, json. Default: table + * : Accepted values: table, csv, json, yaml. Default: table * * @subcommand check-update */ diff --git a/php/commands/cron.php b/php/commands/cron.php index b369ad0593..ccc763485d 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -23,7 +23,7 @@ class Cron_Event_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, json, csv, ids. Default: table. + * : Accepted values: table, json, csv, ids, yaml. Default: table. * * ## AVAILABLE FIELDS * @@ -407,7 +407,7 @@ class Cron_Schedule_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, json, csv, ids. Default: table. + * : Accepted values: table, json, csv, ids, yaml. Default: table. * * ## AVAILABLE FIELDS * diff --git a/php/commands/menu.php b/php/commands/menu.php index 33cfcf0fa3..1c9e7e12b6 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -97,7 +97,7 @@ public function delete( $args, $_ ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids. Default: table + * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -193,7 +193,7 @@ class Menu_Item_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids. Default: table + * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -634,7 +634,7 @@ class Menu_Location_Command extends WP_CLI_Command { * List locations for the current theme. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids. Default: table + * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/package.php b/php/commands/package.php index 5b951a22b8..e85d8c8a13 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -40,7 +40,7 @@ class Package_Command extends WP_CLI_Command { * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv, yaml. Default: table */ public function browse( $_, $assoc_args ) { $this->show_packages( $this->get_community_packages(), $assoc_args ); @@ -127,7 +127,7 @@ public function install( $args, $assoc_args ) { * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * @subcommand list */ diff --git a/php/commands/plugin.php b/php/commands/plugin.php index c9a92fb851..8290ce171d 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -78,7 +78,7 @@ function status( $args ) { * **short_description**: Plugin's Short Description * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## EXAMPLES * @@ -460,7 +460,7 @@ function install( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Output list as table, json, CSV. Defaults to table. + * : Output list as table, json, CSV, yaml. Defaults to table. * * ## EXAMPLES * @@ -594,7 +594,7 @@ function delete( $args, $assoc_args = array() ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/post-type.php b/php/commands/post-type.php index d83ec398fb..4fdff4600b 100644 --- a/php/commands/post-type.php +++ b/php/commands/post-type.php @@ -30,7 +30,7 @@ class Post_Type_Command extends WP_CLI_Command { * : Limit the output to specific post type fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -76,7 +76,7 @@ public function list_( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * diff --git a/php/commands/post.php b/php/commands/post.php index 1fdafec57a..61cbd0beb4 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -164,7 +164,7 @@ protected function _edit( $content, $title ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * @@ -243,7 +243,7 @@ public function delete( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids. Default: table + * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index 02c0c1e17b..d8dac74fcc 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -151,7 +151,7 @@ public function structure( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to match,query,source. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## EXAMPLES * diff --git a/php/commands/role.php b/php/commands/role.php index 31b76cf954..de0b3c15b2 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -21,7 +21,7 @@ class Role_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 0096d4a6c1..53cb9c3ac7 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -20,7 +20,7 @@ class Sidebar_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/site.php b/php/commands/site.php index 923abc5806..70ead9dbcf 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -371,7 +371,7 @@ private function _get_network( $network_id ) { * : Comma-separated list of fields to show. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index 7d34abe7e4..addfb8c324 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -41,7 +41,7 @@ public function __construct() { * : Limit the output to specific taxonomy fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -95,7 +95,7 @@ public function list_( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * diff --git a/php/commands/term.php b/php/commands/term.php index 07061fc0f5..049fa6515c 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -34,7 +34,7 @@ class Term_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -169,7 +169,7 @@ public function create( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * diff --git a/php/commands/theme.php b/php/commands/theme.php index 79d6c08170..980967d7e1 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -72,7 +72,7 @@ function status( $args ) { * **description**: Theme Description * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## EXAMPLES * @@ -411,7 +411,7 @@ function install( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * @@ -557,7 +557,7 @@ function delete( $args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## AVAILABLE FIELDS * diff --git a/php/commands/user.php b/php/commands/user.php index 5d027f69fa..bda3adcfb0 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -42,7 +42,7 @@ public function __construct() { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Accepted values: table, csv, json, count, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -138,7 +138,7 @@ public function list_( $args, $assoc_args ) { * : Get a specific subset of the user's fields. * * [--format=<format>] - * : Accepted values: table, json, csv. Default: table + * : Accepted values: table, json, csv, yaml. Default: table * * ## EXAMPLES * @@ -820,7 +820,7 @@ public function __construct() { * : The metadata key. * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Accepted values: table, json, yaml. Default: table */ public function get( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); diff --git a/php/commands/widget.php b/php/commands/widget.php index 3976272c9e..fbc174beb1 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -37,7 +37,7 @@ class Widget_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids. Default: table + * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * From ea065f5539441423086798e4beeb161f482573d6 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 14:54:17 +0000 Subject: [PATCH 4046/4858] Don't output feedback if --format is json/csv --- php/WP_CLI/CommandWithUpgrade.php | 15 +++++++++------ php/WP_CLI/UpgraderSkin.php | 4 +++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 9bee857de6..26a3688b3e 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -249,6 +249,7 @@ protected function update_many( $args, $assoc_args ) { $cache_manager->whitelist_package($item['update_package'], $this->item_type, $item['name'], $item['update_version']); } $upgrader = $this->get_upgrader( $assoc_args ); + $upgrader->cli_output_format = ! empty( $assoc_args['format'] ) ? $assoc_args['format'] : ''; $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); } @@ -258,12 +259,14 @@ protected function update_many( $args, $assoc_args ) { $line = "Updated $num_updated/$num_to_update {$this->item_type}s."; - if ( $num_to_update == $num_updated ) { - \WP_CLI::success( $line ); - } else if ( $num_updated > 0 ) { - \WP_CLI::warning( $line ); - } else { - \WP_CLI::error( $line ); + if ( empty( $assoc_args['format'] ) || ! in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) { + if ( $num_to_update == $num_updated ) { + \WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + \WP_CLI::warning( $line ); + } else { + \WP_CLI::error( $line ); + } } if ( $num_to_update > 0 ) { diff --git a/php/WP_CLI/UpgraderSkin.php b/php/WP_CLI/UpgraderSkin.php index aa56b43486..0fab75eb06 100644 --- a/php/WP_CLI/UpgraderSkin.php +++ b/php/WP_CLI/UpgraderSkin.php @@ -41,7 +41,9 @@ function feedback( $string ) { $string = str_replace( '…', '...', strip_tags( $string ) ); - \WP_CLI::line( $string ); + if ( empty( $this->upgrader->cli_output_format ) || ! in_array( $this->upgrader->cli_output_format, array( 'csv', 'json' ) ) ) { + \WP_CLI::line( $string ); + } } } From 5684576c609714f2c45edde5d21d6d813918de2e Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 14:54:42 +0000 Subject: [PATCH 4047/4858] Make --dry-run use the correct --format --- php/WP_CLI/CommandWithUpgrade.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 26a3688b3e..9547e4c8f9 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -232,10 +232,17 @@ protected function update_many( $args, $assoc_args ) { return; } - \WP_CLI::line( "Available {$this->item_type} updates:" ); - - \WP_CLI\Utils\format_items( 'table', $items_to_update, - array( 'name', 'status', 'version', 'update_version' ) ); + if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) { + \WP_CLI\Utils\format_items( $assoc_args['format'], $items_to_update, array( 'name', 'status', 'version', 'update_version' ) ); + } else if ( ! empty( $assoc_args['format'] ) && 'summary' === $assoc_args['format'] ) { + \WP_CLI::line( "Available {$this->item_type} updates:" ); + foreach( $items_to_update as $item_to_update => $info ) { + \WP_CLI::log( "{$info['title']} update from version {$info['version']} to version {$info['update_version']}" ); + } + } else { + \WP_CLI::line( "Available {$this->item_type} updates:" ); + \WP_CLI\Utils\format_items( 'table', $items_to_update, array( 'name', 'status', 'version', 'update_version' ) ); + } return; } From 98a99910c32fbc92b63e75a6c817a81e52220229 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 14:54:56 +0000 Subject: [PATCH 4048/4858] Add tests for --dry-run --- features/theme.feature | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 3b0239b244..0665eb33f1 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -250,6 +250,38 @@ Feature: Manage WordPress themes | biker | active | | jolene | parent | + Scenario: When updating a theme --format should be the same when using --dry-run + Given a WP install + + When I run `wp theme update twentyfifteen --version=1.0` + Then STDOUT should not be empty + + When I run `wp theme update twentyfifteen --format=summary --dry-run` + Then STDOUT should contain: + """ + Available theme updates: + Twenty Fifteen update from version 1.0 to version + """ + + When I run `wp theme update twentyfifteen --version=1.0` + Then STDOUT should not be empty + + When I run `wp theme update twentyfifteen --format=json --dry-run` + Then STDOUT should contain: + """ + [{"name":"twentyfifteen","status":"inactive","version":"1.0", + """ + + When I run `wp theme update twentyfifteen --version=1.0` + Then STDOUT should not be empty + + When I run `wp theme update twentyfifteen --format=csv --dry-run` + Then STDOUT should contain: + """ + name,status,version,update_version + twentyfifteen,inactive,1.0, + """ + Scenario: Check json and csv formats when updating a theme Given a WP install From 9fff11456f73a7b493f7cb22742888e5c4457bef Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 16:23:05 +0000 Subject: [PATCH 4049/4858] Use quiet logger --- php/WP_CLI/CommandWithUpgrade.php | 20 +++++++++++--------- php/WP_CLI/UpgraderSkin.php | 4 +--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 9547e4c8f9..e9b02249de 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -212,6 +212,11 @@ protected function get_upgrader( $assoc_args ) { protected function update_many( $args, $assoc_args ) { call_user_func( $this->upgrade_refresh ); + if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) { + $logger = new \WP_CLI\Loggers\Quiet; + \WP_CLI::set_logger( $logger ); + } + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { \WP_CLI::error( "Please specify one or more {$this->item_type}s, or use --all." ); } @@ -256,7 +261,6 @@ protected function update_many( $args, $assoc_args ) { $cache_manager->whitelist_package($item['update_package'], $this->item_type, $item['name'], $item['update_version']); } $upgrader = $this->get_upgrader( $assoc_args ); - $upgrader->cli_output_format = ! empty( $assoc_args['format'] ) ? $assoc_args['format'] : ''; $result = $upgrader->bulk_upgrade( wp_list_pluck( $items_to_update, 'update_id' ) ); } @@ -266,14 +270,12 @@ protected function update_many( $args, $assoc_args ) { $line = "Updated $num_updated/$num_to_update {$this->item_type}s."; - if ( empty( $assoc_args['format'] ) || ! in_array( $assoc_args['format'], array( 'json', 'csv' ) ) ) { - if ( $num_to_update == $num_updated ) { - \WP_CLI::success( $line ); - } else if ( $num_updated > 0 ) { - \WP_CLI::warning( $line ); - } else { - \WP_CLI::error( $line ); - } + if ( $num_to_update == $num_updated ) { + \WP_CLI::success( $line ); + } else if ( $num_updated > 0 ) { + \WP_CLI::warning( $line ); + } else { + \WP_CLI::error( $line ); } if ( $num_to_update > 0 ) { diff --git a/php/WP_CLI/UpgraderSkin.php b/php/WP_CLI/UpgraderSkin.php index 0fab75eb06..a0df91820e 100644 --- a/php/WP_CLI/UpgraderSkin.php +++ b/php/WP_CLI/UpgraderSkin.php @@ -41,9 +41,7 @@ function feedback( $string ) { $string = str_replace( '…', '...', strip_tags( $string ) ); - if ( empty( $this->upgrader->cli_output_format ) || ! in_array( $this->upgrader->cli_output_format, array( 'csv', 'json' ) ) ) { - \WP_CLI::line( $string ); - } + \WP_CLI::log( $string ); } } From a4cc0634cd3d95fa89c7a4a6a54122ab953a1284 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 5 Feb 2016 16:24:46 +0000 Subject: [PATCH 4050/4858] Update tests --- features/theme.feature | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 0665eb33f1..505062fc2a 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -253,53 +253,53 @@ Feature: Manage WordPress themes Scenario: When updating a theme --format should be the same when using --dry-run Given a WP install - When I run `wp theme update twentyfifteen --version=1.0` + When I run `wp theme install --force twentytwelve --version=1.0` Then STDOUT should not be empty - When I run `wp theme update twentyfifteen --format=summary --dry-run` + When I run `wp theme list --name=twentytwelve --field=update_version` + And save STDOUT as {UPDATE_VERSION} + + When I run `wp theme update twentytwelve --format=summary --dry-run` Then STDOUT should contain: """ Available theme updates: - Twenty Fifteen update from version 1.0 to version + Twenty Twelve update from version 1.0 to version {UPDATE_VERSION} """ - When I run `wp theme update twentyfifteen --version=1.0` - Then STDOUT should not be empty - - When I run `wp theme update twentyfifteen --format=json --dry-run` - Then STDOUT should contain: + When I run `wp theme update twentytwelve --format=json --dry-run` + Then STDOUT should be JSON containing: """ - [{"name":"twentyfifteen","status":"inactive","version":"1.0", + [{"name":"twentytwelve","status":"inactive","version":"1.0","update_version":"{UPDATE_VERSION}"}] """ - When I run `wp theme update twentyfifteen --version=1.0` - Then STDOUT should not be empty - - When I run `wp theme update twentyfifteen --format=csv --dry-run` + When I run `wp theme update twentytwelve --format=csv --dry-run` Then STDOUT should contain: """ name,status,version,update_version - twentyfifteen,inactive,1.0, + twentytwelve,inactive,1.0,{UPDATE_VERSION} """ Scenario: Check json and csv formats when updating a theme Given a WP install - When I run `wp theme update twentyfifteen --version=1.0` + When I run `wp theme install --force twentytwelve --version=1.0` Then STDOUT should not be empty - When I run `wp theme update twentyfifteen --format=json` + When I run `wp theme list --name=twentytwelve --field=update_version` + And save STDOUT as {UPDATE_VERSION} + + When I run `wp theme update twentytwelve --format=json` Then STDOUT should contain: """ - [{"name":"twentyfifteen","old_version":"1.0", + [{"name":"twentytwelve","old_version":"1.0","new_version":"{UPDATE_VERSION}","status":"Updated"}] """ - When I run `wp theme update twentyfifteen --version=1.0` + When I run `wp theme install --force twentytwelve --version=1.0` Then STDOUT should not be empty - When I run `wp theme update twentyfifteen --format=csv` + When I run `wp theme update twentytwelve --format=csv` Then STDOUT should contain: """ name,old_version,new_version,status - twentyfifteen,1.0, + twentytwelve,1.0,{UPDATE_VERSION},Updated """ From af4500c3577091c30bcf94378059b8907ac4d3eb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 5 Feb 2016 15:17:58 -0800 Subject: [PATCH 4051/4858] First pass at better documentation of public APIs --- php/class-wp-cli.php | 28 ++++++++++++++++++++++------ php/utils.php | 22 ++++++++++++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 1e360a40e4..e1fc3025ad 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -246,7 +246,10 @@ public static function add_command( $name, $callable, $args = array() ) { } /** - * Display a message in the CLI and end with a newline + * Display a message in the CLI and end with a newline. + * Ignores --quiet flag. To respect, use WP_CLI::log() + * + * @access public * * @param string $message */ @@ -257,6 +260,8 @@ public static function line( $message = '' ) { /** * Log an informational message. * + * @access public + * * @param string $message */ public static function log( $message ) { @@ -264,7 +269,9 @@ public static function log( $message ) { } /** - * Display a success in the CLI and end with a newline + * Display a success in the CLI and end with a newline. + * + * @access public * * @param string $message */ @@ -273,7 +280,10 @@ public static function success( $message ) { } /** - * Log debug information + * Log information when --debug flag is used. + * Helpful for optionally showing greater detail when needed. + * + * @access public * * @param string $message */ @@ -282,7 +292,9 @@ public static function debug( $message ) { } /** - * Display a warning in the CLI and end with a newline + * Display a warning in the CLI and end with a newline. + * + * @access public * * @param string $message */ @@ -291,7 +303,9 @@ public static function warning( $message ) { } /** - * Display an error in the CLI and end with a newline + * Display an error in the CLI and end with a newline. + * + * @access public * * @param string|WP_Error $message * @param bool $exit if true, the script will exit() @@ -309,7 +323,9 @@ public static function error( $message, $exit = true ) { } /** - * Display an error in the CLI and end with a newline + * Display an error in the CLI and end with a newline. + * + * @access public * * @param array $message each element from the array will be printed on its own line */ diff --git a/php/utils.php b/php/utils.php index 8cdc5dbe92..315eb31caa 100644 --- a/php/utils.php +++ b/php/utils.php @@ -241,6 +241,8 @@ function wp_version_compare( $since, $operator ) { /** * Output items in a table, JSON, CSV, ids, or the total count * + * @access public + * * @param string $format Format to use: 'table', 'json', 'csv', 'ids', 'count' * @param array $items Data to output * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list @@ -254,6 +256,8 @@ function format_items( $format, $items, $fields ) { /** * Write data as CSV to a given file. * + * @access public + * * @param resource $fd File descriptor * @param array $rows Array of rows to output * @param array $headers List of CSV columns (optional) @@ -542,7 +546,9 @@ function increment_version( $current_version, $new_version ) { } /** - * Compare two version strings to get the named semantic version + * Compare two version strings to get the named semantic version. + * + * @access public * * @param string $new_version * @param string $original_version @@ -569,18 +575,22 @@ function get_named_sem_ver( $new_version, $original_version ) { /** * Return the flag value or, if it's not set, the $default value. * - * @param array $args Arguments array. - * @param string $flag Flag to get the value. - * @param mixed $default Default value for the flag. Default: NULL + * @access public + * + * @param array $assoc_args Arguments array. + * @param string $flag Flag to get the value. + * @param mixed $default Default value for the flag. Default: NULL * @return mixed */ -function get_flag_value( $args, $flag, $default = null ) { - return isset( $args[ $flag ] ) ? $args[ $flag ] : $default; +function get_flag_value( $assoc_args, $flag, $default = null ) { + return isset( $assoc_args[ $flag ] ) ? $assoc_args[ $flag ] : $default; } /** * Get the temp directory, and let the user know if it isn't writable. * + * @access public + * * @return string */ function get_temp_dir() { From b88b38c20f6c089901a110582d0c2dc25200b2f2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 8 Feb 2016 06:43:56 -0800 Subject: [PATCH 4052/4858] Don't colorize `format=table` by default More often than not, strings are accidentally colorized because they contain colorization tokens. Developers can still colorize their strings in advance, and include the colorized strings in their table. --- composer.json | 2 +- composer.lock | 15 ++++++++------- php/WP_CLI/Formatter.php | 13 ++++++++++++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index a27fe7819d..33a8b6f9a6 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "0.11.0", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "mustangostang/spyc": "0.5.1", "composer/semver": "1.0.0", diff --git a/composer.lock b/composer.lock index 75bb6618c7..e0301b5343 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "be16eacf74b49e94af4974a9c8c2460e", - "content-hash": "5045f45078e9ea1cfb8087b858d377ac", + "hash": "78165aafa4140e764d4f1dc828752cce", + "content-hash": "7b6ae0fa1f96555e592ce2f48493a535", "packages": [ { "name": "composer/composer", @@ -1127,16 +1127,16 @@ }, { "name": "wp-cli/php-cli-tools", - "version": "0.11.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "d0564da283585c7289e18877ed2f9c35c1b67013" + "reference": "5311a4b99103c0505db015a334be4952654d6e21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/d0564da283585c7289e18877ed2f9c35c1b67013", - "reference": "d0564da283585c7289e18877ed2f9c35c1b67013", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/5311a4b99103c0505db015a334be4952654d6e21", + "reference": "5311a4b99103c0505db015a334be4952654d6e21", "shasum": "" }, "require": { @@ -1173,7 +1173,7 @@ "cli", "console" ], - "time": "2015-08-10 12:46:19" + "time": "2016-02-08 14:34:01" } ], "packages-dev": [ @@ -1666,6 +1666,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "wp-cli/php-cli-tools": 20, "composer/composer": 15 }, "prefer-stable": false, diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 0a3cd49781..87f81c8bb5 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -263,13 +263,24 @@ private function show_multiple_fields( $data, $format ) { private static function show_table( $items, $fields ) { $table = new \cli\Table(); + $enabled = \cli\Colors::shouldColorize(); + if ( $enabled ) { + \cli\Colors::disable( true ); + } + $table->setHeaders( $fields ); foreach ( $items as $item ) { $table->addRow( array_values( \WP_CLI\Utils\pick_fields( $item, $fields ) ) ); } - $table->display(); + foreach( $table->getDisplayLines() as $line ) { + \WP_CLI::line( $line ); + } + + if ( $enabled ) { + \cli\Colors::enable( true ); + } } /** From 8dc3798991f5c2850babc091ff072ce44f47b7a2 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Mon, 8 Feb 2016 21:11:34 +0100 Subject: [PATCH 4053/4858] Avoid loading WordPress in `wp core verify-checksums` --- php/commands/core.php | 51 +++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 541161cd5f..71b4d8dbee 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -742,38 +742,57 @@ private static function get_clean_basedomain() { * @when before_wp_load */ public function version( $args = array(), $assoc_args = array() ) { - $versions_path = ABSPATH . 'wp-includes/version.php'; - - if ( !is_readable( $versions_path ) ) { - WP_CLI::error( - "This does not seem to be a WordPress install.\n" . - "Pass --path=`path/to/wordpress` or run `wp core download`." ); - } - - include $versions_path; + $version = self::get_version(); // @codingStandardsIgnoreStart if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra' ) ) { - if ( preg_match( '/(\d)(\d+)-/', $tinymce_version, $match ) ) { + if ( preg_match( '/(\d)(\d+)-/', $version['tinymce'], $match ) ) { $human_readable_tiny_mce = $match[1] . '.' . $match[2]; } else { $human_readable_tiny_mce = ''; } echo \WP_CLI\Utils\mustache_render( 'versions.mustache', array( - 'wp-version' => $wp_version, - 'db-version' => $wp_db_version, + 'wp-version' => $version['wp'], + 'db-version' => $version['db'], 'mce-version' => ( $human_readable_tiny_mce ? - "$human_readable_tiny_mce ($tinymce_version)" - : $tinymce_version + "$human_readable_tiny_mce ({$version['tinymce']})" + : $version['tinymce'] ) ) ); } else { - WP_CLI::line( $wp_version ); + WP_CLI::line( $version['wp'] ); } // @codingStandardsIgnoreEnd } + /** + * Get version information from `wp-includes/version.php`. + * + * @return array { + * @type string $wp The WordPress version. + * @type int $db The WordPress DB revision. + * @type string $tinymce The TinyMCE version. + * } + */ + private static function get_version() { + $versions_path = ABSPATH . 'wp-includes/version.php'; + + if ( !is_readable( $versions_path ) ) { + WP_CLI::error( + "This does not seem to be a WordPress install.\n" . + "Pass --path=`path/to/wordpress` or run `wp core download`." ); + } + + include $versions_path; + + return array( + 'wp' => $wp_version, + 'db' => $wp_db_version, + 'tinymce' => $tinymce_version + ); + } + /** * Security copy of the core function with Requests - Gets the checksums for the given version of WordPress. * @@ -832,7 +851,7 @@ public function verify_checksums( $args, $assoc_args ) { } if ( empty( $wp_version ) ) { - WP_CLI::get_runner()->load_wordpress(); + $wp_version = self::get_version()['wp']; } $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); From 83470aa707ae1d849e3df713f76e63b3b3e50d6a Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Mon, 8 Feb 2016 21:44:50 +0100 Subject: [PATCH 4054/4858] =?UTF-8?q?Fix=20code=20syntax=20for=20prehistor?= =?UTF-8?q?ic=20PHP=20version=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/commands/core.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 71b4d8dbee..e624ed325d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -851,7 +851,8 @@ public function verify_checksums( $args, $assoc_args ) { } if ( empty( $wp_version ) ) { - $wp_version = self::get_version()['wp']; + $version = self::get_version(); + $wp_version = $version['wp']; } $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); From 0fe7d8653c66ece5a459a8fda481ad3ff4989192 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Mon, 8 Feb 2016 22:57:00 +0100 Subject: [PATCH 4055/4858] Automatically find locale from `wp-includes/version.php` --- php/commands/core.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index e624ed325d..855b6d064c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -789,7 +789,8 @@ private static function get_version() { return array( 'wp' => $wp_version, 'db' => $wp_db_version, - 'tinymce' => $tinymce_version + 'tinymce' => $tinymce_version, + 'local_package' => $wp_local_package ); } @@ -853,6 +854,7 @@ public function verify_checksums( $args, $assoc_args ) { if ( empty( $wp_version ) ) { $version = self::get_version(); $wp_version = $version['wp']; + $wp_local_package = $version['local_package']; } $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); From c173123624978eabab4fa22ee455375703b9a5b0 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Mon, 8 Feb 2016 22:57:32 +0100 Subject: [PATCH 4056/4858] Update test for `wp core verify-checksums` without `wp-config.php` --- features/core-verify-checksums.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index 055639275e..8f74cd336c 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -37,9 +37,9 @@ Feature: Validate checksums for WordPress install And I run `wp core download --version=4.3` When I try `wp core verify-checksums` - Then STDERR should contain: + Then STDOUT should be: """ - Error: wp-config.php not found. + Success: WordPress install verifies against checksums. """ When I run `wp core verify-checksums --version=4.3 --locale=en_US` From c8a36a1e62467c4e8bc3fd3c89934f100cfa18b4 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 00:39:16 +0100 Subject: [PATCH 4057/4858] Change `get_version` to `get_wp_details` and fix default value for `--locale` --- php/commands/core.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 855b6d064c..b106d6061d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -742,7 +742,7 @@ private static function get_clean_basedomain() { * @when before_wp_load */ public function version( $args = array(), $assoc_args = array() ) { - $version = self::get_version(); + $version = self::get_wp_details(); // @codingStandardsIgnoreStart if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra' ) ) { @@ -775,7 +775,7 @@ public function version( $args = array(), $assoc_args = array() ) { * @type string $tinymce The TinyMCE version. * } */ - private static function get_version() { + private static function get_wp_details() { $versions_path = ABSPATH . 'wp-includes/version.php'; if ( !is_readable( $versions_path ) ) { @@ -852,9 +852,12 @@ public function verify_checksums( $args, $assoc_args ) { } if ( empty( $wp_version ) ) { - $version = self::get_version(); - $wp_version = $version['wp']; - $wp_local_package = $version['local_package']; + $details = self::get_wp_details(); + $wp_version = $details['wp']; + + if ( empty( $wp_local_package ) ) { + $wp_local_package = $details['local_package']; + } } $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); From 68d8cfa9caa19b0ab39a22ef707d4482b48a0cab Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 00:39:24 +0100 Subject: [PATCH 4058/4858] Fix documentation --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index b106d6061d..1ea089d561 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -773,6 +773,7 @@ public function version( $args = array(), $assoc_args = array() ) { * @type string $wp The WordPress version. * @type int $db The WordPress DB revision. * @type string $tinymce The TinyMCE version. + * @type string $local_package The TinyMCE version. * } */ private static function get_wp_details() { From 4c813a3625bdfc7df226f17ae434b80c4226f9f1 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 00:40:11 +0100 Subject: [PATCH 4059/4858] Parse `wp-includes/version.php` instead of including it --- php/commands/core.php | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 1ea089d561..08ec386fc8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -785,14 +785,42 @@ private static function get_wp_details() { "Pass --path=`path/to/wordpress` or run `wp core download`." ); } - include $versions_path; + $version_content = file_get_contents($versions_path, null, null, 6, 2048); - return array( - 'wp' => $wp_version, - 'db' => $wp_db_version, - 'tinymce' => $tinymce_version, - 'local_package' => $wp_local_package + $vars = array( + 'wp' => 'wp_version', + 'db' => 'wp_db_version', + 'tinymce' => 'tinymce_version', + 'local_package' => 'wp_local_package' ); + + $result = array(); + + foreach($vars as $key => $var) { + $result[$key] = self::find_var($var, $version_content); + } + + return $result; + } + + private static function find_var($key, $content) { + $start = strpos ($content, '$' . $key . ' = '); + + if( ! $start ) { + return ''; + } + + $start = $start + strlen($key) + 3; + $end = strpos($content, "\n", $start); + + $value = substr($content, $start, $end - $start); + $value = rtrim($value, ";"); + + if ($value[0] = "'" ) { + return trim($value, "'"); + } else { + return intval($value); + } } /** From 2d40fd6a375a6987c2fa0da1524e2b54d99c4e75 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 00:43:32 +0100 Subject: [PATCH 4060/4858] Fix test --- features/core-verify-checksums.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index 8f74cd336c..a27d2c354d 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -36,7 +36,7 @@ Feature: Validate checksums for WordPress install Given an empty directory And I run `wp core download --version=4.3` - When I try `wp core verify-checksums` + When I run `wp core verify-checksums` Then STDOUT should be: """ Success: WordPress install verifies against checksums. From 7daa225095f70ddce19973fabacf005c6812bbc7 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 00:46:35 +0100 Subject: [PATCH 4061/4858] Fix coding style --- php/commands/core.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 08ec386fc8..388c0aaf29 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -785,7 +785,7 @@ private static function get_wp_details() { "Pass --path=`path/to/wordpress` or run `wp core download`." ); } - $version_content = file_get_contents($versions_path, null, null, 6, 2048); + $version_content = file_get_contents( $versions_path, null, null, 6, 2048 ); $vars = array( 'wp' => 'wp_version', @@ -796,30 +796,30 @@ private static function get_wp_details() { $result = array(); - foreach($vars as $key => $var) { - $result[$key] = self::find_var($var, $version_content); + foreach( $vars as $key => $var ) { + $result[$key] = self::find_var( $var, $version_content ); } return $result; } - private static function find_var($key, $content) { - $start = strpos ($content, '$' . $key . ' = '); + private static function find_var( $key, $content ) { + $start = strpos( $content, '$' . $key . ' = ' ); if( ! $start ) { return ''; } - $start = $start + strlen($key) + 3; - $end = strpos($content, "\n", $start); + $start = $start + strlen( $key ) + 3; + $end = strpos( $content, "\n", $start ); - $value = substr($content, $start, $end - $start); - $value = rtrim($value, ";"); + $value = substr( $content, $start, $end - $start ); + $value = rtrim( $value, ";" ); - if ($value[0] = "'" ) { - return trim($value, "'"); + if ( $value[0] = "'" ) { + return trim( $value, "'" ); } else { - return intval($value); + return intval( $value ); } } From 12ae1be84e15c01013ac576b95e341e94f6a0cc3 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 01:27:32 +0100 Subject: [PATCH 4062/4858] Check if `$wp_local_package` is empty instead of set --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 388c0aaf29..fe0ab0d2d9 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -889,7 +889,7 @@ public function verify_checksums( $args, $assoc_args ) { } } - $checksums = self::get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' ); + $checksums = self::get_core_checksums( $wp_version, ! empty( $wp_local_package ) ? $wp_local_package : 'en_US' ); if ( ! is_array( $checksums ) ) { WP_CLI::error( "Couldn't get checksums from WordPress.org." ); From 16622647bb7bac4268fe375c3076937b0a572f47 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Feb 2016 05:05:05 -0800 Subject: [PATCH 4063/4858] Add debug output for package loading --- php/WP_CLI/Runner.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 2055cee955..3adde5022d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -616,7 +616,10 @@ public function start() { } if ( file_exists( $package_autoload ) ) { + WP_CLI::debug( 'Loading packages from: ' . $package_autoload ); require_once $package_autoload; + } else { + WP_CLI::debug( 'No package autoload found to load.' ); } if ( isset( $this->config['require'] ) ) { From e5c45d478dbdc144d48973b3115ab0c1a0361a71 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Feb 2016 05:26:12 -0800 Subject: [PATCH 4064/4858] Verify md5 hash when `wp core download` To permit offline use of the download cache, verification only happens when downloading a new copy of WordPress. --- features/core-download.feature | 10 ++++++++++ php/commands/core.php | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/features/core-download.feature b/features/core-download.feature index f35c49f561..c5f7f85f04 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -42,6 +42,16 @@ Feature: Download WordPress Error: Release not found. """ + Scenario: Verify release hash when downloading new version + Given an empty directory + + When I run `wp core download --version=4.4.1` + Then STDOUT should contain: + """ + md5 hash verified: 1907d1dbdac7a009d89224a516496b8d + Success: WordPress downloaded. + """ + Scenario: Core download to a directory specified by `--path` in custom command Given a WP install And a download-command.php file: diff --git a/php/commands/core.php b/php/commands/core.php index 541161cd5f..d8024f3b1f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -142,6 +142,18 @@ public function download( $args, $assoc_args ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})" ); } + $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); + if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { + WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})" ); + } + + $md5_file = md5_file( $temp ); + if ( $md5_file === $md5_response->body ) { + WP_CLI::log( 'md5 hash verified: ' . $md5_file ); + } else { + WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})" ); + } + try { self::_extract( $temp, $download_dir ); } catch ( Exception $e ) { From 28091296c8d3b5a73423ef7a34632e285c2533e5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Feb 2016 06:15:53 -0800 Subject: [PATCH 4065/4858] Strict comparison is more precise --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index d8024f3b1f..92f20e4608 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -138,12 +138,12 @@ public function download( $args, $assoc_args ) { $response = Utils\http_request( 'GET', $download_url, null, $headers, $options ); if ( 404 == $response->status_code ) { WP_CLI::error( "Release not found. Double-check locale or version." ); - } else if ( 20 != substr( $response->status_code, 0, 2 ) ) { + } else if ( 20 !== substr( $response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})" ); } $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); - if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { + if ( 20 !== substr( $md5_response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})" ); } From cd6580b05d38c38156388e1770ea7bab7acc837d Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 17:18:49 +0100 Subject: [PATCH 4066/4858] Clean, document and reorder `verify-checksums` methods --- php/commands/core.php | 202 ++++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 98 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index fe0ab0d2d9..50812cc2f9 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -742,118 +742,30 @@ private static function get_clean_basedomain() { * @when before_wp_load */ public function version( $args = array(), $assoc_args = array() ) { - $version = self::get_wp_details(); + $details = self::get_wp_details(); // @codingStandardsIgnoreStart if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'extra' ) ) { - if ( preg_match( '/(\d)(\d+)-/', $version['tinymce'], $match ) ) { + if ( preg_match( '/(\d)(\d+)-/', $details['tinymce_version'], $match ) ) { $human_readable_tiny_mce = $match[1] . '.' . $match[2]; } else { $human_readable_tiny_mce = ''; } echo \WP_CLI\Utils\mustache_render( 'versions.mustache', array( - 'wp-version' => $version['wp'], - 'db-version' => $version['db'], + 'wp-version' => $details['wp_version'], + 'db-version' => $details['wp_db_version'], 'mce-version' => ( $human_readable_tiny_mce ? - "$human_readable_tiny_mce ({$version['tinymce']})" - : $version['tinymce'] + "$human_readable_tiny_mce ({$details['tinymce_version']})" + : $details['tinymce_version'] ) ) ); } else { - WP_CLI::line( $version['wp'] ); + WP_CLI::line( $details['wp_version'] ); } // @codingStandardsIgnoreEnd } - /** - * Get version information from `wp-includes/version.php`. - * - * @return array { - * @type string $wp The WordPress version. - * @type int $db The WordPress DB revision. - * @type string $tinymce The TinyMCE version. - * @type string $local_package The TinyMCE version. - * } - */ - private static function get_wp_details() { - $versions_path = ABSPATH . 'wp-includes/version.php'; - - if ( !is_readable( $versions_path ) ) { - WP_CLI::error( - "This does not seem to be a WordPress install.\n" . - "Pass --path=`path/to/wordpress` or run `wp core download`." ); - } - - $version_content = file_get_contents( $versions_path, null, null, 6, 2048 ); - - $vars = array( - 'wp' => 'wp_version', - 'db' => 'wp_db_version', - 'tinymce' => 'tinymce_version', - 'local_package' => 'wp_local_package' - ); - - $result = array(); - - foreach( $vars as $key => $var ) { - $result[$key] = self::find_var( $var, $version_content ); - } - - return $result; - } - - private static function find_var( $key, $content ) { - $start = strpos( $content, '$' . $key . ' = ' ); - - if( ! $start ) { - return ''; - } - - $start = $start + strlen( $key ) + 3; - $end = strpos( $content, "\n", $start ); - - $value = substr( $content, $start, $end - $start ); - $value = rtrim( $value, ";" ); - - if ( $value[0] = "'" ) { - return trim( $value, "'" ); - } else { - return intval( $value ); - } - } - - /** - * Security copy of the core function with Requests - Gets the checksums for the given version of WordPress. - * - * @param string $version Version string to query. - * @param string $locale Locale to query. - * @return bool|array False on failure. An array of checksums on success. - */ - private static function get_core_checksums( $version, $locale ) { - $url = 'https://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); - - $options = array( - 'timeout' => 30 - ); - - $headers = array( - 'Accept' => 'application/json' - ); - $response = Utils\http_request( 'GET', $url, null, $headers, $options ); - - if ( ! $response->success || 200 != $response->status_code ) - return false; - - $body = trim( $response->body ); - $body = json_decode( $body, true ); - - if ( ! is_array( $body ) || ! isset( $body['checksums'] ) || ! is_array( $body['checksums'] ) ) - return false; - - return $body['checksums']; - } - /** * Verify WordPress files against WordPress.org's checksums. * @@ -882,14 +794,15 @@ public function verify_checksums( $args, $assoc_args ) { if ( empty( $wp_version ) ) { $details = self::get_wp_details(); - $wp_version = $details['wp']; + $wp_version = $details['wp_version']; if ( empty( $wp_local_package ) ) { - $wp_local_package = $details['local_package']; + $wp_local_package = $details['wp_local_package']; } } - $checksums = self::get_core_checksums( $wp_version, ! empty( $wp_local_package ) ? $wp_local_package : 'en_US' ); + $checksums = self::get_core_checksums( $wp_version, + ! empty( $wp_local_package ) ? $wp_local_package : 'en_US' ); if ( ! is_array( $checksums ) ) { WP_CLI::error( "Couldn't get checksums from WordPress.org." ); @@ -922,6 +835,99 @@ public function verify_checksums( $args, $assoc_args ) { } } + /** + * Get version information from `wp-includes/version.php`. + * + * @return array { + * @type string $wp_version The WordPress version. + * @type int $wp_db_version The WordPress DB revision. + * @type string $tinymce_version The TinyMCE version. + * @type string $wp_local_package The TinyMCE version. + * } + */ + private static function get_wp_details() { + $versions_path = ABSPATH . 'wp-includes/version.php'; + + if ( ! is_readable( $versions_path ) ) { + WP_CLI::error( + "This does not seem to be a WordPress install.\n" . + "Pass --path=`path/to/wordpress` or run `wp core download`." ); + } + + $version_content = file_get_contents( $versions_path, null, null, 6, 2048 ); + + $vars = [ 'wp_version', 'wp_db_version', 'tinymce_version', 'wp_local_package' ]; + $result = [ ]; + + foreach ( $vars as $var_name ) { + $result[ $var_name ] = self::find_var( $var_name, $version_content ); + } + + return $result; + } + + /** + * Search for the value assigned to variable `$var_name` in PHP code `$code`. + * + * This is equivalent to matching the `\$VAR_NAME = ([^;]+)` regular expression and returning + * the first match either as a `string` or as an `integer` (depending if it's surrounded by + * quotes or not). + * + * @param string $var_name Variable name to search for. + * @param string $code PHP code to search in. + * + * @return int|string|null + */ + private static function find_var( $var_name, $code ) { + $start = strpos( $code, '$' . $var_name . ' = ' ); + + if ( ! $start ) { + return null; + } + + $start = $start + strlen( $var_name ) + 3; + $end = strpos( $code, ";", $start ); + + $value = substr( $code, $start, $end - $start ); + + if ( $value[0] = "'" ) { + return trim( $value, "'" ); + } else { + return intval( $value ); + } + } + + /** + * Security copy of the core function with Requests - Gets the checksums for the given version of WordPress. + * + * @param string $version Version string to query. + * @param string $locale Locale to query. + * @return bool|array False on failure. An array of checksums on success. + */ + private static function get_core_checksums( $version, $locale ) { + $url = 'https://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' ); + + $options = array( + 'timeout' => 30 + ); + + $headers = array( + 'Accept' => 'application/json' + ); + $response = Utils\http_request( 'GET', $url, null, $headers, $options ); + + if ( ! $response->success || 200 != $response->status_code ) + return false; + + $body = trim( $response->body ); + $body = json_decode( $body, true ); + + if ( ! is_array( $body ) || ! isset( $body['checksums'] ) || ! is_array( $body['checksums'] ) ) + return false; + + return $body['checksums']; + } + /** * Update WordPress. * From 87b5980576d8aabe66302b16b802ff5996b6829c Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 17:19:16 +0100 Subject: [PATCH 4067/4858] Add feature for `wp core version` --- features/core-version.feature | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 features/core-version.feature diff --git a/features/core-version.feature b/features/core-version.feature new file mode 100644 index 0000000000..978c2960ed --- /dev/null +++ b/features/core-version.feature @@ -0,0 +1,19 @@ +Feature: Find version for WordPress install + + Scenario: Verify core version + Given a WP install + And I run `wp core download --version=4.4.2 --force` + + When I run `wp core version` + Then STDOUT should be: + """ + 4.4.2 + """ + + When I run `wp core version --extra` + Then STDOUT should be: + """ + WordPress version: 4.4.2 + Database revision: 35700 + TinyMCE version: 4.208 (4208-20151113) + """ \ No newline at end of file From 34ca6b8e7ad54fa7646aa07d188700ba76fe8245 Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 17:53:22 +0100 Subject: [PATCH 4068/4858] Correct array syntax for PHP 5.3 --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 50812cc2f9..de13e93951 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -856,8 +856,8 @@ private static function get_wp_details() { $version_content = file_get_contents( $versions_path, null, null, 6, 2048 ); - $vars = [ 'wp_version', 'wp_db_version', 'tinymce_version', 'wp_local_package' ]; - $result = [ ]; + $vars = array( 'wp_version', 'wp_db_version', 'tinymce_version', 'wp_local_package' ); + $result = array(); foreach ( $vars as $var_name ) { $result[ $var_name ] = self::find_var( $var_name, $version_content ); From 0566eb42cd1daf2b1484e3aaeb76481a2a5d9cae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Feb 2016 08:57:04 -0800 Subject: [PATCH 4069/4858] Revert "Strict comparison is more precise" This reverts commit 28091296c8d3b5a73423ef7a34632e285c2533e5. --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 92f20e4608..d8024f3b1f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -138,12 +138,12 @@ public function download( $args, $assoc_args ) { $response = Utils\http_request( 'GET', $download_url, null, $headers, $options ); if ( 404 == $response->status_code ) { WP_CLI::error( "Release not found. Double-check locale or version." ); - } else if ( 20 !== substr( $response->status_code, 0, 2 ) ) { + } else if ( 20 != substr( $response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})" ); } $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); - if ( 20 !== substr( $md5_response->status_code, 0, 2 ) ) { + if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})" ); } From 7af8e2e44ca44abb8a02accd955e10fa52f2310e Mon Sep 17 00:00:00 2001 From: mbovel <matthieu@bovel.net> Date: Tue, 9 Feb 2016 18:18:59 +0100 Subject: [PATCH 4070/4858] Add newline --- features/core-version.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core-version.feature b/features/core-version.feature index 978c2960ed..3904c5b23b 100644 --- a/features/core-version.feature +++ b/features/core-version.feature @@ -16,4 +16,4 @@ Feature: Find version for WordPress install WordPress version: 4.4.2 Database revision: 35700 TinyMCE version: 4.208 (4208-20151113) - """ \ No newline at end of file + """ From c39d284dcb50eab58190876d1c072aa2752475af Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Feb 2016 10:14:37 -0800 Subject: [PATCH 4071/4858] Default title for `wp media import` images shouldn't include extension This better mirrors core's behavior. --- features/media-import.feature | 2 +- php/commands/media.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/media-import.feature b/features/media-import.feature index 81a05db281..a33e787db0 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -71,7 +71,7 @@ Feature: Manage WordPress attachments When I run `wp post get {ATTACHMENT_ID} --field=title` Then STDOUT should be: """ - large-image.jpg + large-image """ Scenario: Import a file and persist its original metadata diff --git a/php/commands/media.php b/php/commands/media.php index 15cf3a80d1..fd77715e4c 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -182,7 +182,7 @@ function import( $args, $assoc_args = array() ) { } if ( empty( $post_array['post_title'] ) ) { - $post_array['post_title'] = $file_array['name']; + $post_array['post_title'] = preg_replace( '/\.[^.]+$/', '', basename( $file ) ); } // Deletes the temporary file. From 9e0ffbc901f90d0011e65852ef60de0c3360661b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Feb 2016 05:15:02 -0800 Subject: [PATCH 4072/4858] Failing test case for #2468 --- features/core-update.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/core-update.feature b/features/core-update.feature index ef52aa8ea2..53db29ba2c 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -193,3 +193,19 @@ Feature: Update WordPress core Then STDOUT should not be empty When I run `wp post create --post_title='Test post' --porcelain` Then STDOUT should be a number + + @less-than-php-7 + Scenario: Minor update on an unlocalized WordPress release + Given a WP install + + When I run `wp core download --version=4.0 --locale=es_ES --force` + Then STDOUT should contain: + """ + Success: WordPress downloaded. + """ + + When I run `wp core update --minor` + Then STDOUT should contain: + """ + Success: WordPress updated successfully + """ From ef24a31153aff410e552fd62e0e91e9c3ab40638 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Feb 2016 05:58:38 -0800 Subject: [PATCH 4073/4858] Use WP.org's download offer for minor updates Sometimes localized versions of WordPress don't have a minor release build, and we need to use the en_US partial instead. Also, when performing `wp core check-update`, don't list release files that don't exist. --- features/core-check-update.feature | 19 ++++++++++++++++ features/core-update.feature | 8 ++++++- php/commands/core.php | 36 ++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 10a6508845..5fb91fe9ef 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -40,3 +40,22 @@ Feature: Check for more recent versions """ 1 """ + + @less-than-php-7 + Scenario: No minor updates for an unlocalized WordPress release + Given a WP install + + When I run `wp core download --version=4.0 --locale=es_ES --force` + Then STDOUT should contain: + """ + Success: WordPress downloaded. + """ + + When I run `wp core check-update --minor` + Then STDOUT should be a table containing rows: + | version | update_type | package_url | + | 4.0.1 | minor | https://es.wordpress.org/wordpress-4.0.1-es_ES.zip | + And STDERR should contain: + """ + Warning: No release found for 4.0.10 (es_ES) + """ diff --git a/features/core-update.feature b/features/core-update.feature index 53db29ba2c..93eec5bf93 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -197,6 +197,7 @@ Feature: Update WordPress core @less-than-php-7 Scenario: Minor update on an unlocalized WordPress release Given a WP install + And an empty cache When I run `wp core download --version=4.0 --locale=es_ES --force` Then STDOUT should contain: @@ -207,5 +208,10 @@ Feature: Update WordPress core When I run `wp core update --minor` Then STDOUT should contain: """ - Success: WordPress updated successfully + Updating to version 4.0.10 (en_US)... + Descargando paquete de instalación desde https://downloads.wordpress.org/release/wordpress-4.0.10-partial-0.zip + """ + And STDOUT should contain: + """ + Success: WordPress updated successfully. """ diff --git a/php/commands/core.php b/php/commands/core.php index 4ec4592de4..1424d2c3aa 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -976,16 +976,6 @@ function update( $args, $assoc_args ) { $update = $from_api = null; $upgrader = 'WP_CLI\\CoreUpgrader'; - if ( empty( $args[0] ) && empty( $assoc_args['version'] ) && \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) ) { - $updates = $this->get_updates( array( 'minor' => true ) ); - if ( ! empty( $updates ) ) { - $assoc_args['version'] = $updates[0]['version']; - } else { - WP_CLI::success( 'WordPress is at the latest minor release.' ); - return; - } - } - if ( ! empty( $args[0] ) ) { $upgrader = 'WP_CLI\\NonDestructiveCoreUpgrader'; @@ -1010,8 +1000,23 @@ function update( $args, $assoc_args ) { wp_version_check(); $from_api = get_site_transient( 'update_core' ); - if ( ! empty( $from_api->updates ) ) { - list( $update ) = $from_api->updates; + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'minor' ) ) { + foreach( $from_api->updates as $offer ) { + $sem_ver = Utils\get_named_sem_ver( $offer->version, $wp_version ); + if ( ! $sem_ver || 'patch' !== $sem_ver ) { + continue; + } + $update = $offer; + break; + } + if ( empty( $update ) ) { + WP_CLI::success( 'WordPress is at the latest minor release.' ); + return; + } + } else { + if ( ! empty( $from_api->updates ) ) { + list( $update ) = $from_api->updates; + } } } else if ( \WP_CLI\Utils\wp_version_compare( $assoc_args['version'], '<' ) @@ -1224,6 +1229,13 @@ private function get_updates( $assoc_args ) { continue; } + $download_url = $this->get_download_url( $release_version, $locale ); + $response = Utils\http_request( 'HEAD', $download_url ); + if ( 20 != substr( $response->status_code, 0, 2 ) ) { + WP_CLI::warning( "No release found for {$release_version} ({$locale})" ); + continue; + } + $updates[ $update_type ] = array( 'version' => $release_version, 'update_type' => $update_type, From a8ec806d42a0006d0264e26acf3c2767c9e6dc51 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Feb 2016 06:13:40 -0800 Subject: [PATCH 4074/4858] Better idea: use core's versions API to check for updates We should've done this in the very beginning. Now lists the partial package for update when it's available --- features/core-check-update.feature | 18 +++++------- php/commands/core.php | 44 ++++++------------------------ 2 files changed, 16 insertions(+), 46 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 5fb91fe9ef..600beba472 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -9,9 +9,9 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 4.4.2 | major | https://wordpress.org/wordpress-4.4.2.zip | - | 3.8.13 | minor | https://wordpress.org/wordpress-3.8.13.zip | + | version | update_type | package_url | + | 4.4.2 | major | https://downloads.wordpress.org/release/wordpress-4.4.2.zip | + | 3.8.13 | minor | https://downloads.wordpress.org/release/wordpress-3.8.13-partial-0.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -21,8 +21,8 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: - | version | update_type | package_url | - | 4.4.2 | major | https://wordpress.org/wordpress-4.4.2.zip | + | version | update_type | package_url | + | 4.4.2 | major | https://downloads.wordpress.org/release/wordpress-4.4.2.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -33,7 +33,7 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.13 | minor | https://wordpress.org/wordpress-3.8.13.zip | + | 3.8.13 | minor | https://downloads.wordpress.org/release/wordpress-3.8.13-partial-0.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: @@ -54,8 +54,4 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0.1 | minor | https://es.wordpress.org/wordpress-4.0.1-es_ES.zip | - And STDERR should contain: - """ - Warning: No release found for 4.0.10 (es_ES) - """ + | 4.0.10 | minor | https://downloads.wordpress.org/release/wordpress-4.0.10-partial-0.zip | diff --git a/php/commands/core.php b/php/commands/core.php index 1424d2c3aa..6fc55c18e4 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1180,40 +1180,21 @@ private function get_download_url($version, $locale = 'en_US', $file_type = 'zip * Returns update information */ private function get_updates( $assoc_args ) { - global $wp_version; - $versions_path = ABSPATH . 'wp-includes/version.php'; - include $versions_path; - - $url = 'https://api.wordpress.org/core/stable-check/1.0/'; - - $options = array( - 'timeout' => 30 - ); - $headers = array( - 'Accept' => 'application/json' - ); - $response = Utils\http_request( 'GET', $url, $headers, $options ); - - if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( "Failed to get latest version list." ); + wp_version_check(); + $from_api = get_site_transient( 'update_core' ); + if ( ! $from_api ) { + return array(); } - $release_data = json_decode( $response->body ); - $release_versions = array_keys( (array) $release_data ); - usort( $release_versions, function( $a, $b ){ - return 1 === version_compare( $a, $b ); - }); - - $locale = get_locale(); $compare_version = str_replace( '-src', '', $GLOBALS['wp_version'] ); $updates = array( 'major' => false, 'minor' => false, ); - foreach ( $release_versions as $release_version ) { + foreach ( $from_api->updates as $offer ) { - $update_type = Utils\get_named_sem_ver( $release_version, $compare_version ); + $update_type = Utils\get_named_sem_ver( $offer->version, $compare_version ); if ( ! $update_type ) { continue; } @@ -1225,21 +1206,14 @@ private function get_updates( $assoc_args ) { $update_type = 'minor'; } - if ( ! empty( $updates[ $update_type ] ) && ! Comparator::greaterThan( $release_version, $updates[ $update_type ]['version'] ) ) { - continue; - } - - $download_url = $this->get_download_url( $release_version, $locale ); - $response = Utils\http_request( 'HEAD', $download_url ); - if ( 20 != substr( $response->status_code, 0, 2 ) ) { - WP_CLI::warning( "No release found for {$release_version} ({$locale})" ); + if ( ! empty( $updates[ $update_type ] ) && ! Comparator::greaterThan( $offer->version, $updates[ $update_type ]['version'] ) ) { continue; } $updates[ $update_type ] = array( - 'version' => $release_version, + 'version' => $offer->version, 'update_type' => $update_type, - 'package_url' => $this->get_download_url( $release_version, $locale ) + 'package_url' => ! empty( $offer->packages->partial ) ? $offer->packages->partial : $offer->packages->full, ); } From 19b35f9c6597af251fb115a06e577aaeb83ee0c8 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 12 Feb 2016 09:05:13 -0200 Subject: [PATCH 4075/4858] Add basic tests for `wp core download` --- features/core.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/features/core.feature b/features/core.feature index 13331c1c5d..0bc830cd04 100644 --- a/features/core.feature +++ b/features/core.feature @@ -240,3 +240,23 @@ Feature: Manage WordPress installation """ Hello world! """ + + Scenario: Download WordPress + Given an empty directory + + When I run `wp core download` + Then STDOUT should contain: + """ + Success: WordPress downloaded. + """ + And the wp-settings.php file should exist + + Scenario: Don't download WordPress when files are already present + Given an empty directory + And WP files + + When I try `wp core download` + Then STDERR should be: + """ + Error: WordPress files seem to already be present here. + """ From 0f113a97d9159422590951437b41781eb0ed2d23 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 12 Feb 2016 09:08:54 -0200 Subject: [PATCH 4076/4858] Check for permission before downloading WordPress when running `wp core download` --- php/commands/core.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4ec4592de4..4f815d392a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -86,6 +86,10 @@ public function download( $args, $assoc_args ) { WP_CLI::launch( Utils\esc_cmd( $mkdir, $download_dir ) ); } + if ( ! is_writable( $download_dir ) ) { + WP_CLI::error( sprintf( "%s is not writable by current user", $download_dir ) ); + } + $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', 'en_US' ); if ( isset( $assoc_args['version'] ) ) { From 6017a94f4ac668cbe242ae0712d10d4a56e55f80 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Fri, 12 Feb 2016 09:15:54 -0200 Subject: [PATCH 4077/4858] Check for permission before creating directory when running `wp core download` --- php/commands/core.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 4f815d392a..ac61a2d281 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -80,7 +80,11 @@ public function download( $args, $assoc_args ) { if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && $wordpress_present ) WP_CLI::error( 'WordPress files seem to already be present here.' ); - if ( !is_dir( $download_dir ) ) { + if ( ! is_dir( $download_dir ) ) { + if ( ! is_writable( dirname( $download_dir ) ) ) { + WP_CLI::error( sprintf( "Insufficient permission to create directory %s", $download_dir ) ); + } + WP_CLI::log( sprintf( 'Creating directory %s', $download_dir ) ); $mkdir = \WP_CLI\Utils\is_windows() ? 'mkdir %s' : 'mkdir -p %s'; WP_CLI::launch( Utils\esc_cmd( $mkdir, $download_dir ) ); From 02e31d3009260d8d85e9da788c6d340aea02c9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 13 Feb 2016 01:07:06 +0100 Subject: [PATCH 4078/4858] Make PHP look leaner on GitHub --- .editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.editorconfig b/.editorconfig index 71f819ca14..ddb90c301f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,7 @@ end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = tab +indent_size = 4 [*.json,*.yml,*.feature] indent_style = space From b442a98ae7f9f7dadf3e2b549a5136bb721571fe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Feb 2016 04:40:44 -0800 Subject: [PATCH 4079/4858] Require WP 4.0 or greater for this step --- features/core-update.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core-update.feature b/features/core-update.feature index 93eec5bf93..2cb55be5f7 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -194,7 +194,7 @@ Feature: Update WordPress core When I run `wp post create --post_title='Test post' --porcelain` Then STDOUT should be a number - @less-than-php-7 + @less-than-php-7 @require-wp-4.0 Scenario: Minor update on an unlocalized WordPress release Given a WP install And an empty cache From c2b562295478b65da9e4380467ba9e44066b5046 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Feb 2016 08:47:21 -0800 Subject: [PATCH 4080/4858] Set default `indent_size=4` when scaffolding `.editorconfig` This makes indentation more readable in editors. --- templates/.editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/.editorconfig b/templates/.editorconfig index e1cc194ebc..79207a40cb 100644 --- a/templates/.editorconfig +++ b/templates/.editorconfig @@ -12,6 +12,7 @@ end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = tab +indent_size = 4 [{.jshintrc,*.json,*.yml}] indent_style = space From 62ed490f3d070df285ed32ecc83305c0edb44a47 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Feb 2016 08:49:01 -0800 Subject: [PATCH 4081/4858] Note: mu-plugins are still loaded with `--skip-plugins` flag --- php/config-spec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index 3fda4edff9..cbaa958fd1 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -31,10 +31,10 @@ 'skip-plugins' => array( 'runtime' => '[=<plugin>]', 'file' => '<list>', - 'desc' => 'Skip loading all or some plugins.', + 'desc' => 'Skip loading all or some plugins. Note: mu-plugins are still loaded.', 'default' => '', ), - + 'skip-themes' => array( 'runtime' => '[=<theme>]', 'file' => '<list>', From 30354ca5e6955e8d917793a594c3d2b5e58d004a Mon Sep 17 00:00:00 2001 From: Mark Jaquith <mark.github@txfx.net> Date: Thu, 18 Feb 2016 09:29:55 -0500 Subject: [PATCH 4082/4858] Avoid PHP Notice about undefined index Was getting this: > Notice: Undefined index: name in `/Users/mark/.composer/vendor/wp-cli/wp-cli/php/export/class-wp-export-query.php` on line `176` --- php/export/class-wp-export-query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index 8cbbb89d13..e228fbfcd4 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -173,7 +173,7 @@ private function post_type_where() { } // Multiple post types - if ( is_array( $post_types_filters['name'] ) ) { + if ( isset( $post_types_filters['name'] ) && is_array( $post_types_filters['name'] ) ) { $post_types = array(); foreach ( $post_types_filters['name'] as $post_type ) { if ( post_type_exists( $post_type ) ) { From e00ce0f69352e03ea2cbbe87cf19700378bb7fdd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 18 Feb 2016 09:31:17 -0800 Subject: [PATCH 4083/4858] Add compatibility with WP 4.5 by loading `WP_Metadata_Lazyloader` Introduced in https://core.trac.wordpress.org/changeset/36566/ --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 000db74a5f..975c59f599 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -160,6 +160,7 @@ Utils\maybe_require( '4.0', ABSPATH . WPINC . '/session.php' ); require( ABSPATH . WPINC . '/meta.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-meta-query.php' ); +Utils\maybe_require( '4.5-alpha-35776', ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php' ); require( ABSPATH . WPINC . '/general-template.php' ); require( ABSPATH . WPINC . '/link-template.php' ); require( ABSPATH . WPINC . '/author-template.php' ); From ec889e62ebbfbaadf196fa25bb4290994ed6f7ff Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 18 Feb 2016 12:21:54 -0800 Subject: [PATCH 4084/4858] Annotate public internal APIs with categories --- php/class-wp-cli.php | 62 +++++++++++++++++++++++++++++++++++--------- php/utils.php | 6 +++-- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index e1fc3025ad..d87cb5e2e1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -247,11 +247,13 @@ public static function add_command( $name, $callable, $args = array() ) { /** * Display a message in the CLI and end with a newline. - * Ignores --quiet flag. To respect, use WP_CLI::log() + * Ignores `--quiet` flag. To respect, use `WP_CLI::log()` * * @access public + * @category Output * - * @param string $message + * @param string $message Message to display to the end user. + * @return null */ public static function line( $message = '' ) { echo $message . "\n"; @@ -261,6 +263,7 @@ public static function line( $message = '' ) { * Log an informational message. * * @access public + * @category Output * * @param string $message */ @@ -272,6 +275,7 @@ public static function log( $message ) { * Display a success in the CLI and end with a newline. * * @access public + * @category Output * * @param string $message */ @@ -280,10 +284,13 @@ public static function success( $message ) { } /** - * Log information when --debug flag is used. - * Helpful for optionally showing greater detail when needed. + * Display debug message prefixed with "Debug: " when `--debug` is used. + * + * Helpful for optionally showing greater detail when needed. Debug message + * is written to STDERR, and includes script execution time. * * @access public + * @category Output * * @param string $message */ @@ -292,23 +299,49 @@ public static function debug( $message ) { } /** - * Display a warning in the CLI and end with a newline. + * Display warning message prefixed with "Warning: ". + * + * Warning message is written to STDERR. + * + * ``` + * # `wp plugin activate` skips activation when plugin is network active. + * $status = $this->get_status( $plugin->file ); + * // Network-active is the highest level of activation status + * if ( 'active-network' === $status ) { + * WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); + * continue; + * } + * ``` * * @access public + * @category Output * - * @param string $message + * @param string $message Message to write to STDERR. + * @return null */ public static function warning( $message ) { self::$logger->warning( self::error_to_string( $message ) ); } /** - * Display an error in the CLI and end with a newline. + * Display error message prefixed with "Error: " and exits script. + * + * Error message is written to STDERR. Defaults to halting + * script execution with return code 1. + * + * ``` + * # `wp cache flush` considers flush failure to be a fatal error. + * if ( false === wp_cache_flush() ) { + * WP_CLI::error( 'The object cache could not be flushed.' ); + * } + * ``` * * @access public + * @category Output * - * @param string|WP_Error $message - * @param bool $exit if true, the script will exit() + * @param string|WP_Error $message Message to write to STDERR. + * @param boolean|integer $exit True defaults to exit(1). + * @return null */ public static function error( $message, $exit = true ) { if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) ) { @@ -375,6 +408,9 @@ public static function get_value_from_arg_or_stdin( $args, $index ) { /** * Read a value, from various formats. * + * @access public + * @category Input + * * @param mixed $value * @param array $assoc_args */ @@ -432,12 +468,14 @@ public static function error_to_string( $errors ) { } /** - * Launch an external process that takes over I/O. + * Launch an arbitrary external process that takes over I/O. + * + * @access public + * @category Execution * * @param string Command to call * @param bool Whether to exit if the command returns an error status - * @param bool Whether to return an exit status (default) or detailed execution results - * + * @param bool Whether to return an exit status (default) or detailed execution results. * @return int|ProcessRun The command exit status, or a ProcessRun instance */ public static function launch( $command, $exit_on_error = true, $return_detailed = false ) { diff --git a/php/utils.php b/php/utils.php index 315eb31caa..a3152b1bf1 100644 --- a/php/utils.php +++ b/php/utils.php @@ -239,13 +239,15 @@ function wp_version_compare( $since, $operator ) { } /** - * Output items in a table, JSON, CSV, ids, or the total count + * Render a collection of items as an ASCII table, JSON, CSV, YAML, list of ids, or count. * * @access public + * @category Output * - * @param string $format Format to use: 'table', 'json', 'csv', 'ids', 'count' + * @param string $format Format to use: 'table', 'json', 'csv', 'yaml', 'ids', 'count' * @param array $items Data to output * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list + * @return null */ function format_items( $format, $items, $fields ) { $assoc_args = compact( 'format', 'fields' ); From 7dcbfa306ce894f6a3f34f97681812fd01c66478 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 18 Feb 2016 16:12:52 -0800 Subject: [PATCH 4085/4858] Round of edits and enhancements for public APIs --- php/class-wp-cli.php | 104 +++++++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d87cb5e2e1..f5318b7e95 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -246,8 +246,10 @@ public static function add_command( $name, $callable, $args = array() ) { } /** - * Display a message in the CLI and end with a newline. - * Ignores `--quiet` flag. To respect, use `WP_CLI::log()` + * Display informational message without prefix, and ignore `--quiet`. + * + * Message is written to STDOUT. `WP_CLI::log()` is typically recommended; + * `WP_CLI::line()` is included for historical compat. * * @access public * @category Output @@ -260,24 +262,46 @@ public static function line( $message = '' ) { } /** - * Log an informational message. + * Display informational message without prefix. + * + * Message is written to STDOUT, or discarded when `--quiet` flag is supplied. + * + * ``` + * # `wp cli update` lets user know of each step in the update process. + * WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) ); + * ``` * * @access public * @category Output * - * @param string $message + * @param string $message Message to write to STDOUT. */ public static function log( $message ) { self::$logger->info( $message ); } /** - * Display a success in the CLI and end with a newline. + * Display success message prefixed with "Success: ". + * + * Success message is written to STDOUT. + * + * Typically recommended to inform user of successful script conclusion. + * + * ``` + * # wp rewrite flush expects 'rewrite_rules' option to be set after flush. + * flush_rewrite_rules( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) ); + * if ( ! get_option( 'rewrite_rules' ) ) { + * WP_CLI::warning( "Rewrite rules are empty." ); + * } else { + * WP_CLI::success( 'Rewrite rules flushed.' ); + * } + * ``` * * @access public * @category Output * - * @param string $message + * @param string $message Message to write to STDOUT. + * @return null */ public static function success( $message ) { self::$logger->success( $message ); @@ -286,13 +310,30 @@ public static function success( $message ) { /** * Display debug message prefixed with "Debug: " when `--debug` is used. * - * Helpful for optionally showing greater detail when needed. Debug message - * is written to STDERR, and includes script execution time. + * Debug message is written to STDERR, and includes script execution time. + * + * Helpful for optionally showing greater detail when needed. Used throughout + * WP-CLI bootstrap process for easier debugging and profiling. + * + * ``` + * # Called in `WP_CLI\Runner::set_wp_root()`. + * private static function set_wp_root( $path ) { + * define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); + * WP_CLI::debug( 'ABSPATH defined: ' . ABSPATH ); + * $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); + * } + * + * # Debug details only appear when `--debug` is used. + * # $ wp --debug + * # [...] + * # Debug: ABSPATH defined: /srv/www/wordpress-develop.dev/src/ (0.225s) + * ``` * * @access public * @category Output * - * @param string $message + * @param string $message Message to write to STDERR. + * @return null */ public static function debug( $message ) { self::$logger->debug( self::error_to_string( $message ) ); @@ -303,6 +344,9 @@ public static function debug( $message ) { * * Warning message is written to STDERR. * + * Use instead of `WP_CLI::debug()` when script execution should be permitted + * to continue. + * * ``` * # `wp plugin activate` skips activation when plugin is network active. * $status = $this->get_status( $plugin->file ); @@ -324,10 +368,13 @@ public static function warning( $message ) { } /** - * Display error message prefixed with "Error: " and exits script. + * Display error message prefixed with "Error: " and exit script. + * + * Error message is written to STDERR. Defaults to halting script execution + * with return code 1. * - * Error message is written to STDERR. Defaults to halting - * script execution with return code 1. + * Use `WP_CLI::warning()` instead when script execution should be permitted + * to continue. * * ``` * # `wp cache flush` considers flush failure to be a fatal error. @@ -470,13 +517,22 @@ public static function error_to_string( $errors ) { /** * Launch an arbitrary external process that takes over I/O. * + * ``` + * # `wp core download` falls back to the `tar` binary when PharData isn't available + * if ( ! class_exists( 'PharData' ) ) { + * $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball"; + * WP_CLI::launch( Utils\esc_cmd( $cmd, $dest ) ); + * return; + * } + * ``` + * * @access public * @category Execution * - * @param string Command to call - * @param bool Whether to exit if the command returns an error status - * @param bool Whether to return an exit status (default) or detailed execution results. - * @return int|ProcessRun The command exit status, or a ProcessRun instance + * @param string $command External process to launch. + * @param boolean $exit_on_error Whether to exit if the command returns an elevated return code. + * @param boolean $return_detailed Whether to return an exit status (default) or detailed execution results. + * @return int|ProcessRun The command exit status, or a ProcessRun object for full details. */ public static function launch( $command, $exit_on_error = true, $return_detailed = false ) { @@ -494,15 +550,17 @@ public static function launch( $command, $exit_on_error = true, $return_detailed } /** - * Launch another WP-CLI command using the runtime arguments for the current process + * Run a WP-CLI command in a new process reusing the current runtime arguments. * - * @param string Command to call - * @param array $args Positional arguments to use - * @param array $assoc_args Associative arguments to use - * @param bool Whether to exit if the command returns an error status - * @param bool Whether to return an exit status (default) or detailed execution results - * @param array $runtime_args Override one or more global args (path,url,user,allow-root) + * @access public + * @category Execution * + * @param string $command WP-CLI command to call. + * @param array $args Positional arguments to include when calling the command. + * @param array $assoc_args Associative arguments to include when calling the command. + * @param bool $exit_on_error Whether to exit if the command returns an elevated return code. + * @param bool $return_detailed Whether to return an exit status (default) or detailed execution results. + * @param array $runtime_args Override one or more global args (path,url,user,allow-root) * @return int|ProcessRun The command exit status, or a ProcessRun instance */ public static function launch_self( $command, $args = array(), $assoc_args = array(), $exit_on_error = true, $return_detailed = false, $runtime_args = array() ) { From c8800cb2bc4e42725f3ec047ea57f38759799987 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 19 Feb 2016 04:03:17 -0800 Subject: [PATCH 4086/4858] Use more robust failed download checking in `wp cli update` Because `php file.xml` returns exit code `0`, we need to run a command where only WP-CLI will return the string we expect. --- features/cli.feature | 32 ++++++++++++++++++++++++++++++++ php/commands/cli.php | 4 ++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/features/cli.feature b/features/cli.feature index 68ed68fde3..081ed727b0 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -32,6 +32,16 @@ Feature: `wp cli` tasks Given an empty directory And a new Phar with version "0.0.0" + When I run `{PHAR_PATH} --info` + Then STDOUT should contain: + """ + WP-CLI version + """ + And STDOUT should contain: + """ + 0.0.0 + """ + When I run `{PHAR_PATH} cli update --yes` Then STDOUT should contain: """ @@ -40,11 +50,27 @@ Feature: `wp cli` tasks And STDERR should be empty And the return code should be 0 + When I run `{PHAR_PATH} --info` + Then STDOUT should contain: + """ + WP-CLI version + """ + And STDOUT should not contain: + """ + 0.0.0 + """ + @github-api Scenario: Patch update from 0.14.0 to 0.14.1 Given an empty directory And a new Phar with version "0.14.0" + When I run `{PHAR_PATH} --version` + Then STDOUT should be: + """ + WP-CLI 0.14.0 + """ + When I run `{PHAR_PATH} cli update --patch --yes` Then STDOUT should contain: """ @@ -53,6 +79,12 @@ Feature: `wp cli` tasks And STDERR should be empty And the return code should be 0 + When I run `{PHAR_PATH} --version` + Then STDOUT should be: + """ + WP-CLI 0.14.1 + """ + @github-api Scenario: Not a patch update from 0.14.0 Given an empty directory diff --git a/php/commands/cli.php b/php/commands/cli.php index a021f6acdc..f68e19d256 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -181,9 +181,9 @@ public function update( $_, $assoc_args ) { $allow_root = WP_CLI::get_runner()->config['allow-root'] ? '--allow-root' : ''; $php_binary = WP_CLI::get_php_binary(); - $process = WP_CLI\Process::create( "{$php_binary} $temp --version {$allow_root}" ); + $process = WP_CLI\Process::create( "{$php_binary} $temp --info {$allow_root}" ); $result = $process->run(); - if ( 0 !== $result->return_code ) { + if ( 0 !== $result->return_code || false === stripos( $result->stdout, 'WP-CLI version:' ) ) { $multi_line = explode( PHP_EOL, $result->stderr ); WP_CLI::error_multi_line( $multi_line ); WP_CLI::error( 'The downloaded PHAR is broken, try running wp cli update again.' ); From 0c810fa84aa2ec2484aa1b19e6262acd512897bd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 19 Feb 2016 04:49:26 -0800 Subject: [PATCH 4087/4858] Fix fatal error when a dependency needs to be installed ``` PHP Catchable fatal error: Argument 1 passed to Composer\DependencyResolver\Rule::getPrettyString() must be an instance of Composer\DependencyResolver\Pool, none given, called in /home/vagrant/.wp-cli/php/WP_CLI/PackageManagerEventSubscriber.php on line 40 and defined in /home/vagrant/.wp-cli/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php on line 161 ``` --- php/WP_CLI/PackageManagerEventSubscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/PackageManagerEventSubscriber.php b/php/WP_CLI/PackageManagerEventSubscriber.php index a4b3798e34..0570135737 100644 --- a/php/WP_CLI/PackageManagerEventSubscriber.php +++ b/php/WP_CLI/PackageManagerEventSubscriber.php @@ -37,7 +37,7 @@ public static function post_install( PackageEvent $event ) { case Rule::RULE_PACKAGE_CONFLICT; case Rule::RULE_PACKAGE_SAME_NAME: case Rule::RULE_PACKAGE_REQUIRES: - $composer_error = $reason->getPrettyString(); + $composer_error = $reason->getPrettyString( $event->getPool() ); break; } From 50e4073a14a8859c662c0c73f416ddf19fd4252d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 07:29:42 -0800 Subject: [PATCH 4088/4858] Mark `WP_CLI\Utils\make_progress_bar()` as a public internal API. --- php/utils.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/php/utils.php b/php/utils.php index a3152b1bf1..9f717d5bb8 100644 --- a/php/utils.php +++ b/php/utils.php @@ -408,6 +408,34 @@ function mustache_render( $template_name, $data ) { return $m->render( $template, $data ); } +/** + * Create a progress bar to display percent completion of a given operation. + * + * Progress bar is written to STDOUT, and disabled when command is piped. Progress + * advances with `$progress->tick()`, and completes with `$progress->finish()`. + * Process bar also indicates elapsed time and expected total time. + * + * ``` + * # `wp user generate` ticks progress bar each time a new user is created. + * # + * # $ wp user generate --count=500 + * # Generating users 22 % [=======> ] 0:05 / 0:23 + * + * $progress = \WP_CLI\Utils\make_progress_bar( 'Generating users', $count ); + * for ( $i = 0; $i < $count; $i++ ) { + * // uses wp_insert_user() to insert the user + * $progress->tick(); + * } + * $progress->finish(); + * ``` + * + * @access public + * @category Output + * + * @param string $message Text to display before the progress bar. + * @param integer $count Total number of ticks to be performed. + * @return cli\progress\Bar|WP_CLI\NoOp + */ function make_progress_bar( $message, $count ) { if ( \cli\Shell::isPiped() ) return new \WP_CLI\NoOp; From 72f360cbf7fb1bb51a23ba8eff2e7756ddc69d59 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 18:26:57 -0800 Subject: [PATCH 4089/4858] Merge project config into global config when latter is already set --- features/config.feature | 38 +++++++++++++++++++++++++++++++++++++ php/WP_CLI/Configurator.php | 12 ++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/features/config.feature b/features/config.feature index 9702f8da7e..86a01c1a6c 100644 --- a/features/config.feature +++ b/features/config.feature @@ -271,6 +271,44 @@ Feature: Have a config file Error: Required file 'foo.php' doesn't exist (from runtime argument). """ + Scenario: Config inheritance + Given an empty directory + And a test-cmd.php file: + """ + <?php + $command = function( $_, $assoc_args ) { + echo json_encode( $assoc_args ); + }; + WP_CLI::add_command( 'test-cmd', $command, array( 'when' => 'before_wp_load' ) ); + """ + And a config.yml file: + """ + test-cmd: + foo: bar + apple: banana + apple: banana + """ + And a wp-cli.yml file: + """ + cli config: + merge: true + test-cmd: + bar: burrito + apple: apple + apple: apple + """ + + When I run `wp --require=test-cmd.php test-cmd` + Then STDOUT should be JSON containing: + """ + {"bar":"burrito","apple":"apple"} + """ + When I run `WP_CLI_CONFIG_PATH=config.yml wp --require=test-cmd.php test-cmd` + Then STDOUT should be JSON containing: + """ + {"foo":"bar","apple":"apple","bar":"burrito"} + """ + @require-wp-3.9 Scenario: WordPress install with local dev DOMAIN_CURRENT_SITE Given a WP multisite install diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 21ae2ad3f1..99d826d71f 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -137,9 +137,17 @@ private function unmix_assoc_args( $mixed_args ) { * @param string $path Path to YAML file. */ public function merge_yml( $path ) { - foreach ( self::load_yml( $path ) as $key => $value ) { + $yaml = self::load_yml( $path ); + foreach ( $yaml as $key => $value ) { if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { - $this->extra_config[ $key ] = $value; + if ( isset( $this->extra_config[ $key ] ) + && ! empty( $yaml['cli config']['merge'] ) + && is_array( $this->extra_config[ $key ] ) + && is_array( $value ) ) { + $this->extra_config[ $key ] = array_merge( $this->extra_config[ $key ], $value ); + } else { + $this->extra_config[ $key ] = $value; + } } elseif ( $this->spec[ $key ]['multiple'] ) { self::arrayify( $value ); $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); From a35ff4b649a62ebf6282343d8c1e3511b351f165 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 18:52:13 -0800 Subject: [PATCH 4090/4858] Support inheritance in config files --- features/config.feature | 72 ++++++++++++++++++++++++++++++++++++- php/WP_CLI/Configurator.php | 3 ++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/features/config.feature b/features/config.feature index 86a01c1a6c..22a1d23ae2 100644 --- a/features/config.feature +++ b/features/config.feature @@ -271,7 +271,7 @@ Feature: Have a config file Error: Required file 'foo.php' doesn't exist (from runtime argument). """ - Scenario: Config inheritance + Scenario: Config inheritance from project to global Given an empty directory And a test-cmd.php file: """ @@ -309,6 +309,76 @@ Feature: Have a config file {"foo":"bar","apple":"apple","bar":"burrito"} """ + Given a wp-cli.yml file: + """ + cli config: + merge: false + test-cmd: + bar: burrito + apple: apple + apple: apple + """ + When I run `WP_CLI_CONFIG_PATH=config.yml wp --require=test-cmd.php test-cmd` + Then STDOUT should be JSON containing: + """ + {"bar":"burrito","apple":"apple"} + """ + + Scenario: Config inheritance from local to project + Given an empty directory + And a test-cmd.php file: + """ + <?php + $command = function( $_, $assoc_args ) { + echo json_encode( $assoc_args ); + }; + WP_CLI::add_command( 'test-cmd', $command, array( 'when' => 'before_wp_load' ) ); + """ + And a wp-cli.yml file: + """ + test-cmd: + foo: bar + apple: banana + apple: banana + """ + + When I run `wp --require=test-cmd.php test-cmd` + Then STDOUT should be JSON containing: + """ + {"foo":"bar","apple":"banana"} + """ + + Given a wp-cli.local.yml file: + """ + cli config: + inherit: wp-cli.yml + merge: true + test-cmd: + bar: burrito + apple: apple + apple: apple + """ + + When I run `wp --require=test-cmd.php test-cmd` + Then STDOUT should be JSON containing: + """ + {"foo":"bar","apple":"apple","bar":"burrito"} + """ + + Given a wp-cli.local.yml file: + """ + test-cmd: + bar: burrito + apple: apple + apple: apple + """ + + When I run `wp --require=test-cmd.php test-cmd` + Then STDOUT should be JSON containing: + """ + {"bar":"burrito","apple":"apple"} + """ + @require-wp-3.9 Scenario: WordPress install with local dev DOMAIN_CURRENT_SITE Given a WP multisite install diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 99d826d71f..6d8ae23037 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -138,6 +138,9 @@ private function unmix_assoc_args( $mixed_args ) { */ public function merge_yml( $path ) { $yaml = self::load_yml( $path ); + if ( ! empty( $yaml['cli config']['inherit'] ) ) { + $this->merge_yml( $yaml['cli config']['inherit'] ); + } foreach ( $yaml as $key => $value ) { if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { if ( isset( $this->extra_config[ $key ] ) From 01655a9e9633e39f4ad4a6a6acb6ecba7796aac2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 19:28:56 -0800 Subject: [PATCH 4091/4858] Run help early for `wp core` commands used when core isn't yet installed While it would be more ideal to run help early _always_ when core isn't installed, we are unable to easily inspect the database for blog tables. This change permits `wp help core install` to be run when `wp-config.php` is created, but the database isn't yet configured. --- features/help.feature | 7 +++++++ php/WP_CLI/Runner.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/features/help.feature b/features/help.feature index fb066f603c..79bb1eee71 100644 --- a/features/help.feature +++ b/features/help.feature @@ -37,6 +37,13 @@ Feature: Get help about WP-CLI commands wp core config """ + When I run `wp core config {CORE_CONFIG_SETTINGS}` + And I run `wp help core install` + Then STDOUT should contain: + """ + wp core install + """ + Scenario: Help for nonexistent commands Given a WP install diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3adde5022d..af857ba093 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -664,7 +664,7 @@ public function start() { self::set_wp_root( $this->find_wp_root() ); // First try at showing man page - if ( 'help' === $this->arguments[0] && ( ! $this->wp_exists() || ! Utils\locate_wp_config() ) ) { + if ( 'help' === $this->arguments[0] && ( ! $this->wp_exists() || ! Utils\locate_wp_config() || 'core' === $this->arguments[1] && in_array( $this->arguments[2], array( 'config', 'install', 'multisite-install', 'verify-checksums', 'version' ) ) ) ) { $this->_run_command(); } From dda8e5c9e45a0f17332207af15dd8ab9cc9a2685 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 19:47:14 -0800 Subject: [PATCH 4092/4858] When running tests inside of a package, autoload composer.json files This is much easier than provisioning a Behat YML config and having to use that. --- features/bootstrap/FeatureContext.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 4ca743bf81..da9e2aac2a 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -12,6 +12,20 @@ if ( file_exists( __DIR__ . '/utils.php' ) ) { require_once __DIR__ . '/utils.php'; require_once __DIR__ . '/Process.php'; + $project_composer = dirname( dirname( dirname( __FILE__ ) ) ) . '/composer.json'; + if ( file_exists( $project_composer ) ) { + $composer = json_decode( file_get_contents( $project_composer ) ); + if ( ! empty( $composer->autoload->files ) ) { + $contents = 'require:' . PHP_EOL; + foreach( $composer->autoload->files as $file ) { + $contents .= ' - ' . dirname( dirname( dirname( __FILE__ ) ) ) . '/' . $file; + } + @mkdir( sys_get_temp_dir() . '/wp-cli-package-test/' ); + $project_config = sys_get_temp_dir() . '/wp-cli-package-test/config.yml'; + file_put_contents( $project_config, $contents ); + putenv( 'WP_CLI_CONFIG_PATH=' . $project_config ); + } + } // Inside WP-CLI } else { require_once __DIR__ . '/../../php/utils.php'; From 900befec21cc025f2802d1dc5dbae1ddff2d22ae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 21:01:49 -0800 Subject: [PATCH 4093/4858] Add an inline code example for `Utils\format_items()` --- php/utils.php | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index 9f717d5bb8..e2e723ddc4 100644 --- a/php/utils.php +++ b/php/utils.php @@ -241,12 +241,46 @@ function wp_version_compare( $since, $operator ) { /** * Render a collection of items as an ASCII table, JSON, CSV, YAML, list of ids, or count. * + * Given a collection of items with a consistent data structure: + * + * ``` + * $items = array( + * array( + * 'key' => 'foo', + * 'value' => 'bar', + * ) + * ); + * ``` + * + * Render `$items` easily render as an ASCII table: + * + * ``` + * WP_CLI\Utils\format_items( 'table', $items, array( 'key', 'value' ) ); + * + * # +-----+-------+ + * # | key | value | + * # +-----+-------+ + * # | foo | bar | + * # +-----+-------+ + * ``` + * + * Or render `$items` as YAML: + * + * ``` + * WP_CLI\Utils\format_items( 'yaml', $items, array( 'key', 'value' ) ); + * + * # --- + * # - + * # key: foo + * # value: bar + * ``` + * * @access public * @category Output * * @param string $format Format to use: 'table', 'json', 'csv', 'yaml', 'ids', 'count' - * @param array $items Data to output - * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list + * @param array $items An array of items to output. + * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list. * @return null */ function format_items( $format, $items, $fields ) { From 072871fd2647a339559186da7b98b5f9d4df8f48 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 20 Feb 2016 21:06:47 -0800 Subject: [PATCH 4094/4858] Fix typo in docs --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index e2e723ddc4..4ecbf164de 100644 --- a/php/utils.php +++ b/php/utils.php @@ -252,7 +252,7 @@ function wp_version_compare( $since, $operator ) { * ); * ``` * - * Render `$items` easily render as an ASCII table: + * Render `$items` as an ASCII table: * * ``` * WP_CLI\Utils\format_items( 'table', $items, array( 'key', 'value' ) ); From b444a2a028886c13e2d035f1e9f7837b9ef40a21 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 23 Feb 2016 10:56:49 -0800 Subject: [PATCH 4095/4858] When scaffolding plugin, use `--plugin_author` value in `package.json` --- features/scaffold.feature | 8 +++++++- templates/plugin-packages.mustache | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 635cd4144b..cc0316dbcf 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -110,7 +110,7 @@ Feature: WordPress code scaffolding Given I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} - When I run `wp scaffold plugin hello-world` + When I run `wp scaffold plugin hello-world --plugin_author="Hello World Author"` Then STDOUT should not be empty And the {PLUGIN_DIR}/hello-world/.gitignore file should exist And the {PLUGIN_DIR}/hello-world/.editorconfig file should exist @@ -124,6 +124,12 @@ Feature: WordPress code scaffolding node_modules/ """ + When I run `cat {PLUGIN_DIR}/hello-world/package.json` + Then STDOUT should be JSON containing: + """ + {"author":"Hello World Author"} + """ + Scenario: Scaffold a plugin by prompting Given a WP install And a session file: diff --git a/templates/plugin-packages.mustache b/templates/plugin-packages.mustache index 657df46087..2554b9b2c5 100644 --- a/templates/plugin-packages.mustache +++ b/templates/plugin-packages.mustache @@ -3,7 +3,7 @@ "name": "{{plugin_slug}}", "version": "0.0.0", "main": "Gruntfile.js", - "author": "YOUR NAME HERE", + "author": "{{plugin_author}}", "devDependencies": { "grunt": "^0.4.5", "grunt-wp-i18n": "^0.5.0", From d957dacd5a942f08469da03506cb9d641329dd12 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 24 Feb 2016 09:04:47 -0800 Subject: [PATCH 4096/4858] Use `_` to denote config config `_` is unlikely to ever be a command, and is colloquially understood to be "private" --- features/config.feature | 6 +++--- php/WP_CLI/Configurator.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/config.feature b/features/config.feature index 22a1d23ae2..091c711166 100644 --- a/features/config.feature +++ b/features/config.feature @@ -290,7 +290,7 @@ Feature: Have a config file """ And a wp-cli.yml file: """ - cli config: + _: merge: true test-cmd: bar: burrito @@ -311,7 +311,7 @@ Feature: Have a config file Given a wp-cli.yml file: """ - cli config: + _: merge: false test-cmd: bar: burrito @@ -350,7 +350,7 @@ Feature: Have a config file Given a wp-cli.local.yml file: """ - cli config: + _: inherit: wp-cli.yml merge: true test-cmd: diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 6d8ae23037..8a92bf6bd0 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -138,13 +138,13 @@ private function unmix_assoc_args( $mixed_args ) { */ public function merge_yml( $path ) { $yaml = self::load_yml( $path ); - if ( ! empty( $yaml['cli config']['inherit'] ) ) { - $this->merge_yml( $yaml['cli config']['inherit'] ); + if ( ! empty( $yaml['_']['inherit'] ) ) { + $this->merge_yml( $yaml['_']['inherit'] ); } foreach ( $yaml as $key => $value ) { if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { if ( isset( $this->extra_config[ $key ] ) - && ! empty( $yaml['cli config']['merge'] ) + && ! empty( $yaml['_']['merge'] ) && is_array( $this->extra_config[ $key ] ) && is_array( $value ) ) { $this->extra_config[ $key ] = array_merge( $this->extra_config[ $key ], $value ); From 0061c3d65923f25ff3e137135db6c3d6988341e9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 24 Feb 2016 14:29:15 -0800 Subject: [PATCH 4097/4858] Support emptying term meta with `wp site empty` --- php/commands/site.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index 70ead9dbcf..b86b144b3c 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -87,6 +87,9 @@ private function _empty_taxonomies() { $wpdb->query( "TRUNCATE $wpdb->terms" ); $wpdb->query( "TRUNCATE $wpdb->term_taxonomy" ); $wpdb->query( "TRUNCATE $wpdb->term_relationships" ); + if ( ! empty( $wpdb->termmeta ) ) { + $wpdb->query( "TRUNCATE $wpdb->termmeta" ); + } } /** From e73d1d563c0d852e8d3af46ccab55ef32b687c3b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 06:24:45 -0800 Subject: [PATCH 4098/4858] Mark `WP_CLI::add_command()` as public; improve docs --- php/class-wp-cli.php | 52 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index f5318b7e95..9b2f4964b0 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -163,15 +163,48 @@ public static function do_hook( $when ) { } /** - * Add a command to the wp-cli list of commands - * - * @param string $name The name of the command that will be used in the CLI - * @param string $callable The command implementation as a class, function or closure - * @param array $args An associative array with additional parameters: - * 'before_invoke' => callback to execute before invoking the command, - * 'shortdesc' => short description (80 char or less) for the command, - * 'synopsis' => the synopsis for the command (string or array) - * 'when' => execute callback on a named WP-CLI hook (e.g. before_wp_load) + * Register a command to WP-CLI. + * + * WP-CLI supports using any callable class, function, or closure as a + * command. `WP_CLI::add_command()` is used for both internal and + * third-party command registration. + * + * Command arguments are parsed from PHPDoc by default, but also can be + * supplied as an optional third argument during registration. + * + * ``` + * # Register a custom 'foo' command to output a supplied positional param. + * # + * # $ wp foo bar + * # Success: bar + * + * /** + * * My awesome closure command + * * + * * <message> + * * : An awesome message to display + * * + * * @when before_wp_load + * *\/ + * $foo = function( $args ) { + * WP_CLI::success( $args[0] ); + * }; + * WP_CLI::add_command( 'foo', $foo ); + * ``` + * + * @access public + * @category Registration + * + * @param string $name Name for the command (e.g. "post list" or "site empty"). + * @param string $callable Command implementation as a class, function or closure. + * @param array $args { + * Optional An associative array with additional registration parameters. + * 'before_invoke' => callback to execute before invoking the command, + * 'shortdesc' => short description (80 char or less) for the command, + * 'synopsis' => the synopsis for the command (string or array), + * 'when' => execute callback on a named WP-CLI hook (e.g. before_wp_load), + * } + * @return true True on success, hard error if registration failed. */ public static function add_command( $name, $callable, $args = array() ) { $valid = false; @@ -243,6 +276,7 @@ public static function add_command( $name, $callable, $args = array() ) { } $command->add_subcommand( $leaf_name, $leaf_command ); + return true; } /** From 3b97b4d6b72bf527e9b5ef3478e2c9ef573da6c4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 07:10:50 -0800 Subject: [PATCH 4099/4858] Failing test case for not persisting object when registering --- features/command.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/features/command.feature b/features/command.feature index c73f906226..4bd08e944f 100644 --- a/features/command.feature +++ b/features/command.feature @@ -221,6 +221,36 @@ Feature: WP-CLI Commands Success: bar """ + Scenario: Use class with __invoke() passed as object + Given an empty directory + And a custom-cmd.php file: + """ + <?php + class Foo_Class { + + public function __construct( $message ) { + $this->message = $message; + } + + /** + * My awesome class method command + * + * @when before_wp_load + */ + function __invoke( $args ) { + WP_CLI::success( $this->message ); + } + } + $foo = new Foo_Class( 'bar' ); + WP_CLI::add_command( 'instantiated-command', $foo ); + """ + + When I run `wp --require=custom-cmd.php instantiated-command` + Then STDOUT should contain: + """ + bar + """ + Scenario: Use an invalid class method as a command Given an empty directory And a custom-cmd.php file: From 538efb2eeeb17c49ef873b3169977f6d33b8390b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 07:16:22 -0800 Subject: [PATCH 4100/4858] Fix registering instantiated object with `__invoke()` method When an instantiated object is passed, we should continue to use it. --- php/WP_CLI/Dispatcher/CommandFactory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index bd3874117a..5b05568c5a 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -29,7 +29,8 @@ public static function create( $name, $callable, $parent ) { } else { $reflection = new \ReflectionClass( $callable ); if ( $reflection->hasMethod( '__invoke' ) ) { - $command = self::create_subcommand( $parent, $name, array( $reflection->name, '__invoke' ), + $class = is_object( $callable ) ? $callable : $reflection->name; + $command = self::create_subcommand( $parent, $name, array( $class, '__invoke' ), $reflection->getMethod( '__invoke' ) ); } else { $command = self::create_composite_command( $parent, $name, $reflection ); From 187f726d682c5b3e8453a89987fce57d3e29869d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 08:27:27 -0800 Subject: [PATCH 4101/4858] Ensure the failing test case would actually fail --- features/command.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/command.feature b/features/command.feature index 4bd08e944f..2497e0f6fe 100644 --- a/features/command.feature +++ b/features/command.feature @@ -250,6 +250,7 @@ Feature: WP-CLI Commands """ bar """ + And STDERR should be empty Scenario: Use an invalid class method as a command Given an empty directory From 47e62a004ff6c5659c10e8aa6184578ded35fc3d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 08:42:15 -0800 Subject: [PATCH 4102/4858] Prevent error notices when `$this->arguments` doesn't have array keys --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index af857ba093..6addd6403f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -664,7 +664,7 @@ public function start() { self::set_wp_root( $this->find_wp_root() ); // First try at showing man page - if ( 'help' === $this->arguments[0] && ( ! $this->wp_exists() || ! Utils\locate_wp_config() || 'core' === $this->arguments[1] && in_array( $this->arguments[2], array( 'config', 'install', 'multisite-install', 'verify-checksums', 'version' ) ) ) ) { + if ( ! empty( $this->arguments[0] ) && 'help' === $this->arguments[0] && ( ! $this->wp_exists() || ! Utils\locate_wp_config() || ( ! empty( $this->arguments[1] ) && ! empty( $this->arguments[2] ) && 'core' === $this->arguments[1] && in_array( $this->arguments[2], array( 'config', 'install', 'multisite-install', 'verify-checksums', 'version' ) ) ) ) ) { $this->_run_command(); } From 9abd5443c5f7c2f983c54a73a6f4dbcc34651b9c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 09:08:44 -0800 Subject: [PATCH 4103/4858] Register `$longdesc` from supplied arguments --- features/command.feature | 22 ++++++++++++++++++++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 9 +++++++++ php/class-wp-cli.php | 13 ++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/features/command.feature b/features/command.feature index c73f906226..da5e47c2b6 100644 --- a/features/command.feature +++ b/features/command.feature @@ -301,3 +301,25 @@ Feature: WP-CLI Commands """ My awesome function command """ + And STDOUT should contain: + """ + SYNOPSIS + """ + And STDOUT should contain: + """ + wp foo <message> --apple=<apple> [--meal=<meal>] + """ + And STDOUT should contain: + """ + OPTIONS + """ + And STDOUT should contain: + """ + <message> + An awesome message to display + """ + And STDOUT should contain: + """ + [--meal=<meal>] + A type of meal. + """ diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index 8ec1f51523..f9728b5145 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -118,6 +118,15 @@ public function get_longdesc() { return $this->longdesc; } + /** + * Set the long description for this composite commmand + * + * @param string + */ + public function set_longdesc( $longdesc ) { + $this->longdesc = $longdesc; + } + /** * Get the synopsis for this composite command. * As a collection of subcommands, the composite diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9b2f4964b0..de348bbfed 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -267,7 +267,18 @@ public static function add_command( $name, $callable, $args = array() ) { if ( is_string( $args['synopsis'] ) ) { $leaf_command->set_synopsis( $args['synopsis'] ); } else if ( is_array( $args['synopsis'] ) ) { - $leaf_command->set_synopsis( \WP_CLI\SynopsisParser::render( $args['synopsis'] ) ); + $synopsis = \WP_CLI\SynopsisParser::render( $args['synopsis'] ); + $leaf_command->set_synopsis( $synopsis ); + $long_desc = ''; + $bits = explode( ' ', $synopsis ); + foreach( $args['synopsis'] as $key => $arg ) { + $long_desc .= $bits[ $key ] . PHP_EOL . ': ' . $arg['description'] . PHP_EOL . PHP_EOL; + } + if ( ! empty( $long_desc ) ) { + $long_desc = rtrim( $long_desc, PHP_EOL ); + $long_desc = '## OPTIONS' . PHP_EOL . PHP_EOL . $long_desc; + $leaf_command->set_longdesc( $long_desc ); + } } } From e139266ccf302b9019f90c9807fce6667f87eedd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 09:26:25 -0800 Subject: [PATCH 4104/4858] Add `WP_CLI::add_hook()` and `WP_CLI::do_hook()` to internal API --- php/class-wp-cli.php | 45 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 9b2f4964b0..04a6e40ee2 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -139,7 +139,39 @@ public static function colorize( $string ) { } /** - * Schedule a callback to be executed at a certain point (before WP is loaded). + * Schedule a callback to be executed at a certain point. + * + * Hooks conceptually are very similar to WordPress actions. WP-CLI hooks + * are typically called before WordPress is loaded. + * + * WP-CLI hooks include: + * + * * 'before_invoke:<command>' - Just before a command is invoked. + * * 'after_invoke:<command>' - Just after a command is involved. + * * 'before_wp_load' - Just before the WP load process begins. + * * 'before_wp_config_load' - After wp-config.php has been located. + * * 'after_wp_config_load' - After wp-config.php has been loaded into scope. + * * 'after_wp_load' - Just after the WP load process has completed. + * + * WP-CLI commands can create their own hooks with `WP_CLI::do_hook()`. + * + * ``` + * # `wp network meta` confirms command is executing in multisite context. + * WP_CLI::add_command( 'network meta', 'Network_Meta_Command', array( + * 'before_invoke' => function () { + * if ( !is_multisite() ) { + * WP_CLI::error( 'This is not a multisite install.' ); + * } + * } + * ) ); + * ``` + * + * @access public + * @category Registration + * + * @param string $when Identifier for the hook. + * @param mixed $callback Callback to execute when hook is called. + * @return null */ public static function add_hook( $when, $callback ) { if ( in_array( $when, self::$hooks_passed ) ) @@ -149,7 +181,16 @@ public static function add_hook( $when, $callback ) { } /** - * Execute registered callbacks. + * Execute callbacks registered to a given hook. + * + * See `WP_CLI::add_hook()` for details on WP-CLI's internal hook system. + * Commands can provide and call their own hooks. + * + * @access public + * @category Registration + * + * @param string $when Identifier for the hook. + * @return null */ public static function do_hook( $when ) { self::$hooks_passed[] = $when; From eb4e0a613720e53c9e008c391d4cde4234364853 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 09:47:51 -0800 Subject: [PATCH 4105/4858] Always sort package lists alphabetically --- php/commands/package.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/package.php b/php/commands/package.php index e85d8c8a13..1845cdbaa8 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -270,6 +270,7 @@ private function show_packages( $packages, $assoc_args ) { $list[$package_output->name] = $package_output; } + ksort( $list ); WP_CLI\Utils\format_items( $assoc_args['format'], $list, $assoc_args['fields'] ); } From 1fa1eb5089aace3609c2b57e0756dd4921627e73 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 09:50:06 -0800 Subject: [PATCH 4106/4858] Provide breathing room between author names --- php/commands/package.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/package.php b/php/commands/package.php index 1845cdbaa8..b4dd6df08a 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -265,7 +265,7 @@ private function show_packages( $packages, $assoc_args ) { $package_output = new stdClass; $package_output->name = $package->getName(); $package_output->description = $package->getDescription(); - $package_output->authors = implode( ',', array_column( (array) $package->getAuthors(), 'name' ) ); + $package_output->authors = implode( ', ', array_column( (array) $package->getAuthors(), 'name' ) ); $package_output->version = $package->getPrettyVersion(); $list[$package_output->name] = $package_output; } From 99ba8af0283061ccc8d61d60a1a229c58fb8d6de Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 13:29:45 -0800 Subject: [PATCH 4107/4858] Improve PHPDoc for `WP_CLI::error_multi_line()` --- php/class-wp-cli.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d8f9d5d06c..d31dfc40f4 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -489,11 +489,14 @@ public static function error( $message, $exit = true ) { } /** - * Display an error in the CLI and end with a newline. + * Display a multi-line error message in a red box. Doesn't exit script. + * + * Error message is written to STDERR. * * @access public + * @category Output * - * @param array $message each element from the array will be printed on its own line + * @param array $message Multi-line error message to be displayed. */ public static function error_multi_line( $message_lines ) { if ( ! isset( self::get_runner()->assoc_args[ 'completions' ] ) && is_array( $message_lines ) ) { From c31fff319f36b13dac62afcf7579580d52e15ee5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 13:30:18 -0800 Subject: [PATCH 4108/4858] Denote `WP_CLI::confirm()` as a public API --- php/class-wp-cli.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index d31dfc40f4..3fc49d1ae6 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -506,6 +506,21 @@ public static function error_multi_line( $message_lines ) { /** * Ask for confirmation before running a destructive operation. + * + * If 'y' is provided to the question, the script execution continues. If + * 'n' or any other response is provided to the question, script exits. + * + * ``` + * # `wp db drop` asks for confirmation before dropping the database. + * + * WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); + * ``` + * + * @access public + * @category Input + * + * @param string $question Question to display before the prompt. + * @param array $assoc_args Skips prompt if 'yes' is provided. */ public static function confirm( $question, $assoc_args = array() ) { if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'yes' ) ) { From 48d0fe384e785475273945966fa7a6ec660f9e70 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 13:31:08 -0800 Subject: [PATCH 4109/4858] PHPDoc cleanup --- php/class-wp-cli.php | 4 ++-- php/utils.php | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 3fc49d1ae6..00407f9b92 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -581,8 +581,8 @@ public static function read_value( $raw_value, $assoc_args = array() ) { /** * Display a value, in various formats * - * @param mixed $value - * @param array $assoc_args + * @param mixed $value Value to display. + * @param array $assoc_args Arguments passed to the command, determining format. */ public static function print_value( $value, $assoc_args = array() ) { if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { diff --git a/php/utils.php b/php/utils.php index 4ecbf164de..597a4d19e4 100644 --- a/php/utils.php +++ b/php/utils.php @@ -639,7 +639,12 @@ function get_named_sem_ver( $new_version, $original_version ) { /** * Return the flag value or, if it's not set, the $default value. * + * Because flags can be negated (e.g. --no-quiet to negate --quiet), this + * function provides a safer alternative to using + * `isset( $assoc_args['quiet'] )` or similar. + * * @access public + * @category Input * * @param array $assoc_args Arguments array. * @param string $flag Flag to get the value. @@ -651,9 +656,10 @@ function get_flag_value( $assoc_args, $flag, $default = null ) { } /** - * Get the temp directory, and let the user know if it isn't writable. + * Get the system's temp directory. Warns user if it isn't writable. * * @access public + * @category System * * @return string */ From c261997fe22227141b990706866eca15c513c295 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 25 Feb 2016 13:31:19 -0800 Subject: [PATCH 4110/4858] Denote `WP_CLI::get_php_binary()` and `WP_CLI\Utils\http_request()` as internal APIs --- php/class-wp-cli.php | 4 ++++ php/utils.php | 21 +++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 00407f9b92..a55ef8fc92 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -696,8 +696,12 @@ public static function launch_self( $command, $args = array(), $assoc_args = arr /** * Get the path to the PHP binary used when executing WP-CLI. + * * Environment values permit specific binaries to be indicated. * + * @access public + * @category System + * * @return string */ public static function get_php_binary() { diff --git a/php/utils.php b/php/utils.php index 597a4d19e4..d8b30f9131 100644 --- a/php/utils.php +++ b/php/utils.php @@ -513,11 +513,24 @@ function replace_path_consts( $source, $path ) { } /** - * Make a HTTP request to a remote URL + * Make a HTTP request to a remote URL. * - * @param string $method - * @param string $url - * @param array $headers + * Wraps the Requests HTTP library to ensure every request includes a cert. + * + * ``` + * # `wp core download` verifies the hash for a downloaded WordPress archive + * + * $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); + * if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { + * WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})" ); + * } + * ``` + * + * @access public + * + * @param string $method HTTP method (GET, POST, DELETE, etc.) + * @param string $url URL to make the HTTP request to. + * @param array $headers Add specific headers to the request. * @param array $options * @return object */ From c172c8dfb1830d1bd73ac9ed649cf93289555c5f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 26 Feb 2016 07:08:39 -0800 Subject: [PATCH 4111/4858] Fix formatting of GLOBAL PARAMETERS when command has subcommands --- features/help.feature | 33 ++++++++++++++++++++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 7 +++-- templates/man-params.mustache | 4 +++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/features/help.feature b/features/help.feature index 79bb1eee71..3f56c0ae24 100644 --- a/features/help.feature +++ b/features/help.feature @@ -174,3 +174,36 @@ Feature: Get help about WP-CLI commands """ test-extra """ + + Scenario: Help renders global parameters correctly + Given a WP install + + When I run `wp help import get` + Then STDOUT should contain: + """ + GLOBAL PARAMETERS + """ + And STDOUT should not contain: + """ + ## GLOBAL PARAMETERS + """ + + When I run `wp help option get` + Then STDOUT should contain: + """ + GLOBAL PARAMETERS + """ + And STDOUT should not contain: + """ + ## GLOBAL PARAMETERS + """ + + When I run `wp help option` + Then STDOUT should contain: + """ + GLOBAL PARAMETERS + """ + And STDOUT should not contain: + """ + ## GLOBAL PARAMETERS + """ diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index f9728b5145..a4712a592b 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -30,7 +30,6 @@ public function __construct( $parent, $name, $docparser ) { $this->shortdesc = $docparser->get_shortdesc(); $this->longdesc = $docparser->get_longdesc(); - $this->longdesc .= $this->get_global_params(); $this->docparser = $docparser; $when_to_invoke = $docparser->get_tag( 'when' ); @@ -115,7 +114,7 @@ public function set_shortdesc( $shortdesc ) { * @return string */ public function get_longdesc() { - return $this->longdesc; + return $this->longdesc . $this->get_global_params(); } /** @@ -278,6 +277,10 @@ protected function get_global_params( $root_command = false ) { ); } + if ( $this->get_subcommands() ) { + $binding['has_subcommands'] = true; + } + return Utils\mustache_render( 'man-params.mustache', $binding ); } } diff --git a/templates/man-params.mustache b/templates/man-params.mustache index 53ca9addcc..d2786014e6 100644 --- a/templates/man-params.mustache +++ b/templates/man-params.mustache @@ -2,6 +2,10 @@ {{/is_subcommand}} +{{#has_subcommands}} + + +{{/has_subcommands}} ## GLOBAL PARAMETERS {{#parameters}} From 00537c7c16b154ece035b24b312ae4d0f9dfcec1 Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 2 Mar 2016 15:45:10 -0300 Subject: [PATCH 4112/4858] Add test for `wp comment delete --force` --- features/comment.feature | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/features/comment.feature b/features/comment.feature index f636f60874..2286a23455 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -28,7 +28,25 @@ Feature: Manage WordPress comments """ Success: Deleted comment {COMMENT_ID}. """ - + + When I run `wp comment get {COMMENT_ID} --field=comment_approved` + Then STDOUT should be: + """ + trash + """ + + When I run `wp comment delete {COMMENT_ID} --force` + Then STDOUT should be: + """ + Success: Deleted comment {COMMENT_ID}. + """ + + When I try `wp comment get {COMMENT_ID}` + Then STDERR should be: + """ + Error: Invalid comment ID. + """ + When I run `wp comment create --comment_post_ID=1` And I run `wp comment create --comment_post_ID=1` And I run `wp comment delete 3 4` From 5913d5c3feb8bf3d5d8ed2f3ccada3b00c032d8e Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 2 Mar 2016 15:45:42 -0300 Subject: [PATCH 4113/4858] typo --- features/comment.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 2286a23455..0351c0eecf 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -55,7 +55,7 @@ Feature: Manage WordPress comments Success: Deleted comment 3. Success: Deleted comment 4. """ - + Scenario: Get details about an existing comment When I run `wp comment get 1` Then STDOUT should be a table containing rows: @@ -91,7 +91,7 @@ Feature: Manage WordPress comments #comment-1 """ - Scenario: Count comments + Scenario: Count comments When I run `wp comment count 1` Then STDOUT should contain: """ From 387277b98c6844174463c04335402cfde4f16c8e Mon Sep 17 00:00:00 2001 From: Rodrigo Primo <rodrigo@hacklab.com.br> Date: Wed, 2 Mar 2016 15:47:01 -0300 Subject: [PATCH 4114/4858] Differentiate output when moving comments to trash from output when deleting comments --- features/comment.feature | 6 +++--- php/commands/comment.php | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 0351c0eecf..9a4fb0de21 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -26,7 +26,7 @@ Feature: Manage WordPress comments When I run `wp comment delete {COMMENT_ID}` Then STDOUT should be: """ - Success: Deleted comment {COMMENT_ID}. + Success: Trashed comment {COMMENT_ID}. """ When I run `wp comment get {COMMENT_ID} --field=comment_approved` @@ -52,8 +52,8 @@ Feature: Manage WordPress comments And I run `wp comment delete 3 4` Then STDOUT should be: """ - Success: Deleted comment 3. - Success: Deleted comment 4. + Success: Trashed comment 3. + Success: Trashed comment 4. """ Scenario: Get details about an existing comment diff --git a/php/commands/comment.php b/php/commands/comment.php index 45a01d86f9..8c8b82a3b0 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -247,10 +247,16 @@ public function list_( $_, $assoc_args ) { */ public function delete( $args, $assoc_args ) { parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { - $r = wp_delete_comment( $comment_id, \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + + $r = wp_delete_comment( $comment_id, $force ); if ( $r ) { - return array( 'success', "Deleted comment $comment_id." ); + if ( $force ) { + return array( 'success', "Deleted comment $comment_id." ); + } else { + return array( 'success', "Trashed comment $comment_id." ); + } } else { return array( 'error', "Failed deleting comment $comment_id" ); } From 1ac584ff021b6e3873799e7b302eb4d22ff2286b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 2 Mar 2016 11:11:58 -0800 Subject: [PATCH 4115/4858] Accommodate spaces in `ps -o ppid,pid,command` output Some shells format output differently. We can easily accommodate minor formatting changes, though. --- features/bootstrap/FeatureContext.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index da9e2aac2a..d2248100cb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -127,22 +127,24 @@ private static function terminate_proc( $proc ) { $master_pid = $status['pid']; - $output = `ps -o ppid,pid,command | grep ^$master_pid`; + $output = `ps -o ppid,pid,command | grep $master_pid`; - foreach ( explode( "\n", $output ) as $line ) { - if ( preg_match( '/^(\d+)\s+(\d+)/', $line, $matches ) ) { + foreach ( explode( PHP_EOL, $output ) as $line ) { + if ( preg_match( '/^\s+?(\d+)\s+(\d+)/', $line, $matches ) ) { $parent = $matches[1]; $child = $matches[2]; if ( $parent == $master_pid ) { - if ( ! posix_kill( $child, 9 ) ) { + if ( ! posix_kill( (int) $child, 9 ) ) { throw new RuntimeException( posix_strerror( posix_get_last_error() ) ); } } } } - posix_kill( $master_pid, 9 ); + if ( ! posix_kill( (int) $master_pid, 9 ) ) { + throw new RuntimeException( posix_strerror( posix_get_last_error() ) ); + } } public static function create_cache_dir() { From 2227de2940bf3a8077969d0299d147fea5cb1fc7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 2 Mar 2016 12:56:18 -0800 Subject: [PATCH 4116/4858] More precise regex --- features/bootstrap/FeatureContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index d2248100cb..b6897e4fb3 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -130,7 +130,7 @@ private static function terminate_proc( $proc ) { $output = `ps -o ppid,pid,command | grep $master_pid`; foreach ( explode( PHP_EOL, $output ) as $line ) { - if ( preg_match( '/^\s+?(\d+)\s+(\d+)/', $line, $matches ) ) { + if ( preg_match( '/^\s*(\d+)\s+(\d+)/', $line, $matches ) ) { $parent = $matches[1]; $child = $matches[2]; From 370a3cf43d5d5585934cc9108945f64ea96e0d74 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 05:20:13 -0800 Subject: [PATCH 4117/4858] Fix formatting of search-replace wildcard example Otherwise, the `*` is markdownified. --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c4088216b0..f8c9ee3183 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -38,7 +38,7 @@ class Search_Replace_Command extends WP_CLI_Command { * * [<table>...] * : List of database tables to restrict the replacement to. Wildcards are - * supported, e.g. 'wp_*_options' or 'wp_post*'. + * supported, e.g. `'wp_*_options'` or `'wp_post*'`. * * [--dry-run] * : Run the entire search/replace operation and show report, but don't save From 53e7c380b583fa7aba372aa647ddd6c125728756 Mon Sep 17 00:00:00 2001 From: Mark Kimsal <metrofindings@gmail.com> Date: Mon, 7 Mar 2016 12:49:25 -0500 Subject: [PATCH 4118/4858] Handle multi-column keys in search and replace The where clause was constructed without regard to handling multiple keys nor quoting values properly. The example table that the previous technique doesn't work with is wp_wp_super_edit_options which has a primary key on id and name. --- php/commands/search-replace.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c4088216b0..85fb80ea37 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -288,7 +288,8 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { foreach ( $rows as $keys ) { $where_sql = ''; foreach( (array) $keys as $k => $v ) { - $where_sql .= "{$k}={$v}"; + if (strlen($where_sql)) $where_sql .= ' AND '; + $where_sql .= "{$k}='{$v}'"; } $col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" ); if ( '' === $col_value ) From 6b700a74cb05a2653d5ce4a21dd93540a0347b56 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 10:31:29 -0800 Subject: [PATCH 4119/4858] Add package directory path to `wp cli info` See #1564 --- features/cli-info.feature | 16 ++++++++++++++++ php/WP_CLI/Runner.php | 20 +++++++++++++++----- php/commands/cli.php | 2 ++ 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 features/cli-info.feature diff --git a/features/cli-info.feature b/features/cli-info.feature new file mode 100644 index 0000000000..7d3fef3463 --- /dev/null +++ b/features/cli-info.feature @@ -0,0 +1,16 @@ +Feature: Review CLI information + + Scenario: Get the path to the packages directory + Given an empty directory + + When I run `wp cli info --format=json` + Then STDOUT should be JSON containing: + """ + {"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"} + """ + + When I run `WP_CLI_PACKAGES_DIR=/tmp/packages wp cli info --format=json` + Then STDOUT should be JSON containing: + """ + {"wp_cli_packages_dir_path":"/tmp/packages/"} + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6addd6403f..49f9f57d79 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -118,6 +118,20 @@ private function get_project_config_path() { return $project_config_path; } + /** + * Get the path to the packages directory + * + * @return string + */ + public function get_packages_dir_path() { + if ( getenv( 'WP_CLI_PACKAGES_DIR' ) ) { + $packages_dir = rtrim( getenv( 'WP_CLI_PACKAGES_DIR' ), '/' ) . '/'; + } else { + $packages_dir = getenv( 'HOME' ) . '/.wp-cli/packages/'; + } + return $packages_dir; + } + /** * Attempts to find the path to the WP install inside index.php * @@ -609,11 +623,7 @@ public function start() { // APIs as non-bundled commands. Utils\load_command( $this->arguments[0] ); - if ( getenv( 'WP_CLI_PACKAGES_DIR' ) ) { - $package_autoload = rtrim( getenv( 'WP_CLI_PACKAGES_DIR' ), '/' ) . '/vendor/autoload.php'; - } else { - $package_autoload = getenv( 'HOME' ) . '/.wp-cli/packages/vendor/autoload.php'; - } + $package_autoload = $this->get_packages_dir_path() . 'vendor/autoload.php'; if ( file_exists( $package_autoload ) ) { WP_CLI::debug( 'Loading packages from: ' . $package_autoload ); diff --git a/php/commands/cli.php b/php/commands/cli.php index f68e19d256..4c0d8b213b 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -55,6 +55,7 @@ public function info( $_, $assoc_args ) { 'global_config_path' => $runner->global_config_path, 'project_config_path' => $runner->project_config_path, 'wp_cli_dir_path' => WP_CLI_ROOT, + 'wp_cli_packages_dir_path' => $runner->get_packages_dir_path(), 'wp_cli_version' => WP_CLI_VERSION, ); @@ -64,6 +65,7 @@ public function info( $_, $assoc_args ) { WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); WP_CLI::line( "WP-CLI root dir:\t" . WP_CLI_ROOT ); + WP_CLI::line( "WP-CLI packages dir:\t" . $runner->get_packages_dir_path() ); WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); From 46a4d83f9d632d032a3a052fcd064006c0710704 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 10:40:15 -0800 Subject: [PATCH 4120/4858] Prefer Git (and other VCS) when installing packages This will make it easier for users to become contributors. --- php/commands/package.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/package.php b/php/commands/package.php index b4dd6df08a..df9ca34076 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -104,6 +104,7 @@ public function install( $args, $assoc_args ) { // Set up the installer $install = Installer::create( new ComposerIO, $composer ); $install->setUpdate( true ); // Installer class will only override composer.lock with this flag + $install->setPreferSource( true ); // Use VCS when VCS for easier contributions. // Try running the installer, but revert composer.json if failed WP_CLI::log( 'Using Composer to install the package...' ); From c7175faf7ad144dcbe53a580d24b78f825861332 Mon Sep 17 00:00:00 2001 From: Mark Kimsal <metrofindings@gmail.com> Date: Mon, 7 Mar 2016 13:42:27 -0500 Subject: [PATCH 4121/4858] Feature test for multi-column key search-replace --- features/search-replace.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index 0f98c95dc8..99ec9b0c0b 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -232,6 +232,18 @@ Feature: Do global search/replace """ And STDOUT should be empty + Scenario: Search and replace a table that has a multi-column primary key + Given a WP install + And I run `wp db query "CREATE TABLE wp_multicol ( "id" bigint(20) NOT NULL AUTO_INCREMENT,"name" varchar(60) NOT NULL,"value" text NOT NULL,PRIMARY KEY ("id","name"),UNIQUE KEY "name" ("name") ) ENGINE=InnoDB DEFAULT CHARSET=utf8 "` + And I run `wp db query "INSERT INTO wp_multicol VALUES (1, 'foo', 'bar')"` + And I run `wp db query "INSERT INTO wp_multicol VALUES (2, 'bar', 'foo')"` + + When I run `wp search-replace bar replaced wp_multicol` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_multicol | name | 1 | SQL | + | wp_multicol | value | 1 | SQL | + Scenario Outline: Large guid search/replace where replacement contains search (or not) Given a WP install And I run `wp option get siteurl` From 4abe4ebd755007cd4c220241a166b64ca6e592d4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 10:44:11 -0800 Subject: [PATCH 4122/4858] Quote example in `wp search-replace` instead of escaping Quotes are more friendly and understandable to end users. --- php/commands/search-replace.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index f8c9ee3183..9a2d1703ff 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -87,7 +87,7 @@ class Search_Replace_Command extends WP_CLI_Command { * 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 + * 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 From 9d37a5ca728e47fa179e9bd3bdd5b31782f6dbbe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 12:11:59 -0800 Subject: [PATCH 4123/4858] Support nightly builds with `wp cli check-update` If there are no major, minor, or patch updates available, let's assume the user is running a nightly build for the latest release. If they're running a nightly build for the latest release, we can compare their current hash to the latest nightly build hash. When they differ, we can assume the latest nightly build is more recent than the local copy. --- php/commands/cli.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index 4c0d8b213b..a6e2529905 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -274,6 +274,33 @@ private function get_updates( $assoc_args ) { return ! empty( $updates[ $type ] ) ? array( $updates[ $type ] ) : false; } } + + if ( empty( $updates ) && preg_match( '#-alpha-(.+)$#', WP_CLI_VERSION, $matches ) ) { + $url = 'https://api.github.com/repos/wp-cli/wp-cli/git/refs/heads/master'; + + $response = Utils\http_request( 'GET', $url, $headers, $options ); + + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( sprintf( "Failed to get master hash (HTTP code %d)", $response->status_code ) ); + } + + $latest_hash_data = json_decode( $response->body ); + $latest_short_hash = substr( $latest_hash_data->object->sha, 0, 7 ); + + if ( $latest_short_hash != $matches[1] ) { + $version_url = 'https://raw.githubusercontent.com/wp-cli/wp-cli/master/VERSION'; + $response = Utils\http_request( 'GET', $version_url ); + if ( ! $response->success || 200 !== $response->status_code ) { + WP_CLI::error( sprintf( "Failed to get current version (HTTP code %d)", $response->status_code ) ); + } + $updates['nightly'] = array( + 'version' => trim( $response->body ) . '-' . $latest_short_hash, + 'update_type' => 'nightly', + 'package_url' => 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar', + ); + } + } + return array_values( $updates ); } From 39960263196ecff386ccc44f37afe3a211e80843 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 12:20:21 -0800 Subject: [PATCH 4124/4858] Store nightly version on deploy When we want to reference the built version, this is easier than recreating it on our own. See https://github.com/wp-cli/wp-cli/pull/2536 --- ci/deploy.sh | 3 ++- ci/prepare.sh | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index 45de26a955..b9b109b276 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -22,6 +22,7 @@ set -x echo "|1|qPmmP7LVZ7Qbpk7AylmkfR0FApQ=|WUy1WS3F4qcr3R5Sc728778goPw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts git clone git@github.com:wp-cli/builds.git +mv PHAR_BUILD_VERSION builds/phar/NIGHTLY_VERSION cd builds git config user.name "Travis CI" @@ -36,7 +37,7 @@ chmod -x $fname md5sum $fname | cut -d ' ' -f 1 > $fname.md5 sha512sum $fname | cut -d ' ' -f 1 > $fname.sha512 -git add $fname $fname.md5 $fname.sha512 +git add $fname $fname.md5 $fname.sha512 NIGHTLY_VERSION git commit -m "phar build: $TRAVIS_REPO_SLUG@$TRAVIS_COMMIT" git push diff --git a/ci/prepare.sh b/ci/prepare.sh index a64af0f673..f2fea77e5a 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -27,6 +27,8 @@ else chmod +x $WP_CLI_BIN_DIR/wp fi +echo $CLI_VERSION > PHAR_BUILD_VERSION + # Install CodeSniffer things ./ci/prepare-codesniffer.sh From c8e580a9bd64769dfe7da4dc3ce2e07307b4bee6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 13:18:09 -0800 Subject: [PATCH 4125/4858] Make `wp package install` more verbose * Update `WP_CLI\ComposerIO` to write error messages too. * Display return code when Composer installer returns one. --- php/WP_CLI/ComposerIO.php | 14 +++++++++++++- php/commands/package.php | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/ComposerIO.php b/php/WP_CLI/ComposerIO.php index b4df56a7b2..01197c9226 100644 --- a/php/WP_CLI/ComposerIO.php +++ b/php/WP_CLI/ComposerIO.php @@ -21,7 +21,19 @@ public function isVerbose() { * {@inheritDoc} */ public function write( $messages, $newline = true ) { - WP_CLI::log( " - " . strip_tags( $messages ) ); + self::output_clean_message( $messages ); + } + + /** + * {@inheritDoc} + */ + public function writeError( $messages, $newline = true ) { + self::output_clean_message( $messages ); + } + + private static function output_clean_message( $message ) { + $message = preg_replace( '#<(https?)([^>]+)>#', '$1$2', $message ); + WP_CLI::log( strip_tags( trim( $message ) ) ); } } diff --git a/php/commands/package.php b/php/commands/package.php index df9ca34076..1141d9d8ee 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -108,17 +108,19 @@ public function install( $args, $assoc_args ) { // Try running the installer, but revert composer.json if failed WP_CLI::log( 'Using Composer to install the package...' ); + WP_CLI::log( '---' ); try { $res = $install->run(); } catch ( Exception $e ) { WP_CLI::warning( $e->getMessage() ); } + WP_CLI::log( '---' ); if ( 0 === $res ) { WP_CLI::success( "Package installed successfully." ); } else { file_put_contents( $composer_json_obj->getPath(), $composer_backup ); - WP_CLI::error( "Package installation failed. Reverted composer.json" ); + WP_CLI::error( "Package installation failed (Composer return code {$res}). Reverted composer.json" ); } } From 8af196a26302d9359e62d5580eca8714b8791965 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 13:53:38 -0800 Subject: [PATCH 4126/4858] Add the proper path when including NIGHTLY_VERSION --- ci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deploy.sh b/ci/deploy.sh index b9b109b276..7a7dab1925 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -37,7 +37,7 @@ chmod -x $fname md5sum $fname | cut -d ' ' -f 1 > $fname.md5 sha512sum $fname | cut -d ' ' -f 1 > $fname.sha512 -git add $fname $fname.md5 $fname.sha512 NIGHTLY_VERSION +git add $fname $fname.md5 $fname.sha512 phar/NIGHTLY_VERSION git commit -m "phar build: $TRAVIS_REPO_SLUG@$TRAVIS_COMMIT" git push From 1aff63bdf14f680e28077736e0fa8425570c29f3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 14:42:56 -0800 Subject: [PATCH 4127/4858] Use one HTTP request instead of two --- php/commands/cli.php | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index a6e2529905..4446d5f802 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -276,25 +276,15 @@ private function get_updates( $assoc_args ) { } if ( empty( $updates ) && preg_match( '#-alpha-(.+)$#', WP_CLI_VERSION, $matches ) ) { - $url = 'https://api.github.com/repos/wp-cli/wp-cli/git/refs/heads/master'; - - $response = Utils\http_request( 'GET', $url, $headers, $options ); - + $version_url = 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/NIGHTLY_VERSION'; + $response = Utils\http_request( 'GET', $version_url ); if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( sprintf( "Failed to get master hash (HTTP code %d)", $response->status_code ) ); + WP_CLI::error( sprintf( "Failed to get current nightly version (HTTP code %d)", $response->status_code ) ); } - - $latest_hash_data = json_decode( $response->body ); - $latest_short_hash = substr( $latest_hash_data->object->sha, 0, 7 ); - - if ( $latest_short_hash != $matches[1] ) { - $version_url = 'https://raw.githubusercontent.com/wp-cli/wp-cli/master/VERSION'; - $response = Utils\http_request( 'GET', $version_url ); - if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( sprintf( "Failed to get current version (HTTP code %d)", $response->status_code ) ); - } + $nightly_version = trim( $response->body ); + if ( WP_CLI_VERSION != $nightly_version ) { $updates['nightly'] = array( - 'version' => trim( $response->body ) . '-' . $latest_short_hash, + 'version' => $nightly_version, 'update_type' => 'nightly', 'package_url' => 'https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar', ); From 959b8c6b589580658756cc438e015c5dd9c519b1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 14:45:25 -0800 Subject: [PATCH 4128/4858] Coding standards for #2531 --- php/commands/search-replace.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c583bda7e7..812258badd 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -288,7 +288,9 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { foreach ( $rows as $keys ) { $where_sql = ''; foreach( (array) $keys as $k => $v ) { - if (strlen($where_sql)) $where_sql .= ' AND '; + if ( strlen( $where_sql ) ) { + $where_sql .= ' AND '; + } $where_sql .= "{$k}='{$v}'"; } $col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" ); From dfd3cbcd2a37124a3d8f30aac5c499e2be48228f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 15:48:50 -0800 Subject: [PATCH 4129/4858] Nag user when there's an update to WP-CLI available Auto check update only happens when a user is driving WP-CLI, not a script. `WP_CLI_AUTO_CHECK_UPDATE_DAYS` environment variable can be used to change the number of days between checks (defaults to 1). `WP_CLI_DISABLE_AUTO_CHECK_UPDATE` can be used to disable the update check entirely. --- php/WP_CLI/Runner.php | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 49f9f57d79..a8467db9b8 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -675,6 +675,7 @@ public function start() { // First try at showing man page if ( ! empty( $this->arguments[0] ) && 'help' === $this->arguments[0] && ( ! $this->wp_exists() || ! Utils\locate_wp_config() || ( ! empty( $this->arguments[1] ) && ! empty( $this->arguments[2] ) && 'core' === $this->arguments[1] && in_array( $this->arguments[2], array( 'config', 'install', 'multisite-install', 'verify-checksums', 'version' ) ) ) ) ) { + $this->auto_check_update(); $this->_run_command(); } @@ -860,5 +861,62 @@ private function maybe_update_url_from_domain_constant() { } } + /** + * Check whether there's a WP-CLI update available, and suggest update if so. + */ + private function auto_check_update() { + + // `wp cli update` only works with Phars at this time. + if ( ! Utils\inside_phar() ) { + return; + } + + // Only check for update when a human is operating. + if ( ! function_exists( 'posix_isatty' ) || ! posix_isatty( STDOUT ) ) { + return; + } + + // Allow hosts and other providers to disable automatic check update. + if ( getenv( 'WP_CLI_DISABLE_AUTO_CHECK_UPDATE' ) ) { + return; + } + + // Permit configuration of number of days between checks. + $days_between_checks = getenv( 'WP_CLI_AUTO_CHECK_UPDATE_DAYS' ); + if ( false === $days_between_checks ) { + $days_between_checks = 1; + } + + $cache = WP_CLI::get_cache(); + $cache_key = 'wp-cli-update-check'; + // Bail early on the first check, so we don't always check on an unwritable cache. + if ( ! $cache->has( $cache_key ) ) { + $cache->write( $cache_key, time() ); + return; + } + + // Bail if last check is still within our update check time period. + $last_check = (int) $cache->read( $cache_key ); + if ( time() - ( 24 * 60 * 60 * $days_between_checks ) < $last_check ) { + return; + } + + // In case the operation fails, ensure the timestamp has been updated. + $cache->write( $cache_key, time() ); + + // Check whether any updates are available. + ob_start(); + WP_CLI::run_command( array( 'cli', 'check-update' ), array( 'format' => 'count' ) ); + $count = ob_get_clean(); + if ( ! $count ) { + return; + } + + // Looks like an update is available, so let's prompt to update. + WP_CLI::run_command( array( 'cli', 'update' ) ); + // If the Phar was replaced, we can't proceed with the original process. + exit; + } + } From 960754295940f136b3842e6e5d515b3c297dccba Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 15:54:53 -0800 Subject: [PATCH 4130/4858] Bail early when the Phar isn't writable --- php/WP_CLI/Runner.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a8467db9b8..628a9a67f0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -871,6 +871,12 @@ private function auto_check_update() { return; } + $existing_phar = realpath( $_SERVER['argv'][0] ); + // Phar needs to be writable to be easily updateable. + if ( ! is_writable( $existing_phar ) || ! is_writeable( dirname( $existing_phar ) ) ) { + return; + } + // Only check for update when a human is operating. if ( ! function_exists( 'posix_isatty' ) || ! posix_isatty( STDOUT ) ) { return; From 649ee18570fd460d74c5fddb02da1f4e34fcd4dc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 16:00:16 -0800 Subject: [PATCH 4131/4858] PHAR_BUILD_VERSION shouldn't ever be committed to this repo [ci skip] --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0d5a442ae4..6f48837621 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ config.yml +PHAR_BUILD_VERSION /cache /packages /vendor From aef52173f29fc9bc397b57cd54bb43c3d804641f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 16:09:17 -0800 Subject: [PATCH 4132/4858] Remove `wp scaffold package-tests` It's been broken in a while, and is now included in https://github.com/wp-cli/scaffold-package-command --- features/scaffold.feature | 74 -------------------- php/commands/scaffold.php | 105 ----------------------------- templates/.travis.package.yml | 24 ------- templates/install-package-tests.sh | 54 --------------- templates/load-wp-cli.feature | 10 --- utils/make-phar.php | 1 - 6 files changed, 268 deletions(-) delete mode 100644 templates/.travis.package.yml delete mode 100644 templates/install-package-tests.sh delete mode 100644 templates/load-wp-cli.feature diff --git a/features/scaffold.feature b/features/scaffold.feature index cc0316dbcf..e7ddedaa8e 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -219,80 +219,6 @@ Feature: WordPress code scaffolding executable """ - Scenario: Scaffold package tests - Given a WP install - Given a community-command/command.php file: - """ - <?php - """ - And a community-command/composer.json file: - """ - { - "name": "wp-cli/community-command", - "description": "A demo community command.", - "license": "MIT", - "minimum-stability": "dev", - "require": { - }, - "autoload": { - "files": [ "dictator.php" ] - }, - "require-dev": { - "behat/behat": "~2.5" - } - } - """ - And a invalid-command/command.php file: - """ - <?php - """ - - When I run `wp scaffold package-tests community-command` - Then STDOUT should not be empty - And the community-command/.travis.yml file should exist - And the community-command/bin/install-package-tests.sh file should exist - And the community-command/utils/behat-tags.php file should contain: - """ - require-wp - """ - And the community-command/utils/get-package-require-from-composer.php file should exist - And the community-command/features directory should contain: - """ - bootstrap - extra - load-wp-cli.feature - steps - """ - And the community-command/features/bootstrap directory should contain: - """ - FeatureContext.php - Process.php - support.php - utils.php - """ - And the community-command/features/steps directory should contain: - """ - given.php - then.php - when.php - """ - And the community-command/features/extra directory should contain: - """ - no-mail.php - """ - - When I run `wp eval "if ( is_executable( 'community-command/bin/install-package-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` - Then STDOUT should be: - """ - executable - """ - - When I try `wp scaffold package-tests invalid-command` - Then STDERR should be: - """ - Error: Invalid package directory. composer.json file must be present. - """ - Scenario: Scaffold starter code for a theme Given a WP install Given I run `wp theme path` diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 1df51eb1b0..ed2524c46d 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -370,111 +370,6 @@ private function get_output_path( $assoc_args, $subdir ) { return $path; } - /** - * Generate files needed for writing Behat tests for your command. - * - * ## DESCRIPTION - * - * These are the files that are generated: - * - * * `.travis.yml` is the configuration file for Travis CI - * * `bin/install-package-tests.sh` will configure environment to run tests. Script expects WP_CLI_BIN_DIR and WP_CLI_CONFIG_PATH environment variables. - * * `features/load-wp-cli.feature` is a basic test to confirm WP-CLI can load. - * * `features/bootstrap`, `features/steps`, `features/extra` are Behat configuration files. - * * `utils/generate-package-require-from-composer.php` generates a test config.yml file from your package's composer.json - * - * ## ENVIRONMENT - * - * The `features/bootstrap/FeatureContext.php` file expects the WP_CLI_BIN_DIR and WP_CLI_CONFIG_PATH environment variables. - * - * WP-CLI Behat framework uses Behat ~2.5. - * - * ## OPTIONS - * - * <dir> - * : The package directory to generate tests for. - * - * [--force] - * : Overwrite files that already exist. - * - * ## EXAMPLE - * - * wp scaffold package-tests /path/to/command/dir/ - * - * @when before_wp_load - * @subcommand package-tests - */ - public function package_tests( $args, $assoc_args ) { - - list( $package_dir ) = $args; - - if ( is_file( $package_dir ) ) { - $package_dir = dirname( $package_dir ); - } else if ( is_dir( $package_dir ) ) { - $package_dir = rtrim( $package_dir, '/' ); - } - - if ( ! is_dir( $package_dir ) || ! file_exists( $package_dir . '/composer.json' ) ) { - WP_CLI::error( "Invalid package directory. composer.json file must be present." ); - } - - $package_dir .= '/'; - $bin_dir = $package_dir . 'bin/'; - $utils_dir = $package_dir . 'utils/'; - $features_dir = $package_dir . 'features/'; - $bootstrap_dir = $features_dir . 'bootstrap/'; - $steps_dir = $features_dir . 'steps/'; - $extra_dir = $features_dir . 'extra/'; - foreach ( array( $features_dir, $bootstrap_dir, $steps_dir, $extra_dir, $utils_dir, $bin_dir ) as $dir ) { - if ( ! is_dir( $dir ) ) { - Process::create( Utils\esc_cmd( 'mkdir %s', $dir ) )->run(); - } - } - - $to_copy = array( - 'templates/.travis.package.yml' => $package_dir, - 'templates/load-wp-cli.feature' => $features_dir, - 'templates/install-package-tests.sh' => $bin_dir, - 'features/bootstrap/FeatureContext.php' => $bootstrap_dir, - 'features/bootstrap/support.php' => $bootstrap_dir, - 'php/WP_CLI/Process.php' => $bootstrap_dir, - 'php/utils.php' => $bootstrap_dir, - 'ci/behat-tags.php' => $utils_dir, - 'utils/get-package-require-from-composer.php' => $utils_dir, - 'features/steps/given.php' => $steps_dir, - 'features/steps/when.php' => $steps_dir, - 'features/steps/then.php' => $steps_dir, - 'features/extra/no-mail.php' => $extra_dir, - ); - - $files_written = array(); - foreach ( $to_copy as $file => $dir ) { - // file_get_contents() works with Phar-archived files - $contents = file_get_contents( WP_CLI_ROOT . "/{$file}" ); - $file_path = $dir . basename( $file ); - $file_path = str_replace( array( '.travis.package.yml' ), array( '.travis.yml' ), $file_path ); - - $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); - $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path, $force ); - if ( ! $should_write_file ) { - continue; - } - $files_written[] = $file_path; - - $result = Process::create( Utils\esc_cmd( 'touch %s', $file_path ) )->run(); - file_put_contents( $file_path, $contents ); - if ( 'templates/install-package-tests.sh' === $file ) { - Process::create( Utils\esc_cmd( 'chmod +x %s', $file_path ) )->run(); - } - } - $this->log_whether_files_written( - $files_written, - $skip_message = 'All package tests were skipped.', - $success_message = 'Created test files.' - ); - - } - /** * Generate starter code for a plugin. * diff --git a/templates/.travis.package.yml b/templates/.travis.package.yml deleted file mode 100644 index bb11edec43..0000000000 --- a/templates/.travis.package.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: php - -notifications: - email: - on_success: never - on_failure: change - -branches: - only: - - master - -php: - - 5.3 - - 5.6 - -env: - global: - - WP_CLI_BIN_DIR=/tmp/wp-cli-phar - - WP_CLI_CONFIG_PATH=/tmp/wp-cli-phar/config.yml - -before_script: - - bash bin/install-package-tests.sh - -script: ./vendor/bin/behat diff --git a/templates/install-package-tests.sh b/templates/install-package-tests.sh deleted file mode 100644 index 37fa695251..0000000000 --- a/templates/install-package-tests.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -PACKAGE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../ && pwd )" - -download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi -} - -install_wp_cli() { - - # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR - mkdir -p $WP_CLI_BIN_DIR - download https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli-nightly.phar $WP_CLI_BIN_DIR/wp - chmod +x $WP_CLI_BIN_DIR/wp - -} - -set_package_context() { - - touch $WP_CLI_CONFIG_PATH - printf 'require:' > $WP_CLI_CONFIG_PATH - requires=$(php $PACKAGE_DIR/utils/get-package-require-from-composer.php composer.json) - for require in "${requires[@]}" - do - printf "\n%2s-%1s$PACKAGE_DIR/$require" >> $WP_CLI_CONFIG_PATH - done - printf "\n" >> $WP_CLI_CONFIG_PATH - -} - -download_behat() { - - cd $PACKAGE_DIR - download https://getcomposer.org/installer installer - php installer - php composer.phar require --dev behat/behat='~2.5' - -} - -install_db() { - mysql -e 'CREATE DATABASE IF NOT EXISTS wp_cli_test;' -uroot - mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot -} - -install_wp_cli -set_package_context -download_behat -install_db diff --git a/templates/load-wp-cli.feature b/templates/load-wp-cli.feature deleted file mode 100644 index 035b86730d..0000000000 --- a/templates/load-wp-cli.feature +++ /dev/null @@ -1,10 +0,0 @@ -Feature: Test that WP-CLI loads. - - Scenario: WP-CLI loads for your tests - Given a WP install - - When I run `wp eval 'echo "Hello world.";'` - Then STDOUT should contain: - """ - Hello world. - """ diff --git a/utils/make-phar.php b/utils/make-phar.php index 3c32064164..30c261c11c 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -101,7 +101,6 @@ function set_file_contents( $phar, $path, $content ) { add_file( $phar, WP_CLI_ROOT . '/ci/behat-tags.php' ); add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/LICENSE' ); add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/res/composer-schema.json' ); -add_file( $phar, WP_CLI_ROOT . '/utils/get-package-require-from-composer.php' ); add_file( $phar, WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); set_file_contents( $phar, WP_CLI_ROOT . '/VERSION', $current_version ); From 0a04bc51a9bbb8eb6c0578f012686affbb3326e3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 7 Mar 2016 16:48:31 -0800 Subject: [PATCH 4133/4858] `wp package browse` should list all available versions --- php/commands/package.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 1141d9d8ee..a0027b0396 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -265,14 +265,24 @@ private function show_packages( $packages, $assoc_args ) { $list = array(); foreach ( $packages as $package ) { - $package_output = new stdClass; - $package_output->name = $package->getName(); - $package_output->description = $package->getDescription(); - $package_output->authors = implode( ', ', array_column( (array) $package->getAuthors(), 'name' ) ); - $package_output->version = $package->getPrettyVersion(); - $list[$package_output->name] = $package_output; + $name = $package->getName(); + if ( isset( $list[ $name ] ) ) { + $list[ $name ]->version[] = $package->getPrettyVersion(); + } else { + $package_output = new stdClass; + $package_output->name = $package->getName(); + $package_output->description = $package->getDescription(); + $package_output->authors = implode( ', ', array_column( (array) $package->getAuthors(), 'name' ) ); + $package_output->version = array( $package->getPrettyVersion() ); + $list[ $package_output->name ] = $package_output; + } } + $list = array_map( function( $package ){ + $package->version = implode( ', ', $package->version ); + return $package; + }, $list ); + ksort( $list ); WP_CLI\Utils\format_items( $assoc_args['format'], $list, $assoc_args['fields'] ); } From 4fe5c5a483cd4032a457881b76bba40bd9c0f559 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 8 Mar 2016 12:40:16 -0800 Subject: [PATCH 4134/4858] Clean up `wp package` PHPDoc; support `--format=ids` --- php/commands/package.php | 43 ++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index a0027b0396..2dc50ae0e1 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -17,7 +17,7 @@ use \WP_CLI\ComposerIO; /** - * Manage WP-CLI community packages. + * Manage WP-CLI packages. * * @package WP-CLI * @@ -35,24 +35,26 @@ class Package_Command extends WP_CLI_Command { ); /** - * Browse available WP-CLI community packages. + * Browse WP-CLI packages available for installation. + * + * Lists packages available for installation from the [Package Index](http://wp-cli.org/package-index/). * * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Accepted values: table, json, csv, yaml, ids. Default: table. */ public function browse( $_, $assoc_args ) { $this->show_packages( $this->get_community_packages(), $assoc_args ); } /** - * Install a WP-CLI community package. + * Install a WP-CLI package. * * ## OPTIONS * - * <package> - * : The name of the package to install. Can optionally contain a version constraint. + * <name> + * : Name of the package to install. Can optionally contain a version constraint. * * ## EXAMPLES * @@ -125,12 +127,12 @@ public function install( $args, $assoc_args ) { } /** - * List installed WP-CLI community packages. + * List installed WP-CLI packages. * * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Accepted values: table, json, csv, yaml, ids. Default: table * * @subcommand list */ @@ -139,12 +141,12 @@ public function list_( $args, $assoc_args ) { } /** - * Uninstall a WP-CLI community package. + * Uninstall a WP-CLI package. * * ## OPTIONS * - * <package> - * : The name of the package to uninstall. + * <name> + * : Name of the package to uninstall. */ public function uninstall( $args ) { list( $package_name ) = $args; @@ -267,23 +269,26 @@ private function show_packages( $packages, $assoc_args ) { foreach ( $packages as $package ) { $name = $package->getName(); if ( isset( $list[ $name ] ) ) { - $list[ $name ]->version[] = $package->getPrettyVersion(); + $list[ $name ]['version'][] = $package->getPrettyVersion(); } else { - $package_output = new stdClass; - $package_output->name = $package->getName(); - $package_output->description = $package->getDescription(); - $package_output->authors = implode( ', ', array_column( (array) $package->getAuthors(), 'name' ) ); - $package_output->version = array( $package->getPrettyVersion() ); - $list[ $package_output->name ] = $package_output; + $package_output = array(); + $package_output['name'] = $package->getName(); + $package_output['description'] = $package->getDescription(); + $package_output['authors'] = implode( ', ', array_column( (array) $package->getAuthors(), 'name' ) ); + $package_output['version'] = array( $package->getPrettyVersion() ); + $list[ $package_output['name'] ] = $package_output; } } $list = array_map( function( $package ){ - $package->version = implode( ', ', $package->version ); + $package['version'] = implode( ', ', $package['version'] ); return $package; }, $list ); ksort( $list ); + if ( 'ids' === $assoc_args['format'] ) { + $list = array_keys( $list ); + } WP_CLI\Utils\format_items( $assoc_args['format'], $list, $assoc_args['fields'] ); } From 29cedaf6379e70463aae07e390346bfd12f9e0f5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 8 Mar 2016 13:36:31 -0800 Subject: [PATCH 4135/4858] Move Contributing details to their own doc pages [ci skip] --- CONTRIBUTING.md | 72 +------------------------------------------------ 1 file changed, 1 insertion(+), 71 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 415dc8c24a..1ceb46a615 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,74 +1,4 @@ Contribute ========== -Setting up ----------- - -1. Clone this git repository on your local machine. -2. Install [Composer](https://getcomposer.org/) if you don't already have it. -2. Run `composer install` to fetch all the dependencies. -3. Run `./bin/wp --info` to test if everything was installed properly. - -Submitting patches ------------------- - -Whether you want to fix a bug or implement a new feature, the process is pretty much the same: - -0. [Search existing issues](https://github.com/wp-cli/wp-cli/issues); if you can't find anything related to what you want to work on, [open a new issue](https://github.com/wp-cli/wp-cli/wiki/Creating-Helpful-Bug-Reports) so that you can get some initial feedback. -1. [Fork](https://github.com/wp-cli/wp-cli/fork) the repository. -2. Create a branch for each issue you'd like to address. Commit your changes. -3. Push the code changes from your local clone to your fork. -4. Open a pull request. - -It doesn't matter if the code isn't perfect. The idea is to get it reviewed early and iterate on it. - -If you're adding a new feature, please add one or more functional tests for it in the `features/` directory. See below. - -Lastly, please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/). - -Running and writing tests -------------------------- - -There are two types of automated tests: - -* unit tests, implemented using [PHPUnit](http://phpunit.de/) -* functional tests, implemented using [Behat](http://behat.org) - -### Unit tests - -The unit test files are in the `tests/` directory. - -To run the unit tests, just execute: - -```bash -./vendor/bin/phpunit -``` - -### Functional tests - -The functional test files are in the `features/` directory. - -Before running the functional tests, you'll need a MySQL (or MariaDB) user called `wp_cli_test` with the password `password1` that has full privileges on the MySQL database `wp_cli_test`. Running the following as root in MySQL should do the trick: - -```sql -GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"; -``` - -Then, to run the entire test suite: - -```bash -./vendor/bin/behat --expand -``` - -Or to test a single feature: - -```bash -./vendor/bin/behat features/core.feature -``` - -More info can be found by using `./vendor/bin/behat --help`. - -Finally... ----------- - -Thanks! Hacking on WP-CLI should be fun. If you find any of this hard to figure out, let us know so we can improve our process or documentation! +Thanks in advance for helping to improve WP-CLI. To get started, please review our documentation on [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). From 460acdaf93ccccdeca6d2e7e17b33309735c7e4e Mon Sep 17 00:00:00 2001 From: jacobischwartz <jacob@schwambell.com> Date: Tue, 8 Mar 2016 16:01:35 -0600 Subject: [PATCH 4136/4858] Initial idea for carrying list of imported posts through to subsequent import files in a batch. --- php/commands/import.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/import.php b/php/commands/import.php index 40b9c31bf6..16372d6bb3 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -2,6 +2,8 @@ class Import_Command extends WP_CLI_Command { + var $processed_posts = array(); + /** * Import content from a WXR file. * @@ -69,6 +71,7 @@ public function __invoke( $args, $assoc_args ) { private function import_wxr( $file, $args ) { $wp_import = new WP_Import; + $wp_import->processed_posts = $this->processed_posts; $import_data = $wp_import->parse( $file ); if ( is_wp_error( $import_data ) ) return $import_data; @@ -138,6 +141,7 @@ private function import_wxr( $file, $args ) { } $wp_import->import( $file ); + $this->processed_posts = array_merge($this->processed_posts, $wp_import->processed_posts); return true; } From b87bd9174a1fb45b83c25df7feefc1341ff03b7f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 8 Mar 2016 15:30:44 -0800 Subject: [PATCH 4137/4858] Failing test case for #2493 --- features/package-install.feature | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 features/package-install.feature diff --git a/features/package-install.feature b/features/package-install.feature new file mode 100644 index 0000000000..d883aafd0e --- /dev/null +++ b/features/package-install.feature @@ -0,0 +1,20 @@ +Feature: Install WP-CLI packages + + Scenario: Install a package with 'wp-cli/wp-cli' as a dependency + Given a WP install + + When I run `wp package install sinebridge/wp-cli-about:v1.0.1` + Then STDOUT should contain: + """ + Success: Package installed + """ + And STDOUT should not contain: + """ + requires wp-cli/wp-cli + """ + + When I run `wp about` + Then STDOUT should contain: + """ + Site Information + """ From b86a90a476554dc66cfe4d4dced90e026f9f466e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 8 Mar 2016 15:35:00 -0800 Subject: [PATCH 4138/4858] Use 'wp-cli/wp-cli' for the Composer project name in our package dir Apparently this causes Composer to skip 'wp-cli/wp-cli' as a dependency, which is exactly what we want. --- php/commands/package.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/package.php b/php/commands/package.php index 2dc50ae0e1..27f14c3174 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -91,6 +91,7 @@ public function install( $args, $assoc_args ) { WP_CLI::log( sprintf( "Updating %s to require the package...", $composer_json_obj->getPath() ) ); $composer_backup = file_get_contents( $composer_json_obj->getPath() ); $json_manipulator = new JsonManipulator( $composer_backup ); + $json_manipulator->addMainKey( 'name', 'wp-cli/wp-cli' ); $json_manipulator->addLink( 'require', $package_name, $version ); file_put_contents( $composer_json_obj->getPath(), $json_manipulator->getContents() ); try { @@ -413,7 +414,7 @@ private function create_default_composer_json( $composer_path ) { ); $options = array( - 'name' => 'wp-cli/wp-cli-community-packages', + 'name' => 'wp-cli/wp-cli', 'description' => 'Installed community packages used by WP-CLI', 'authors' => array( $author ), 'homepage' => self::PACKAGE_INDEX_URL, From a279f661f29aade58b767b31983cb8673f67b315 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 8 Mar 2016 16:30:30 -0800 Subject: [PATCH 4139/4858] Use `wp package path` to get the path of an installed package If you want to contribute to one, this is an easy way to dive in. --- php/commands/package.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/php/commands/package.php b/php/commands/package.php index 27f14c3174..8f7c651048 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -141,6 +141,31 @@ public function list_( $args, $assoc_args ) { $this->show_packages( $this->get_installed_packages(), $assoc_args ); } + /** + * Get the path to an installed WP-CLI package, or the package directory. + * + * If you want to contribute to a package, this is a great way to jump to it. + * + * ## OPTIONS + * + * [<name>] + * : Name of the package to get the directory for. + * + * ## EXAMPLES + * + * cd $(wp package path) + */ + function path( $args ) { + $packages_dir = WP_CLI::get_runner()->get_packages_dir_path(); + if ( ! empty( $args ) ) { + $packages_dir .= 'vendor/' . $args[0]; + if ( ! is_dir( $packages_dir ) ) { + WP_CLI::error( 'Invalid package name.' ); + } + } + WP_CLI::line( $packages_dir ); + } + /** * Uninstall a WP-CLI package. * From 0bcd2fe28131eee400ed4c9646944fa63fb2821d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 8 Mar 2016 16:53:03 -0800 Subject: [PATCH 4140/4858] Newline is better formatting [ci skip] --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1ceb46a615..e6bb879c56 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,6 @@ Contribute ========== -Thanks in advance for helping to improve WP-CLI. To get started, please review our documentation on [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). +Thanks in advance for helping to improve WP-CLI. + +To get started, please review our documentation on [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). From b9a9e0144a6cf3a4befc4849472c37fba53df1ad Mon Sep 17 00:00:00 2001 From: Mike Pretzlaw <pretzlaw@gmail.com> Date: Wed, 9 Mar 2016 19:47:47 +0100 Subject: [PATCH 4141/4858] Bugfix: Vendor-dir is defined in the config-section The composer-vendor-dir can be defined in the config section of the composer.json. Unfortunately the utils.php looks up the vendor dir at another place. This commit fixes the flaw in ::get_vendor_paths(). --- php/utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/utils.php b/php/utils.php index d8b30f9131..67c7093647 100644 --- a/php/utils.php +++ b/php/utils.php @@ -62,8 +62,8 @@ function get_vendor_paths() { $maybe_composer_json = WP_CLI_ROOT . '/../../../composer.json'; if ( file_exists( $maybe_composer_json ) && is_readable( $maybe_composer_json ) ) { $composer = json_decode( file_get_contents( $maybe_composer_json ) ); - if ( ! empty( $composer->{'vendor-dir'} ) ) { - array_unshift( $vendor_paths, WP_CLI_ROOT . '/../../../' . $composer->{'vendor-dir'} ); + if ( ! empty( $composer->config ) && ! empty( $composer->config->{'vendor-dir'} ) ) { + array_unshift( $vendor_paths, WP_CLI_ROOT . '/../../../' . $composer->config->{'vendor-dir'} ); } } return $vendor_paths; From 85e0813157bc3ceb117ce24b711c56d8e7fe9d2a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Mar 2016 05:04:26 -0800 Subject: [PATCH 4142/4858] Add WP REST API registration args to `scaffold (post-type|taxonomy)` These are pretty well-established now. --- templates/post_type.mustache | 3 +++ templates/taxonomy.mustache | 3 +++ 2 files changed, 6 insertions(+) diff --git a/templates/post_type.mustache b/templates/post_type.mustache index a86f731310..02f96e1978 100644 --- a/templates/post_type.mustache +++ b/templates/post_type.mustache @@ -23,4 +23,7 @@ 'rewrite' => true, 'query_var' => true, 'menu_icon' => 'dashicons-{{dashicon}}', + 'show_in_rest' => true, + 'rest_base' => '{{slug}}', + 'rest_controller_class' => 'WP_REST_Posts_Controller', ) ); diff --git a/templates/taxonomy.mustache b/templates/taxonomy.mustache index e47807605b..549c46ed24 100644 --- a/templates/taxonomy.mustache +++ b/templates/taxonomy.mustache @@ -30,4 +30,7 @@ 'not_found' => __( 'No {{label_plural}} found.', '{{textdomain}}' ), 'menu_name' => __( '{{label_plural_ucfirst}}', '{{textdomain}}' ), ), + 'show_in_rest' => true, + 'rest_base' => '{{slug}}', + 'rest_controller_class' => 'WP_REST_Terms_Controller', ) ); From 2002b537dcfeccb9735df590757ebc3fdab06aa6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Mar 2016 17:08:45 -0800 Subject: [PATCH 4143/4858] Permit composer/semver >= 1.0 for greater flexibility --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 33a8b6f9a6..7cae33f61d 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "mustangostang/spyc": "0.5.1", - "composer/semver": "1.0.0", + "composer/semver": "~1.0", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", "symfony/finder": "2.7.*", From e5ff5d527d4282e57b114c31eda1b7451622864b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Mar 2016 17:09:41 -0800 Subject: [PATCH 4144/4858] Update Composer dependencies across the board --- composer.lock | 136 ++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/composer.lock b/composer.lock index e0301b5343..2a6b72b4bb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "78165aafa4140e764d4f1dc828752cce", - "content-hash": "7b6ae0fa1f96555e592ce2f48493a535", + "hash": "3ce120babd1d96753c754447b76336ab", + "content-hash": "f5581ba07d3403776f73de169913990d", "packages": [ { "name": "composer/composer", @@ -83,29 +83,29 @@ }, { "name": "composer/semver", - "version": "1.0.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", - "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "url": "https://api.github.com/repos/composer/semver/zipball/df4463baa9f44fe6cf0a6da4fde2934d4c0a2747", + "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "~2.3" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.1-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -118,10 +118,6 @@ "MIT" ], "authors": [ - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com" - }, { "name": "Nils Adermann", "email": "naderman@naderman.de", @@ -131,6 +127,11 @@ "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], "description": "Semver library that offers utilities, version constraint parsing and validation.", @@ -140,7 +141,7 @@ "validation", "versioning" ], - "time": "2015-09-21 09:42:36" + "time": "2016-02-25 22:23:39" }, { "name": "composer/spdx-licenses", @@ -271,16 +272,16 @@ }, { "name": "mustache/mustache", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "c745b01956caf27d26b55a72a90aff56bc169cd6" + "reference": "0bb2f76e2f34a8864a32be34c4ec66274d76c05e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/c745b01956caf27d26b55a72a90aff56bc169cd6", - "reference": "c745b01956caf27d26b55a72a90aff56bc169cd6", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/0bb2f76e2f34a8864a32be34c4ec66274d76c05e", + "reference": "0bb2f76e2f34a8864a32be34c4ec66274d76c05e", "shasum": "" }, "require": { @@ -288,7 +289,7 @@ }, "require-dev": { "fabpot/php-cs-fixer": "~1.6", - "phpunit/phpunit": "~3.7|~4.0" + "phpunit/phpunit": "~3.7|~4.0|~5.0" }, "type": "library", "autoload": { @@ -313,7 +314,7 @@ "mustache", "templating" ], - "time": "2015-08-15 19:23:13" + "time": "2016-02-27 19:22:46" }, { "name": "mustangostang/spyc", @@ -637,22 +638,25 @@ }, { "name": "symfony/config", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "fbd0083cd9dac06556bd1096deaa0295c18a7584" + "reference": "833beea4b0bc083a5aea84b9cf725248a74aaaff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/fbd0083cd9dac06556bd1096deaa0295c18a7584", - "reference": "fbd0083cd9dac06556bd1096deaa0295c18a7584", + "url": "https://api.github.com/repos/symfony/config/zipball/833beea4b0bc083a5aea84b9cf725248a74aaaff", + "reference": "833beea4b0bc083a5aea84b9cf725248a74aaaff", "shasum": "" }, "require": { "php": ">=5.3.9", "symfony/filesystem": "~2.3" }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, "type": "library", "extra": { "branch-alias": { @@ -683,20 +687,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-01-03 15:32:00" + "time": "2016-02-22 16:12:29" }, { "name": "symfony/console", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d3fc138b6ed8f8074591821d3416d8f9c04d6ca6" + "reference": "ee91ec301cd88ee38ab14505025fe94bbc19a9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d3fc138b6ed8f8074591821d3416d8f9c04d6ca6", - "reference": "d3fc138b6ed8f8074591821d3416d8f9c04d6ca6", + "url": "https://api.github.com/repos/symfony/console/zipball/ee91ec301cd88ee38ab14505025fe94bbc19a9c1", + "reference": "ee91ec301cd88ee38ab14505025fe94bbc19a9c1", "shasum": "" }, "require": { @@ -742,20 +746,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-01-14 08:26:43" + "time": "2016-02-28 16:19:47" }, { "name": "symfony/dependency-injection", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "37dfddbf3791d79b46b11f610b39e90d622e7183" + "reference": "157326648175d52326cd9b9e5f4fef207dc447f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/37dfddbf3791d79b46b11f610b39e90d622e7183", - "reference": "37dfddbf3791d79b46b11f610b39e90d622e7183", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/157326648175d52326cd9b9e5f4fef207dc447f9", + "reference": "157326648175d52326cd9b9e5f4fef207dc447f9", "shasum": "" }, "require": { @@ -804,20 +808,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-01-12 17:44:11" + "time": "2016-02-28 16:34:40" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "79493b6421786e5a0fc2d161410aa86f400bcaea" + "reference": "b68c0348ba5b3927a6c8e413cc7d594f3ccff3ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/79493b6421786e5a0fc2d161410aa86f400bcaea", - "reference": "79493b6421786e5a0fc2d161410aa86f400bcaea", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b68c0348ba5b3927a6c8e413cc7d594f3ccff3ce", + "reference": "b68c0348ba5b3927a6c8e413cc7d594f3ccff3ce", "shasum": "" }, "require": { @@ -864,20 +868,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-01-13 10:26:43" + "time": "2016-01-27 05:09:39" }, { "name": "symfony/filesystem", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "78188c6971053ff8eaa00fa180c0747c296152f6" + "reference": "ce25d60462dd7088fca4feadba08321bee4273b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/78188c6971053ff8eaa00fa180c0747c296152f6", - "reference": "78188c6971053ff8eaa00fa180c0747c296152f6", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ce25d60462dd7088fca4feadba08321bee4273b4", + "reference": "ce25d60462dd7088fca4feadba08321bee4273b4", "shasum": "" }, "require": { @@ -913,20 +917,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-01-13 07:57:33" + "time": "2016-02-18 16:03:55" }, { "name": "symfony/finder", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d20ac81c81a67ab898b0c0afa435f3e9a7d460cf" + "reference": "addcb70b33affbca4f3979b0d000259b63dd6711" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d20ac81c81a67ab898b0c0afa435f3e9a7d460cf", - "reference": "d20ac81c81a67ab898b0c0afa435f3e9a7d460cf", + "url": "https://api.github.com/repos/symfony/finder/zipball/addcb70b33affbca4f3979b0d000259b63dd6711", + "reference": "addcb70b33affbca4f3979b0d000259b63dd6711", "shasum": "" }, "require": { @@ -962,20 +966,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-01-14 08:26:43" + "time": "2016-02-22 16:12:29" }, { "name": "symfony/process", - "version": "v2.8.2", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac" + "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac", - "reference": "6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac", + "url": "https://api.github.com/repos/symfony/process/zipball/7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", + "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", "shasum": "" }, "require": { @@ -1011,20 +1015,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-01-06 09:59:23" + "time": "2016-02-02 13:33:15" }, { "name": "symfony/translation", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "8cbab8445ad4269427077ba02fff8718cb397e22" + "reference": "4c61cf815af17eee4cebf0e4c66f56a2f704cfd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/8cbab8445ad4269427077ba02fff8718cb397e22", - "reference": "8cbab8445ad4269427077ba02fff8718cb397e22", + "url": "https://api.github.com/repos/symfony/translation/zipball/4c61cf815af17eee4cebf0e4c66f56a2f704cfd8", + "reference": "4c61cf815af17eee4cebf0e4c66f56a2f704cfd8", "shasum": "" }, "require": { @@ -1074,20 +1078,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-01-03 15:32:00" + "time": "2016-02-01 20:45:15" }, { "name": "symfony/yaml", - "version": "v2.7.9", + "version": "v2.7.10", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "a91e8af3dcde226e00be2e1c068764eef7b4c153" + "reference": "fc0ad7a7450ed4434c9a397796a9f56199de2053" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a91e8af3dcde226e00be2e1c068764eef7b4c153", - "reference": "a91e8af3dcde226e00be2e1c068764eef7b4c153", + "url": "https://api.github.com/repos/symfony/yaml/zipball/fc0ad7a7450ed4434c9a397796a9f56199de2053", + "reference": "fc0ad7a7450ed4434c9a397796a9f56199de2053", "shasum": "" }, "require": { @@ -1123,7 +1127,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-01-13 10:26:43" + "time": "2016-02-23 07:38:51" }, { "name": "wp-cli/php-cli-tools", From 04a6224bfe27a259fc75afe5cbd5e894e5b0c80f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Mar 2016 17:39:58 -0800 Subject: [PATCH 4145/4858] Failing test case for a bad command causing `wp package` failure --- features/package.feature | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/features/package.feature b/features/package.feature index ec40ebf7cc..9effd8f3c4 100644 --- a/features/package.feature +++ b/features/package.feature @@ -29,3 +29,20 @@ Feature: Manage WP-CLI packages """ danielbachhuber/wp-cli-reset-post-date-command """ + + Scenario: Run package commands early, before any bad code can break them + Given an empty directory + And a bad-command.php file: + """ + <?php + WP_CLI::error( "Doing it wrong." ); + """ + + When I try `wp --require=bad-command.php option` + Then STDERR should contain: + """ + Error: Doing it wrong. + """ + + When I run `wp --require=bad-command.php package list` + Then STDERR should be empty From 2b2a07071e72cf3f906d023279977b3f73ddb6fc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 10 Mar 2016 17:42:48 -0800 Subject: [PATCH 4146/4858] Run `wp package` commands before any packages are loaded If a user installs a bad package, we want them to be able to back out of it. --- php/WP_CLI/Runner.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 628a9a67f0..fe88ae9cba 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -619,6 +619,12 @@ public function start() { exit; } + // Protect 'package' commands from most of the runtime too + if ( 'package' === $this->arguments[0] ) { + $this->_run_command(); + exit; + } + // Load bundled commands early, so that they're forced to use the same // APIs as non-bundled commands. Utils\load_command( $this->arguments[0] ); From 05ff88bf66c7276fc95cd80f9fa8f85547c55b2f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 11 Mar 2016 07:43:29 -0800 Subject: [PATCH 4147/4858] Support registering `default` and `options` for positional/assoc args `default` fills the value when it isn't set. `options` validates the filled value against an enum of values. YAML for the win: ``` --volume=<number> : Sets the volume. --- default: 10 --- ``` --- features/command.feature | 115 +++++++++++++++++++++++++++ php/WP_CLI/Dispatcher/Subcommand.php | 44 +++++++++- php/WP_CLI/DocParser.php | 30 +++++++ php/class-wp-cli.php | 13 ++- tests/test-doc-parser.php | 41 ++++++++++ 5 files changed, 239 insertions(+), 4 deletions(-) diff --git a/features/command.feature b/features/command.feature index 92f640bbf6..9e4ab00a5a 100644 --- a/features/command.feature +++ b/features/command.feature @@ -354,3 +354,118 @@ Feature: WP-CLI Commands [--meal=<meal>] A type of meal. """ + + Scenario: Register a command with default and accepted arguments. + Given an empty directory + And a test-cmd.php file: + """ + <?php + /** + * An amazing command for managing burritos. + * + * [<bar>] + * : This is the bar argument. + * --- + * default: burrito + * --- + * + * [<shop>] + * : This is where you buy burritos. + * --- + * options: + * - left_coast_siesta + * - cha cha cha + * --- + * + * [--burrito=<burrito>] + * : This is the burrito argument. + * --- + * options: + * - beans + * - veggies + * --- + * + * @when before_wp_load + */ + $foo = function( $args, $assoc_args ) { + $out = array( + 'bar' => isset( $args[0] ) ? $args[0] : '', + 'shop' => isset( $args[1] ) ? $args[1] : '', + 'burrito' => isset( $assoc_args['burrito'] ) ? $assoc_args['burrito'] : '', + ); + WP_CLI::print_value( $out, array( 'format' => 'yaml' ) ); + }; + WP_CLI::add_command( 'foo', $foo ); + """ + + When I run `wp --require=test-cmd.php foo --help` + Then STDOUT should contain: + """ + [<bar>] + This is the bar argument. + --- + default: burrito + --- + """ + And STDOUT should contain: + """ + [--burrito=<burrito>] + This is the burrito argument. + --- + options: + - beans + - veggies + --- + """ + + When I run `wp --require=test-cmd.php foo` + Then STDOUT should be YAML containing: + """ + bar: burrito + shop: + burrito: + """ + + When I run `wp --require=test-cmd.php foo ''` + Then STDOUT should be YAML containing: + """ + bar: + shop: + burrito: + """ + + When I run `wp --require=test-cmd.php foo apple --burrito=veggies` + Then STDOUT should be YAML containing: + """ + bar: apple + shop: + burrito: veggies + """ + + When I try `wp --require=test-cmd.php foo apple --burrito=meat` + Then STDERR should contain: + """ + Error: Parameter errors: + Invalid value specified for 'burrito' (This is the burrito argument.) + """ + + When I try `wp --require=test-cmd.php foo apple --burrito=''` + Then STDERR should contain: + """ + Error: Parameter errors: + Invalid value specified for 'burrito' (This is the burrito argument.) + """ + + When I try `wp --require=test-cmd.php foo apple taco_del_mar` + Then STDERR should contain: + """ + Error: Invalid value specified for positional arg. + """ + + When I run `wp --require=test-cmd.php foo apple 'cha cha cha'` + Then STDOUT should be YAML containing: + """ + bar: apple + shop: cha cha cha + burrito: + """ diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 202d51e736..de5f629fdb 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -252,9 +252,47 @@ private function validate_args( $args, $assoc_args, $extra_args ) { implode( ' ', $unknown_positionals ) ); } - list( $errors, $to_unset ) = $validator->validate_assoc( + $synopsis_spec = \WP_CLI\SynopsisParser::parse( $synopsis ); + $i = 0; + $errors = array( 'fatal' => array(), 'warning' => array() ); + foreach( $synopsis_spec as $spec ) { + if ( ! empty( $spec['repeating'] ) ) { + continue; + } + if ( 'positional' === $spec['type'] ) { + $spec_args = $this->docparser->get_arg_args( $spec['name'] ); + if ( ! isset( $args[ $i ] ) ) { + if ( isset( $spec_args['default'] ) ) { + $args[ $i ] = $spec_args['default']; + } + } + if ( isset( $args[ $i ] ) && isset( $spec_args['options'] ) ) { + if ( ! in_array( $args[ $i ], $spec_args['options'] ) ) { + \WP_CLI::error( 'Invalid value specified for positional arg.' ); + } + } + $i++; + } else if ( 'assoc' === $spec['type'] ) { + $spec_args = $this->docparser->get_param_args( $spec['name'] ); + if ( ! isset( $assoc_args[ $spec['name'] ] ) ) { + if ( isset( $spec_args['default'] ) ) { + $assoc_args[ $spec['name'] ] = $spec_args['default']; + } + } + if ( isset( $assoc_args[ $spec['name'] ] ) && isset( $spec_args['options'] ) ) { + if ( ! in_array( $assoc_args[ $spec['name'] ], $spec_args['options'] ) ) { + $errors['fatal'][ $spec['name'] ] = "Invalid value specified for '{$spec['name']}'"; + } + } + } + } + + list( $returned_errors, $to_unset ) = $validator->validate_assoc( array_merge( \WP_CLI::get_config(), $extra_args, $assoc_args ) ); + foreach( array( 'fatal', 'warning' ) as $error_type ) { + $errors[ $error_type ] = array_merge( $errors[ $error_type ], $returned_errors[ $error_type ] ); + } if ( $this->name != 'help' ) { foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) { @@ -276,7 +314,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { array_map( '\\WP_CLI::warning', $errors['warning'] ); - return $to_unset; + return array( $to_unset, $args, $assoc_args, $extra_args ); } /** @@ -294,7 +332,7 @@ public function invoke( $args, $assoc_args, $extra_args ) { $prompted_once = true; } - $to_unset = $this->validate_args( $args, $assoc_args, $extra_args ); + 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 ] ); diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index 06d57d328d..9249003f94 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -2,6 +2,8 @@ namespace WP_CLI; +use Spyc; + /** * Parse command attributes from its PHPdoc. * Used to determine execution characteristics (arguments, etc.). @@ -111,6 +113,19 @@ public function get_arg_desc( $name ) { } + /** + * Get the arguments for a given argument. + * + * @param string $name Argument's doc name. + * @return mixed|null + */ + public function get_arg_args( $name ) { + if ( preg_match( "/\[?<{$name}>.+(\n: (.+?)(\n|$))?\n---\n(.+)\n---/sU", $this->docComment, $matches ) ) { + return Spyc::YAMLLoadString( $matches[4] ); + } + return null; + } + /** * Get the description for a given parameter. * @@ -126,4 +141,19 @@ public function get_param_desc( $key ) { return ''; } + /** + * Get the arguments for a given parameter. + * + * @param string $key Parameter's key. + * @return mixed|null + */ + public function get_param_args( $key ) { + + if ( preg_match( "/\[?--{$key}=.+(\n: (.+?)(\n|$))?\n---\n(.+)\n---/sU", $this->docComment, $matches ) ) { + return Spyc::YAMLLoadString( $matches[4] ); + } + + return null; + } + } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index a55ef8fc92..ee48c2a965 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -313,7 +313,18 @@ public static function add_command( $name, $callable, $args = array() ) { $long_desc = ''; $bits = explode( ' ', $synopsis ); foreach( $args['synopsis'] as $key => $arg ) { - $long_desc .= $bits[ $key ] . PHP_EOL . ': ' . $arg['description'] . PHP_EOL . PHP_EOL; + $long_desc .= $bits[ $key ] . PHP_EOL . ': ' . $arg['description'] . PHP_EOL; + $yamlify = array(); + foreach( array( 'options', 'default' ) as $key ) { + if ( isset( $arg[ $key ] ) ) { + $yamlify[ $key ] = $arg[ $key ]; + } + } + if ( ! empty( $yamlify ) ) { + $long_desc .= \Spyc::YAMLDump( $yamlify ); + $long_desc .= '---' . PHP_EOL; + } + $long_desc .= PHP_EOL; } if ( ! empty( $long_desc ) ) { $long_desc = rtrim( $long_desc, PHP_EOL ); diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index 150a33158d..ec91eed0bd 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -94,5 +94,46 @@ function test_complete() { ; $this->assertEquals( $longdesc, $doc->get_longdesc() ); } + + public function test_desc_parses_yaml() { + $longdesc = <<<EOB +## OPTIONS + +<genre>... +: Start with one or more genres. +--- +options: + - rock + - electronic +default: rock +--- + +--volume=<number> +: Sets the volume. +--- +default: 10 +--- + +--artist=<artist-name> +: Limit to a specific artist. + +## EXAMPLES + +wp rock-on electronic --volume=11 + +EOB; + $doc = new DocParser( $longdesc ); + $this->assertEquals( 'Start with one or more genres.', $doc->get_arg_desc( 'genre' ) ); + $this->assertEquals( 'Sets the volume.', $doc->get_param_desc( 'volume' ) ); + $this->assertEquals( array( + 'options' => array( 'rock', 'electronic' ), + 'default' => 'rock', + ), $doc->get_arg_args( 'genre' ) ); + $this->assertEquals( array( + 'default' => 10, + ), $doc->get_param_args( 'volume' ) ); + $this->assertNull( $doc->get_param_args( 'artist' ) ); + } + } From d34940b479d8b8f0aec40ec7f445138ea4250ceb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 11 Mar 2016 10:26:01 -0800 Subject: [PATCH 4148/4858] Validate options for repeating positional args --- features/command.feature | 8 +++++++- php/WP_CLI/Dispatcher/Subcommand.php | 18 ++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/features/command.feature b/features/command.feature index 9e4ab00a5a..405ec84368 100644 --- a/features/command.feature +++ b/features/command.feature @@ -369,7 +369,7 @@ Feature: WP-CLI Commands * default: burrito * --- * - * [<shop>] + * [<shop>...] * : This is where you buy burritos. * --- * options: @@ -462,6 +462,12 @@ Feature: WP-CLI Commands Error: Invalid value specified for positional arg. """ + When I try `wp --require=test-cmd.php foo apple 'cha cha cha' taco_del_mar` + Then STDERR should contain: + """ + Error: Invalid value specified for positional arg. + """ + When I run `wp --require=test-cmd.php foo apple 'cha cha cha'` Then STDOUT should be YAML containing: """ diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index de5f629fdb..34ac0900bc 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -256,9 +256,6 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $i = 0; $errors = array( 'fatal' => array(), 'warning' => array() ); foreach( $synopsis_spec as $spec ) { - if ( ! empty( $spec['repeating'] ) ) { - continue; - } if ( 'positional' === $spec['type'] ) { $spec_args = $this->docparser->get_arg_args( $spec['name'] ); if ( ! isset( $args[ $i ] ) ) { @@ -266,9 +263,18 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $args[ $i ] = $spec_args['default']; } } - if ( isset( $args[ $i ] ) && isset( $spec_args['options'] ) ) { - if ( ! in_array( $args[ $i ], $spec_args['options'] ) ) { - \WP_CLI::error( 'Invalid value specified for positional arg.' ); + if ( isset( $spec_args['options'] ) ) { + if ( ! empty( $spec['repeating'] ) ) { + do { + if ( isset( $args[ $i ] ) && ! in_array( $args[ $i ], $spec_args['options'] ) ) { + \WP_CLI::error( 'Invalid value specified for positional arg.' ); + } + $i++; + } while ( isset( $args[ $i ] ) ); + } else { + if ( ! in_array( $args[ $i ], $spec_args['options'] ) ) { + \WP_CLI::error( 'Invalid value specified for positional arg.' ); + } } } $i++; From ab67e727909653c55aef649eb815d956ff538cef Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 11 Mar 2016 10:30:27 -0800 Subject: [PATCH 4149/4858] Add tests for `options` and `default` on dynamic registration Also, `default` makes sense to include before `options` --- features/command.feature | 15 +++++++++++++++ php/class-wp-cli.php | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/features/command.feature b/features/command.feature index 405ec84368..59015ad572 100644 --- a/features/command.feature +++ b/features/command.feature @@ -299,6 +299,7 @@ Feature: WP-CLI Commands 'name' => 'message', 'description' => 'An awesome message to display', 'optional' => false, + 'options' => array( 'hello', 'goodbye' ), ), array( 'type' => 'assoc', @@ -311,6 +312,8 @@ Feature: WP-CLI Commands 'name' => 'meal', 'description' => 'A type of meal.', 'optional' => true, + 'default' => 'breakfast', + 'options' => array( 'breakfast', 'lunch', 'dinner' ), ), ), ) ); @@ -348,11 +351,23 @@ Feature: WP-CLI Commands """ <message> An awesome message to display + --- + options: + - hello + - goodbye + --- """ And STDOUT should contain: """ [--meal=<meal>] A type of meal. + --- + default: breakfast + options: + - breakfast + - lunch + - dinner + --- """ Scenario: Register a command with default and accepted arguments. diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ee48c2a965..eee3cd4e4d 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -315,7 +315,7 @@ public static function add_command( $name, $callable, $args = array() ) { foreach( $args['synopsis'] as $key => $arg ) { $long_desc .= $bits[ $key ] . PHP_EOL . ': ' . $arg['description'] . PHP_EOL; $yamlify = array(); - foreach( array( 'options', 'default' ) as $key ) { + foreach( array( 'default', 'options' ) as $key ) { if ( isset( $arg[ $key ] ) ) { $yamlify[ $key ] = $arg[ $key ]; } From 074c26bdf4484033ddcf5568c8436c249ba276b0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 11 Mar 2016 11:24:35 -0800 Subject: [PATCH 4150/4858] Accommodate `$args` that isn't zero-indexed --- php/WP_CLI/Dispatcher/Subcommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 34ac0900bc..faf4846b98 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -253,7 +253,8 @@ private function validate_args( $args, $assoc_args, $extra_args ) { } $synopsis_spec = \WP_CLI\SynopsisParser::parse( $synopsis ); - $i = 0; + reset( $args ); + $i = key( $args ); $errors = array( 'fatal' => array(), 'warning' => array() ); foreach( $synopsis_spec as $spec ) { if ( 'positional' === $spec['type'] ) { From 4a84de4b5f5441301ea3e2655c6913d5c5e92cba Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 11 Mar 2016 11:36:20 -0800 Subject: [PATCH 4151/4858] Revert "Accommodate `$args` that isn't zero-indexed" This reverts commit 074c26bdf4484033ddcf5568c8436c249ba276b0. --- php/WP_CLI/Dispatcher/Subcommand.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index faf4846b98..34ac0900bc 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -253,8 +253,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { } $synopsis_spec = \WP_CLI\SynopsisParser::parse( $synopsis ); - reset( $args ); - $i = key( $args ); + $i = 0; $errors = array( 'fatal' => array(), 'warning' => array() ); foreach( $synopsis_spec as $spec ) { if ( 'positional' === $spec['type'] ) { From 9a43ec3f4d710c2151d63eb96ebbbecdd4d048fb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 11 Mar 2016 11:47:32 -0800 Subject: [PATCH 4152/4858] Update return signature, so we don't noop args for commands without synopsis --- php/WP_CLI/Dispatcher/Subcommand.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 34ac0900bc..6b9eef078c 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -228,8 +228,9 @@ private function prompt_args( $args, $assoc_args ) { */ private function validate_args( $args, $assoc_args, $extra_args ) { $synopsis = $this->get_synopsis(); - if ( !$synopsis ) - return array(); + if ( !$synopsis ) { + return array( array(), $args, $assoc_args, $extra_args ); + } $validator = new \WP_CLI\SynopsisValidator( $synopsis ); From 24e64a6f29c81cab2b3dac4e1d0245d8187e4a2f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 13 Mar 2016 06:45:01 -0700 Subject: [PATCH 4153/4858] Only register `description` for a command when present Doing so prevents wonky formatting when `description` isn't set. --- php/class-wp-cli.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index eee3cd4e4d..0847b95df4 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -313,7 +313,10 @@ public static function add_command( $name, $callable, $args = array() ) { $long_desc = ''; $bits = explode( ' ', $synopsis ); foreach( $args['synopsis'] as $key => $arg ) { - $long_desc .= $bits[ $key ] . PHP_EOL . ': ' . $arg['description'] . PHP_EOL; + $long_desc .= $bits[ $key ] . PHP_EOL; + if ( ! empty( $arg['description'] ) ) { + $long_desc .= ': ' . $arg['description'] . PHP_EOL; + } $yamlify = array(); foreach( array( 'default', 'options' ) as $key ) { if ( isset( $arg[ $key ] ) ) { From d80e84a178cb59b7ea06836b04b2e945302e2735 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 13 Mar 2016 07:11:08 -0700 Subject: [PATCH 4154/4858] Clean up `scaffold plugin-tests` docs; link to documentation page --- php/commands/scaffold.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ed2524c46d..4cb86394de 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -466,14 +466,17 @@ function plugin( $args, $assoc_args ) { /** * Generate files needed for running PHPUnit tests. * - * ## DESCRIPTION + * ## OVERVIEW * - * These are the files that are generated: + * The following files are generated for your plugin by this command: * - * * `phpunit.xml.dist` is the configuration file for PHPUnit - * * `.travis.yml` is the configuration file for Travis CI - * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite - * * `tests/test-sample.php` is a sample file containing the actual tests + * * `phpunit.xml.dist` is the configuration file for PHPUnit. + * * `.travis.yml` is the configuration file for Travis CI. + * * `bin/install-wp-tests.sh` configures the WordPress test suite and a test database. + * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite. + * * `tests/test-sample.php` is a sample file containing the actual tests. + * + * Learn more from the [plugin unit tests documentation](http://wp-cli.org/docs/plugin-unit-tests/). * * ## ENVIRONMENT * From 1de81217c5c0b21cc6fbb14f323b3c1d3c10f377 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 13 Mar 2016 07:48:38 -0700 Subject: [PATCH 4155/4858] Use `--skip-packages` to skip loading installed packages A similar idea to `--skip-plugins`, if a package has gone awry, permit normal usage of WP-CLI. --- features/package.feature | 10 ++++++++++ php/WP_CLI/Runner.php | 16 ++++++++++------ php/config-spec.php | 7 +++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/features/package.feature b/features/package.feature index 9effd8f3c4..9d0591f7c2 100644 --- a/features/package.feature +++ b/features/package.feature @@ -15,6 +15,16 @@ Feature: Manage WP-CLI packages When I run `wp help reset-post-date` Then STDERR should be empty + When I try `wp --skip-packages --debug help reset-post-date` + Then STDERR should contain: + """ + Debug: Skipped loading packages. + """ + And STDERR should contain: + """ + Error: This does not seem to be a WordPress install. + """ + When I run `wp package list` Then STDOUT should contain: """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index fe88ae9cba..cd16de1147 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -629,13 +629,17 @@ public function start() { // APIs as non-bundled commands. Utils\load_command( $this->arguments[0] ); - $package_autoload = $this->get_packages_dir_path() . 'vendor/autoload.php'; - - if ( file_exists( $package_autoload ) ) { - WP_CLI::debug( 'Loading packages from: ' . $package_autoload ); - require_once $package_autoload; + $skip_packages = \WP_CLI::get_runner()->config['skip-packages']; + if ( true === $skip_packages ) { + WP_CLI::debug( 'Skipped loading packages.' ); } else { - WP_CLI::debug( 'No package autoload found to load.' ); + $package_autoload = $this->get_packages_dir_path() . 'vendor/autoload.php'; + if ( file_exists( $package_autoload ) ) { + WP_CLI::debug( 'Loading packages from: ' . $package_autoload ); + require_once $package_autoload; + } else { + WP_CLI::debug( 'No package autoload found to load.' ); + } } if ( isset( $this->config['require'] ) ) { diff --git a/php/config-spec.php b/php/config-spec.php index cbaa958fd1..6e55a544c5 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -42,6 +42,13 @@ 'default' => '', ), + 'skip-packages' => array( + 'runtime' => '', + 'file' => '<bool>', + 'desc' => 'Skip loading all installed packages.', + 'default' => false, + ), + 'require' => array( 'runtime' => '=<path>', 'file' => '<path>', From 1fb032ac29875aa863b744487f61da472304d2f1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 18 Mar 2016 05:59:46 -0700 Subject: [PATCH 4156/4858] Properly add `wp plugin search` fields to plugins_api() request They need to be supplied in the first place, and passed in a non-standard format. --- features/plugin-search.feature | 14 ++++++++++++++ php/WP_CLI/CommandWithUpgrade.php | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 features/plugin-search.feature diff --git a/features/plugin-search.feature b/features/plugin-search.feature new file mode 100644 index 0000000000..00a78875bc --- /dev/null +++ b/features/plugin-search.feature @@ -0,0 +1,14 @@ +Feature: Search WordPress.org plugins + + Scenario: Search for plugins with active_installs field + Given a WP install + + When I run `wp plugin search foo --fields=name,slug,active_installs --format=csv` + Then STDOUT should contain: + """ + Success: Showing + """ + And STDOUT should contain: + """ + name,slug,active_installs + """ diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e9b02249de..7cb1adb5bc 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -407,15 +407,20 @@ protected function _search( $args, $assoc_args ) { $defaults = array( 'per-page' => 10, - 'fields' => array( 'name', 'slug', 'rating' ) + 'fields' => implode( ',', array( 'name', 'slug', 'rating' ) ), ); $assoc_args = array_merge( $defaults, $assoc_args ); + $fields = array(); + foreach( explode( ',', $assoc_args['fields'] ) as $field ) { + $fields[ $field ] = true; + } $formatter = $this->get_formatter( $assoc_args ); $api_args = array( 'per_page' => (int) $assoc_args['per-page'], 'search' => $term, + 'fields' => $fields, ); if ( 'plugin' == $this->item_type ) { From 860cdfc0e896eccb807ef69953c1acc557b8755b Mon Sep 17 00:00:00 2001 From: hinoue-work <wpuser@wp-cli-14.04> Date: Fri, 18 Mar 2016 20:42:33 +0000 Subject: [PATCH 4157/4858] Added support for page parameter. --- php/WP_CLI/CommandWithUpgrade.php | 2 ++ php/commands/plugin.php | 3 +++ 2 files changed, 5 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 7cb1adb5bc..965d3e1d77 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -407,6 +407,7 @@ protected function _search( $args, $assoc_args ) { $defaults = array( 'per-page' => 10, + 'page' => 1, 'fields' => implode( ',', array( 'name', 'slug', 'rating' ) ), ); $assoc_args = array_merge( $defaults, $assoc_args ); @@ -419,6 +420,7 @@ protected function _search( $args, $assoc_args ) { $api_args = array( 'per_page' => (int) $assoc_args['per-page'], + 'page' => (int) $assoc_args['page'], 'search' => $term, 'fields' => $fields, ); diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 8290ce171d..a7fdcb5c6b 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -53,6 +53,9 @@ function status( $args ) { * <search> * : The string to search for. * + * [--page=<page>] + * : Optional page to display. Defaults to 1. + * * [--per-page=<per-page>] * : Optional number of results to display. Defaults to 10. * From 656490380c8771d1e35de0a116891a8eed5ce6a6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 18 Mar 2016 15:32:08 -0700 Subject: [PATCH 4158/4858] Add `parent` as a potential status in `wp theme status` Fixes error notices when we're rendering the special case `parent` status. --- php/WP_CLI/CommandWithUpgrade.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e9b02249de..b5b233f528 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -372,12 +372,14 @@ protected function get_update_info( $slug ) { 'active' => 'A', 'active-network' => 'N', 'must-use' => 'M', + 'parent' => 'P', ), 'long' => array( 'inactive' => 'Inactive', 'active' => 'Active', 'active-network' => 'Network Active', 'must-use' => 'Must Use', + 'parent' => 'Parent', ) ); @@ -391,6 +393,7 @@ private function get_color( $status ) { 'active' => '%g', 'active-network' => '%g', 'must-use' => '%c', + 'parent' => '%p', ); return $colors[ $status ]; From 4a3f43d8ba7fb83c4ab64e8408d4f21d29873b1d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 18 Mar 2016 15:37:40 -0700 Subject: [PATCH 4159/4858] Lock php-cli-tools to v0.11.1 --- composer.json | 2 +- composer.lock | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 7cae33f61d..094e138683 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.2", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "~0.11.1", "mustache/mustache": "~2.4", "mustangostang/spyc": "0.5.1", "composer/semver": "~1.0", diff --git a/composer.lock b/composer.lock index 2a6b72b4bb..7f71b981d7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "3ce120babd1d96753c754447b76336ab", - "content-hash": "f5581ba07d3403776f73de169913990d", + "hash": "826f45f99932268bb0bd8d8ad99505db", + "content-hash": "2aa6852b8aa1adbdaa0bf5bf09014eed", "packages": [ { "name": "composer/composer", @@ -1131,7 +1131,7 @@ }, { "name": "wp-cli/php-cli-tools", - "version": "dev-master", + "version": "v0.11.1", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", @@ -1670,7 +1670,6 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "wp-cli/php-cli-tools": 20, "composer/composer": 15 }, "prefer-stable": false, From cf5f75598f8bf292a0e5c44f6bf5ef6739daac5f Mon Sep 17 00:00:00 2001 From: jacobischwartz <jacob@schwambell.com> Date: Sat, 19 Mar 2016 13:01:46 -0500 Subject: [PATCH 4160/4858] Behat test for importer fix. Also, refinement to bug fix. --- features/import.feature | 60 ++++++++++++++++++++++++++++++++++++++++- php/commands/import.php | 2 +- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/features/import.feature b/features/import.feature index c975325b23..893b69b443 100644 --- a/features/import.feature +++ b/features/import.feature @@ -69,7 +69,7 @@ Feature: Import content. When I run `find export-* -type f | wc -l` Then STDOUT should be: """ - 2 + 2 """ When I run `wp plugin install wordpress-importer --activate` @@ -87,3 +87,61 @@ Feature: Import content. """ 100 """ + + Scenario: Export and import page and referencing menu item in separate files + Given a WP install + And I run `mkdir export` + + When I run `wp menu create "My Menu"` + And I run `wp menu item add-post my-menu 2` + And I run `wp menu item list my-menu --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp export --dir=export --post_type=page --filename_format=0.page.xml` + When I run `wp export --dir=export --post_type=nav_menu_item --filename_format=1.menu.xml` + Then STDOUT should not be empty + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp post list --post_type=nav_menu_item --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `find export -type f | wc -l` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDERR should not contain: + """ + Warning: + """ + + When I run `wp import export --authors=skip --skip=image_resize` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp post list --post_type=nav_menu_item --format=count` + Then STDOUT should be: + """ + 1 + """ \ No newline at end of file diff --git a/php/commands/import.php b/php/commands/import.php index 16372d6bb3..c0644e33ae 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -141,7 +141,7 @@ private function import_wxr( $file, $args ) { } $wp_import->import( $file ); - $this->processed_posts = array_merge($this->processed_posts, $wp_import->processed_posts); + $this->processed_posts += $wp_import->processed_posts; return true; } From 93229c0ca3788ce0601519102086d849f7bc1421 Mon Sep 17 00:00:00 2001 From: jacobischwartz <jacob@schwambell.com> Date: Sat, 19 Mar 2016 18:14:41 -0500 Subject: [PATCH 4161/4858] Minor refinements to import automated testing. Minor formatting fixes & more explicit verification. --- features/import.feature | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/features/import.feature b/features/import.feature index 893b69b443..6d48cfdb28 100644 --- a/features/import.feature +++ b/features/import.feature @@ -66,10 +66,10 @@ Feature: Import content. 0 """ - When I run `find export-* -type f | wc -l` + When I run `find export-* -type f | wc -l | sed 's/^ *//'` Then STDOUT should be: """ - 2 + 2 """ When I run `wp plugin install wordpress-importer --activate` @@ -92,6 +92,7 @@ Feature: Import content. Given a WP install And I run `mkdir export` + # NOTE: The Hello World page ID is 2. When I run `wp menu create "My Menu"` And I run `wp menu item add-post my-menu 2` And I run `wp menu item list my-menu --format=count` @@ -101,7 +102,7 @@ Feature: Import content. """ When I run `wp export --dir=export --post_type=page --filename_format=0.page.xml` - When I run `wp export --dir=export --post_type=nav_menu_item --filename_format=1.menu.xml` + And I run `wp export --dir=export --post_type=nav_menu_item --filename_format=1.menu.xml` Then STDOUT should not be empty When I run `wp site empty --yes` @@ -119,10 +120,10 @@ Feature: Import content. 0 """ - When I run `find export -type f | wc -l` + When I run `find export -type f | wc -l | sed 's/^ *//'` Then STDOUT should be: """ - 2 + 2 """ When I run `wp plugin install wordpress-importer --activate` @@ -144,4 +145,16 @@ Feature: Import content. Then STDOUT should be: """ 1 - """ \ No newline at end of file + """ + + When I run `wp menu item list my-menu --fields=object --format=csv | sed -n '2p'` + Then STDOUT should be: + """ + page + """ + + When I run `wp menu item list my-menu --fields=object_id --format=csv | sed -n '2p'` + Then STDOUT should be: + """ + 2 + """ From 7f4db5f3f707a29c08e81d6d6e5945046a6f519d Mon Sep 17 00:00:00 2001 From: jacobischwartz <jacob@schwambell.com> Date: Sun, 20 Mar 2016 16:12:28 -0500 Subject: [PATCH 4162/4858] Add import scenario to demonstrate existing failures. WP 3.7.11 and PHP 7 both cause menu imports to fail. Also, switch from sed to "contain" syntax. --- features/import.feature | 88 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) diff --git a/features/import.feature b/features/import.feature index 6d48cfdb28..4e808d86ed 100644 --- a/features/import.feature +++ b/features/import.feature @@ -66,8 +66,8 @@ Feature: Import content. 0 """ - When I run `find export-* -type f | wc -l | sed 's/^ *//'` - Then STDOUT should be: + When I run `find export-* -type f | wc -l` + Then STDOUT should contain: """ 2 """ @@ -88,6 +88,78 @@ Feature: Import content. 100 """ + Scenario: Export and import page and referencing menu item + # This will not work with WP 3.7.11 or PHP 7. + # PHP 7 issue: https://wordpress.org/support/topic/importer-fails-to-import-menu-items-in-php7 + Given a WP install + And I run `mkdir export` + + # NOTE: The Hello World page ID is 2. + When I run `wp menu create "My Menu"` + And I run `wp menu item add-post my-menu 2` + And I run `wp menu item list my-menu --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp export --dir=export` + Then STDOUT should not be empty + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp post list --post_type=nav_menu_item --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `find export -type f | wc -l` + Then STDOUT should contain: + """ + 1 + """ + + When I run `wp plugin install wordpress-importer --activate` + Then STDERR should not contain: + """ + Warning: + """ + + When I run `wp import export --authors=skip --skip=image_resize` + Then STDOUT should not be empty + + When I run `wp post list --post_type=page --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp post list --post_type=nav_menu_item --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp menu item list my-menu --fields=object --format=csv` + Then STDOUT should contain: + """ + page + """ + + When I run `wp menu item list my-menu --fields=object_id --format=csv` + Then STDOUT should contain: + """ + 2 + """ + Scenario: Export and import page and referencing menu item in separate files Given a WP install And I run `mkdir export` @@ -120,8 +192,8 @@ Feature: Import content. 0 """ - When I run `find export -type f | wc -l | sed 's/^ *//'` - Then STDOUT should be: + When I run `find export -type f | wc -l` + Then STDOUT should contain: """ 2 """ @@ -147,14 +219,14 @@ Feature: Import content. 1 """ - When I run `wp menu item list my-menu --fields=object --format=csv | sed -n '2p'` - Then STDOUT should be: + When I run `wp menu item list my-menu --fields=object --format=csv` + Then STDOUT should contain: """ page """ - When I run `wp menu item list my-menu --fields=object_id --format=csv | sed -n '2p'` - Then STDOUT should be: + When I run `wp menu item list my-menu --fields=object_id --format=csv` + Then STDOUT should contain: """ 2 """ From fdddd176f20457dd5503d7bc1948fd72638d6dcc Mon Sep 17 00:00:00 2001 From: jacobischwartz <jacob@schwambell.com> Date: Sun, 20 Mar 2016 17:52:27 -0500 Subject: [PATCH 4163/4858] Excempt new scenarios from PHP7 & WP below v4. --- features/import.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/import.feature b/features/import.feature index 4e808d86ed..54a06829b1 100644 --- a/features/import.feature +++ b/features/import.feature @@ -88,6 +88,7 @@ Feature: Import content. 100 """ + @less-than-php-7 @require-wp-4.0 Scenario: Export and import page and referencing menu item # This will not work with WP 3.7.11 or PHP 7. # PHP 7 issue: https://wordpress.org/support/topic/importer-fails-to-import-menu-items-in-php7 @@ -160,6 +161,7 @@ Feature: Import content. 2 """ + @less-than-php-7 @require-wp-4.0 Scenario: Export and import page and referencing menu item in separate files Given a WP install And I run `mkdir export` From 83530139eb7819a66ce5fe5b4ed5a62561f41ab9 Mon Sep 17 00:00:00 2001 From: Gary Jones <gamajo@gamajo.com> Date: Mon, 21 Mar 2016 17:03:47 +0000 Subject: [PATCH 4164/4858] Add documentation to bootstrap template File and functions should be documented. --- templates/bootstrap.mustache | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index be86eeaeac..fb44b66402 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -1,15 +1,25 @@ <?php +/** + * PHPUnit bootstrap file + * + * @package {{plugin_slug}} + */ $_tests_dir = getenv( 'WP_TESTS_DIR' ); if ( ! $_tests_dir ) { $_tests_dir = '/tmp/wordpress-tests-lib'; } +// Give access to tests_add_filter() function. require_once $_tests_dir . '/includes/functions.php'; +/** + * Manually load the plugin being tested. + */ function _manually_load_plugin() { require dirname( dirname( __FILE__ ) ) . '/{{plugin_slug}}.php'; } tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); +// Start up the WP testing environment. require $_tests_dir . '/includes/bootstrap.php'; From f7e3fef8bf068f471808ee3dbff06c7515d4e917 Mon Sep 17 00:00:00 2001 From: Gary Jones <gamajo@gamajo.com> Date: Mon, 21 Mar 2016 17:21:18 +0000 Subject: [PATCH 4165/4858] Add documentation to test-sample.php --- templates/test-sample.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/templates/test-sample.php b/templates/test-sample.php index 79ba8f9a2e..0264e9ffd0 100644 --- a/templates/test-sample.php +++ b/templates/test-sample.php @@ -1,9 +1,20 @@ <?php +/** + * Class SampleTest + * + * @package + */ +/** + * Sample test case. + */ class SampleTest extends WP_UnitTestCase { + /** + * A single example test. + */ function test_sample() { - // replace this with some actual testing code + // Replace this with some actual testing code. $this->assertTrue( true ); } } From cbb62985a742a24843a345ebd68318f9a2e71055 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Mar 2016 14:51:46 -0700 Subject: [PATCH 4166/4858] Update `.mailmap` for 0.23.0 --- .mailmap | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.mailmap b/.mailmap index 9f24a1a943..115f09c474 100644 --- a/.mailmap +++ b/.mailmap @@ -1,6 +1,7 @@ 2ndkauboy <bernhard@kau-boys.de> Akeda Bagus <admin@gedex.web.id> Alex Mills <git@viper007bond.com> +Anant Shrivastava <anant@anantshri.info> Andreas Heigl <andreas@heigl.org> andreascreten <andreas@madewithlove.be> Andrew Patton <andrew@acusti.ca> @@ -34,23 +35,29 @@ dlh01 <david@alleyinteractive.com> drrobotnik <B@Brandons-Mac-Pro-4.local> Duncan Brown <duncanjbrown@gmail.com> dwightjack <marco.solazzi@gmail.com> +Eduardo Alencar <ealencar10@gmail.com> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> eugeneware <eugene@noblesamurai.com> Evan Mattson <me@aaemnnost.tv> francescolaffi <francesco.laffi@gmail.com> +Frank Staude <frank@staude.net> Frankie Jarrett <fjarrett@godaddy.com> future500 <ramon@future500.nl> +Gary Jones <gamajo@gamajo.com> getsource <mike.schroder@dreamhost.com> Gilbert Pellegrom <gilbert@pellegrom.me> glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> Grant McInnes <grant.mcinnes@eyesopen.ca> Greg Anderson <greg.1.anderson@greenknowe.org> +hina <hina@hinaloe.net> +hinoue-work <wpuser@wp-cli-14.04> Hiroshi Urabe <mail@torounit.com> Ian Dunn <ian@iandunn.name> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> +jacobischwartz <jacob@schwambell.com> Jan Voráček <jan@voracek.net> Jeff Gould <jrgould@gmail.com> jeichorn <joshua.eichorn@pagely.com> @@ -76,14 +83,19 @@ lackingpenguin <benjamin.j.brooks@gmail.com> leewillis77 <leewillis77@gmail.com> lkwdwrd <woodward.lucas@gmail.com> Marc Addeo <marcaddeo@gmail.com> +Marco <mcastelluccio@mozilla.com> marcoceppi <marco@ceppi.net> +Mark Jaquith <mark.github@txfx.net> +Mark Kimsal <metrofindings@gmail.com> matiskay <matiskay@gmail.com> mattes <matthias.kadenbach@gmail.com> mattheu <matthew@matth.eu> +mbovel <matthieu@bovel.net> mboynes <mboynes@alleyinteractive.com> mgburns <mgburns@bu.edu> mgburns <mike@grady-etc.com> Mihail Minkov <Mihail.Minkov.BG@gmail.com> +Mike Pretzlaw <pretzlaw@gmail.com> mikey dubs <mike@herebox.org> milesj <mileswjohnson@gmail.com> MiteshShah <Mitesh.Shah@rtCamp.com> @@ -107,9 +119,11 @@ oknoway <nate@oknoway.com> om4james <james@jamesc.id.au> om4james <james@om4.com.au> oneumyvakin <oneumyvakin@gmail.com> +Otto Kekäläinen <otto@seravo.fi> ozh <ozh@ozh.org> phh <phh@peytz.dk> Pippin Williamson <pippin@pippinsplugins.com> +Radu Dan <za_creature@yahoo.com> Rarst <contact@rarst.net> robertboloc <robertboloc@gmail.com> Robin Schneider <ypid@riseup.net> From 31b9c00c688b50d9654a00c4449e88d63593d5ae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 22 Mar 2016 14:52:58 -0700 Subject: [PATCH 4167/4858] Version bump --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c648a65ef2..ca222b7cf3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.23.0-alpha +0.23.0 From 9cbbc6e3355a9484622e81bf4c86f99816495302 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 23 Mar 2016 05:57:46 -0700 Subject: [PATCH 4168/4858] Version bump --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ca222b7cf3..5d22270f29 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.23.0 +0.24.0-alpha From 44ebeb299657746fd28328fa1b3b517c1373a57c Mon Sep 17 00:00:00 2001 From: Geo <geo.artemenko@gmail.com> Date: Wed, 23 Mar 2016 16:25:23 -0400 Subject: [PATCH 4169/4858] remove redundant period --- php/commands/help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/help.php b/php/commands/help.php index 4894c54f3e..7210df898e 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -6,7 +6,7 @@ class Help_Command extends WP_CLI_Command { /** - * Get help on WP-CLI, or on a specific. command. + * Get help on WP-CLI, or on a specific command. * * [<command>...] * : Get help on a specific command. From 4d9ed2649d8b4b404d75fa8316c3614f68c4524f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 23 Mar 2016 14:41:28 -0700 Subject: [PATCH 4170/4858] Clarify the `wp_blogs` table also needs to be replaced on MS --- php/commands/search-replace.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 812258badd..5de6afa3cc 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -86,8 +86,8 @@ class Search_Replace_Command extends WP_CLI_Command { * * 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' + * # Turn your production multisite database into a local dev database + * wp search-replace --url=example.com example.com example.dev 'wp_*_options' wp_blogs * * # Search/replace to a SQL file without transforming the database * wp search-replace foo bar --export=database.sql From 8eb904456f63364259e801ead16f254cbcec5cc6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 23 Mar 2016 16:25:11 -0700 Subject: [PATCH 4171/4858] Use next significant release operators for Composer dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` local ➜ wp-cli git:(master) composer update Loading composer repositories with package information Updating dependencies (including require-dev) - Removing symfony/filesystem (v2.7.10) - Installing symfony/filesystem (v2.8.3) Downloading: 100% - Removing symfony/finder (v2.7.10) - Installing symfony/finder (v2.8.3) Downloading: 100% - Installing symfony/polyfill-mbstring (v1.1.1) Downloading: 100% - Removing symfony/console (v2.7.10) - Installing symfony/console (v2.8.3) Downloading: 100% - Removing composer/composer (1.0.0-alpha11) - Installing composer/composer (1.0.0-beta1) Downloading: 100% - Removing symfony/yaml (v2.7.10) - Installing symfony/yaml (v2.8.3) Downloading: 100% - Removing symfony/config (v2.7.10) - Installing symfony/config (v2.8.3) Downloading: 100% - Removing symfony/dependency-injection (v2.7.10) - Installing symfony/dependency-injection (v2.8.3) Downloading: 100% - Removing symfony/event-dispatcher (v2.7.10) - Installing symfony/event-dispatcher (v2.8.3) Downloading: 100% - Removing symfony/translation (v2.7.10) - Installing symfony/translation (v2.8.3) Downloading: 100% Writing lock file Generating autoload files ``` --- composer.json | 22 +++--- composer.lock | 210 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 147 insertions(+), 85 deletions(-) diff --git a/composer.json b/composer.json index 094e138683..66efa52b31 100644 --- a/composer.json +++ b/composer.json @@ -11,21 +11,21 @@ "php": ">=5.3.2", "wp-cli/php-cli-tools": "~0.11.1", "mustache/mustache": "~2.4", - "mustangostang/spyc": "0.5.1", + "mustangostang/spyc": "~0.5", "composer/semver": "~1.0", "ramsey/array_column": "~1.1", "rmccue/requests": "~1.6", - "symfony/finder": "2.7.*", - "symfony/yaml": "2.7.*", - "symfony/filesystem": "2.7.*", - "symfony/config": "2.7.*", - "symfony/console": "2.7.*", - "symfony/dependency-injection": "2.7.*", - "symfony/event-dispatcher": "2.7.*", + "symfony/finder": "~2.7", + "symfony/yaml": "~2.7", + "symfony/filesystem": "~2.7", + "symfony/config": "~2.7", + "symfony/console": "~2.7", + "symfony/dependency-injection": "~2.7", + "symfony/event-dispatcher": "~2.7", "symfony/process": "~2.1", - "symfony/translation": "2.7.*", - "nb/oxymel": "0.1.0", - "composer/composer": "1.0.0-alpha11" + "symfony/translation": "~2.7", + "nb/oxymel": "~0.1.0", + "composer/composer": "~1.0.0-beta" }, "require-dev": { "phpunit/phpunit": "3.7.*", diff --git a/composer.lock b/composer.lock index 7f71b981d7..3d9ba656de 100644 --- a/composer.lock +++ b/composer.lock @@ -4,30 +4,30 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "826f45f99932268bb0bd8d8ad99505db", - "content-hash": "2aa6852b8aa1adbdaa0bf5bf09014eed", + "hash": "486865db5310fe94efdc68e6f0bcd370", + "content-hash": "6b640d71d1ddb8f42c44dfc0b508b9ae", "packages": [ { "name": "composer/composer", - "version": "1.0.0-alpha11", + "version": "1.0.0-beta1", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "cd9054ce2abd1d06ed0eb1244eba1b2c2af633b6" + "reference": "5cb2b522637a941d608c58bd522f3b2a7bda4a1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/cd9054ce2abd1d06ed0eb1244eba1b2c2af633b6", - "reference": "cd9054ce2abd1d06ed0eb1244eba1b2c2af633b6", + "url": "https://api.github.com/repos/composer/composer/zipball/5cb2b522637a941d608c58bd522f3b2a7bda4a1c", + "reference": "5cb2b522637a941d608c58bd522f3b2a7bda4a1c", "shasum": "" }, "require": { "composer/semver": "^1.0", "composer/spdx-licenses": "^1.0", - "justinrainbow/json-schema": "^1.4.4", + "justinrainbow/json-schema": "^1.6", "php": "^5.3.2 || ^7.0", "seld/cli-prompt": "^1.0", - "seld/jsonlint": "^1.0", + "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.0", "symfony/console": "^2.5 || ^3.0", "symfony/filesystem": "^2.5 || ^3.0", @@ -40,7 +40,8 @@ }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", - "ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic" + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" }, "bin": [ "bin/composer" @@ -79,7 +80,7 @@ "dependency", "package" ], - "time": "2015-11-14 16:21:07" + "time": "2016-03-03 15:15:10" }, { "name": "composer/semver", @@ -638,21 +639,21 @@ }, { "name": "symfony/config", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "833beea4b0bc083a5aea84b9cf725248a74aaaff" + "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/833beea4b0bc083a5aea84b9cf725248a74aaaff", - "reference": "833beea4b0bc083a5aea84b9cf725248a74aaaff", + "url": "https://api.github.com/repos/symfony/config/zipball/0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19", + "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19", "shasum": "" }, "require": { "php": ">=5.3.9", - "symfony/filesystem": "~2.3" + "symfony/filesystem": "~2.3|~3.0.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -660,7 +661,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -687,29 +688,30 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-02-22 16:12:29" + "time": "2016-02-22 16:12:45" }, { "name": "symfony/console", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ee91ec301cd88ee38ab14505025fe94bbc19a9c1" + "reference": "56cc5caf051189720b8de974e4746090aaa10d44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ee91ec301cd88ee38ab14505025fe94bbc19a9c1", - "reference": "ee91ec301cd88ee38ab14505025fe94bbc19a9c1", + "url": "https://api.github.com/repos/symfony/console/zipball/56cc5caf051189720b8de974e4746090aaa10d44", + "reference": "56cc5caf051189720b8de974e4746090aaa10d44", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/process": "~2.1" + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" }, "suggest": { "psr/log": "For using the console logger", @@ -719,7 +721,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -746,20 +748,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-02-28 16:19:47" + "time": "2016-02-28 16:20:50" }, { "name": "symfony/dependency-injection", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "157326648175d52326cd9b9e5f4fef207dc447f9" + "reference": "62251761a7615435b22ccf562384c588b431be44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/157326648175d52326cd9b9e5f4fef207dc447f9", - "reference": "157326648175d52326cd9b9e5f4fef207dc447f9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/62251761a7615435b22ccf562384c588b431be44", + "reference": "62251761a7615435b22ccf562384c588b431be44", "shasum": "" }, "require": { @@ -769,9 +771,9 @@ "symfony/expression-language": "<2.6" }, "require-dev": { - "symfony/config": "~2.2", - "symfony/expression-language": "~2.6", - "symfony/yaml": "~2.1" + "symfony/config": "~2.2|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/yaml": "~2.1|~3.0.0" }, "suggest": { "symfony/config": "", @@ -781,7 +783,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -808,20 +810,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-02-28 16:34:40" + "time": "2016-02-28 16:34:46" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b68c0348ba5b3927a6c8e413cc7d594f3ccff3ce" + "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b68c0348ba5b3927a6c8e413cc7d594f3ccff3ce", - "reference": "b68c0348ba5b3927a6c8e413cc7d594f3ccff3ce", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3", + "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3", "shasum": "" }, "require": { @@ -829,10 +831,10 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5", - "symfony/dependency-injection": "~2.6", - "symfony/expression-language": "~2.6", - "symfony/stopwatch": "~2.3" + "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" }, "suggest": { "symfony/dependency-injection": "", @@ -841,7 +843,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -868,20 +870,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-01-27 05:09:39" + "time": "2016-01-27 05:14:19" }, { "name": "symfony/filesystem", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "ce25d60462dd7088fca4feadba08321bee4273b4" + "reference": "65cb36b6539b1d446527d60457248f30d045464d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/ce25d60462dd7088fca4feadba08321bee4273b4", - "reference": "ce25d60462dd7088fca4feadba08321bee4273b4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/65cb36b6539b1d446527d60457248f30d045464d", + "reference": "65cb36b6539b1d446527d60457248f30d045464d", "shasum": "" }, "require": { @@ -890,7 +892,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -917,20 +919,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-02-18 16:03:55" + "time": "2016-02-22 15:02:30" }, { "name": "symfony/finder", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "addcb70b33affbca4f3979b0d000259b63dd6711" + "reference": "877bb4b16ea573cc8c024e9590888fcf7eb7e0f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/addcb70b33affbca4f3979b0d000259b63dd6711", - "reference": "addcb70b33affbca4f3979b0d000259b63dd6711", + "url": "https://api.github.com/repos/symfony/finder/zipball/877bb4b16ea573cc8c024e9590888fcf7eb7e0f7", + "reference": "877bb4b16ea573cc8c024e9590888fcf7eb7e0f7", "shasum": "" }, "require": { @@ -939,7 +941,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -966,7 +968,66 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-02-22 16:12:29" + "time": "2016-02-22 16:12:45" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "1289d16209491b584839022f29257ad859b8532d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", + "reference": "1289d16209491b584839022f29257ad859b8532d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2016-01-20 09:13:37" }, { "name": "symfony/process", @@ -1019,29 +1080,30 @@ }, { "name": "symfony/translation", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "4c61cf815af17eee4cebf0e4c66f56a2f704cfd8" + "reference": "b7b4ebadd2b5e614ff7d2d6fc63e0ed0578909c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/4c61cf815af17eee4cebf0e4c66f56a2f704cfd8", - "reference": "4c61cf815af17eee4cebf0e4c66f56a2f704cfd8", + "url": "https://api.github.com/repos/symfony/translation/zipball/b7b4ebadd2b5e614ff7d2d6fc63e0ed0578909c7", + "reference": "b7b4ebadd2b5e614ff7d2d6fc63e0ed0578909c7", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { "symfony/config": "<2.7" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.7", - "symfony/intl": "~2.4", - "symfony/yaml": "~2.2" + "symfony/config": "~2.8", + "symfony/intl": "~2.4|~3.0.0", + "symfony/yaml": "~2.2|~3.0.0" }, "suggest": { "psr/log": "To use logging capability in translator", @@ -1051,7 +1113,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -1078,20 +1140,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-02-01 20:45:15" + "time": "2016-02-02 09:49:18" }, { "name": "symfony/yaml", - "version": "v2.7.10", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "fc0ad7a7450ed4434c9a397796a9f56199de2053" + "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/fc0ad7a7450ed4434c9a397796a9f56199de2053", - "reference": "fc0ad7a7450ed4434c9a397796a9f56199de2053", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", + "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", "shasum": "" }, "require": { @@ -1100,7 +1162,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -1127,7 +1189,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-02-23 07:38:51" + "time": "2016-02-23 07:41:20" }, { "name": "wp-cli/php-cli-tools", @@ -1670,7 +1732,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "composer/composer": 15 + "composer/composer": 10 }, "prefer-stable": false, "prefer-lowest": false, From 9d70d2f8fd332073c0915341813072ed2d1aa691 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 04:21:40 -0700 Subject: [PATCH 4172/4858] Catch exceptions in a couple more places --- php/commands/package.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 8f7c651048..33eb33044c 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -248,7 +248,11 @@ private function get_community_packages() { static $community_packages; if ( null === $community_packages ) { - $community_packages = $this->package_index()->getPackages(); + try { + $community_packages = $this->package_index()->getPackages(); + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } } return $community_packages; @@ -272,7 +276,11 @@ private function package_index() { ))); $config->setConfigSource( new JsonConfigSource( $this->get_composer_json() ) ); - $package_index = new ComposerRepository( array( 'url' => self::PACKAGE_INDEX_URL ), new NullIO, $config ); + try { + $package_index = new ComposerRepository( array( 'url' => self::PACKAGE_INDEX_URL ), new NullIO, $config ); + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } } return $package_index; From 8b1eff834b660e66c9047f94a7b341f7d99ec71e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 04:24:29 -0700 Subject: [PATCH 4173/4858] Permit downloading Composer packages over http The Package Index is served over http, which we should probably change. For the time being, we need to unfatal the fatal. --- php/commands/package.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 33eb33044c..0fde97e9f8 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -271,9 +271,12 @@ private function package_index() { if ( !$package_index ) { $config = new Config(); - $config->merge(array('config' => array( - 'home' => dirname( $this->get_composer_json_path() ), - ))); + $config->merge( array( + 'config' => array( + 'secure-http' => false, + 'home' => dirname( $this->get_composer_json_path() ), + ) + )); $config->setConfigSource( new JsonConfigSource( $this->get_composer_json() ) ); try { From aee7928565567a9b347c5c86969b0adfe88481b4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 06:36:35 -0700 Subject: [PATCH 4174/4858] Use the proper method signature to prevent another fatal --- php/WP_CLI/ComposerIO.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/ComposerIO.php b/php/WP_CLI/ComposerIO.php index 01197c9226..85afaf9ffb 100644 --- a/php/WP_CLI/ComposerIO.php +++ b/php/WP_CLI/ComposerIO.php @@ -20,14 +20,14 @@ public function isVerbose() { /** * {@inheritDoc} */ - public function write( $messages, $newline = true ) { + public function write( $messages, $newline = true, $verbosity = self::NORMAL ) { self::output_clean_message( $messages ); } /** * {@inheritDoc} */ - public function writeError( $messages, $newline = true ) { + public function writeError( $messages, $newline = true, $verbosity = self::NORMAL ) { self::output_clean_message( $messages ); } From f79ba98346cbfaac5b2b0d286343ef6331118dff Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 12:14:33 -0700 Subject: [PATCH 4175/4858] Define variable, for when `$install->run()` doesn't return a value --- php/commands/package.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/package.php b/php/commands/package.php index 0fde97e9f8..3be813eb49 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -112,6 +112,7 @@ public function install( $args, $assoc_args ) { // Try running the installer, but revert composer.json if failed WP_CLI::log( 'Using Composer to install the package...' ); WP_CLI::log( '---' ); + $res = false; try { $res = $install->run(); } catch ( Exception $e ) { From a7d9f9a9793915a5e14f601251d5cd90e2168b82 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 12:16:43 -0700 Subject: [PATCH 4176/4858] Also set `secure-http=>false` for the packages composer.json See 8b1eff834b660e66c9047f94a7b341f7d99ec71e --- php/commands/package.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/package.php b/php/commands/package.php index 3be813eb49..5605a39c1a 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -93,6 +93,7 @@ public function install( $args, $assoc_args ) { $json_manipulator = new JsonManipulator( $composer_backup ); $json_manipulator->addMainKey( 'name', 'wp-cli/wp-cli' ); $json_manipulator->addLink( 'require', $package_name, $version ); + $json_manipulator->addConfigSetting( 'secure-http', false ); file_put_contents( $composer_json_obj->getPath(), $json_manipulator->getContents() ); try { $composer = $this->get_composer(); From d265824ed5f16c78a1a482fe240c151682eed1c9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 12:31:26 -0700 Subject: [PATCH 4177/4858] Mark `WP_CLI::run_command()` public; clarify `::launch_self()` See https://github.com/wp-cli/scaffold-package-command/commit/7dc321c864893e5d2afda17471cd2a664a2968b5 --- php/WP_CLI/Runner.php | 3 +-- php/class-wp-cli.php | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index cd16de1147..43bde527a2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -300,8 +300,7 @@ public function find_command_to_run( $args ) { } /** - * Find the WP-CLI command to run given arguments, - * and invoke it. + * Find the WP-CLI command to run given arguments, and invoke it. * * @param array $args Positional arguments including command name * @param array $assoc_args diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 0847b95df4..7e2c1de3ce 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -670,6 +670,11 @@ public static function launch( $command, $exit_on_error = true, $return_detailed /** * Run a WP-CLI command in a new process reusing the current runtime arguments. * + * Note: While this command does persist a limited set of runtime arguments, + * it *does not* persist environment variables. Practically speaking, WP-CLI + * packages won't be loaded when using WP_CLI::launch_self() because the + * launched process doesn't have access to the current process $HOME. + * * @access public * @category Execution * @@ -745,13 +750,24 @@ public static function get_config( $key = null ) { } /** - * Run a given command within the current process using the same global parameters. + * Run a given command within the current process using the same global + * parameters. + * + * To run a command using a new process with the same global parameters, + * use WP_CLI::launch_self(). To run a command using a new process with + * different global parameters, use WP_CLI::launch(). + * + * ``` + * ob_start(); + * WP_CLI::run_command( array( 'cli', 'cmd-dump' ) ); + * $ret = ob_get_clean(); + * ``` * - * To run a command using a new process with the same global parameters, use WP_CLI::launch_self() - * To run a command using a new process with different global parameters, use WP_CLI::launch() + * @access public + * @category Execution * - * @param array - * @param array + * @param array $args Positional arguments including command name. + * @param array $assoc_args */ public static function run_command( $args, $assoc_args = array() ) { self::get_runner()->run_command( $args, $assoc_args ); From 54be268e9e6df19ba4ae399355e41b38f46ea88e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 24 Mar 2016 14:57:17 -0700 Subject: [PATCH 4178/4858] Failing test case for arg/param arg parsing --- tests/test-doc-parser.php | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index ec91eed0bd..41b43138d2 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -135,5 +135,57 @@ public function test_desc_parses_yaml() { $this->assertNull( $doc->get_param_args( 'artist' ) ); } + public function test_desc_doesnt_parse_far_params_yaml() { + $longdesc = <<<EOB +## OPTIONS + +<hook> +: The name of the action or filter. + +[--format=<format>] +: List callbacks as a table, JSON, CSV, or YAML. +--- +default: table +options: + - table + - json + - csv + - yaml +--- +EOB; + $doc = new DocParser( $longdesc ); + $this->assertEquals( $doc->get_param_args( 'format' ), array( + 'default' => 'table', + 'options' => array( 'table', 'json', 'csv', 'yaml' ), + ) ); + $this->assertNull( $doc->get_arg_args( 'hook' ) ); + } + + public function test_desc_doesnt_parse_far_args_yaml() { + $longdesc = <<<EOB +## OPTIONS + +<hook> +: The name of the action or filter. + +<format> +: List callbacks as a table, JSON, CSV, or YAML. +--- +default: table +options: + - table + - json + - csv + - yaml +--- +EOB; + $doc = new DocParser( $longdesc ); + $this->assertEquals( $doc->get_arg_args( 'format' ), array( + 'default' => 'table', + 'options' => array( 'table', 'json', 'csv', 'yaml' ), + ) ); + $this->assertNull( $doc->get_arg_args( 'hook' ) ); + } + } From a7d86a3ea445d1a344f4e62a9db444e602cb1edc Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Fri, 25 Mar 2016 01:33:01 -0400 Subject: [PATCH 4179/4858] Fix plugin header formatting Currently the `@package` tag and the plugin name header are both formatted as `Plugin-name`. Logically, you'd expect the plugin name header to be formatted as `Plugin Name`, and according to the WordPress documentation standards the `@package` tag should be capitalized and separated by underscores (e.g. `Plugin_Name`). This commit fixes those issues. --- php/commands/scaffold.php | 7 +++++-- templates/plugin.mustache | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 1df51eb1b0..d60fe821e6 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -515,11 +515,14 @@ public function package_tests( $args, $assoc_args ) { * */ function plugin( $args, $assoc_args ) { - $plugin_slug = $args[0]; + $plugin_slug = $args[0]; + $plugin_name = ucwords( str_replace( '-', ' ', $plugin_slug ) ); + $plugin_package = str_replace( ' ', '_', $plugin_name ); $data = wp_parse_args( $assoc_args, array( 'plugin_slug' => $plugin_slug, - 'plugin_name' => ucfirst( $plugin_slug ), + 'plugin_name' => $plugin_name, + 'plugin_package' => $plugin_package, 'plugin_description' => 'PLUGIN DESCRIPTION HERE', 'plugin_author' => 'YOUR NAME HERE', 'plugin_author_uri' => 'YOUR SITE HERE', diff --git a/templates/plugin.mustache b/templates/plugin.mustache index 1673f7357e..c96eb303db 100644 --- a/templates/plugin.mustache +++ b/templates/plugin.mustache @@ -8,5 +8,5 @@ * Plugin URI: {{plugin_uri}} * Text Domain: {{textdomain}} * Domain Path: /languages - * @package {{plugin_name}} + * @package {{plugin_package}} */ From 345d80420e93d3be18926f2f8d7ce1d6b35e46a3 Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Fri, 25 Mar 2016 01:33:01 -0400 Subject: [PATCH 4180/4858] Fix plugin header formatting Currently the `@package` tag and the plugin name header are both formatted as `Plugin-name`. Logically, you'd expect the plugin name header to be formatted as `Plugin Name`, and according to the WordPress documentation standards the `@package` tag should be capitalized and separated by underscores (e.g. `Plugin_Name`). This commit fixes those issues. --- php/commands/scaffold.php | 7 +++++-- templates/plugin.mustache | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 4cb86394de..4903b6ad4a 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -410,11 +410,14 @@ private function get_output_path( $assoc_args, $subdir ) { * */ function plugin( $args, $assoc_args ) { - $plugin_slug = $args[0]; + $plugin_slug = $args[0]; + $plugin_name = ucwords( str_replace( '-', ' ', $plugin_slug ) ); + $plugin_package = str_replace( ' ', '_', $plugin_name ); $data = wp_parse_args( $assoc_args, array( 'plugin_slug' => $plugin_slug, - 'plugin_name' => ucfirst( $plugin_slug ), + 'plugin_name' => $plugin_name, + 'plugin_package' => $plugin_package, 'plugin_description' => 'PLUGIN DESCRIPTION HERE', 'plugin_author' => 'YOUR NAME HERE', 'plugin_author_uri' => 'YOUR SITE HERE', diff --git a/templates/plugin.mustache b/templates/plugin.mustache index 1673f7357e..c96eb303db 100644 --- a/templates/plugin.mustache +++ b/templates/plugin.mustache @@ -8,5 +8,5 @@ * Plugin URI: {{plugin_uri}} * Text Domain: {{textdomain}} * Domain Path: /languages - * @package {{plugin_name}} + * @package {{plugin_package}} */ From 708bf6975a8fc9d57c3e9f2cc53dcf776c0f0722 Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Sat, 26 Mar 2016 14:34:40 -0400 Subject: [PATCH 4181/4858] Fix headers for other plugin files Updated the `@package` tags in `templates/bootstrap.mustache` and `templates/test-sample.php` --- templates/bootstrap.mustache | 2 +- templates/test-sample.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/bootstrap.mustache b/templates/bootstrap.mustache index fb44b66402..05c21bf1e6 100644 --- a/templates/bootstrap.mustache +++ b/templates/bootstrap.mustache @@ -2,7 +2,7 @@ /** * PHPUnit bootstrap file * - * @package {{plugin_slug}} + * @package {{plugin_package}} */ $_tests_dir = getenv( 'WP_TESTS_DIR' ); diff --git a/templates/test-sample.php b/templates/test-sample.php index 0264e9ffd0..2e897d13dd 100644 --- a/templates/test-sample.php +++ b/templates/test-sample.php @@ -2,7 +2,7 @@ /** * Class SampleTest * - * @package + * @package {{plugin_package}} */ /** @@ -18,4 +18,3 @@ function test_sample() { $this->assertTrue( true ); } } - From 27993ff60bc6928748f6503bb7fd2d473d43574f Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Sat, 26 Mar 2016 23:14:16 -0400 Subject: [PATCH 4182/4858] Update functional tests for new plugin header values --- features/scaffold.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index e7ddedaa8e..dfe8ee71ee 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -123,6 +123,14 @@ Feature: WordPress code scaffolding .DS_Store node_modules/ """ + And the {PLUGIN_DIR}/hello-world/hello-world.php should contain: + """ + * Plugin Name: Hello World + """ + And the {PLUGIN_DIR}/hello-world/hello-world.php should contain: + """ + * @package Hello_World + """ When I run `cat {PLUGIN_DIR}/hello-world/package.json` Then STDOUT should be JSON containing: @@ -206,6 +214,14 @@ Feature: WordPress code scaffolding """ require dirname( dirname( __FILE__ ) ) . '/hello-world.php'; """ + And the {PLUGIN_DIR}/hello-world/tests/bootstrap.php file should contain: + """ + * @package Hello World + """ + And the {PLUGIN_DIR}/hello-world/tests/test-sample.php file should contain: + """ + * @package Hello World + """ And the {PLUGIN_DIR}/hello-world/bin directory should contain: """ install-wp-tests.sh From bcb114c3314428fd94c4872ea0376bd176a7fa7c Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Sun, 27 Mar 2016 01:27:01 -0400 Subject: [PATCH 4183/4858] Fix missing `@package` in plugin test files Also fixed a couple of typos in `scaffold.feature` --- features/scaffold.feature | 4 ++-- php/commands/scaffold.php | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index dfe8ee71ee..201db6568d 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -216,11 +216,11 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/tests/bootstrap.php file should contain: """ - * @package Hello World + * @package Hello_World """ And the {PLUGIN_DIR}/hello-world/tests/test-sample.php file should contain: """ - * @package Hello World + * @package Hello_World """ And the {PLUGIN_DIR}/hello-world/bin directory should contain: """ diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 4903b6ad4a..60873ad79c 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -528,6 +528,9 @@ function plugin_tests( $args, $assoc_args ) { WP_CLI::error( 'Invalid plugin specified.' ); } + $plugin_name = ucwords( str_replace( '-', ' ', $plugin_slug ) ); + $plugin_package = str_replace( ' ', '_', $plugin_name ); + $tests_dir = "$plugin_dir/tests"; $bin_dir = "$plugin_dir/bin"; @@ -549,16 +552,21 @@ function plugin_tests( $args, $assoc_args ) { } } + $plugin_data = array( + 'plugin_slug' => $plugin_slug, + 'plugin_package' => $plugin_package, + ); + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( - "$tests_dir/bootstrap.php" => Utils\mustache_render( 'bootstrap.mustache', compact( 'plugin_slug' ) ), - "$plugin_dir/.travis.yml" => Utils\mustache_render( '.travis.mustache', compact( 'wp_versions_to_test' ) ) + "$tests_dir/bootstrap.php" => Utils\mustache_render( 'bootstrap.mustache', $plugin_data ), + "$tests_dir/test-sample.php" => Utils\mustache_render( 'test-sample.php', $plugin_data ), + "$plugin_dir/.travis.yml" => Utils\mustache_render( '.travis.mustache', compact( 'wp_versions_to_test' ) ), ), $force ); $to_copy = array( 'install-wp-tests.sh' => $bin_dir, 'phpunit.xml.dist' => $plugin_dir, - 'test-sample.php' => $tests_dir, ); foreach ( $to_copy as $file => $dir ) { From 314ccebbbb9f72063e1fe77a29f891de618b21f7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 27 Mar 2016 06:35:53 -0700 Subject: [PATCH 4184/4858] Use `is_callable()` in `WP_CLI:add_command()` This is much better than rolling our own equivalent logic --- php/class-wp-cli.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7e2c1de3ce..17e66724b6 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -249,16 +249,12 @@ public static function do_hook( $when ) { */ public static function add_command( $name, $callable, $args = array() ) { $valid = false; - if ( is_object( $callable ) && ( $callable instanceof \Closure ) ) { - $valid = true; - } else if ( is_string( $callable ) && function_exists( $callable ) ) { + if ( is_callable( $callable ) ) { $valid = true; } else if ( is_string( $callable ) && class_exists( (string) $callable ) ) { $valid = true; } else if ( is_object( $callable ) ) { $valid = true; - } else if ( is_array( $callable ) && is_callable( $callable ) ) { - $valid = true; } if ( ! $valid ) { if ( is_array( $callable ) ) { From 90950a1ee1c23d3cb9221fcad0dd71a12ce7f7f5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Mar 2016 04:35:31 -0700 Subject: [PATCH 4185/4858] Rename test-sample.php to test-sample.mustache It's now a template --- php/commands/scaffold.php | 2 +- templates/{test-sample.php => test-sample.mustache} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename templates/{test-sample.php => test-sample.mustache} (100%) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 60873ad79c..27a48e1972 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -560,7 +560,7 @@ function plugin_tests( $args, $assoc_args ) { $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); $files_written = $this->create_files( array( "$tests_dir/bootstrap.php" => Utils\mustache_render( 'bootstrap.mustache', $plugin_data ), - "$tests_dir/test-sample.php" => Utils\mustache_render( 'test-sample.php', $plugin_data ), + "$tests_dir/test-sample.php" => Utils\mustache_render( 'test-sample.mustache', $plugin_data ), "$plugin_dir/.travis.yml" => Utils\mustache_render( '.travis.mustache', compact( 'wp_versions_to_test' ) ), ), $force ); diff --git a/templates/test-sample.php b/templates/test-sample.mustache similarity index 100% rename from templates/test-sample.php rename to templates/test-sample.mustache From 867b0331b7e30beb508dd40f641a80aac1d9cfdc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 28 Mar 2016 04:37:56 -0700 Subject: [PATCH 4186/4858] Fix assertions --- features/scaffold.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 201db6568d..e7fd1fd23f 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -123,11 +123,11 @@ Feature: WordPress code scaffolding .DS_Store node_modules/ """ - And the {PLUGIN_DIR}/hello-world/hello-world.php should contain: + And the {PLUGIN_DIR}/hello-world/hello-world.php file should contain: """ * Plugin Name: Hello World """ - And the {PLUGIN_DIR}/hello-world/hello-world.php should contain: + And the {PLUGIN_DIR}/hello-world/hello-world.php file should contain: """ * @package Hello_World """ From 15693aa98b041ed9b62ef0351abac3888b282d3a Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Mon, 28 Mar 2016 17:46:20 -0700 Subject: [PATCH 4187/4858] allow newlines in $prompt --- php/WP_CLI/REPL.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index 576359ecc0..0a14b3e422 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -80,18 +80,14 @@ private static function create_prompt_cmd( $prompt, $history_path ) { $prompt = escapeshellarg( $prompt ); $history_path = escapeshellarg( $history_path ); - $cmd = <<<BASH -set -f -history -r $history_path -LINE="" -read -re -p $prompt LINE -[ $? -eq 0 ] || exit -history -s "\$LINE" -history -w $history_path -echo \$LINE -BASH; - - $cmd = str_replace( "\n", '; ', $cmd ); + $cmd = "set -f; " + . "history -r $history_path; " + . "LINE=\"\"; " + . "read -re -p $prompt LINE; " + . "[ $? -eq 0 ] || exit; " + . "history -s \"\$LINE\"; " + . "history -w $history_path; " + . "echo \$LINE; "; return '/bin/bash -c ' . escapeshellarg( $cmd ); } From f82f244b823223f646cb31492e901dfa671f38ad Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Mon, 28 Mar 2016 17:46:52 -0700 Subject: [PATCH 4188/4858] add newline to REPL prompt --- php/commands/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index 0bb052ff57..d0c39bd721 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -35,7 +35,7 @@ public function __invoke( $_, $assoc_args ) { if ( '\\Psy\\Shell' == $class ) { \Psy\Shell::debug(); } else { - $repl = new $class( 'wp> ' ); + $repl = new $class( "\nwp> " ); $repl->start(); } } From e89d03a03025ff477a0927c4eb7fb5af0a298a5a Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Tue, 29 Mar 2016 17:51:35 -0700 Subject: [PATCH 4189/4858] force set default timezone --- php/commands/package.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/package.php b/php/commands/package.php index 5605a39c1a..e23040d150 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -238,6 +238,10 @@ private function get_composer() { // the 'vendor-dir' is, and where Composer is running from. // Best to just pretend we're installing a package from ~/.wp-cli or similar chdir( pathinfo( $composer_path, PATHINFO_DIRNAME ) ); + + // Prevent DateTime error/warning when no timezone set + date_default_timezone_set( @date_default_timezone_get() ); + return Factory::create( new NullIO, $composer_path ); } From f242229dd2b35b034a808efc4a5143c1b53d994a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 31 Mar 2016 08:48:54 -0700 Subject: [PATCH 4190/4858] Explain what `wp cron test` actually does --- php/commands/cron.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index ccc763485d..4b52d42a39 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -487,6 +487,13 @@ class Cron_Command extends WP_CLI_Command { /** * Test the WP Cron spawning system and report back its status. + * + * This command tests the spawning system by performing the following steps: + * * Checks to see if the `DISABLE_WP_CRON` constant is set; errors if true + * because WP-Cron is disabled. + * * Checks to see if the `ALTERNATE_WP_CRON` constant is set; warns if true + * * Attempts to spawn WP-Cron over HTTP; warns if non 200 response code is + * returned. */ public function test() { From 02b5b8cd54add1b2b0c370a386d5b23f5a7a0477 Mon Sep 17 00:00:00 2001 From: Mark Jaquith <mark.github@txfx.net> Date: Thu, 31 Mar 2016 22:43:38 -0400 Subject: [PATCH 4191/4858] Squash `wp export` notice about `skip_comments` 2ad7b8e21fa introduced a PHP notice because `$this->filters['skip_comments']` is checked, but it won't exist if the flag isn't set. --- php/export/class-wp-export-query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/export/class-wp-export-query.php b/php/export/class-wp-export-query.php index e228fbfcd4..6258d21691 100644 --- a/php/export/class-wp-export-query.php +++ b/php/export/class-wp-export-query.php @@ -356,7 +356,7 @@ private static function get_meta_for_post( $post ) { private function get_comments_for_post( $post ) { global $wpdb; - if ( $this->filters['skip_comments'] ) { + if ( isset( $this->filters['skip_comments'] ) ) { return array(); } From 4c6b3a75ddd77c1871ec1cf390eaa679d836c96a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Apr 2016 09:13:00 -0700 Subject: [PATCH 4192/4858] Use `--format=ids` with `wp (*) generate` output generated ids More helpful than a progress bar for chaining commands together: ``` wp user generate --format=ids | xargs -0 -d ' ' -I % wp user meta add % foo bar ``` --- features/comment-generate.feature | 17 ++++++++++++---- features/post-generate.feature | 11 +++++++++++ features/term-generate.feature | 14 +++++++++++++ features/user-generate.feature | 14 +++++++++++++ php/commands/comment.php | 33 +++++++++++++++++++++++++++---- php/commands/post.php | 27 ++++++++++++++++++++++--- php/commands/term.php | 27 ++++++++++++++++++++++--- php/commands/user.php | 28 +++++++++++++++++++++++--- 8 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 features/term-generate.feature create mode 100644 features/user-generate.feature diff --git a/features/comment-generate.feature b/features/comment-generate.feature index e3742ee9a2..ee7cc72fdd 100644 --- a/features/comment-generate.feature +++ b/features/comment-generate.feature @@ -1,8 +1,9 @@ Feature: Generate comments - Scenario: Generate a specific number of comments - Given a WP install + Background: + Given a WP install + Scenario: Generate a specific number of comments When I run `wp comment generate --count=20` And I run `wp comment list --format=count` Then STDOUT should be: @@ -11,8 +12,6 @@ Feature: Generate comments """ Scenario: Generate comments assigned to a specific post - Given a WP install - When I run `wp comment generate --count=4 --post_id=2` And I run `wp comment list --post_id=2 --format=count` Then STDOUT should be: @@ -25,3 +24,13 @@ Feature: Generate comments """ 1 """ + + Scenario: Generating comments and outputting ids + When I run `wp comment generate --count=1 --format=ids` + Then save STDOUT as {COMMENT_ID} + + When I run `wp comment update {COMMENT_ID} --comment_content="foo"` + Then STDOUT should contain: + """ + Success: + """ diff --git a/features/post-generate.feature b/features/post-generate.feature index 9a3e039c53..6dec688abf 100644 --- a/features/post-generate.feature +++ b/features/post-generate.feature @@ -31,3 +31,14 @@ Feature: Generate new WordPress posts """ 1 """ + + Scenario: Generating posts and outputting ids + When I run `wp post generate --count=1 --format=ids` + Then save STDOUT as {POST_ID} + + When I run `wp post update {POST_ID} --post_title="foo"` + Then STDOUT should contain: + """ + Success: + """ + diff --git a/features/term-generate.feature b/features/term-generate.feature new file mode 100644 index 0000000000..58918ddfc2 --- /dev/null +++ b/features/term-generate.feature @@ -0,0 +1,14 @@ +Feature: Generate WP terms + + Background: + Given a WP install + + Scenario: Generating terms and outputting ids + When I run `wp term generate category --count=1 --format=ids` + Then save STDOUT as {TERM_ID} + + When I run `wp term update category {TERM_ID} --name="foo"` + Then STDOUT should contain: + """ + Success: + """ diff --git a/features/user-generate.feature b/features/user-generate.feature new file mode 100644 index 0000000000..bf747d4a51 --- /dev/null +++ b/features/user-generate.feature @@ -0,0 +1,14 @@ +Feature: Generate WP users + + Background: + Given a WP install + + Scenario: Generating users and outputting ids + When I run `wp user generate --count=1 --format=ids` + Then save STDOUT as {USER_ID} + + When I run `wp user update {USER_ID} --display_name="foo"` + Then STDOUT should contain: + """ + Success: + """ diff --git a/php/commands/comment.php b/php/commands/comment.php index 45a01d86f9..3eb74fa305 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -99,6 +99,14 @@ public function update( $args, $assoc_args ) { * * [--post_id=<post-id>] * : Assign comments to a specific post. + * + * [--format=<format>] + * : Accepted values: progress, ids. Default: ids. + * + * ## EXAMPLES + * + * # Add meta to every generated comment + * wp comment generate --format=ids | xargs -0 -d ' ' -I % wp comment meta add % foo bar */ public function generate( $args, $assoc_args ) { @@ -108,20 +116,37 @@ public function generate( $args, $assoc_args ) { ); $assoc_args = array_merge( $defaults, $assoc_args ); - $notify = \WP_CLI\Utils\make_progress_bar( 'Generating comments', $assoc_args['count'] ); + $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++ ) { - wp_insert_comment( array( + $comment_id = wp_insert_comment( array( 'comment_content' => "Comment {$i}", 'comment_post_ID' => $assoc_args['post_id'], ) ); - $notify->tick(); + if ( 'progress' === $format ) { + $notify->tick(); + } else if ( 'ids' === $format ) { + if ( 'ids' === $format ) { + echo $comment_id; + if ( $i < $limit - 1 ) { + echo ' '; + } + } + } } - $notify->finish(); + if ( 'progress' === $format ) { + $notify->finish(); + } } diff --git a/php/commands/post.php b/php/commands/post.php index 61cbd0beb4..aa75dfd21b 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -352,10 +352,16 @@ public function list_( $_, $assoc_args ) { * [--max_depth=<number>] * : For hierarchical post types, generate child posts down to a certain depth. Default: 1 * + * [--format=<format>] + * : Accepted values: progress, ids. Default: ids. + * * ## 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 + * + * # Add meta to every generated post + * wp post generate --format=ids | xargs -0 -d ' ' -I % wp post meta add % foo bar */ public function generate( $args, $assoc_args ) { global $wpdb; @@ -394,7 +400,12 @@ public function generate( $args, $assoc_args ) { $limit = $count + $total; - $notify = \WP_CLI\Utils\make_progress_bar( 'Generating posts', $count ); + $format = \WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'progress' ); + + $notify = false; + if ( 'progress' === $format ) { + $notify = \WP_CLI\Utils\make_progress_bar( 'Generating posts', $count ); + } $previous_post_id = 0; $current_depth = 1; @@ -433,11 +444,21 @@ public function generate( $args, $assoc_args ) { WP_CLI::warning( $post_id ); } else { $previous_post_id = $post_id; + if ( 'ids' === $format ) { + echo $post_id; + if ( $i < $limit - 1 ) { + echo ' '; + } + } } - $notify->tick(); + if ( 'progress' === $format ) { + $notify->tick(); + } + } + if ( 'progress' === $format ) { + $notify->finish(); } - $notify->finish(); // @codingStandardsIgnoreEnd } diff --git a/php/commands/term.php b/php/commands/term.php index 049fa6515c..84ac9d61d5 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -293,9 +293,15 @@ public function delete( $args ) { * [--max_depth=<number>] * : Generate child terms down to a certain depth. Default: 1 * + * [--format=<format>] + * : Accepted values: progress, ids. Default: ids. + * * ## EXAMPLES * * wp term generate --count=10 + * + * # Add meta to every generated term + * wp term generate category --format=ids | xargs -0 -d ' ' -I % wp term meta add % foo bar */ public function generate( $args, $assoc_args ) { global $wpdb; @@ -318,7 +324,12 @@ public function generate( $args, $assoc_args ) { $hierarchical = get_taxonomy( $taxonomy )->hierarchical; - $notify = \WP_CLI\Utils\make_progress_bar( 'Generating terms', $count ); + $format = \WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'progress' ); + + $notify = false; + if ( 'progress' === $format ) { + $notify = \WP_CLI\Utils\make_progress_bar( 'Generating terms', $count ); + } $previous_term_id = 0; $current_parent = 0; @@ -359,15 +370,25 @@ public function generate( $args, $assoc_args ) { } else { $created[] = $term['term_id']; $previous_term_id = $term['term_id']; + if ( 'ids' === $format ) { + echo $term['term_id']; + if ( $i < $max_id + $count ) { + echo ' '; + } + } } - $notify->tick(); + if ( 'progress' === $format ) { + $notify->tick(); + } } wp_suspend_cache_invalidation( $suspend_cache_invalidation ); clean_term_cache( $created, $taxonomy ); - $notify->finish(); + if ( 'progress' === $format ) { + $notify->finish(); + } } /** diff --git a/php/commands/user.php b/php/commands/user.php index bda3adcfb0..98c4861505 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -366,6 +366,14 @@ public function update( $args, $assoc_args ) { * * [--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 | xargs -0 -d ' ' -I % wp user meta add % foo bar */ public function generate( $args, $assoc_args ) { global $blog_id; @@ -386,7 +394,12 @@ public function generate( $args, $assoc_args ) { $total = $user_count['total_users']; $limit = $assoc_args['count'] + $total; - $notify = \WP_CLI\Utils\make_progress_bar( 'Generating users', $assoc_args['count'] ); + $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 ); @@ -405,10 +418,19 @@ public function generate( $args, $assoc_args ) { delete_user_option( $user_id, 'user_level' ); } - $notify->tick(); + if ( 'progress' === $format ) { + $notify->tick(); + } else if ( 'ids' === $format ) { + echo $user_id; + if ( $i < $limit - 1 ) { + echo ' '; + } + } } - $notify->finish(); + if ( 'progress' === $format ) { + $notify->finish(); + } } /** From 6597a6db5a773734a014b3015875ec3ad9b59aca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Apr 2016 09:16:55 -0700 Subject: [PATCH 4193/4858] Move tests to more sensible files --- features/term-generate.feature | 17 +++++++++++++++++ features/term.feature | 17 ----------------- features/user-generate.feature | 21 +++++++++++++++++++++ features/user.feature | 23 ----------------------- 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/features/term-generate.feature b/features/term-generate.feature index 58918ddfc2..8da008a7b7 100644 --- a/features/term-generate.feature +++ b/features/term-generate.feature @@ -3,6 +3,23 @@ Feature: Generate WP terms Background: Given a WP install + Scenario: Generating terms + When I run `wp term generate category --count=10` + And I run `wp term list category --format=count` + Then STDOUT should be: + """ + 11 + """ + + Scenario: Generating terms when terms already exist + When I run `wp term generate category --count=10` + And I run `wp term generate category --count=10` + And I run `wp term list category --format=count` + Then STDOUT should be: + """ + 21 + """ + Scenario: Generating terms and outputting ids When I run `wp term generate category --count=1 --format=ids` Then save STDOUT as {TERM_ID} diff --git a/features/term.feature b/features/term.feature index 5efcc7c7f5..91781bdb90 100644 --- a/features/term.feature +++ b/features/term.feature @@ -75,23 +75,6 @@ Feature: Manage WordPress terms When I try the previous command again Then STDERR should not be empty - Scenario: Generating terms - When I run `wp term generate category --count=10` - And I run `wp term list category --format=count` - Then STDOUT should be: - """ - 11 - """ - - Scenario: Generating terms when terms already exist - When I run `wp term generate category --count=10` - And I run `wp term generate category --count=10` - And I run `wp term list category --format=count` - Then STDOUT should be: - """ - 21 - """ - Scenario: Term with a non-existent parent When I try `wp term create category Apple --parent=99 --porcelain` Then STDERR should be: diff --git a/features/user-generate.feature b/features/user-generate.feature index bf747d4a51..cbe263b3c7 100644 --- a/features/user-generate.feature +++ b/features/user-generate.feature @@ -3,6 +3,27 @@ Feature: Generate WP users Background: Given a WP install + Scenario: Generating and deleting users + When I run `wp user list --role=editor --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I run `wp user generate --count=10 --role=editor` + And I run `wp user list --role=editor --format=count` + Then STDOUT should be: + """ + 10 + """ + + When I try `wp user list --field=ID | xargs wp user delete invalid-user --yes` + And I run `wp user list --format=count` + Then STDOUT should be: + """ + 0 + """ + Scenario: Generating users and outputting ids When I run `wp user generate --count=1 --format=ids` Then save STDOUT as {USER_ID} diff --git a/features/user.feature b/features/user.feature index 93a012bb15..3b8662b308 100644 --- a/features/user.feature +++ b/features/user.feature @@ -102,29 +102,6 @@ Feature: Manage WordPress users When I try `wp user get bobjones` Then STDERR should not be empty - Scenario: Generating and deleting users - Given a WP install - - When I run `wp user list --role=editor --format=count` - Then STDOUT should be: - """ - 0 - """ - - When I run `wp user generate --count=10 --role=editor` - And I run `wp user list --role=editor --format=count` - Then STDOUT should be: - """ - 10 - """ - - When I try `wp user list --field=ID | xargs wp user delete invalid-user --yes` - And I run `wp user list --format=count` - Then STDOUT should be: - """ - 0 - """ - Scenario: Create new users on multisite Given a WP multisite install From c6d9601e6067d220297505748dfe43ccca7803d4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Apr 2016 09:25:40 -0700 Subject: [PATCH 4194/4858] Link to the documentation portal from the readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 35090ea9aa..daf127aa0d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ If you want to hack on WP-CLI, see [CONTRIBUTING.md](CONTRIBUTING.md). Where can I get more info? -------------------------- -For documentation and examples, check out [wp-cli.org](http://wp-cli.org/) and the [wiki](https://github.com/wp-cli/wp-cli/wiki). +For documentation and examples, check out [wp-cli.org](http://wp-cli.org/) and the [documentation portal](http://wp-cli.org/docs/). Also, WordPress Answers has a growing list of [WP-CLI related questions](http://wordpress.stackexchange.com/questions/tagged/wp-cli). @@ -23,7 +23,7 @@ I'm running into troubles, what can I do? ----------------------------------------- To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). -If you're reporting a bug, please also post the output from `wp --info`. +If you're reporting a bug, please include the output from `wp --info` and do your best to follow [bug reporting best practices](http://wp-cli.org/docs/bug-reports/). Credits ------- @@ -43,6 +43,6 @@ Who's behind this thing? * [Cristi Burcă](https://github.com/scribu) - previous maintainer * [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer -For more info, see [Governance](https://github.com/wp-cli/wp-cli/wiki/Governance). +For more info, see [Governance](http://wp-cli.org/docs/governance/). A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). From a57b13c2e322048a1e0023d16a7ed0a38988697f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Apr 2016 10:47:59 -0700 Subject: [PATCH 4195/4858] Expand upon `wp db *` docs; explicitly mark methods as public --- php/commands/db.php | 68 +++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index f8a7a281a5..1d1900b440 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -8,9 +8,13 @@ class DB_Command extends WP_CLI_Command { /** - * Create the database, as specified in wp-config.php + * Create the database in MySQL. + * + * Runs `CREATE_DATABASE` MySQL statement using `DB_HOST`, `DB_NAME`, + * `DB_USER` and `DB_PASSWORD` database credentials specified in + * wp-config.php. */ - function create( $_, $assoc_args ) { + public function create( $_, $assoc_args ) { self::run_query( self::get_create_query() ); @@ -18,14 +22,18 @@ function create( $_, $assoc_args ) { } /** - * Delete the database. + * Delete the database in MySQL. + * + * Runs `DROP_DATABASE` MySQL statement using `DB_HOST`, `DB_NAME`, + * `DB_USER` and `DB_PASSWORD` database credentials specified in + * wp-config.php. * * ## OPTIONS * * [--yes] * : Answer yes to the confirmation message. */ - function drop( $_, $assoc_args ) { + public function drop( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); self::run_query( sprintf( 'DROP DATABASE `%s`', DB_NAME ) ); @@ -34,14 +42,18 @@ function drop( $_, $assoc_args ) { } /** - * Remove all tables from the database. + * Remove all tables from the database in MySQL. + * + * Runs `DROP_DATABASE` and `CREATE_DATABASE` MySQL statements using + * `DB_HOST`, `DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials + * specified in wp-config.php. * * ## OPTIONS * * [--yes] * : Answer yes to the confirmation message. */ - function reset( $_, $assoc_args ) { + public function reset( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); self::run_query( sprintf( 'DROP DATABASE IF EXISTS `%s`', DB_NAME ) ); @@ -51,9 +63,16 @@ function reset( $_, $assoc_args ) { } /** - * Optimize the database. + * Optimize the database in MySQL. + * + * Runs `mysqlcheck` utility with `--optimize=true` using `DB_HOST`, + * `DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials + * specified in wp-config.php. + * + * [See docs](http://dev.mysql.com/doc/refman/5.7/en/optimize-table.html) + * for more details on the `OPTIMIZE_TABLE` statement. */ - function optimize() { + public function optimize() { self::run( Utils\esc_cmd( 'mysqlcheck --no-defaults %s', DB_NAME ), array( 'optimize' => true, ) ); @@ -62,9 +81,16 @@ function optimize() { } /** - * Repair the database. + * Repair the database in MySQL. + * + * Runs `mysqlcheck` utility with `--repair=true` using `DB_HOST`, + * `DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials + * specified in wp-config.php. + * + * [See docs](http://dev.mysql.com/doc/refman/5.7/en/repair-table.html) for + * more details on the `REPAIR_TABLE` statement. */ - function repair() { + public function repair() { self::run( Utils\esc_cmd( 'mysqlcheck --no-defaults %s', DB_NAME ), array( 'repair' => true, ) ); @@ -73,18 +99,21 @@ function repair() { } /** - * Open a mysql console using the WordPress credentials. + * Open a MySQL console using credentials from wp-config.php * * @alias connect */ - function cli() { + public function cli() { self::run( 'mysql --no-defaults --no-auto-rehash', array( 'database' => DB_NAME ) ); } /** - * Execute a query against the database. + * Execute a MySQL query against the database. + * + * Executes an arbitrary MySQL query using `DB_HOST`, `DB_NAME`, `DB_USER` + * and `DB_PASSWORD` database credentials specified in wp-config.php. * * ## OPTIONS * @@ -99,7 +128,7 @@ function cli() { * # check all tables in the database * wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" */ - function query( $args ) { + public function query( $args ) { $assoc_args = array( 'database' => DB_NAME ); @@ -113,7 +142,10 @@ function query( $args ) { } /** - * Exports the database to a file or to STDOUT. + * Exports the MySQL database to a file or to STDOUT. + * + * Runs `mysqldump` utility using `DB_HOST`, `DB_NAME`, `DB_USER` and + * `DB_PASSWORD` database credentials specified in wp-config.php. * * ## OPTIONS * @@ -170,14 +202,14 @@ function export( $args, $assoc_args ) { } /** - * Import database from a file or from STDIN. + * Import a MySQL database from a file or from STDIN. * * ## OPTIONS * * [<file>] * : The name of the SQL file to import. If '-', then reads from STDIN. If omitted, it will look for '{dbname}.sql'. */ - function import( $args, $assoc_args ) { + public function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); if ( '-' === $result_file ) { @@ -206,7 +238,7 @@ function import( $args, $assoc_args ) { } /** - * List the database tables. + * List the MySQL database tables. * * Defaults to all tables registered to $wpdb. * From 3d529044ca0ce61cea8b859644ccfd10a60ff169 Mon Sep 17 00:00:00 2001 From: "pete@petenelson.com" <petenelson@fortress.local> Date: Fri, 1 Apr 2016 14:51:17 -0500 Subject: [PATCH 4196/4858] adds the 'term recount' CLI command to update the term count for taxonomies --- php/commands/term.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index 84ac9d61d5..412c066f4e 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -417,6 +417,36 @@ public function url( $args ) { } } + /** + * Recount the term_taxonomy count for one or more taxonomies. + * + * <taxonomy>... + * : One or more taxonomies to update + * + * ## EXAMPLES + * + * wp term recount category post_tag + * + * wp taxonomy list --field=name | xargs wp term recount + */ + public function recount( $args ) { + foreach( $args as $taxonomy ) { + + if ( ! taxonomy_exists( $taxonomy ) ) { + WP_CLI::warning( sprintf( "%s %d doesn't exist.", $taxonomy, $term_id ) ); + } else { + + $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); + $term_taxonomy_ids = wp_list_pluck( $terms, 'term_taxonomy_id' ); + + wp_update_term_count( $term_taxonomy_ids, $taxonomy ); + + WP_CLI::success( sprintf( "Recounted %s.", $taxonomy ) ); + } + + } + } + private function maybe_make_child() { // 50% chance of making child term return ( mt_rand(1, 2) == 1 ); From 0e6e839836c46c7f13b01cfe4025d311ca784cf4 Mon Sep 17 00:00:00 2001 From: "pete@petenelson.com" <petenelson@fortress.local> Date: Fri, 1 Apr 2016 14:54:21 -0500 Subject: [PATCH 4197/4858] updated success and warning messages --- php/commands/term.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 412c066f4e..4eca50e855 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -433,7 +433,7 @@ public function recount( $args ) { foreach( $args as $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { - WP_CLI::warning( sprintf( "%s %d doesn't exist.", $taxonomy, $term_id ) ); + WP_CLI::warning( sprintf( "Taxonomy %s doesn't exist.", $taxonomy ) ); } else { $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); @@ -441,7 +441,7 @@ public function recount( $args ) { wp_update_term_count( $term_taxonomy_ids, $taxonomy ); - WP_CLI::success( sprintf( "Recounted %s.", $taxonomy ) ); + WP_CLI::success( sprintf( "Updated %s term count", $taxonomy ) ); } } From 89e8ca1262ac4cc275d763795599e13e58e21c34 Mon Sep 17 00:00:00 2001 From: "pete@petenelson.com" <petenelson@fortress.local> Date: Fri, 1 Apr 2016 15:27:32 -0500 Subject: [PATCH 4198/4858] changed taxonomy warning to not be a contraction --- php/commands/term.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index 4eca50e855..2d8c8548d5 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -433,7 +433,7 @@ public function recount( $args ) { foreach( $args as $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { - WP_CLI::warning( sprintf( "Taxonomy %s doesn't exist.", $taxonomy ) ); + WP_CLI::warning( sprintf( "Taxonomy %s does not exist.", $taxonomy ) ); } else { $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); From 6ec21273a7b578127a0834f934f198cbf0fb881e Mon Sep 17 00:00:00 2001 From: "pete@petenelson.com" <petenelson@fortress.local> Date: Fri, 1 Apr 2016 15:28:03 -0500 Subject: [PATCH 4199/4858] added feature test for term recount with an invalid taxonomy --- features/term-recount.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 features/term-recount.feature diff --git a/features/term-recount.feature b/features/term-recount.feature new file mode 100644 index 0000000000..de584effda --- /dev/null +++ b/features/term-recount.feature @@ -0,0 +1,13 @@ +Feature: Manage WordPress term recounts + + Background: + Given a WP install + + + Scenario: Term recount with an invalid taxonomy + When I try `wp term recount some-fake-taxonomy` + Then STDERR should be: + """ + Warning: Taxonomy some-fake-taxonomy does not exist. + """ + \ No newline at end of file From ff752afefe1d2738bad0af8a30e4720f2a798f4f Mon Sep 17 00:00:00 2001 From: "pete@petenelson.com" <petenelson@fortress.local> Date: Fri, 1 Apr 2016 15:30:27 -0500 Subject: [PATCH 4200/4858] added feature test for term recount with valid taxonomies --- features/term-recount.feature | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/features/term-recount.feature b/features/term-recount.feature index de584effda..bbb79458b0 100644 --- a/features/term-recount.feature +++ b/features/term-recount.feature @@ -10,4 +10,18 @@ Feature: Manage WordPress term recounts """ Warning: Taxonomy some-fake-taxonomy does not exist. """ - \ No newline at end of file + + Scenario: Term recount with a valid taxonomy + When I try `wp term recount category` + Then STDOUT should be: + """ + Success: Updated category term count + """ + + Scenario: Term recount with a multiple taxonomies + When I try `wp term recount category post_tag` + Then STDOUT should be: + """ + Success: Updated category term count + Success: Updated post_tag term count + """ From fa3947c70c9946717bc81d29ed26ceb6add39a30 Mon Sep 17 00:00:00 2001 From: Pete Nelson <pete@petenelson.com> Date: Mon, 4 Apr 2016 08:21:35 -0500 Subject: [PATCH 4201/4858] added missing OPTIONS in term recount docblock --- php/commands/term.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index 2d8c8548d5..82e95ef46f 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -420,6 +420,8 @@ public function url( $args ) { /** * Recount the term_taxonomy count for one or more taxonomies. * + * ## OPTIONS + * * <taxonomy>... * : One or more taxonomies to update * From 9c236bdaf9a29fd99e0cfab83d6d58a9587125c4 Mon Sep 17 00:00:00 2001 From: Pete Nelson <pete@petenelson.com> Date: Mon, 4 Apr 2016 08:48:18 -0500 Subject: [PATCH 4202/4858] added a more detailed description of the term recount command --- php/commands/term.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index 82e95ef46f..6437c0598d 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -418,7 +418,16 @@ public function url( $args ) { } /** - * Recount the term_taxonomy count for one or more taxonomies. + * Updates the amount of terms in one or more taxonomies + * + * ## DESCRIPTION + * + * In instances where manual updates are made to the terms assigned to + * posts in the database, the number of posts associated with a term + * can become out-of-sync with the actual number of posts. + * + * This command runs wp_update_term_count() on the taxonomy's terms + * to bring the count back to the correct value. * * ## OPTIONS * From 54d8e0ec46c44452814217bda4084fc41cd706f5 Mon Sep 17 00:00:00 2001 From: Pete Nelson <pete@petenelson.com> Date: Mon, 4 Apr 2016 08:50:37 -0500 Subject: [PATCH 4203/4858] added missing OPTIONS to comment recount docblock --- php/commands/comment.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/comment.php b/php/commands/comment.php index 3eb74fa305..de0eb534b6 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -445,6 +445,8 @@ public function count( $args, $assoc_args ) { /** * Recount the comment_count value for one or more posts. * + * ## OPTIONS + * * <id>... * : IDs for one or more posts to update. */ From e19af4a46151382e5e5ef9ec7f33bf18d7ea703c Mon Sep 17 00:00:00 2001 From: Pete Nelson <pete@petenelson.com> Date: Mon, 4 Apr 2016 13:27:25 -0500 Subject: [PATCH 4204/4858] update Feature description for term recount test --- features/term-recount.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/term-recount.feature b/features/term-recount.feature index bbb79458b0..b79b957ff4 100644 --- a/features/term-recount.feature +++ b/features/term-recount.feature @@ -1,4 +1,4 @@ -Feature: Manage WordPress term recounts +Feature: Recount terms on a taxonomy Background: Given a WP install From a533f8b0ec797df5ebb202cde42a9a7259e112ea Mon Sep 17 00:00:00 2001 From: Pete Nelson <pete@petenelson.com> Date: Mon, 4 Apr 2016 18:16:45 -0500 Subject: [PATCH 4205/4858] added term recount test that forces an invalid term count and fixes it via the WP-CLI command --- features/term-recount.feature | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/features/term-recount.feature b/features/term-recount.feature index b79b957ff4..03dad922b6 100644 --- a/features/term-recount.feature +++ b/features/term-recount.feature @@ -25,3 +25,30 @@ Feature: Recount terms on a taxonomy Success: Updated category term count Success: Updated post_tag term count """ + + Scenario: Fixes an invalid term count for a taxonomy + When I run `wp term create category "Term Recount Category" --porcelain` + Then STDOUT should be a number + Then save STDOUT as {TERM_ID} + + When I run `wp post create --post_title='Term Recount Test' --post_status=publish --post_category={TERM_ID} --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID} + + When I run `wp term get category {TERM_ID} --field=count` + Then STDOUT should be: + """ + 1 + """ + When I run `wp eval 'global $wpdb; $wpdb->update( $wpdb->term_taxonomy, array( "count" => 3 ), array( "term_id" => {TERM_ID} ) );'` + And I run `wp term get category {TERM_ID} --field=count` + Then STDOUT should be: + """ + 3 + """ + + When I run `wp term recount category` + And I run `wp term get category {TERM_ID} --field=count` + """ + 1 + """ From 7423615d9c533107b0e69d67453a7f40ac626a70 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Apr 2016 05:10:16 -0700 Subject: [PATCH 4206/4858] Clean up docs for `wp term recount` --- php/commands/term.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 6437c0598d..aeee574f0e 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -418,9 +418,7 @@ public function url( $args ) { } /** - * Updates the amount of terms in one or more taxonomies - * - * ## DESCRIPTION + * Recalculate number of posts assigned to each term. * * In instances where manual updates are made to the terms assigned to * posts in the database, the number of posts associated with a term @@ -432,7 +430,7 @@ public function url( $args ) { * ## OPTIONS * * <taxonomy>... - * : One or more taxonomies to update + * : One or more taxonomies to recalculate. * * ## EXAMPLES * From 9b0f8ed5fec2bfbd42ae1560b0625e996a89f9f9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Apr 2016 05:29:05 -0700 Subject: [PATCH 4207/4858] Introduce `CompositeCommand->remove_subcommand()` This permits a subcommand to be de-registered from its parent. Also modifies the bootstrap process to always register commands, instead of lazyloading them based on command name. Packages and required commands are always loaded, so we should follow similar behavior with core commands. --- features/command.feature | 21 +++++++++++++++++++++ php/WP_CLI/Dispatcher/CompositeCommand.php | 13 +++++++++++++ php/WP_CLI/Dispatcher/RootCommand.php | 2 -- php/WP_CLI/Runner.php | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/features/command.feature b/features/command.feature index 59015ad572..781ebf6fb6 100644 --- a/features/command.feature +++ b/features/command.feature @@ -490,3 +490,24 @@ Feature: WP-CLI Commands shop: cha cha cha burrito: """ + + Scenario: Removing a subcommand should remove it from the index + Given an empty directory + And a remove-comment.php file: + """ + <?php + $command = WP_CLI::get_root_command(); + $command->remove_subcommand( 'comment' ); + """ + + When I run `wp` + Then STDOUT should contain: + """ + Manage comments. + """ + + When I run `wp --require=remove-comment.php` + Then STDOUT should not contain: + """ + Manage comments. + """ diff --git a/php/WP_CLI/Dispatcher/CompositeCommand.php b/php/WP_CLI/Dispatcher/CompositeCommand.php index a4712a592b..53862245b0 100644 --- a/php/WP_CLI/Dispatcher/CompositeCommand.php +++ b/php/WP_CLI/Dispatcher/CompositeCommand.php @@ -58,6 +58,19 @@ public function add_subcommand( $name, $command ) { $this->subcommands[ $name ] = $command; } + /** + * Remove a named subcommand from this composite command's set of contained + * subcommands + * + * @param string $name Represents how subcommand should be invoked + */ + public function remove_subcommand( $name ) { + if ( isset( $this->subcommands[ $name ] ) ) { + unset( $this->subcommands[ $name ] ); + } + } + + /** * Composite commands always contain subcommands. * diff --git a/php/WP_CLI/Dispatcher/RootCommand.php b/php/WP_CLI/Dispatcher/RootCommand.php index fb730da07e..0b720aea0c 100644 --- a/php/WP_CLI/Dispatcher/RootCommand.php +++ b/php/WP_CLI/Dispatcher/RootCommand.php @@ -53,8 +53,6 @@ public function find_subcommand( &$args ) { * @return array */ public function get_subcommands() { - Utils\load_all_commands(); - return parent::get_subcommands(); } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 43bde527a2..ee11655a99 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -626,7 +626,7 @@ public function start() { // Load bundled commands early, so that they're forced to use the same // APIs as non-bundled commands. - Utils\load_command( $this->arguments[0] ); + Utils\load_all_commands(); $skip_packages = \WP_CLI::get_runner()->config['skip-packages']; if ( true === $skip_packages ) { From 4c4efa938835d71527ebbfe7e8d77edd8a877a05 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Apr 2016 06:07:29 -0700 Subject: [PATCH 4208/4858] Mark `WP_CLI::colorize()` as a public API --- php/class-wp-cli.php | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 17e66724b6..4e70d1edf1 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -134,6 +134,59 @@ public static function get_http_cache_manager() { return $http_cacher; } + /** + * Colorize a string for output. + * + * Yes, you too can change the color of command line text. For instance, + * here's how `WP_CLI::success()` colorizes "Success: " + * + * ``` + * WP_CLI::colorize( "%GSuccess:%n " ) + * ``` + * + * Uses `\cli\Colors::colorize()` to transform color tokens to display + * settings. Choose from the following tokens (and note 'reset'): + * + * * %y => ['color' => 'yellow'], + * * %g => ['color' => 'green'], + * * %b => ['color' => 'blue'], + * * %r => ['color' => 'red'], + * * %p => ['color' => 'magenta'], + * * %m => ['color' => 'magenta'], + * * %c => ['color' => 'cyan'], + * * %w => ['color' => 'grey'], + * * %k => ['color' => 'black'], + * * %n => ['color' => 'reset'], + * * %Y => ['color' => 'yellow', 'style' => 'bright'], + * * %G => ['color' => 'green', 'style' => 'bright'], + * * %B => ['color' => 'blue', 'style' => 'bright'], + * * %R => ['color' => 'red', 'style' => 'bright'], + * * %P => ['color' => 'magenta', 'style' => 'bright'], + * * %M => ['color' => 'magenta', 'style' => 'bright'], + * * %C => ['color' => 'cyan', 'style' => 'bright'], + * * %W => ['color' => 'grey', 'style' => 'bright'], + * * %K => ['color' => 'black', 'style' => 'bright'], + * * %N => ['color' => 'reset', 'style' => 'bright'], + * * %3 => ['background' => 'yellow'], + * * %2 => ['background' => 'green'], + * * %4 => ['background' => 'blue'], + * * %1 => ['background' => 'red'], + * * %5 => ['background' => 'magenta'], + * * %6 => ['background' => 'cyan'], + * * %7 => ['background' => 'grey'], + * * %0 => ['background' => 'black'], + * * %F => ['style' => 'blink'], + * * %U => ['style' => 'underline'], + * * %8 => ['style' => 'inverse'], + * * %9 => ['style' => 'bright'], + * * %_ => ['style' => 'bright') + * + * @access public + * @category Output + * + * @param string $string String to colorize for output, with color tokens. + * @return string Colorized string. + */ public static function colorize( $string ) { return \cli\Colors::colorize( $string, self::get_runner()->in_color() ); } From b766cb820d152d57b54d3f0bac774c951535734f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Apr 2016 13:45:19 -0700 Subject: [PATCH 4209/4858] Expected before actual --- tests/test-doc-parser.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index 41b43138d2..90cd205c2d 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -154,10 +154,10 @@ public function test_desc_doesnt_parse_far_params_yaml() { --- EOB; $doc = new DocParser( $longdesc ); - $this->assertEquals( $doc->get_param_args( 'format' ), array( + $this->assertEquals( array( 'default' => 'table', 'options' => array( 'table', 'json', 'csv', 'yaml' ), - ) ); + ), $doc->get_param_args( 'format' ) ); $this->assertNull( $doc->get_arg_args( 'hook' ) ); } @@ -180,10 +180,10 @@ public function test_desc_doesnt_parse_far_args_yaml() { --- EOB; $doc = new DocParser( $longdesc ); - $this->assertEquals( $doc->get_arg_args( 'format' ), array( + $this->assertEquals( array( 'default' => 'table', 'options' => array( 'table', 'json', 'csv', 'yaml' ), - ) ); + ), $doc->get_arg_args( 'format' ) ); $this->assertNull( $doc->get_arg_args( 'hook' ) ); } From 649b23fb596fe3746fb45bebfe8f6c664ca608ac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Apr 2016 15:08:52 -0700 Subject: [PATCH 4210/4858] Don't use regex to find the YAML doc --- php/WP_CLI/DocParser.php | 43 ++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index 9249003f94..b9ab93d198 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -120,10 +120,7 @@ public function get_arg_desc( $name ) { * @return mixed|null */ public function get_arg_args( $name ) { - if ( preg_match( "/\[?<{$name}>.+(\n: (.+?)(\n|$))?\n---\n(.+)\n---/sU", $this->docComment, $matches ) ) { - return Spyc::YAMLLoadString( $matches[4] ); - } - return null; + return $this->get_arg_or_param_args( "/\[?<{$name}>.*/" ); } /** @@ -148,11 +145,45 @@ public function get_param_desc( $key ) { * @return mixed|null */ public function get_param_args( $key ) { + return $this->get_arg_or_param_args( "/\[?--{$key}=.*/" ); + } - if ( preg_match( "/\[?--{$key}=.+(\n: (.+?)(\n|$))?\n---\n(.+)\n---/sU", $this->docComment, $matches ) ) { - return Spyc::YAMLLoadString( $matches[4] ); + /** + * Get the args for an arg or param + * + * @param string $regex Pattern to match against + * @return array|null Interpreted YAML document, or null. + */ + private function get_arg_or_param_args( $regex ) { + $bits = explode( PHP_EOL, $this->docComment ); + $within_arg = $within_doc = false; + $document = array(); + foreach( $bits as $bit ) { + if ( preg_match( $regex, $bit ) ) { + $within_arg = true; + } + + if ( $within_arg && $within_doc && '---' === $bit ) { + $within_doc = false; + } + + if ( $within_arg && ! $within_doc && '---' === $bit ) { + $within_doc = true; + } + + if ( $within_doc ) { + $document[] = $bit; + } + + if ( $within_arg && '' === $bit ) { + $within_arg = false; + break; + } } + if ( $document ) { + return Spyc::YAMLLoadString( implode( PHP_EOL, $document ) ); + } return null; } From 4648af607bdda3327220c98c055c4969b789fedd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Apr 2016 15:19:43 -0700 Subject: [PATCH 4211/4858] Ensure vendor libraries are available When Behat has been globally installed, our project autoload isn't always called. --- features/bootstrap/FeatureContext.php | 1 + 1 file changed, 1 insertion(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index b6897e4fb3..85748947bb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -30,6 +30,7 @@ } else { require_once __DIR__ . '/../../php/utils.php'; require_once __DIR__ . '/../../php/WP_CLI/Process.php'; + require_once __DIR__ . '/../../vendor/autoload.php'; } /** From e2a977266479ecaf407026ef9bf5ee8291a04c13 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 8 Apr 2016 10:47:48 +0100 Subject: [PATCH 4212/4858] Warn with verify-checksums when extra files exist in wp-admin or wp-includes --- php/commands/core.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 6f589ff1db..778bf8c6c1 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -861,6 +861,16 @@ public function verify_checksums( $args, $assoc_args ) { } } + $core_checksums_files = array_filter( array_keys( $checksums ), array( $this, 'remove_wp_content_files_filter' ) ); + $core_files = $this->get_wp_core_files(); + $additional_files = array_diff( $core_files, $core_checksums_files ); + + if ( ! empty( $additional_files ) ) { + foreach ( $additional_files as $additional_file ) { + WP_CLI::warning( "File should not exist: {$additional_file}" ); + } + } + if ( ! $has_errors ) { WP_CLI::success( "WordPress install verifies against checksums." ); } else { @@ -868,6 +878,26 @@ public function verify_checksums( $args, $assoc_args ) { } } + private function get_wp_core_files() { + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( ABSPATH, RecursiveDirectoryIterator::SKIP_DOTS ), + RecursiveIteratorIterator::CHILD_FIRST + ); + + $core_files = array(); + foreach ( $files as $file_info ) { + if ( $file_info->isFile() && 'wp-config.php' !== basename( $file_info->getPathname() ) && false === strpos( $file_info->getPathname(), 'wp-content/' ) ) { + $core_files[] = str_replace( ABSPATH, '', $file_info->getPathname() ); + } + } + + return $core_files; + } + + private function remove_wp_content_files_filter( $file ) { + return strpos( $file, 'wp-content/' ) === false; + } + /** * Update WordPress. * From cf13f4f91370b65e7f3a1582eba87c7566919124 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 8 Apr 2016 10:48:10 +0100 Subject: [PATCH 4213/4858] Update tests --- features/core-verify-checksums.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index 055639275e..f71a52ebb5 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -19,6 +19,7 @@ Feature: Validate checksums for WordPress install Then STDERR should be: """ Warning: File doesn't verify against checksum: readme.html + Warning: File should not exist: readme.html.bak Error: WordPress install doesn't verify against checksums. """ @@ -29,6 +30,7 @@ Feature: Validate checksums for WordPress install Then STDERR should be: """ Warning: File doesn't exist: readme.html + Warning: File should not exist: readme.html.bak Error: WordPress install doesn't verify against checksums. """ From 46b66508959603eb5c8703cf569c2b67280008a0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 8 Apr 2016 04:49:19 -0700 Subject: [PATCH 4214/4858] Update versions specified in `packages.json` --- templates/plugin-packages.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/plugin-packages.mustache b/templates/plugin-packages.mustache index 2554b9b2c5..fe7f057452 100644 --- a/templates/plugin-packages.mustache +++ b/templates/plugin-packages.mustache @@ -5,8 +5,8 @@ "main": "Gruntfile.js", "author": "{{plugin_author}}", "devDependencies": { - "grunt": "^0.4.5", - "grunt-wp-i18n": "^0.5.0", - "grunt-wp-readme-to-markdown": "~0.9.0" + "grunt": "~0.4.5", + "grunt-wp-i18n": "~0.5.0", + "grunt-wp-readme-to-markdown": "~1.0.0" } } From 7636f3c0c7b48a31c9cd6619743a0dee912f6554 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 8 Apr 2016 13:51:07 +0100 Subject: [PATCH 4215/4858] Only check in wp-admin and wp-includes --- php/commands/core.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index ebabda3b47..e60505e79f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -848,7 +848,7 @@ public function verify_checksums( $args, $assoc_args ) { } } - $core_checksums_files = array_filter( array_keys( $checksums ), array( $this, 'remove_wp_content_files_filter' ) ); + $core_checksums_files = array_filter( array_keys( $checksums ), array( $this, 'only_core_files_filter' ) ); $core_files = $this->get_wp_core_files(); $additional_files = array_diff( $core_files, $core_checksums_files ); @@ -873,7 +873,7 @@ private function get_wp_core_files() { $core_files = array(); foreach ( $files as $file_info ) { - if ( $file_info->isFile() && 'wp-config.php' !== basename( $file_info->getPathname() ) && false === strpos( $file_info->getPathname(), 'wp-content/' ) ) { + if ( $file_info->isFile() && ( false !== strpos( $file_info->getPathname(), 'wp-admin/' ) || false !== strpos( $file_info->getPathname(), 'wp-includes/' ) ) ) { $core_files[] = str_replace( ABSPATH, '', $file_info->getPathname() ); } } @@ -881,8 +881,8 @@ private function get_wp_core_files() { return $core_files; } - private function remove_wp_content_files_filter( $file ) { - return strpos( $file, 'wp-content/' ) === false; + private function only_core_files_filter( $file ) { + return ( false !== strpos( $file, 'wp-admin/' ) || false !== strpos( $file, 'wp-includes/' ) ); } /** From 4dea7e0070d89dfc93d77fed2740b98a40351c58 Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 8 Apr 2016 13:51:14 +0100 Subject: [PATCH 4216/4858] Update tests --- features/core-verify-checksums.feature | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index c2d98418c9..7c7d5858fd 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -19,7 +19,6 @@ Feature: Validate checksums for WordPress install Then STDERR should be: """ Warning: File doesn't verify against checksum: readme.html - Warning: File should not exist: readme.html.bak Error: WordPress install doesn't verify against checksums. """ @@ -30,7 +29,6 @@ Feature: Validate checksums for WordPress install Then STDERR should be: """ Warning: File doesn't exist: readme.html - Warning: File should not exist: readme.html.bak Error: WordPress install doesn't verify against checksums. """ @@ -65,3 +63,19 @@ Feature: Validate checksums for WordPress install """ Success: WordPress install verifies against checksums. """ + + Scenario: Verify core checksums with extra files + Given a WP install + + When I run `wp core update` + Then STDOUT should not be empty + + When I run `touch wp-includes/extra-file.txt` + Then the wp-includes/extra-file.txt file should exist + + When I run `wp core verify-checksums` + Then STDOUT should be: + """ + Warning: File should not exist: wp-includes/extra-file.txt + Success: WordPress install verifies against checksums. + """ From 7fa9e762bb02cd67f87de09dbee9683a449c3034 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 8 Apr 2016 06:31:44 -0700 Subject: [PATCH 4217/4858] Update Composer dependencies to their latest ``` Loading composer repositories with package information Updating dependencies (including require-dev) - Removing symfony/yaml (v2.8.3) - Installing symfony/yaml (v2.8.4) Downloading: 100% - Removing symfony/filesystem (v2.8.3) - Installing symfony/filesystem (v2.8.4) Downloading: 100% - Removing symfony/config (v2.8.3) - Installing symfony/config (v2.8.4) Downloading: 100% - Removing symfony/dependency-injection (v2.8.3) - Installing symfony/dependency-injection (v2.8.4) Downloading: 100% - Removing symfony/event-dispatcher (v2.8.3) - Installing symfony/event-dispatcher (v2.8.4) Downloading: 100% - Removing symfony/translation (v2.8.3) - Installing symfony/translation (v2.8.4) Downloading: 100% - Removing symfony/process (v2.8.3) - Installing symfony/process (v2.8.4) Downloading: 100% - Removing symfony/finder (v2.8.3) - Installing symfony/finder (v2.8.4) Downloading: 100% - Removing symfony/console (v2.8.3) - Installing symfony/console (v2.8.4) Downloading: 100% - Removing composer/semver (1.3.0) - Installing composer/semver (1.4.0) Downloading: 100% - Removing composer/spdx-licenses (1.1.2) - Installing composer/spdx-licenses (1.1.3) Downloading: 100% - Removing composer/composer (1.0.0-beta1) - Installing composer/composer (1.0.0) Downloading: 100% Writing lock file Generating autoload files ``` --- composer.lock | 126 +++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/composer.lock b/composer.lock index 3d9ba656de..2616ef216e 100644 --- a/composer.lock +++ b/composer.lock @@ -9,16 +9,16 @@ "packages": [ { "name": "composer/composer", - "version": "1.0.0-beta1", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "5cb2b522637a941d608c58bd522f3b2a7bda4a1c" + "reference": "32df3aa8cdbdaa16df9491b5e672e81c87f94c78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/5cb2b522637a941d608c58bd522f3b2a7bda4a1c", - "reference": "5cb2b522637a941d608c58bd522f3b2a7bda4a1c", + "url": "https://api.github.com/repos/composer/composer/zipball/32df3aa8cdbdaa16df9491b5e672e81c87f94c78", + "reference": "32df3aa8cdbdaa16df9491b5e672e81c87f94c78", "shasum": "" }, "require": { @@ -80,20 +80,20 @@ "dependency", "package" ], - "time": "2016-03-03 15:15:10" + "time": "2016-04-05 12:27:26" }, { "name": "composer/semver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747" + "reference": "84c47f3d8901440403217afc120683c7385aecb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/df4463baa9f44fe6cf0a6da4fde2934d4c0a2747", - "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747", + "url": "https://api.github.com/repos/composer/semver/zipball/84c47f3d8901440403217afc120683c7385aecb8", + "reference": "84c47f3d8901440403217afc120683c7385aecb8", "shasum": "" }, "require": { @@ -142,28 +142,28 @@ "validation", "versioning" ], - "time": "2016-02-25 22:23:39" + "time": "2016-03-30 13:16:03" }, { "name": "composer/spdx-licenses", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "9e1c3926bb0842812967213d7c92827bc5883671" + "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/9e1c3926bb0842812967213d7c92827bc5883671", - "reference": "9e1c3926bb0842812967213d7c92827bc5883671", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/547659c3cacd3ccfe1b4714c2ff88cafc6b6793b", + "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "~2.3" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, "type": "library", "extra": { @@ -203,7 +203,7 @@ "spdx", "validator" ], - "time": "2015-10-05 11:27:42" + "time": "2016-03-25 10:57:10" }, { "name": "justinrainbow/json-schema", @@ -639,16 +639,16 @@ }, { "name": "symfony/config", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19" + "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19", - "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19", + "url": "https://api.github.com/repos/symfony/config/zipball/5273f4724dc5288fe7a33cb08077ab9852621f2c", + "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c", "shasum": "" }, "require": { @@ -688,20 +688,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-02-22 16:12:45" + "time": "2016-03-04 07:54:35" }, { "name": "symfony/console", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "56cc5caf051189720b8de974e4746090aaa10d44" + "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/56cc5caf051189720b8de974e4746090aaa10d44", - "reference": "56cc5caf051189720b8de974e4746090aaa10d44", + "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154", + "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154", "shasum": "" }, "require": { @@ -748,20 +748,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-02-28 16:20:50" + "time": "2016-03-17 09:19:04" }, { "name": "symfony/dependency-injection", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "62251761a7615435b22ccf562384c588b431be44" + "reference": "f7b4a498e679fa440b16facb934680a1527ed48c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/62251761a7615435b22ccf562384c588b431be44", - "reference": "62251761a7615435b22ccf562384c588b431be44", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7b4a498e679fa440b16facb934680a1527ed48c", + "reference": "f7b4a498e679fa440b16facb934680a1527ed48c", "shasum": "" }, "require": { @@ -810,20 +810,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-02-28 16:34:46" + "time": "2016-03-21 07:27:21" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3" + "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3", - "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87", + "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87", "shasum": "" }, "require": { @@ -870,20 +870,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:19" + "time": "2016-03-07 14:04:32" }, { "name": "symfony/filesystem", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "65cb36b6539b1d446527d60457248f30d045464d" + "reference": "f08ffdf229252cd2745558cb2112df43903bcae4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/65cb36b6539b1d446527d60457248f30d045464d", - "reference": "65cb36b6539b1d446527d60457248f30d045464d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4", + "reference": "f08ffdf229252cd2745558cb2112df43903bcae4", "shasum": "" }, "require": { @@ -919,20 +919,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-02-22 15:02:30" + "time": "2016-03-27 10:20:16" }, { "name": "symfony/finder", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "877bb4b16ea573cc8c024e9590888fcf7eb7e0f7" + "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/877bb4b16ea573cc8c024e9590888fcf7eb7e0f7", - "reference": "877bb4b16ea573cc8c024e9590888fcf7eb7e0f7", + "url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1", + "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1", "shasum": "" }, "require": { @@ -968,7 +968,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-02-22 16:12:45" + "time": "2016-03-10 10:53:53" }, { "name": "symfony/polyfill-mbstring", @@ -1031,16 +1031,16 @@ }, { "name": "symfony/process", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe" + "reference": "fb467471952ef5cf8497c029980e556b47545333" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", - "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", + "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333", + "reference": "fb467471952ef5cf8497c029980e556b47545333", "shasum": "" }, "require": { @@ -1076,20 +1076,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-02-02 13:33:15" + "time": "2016-03-23 13:11:46" }, { "name": "symfony/translation", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b7b4ebadd2b5e614ff7d2d6fc63e0ed0578909c7" + "reference": "d60b8e076d22953aabebeebda53bf334438e7aca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b7b4ebadd2b5e614ff7d2d6fc63e0ed0578909c7", - "reference": "b7b4ebadd2b5e614ff7d2d6fc63e0ed0578909c7", + "url": "https://api.github.com/repos/symfony/translation/zipball/d60b8e076d22953aabebeebda53bf334438e7aca", + "reference": "d60b8e076d22953aabebeebda53bf334438e7aca", "shasum": "" }, "require": { @@ -1140,20 +1140,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-02-02 09:49:18" + "time": "2016-03-25 01:40:30" }, { "name": "symfony/yaml", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995" + "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", - "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", + "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb", + "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb", "shasum": "" }, "require": { @@ -1189,7 +1189,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-02-23 07:41:20" + "time": "2016-03-04 07:54:35" }, { "name": "wp-cli/php-cli-tools", From c94e822a90e59d5a06646183d33b8cbe953a9b3b Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 8 Apr 2016 15:44:37 +0100 Subject: [PATCH 4218/4858] Update test --- features/core-verify-checksums.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index 7c7d5858fd..1f817755af 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -70,7 +70,10 @@ Feature: Validate checksums for WordPress install When I run `wp core update` Then STDOUT should not be empty - When I run `touch wp-includes/extra-file.txt` + Given a wp-includes/extra-file.txt file: + """ + hello world + """ Then the wp-includes/extra-file.txt file should exist When I run `wp core verify-checksums` From 5bdd9f369127edc5ba36c81fe7092276e11d6d2d Mon Sep 17 00:00:00 2001 From: Gilbert Pellegrom <gilbert@pellegrom.me> Date: Fri, 8 Apr 2016 17:26:34 +0100 Subject: [PATCH 4219/4858] Fix test --- features/core-verify-checksums.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index 1f817755af..5f40e66b71 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -77,8 +77,11 @@ Feature: Validate checksums for WordPress install Then the wp-includes/extra-file.txt file should exist When I run `wp core verify-checksums` - Then STDOUT should be: + Then STDERR should be: """ Warning: File should not exist: wp-includes/extra-file.txt + """ + And STDOUT should be: + """ Success: WordPress install verifies against checksums. """ From 2bec119c088616f5b225b162ed92dbce448ed8b1 Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Sun, 10 Apr 2016 15:50:49 -0400 Subject: [PATCH 4220/4858] Update `plugin.mustache` and `plugin-packages.mustache` Currently if you scaffold a child theme and a plugin, the plugin headers are formatted differently than the child theme headers. The plugin also uses a different version number `0.1-alpha`), which is itself different than the version used in the plugin's `package.json` (`0.0.0`). This commit normalizes the header formatting and updates the version numbers. --- templates/plugin-packages.mustache | 2 +- templates/plugin.mustache | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/templates/plugin-packages.mustache b/templates/plugin-packages.mustache index fe7f057452..84a60ca66a 100644 --- a/templates/plugin-packages.mustache +++ b/templates/plugin-packages.mustache @@ -1,7 +1,7 @@ { "name": "{{plugin_slug}}", - "version": "0.0.0", + "version": "0.1.0", "main": "Gruntfile.js", "author": "{{plugin_author}}", "devDependencies": { diff --git a/templates/plugin.mustache b/templates/plugin.mustache index c96eb303db..fc502b67a8 100644 --- a/templates/plugin.mustache +++ b/templates/plugin.mustache @@ -1,12 +1,13 @@ <?php /** - * Plugin Name: {{plugin_name}} - * Version: 0.1-alpha - * Description: {{plugin_description}} - * Author: {{plugin_author}} - * Author URI: {{plugin_author_uri}} - * Plugin URI: {{plugin_uri}} - * Text Domain: {{textdomain}} - * Domain Path: /languages - * @package {{plugin_package}} + * Plugin Name: {{plugin_name}} + * Plugin URI: {{plugin_uri}} + * Description: {{plugin_description}} + * Author: {{plugin_author}} + * Author URI: {{plugin_author_uri}} + * Text Domain: {{textdomain}} + * Domain Path: /languages + * Version: 0.1.0 + * + * @package {{plugin_package}} */ From 6ccf35d3269abcfce7e390c323b511f9540075fe Mon Sep 17 00:00:00 2001 From: Wes Moberly <wesm87@gmail.com> Date: Sun, 10 Apr 2016 18:27:28 -0400 Subject: [PATCH 4221/4858] Update functional tests --- features/plugin.feature | 6 +++--- features/scaffold.feature | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/features/plugin.feature b/features/plugin.feature index 65da74df61..063155a6c4 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -42,7 +42,7 @@ Feature: Manage WordPress plugins Plugin Zombieland details: Name: Zombieland Status: Inactive - Version: 0.1-alpha + Version: 0.1.0 Author: YOUR NAME HERE Description: PLUGIN DESCRIPTION HERE """ @@ -61,8 +61,8 @@ Feature: Manage WordPress plugins When I run `wp plugin list` Then STDOUT should be a table containing rows: - | name | status | update | version | - | Zombieland | active | none | 0.1-alpha | + | name | status | update | version | + | Zombieland | active | none | 0.1.0 | When I try `wp plugin uninstall Zombieland` Then STDERR should contain: diff --git a/features/scaffold.feature b/features/scaffold.feature index e7fd1fd23f..54c6100394 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -125,11 +125,15 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/hello-world.php file should contain: """ - * Plugin Name: Hello World + * Plugin Name: Hello World """ And the {PLUGIN_DIR}/hello-world/hello-world.php file should contain: """ - * @package Hello_World + * Version: 0.1.0 + """ + And the {PLUGIN_DIR}/hello-world/hello-world.php file should contain: + """ + * @package Hello_World """ When I run `cat {PLUGIN_DIR}/hello-world/package.json` @@ -137,6 +141,10 @@ Feature: WordPress code scaffolding """ {"author":"Hello World Author"} """ + And STDOUT should be JSON containing: + """ + {"version":"0.1.0"} + """ Scenario: Scaffold a plugin by prompting Given a WP install From ddcb81606ba86ddce421e5e3e8e27a7fdcd4acbd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 11 Apr 2016 04:54:46 -0700 Subject: [PATCH 4222/4858] Failing test case for #2608 --- features/media-regenerate.feature | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/features/media-regenerate.feature b/features/media-regenerate.feature index fb4f99be60..0981e41c87 100644 --- a/features/media-regenerate.feature +++ b/features/media-regenerate.feature @@ -144,3 +144,51 @@ Feature: Regenerate WordPress attachments """ Success: Finished regenerating all images. """ + + Scenario: Regenerate images which are missing globally-defined image sizes + Given download: + | path | url | + | {CACHE_DIR}/large-image.jpg | http://wp-cli.org/behat-data/large-image.jpg | + And I run `wp option update uploads_use_yearmonth_folders 0` + + When I run `wp media import {CACHE_DIR}/large-image.jpg --title="My imported attachment" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + And the wp-content/uploads/large-image-100x100.jpg file should not exist + + Given a wp-content/mu-plugins/media-settings.php file: + """ + <?php + add_action( 'after_setup_theme', function(){ + add_image_size( 'test1', 100, 100, true ); + }); + """ + + When I run `wp media regenerate --only-missing --yes` + Then STDOUT should contain: + """ + Found 1 image to regenerate. + """ + And STDOUT should contain: + """ + Regenerated thumbnails for "My imported attachment" + """ + And STDOUT should contain: + """ + Success: Finished regenerating the image. + """ + And the wp-content/uploads/large-image-100x100.jpg file should exist + + When I run `wp media regenerate --only-missing --yes` + Then STDOUT should contain: + """ + Found 1 image to regenerate + """ + And STDOUT should contain: + """ + No thumbnail regeneration needed for "My imported attachment" + """ + And STDOUT should contain: + """ + Success: Finished regenerating the image. + """ + And the wp-content/uploads/large-image-100x100.jpg file should exist From d51edfd876bc33f868e05cbcd45ee292327b171d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 11 Apr 2016 04:56:55 -0700 Subject: [PATCH 4223/4858] Consider image sizes missing when `sizes` doesn't have registered sizes Also considers image needing regeneration if `sizes` is empty (which means its missing all sizes). --- php/commands/media.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index fd77715e4c..df37e75215 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -315,7 +315,11 @@ private function needs_regeneration( $att_id ) { $original_path = $dir_path . basename( $metadata['file'] ); if ( empty( $metadata['sizes'] ) ) { - return false; + return true; + } + + if ( array_diff( get_intermediate_image_sizes(), array_keys( $metadata['sizes'] ) ) ) { + return true; } foreach( $metadata['sizes'] as $size_info ) { From a129489450122aab942955ce95ec64271e2dc547 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 11 Apr 2016 06:14:30 -0700 Subject: [PATCH 4224/4858] Run `before_invoke` and `after_invoke` callbacks on subcommands This appears to be an oversight from 6ae19150fe3263b5b19e1237c58b92f73d9eab15 that no one has noticed since. Keep calling the parent too, for backwards compat purposes. --- features/command.feature | 25 +++++++++++++++++++++++++ php/WP_CLI/Dispatcher/Subcommand.php | 10 ++++++++-- php/class-wp-cli.php | 7 +++++-- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/features/command.feature b/features/command.feature index 781ebf6fb6..dafbf31613 100644 --- a/features/command.feature +++ b/features/command.feature @@ -511,3 +511,28 @@ Feature: WP-CLI Commands """ Manage comments. """ + + Scenario: before_invoke should call subcommands + Given an empty directory + And a call-invoke.php file: + """ + <?php + /** + * @when before_wp_load + */ + WP_CLI::add_command( 'before invoke', function() { + WP_CLI::success( 'Invoked' ); + }, array( 'before_invoke' => function() { + WP_CLI::success( 'before invoke' ); + }, 'after_invoke' => function() { + WP_CLI::success( 'after invoke' ); + })); + """ + + When I run `wp --require=call-invoke.php before invoke` + Then STDOUT should contain: + """ + Success: before invoke + Success: Invoked + Success: after invoke + """ diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 6b9eef078c..97906b4df9 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -2,6 +2,8 @@ namespace WP_CLI\Dispatcher; +use WP_CLI; + /** * A leaf node in the command tree. * @@ -346,11 +348,15 @@ public function invoke( $args, $assoc_args, $extra_args ) { } $path = get_path( $this->get_parent() ); - \WP_CLI::do_hook( 'before_invoke:' . implode( ' ', array_slice( $path, 1 ) ) ); + $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:' . implode( ' ', array_slice( $path, 1 ) ) ); + WP_CLI::do_hook( "after_invoke:{$parent}" ); + WP_CLI::do_hook( "after_invoke:{$cmd}" ); } } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 4e70d1edf1..0de667fc0a 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -294,6 +294,7 @@ public static function do_hook( $when ) { * @param array $args { * Optional An associative array with additional registration parameters. * 'before_invoke' => callback to execute before invoking the command, + * 'after_invoke' => callback to execute after invoking the command, * 'shortdesc' => short description (80 char or less) for the command, * 'synopsis' => the synopsis for the command (string or array), * 'when' => execute callback on a named WP-CLI hook (e.g. before_wp_load), @@ -317,8 +318,10 @@ public static function add_command( $name, $callable, $args = array() ) { WP_CLI::error( sprintf( "Callable %s does not exist, and cannot be registered as `wp %s`.", json_encode( $callable ), $name ) ); } - if ( isset( $args['before_invoke'] ) ) { - self::add_hook( "before_invoke:$name", $args['before_invoke'] ); + foreach( array( 'before_invoke', 'after_invoke' ) as $when ) { + if ( isset( $args[ $when ] ) ) { + self::add_hook( "{$when}:{$name}", $args[ $when ] ); + } } $path = preg_split( '/\s+/', $name ); From 0e96864c180a0c3296be257dc126055b60ae565f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 11 Apr 2016 07:16:34 -0700 Subject: [PATCH 4225/4858] Use `--debug=<group>` to limit debug output to a particular group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` salty-wordpress ➜ wordpress-develop.dev wp option get home --debug Debug (bootstrap): Using default global config: /home/vagrant/.wp-cli/config.yml (0.051s) Debug (bootstrap): Using project config: /srv/www/wordpress-develop.dev/wp-cli.yml (0.054s) Debug (bootstrap): Loading packages from: /home/vagrant/.wp-cli/packages/vendor/autoload.php (0.287s) Debug (bootstrap): Required file from config: /srv/www/wp-hook-command/command.php (0.428s) Debug (bootstrap): ABSPATH defined: /srv/www/wordpress-develop.dev/src/ (0.428s) Debug (bootstrap): Begin WordPress load (0.433s) Debug (bootstrap): wp-config.php path: /srv/www/wordpress-develop.dev/wp-config.php (0.436s) Debug (bootstrap): Loaded WordPress (1.307s) Debug: No schema title found for /, skipping REST command registration. (1.487s) Debug: No schema title found for /wp/v2, skipping REST command registration. (1.487s) Debug: No schema title found for /wp/v2/users/me, skipping REST command registration. (1.507s) Debug: No schema title found for /oembed/1.0, skipping REST command registration. (1.51s) Debug: No schema title found for /oembed/1.0/embed, skipping REST command registration. (1.51s) Debug: No schema title found for /wpx/v1, skipping REST command registration. (1.51s) Debug: No schema title found for /wpx/v1/page-templates, skipping REST command registration. (1.51s) Debug (bootstrap): Running command: option get (1.511s) http://wordpress-develop.dev salty-wordpress ➜ wordpress-develop.dev wp option get home --debug=bootstrap Debug: Using default global config: /home/vagrant/.wp-cli/config.yml (0.05s) Debug: Using project config: /srv/www/wordpress-develop.dev/wp-cli.yml (0.053s) Debug: Loading packages from: /home/vagrant/.wp-cli/packages/vendor/autoload.php (0.209s) Debug: Required file from config: /srv/www/wp-hook-command/command.php (0.298s) Debug: ABSPATH defined: /srv/www/wordpress-develop.dev/src/ (0.299s) Debug: Begin WordPress load (0.303s) Debug: wp-config.php path: /srv/www/wordpress-develop.dev/wp-config.php (0.306s) Debug: Loaded WordPress (1.105s) Debug: Running command: option get (1.304s) http://wordpress-develop.dev ``` --- features/config.feature | 52 +++++++++++++++++++++++++++++++++++++ php/WP_CLI/Loggers/Base.php | 18 ++++++++++--- php/WP_CLI/Runner.php | 22 ++++++++-------- php/class-wp-cli.php | 7 ++--- php/config-spec.php | 4 +-- 5 files changed, 83 insertions(+), 20 deletions(-) diff --git a/features/config.feature b/features/config.feature index 091c711166..7912d1d539 100644 --- a/features/config.feature +++ b/features/config.feature @@ -228,6 +228,58 @@ Feature: Have a config file Running command: option get """ + When I run `wp option get home --debug=bootstrap` + Then STDERR should contain: + """ + No readable global config found + """ + Then STDERR should contain: + """ + No project config found + """ + And STDERR should contain: + """ + Begin WordPress load + """ + And STDERR should contain: + """ + wp-config.php path: + """ + And STDERR should contain: + """ + Loaded WordPress + """ + And STDERR should contain: + """ + Running command: option get + """ + + When I run `wp option get home --debug=foo` + Then STDERR should not contain: + """ + No readable global config found + """ + Then STDERR should not contain: + """ + No project config found + """ + And STDERR should not contain: + """ + Begin WordPress load + """ + And STDERR should not contain: + """ + wp-config.php path: + """ + And STDERR should not contain: + """ + Loaded WordPress + """ + And STDERR should not contain: + """ + Running command: option get + """ + Scenario: Missing required files should not fatal WP-CLI Given an empty directory And a wp-cli.yml file: diff --git a/php/WP_CLI/Loggers/Base.php b/php/WP_CLI/Loggers/Base.php index 2f36446ced..11b26e304a 100644 --- a/php/WP_CLI/Loggers/Base.php +++ b/php/WP_CLI/Loggers/Base.php @@ -29,12 +29,22 @@ protected function get_runner() { * Write a message to STDERR, prefixed with "Debug: ". * * @param string $message Message to write. + * @param string $group Organize debug message to a specific group. */ - public function debug( $message ) { - if ( $this->get_runner()->config['debug'] ) { - $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); - $this->_line( "$message ({$time}s)", 'Debug', '%B', STDERR ); + public function debug( $message, $group = false ) { + $debug = $this->get_runner()->config['debug']; + if ( ! $debug ) { + return; } + if ( true !== $debug && $group !== $debug ) { + return; + } + $time = round( microtime( true ) - WP_CLI_START_MICROTIME, 3 ); + $prefix = 'Debug'; + if ( $group && true === $debug ) { + $prefix = 'Debug (' . $group . ')'; + } + $this->_line( "$message ({$time}s)", $prefix, '%B', STDERR ); } /** diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ee11655a99..b8ec97b773 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -202,7 +202,7 @@ private function find_wp_root() { */ private static function set_wp_root( $path ) { define( 'ABSPATH', rtrim( $path, '/' ) . '/' ); - WP_CLI::debug( 'ABSPATH defined: ' . ABSPATH ); + WP_CLI::debug( 'ABSPATH defined: ' . ABSPATH, 'bootstrap' ); $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); } @@ -321,7 +321,7 @@ public function run_command( $args, $assoc_args = array() ) { $extra_args = array(); } - WP_CLI::debug( 'Running command: ' . $name ); + WP_CLI::debug( 'Running command: ' . $name, 'bootstrap' ); try { $command->invoke( $final_args, $assoc_args, $extra_args ); } catch ( WP_CLI\Iterators\Exception $e ) { @@ -604,8 +604,8 @@ public function start() { $this->init_colorization(); $this->init_logger(); - WP_CLI::debug( $this->_global_config_path_debug ); - WP_CLI::debug( $this->_project_config_path_debug ); + WP_CLI::debug( $this->_global_config_path_debug, 'bootstrap' ); + WP_CLI::debug( $this->_project_config_path_debug, 'bootstrap' ); $this->check_root(); @@ -630,14 +630,14 @@ public function start() { $skip_packages = \WP_CLI::get_runner()->config['skip-packages']; if ( true === $skip_packages ) { - WP_CLI::debug( 'Skipped loading packages.' ); + WP_CLI::debug( 'Skipped loading packages.', 'bootstrap' ); } else { $package_autoload = $this->get_packages_dir_path() . 'vendor/autoload.php'; if ( file_exists( $package_autoload ) ) { - WP_CLI::debug( 'Loading packages from: ' . $package_autoload ); + WP_CLI::debug( 'Loading packages from: ' . $package_autoload, 'bootstrap' ); require_once $package_autoload; } else { - WP_CLI::debug( 'No package autoload found to load.' ); + WP_CLI::debug( 'No package autoload found to load.', 'bootstrap' ); } } @@ -664,7 +664,7 @@ public function start() { WP_CLI::error( sprintf( "Required file '%s' doesn't exist%s.", basename( $path ), $context ) ); } Utils\load_file( $path ); - WP_CLI::debug( 'Required file from config: ' . $path ); + WP_CLI::debug( 'Required file from config: ' . $path, 'bootstrap' ); } } @@ -771,7 +771,7 @@ public function load_wordpress() { $wp_cli_is_loaded = true; - WP_CLI::debug( 'Begin WordPress load' ); + WP_CLI::debug( 'Begin WordPress load', 'bootstrap' ); WP_CLI::do_hook( 'before_wp_load' ); $this->check_wp_version(); @@ -783,7 +783,7 @@ public function load_wordpress() { "Either create one manually or use `wp core config`." ); } - WP_CLI::debug( 'wp-config.php path: ' . $wp_config_path ); + WP_CLI::debug( 'wp-config.php path: ' . $wp_config_path, 'bootstrap' ); WP_CLI::do_hook( 'before_wp_config_load' ); // Load wp-config.php code, in the global scope @@ -818,7 +818,7 @@ public function load_wordpress() { self::set_user( $this->config ); } - WP_CLI::debug( 'Loaded WordPress' ); + WP_CLI::debug( 'Loaded WordPress', 'bootstrap' ); WP_CLI::do_hook( 'after_wp_load' ); } diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 4e70d1edf1..72f2433f55 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -93,7 +93,7 @@ public static function get_cache() { * Set the context in which WP-CLI should be run */ public static function set_url( $url ) { - WP_CLI::debug( 'Set URL: ' . $url ); + WP_CLI::debug( 'Set URL: ' . $url, 'bootstrap' ); $url_parts = Utils\parse_url( $url ); self::set_url_params( $url_parts ); } @@ -482,10 +482,11 @@ public static function success( $message ) { * @category Output * * @param string $message Message to write to STDERR. + * @param string $group Organize debug message to a specific group. * @return null */ - public static function debug( $message ) { - self::$logger->debug( self::error_to_string( $message ) ); + public static function debug( $message, $group = false ) { + self::$logger->debug( self::error_to_string( $message ), $group ); } /** diff --git a/php/config-spec.php b/php/config-spec.php index 6e55a544c5..84221c0f04 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -71,8 +71,8 @@ ), 'debug' => array( - 'runtime' => '', - 'file' => '<bool>', + 'runtime' => '[=<group>]', + 'file' => '<group>', 'default' => false, 'desc' => 'Show all PHP errors; add verbosity to WP-CLI bootstrap.', ), From c658f693e8f9ae110b18045ae3e0a1dbcada4054 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 11 Apr 2016 09:01:08 -0700 Subject: [PATCH 4226/4858] Fix test to expect new string --- features/package.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/package.feature b/features/package.feature index 9d0591f7c2..daafbc4e72 100644 --- a/features/package.feature +++ b/features/package.feature @@ -18,7 +18,7 @@ Feature: Manage WP-CLI packages When I try `wp --skip-packages --debug help reset-post-date` Then STDERR should contain: """ - Debug: Skipped loading packages. + Debug (bootstrap): Skipped loading packages. """ And STDERR should contain: """ From 6e9cd2916359faa3a53dce495012c4410810074c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Apr 2016 06:05:51 -0700 Subject: [PATCH 4227/4858] Mention that custom database tables won't be emptied Doing so requires a bit of custom code. --- php/commands/site.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index b86b144b3c..5778c16d5a 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -122,6 +122,19 @@ private function _insert_default_terms() { /** * Empty a site of its content (posts, comments, and terms). * + * This command doesn't empty custom database tables by default. To do so, + * you'll need to hook into command execution: + * + * ``` + * WP_CLI::add_hook( 'after_invoke:site empty', function(){ + * global $wpdb; + * foreach( array( 'p2p', 'p2pmeta' ) as $table ) { + * $table = $wpdb->$table; + * $wpdb->query( "TRUNCATE $table" ); + * } + * }); + * ``` + * * ## OPTIONS * * [--uploads] From 6c76fde70220181f5c54c45d1067618320c092f4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Apr 2016 13:32:55 -0700 Subject: [PATCH 4228/4858] Lock to a specific version, so it doesn't break on new release --- features/core-download.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core-download.feature b/features/core-download.feature index c5f7f85f04..0b5cd4bd33 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -28,7 +28,7 @@ Feature: Download WordPress Scenario: Localized install Given an empty directory And an empty cache - When I run `wp core download --locale=de_DE` + When I run `wp core download --version=4.4.2 --locale=de_DE` And save STDOUT 'Downloading WordPress ([\d\.]+)' as {VERSION} Then the wp-settings.php file should exist And the {SUITE_CACHE_DIR}/core/wordpress-{VERSION}-de_DE.tar.gz file should exist From 7b5c24e7696a3d1b630bbcd33744ca98e9f8c8ae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Apr 2016 13:35:32 -0700 Subject: [PATCH 4229/4858] Update tests for WordPress 4.5 --- features/core-check-update.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 600beba472..c99d9beb25 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -10,7 +10,7 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.4.2 | major | https://downloads.wordpress.org/release/wordpress-4.4.2.zip | + | 4.5 | major | https://downloads.wordpress.org/release/wordpress-4.5.zip | | 3.8.13 | minor | https://downloads.wordpress.org/release/wordpress-3.8.13-partial-0.zip | When I run `wp core check-update --format=count` @@ -22,7 +22,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.4.2 | major | https://downloads.wordpress.org/release/wordpress-4.4.2.zip | + | 4.5 | major | https://downloads.wordpress.org/release/wordpress-4.5.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: From fdbee85ed8a652bf0ca5fcac6bb14de2f69c5e71 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Apr 2016 04:09:49 -0700 Subject: [PATCH 4230/4858] Use backticks when mentioning hooks This prevents the comment from being rendered as HTML on the website. --- php/class-wp-cli.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 2994124cd4..ad871ec168 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -199,12 +199,12 @@ public static function colorize( $string ) { * * WP-CLI hooks include: * - * * 'before_invoke:<command>' - Just before a command is invoked. - * * 'after_invoke:<command>' - Just after a command is involved. - * * 'before_wp_load' - Just before the WP load process begins. - * * 'before_wp_config_load' - After wp-config.php has been located. - * * 'after_wp_config_load' - After wp-config.php has been loaded into scope. - * * 'after_wp_load' - Just after the WP load process has completed. + * * `before_invoke:<command>` - Just before a command is invoked. + * * `after_invoke:<command>` - Just after a command is involved. + * * `before_wp_load` - Just before the WP load process begins. + * * `before_wp_config_load` - After wp-config.php has been located. + * * `after_wp_config_load` - After wp-config.php has been loaded into scope. + * * `after_wp_load` - Just after the WP load process has completed. * * WP-CLI commands can create their own hooks with `WP_CLI::do_hook()`. * From 639e52cfe417aa7f9cb728ee0f8566d8b8a891ae Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Apr 2016 07:40:19 -0700 Subject: [PATCH 4231/4858] Make `launch_editor_for_input()` usable without WordPress available Internalize the core logic of generating a random temp file. --- php/utils.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/php/utils.php b/php/utils.php index 67c7093647..62047f0eb6 100644 --- a/php/utils.php +++ b/php/utils.php @@ -338,12 +338,28 @@ function pick_fields( $item, $fields ) { * @return str|bool Edited text, if file is saved from editor * False, if no change to file */ -function launch_editor_for_input( $input, $title = 'WP-CLI' ) { - - $tmpfile = wp_tempnam( $title ); +function launch_editor_for_input( $input, $filename = 'WP-CLI' ) { + + $tmpdir = get_temp_dir(); + + do { + $tmpfile = basename( $filename ); + $tmpfile = preg_replace( '|\.[^.]*$|', '', $tmpfile ); + $tmpfile .= '-' . substr( md5( rand() ), 0, 6 ); + $tmpfile = $tmpdir . $tmpfile . '.tmp'; + $fp = @fopen( $tmpfile, 'x' ); + if ( ! $fp && is_writable( $tmpdir ) && file_exists( $tmpfile ) ) { + $tmpfile = ''; + continue; + } + if ( $fp ) { + fclose( $fp ); + } + } while( ! $tmpfile ); - if ( !$tmpfile ) + if ( ! $tmpfile ) { \WP_CLI::error( 'Error creating temporary file.' ); + } $output = ''; file_put_contents( $tmpfile, $input ); From 4c8aff4d23c6fca93f784440bfe98b3dbddb7246 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Apr 2016 07:45:05 -0700 Subject: [PATCH 4232/4858] Mark `launch_editor_for_input()` a public internal API --- php/utils.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/php/utils.php b/php/utils.php index 62047f0eb6..23d28b99d6 100644 --- a/php/utils.php +++ b/php/utils.php @@ -332,11 +332,13 @@ function pick_fields( $item, $fields ) { } /** - * Launch system's $EDITOR to edit text + * Launch system's $EDITOR for the user to edit some text. * - * @param str $content Text to edit (eg post content) - * @return str|bool Edited text, if file is saved from editor - * False, if no change to file + * @access public + * @category Input + * + * @param string $content Some form of text to edit (e.g. post content) + * @return string|bool Edited text, if file is saved from editor; false, if no change to file. */ function launch_editor_for_input( $input, $filename = 'WP-CLI' ) { From 03e8749eecfa8d403e103e5c280792fb97a564e0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Apr 2016 16:43:16 -0700 Subject: [PATCH 4233/4858] Permit `wp cron (event|schedule) list` to output a single field --- php/commands/cron.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index 4b52d42a39..00d67f7df9 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -22,6 +22,9 @@ class Cron_Event_Command extends WP_CLI_Command { * [--fields=<fields>] * : Limit the output to specific object fields. * + * [--field=<field>] + * : Prints the value of a single field for each event. + * * [--format=<format>] * : Accepted values: table, json, csv, ids, yaml. Default: table. * @@ -406,6 +409,9 @@ class Cron_Schedule_Command extends WP_CLI_Command { * [--fields=<fields>] * : Limit the output to specific object fields. * + * [--field=<field>] + * : Prints the value of a single field for each schedule. + * * [--format=<format>] * : Accepted values: table, json, csv, ids, yaml. Default: table. * From 5e94445a69a899d9eec2118ba2c7b242ba7144c0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Apr 2016 17:10:11 -0700 Subject: [PATCH 4234/4858] Use `--due-now` to run all cron events due or overdue --- features/cron.feature | 49 ++++++++++++++++++++++++++++++++++++++++++- php/commands/cron.php | 23 ++++++++++++++------ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index c545908518..55092dbeca 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -187,7 +187,7 @@ Feature: Manage WP-Cron events and schedules When I try `wp cron event run` Then STDERR should be: """ - Error: Please specify one or more cron events, or use --all. + Error: Please specify one or more cron events, or use --due-now/--all. """ When I run `wp cron event run wp_version_check wp_update_plugins` @@ -221,3 +221,50 @@ Feature: Manage WP-Cron events and schedules """ Success: Executed a total of """ + + Scenario: Run currently scheduled events + When I run `wp cron event run --all` + Then STDOUT should contain: + """ + Executed the cron event 'wp_version_check' + """ + And STDOUT should contain: + """ + Executed the cron event 'wp_update_plugins' + """ + And STDOUT should contain: + """ + Executed the cron event 'wp_update_themes' + """ + And STDOUT should contain: + """ + Success: Executed a total of + """ + + When I run `wp cron event run --due-now` + Then STDOUT should contain: + """ + Executed a total of 0 cron event(s) + """ + + When I run `wp cron event schedule wp_cli_test_event_1 now hourly` + Then STDOUT should contain: + """ + Success: Scheduled event with hook 'wp_cli_test_event_1' + """ + + When I run `wp cron event run --due-now` + Then STDOUT should contain: + """ + Executed the cron event 'wp_cli_test_event_1' + """ + And STDOUT should contain: + """ + Executed a total of 1 cron event(s) + """ + + When I run `wp cron event run --due-now` + Then STDOUT should contain: + """ + Executed a total of 0 cron event(s) + """ diff --git a/php/commands/cron.php b/php/commands/cron.php index 4b52d42a39..c1c1e8e614 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -141,18 +141,21 @@ public function schedule( $args, $assoc_args ) { * [<hook>...] * : One or more hooks to run. * + * [--due-now] + * : Run all hooks due right now. + * * [--all] * : Run all hooks. * * ## EXAMPLES * * # Run all cron events due right now - * wp cron event run $( wp cron event list --fields=hook,next_run_relative --format=csv | awk -F, '$2=="now" {print $1}' ) + * wp cron event run --due-now */ public function run( $args, $assoc_args ) { - if ( empty( $args ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { - WP_CLI::error( 'Please specify one or more cron events, or use --all.' ); + if ( empty( $args ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + WP_CLI::error( 'Please specify one or more cron events, or use --due-now/--all.' ); } $events = self::get_cron_events(); @@ -161,9 +164,17 @@ public function run( $args, $assoc_args ) { WP_CLI::error( $events ); } - - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) ) { + $due_events = array(); + foreach( $events as $event ) { + if ( time() >= $event->time ) { + $due_events[] = $event; + } + } + $events = $due_events; + } else if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { $hooks = wp_list_pluck( $events, 'hook' ); + $due_events = array(); foreach( $args as $hook ) { if ( ! in_array( $hook, $hooks ) ) { WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); @@ -173,7 +184,7 @@ public function run( $args, $assoc_args ) { $executed = 0; foreach ( $events as $event ) { - if ( in_array( $event->hook, $args ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + if ( in_array( $event->hook, $args ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) ) { $start = microtime( true ); $result = self::run_event( $event ); $total = round( microtime( true ) - $start, 3 ); From f57a13f283b0ef44a878662fcdc24c768f312825 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 13 Apr 2016 17:14:49 -0700 Subject: [PATCH 4235/4858] Remove the convoluted logic so it's more clear what's going on --- php/commands/cron.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index c1c1e8e614..b414b5586e 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -180,17 +180,21 @@ public function run( $args, $assoc_args ) { WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); } } + foreach( $events as $event ) { + if ( in_array( $event->hook, $args ) ) { + $due_events[] = $event; + } + } + $events = $due_events; } $executed = 0; foreach ( $events as $event ) { - if ( in_array( $event->hook, $args ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) || \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) ) { - $start = microtime( true ); - $result = self::run_event( $event ); - $total = round( microtime( true ) - $start, 3 ); - $executed++; - WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); - } + $start = microtime( true ); + $result = self::run_event( $event ); + $total = round( microtime( true ) - $start, 3 ); + $executed++; + WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); } $message = 'Executed a total of %d cron event(s).'; From 1e439adc530d624d2b0e32efcdf322c076b4f636 Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Wed, 13 Apr 2016 17:58:24 -0700 Subject: [PATCH 4236/4858] don't include newline in prompt --- php/commands/shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index d0c39bd721..a4b8ebb3fd 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -35,7 +35,7 @@ public function __invoke( $_, $assoc_args ) { if ( '\\Psy\\Shell' == $class ) { \Psy\Shell::debug(); } else { - $repl = new $class( "\nwp> " ); + $repl = new $class( "wp> " ); $repl->start(); } } From 6d84612c2e9ea3b2e3a2997d3c0b268a8a1c07bb Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Wed, 13 Apr 2016 18:04:37 -0700 Subject: [PATCH 4237/4858] always include a newline after non-null eval output --- php/WP_CLI/REPL.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index 0a14b3e422..c9f2b27b9e 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -21,7 +21,13 @@ public function start() { $line = rtrim( $line, ';' ) . ';'; if ( self::starts_with( self::non_expressions(), $line ) ) { + ob_start(); eval( $line ); + $out = ob_get_clean(); + if ( 0 < strlen ( $out ) ) { + $out = rtrim( $out, "\n" ) . "\n"; + } + fwrite( STDOUT, $out ); } else { if ( !self::starts_with( 'return', $line ) ) $line = 'return ' . $line; @@ -29,7 +35,8 @@ public function start() { // Write directly to STDOUT, to sidestep any output buffers created by plugins ob_start(); var_dump( eval( $line ) ); - fwrite( STDOUT, ob_get_clean() ); + $out = rtrim( ob_get_clean(), "\n" ) . "\n"; + fwrite( STDOUT, $out ); } } } From 0f5dcf88ec5faa682a4e48c94f4c4828ab18fad1 Mon Sep 17 00:00:00 2001 From: Jeff Gould <jrgould@gmail.com> Date: Wed, 13 Apr 2016 18:52:29 -0700 Subject: [PATCH 4238/4858] denote return vs output of expressions --- php/WP_CLI/REPL.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/REPL.php b/php/WP_CLI/REPL.php index c9f2b27b9e..4bb85ccf3e 100644 --- a/php/WP_CLI/REPL.php +++ b/php/WP_CLI/REPL.php @@ -34,9 +34,14 @@ public function start() { // Write directly to STDOUT, to sidestep any output buffers created by plugins ob_start(); - var_dump( eval( $line ) ); - $out = rtrim( ob_get_clean(), "\n" ) . "\n"; - fwrite( STDOUT, $out ); + $evl = eval( $line ); + $out = ob_get_clean(); + if ( 0 < strlen ( $out ) ) { + echo rtrim( $out, "\n" ) . "\n"; + } + echo "=> "; + var_dump( $evl ); + fwrite( STDOUT, ob_get_clean() ); } } } From f2454ba552678808df79529a1c1f7b226b20e2ad Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 14 Apr 2016 07:56:52 -0700 Subject: [PATCH 4239/4858] Include more details about package management --- php/commands/package.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/php/commands/package.php b/php/commands/package.php index e23040d150..461da96cfe 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -19,6 +19,15 @@ /** * Manage WP-CLI packages. * + * WP-CLI packages are community-maintained projects built on WP-CLI. They can + * contain WP-CLI commands, but they can also just extend WP-CLI in some way. + * + * Installable packages are listed in the + * [Package Index](http://wp-cli.org/package-index/). + * + * Learn how to create your own command from the + * [Commands Cookbook](http://wp-cli.org/docs/commands-cookbook/) + * * @package WP-CLI * * @when before_wp_load From 107dbfd349b63cd3189830863bd0017bb27f6678 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 18 Apr 2016 04:53:00 -0700 Subject: [PATCH 4240/4858] Bump composer.json to use Composer 1.0.0 ``` Loading composer repositories with package information Updating dependencies (including require-dev) - Removing seld/cli-prompt (1.0.1) - Installing seld/cli-prompt (1.0.2) Downloading: 100% Writing lock file Generating autoload files ``` --- composer.json | 2 +- composer.lock | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 66efa52b31..dbb80f7fa1 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "symfony/process": "~2.1", "symfony/translation": "~2.7", "nb/oxymel": "~0.1.0", - "composer/composer": "~1.0.0-beta" + "composer/composer": "~1.0.0" }, "require-dev": { "phpunit/phpunit": "3.7.*", diff --git a/composer.lock b/composer.lock index 2616ef216e..a11e791542 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "486865db5310fe94efdc68e6f0bcd370", - "content-hash": "6b640d71d1ddb8f42c44dfc0b508b9ae", + "hash": "7ea94f35bcaf09d491aba12444239a8a", + "content-hash": "81bc0608aece4400356ef972498724d4", "packages": [ { "name": "composer/composer", @@ -501,16 +501,16 @@ }, { "name": "seld/cli-prompt", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/Seldaek/cli-prompt.git", - "reference": "b27db1514f7d7bb7a366ad95d4eb2b17140a0691" + "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b27db1514f7d7bb7a366ad95d4eb2b17140a0691", - "reference": "b27db1514f7d7bb7a366ad95d4eb2b17140a0691", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", + "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", "shasum": "" }, "require": { @@ -545,7 +545,7 @@ "input", "prompt" ], - "time": "2016-01-09 17:55:27" + "time": "2016-04-18 09:31:41" }, { "name": "seld/jsonlint", @@ -1731,9 +1731,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "composer/composer": 10 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 1b0061b255a31c20d48d529bd5f66392c0024f05 Mon Sep 17 00:00:00 2001 From: Akeda Bagus <admin@gedex.web.id> Date: Mon, 18 Apr 2016 22:45:18 +0700 Subject: [PATCH 4241/4858] Added field filtering in cron event list command. Resolves #2666. --- php/commands/cron.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index 20d8eb3fb0..4f8a6a4f6f 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -22,6 +22,9 @@ class Cron_Event_Command extends WP_CLI_Command { * [--fields=<fields>] * : Limit the output to specific object fields. * + * [--<field>=<value>] + * : Filter by one or more fields. + * * [--field=<field>] * : Prints the value of a single field for each event. * @@ -61,6 +64,15 @@ public function list_( $args, $assoc_args ) { $events = array(); } + foreach ( $events as $key => $event ) { + foreach ( $this->fields as $field ) { + if ( ! empty( $assoc_args[ $field ] ) && $event->{$field} !== $assoc_args[ $field ] ) { + unset( $events[ $key ] ); + break; + } + } + } + if ( 'ids' == $formatter->format ) { echo implode( ' ', wp_list_pluck( $events, 'hook' ) ); } else { From 865a5525658f4b2170cfd27421b82805b4f8633e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Apr 2016 07:04:33 -0700 Subject: [PATCH 4242/4858] Catch `WP_Error` from `translations_api()` --- php/WP_CLI/CommandWithTranslation.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 277fb630e8..d4735e9c34 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -342,6 +342,9 @@ protected function get_all_languages() { require_once ABSPATH . '/wp-admin/includes/translation-install.php'; $response = translations_api( $this->obj_type ); + if ( is_wp_error( $response ) ) { + WP_CLI::error( $response ); + } $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); $en_us = array( From 326009406bceaceefa73ceedc4235a1df146a6b1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Apr 2016 07:13:02 -0700 Subject: [PATCH 4243/4858] Increase minimum supported version to PHP 5.3.29 While WP-CLI may work with earlier versions, this is the minimum version we can support because 5.3.29 is the version available in Travis. --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index dbb80f7fa1..f0281a185c 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "bin/wp.bat", "bin/wp" ], "require": { - "php": ">=5.3.2", + "php": ">=5.3.29", "wp-cli/php-cli-tools": "~0.11.1", "mustache/mustache": "~2.4", "mustangostang/spyc": "~0.5", diff --git a/composer.lock b/composer.lock index a11e791542..0f3fca2175 100644 --- a/composer.lock +++ b/composer.lock @@ -1735,7 +1735,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.3.2" + "php": ">=5.3.29" }, "platform-dev": [] } From c0d47fd4dcca9d3a851c7c01533bdfcc81028a93 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Apr 2016 07:16:48 -0700 Subject: [PATCH 4244/4858] Update to Composer v1.0.1 --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index a11e791542..0e5c701333 100644 --- a/composer.lock +++ b/composer.lock @@ -9,16 +9,16 @@ "packages": [ { "name": "composer/composer", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "32df3aa8cdbdaa16df9491b5e672e81c87f94c78" + "reference": "de0e25b0d494ace6b571a9205b82d017e5cb9257" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/32df3aa8cdbdaa16df9491b5e672e81c87f94c78", - "reference": "32df3aa8cdbdaa16df9491b5e672e81c87f94c78", + "url": "https://api.github.com/repos/composer/composer/zipball/de0e25b0d494ace6b571a9205b82d017e5cb9257", + "reference": "de0e25b0d494ace6b571a9205b82d017e5cb9257", "shasum": "" }, "require": { @@ -80,7 +80,7 @@ "dependency", "package" ], - "time": "2016-04-05 12:27:26" + "time": "2016-04-18 20:14:28" }, { "name": "composer/semver", From b2b019c26ee2eb9a35dd9debe3f904c69e5a56fe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Apr 2016 07:23:23 -0700 Subject: [PATCH 4245/4858] Add a functional test for `wp cron event list --<field>=<value>` --- features/cron.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/cron.feature b/features/cron.feature index 55092dbeca..fbdfae4d59 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -21,6 +21,18 @@ Feature: Manage WP-Cron events and schedules 1 hour """ + When I run `wp cron event list --hook=wp_cli_test_event_1 --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp cron event list --hook=apple --format=count` + Then STDOUT should be: + """ + 0 + """ + When I run `wp cron event delete wp_cli_test_event_1` Then STDOUT should contain: """ From 2430bceb193686471cb5afe0de068e37ec6caea3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Apr 2016 11:11:46 -0700 Subject: [PATCH 4246/4858] Failing test case for #1981 --- features/rewrite.feature | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/features/rewrite.feature b/features/rewrite.feature index f5c22050d5..ac033e6a33 100644 --- a/features/rewrite.feature +++ b/features/rewrite.feature @@ -59,15 +59,24 @@ Feature: Manage WordPress rewrites Success: Rewrite rules flushed. """ - Scenario: Generate .htaccess on hard flush + Scenario: Generate .htaccess on hard flush with a project config Given a WP install And a wp-cli.yml file: """ apache_modules: [mod_rewrite] """ - When I run `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/` - And I run `wp rewrite flush --hard` + When I run `wp rewrite structure /%year%/%monthnum%/%day%/%postname%/ --hard` + Then the .htaccess file should exist + + Scenario: Generate .htaccess on hard flush with a global config + Given a WP install + And a config.yml file: + """ + apache_modules: [mod_rewrite] + """ + + When I run `WP_CLI_CONFIG_PATH=config.yml wp rewrite structure /%year%/%monthnum%/%day%/%postname%/ --hard` Then the .htaccess file should exist Scenario: Error when trying to generate .htaccess on a multisite install From 2c309947675a73366543c47d976b619f39fbbfd3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Apr 2016 11:14:34 -0700 Subject: [PATCH 4247/4858] Persist global WP-CLI config when using WP_CLI::launch_self() Use of this method has a reasonable expectation that the launched process will mirror the existing process as closely as possible. Including the global WP-CLI config is necessary for mirroring the existing process. --- php/class-wp-cli.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index ad871ec168..7d3d970993 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -758,10 +758,17 @@ public static function launch_self( $command, $args = array(), $assoc_args = arr $script_path = $GLOBALS['argv'][0]; + if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) { + $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + } else { + $config_path = getenv( 'HOME' ) . '/.wp-cli/config.yml'; + } + $config_path = escapeshellarg( $config_path ); + $args = implode( ' ', array_map( 'escapeshellarg', $args ) ); $assoc_args = \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); - $full_command = "{$php_bin} {$script_path} {$command} {$args} {$assoc_args}"; + $full_command = "WP_CLI_CONFIG_PATH={$config_path} {$php_bin} {$script_path} {$command} {$args} {$assoc_args}"; return self::launch( $full_command, $exit_on_error, $return_detailed ); } From 255094c2ad2ab9ba7e6447bd12ef7dc040e3e01a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 26 Apr 2016 09:43:29 -0700 Subject: [PATCH 4248/4858] Failing test case for calling `before_invoke` on top-level command --- features/command.feature | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/features/command.feature b/features/command.feature index dafbf31613..d28865f7fd 100644 --- a/features/command.feature +++ b/features/command.feature @@ -520,13 +520,16 @@ Feature: WP-CLI Commands /** * @when before_wp_load */ - WP_CLI::add_command( 'before invoke', function() { + $before_invoke = function() { WP_CLI::success( 'Invoked' ); - }, array( 'before_invoke' => function() { + }; + $before_invoke_args = array( 'before_invoke' => function() { WP_CLI::success( 'before invoke' ); }, 'after_invoke' => function() { WP_CLI::success( 'after invoke' ); - })); + }); + WP_CLI::add_command( 'before invoke', $before_invoke, $before_invoke_args ); + WP_CLI::add_command( 'before-invoke', $before_invoke, $before_invoke_args ); """ When I run `wp --require=call-invoke.php before invoke` @@ -536,3 +539,11 @@ Feature: WP-CLI Commands Success: Invoked Success: after invoke """ + + When I run `wp --require=call-invoke.php before-invoke` + Then STDOUT should contain: + """ + Success: before invoke + Success: Invoked + Success: after invoke + """ From 2aa6b1857e3c3fbf35023ee4f69cade68a897e19 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 26 Apr 2016 09:45:54 -0700 Subject: [PATCH 4249/4858] Ensure `before_invoke` and `after_invoke` are called on top-level commands too --- php/WP_CLI/Dispatcher/Subcommand.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 97906b4df9..d8127a6b28 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -349,13 +349,18 @@ public function invoke( $args, $assoc_args, $extra_args ) { $path = get_path( $this->get_parent() ); $parent = implode( ' ', array_slice( $path, 1 ) ); - $cmd = $parent . ' ' . $this->name; - WP_CLI::do_hook( "before_invoke:{$parent}" ); + $cmd = $this->name; + if ( $parent ) { + WP_CLI::do_hook( "before_invoke:{$parent}" ); + $cmd = $parent . ' ' . $cmd; + } 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}" ); + if ( $parent ) { + WP_CLI::do_hook( "after_invoke:{$parent}" ); + } WP_CLI::do_hook( "after_invoke:{$cmd}" ); } } From fcdc1e5cc7fc7001904471bbb5c1bd9d01264458 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 26 Apr 2016 16:18:30 -0700 Subject: [PATCH 4250/4858] Update tests for WordPress 4.5.1 --- features/core-check-update.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index c99d9beb25..7750d65266 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -10,7 +10,7 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5 | major | https://downloads.wordpress.org/release/wordpress-4.5.zip | + | 4.5.1 | major | https://downloads.wordpress.org/release/wordpress-4.5.1.zip | | 3.8.13 | minor | https://downloads.wordpress.org/release/wordpress-3.8.13-partial-0.zip | When I run `wp core check-update --format=count` @@ -22,7 +22,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5 | major | https://downloads.wordpress.org/release/wordpress-4.5.zip | + | 4.5.1 | major | https://downloads.wordpress.org/release/wordpress-4.5.1.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: From cc1befe4c4bf7f8c90294b44bb3be78cf431831a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 26 Apr 2016 16:32:00 -0700 Subject: [PATCH 4251/4858] Only attempt to use `add_user_to_blog()` on multisite The function isn't available on a normal WordPress. --- php/commands/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 98c4861505..ccd973a72f 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -718,7 +718,7 @@ public function import_csv( $args, $assoc_args ) { $new_user['ID'] = $existing_user->ID; $user_id = wp_update_user( $new_user ); - if ( !in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) && $new_user['role'] ) { + if ( !in_array( $existing_user->user_login, wp_list_pluck( $blog_users, 'user_login' ) ) && is_multisite() && $new_user['role'] ) { add_user_to_blog( get_current_blog_id(), $existing_user->ID, $new_user['role'] ); WP_CLI::log( "{$existing_user->user_login} added as {$new_user['role']}." ); } From ea9b83a0239c38f952bceec1775e2151f5153c4e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 26 Apr 2016 16:35:43 -0700 Subject: [PATCH 4252/4858] Define `DOING_CRON` before WordPress is loaded Some plugins make use of this constant to conditionally load code, which is a valid use case we should do our best to accommodate. --- php/WP_CLI/Runner.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index b8ec97b773..8d13f2690c 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -747,6 +747,10 @@ public function start() { define( 'WP_IMPORTING', true ); } + if ( $this->cmd_starts_with( array( 'cron', 'event', 'run' ) ) ) { + define( 'DOING_CRON', true ); + } + if ( $this->cmd_starts_with( array( 'plugin' ) ) ) { $GLOBALS['pagenow'] = 'plugins.php'; } From 6dbca8ae0f26d83cd5af7ceaa3d70f12ddf7e3d5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 26 Apr 2016 16:52:45 -0700 Subject: [PATCH 4253/4858] Don't erroneously try to (de)activate plugins with `--all` flag When the `--all` flag is provided, we should only try to activate plugins that aren't active, and deactivate plugins that are active. --- features/plugin.feature | 12 ++++++++++++ php/commands/plugin.php | 23 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 063155a6c4..acae9581ba 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -262,6 +262,12 @@ Feature: Manage WordPress plugins Success: Plugin 'hello' activated. """ + When I run `wp plugin activate --all` + Then STDOUT should be: + """ + Success: All plugins are already activated. + """ + When I run `wp plugin list --field=status` Then STDOUT should be: """ @@ -277,6 +283,12 @@ Feature: Manage WordPress plugins Success: Plugin 'hello' deactivated. """ + When I run `wp plugin deactivate --all` + Then STDOUT should be: + """ + Success: All plugins are already deactivated. + """ + When I run `wp plugin list --field=status` Then STDOUT should be: """ diff --git a/php/commands/plugin.php b/php/commands/plugin.php index a7fdcb5c6b..734e2fec6e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -157,15 +157,21 @@ protected function get_all_items() { */ function activate( $args, $assoc_args = array() ) { $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); + $all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all', false ); - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + if ( $all ) { $args = array_map( function( $file ){ return Utils\get_plugin_name( $file ); }, array_keys( get_plugins() ) ); } + $needing_activation = count( $args ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { $status = $this->get_status( $plugin->file ); + if ( $all && in_array( $status, array( 'active', 'active-network' ) ) ) { + $needing_activation--; + continue; + } // Network-active is the highest level of activation status if ( 'active-network' === $status ) { WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." ); @@ -187,6 +193,10 @@ function activate( $args, $assoc_args = array() ) { $this->active_output( $plugin->name, $plugin->file, $network_wide, "activate" ); } + if ( ! $needing_activation ) { + WP_CLI::success( 'All plugins are already activated.' ); + } + } /** @@ -216,9 +226,15 @@ function deactivate( $args, $assoc_args = array() ) { }, array_keys( get_plugins() ) ); } + $needing_deactivation = count( $args ); foreach ( $this->fetcher->get_many( $args ) as $plugin ) { $status = $this->get_status( $plugin->file ); + if ( $disable_all && ! in_array( $status, array( 'active', 'active-network' ) ) ) { + $needing_deactivation--; + continue; + } + // Network active plugins must be explicitly deactivated if ( ! $network_wide && 'active-network' === $status ) { WP_CLI::warning( "Plugin '{$plugin->name}' is network active and must be deactivated with --network flag." ); @@ -240,6 +256,11 @@ function deactivate( $args, $assoc_args = array() ) { } } + + if ( ! $needing_deactivation ) { + WP_CLI::success( 'All plugins are already deactivated.' ); + } + } /** From ebed88ab095856b584f6caf33af42f19a3f9dc6d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 12:54:16 -0700 Subject: [PATCH 4254/4858] Use a better next significant release operator; update to Composer 1.0.2 --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index f0281a185c..8b2590b798 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "symfony/process": "~2.1", "symfony/translation": "~2.7", "nb/oxymel": "~0.1.0", - "composer/composer": "~1.0.0" + "composer/composer": "^1.0.0" }, "require-dev": { "phpunit/phpunit": "3.7.*", diff --git a/composer.lock b/composer.lock index 3a8ed67d11..389c55967c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,21 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7ea94f35bcaf09d491aba12444239a8a", - "content-hash": "81bc0608aece4400356ef972498724d4", + "hash": "f0bf52c59aa6e9fe44d6a611f8006a52", + "content-hash": "10cf19699e3fed767e31e1493a07c8f0", "packages": [ { "name": "composer/composer", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "de0e25b0d494ace6b571a9205b82d017e5cb9257" + "reference": "a083aa5e0c9b8ad989c622638aa380c1f88a68ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/de0e25b0d494ace6b571a9205b82d017e5cb9257", - "reference": "de0e25b0d494ace6b571a9205b82d017e5cb9257", + "url": "https://api.github.com/repos/composer/composer/zipball/a083aa5e0c9b8ad989c622638aa380c1f88a68ec", + "reference": "a083aa5e0c9b8ad989c622638aa380c1f88a68ec", "shasum": "" }, "require": { @@ -80,7 +80,7 @@ "dependency", "package" ], - "time": "2016-04-18 20:14:28" + "time": "2016-04-21 11:30:19" }, { "name": "composer/semver", From 4f3a36541fca3b68a9633d40ae23ce93c54f8b32 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 14:09:53 -0700 Subject: [PATCH 4255/4858] Include a `.svnignore` when scaffolding a new plugin For authors intending to distribute to WordPress.org, this is a helpful starter template of exclusions. --- features/scaffold.feature | 5 +++++ php/commands/scaffold.php | 1 + templates/plugin-svnignore.mustache | 12 ++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 templates/plugin-svnignore.mustache diff --git a/features/scaffold.feature b/features/scaffold.feature index 54c6100394..7c98f9cfe5 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -123,6 +123,11 @@ Feature: WordPress code scaffolding .DS_Store node_modules/ """ + And the {PLUGIN_DIR}/hello-world/.svnignore file should contain: + """ + .git + .gitignore + """ And the {PLUGIN_DIR}/hello-world/hello-world.php file should contain: """ * Plugin Name: Hello World diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 27a48e1972..ca566becc0 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -446,6 +446,7 @@ function plugin( $args, $assoc_args ) { "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), "$plugin_dir/.gitignore" => Utils\mustache_render( 'plugin-gitignore.mustache', $data ), + "$plugin_dir/.svnignore" => Utils\mustache_render( 'plugin-svnignore.mustache', $data ), "$plugin_dir/.editorconfig" => file_get_contents( WP_CLI_ROOT . "/templates/.editorconfig" ), ), $force ); diff --git a/templates/plugin-svnignore.mustache b/templates/plugin-svnignore.mustache new file mode 100644 index 0000000000..e2aafda73f --- /dev/null +++ b/templates/plugin-svnignore.mustache @@ -0,0 +1,12 @@ +# A set of files you probably don't want in your WordPress.org distribution +.editorconfig +.git +.gitignore +.travis.yml +bin +composer.json +composer.lock +phpunit.xml +tests +vendor +node_modules From 7835f732bb37580ff25e212f2a49c1016b0e0cbe Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 14:44:28 -0700 Subject: [PATCH 4256/4858] A few more files we don't want to include by default --- templates/plugin-svnignore.mustache | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/plugin-svnignore.mustache b/templates/plugin-svnignore.mustache index e2aafda73f..7c2581b323 100644 --- a/templates/plugin-svnignore.mustache +++ b/templates/plugin-svnignore.mustache @@ -1,4 +1,5 @@ # A set of files you probably don't want in your WordPress.org distribution +.svnignore .editorconfig .git .gitignore @@ -6,7 +7,11 @@ bin composer.json composer.lock +Gruntfile.js +package.json phpunit.xml +phpunit.xml.dist +README.md tests vendor node_modules From e5561013950cccca23a0dd3a5d852f316dccd2ff Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 15:20:19 -0700 Subject: [PATCH 4257/4858] Genuinely run test suite against built Phar file Apparently this hasn't been happening for a while --- ci/test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/test.sh b/ci/test.sh index 930f2b4a53..3295945f08 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -2,6 +2,8 @@ set -ex +export WP_CLI_BIN_DIR=/tmp/wp-cli-phar + # Run the unit tests vendor/bin/phpunit From 2a24ea9f9c49db178f071d6df664dd5ac8d94a75 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 15:35:33 -0700 Subject: [PATCH 4258/4858] Better way of verifying the `wp` binary --- ci/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/test.sh b/ci/test.sh index 3295945f08..34233ebad8 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -2,7 +2,7 @@ set -ex -export WP_CLI_BIN_DIR=/tmp/wp-cli-phar +$WP_CLI_BIN_DIR/wp --info # Run the unit tests vendor/bin/phpunit From 9d98f5c9f7607f234cefc12b0d992d3b59453568 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 15:41:39 -0700 Subject: [PATCH 4259/4858] Restore global `WP_CLI_BIN_DIR` env variable We can't set env variables in scripts. Unfortunately, this means the test suite hasn't been running against the Phar build for a while --- .travis.yml | 6 +++++- ci/prepare.sh | 2 -- ci/test.sh | 2 -- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 81b0e2b1da..b811927a52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ sudo: false language: php +env: + global: + - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + matrix: include: - php: 5.3 @@ -11,7 +15,7 @@ matrix: - php: 5.6 env: WP_VERSION=latest - php: 5.6 - env: WP_VERSION=latest BUILD=git + env: WP_VERSION=latest BUILD=git WP_CLI_BIN_DIR='' - php: 5.6 env: WP_VERSION=trunk - php: 7.0 diff --git a/ci/prepare.sh b/ci/prepare.sh index f2fea77e5a..bbf2aa502b 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -17,10 +17,8 @@ fi # the Behat test suite will pick up the executable found in $WP_CLI_BIN_DIR if [[ $BUILD == 'git' ]] then - export WP_CLI_BIN_DIR=bin/wp echo $CLI_VERSION > VERSION else - export WP_CLI_BIN_DIR=/tmp/wp-cli-phar mkdir -p $WP_CLI_BIN_DIR php -dphar.readonly=0 utils/make-phar.php wp-cli.phar --quiet --version=$CLI_VERSION mv wp-cli.phar $WP_CLI_BIN_DIR/wp diff --git a/ci/test.sh b/ci/test.sh index 34233ebad8..930f2b4a53 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -2,8 +2,6 @@ set -ex -$WP_CLI_BIN_DIR/wp --info - # Run the unit tests vendor/bin/phpunit From 4c7b3c7937241d18db088cce1defd6c237312944 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 15:44:32 -0700 Subject: [PATCH 4260/4858] Make it much easier to determine which `wp` binary we're running against --- features/bootstrap/FeatureContext.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 85748947bb..4886aa75ad 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -85,6 +85,10 @@ private static function cache_wp_files() { * @BeforeSuite */ public static function prepare( SuiteEvent $event ) { + $result = Process::create( 'wp cli info', null, self::get_process_env_variables() )->run_check(); + echo PHP_EOL; + echo $result->stdout; + echo PHP_EOL; self::cache_wp_files(); } From 312c3c8af754f97dd3a97ffce0cde6106d3973b2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 16:12:13 -0700 Subject: [PATCH 4261/4858] Include more dependencies the Phar build is expected to have --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 30c261c11c..7bbf083e07 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -69,6 +69,7 @@ function set_file_contents( $phar, $path, $content ) { ->in(WP_CLI_ROOT . '/vendor/mustache') ->in(WP_CLI_ROOT . '/vendor/rmccue/requests') ->in(WP_CLI_ROOT . '/vendor/composer') + ->in(WP_CLI_ROOT . '/vendor/seld') ->in(WP_CLI_ROOT . '/vendor/symfony') ->in(WP_CLI_ROOT . '/vendor/nb/oxymel') ->in(WP_CLI_ROOT . '/vendor/ramsey/array_column') From 8e4b55364b62a57eca19b8a84b7615a1fea78ee1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 28 Apr 2016 17:03:25 -0700 Subject: [PATCH 4262/4858] Include pem file that is occasionally needed by Composer --- utils/make-phar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 7bbf083e07..219164bd66 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -101,6 +101,7 @@ function set_file_contents( $phar, $path, $content ) { add_file( $phar, WP_CLI_ROOT . '/vendor/autoload.php' ); add_file( $phar, WP_CLI_ROOT . '/ci/behat-tags.php' ); add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/LICENSE' ); +add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/res/cacert.pem' ); add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/res/composer-schema.json' ); add_file( $phar, WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); From 1de6e47fc87661584c8494b9431bb5ea64235c32 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:26:25 -0700 Subject: [PATCH 4263/4858] Fix listing user meta associated with a given username All methods on this class need to replace a provided username / email address with the user id, which this method wasn't doing. --- features/user-meta.feature | 6 ++++++ php/commands/user.php | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/features/user-meta.feature b/features/user-meta.feature index 8d96312b24..4a8901ab4e 100644 --- a/features/user-meta.feature +++ b/features/user-meta.feature @@ -69,3 +69,9 @@ Feature: Manage user custom fields | user_id | meta_key | meta_value | | 1 | nickname | admin | | 1 | foo | ["1","2"] | + + When I run `wp user meta list admin --keys=nickname,foo` + Then STDOUT should be a table containing rows: + | user_id | meta_key | meta_value | + | 1 | nickname | admin | + | 1 | foo | ["1","2"] | diff --git a/php/commands/user.php b/php/commands/user.php index ccd973a72f..1973262926 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -830,6 +830,30 @@ public function __construct() { $this->fetcher = new \WP_CLI\Fetchers\User; } + /** + * List all metadata associated with a user. + * + * ## OPTIONS + * + * <id> + * : ID for the object. + * + * [--keys=<keys>] + * : Limit output to metadata of specific keys. + * + * [--fields=<fields>] + * : Limit the output to specific row fields. Defaults to id,meta_key,meta_value. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::list_( $args, $assoc_args ); + } + /** * Get meta field value. * From bdeae3675d1db7c064d62080463553d1decbe1ba Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:39:03 -0700 Subject: [PATCH 4264/4858] If comment was already trashed, then it will be deleted --- features/comment.feature | 12 ++++++++++++ php/commands/comment.php | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/features/comment.feature b/features/comment.feature index 9a4fb0de21..514b1e70ad 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -56,6 +56,18 @@ Feature: Manage WordPress comments Success: Trashed comment 4. """ + When I run `wp comment delete 3` + Then STDOUT should be: + """ + Success: Deleted comment 3. + """ + + When I try `wp comment get 3` + Then STDERR should be: + """ + Error: Invalid comment ID. + """ + Scenario: Get details about an existing comment When I run `wp comment get 1` Then STDOUT should be a table containing rows: diff --git a/php/commands/comment.php b/php/commands/comment.php index 8c8b82a3b0..b287a06f3e 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -249,10 +249,11 @@ public function delete( $args, $assoc_args ) { parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + $status = wp_get_comment_status( $comment_id ); $r = wp_delete_comment( $comment_id, $force ); if ( $r ) { - if ( $force ) { + if ( $force || 'trash' === $status ) { return array( 'success', "Deleted comment $comment_id." ); } else { return array( 'success', "Trashed comment $comment_id." ); From 8087e2ccac337e93c82952981e3e81292c5006f7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:45:23 -0700 Subject: [PATCH 4265/4858] Clearly denote OPTIONS in `wp cache *` docs --- php/commands/cache.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/php/commands/cache.php b/php/commands/cache.php index 51df60802a..2999399808 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -16,6 +16,8 @@ class Cache_Command extends WP_CLI_Command { * * If a value already exists for the key, the value isn't added. * + * ## OPTIONS + * * <key> * : Cache key. * @@ -45,6 +47,8 @@ public function add( $args, $assoc_args ) { /** * Decrement a value in the object cache. * + * ## OPTIONS + * * <key> * : Cache key. * @@ -73,6 +77,8 @@ public function decr( $args, $assoc_args ) { /** * Remove a value from the object cache. * + * ## OPTIONS + * * <key> * : Cache key. * @@ -112,6 +118,8 @@ public function flush( $args, $assoc_args ) { /** * Get a value from the object cache. * + * ## OPTIONS + * * <key> * : Cache key. * @@ -135,6 +143,8 @@ public function get( $args, $assoc_args ) { /** * Increment a value in the object cache. * + * ## OPTIONS + * * <key> * : Cache key. * @@ -163,6 +173,8 @@ public function incr( $args, $assoc_args ) { /** * Replace a value in the object cache, if the value already exists. * + * ## OPTIONS + * * <key> * : Cache key. * @@ -194,6 +206,8 @@ public function replace( $args, $assoc_args ) { /** * Set a value to the object cache, regardless of whether it already exists. * + * ## OPTIONS + * * <key> * : Cache key. * From 700d125689ed40a6ff9559346df934d30017d728 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:46:24 -0700 Subject: [PATCH 4266/4858] Clearly denote OPTIONS in `wp cap *` docs --- php/commands/cap.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/cap.php b/php/commands/cap.php index 9330c2c9a7..3f65b1f239 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -19,6 +19,8 @@ class Capabilities_Command extends WP_CLI_Command { /** * List capabilities for a given role. * + * ## OPTIONS + * * <role> * : Key for the role. * @@ -39,6 +41,8 @@ public function list_( $args ) { /** * Add capabilities to a given role. * + * ## OPTIONS + * * <role> * : Key for the role. * @@ -69,6 +73,8 @@ public function add( $args ) { /** * Remove capabilities from a given role. * + * ## OPTIONS + * * <role> * : Key for the role. * From 3ce23272f6c1da9e78f0d6d88a0886ecc36642a9 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:48:22 -0700 Subject: [PATCH 4267/4858] Clarify that `wp core verify-checksums` doesn't actually load WP This behavior changed in the last release --- php/commands/core.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index e60505e79f..7208c05ea3 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -789,7 +789,9 @@ public function version( $args = array(), $assoc_args = array() ) { /** * Verify WordPress files against WordPress.org's checksums. * - * Specify version to verify checksums without loading WordPress. + * For security, avoids loading WordPress when verifying checksums. + * + * ## OPTIONS * * [--version=<version>] * : Verify checksums against a specific version of WordPress. From 800261159688cb30b278c98bb7ffe18102aa4fdd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:49:30 -0700 Subject: [PATCH 4268/4858] Clearly denote OPTIONS in `wp eval` docs --- php/commands/eval.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/eval.php b/php/commands/eval.php index f81a626dab..11847ccfde 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -5,6 +5,8 @@ class Eval_Command extends WP_CLI_Command { /** * Execute arbitrary PHP code. * + * ## OPTIONS + * * <php-code> * : The code to execute, as a string. * From a18bf85eb9073b6ad29e70a6b73608ec64d8a71b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 04:51:52 -0700 Subject: [PATCH 4269/4858] Clearly denote OPTIONS in `wp menu *` docs --- php/commands/menu.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index 1c9e7e12b6..b4272494fe 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -31,6 +31,8 @@ class Menu_Command extends WP_CLI_Command { /** * Create a new menu * + * ## OPTIONS + * * <menu-name> * : A descriptive name for the menu * @@ -63,6 +65,8 @@ public function create( $args, $assoc_args ) { /** * Delete one or more menus * + * ## OPTIONS + * * <menu>... * : The name, slug, or term ID for the menu(s) * @@ -253,6 +257,8 @@ public function list_( $args, $assoc_args ) { /** * Add a post as a menu item * + * ## OPTIONS + * * <menu> * : The name, slug, or term ID for the menu * @@ -308,6 +314,8 @@ public function add_post( $args, $assoc_args ) { /** * Add a taxonomy term as a menu item * + * ## OPTIONS + * * <menu> * : The name, slug, or term ID for the menu * @@ -367,6 +375,8 @@ public function add_term( $args, $assoc_args ) { /** * Add a custom menu item * + * ## OPTIONS + * * <menu> * : The name, slug, or term ID for the menu * @@ -415,6 +425,8 @@ public function add_custom( $args, $assoc_args ) { /** * Update a menu item * + * ## OPTIONS + * * <db-id> * : Database ID for the menu item. * @@ -466,6 +478,8 @@ public function update( $args, $assoc_args ) { /** * Delete one or more items from a menu * + * ## OPTIONS + * * <db-id>... * : Database ID for the menu item(s). * @@ -633,6 +647,8 @@ class Menu_Location_Command extends WP_CLI_Command { /** * List locations for the current theme. * + * ## OPTIONS + * * [--format=<format>] * : Accepted values: table, csv, json, count, ids, yaml. Default: table * @@ -667,6 +683,8 @@ public function list_( $_, $assoc_args ) { /** * Assign a location to a menu * + * ## OPTIONS + * * <menu> * : The name, slug, or term ID for the menu * @@ -704,6 +722,8 @@ public function assign( $args, $_ ) { /** * Remove a location from a menu * + * ## OPTIONS + * * <menu> * : The name, slug, or term ID for the menu * From b51b05fc0b9146a920198615ba28db3d73fd111a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 29 Apr 2016 13:42:45 -0700 Subject: [PATCH 4270/4858] Document how to handle WP in subdirectory; add test to doc behavior --- features/core.feature | 60 +++++++++++++++++++++++++++++++++++++++++++ php/commands/core.php | 12 ++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/features/core.feature b/features/core.feature index 0bc830cd04..a0f2f54ec6 100644 --- a/features/core.feature +++ b/features/core.feature @@ -260,3 +260,63 @@ Feature: Manage WordPress installation """ Error: WordPress files seem to already be present here. """ + + Scenario: Install WordPress in a subdirectory + Given an empty directory + And a wp-config.php file: + """ + <?php + // ** MySQL settings ** // + /** The name of the database for WordPress */ + define('DB_NAME', 'wp_cli_test'); + + /** MySQL database username */ + define('DB_USER', 'wp_cli_test'); + + /** MySQL database password */ + define('DB_PASSWORD', 'password1'); + + /** MySQL hostname */ + define('DB_HOST', '127.0.0.1'); + + /** Database Charset to use in creating database tables. */ + define('DB_CHARSET', 'utf8'); + + /** The Database Collate type. Don't change this if in doubt. */ + define('DB_COLLATE', ''); + + $table_prefix = 'wp_'; + + /* That's all, stop editing! Happy blogging. */ + + /** Absolute path to the WordPress directory. */ + if ( !defined('ABSPATH') ) + define('ABSPATH', dirname(__FILE__) . '/'); + + /** Sets up WordPress vars and included files. */ + require_once(ABSPATH . 'wp-settings.php'); + """ + And a wp-cli.yml file: + """ + path: wp + """ + + When I run `wp core download` + Then the wp directory should exist + And the wp/wp-blog-header.php file should exist + + When I run `wp db create` + And I run `wp core install --url=wp.dev --title="WP Dev" --admin_user=wpcli --admin_password=wpcli --admin_email=wpcli@example.com` + Then STDOUT should not be empty + + When I run `wp option get home` + Then STDOUT should be: + """ + http://wp.dev + """ + + When I run `wp option get siteurl` + Then STDOUT should be: + """ + http://wp.dev + """ diff --git a/php/commands/core.php b/php/commands/core.php index 7208c05ea3..4ef5755074 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -414,7 +414,17 @@ public function is_installed( $_, $assoc_args ) { } /** - * Create the WordPress tables in the database. + * Runs the standard WordPress installation process. + * + * Creates the WordPress tables in the database using the URL, title, and + * default admin user details provided. Performs the famous 5 minute install + * in seconds or less. + * + * Note: if you've installed WordPress in a subdirectory, then you'll need + * to `wp option update siteurl` after `wp core install`. For instance, if + * WordPress is installed in the `/wp` directory and your domain is wp.dev, + * then you'll need to run `wp option update siteurl http://wp.dev/wp` for + * your WordPress install to function properly. * * ## OPTIONS * From c863051646da854b5d20a32ccbe60ff92f5206c7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 2 May 2016 16:11:58 -0700 Subject: [PATCH 4271/4858] Document how to import an attachment and assign multiple thumbnails --- php/commands/media.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/media.php b/php/commands/media.php index df37e75215..ddbf001b1c 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -120,6 +120,12 @@ function regenerate( $args, $assoc_args = array() ) { * # Import a local image and set it to be the post thumbnail for a post * wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image * + * # Import a local image, but set it as the featured image for all posts + * # 1. Import the image and get its attachment ID + * * 2. Assign the attachment ID as the featured image for all posts + * ATTACHMENT_ID="$(wp media import ~/Downloads/image.png --porcelain)" + * wp post list --post_type=post --format=ids | xargs -0 -d ' ' -I % wp post meta add % _thumbnail_id $ATTACHMENT_ID + * * # Import an image from the web * wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" */ From d601bf0989b4c1a2b87d9390cb14bf5748ce2816 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 3 May 2016 10:16:10 +0545 Subject: [PATCH 4272/4858] issue of taking only first digit from Comment ID --- php/commands/comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 4031bcc798..a29f135b2a 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -302,7 +302,7 @@ private function call( $args, $status, $success, $failure ) { } private function set_status( $args, $status, $success ) { - $comment = $this->fetcher->get_check( $args[0] ); + $comment = $this->fetcher->get_check( $args ); $r = wp_set_comment_status( $comment->comment_ID, $status, true ); From 656482e074e815b27f8f1d0a3674af7c80f1abe1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 3 May 2016 17:21:57 +0545 Subject: [PATCH 4273/4858] add test for comment issue --- features/comment.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 514b1e70ad..bc5fa51c75 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -159,3 +159,33 @@ Feature: Manage WordPress comments """ 0 """ + + Scenario: Approving/unapproving comments with multidigit comment ID + Given I run `wp comment generate --count=10 --quiet` + And I run `wp comment create --porcelain` + And save STDOUT as {COMMENT_ID} + + When I run `wp comment unapprove {COMMENT_ID}` + Then STDOUT should contain: + """ + Unapproved comment {COMMENT_ID} + """ + + When I run `wp comment get --field=comment_approved {COMMENT_ID}` + Then STDOUT should be: + """ + 10 + """ + + When I run `wp comment approve {COMMENT_ID}` + Then STDOUT should contain: + """ + Approved comment {COMMENT_ID} + """ + + When I run `wp comment get --field=comment_approved {COMMENT_ID}` + Then STDOUT should be: + """ + 11 + """ + From a936bf6bf5d29a7f34aa793f9994c6f3359532b7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 3 May 2016 04:58:25 -0700 Subject: [PATCH 4274/4858] Ignore ambigious empty plugin and theme slugs when installing If a user supplies an empty slug, its likely a mistake. WP-CLI shouldn't proceeed to install the first result from WordPress.org --- features/plugin.feature | 13 +++++++++++++ php/WP_CLI/CommandWithUpgrade.php | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index acae9581ba..ff89ccb2ed 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -401,3 +401,16 @@ Feature: Manage WordPress plugins Then STDOUT should be a table containing rows: | name | version | | akismet | 2.6.0 | + + Scenario: Ignore empty slugs + Given a WP install + + When I run `wp plugin install ''` + Then STDERR should contain: + """ + Warning: Ignoring ambigious empty slug value. + """ + And STDOUT should not contain: + """ + Plugin installed successfully + """ diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index e1c5dd0d78..561b2331d2 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -2,6 +2,8 @@ namespace WP_CLI; +use WP_CLI; + abstract class CommandWithUpgrade extends \WP_CLI_Command { protected $item_type; @@ -117,6 +119,12 @@ private function show_legend( $items ) { function install( $args, $assoc_args ) { foreach ( $args as $slug ) { + + if ( empty( $slug ) ) { + WP_CLI::warning( "Ignoring ambigious empty slug value." ); + continue; + } + $local_or_remote_zip_file = false; $result = false; From 43e313e90a7ab0caec2aff590c237aa93a3321e7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 3 May 2016 05:19:52 -0700 Subject: [PATCH 4275/4858] Prevent runaway memory usage by clearing object cache after each file --- php/commands/export.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/export.php b/php/commands/export.php index 8d5731df0f..7d89b0a0ad 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -94,6 +94,7 @@ public function __invoke( $_, $assoc_args ) { add_action( 'wp_export_new_file', function( $file_path ) { WP_CLI::log( sprintf( "Writing to file %s", $file_path ) ); + WP_CLI\Utils\wp_clear_object_cache(); } ); try { From 7e9159e5c81afbd2b5d3b2fd89722ae69d7e73d7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 3 May 2016 05:33:57 -0700 Subject: [PATCH 4276/4858] Failing test case for greedy parsing of args again --- tests/test-doc-parser.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test-doc-parser.php b/tests/test-doc-parser.php index 90cd205c2d..c82ed4e69e 100644 --- a/tests/test-doc-parser.php +++ b/tests/test-doc-parser.php @@ -97,6 +97,13 @@ function test_complete() { public function test_desc_parses_yaml() { $longdesc = <<<EOB +Play some music loudly + +``` +# Here's an example of how you might run the command +wp rock-on electronic --volume=11 +``` + ## OPTIONS <genre>... From 7bdc0a4a51a1dc6e07520145cd4c39efb8ac6f9b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 3 May 2016 05:35:42 -0700 Subject: [PATCH 4277/4858] Fix greedy parsing of command args, part two When an example is included at the beginning of the command, we need to make sure we don't match on example usage. --- php/WP_CLI/DocParser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/DocParser.php b/php/WP_CLI/DocParser.php index b9ab93d198..7d3df55324 100644 --- a/php/WP_CLI/DocParser.php +++ b/php/WP_CLI/DocParser.php @@ -120,7 +120,7 @@ public function get_arg_desc( $name ) { * @return mixed|null */ public function get_arg_args( $name ) { - return $this->get_arg_or_param_args( "/\[?<{$name}>.*/" ); + return $this->get_arg_or_param_args( "/^\[?<{$name}>.*/" ); } /** @@ -145,7 +145,7 @@ public function get_param_desc( $key ) { * @return mixed|null */ public function get_param_args( $key ) { - return $this->get_arg_or_param_args( "/\[?--{$key}=.*/" ); + return $this->get_arg_or_param_args( "/^\[?--{$key}=.*/" ); } /** From 9dd7d2b0dac82a88ac9e420298b5a762c4904ac7 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 4 May 2016 10:38:52 +0545 Subject: [PATCH 4278/4858] fix command in comment feature test --- features/comment.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index bc5fa51c75..7bdad4fa2f 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -171,7 +171,7 @@ Feature: Manage WordPress comments Unapproved comment {COMMENT_ID} """ - When I run `wp comment get --field=comment_approved {COMMENT_ID}` + When I run `wp comment list --format=count --status=approve` Then STDOUT should be: """ 10 @@ -183,7 +183,7 @@ Feature: Manage WordPress comments Approved comment {COMMENT_ID} """ - When I run `wp comment get --field=comment_approved {COMMENT_ID}` + When I run `wp comment list --format=count --status=approve` Then STDOUT should be: """ 11 From 3ea2c2ccc2e40b06e854683ffc7e9bc09fa52217 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 4 May 2016 11:16:40 +0545 Subject: [PATCH 4279/4858] remove all comments before test --- features/comment.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/comment.feature b/features/comment.feature index 7bdad4fa2f..ef11b422ce 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -161,7 +161,8 @@ Feature: Manage WordPress comments """ Scenario: Approving/unapproving comments with multidigit comment ID - Given I run `wp comment generate --count=10 --quiet` + Given I run `wp comment delete $(wp comment list --field=ID)` + And I run `wp comment generate --count=10 --quiet` And I run `wp comment create --porcelain` And save STDOUT as {COMMENT_ID} From 25e62e4103637ba783e2472ad4fe693197be1918 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 4 May 2016 04:06:06 -0700 Subject: [PATCH 4280/4858] Interact with the Package Index over SSL More secure! More better! --- php/commands/package.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 461da96cfe..4129c92fd1 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -34,7 +34,7 @@ */ class Package_Command extends WP_CLI_Command { - const PACKAGE_INDEX_URL = 'http://wp-cli.org/package-index/'; + const PACKAGE_INDEX_URL = 'https://wp-cli.org/package-index/'; private $fields = array( 'name', @@ -102,7 +102,7 @@ public function install( $args, $assoc_args ) { $json_manipulator = new JsonManipulator( $composer_backup ); $json_manipulator->addMainKey( 'name', 'wp-cli/wp-cli' ); $json_manipulator->addLink( 'require', $package_name, $version ); - $json_manipulator->addConfigSetting( 'secure-http', false ); + $json_manipulator->addConfigSetting( 'secure-http', true ); file_put_contents( $composer_json_obj->getPath(), $json_manipulator->getContents() ); try { $composer = $this->get_composer(); @@ -288,7 +288,7 @@ private function package_index() { $config = new Config(); $config->merge( array( 'config' => array( - 'secure-http' => false, + 'secure-http' => true, 'home' => dirname( $this->get_composer_json_path() ), ) )); From bfb51cffec980e8f823e83a64a3533e8809582bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 4 May 2016 09:01:46 -0700 Subject: [PATCH 4281/4858] Mention multisite rewrite rules will need to be added manually. --- php/commands/core.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4ef5755074..4e23f1509e 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -457,6 +457,9 @@ public function install( $args, $assoc_args ) { /** * Transform a single-site install into a multi-site install. * + * For those using WordPress with Apache, remember to update the `.htaccess` + * file with the appropriate multisite rewrite rules. + * * ## OPTIONS * * [--title=<network-title>] From 4b696f3cfb3479205feb3f81f904465b925a6965 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 11 May 2016 10:27:31 +0545 Subject: [PATCH 4282/4858] fix incorrect parameter in post-type list command doc --- php/commands/post-type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post-type.php b/php/commands/post-type.php index 4fdff4600b..ae73a2dd0f 100644 --- a/php/commands/post-type.php +++ b/php/commands/post-type.php @@ -49,7 +49,7 @@ class Post_Type_Command extends WP_CLI_Command { * * wp post-type list --format=csv * - * wp post-type list --object-type=post --fields=name,public + * wp post-type list --capability_type=post --fields=name,public * * @subcommand list */ From 182d003d4bfc10be4cca4c854bac0e0ec1fc0d5e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 11 May 2016 04:08:32 -0700 Subject: [PATCH 4283/4858] Update tests for WP 4.5.2 --- features/core-check-update.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 7750d65266..ad3cf2a695 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -10,8 +10,8 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5.1 | major | https://downloads.wordpress.org/release/wordpress-4.5.1.zip | - | 3.8.13 | minor | https://downloads.wordpress.org/release/wordpress-3.8.13-partial-0.zip | + | 4.5.2 | major | https://downloads.wordpress.org/release/wordpress-4.5.2.zip | + | 3.8.14 | minor | https://downloads.wordpress.org/release/wordpress-3.8.14-partial-0.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -22,7 +22,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5.1 | major | https://downloads.wordpress.org/release/wordpress-4.5.1.zip | + | 4.5.2 | major | https://downloads.wordpress.org/release/wordpress-4.5.2.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -33,7 +33,7 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.13 | minor | https://downloads.wordpress.org/release/wordpress-3.8.13-partial-0.zip | + | 3.8.14 | minor | https://downloads.wordpress.org/release/wordpress-3.8.14-partial-0.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: @@ -54,4 +54,4 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0.10 | minor | https://downloads.wordpress.org/release/wordpress-4.0.10-partial-0.zip | + | 4.0.11 | minor | https://downloads.wordpress.org/release/wordpress-4.0.11-partial-0.zip | From 3c1f28fa584366fb2d98179623bea587d4f261aa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 11 May 2016 04:32:19 -0700 Subject: [PATCH 4284/4858] Version bump for minor releases too --- features/core-update.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core-update.feature b/features/core-update.feature index 2cb55be5f7..ea20e10492 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -40,7 +40,7 @@ Feature: Update WordPress core When I run `wp core update --minor` Then STDOUT should contain: """ - Updating to version 3.7.13 + Updating to version 3.7.14 """ When I run `wp core update --minor` @@ -52,7 +52,7 @@ Feature: Update WordPress core When I run `wp core version` Then STDOUT should be: """ - 3.7.13 + 3.7.14 """ @less-than-php-7 From a5a1426acfe1726f5750a53bcd354fe5c9aee11f Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 12 May 2016 13:53:13 +0545 Subject: [PATCH 4285/4858] display success message in dry run in search-replace --- features/search-replace.feature | 6 ++++++ php/commands/search-replace.php | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index 99ec9b0c0b..2fd3e14e8a 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -216,6 +216,12 @@ Feature: Do global search/replace | Table | Column | Replacements | Type | | wp_posts | post_content | 1 | SQL | + When I run `wp search-replace '<a href="http://google.com">Google</a>' '<a href="http://apple.com">Apple</a>' --dry-run` + Then STDOUT should contain: + """ + 1 replacement(s) to be made. + """ + When I run `wp post get {POST_ID} --field=content` Then STDOUT should be: """ diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 5de6afa3cc..7ab5f51730 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -207,6 +207,10 @@ public function __invoke( $args, $assoc_args ) { } WP_CLI::success( $success_message ); } + else { + $success_message = "$total replacement(s) to be made."; + WP_CLI::success( $success_message ); + } } private function php_export_table( $table, $old, $new ) { From 5f51f673370349097c0bf2e6db0246d9b90ce2ed Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 12 May 2016 06:07:53 -0700 Subject: [PATCH 4286/4858] Failing test case for using supplied `default` and `options` --- features/command.feature | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/features/command.feature b/features/command.feature index d28865f7fd..490b13c315 100644 --- a/features/command.feature +++ b/features/command.feature @@ -285,10 +285,10 @@ Feature: WP-CLI Commands And a custom-cmd.php file: """ <?php - function foo( $args ) { + function foo( $args, $assoc_args ) { $message = array_shift( $args ); WP_CLI::log( 'Message is: ' . $message ); - WP_CLI::success( $args[0] ); + WP_CLI::success( $assoc_args['meal'] ); } WP_CLI::add_command( 'foo', 'foo', array( 'shortdesc' => 'My awesome function command', @@ -370,6 +370,32 @@ Feature: WP-CLI Commands --- """ + When I try `wp foo nana --apple=fuji` + Then STDERR should contain: + """ + Error: Invalid value specified for positional arg. + """ + + When I try `wp foo hello --apple=fuji --meal=snack` + Then STDERR should contain: + """ + Invalid value specified for 'meal' (A type of meal.) + """ + + When I run `wp foo hello --apple=fuji` + Then STDOUT should be: + """ + Message is: hello + Success: breakfast + """ + + When I run `wp foo hello --apple=fuji --meal=dinner` + Then STDOUT should be: + """ + Message is: hello + Success: dinner + """ + Scenario: Register a command with default and accepted arguments. Given an empty directory And a test-cmd.php file: From 1fa689fd3da74c0b747a92f5cf3235998b94ecfa Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 12 May 2016 12:43:38 -0700 Subject: [PATCH 4287/4858] Mock command PHPDoc so we can reparse it This enables `default` and `options` are used when supplied as the third argument to `WP_CLI::add_command()` At some point, this storing of command metadata in PHPdoc needs to be dealt with. But not yet. --- php/WP_CLI/Dispatcher/Subcommand.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index d8127a6b28..35d8922cb3 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -258,9 +258,13 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $synopsis_spec = \WP_CLI\SynopsisParser::parse( $synopsis ); $i = 0; $errors = array( 'fatal' => array(), 'warning' => array() ); + $mock_doc = array( $this->get_shortdesc(), '' ); + $mock_doc = array_merge( $mock_doc, explode( PHP_EOL, $this->get_longdesc() ) ); + $mock_doc = '/**' . PHP_EOL . '* ' . implode( PHP_EOL . '* ', $mock_doc ) . PHP_EOL . '*/'; + $docparser = new \WP_CLI\DocParser( $mock_doc ); foreach( $synopsis_spec as $spec ) { if ( 'positional' === $spec['type'] ) { - $spec_args = $this->docparser->get_arg_args( $spec['name'] ); + $spec_args = $docparser->get_arg_args( $spec['name'] ); if ( ! isset( $args[ $i ] ) ) { if ( isset( $spec_args['default'] ) ) { $args[ $i ] = $spec_args['default']; @@ -282,7 +286,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { } $i++; } else if ( 'assoc' === $spec['type'] ) { - $spec_args = $this->docparser->get_param_args( $spec['name'] ); + $spec_args = $docparser->get_param_args( $spec['name'] ); if ( ! isset( $assoc_args[ $spec['name'] ] ) ) { if ( isset( $spec_args['default'] ) ) { $assoc_args[ $spec['name'] ] = $spec_args['default']; @@ -313,7 +317,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $out = 'Parameter errors:'; foreach ( $errors['fatal'] as $key => $error ) { $out .= "\n {$error}"; - if ( $desc = $this->docparser->get_param_desc( $key ) ) { + if ( $desc = $docparser->get_param_desc( $key ) ) { $out .= " ({$desc})"; } } From fc1797cfa3efe9e3a412c30e24c8d9474de6cd04 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Fri, 13 May 2016 16:11:15 +0300 Subject: [PATCH 4288/4858] Extended insert format to search-replace SQL export --- php/commands/search-replace.php | 45 ++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7ab5f51730..0853258de4 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -228,6 +228,8 @@ private function php_export_table( $table, $old, $new ) { $this->start_time = microtime( true ); WP_CLI::log( sprintf( 'Checking: %s', $table ) ); } + + $rows = array(); foreach ( new \WP_CLI\Iterators\Table( $args ) as $i => $row ) { $row_fields = array(); foreach( $all_columns as $col ) { @@ -241,8 +243,9 @@ private function php_export_table( $table, $old, $new ) { } $row_fields[ $col ] = $value; } - $this->write_sql_row_fields( $table, $row_fields ); + $rows[] = $row_fields; } + $this->write_sql_row_fields( $table, $rows ); $table_report = array(); $total_rows = $total_cols = 0; @@ -328,20 +331,33 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { return $count; } - private function write_sql_row_fields( $table, $row_fields ) { + private function write_sql_row_fields( $table, $rows ) { global $wpdb; - $sql = "INSERT INTO `$table` ("; - $sql .= join( ', ', array_map( - function ( $field ) { - return "`$field`"; - }, - array_keys( $row_fields ) - ) ); - $sql .= ') VALUES ('; - $sql .= join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ); - $sql .= ");\n"; - $sql = $wpdb->prepare( $sql, array_values( $row_fields ) ); - fwrite( $this->export_handle, $sql ); + + if(!empty($rows)) { + $sql = "INSERT INTO `$table` ("; + $sql .= join( ', ', array_map( + function ( $field ) { + return "`$field`"; + }, + array_keys( $rows[0] ) + ) ); + $sql .= ') VALUES '; + $sql .= "\n"; + + $values = array(); + $count = count( $rows ); // No comma to last row + foreach($rows as $row_fields) { + $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')' . ($count-- > 1 ? ',' : ''); + $sql .= "\n"; + $values = array_merge( $values, array_values( $row_fields ) ); + } + + $sql .= ";\n"; + + $sql = $wpdb->prepare( $sql, array_values( $values ) ); + fwrite( $this->export_handle, $sql ); + } } private static function get_columns( $table ) { @@ -387,4 +403,3 @@ private static function esc_like( $old ) { } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); - From 8d80c06ce23a7d7fca7ec28f69bb207abc05c38d Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Fri, 13 May 2016 17:03:35 +0300 Subject: [PATCH 4289/4858] Updated search-replace-export feature test --- features/search-replace-export.feature | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index e50bde0cc0..630c733095 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -11,7 +11,11 @@ Feature: Search / replace with file export """ And STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.net', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + """ + And STDOUT should contain: + """ + ('1', 'siteurl', 'http://example.net', 'yes') """ When I run `wp option get home` @@ -23,8 +27,12 @@ Feature: Search / replace with file export When I run `wp search-replace example.com example.net --skip-columns=option_value --export` Then STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.com', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES """ + And STDOUT should contain: + """ + ('1', 'siteurl', 'http://example.com', 'yes') + """ When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: From 3751db8ffa51230a02a271da79602dc523c353b4 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Fri, 13 May 2016 17:28:44 +0300 Subject: [PATCH 4290/4858] Split insert queries into separate chunks --- php/commands/search-replace.php | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0853258de4..7df844116f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -335,25 +335,40 @@ private function write_sql_row_fields( $table, $rows ) { global $wpdb; if(!empty($rows)) { - $sql = "INSERT INTO `$table` ("; - $sql .= join( ', ', array_map( + $insert = "INSERT INTO `$table` ("; + $insert .= join( ', ', array_map( function ( $field ) { return "`$field`"; }, array_keys( $rows[0] ) ) ); - $sql .= ') VALUES '; - $sql .= "\n"; + $insert .= ') VALUES '; + $insert .= "\n"; + $sql = $insert; $values = array(); - $count = count( $rows ); // No comma to last row + + $index = 1; + $count = count( $rows ); + $export_chunk_size = 50; // Amount of rows in one insert query + foreach($rows as $row_fields) { - $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')' . ($count-- > 1 ? ',' : ''); - $sql .= "\n"; + $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; $values = array_merge( $values, array_values( $row_fields ) ); - } - $sql .= ";\n"; + if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { + $sql .= ";\n"; + + if( $count > $index ) { + $sql .= $insert; + } + } else { + $sql .= ",\n"; + + } + + $index++; + } $sql = $wpdb->prepare( $sql, array_values( $values ) ); fwrite( $this->export_handle, $sql ); From 8a9d2d4b455dd2ab5a0b34b7778da39a990ab9a7 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sat, 14 May 2016 20:49:31 +0900 Subject: [PATCH 4291/4858] fix #2711 --- features/post.feature | 8 +++++++- php/WP_CLI/Formatter.php | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/post.feature b/features/post.feature index d9e5e07933..b503ccee37 100644 --- a/features/post.feature +++ b/features/post.feature @@ -100,7 +100,7 @@ Feature: Manage WordPress posts """ This is some bunkum. """ - + When I run `wp post url 1 {POST_ID}` Then STDOUT should be: """ @@ -176,6 +176,12 @@ Feature: Manage WordPress posts | Publish post | publish-post | publish | | Draft post | | draft | + When I run `wp post list --post_type='post' --fields="title, name, status" --format=csv` + Then STDOUT should be CSV containing: + | post_title | post_name | post_status | + | Publish post | publish-post | publish | + | Draft post | | draft | + When I run `wp post list --post__in={POST_ID} --format=count` Then STDOUT should be: """ diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 87f81c8bb5..0b04ec5e81 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -40,6 +40,8 @@ public function __construct( &$assoc_args, $fields = null, $prefix = false ) { $format_args['fields'] = explode( ',', $format_args['fields'] ); } + $format_args['fields'] = array_map( 'trim', $format_args['fields'] ); + $this->args = $format_args; $this->prefix = $prefix; } From 66612c02ecbc69c1928c9566058ea6386707c999 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sun, 15 May 2016 05:20:07 +0900 Subject: [PATCH 4292/4858] get wp version when scaffolding plugin --- features/scaffold.feature | 16 ++++++++++++++-- php/commands/scaffold.php | 15 ++++++++------- templates/plugin-readme.mustache | 6 +++--- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 7c98f9cfe5..cc79744ae7 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -109,6 +109,8 @@ Feature: WordPress code scaffolding Given a WP install Given I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} + Given I run `wp core version` + And save STDOUT as {WP_VERSION} When I run `wp scaffold plugin hello-world --plugin_author="Hello World Author"` Then STDOUT should not be empty @@ -140,6 +142,14 @@ Feature: WordPress code scaffolding """ * @package Hello_World """ + And the {PLUGIN_DIR}/hello-world/readme.txt file should contain: + """ + Stable tag: 0.1.0 + """ + And the {PLUGIN_DIR}/hello-world/readme.txt file should contain: + """ + Tested up to: {WP_VERSION} + """ When I run `cat {PLUGIN_DIR}/hello-world/package.json` Then STDOUT should be JSON containing: @@ -332,6 +342,8 @@ Feature: WordPress code scaffolding Scenario: Scaffold tests parses plugin readme.txt Given a WP install + When I run `wp core version` + Then save STDOUT as {WP_VERSION} When I run `wp plugin path` Then save STDOUT as {PLUGIN_DIR} @@ -343,8 +355,8 @@ Feature: WordPress code scaffolding """ env: - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=3.0.1 WP_MULTISITE=0 - - WP_VERSION=3.4 WP_MULTISITE=0 + - WP_VERSION=3.7 WP_MULTISITE=0 + - WP_VERSION={WP_VERSION} WP_MULTISITE=0 """ Scenario: Scaffold starter code for a theme and network enable it diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ca566becc0..11bf1b9107 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -415,13 +415,14 @@ function plugin( $args, $assoc_args ) { $plugin_package = str_replace( ' ', '_', $plugin_name ); $data = wp_parse_args( $assoc_args, array( - 'plugin_slug' => $plugin_slug, - 'plugin_name' => $plugin_name, - 'plugin_package' => $plugin_package, - 'plugin_description' => 'PLUGIN DESCRIPTION HERE', - 'plugin_author' => 'YOUR NAME HERE', - 'plugin_author_uri' => 'YOUR SITE HERE', - 'plugin_uri' => 'PLUGIN SITE HERE', + 'plugin_slug' => $plugin_slug, + 'plugin_name' => $plugin_name, + 'plugin_package' => $plugin_package, + 'plugin_description' => 'PLUGIN DESCRIPTION HERE', + 'plugin_author' => 'YOUR NAME HERE', + 'plugin_author_uri' => 'YOUR SITE HERE', + 'plugin_uri' => 'PLUGIN SITE HERE', + 'plugin_tested_up_to' => get_bloginfo('version'), ) ); $data['textdomain'] = $plugin_slug; diff --git a/templates/plugin-readme.mustache b/templates/plugin-readme.mustache index 44c117a686..6d69534794 100644 --- a/templates/plugin-readme.mustache +++ b/templates/plugin-readme.mustache @@ -2,9 +2,9 @@ Contributors: (this should be a list of wordpress.org userid's) Donate link: http://example.com/ Tags: comments, spam -Requires at least: 3.0.1 -Tested up to: 3.4 -Stable tag: 4.3 +Requires at least: 3.7 +Tested up to: {{plugin_tested_up_to}} +Stable tag: 0.1.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html From b2545163c01931ac4e0dec652c66f34d0fb23a75 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Sun, 15 May 2016 20:57:46 +0300 Subject: [PATCH 4293/4858] Code structure improved --- php/commands/search-replace.php | 68 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7df844116f..64de7aafbd 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -334,45 +334,47 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { private function write_sql_row_fields( $table, $rows ) { global $wpdb; - if(!empty($rows)) { - $insert = "INSERT INTO `$table` ("; - $insert .= join( ', ', array_map( - function ( $field ) { - return "`$field`"; - }, - array_keys( $rows[0] ) - ) ); - $insert .= ') VALUES '; - $insert .= "\n"; - - $sql = $insert; - $values = array(); - - $index = 1; - $count = count( $rows ); - $export_chunk_size = 50; // Amount of rows in one insert query - - foreach($rows as $row_fields) { - $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; - $values = array_merge( $values, array_values( $row_fields ) ); - - if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { - $sql .= ";\n"; - - if( $count > $index ) { - $sql .= $insert; - } - } else { - $sql .= ",\n"; + if(empty($rows)) { + return; + } + + $insert = "INSERT INTO `$table` ("; + $insert .= join( ', ', array_map( + function ( $field ) { + return "`$field`"; + }, + array_keys( $rows[0] ) + ) ); + $insert .= ') VALUES '; + $insert .= "\n"; + + $sql = $insert; + $values = array(); + $index = 1; + $count = count( $rows ); + $export_chunk_size = 50; // Amount of rows in one insert query + + foreach($rows as $row_fields) { + $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; + $values = array_merge( $values, array_values( $row_fields ) ); + + if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { + $sql .= ";\n"; + + if( $count > $index ) { + $sql .= $insert; } + } else { + $sql .= ",\n"; - $index++; } - $sql = $wpdb->prepare( $sql, array_values( $values ) ); - fwrite( $this->export_handle, $sql ); + $index++; } + + $sql = $wpdb->prepare( $sql, array_values( $values ) ); + fwrite( $this->export_handle, $sql ); } private static function get_columns( $table ) { From 7721029e16ba515d7613841a9b6b6f1dd318a5be Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 16 May 2016 04:22:07 -0700 Subject: [PATCH 4294/4858] Conditionally require `WP_HTTP_Requests_Response` for WP 4.6 compat --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 975c59f599..ba5c9243ea 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -208,6 +208,7 @@ Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-cookie.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-encoding.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-response.php' ); +Utils\maybe_require( '4.6-alpha-37438', ABSPATH . WPINC . '/class-wp-http-requests-response.php' ); require( ABSPATH . WPINC . '/widgets.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-widget.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-widget-factory.php' ); From 4834764c453f74e74ffaa98df4399ded7e1cfef7 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 14:48:40 +0300 Subject: [PATCH 4295/4858] Updated tests --- features/search-replace-export.feature | 38 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index 630c733095..d5ff992c9e 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -11,11 +11,16 @@ Feature: Search / replace with file export """ And STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + ('1', 'siteurl', 'http://example.net', 'yes'), + """ + And STDOUT should contain: + """ + ('51', 'blog_public', '1', 'yes'), """ And STDOUT should contain: """ - ('1', 'siteurl', 'http://example.net', 'yes') + ('50', 'upload_path', '', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES """ When I run `wp option get home` @@ -27,12 +32,16 @@ Feature: Search / replace with file export When I run `wp search-replace example.com example.net --skip-columns=option_value --export` Then STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + ('1', 'siteurl', 'http://example.com', 'yes'), + ('2', 'home', 'http://example.com', 'yes'), + """ + Then STDOUT should contain: + """ + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + ('51', 'blog_public', '1', 'yes'), + ('52', 'default_link_category', '2', 'yes'), """ - And STDOUT should contain: - """ - ('1', 'siteurl', 'http://example.com', 'yes') - """ When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: @@ -52,16 +61,17 @@ Feature: Search / replace with file export Scenario: Search / replace export to file Given a WP install - And I run `wp post generate --count=30` + And I run `wp post generate --count=100` + And I run `wp option add example_url http://example.com` When I run `wp search-replace example.com example.net --export=wordpress.sql` Then STDOUT should contain: """ - Success: Made 39 replacements and exported to wordpress.sql + Success: Made 110 replacements and exported to wordpress.sql """ And STDOUT should be a table containing rows: | Table | Column | Replacements | Type | - | wp_options | option_value | 5 | PHP | + | wp_options | option_value | 6 | PHP | When I run `wp option get home` Then STDOUT should be: @@ -85,10 +95,16 @@ Feature: Search / replace with file export http://example.net """ + When I run `wp option get example_url` + Then STDOUT should be: + """ + http://example.net + """ + When I run `wp post list --format=count` Then STDOUT should be: """ - 31 + 101 """ Scenario: Search / replace export to file with verbosity From da1d31bd0ec51ba79012b10943eedd9c4902c9ea Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 15:29:43 +0300 Subject: [PATCH 4296/4858] Improved performance --- php/commands/search-replace.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 64de7aafbd..9af81577e3 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -361,9 +361,13 @@ function ( $field ) { if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { $sql .= ";\n"; - + + $sql = $wpdb->prepare( $sql, array_values( $values ) ); + fwrite( $this->export_handle, $sql ); + if( $count > $index ) { - $sql .= $insert; + $sql = $insert; + $values = array(); } } else { $sql .= ",\n"; @@ -372,9 +376,6 @@ function ( $field ) { $index++; } - - $sql = $wpdb->prepare( $sql, array_values( $values ) ); - fwrite( $this->export_handle, $sql ); } private static function get_columns( $table ) { From 45f308bd664526988f97e0a09280d5d74f5e24bb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 16 May 2016 11:19:32 -0700 Subject: [PATCH 4297/4858] Use `--ssh=<host>[:<path>]` to run commands on remote servers --- php/WP_CLI/Runner.php | 43 +++++++++++++++++++++++++++++++++++++++++++ php/config-spec.php | 6 ++++++ 2 files changed, 49 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8d13f2690c..0b19a3fc81 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -333,6 +333,44 @@ private function _run_command() { $this->run_command( $this->arguments, $this->assoc_args ); } + /** + * Perform a command against a remote server over SSH + */ + private function run_ssh_command( $ssh ) { + + $host = $ssh; + $path = ''; + if ( false !== ( $key = stripos( $host, ':' ) ) ) { + $path = substr( $host, $key + 1 ); + $host = substr( $host, 0, $key ); + } + + WP_CLI::debug( 'SSH host: ' . $host, 'bootstrap' ); + WP_CLI::debug( 'SSH path: ' . $path, 'bootstrap' ); + + $is_tty = function_exists( 'posix_isatty' ) && posix_isatty( STDOUT ); + + $wp_binary = 'wp'; + $wp_args = array_slice( $GLOBALS['argv'], 1 ); + $wp_path = $path ? sprintf( '--path=%s', $path ) : ''; + foreach( $wp_args as $k => $v ) { + if ( preg_match( '#--ssh=#', $v ) ) { + unset( $wp_args[ $k ] ); + } + } + $command = sprintf( + 'ssh -q %s %s %s', + escapeshellarg( $host ), + $is_tty ? '-t' : '-T', + escapeshellarg( $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', $wp_args ) ) + ); + + passthru( $command, $exit_code ); + if ( 0 !== $exit_code ) { + exit( $exit_code ); + } + } + /** * Check whether a given command is disabled by the config * @@ -668,6 +706,11 @@ public function start() { } } + if ( $this->config['ssh'] ) { + $this->run_ssh_command( $this->config['ssh'] ); + return; + } + // Show synopsis if it's a composite command. $r = $this->find_command_to_run( $this->arguments ); if ( is_array( $r ) ) { diff --git a/php/config-spec.php b/php/config-spec.php index 84221c0f04..b38f595849 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -7,6 +7,12 @@ 'desc' => 'Path to the WordPress files.', ), + 'ssh' => array( + 'runtime' => '=<ssh>', + 'file' => '<ssh>', + 'desc' => 'Perform operation against a remote server over SSH.', + ), + 'url' => array( 'runtime' => '=<url>', 'file' => '<url>', From d607efec83bf266808ccaf8473b80996e1f7760a Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 22:30:00 +0300 Subject: [PATCH 4298/4858] Flag to define number of rows in one INSERT query --- features/search-replace-export.feature | 14 ++++++++++++++ php/commands/search-replace.php | 18 ++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index d5ff992c9e..da829ac899 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -43,6 +43,20 @@ Feature: Search / replace with file export ('52', 'default_link_category', '2', 'yes'), """ + When I run `wp search-replace example.com example.net --skip-columns=option_value --export --export_insert_size=5` + Then STDOUT should contain: + """ + ('5', 'users_can_register', '0', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + """ + + When I run `wp search-replace example.com example.net --export --export_insert_size=text` + Then STDOUT should contain: + """ + ('50', 'upload_path', '', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + """ + When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: """ diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 9af81577e3..8c12594f5c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -9,6 +9,7 @@ class Search_Replace_Command extends WP_CLI_Command { private $dry_run; private $export_handle = false; + private $export_insert_size; private $recurse_objects; private $regex; private $skip_columns; @@ -61,6 +62,9 @@ class Search_Replace_Command extends WP_CLI_Command { * : Write transformed data as SQL file instead of saving replacements to * the database. If <file> is not supplied, will output to STDOUT. * + * [--export_insert_size[=<rows>]] + * : Define number of rows in single INSERT statement when doing SQL export. + * * [--skip-columns=<columns>] * : Do not perform the replacement on specific columns. Use commas to * specify multiple columns. 'guid' is skipped by default. @@ -124,6 +128,12 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( sprintf( 'Unable to open "%s" for writing.', $assoc_args['export'] ) ); } } + $export_insert_size = \WP_CLI\Utils\get_flag_value( $assoc_args, 'export_insert_size' ); + if ( (int) $export_insert_size == $export_insert_size && $export_insert_size > 0 ) { + $this->export_insert_size = $export_insert_size; + } else { + $this->export_insert_size = 50; + } $php_only = true; } @@ -353,18 +363,18 @@ function ( $field ) { $index = 1; $count = count( $rows ); - $export_chunk_size = 50; // Amount of rows in one insert query + $export_insert_size = $this->export_insert_size; foreach($rows as $row_fields) { $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; $values = array_merge( $values, array_values( $row_fields ) ); - if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { + if( ( $index % $export_insert_size == 0 && $index > 0 ) || $index == $count ) { $sql .= ";\n"; - + $sql = $wpdb->prepare( $sql, array_values( $values ) ); fwrite( $this->export_handle, $sql ); - + if( $count > $index ) { $sql = $insert; $values = array(); From 2889fd337a6339661df7694562efd4f25510c4f7 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 22:34:56 +0300 Subject: [PATCH 4299/4858] Fixed tests for WP 3.7 Testing option rows was too specific. Insert statement creation is practically tested later by checking data inserted to database with that query. --- features/search-replace-export.feature | 9 --------- 1 file changed, 9 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index da829ac899..96c34cbb74 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -13,15 +13,6 @@ Feature: Search / replace with file export """ ('1', 'siteurl', 'http://example.net', 'yes'), """ - And STDOUT should contain: - """ - ('51', 'blog_public', '1', 'yes'), - """ - And STDOUT should contain: - """ - ('50', 'upload_path', '', 'yes'); - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES - """ When I run `wp option get home` Then STDOUT should be: From c0ab1d83fb1c7a52687996d5c32fe7f3618a2216 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 16 May 2016 15:16:07 -0700 Subject: [PATCH 4300/4858] Rename to `.distignore` to imply use for generic distibution --- features/scaffold.feature | 2 +- php/commands/scaffold.php | 2 +- .../{plugin-svnignore.mustache => plugin-distignore.mustache} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename templates/{plugin-svnignore.mustache => plugin-distignore.mustache} (95%) diff --git a/features/scaffold.feature b/features/scaffold.feature index cc79744ae7..9b52d6cd65 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -125,7 +125,7 @@ Feature: WordPress code scaffolding .DS_Store node_modules/ """ - And the {PLUGIN_DIR}/hello-world/.svnignore file should contain: + And the {PLUGIN_DIR}/hello-world/.distignore file should contain: """ .git .gitignore diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 11bf1b9107..7f29542a6d 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -447,7 +447,7 @@ function plugin( $args, $assoc_args ) { "$plugin_dir/package.json" => Utils\mustache_render( 'plugin-packages.mustache', $data ), "$plugin_dir/Gruntfile.js" => Utils\mustache_render( 'plugin-gruntfile.mustache', $data ), "$plugin_dir/.gitignore" => Utils\mustache_render( 'plugin-gitignore.mustache', $data ), - "$plugin_dir/.svnignore" => Utils\mustache_render( 'plugin-svnignore.mustache', $data ), + "$plugin_dir/.distignore" => Utils\mustache_render( 'plugin-distignore.mustache', $data ), "$plugin_dir/.editorconfig" => file_get_contents( WP_CLI_ROOT . "/templates/.editorconfig" ), ), $force ); diff --git a/templates/plugin-svnignore.mustache b/templates/plugin-distignore.mustache similarity index 95% rename from templates/plugin-svnignore.mustache rename to templates/plugin-distignore.mustache index 7c2581b323..6a8b3da106 100644 --- a/templates/plugin-svnignore.mustache +++ b/templates/plugin-distignore.mustache @@ -1,5 +1,5 @@ # A set of files you probably don't want in your WordPress.org distribution -.svnignore +.distignore .editorconfig .git .gitignore From f7d80a97b290430bbe67031df730f798bbc3b047 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Fri, 13 May 2016 16:11:15 +0300 Subject: [PATCH 4301/4858] Extended insert format to search-replace SQL export --- php/commands/search-replace.php | 45 ++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7ab5f51730..0853258de4 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -228,6 +228,8 @@ private function php_export_table( $table, $old, $new ) { $this->start_time = microtime( true ); WP_CLI::log( sprintf( 'Checking: %s', $table ) ); } + + $rows = array(); foreach ( new \WP_CLI\Iterators\Table( $args ) as $i => $row ) { $row_fields = array(); foreach( $all_columns as $col ) { @@ -241,8 +243,9 @@ private function php_export_table( $table, $old, $new ) { } $row_fields[ $col ] = $value; } - $this->write_sql_row_fields( $table, $row_fields ); + $rows[] = $row_fields; } + $this->write_sql_row_fields( $table, $rows ); $table_report = array(); $total_rows = $total_cols = 0; @@ -328,20 +331,33 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { return $count; } - private function write_sql_row_fields( $table, $row_fields ) { + private function write_sql_row_fields( $table, $rows ) { global $wpdb; - $sql = "INSERT INTO `$table` ("; - $sql .= join( ', ', array_map( - function ( $field ) { - return "`$field`"; - }, - array_keys( $row_fields ) - ) ); - $sql .= ') VALUES ('; - $sql .= join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ); - $sql .= ");\n"; - $sql = $wpdb->prepare( $sql, array_values( $row_fields ) ); - fwrite( $this->export_handle, $sql ); + + if(!empty($rows)) { + $sql = "INSERT INTO `$table` ("; + $sql .= join( ', ', array_map( + function ( $field ) { + return "`$field`"; + }, + array_keys( $rows[0] ) + ) ); + $sql .= ') VALUES '; + $sql .= "\n"; + + $values = array(); + $count = count( $rows ); // No comma to last row + foreach($rows as $row_fields) { + $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')' . ($count-- > 1 ? ',' : ''); + $sql .= "\n"; + $values = array_merge( $values, array_values( $row_fields ) ); + } + + $sql .= ";\n"; + + $sql = $wpdb->prepare( $sql, array_values( $values ) ); + fwrite( $this->export_handle, $sql ); + } } private static function get_columns( $table ) { @@ -387,4 +403,3 @@ private static function esc_like( $old ) { } WP_CLI::add_command( 'search-replace', 'Search_Replace_Command' ); - From adf71bd4b059fc59ec0034af20474c75df7a5e58 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Fri, 13 May 2016 17:03:35 +0300 Subject: [PATCH 4302/4858] Updated search-replace-export feature test --- features/search-replace-export.feature | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index e50bde0cc0..630c733095 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -11,7 +11,11 @@ Feature: Search / replace with file export """ And STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.net', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + """ + And STDOUT should contain: + """ + ('1', 'siteurl', 'http://example.net', 'yes') """ When I run `wp option get home` @@ -23,8 +27,12 @@ Feature: Search / replace with file export When I run `wp search-replace example.com example.net --skip-columns=option_value --export` Then STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.com', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES """ + And STDOUT should contain: + """ + ('1', 'siteurl', 'http://example.com', 'yes') + """ When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: From 6ca1e274be82247185d100263874d2255156b35f Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Fri, 13 May 2016 17:28:44 +0300 Subject: [PATCH 4303/4858] Split insert queries into separate chunks --- php/commands/search-replace.php | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 0853258de4..7df844116f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -335,25 +335,40 @@ private function write_sql_row_fields( $table, $rows ) { global $wpdb; if(!empty($rows)) { - $sql = "INSERT INTO `$table` ("; - $sql .= join( ', ', array_map( + $insert = "INSERT INTO `$table` ("; + $insert .= join( ', ', array_map( function ( $field ) { return "`$field`"; }, array_keys( $rows[0] ) ) ); - $sql .= ') VALUES '; - $sql .= "\n"; + $insert .= ') VALUES '; + $insert .= "\n"; + $sql = $insert; $values = array(); - $count = count( $rows ); // No comma to last row + + $index = 1; + $count = count( $rows ); + $export_chunk_size = 50; // Amount of rows in one insert query + foreach($rows as $row_fields) { - $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')' . ($count-- > 1 ? ',' : ''); - $sql .= "\n"; + $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; $values = array_merge( $values, array_values( $row_fields ) ); - } - $sql .= ";\n"; + if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { + $sql .= ";\n"; + + if( $count > $index ) { + $sql .= $insert; + } + } else { + $sql .= ",\n"; + + } + + $index++; + } $sql = $wpdb->prepare( $sql, array_values( $values ) ); fwrite( $this->export_handle, $sql ); From fd7b24a5d4c22e5f84bc2e1f516c5b1b67b11710 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sat, 14 May 2016 20:49:31 +0900 Subject: [PATCH 4304/4858] fix #2711 --- features/post.feature | 8 +++++++- php/WP_CLI/Formatter.php | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/features/post.feature b/features/post.feature index d9e5e07933..b503ccee37 100644 --- a/features/post.feature +++ b/features/post.feature @@ -100,7 +100,7 @@ Feature: Manage WordPress posts """ This is some bunkum. """ - + When I run `wp post url 1 {POST_ID}` Then STDOUT should be: """ @@ -176,6 +176,12 @@ Feature: Manage WordPress posts | Publish post | publish-post | publish | | Draft post | | draft | + When I run `wp post list --post_type='post' --fields="title, name, status" --format=csv` + Then STDOUT should be CSV containing: + | post_title | post_name | post_status | + | Publish post | publish-post | publish | + | Draft post | | draft | + When I run `wp post list --post__in={POST_ID} --format=count` Then STDOUT should be: """ diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 87f81c8bb5..0b04ec5e81 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -40,6 +40,8 @@ public function __construct( &$assoc_args, $fields = null, $prefix = false ) { $format_args['fields'] = explode( ',', $format_args['fields'] ); } + $format_args['fields'] = array_map( 'trim', $format_args['fields'] ); + $this->args = $format_args; $this->prefix = $prefix; } From 2bbf4970a31330344d69628bb226036d6a1aa5a2 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Sun, 15 May 2016 05:20:07 +0900 Subject: [PATCH 4305/4858] get wp version when scaffolding plugin --- features/scaffold.feature | 16 ++++++++++++++-- php/commands/scaffold.php | 15 ++++++++------- templates/plugin-readme.mustache | 6 +++--- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 7c98f9cfe5..cc79744ae7 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -109,6 +109,8 @@ Feature: WordPress code scaffolding Given a WP install Given I run `wp plugin path` And save STDOUT as {PLUGIN_DIR} + Given I run `wp core version` + And save STDOUT as {WP_VERSION} When I run `wp scaffold plugin hello-world --plugin_author="Hello World Author"` Then STDOUT should not be empty @@ -140,6 +142,14 @@ Feature: WordPress code scaffolding """ * @package Hello_World """ + And the {PLUGIN_DIR}/hello-world/readme.txt file should contain: + """ + Stable tag: 0.1.0 + """ + And the {PLUGIN_DIR}/hello-world/readme.txt file should contain: + """ + Tested up to: {WP_VERSION} + """ When I run `cat {PLUGIN_DIR}/hello-world/package.json` Then STDOUT should be JSON containing: @@ -332,6 +342,8 @@ Feature: WordPress code scaffolding Scenario: Scaffold tests parses plugin readme.txt Given a WP install + When I run `wp core version` + Then save STDOUT as {WP_VERSION} When I run `wp plugin path` Then save STDOUT as {PLUGIN_DIR} @@ -343,8 +355,8 @@ Feature: WordPress code scaffolding """ env: - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=3.0.1 WP_MULTISITE=0 - - WP_VERSION=3.4 WP_MULTISITE=0 + - WP_VERSION=3.7 WP_MULTISITE=0 + - WP_VERSION={WP_VERSION} WP_MULTISITE=0 """ Scenario: Scaffold starter code for a theme and network enable it diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ca566becc0..11bf1b9107 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -415,13 +415,14 @@ function plugin( $args, $assoc_args ) { $plugin_package = str_replace( ' ', '_', $plugin_name ); $data = wp_parse_args( $assoc_args, array( - 'plugin_slug' => $plugin_slug, - 'plugin_name' => $plugin_name, - 'plugin_package' => $plugin_package, - 'plugin_description' => 'PLUGIN DESCRIPTION HERE', - 'plugin_author' => 'YOUR NAME HERE', - 'plugin_author_uri' => 'YOUR SITE HERE', - 'plugin_uri' => 'PLUGIN SITE HERE', + 'plugin_slug' => $plugin_slug, + 'plugin_name' => $plugin_name, + 'plugin_package' => $plugin_package, + 'plugin_description' => 'PLUGIN DESCRIPTION HERE', + 'plugin_author' => 'YOUR NAME HERE', + 'plugin_author_uri' => 'YOUR SITE HERE', + 'plugin_uri' => 'PLUGIN SITE HERE', + 'plugin_tested_up_to' => get_bloginfo('version'), ) ); $data['textdomain'] = $plugin_slug; diff --git a/templates/plugin-readme.mustache b/templates/plugin-readme.mustache index 44c117a686..6d69534794 100644 --- a/templates/plugin-readme.mustache +++ b/templates/plugin-readme.mustache @@ -2,9 +2,9 @@ Contributors: (this should be a list of wordpress.org userid's) Donate link: http://example.com/ Tags: comments, spam -Requires at least: 3.0.1 -Tested up to: 3.4 -Stable tag: 4.3 +Requires at least: 3.7 +Tested up to: {{plugin_tested_up_to}} +Stable tag: 0.1.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html From 76ea245e146d3323c4f535522d146f2a054b7709 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Sun, 15 May 2016 20:57:46 +0300 Subject: [PATCH 4306/4858] Code structure improved --- php/commands/search-replace.php | 68 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7df844116f..64de7aafbd 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -334,45 +334,47 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { private function write_sql_row_fields( $table, $rows ) { global $wpdb; - if(!empty($rows)) { - $insert = "INSERT INTO `$table` ("; - $insert .= join( ', ', array_map( - function ( $field ) { - return "`$field`"; - }, - array_keys( $rows[0] ) - ) ); - $insert .= ') VALUES '; - $insert .= "\n"; - - $sql = $insert; - $values = array(); - - $index = 1; - $count = count( $rows ); - $export_chunk_size = 50; // Amount of rows in one insert query - - foreach($rows as $row_fields) { - $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; - $values = array_merge( $values, array_values( $row_fields ) ); - - if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { - $sql .= ";\n"; - - if( $count > $index ) { - $sql .= $insert; - } - } else { - $sql .= ",\n"; + if(empty($rows)) { + return; + } + + $insert = "INSERT INTO `$table` ("; + $insert .= join( ', ', array_map( + function ( $field ) { + return "`$field`"; + }, + array_keys( $rows[0] ) + ) ); + $insert .= ') VALUES '; + $insert .= "\n"; + + $sql = $insert; + $values = array(); + $index = 1; + $count = count( $rows ); + $export_chunk_size = 50; // Amount of rows in one insert query + + foreach($rows as $row_fields) { + $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; + $values = array_merge( $values, array_values( $row_fields ) ); + + if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { + $sql .= ";\n"; + + if( $count > $index ) { + $sql .= $insert; } + } else { + $sql .= ",\n"; - $index++; } - $sql = $wpdb->prepare( $sql, array_values( $values ) ); - fwrite( $this->export_handle, $sql ); + $index++; } + + $sql = $wpdb->prepare( $sql, array_values( $values ) ); + fwrite( $this->export_handle, $sql ); } private static function get_columns( $table ) { From a503bbddd18dfa5ec2e20e82f7f80c43bf4bd265 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 16 May 2016 04:22:07 -0700 Subject: [PATCH 4307/4858] Conditionally require `WP_HTTP_Requests_Response` for WP 4.6 compat --- php/wp-settings-cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 975c59f599..ba5c9243ea 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -208,6 +208,7 @@ Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-cookie.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-encoding.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-http-response.php' ); +Utils\maybe_require( '4.6-alpha-37438', ABSPATH . WPINC . '/class-wp-http-requests-response.php' ); require( ABSPATH . WPINC . '/widgets.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-widget.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-widget-factory.php' ); From f005f6152247be1a2acfda85efe0c503be99807a Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 14:48:40 +0300 Subject: [PATCH 4308/4858] Updated tests --- features/search-replace-export.feature | 38 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index 630c733095..d5ff992c9e 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -11,11 +11,16 @@ Feature: Search / replace with file export """ And STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + ('1', 'siteurl', 'http://example.net', 'yes'), + """ + And STDOUT should contain: + """ + ('51', 'blog_public', '1', 'yes'), """ And STDOUT should contain: """ - ('1', 'siteurl', 'http://example.net', 'yes') + ('50', 'upload_path', '', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES """ When I run `wp option get home` @@ -27,12 +32,16 @@ Feature: Search / replace with file export When I run `wp search-replace example.com example.net --skip-columns=option_value --export` Then STDOUT should contain: """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + ('1', 'siteurl', 'http://example.com', 'yes'), + ('2', 'home', 'http://example.com', 'yes'), + """ + Then STDOUT should contain: + """ + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + ('51', 'blog_public', '1', 'yes'), + ('52', 'default_link_category', '2', 'yes'), """ - And STDOUT should contain: - """ - ('1', 'siteurl', 'http://example.com', 'yes') - """ When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: @@ -52,16 +61,17 @@ Feature: Search / replace with file export Scenario: Search / replace export to file Given a WP install - And I run `wp post generate --count=30` + And I run `wp post generate --count=100` + And I run `wp option add example_url http://example.com` When I run `wp search-replace example.com example.net --export=wordpress.sql` Then STDOUT should contain: """ - Success: Made 39 replacements and exported to wordpress.sql + Success: Made 110 replacements and exported to wordpress.sql """ And STDOUT should be a table containing rows: | Table | Column | Replacements | Type | - | wp_options | option_value | 5 | PHP | + | wp_options | option_value | 6 | PHP | When I run `wp option get home` Then STDOUT should be: @@ -85,10 +95,16 @@ Feature: Search / replace with file export http://example.net """ + When I run `wp option get example_url` + Then STDOUT should be: + """ + http://example.net + """ + When I run `wp post list --format=count` Then STDOUT should be: """ - 31 + 101 """ Scenario: Search / replace export to file with verbosity From e7ae1b6325129f4ef1fca2c03add0bc2091e2c35 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 15:29:43 +0300 Subject: [PATCH 4309/4858] Improved performance --- php/commands/search-replace.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 64de7aafbd..9af81577e3 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -361,9 +361,13 @@ function ( $field ) { if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { $sql .= ";\n"; - + + $sql = $wpdb->prepare( $sql, array_values( $values ) ); + fwrite( $this->export_handle, $sql ); + if( $count > $index ) { - $sql .= $insert; + $sql = $insert; + $values = array(); } } else { $sql .= ",\n"; @@ -372,9 +376,6 @@ function ( $field ) { $index++; } - - $sql = $wpdb->prepare( $sql, array_values( $values ) ); - fwrite( $this->export_handle, $sql ); } private static function get_columns( $table ) { From f38fbc0da53a0b1f12b63b42aec2b258e967b78e Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 22:30:00 +0300 Subject: [PATCH 4310/4858] Flag to define number of rows in one INSERT query --- features/search-replace-export.feature | 14 ++++++++++++++ php/commands/search-replace.php | 18 ++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index d5ff992c9e..da829ac899 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -43,6 +43,20 @@ Feature: Search / replace with file export ('52', 'default_link_category', '2', 'yes'), """ + When I run `wp search-replace example.com example.net --skip-columns=option_value --export --export_insert_size=5` + Then STDOUT should contain: + """ + ('5', 'users_can_register', '0', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + """ + + When I run `wp search-replace example.com example.net --export --export_insert_size=text` + Then STDOUT should contain: + """ + ('50', 'upload_path', '', 'yes'); + INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES + """ + When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: """ diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 9af81577e3..8c12594f5c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -9,6 +9,7 @@ class Search_Replace_Command extends WP_CLI_Command { private $dry_run; private $export_handle = false; + private $export_insert_size; private $recurse_objects; private $regex; private $skip_columns; @@ -61,6 +62,9 @@ class Search_Replace_Command extends WP_CLI_Command { * : Write transformed data as SQL file instead of saving replacements to * the database. If <file> is not supplied, will output to STDOUT. * + * [--export_insert_size[=<rows>]] + * : Define number of rows in single INSERT statement when doing SQL export. + * * [--skip-columns=<columns>] * : Do not perform the replacement on specific columns. Use commas to * specify multiple columns. 'guid' is skipped by default. @@ -124,6 +128,12 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( sprintf( 'Unable to open "%s" for writing.', $assoc_args['export'] ) ); } } + $export_insert_size = \WP_CLI\Utils\get_flag_value( $assoc_args, 'export_insert_size' ); + if ( (int) $export_insert_size == $export_insert_size && $export_insert_size > 0 ) { + $this->export_insert_size = $export_insert_size; + } else { + $this->export_insert_size = 50; + } $php_only = true; } @@ -353,18 +363,18 @@ function ( $field ) { $index = 1; $count = count( $rows ); - $export_chunk_size = 50; // Amount of rows in one insert query + $export_insert_size = $this->export_insert_size; foreach($rows as $row_fields) { $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; $values = array_merge( $values, array_values( $row_fields ) ); - if( ( $index % $export_chunk_size == 0 && $index > 0 ) || $index == $count ) { + if( ( $index % $export_insert_size == 0 && $index > 0 ) || $index == $count ) { $sql .= ";\n"; - + $sql = $wpdb->prepare( $sql, array_values( $values ) ); fwrite( $this->export_handle, $sql ); - + if( $count > $index ) { $sql = $insert; $values = array(); From b438b95d5562d7163d4b1038e535c5c9b80a29f8 Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Mon, 16 May 2016 22:34:56 +0300 Subject: [PATCH 4311/4858] Fixed tests for WP 3.7 Testing option rows was too specific. Insert statement creation is practically tested later by checking data inserted to database with that query. --- features/search-replace-export.feature | 9 --------- 1 file changed, 9 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index da829ac899..96c34cbb74 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -13,15 +13,6 @@ Feature: Search / replace with file export """ ('1', 'siteurl', 'http://example.net', 'yes'), """ - And STDOUT should contain: - """ - ('51', 'blog_public', '1', 'yes'), - """ - And STDOUT should contain: - """ - ('50', 'upload_path', '', 'yes'); - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES - """ When I run `wp option get home` Then STDOUT should be: From 2458a57d0ef8b29c32f09c4207ec33379e9e4a5b Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Tue, 17 May 2016 10:32:10 +0300 Subject: [PATCH 4312/4858] Fixed search replace export bug --- features/search-replace-export.feature | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/features/search-replace-export.feature b/features/search-replace-export.feature index 96c34cbb74..3730a98b1d 100644 --- a/features/search-replace-export.feature +++ b/features/search-replace-export.feature @@ -25,29 +25,15 @@ Feature: Search / replace with file export """ INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES ('1', 'siteurl', 'http://example.com', 'yes'), - ('2', 'home', 'http://example.com', 'yes'), - """ - Then STDOUT should contain: - """ - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES - ('51', 'blog_public', '1', 'yes'), - ('52', 'default_link_category', '2', 'yes'), """ - When I run `wp search-replace example.com example.net --skip-columns=option_value --export --export_insert_size=5` - Then STDOUT should contain: - """ - ('5', 'users_can_register', '0', 'yes'); - INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES - """ - - When I run `wp search-replace example.com example.net --export --export_insert_size=text` + When I run `wp search-replace example.com example.net --skip-columns=option_value --export --export_insert_size=1` Then STDOUT should contain: """ - ('50', 'upload_path', '', 'yes'); + ('1', 'siteurl', 'http://example.com', 'yes'); INSERT INTO `wp_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES """ - + When I run `wp search-replace foo bar --export | tail -n 1` Then STDOUT should not contain: """ From b788e52a384150b4cbd5c8ae0a8d28ba37f84e6b Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Wed, 18 May 2016 09:22:58 +0300 Subject: [PATCH 4313/4858] Better option handling --- php/commands/search-replace.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 8c12594f5c..b6f285a1c0 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -62,8 +62,10 @@ class Search_Replace_Command extends WP_CLI_Command { * : Write transformed data as SQL file instead of saving replacements to * the database. If <file> is not supplied, will output to STDOUT. * - * [--export_insert_size[=<rows>]] + * [--export_insert_size=<rows>] * : Define number of rows in single INSERT statement when doing SQL export. + * You might want to change this depending on your database configuration + * (e.g. if you need to do fewer queries). Default: 50 * * [--skip-columns=<columns>] * : Do not perform the replacement on specific columns. Use commas to @@ -128,7 +130,7 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( sprintf( 'Unable to open "%s" for writing.', $assoc_args['export'] ) ); } } - $export_insert_size = \WP_CLI\Utils\get_flag_value( $assoc_args, 'export_insert_size' ); + $export_insert_size = $assoc_args['export_insert_size']; if ( (int) $export_insert_size == $export_insert_size && $export_insert_size > 0 ) { $this->export_insert_size = $export_insert_size; } else { From e6c5aed5ca0519d3c55a66227322b0f6b55248de Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 18 May 2016 04:51:53 -0700 Subject: [PATCH 4314/4858] Remove `--config=<config>` as a runtime argument It's been broken since 7a1499e0a3683f9d51dc18d73d8b087685a9e318 (v0.13.0) --- php/WP_CLI/Runner.php | 5 +---- php/config-spec.php | 5 ----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8d13f2690c..e8b1561c18 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -68,10 +68,7 @@ private function do_early_invoke( $when ) { */ private function get_global_config_path() { - if ( isset( $runtime_config['config'] ) ) { - $config_path = $runtime_config['config']; - $this->_global_config_path_debug = 'Using global config from config runtime arg: ' . $config_path; - } else if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) { + if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) { $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); $this->_global_config_path_debug = 'Using global config from WP_CLI_CONFIG_PATH env var: ' . $config_path; } else { diff --git a/php/config-spec.php b/php/config-spec.php index 84221c0f04..ff6fa851b5 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -17,11 +17,6 @@ 'runtime' => '=<url>', ), - 'config' => array( - 'deprecated' => 'Use the WP_CLI_CONFIG_PATH environment variable instead.', - 'runtime' => '=<path>', - ), - 'user' => array( 'runtime' => '=<id|login|email>', 'file' => '<id|login|email>', From b580bbaa7610038a47cc7b2110611b76ab737f31 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 18 May 2016 05:31:18 -0700 Subject: [PATCH 4315/4858] Introduce `WP_CLI_SSH_PRE_CMD` for users to set up env as needed ``` WP_CLI::add_hook( 'before_ssh', function() { if ( $ssh = WP_CLI::get_runner()->config['ssh'] ) { list( $host, $path ) = explode( ':', $ssh ); switch( $host ) { case 'hb': putenv( 'WP_CLI_SSH_PRE_CMD=export PATH=$HOME/bin:$PATH' ); break; } } }); ``` --- php/WP_CLI/Runner.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 0b19a3fc81..be27d56614 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -345,14 +345,20 @@ private function run_ssh_command( $ssh ) { $host = substr( $host, 0, $key ); } + WP_CLI::do_hook( 'before_ssh' ); + WP_CLI::debug( 'SSH host: ' . $host, 'bootstrap' ); WP_CLI::debug( 'SSH path: ' . $path, 'bootstrap' ); $is_tty = function_exists( 'posix_isatty' ) && posix_isatty( STDOUT ); + $pre_cmd = getenv( 'WP_CLI_SSH_PRE_CMD' ); + if ( $pre_cmd ) { + $pre_cmd = rtrim( $pre_cmd, ';' ) . '; '; + } $wp_binary = 'wp'; $wp_args = array_slice( $GLOBALS['argv'], 1 ); - $wp_path = $path ? sprintf( '--path=%s', $path ) : ''; + $wp_path = $path ? sprintf( '--path=%s', str_replace( '~', '$HOME', $path ) ) : ''; foreach( $wp_args as $k => $v ) { if ( preg_match( '#--ssh=#', $v ) ) { unset( $wp_args[ $k ] ); @@ -362,9 +368,11 @@ private function run_ssh_command( $ssh ) { 'ssh -q %s %s %s', escapeshellarg( $host ), $is_tty ? '-t' : '-T', - escapeshellarg( $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', $wp_args ) ) + escapeshellarg( $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', $wp_args ) ) ); + WP_CLI::debug( 'Running SSH command: ' . $command, 'bootstrap' ); + passthru( $command, $exit_code ); if ( 0 !== $exit_code ) { exit( $exit_code ); From 7c25f31f790bd512c6f8005a06a991ff2f2fc894 Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Wed, 18 May 2016 15:14:56 +0100 Subject: [PATCH 4316/4858] wp-cli/wp-cli#2760 Update readme with new format and fresh content --- README.md | 103 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index daf127aa0d..9add684c7d 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,89 @@ -WP-CLI -====== +# WP-CLI + +Command-line tools for managing WordPress installations. [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) -WP-CLI is a set of command-line tools for managing WordPress installations. +[Documentation](http://wp-cli.org/) + +Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) + +## Using + +This project aims to provide command-line support for any action you can perform in the WordPress admin and many you can't. So you can [install a plugin](http://wp-cli.org/commands/plugin/install/): + +` +$ wp plugin install rest-api +` + +And [activate it](http://wp-cli.org/commands/plugin/activate/): + +` +$ wp plugin activate rest-api +` + +View the [Quick Start](http://wp-cli.org/docs/quick-start/) guide or jump to the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. + +## Installing + +The recommended way to install WP-CLI is to download the Phar build, mark it executable and place it in your PATH. + +Download the `[wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar)` using `wget` or `curl`. For example: + +`$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar` + +Check if it is working: + +`$ php wp-cli.phar --info` + +To use it from the command line by typing `wp`, make the file executable and move it to somewhere in your PATH. For example: + +` +$ chmod +x wp-cli.phar +$ sudo mv wp-cli.phar /usr/local/bin/wp +` -Installing ------------- -If you just want to use WP-CLI, see <http://wp-cli.org/#install>. +If WP-CLI installed successfully, you should see something like this when you run `wp --info`: -If you want to hack on WP-CLI, see [CONTRIBUTING.md](CONTRIBUTING.md). +` +$ wp --info +PHP binary: /usr/bin/php5 +PHP version: 5.5.9-1ubuntu4.14 +php.ini used: /etc/php5/cli/php.ini +WP-CLI root dir: /home/wp-cli/.wp-cli +WP-CLI packages dir: /home/wp-cli/.wp-cli/packages/ +WP-CLI global config: /home/wp-cli/.wp-cli/config.yml +WP-CLI project config: +WP-CLI version: 0.23.0 +` -Where can I get more info? --------------------------- -For documentation and examples, check out [wp-cli.org](http://wp-cli.org/) and the [documentation portal](http://wp-cli.org/docs/). +Now that you've got WP-CLI, read the [Quick Start](http://wp-cli.org/docs/quick-start/) guide. Or view the [full installation guide](http://wp-cli.org/docs/installing/) with alternative installation methods. -Also, WordPress Answers has a growing list of [WP-CLI related questions](http://wordpress.stackexchange.com/questions/tagged/wp-cli). +## Support -If you want to receive an email for every single commit, you can subscribe to the [wp-cli-commits](https://groups.google.com/forum/?fromgroups=#!forum/wp-cli-commits) mailing list. +WP-CLI is a volunteer-led project and can't support every user individually. If you run into trouble, here are some places to look for help: -I'm running into troubles, what can I do? ------------------------------------------ -To suggest a feature, report a bug, or general discussion, visit the [issues section](https://github.com/wp-cli/wp-cli/issues). +- [Common issues and their fixes](http://wp-cli.org/docs/common-issues/) +- [Bug reports](http://wp-cli.org/docs/bug-reports/) +- [External resources](http://wp-cli.org/docs/external-resources/) -If you're reporting a bug, please include the output from `wp --info` and do your best to follow [bug reporting best practices](http://wp-cli.org/docs/bug-reports/). +## Extending + +Creating a custom WP-CLI command can be easier than it looks. Read the [commands cookbook](http://wp-cli.org/docs/commands-cookbook/). + +## Contributing + +Thanks for helping to improve WP-CLI. Please read about [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). + +### Contributors +* [Andreas Creten](https://github.com/andreascreten) - founder +* [Cristi Burcă](https://github.com/scribu) - previous maintainer +* [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer + +Read more about the project's [Governance](http://wp-cli.org/docs/governance/) and view a [complete list of contributors](https://github.com/wp-cli/wp-cli/contributors). + +## Credits -Credits -------- Besides the libraries defined in [composer.json](composer.json), we have used code or ideas from the following projects: * [Drush](http://drush.ws/) for... a lot of things @@ -36,13 +93,3 @@ Besides the libraries defined in [composer.json](composer.json), we have used co * [WordPress-CLI-Exporter](https://github.com/Automattic/WordPress-CLI-Exporter) for `wp export` * [WordPress-CLI-Importer](https://github.com/Automattic/WordPress-CLI-Importer) for `wp import` * [wordpress-plugin-tests](https://github.com/benbalter/wordpress-plugin-tests/) for `wp scaffold plugin-tests` - -Who's behind this thing? ------------------------- -* [Andreas Creten](https://github.com/andreascreten) - founder -* [Cristi Burcă](https://github.com/scribu) - previous maintainer -* [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer - -For more info, see [Governance](http://wp-cli.org/docs/governance/). - -A complete list of contributors can be found [here](https://github.com/wp-cli/wp-cli/contributors). From 3a84c919afda48d0d3695db0bc647e3538f6839a Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Wed, 18 May 2016 15:18:41 +0100 Subject: [PATCH 4317/4858] wp-cli/wp-cli#2760 Mimic GitHub descriptions in docs link at the top of README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 9add684c7d..3f3bacd6df 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ # WP-CLI -Command-line tools for managing WordPress installations. +Command-line tools for managing WordPress installations. [http://wp-cli.org/](http://wp-cli.org/). [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) -[Documentation](http://wp-cli.org/) - Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) ## Using From 58ffdd38b9bb578a27d2047d60c8ee0fa9aa39b7 Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Wed, 18 May 2016 15:19:39 +0100 Subject: [PATCH 4318/4858] wp-cli/wp-cli#2760 Add credits to quick links in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f3bacd6df..3c16bc2838 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Command-line tools for managing WordPress installations. [http://wp-cli.org/](ht [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) -Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) +Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) | [Credits](#credits) ## Using From 6f2e2d32778035857433d64f691580989be8d03f Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Wed, 18 May 2016 15:21:05 +0100 Subject: [PATCH 4319/4858] wp-cli/wp-cli#2760 Links can't be in code --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c16bc2838..aed43a805d 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ View the [Quick Start](http://wp-cli.org/docs/quick-start/) guide or jump to the The recommended way to install WP-CLI is to download the Phar build, mark it executable and place it in your PATH. -Download the `[wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar)` using `wget` or `curl`. For example: +Download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) using `wget` or `curl`. For example: `$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar` From a266317f09e04fb606efdfba75fce12477186bc4 Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Wed, 18 May 2016 15:22:40 +0100 Subject: [PATCH 4320/4858] wp-cli/wp-cli#2760 Use triple ticks for code blocks --- README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index aed43a805d..b5395b045b 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,15 @@ Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | This project aims to provide command-line support for any action you can perform in the WordPress admin and many you can't. So you can [install a plugin](http://wp-cli.org/commands/plugin/install/): -` +``` $ wp plugin install rest-api -` +``` And [activate it](http://wp-cli.org/commands/plugin/activate/): -` +``` $ wp plugin activate rest-api -` +``` View the [Quick Start](http://wp-cli.org/docs/quick-start/) guide or jump to the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. @@ -28,22 +28,26 @@ The recommended way to install WP-CLI is to download the Phar build, mark it exe Download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) using `wget` or `curl`. For example: -`$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar` +``` +$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar +``` Check if it is working: -`$ php wp-cli.phar --info` +``` +$ php wp-cli.phar --info +``` To use it from the command line by typing `wp`, make the file executable and move it to somewhere in your PATH. For example: -` +``` $ chmod +x wp-cli.phar $ sudo mv wp-cli.phar /usr/local/bin/wp -` +``` If WP-CLI installed successfully, you should see something like this when you run `wp --info`: -` +``` $ wp --info PHP binary: /usr/bin/php5 PHP version: 5.5.9-1ubuntu4.14 @@ -53,7 +57,7 @@ WP-CLI packages dir: /home/wp-cli/.wp-cli/packages/ WP-CLI global config: /home/wp-cli/.wp-cli/config.yml WP-CLI project config: WP-CLI version: 0.23.0 -` +``` Now that you've got WP-CLI, read the [Quick Start](http://wp-cli.org/docs/quick-start/) guide. Or view the [full installation guide](http://wp-cli.org/docs/installing/) with alternative installation methods. From f7cb087d32a0408806591da800ef928bf9be87b5 Mon Sep 17 00:00:00 2001 From: Patrick <phh@peytz.dk> Date: Wed, 18 May 2016 20:35:07 +0200 Subject: [PATCH 4321/4858] Update search-replace.php --- php/commands/search-replace.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 7ab5f51730..89d3306247 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -91,6 +91,13 @@ class Search_Replace_Command extends WP_CLI_Command { * * # Search/replace to a SQL file without transforming the database * wp search-replace foo bar --export=database.sql + * + * # Search/replace production to development url (multisite compatible) + * if $(wp --url=http://example.com core is-installed --network); then + * wp search-replace --url=http://example.com 'http://example.com' 'http://example.dev' --recurse-objects --network --skip-columns=guid + * else + * wp search-replace 'http://example.com' 'http://example.dev' --recurse-objects --skip-columns=guid + * fi */ public function __invoke( $args, $assoc_args ) { global $wpdb; From 97667d970919c34db48c1486489666423e14f3e4 Mon Sep 17 00:00:00 2001 From: Patrick <phh@peytz.dk> Date: Wed, 18 May 2016 20:56:58 +0200 Subject: [PATCH 4322/4858] Update db.php --- php/commands/db.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/commands/db.php b/php/commands/db.php index 1d1900b440..ef87f2b174 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -52,6 +52,10 @@ public function drop( $_, $assoc_args ) { * * [--yes] * : Answer yes to the confirmation message. + * + * ## EXAMPLES + * + * wp db reset --yes */ public function reset( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); From 1195f8caf1d233e112d52db2a1d6e11f6d96fc15 Mon Sep 17 00:00:00 2001 From: Patrick <phh@peytz.dk> Date: Wed, 18 May 2016 21:14:52 +0200 Subject: [PATCH 4323/4858] Update db.php Output feedback message and add example for `wp db drop --yes` --- php/commands/db.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index ef87f2b174..6c87dcb243 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -32,6 +32,11 @@ public function create( $_, $assoc_args ) { * * [--yes] * : Answer yes to the confirmation message. + * + * ## EXAMPLES + * + * $ wp db drop --yes + * Success: Database dropped. */ public function drop( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args ); @@ -55,7 +60,8 @@ public function drop( $_, $assoc_args ) { * * ## EXAMPLES * - * wp db reset --yes + * $ wp db reset --yes + * Success: Database reset. */ public function reset( $_, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to reset the database?", $assoc_args ); From ab6f75e7e768a2b21d8de0ec11e159942ea1ebfb Mon Sep 17 00:00:00 2001 From: Patrick <phh@peytz.dk> Date: Wed, 18 May 2016 21:43:58 +0200 Subject: [PATCH 4324/4858] Update search-replace.php Documentation: Tell that this is a bash script --- php/commands/search-replace.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 89d3306247..ca07963d6f 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -92,7 +92,8 @@ class Search_Replace_Command extends WP_CLI_Command { * # Search/replace to a SQL file without transforming the database * wp search-replace foo bar --export=database.sql * - * # Search/replace production to development url (multisite compatible) + * # Bash script: Search/replace production to development url (multisite compatible) + * #!/bin/bash * if $(wp --url=http://example.com core is-installed --network); then * wp search-replace --url=http://example.com 'http://example.com' 'http://example.dev' --recurse-objects --network --skip-columns=guid * else From aebd05781000e53b89376f800e9fc8129ca71a03 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 18 May 2016 13:40:55 -0700 Subject: [PATCH 4325/4858] Only display packages directory path when it exists This is more consistent with the other parameters displayed --- php/commands/cli.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 4446d5f802..be6d1bd61b 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -49,13 +49,17 @@ public function info( $_, $assoc_args ) { $runner = WP_CLI::get_runner(); + $packages_dir = $runner->get_packages_dir_path(); + if ( ! is_dir( $packages_dir ) ) { + $packages_dir = null; + } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) { $info = array( 'php_binary_path' => $php_bin, 'global_config_path' => $runner->global_config_path, 'project_config_path' => $runner->project_config_path, 'wp_cli_dir_path' => WP_CLI_ROOT, - 'wp_cli_packages_dir_path' => $runner->get_packages_dir_path(), + 'wp_cli_packages_dir_path' => $packages_dir, 'wp_cli_version' => WP_CLI_VERSION, ); @@ -65,7 +69,7 @@ public function info( $_, $assoc_args ) { WP_CLI::line( "PHP version:\t" . PHP_VERSION ); WP_CLI::line( "php.ini used:\t" . get_cfg_var( 'cfg_file_path' ) ); WP_CLI::line( "WP-CLI root dir:\t" . WP_CLI_ROOT ); - WP_CLI::line( "WP-CLI packages dir:\t" . $runner->get_packages_dir_path() ); + WP_CLI::line( "WP-CLI packages dir:\t" . $packages_dir ); WP_CLI::line( "WP-CLI global config:\t" . $runner->global_config_path ); WP_CLI::line( "WP-CLI project config:\t" . $runner->project_config_path ); WP_CLI::line( "WP-CLI version:\t" . WP_CLI_VERSION ); From 8d7ac8abbee13cf407c300cfbabbbafdeaf9aad8 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 19 May 2016 05:55:12 +0900 Subject: [PATCH 4326/4858] Example: core update --- php/commands/core.php | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 4e23f1509e..e2d931a393 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1015,11 +1015,30 @@ private static function get_core_checksums( $version, $locale ) { * * ## EXAMPLES * - * wp core update - * - * wp core update --version=3.8 ../latest.zip - * - * wp core update --version=3.1 --force + * $ wp core update + * Updating to version 4.5.2 (en_US)... + * Downloading update from https://downloads.wordpress.org/release/wordpress-4.5.2-no-content.zip... + * Unpacking the update... + * Cleaning up files... + * No files found that need cleaned up + * Success: WordPress updated successfully. + * + * $ wp core update --version=3.8 ../latest.zip + * Updating to version 3.8 ()... + * Unpacking the update... + * Cleaning up files... + * File removed: wp-admin/js/tags-box.js + * ... + * File removed: wp-admin/js/updates.min. + * 377 files cleaned up + * Success: WordPress updated successfully. + * + * $ wp core update --version=3.1 --force + * Updating to version 3.1 (en_US)... + * Downloading update from https://wordpress.org/wordpress-3.1.zip... + * Unpacking the update... + * Warning: Failed to fetch checksums. Please cleanup files manually. + * Success: WordPress updated successfully. * * @alias upgrade */ From 9a63893cce9df98eb78fdddabd6343cd6780456a Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 19 May 2016 06:13:14 +0900 Subject: [PATCH 4327/4858] Example: core update-db --- php/commands/core.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4e23f1509e..e9e16c48ee 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1146,6 +1146,15 @@ function update( $args, $assoc_args ) { * [--dry-run] * : Compare database versions without performing the update. * + * ## EXAMPLES + * + * $ wp core update-db + * Success: WordPress database upgraded successfully from db version 36686 to 35700 + * + * $ wp core update-db --network + * WordPress database upgraded successfully from db version 35700 to 29630 on example.com/ + * Success: WordPress database upgraded on 123/123 sites + * * @subcommand update-db */ function update_db( $_, $assoc_args ) { From a823c0f1162817190a533ff3baab807dacf6ba61 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 19 May 2016 06:24:50 +0900 Subject: [PATCH 4328/4858] Example: core verify-checksums --- php/commands/core.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4e23f1509e..529d7f0088 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -812,6 +812,17 @@ public function version( $args = array(), $assoc_args = array() ) { * [--locale=<locale>] * : Verify checksums against a specific locale of WordPress. * + * ## EXAMPLES + * + * $ wp core verify-checksums + * Success: WordPress install verifies against checksums. + * + * $ wp core verify-checksums --version=4.0 + * Success: WordPress install verifies against checksums. + * + * $ wp core verify-checksums --locale=en_US + * Success: WordPress install verifies against checksums. + * * @when before_wp_load * * @subcommand verify-checksums From 390c273b0323864b0b16723282c0e80426813551 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 19 May 2016 06:42:26 +0900 Subject: [PATCH 4329/4858] Example: core version --- php/commands/core.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4e23f1509e..f78be570a0 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -772,6 +772,16 @@ private static function get_clean_basedomain() { * [--extra] * : Show extended version information. * + * ## EXAMPLES + * + * $ wp core version + * 4.5.2 + * + * $ wp core version --extra + * WordPress version: 4.5.2 + * Database revision: 36686 + * TinyMCE version: 4.310 (4310-20160418) + * * @when before_wp_load */ public function version( $args = array(), $assoc_args = array() ) { From 2efbc78866b08b45b9185c217e00fd61fd0dec56 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 18 May 2016 15:16:15 -0700 Subject: [PATCH 4330/4858] Update tests for aebd05781000e53b89376f800e9fc8129ca71a03 --- features/cli-info.feature | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/features/cli-info.feature b/features/cli-info.feature index 7d3fef3463..e5911b1d56 100644 --- a/features/cli-info.feature +++ b/features/cli-info.feature @@ -6,11 +6,14 @@ Feature: Review CLI information When I run `wp cli info --format=json` Then STDOUT should be JSON containing: """ - {"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"} + {"wp_cli_packages_dir_path":null} """ - When I run `WP_CLI_PACKAGES_DIR=/tmp/packages wp cli info --format=json` + When I run `wp package install danielbachhuber/wp-cli-reset-post-date-command` + Then STDERR should be empty + + When I run `wp cli info --format=json` Then STDOUT should be JSON containing: """ - {"wp_cli_packages_dir_path":"/tmp/packages/"} + {"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"} """ From 5ec67432ef721c3a2e57a8cc5f73fea4864f700a Mon Sep 17 00:00:00 2001 From: Ville Vuorenmaa <villevuor@gmail.com> Date: Thu, 19 May 2016 09:56:40 +0300 Subject: [PATCH 4331/4858] Added some comments --- php/commands/search-replace.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index b6f285a1c0..3403c78144 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -371,19 +371,25 @@ function ( $field ) { $sql .= '(' . join( ', ', array_fill( 0, count( $row_fields ), '%s' ) ) . ')'; $values = array_merge( $values, array_values( $row_fields ) ); + // Add new insert statement if needed. Before this we close the previous with semicolon and write statement to sql-file. + // "Statement break" is needed: + // 1. When the loop is running every nth time (where n is insert statement size, $export_index_size). Remainder is zero also on first round, so it have to be excluded. + // $index % $export_insert_size == 0 && $index > 0 + // 2. Or when the loop is running last time + // $index == $count if( ( $index % $export_insert_size == 0 && $index > 0 ) || $index == $count ) { $sql .= ";\n"; $sql = $wpdb->prepare( $sql, array_values( $values ) ); fwrite( $this->export_handle, $sql ); - + + // If there is still rows to loop, reset $sql and $values variables. if( $count > $index ) { $sql = $insert; $values = array(); } - } else { + } else { // Otherwise just add comma and new line $sql .= ",\n"; - } $index++; From 1c205a8f170cfdfddcd80ab86e01765eb6ba4c01 Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Thu, 19 May 2016 09:04:07 +0100 Subject: [PATCH 4332/4858] wp-cli/wp-cli#2760 Updates based on feedback. - Basic language and formatting adjustments - Adjust demonstration examples in Usage - Added summary of a command to Extending - Rename Contributors to Leadership - Added minimum requirements - Indicated support was available --- README.md | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b5395b045b..67f8b8d9a5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# WP-CLI +WP-CLI +====== -Command-line tools for managing WordPress installations. [http://wp-cli.org/](http://wp-cli.org/). +[WP-CLI](http://wp-cli.org/) is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs and much more, without using a web browser. [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) @@ -8,24 +9,40 @@ Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | ## Using -This project aims to provide command-line support for any action you can perform in the WordPress admin and many you can't. So you can [install a plugin](http://wp-cli.org/commands/plugin/install/): +The goal of WP-CLI is to provide a command-line interface for any action you can perform in the WordPress admin. The project also includes commands for many actions you can't perform in the WordPress admin. + +For instance, `wp plugin install` ([doc](http://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: ``` -$ wp plugin install rest-api +$ wp plugin install rest-api --activate +Installing WordPress REST API (Version 2) (2.0-beta13) +Downloading install package from https://downloads.wordpress.org/plugin/rest-api.2.0-beta13.zip... +Unpacking the package... +Installing the plugin... +Plugin installed successfully. +Activating 'rest-api'... +Success: Plugin 'rest-api' activated. ``` -And [activate it](http://wp-cli.org/commands/plugin/activate/): +`wp transient` ([doc](http://wp-cli.org/commands/transient/)) lets you delete one or all transients: ``` -$ wp plugin activate rest-api +$ wp transient delete-all +Success: 34 transients deleted from the database. ``` -View the [Quick Start](http://wp-cli.org/docs/quick-start/) guide or jump to the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. +For a complete introduction, the [Quick Start guide](http://wp-cli.org/docs/quick-start/). If you already feel comfortable with the basics, jump into the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. ## Installing The recommended way to install WP-CLI is to download the Phar build, mark it executable and place it in your PATH. +Before you install though, please make sure your environment meets the minimum requirements: + +- UNIX-like environment (OS X, Linux, FreeBSD, Cygwin); limited support in Windows environment +- PHP 5.3.29 or later +- WordPress 3.7 or later + Download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) using `wget` or `curl`. For example: ``` @@ -63,21 +80,23 @@ Now that you've got WP-CLI, read the [Quick Start](http://wp-cli.org/docs/quick- ## Support -WP-CLI is a volunteer-led project and can't support every user individually. If you run into trouble, here are some places to look for help: +WP-CLI's project maintainers do their best to respond to all bug reports and configuration errors within reason and the constraints on their time. Before requesting help, please read to find a solution to your problem in the following resources: - [Common issues and their fixes](http://wp-cli.org/docs/common-issues/) -- [Bug reports](http://wp-cli.org/docs/bug-reports/) +- [Submit a bug report](http://wp-cli.org/docs/bug-reports/) - [External resources](http://wp-cli.org/docs/external-resources/) ## Extending -Creating a custom WP-CLI command can be easier than it looks. Read the [commands cookbook](http://wp-cli.org/docs/commands-cookbook/). +A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](http://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](http://wp-cli.org/commands/plugin/activate/)) is another. + +WP-CLI comes with dozens of commands. But it's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](http://wp-cli.org/docs/commands-cookbook/) to learn more. ## Contributing Thanks for helping to improve WP-CLI. Please read about [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). -### Contributors +### Leadership * [Andreas Creten](https://github.com/andreascreten) - founder * [Cristi Burcă](https://github.com/scribu) - previous maintainer * [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer From 744fc7c34a1b9ab9ca325873e5aeb7559ca9185e Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Thu, 19 May 2016 09:07:29 +0100 Subject: [PATCH 4333/4858] wp-cli/wp-cli#2760 Add missing word in sentence --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 67f8b8d9a5..f0c1ecc5e8 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ $ wp transient delete-all Success: 34 transients deleted from the database. ``` -For a complete introduction, the [Quick Start guide](http://wp-cli.org/docs/quick-start/). If you already feel comfortable with the basics, jump into the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. +For a complete introduction, read the [Quick Start guide](http://wp-cli.org/docs/quick-start/). If you already feel comfortable with the basics, jump into the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. ## Installing From e063b0d794397551f47fd2a3f0139bc634b82dfb Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 19 May 2016 23:33:31 +0900 Subject: [PATCH 4334/4858] add example of error --- php/commands/core.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 529d7f0088..32ea90d10f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -823,6 +823,12 @@ public function version( $args = array(), $assoc_args = array() ) { * $ wp core verify-checksums --locale=en_US * Success: WordPress install verifies against checksums. * + * $ wp core verify-checksums --locale=ja + * Warning: File doesn't verify against checksum: wp-includes/version.php + * Warning: File doesn't verify against checksum: readme.html + * Warning: File doesn't verify against checksum: wp-config-sample.php + * Error: WordPress install doesn't verify against checksums. + * * @when before_wp_load * * @subcommand verify-checksums From e8f1039c39b117bbb2cead089f346e01dcf4561f Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 20 May 2016 00:12:47 +0900 Subject: [PATCH 4335/4858] Example: core multisite-convert --- php/commands/core.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4e23f1509e..b27ad6337b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -472,6 +472,13 @@ public function install( $args, $assoc_args ) { * [--subdomains] * : If passed, the network will use subdomains, instead of subdirectories. Doesn't work with 'localhost'. * + * ## EXAMPLES + * + * $ wp core multisite-convert + * Set up multisite database tables. + * Added multisite constants to wp-config.php. + * Success: Network installed. Don't forget to set up rewrite rules. + * * @subcommand multisite-convert * @alias install-network */ From 4ad1b14c1e42290cc0cbd4e8136041de41bb74bd Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 20 May 2016 00:25:10 +0900 Subject: [PATCH 4336/4858] Example: core multisite-install --- php/commands/core.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 4e23f1509e..f0ddcb9d32 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -519,6 +519,16 @@ public function multisite_convert( $args, $assoc_args ) { * [--skip-email] * : Don't send an email notification to the new admin user. * + * ## EXAMPLES + * + * $ wp core multisite-install --title="Welcome to the WordPress" \ + * > --admin_user="admin" --admin_password="password" \ + * > --admin_email="user@example.com" + * Single site database tables already present. + * Set up multisite database tables. + * Added multisite constants to wp-config.php. + * Success: Network installed. Don't forget to set up rewrite rules. + * * @subcommand multisite-install */ public function multisite_install( $args, $assoc_args ) { From 818cbe49b8b3b58bbd8e2bfa657b12b87873a286 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 15:53:17 +0000 Subject: [PATCH 4337/4858] Example: plugin list #2769 --- php/commands/plugin.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..a70003147c 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -639,10 +639,24 @@ function delete( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * wp plugin list --status=active --format=json + * $ wp plugin list --status=active --format=json + * [{"name":"dynamic-hostname","status":"active","update":"none","version":"0.4.2"},{"name":"tinymce-templates","status":"active","update":"none","version":"4.4.3"},{"name":"wp-multibyte-patch","status":"active","update":"none","version":"2.4"},{"name":"wp-total-hacks","status":"active","update":"none","version":"2.0.1"}] * * # List plugins on each site in a network - * wp site list --field=url | xargs -n 1 -I % wp plugin list --url=% + * $ wp site list --field=url | xargs -n 1 -I % wp plugin list --url=% + * +------------------------------+----------------+-----------+------------+ + * | name | status | update | version | + * +------------------------------+----------------+-----------+------------+ + * | akismet | active-network | none | 3.1.11 | + * | hello | inactive | none | 1.6 | + * +------------------------------+----------------+-----------+------------+ + * +------------------------------+----------------+-----------+------------+ + * | name | status | update | version | + * +------------------------------+----------------+-----------+------------+ + * | akismet | active-network | none | 3.1.11 | + * | hello | inactive | none | 1.6 | + * +------------------------------+----------------+-----------+------------+ + * * * @subcommand list */ From 5b9954e7e10f1039b1e753daaa6c23656ada8845 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 15:58:21 +0000 Subject: [PATCH 4338/4858] Example: plugin delete #2770 --- php/commands/plugin.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..32994bf613 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -590,10 +590,12 @@ function is_installed( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * wp plugin delete hello + * $ wp plugin delete hello + * Success: Deleted 'hello' plugin. * * # Delete inactive plugins - * wp plugin delete $(wp plugin list --status=inactive --field=name) + * $ wp plugin delete $(wp plugin list --status=inactive --field=name) + * Success: Deleted 'tinymce-templates' plugin. */ function delete( $args, $assoc_args = array() ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { From 58bbdb3972bd97344613d739edb7fc5704ab16cb Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:03:43 +0000 Subject: [PATCH 4339/4858] Example: plugin path #2770 --- php/commands/plugin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..ed72dfca60 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -301,7 +301,8 @@ function toggle( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * cd $(wp plugin path) + * $ cd $(wp plugin path) && pwd + * /var/www/wordpress/wp-content/plugins */ function path( $args, $assoc_args ) { $path = untrailingslashit( WP_PLUGIN_DIR ); From 9cab5f53042bfc2ebac86bd576050dc29f30f660 Mon Sep 17 00:00:00 2001 From: Shinichi Nishikawa <shinichi.nishikawa@gmail.com> Date: Fri, 20 May 2016 01:03:44 +0900 Subject: [PATCH 4340/4858] #2769 add example to cli update command document. --- php/commands/cli.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index be6d1bd61b..d0b31dd411 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -135,6 +135,14 @@ public function check_update( $_, $assoc_args ) { * * [--yes] * : Do not prompt for confirmation + * + * ## EXAMPLES + * + * $ wp cli update + * You have version 0.23.0. Would you like to update to 0.23.1? [y/n] y + * Downloading from https://github.com/wp-cli/wp-cli/releases/download/v0.23.1/wp-cli-0.23.1.phar... + * New version works. Proceeding to replace. + * Success: Updated WP-CLI to 0.23.1 */ public function update( $_, $assoc_args ) { if ( ! Utils\inside_phar() ) { From 277eda42f7252543126ed627a00cca2cabef35f4 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:14:14 +0000 Subject: [PATCH 4341/4858] Example: plugin update #2770 --- php/commands/plugin.php | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..e3d067a607 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -366,9 +366,34 @@ protected function install_from_repo( $slug, $assoc_args ) { * * ## EXAMPLES * - * wp plugin update bbpress --version=dev - * - * wp plugin update --all + * $ wp plugin update bbpress --version=dev + * Installing bbPress (Development Version) + * Downloading install package from https://downloads.wordpress.org/plugin/bbpress.zip... + * Unpacking the package... + * Installing the plugin... + * Removing the old version of the plugin... + * Plugin updated successfully. + * + * $ wp plugin update --all + * Enabling Maintenance mode... + * Downloading update from https://downloads.wordpress.org/plugin/akismet.3.1.11.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the plugin... + * Plugin updated successfully. + * Downloading update from https://downloads.wordpress.org/plugin/nginx-champuru.3.2.0.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the plugin... + * Plugin updated successfully. + * Disabling Maintenance mode... + * Success: Updated 2/2 plugins. + * +------------------------+-------------+-------------+---------+ + * | name | old_version | new_version | status | + * +------------------------+-------------+-------------+---------+ + * | akismet | 3.1.3 | 3.1.11 | Updated | + * | nginx-cache-controller | 3.1.1 | 3.2.0 | Updated | + * +------------------------+-------------+-------------+---------+ * * @alias upgrade */ From 3984f650372eb1808952ba115e6cb3936c8c23f0 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:17:12 +0000 Subject: [PATCH 4342/4858] Example: plugin get #2770 --- php/commands/plugin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..06b6502a9e 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -488,7 +488,8 @@ function install( $args, $assoc_args ) { * * ## EXAMPLES * - * wp plugin get bbpress --format=json + * $ wp plugin get bbpress --format=json + * {"name":"bbpress","title":"bbPress","author":"The bbPress Contributors","version":"2.6-alpha","description":"bbPress is forum software with a twist from the creators of WordPress.","status":"active"} */ public function get( $args, $assoc_args ) { $plugin = $this->fetcher->get_check( $args[0] ); From 99a08721d56e3df2232c54ce546861303b3c712a Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:20:16 +0000 Subject: [PATCH 4343/4858] Example: plugin uninstall #2770 --- php/commands/plugin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..96f174106c 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -531,7 +531,8 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp plugin uninstall hello + * $ wp plugin uninstall hello + * Success: Uninstalled and deleted 'hello' plugin. */ function uninstall( $args, $assoc_args = array() ) { foreach ( $this->fetcher->get_many( $args ) as $plugin ) { From 99e96cd9cc31f96a88b6cb7406733fdd570ec480 Mon Sep 17 00:00:00 2001 From: Shinichi Nishikawa <shinichi.nishikawa@gmail.com> Date: Fri, 20 May 2016 01:20:50 +0900 Subject: [PATCH 4344/4858] Example: cli version --- php/commands/cli.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index be6d1bd61b..ee9407454e 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -43,6 +43,11 @@ public function version() { * * [--format=<format>] * : Accepted values: json + * + * ## EXAMPLES + * + * $ wp cli version + * WP-CLI 0.23.1 */ public function info( $_, $assoc_args ) { $php_bin = WP_CLI::get_php_binary(); From 7ca3799aa6870d4bf43f79f7c22c46a256df8ac3 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:38:09 +0000 Subject: [PATCH 4345/4858] Example: plugin search #2770 --- php/commands/plugin.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..d8bd16d417 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -85,9 +85,19 @@ function status( $args ) { * * ## EXAMPLES * - * wp plugin search dsgnwrks --per-page=20 --format=json - * - * wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings + * $ wp plugin search dsgnwrks --per-page=20 --format=json + * Success: Showing 3 of 3 plugins. + * [{"name":"DsgnWrks Instagram Importer Debug","slug":"dsgnwrks-instagram-importer-debug","rating":0},{"name":"DsgnWrks Instagram Importer","slug":"dsgnwrks-instagram-importer","rating":84},{"name":"DsgnWrks Twitter Importer","slug":"dsgnwrks-twitter-importer","rating":80}] + * + * $ wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings + * Success: Showing 3 of 3 plugins. + * +-----------------------------------+---------+-----------------------------------+--------+-------------+ + * | name | version | slug | rating | num_ratings | + * +-----------------------------------+---------+-----------------------------------+--------+-------------+ + * | DsgnWrks Instagram Importer Debug | 0.1.6 | dsgnwrks-instagram-importer-debug | 0 | 0 | + * | DsgnWrks Instagram Importer | 1.3.7 | dsgnwrks-instagram-importer | 84 | 23 | + * | DsgnWrks Twitter Importer | 1.1.1 | dsgnwrks-twitter-importer | 80 | 1 | + * +-----------------------------------+---------+-----------------------------------+--------+-------------+ */ public function search( $args, $assoc_args ) { parent::_search( $args, $assoc_args ); From f86d5b77553987874e78bdd1249f4d43cdd7f735 Mon Sep 17 00:00:00 2001 From: Shinichi Nishikawa <shinichi.nishikawa@gmail.com> Date: Fri, 20 May 2016 01:38:39 +0900 Subject: [PATCH 4346/4858] Example: option get --- php/commands/option.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/commands/option.php b/php/commands/option.php index 6fd5274295..787c1e8080 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -28,6 +28,14 @@ class Option_Command extends WP_CLI_Command { * * [--format=<format>] * : Get value as var_export() or JSON. Default: var_export() + * + * ## EXAMPLES + * + * $ wp option get home + * http://example.com + * + * $ wp option get active_plugins --format=json + * {"0":"dynamically-dynamic-sidebar\/dynamically-dynamic-sidebar.php","1":"monster-widget\/monster-widget.php","2":"show-current-template\/show-current-template.php","3":"theme-check\/theme-check.php","5":"wordpress-importer\/wordpress-importer.php"} */ public function get( $args, $assoc_args ) { list( $key ) = $args; From 40379876ec591cadf0061473e0934af869a9a67f Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 19 May 2016 22:24:47 +0545 Subject: [PATCH 4347/4858] add example for transient delete-all command --- php/commands/transient.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index 09d05eb1ce..78fad25930 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -133,6 +133,11 @@ public function delete_expired() { /** * Delete all transients. * + * ## EXAMPLES + * + * wp transient delete-all + * Success: 14 transients deleted from the database. + * * @subcommand delete-all */ public function delete_all() { From a8cc9be5941c5805963bafe1af826331b96f2ac3 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 19 May 2016 22:27:14 +0545 Subject: [PATCH 4348/4858] add missing dollar sign in command example --- php/commands/transient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 78fad25930..3fc77dba4d 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -135,7 +135,7 @@ public function delete_expired() { * * ## EXAMPLES * - * wp transient delete-all + * $ wp transient delete-all * Success: 14 transients deleted from the database. * * @subcommand delete-all From 1fb32b76b362191083366f6c264d11de08601d26 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:42:40 +0000 Subject: [PATCH 4349/4858] add Command Example: plugin toggle #2770 --- php/commands/plugin.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..c44029926d 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -273,6 +273,14 @@ function deactivate( $args, $assoc_args = array() ) { * * [--network] * : If set, the plugin will be toggled for the entire multisite network. + * + * ## EXAMPLES + * + * $ wp plugin toggle akismet + * Success: Plugin 'akismet' deactivated. + * + * $ wp plugin toggle akismet + * Success: Plugin 'akismet' activated. */ function toggle( $args, $assoc_args = array() ) { $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); From 8f6cfd8685ee4ebf85fea53a5c2ec666b46ec2aa Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 19 May 2016 22:29:33 +0545 Subject: [PATCH 4350/4858] Add example for transient delete-expired --- php/commands/transient.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index 09d05eb1ce..31ab2bff92 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -104,6 +104,11 @@ public function type() { /** * Delete all expired transients. * + * ## EXAMPLES + * + * $ wp transient delete-expired + * Success: 12 expired transients deleted from the database. + * * @subcommand delete-expired */ public function delete_expired() { From 3388d39693b0a7969b9389e7b27a9208a74b6d40 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Thu, 19 May 2016 16:50:55 +0000 Subject: [PATCH 4351/4858] Example:plugin install #2770 --- php/commands/plugin.php | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 734e2fec6e..c55a5bec97 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -449,16 +449,36 @@ protected function filter_item_list( $items, $args ) { * ## EXAMPLES * * # Install the latest version from wordpress.org and activate - * wp plugin install bbpress --activate + * $ wp plugin install bbpress --activate + * Installing bbPress (2.5.9) + * Downloading install package from https://downloads.wordpress.org/plugin/bbpress.2.5.9.zip... + * Using cached file '/home/vagrant/.wp-cli/cache/plugin/bbpress-2.5.9.zip'... + * Unpacking the package... + * Installing the plugin... + * Plugin installed successfully. + * Activating 'bbpress'... + * Success: Plugin 'bbpress' activated. * * # Install the development version from wordpress.org - * wp plugin install bbpress --version=dev + * $ wp plugin install bbpress --version=dev + * Installing bbPress (Development Version) + * Downloading install package from https://downloads.wordpress.org/plugin/bbpress.zip... + * Unpacking the package... + * Installing the plugin... + * Plugin installed successfully. * * # Install from a local zip file - * wp plugin install ../my-plugin.zip + * $ wp plugin install ../my-plugin.zip + * Unpacking the package... + * Installing the plugin... + * Plugin installed successfully. * * # Install from a remote zip file - * wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef + * $ wp plugin install http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef + * Downloading install package from http://s3.amazonaws.com/bucketname/my-plugin.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef + * Unpacking the package... + * Installing the plugin... + * Plugin installed successfully. */ function install( $args, $assoc_args ) { From f89a55bb27415ac88efa373050bf8468a489eb5a Mon Sep 17 00:00:00 2001 From: Shinichi Nishikawa <shinichi.nishikawa@gmail.com> Date: Fri, 20 May 2016 01:55:13 +0900 Subject: [PATCH 4352/4858] Example: taxonomy get --- php/commands/taxonomy.php | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index addfb8c324..3579ebbf69 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -99,7 +99,38 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp taxonomy get post_tag --format=json + * $ wp taxonomy get category + * +---------------+---------------------------------------------------+ + * | Field | Value | + * +---------------+---------------------------------------------------+ + * | name | category | + * | label | Categories | + * | description | | + * | object_type | ["post"] | + * | show_tagcloud | true | + * | hierarchical | true | + * | public | true | + * | labels | {"name":"Categories","singular_name":"Category"," | + * | | search_items":"Search Categories","popular_items" | + * | | :null,"all_items":"All Categories","parent_item": | + * | | "Parent Category","parent_item_colon":"Parent Cat | + * | | egory:","edit_item":"Edit Category","view_item":" | + * | | View Category","update_item":"Update Category","a | + * | | dd_new_item":"Add New Category","new_item_name":" | + * | | New Category Name","separate_items_with_commas":n | + * | | ull,"add_or_remove_items":null,"choose_from_most_ | + * | | used":null,"not_found":"No categories found.","no | + * | | _terms":"No categories","items_list_navigation":" | + * | | Categories list navigation","items_list":"Categor | + * | | ies list","menu_name":"Categories","name_admin_ba | + * | | r":"category"} | + * | cap | {"manage_terms":"manage_categories","edit_terms": | + * | | "manage_categories","delete_terms":"manage_catego | + * | | ries","assign_terms":"edit_posts"} | + * +---------------+---------------------------------------------------+ + * + * $ wp taxonomy get post_tag --field=cap + * {"manage_terms":"manage_categories","edit_terms":"manage_categories","delete_terms":"manage_categories","assign_terms":"edit_posts"} */ public function get( $args, $assoc_args ) { $taxonomy = get_taxonomy( $args[0] ); From a30d40fba4df4f8fe17e75919df7b19e828dac89 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 20 May 2016 14:45:10 +0545 Subject: [PATCH 4353/4858] bail early in theme command if theme is broken or has error --- php/commands/theme.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 980967d7e1..45ca6ea005 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -127,6 +127,12 @@ protected function get_status( $theme ) { public function activate( $args = array() ) { $theme = $this->fetcher->get_check( $args[0] ); + $errors = $theme->errors(); + if ( is_wp_error( $errors ) ) { + $message = $errors->get_error_message(); + WP_CLI::error( $message ); + } + $name = $theme->get('Name'); if ( 'active' === $this->get_status( $theme ) ) { @@ -420,6 +426,12 @@ function install( $args, $assoc_args ) { public function get( $args, $assoc_args ) { $theme = $this->fetcher->get_check( $args[0] ); + $errors = $theme->errors(); + if ( is_wp_error( $errors ) ) { + $message = $errors->get_error_message(); + WP_CLI::error( $message ); + } + // WP_Theme object employs magic getter, unfortunately $theme_vars = array( 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', ); From 89e4a1bf8ba9da7cee2702a833fff194a02d508c Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 20 May 2016 22:05:31 +0545 Subject: [PATCH 4354/4858] add example for transient type command --- php/commands/transient.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index f41919170d..6bbc328209 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -89,6 +89,11 @@ public function delete( $args, $assoc_args ) { /** * See whether the transients API is using an object cache or the options table. + * + * ## EXAMPLES + * + * $ wp transient type + * Transients are saved to the wp_options table. */ public function type() { global $_wp_using_ext_object_cache, $wpdb; From ecc58f2fe6233b633f1ea6df2bee930651704e46 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 20 May 2016 22:18:38 +0545 Subject: [PATCH 4355/4858] Add example for transient set command --- php/commands/transient.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index f41919170d..44612e8106 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -49,6 +49,11 @@ public function get( $args, $assoc_args ) { * * [--network] * : Set the transient value on the network, instead of single site. + * + * ## EXAMPLES + * + * $ wp transient set sample_key "test data" 3600 + * Success: Transient added. */ public function set( $args, $assoc_args ) { list( $key, $value ) = $args; From 2ebe89e5797a8516c5fa9cf39d5dc34bb98c067f Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 20 May 2016 22:25:20 +0545 Subject: [PATCH 4356/4858] Add example for transient get command --- php/commands/transient.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index f41919170d..6174baeb67 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -20,6 +20,15 @@ class Transient_Command extends WP_CLI_Command { * * [--network] * : Get the value of the network transient, instead of the single site. + * + * ## EXAMPLES + * + * $ wp transient get sample_key + * test data + * + * $ wp transient get random_key + * Warning: Transient with key "random_key" is not set. + * */ public function get( $args, $assoc_args ) { list( $key ) = $args; From 147793d2e68906fa0ec7de696f82dc5c0657f9d5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 21 May 2016 21:00:17 +0545 Subject: [PATCH 4357/4858] fix doc in transient get command --- php/commands/transient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 6deb8c3574..c19de7b6c7 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -15,8 +15,8 @@ class Transient_Command extends WP_CLI_Command { * <key> * : Key for the transient. * - * [--json] - * : Format output as JSON. + * [--format=<format>] + * : Accepted values: table, json, csv, yaml. Default: table * * [--network] * : Get the value of the network transient, instead of the single site. From 2941fbe5fb94d09164f99a4dce43851a48d61805 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 21 May 2016 22:01:41 +0545 Subject: [PATCH 4358/4858] fix error message in theme activate scenario as message for broken theme is changed --- features/theme.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/theme.feature b/features/theme.feature index 505062fc2a..f6e2cb14ce 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -236,7 +236,7 @@ Feature: Manage WordPress themes When I try `wp theme activate biker` Then STDERR should contain: """ - Error: The 'biker' theme cannot be activated without its parent, 'jolene'. + Error: The parent theme is missing. Please install the "jolene" parent theme. """ Scenario: List an active theme with its parent From ac00c9783e2424ecdf06f7b830c5bb542a31b9c9 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 21 May 2016 22:11:02 +0545 Subject: [PATCH 4359/4858] add scenario for add error message in theme get and theme activate --- features/theme.feature | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index f6e2cb14ce..6704bf24a0 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -129,6 +129,22 @@ Feature: Manage WordPress themes | name | status | | p2 | active | + Scenario: Attempt to activate or fetch a broken theme + Given a WP install + And I run `mkdir -pv wp-content/themes/just-test-theme` + + When I try `wp theme activate just-test-theme` + Then STDERR should contain: + """ + Error: Stylesheet is missing. + """ + + When I try `wp theme get just-test-theme` + Then STDERR should contain: + """ + Error: Stylesheet is missing. + """ + Scenario: Enabling and disabling a theme Given a WP multisite install And I run `wp theme install jolene` From 257a708e314909e523d390731e5c772d17bd2842 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 21 May 2016 22:22:19 +0545 Subject: [PATCH 4360/4858] Example: transient delete --- php/commands/transient.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/transient.php b/php/commands/transient.php index 6deb8c3574..44f8a8bbef 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -85,6 +85,11 @@ public function set( $args, $assoc_args ) { * * [--network] * : Delete the value of a network transient, instead of that on a single site. + * + * ## EXAMPLES + * + * $ wp transient delete sample_key + * Success: Transient deleted. */ public function delete( $args, $assoc_args ) { list( $key ) = $args; From 278ef5b9068bee74f38cf8b4d38190b4e7d28b53 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Sun, 22 May 2016 00:12:35 +0000 Subject: [PATCH 4361/4858] add one more space #2791 --- php/commands/plugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index d8bd16d417..26edd13187 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -87,7 +87,7 @@ function status( $args ) { * * $ wp plugin search dsgnwrks --per-page=20 --format=json * Success: Showing 3 of 3 plugins. - * [{"name":"DsgnWrks Instagram Importer Debug","slug":"dsgnwrks-instagram-importer-debug","rating":0},{"name":"DsgnWrks Instagram Importer","slug":"dsgnwrks-instagram-importer","rating":84},{"name":"DsgnWrks Twitter Importer","slug":"dsgnwrks-twitter-importer","rating":80}] + * [{"name":"DsgnWrks Instagram Importer Debug","slug":"dsgnwrks-instagram-importer-debug","rating":0},{"name":"DsgnWrks Instagram Importer","slug":"dsgnwrks-instagram-importer","rating":84},{"name":"DsgnWrks Twitter Importer","slug":"dsgnwrks-twitter-importer","rating":80}] * * $ wp plugin search dsgnwrks --fields=name,version,slug,rating,num_ratings * Success: Showing 3 of 3 plugins. From af66de2cbc956ba32636b2f1138df14ac219ce16 Mon Sep 17 00:00:00 2001 From: Hidetaka Okamoto <kokkoku214@gmail.com> Date: Sun, 22 May 2016 09:17:40 +0900 Subject: [PATCH 4362/4858] fix Example indent #2794 --- php/commands/plugin.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index c44029926d..b5bcdf2d75 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -277,10 +277,10 @@ function deactivate( $args, $assoc_args = array() ) { * ## EXAMPLES * * $ wp plugin toggle akismet - * Success: Plugin 'akismet' deactivated. + * Success: Plugin 'akismet' deactivated. * - * $ wp plugin toggle akismet - * Success: Plugin 'akismet' activated. + * $ wp plugin toggle akismet + * Success: Plugin 'akismet' activated. */ function toggle( $args, $assoc_args = array() ) { $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); From 0c4da059b907c3413c0a2032f150077286dfdabb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 22 May 2016 10:20:18 +0545 Subject: [PATCH 4363/4858] Example: sidebar list --- php/commands/sidebar.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 53cb9c3ac7..6f52022cf3 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -40,7 +40,10 @@ class Sidebar_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp sidebar list --fields=name,id --format=csv + * $ wp sidebar list --fields=name,id --format=csv + * name,id + * "Widget Area",sidebar-1 + * "Inactive Widgets",wp_inactive_widgets * * @subcommand list */ From 6f8749fac2a0f5889717944633ec8199c5fa2e59 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 22 May 2016 14:27:44 +0545 Subject: [PATCH 4364/4858] Example: theme status --- php/commands/theme.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 980967d7e1..25123a07ed 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -38,6 +38,15 @@ protected function get_upgrader_class( $force ) { * * [<theme>] * : A particular theme to show the status for. + * + * ## EXAMPLES + * + * $ wp theme status twentysixteen + * Theme twentysixteen details: + * Name: Twenty Sixteen + * Status: Inactive + * Version: 1.2 + * Author: the WordPress team */ function status( $args ) { parent::status( $args ); From ac3a58e5dad5515d5f4226eb296aef79767b4f6a Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 22 May 2016 14:38:35 +0545 Subject: [PATCH 4365/4858] Example: theme search --- php/commands/theme.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 980967d7e1..43e19abd46 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -76,9 +76,18 @@ function status( $args ) { * * ## EXAMPLES * - * wp theme search automattic --per-page=20 - * - * wp theme search automattic --fields=name,version,slug,rating,num_ratings,description + * $ wp theme search photo --per-page=6 + * Success: Showing 6 of 203 themes. + * +----------------------+----------------------+--------+ + * | name | slug | rating | + * +----------------------+----------------------+--------+ + * | Photos | photos | 100 | + * | Infinite Photography | infinite-photography | 100 | + * | PhotoBook | photobook | 100 | + * | BG Photo Frame | bg-photo-frame | 0 | + * | fPhotography | fphotography | 0 | + * | Photo Perfect | photo-perfect | 98 | + * +----------------------+----------------------+--------+ */ public function search( $args, $assoc_args ) { parent::_search( $args, $assoc_args ); From 4579ba57b2be57a523d9fdca4cfb3694429824a5 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 22 May 2016 14:42:55 +0545 Subject: [PATCH 4366/4858] Example: theme activate --- php/commands/theme.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 980967d7e1..fb57f7e956 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -123,6 +123,11 @@ protected function get_status( $theme ) { * * <theme> * : The theme to activate. + * + * ## EXAMPLES + * + * $ wp theme activate twentysixteen + * Success: Switched to 'Twenty Sixteen' theme. */ public function activate( $args = array() ) { $theme = $this->fetcher->get_check( $args[0] ); From b83159cd9ef0719fcc8c9e72bcfaa092a0d98ae1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 22 May 2016 14:52:34 +0545 Subject: [PATCH 4367/4858] Example: theme get --- php/commands/theme.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 980967d7e1..7e5cca7a75 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -415,7 +415,14 @@ function install( $args, $assoc_args ) { * * ## EXAMPLES * - * wp theme get twentytwelve --format=json + * $ wp theme get twentysixteen --fields=name,title,version + * +---------+----------------+ + * | Field | Value | + * +---------+----------------+ + * | name | Twenty Sixteen | + * | title | Twenty Sixteen | + * | version | 1.2 | + * +---------+----------------+ */ public function get( $args, $assoc_args ) { $theme = $this->fetcher->get_check( $args[0] ); From 0dba5bb20889ae8bde3b1b6dda2748aefd0f7ce5 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 22 May 2016 14:57:27 +0545 Subject: [PATCH 4368/4858] Example: theme delete --- php/commands/theme.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 980967d7e1..fda80015a1 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -519,7 +519,8 @@ function is_installed( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * wp theme delete twentyeleven + * $ wp theme delete twentytwelve + * Success: Deleted 'twentytwelve' theme. * * @alias uninstall */ From 1d55131fe9e2146906b78aadccc8d5e6fa090276 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 23 May 2016 15:52:27 +0545 Subject: [PATCH 4369/4858] Example: sidebar main class --- php/commands/sidebar.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 53cb9c3ac7..0423cc823d 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -2,6 +2,14 @@ /** * Manage sidebars. + * + * ## EXAMPLES + * + * # List sidebars + * $ wp sidebar list --fields=name,id --format=csv + * name,id + * "Widget Area",sidebar-1 + * "Inactive Widgets",wp_inactive_widgets */ class Sidebar_Command extends WP_CLI_Command { From da74d1ad05c930e86b07dc7ee2aadca4f41168ad Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 23 May 2016 16:02:10 +0545 Subject: [PATCH 4370/4858] Examples for transient main class --- php/commands/transient.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index c19de7b6c7..3221f8b781 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -5,7 +5,25 @@ * * ## EXAMPLES * - * wp transient set my_key my_value 300 + * # Set transient + * $ wp transient set sample_key "test data" 3600 + * Success: Transient added. + * + * # Get transient + * $ wp transient get sample_key + * test data + * + * # Delete transient + * $ wp transient delete sample_key + * Success: Transient deleted. + * + * # Delete expired transients + * $ wp transient delete-expired + * Success: 12 expired transients deleted from the database. + * + * # Delete all transients + * $ wp transient delete-all + * Success: 14 transients deleted from the database. */ class Transient_Command extends WP_CLI_Command { From 5a896b839b5e747f88c41c8156f053d8d022f7b8 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 23 May 2016 17:29:20 +0545 Subject: [PATCH 4371/4858] Example: rewrite flush --- php/commands/rewrite.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index d8dac74fcc..2134a3dd00 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -24,6 +24,11 @@ class Rewrite_Command extends WP_CLI_Command { * * [--hard] * : Perform a hard flush - update `.htaccess` rules as well as rewrite rules in database. Works only on single site installs. + * + * ## EXAMPLES + * + * $ wp rewrite flush + * Success: Rewrite rules flushed. */ public function flush( $args, $assoc_args ) { // make sure we detect mod_rewrite if configured in apache_modules in config From 91b8b438b6ccfb993450a19bc658376902567a38 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 23 May 2016 17:33:05 +0545 Subject: [PATCH 4372/4858] Example: rewrite structure --- php/commands/rewrite.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index d8dac74fcc..9591d1a2f3 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -75,7 +75,8 @@ public function flush( $args, $assoc_args ) { * * ## EXAMPLES * - * wp rewrite structure '/%year%/%monthnum%/%postname%' + * $ wp rewrite structure '/%year%/%monthnum%/%postname%' + * Success: Rewrite structure set. */ public function structure( $args, $assoc_args ) { global $wp_rewrite; From 628e0f8d513eef8368c08509e2914c4e79a788ca Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 23 May 2016 17:41:59 +0545 Subject: [PATCH 4373/4858] Example: rewrite list --- php/commands/rewrite.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index d8dac74fcc..c79e87accb 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -155,7 +155,13 @@ public function structure( $args, $assoc_args ) { * * ## EXAMPLES * - * wp rewrite list --format=csv + * $ wp rewrite list --format=csv + * match,query,source + * ^wp-json/?$,index.php?rest_route=/,other + * ^wp-json/(.*)?,index.php?rest_route=/$matches[1],other + * category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$,index.php?category_name=$matches[1]&feed=$matches[2],category + * category/(.+?)/(feed|rdf|rss|rss2|atom)/?$,index.php?category_name=$matches[1]&feed=$matches[2],category + * category/(.+?)/embed/?$,index.php?category_name=$matches[1]&embed=true,category * * @subcommand list */ From 6421df0def2a422c466632c0d4753bfda6c6955c Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 23 May 2016 17:52:13 +0545 Subject: [PATCH 4374/4858] Examples for rewrite commands --- php/commands/rewrite.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index d8dac74fcc..9b2126be80 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -3,6 +3,25 @@ /** * Manage rewrite rules. * + * ## EXAMPLES + * + * # Flush rewrite rules + * $ wp rewrite flush + * Success: Rewrite rules flushed. + * + * # Update permalink structure + * $ wp rewrite structure '/%year%/%monthnum%/%postname%' + * Success: Rewrite structure set. + * + * # List rewrite rules + * $ wp rewrite list --format=csv + * match,query,source + * ^wp-json/?$,index.php?rest_route=/,other + * ^wp-json/(.*)?,index.php?rest_route=/$matches[1],other + * category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$,index.php?category_name=$matches[1]&feed=$matches[2],category + * category/(.+?)/(feed|rdf|rss|rss2|atom)/?$,index.php?category_name=$matches[1]&feed=$matches[2],category + * category/(.+?)/embed/?$,index.php?category_name=$matches[1]&embed=true,category + * * @package wp-cli */ class Rewrite_Command extends WP_CLI_Command { From 0d9376399fa167ac8d57c1ee7f3f7f5ffb09d6c0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 May 2016 07:40:47 -0700 Subject: [PATCH 4375/4858] Display error if theme directory exists but is errored --- features/theme.feature | 14 +++++++++++--- php/commands/theme.php | 7 +++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 6704bf24a0..efad35776e 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -131,20 +131,28 @@ Feature: Manage WordPress themes Scenario: Attempt to activate or fetch a broken theme Given a WP install - And I run `mkdir -pv wp-content/themes/just-test-theme` - When I try `wp theme activate just-test-theme` + When I run `mkdir -pv wp-content/themes/myth` + Then the wp-content/themes/myth directory should exist + + When I try `wp theme activate myth` Then STDERR should contain: """ Error: Stylesheet is missing. """ - When I try `wp theme get just-test-theme` + When I try `wp theme get myth` Then STDERR should contain: """ Error: Stylesheet is missing. """ + When I try `wp theme status myth` + Then STDERR should be: + """ + Error: Stylesheet is missing. + """ + Scenario: Enabling and disabling a theme Given a WP multisite install And I run `wp theme install jolene` diff --git a/php/commands/theme.php b/php/commands/theme.php index 1c89ac16ac..2ff81bbf9e 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -49,6 +49,13 @@ protected function get_upgrader_class( $force ) { * Author: the WordPress team */ function status( $args ) { + $theme = $this->fetcher->get_check( $args[0] ); + $errors = $theme->errors(); + if ( is_wp_error( $errors ) ) { + $message = $errors->get_error_message(); + WP_CLI::error( $message ); + } + parent::status( $args ); } From 6c44f2703a09e9507634ac8b020f715fe56855ba Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 23 May 2016 14:05:36 -0700 Subject: [PATCH 4376/4858] Add a test for expected behavior with `--force` --- features/theme.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index efad35776e..5e6bf2a69b 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -153,6 +153,12 @@ Feature: Manage WordPress themes Error: Stylesheet is missing. """ + When I run `wp theme install myth --force` + Then STDOUT should contain: + """ + Theme updated successfully. + """ + Scenario: Enabling and disabling a theme Given a WP multisite install And I run `wp theme install jolene` From 14b1408561bc6dfbf7adae875729ba48edeb3640 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Tue, 24 May 2016 01:31:44 +0000 Subject: [PATCH 4377/4858] Example: server #2770 --- php/commands/server.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/php/commands/server.php b/php/commands/server.php index c13e917a42..ec6d0656c4 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -21,10 +21,18 @@ class Server_Command extends WP_CLI_Command { * ## EXAMPLES * * # Make the instance available on any address (with port 8080) - * wp server --host=0.0.0.0 + * $ wp server --host=0.0.0.0 + * PHP 5.6.9 Development Server started at Tue May 24 01:27:11 2016 + * Listening on http://0.0.0.0:8080 + * Document root is / + * Press Ctrl-C to quit. * * # Run on port 80 (for multisite) - * sudo wp server --host=localhost.localdomain --port=80 + * $ sudo wp server --host=localhost.localdomain --port=80 + * PHP 5.6.9 Development Server started at Tue May 24 01:30:06 2016 + * Listening on http://localhost1.localdomain1:8080 + * Document root is / + * Press Ctrl-C to quit. * * @when before_wp_load */ From b312019df833d5d0eeeec0f2609af01f7c5270e6 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 09:04:17 +0545 Subject: [PATCH 4378/4858] Example: role list --- php/commands/role.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index de0b3c15b2..9d5a0f07aa 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -34,7 +34,13 @@ class Role_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp role list --fields=role --format=csv + * $ wp role list --fields=role --format=csv + * role + * administrator + * editor + * author + * contributor + * subscriber * * @subcommand list */ From 014387adb8e476085c5eed684383362992559bca Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 09:07:32 +0545 Subject: [PATCH 4379/4858] Example: role exists --- php/commands/role.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index de0b3c15b2..23ebc09a93 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -69,7 +69,8 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp role exists editor + * $ wp role exists editor + * Success: Role with ID editor exists. */ public function exists( $args ) { global $wp_roles; From 75e23e3189b47dca2e1a96930be9a7cbee81a64a Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 09:13:49 +0545 Subject: [PATCH 4380/4858] Example: role create --- php/commands/role.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index de0b3c15b2..17040efdac 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -97,9 +97,13 @@ public function exists( $args ) { * * ## EXAMPLES * - * wp role create approver Approver + * # Create role for Approver + * $ wp role create approver Approver + * Success: Role with key approver created. * - * wp role create productadmin "Product Administrator" + * # Create role for Product Administrator + * $ wp role create productadmin "Product Administrator" + * Success: Role with key productadmin created. */ public function create( $args, $assoc_args ) { global $wp_roles; From 91134e08d49b2b02ac4fae6c8e6972778d6bfec8 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 09:16:43 +0545 Subject: [PATCH 4381/4858] Example: role delete --- php/commands/role.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index de0b3c15b2..2fde4263da 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -147,9 +147,13 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp role delete approver + * # Delete approver role + * $ wp role delete approver + * Success: Role with key approver deleted. * + * # Delete productadmin role * wp role delete productadmin + * Success: Role with key productadmin deleted. */ public function delete( $args ) { global $wp_roles; From 8be776171d1963578c22ddd848bca51fb1077f58 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 09:20:26 +0545 Subject: [PATCH 4382/4858] Example: role reset --- php/commands/role.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index de0b3c15b2..55ac198da5 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -185,9 +185,13 @@ public function delete( $args ) { * * ## EXAMPLES * - * wp role reset administrator author contributor + * # Reset role + * $ wp role reset administrator author contributor + * Success: Reset 1/3 roles * - * wp role reset --all + * # Reset all default roles + * $ wp role reset --all + * Success: All default roles reset. */ public function reset( $args, $assoc_args ) { From 34b98de98a3e5eeeebf953d94d0c3acd5a8026a1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 09:33:44 +0545 Subject: [PATCH 4383/4858] Examples for role main class --- php/commands/role.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/php/commands/role.php b/php/commands/role.php index de0b3c15b2..3f2dbe8509 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -3,6 +3,33 @@ /** * Manage user roles. * + * ## EXAMPLES + * + * # List roles + * $ wp role list --fields=role --format=csv + * role + * administrator + * editor + * author + * contributor + * subscriber + * + * # Check if a role exists + * $ wp role exists editor + * Success: Role with ID editor exists. + * + * # Create role + * $ wp role create approver Approver + * Success: Role with key approver created. + * + * # Delete role + * $ wp role delete approver + * Success: Role with key approver deleted. + * + * # Reset role + * $ wp role reset administrator author contributor + * Success: Reset 3/3 roles + * * @package wp-cli */ class Role_Command extends WP_CLI_Command { From 6cf1d442f24519bcd6c081d5b1cedacff376c057 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 24 May 2016 11:39:42 +0545 Subject: [PATCH 4384/4858] Example: export command --- php/commands/export.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index 7d89b0a0ad..fa6f61673d 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -59,12 +59,17 @@ class Export_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + * # Export posts published by the user between given start and end date + * $ wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + * Starting export process... + * Writing to file /tmp/staging.wordpress.2016-05-24.000.xml + * Success: All done with export. * - * wp export --dir=/tmp/ --post__in=123,124,125 - * - * # Export a random subset of content - * wp export --post__in=$(wp post list --post_type=post --orderby=rand --posts_per_page=8 --format=ids) + * # Export posts by IDs + * $ wp export --dir=/tmp/ --post__in=123,124,125 + * Starting export process... + * Writing to file /tmp/staging.wordpress.2016-05-24.000.xml + * Success: All done with export. */ public function __invoke( $_, $assoc_args ) { $defaults = array( From 5e90e8d810acdff2d3cd1e28a0208798bb0efd37 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 24 May 2016 22:45:03 +0545 Subject: [PATCH 4385/4858] Example: widget list --- php/commands/widget.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index fbc174beb1..32442437a8 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -52,7 +52,10 @@ class Widget_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp widget list sidebar-1 --fields=name --format=csv + * $ wp widget list sidebar-1 --fields=name,id --format=csv + * name,id + * meta,meta-5 + * search,search-3 * * @subcommand list */ From 372c246e15d47ddc009e2b32a8441aa3972cc40a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 24 May 2016 22:50:18 +0545 Subject: [PATCH 4386/4858] Example: widget add --- php/commands/widget.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index fbc174beb1..5764b527a0 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -90,7 +90,8 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp widget add calendar sidebar-1 2 --title="Calendar" + * $ wp widget add calendar sidebar-1 2 --title="Calendar" + * Success: Added widget to sidebar. * * @subcommand add */ From 6f7623ce5d11df07bff120bd30aaa9bcff067b97 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 24 May 2016 22:56:48 +0545 Subject: [PATCH 4387/4858] Example: widget update --- php/commands/widget.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index fbc174beb1..89ab8b21d6 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -140,7 +140,8 @@ public function add( $args, $assoc_args ) { * * ## EXAMPLES * - * wp widget update calendar-1 --title="Calendar" + * $ wp widget update calendar-1 --title="Our Calendar" + * Success: Widget updated. * * @subcommand update */ From 5227ccce1d5e109f5389b1d49c11efec33e3bbb5 Mon Sep 17 00:00:00 2001 From: Nate Wright <natew@notthisway.com> Date: Tue, 24 May 2016 21:01:11 +0100 Subject: [PATCH 4388/4858] wp-cli/wp-cli#2760 Minor language adjustments in readme --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f0c1ecc5e8..810fe5ff93 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Activating 'rest-api'... Success: Plugin 'rest-api' activated. ``` -`wp transient` ([doc](http://wp-cli.org/commands/transient/)) lets you delete one or all transients: +Similarly, `wp transient` ([doc](http://wp-cli.org/commands/transient/)) lets you delete one or all transients: ``` $ wp transient delete-all @@ -35,7 +35,7 @@ For a complete introduction, read the [Quick Start guide](http://wp-cli.org/docs ## Installing -The recommended way to install WP-CLI is to download the Phar build, mark it executable and place it in your PATH. +The recommended way to install WP-CLI is to download the Phar build, mark it executable and place it in your PATH. See also our documentation on [alternative installation methods](http://wp-cli.org/docs/installing/). Before you install though, please make sure your environment meets the minimum requirements: @@ -76,11 +76,9 @@ WP-CLI project config: WP-CLI version: 0.23.0 ``` -Now that you've got WP-CLI, read the [Quick Start](http://wp-cli.org/docs/quick-start/) guide. Or view the [full installation guide](http://wp-cli.org/docs/installing/) with alternative installation methods. - ## Support -WP-CLI's project maintainers do their best to respond to all bug reports and configuration errors within reason and the constraints on their time. Before requesting help, please read to find a solution to your problem in the following resources: +WP-CLI's project maintainers do their best to respond to all bug reports and configuration errors within reason and the constraints on their volunteered time. Before requesting help, please read to find a solution to your problem in the following resources: - [Common issues and their fixes](http://wp-cli.org/docs/common-issues/) - [Submit a bug report](http://wp-cli.org/docs/bug-reports/) @@ -90,11 +88,11 @@ WP-CLI's project maintainers do their best to respond to all bug reports and con A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](http://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](http://wp-cli.org/commands/plugin/activate/)) is another. -WP-CLI comes with dozens of commands. But it's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](http://wp-cli.org/docs/commands-cookbook/) to learn more. +WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](http://wp-cli.org/docs/commands-cookbook/) to learn more. ## Contributing -Thanks for helping to improve WP-CLI. Please read about [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). +To get involved, please first read about [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). ### Leadership * [Andreas Creten](https://github.com/andreascreten) - founder From 13fcae51cb851c011e04cab20c7325e3a5dab970 Mon Sep 17 00:00:00 2001 From: John Blackbourn <john@johnblackbourn.com> Date: Wed, 25 May 2016 00:07:43 +0100 Subject: [PATCH 4389/4858] Correct spelling of 'separate' in the `wp export` command docs. --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 7d89b0a0ad..cbecab7387 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -36,7 +36,7 @@ class Export_Command extends WP_CLI_Command { * comma. Defaults to all. * * [--post_type__not_in=<post-type>] - * : Export all post types except those identified. Seperate multiple post types + * : Export all post types except those identified. Separate multiple post types * with a comma. Defaults to none. * * [--post__in=<pid>] From 113382531f63f32a4ba158c396cc89c022bfc135 Mon Sep 17 00:00:00 2001 From: John Blackbourn <john@johnblackbourn.com> Date: Wed, 25 May 2016 00:10:50 +0100 Subject: [PATCH 4390/4858] Display the default value for the `--max-file-size` flag in `wp export`. --- php/commands/export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/export.php b/php/commands/export.php index 7d89b0a0ad..dedd36a74f 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -21,7 +21,7 @@ class Export_Command extends WP_CLI_Command { * : Don't export comments. * * [--max_file_size=<MB>] - * : A single export file should have this many megabytes. + * : A single export file should have this many megabytes. Default: 15 * * ## FILTERS * From a85e434ca0113dbebf7d01832cb43fbf617ccbc6 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 25 May 2016 05:58:36 +0545 Subject: [PATCH 4391/4858] Example: widget move --- php/commands/widget.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index f23f50cf3d..b60abd288e 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -182,9 +182,13 @@ public function update( $args, $assoc_args ) { * * ## EXAMPLES * - * wp widget move recent-comments-2 --position=2 + * # Change position of widget + * $ wp widget move recent-comments-2 --position=2 + * Success: Widget moved. * - * wp widget move recent-comments-2 --sidebar-id=wp_inactive_widgets + * # Move widget to Inactive Widgets + * $ wp widget move recent-comments-2 --sidebar-id=wp_inactive_widgets + * Success: Widget moved. * * @subcommand move */ From 023ebfea7864c8e31069941a9cbc88899118f12b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 25 May 2016 06:03:43 +0545 Subject: [PATCH 4392/4858] Example: widget deactivate --- php/commands/widget.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index f23f50cf3d..6bcc765a91 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -223,7 +223,8 @@ public function move( $args, $assoc_args ) { * * ## EXAMPLES * - * wp widget deactivate recent-comments-2 + * $ wp widget deactivate recent-comments-2 + * Success: Widget(s) deactivated * * @subcommand deactivate */ From 94e5c9e7b37b5106ff735843f5132ea71b4680d2 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 25 May 2016 06:06:49 +0545 Subject: [PATCH 4393/4858] Example: widget delete --- php/commands/widget.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index f23f50cf3d..66fa35285a 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -253,7 +253,8 @@ public function deactivate( $args, $assoc_args ) { * * ## EXAMPLES * - * wp widget delete recent-comments-2 + * $ wp widget delete recent-comments-2 + * Success: Widget(s) removed from sidebar. * * @subcommand delete */ From 0765dd90f122ebf761b19b49394003b54a03fde2 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 25 May 2016 06:21:30 +0545 Subject: [PATCH 4394/4858] Examples for Widget main class --- php/commands/widget.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index f23f50cf3d..cdf6b91e5c 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -6,16 +6,25 @@ * ## EXAMPLES * * # List widgets on a given sidebar - * wp widget list sidebar-1 + * $ wp widget list sidebar-1 + * +----------+------------+----------+----------------------+ + * | name | id | position | options | + * +----------+------------+----------+----------------------+ + * | meta | meta-6 | 1 | {"title":"Meta"} | + * | calendar | calendar-2 | 2 | {"title":"Calendar"} | + * +----------+------------+----------+----------------------+ * * # Add a calendar widget to the second position on the sidebar - * wp widget add calendar sidebar-1 2 + * $ wp widget add calendar sidebar-1 2 + * Success: Added widget to sidebar. * * # Update option(s) associated with a given widget - * wp widget update calendar-1 --title="Calendar" + * $ wp widget update calendar-1 --title="Calendar" + * Success: Widget updated. * * # Delete one or more widgets entirely - * wp widget delete calendar-2 archive-1 + * $ wp widget delete calendar-2 archive-1 + * Success: Widget(s) removed from sidebar. */ class Widget_Command extends WP_CLI_Command { From 4f2fc72aca1703c6ed89963ad2b65f80b1c0d832 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 11:37:57 +0545 Subject: [PATCH 4395/4858] Example: cap list --- php/commands/cap.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index 3f65b1f239..b469fa1677 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -26,8 +26,13 @@ class Capabilities_Command extends WP_CLI_Command { * * ## EXAMPLES * - * # Display alphabetical list of bbPress moderator capabilities - * wp cap list 'bbp_moderator' | sort + * # Display alphabetical list of Contributor capabilities + * $ wp cap list 'contributor' | sort + * delete_posts + * edit_posts + * level_0 + * level_1 + * read * * @subcommand list */ From 59a4ea226cfb082d0cfeda4570bd088f3883e95e Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 11:42:18 +0545 Subject: [PATCH 4396/4858] Example: cap add --- php/commands/cap.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/cap.php b/php/commands/cap.php index 3f65b1f239..b3471529ac 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -48,6 +48,12 @@ public function list_( $args ) { * * <cap>... * : One or more capabilities to add. + * + * ## EXAMPLES + * + * # Add 'spectate' capability to 'author' role + * $ wp cap add author spectate + * Success: Added 1 capabilities to 'author' role. */ public function add( $args ) { self::persistence_check(); From e9484f1e72fc58ff6dc42b17542a546e530ba799 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 11:45:44 +0545 Subject: [PATCH 4397/4858] Example: cap remove --- php/commands/cap.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/cap.php b/php/commands/cap.php index 3f65b1f239..d76a828c99 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -80,6 +80,12 @@ public function add( $args ) { * * <cap>... * : One or more capabilities to remove. + * + * ## EXAMPLES + * + * # Remove 'spectate' capability from 'author' role + * $ wp cap remove author spectate + * Success: Removed 1 capabilities from 'author' role. */ public function remove( $args ) { self::persistence_check(); From 22cbf21a284df806285c24f1515645ad98c14c11 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 11:52:19 +0545 Subject: [PATCH 4398/4858] Examples for cap main class --- php/commands/cap.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index 3f65b1f239..fdeb1694ff 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -6,13 +6,16 @@ * ## EXAMPLES * * # Add 'spectate' capability to 'author' role - * wp cap add 'author' 'spectate' + * $ wp cap add 'author' 'spectate' + * Success: Added 1 capabilities to 'author' role. * * # Add all caps from 'editor' role to 'author' role - * wp cap list 'editor' | xargs wp cap add 'author' + * $ wp cap list 'editor' | xargs wp cap add 'author' + * Success: Added 24 capabilities to 'author' role. * * # Remove all caps from 'editor' role that also appear in 'author' role * wp cap list 'author' | xargs wp cap remove 'editor' + * Success: Removed 34 capabilities from 'editor' role. */ class Capabilities_Command extends WP_CLI_Command { From 55a2a3289d24b97ec0d12766d4a7aa0f2a39c1a6 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 11:53:09 +0545 Subject: [PATCH 4399/4858] Add missing dollar sign in cap example --- php/commands/cap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index fdeb1694ff..950c62667d 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -14,7 +14,7 @@ * Success: Added 24 capabilities to 'author' role. * * # Remove all caps from 'editor' role that also appear in 'author' role - * wp cap list 'author' | xargs wp cap remove 'editor' + * $ wp cap list 'author' | xargs wp cap remove 'editor' * Success: Removed 34 capabilities from 'editor' role. */ class Capabilities_Command extends WP_CLI_Command { From 0d0a89ea7fa66739dbe01a6b36a5c206454f677c Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Wed, 25 May 2016 06:34:49 +0000 Subject: [PATCH 4400/4858] Add Example: cli check-update & cli param-dump, #2770 --- php/commands/cli.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index 5d81358a23..6c4f6ba1a9 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -104,6 +104,11 @@ public function info( $_, $assoc_args ) { * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## EXAMPLES + * + * $ wp cli check-update + * Success: WP-CLI is at the latest version. + * * @subcommand check-update */ public function check_update( $_, $assoc_args ) { @@ -322,6 +327,11 @@ private function get_updates( $assoc_args ) { * [--format=<format>] * : Accepted values: var_export, json. Default: json. * + * ## EXAMPLES + * + * $ wp cli param-dump + * {"path":{"runtime":"=<path>","file":"<path>","synopsis":"","default":null,"multiple":false,"desc":"Path to the WordPress files."},"url":{"runtime":"=<url>","file":"<url>","synopsis":"","default":null,"multiple":false,"desc":"Pretend request came from given URL. In multisite, this argument is how the target site is specified."},"blog":{"runtime":"=<url>","file":false,"synopsis":"","default":null,"multiple":false,"deprecated":"Use --url instead."},"config":{"runtime":"=<path>","file":false,"synopsis":"","default":null,"multiple":false,"deprecated":"Use the WP_CLI_CONFIG_PATH environment variable instead."},"user":{"runtime":"=<id|login|email>","file":"<id|login|email>","synopsis":"","default":null,"multiple":false,"desc":"Set the WordPress user."},"skip-plugins":{"runtime":"[=<plugin>]","file":"<list>","synopsis":"","default":"","multiple":false,"desc":"Skip loading all or some plugins. Note: mu-plugins are still loaded."},"skip-themes":{"runtime":"[=<theme>]","file":"<list>","synopsis":"","default":"","multiple":false,"desc":"Skip loading all or some themes."},"skip-packages":{"runtime":"","file":"<bool>","synopsis":"","default":false,"multiple":false,"desc":"Skip loading all installed packages."},"require":{"runtime":"=<path>","file":"<path>","synopsis":"","default":[],"multiple":true,"desc":"Load PHP file before running the command (may be used more than once)."},"disabled_commands":{"runtime":false,"file":"<list>","synopsis":"","default":[],"multiple":false,"desc":"(Sub)commands to disable."},"color":{"runtime":true,"file":"<bool>","synopsis":"","default":"auto","multiple":false,"desc":"Whether to colorize the output."},"debug":{"runtime":"","file":"<bool>","synopsis":"","default":false,"multiple":false,"desc":"Show all PHP errors; add verbosity to WP-CLI bootstrap."},"prompt":{"runtime":"","file":false,"synopsis":"","default":false,"multiple":false,"desc":"Prompt the user to enter values for all command arguments."},"quiet":{"runtime":"","file":"<bool>","synopsis":"","default":false,"multiple":false,"desc":"Suppress informational messages."},"apache_modules":{"runtime":false,"file":"<list>","synopsis":"","default":[],"multiple":true,"desc":"List of Apache Modules that are to be reported as loaded."},"allow-root":{"runtime":"","file":false,"synopsis":"","default":null,"multiple":false,"hidden":true}} + * * @subcommand param-dump */ function param_dump( $_, $assoc_args ) { From ebe1008b2bb83290487139acaf77069dcb3646d1 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Wed, 25 May 2016 06:38:04 +0000 Subject: [PATCH 4401/4858] Add Example: eval , #2770 --- php/commands/eval.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/eval.php b/php/commands/eval.php index 11847ccfde..33250f8f16 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -17,7 +17,8 @@ class Eval_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp eval 'echo WP_CONTENT_DIR;' + * $ wp eval 'echo WP_CONTENT_DIR;' + * /var/www/wordpress/wp-content */ public function __invoke( $args, $assoc_args ) { From 1830263c6379f49c1cc0456785c1482c362338d3 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Wed, 25 May 2016 06:38:44 +0000 Subject: [PATCH 4402/4858] Add Example: eval with --skip-wordpress, #2770 --- php/commands/eval.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/eval.php b/php/commands/eval.php index 33250f8f16..12c2c85d71 100644 --- a/php/commands/eval.php +++ b/php/commands/eval.php @@ -19,6 +19,9 @@ class Eval_Command extends WP_CLI_Command { * * $ wp eval 'echo WP_CONTENT_DIR;' * /var/www/wordpress/wp-content + * + * $ wp eval 'echo rand();' --skip-wordpress + * 479620423 */ public function __invoke( $args, $assoc_args ) { From 124c00501f2c56288591a2064ecb088448599ba9 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 17:39:43 +0545 Subject: [PATCH 4403/4858] introduce --format parameter in cap list --- php/commands/cap.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index f5f99d55a8..e63eb1e218 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -19,6 +19,10 @@ */ class Capabilities_Command extends WP_CLI_Command { + private $fields = array( + 'name' + ); + /** * List capabilities for a given role. * @@ -27,6 +31,9 @@ class Capabilities_Command extends WP_CLI_Command { * <role> * : Key for the role. * + * [--format=<format>] + * : Accepted values: table, csv, json, count, yaml. Default: table + * * ## EXAMPLES * * # Display alphabetical list of Contributor capabilities @@ -39,11 +46,19 @@ class Capabilities_Command extends WP_CLI_Command { * * @subcommand list */ - public function list_( $args ) { + public function list_( $args, $assoc_args ) { $role_obj = self::get_role( $args[0] ); - foreach ( array_keys( $role_obj->capabilities ) as $cap ) - WP_CLI::line( $cap ); + $output_caps = array(); + foreach ( array_keys( $role_obj->capabilities ) as $cap ) { + $output_cap = new stdClass; + + $output_cap->name = $cap; + + $output_caps[] = $output_cap; + } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); + $formatter->display_items( $output_caps ); } /** From 26d1e3299c2947d7c1145b71b42826264fd935f0 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 25 May 2016 17:49:55 +0545 Subject: [PATCH 4404/4858] add test scenario for cap list --- features/roles.feature | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/features/roles.feature b/features/roles.feature index 53ac7046ab..5e62fdc846 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -67,9 +67,10 @@ Feature: Manage WordPress roles | name | role | | Reporter | reporter | - When I run `wp cap list reporter` + When I run `wp cap list reporter --format=csv` Then STDOUT should be: """ + name upload_files edit_posts edit_published_posts @@ -81,3 +82,19 @@ Feature: Manage WordPress roles delete_posts delete_published_posts """ + + When I run `wp cap list reporter` + Then STDOUT should be a table containing rows: + """ + | name | + | upload_files | + | edit_posts | + | edit_published_posts | + | publish_posts | + | read | + | level_2 | + | level_1 | + | level_0 | + | delete_posts | + | delete_published_posts | + """ From 5a4abf0faf02c58e22ee7c160f4bfa3bfe92d1e7 Mon Sep 17 00:00:00 2001 From: John Blackbourn <john@johnblackbourn.com> Date: Wed, 25 May 2016 15:01:10 +0100 Subject: [PATCH 4405/4858] Add a missing parameter to the example command for `wp term generate`. --- php/commands/term.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index aeee574f0e..c92fb8b263 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -298,7 +298,7 @@ public function delete( $args ) { * * ## EXAMPLES * - * wp term generate --count=10 + * wp term generate category --count=10 * * # Add meta to every generated term * wp term generate category --format=ids | xargs -0 -d ' ' -I % wp term meta add % foo bar From fdabde6bfdb6daa44060b7699d33a549a5ea8287 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Wed, 25 May 2016 15:00:24 +0000 Subject: [PATCH 4406/4858] Change Example: param-dump , #2770 --- php/commands/cli.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 6c4f6ba1a9..ba8aa7df31 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -329,8 +329,19 @@ private function get_updates( $assoc_args ) { * * ## EXAMPLES * - * $ wp cli param-dump - * {"path":{"runtime":"=<path>","file":"<path>","synopsis":"","default":null,"multiple":false,"desc":"Path to the WordPress files."},"url":{"runtime":"=<url>","file":"<url>","synopsis":"","default":null,"multiple":false,"desc":"Pretend request came from given URL. In multisite, this argument is how the target site is specified."},"blog":{"runtime":"=<url>","file":false,"synopsis":"","default":null,"multiple":false,"deprecated":"Use --url instead."},"config":{"runtime":"=<path>","file":false,"synopsis":"","default":null,"multiple":false,"deprecated":"Use the WP_CLI_CONFIG_PATH environment variable instead."},"user":{"runtime":"=<id|login|email>","file":"<id|login|email>","synopsis":"","default":null,"multiple":false,"desc":"Set the WordPress user."},"skip-plugins":{"runtime":"[=<plugin>]","file":"<list>","synopsis":"","default":"","multiple":false,"desc":"Skip loading all or some plugins. Note: mu-plugins are still loaded."},"skip-themes":{"runtime":"[=<theme>]","file":"<list>","synopsis":"","default":"","multiple":false,"desc":"Skip loading all or some themes."},"skip-packages":{"runtime":"","file":"<bool>","synopsis":"","default":false,"multiple":false,"desc":"Skip loading all installed packages."},"require":{"runtime":"=<path>","file":"<path>","synopsis":"","default":[],"multiple":true,"desc":"Load PHP file before running the command (may be used more than once)."},"disabled_commands":{"runtime":false,"file":"<list>","synopsis":"","default":[],"multiple":false,"desc":"(Sub)commands to disable."},"color":{"runtime":true,"file":"<bool>","synopsis":"","default":"auto","multiple":false,"desc":"Whether to colorize the output."},"debug":{"runtime":"","file":"<bool>","synopsis":"","default":false,"multiple":false,"desc":"Show all PHP errors; add verbosity to WP-CLI bootstrap."},"prompt":{"runtime":"","file":false,"synopsis":"","default":false,"multiple":false,"desc":"Prompt the user to enter values for all command arguments."},"quiet":{"runtime":"","file":"<bool>","synopsis":"","default":false,"multiple":false,"desc":"Suppress informational messages."},"apache_modules":{"runtime":false,"file":"<list>","synopsis":"","default":[],"multiple":true,"desc":"List of Apache Modules that are to be reported as loaded."},"allow-root":{"runtime":"","file":false,"synopsis":"","default":null,"multiple":false,"hidden":true}} + * $ wp cli param-dump --format=var_export + * array ( + * 'path' => + * array ( + * 'runtime' => '=<path>', + * 'file' => '<path>', + * 'synopsis' => '', + * 'default' => NULL, + * 'multiple' => false, + * 'desc' => 'Path to the WordPress files.', + * ), + * 'url' => + * array ( * * @subcommand param-dump */ From 9705f0b0a08b19cc6f8bb7138a9e5897c3e54cd9 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 25 May 2016 23:43:16 +0545 Subject: [PATCH 4407/4858] fix testing of table output --- features/roles.feature | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index 5e62fdc846..9f4764af83 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -86,15 +86,6 @@ Feature: Manage WordPress roles When I run `wp cap list reporter` Then STDOUT should be a table containing rows: """ - | name | - | upload_files | - | edit_posts | - | edit_published_posts | - | publish_posts | - | read | - | level_2 | - | level_1 | - | level_0 | - | delete_posts | - | delete_published_posts | + | name | + | upload_files | """ From 9f7f3cb2ed52e3085c69c146f1630d319e7248b5 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 09:18:49 +0545 Subject: [PATCH 4408/4858] Update doc for cap list as per new standard --- php/commands/cap.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index e63eb1e218..027eccd168 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -32,7 +32,17 @@ class Capabilities_Command extends WP_CLI_Command { * : Key for the role. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: list + * options: + * - list + * - table + * - csv + * - json + * - count + * - yaml + * --- * * ## EXAMPLES * From 40c21d52d0f33f071d9f7235d67b8c6ffb4149b1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 09:28:15 +0545 Subject: [PATCH 4409/4858] Display cap list in list by default --- php/commands/cap.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index 027eccd168..90db4a1d90 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -59,16 +59,23 @@ class Capabilities_Command extends WP_CLI_Command { public function list_( $args, $assoc_args ) { $role_obj = self::get_role( $args[0] ); - $output_caps = array(); - foreach ( array_keys( $role_obj->capabilities ) as $cap ) { - $output_cap = new stdClass; + if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'list' ) ) ) { + foreach ( array_keys( $role_obj->capabilities ) as $cap ) { + WP_CLI::line( $cap ); + } + } + else { + $output_caps = array(); + foreach ( array_keys( $role_obj->capabilities ) as $cap ) { + $output_cap = new stdClass; - $output_cap->name = $cap; + $output_cap->name = $cap; - $output_caps[] = $output_cap; + $output_caps[] = $output_cap; + } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); + $formatter->display_items( $output_caps ); } - $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); - $formatter->display_items( $output_caps ); } /** From dc85b5d35d3311a946b9b72f62c14f774cc57c5d Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 09:37:39 +0545 Subject: [PATCH 4410/4858] Fix test of cap list for --format parameter --- features/roles.feature | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index 9f4764af83..c4df0c9075 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -67,10 +67,9 @@ Feature: Manage WordPress roles | name | role | | Reporter | reporter | - When I run `wp cap list reporter --format=csv` + When I run `wp cap list reporter` Then STDOUT should be: """ - name upload_files edit_posts edit_published_posts @@ -83,9 +82,8 @@ Feature: Manage WordPress roles delete_published_posts """ - When I run `wp cap list reporter` - Then STDOUT should be a table containing rows: + When I run `wp cap list reporter --format=count` + Then STDOUT should be: """ - | name | - | upload_files | + 10 """ From d33c8fa31b33f8b87fd864eb602671baacfdd203 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 10:09:56 +0545 Subject: [PATCH 4411/4858] Fix sniffer issue in cap list --- php/commands/cap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index 90db4a1d90..b89cea9d6f 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -61,7 +61,7 @@ public function list_( $args, $assoc_args ) { if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'list' ) ) ) { foreach ( array_keys( $role_obj->capabilities ) as $cap ) { - WP_CLI::line( $cap ); + WP_CLI::line( $cap ); } } else { From fe1550f293723c8cd4782b252f7a1d7695c2339c Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 12:57:18 +0545 Subject: [PATCH 4412/4858] Example: term list --- php/commands/term.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..9b01395aa0 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -52,9 +52,24 @@ class Term_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp term list category --format=csv - * - * wp term list post_tag --fields=name,slug + * # List post categories + * $ wp term list category --format=csv + * term_id,term_taxonomy_id,name,slug,description,parent,count + * 2,2,aciform,aciform,,0,1 + * 3,3,antiquarianism,antiquarianism,,0,1 + * 4,4,arrangement,arrangement,,0,1 + * 5,5,asmodeus,asmodeus,,0,1 + * + * # List post tags + * $ wp term list post_tag --fields=name,slug + * +-----------+-------------+ + * | name | slug | + * +-----------+-------------+ + * | 8BIT | 8bit | + * | alignment | alignment-2 | + * | Articles | articles | + * | aside | aside | + * +-----------+-------------+ * * @subcommand list */ From b901da35e7e0990d1fc361d5a241d77a8859a384 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:01:05 +0545 Subject: [PATCH 4413/4858] Example: term create --- php/commands/term.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..6f7dea9300 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -118,7 +118,8 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term create category Apple --description="A type of fruit" + * $ wp term create category Apple --description="A type of fruit" + * Success: Created category 199. */ public function create( $args, $assoc_args ) { From ac55695fc888a39207209092ac67cde49574a9b1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:03:52 +0545 Subject: [PATCH 4414/4858] Example: term get --- php/commands/term.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..e41c3dc7db 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -173,7 +173,8 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term get category 1 --format=json + * $ wp term get category 199 --format=json + * {"term_id":199,"name":"Apple","slug":"apple","term_group":0,"term_taxonomy_id":199,"taxonomy":"category","description":"A type of fruit","parent":0,"count":0,"filter":"raw"} */ public function get( $args, $assoc_args ) { From 0bd5fc8c702c0ae6046a1739b99703e5bd177844 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:07:20 +0545 Subject: [PATCH 4415/4858] Example: term update --- php/commands/term.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..27d2aa8861 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -220,7 +220,8 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term update category 15 --name=Apple + * $ wp term update category 15 --name=Apple + * Success: Term updated. */ public function update( $args, $assoc_args ) { From b6072443ededc31a47194783ec7208c60dec3164 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:25:47 +0545 Subject: [PATCH 4416/4858] Example: term delete --- php/commands/term.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..9ab3540cc5 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -260,8 +260,15 @@ public function update( $args, $assoc_args ) { * * ## EXAMPLES * - * # delete all post tags - * wp term list post_tag --field=term_id | xargs wp term delete post_tag + * # Delete post category + * $ wp term delete category 15 + * Success: Deleted category 15. + * + * # Delete all post tags + * $ wp term list post_tag --field=term_id | xargs wp term delete post_tag + * Success: Deleted post_tag 159. + * Success: Deleted post_tag 160. + * Success: Deleted post_tag 161. */ public function delete( $args ) { $taxonomy = array_shift( $args ); From 78573a2c11412c9b2cf88d317eaa20f994fd1094 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:35:36 +0545 Subject: [PATCH 4417/4858] Example: term generate --- php/commands/term.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..6bd0816286 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -298,10 +298,15 @@ public function delete( $args ) { * * ## EXAMPLES * - * wp term generate category --count=10 + * # Generate post categories + * $ wp term generate category --count=10 + * Generating terms 100% [=========] 0:02 / 0:02 * * # Add meta to every generated term - * wp term generate category --format=ids | xargs -0 -d ' ' -I % wp term meta add % foo bar + * $ wp term generate category --format=ids --count=3 | xargs -0 -d ' ' -I % wp term meta add % foo bar + * Success: Added custom field. + * Success: Added custom field. + * Success: Added custom field. */ public function generate( $args, $assoc_args ) { global $wpdb; From a6c06a3606318263aca029de8c911706342baa3a Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:41:48 +0545 Subject: [PATCH 4418/4858] Example: term url --- php/commands/term.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..2829a6178a 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -404,9 +404,8 @@ public function generate( $args, $assoc_args ) { * * ## EXAMPLES * - * wp term url post_tag 123 - * - * wp term url post_tag 123 324 + * $ wp term url post_tag 123 + * http://example.com/tag/tips-and-tricks */ public function url( $args ) { $term_link = get_term_link( (int)$args[1], $args[0] ); From bdef6c5e13502bee300daba78dfec3251f35f519 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 13:49:21 +0545 Subject: [PATCH 4419/4858] Example: term recount --- php/commands/term.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..b325eb320b 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -434,9 +434,18 @@ public function url( $args ) { * * ## EXAMPLES * - * wp term recount category post_tag - * - * wp taxonomy list --field=name | xargs wp term recount + * # Recount posts assigned to each categories and tags + * $ wp term recount category post_tag + * Success: Updated category term count + * Success: Updated post_tag term count + * + * # Recount all listed taxonomies + * $ wp taxonomy list --field=name | xargs wp term recount + * Success: Updated category term count + * Success: Updated post_tag term count + * Success: Updated nav_menu term count + * Success: Updated link_category term count + * Success: Updated post_format term count */ public function recount( $args ) { foreach( $args as $taxonomy ) { From 8b02d3c3fedc097a8b9f71bc8fdbaa2f574aa8ac Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 14:26:34 +0545 Subject: [PATCH 4420/4858] Example: term meta --- php/commands/term.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..8c3b164a6d 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -481,7 +481,21 @@ private function get_formatter( &$assoc_args ) { * * ## EXAMPLES * - * wp term meta set category 123 description "Mary is a WordPress developer." + * # Set term meta + * $ wp term meta set 123 bio "Mary is a WordPress developer." + * Success: Updated custom field 'bio'. + * + * # Get term meta + * $ wp term meta get 123 bio + * Mary is a WordPress developer. + * + * # Update term meta + * $ wp term meta update 123 bio "Mary is an awesome WordPress developer." + * Success: Updated custom field 'bio'. + * + * # Delete term meta + * $ wp term meta delete 123 bio + * Success: Deleted custom field. */ class Term_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'term'; From acc8de086a3d559fcb362e38c62aa27a380dfb73 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 14:51:57 +0545 Subject: [PATCH 4421/4858] Accept multiple term IDs in term url --- php/commands/term.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c92fb8b263..9a275fb2ae 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -409,11 +409,14 @@ public function generate( $args, $assoc_args ) { * wp term url post_tag 123 324 */ public function url( $args ) { - $term_link = get_term_link( (int)$args[1], $args[0] ); - if ( $term_link && ! is_wp_error( $term_link ) ) { - WP_CLI::line( $term_link ); - } else { - WP_CLI::error( "Invalid term." ); + $term_ids = array_slice( $args, 1 ); + foreach ( $term_ids as $term_id ) { + $term_link = get_term_link( (int)$term_id, $args[0] ); + if ( $term_link && ! is_wp_error( $term_link ) ) { + WP_CLI::line( $term_link ); + } else { + WP_CLI::warning( sprintf( "Invalid term %d.", $term_id ) ); + } } } From 5c5d624ddc08d7794a332bcbfa85e9100539ea1c Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 14:55:22 +0545 Subject: [PATCH 4422/4858] Use string placeholder for error message in term url --- php/commands/term.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/term.php b/php/commands/term.php index 9a275fb2ae..8df6543672 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -415,7 +415,7 @@ public function url( $args ) { if ( $term_link && ! is_wp_error( $term_link ) ) { WP_CLI::line( $term_link ); } else { - WP_CLI::warning( sprintf( "Invalid term %d.", $term_id ) ); + WP_CLI::warning( sprintf( "Invalid term %s.", $term_id ) ); } } } From 9f054d090c9decfe24fc210a8dcb7dc2b226aaf4 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 15:37:25 +0545 Subject: [PATCH 4423/4858] Example: taxonomy list --- php/commands/taxonomy.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index 3579ebbf69..b7f9881219 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -57,9 +57,24 @@ public function __construct() { * * ## EXAMPLES * - * wp taxonomy list --format=csv - * - * wp taxonomy list --object-type=post --fields=name,public + * # List all taxonomies + * $ wp taxonomy list --format=csv + * name,label,description,object_type,show_tagcloud,hierarchical,public + * category,Categories,,post,1,1,1 + * post_tag,Tags,,post,1,,1 + * nav_menu,"Navigation Menus",,nav_menu_item,,, + * link_category,"Link Categories",,link,1,, + * post_format,Format,,post,,,1 + * + * # List all taxonomies with 'post' object type + * $ wp taxonomy list --object_type=post --fields=name,public + * +-------------+--------+ + * | name | public | + * +-------------+--------+ + * | category | 1 | + * | post_tag | 1 | + * | post_format | 1 | + * +-------------+--------+ * * @subcommand list */ From 0364d523f87544ac035d51abfbe52692a3ae4e21 Mon Sep 17 00:00:00 2001 From: Dominik Schilling <dominikschilling+git@gmail.com> Date: Thu, 26 May 2016 12:09:43 +0200 Subject: [PATCH 4424/4858] Conditionally require `WP_Site_Query` and `WP_Term_Query` for WP 4.6 compat. --- php/wp-settings-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index ba5c9243ea..b84f3e1d9a 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -124,6 +124,7 @@ // Initialize multisite if enabled. if ( is_multisite() ) { + Utils\maybe_require( '4.6-alpha-37575', ABSPATH . WPINC . '/class-wp-site-query.php' ); require( ABSPATH . WPINC . '/ms-blogs.php' ); require( ABSPATH . WPINC . '/ms-settings.php' ); } elseif ( ! defined( 'MULTISITE' ) ) { @@ -192,6 +193,7 @@ require( ABSPATH . WPINC . '/script-loader.php' ); require( ABSPATH . WPINC . '/taxonomy.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-term.php' ); +Utils\maybe_require( '4.6-alpha-37575', ABSPATH . WPINC . '/class-wp-term-query.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-tax-query.php' ); require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); From b9795d530016ba995e3b7c21e5f3c071a426a18f Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 16:03:40 +0545 Subject: [PATCH 4425/4858] Example: plugin status --- php/commands/plugin.php | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 917b25ae1f..49966cc5b5 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -40,6 +40,27 @@ protected function get_upgrader_class( $force ) { * * [<plugin>] * : A particular plugin to show the status for. + * + * ## EXAMPLES + * + * # Displays status of all plugins + * $ wp plugin status + * 5 installed plugins: + * I akismet 3.1.11 + * I easy-digital-downloads 2.5.16 + * A theme-check 20160523.1 + * I wen-logo-slider 2.0.3 + * M ns-pack 1.0.0 + * Legend: I = Inactive, A = Active, M = Must Use + * + * # Displays status of a plugin + * $ wp plugin status theme-check + * Plugin theme-check details: + * Name: Theme Check + * Status: Active + * Version: 20160523.1 + * Author: Otto42, pross + * Description: A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool! */ function status( $args ) { parent::status( $args ); @@ -456,7 +477,7 @@ protected function get_item_list() { continue; } foreach( $files as $file ) { - $items[ $file ]['name'] = str_replace( '.' . pathinfo( $file, PATHINFO_EXTENSION ), '', $file ); + $items[ $file ]['name'] = str_replace( '.' . pathinfo( $file, PATHINFO_EXTENSION ), '', $file ); } } @@ -786,12 +807,12 @@ private function _delete( $plugin ) { $path = path_join( WP_PLUGIN_DIR, $plugin_dir ); if ( \WP_CLI\Utils\is_windows() ) { - // Handles plugins that are not in own folders + // Handles plugins that are not in own folders // e.g. Hello Dolly -> plugins/hello.php - if ( is_file( $path ) ) { + if ( is_file( $path ) ) { $command = 'del /f /q '; } else { - $command = 'rd /s /q '; + $command = 'rd /s /q '; } $path = str_replace( "/", "\\", $path ); } else { From bdbf4d38742025304ea0c156957f3d31bbb7e1bb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 16:19:22 +0545 Subject: [PATCH 4426/4858] Example: media regenerate --- php/commands/media.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index ddbf001b1c..cfde507473 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -26,11 +26,22 @@ class Media_Command extends WP_CLI_Command { * * ## EXAMPLES * - * # re-generate all thumbnails, without confirmation - * wp media regenerate --yes + * # Re-generate all thumbnails, without confirmation + * $ wp media regenerate --yes + * Found 3 images to regenerate. + * Regenerated thumbnails for "Sydney Harbor Bridge" (ID 760). + * Regenerated thumbnails for "Boardwalk" (ID 757). + * Regenerated thumbnails for "Sunburst Over River" (ID 756). + * Success: Finished regenerating all images. * - * # re-generate all thumbnails that have IDs between 1000 and 2000 - * seq 1000 2000 | xargs wp media regenerate + * # Re-generate all thumbnails that have IDs between 1000 and 2000 + * $ seq 1000 2000 | xargs wp media regenerate + * Found 4 images to regenerate. + * Regenerated thumbnails for "Vertical Featured Image" (ID 1027). + * Regenerated thumbnails for "Horizontal Featured Image" (ID 1022). + * Regenerated thumbnails for "Unicorn Wallpaper" (ID 1045). + * Regenerated thumbnails for "I Am Worth Loving Wallpaper" (ID 1023). + * Success: Finished regenerating all images. */ function regenerate( $args, $assoc_args = array() ) { if ( empty( $args ) ) { From 44f32ab534d8dfe1addfde3a23c800dfc6d03baa Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 16:33:48 +0545 Subject: [PATCH 4427/4858] Example: media import --- php/commands/media.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index ddbf001b1c..e2f6965f79 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -115,19 +115,25 @@ function regenerate( $args, $assoc_args = array() ) { * ## EXAMPLES * * # Import all jpgs in the current user's "Pictures" directory, not attached to any post - * wp media import ~/Pictures/**\/*.jpg + * $ wp media import ~/Pictures/**\/*.jpg + * Success: Imported file /home/person/Pictures/beautiful-youg-girl-in-ivy.jpg as attachment ID 1751. + * Success: Imported file /home/person/Pictures/fashion-girl.jpg as attachment ID 1752. * * # Import a local image and set it to be the post thumbnail for a post - * wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image + * $ wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image + * Success: Imported file /home/person/Downloads/image.png as attachment ID 1753 and attached to post 123 as featured image. * * # Import a local image, but set it as the featured image for all posts * # 1. Import the image and get its attachment ID - * * 2. Assign the attachment ID as the featured image for all posts - * ATTACHMENT_ID="$(wp media import ~/Downloads/image.png --porcelain)" - * wp post list --post_type=post --format=ids | xargs -0 -d ' ' -I % wp post meta add % _thumbnail_id $ATTACHMENT_ID + * # 2. Assign the attachment ID as the featured image for all posts + * $ ATTACHMENT_ID="$(wp media import ~/Downloads/image.png --porcelain)" + * $ wp post list --post_type=post --format=ids | xargs -0 -d ' ' -I % wp post meta add % _thumbnail_id $ATTACHMENT_ID + * Success: Added custom field. + * Success: Added custom field. * * # Import an image from the web - * wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" + * $ wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" + * Success: Imported file http://s.wordpress.org/style/images/wp-header-logo.png as attachment ID 1755. */ function import( $args, $assoc_args = array() ) { $assoc_args = wp_parse_args( $assoc_args, array( From e3c435d8862a01ebd595fa85f25d0c14aca3b075 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 16:37:50 +0545 Subject: [PATCH 4428/4858] Examples for media main class --- php/commands/media.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/php/commands/media.php b/php/commands/media.php index ddbf001b1c..937d3da269 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -3,6 +3,20 @@ /** * Manage attachments. * + * ## EXAMPLES + * + * # Re-generate all thumbnails, without confirmation + * $ wp media regenerate --yes + * Found 3 images to regenerate. + * Regenerated thumbnails for "Sydney Harbor Bridge" (ID 760). + * Regenerated thumbnails for "Boardwalk" (ID 757). + * Regenerated thumbnails for "Sunburst Over River" (ID 756). + * Success: Finished regenerating all images. + * + * # Import a local image and set it to be the featured image for a post + * $ wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image + * Success: Imported file /home/person/Downloads/image.png as attachment ID 1753 and attached to post 123 as featured image. + * * @package wp-cli */ class Media_Command extends WP_CLI_Command { From 32df792a12752165ee13b03cf01c8b45241eeea6 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 26 May 2016 17:28:32 +0545 Subject: [PATCH 4429/4858] Add tests for term url --- features/term.feature | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/features/term.feature b/features/term.feature index 91781bdb90..61b598328e 100644 --- a/features/term.feature +++ b/features/term.feature @@ -92,3 +92,22 @@ Feature: Manage WordPress terms """ My Test Category """ + + Scenario: Fetch term url + When I run `wp term create category "First Category" --porcelain` + And save STDOUT as {TERM_ID_1} + And I run `wp term create category "Second Category" --porcelain` + And save STDOUT as {TERM_ID_2} + + When I run `wp term url category {TERM_ID_1}` + Then STDOUT should be: + """ + http://localhost:8001/category/first-category + """ + + When I run `wp term url category {TERM_ID_1} {TERM_ID_2}` + Then STDOUT should be: + """ + http://localhost:8001/category/first-category + http://localhost:8001/category/second-category + """ From 8b0f9ce01e15e8f8b1ccd51cfb36dd9a20543ba0 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 26 May 2016 21:03:37 +0545 Subject: [PATCH 4430/4858] Example: option add --- php/commands/option.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/option.php b/php/commands/option.php index 787c1e8080..f35b358fc4 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -68,7 +68,8 @@ public function get( $args, $assoc_args ) { * ## EXAMPLES * * # Create an option by reading a JSON file - * wp option add my_option --format=json < config.json + * $ wp option add my_option --format=json < config.json + * Success: Added 'my_option' option. */ public function add( $args, $assoc_args ) { $key = $args[0]; From 1b3ed1b687e4f8f024e416054f9c41288762aa04 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 26 May 2016 21:15:02 +0545 Subject: [PATCH 4431/4858] Example: option delete --- php/commands/option.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/option.php b/php/commands/option.php index 787c1e8080..0552d9b032 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -239,6 +239,11 @@ public function update( $args, $assoc_args ) { * * <key> * : Key for the option. + * + * ## EXAMPLES + * + * $ wp option delete my_option + * Success: Deleted 'my_option' option. */ public function delete( $args ) { list( $key ) = $args; From 76a9d418bcf72080db92dfcea2982d74d90c720b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 26 May 2016 21:31:37 +0545 Subject: [PATCH 4432/4858] modify conditionals in cap list --- php/commands/cap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cap.php b/php/commands/cap.php index b89cea9d6f..0663f248e4 100644 --- a/php/commands/cap.php +++ b/php/commands/cap.php @@ -59,7 +59,7 @@ class Capabilities_Command extends WP_CLI_Command { public function list_( $args, $assoc_args ) { $role_obj = self::get_role( $args[0] ); - if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'list' ) ) ) { + if ( 'list' === $assoc_args['format'] ) { foreach ( array_keys( $role_obj->capabilities ) as $cap ) { WP_CLI::line( $cap ); } From cf17c68d5c50aabdab152d2f20eee4916281135e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 26 May 2016 22:31:54 +0545 Subject: [PATCH 4433/4858] Revert export example after fixing aphostrophe error --- php/commands/export.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/export.php b/php/commands/export.php index fa6f61673d..d0cbb238c1 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -70,6 +70,13 @@ class Export_Command extends WP_CLI_Command { * Starting export process... * Writing to file /tmp/staging.wordpress.2016-05-24.000.xml * Success: All done with export. + * + * # Export a random subset of content + * $ wp export --post__in="$(wp post list --post_type=post --orderby=rand --posts_per_page=8 --format=ids)" + * Starting export process... + * Writing to file /var/www/example.com/public_html/staging.wordpress.2016-05-24.000.xml + * Success: All done with export. + * */ public function __invoke( $_, $assoc_args ) { $defaults = array( From 3bf657b8c5c7f747b0d935875c24ad0320e0f0e0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 26 May 2016 16:25:11 -0700 Subject: [PATCH 4434/4858] Mention the WordPress.org Slack channel --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 810fe5ff93..ddda1de27a 100644 --- a/README.md +++ b/README.md @@ -78,11 +78,13 @@ WP-CLI version: 0.23.0 ## Support -WP-CLI's project maintainers do their best to respond to all bug reports and configuration errors within reason and the constraints on their volunteered time. Before requesting help, please read to find a solution to your problem in the following resources: +WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: - [Common issues and their fixes](http://wp-cli.org/docs/common-issues/) -- [Submit a bug report](http://wp-cli.org/docs/bug-reports/) -- [External resources](http://wp-cli.org/docs/external-resources/) +- [Best practices for submitting a bug report](http://wp-cli.org/docs/bug-reports/) +- [Documentation portal](http://wp-cli.org/docs/) + +If you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). ## Extending From a55c0b903b113d9682f2310cbbb06fe72c9737c3 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:03:10 +0545 Subject: [PATCH 4435/4858] Example: comment create --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..ad0d69dc81 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -40,7 +40,8 @@ public function __construct() { * * ## EXAMPLES * - * wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" + * $ wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" + * Success: Created comment 932. */ public function create( $args, $assoc_args ) { parent::_create( $args, $assoc_args, function ( $params ) { From bee565ad1a97a3a7d2f28cdc2b41e91e9179f6cd Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:06:39 +0545 Subject: [PATCH 4436/4858] Example: comment update --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..31c21ae4e6 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -77,7 +77,8 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment update 123 --comment_author='That Guy' + * $ wp comment update 123 --comment_author='That Guy' + * Success: Updated comment 123. */ public function update( $args, $assoc_args ) { parent::_update( $args, $assoc_args, function ( $params ) { From 012a1a55db0dad0cbe7219baeed80f98c9e7ffa4 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:16:20 +0545 Subject: [PATCH 4437/4858] Example: comment generate --- php/commands/comment.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..b79783533f 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -106,7 +106,10 @@ public function update( $args, $assoc_args ) { * ## EXAMPLES * * # Add meta to every generated comment - * wp comment generate --format=ids | xargs -0 -d ' ' -I % wp comment meta add % foo bar + * $ 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 ) { From 76ee0c12c67e13a121eacfce2a5412661818a8bb Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:22:19 +0545 Subject: [PATCH 4438/4858] Example: comment get --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..6fdef366fb 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -169,7 +169,8 @@ public function generate( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment get 1 --field=content + * $ wp comment get 21 --field=content + * Thanks for all the comments, everyone! */ public function get( $args, $assoc_args ) { $comment_id = (int)$args[0]; From aeeec5e1718338c8f290388f8674b319d21ca155 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:27:17 +0545 Subject: [PATCH 4439/4858] Example: comment delete --- php/commands/comment.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..50e262b58d 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -266,9 +266,14 @@ public function list_( $_, $assoc_args ) { * * ## EXAMPLES * - * wp comment delete 1337 --force - * - * wp comment delete 1337 2341 --force + * # Delete comment + * $ wp comment delete 1337 --force + * Success: Deleted comment 1337. + * + * # Delete multiple comments + * $ wp comment delete 1337 2341 --force + * Success: Deleted comment 1337. + * Success: Deleted comment 2341. */ public function delete( $args, $assoc_args ) { parent::_delete( $args, $assoc_args, function ( $comment_id, $assoc_args ) { From 47df73a606d4912907fcf14e21532a494fc62ca4 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:31:47 +0545 Subject: [PATCH 4440/4858] Example: comment trash --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..1f6b197765 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -323,7 +323,8 @@ private function set_status( $args, $status, $success ) { * * ## EXAMPLES * - * wp comment trash 1337 + * $ wp comment trash 1337 + * Success: Trashed comment 1337. */ public function trash( $args, $assoc_args ) { foreach( $args as $id ) { From e6b13d5888145b7486cb86f2b7389718fc44729a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:34:39 +0545 Subject: [PATCH 4441/4858] Example: comment untrash --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..ea39b811ed 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -341,7 +341,8 @@ public function trash( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment untrash 1337 + * $ wp comment untrash 1337 + * Success: Untrashed comment 1337. */ public function untrash( $args, $assoc_args ) { foreach( $args as $id ) { From eae89a299cddede011144803c6fc7f3e00bdf90d Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:40:23 +0545 Subject: [PATCH 4442/4858] Example: comment spam --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..5fa930fb44 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -359,7 +359,8 @@ public function untrash( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment spam 1337 + * $ wp comment spam 1337 + * Success: Marked as spam comment 1337. */ public function spam( $args, $assoc_args ) { foreach( $args as $id ) { From 11c6931056f61190008cad63bd9f4c9795febf86 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:42:44 +0545 Subject: [PATCH 4443/4858] Example: comment unspam --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..6996863bef 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -377,7 +377,8 @@ public function spam( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment unspam 1337 + * $ wp comment unspam 1337 + * Success: Unspammed comment 1337. */ public function unspam( $args, $assoc_args ) { foreach( $args as $id ) { From d329d3b36fd0a5215a40e24cac0f38cbf322e542 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:46:07 +0545 Subject: [PATCH 4444/4858] Example: comment approve --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..244628c043 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -395,7 +395,8 @@ public function unspam( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment approve 1337 + * $ wp comment approve 1337 + * Success: Approved comment 1337 */ public function approve( $args, $assoc_args ) { foreach( $args as $id ) { From 3db9c15a5e4900578745468ae0338664e55f963d Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:48:46 +0545 Subject: [PATCH 4445/4858] Example: comment unapprove --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..7f97331624 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -413,7 +413,8 @@ public function approve( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment unapprove 1337 + * $ wp comment unapprove 1337 + * Success: Unapproved comment 1337 */ public function unapprove( $args, $assoc_args ) { foreach( $args as $id ) { From bf8a386096de03bc63089350330fe555cdf33f34 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 06:56:33 +0545 Subject: [PATCH 4446/4858] Example: comment count --- php/commands/comment.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..a7e8956e02 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -431,8 +431,25 @@ public function unapprove( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment count - * wp comment count 42 + * # Count comments on whole blog + * $ wp comment count + * approved: 33 + * spam: 3 + * trash: 1 + * post-trashed: 0 + * all: 34 + * moderated: 1 + * total_comments: 37 + * + * # Count comments in a post + * $ wp comment count 42 + * approved: 19 + * spam: 0 + * trash: 0 + * post-trashed: 0 + * all: 19 + * moderated: 0 + * total_comments: 19 */ public function count( $args, $assoc_args ) { $post_id = \WP_CLI\Utils\get_flag_value( $args, 0, 0 ); From d0cc6d11e779169ef95f0f6d03d1bba6c68a0ed5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 07:07:20 +0545 Subject: [PATCH 4447/4858] Example: comment recount --- php/commands/comment.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..35b23aa5e7 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -456,6 +456,11 @@ public function count( $args, $assoc_args ) { * * <id>... * : IDs for one or more posts to update. + * + * ## EXAMPLES + * + * $ wp comment recount 123 + * Updated post 123 comment count to 67 */ public function recount( $args ) { foreach( $args as $id ) { From 60141c24620184992acf33c04d8daa48293116f6 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 07:10:07 +0545 Subject: [PATCH 4448/4858] Example: comment status --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..1cd4e01de3 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -479,7 +479,8 @@ public function recount( $args ) { * * ## EXAMPLES * - * wp comment status 1337 + * $ wp comment status 1337 + * approved */ public function status( $args, $assoc_args ) { list( $comment_id ) = $args; From 235937eb7cabe0d62cc0fa2ed538c30c787afd0a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 07:12:52 +0545 Subject: [PATCH 4449/4858] Example: comment exists --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..e6396bd765 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -503,7 +503,8 @@ public function status( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment exists 1337 + * $ wp comment exists 1337 + * Success: Comment with ID 1337 exists. */ public function exists( $args ) { if ( $this->fetcher->get( $args[0] ) ) { From 94ca05e48f8f6de229fe132fb108cf67e46426ab Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 27 May 2016 07:16:50 +0545 Subject: [PATCH 4450/4858] Example: comment url --- php/commands/comment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index a29f135b2a..736e45071a 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -521,7 +521,8 @@ public function exists( $args ) { * * ## EXAMPLES * - * wp comment url 123 + * $ wp comment url 123 + * http://example.com/about/page-with-comments/#comment-123 */ public function url( $args ) { parent::_url( $args, 'get_comment_link' ); From 33a28043c7fa57b0fdb8a437a28d83cc1153116e Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:11:33 +0000 Subject: [PATCH 4451/4858] add indent #2849 --- php/commands/cli.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index ba8aa7df31..c49b5d6304 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -106,8 +106,8 @@ public function info( $_, $assoc_args ) { * * ## EXAMPLES * - * $ wp cli check-update - * Success: WP-CLI is at the latest version. + * $ wp cli check-update + * Success: WP-CLI is at the latest version. * * @subcommand check-update */ @@ -329,19 +329,19 @@ private function get_updates( $assoc_args ) { * * ## EXAMPLES * - * $ wp cli param-dump --format=var_export - * array ( - * 'path' => - * array ( - * 'runtime' => '=<path>', - * 'file' => '<path>', - * 'synopsis' => '', - * 'default' => NULL, - * 'multiple' => false, - * 'desc' => 'Path to the WordPress files.', - * ), - * 'url' => - * array ( + * $ wp cli param-dump --format=var_export + * array ( + * 'path' => + * array ( + * 'runtime' => '=<path>', + * 'file' => '<path>', + * 'synopsis' => '', + * 'default' => NULL, + * 'multiple' => false, + * 'desc' => 'Path to the WordPress files.', + * ), + * 'url' => + * array ( * * @subcommand param-dump */ From 6e7761c726ca9a1803ac15ae68cf5c769f1876a8 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:19:34 +0000 Subject: [PATCH 4452/4858] Example: site list, #2770 --- php/commands/site.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index 5778c16d5a..1e8120930d 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -413,7 +413,9 @@ private function _get_network( $network_id ) { * ## EXAMPLES * * # Output a simple list of site URLs - * wp site list --field=url + * $ wp site list --field=url + * http://example.com/ + * http://example.com/subdir/ * * @subcommand list */ From f679058304ee6b1c832f2fae26eab568249bbb57 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:25:48 +0000 Subject: [PATCH 4453/4858] Example: site deactivate, #2770 --- php/commands/site.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index 5778c16d5a..bb0b4b0e0a 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -527,7 +527,8 @@ public function activate( $args ) { * * ## EXAMPLES * - * wp site deactivate 123 + * $ wp site deactivate 123 + * Success: Site 123 deactivated. */ public function deactivate( $args ) { $this->update_site_status( $args, 'deleted', 1 ); From a7555d4153cac70504af2143370799c3fb2148fe Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:27:11 +0000 Subject: [PATCH 4454/4858] Example: site activate, #2770 --- php/commands/site.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/site.php b/php/commands/site.php index 5778c16d5a..c7dfc974a4 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -511,7 +511,8 @@ public function unarchive( $args ) { * * ## EXAMPLES * - * wp site activate 123 + * $ wp site activate 123 + * Success: Site 123 activated. */ public function activate( $args ) { $this->update_site_status( $args, 'deleted', 0 ); From ae5a92c3781f817c18aecd2d8c433fccbe7aad92 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:28:57 +0000 Subject: [PATCH 4455/4858] Example: site span & unspam, #2770 --- php/commands/site.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 5778c16d5a..ee0eb26bad 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -543,7 +543,8 @@ public function deactivate( $args ) { * * ## EXAMPLES * - * wp site spam 123 + * $ wp site spam 123 + * Success: Site 123 marked as spam. */ public function spam( $args ) { $this->update_site_status( $args, 'spam', 1 ); @@ -559,7 +560,8 @@ public function spam( $args ) { * * ## EXAMPLES * - * wp site unspam 123 + * $ wp site unspam 123 + * Success: Site 123 removed from spam. * * @subcommand unspam */ From e3abc278bcf6a2969228bf69a85956ff23491b77 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:32:00 +0000 Subject: [PATCH 4456/4858] Example: site archive & unarchive, #2770 --- php/commands/site.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 5778c16d5a..0df3bbdfca 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -479,7 +479,8 @@ public function list_( $_, $assoc_args ) { * * ## EXAMPLES * - * wp site archive 123 + * $ wp site archive 123 + * Success: Site 123 archived. */ public function archive( $args ) { $this->update_site_status( $args, 'archived', 1 ); @@ -495,7 +496,8 @@ public function archive( $args ) { * * ## EXAMPLES * - * wp site unarchive 123 + * $ wp site unarchive 123 + * Success: Site 123 unarchived. */ public function unarchive( $args ) { $this->update_site_status( $args, 'archived', 0 ); From b3ecaf96452da7648ad92ada746761bc401d40f5 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Fri, 27 May 2016 16:34:50 +0000 Subject: [PATCH 4457/4858] Example: site delete, #2770 --- php/commands/site.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/commands/site.php b/php/commands/site.php index 5778c16d5a..b010e2e2d4 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -197,6 +197,13 @@ public function _empty( $args, $assoc_args ) { * * [--keep-tables] * : Delete the blog from the list, but don't drop it's tables. + * + * ## EXAMPLES + * + * $ wp site delete 123 + * Are you sure you want to delete the http://www.example.com/example site? [y/n] y + * Success: The site at http://www.example.com/example was deleted. + * */ function delete( $args, $assoc_args ) { if ( !is_multisite() ) { From 43d312fc3ebd5cb464664e2979841eab4f977c07 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 07:21:03 +0545 Subject: [PATCH 4458/4858] fix strange test issue in term url --- features/term.feature | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/features/term.feature b/features/term.feature index 61b598328e..d2e45f1ea3 100644 --- a/features/term.feature +++ b/features/term.feature @@ -95,19 +95,19 @@ Feature: Manage WordPress terms Scenario: Fetch term url When I run `wp term create category "First Category" --porcelain` - And save STDOUT as {TERM_ID_1} + And save STDOUT as {TERM_ID} And I run `wp term create category "Second Category" --porcelain` - And save STDOUT as {TERM_ID_2} + And save STDOUT as {SECOND_TERM_ID} - When I run `wp term url category {TERM_ID_1}` + When I run `wp term url category {TERM_ID}` Then STDOUT should be: """ - http://localhost:8001/category/first-category + http://example.com/?cat=2 """ - When I run `wp term url category {TERM_ID_1} {TERM_ID_2}` + When I run `wp term url category {TERM_ID} {SECOND_TERM_ID}` Then STDOUT should be: """ - http://localhost:8001/category/first-category - http://localhost:8001/category/second-category + http://example.com/?cat=2 + http://example.com/?cat=3 """ From 64a764b0639d715454d1ede741ab9f38bb588e6b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 08:00:45 +0545 Subject: [PATCH 4459/4858] fix comment id issue in spam and unspam --- php/commands/comment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 34a912cc77..47891656e9 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -301,7 +301,7 @@ public function delete( $args, $assoc_args ) { } private function call( $args, $status, $success, $failure ) { - list( $comment_id ) = $args; + $comment_id = absint( $args ); $func = sprintf( 'wp_%s_comment', $status ); @@ -395,7 +395,7 @@ public function spam( $args, $assoc_args ) { */ public function unspam( $args, $assoc_args ) { foreach( $args as $id ) { - $this->call( $args, __FUNCTION__, 'Unspammed', 'Failed unspamming' ); + $this->call( $id, __FUNCTION__, 'Unspammed', 'Failed unspamming' ); } } From b473ca695beea373a82e961e76f39c1090b7de32 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 08:04:39 +0545 Subject: [PATCH 4460/4858] add test for comment spam/unspam --- features/comment.feature | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index ef11b422ce..12a28912da 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -190,3 +190,32 @@ Feature: Manage WordPress comments 11 """ + Scenario: Spam/unspam comments with multidigit comment ID + Given I run `wp comment delete $(wp comment list --field=ID)` + And I run `wp comment generate --count=10 --quiet` + And I run `wp comment create --porcelain` + And save STDOUT as {COMMENT_ID} + + When I run `wp comment spam {COMMENT_ID}` + Then STDOUT should contain: + """ + Marked as spam comment {COMMENT_ID}. + """ + + When I run `wp comment list --format=count --status=spam` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp comment unspam {COMMENT_ID}` + Then STDOUT should contain: + """ + Unspammed comment {COMMENT_ID}. + """ + + When I run `wp comment list --format=count --status=spam` + Then STDOUT should be: + """ + 0 + """ From 2512afdf71416d6810093fe25d6f29335f0d64b3 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 08:21:11 +0545 Subject: [PATCH 4461/4858] add test for comment trash/unstrash with multidigit comment ID --- features/comment.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 12a28912da..0eaacc0048 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -219,3 +219,33 @@ Feature: Manage WordPress comments """ 0 """ + + Scenario: Trash/untrash comments with multidigit comment ID + Given I run `wp comment delete $(wp comment list --field=ID) --force` + And I run `wp comment generate --count=10 --quiet` + And I run `wp comment create --porcelain` + And save STDOUT as {COMMENT_ID} + + When I run `wp comment trash {COMMENT_ID}` + Then STDOUT should contain: + """ + Success: Trashed comment {COMMENT_ID}. + """ + + When I run `wp comment list --format=count --status=trash` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp comment untrash {COMMENT_ID}` + Then STDOUT should contain: + """ + Untrashed comment {COMMENT_ID}. + """ + + When I run `wp comment list --format=count --status=trash` + Then STDOUT should be: + """ + 0 + """ From 4784ac1f72cdc880e422fcadd252557e6e8a09e2 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 10:23:01 +0545 Subject: [PATCH 4462/4858] Add more tests for scaffold child-theme --- features/scaffold.feature | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 9b52d6cd65..7ece65d815 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -9,6 +9,38 @@ Feature: WordPress code scaffolding When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com` Then STDOUT should not be empty And the {THEME_DIR}/zombieland/style.css file should exist + And the {THEME_DIR}/zombieland/functions.php file should exist + + Scenario: Scaffold a child theme with only --parent_theme parameter + Given a WP install + Given I run `wp theme path` + And save STDOUT as {THEME_DIR} + + When I run `wp scaffold child-theme hello-world --parent_theme=simple-life` + Then STDOUT should not be empty + And the {THEME_DIR}/hello-world/style.css file should exist + And the {THEME_DIR}/hello-world/style.css file should contain: + """ + Theme Name: Hello-world + """ + + Scenario: Scaffold a child theme with non existing parent theme and also activate parameter + Given a WP install + + When I try `wp scaffold child-theme hello-world --parent_theme=just-test --activate --quiet` + Then STDERR should contain: + """ + Error: The parent theme is missing. Please install the "just-test" parent theme. + """ + + Scenario: Scaffold a child theme with non existing parent theme and also network activate parameter + Given a WP install + + When I try `wp scaffold child-theme hello-world --parent_theme=just-test --enable-network --quiet` + Then STDERR should contain: + """ + Error: This is not a multisite install. + """ Scenario: Scaffold a child theme and network enable it Given a WP multisite install From b9c64f963361678c4f488ff99bc74122d6a4e4db Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 11:54:37 +0545 Subject: [PATCH 4463/4858] Example: comment list --- php/commands/comment.php | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 34a912cc77..b8b5f60457 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -235,11 +235,29 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp comment list --field=ID - * - * wp comment list --post_id=2 - * - * wp comment list --number=20 --status=approve + * # List comment IDs + * $ wp comment list --field=ID + * 22 + * 23 + * 24 + * + * # List comments of a post + * $ wp comment list --post_id=1 --fields=ID,comment_date,comment_author + * +------------+---------------------+----------------+ + * | comment_ID | comment_date | comment_author | + * +------------+---------------------+----------------+ + * | 1 | 2015-06-20 09:00:10 | Mr WordPress | + * +------------+---------------------+----------------+ + * + * # List approved comments + * $ wp comment list --number=3 --status=approve --fields=ID,comment_date,comment_author + * +------------+---------------------+----------------+ + * | comment_ID | comment_date | comment_author | + * +------------+---------------------+----------------+ + * | 1 | 2015-06-20 09:00:10 | Mr WordPress | + * | 30 | 2013-03-14 12:35:07 | John Doe | + * | 29 | 2013-03-14 11:56:08 | Jane Doe | + * +------------+---------------------+----------------+ * * @subcommand list */ From 016447447f3c053e0ccb5e03433f499a81a92a6e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:01:12 +0545 Subject: [PATCH 4464/4858] Examples for comment main --- php/commands/comment.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 34a912cc77..3414210408 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -5,8 +5,22 @@ * * ## EXAMPLES * - * # delete all spam comments. - * wp comment delete $(wp comment list --status=spam --format=ids) + * # Create comment + * $ wp comment create --comment_post_ID=15 --comment_content="hello blog" --comment_author="wp-cli" + * Success: Created comment 932. + * + * # Update comment + * $ wp comment update 123 --comment_author='That Guy' + * Success: Updated comment 123. + * + * # Delete comment + * $ wp comment delete 1337 --force + * Success: Deleted comment 1337. + * + * # Delete all spam comments. + * $ wp comment delete $(wp comment list --status=spam --format=ids) + * Success: Deleted comment 264. + * Success: Deleted comment 262. * * @package wp-cli */ From 00f94bfd25673ed8c15b5fa5cb4ae9d53f8423b5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:06:10 +0545 Subject: [PATCH 4465/4858] Examples for comment meta --- php/commands/comment.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index 34a912cc77..4be14dcfa1 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -579,7 +579,21 @@ public function url( $args ) { * * ## EXAMPLES * - * wp comment meta set 123 description "Mary is a WordPress developer." + * # Set comment meta + * $ wp comment meta set 123 description "Mary is a WordPress developer." + * Success: Updated custom field 'description'. + * + * # Get comment meta + * $ wp comment meta get 123 description + * Mary is a WordPress developer. + * + * # Update comment meta + * $ wp comment meta update 123 description "Mary is an awesome WordPress developer." + * Success: Updated custom field 'description'. + * + * # Delete comment meta + * $ wp comment meta delete 123 description + * Success: Deleted custom field. */ class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'comment'; From d9335ebdb87989410b5dd7dd91220711cf014dfd Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:18:38 +0545 Subject: [PATCH 4466/4858] Examples for term main class --- php/commands/term.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index 58b9c1bc0a..92119f5b0a 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -2,6 +2,33 @@ /** * Manage terms. * + * ## EXAMPLES + * + * # Create term + * $ wp term create category Apple --description="A type of fruit" + * Success: Created category 199. + * + * # Get term + * $ wp term get category 199 --format=json --fields=term_id,name,slug,count + * {"term_id":199,"name":"Apple","slug":"apple","count":1} + * + * # Update term + * $ wp term update category 15 --name=Apple + * Success: Term updated. + * + * # Get term url + * $ wp term url post_tag 123 + * http://example.com/tag/tips-and-tricks + * + * # Delete post category + * $ wp term delete category 15 + * Success: Deleted category 15. + * + * # Recount posts assigned to each categories and tags + * $ wp term recount category post_tag + * Success: Updated category term count + * Success: Updated post_tag term count + * * @package wp-cli */ class Term_Command extends WP_CLI_Command { From ec381cc75f8d505ee12d9da4b12e264ccfa0b7ec Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:36:00 +0545 Subject: [PATCH 4467/4858] Examples for menu main class --- php/commands/menu.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..4afa70057f 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -6,16 +6,25 @@ * ## EXAMPLES * * # Create a new menu - * wp menu create "My Menu" + * $ wp menu create "My Menu" + * Success: Created menu 200. * * # List existing menus - * wp menu list + * $ wp menu list + * +---------+----------+----------+-----------+-------+ + * | term_id | name | slug | locations | count | + * +---------+----------+----------+-----------+-------+ + * | 200 | My Menu | my-menu | | 0 | + * | 177 | Top Menu | top-menu | primary | 7 | + * +---------+----------+----------+-----------+-------+ * * # Create a new menu link item - * wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain + * $ wp menu item add-custom my-menu Apple http://apple.com --porcelain + * 1922 * - * # Assign the 'primary-menu' menu to the 'primary' location - * wp menu location assign primary-menu primary + * # Assign the 'my-menu' menu to the 'primary' location + * $ wp menu location assign my-menu primary + * Success: Assigned location to menu. */ class Menu_Command extends WP_CLI_Command { From a30f3bc3023ba239b0b470e4d911906b7d13bf53 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:39:34 +0545 Subject: [PATCH 4468/4858] Example: menu create --- php/commands/menu.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..3b7f861406 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -41,7 +41,8 @@ class Menu_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp menu create "My Menu" + * $ wp menu create "My Menu" + * Success: Created menu 200. */ public function create( $args, $assoc_args ) { From e93ff861e38c523c46ec0b59fb73747db70fe98e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:42:19 +0545 Subject: [PATCH 4469/4858] Example: menu list --- php/commands/menu.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..9c03a4f60e 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -123,7 +123,13 @@ public function delete( $args, $_ ) { * * ## EXAMPLES * - * wp menu list + * $ wp menu list + * +---------+----------+----------+-----------+-------+ + * | term_id | name | slug | locations | count | + * +---------+----------+----------+-----------+-------+ + * | 200 | My Menu | my-menu | | 0 | + * | 177 | Top Menu | top-menu | primary | 7 | + * +---------+----------+----------+-----------+-------+ * * @subcommand list */ From 16dbc9cd58951f0f67e35f0c2bf5f09f6cd2aca1 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 12:44:39 +0545 Subject: [PATCH 4470/4858] Example: menu delete --- php/commands/menu.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..5cd837939c 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -72,7 +72,8 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu delete "My Menu" + * $ wp menu delete "My Menu" + * Success: Menu(s) deleted. */ public function delete( $args, $_ ) { From fedda19193124b8de97623d0a81754f52a667cb5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 15:43:40 +0545 Subject: [PATCH 4471/4858] Example: menu location list --- php/commands/menu.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..f5c0f3f5bc 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -661,7 +661,13 @@ class Menu_Location_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp menu location list + * $ wp menu location list + * +----------+-------------------+ + * | location | description | + * +----------+-------------------+ + * | primary | Primary Menu | + * | social | Social Links Menu | + * +----------+-------------------+ * * @subcommand list */ From 4906bd31254dbacd01cbc8f6dc6e3b2782adf55a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 15:46:39 +0545 Subject: [PATCH 4472/4858] Example: menu location assign --- php/commands/menu.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..8b7bf4143a 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -693,7 +693,8 @@ public function list_( $_, $assoc_args ) { * * ## EXAMPLES * - * wp menu location assign primary-menu primary + * $ wp menu location assign primary-menu primary + * Success: Assigned location to menu. * * @subcommand assign */ From 60a1a3665debad7d3c1f53fdd5d1d2706f512a8d Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 15:54:37 +0545 Subject: [PATCH 4473/4858] Example: menu location remove --- php/commands/menu.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index b4272494fe..26e323b5bc 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -732,7 +732,8 @@ public function assign( $args, $_ ) { * * ## EXAMPLES * - * wp menu location remove primary-menu primary + * $ wp menu location remove primary-menu primary + * Success: Removed location from menu. * * @subcommand remove */ From 07069c9cf6ac2c4bbe4705423c02112e7b841f9e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 21:57:55 +0545 Subject: [PATCH 4474/4858] Example: theme enable --- php/commands/theme.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 2ff81bbf9e..7ef8f14062 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -200,11 +200,17 @@ public function activate( $args = array() ) { * * ## EXAMPLES * - * wp theme enable twentythirteen + * # Enable theme + * $ wp theme enable twentysixteen + * Success: Enabled the 'Twenty Sixteen' theme. * - * wp theme enable twentythirteen --network + * # Network enable theme + * $ wp theme enable twentysixteen --network + * Success: Network enabled the 'Twenty Sixteen' theme. * - * wp theme enable twentythirteen --activate + * # Network enable and activate theme for current site + * $ wp theme enable twentysixteen --activate + * Success: Enabled the 'Twenty Sixteen' theme. */ public function enable( $args, $assoc_args ) { if ( ! is_multisite() ) { From 3f76e9f64aa0e3133d74b1cdb2862335ae27f112 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 28 May 2016 22:02:43 +0545 Subject: [PATCH 4475/4858] Add missing success message in theme enable with activate --- php/commands/theme.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 7ef8f14062..d2f3443e47 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -211,6 +211,7 @@ public function activate( $args = array() ) { * # Network enable and activate theme for current site * $ wp theme enable twentysixteen --activate * Success: Enabled the 'Twenty Sixteen' theme. + * Success: Switched to 'Twenty Sixteen' theme. */ public function enable( $args, $assoc_args ) { if ( ! is_multisite() ) { From d4575b938156465aef06d6f8af9913319fec8b8c Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 31 May 2016 09:01:07 +0545 Subject: [PATCH 4476/4858] Add examples for db commands --- php/commands/db.php | 71 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 6c87dcb243..cb5afe820a 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -13,6 +13,11 @@ class DB_Command extends WP_CLI_Command { * Runs `CREATE_DATABASE` MySQL statement using `DB_HOST`, `DB_NAME`, * `DB_USER` and `DB_PASSWORD` database credentials specified in * wp-config.php. + * + * ## EXAMPLES + * + * $ wp db create + * Success: Database created. */ public function create( $_, $assoc_args ) { @@ -32,7 +37,7 @@ public function create( $_, $assoc_args ) { * * [--yes] * : Answer yes to the confirmation message. - * + * * ## EXAMPLES * * $ wp db drop --yes @@ -57,7 +62,7 @@ public function drop( $_, $assoc_args ) { * * [--yes] * : Answer yes to the confirmation message. - * + * * ## EXAMPLES * * $ wp db reset --yes @@ -81,6 +86,11 @@ public function reset( $_, $assoc_args ) { * * [See docs](http://dev.mysql.com/doc/refman/5.7/en/optimize-table.html) * for more details on the `OPTIMIZE_TABLE` statement. + * + * ## EXAMPLES + * + * $ wp db optimize + * Success: Database optimized. */ public function optimize() { self::run( Utils\esc_cmd( 'mysqlcheck --no-defaults %s', DB_NAME ), array( @@ -99,6 +109,11 @@ public function optimize() { * * [See docs](http://dev.mysql.com/doc/refman/5.7/en/repair-table.html) for * more details on the `REPAIR_TABLE` statement. + * + * ## EXAMPLES + * + * $ wp db repair + * Success: Database repaired. */ public function repair() { self::run( Utils\esc_cmd( 'mysqlcheck --no-defaults %s', DB_NAME ), array( @@ -111,6 +126,12 @@ public function repair() { /** * Open a MySQL console using credentials from wp-config.php * + * ## EXAMPLES + * + * # Open MySQL console + * $ wp db cli + * mysql> + * * @alias connect */ public function cli() { @@ -132,11 +153,27 @@ public function cli() { * * ## EXAMPLES * - * # execute a query stored in a file + * # Execute a query stored in a file * wp db query < debug.sql * - * # check all tables in the database + * # Check all tables in the database * wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" + * +---------------------------------------+-------+----------+----------+ + * | Table | Op | Msg_type | Msg_text | + * +---------------------------------------+-------+----------+----------+ + * | wordpress_dbase.wp_users | check | status | OK | + * | wordpress_dbase.wp_usermeta | check | status | OK | + * | wordpress_dbase.wp_posts | check | status | OK | + * | wordpress_dbase.wp_comments | check | status | OK | + * | wordpress_dbase.wp_links | check | status | OK | + * | wordpress_dbase.wp_options | check | status | OK | + * | wordpress_dbase.wp_postmeta | check | status | OK | + * | wordpress_dbase.wp_terms | check | status | OK | + * | wordpress_dbase.wp_term_taxonomy | check | status | OK | + * | wordpress_dbase.wp_term_relationships | check | status | OK | + * | wordpress_dbase.wp_termmeta | check | status | OK | + * | wordpress_dbase.wp_commentmeta | check | status | OK | + * +---------------------------------------+-------+----------+----------+ */ public function query( $args ) { $assoc_args = array( @@ -170,14 +207,21 @@ public function query( $args ) { * * ## EXAMPLES * - * wp db export --add-drop-table - * wp db export --tables=wp_options,wp_users + * # Export database with drop query included + * $ wp db export --add-drop-table + * Success: Exported to wordpress_dbase.sql + * + * # Export certain tables + * $ wp db export --tables=wp_options,wp_users + * Success: Exported to wordpress_dbase.sql * * # Export all tables matching a wildcard - * wp db export --tables=$(wp db tables 'wp_user*' --format=csv) + * $ wp db export --tables=$(wp db tables 'wp_user*' --format=csv) + * Success: Exported to wordpress_dbase.sql * * # Export all tables matching prefix - * wp db export --tables=$(wp db tables --all-tables-with-prefix --format=csv) + * $ wp db export --tables=$(wp db tables --all-tables-with-prefix --format=csv) + * Success: Exported to wordpress_dbase.sql * * @alias dump */ @@ -218,6 +262,11 @@ function export( $args, $assoc_args ) { * * [<file>] * : The name of the SQL file to import. If '-', then reads from STDIN. If omitted, it will look for '{dbname}.sql'. + * + * ## EXAMPLES + * + * $ wp db import wordpress_dbase.sql + * Success: Imported from wordpress_dbase.sql */ public function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); @@ -275,10 +324,8 @@ public function import( $args, $assoc_args ) { * ## EXAMPLES * * # Export only tables for a single site - * wp db export --tables=$(wp db tables --url=sub.example.com --format=csv) - * - * # Export all tables matching prefix - * wp db export --tables=$(wp db tables --all-tables-with-prefix --format=csv) + * $ wp db export --tables=$(wp db tables --url=sub.example.com --format=csv) + * Success: Exported to wordpress_dbase.sql */ function tables( $args, $assoc_args ) { From 86f996dee7aded45c87ec5c0880ce2332ab5a029 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 31 May 2016 16:15:59 +0545 Subject: [PATCH 4477/4858] Add examples for cron commands --- php/commands/cron.php | 56 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 4f8a6a4f6f..d552661f66 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -49,9 +49,19 @@ class Cron_Event_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp cron event list - * - * wp cron event list --fields=hook,next_run --format=json + * # List scheduled cron events + * $ wp cron event list + * +-------------------+---------------------+---------------------+------------+ + * | hook | next_run_gmt | next_run_relative | recurrence | + * +-------------------+---------------------+---------------------+------------+ + * | wp_version_check | 2016-05-31 22:15:13 | 11 hours 57 minutes | 12 hours | + * | wp_update_plugins | 2016-05-31 22:15:13 | 11 hours 57 minutes | 12 hours | + * | wp_update_themes | 2016-05-31 22:15:14 | 11 hours 57 minutes | 12 hours | + * +-------------------+---------------------+---------------------+------------+ + * + * # List scheduled cron events in JSON + * $ wp cron event list --fields=hook,next_run --format=json + * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] * * @subcommand list */ @@ -100,11 +110,17 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp cron event schedule cron_test + * # Schedule a new cron event + * $ wp cron event schedule cron_test + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:19:16 GMT. * - * wp cron event schedule cron_test now hourly + * # Schedule new cron event with hourly recurrence + * $ wp cron event schedule cron_test now hourly + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:20:32 GMT. * - * wp cron event schedule cron_test '+1 hour' --foo=1 --bar=2 + * # Schedule new cron event and pass associative arguments + * $ wp cron event schedule cron_test '+1 hour' --foo=1 --bar=2 + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 11:21:35 GMT. */ public function schedule( $args, $assoc_args ) { @@ -165,7 +181,8 @@ public function schedule( $args, $assoc_args ) { * ## EXAMPLES * * # Run all cron events due right now - * wp cron event run --due-now + * $ wp cron event run --due-now + * Success: Executed a total of 2 cron event(s). */ public function run( $args, $assoc_args ) { @@ -248,6 +265,12 @@ protected static function run_event( stdClass $event ) { * * <hook> * : The hook name + * + * ## EXAMPLES + * + * # Delete the next scheduled cron event + * $ wp cron event delete cron_test + * Success: Deleted 2 instances of the cron event 'cron_test' */ public function delete( $args, $assoc_args ) { @@ -454,9 +477,19 @@ class Cron_Schedule_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp cron schedule list + * # List available cron schedules + * $ wp cron schedule list + * +------------+-------------+----------+ + * | name | display | interval | + * +------------+-------------+----------+ + * | hourly | Once Hourly | 3600 | + * | twicedaily | Twice Daily | 43200 | + * | daily | Once Daily | 86400 | + * +------------+-------------+----------+ * - * wp cron schedule list --fields=name --format=ids + * # List id of available cron schedule + * $ wp cron schedule list --fields=name --format=ids + * hourly twicedaily daily * * @subcommand list */ @@ -527,6 +560,11 @@ class Cron_Command extends WP_CLI_Command { * * Checks to see if the `ALTERNATE_WP_CRON` constant is set; warns if true * * Attempts to spawn WP-Cron over HTTP; warns if non 200 response code is * returned. + * + * ## EXAMPLES + * + * $ wp cron test + * Success: WP-Cron spawning is working as expected. */ public function test() { From daf08407233c9c435ce41cdbb66255ad946ea2dd Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 31 May 2016 16:20:56 +0545 Subject: [PATCH 4478/4858] Examples for menu location commands --- php/commands/menu.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 1ba04d14d2..095047a21c 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -651,13 +651,21 @@ protected function get_formatter( &$assoc_args ) { * ## EXAMPLES * * # List available menu locations - * wp menu location list + * $ wp menu location list + * +----------+-------------------+ + * | location | description | + * +----------+-------------------+ + * | primary | Primary Menu | + * | social | Social Links Menu | + * +----------+-------------------+ * * # Assign the 'primary-menu' menu to the 'primary' location - * wp menu location assign primary-menu primary + * $ wp menu location assign primary-menu primary + * Success: Assigned location to menu. * * # Remove the 'primary-menu' menu from the 'primary' location - * wp menu location remove primary-menu primary + * $ wp menu location remove primary-menu primary + * Success: Removed location from menu. */ class Menu_Location_Command extends WP_CLI_Command { From 92b8cf91770541301a4e1c43818ccd8fb7ec6fe7 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 31 May 2016 16:41:23 +0545 Subject: [PATCH 4479/4858] Add examples for Menu Item main class --- php/commands/menu.php | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 1ba04d14d2..6d3855f4ea 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -187,10 +187,16 @@ protected function get_formatter( &$assoc_args ) { * ## EXAMPLES * * # Add an existing post to an existing menu - * wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * $ wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * Success: Menu item added. * * # Create a new menu link item - * wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain + * $ wp menu item add-custom sidebar-menu Apple http://apple.com + * Success: Menu item added. + * + * # Delete menu item + * $ wp menu item delete 45 + * Success: Menu item(s) deleted. */ class Menu_Item_Command extends WP_CLI_Command { @@ -241,7 +247,13 @@ class Menu_Item_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp menu item list <menu> + * $ wp menu item list main-menu + * +-------+-----------+-------------+---------------------------------+----------+ + * | db_id | type | title | link | position | + * +-------+-----------+-------------+---------------------------------+----------+ + * | 5 | custom | Home | http://example.com | 1 | + * | 6 | post_type | Sample Page | http://example.com/sample-page/ | 2 | + * +-------+-----------+-------------+---------------------------------+----------+ * * @subcommand list */ @@ -311,7 +323,8 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * $ wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * Success: Menu item added. * * @subcommand add-post */ @@ -371,7 +384,8 @@ public function add_post( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu item add-term sidebar-menu post_tag 24 + * $ wp menu item add-term sidebar-menu post_tag 24 + * Success: Menu item added. * * @subcommand add-term */ @@ -426,7 +440,8 @@ public function add_term( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu item add-custom sidebar-menu Apple http://apple.com --porcelain + * $ wp menu item add-custom sidebar-menu Apple http://apple.com + * Success: Menu item added. * * @subcommand add-custom */ @@ -473,7 +488,8 @@ public function add_custom( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu item update 45 --title=WordPress --link='http://wordpress.org' --target=_blank --position=2 + * $ wp menu item update 45 --title=WordPress --link='http://wordpress.org' --target=_blank --position=2 + * Success: Menu item updated. * * @subcommand update */ @@ -502,7 +518,8 @@ public function update( $args, $assoc_args ) { * * ## EXAMPLES * - * wp menu item delete 45 + * $ wp menu item delete 45 + * Success: Menu item(s) deleted. * * @subcommand delete */ From c25542260a960346342d9ca224e3ac823d85d7da Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 31 May 2016 06:00:02 -0700 Subject: [PATCH 4480/4858] Prevent pass by reference PHP notice --- php/WP_CLI/CommandWithTranslation.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index d4735e9c34..628f57f7f9 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -176,9 +176,10 @@ public function update( $args, $assoc_args ) { } // Gets the translation data. - $translation = (object) reset( wp_list_filter( $all_languages, array( + $translation = wp_list_filter( $all_languages, array( 'language' => $update->language - ) ) ); + ) ); + $translation = (object) reset( $translation ); $update->Type = ucfirst( $update->type ); $update->Name = $name; From c3148b4d7a2794fd7e8814bc6b2b445ac46e52ea Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 31 May 2016 20:19:40 +0545 Subject: [PATCH 4481/4858] Example: cron schedule --- php/commands/cron.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index d552661f66..1fe92de68a 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -442,6 +442,18 @@ private function get_formatter( &$assoc_args ) { /** * Manage WP-Cron schedules. + * + * ## EXAMPLES + * + * # List available cron schedules + * $ wp cron schedule list + * +------------+-------------+----------+ + * | name | display | interval | + * +------------+-------------+----------+ + * | hourly | Once Hourly | 3600 | + * | twicedaily | Twice Daily | 43200 | + * | daily | Once Daily | 86400 | + * +------------+-------------+----------+ */ class Cron_Schedule_Command extends WP_CLI_Command { From b89175b19115bdc2790611f4d71f2fd3bb11e280 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 31 May 2016 20:24:51 +0545 Subject: [PATCH 4482/4858] Example for main cron command --- php/commands/cron.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index d552661f66..ed9c498b27 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -548,6 +548,12 @@ private function get_formatter( &$assoc_args ) { /** * Manage WP-Cron events and schedules. + * + * ## EXAMPLES + * + * # Test WP Cron spawning system + * $ wp cron test + * Success: WP-Cron spawning is working as expected. */ class Cron_Command extends WP_CLI_Command { From 6a392cba4ca7f143e351478df6d2621e9d4f9a4d Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 31 May 2016 20:31:12 +0545 Subject: [PATCH 4483/4858] Examples for cron event main command class --- php/commands/cron.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index d552661f66..b34dfcd473 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -3,6 +3,24 @@ /** * Manage WP-Cron events. * + * ## EXAMPLES + * + * # Schedule a new cron event + * $ wp cron event schedule cron_test + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:19:16 GMT. + * + * # Run all cron events due right now + * $ wp cron event run --due-now + * Success: Executed a total of 2 cron event(s). + * + * # Delete the next scheduled cron event + * $ wp cron event delete cron_test + * Success: Deleted 2 instances of the cron event 'cron_test' + * + * # List scheduled cron events in JSON + * $ wp cron event list --fields=hook,next_run --format=json + * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] + * */ class Cron_Event_Command extends WP_CLI_Command { From 642be052ff7242e73c06cfd359d8a14876ec3d3b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 31 May 2016 20:52:48 +0545 Subject: [PATCH 4484/4858] Add examples for subcommands of cli --- php/commands/cli.php | 52 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index c49b5d6304..ee8ac7b7ef 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -7,6 +7,23 @@ /** * Get information about WP-CLI itself. * + * ## EXAMPLES + * + * # Display CLI version + * $ wp cli version + * WP-CLI 0.23.1 + * + * # Check for update + * $ wp cli check-update + * Success: WP-CLI is at the latest version. + * + * # Update CLI + * $ wp cli update + * You have version 0.23.0. Would you like to update to 0.23.1? [y/n] y + * Downloading from https://github.com/wp-cli/wp-cli/releases/download/v0.23.1/wp-cli-0.23.1.phar... + * New version works. Proceeding to replace. + * Success: Updated WP-CLI to 0.23.1 + * * @when before_wp_load */ class CLI_Command extends WP_CLI_Command { @@ -31,6 +48,11 @@ private function command_to_array( $command ) { /** * Print WP-CLI version. + * + * ## EXAMPLES + * + * $ wp cli version + * WP-CLI 0.23.1 */ public function version() { WP_CLI::line( 'WP-CLI ' . WP_CLI_VERSION ); @@ -46,8 +68,15 @@ public function version() { * * ## EXAMPLES * - * $ wp cli version - * WP-CLI 0.23.1 + * $ wp cli info + * PHP binary: /usr/bin/php5 + * PHP version: 5.5.9-1ubuntu4.16 + * php.ini used: /etc/php5/cli/php.ini + * WP-CLI root dir: phar://wp-cli.phar + * WP-CLI packages dir: /home/person/.wp-cli/packages/ + * WP-CLI global config: + * WP-CLI project config: + * WP-CLI version: 0.23.1 */ public function info( $_, $assoc_args ) { $php_bin = WP_CLI::get_php_binary(); @@ -105,10 +134,19 @@ public function info( $_, $assoc_args ) { * : Accepted values: table, csv, json, count. Default: table * * ## EXAMPLES - * + * + * # Check for update * $ wp cli check-update * Success: WP-CLI is at the latest version. * + * # Check for update and new version is available + * $ wp cli check-update + * +---------+-------------+-------------------------------------------------------------------------------+ + * | version | update_type | package_url | + * +---------+-------------+-------------------------------------------------------------------------------+ + * | 0.23.1 | patch | https://github.com/wp-cli/wp-cli/releases/download/v0.23.1/wp-cli-0.23.1.phar | + * +---------+-------------+-------------------------------------------------------------------------------+ + * * @subcommand check-update */ public function check_update( $_, $assoc_args ) { @@ -331,7 +369,7 @@ private function get_updates( $assoc_args ) { * * $ wp cli param-dump --format=var_export * array ( - * 'path' => + * 'path' => * array ( * 'runtime' => '=<path>', * 'file' => '<path>', @@ -340,7 +378,7 @@ private function get_updates( $assoc_args ) { * 'multiple' => false, * 'desc' => 'Path to the WordPress files.', * ), - * 'url' => + * 'url' => * array ( * * @subcommand param-dump @@ -371,6 +409,10 @@ function param_dump( $_, $assoc_args ) { /** * Dump the list of installed commands, as JSON. * + * # Dump the list of installed commands + * $ wp cli version + * {"name":"wp","description":"Manage WordPress through the command-line.","longdesc":"\n\n## GLOBAL PARAMETERS\n\n --path=<path>\n Path to the WordPress files.\n\n --ssh=<ssh>\n Perform operation against a remote server over SSH.\n\n --url=<url>\n Pretend request came from given URL. In multisite, this argument is how the target site is specified. \n\n --user=<id|login|email>\n + * * @subcommand cmd-dump */ public function cmd_dump() { From dd19031d709f8fcc3de2474f5f8375e8ca537460 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 31 May 2016 20:54:42 +0545 Subject: [PATCH 4485/4858] fix error in command example in cli cmd-dump --- php/commands/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index ee8ac7b7ef..c5ced77bed 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -410,7 +410,7 @@ function param_dump( $_, $assoc_args ) { * Dump the list of installed commands, as JSON. * * # Dump the list of installed commands - * $ wp cli version + * $ wp cli cmd-dump * {"name":"wp","description":"Manage WordPress through the command-line.","longdesc":"\n\n## GLOBAL PARAMETERS\n\n --path=<path>\n Path to the WordPress files.\n\n --ssh=<ssh>\n Perform operation against a remote server over SSH.\n\n --url=<url>\n Pretend request came from given URL. In multisite, this argument is how the target site is specified. \n\n --user=<id|login|email>\n * * @subcommand cmd-dump From 0498beb8333bcc88f848e60960d4f5d87549ab7b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 31 May 2016 21:23:38 +0545 Subject: [PATCH 4486/4858] Examples for post-type commands --- php/commands/post-type.php | 42 ++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/php/commands/post-type.php b/php/commands/post-type.php index ae73a2dd0f..c42a741ef1 100644 --- a/php/commands/post-type.php +++ b/php/commands/post-type.php @@ -2,6 +2,23 @@ /** * Manage post types. * + * ## EXAMPLES + * + * # Get a post type + * $ wp post-type get page --fields=name,label,hierarchical --format=json + * {"name":"page","label":"Pages","hierarchical":true} + * + * # List post types with 'post' capability type + * $ wp post-type list --capability_type=post --fields=name,public + * +---------------+--------+ + * | name | public | + * +---------------+--------+ + * | post | 1 | + * | attachment | 1 | + * | revision | | + * | nav_menu_item | | + * +---------------+--------+ + * * @package wp-cli */ class Post_Type_Command extends WP_CLI_Command { @@ -47,9 +64,25 @@ class Post_Type_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp post-type list --format=csv - * - * wp post-type list --capability_type=post --fields=name,public + * # List registered post types + * $ wp post-type list --format=csv + * name,label,description,hierarchical,public,capability_type + * post,Posts,,,1,post + * page,Pages,,1,1,page + * attachment,Media,,,1,post + * revision,Revisions,,,,post + * nav_menu_item,"Navigation Menu Items",,,,post + * + * # List post types with 'post' capability type + * $ wp post-type list --capability_type=post --fields=name,public + * +---------------+--------+ + * | name | public | + * +---------------+--------+ + * | post | 1 | + * | attachment | 1 | + * | revision | | + * | nav_menu_item | | + * +---------------+--------+ * * @subcommand list */ @@ -80,7 +113,8 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp post-type get page --format=json + * $ wp post-type get page --fields=name,label,hierarchical --format=json + * {"name":"page","label":"Pages","hierarchical":true} */ public function get( $args, $assoc_args ) { $post_type = get_post_type_object( $args[0] ); From a262a095555c2bef4a58db8cfa1ad4c20eaf12f1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 1 Jun 2016 08:40:13 +0545 Subject: [PATCH 4487/4858] Add examples for main db class --- php/commands/db.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index cb5afe820a..265b747111 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -4,6 +4,23 @@ /** * Perform basic database operations. + * + * ## EXAMPLES + * + * # Create database + * $ wp db create + * Success: Database created. + * + * # Drop database + * $ wp db drop --yes + * Success: Database dropped. + * + * # Reset database + * $ wp db reset --yes + * Success: Database reset. + * + * # Execute a query stored in a file + * $ wp db query < debug.sql */ class DB_Command extends WP_CLI_Command { @@ -154,10 +171,10 @@ public function cli() { * ## EXAMPLES * * # Execute a query stored in a file - * wp db query < debug.sql + * $ wp db query < debug.sql * * # Check all tables in the database - * wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" + * $ wp db query "CHECK TABLE $(wp db tables | paste -s -d',');" * +---------------------------------------+-------+----------+----------+ * | Table | Op | Msg_type | Msg_text | * +---------------------------------------+-------+----------+----------+ From b345f318b138145064486909ce936bd40c8a09e7 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 1 Jun 2016 08:58:46 +0545 Subject: [PATCH 4488/4858] Add examples for option commands --- php/commands/option.php | 57 +++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index f4c5603547..4328879643 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -10,13 +10,21 @@ * * ## EXAMPLES * - * wp option get siteurl + * # Get site URL + * $ wp option get siteurl + * http://example.com * - * wp option add my_option foobar + * # Add option + * $ wp option add my_option foobar + * Success: Added 'my_option' option. * - * wp option update my_option '{"foo": "bar"}' --format=json + * # Update option + * $ wp option update my_option '{"foo": "bar"}' --format=json + * Success: Updated 'my_option' option. * - * wp option delete my_option + * # Delete option + * $ wp option delete my_option + * Success: Deleted 'my_option' option. */ class Option_Command extends WP_CLI_Command { @@ -105,17 +113,6 @@ public function add( $args, $assoc_args ) { * [--format=<format>] * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. Accepted values: table, json, csv, count, total_bytes. Default: table * - * ## EXAMPLES - * - * # Get the total size of all autoload options - * wp option list --autoload=on --format=total_bytes - * - * # Find biggest transients - * wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail - * - * # List all options begining with "i2f_" - * wp option list --search "i2f_*" - * * ## AVAILABLE FIELDS * * This field will be displayed by default for each matching option: @@ -128,6 +125,29 @@ public function add( $args, $assoc_args ) { * * autoload * * size_bytes * + * ## EXAMPLES + * + * # Get the total size of all autoload options + * $ wp option list --autoload=on --format=total_bytes + * 33198 + * + * # Find biggest transients + * $ wp option list --search="*_transient_*" --fields=option_name,size_bytes | sort -n -k 2 | tail + * option_name size_bytes + * _site_transient_timeout_theme_roots 10 + * _site_transient_theme_roots 76 + * _site_transient_update_themes 181 + * _site_transient_update_core 808 + * _site_transient_update_plugins 6645 + * + * # List all options begining with "i2f_" + * $ wp option list --search="i2f_*" + * +-------------+--------------+ + * | option_name | option_value | + * +-------------+--------------+ + * | i2f_version | 0.1.0 | + * +-------------+--------------+ + * * @subcommand list */ public function list_( $args, $assoc_args ) { @@ -203,10 +223,13 @@ public function list_( $args, $assoc_args ) { * ## EXAMPLES * * # Update an option by reading from a file - * wp option update my_option < value.txt + * $ wp option update my_option < value.txt + * Success: Updated 'my_option' option. * * # Update one option on multiple sites using xargs - * wp site list --field=url | xargs -n1 -I {} sh -c 'wp --url={} option update <key> <value>' + * $ wp site list --field=url | xargs -n1 -I {} sh -c 'wp --url={} option update my_option my_value' + * Success: Updated 'my_option' option. + * Success: Updated 'my_option' option. * * @alias set */ From 6d4d1572401b3132557937e8b259ae83858f7491 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 1 Jun 2016 18:34:33 +0545 Subject: [PATCH 4489/4858] Example: network meta --- php/commands/network.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/commands/network.php b/php/commands/network.php index 709c16b497..3b0c47ddbf 100644 --- a/php/commands/network.php +++ b/php/commands/network.php @@ -13,8 +13,11 @@ * * ## EXAMPLES * - * # get a list of super-admins - * wp network meta get 1 site_admins + * # Get a list of super-admins + * $ wp network meta get 1 site_admins + * array ( + * 0 => 'supervisor', + * ) */ class Network_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'site'; From 090f6c8ecc931a32d39ea7380ec5bebcb2ee12d5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 1 Jun 2016 18:51:06 +0545 Subject: [PATCH 4490/4858] Add examples for plugin commands --- php/commands/plugin.php | 48 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 49966cc5b5..30f941ba8d 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -5,6 +5,31 @@ /** * Manage plugins. * + * ## EXAMPLES + * + * # Activate plugin + * $ wp plugin activate hello-dolly + * Success: Plugin 'hello-dolly' activated. + * + * # Deactivate plugin + * $ wp plugin deactivate hello-dolly + * Success: Plugin 'hello-dolly' deactivated. + * + * # Delete plugin + * $ wp plugin delete hello-dolly + * Success: Deleted 'hello-dolly' plugin. + * + * # Install the latest version from wordpress.org and activate + * $ wp plugin install bbpress --activate + * Installing bbPress (2.5.9) + * Downloading install package from https://downloads.wordpress.org/plugin/bbpress.2.5.9.zip... + * Using cached file '/home/vagrant/.wp-cli/cache/plugin/bbpress-2.5.9.zip'... + * Unpacking the package... + * Installing the plugin... + * Plugin installed successfully. + * Activating 'bbpress'... + * Success: Plugin 'bbpress' activated. + * * @package wp-cli */ class Plugin_Command extends \WP_CLI\CommandWithUpgrade { @@ -185,6 +210,16 @@ protected function get_all_items() { * * [--network] * : If set, the plugin will be activated for the entire multisite network. + * + * ## EXAMPLES + * + * # Activate plugin + * $ wp plugin activate hello-dolly + * Success: Plugin 'hello-dolly' activated. + * + * # Activate plugin in entire multisite network + * $ wp plugin activate hello-dolly --network + * Success: Plugin 'hello-dolly' network activated. */ function activate( $args, $assoc_args = array() ) { $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); @@ -246,6 +281,12 @@ function activate( $args, $assoc_args = array() ) { * * [--network] * : If set, the plugin will be deactivated for the entire multisite network. + * + * ## EXAMPLES + * + * # Deactivate plugin + * $ wp plugin deactivate hello-dolly + * Success: Plugin 'hello-dolly' deactivated. */ function deactivate( $args, $assoc_args = array() ) { $network_wide = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ); @@ -654,8 +695,10 @@ function uninstall( $args, $assoc_args = array() ) { * * ## EXAMPLES * - * wp plugin is-installed hello - * echo $? # displays 0 or 1 + * # Check whether plugin is installed; exit status 0 if installed, otherwise 1 + * $ wp plugin is-installed hello-dolly + * $ echo $? + * 1 * * @subcommand is-installed */ @@ -677,6 +720,7 @@ function is_installed( $args, $assoc_args = array() ) { * * ## EXAMPLES * + * # Delete plugin * $ wp plugin delete hello * Success: Deleted 'hello' plugin. * From 6a63133f5cd4e9059382723885af815b19328d70 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 1 Jun 2016 20:42:10 +0545 Subject: [PATCH 4491/4858] Add examples for post commands --- php/commands/post.php | 125 +++++++++++++++++++++++++++++++++--------- 1 file changed, 100 insertions(+), 25 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index aa75dfd21b..856d04776a 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -3,6 +3,20 @@ /** * Manage posts. * + * ## EXAMPLES + * + * # Create post + * $ wp post create --post_type=post --post_title='A sample post' + * Success: Created post 123. + * + * # Update post + * $ wp post update 123 --post_status=draft + * Success: Updated post 123. + * + * # Delete post + * $ wp post delete 123 + * Success: Trashed post 123. + * * @package wp-cli */ class Post_Command extends \WP_CLI\CommandWithDBObject { @@ -46,9 +60,13 @@ public function __construct() { * * ## EXAMPLES * - * wp post create --post_type=page --post_title='A future post' --post_status=future --post_date='2020-12-01 07:00:00' + * # Create post and schedule for future + * $ wp post create --post_type=page --post_title='A future post' --post_status=future --post_date='2020-12-01 07:00:00' + * Success: Created post 1921. * - * wp post create ./post-content.txt --post_category=201,345 --post_title='Post from file' + * # Create post with content from given file + * $ wp post create ./post-content.txt --post_category=201,345 --post_title='Post from file' + * Success: Created post 1922. */ public function create( $args, $assoc_args ) { if ( ! empty( $args[0] ) ) { @@ -96,7 +114,8 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp post update 123 --post_name=something --post_status=draft + * $ wp post update 123 --post_name=something --post_status=draft + * Success: Updated post 123. */ public function update( $args, $assoc_args ) { @@ -129,7 +148,8 @@ public function update( $args, $assoc_args ) { * * ## EXAMPLES * - * wp post edit 123 + * # Launch system editor to edit post + * $ wp post edit 123 */ public function edit( $args, $_ ) { $post = $this->fetcher->get_check( $args[0] ); @@ -168,8 +188,8 @@ protected function _edit( $content, $title ) { * * ## EXAMPLES * - * # save the post content to a file - * wp post get 12 --field=content > file.txt + * # Save the post content to a file + * $ wp post get 123 --field=content > file.txt */ public function get( $args, $assoc_args ) { $post = $this->fetcher->get_check( $args[0] ); @@ -201,12 +221,19 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp post delete 123 --force + * # Delete post skipping trash + * $ wp post delete 123 --force + * Success: Deleted post 123. * - * wp post delete $(wp post list --post_type='page' --format=ids) + * # Delete all pages + * $ wp post delete $(wp post list --post_type='page' --format=ids) + * Success: Trashed post 1164. + * Success: Trashed post 1186. * - * # delete all posts in the trash - * wp post delete $(wp post list --post_status=trash --format=ids) + * # Delete all posts in the trash + * $ wp post delete $(wp post list --post_status=trash --format=ids) + * Success: Trashed post 1268. + * Success: Trashed post 1294. */ public function delete( $args, $assoc_args ) { $defaults = array( @@ -280,15 +307,37 @@ public function delete( $args, $assoc_args ) { * * ## EXAMPLES * - * wp post list --field=ID - * - * wp post list --post_type=post --posts_per_page=5 --format=json - * - * wp post list --post_type=page --fields=post_title,post_status - * - * wp post list --post_type=page,post --format=ids - * - * wp post list --post__in=1,3 + * # List post + * $ wp post list --field=ID + * 568 + * 829 + * 1329 + * 1695 + * + * # List posts in JSON + * $ wp post list --post_type=post --posts_per_page=5 --format=json + * [{"ID":1,"post_title":"Hello world!","post_name":"hello-world","post_date":"2015-06-20 09:00:10","post_status":"publish"},{"ID":1178,"post_title":"Markup: HTML Tags and Formatting","post_name":"markup-html-tags-and-formatting","post_date":"2013-01-11 20:22:19","post_status":"draft"}] + * + * # List all pages + * $ wp post list --post_type=page --fields=post_title,post_status + * +-------------+-------------+ + * | post_title | post_status | + * +-------------+-------------+ + * | Sample Page | publish | + * +-------------+-------------+ + * + * # List ids of all pages and posts + * $ wp post list --post_type=page,post --format=ids + * 15 25 34 37 198 + * + * # List given posts + * $ wp post list --post__in=1,3 + * +----+--------------+-------------+---------------------+-------------+ + * | ID | post_title | post_name | post_date | post_status | + * +----+--------------+-------------+---------------------+-------------+ + * | 3 | Lorem Ipsum | lorem-ipsum | 2016-06-01 14:34:36 | publish | + * | 1 | Hello world! | hello-world | 2016-06-01 14:31:12 | publish | + * +----+--------------+-------------+---------------------+-------------+ * * @subcommand list */ @@ -357,11 +406,22 @@ public function list_( $_, $assoc_args ) { * * ## 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 + * # Generate posts + * $ wp post generate --count=10 --post_type=page --post_date=1999-01-04 + * Generating posts 100% [================================================] 0:01 / 0:04 + * + * # Generate posts with fetched content + * $ curl http://loripsum.net/api/5 | wp post generate --post_content --count=10 + * % Total % Received % Xferd Average Speed Time Time Time Current + * Dload Upload Total Spent Left Speed + * 100 2509 100 2509 0 0 616 0 0:00:04 0:00:04 --:--:-- 616 + * Generating posts 100% [================================================] 0:01 / 0:04 * * # Add meta to every generated post - * wp post generate --format=ids | xargs -0 -d ' ' -I % wp post meta add % foo bar + * $ wp post generate --format=ids | xargs -0 -d ' ' -I % wp post meta add % foo bar + * Success: Added custom field. + * Success: Added custom field. + * Success: Added custom field. */ public function generate( $args, $assoc_args ) { global $wpdb; @@ -501,7 +561,21 @@ private function read_from_file_or_stdin( $arg ) { * * ## EXAMPLES * - * wp post meta set 123 _wp_page_template about.php + * # Set post meta + * $ wp post meta set 123 _wp_page_template about.php + * Success: Updated custom field '_wp_page_template'. + * + * # Get post meta + * $ wp post meta get 123 _wp_page_template + * about.php + * + * # Update post meta + * $ wp post meta update 123 _wp_page_template contact.php + * Success: Updated custom field '_wp_page_template'. + * + * # Delete post meta + * $ wp post meta delete 123 _wp_page_template + * Success: Deleted custom field. */ class Post_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'post'; @@ -521,10 +595,11 @@ protected function check_object_id( $object_id ) { /** * Manage post terms. * - * * ## EXAMPLES * - * wp post term set 123 test category + * # Set post terms + * $ wp post term set 123 test category + * Set terms. */ class Post_Term_Command extends \WP_CLI\CommandWithTerms { protected $obj_type = 'post'; From 7c0faf2b79aab738066fac294dca3a54180e01ab Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 1 Jun 2016 16:29:01 -0700 Subject: [PATCH 4492/4858] Add more explicit tests for skip-plugins feature --- features/skip-plugins.feature | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/features/skip-plugins.feature b/features/skip-plugins.feature index 2dc828d8c8..8105cc620e 100644 --- a/features/skip-plugins.feature +++ b/features/skip-plugins.feature @@ -24,10 +24,10 @@ Feature: Skipping plugins """ # The specified plugin should still show up as an active plugin - When I run `wp --skip-plugins=akismet plugin status` + When I run `wp --skip-plugins=akismet plugin status akismet` Then STDOUT should contain: """ - akismet + Status: Active """ # The un-specified plugin should continue to be loaded @@ -85,3 +85,20 @@ Feature: Skipping plugins """ Call to undefined function hello_dolly() """ + + Scenario: Skip network active plugins + Given a WP multisite install + And I run `wp plugin deactivate akismet` + And I run `wp plugin activate --network akismet` + + When I run `wp eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );'` + Then STDOUT should be: + """ + false + """ From 2d5c1f8e6ad756b1a0a8ea353c56c1e22c001c60 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 2 Jun 2016 08:49:51 +0545 Subject: [PATCH 4493/4858] Add examples for package commands --- php/commands/package.php | 82 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 4129c92fd1..bc73402808 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -28,6 +28,41 @@ * Learn how to create your own command from the * [Commands Cookbook](http://wp-cli.org/docs/commands-cookbook/) * + * ## EXAMPLES + * + * # List installed packages + * $ wp package list + * +-----------------------+------------------------------------------+---------+------------+ + * | name | description | authors | version | + * +-----------------------+------------------------------------------+---------+------------+ + * | wp-cli/server-command | Start a development server for WordPress | | dev-master | + * +-----------------------+------------------------------------------+---------+------------+ + * + * # Install the latest development version of the package + * $ wp package install wp-cli/server-command + * Installing wp-cli/server-command (dev-master) + * Updating /home/person/.wp-cli/packages/composer.json to require the package... + * Using Composer to install the package... + * --- + * Loading composer repositories with package information + * Updating dependencies + * Resolving dependencies through SAT + * Dependency resolution completed in 0.005 seconds + * Analyzed 732 packages to resolve dependencies + * Analyzed 1034 rules to resolve dependencies + * - Installing package + * Writing lock file + * Generating autoload files + * --- + * Success: Package installed successfully. + * + * # Uninstall package + * $ wp package uninstall wp-cli/server-command + * Removing require statement from /home/person/.wp-cli/packages/composer.json + * Deleting package directory /home/person/.wp-cli/packages/vendor/wp-cli/server-command + * Regenerating Composer autoload. + * Success: Uninstalled package. + * * @package WP-CLI * * @when before_wp_load @@ -67,11 +102,26 @@ public function browse( $_, $assoc_args ) { * * ## EXAMPLES * - * # install the latest development version - * wp package install wp-cli/server-command + * # Install the latest development version + * $ wp package install wp-cli/server-command + * Installing wp-cli/server-command (dev-master) + * Updating /home/person/.wp-cli/packages/composer.json to require the package... + * Using Composer to install the package... + * --- + * Loading composer repositories with package information + * Updating dependencies + * Resolving dependencies through SAT + * Dependency resolution completed in 0.005 seconds + * Analyzed 732 packages to resolve dependencies + * Analyzed 1034 rules to resolve dependencies + * - Installing package + * Writing lock file + * Generating autoload files + * --- + * Success: Package installed successfully. * - * # install the latest stable version - * wp package install wp-cli/server-command:@stable + * # Install the latest stable version + * $ wp package install wp-cli/server-command:@stable */ public function install( $args, $assoc_args ) { list( $package_name ) = $args; @@ -146,6 +196,15 @@ public function install( $args, $assoc_args ) { * [--format=<format>] * : Accepted values: table, json, csv, yaml, ids. Default: table * + * ## EXAMPLES + * + * $ wp package list + * +-----------------------+------------------------------------------+---------+------------+ + * | name | description | authors | version | + * +-----------------------+------------------------------------------+---------+------------+ + * | wp-cli/server-command | Start a development server for WordPress | | dev-master | + * +-----------------------+------------------------------------------+---------+------------+ + * * @subcommand list */ public function list_( $args, $assoc_args ) { @@ -164,7 +223,12 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * cd $(wp package path) + * # Get package path + * $ wp package path + * /home/person/.wp-cli/packages/ + * + * # Change directory to package path + * $ cd $(wp package path) */ function path( $args ) { $packages_dir = WP_CLI::get_runner()->get_packages_dir_path(); @@ -184,6 +248,14 @@ function path( $args ) { * * <name> * : Name of the package to uninstall. + * + * ## EXAMPLES + * + * $ wp package uninstall wp-cli/server-command + * Removing require statement from /home/person/.wp-cli/packages/composer.json + * Deleting package directory /home/person/.wp-cli/packages/vendor/wp-cli/server-command + * Regenerating Composer autoload. + * Success: Uninstalled package. */ public function uninstall( $args ) { list( $package_name ) = $args; From 05130b40e74ccd29d01fa50fba95f8dceefe8e1e Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 2 Jun 2016 09:04:50 +0545 Subject: [PATCH 4494/4858] Add examples for site commands --- php/commands/site.php | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 6e754c0029..d2971c588a 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -3,6 +3,22 @@ /** * Perform site-wide operations. * + * ## EXAMPLES + * + * # Create site + * $ wp site create --slug=example + * Success: Site 3 created: www.example.com/example/ + * + * # Output a simple list of site URLs + * $ wp site list --field=url + * http://www.example.com/ + * http://www.example.com/subdir/ + * + * # Delete site + * $ wp site delete 123 + * Are you sure you want to delete the http://www.example.com/example site? [y/n] y + * Success: The site at http://www.example.com/example was deleted. + * * @package wp-cli */ class Site_Command extends \WP_CLI\CommandWithDBObject { @@ -143,6 +159,12 @@ private function _insert_default_terms() { * [--yes] * : Proceed to empty the site without a confirmation prompt. * + * ## EXAMPLES + * + * $ wp site empty + * Are you sure you want to empty the site at http://www.example.com of all posts, comments, and terms? [y/n] y + * Success: The site at http://www.example.com was emptied. + * * @subcommand empty */ public function _empty( $args, $assoc_args ) { @@ -203,7 +225,6 @@ public function _empty( $args, $assoc_args ) { * $ wp site delete 123 * Are you sure you want to delete the http://www.example.com/example site? [y/n] y * Success: The site at http://www.example.com/example was deleted. - * */ function delete( $args, $assoc_args ) { if ( !is_multisite() ) { @@ -255,6 +276,11 @@ function delete( $args, $assoc_args ) { * * [--porcelain] * : If set, only the site id will be output on success. + * + * ## EXAMPLES + * + * $ wp site create --slug=example + * Success: Site 3 created: www.example.com/example/ */ public function create( $_, $assoc_args ) { if ( !is_multisite() ) { @@ -421,8 +447,8 @@ private function _get_network( $network_id ) { * * # Output a simple list of site URLs * $ wp site list --field=url - * http://example.com/ - * http://example.com/subdir/ + * http://www.example.com/ + * http://www.example.com/subdir/ * * @subcommand list */ From 1bdddcfe4dbaf8c00cf9406dfa0d7642dae21ff9 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 2 Jun 2016 14:38:35 +0545 Subject: [PATCH 4495/4858] Add examples for core commands --- php/commands/core.php | 67 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index a00cf63c07..38d9124462 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -32,6 +32,15 @@ class Core_Command extends WP_CLI_Command { * [--format=<format>] * : Accepted values: table, csv, json, yaml. Default: table * + * ## EXAMPLES + * + * $ wp core check-update + * +---------+-------------+-------------------------------------------------------------+ + * | version | update_type | package_url | + * +---------+-------------+-------------------------------------------------------------+ + * | 4.5.2 | major | https://downloads.wordpress.org/release/wordpress-4.5.2.zip | + * +---------+-------------+-------------------------------------------------------------+ + * * @subcommand check-update */ function check_update( $_, $assoc_args ) { @@ -68,7 +77,10 @@ function check_update( $_, $assoc_args ) { * * ## EXAMPLES * - * wp core download --locale=nl_NL + * $ wp core download --locale=nl_NL + * Downloading WordPress 4.5.2 (nl_NL)... + * md5 hash verified: c5366d05b521831dd0b29dfc386e56a5 + * Success: WordPress downloaded. * * @when before_wp_load */ @@ -318,13 +330,15 @@ private static function get_initial_locale() { * ## EXAMPLES * * # Standard wp-config.php file - * wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --locale=ro_RO + * $ wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --locale=ro_RO + * Success: Generated wp-config.php file. * * # Enable WP_DEBUG and WP_DEBUG_LOG - * wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP - * define( 'WP_DEBUG', true ); - * define( 'WP_DEBUG_LOG', true ); - * PHP + * $ wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP + * $ define( 'WP_DEBUG', true ); + * $ define( 'WP_DEBUG_LOG', true ); + * $ PHP + * Success: Generated wp-config.php file. */ public function config( $_, $assoc_args ) { global $wp_version; @@ -445,6 +459,11 @@ public function is_installed( $_, $assoc_args ) { * * [--skip-email] * : Don't send an email notification to the new admin user. + * + * ## EXAMPLES + * + * $ wp core install --url=example.com --title=Example --admin_user=supervisor --admin_password=strongpassword --admin_email=info@example.com + * Success: WordPress installed successfully. */ public function install( $args, $assoc_args ) { if ( $this->_install( $assoc_args ) ) { @@ -791,9 +810,11 @@ private static function get_clean_basedomain() { * * ## EXAMPLES * + * # Display the WordPress version * $ wp core version * 4.5.2 * + * # Display WordPress version along with other information * $ wp core version --extra * WordPress version: 4.5.2 * Database revision: 36686 @@ -841,15 +862,19 @@ public function version( $args = array(), $assoc_args = array() ) { * * ## EXAMPLES * + * # Verify checksums * $ wp core verify-checksums * Success: WordPress install verifies against checksums. * + * # Verify checksums for given WordPress version * $ wp core verify-checksums --version=4.0 * Success: WordPress install verifies against checksums. * + * # Verify checksums for given locale * $ wp core verify-checksums --locale=en_US * Success: WordPress install verifies against checksums. * + * # Verify checksums for given locale * $ wp core verify-checksums --locale=ja * Warning: File doesn't verify against checksum: wp-includes/version.php * Warning: File doesn't verify against checksum: readme.html @@ -1059,6 +1084,7 @@ private static function get_core_checksums( $version, $locale ) { * * ## EXAMPLES * + * # Update WordPress * $ wp core update * Updating to version 4.5.2 (en_US)... * Downloading update from https://downloads.wordpress.org/release/wordpress-4.5.2-no-content.zip... @@ -1067,6 +1093,7 @@ private static function get_core_checksums( $version, $locale ) { * No files found that need cleaned up * Success: WordPress updated successfully. * + * # Update WordPress to latest version of 3.8 release * $ wp core update --version=3.8 ../latest.zip * Updating to version 3.8 ()... * Unpacking the update... @@ -1077,6 +1104,7 @@ private static function get_core_checksums( $version, $locale ) { * 377 files cleaned up * Success: WordPress updated successfully. * + * # Update WordPress to 3.1 forcefully * $ wp core update --version=3.1 --force * Updating to version 3.1 (en_US)... * Downloading update from https://wordpress.org/wordpress-3.1.zip... @@ -1211,9 +1239,11 @@ function update( $args, $assoc_args ) { * * ## EXAMPLES * + * # Update the WordPress database * $ wp core update-db * Success: WordPress database upgraded successfully from db version 36686 to 35700 * + * # Update databases for all sites on a network * $ wp core update-db --network * WordPress database upgraded successfully from db version 35700 to 29630 on example.com/ * Success: WordPress database upgraded on 123/123 sites @@ -1402,6 +1432,31 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { WP_CLI::add_command( 'core', 'Core_Command' ); +/** + * Manage core language. + * + * ## EXAMPLES + * + * # Install language + * $ wp core language install nl_NL + * Success: Language installed. + * + * # Activate language + * $ wp core language activate nl_NL + * Success: Language activated. + * + * # Uninstall language + * $ wp core language uninstall nl_NL + * Success: Language uninstalled. + * + * # List installed languages + * $ wp core language list --status=installed + * +----------+--------------+-------------+-----------+-----------+---------------------+ + * | language | english_name | native_name | status | update | updated | + * +----------+--------------+-------------+-----------+-----------+---------------------+ + * | nl_NL | Dutch | Nederlands | installed | available | 2016-05-13 08:12:50 | + * +----------+--------------+-------------+-----------+-----------+---------------------+ + */ class Core_Language_Command extends WP_CLI\CommandWithTranslation { protected $obj_type = 'core'; From 75f3e45e47ff284e01dc36636fb1ac4daac60cee Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 2 Jun 2016 17:08:53 +0545 Subject: [PATCH 4496/4858] Add examples for scaffold commands --- php/commands/scaffold.php | 42 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 7f29542a6d..795a284691 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -6,6 +6,21 @@ /** * Generate code for post types, taxonomies, etc. * + * ## EXAMPLES + * + * # Generate plugin + * $ wp scaffold plugin sample-plugin + * Success: Created plugin files. + * Success: Created test files. + * + * # Generate theme based on _s + * $ wp scaffold _s sample-theme --theme_name="Sample Theme" --author="John Doe" + * Success: Created theme 'Sample Theme'. + * + * # Generate code for post type registration in given theme + * $ wp scaffold post-type movie --label=Movie --theme=simple-life + * Success: Created /var/www/example.com/public_html/wp-content/themes/simple-life/post-types/movie.php + * * @package wp-cli */ class Scaffold_Command extends WP_CLI_Command { @@ -40,6 +55,11 @@ class Scaffold_Command extends WP_CLI_Command { * [--force] * : Overwrite files that already exist. * + * ## EXAMPLES + * + * $ wp scaffold post-type movie --label=Movie --theme=simple-life + * Success: Created /var/www/example.com/public_html/wp-content/themes/simple-life/post-types/movie.php + * * @subcommand post-type * * @alias cpt @@ -93,7 +113,8 @@ function post_type( $args, $assoc_args ) { * * ## EXAMPLES * - * wp scaffold taxonomy venue --post_types=event,presentation + * # Generate PHP code for registering a custom taxonomy and save in a file + * $ wp scaffold taxonomy venue --post_types=event,presentation > taxonomy.php * * @subcommand taxonomy * @@ -202,6 +223,10 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * [--force] * : Overwrite files that already exist. * + * ## EXAMPLES + * + * $ wp scaffold _s sample-theme --theme_name="Sample Theme" --author="John Doe" + * Success: Created theme 'Sample Theme'. */ function _s( $args, $assoc_args ) { @@ -307,6 +332,11 @@ function _s( $args, $assoc_args ) { * [--force] * : Overwrite files that already exist. * + * ## EXAMPLES + * + * $ wp scaffold child-theme sample-theme --parent_theme=twentysixteen + * Success: Created /var/www/example.com/public_html/wp-content/themes/sample-theme. + * * @subcommand child-theme */ function child_theme( $args, $assoc_args ) { @@ -408,6 +438,11 @@ private function get_output_path( $assoc_args, $subdir ) { * [--force] * : Overwrite files that already exist. * + * ## EXAMPLES + * + * $ wp scaffold plugin sample-plugin + * Success: Created plugin files. + * Success: Created test files. */ function plugin( $args, $assoc_args ) { $plugin_slug = $args[0]; @@ -499,9 +534,10 @@ function plugin( $args, $assoc_args ) { * [--force] * : Overwrite files that already exist. * - * ## EXAMPLE + * ## EXAMPLES * - * wp scaffold plugin-tests hello + * $ wp scaffold plugin-tests sample-plugin + * Success: Created test files. * * @subcommand plugin-tests */ From be9aa2c190fb486f504e115668584e44419739b1 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 2 Jun 2016 20:59:20 +0545 Subject: [PATCH 4497/4858] Examples for core main class --- php/commands/core.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 38d9124462..f52846cd0c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -6,6 +6,22 @@ /** * Download, install, update and otherwise manage WordPress proper. * + * ## EXAMPLES + * + * # Download WordPress core + * $ wp core download --locale=nl_NL + * Downloading WordPress 4.5.2 (nl_NL)... + * md5 hash verified: c5366d05b521831dd0b29dfc386e56a5 + * Success: WordPress downloaded. + * + * # Install WordPress + * $ wp core install --url=example.com --title=Example --admin_user=supervisor --admin_password=strongpassword --admin_email=info@example.com + * Success: WordPress installed successfully. + * + * # Display the WordPress version + * $ wp core version + * 4.5.2 + * * @package wp-cli */ class Core_Command extends WP_CLI_Command { From c68b91e06febbd4a0c80967cfb82e858f79dd07c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 2 Jun 2016 14:02:08 -0700 Subject: [PATCH 4498/4858] Move `--skip-themes` feature to a filter, instead of wp-settings hack Introduces `Runner->add_wp_hook()` and `Runner->remove_wp_hook()` for adding actions and filters before `add_filter()` is defined. To ensure child themes can be skipped from loading, the `stylesheet` value is always checked. Filter is added late on `setup_theme` hook to noop TEMPLATEPATH and `STYLESHEETPATH`, and then removed early on `after_setup_theme` to ensure use of `get_template_directory()` still works as expected. Unfortunately, the downside is that the constants are defined incorrectly in this request, but hopefully this is an acceptable cost to the value of `--skip-themes`. --- features/skip-themes.feature | 54 ++++++++++++++ php/WP_CLI/Runner.php | 135 +++++++++++++++++++++++++++++++++++ php/wp-settings-cli.php | 10 ++- 3 files changed, 193 insertions(+), 6 deletions(-) diff --git a/features/skip-themes.feature b/features/skip-themes.feature index a285eec796..abfe6e2d3a 100644 --- a/features/skip-themes.feature +++ b/features/skip-themes.feature @@ -46,6 +46,60 @@ Feature: Skipping themes false """ + Scenario: Skip parent and child themes + Given a WP install + And I run `wp theme install jolene biker` + + When I run `wp theme activate jolene` + When I run `wp eval 'var_export( function_exists( "jolene_setup" ) );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp --skip-themes=jolene eval 'var_export( function_exists( "jolene_setup" ) );'` + Then STDOUT should be: + """ + false + """ + + When I run `wp theme activate biker` + When I run `wp eval 'var_export( function_exists( "jolene_setup" ) );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp eval 'var_export( function_exists( "biker_setup" ) );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp --skip-themes=biker eval 'var_export( function_exists( "jolene_setup" ) );'` + Then STDOUT should be: + """ + false + """ + + When I run `wp --skip-themes=biker eval 'var_export( function_exists( "biker_setup" ) );'` + Then STDOUT should be: + """ + false + """ + + When I run `wp --skip-themes=biker eval 'echo get_template_directory();'` + Then STDOUT should contain: + """ + wp-content/themes/jolene + """ + + When I run `wp --skip-themes=biker eval 'echo get_stylesheet_directory();'` + Then STDOUT should contain: + """ + wp-content/themes/biker + """ + Scenario: Skipping multiple themes via config file Given a WP install And a wp-cli.yml file: diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7b94d703e1..f9e80df2bd 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -854,6 +854,9 @@ public function load_wordpress() { // Load WP-CLI utilities require WP_CLI_ROOT . '/php/utils-wp.php'; + // Set up WordPress bootstrap actions and filters + $this->setup_bootstrap_hooks(); + // Load Core, mu-plugins, plugins, themes etc. require WP_CLI_ROOT . '/php/wp-settings-cli.php'; @@ -922,6 +925,138 @@ private function maybe_update_url_from_domain_constant() { } } + /** + * Set up hooks meant to run during the WordPress bootstrap process + */ + private function setup_bootstrap_hooks() { + + if ( $this->config['skip-themes'] ) { + $this->add_wp_hook( 'setup_theme', array( $this, 'action_setup_theme_wp_cli_skip_themes' ), 999 ); + } + + } + + /** + * Set up the filters to skip the loaded theme + */ + public function action_setup_theme_wp_cli_skip_themes() { + $wp_cli_filter_active_theme = function( $value ) { + $skipped_themes = WP_CLI::get_runner()->config['skip-themes']; + if ( true === $skipped_themes ) { + return ''; + } + if ( ! is_array( $skipped_themes ) ) { + $skipped_themes = explode( ',', $skipped_themes ); + } + // Always check against the stylesheet value + // This ensures a child theme can be skipped when template differs + if ( false !== stripos( current_filter(), 'option_template' ) ) { + $checked_value = get_option( 'stylesheet' ); + } else { + $checked_value = $value; + } + if ( '' === $checked_value || in_array( $checked_value, $skipped_themes ) ) { + return ''; + } + return $value; + }; + $hooks = array( + 'pre_option_template', + 'option_template', + 'pre_option_stylesheet', + 'option_stylesheet', + ); + foreach( $hooks as $hook ) { + add_filter( $hook, $wp_cli_filter_active_theme, 999 ); + } + // Clean up after the TEMPLATEPATH and STYLESHEETPATH constants are defined + $this->add_wp_hook( 'after_setup_theme', function() use ( $hooks, $wp_cli_filter_active_theme ) { + foreach( $hooks as $hook ) { + remove_filter( $hook, $wp_cli_filter_active_theme, 999 ); + } + }, 0 ); + } + + /** + * Add a callback to a WordPress action or filter + * + * Essentially add_filter() without needing access to add_filter() + */ + private function add_wp_hook( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { + global $wp_filter, $merged_filters; + $idx = $this->wp_hook_build_unique_id($tag, $function_to_add, $priority); + $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); + unset( $merged_filters[ $tag ] ); + return true; + } + + /** + * Remove a callback from a WordPress action or filter + * + * Essentially remove_filter() without needing access to remove_filter() + */ + private function remove_wp_hook( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { + $function_to_remove = $this->wp_hook_build_unique_id( $tag, $function_to_remove, $priority ); + + $r = isset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); + + if ( true === $r ) { + unset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); + if ( empty( $GLOBALS['wp_filter'][ $tag ][ $priority ] ) ) { + unset( $GLOBALS['wp_filter'][ $tag ][ $priority ] ); + } + if ( empty( $GLOBALS['wp_filter'][ $tag ] ) ) { + $GLOBALS['wp_filter'][ $tag ] = array(); + } + unset( $GLOBALS['merged_filters'][ $tag ] ); + } + + return $r; + } + + /** + * Build Unique ID for storage and retrieval. + * + * Essentially _wp_filter_build_unique_id() without needing access to _wp_filter_build_unique_id() + */ + private function wp_hook_build_unique_id( $tag, $function, $priority ) { + global $wp_filter; + static $filter_id_count = 0; + + if ( is_string($function) ) + return $function; + + if ( is_object($function) ) { + // Closures are currently implemented as objects + $function = array( $function, '' ); + } else { + $function = (array) $function; + } + + if (is_object($function[0]) ) { + // Object Class Calling + if ( function_exists('spl_object_hash') ) { + return spl_object_hash($function[0]) . $function[1]; + } else { + $obj_idx = get_class($function[0]).$function[1]; + if ( !isset($function[0]->wp_filter_id) ) { + if ( false === $priority ) + return false; + $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; + $function[0]->wp_filter_id = $filter_id_count; + ++$filter_id_count; + } else { + $obj_idx .= $function[0]->wp_filter_id; + } + + return $obj_idx; + } + } elseif ( is_string( $function[0] ) ) { + // Static Calling + return $function[0] . '::' . $function[1]; + } + } + /** * Check whether there's a WP-CLI update available, and suggest update if so. */ diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index b84f3e1d9a..1326e24954 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -383,12 +383,10 @@ function wp_is_mobile() { // Load the functions for the active theme, for both parent and child theme if applicable. global $pagenow; if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) { - if ( !Utils\is_theme_skipped( TEMPLATEPATH ) ) { - if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) - include( STYLESHEETPATH . '/functions.php' ); - if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) - include( TEMPLATEPATH . '/functions.php' ); - } + if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) + include( STYLESHEETPATH . '/functions.php' ); + if ( file_exists( TEMPLATEPATH . '/functions.php' ) ) + include( TEMPLATEPATH . '/functions.php' ); } do_action( 'after_setup_theme' ); From b3c9f8da3cf75585aa20874d340048588be66b32 Mon Sep 17 00:00:00 2001 From: Steven K Word <stevenword@gmail.com> Date: Thu, 2 Jun 2016 15:44:04 -0700 Subject: [PATCH 4499/4858] Adds support for PHP 5.5 Memcache extension --- php/utils-wp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index b4202dd847..c0a054f2f4 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -152,7 +152,7 @@ function wp_get_cache_type() { } elseif ( isset( $wp_object_cache->mc ) ) { $is_memcache = true; foreach ( $wp_object_cache->mc as $bucket ) { - if ( ! is_a( $bucket, 'Memcache' ) ) + if ( ! is_a( $bucket, 'Memcache' ) && ! is_a( $bucket, 'Memcached' ) ) $is_memcache = false; } From fa98ca601536c268d2f7cad97609f72480f0c08c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 2 Jun 2016 15:53:24 -0700 Subject: [PATCH 4500/4858] Move `--skip-plugins` feature to a filter, instead of wp-settings hack Filters are added before the bootstrap process, to noop `wp_get_active_network_plugins()` and `wp_get_active_and_valid_plugins()`, and then removed early on `plugins_loaded` to ensure later use of `get_option( 'active_plugins' );` works as expected. Unfortunately, `get_options( 'active_plugins' );` will be inaccurate on the `muplugins_loaded` hook. Hopefully this will be an acceptable cost to being able to continue using `--skip-plugins`. --- php/WP_CLI/Runner.php | 40 ++++++++++++++++++++++++++++++++++++++++ php/wp-settings-cli.php | 16 ++++++---------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index f9e80df2bd..8cd84d8eaf 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -930,12 +930,52 @@ private function maybe_update_url_from_domain_constant() { */ private function setup_bootstrap_hooks() { + if ( $this->config['skip-plugins'] ) { + $this->setup_skip_plugins_filters(); + } + if ( $this->config['skip-themes'] ) { $this->add_wp_hook( 'setup_theme', array( $this, 'action_setup_theme_wp_cli_skip_themes' ), 999 ); } } + /** + * Set up the filters to skip the loaded plugins + */ + private function setup_skip_plugins_filters() { + $wp_cli_filter_active_plugins = function( $plugins ) use( $skip_plugins ) { + $skipped_plugins = WP_CLI::get_runner()->config['skip-plugins']; + if ( true === $skipped_plugins ) { + return array(); + } + if ( ! is_array( $plugins ) ) { + return $plugins; + } + foreach( $plugins as $key => $plugin ) { + if ( Utils\is_plugin_skipped( $plugin ) ) { + unset( $plugins[ $key ] ); + } + } + return array_values( $plugins ); + }; + + $hooks = array( + 'pre_site_option_active_sitewide_plugins', + 'site_option_active_sitewide_plugins', + 'pre_option_active_plugins', + 'option_active_plugins', + ); + foreach( $hooks as $hook ) { + $this->add_wp_hook( $hook, $wp_cli_filter_active_plugins, 999 ); + } + $this->add_wp_hook( 'plugins_loaded', function() use ( $hooks, $wp_cli_filter_active_plugins ) { + foreach( $hooks as $hook ) { + remove_filter( $hook, $wp_cli_filter_active_plugins, 999 ); + } + }, 0 ); + } + /** * Set up the filters to skip the loaded theme */ diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 1326e24954..56ab53530c 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -247,11 +247,9 @@ // Load network activated plugins. if ( is_multisite() ) { foreach( wp_get_active_network_plugins() as $network_plugin ) { - if ( !Utils\is_plugin_skipped( $network_plugin ) ) { - if ( $symlinked_plugins_supported ) - wp_register_plugin_realpath( $network_plugin ); - include_once( $network_plugin ); - } + if ( $symlinked_plugins_supported ) + wp_register_plugin_realpath( $network_plugin ); + include_once( $network_plugin ); } unset( $network_plugin ); } @@ -284,11 +282,9 @@ function wp_is_mobile() { // Load active plugins. foreach ( wp_get_active_and_valid_plugins() as $plugin ) { - if ( !Utils\is_plugin_skipped( $plugin ) ) { - if ( $symlinked_plugins_supported ) - wp_register_plugin_realpath( $plugin ); - include_once( $plugin ); - } + if ( $symlinked_plugins_supported ) + wp_register_plugin_realpath( $plugin ); + include_once( $plugin ); } unset( $plugin, $symlinked_plugins_supported ); From 1eea29165b553cd0871160af740d4ee36c18efec Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 2 Jun 2016 16:02:04 -0700 Subject: [PATCH 4501/4858] Load wp-includes/vars.php in wp-settings-cli.php It doesn't appear there is an actual reason not to. --- php/wp-settings-cli.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 1326e24954..6830d3814d 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -267,12 +267,8 @@ // Define and enforce our SSL constants wp_ssl_constants( ); -// Don't create common globals, but we still need wp_is_mobile() and $pagenow -// require( ABSPATH . WPINC . '/vars.php' ); -$GLOBALS['pagenow'] = null; -function wp_is_mobile() { - return false; -} +// Create common globals. +require( ABSPATH . WPINC . '/vars.php' ); // Make taxonomies and posts available to plugins and themes. // @plugin authors: warning: these get registered again on the init hook. From 765f0b75d7a8ec7d19be24e8e21947cd1138fa50 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 3 Jun 2016 08:47:19 +0545 Subject: [PATCH 4502/4858] Introduce format parameter for super-admin list command --- php/commands/super-admin.php | 70 ++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index c57d6be30d..2537a326e8 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -2,9 +2,28 @@ /** * List, add, and remove super admins from a network. + * + * ## EXAMPLES + * + * # List user with super-admin capabilities + * $ wp super-admin list + * supervisor + * administrator + * + * # Grant super-admin privileges to the user. + * $ wp super-admin add superadmin2 + * Success: Granted super-admin capabilities. + * + * # Revoke super-admin privileges to the user. + * $ wp super-admin remove superadmin2 + * Success: Revoked super-admin capabilities. */ class Super_Admin_Command extends WP_CLI_Command { + private $fields = array( + 'user_login' + ); + public function __construct() { $this->fetcher = new \WP_CLI\Fetchers\User; } @@ -12,12 +31,49 @@ public function __construct() { /** * Show a list of users with super-admin capabilities. * + * ## OPTIONS + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: list + * options: + * - list + * - table + * - csv + * - json + * - count + * - yaml + * --- + * + * ## EXAMPLES + * + * # List user with super-admin capabilities + * $ wp super-admin list + * supervisor + * administrator + * * @subcommand list */ public function _list( $_, $assoc_args ) { $super_admins = self::get_admins(); - foreach ( $super_admins as $user_login ) { - WP_CLI::line( $user_login ); + + if ( 'list' === $assoc_args['format'] ) { + foreach ( $super_admins as $user_login ) { + WP_CLI::line( $user_login ); + } + } + else { + $output_users = array(); + foreach ( $super_admins as $user_login ) { + $output_user = new stdClass; + + $output_user->user_login = $user_login; + + $output_users[] = $output_user; + } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); + $formatter->display_items( $output_users ); } } @@ -26,6 +82,11 @@ public function _list( $_, $assoc_args ) { * * <user>... * : One or more user IDs, user emails, or user logins. + * + * ## EXAMPLES + * + * $ wp super-admin add superadmin2 + * Success: Granted super-admin capabilities. */ public function add( $args, $_ ) { @@ -66,6 +127,11 @@ public function add( $args, $_ ) { * * <user>... * : One or more user IDs, user emails, or user logins. + * + * ## EXAMPLES + * + * $ wp super-admin remove superadmin2 + * Success: Revoked super-admin capabilities. */ public function remove( $args, $_ ) { $users = $this->fetcher->get_many( $args ); From ac1e8cd6f1d4a10cae37f92012cdad9bece0d5d3 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 3 Jun 2016 08:53:14 +0545 Subject: [PATCH 4503/4858] Add test for format parameter in super-admin list --- features/super-admin.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/super-admin.feature b/features/super-admin.feature index 656499e23a..219b65033c 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -30,9 +30,21 @@ Feature: Manage super admins associated with a multisite instance superadmin """ + When I run `wp super-admin list --format=table` + Then STDOUT should be a table containing rows: + | user_login | + | admin | + | superadmin | + When I run `wp super-admin remove admin` And I run `wp super-admin list` Then STDOUT should be: """ superadmin """ + + When I run `wp super-admin list --format=json` + Then STDOUT should be: + """ + [{"user_login":"superadmin"}] + """ From fc9b349fddf81e7311a6c0c08f826231fa2ff1d2 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 3 Jun 2016 10:05:16 +0545 Subject: [PATCH 4504/4858] Examples for search-replace command --- php/commands/search-replace.php | 40 +++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 174de9ddfa..89bd09daa9 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -3,6 +3,30 @@ /** * Search and replace strings in the database. * + * ## EXAMPLES + * + * # Search and replace strings in the table + * $ wp search-replace foo bar wp_options + * +------------+--------------+--------------+------+ + * | Table | Column | Replacements | Type | + * +------------+--------------+--------------+------+ + * | wp_options | option_name | 2 | SQL | + * | wp_options | option_value | 0 | PHP | + * | wp_options | autoload | 0 | SQL | + * +------------+--------------+--------------+------+ + * Success: Made 2 replacements. + * + * # Run search/replace operation but dont save in database + * $ wp search-replace foo bar wp_options --dry-run + * +------------+--------------+--------------+------+ + * | Table | Column | Replacements | Type | + * +------------+--------------+--------------+------+ + * | wp_options | option_name | 2 | SQL | + * | wp_options | option_value | 0 | PHP | + * | wp_options | autoload | 0 | SQL | + * +------------+--------------+--------------+------+ + * Success: 2 replacement(s) to be made. + * * @package wp-cli */ class Search_Replace_Command extends WP_CLI_Command { @@ -88,16 +112,18 @@ class Search_Replace_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp search-replace 'http://example.dev' 'http://example.com' --skip-columns=guid + * # Search and replace but skip one column + * $ 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 + * # Run search/replace operation but dont save in database + * $ wp search-replace 'foo' 'bar' wp_posts wp_postmeta wp_terms --dry-run * * # Turn your production multisite database into a local dev database - * wp search-replace --url=example.com example.com example.dev 'wp_*_options' wp_blogs + * $ wp search-replace --url=example.com example.com example.dev 'wp_*_options' wp_blogs * * # Search/replace to a SQL file without transforming the database - * wp search-replace foo bar --export=database.sql - * + * $ wp search-replace foo bar --export=database.sql + * * # Bash script: Search/replace production to development url (multisite compatible) * #!/bin/bash * if $(wp --url=http://example.com core is-installed --network); then @@ -384,13 +410,13 @@ function ( $field ) { // 1. When the loop is running every nth time (where n is insert statement size, $export_index_size). Remainder is zero also on first round, so it have to be excluded. // $index % $export_insert_size == 0 && $index > 0 // 2. Or when the loop is running last time - // $index == $count + // $index == $count if( ( $index % $export_insert_size == 0 && $index > 0 ) || $index == $count ) { $sql .= ";\n"; $sql = $wpdb->prepare( $sql, array_values( $values ) ); fwrite( $this->export_handle, $sql ); - + // If there is still rows to loop, reset $sql and $values variables. if( $count > $index ) { $sql = $insert; From 2c695cfd9435042ec5ef35163667cc8531d83fc7 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 3 Jun 2016 10:27:08 +0545 Subject: [PATCH 4505/4858] Add example for user term --- php/commands/user.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 1973262926..3066a3dd5d 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -950,17 +950,16 @@ private function replace_login_with_user_id( $args ) { /** * Manage user terms. * - * * ## EXAMPLES * + * # Set user terms * wp user term set 123 test category + * Set terms. */ class User_Term_Command extends \WP_CLI\CommandWithTerms { protected $obj_type = 'user'; } - WP_CLI::add_command( 'user', 'User_Command' ); WP_CLI::add_command( 'user meta', 'User_Meta_Command' ); WP_CLI::add_command( 'user term', 'User_Term_Command' ); - From c9546220940e52ee941bf2c2614319baedb37702 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 3 Jun 2016 10:43:45 +0545 Subject: [PATCH 4506/4858] Add examples for user meta commands --- php/commands/user.php | 61 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 3066a3dd5d..645c1cceb1 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -812,16 +812,29 @@ private static function wp_new_user_notification( $user_id, $password ) { /** * Manage user custom fields. * - * ## OPTIONS + * ## EXAMPLES * - * --format=json - * : Encode/decode values as JSON. + * # Add user meta + * $ wp user meta add 123 bio "Mary is an WordPress developer." + * Success: Added custom field. * - * ## EXAMPLES + * # List user meta + * $ wp user meta list 123 --keys=nickname,description,wp_capabilities + * +---------+-----------------+--------------------------------+ + * | user_id | meta_key | meta_value | + * +---------+-----------------+--------------------------------+ + * | 123 | nickname | supervisor | + * | 123 | description | Mary is a WordPress developer. | + * | 123 | wp_capabilities | {"administrator":true} | + * +---------+-----------------+--------------------------------+ * - * wp user meta set 123 description "Mary is a WordPress developer." + * # Update user meta + * $ wp user meta update 123 bio "Mary is an awesome WordPress developer." + * Success: Updated custom field 'bio'. * - * wp user meta update admin first_name "George" + * # Delete user meta + * $ wp user meta delete 123 bio + * Success: Deleted custom field. */ class User_Meta_Command extends \WP_CLI\CommandWithMeta { protected $meta_type = 'user'; @@ -847,6 +860,18 @@ public function __construct() { * [--format=<format>] * : Accepted values: table, csv, json, count. Default: table * + * ## EXAMPLES + * + * # List user meta + * $ wp user meta list 123 --keys=nickname,description,wp_capabilities + * +---------+-----------------+--------------------------------+ + * | user_id | meta_key | meta_value | + * +---------+-----------------+--------------------------------+ + * | 123 | nickname | supervisor | + * | 123 | description | Mary is a WordPress developer. | + * | 123 | wp_capabilities | {"administrator":true} | + * +---------+-----------------+--------------------------------+ + * * @subcommand list */ public function list_( $args, $assoc_args ) { @@ -867,6 +892,12 @@ public function list_( $args, $assoc_args ) { * * [--format=<format>] * : Accepted values: table, json, yaml. Default: table + * + * ## EXAMPLES + * + * # Get user meta + * $ wp user meta get 123 bio + * Mary is an WordPress developer. */ public function get( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); @@ -884,6 +915,12 @@ public function get( $args, $assoc_args ) { * * [<value>] * : The value to delete. If omitted, all rows with key will deleted. + * + * ## EXAMPLES + * + * # Delete user meta + * $ wp user meta delete 123 bio + * Success: Deleted custom field. */ public function delete( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); @@ -904,6 +941,12 @@ public function delete( $args, $assoc_args ) { * * [--format=<format>] * : The serialization format for the value. Default is plaintext. + * + * ## EXAMPLES + * + * # Add user meta + * $ wp user meta add 123 bio "Mary is an WordPress developer." + * Success: Added custom field. */ public function add( $args, $assoc_args ) { $args = $this->replace_login_with_user_id( $args ); @@ -925,6 +968,12 @@ public function add( $args, $assoc_args ) { * [--format=<format>] * : The serialization format for the value. Default is plaintext. * + * ## EXAMPLES + * + * # Update user meta + * $ wp user meta update 123 bio "Mary is an awesome WordPress developer." + * Success: Updated custom field 'bio'. + * * @alias set */ public function update( $args, $assoc_args ) { From fd38aa2f845286b238810ba3e5278d712ad999fb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 3 Jun 2016 11:23:00 +0545 Subject: [PATCH 4507/4858] Add examples for user commands --- php/commands/user.php | 77 ++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 645c1cceb1..5ab8b81aab 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -71,11 +71,18 @@ public function __construct() { * * ## EXAMPLES * - * wp user list --field=ID + * # List user IDs + * $ wp user list --field=ID + * 1 * - * wp user list --role=administrator --format=csv + * # List users with administrator role + * $ wp user list --role=administrator --format=csv + * ID,user_login,display_name,user_email,user_registered,roles + * 1,supervisor,supervisor,supervisor@gmail.com,"2016-06-03 04:37:00",administrator * - * wp user list --fields=display_name,user_email --format=json + * # List users with only given fields + * $ wp user list --fields=display_name,user_email --format=json + * [{"display_name":"supervisor","user_email":"supervisor@gmail.com"}] * * @subcommand list */ @@ -142,9 +149,12 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user get 12 --field=login + * # Get user + * $ wp user get 12 --field=login + * supervisor * - * wp user get bob --format=json > bob.json + * # Get user and export to JSON file + * $ wp user get bob --format=json > bob.json */ public function get( $args, $assoc_args ) { $user = $this->fetcher->get_check( $args[0] ); @@ -175,7 +185,8 @@ public function get( $args, $assoc_args ) { * ## EXAMPLES * * # Delete user 123 and reassign posts to user 567 - * wp user delete 123 --reassign=567 + * $ wp user delete 123 --reassign=567 + * Success: Removed user 123 from http://example.com */ public function delete( $args, $assoc_args ) { $network = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) && is_multisite(); @@ -247,7 +258,10 @@ public function delete( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user create bob bob@example.com --role=author + * # Create user + * $ wp user create bob bob@example.com --role=author + * Success: Created user 3. + * Password: k9**&I4vNH(& */ public function create( $args, $assoc_args ) { $user = new stdClass; @@ -340,7 +354,9 @@ public function create( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user update 123 --display_name=Mary --user_pass=marypass + * # Update user + * $ wp user update 123 --display_name=Mary --user_pass=marypass + * Success: Updated user 1. */ public function update( $args, $assoc_args ) { if ( isset( $assoc_args['user_login'] ) ) { @@ -373,7 +389,10 @@ public function update( $args, $assoc_args ) { * ## EXAMPLES * * # Add meta to every generated user - * wp user generate --format=ids | xargs -0 -d ' ' -I % wp user meta add % foo bar + * 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; @@ -447,8 +466,8 @@ public function generate( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user set-role bob author - * wp user set-role 12 author + * $ wp user set-role 12 author + * Success: Added johndoe (12) to http://example.com as author * * @subcommand set-role */ @@ -481,8 +500,8 @@ public function set_role( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user add-role bob author - * wp user add-role 12 author + * $ wp user add-role 12 author + * Success: Added 'author' role for johndoe (12). * * @subcommand add-role */ @@ -511,8 +530,8 @@ public function add_role( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user remove-role bob - * wp user remove-role 12 editor + * $ wp user remove-role 12 author + * Success: Removed 'author' role for johndoe (12). * * @subcommand remove-role */ @@ -551,8 +570,13 @@ public function remove_role( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user add-cap john create_premium_item - * wp user add-cap 15 edit_product + * # Add a capability for a user + * $ wp user add-cap john create_premium_item + * Success: Added 'create_premium_item' capability for john (16). + * + * # Add a capability for a user + * $ wp user add-cap 15 edit_product + * Success: Added 'edit_product' capability for johndoe (15). * * @subcommand add-cap */ @@ -579,8 +603,8 @@ public function add_cap( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user remove-cap bob edit_themes - * wp user remove-cap 11 publish_newsletters + * $ wp user remove-cap 11 publish_newsletters + * Success: Removed 'publish_newsletters' cap for supervisor (11). * * @subcommand remove-cap */ @@ -604,8 +628,9 @@ public function remove_cap( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user list-caps admin - * wp user list-caps 21 + * $ wp user list-caps 21 + * edit_product + * create_premium_item * * @subcommand list-caps */ @@ -641,8 +666,14 @@ public function list_caps( $args, $assoc_args ) { * * ## EXAMPLES * - * wp user import-csv /path/to/users.csv - * wp user import-csv http://example.com/users.csv + * # Import users from local CSV file + * $ wp user import-csv /path/to/users.csv + * Success: bobjones created + * Success: newuser1 created + * Success: existinguser created + * + * # Import users from remote CSV file + * $wp user import-csv http://example.com/users.csv * * Sample users.csv file: * From a2c86d96f51c9e5afe64a1a545b0c56b4c790ecc Mon Sep 17 00:00:00 2001 From: Dominik Schilling <dominikschilling+git@gmail.com> Date: Fri, 3 Jun 2016 11:25:51 +0200 Subject: [PATCH 4508/4858] Load plugin.php earlier in wp-settings-cli.php for 4.6 compat. See https://core.trac.wordpress.org/changeset/37588 and https://core.trac.wordpress.org/changeset/37626. --- php/wp-settings-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 1326e24954..a2e2cd9957 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -15,6 +15,7 @@ // Include files required for initialization. require( ABSPATH . WPINC . '/load.php' ); require( ABSPATH . WPINC . '/default-constants.php' ); +require( ABSPATH . WPINC . '/plugin.php' ); /* * These can't be directly globalized in version.php. When updating, @@ -66,7 +67,6 @@ require( ABSPATH . WPINC . '/functions.php' ); require( ABSPATH . WPINC . '/class-wp.php' ); require( ABSPATH . WPINC . '/class-wp-error.php' ); -require( ABSPATH . WPINC . '/plugin.php' ); require( ABSPATH . WPINC . '/pomo/mo.php' ); // WP_CLI: Early hooks From 3c8da846d5bc5ed919e6c7589fe641e370973329 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 3 Jun 2016 04:09:03 -0700 Subject: [PATCH 4509/4858] Variable is no longer being passed --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8cd84d8eaf..4a08c81b22 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -944,7 +944,7 @@ private function setup_bootstrap_hooks() { * Set up the filters to skip the loaded plugins */ private function setup_skip_plugins_filters() { - $wp_cli_filter_active_plugins = function( $plugins ) use( $skip_plugins ) { + $wp_cli_filter_active_plugins = function( $plugins ) { $skipped_plugins = WP_CLI::get_runner()->config['skip-plugins']; if ( true === $skipped_plugins ) { return array(); From 41e72a9cf6b08d7be0342efa94759ae96949b368 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 3 Jun 2016 20:03:11 +0545 Subject: [PATCH 4510/4858] Add examples for User main class --- php/commands/user.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 5ab8b81aab..673cbbe756 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -3,6 +3,25 @@ /** * Manage users. * + * ## EXAMPLES + * + * # List user IDs + * $ wp user list --field=ID + * 1 + * + * # Create user + * $ wp user create bob bob@example.com --role=author + * Success: Created user 3. + * Password: k9**&I4vNH(& + * + * # Update user + * $ wp user update 123 --display_name=Mary --user_pass=marypass + * Success: Updated user 123. + * + * # Delete user 123 and reassign posts to user 567 + * $ wp user delete 123 --reassign=567 + * Success: Removed user 123 from http://example.com + * * @package wp-cli */ class User_Command extends \WP_CLI\CommandWithDBObject { @@ -356,7 +375,7 @@ public function create( $args, $assoc_args ) { * * # Update user * $ wp user update 123 --display_name=Mary --user_pass=marypass - * Success: Updated user 1. + * Success: Updated user 123. */ public function update( $args, $assoc_args ) { if ( isset( $assoc_args['user_login'] ) ) { @@ -389,7 +408,7 @@ public function update( $args, $assoc_args ) { * ## EXAMPLES * * # Add meta to every generated user - * wp user generate --format=ids --count=3 | xargs -0 -d ' ' -I % wp user meta add % foo bar + * $ 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. @@ -673,7 +692,7 @@ public function list_caps( $args, $assoc_args ) { * Success: existinguser created * * # Import users from remote CSV file - * $wp user import-csv http://example.com/users.csv + * $ wp user import-csv http://example.com/users.csv * * Sample users.csv file: * @@ -1033,7 +1052,7 @@ private function replace_login_with_user_id( $args ) { * ## EXAMPLES * * # Set user terms - * wp user term set 123 test category + * $ wp user term set 123 test category * Set terms. */ class User_Term_Command extends \WP_CLI\CommandWithTerms { From a6fdbf59b11f6f3dee588e13381dd10f3b14b62c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 3 Jun 2016 07:33:38 -0700 Subject: [PATCH 4511/4858] Remove `$pagenow` definition in `\WP_CLI\Runner` Originally introduced in 58ea052de3090dc5738ef933fde2120ac39fe64e, it hasn't worked since dc8502de2d5fb39fe2430b4447633a171628adbb. The original issue this hack solved should just be addressed in the plugin. --- php/WP_CLI/Runner.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4a08c81b22..91bd336e37 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -799,10 +799,6 @@ public function start() { define( 'DOING_CRON', true ); } - if ( $this->cmd_starts_with( array( 'plugin' ) ) ) { - $GLOBALS['pagenow'] = 'plugins.php'; - } - $this->load_wordpress(); $this->_run_command(); From d8402127aa3ce4732abfd518d082d3fc081c4ad7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 3 Jun 2016 12:57:32 -0700 Subject: [PATCH 4512/4858] Hook wp_die handler in \WP_CLI\Runner instead of wp-settings-cli.php It's not necessary to add the callback as a part of the WP bootstrap process, given the existing `\WP_CLI\Utils\replace_wp_die_handler()` erroneously removes a callback that doesn't exist --- features/db.feature | 12 +++++++++++- php/WP_CLI/Runner.php | 2 ++ php/wp-settings-cli.php | 1 - 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/features/db.feature b/features/db.feature index 3734989519..046fd29d1a 100644 --- a/features/db.feature +++ b/features/db.feature @@ -5,8 +5,18 @@ Feature: Perform database operations And WP files And wp-config.php + When I try `wp option get home` + Then STDOUT should be empty + And STDERR should be: + """ + Error: Can’t select database + """ + When I run `wp db create` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: Database created. + """ When I try the previous command again Then the return code should be 1 diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 91bd336e37..10af1d3f03 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -934,6 +934,8 @@ private function setup_bootstrap_hooks() { $this->add_wp_hook( 'setup_theme', array( $this, 'action_setup_theme_wp_cli_skip_themes' ), 999 ); } + $this->add_wp_hook( 'wp_die_handler', function() { return '\WP_CLI\Utils\wp_die_handler'; } ); + } /** diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 9e80fa2d5f..06628d9d73 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -70,7 +70,6 @@ require( ABSPATH . WPINC . '/pomo/mo.php' ); // WP_CLI: Early hooks -Utils\replace_wp_die_handler(); add_filter( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); if ( defined( 'WP_INSTALLING' ) && is_multisite() ) { $values = array( From 6ebe10c728530cfcb478dfd622caf513ff35a7b9 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 06:32:52 +0545 Subject: [PATCH 4513/4858] Add format parameter in list-caps --- php/commands/user.php | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/php/commands/user.php b/php/commands/user.php index 673cbbe756..a775acccc8 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -36,6 +36,10 @@ class User_Command extends \WP_CLI\CommandWithDBObject { 'roles' ); + private $cap_fields = array( + 'name' + ); + public function __construct() { $this->fetcher = new \WP_CLI\Fetchers\User; } @@ -645,6 +649,19 @@ public function remove_cap( $args, $assoc_args ) { * <user> * : User ID, user email, or login. * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: list + * options: + * - list + * - table + * - csv + * - json + * - count + * - yaml + * --- + * * ## EXAMPLES * * $ wp user list-caps 21 @@ -661,11 +678,34 @@ public function list_caps( $args, $assoc_args ) { $user_caps_list = $user->allcaps; + $active_user_cap_list = array(); + foreach ( $user_caps_list as $cap => $active ) { if ( $active ) { - \cli\line( $cap ); + $active_user_cap_list[] = $cap; + } + } + + if ( ! empty( $active_user_cap_list ) ) { + if ( 'list' === $assoc_args['format'] ) { + foreach ( $active_user_cap_list as $cap ) { + WP_CLI::line( $cap ); + } + } + else { + $output_caps = array(); + foreach ( $active_user_cap_list as $cap ) { + $output_cap = new stdClass; + + $output_cap->name = $cap; + + $output_caps[] = $output_cap; + } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->cap_fields ); + $formatter->display_items( $output_caps ); } } + } } From 7c9b8ed3867d8c01b272a180b5e18a52593193d0 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 06:48:47 +0545 Subject: [PATCH 4514/4858] Add tests for format parameter in user list-caps --- features/user.feature | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/features/user.feature b/features/user.feature index 3b8662b308..72b78927cf 100644 --- a/features/user.feature +++ b/features/user.feature @@ -169,7 +169,7 @@ Feature: Manage WordPress users Then STDOUT should be a table containing rows: | Field | Value | | roles | | - + Scenario: Managing user capabilities Given a WP install @@ -178,13 +178,13 @@ Feature: Manage WordPress users """ Success: Added 'edit_vip_product' capability for admin (1). """ - + And I run `wp user list-caps 1 | tail -n 1` Then STDOUT should be: """ edit_vip_product """ - + And I run `wp user remove-cap 1 edit_vip_product` Then STDOUT should be: """ @@ -238,3 +238,30 @@ Feature: Manage WordPress users """ testsubscriber """ + + Scenario: Listing user capabilities + Given a WP install + + When I run `wp user create bob bob@gmail.com --role=contributor` + And I run `wp user list-caps bob` + Then STDOUT should be: + """ + edit_posts + read + level_1 + level_0 + delete_posts + contributor + """ + + And I run `wp user list-caps bob --format=json` + Then STDOUT should be: + """ + [{"name":"edit_posts"},{"name":"read"},{"name":"level_1"},{"name":"level_0"},{"name":"delete_posts"},{"name":"contributor"}] + """ + + And I run `wp user list-caps bob --format=count` + Then STDOUT should be: + """ + 6 + """ From c6e7884808921698f45dac3c34cb351e597f90ac Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 06:52:42 +0545 Subject: [PATCH 4515/4858] fix intendation issue in test of user list-caps --- features/user.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/user.feature b/features/user.feature index 72b78927cf..4ca85cc0c6 100644 --- a/features/user.feature +++ b/features/user.feature @@ -247,11 +247,11 @@ Feature: Manage WordPress users Then STDOUT should be: """ edit_posts - read - level_1 - level_0 - delete_posts - contributor + read + level_1 + level_0 + delete_posts + contributor """ And I run `wp user list-caps bob --format=json` From e89f73dd698063e0b1bbd022dc416ce78e9a5bd2 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 07:08:48 +0545 Subject: [PATCH 4516/4858] Improve docs in taxonomy commands --- php/commands/taxonomy.php | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index b7f9881219..3abcba920c 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -2,6 +2,22 @@ /** * Manage taxonomies. * + * ## EXAMPLES + * + * # List all taxonomies with 'post' object type + * $ wp taxonomy list --object_type=post --fields=name,public + * +-------------+--------+ + * | name | public | + * +-------------+--------+ + * | category | 1 | + * | post_tag | 1 | + * | post_format | 1 | + * +-------------+--------+ + * + * # Get capabilities of a taxonomy + * $ wp taxonomy get post_tag --field=cap + * {"manage_terms":"manage_categories","edit_terms":"manage_categories","delete_terms":"manage_categories","assign_terms":"edit_posts"} + * * @package wp-cli */ class Taxonomy_Command extends WP_CLI_Command { @@ -41,7 +57,16 @@ public function __construct() { * : Limit the output to specific taxonomy fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -110,7 +135,15 @@ public function list_( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * From 64282b69d5821064ad97eb1e7b63b86eb8baf829 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 07:22:37 +0545 Subject: [PATCH 4517/4858] Improve format parameter docs in term commands --- php/commands/term.php | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index c24aefe7f8..2565846822 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -61,7 +61,16 @@ class Term_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -212,7 +221,15 @@ public function create( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -346,7 +363,13 @@ public function delete( $args ) { * : Generate child terms down to a certain depth. Default: 1 * * [--format=<format>] - * : Accepted values: progress, ids. Default: ids. + * : Render output in a particular format. + * --- + * default: progress + * options: + * - progress + * - ids + * --- * * ## EXAMPLES * From f3c166a8d4cfd96c8bfd4e07496abe64bef56f9b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 07:31:14 +0545 Subject: [PATCH 4518/4858] Improve doc for format parameter in transient command --- php/commands/transient.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index 62190eb227..f0d34437dc 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -34,7 +34,15 @@ class Transient_Command extends WP_CLI_Command { * : Key for the transient. * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * [--network] * : Get the value of the network transient, instead of the single site. @@ -46,7 +54,6 @@ class Transient_Command extends WP_CLI_Command { * * $ wp transient get random_key * Warning: Transient with key "random_key" is not set. - * */ public function get( $args, $assoc_args ) { list( $key ) = $args; From 8477fde97e3cba9c369a145750f71982b1130d4c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 3 Jun 2016 20:17:26 -0700 Subject: [PATCH 4519/4858] Always expect UTF-8 for consistent behavior between PHP versions --- php/utils-wp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils-wp.php b/php/utils-wp.php index c0a054f2f4..be7a4e1a79 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -40,7 +40,7 @@ function wp_die_handler( $message ) { $message = $matches[1]; } - $message = html_entity_decode( $message ); + $message = html_entity_decode( $message, ENT_COMPAT, 'UTF-8' ); \WP_CLI::error( $message ); } From 361aea6bc7856d5c94b4da0c1f1d8effea62ccb5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 15:11:53 +0545 Subject: [PATCH 4520/4858] add ids paramter in format --- php/commands/term.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/term.php b/php/commands/term.php index 2565846822..7eca69d9ae 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -67,6 +67,7 @@ class Term_Command extends WP_CLI_Command { * options: * - table * - csv + * - ids * - json * - count * - yaml From 57904d6da5ac1b66cd9c3808ce61c592d1e8d8ce Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 15:27:27 +0545 Subject: [PATCH 4521/4858] Improve format parameter in post-type commands --- php/commands/post-type.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/php/commands/post-type.php b/php/commands/post-type.php index c42a741ef1..73d96afa4f 100644 --- a/php/commands/post-type.php +++ b/php/commands/post-type.php @@ -47,7 +47,16 @@ class Post_Type_Command extends WP_CLI_Command { * : Limit the output to specific post type fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -109,7 +118,15 @@ public function list_( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * From 0979a5f896eea1d6025efdad7e9a73f626a9b5ce Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 15:37:39 +0545 Subject: [PATCH 4522/4858] Improve format parameter doc in role command --- php/commands/role.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index 0eb2bab515..cccd636bff 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -48,7 +48,17 @@ class Role_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- + * * * ## AVAILABLE FIELDS * From 2b9c5e50ebb85fc7b77f172161cacb3b19fb325d Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 15:51:17 +0545 Subject: [PATCH 4523/4858] Improve format parameter doc in cli commands --- php/commands/cli.php | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index c5ced77bed..ce2db05cce 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -64,7 +64,12 @@ public function version() { * ## OPTIONS * * [--format=<format>] - * : Accepted values: json + * : Render output in a particular format. + * --- + * default: json + * options: + * - json + * --- * * ## EXAMPLES * @@ -131,7 +136,15 @@ public function info( $_, $assoc_args ) { * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * --- * * ## EXAMPLES * @@ -363,7 +376,13 @@ private function get_updates( $assoc_args ) { * : Display current values also. * * [--format=<format>] - * : Accepted values: var_export, json. Default: json. + * : Render output in a particular format. + * --- + * default: json + * options: + * - var_export + * - json + * --- * * ## EXAMPLES * From 12b197dea15ec12535d83c05b672495ba5c0cc24 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 16:16:11 +0545 Subject: [PATCH 4524/4858] Improve format parameter doc in comment commands --- php/commands/comment.php | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index bb424ca06d..10a6796a0e 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -117,7 +117,13 @@ public function update( $args, $assoc_args ) { * : Assign comments to a specific post. * * [--format=<format>] - * : Accepted values: progress, ids. Default: ids. + * : Render output in a particular format. + * --- + * default: progress + * options: + * - progress + * - ids + * --- * * ## EXAMPLES * @@ -184,7 +190,15 @@ public function generate( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -222,7 +236,17 @@ public function get( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - ids + * - csv + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * From bfc3819de5807a3fb20e8a73ab9e306c55cc9f48 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 4 Jun 2016 05:18:27 -0700 Subject: [PATCH 4525/4858] Move `ms_site_not_found` action inside of `WP_CLI\Runner` --- php/WP_CLI/Runner.php | 25 +++++++++++++++++++++++++ php/wp-settings-cli.php | 7 ------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 10af1d3f03..cf4cfa1067 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -936,6 +936,13 @@ private function setup_bootstrap_hooks() { $this->add_wp_hook( 'wp_die_handler', function() { return '\WP_CLI\Utils\wp_die_handler'; } ); + // In a multisite install, die if unable to find site given in --url parameter + if ( $this->is_multisite() ) { + $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { + WP_CLI::error( "Site {$domain}{$path} not found." ); + }, 10, 3 ); + } + } /** @@ -1095,6 +1102,24 @@ private function wp_hook_build_unique_id( $tag, $function, $priority ) { } } + /** + * Whether or not this WordPress install is multisite. + * + * For use after wp-config.php has loaded, but before the rest of WordPress + * is loaded. + */ + private function is_multisite() { + if ( defined( 'MULTISITE' ) ) { + return MULTISITE; + } + + if ( defined( 'SUBDOMAIN_INSTALL' ) || defined( 'VHOST' ) || defined( 'SUNRISE' ) ) { + return true; + } + + return false; + } + /** * Check whether there's a WP-CLI update available, and suggest update if so. */ diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 06628d9d73..0f7572875c 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -88,13 +88,6 @@ unset( $values, $key, $value ); } -// In a multisite install, die if unable to find site given in --url parameter -if ( is_multisite() ) { - add_action( 'ms_site_not_found', function( $current_site, $domain, $path ) { - WP_CLI::error( "Site {$domain}{$path} not found." ); - }, 10, 3 ); -} - // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); From ae0b6fba9f1d335d8ac127a874b88627332f7106 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 4 Jun 2016 05:24:36 -0700 Subject: [PATCH 4526/4858] Move `wp_redirect` handler to Runner from wp-settings-cli.php --- features/framework.feature | 16 ++++++++++++++++ php/WP_CLI/Runner.php | 3 +++ php/wp-settings-cli.php | 1 - 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/features/framework.feature b/features/framework.feature index d79936e0db..d39e90c5f4 100644 --- a/features/framework.feature +++ b/features/framework.feature @@ -148,3 +148,19 @@ Feature: Load WP-CLI Error: This has no exit. Error: So I can use multiple lines. """ + + Scenario: A plugin calling wp_redirect() shouldn't redirect + Given a WP install + And a wp-content/mu-plugins/redirect.php file: + """ + <?php + add_action( 'init', function(){ + wp_redirect( 'http://apple.com' ); + }); + """ + + When I try `wp option get home` + Then STDERR should contain: + """ + Warning: Some code is trying to do a URL redirect. + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index cf4cfa1067..d5291c4bfe 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -936,6 +936,9 @@ private function setup_bootstrap_hooks() { $this->add_wp_hook( 'wp_die_handler', function() { return '\WP_CLI\Utils\wp_die_handler'; } ); + // Prevent code from performing a redirect + $this->add_wp_hook( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); + // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 0f7572875c..e574ce91fc 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -70,7 +70,6 @@ require( ABSPATH . WPINC . '/pomo/mo.php' ); // WP_CLI: Early hooks -add_filter( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); if ( defined( 'WP_INSTALLING' ) && is_multisite() ) { $values = array( 'ms_files_rewriting' => null, From c34f1334cdab158076f269173802db08e9e981fb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 4 Jun 2016 05:43:54 -0700 Subject: [PATCH 4527/4858] Move filters for suppressing multisite installation warnings --- features/core.feature | 17 +++++++++++++++-- php/WP_CLI/Runner.php | 17 +++++++++++++++++ php/wp-settings-cli.php | 18 ------------------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/features/core.feature b/features/core.feature index a0f2f54ec6..0f91b7b622 100644 --- a/features/core.feature +++ b/features/core.feature @@ -132,7 +132,13 @@ Feature: Manage WordPress installation Then the return code should be 1 When I run `wp core install-network --title='test network'` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Set up multisite database tables. + Added multisite constants to wp-config.php. + Success: Network installed. Don't forget to set up rewrite rules. + """ + And STDERR should be empty When I run `wp eval 'var_export( is_multisite() );'` Then STDOUT should be: @@ -159,7 +165,14 @@ Feature: Manage WordPress installation And a database When I run `wp core multisite-install --url=foobar.org --title=Test --admin_user=wpcli --admin_email=admin@example.com --admin_password=1` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Created single site database tables. + Set up multisite database tables. + Added multisite constants to wp-config.php. + Success: Network installed. Don't forget to set up rewrite rules. + """ + And STDERR should be empty When I run `wp eval 'echo $GLOBALS["current_site"]->domain;'` Then STDOUT should be: diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index d5291c4bfe..50141bb096 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -939,6 +939,23 @@ private function setup_bootstrap_hooks() { // Prevent code from performing a redirect $this->add_wp_hook( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); + // Get rid of warnings when converting single site to multisite + if ( defined( 'WP_INSTALLING' ) && $this->is_multisite() ) { + $values = array( + 'ms_files_rewriting' => null, + 'active_sitewide_plugins' => array(), + '_site_transient_update_core' => null, + '_site_transient_update_themes' => null, + '_site_transient_update_plugins' => null, + 'WPLANG' => '', + ); + foreach ( $values as $key => $value ) { + $this->add_wp_hook( "pre_site_option_$key", function () use ( $values, $key ) { + return $values[ $key ]; + } ); + } + } + // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index e574ce91fc..9bbb77c428 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -69,24 +69,6 @@ require( ABSPATH . WPINC . '/class-wp-error.php' ); require( ABSPATH . WPINC . '/pomo/mo.php' ); -// WP_CLI: Early hooks -if ( defined( 'WP_INSTALLING' ) && is_multisite() ) { - $values = array( - 'ms_files_rewriting' => null, - 'active_sitewide_plugins' => array(), - '_site_transient_update_core' => null, - '_site_transient_update_themes' => null, - '_site_transient_update_plugins' => null, - 'WPLANG' => '', - ); - foreach ( $values as $key => $value ) { - add_filter( "pre_site_option_$key", function () use ( $values, $key ) { - return $values[ $key ]; - } ); - } - unset( $values, $key, $value ); -} - // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); From c1fdcb0ea17138fbe89a7a8062e4b13b1d98f242 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 4 Jun 2016 05:48:42 -0700 Subject: [PATCH 4528/4858] Skip `ms_site_check` when installing --- php/WP_CLI/Runner.php | 4 ++++ php/wp-settings-cli.php | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 50141bb096..6192de3140 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -956,6 +956,10 @@ private function setup_bootstrap_hooks() { } } + if ( defined( 'WP_INSTALLING' ) ) { + $this->add_wp_hook( 'ms_site_check', '__return_true' ); + } + // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 9bbb77c428..76d9f75673 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -369,8 +369,7 @@ do_action( 'init' ); // Check site status -# if ( is_multisite() ) { // WP-CLI -if ( is_multisite() && !defined('WP_INSTALLING') ) { +if ( is_multisite() ) { if ( true !== ( $file = ms_site_check() ) ) { require( $file ); die(); From 49ed9a43f502dd352224668d3f7f28ba2926b4ae Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 4 Jun 2016 20:10:43 +0545 Subject: [PATCH 4529/4858] remove if empty condition check in list-caps --- php/commands/user.php | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index a775acccc8..4db4b5482f 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -686,24 +686,22 @@ public function list_caps( $args, $assoc_args ) { } } - if ( ! empty( $active_user_cap_list ) ) { - if ( 'list' === $assoc_args['format'] ) { - foreach ( $active_user_cap_list as $cap ) { - WP_CLI::line( $cap ); - } + if ( 'list' === $assoc_args['format'] ) { + foreach ( $active_user_cap_list as $cap ) { + WP_CLI::line( $cap ); } - else { - $output_caps = array(); - foreach ( $active_user_cap_list as $cap ) { - $output_cap = new stdClass; + } + else { + $output_caps = array(); + foreach ( $active_user_cap_list as $cap ) { + $output_cap = new stdClass; - $output_cap->name = $cap; + $output_cap->name = $cap; - $output_caps[] = $output_cap; - } - $formatter = new \WP_CLI\Formatter( $assoc_args, $this->cap_fields ); - $formatter->display_items( $output_caps ); + $output_caps[] = $output_cap; } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->cap_fields ); + $formatter->display_items( $output_caps ); } } From b312b063a271952aef9cc612f3b5e24ea0e20c9e Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 6 Jun 2016 11:25:35 +0545 Subject: [PATCH 4530/4858] Add examples for theme commands --- php/commands/theme.php | 95 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 12 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index d2f3443e47..5a9361e2a8 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -3,6 +3,36 @@ /** * Manage themes. * + * ## EXAMPLES + * + * # Install the latest version from wordpress.org and activate + * $ wp theme install twentysixteen --activate + * Installing Twenty Sixteen (1.2) + * Downloading install package from http://downloads.wordpress.org/theme/twentysixteen.1.2.zip... + * Unpacking the package... + * Installing the theme... + * Theme installed successfully. + * Activating 'twentysixteen'... + * Success: Switched to 'Twenty Sixteen' theme. + * + * # Get theme + * $ wp theme get twentysixteen --fields=name,title,version + * +---------+----------------+ + * | Field | Value | + * +---------+----------------+ + * | name | Twenty Sixteen | + * | title | Twenty Sixteen | + * | version | 1.2 | + * +---------+----------------+ + * + * # Get status of theme + * $ wp theme status twentysixteen + * Theme twentysixteen details: + * Name: Twenty Sixteen + * Status: Active + * Version: 1.2 + * Author: the WordPress team + * * @package wp-cli */ class Theme_Command extends \WP_CLI\CommandWithUpgrade { @@ -257,9 +287,13 @@ public function enable( $args, $assoc_args ) { * * ## EXAMPLES * - * wp theme disable twentythirteen + * # Disable theme + * $ wp theme disable twentysixteen + * Success: Disabled the 'Twenty Sixteen' theme. * - * wp theme disable twentythirteen --network + * # Disable theme in network level + * $ wp theme disable twentysixteen --network + * Success: Network disabled the 'Twenty Sixteen' theme. */ public function disable( $args, $assoc_args ) { if ( ! is_multisite() ) { @@ -303,7 +337,12 @@ private function is_active_theme( $theme ) { * * ## EXAMPLES * - * cd $(wp theme path) + * # Get theme path + * $ wp theme path + * /var/www/example.com/public_html/wp-content/themes + * + * # Change directory to theme path + * $ cd $(wp theme path) */ public function path( $args, $assoc_args ) { if ( empty( $args ) ) { @@ -420,13 +459,20 @@ protected function filter_item_list( $items, $args ) { * ## EXAMPLES * * # Install the latest version from wordpress.org and activate - * wp theme install twentytwelve --activate + * $ wp theme install twentysixteen --activate + * Installing Twenty Sixteen (1.2) + * Downloading install package from http://downloads.wordpress.org/theme/twentysixteen.1.2.zip... + * Unpacking the package... + * Installing the theme... + * Theme installed successfully. + * Activating 'twentysixteen'... + * Success: Switched to 'Twenty Sixteen' theme. * * # Install from a local zip file - * wp theme install ../my-theme.zip + * $ wp theme install ../my-theme.zip * * # Install from a remote zip file - * wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef + * $ wp theme install http://s3.amazonaws.com/bucketname/my-theme.zip?AWSAccessKeyId=123&Expires=456&Signature=abcdef */ function install( $args, $assoc_args ) { @@ -516,9 +562,28 @@ public function get( $args, $assoc_args ) { * * ## EXAMPLES * - * wp theme update twentyeleven twentytwelve - * - * wp theme update --all + * # Update multiple themes + * $ wp theme update twentyfifteen twentysixteen + * Downloading update from https://downloads.wordpress.org/theme/twentyfifteen.1.5.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the theme... + * Theme updated successfully. + * Downloading update from https://downloads.wordpress.org/theme/twentysixteen.1.2.zip... + * Unpacking the update... + * Installing the latest version... + * Removing the old version of the theme... + * Theme updated successfully. + * Success: Updated 2/2 themes. + * +---------------+-------------+-------------+---------+ + * | name | old_version | new_version | status | + * +---------------+-------------+-------------+---------+ + * | twentyfifteen | 1.4 | 1.5 | Updated | + * | twentysixteen | 1.1 | 1.2 | Updated | + * +---------------+-------------+-------------+---------+ + * + * # Update all themes + * $ wp theme update --all * * @alias upgrade */ @@ -550,8 +615,10 @@ function update( $args, $assoc_args ) { * * ## EXAMPLES * - * wp theme is-installed twentytwelve - * echo $? # displays 0 or 1 + * # Check whether theme is installed; exit status 0 if installed, otherwise 1 + * $ wp theme is-installed hello-dolly + * $ echo $? + * 1 * * @subcommand is-installed */ @@ -635,7 +702,11 @@ function delete( $args ) { * * ## EXAMPLES * - * wp theme list --status=inactive --format=csv + * # List themes + * $ wp theme list --status=inactive --format=csv + * name,status,update,version + * twentyfourteen,inactive,none,1.7 + * twentysixteen,inactive,available,1.1 * * @subcommand list */ From 873ffaa85a860488e293351427cae58a77ed462c Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 6 Jun 2016 13:18:57 +0545 Subject: [PATCH 4531/4858] Add examples for theme mods commands --- php/commands/theme.php | 64 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 5a9361e2a8..79380cfd0e 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -718,6 +718,19 @@ public function list_( $_, $assoc_args ) { /** * Manage theme mods. * + * ## EXAMPLES + * + * # Set theme mod + * $ wp theme mod set background_color 000000 + * Success: Theme mod background_color set to 000000 + * + * # Get single theme mod in JSON format + * $ wp theme mod get background_color --format=json + * [{"key":"background_color","value":"dd3333"}] + * + * # Remove all theme mods + * $ wp theme mod remove --all + * Success: Theme mods removed. */ class Theme_Mod_command extends WP_CLI_Command { @@ -733,13 +746,38 @@ class Theme_Mod_command extends WP_CLI_Command { * : List all theme mods * * [--format=<format>] - * : Accepted values: table, json. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - json + * --- * * ## EXAMPLES * - * wp theme mod get --all - * wp theme mod get background_color --format=json - * wp theme mod get background_color header_textcolor + * # Get all theme mods + * $ wp theme mod get --all + * +------------------+---------+ + * | key | value | + * +------------------+---------+ + * | background_color | dd3333 | + * | link_color | #dd9933 | + * | main_text_color | #8224e3 | + * +------------------+---------+ + * + * # Get single theme mod in JSON format + * $ wp theme mod get background_color --format=json + * [{"key":"background_color","value":"dd3333"}] + * + * # Get multiple theme mods + * $ wp theme mod get background_color header_textcolor + * +------------------+--------+ + * | key | value | + * +------------------+--------+ + * | background_color | dd3333 | + * | header_textcolor | | + * +------------------+--------+ */ public function get( $args = array(), $assoc_args = array() ) { @@ -797,9 +835,17 @@ public function get( $args = array(), $assoc_args = array() ) { * * ## EXAMPLES * - * wp theme mod remove --all - * wp theme mod remove background_color - * wp theme mod remove background_color header_textcolor + * # Remove all theme mods + * $ wp theme mod remove --all + * Success: Theme mods removed. + * + * # Remove single theme mods + * $ wp theme mod remove background_color + * Success: 1 mods removed. + * + * # Remove multiple theme mods + * $ wp theme mod remove background_color header_textcolor + * Success: 2 mods removed. */ public function remove( $args = array(), $assoc_args = array() ) { @@ -834,7 +880,9 @@ public function remove( $args = array(), $assoc_args = array() ) { * * ## EXAMPLES * - * wp theme mod set background_color 000000 + * # Set theme mod + * $ wp theme mod set background_color 000000 + * Success: Theme mod background_color set to 000000 */ public function set( $args = array(), $assoc_args = array() ) { list( $mod, $value ) = $args; From 730f0d94fa64ead44349b74e5e95fee37971c8dd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 06:10:18 -0700 Subject: [PATCH 4532/4858] Treat `@[A-Za-z0-9-_]+` defined in `wp-cli.yml` as an alias More than one named alias can be registered. The matching alias will overload the global parameters it defines. --- php/WP_CLI/Configurator.php | 18 +++++++++++++++++- php/WP_CLI/Runner.php | 26 ++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 8a92bf6bd0..d9921425a6 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -24,6 +24,11 @@ class Configurator { */ private $extra_config = array(); + /** + * @var array $aliases Any aliases defined in config files. + */ + private $aliases = array(); + /** * @param string $path Path to config spec file. */ @@ -63,6 +68,15 @@ function get_spec() { return $this->spec; } + /** + * Get any aliases defined in config files. + * + * @return array + */ + function get_aliases() { + return $this->aliases; + } + /** * Splits a list of arguments into positional, associative and config. * @@ -142,7 +156,9 @@ public function merge_yml( $path ) { $this->merge_yml( $yaml['_']['inherit'] ); } foreach ( $yaml as $key => $value ) { - if ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { + if ( preg_match( '#@[A-Za-z0-9-_]+#', $key ) ) { + $this->aliases[ $key ] = $value; + } elseif ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { if ( isset( $this->extra_config[ $key ] ) && ! empty( $yaml['_']['merge'] ) && is_array( $this->extra_config[ $key ] ) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6192de3140..ef2c323ae8 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -17,6 +17,10 @@ class Runner { private $config, $extra_config; + private $alias; + + private $aliases; + private $arguments, $assoc_args; private $_early_invoke = array(); @@ -587,6 +591,14 @@ private function check_wp_version() { private function init_config() { $configurator = \WP_CLI::get_configurator(); + $argv = array_slice( $GLOBALS['argv'], 1 ); + + if ( ! empty( $argv[0] ) && preg_match( '#^@[A-Za-z0-9-_]+$#', $argv[0], $matches ) ) { + $this->alias = array_shift( $argv ); + } else { + $this->alias = null; + } + // File config { $this->global_config_path = $this->get_global_config_path(); @@ -602,8 +614,7 @@ private function init_config() { // Runtime config and args { - list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( - array_slice( $GLOBALS['argv'], 1 ) ); + list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( $argv ); list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions( $args, $assoc_args ); @@ -612,6 +623,7 @@ private function init_config() { } list( $this->config, $this->extra_config ) = $configurator->to_array(); + $this->aliases = $configurator->get_aliases(); $this->_required_files['runtime'] = $this->config['require']; } @@ -642,6 +654,13 @@ private function check_root() { ); } + private function set_alias( $alias ) { + if ( ! array_key_exists( $alias, $this->aliases ) ) { + WP_CLI::error( "Alias '{$alias}' not found." ); + } + $this->config = array_merge( $this->config, $this->aliases[ $this->alias ] ); + } + public function start() { $this->init_config(); $this->init_colorization(); @@ -651,6 +670,9 @@ public function start() { WP_CLI::debug( $this->_project_config_path_debug, 'bootstrap' ); $this->check_root(); + if ( $this->alias ) { + $this->set_alias( $this->alias ); + } if ( empty( $this->arguments ) ) $this->arguments[] = 'help'; From 513e85bf345148df7db364ee714b02084ca2462c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 06:12:34 -0700 Subject: [PATCH 4533/4858] Tests for 730f0d9 --- features/aliases.feature | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 features/aliases.feature diff --git a/features/aliases.feature b/features/aliases.feature new file mode 100644 index 0000000000..2bd738e039 --- /dev/null +++ b/features/aliases.feature @@ -0,0 +1,28 @@ +Feature: Create shortcuts to specific WordPress installs + + Scenario: Alias for a path to a specific WP install + Given a WP install in 'testdir' + And a wp-cli.yml file: + """ + @testdir: + path: testdir + """ + + When I try `wp core is-installed` + Then STDERR should contain: + """ + Error: This does not seem to be a WordPress install. + """ + And the return code should be 1 + + When I run `wp @testdir core is-installed` + Then the return code should be 0 + + Scenario: Error when invalid alias provided + Given an empty directory + + When I try `wp @test option get home` + Then STDERR should be: + """ + Error: Alias '@test' not found. + """ From 82c8dadcaeca22ce6ad54015907ad88ae33c4d8d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 06:26:24 -0700 Subject: [PATCH 4534/4858] Treat global params as local when alias is used --- features/aliases.feature | 24 ++++++++++++++++++++++++ php/WP_CLI/Runner.php | 9 ++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/features/aliases.feature b/features/aliases.feature index 2bd738e039..b8d9b9fbc1 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -26,3 +26,27 @@ Feature: Create shortcuts to specific WordPress installs """ Error: Alias '@test' not found. """ + + Scenario: Treat global params as local when alias is used + Given a WP install in 'testdir' + And a wp-cli.yml file: + """ + @testdir: + path: testdir + """ + + When I run `wp @testdir option get home` + Then STDOUT should be: + """ + http://example.com + """ + + When I try `wp @testdir option get home --path=testdir` + Then STDERR should contain: + """ + Parameter errors: + """ + And STDERR should contain: + """ + unknown --path parameter + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ef2c323ae8..f2e5c8cc90 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -658,7 +658,14 @@ private function set_alias( $alias ) { if ( ! array_key_exists( $alias, $this->aliases ) ) { WP_CLI::error( "Alias '{$alias}' not found." ); } - $this->config = array_merge( $this->config, $this->aliases[ $this->alias ] ); + $orig_config = $this->config; + $alias_config = $this->aliases[ $this->alias ]; + $this->config = array_merge( $orig_config, $alias_config ); + foreach( $alias_config as $key => $_ ) { + if ( isset( $orig_config[ $key ] ) && ! is_null( $orig_config[ $key ] ) ) { + $this->assoc_args[ $key ] = $orig_config[ $key ]; + } + } } public function start() { From 867438b9e79bba30ebf93c559dc22a0420434ad4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 06:57:55 -0700 Subject: [PATCH 4535/4858] Aliases are config parameters specific to the WP install, not WP-CLI runtime --- features/aliases.feature | 16 ++++++++++++++++ php/WP_CLI/Configurator.php | 12 +++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/features/aliases.feature b/features/aliases.feature index b8d9b9fbc1..176eff1cfe 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -50,3 +50,19 @@ Feature: Create shortcuts to specific WordPress installs """ unknown --path parameter """ + + Scenario: Support global params specific to the WordPress install, not WP-CLI generally + Given a WP install in 'testdir' + And a wp-cli.yml file: + """ + @testdir: + path: testdir + debug: true + """ + + When I run `wp @testdir option get home` + Then STDOUT should be: + """ + http://example.com + """ + And STDERR should be empty diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index d9921425a6..d9cb9789a2 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -157,7 +157,17 @@ public function merge_yml( $path ) { } foreach ( $yaml as $key => $value ) { if ( preg_match( '#@[A-Za-z0-9-_]+#', $key ) ) { - $this->aliases[ $key ] = $value; + $this->aliases[ $key ] = array(); + foreach( array( + 'user', + 'url', + 'path', + 'ssh', + ) as $i ) { + if ( isset( $value[ $i ] ) ) { + $this->aliases[ $key ][ $i ] = $value[ $i ]; + } + } } elseif ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { if ( isset( $this->extra_config[ $key ] ) && ! empty( $yaml['_']['merge'] ) From 00e03ec0858d9182170ca7b25c10465ecc40c481 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 07:05:51 -0700 Subject: [PATCH 4536/4858] Set current user on `init` early, instead of after wp-settings.php load This more closely mirrors WordPress' behavior, allowing the rest of `wp-settings.php` to operate under the expected user context. --- php/WP_CLI/Runner.php | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6192de3140..e28e7f9c64 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -204,21 +204,6 @@ private static function set_wp_root( $path ) { $_SERVER['DOCUMENT_ROOT'] = realpath( $path ); } - /** - * Set a specific user context for WordPress. - * - * @param array $assoc_args - */ - private static function set_user( $assoc_args ) { - if ( isset( $assoc_args['user'] ) ) { - $fetcher = new \WP_CLI\Fetchers\User; - $user = $fetcher->get_check( $assoc_args['user'] ); - wp_set_current_user( $user->ID ); - } else { - kses_remove_filters(); - } - } - /** * Guess which URL context WP-CLI has been invoked under. * @@ -864,11 +849,6 @@ public function load_wordpress() { add_filter( 'filesystem_method', function() { return 'direct'; }, 99 ); - // Handle --user parameter - if ( ! defined( 'WP_INSTALLING' ) ) { - self::set_user( $this->config ); - } - WP_CLI::debug( 'Loaded WordPress', 'bootstrap' ); WP_CLI::do_hook( 'after_wp_load' ); @@ -967,6 +947,20 @@ private function setup_bootstrap_hooks() { }, 10, 3 ); } + // Handle --user parameter + if ( ! defined( 'WP_INSTALLING' ) ) { + $config = $this->config; + $this->add_wp_hook( 'init', function() use ( $config ) { + if ( isset( $config['user'] ) ) { + $fetcher = new \WP_CLI\Fetchers\User; + $user = $fetcher->get_check( $config['user'] ); + wp_set_current_user( $user->ID ); + } else { + kses_remove_filters(); + } + }, 0 ); + } + } /** From 83524c81fff372d63fdac34e9776da2926107367 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 08:47:39 -0700 Subject: [PATCH 4537/4858] `kses_init` happens with default priority, so we need to do this after --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e28e7f9c64..e5832d36cd 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -956,7 +956,7 @@ private function setup_bootstrap_hooks() { $user = $fetcher->get_check( $config['user'] ); wp_set_current_user( $user->ID ); } else { - kses_remove_filters(); + add_action( 'init', 'kses_remove_filters', 11 ); } }, 0 ); } From 13667aad29a7528c63b01f718178c29fb40fa984 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 08:59:09 -0700 Subject: [PATCH 4538/4858] Add explicit test case for expected behavior of `--user` --- features/aliases.feature | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/features/aliases.feature b/features/aliases.feature index 176eff1cfe..06ff9197b9 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -27,7 +27,7 @@ Feature: Create shortcuts to specific WordPress installs Error: Alias '@test' not found. """ - Scenario: Treat global params as local when alias is used + Scenario: Treat global params as local when included in alias Given a WP install in 'testdir' And a wp-cli.yml file: """ @@ -51,6 +51,35 @@ Feature: Create shortcuts to specific WordPress installs unknown --path parameter """ + When I run `wp @testdir eval 'echo get_current_user_id();' --user=admin` + Then STDOUT should be: + """ + 1 + """ + + Given a wp-cli.yml file: + """ + @testdir: + path: testdir + user: admin + """ + + When I run `wp @testdir eval 'echo get_current_user_id();'` + Then STDOUT should be: + """ + 1 + """ + + When I try `wp @testdir eval 'echo get_current_user_id();' --user=admin` + Then STDERR should contain: + """ + Parameter errors: + """ + And STDERR should contain: + """ + unknown --user parameter + """ + Scenario: Support global params specific to the WordPress install, not WP-CLI generally Given a WP install in 'testdir' And a wp-cli.yml file: From 0f59dfbde0c561f1ee06becba1c23ca96d1299ff Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 6 Jun 2016 22:00:59 +0545 Subject: [PATCH 4539/4858] Add csv and yaml for allowed values as format in theme mod get command --- php/commands/theme.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 79380cfd0e..ea7785cce4 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -752,6 +752,8 @@ class Theme_Mod_command extends WP_CLI_Command { * options: * - table * - json + * - csv + * - yaml * --- * * ## EXAMPLES From 359b7d6b7b0b76da337882261652a41ede3f55e4 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 6 Jun 2016 22:07:45 +0545 Subject: [PATCH 4540/4858] Add yaml as allowed parameter in cli check-update --- php/commands/cli.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index ce2db05cce..83749f4ce1 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -144,6 +144,7 @@ public function info( $_, $assoc_args ) { * - csv * - json * - count + * - yaml * --- * * ## EXAMPLES From e9ecb8e69c71928f698d78bff07fe4f24a640b9c Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 6 Jun 2016 22:11:50 +0545 Subject: [PATCH 4541/4858] Add list as default format in cli info command --- php/commands/cli.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 83749f4ce1..05660833b3 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -66,8 +66,9 @@ public function version() { * [--format=<format>] * : Render output in a particular format. * --- - * default: json + * default: list * options: + * - list * - json * --- * From 3922a9b15353b7f0e56fd9af9d48d8fc83afbb1b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 09:32:36 -0700 Subject: [PATCH 4542/4858] Fix PHP notice when installing a child theme `Plugin_Installer_Skin` and `Theme_Installer_Skin` both use a public `$api` class variable. We can safely define this too to prevent the error notice. --- php/WP_CLI/UpgraderSkin.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/UpgraderSkin.php b/php/WP_CLI/UpgraderSkin.php index a0df91820e..7af55981c3 100644 --- a/php/WP_CLI/UpgraderSkin.php +++ b/php/WP_CLI/UpgraderSkin.php @@ -9,6 +9,8 @@ */ class UpgraderSkin extends \WP_Upgrader_Skin { + public $api; + function header() {} function footer() {} function bulk_header() {} From 9fd087ddfbbda553b8cd6ea5debcb99d4754e705 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 6 Jun 2016 22:32:23 +0545 Subject: [PATCH 4543/4858] Add test for cli info without format parameter --- features/cli-info.feature | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/cli-info.feature b/features/cli-info.feature index e5911b1d56..1439a49774 100644 --- a/features/cli-info.feature +++ b/features/cli-info.feature @@ -17,3 +17,8 @@ Feature: Review CLI information """ {"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"} """ + And I run `wp cli info` + Then STDOUT should contain: + """ + WP-CLI packages dir: /tmp/wp-cli-home/.wp-cli/packages/ + """ From c9eda43712512548d1cd56ac170fe7c83725fba3 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 6 Jun 2016 22:35:46 +0545 Subject: [PATCH 4544/4858] Separate when condition for cli info test --- features/cli-info.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/cli-info.feature b/features/cli-info.feature index 1439a49774..ca455f6421 100644 --- a/features/cli-info.feature +++ b/features/cli-info.feature @@ -17,7 +17,8 @@ Feature: Review CLI information """ {"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"} """ - And I run `wp cli info` + + When I run `wp cli info` Then STDOUT should contain: """ WP-CLI packages dir: /tmp/wp-cli-home/.wp-cli/packages/ From 3192ae065b06ce95af08d15faa035da8545af6d2 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 6 Jun 2016 22:57:52 +0545 Subject: [PATCH 4545/4858] Default improvement in sidebar commands --- php/commands/sidebar.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index f71236059e..8745073960 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -28,7 +28,16 @@ class Sidebar_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * From 61393a833c98bbdb4df91b94eb009c8c19c80c29 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 11:00:14 -0700 Subject: [PATCH 4546/4858] Add explicit test for inheritance behavior --- features/aliases.feature | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/features/aliases.feature b/features/aliases.feature index 06ff9197b9..eb17625f66 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -95,3 +95,28 @@ Feature: Create shortcuts to specific WordPress installs http://example.com """ And STDERR should be empty + + Scenario: Defining a project alias completely overrides a global alias + Given a WP install in 'testdir' + And a config.yml file: + """ + @testdir: + path: testdir + """ + + When I run `WP_CLI_CONFIG_PATH=config.yml wp @testdir option get home` + Then STDOUT should be: + """ + http://example.com + """ + + Given a wp-cli.yml file: + """ + @testdir: + path: none-existent-install + """ + When I try `WP_CLI_CONFIG_PATH=config.yml wp @testdir option get home` + Then STDERR should contain: + """ + Error: This does not seem to be a WordPress install. + """ From 04ca01514e7601379e3d033fe9e7f91a4a375369 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 13:31:10 -0700 Subject: [PATCH 4547/4858] Escape ssh arguments to ensure they're quoted; include pretty version --- php/WP_CLI/Runner.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 13a042bfba..8de0b52199 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -350,16 +350,24 @@ private function run_ssh_command( $ssh ) { unset( $wp_args[ $k ] ); } } - $command = sprintf( + + $unescaped_command = sprintf( 'ssh -q %s %s %s', - escapeshellarg( $host ), + $host, $is_tty ? '-t' : '-T', - escapeshellarg( $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', $wp_args ) ) + $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ); - WP_CLI::debug( 'Running SSH command: ' . $command, 'bootstrap' ); + WP_CLI::debug( 'Running SSH command: ' . $unescaped_command, 'bootstrap' ); + + $escaped_command = sprintf( + 'ssh -q %s %s %s', + escapeshellarg( $host ), + $is_tty ? '-t' : '-T', + escapeshellarg( $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ) + ); - passthru( $command, $exit_code ); + passthru( $escaped_command, $exit_code ); if ( 0 !== $exit_code ) { exit( $exit_code ); } From 7bca58052d316ada65c67c4baec115389eda5dd2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 16:44:37 -0700 Subject: [PATCH 4548/4858] Always permit CLI operations against sites, regardless of status When using WP-CLI without the `--user=<user>` argument, the expectation is that you can perform any operation, and those operations aren't run as any user. Even when the `--user=<user>` argument is provided, there's a reasonable assumption the CLI operation isn't meant to run into a capability check. --- features/site.feature | 17 +++++++++++++++++ php/WP_CLI/Runner.php | 5 ++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/features/site.feature b/features/site.feature index a6980b1638..42c29ab520 100644 --- a/features/site.feature +++ b/features/site.feature @@ -257,3 +257,20 @@ Feature: Manage sites in a multisite installation """ Warning: You are not allowed to change the main site. """ + + Scenario: Permit CLI operations against archived and suspended sites + Given a WP multisite install + And I run `wp site create --slug=first --porcelain` + And save STDOUT as {FIRST_SITE} + + When I run `wp site archive {FIRST_SITE}` + Then STDOUT should be: + """ + Success: Site {FIRST_SITE} archived. + """ + + When I run `wp --url=example.com/first option get home` + Then STDOUT should be: + """ + http://example.com/first + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 13a042bfba..51773a8e71 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -965,9 +965,8 @@ private function setup_bootstrap_hooks() { } } - if ( defined( 'WP_INSTALLING' ) ) { - $this->add_wp_hook( 'ms_site_check', '__return_true' ); - } + // Always permit operations against sites, regardless of status + $this->add_wp_hook( 'ms_site_check', '__return_true' ); // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { From fcd1c76b2806d3cf52d1bc5f67a9e88592120d48 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 6 Jun 2016 16:48:38 -0700 Subject: [PATCH 4549/4858] Fix PHPCS issue --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8de0b52199..5c435bdb59 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -353,7 +353,7 @@ private function run_ssh_command( $ssh ) { $unescaped_command = sprintf( 'ssh -q %s %s %s', - $host, + $host, $is_tty ? '-t' : '-T', $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ); From ee1d0a13739678a79e02107dd2f3c7ba8d8eac94 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 7 Jun 2016 09:14:55 +0545 Subject: [PATCH 4550/4858] Fix build error in test of cli info --- features/cli-info.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/cli-info.feature b/features/cli-info.feature index ca455f6421..b5cedc1457 100644 --- a/features/cli-info.feature +++ b/features/cli-info.feature @@ -21,5 +21,5 @@ Feature: Review CLI information When I run `wp cli info` Then STDOUT should contain: """ - WP-CLI packages dir: /tmp/wp-cli-home/.wp-cli/packages/ + WP-CLI packages dir: """ From 5311f42423d467b6e003e0fb33ff714e3c3eaf86 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 7 Jun 2016 16:25:41 +0545 Subject: [PATCH 4551/4858] Improve doc in server command --- php/commands/server.php | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/php/commands/server.php b/php/commands/server.php index ec6d0656c4..c05ba5bac4 100644 --- a/php/commands/server.php +++ b/php/commands/server.php @@ -1,5 +1,18 @@ <?php - +/** + * Launch PHP's built-in web server. + * + * ## EXAMPLES + * + * # Make the instance available on any address (with port 8080) + * $ wp server --host=0.0.0.0 + * PHP 5.6.9 Development Server started at Tue May 24 01:27:11 2016 + * Listening on http://0.0.0.0:8080 + * Document root is / + * Press Ctrl-C to quit. + * + * @package wp-cli + */ class Server_Command extends WP_CLI_Command { /** @@ -10,10 +23,16 @@ class Server_Command extends WP_CLI_Command { * ## OPTIONS * * [--host=<host>] - * : The hostname to bind the server to. Default: localhost + * : The hostname to bind the server to. + * --- + * default: localhost + * --- * * [--port=<port>] - * : The port number to bind the server to. Default: 8080 + * : The port number to bind the server to. + * --- + * default: 8080 + * --- * * [--docroot=<path>] * : The path to use as the document root. From e67f14db9c7b06f297d86440fb497fd03242e5db Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 7 Jun 2016 16:35:12 +0545 Subject: [PATCH 4552/4858] Example: shell command --- php/commands/shell.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/php/commands/shell.php b/php/commands/shell.php index a4b8ebb3fd..5fe7dfa6ef 100644 --- a/php/commands/shell.php +++ b/php/commands/shell.php @@ -1,5 +1,15 @@ <?php - +/** + * Interactive PHP console. + * + * ## EXAMPLES + * + * # Start interactive PHP console + * $ wp shell + * wp> + * + * @package wp-cli + */ class Shell_Command extends \WP_CLI_Command { /** @@ -13,6 +23,12 @@ class Shell_Command extends \WP_CLI_Command { * * [--basic] * : Start in fail-safe mode, even if Boris is available. + * + * ## EXAMPLES + * + * # Start interactive PHP console + * $ wp shell + * wp> */ public function __invoke( $_, $assoc_args ) { $implementations = array( From 489f78950537d2c7e5094b85986b7b81eb148d79 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 8 Jun 2016 09:23:34 +0545 Subject: [PATCH 4553/4858] Example: core is-installed --- php/commands/core.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index f52846cd0c..80a3eadaec 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -422,6 +422,12 @@ public function config( $_, $assoc_args ) { * * ## EXAMPLES * + * # Check whether WordPress is installed; exit status 0 if installed, otherwise 1 + * $ wp core is-installed + * $ echo $? + * 1 + * + * # Bash script for checking whether WordPress is installed or not * if ! $(wp core is-installed); then * wp core install * fi From 5349e8c660e6456787151deee0762d50e062c927 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 8 Jun 2016 09:46:09 +0545 Subject: [PATCH 4554/4858] Improve doc in option commands --- php/commands/option.php | 57 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index 4328879643..a680fefd63 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -32,16 +32,25 @@ class Option_Command extends WP_CLI_Command { * Get an option. * * <key> - * : Key for the option + * : Key for the option. * * [--format=<format>] - * : Get value as var_export() or JSON. Default: var_export() + * : Get value in a particular format. + * --- + * default: var_export + * options: + * - var_export + * - json + * - yaml + * --- * * ## EXAMPLES * + * # Get option * $ wp option get home * http://example.com * + * # Get option in JSON format * $ wp option get active_plugins --format=json * {"0":"dynamically-dynamic-sidebar\/dynamically-dynamic-sidebar.php","1":"monster-widget\/monster-widget.php","2":"show-current-template\/show-current-template.php","3":"theme-check\/theme-check.php","5":"wordpress-importer\/wordpress-importer.php"} */ @@ -68,10 +77,22 @@ public function get( $args, $assoc_args ) { * : The value of the option to add. If ommited, the value is read from STDIN. * * [--format=<format>] - * : The serialization format for the value. Default is plaintext. + * : The serialization format for the value. + * --- + * default: plaintext + * options: + * - plaintext + * - json + * --- * * [--autoload=<autoload>] - * : Should this option be automatically loaded. Accepted values: yes, no. Default: yes + * : Should this option be automatically loaded. + * --- + * default: yes + * options: + * - yes + * - no + * --- * * ## EXAMPLES * @@ -111,7 +132,17 @@ public function add( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. Accepted values: table, json, csv, count, total_bytes. Default: table + * : The serialization format for the value. total_bytes displays the total size of matching options in bytes. + * --- + * default: table + * options: + * - table + * - json + * - csv + * - count + * - yaml + * - total_bytes + * --- * * ## AVAILABLE FIELDS * @@ -215,10 +246,22 @@ public function list_( $args, $assoc_args ) { * : The new value. If ommited, the value is read from STDIN. * * [--autoload=<autoload>] - * : Requires WP 4.2. Should this option be automatically loaded. Accepted values: yes, no. Default: yes + * : Requires WP 4.2. Should this option be automatically loaded. + * --- + * default: yes + * options: + * - yes + * - no + * --- * * [--format=<format>] - * : The serialization format for the value. Default is plaintext. + * : The serialization format for the value. + * --- + * default: plaintext + * options: + * - plaintext + * - json + * --- * * ## EXAMPLES * From 64aaccbd002659b8aa693f7bfbbc1bfe4e72ab31 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 8 Jun 2016 20:46:57 +0545 Subject: [PATCH 4555/4858] Improve doc in rewrite commands --- php/commands/rewrite.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index bb0ecaafba..de7a62767d 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -173,10 +173,22 @@ public function structure( $args, $assoc_args ) { * : Show rewrite rules from a particular source. * * [--fields=<fields>] - * : Limit the output to specific fields. Defaults to match,query,source. + * : Limit the output to specific fields. + * --- + * default: match,query,source + * --- * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * --- * * ## EXAMPLES * From ba5f32bb3bafd4ef957ba5768a4a9b133666160d Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Wed, 8 Jun 2016 15:29:24 +0000 Subject: [PATCH 4556/4858] Example wp package browse, #2770 --- php/commands/package.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/php/commands/package.php b/php/commands/package.php index bc73402808..63713095d2 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -87,6 +87,27 @@ class Package_Command extends WP_CLI_Command { * * [--format=<format>] * : Accepted values: table, json, csv, yaml, ids. Default: table. + * + * ## EXAMPLES + * + * $ wp package browse --format=yaml + * --- + * 10up/mu-migration: + * name: 10up/mu-migration + * description: A set of WP-CLI commands to support the migration of single WordPress instances to multisite + * authors: Nícholas André + * version: dev-master, dev-develop + * aaemnnosttv/wp-cli-dotenv-command: + * name: aaemnnosttv/wp-cli-dotenv-command + * description: Dotenv commands for WP-CLI + * authors: Evan Mattson + * version: v0.1, v0.1-beta.1, v0.2, dev-master, dev-dev, dev-develop, dev-tests/behat + * aaemnnosttv/wp-cli-http-command: + * name: aaemnnosttv/wp-cli-http-command + * description: WP-CLI command for using the WordPress HTTP API + * authors: Evan Mattson + * version: dev-master + * */ public function browse( $_, $assoc_args ) { $this->show_packages( $this->get_community_packages(), $assoc_args ); From 2bd814bec4f345747117b88f2e820153141d67b6 Mon Sep 17 00:00:00 2001 From: hideokamoto <kokkoku214@gmail.com> Date: Wed, 8 Jun 2016 15:33:40 +0000 Subject: [PATCH 4557/4858] Example wp package path, #2770 --- php/commands/package.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/package.php b/php/commands/package.php index bc73402808..41e5021d3b 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -228,7 +228,8 @@ public function list_( $args, $assoc_args ) { * /home/person/.wp-cli/packages/ * * # Change directory to package path - * $ cd $(wp package path) + * $ cd $(wp package path) && pwd + * /home/vagrant/.wp-cli/packages */ function path( $args ) { $packages_dir = WP_CLI::get_runner()->get_packages_dir_path(); From f19ea02ebb093195c309a622a75f6315713eb55c Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 11:56:02 +0545 Subject: [PATCH 4558/4858] Add trailing period in widget commands messages --- features/widget.feature | 5 ++++- php/commands/widget.php | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/features/widget.feature b/features/widget.feature index 610d963ea0..51d746ae67 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -33,7 +33,10 @@ Feature: Manage widgets in WordPress sidebar Then STDOUT should not be empty When I run `wp widget deactivate meta-2` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: Widget(s) deactivated. + """ When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: diff --git a/php/commands/widget.php b/php/commands/widget.php index ef4dcc347b..6a7cf0c797 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -238,7 +238,7 @@ public function move( $args, $assoc_args ) { * ## EXAMPLES * * $ wp widget deactivate recent-comments-2 - * Success: Widget(s) deactivated + * Success: Widget(s) deactivated. * * @subcommand deactivate */ @@ -257,7 +257,7 @@ public function deactivate( $args, $assoc_args ) { } - WP_CLI::success( "Widget(s) deactivated" ); + WP_CLI::success( "Widget(s) deactivated." ); } /** From c111f6a730fe435c9fb9e4a2a31d50c4b9441cc5 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 12:10:22 +0545 Subject: [PATCH 4559/4858] Comment: add trailing period in messages --- features/comment-recount.feature | 2 +- php/commands/comment.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/features/comment-recount.feature b/features/comment-recount.feature index 5de768a0fe..7208b97bdc 100644 --- a/features/comment-recount.feature +++ b/features/comment-recount.feature @@ -21,5 +21,5 @@ Feature: Recount comments on a post When I run `wp comment recount 1` Then STDOUT should be: """ - Updated post 1 comment count to 3 + Updated post 1 comment count to 3. """ diff --git a/php/commands/comment.php b/php/commands/comment.php index 10a6796a0e..56b1ad0b77 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -351,7 +351,7 @@ public function delete( $args, $assoc_args ) { return array( 'success', "Trashed comment $comment_id." ); } } else { - return array( 'error', "Failed deleting comment $comment_id" ); + return array( 'error', "Failed deleting comment $comment_id." ); } } ); } @@ -364,7 +364,7 @@ private function call( $args, $status, $success, $failure ) { if ( $func( $comment_id ) ) { WP_CLI::success( "$success comment $comment_id." ); } else { - WP_CLI::error( "$failure comment $comment_id" ); + WP_CLI::error( "$failure comment $comment_id." ); } } @@ -376,7 +376,7 @@ private function set_status( $args, $status, $success ) { if ( is_wp_error( $r ) ) { WP_CLI::error( $r ); } else { - WP_CLI::success( "$success comment $comment->comment_ID" ); + WP_CLI::success( "$success comment $comment->comment_ID." ); } } @@ -550,16 +550,16 @@ public function count( $args, $assoc_args ) { * ## EXAMPLES * * $ wp comment recount 123 - * Updated post 123 comment count to 67 + * Updated post 123 comment count to 67. */ public function recount( $args ) { foreach( $args as $id ) { wp_update_comment_count( $id ); $post = get_post( $id ); if ( $post ) { - WP_CLI::log( sprintf( "Updated post %d comment count to %d", $post->ID, $post->comment_count ) ); + WP_CLI::log( sprintf( "Updated post %d comment count to %d.", $post->ID, $post->comment_count ) ); } else { - WP_CLI::warning( sprintf( "Post %d doesn't exist", $post->ID ) ); + WP_CLI::warning( sprintf( "Post %d doesn't exist.", $post->ID ) ); } } } From 8660c2fc3af44f8a666e8ba1e57b448808629deb Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 12:23:36 +0545 Subject: [PATCH 4560/4858] CLI: add trailing period in messages --- features/cli.feature | 2 +- php/commands/cli.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/cli.feature b/features/cli.feature index 081ed727b0..84046f49ed 100644 --- a/features/cli.feature +++ b/features/cli.feature @@ -109,7 +109,7 @@ Feature: `wp cli` tasks When I run `{PHAR_PATH} cli update --nightly --yes` Then STDOUT should contain: """ - Success: Updated WP-CLI to the latest nightly release + Success: Updated WP-CLI to the latest nightly release. """ And STDERR should be empty diff --git a/php/commands/cli.php b/php/commands/cli.php index 05660833b3..3e33904fa2 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -215,9 +215,9 @@ public function update( $_, $assoc_args ) { $old_phar = realpath( $_SERVER['argv'][0] ); if ( ! is_writable( $old_phar ) ) { - WP_CLI::error( sprintf( "%s is not writable by current user", $old_phar ) ); + WP_CLI::error( sprintf( "%s is not writable by current user.", $old_phar ) ); } else if ( ! is_writeable( dirname( $old_phar ) ) ) { - WP_CLI::error( sprintf( "%s is not writable by current user", dirname( $old_phar ) ) ); + WP_CLI::error( sprintf( "%s is not writable by current user.", dirname( $old_phar ) ) ); } if ( isset( $assoc_args['nightly'] ) ) { @@ -271,7 +271,7 @@ public function update( $_, $assoc_args ) { $mode = fileperms( $old_phar ) & 511; if ( false === @chmod( $temp, $mode ) ) { - WP_CLI::error( sprintf( "Cannot chmod %s", $temp ) ); + WP_CLI::error( sprintf( "Cannot chmod %s.", $temp ) ); } class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the file we no longer have access to this class @@ -285,7 +285,7 @@ class_exists( '\cli\Colors' ); // this autoloads \cli\Colors - after we move the } else { $updated_version = $newest['version']; } - WP_CLI::success( sprintf( 'Updated WP-CLI to %s', $updated_version ) ); + WP_CLI::success( sprintf( 'Updated WP-CLI to %s.', $updated_version ) ); } /** @@ -304,7 +304,7 @@ private function get_updates( $assoc_args ) { $response = Utils\http_request( 'GET', $url, $headers, $options ); if ( ! $response->success || 200 !== $response->status_code ) { - WP_CLI::error( sprintf( "Failed to get latest version (HTTP code %d)", $response->status_code ) ); + WP_CLI::error( sprintf( "Failed to get latest version (HTTP code %d).", $response->status_code ) ); } $release_data = json_decode( $response->body ); From 7e256a3b4d306caccb4c47c7cb2807299be2937e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 16:21:55 +0545 Subject: [PATCH 4561/4858] Cron: add trailing period in command messages --- features/cron.feature | 4 ++-- php/commands/cron.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index fbdfae4d59..76b1ee0e81 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -122,7 +122,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event delete wp_cli_test_event_5` Then STDOUT should be: """ - Success: Deleted 2 instances of the cron event 'wp_cli_test_event_5' + Success: Deleted 2 instances of the cron event 'wp_cli_test_event_5'. """ When I run `wp cron event list` @@ -134,7 +134,7 @@ Feature: Manage WP-Cron events and schedules When I try `wp cron event delete wp_cli_test_event_5` Then STDERR should be: """ - Error: Invalid cron event 'wp_cli_test_event_5' + Error: Invalid cron event 'wp_cli_test_event_5'. """ Scenario: Scheduling and then running a re-occurring event diff --git a/php/commands/cron.php b/php/commands/cron.php index 297d950f9c..6e531e6c87 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -177,7 +177,7 @@ public function schedule( $args, $assoc_args ) { if ( false !== $event ) { WP_CLI::success( sprintf( "Scheduled event with hook '%s' for %s GMT.", $hook, date( self::$time_format, $timestamp ) ) ); } else { - WP_CLI::error( 'Event not scheduled' ); + WP_CLI::error( 'Event not scheduled.' ); } } @@ -306,16 +306,16 @@ public function delete( $args, $assoc_args ) { if ( $result ) { $deleted++; } else { - WP_CLI::warning( sprintf( "Failed to the delete the cron event '%s'", $hook ) ); + WP_CLI::warning( sprintf( "Failed to the delete the cron event '%s'.", $hook ) ); } } } if ( $deleted ) { - $message = ( 1 == $deleted ) ? "Deleted the cron event '%2\$s'" : "Deleted %1\$d instances of the cron event '%2\$s'"; + $message = ( 1 == $deleted ) ? "Deleted the cron event '%2\$s'." : "Deleted %1\$d instances of the cron event '%2\$s'."; WP_CLI::success( sprintf( $message, $deleted, $hook ) ); } else { - WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); + WP_CLI::error( sprintf( "Invalid cron event '%s'.", $hook ) ); } } From aadd8c58ef4a2e570e13f3b289ba4273ce4dd0a4 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 16:28:11 +0545 Subject: [PATCH 4562/4858] Transient: add trailing period in command messages --- php/commands/transient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/transient.php b/php/commands/transient.php index f0d34437dc..3797d11fce 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -176,7 +176,7 @@ public function delete_expired() { if ( $count > 0 ) { WP_CLI::success( "$count expired transients deleted from the database." ); } else { - WP_CLI::success( "No expired transients found" ); + WP_CLI::success( "No expired transients found." ); } if ( $_wp_using_ext_object_cache ) { @@ -207,7 +207,7 @@ public function delete_all() { if ( $count > 0 ) { WP_CLI::success( "$count transients deleted from the database." ); } else { - WP_CLI::success( "No transients found" ); + WP_CLI::success( "No transients found." ); } if ( $_wp_using_ext_object_cache ) { From 8455c1c52f164c494ce4892cacffcba9e00821fb Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 16:35:00 +0545 Subject: [PATCH 4563/4858] Theme: add trailing period to theme commands messages --- features/theme-mod.feature | 2 +- php/commands/theme.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/theme-mod.feature b/features/theme-mod.feature index 7ef2115f7e..61ac1d6aa8 100644 --- a/features/theme-mod.feature +++ b/features/theme-mod.feature @@ -32,7 +32,7 @@ Feature: Manage WordPress theme mods When I run `wp theme mod set background_color 123456` Then STDOUT should be: """ - Success: Theme mod background_color set to 123456 + Success: Theme mod background_color set to 123456. """ Scenario: Removing theme mods diff --git a/php/commands/theme.php b/php/commands/theme.php index ea7785cce4..54181962cf 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -892,9 +892,9 @@ public function set( $args = array(), $assoc_args = array() ) { set_theme_mod( $mod, $value ); if ( $value == get_theme_mod( $mod ) ) { - WP_CLI::success( sprintf( "Theme mod %s set to %s", $mod, $value ) ); + WP_CLI::success( sprintf( "Theme mod %s set to %s.", $mod, $value ) ); } else { - WP_CLI::success( sprintf( "Could not update theme mod %s", $mod ) ); + WP_CLI::success( sprintf( "Could not update theme mod %s.", $mod ) ); } } From bf05d7d40a1b962bc36663c3696e9b2cccb63fea Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 11 Jun 2016 17:01:59 +0545 Subject: [PATCH 4564/4858] Improve default doc for widget commands --- php/commands/widget.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index ef4dcc347b..8c10c75519 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -46,7 +46,17 @@ class Widget_Command extends WP_CLI_Command { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * From 560a472e99a86dbc46b25f16265d80efa5b56477 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 13 Jun 2016 05:20:54 -0700 Subject: [PATCH 4565/4858] Update Composer dependencies to latest ``` Loading composer repositories with package information Updating dependencies (including require-dev) - Removing symfony/yaml (v2.7.11) - Installing symfony/yaml (v2.8.7) Downloading: 100% - Removing symfony/filesystem (v2.7.11) - Installing symfony/filesystem (v2.8.7) Downloading: 100% - Removing symfony/config (v2.7.11) - Installing symfony/config (v2.8.7) Downloading: 100% - Removing symfony/dependency-injection (v2.7.11) - Installing symfony/dependency-injection (v2.8.7) Downloading: 100% - Removing symfony/event-dispatcher (v2.7.11) - Installing symfony/event-dispatcher (v2.8.7) Downloading: 100% - Installing symfony/polyfill-mbstring (v1.2.0) Loading from cache - Removing symfony/translation (v2.7.11) - Installing symfony/translation (v2.8.7) Downloading: 100% - Installing psr/log (1.0.0) Loading from cache - Removing symfony/process (v2.8.4) - Installing symfony/process (v2.8.7) Downloading: 100% - Removing symfony/finder (v2.7.11) - Installing symfony/finder (v2.8.7) Downloading: 100% - Removing symfony/console (v2.7.11) - Installing symfony/console (v2.8.7) Downloading: 100% - Removing composer/spdx-licenses (1.1.3) - Installing composer/spdx-licenses (1.1.4) Downloading: 100% - Removing composer/semver (1.4.0) - Installing composer/semver (1.4.1) Downloading: 100% - Installing composer/ca-bundle (1.0.2) Downloading: 100% - Removing composer/composer (1.0.2) - Installing composer/composer (1.1.2) Downloading: 100% - Removing phpunit/php-timer (1.0.7) - Installing phpunit/php-timer (1.0.8) Loading from cache Writing lock file Generating autoload files ``` --- composer.lock | 243 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 171 insertions(+), 72 deletions(-) diff --git a/composer.lock b/composer.lock index 389c55967c..ab7cf9aaa2 100644 --- a/composer.lock +++ b/composer.lock @@ -8,24 +8,81 @@ "content-hash": "10cf19699e3fed767e31e1493a07c8f0", "packages": [ { - "name": "composer/composer", + "name": "composer/ca-bundle", "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "a2995e5fe351055f2c7630166af12ce8fd03edfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/a2995e5fe351055f2c7630166af12ce8fd03edfc", + "reference": "a2995e5fe351055f2c7630166af12ce8fd03edfc", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "symfony/process": "^2.5 || ^3.0" + }, + "suggest": { + "symfony/process": "This is necessary to reliably check whether openssl_x509_parse is vulnerable on older php versions, but can be ignored on PHP 5.5.6+" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2016-04-13 10:13:24" + }, + { + "name": "composer/composer", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "a083aa5e0c9b8ad989c622638aa380c1f88a68ec" + "reference": "b2cf67b1a575d7e648c742be2454339232ef32b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/a083aa5e0c9b8ad989c622638aa380c1f88a68ec", - "reference": "a083aa5e0c9b8ad989c622638aa380c1f88a68ec", + "url": "https://api.github.com/repos/composer/composer/zipball/b2cf67b1a575d7e648c742be2454339232ef32b2", + "reference": "b2cf67b1a575d7e648c742be2454339232ef32b2", "shasum": "" }, "require": { + "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", "composer/spdx-licenses": "^1.0", "justinrainbow/json-schema": "^1.6", "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", "seld/cli-prompt": "^1.0", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.0", @@ -49,7 +106,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.1-dev" } }, "autoload": { @@ -80,20 +137,20 @@ "dependency", "package" ], - "time": "2016-04-21 11:30:19" + "time": "2016-05-31 18:48:12" }, { "name": "composer/semver", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "84c47f3d8901440403217afc120683c7385aecb8" + "reference": "03c9de5aa25e7672c4ad251eeaba0c47a06c8b98" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/84c47f3d8901440403217afc120683c7385aecb8", - "reference": "84c47f3d8901440403217afc120683c7385aecb8", + "url": "https://api.github.com/repos/composer/semver/zipball/03c9de5aa25e7672c4ad251eeaba0c47a06c8b98", + "reference": "03c9de5aa25e7672c4ad251eeaba0c47a06c8b98", "shasum": "" }, "require": { @@ -142,20 +199,20 @@ "validation", "versioning" ], - "time": "2016-03-30 13:16:03" + "time": "2016-06-02 09:04:51" }, { "name": "composer/spdx-licenses", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b" + "reference": "88c26372b1afac36d8db601cdf04ad8716f53d88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/547659c3cacd3ccfe1b4714c2ff88cafc6b6793b", - "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/88c26372b1afac36d8db601cdf04ad8716f53d88", + "reference": "88c26372b1afac36d8db601cdf04ad8716f53d88", "shasum": "" }, "require": { @@ -203,7 +260,7 @@ "spdx", "validator" ], - "time": "2016-03-25 10:57:10" + "time": "2016-05-04 12:27:30" }, { "name": "justinrainbow/json-schema", @@ -405,6 +462,44 @@ ], "time": "2013-02-24 15:01:54" }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, { "name": "ramsey/array_column", "version": "1.1.3", @@ -639,16 +734,16 @@ }, { "name": "symfony/config", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c" + "reference": "a2edd59c2163c65747fc3f35d132b5a39266bd05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/5273f4724dc5288fe7a33cb08077ab9852621f2c", - "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c", + "url": "https://api.github.com/repos/symfony/config/zipball/a2edd59c2163c65747fc3f35d132b5a39266bd05", + "reference": "a2edd59c2163c65747fc3f35d132b5a39266bd05", "shasum": "" }, "require": { @@ -688,20 +783,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-03-04 07:54:35" + "time": "2016-06-06 11:11:27" }, { "name": "symfony/console", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154" + "reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154", - "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154", + "url": "https://api.github.com/repos/symfony/console/zipball/5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3", + "reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3", "shasum": "" }, "require": { @@ -748,20 +843,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-03-17 09:19:04" + "time": "2016-06-06 15:06:25" }, { "name": "symfony/dependency-injection", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f7b4a498e679fa440b16facb934680a1527ed48c" + "reference": "2d05009d890cf1139988ff059b5b2e0eb280ed13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7b4a498e679fa440b16facb934680a1527ed48c", - "reference": "f7b4a498e679fa440b16facb934680a1527ed48c", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2d05009d890cf1139988ff059b5b2e0eb280ed13", + "reference": "2d05009d890cf1139988ff059b5b2e0eb280ed13", "shasum": "" }, "require": { @@ -777,6 +872,7 @@ }, "suggest": { "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", "symfony/yaml": "" }, @@ -810,20 +906,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-03-21 07:27:21" + "time": "2016-06-06 11:11:27" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87" + "reference": "2a6b8713f8bdb582058cfda463527f195b066110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87", - "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2a6b8713f8bdb582058cfda463527f195b066110", + "reference": "2a6b8713f8bdb582058cfda463527f195b066110", "shasum": "" }, "require": { @@ -870,20 +966,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-03-07 14:04:32" + "time": "2016-06-06 11:11:27" }, { "name": "symfony/filesystem", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "f08ffdf229252cd2745558cb2112df43903bcae4" + "reference": "dee379131dceed90a429e951546b33edfe7dccbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4", - "reference": "f08ffdf229252cd2745558cb2112df43903bcae4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dee379131dceed90a429e951546b33edfe7dccbb", + "reference": "dee379131dceed90a429e951546b33edfe7dccbb", "shasum": "" }, "require": { @@ -919,20 +1015,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-03-27 10:20:16" + "time": "2016-04-12 18:01:21" }, { "name": "symfony/finder", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1" + "reference": "3ec095fab1800222732ca522a95dce8fa124007b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1", - "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1", + "url": "https://api.github.com/repos/symfony/finder/zipball/3ec095fab1800222732ca522a95dce8fa124007b", + "reference": "3ec095fab1800222732ca522a95dce8fa124007b", "shasum": "" }, "require": { @@ -968,20 +1064,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-03-10 10:53:53" + "time": "2016-06-06 11:11:27" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.1.1", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "1289d16209491b584839022f29257ad859b8532d" + "reference": "dff51f72b0706335131b00a7f49606168c582594" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", - "reference": "1289d16209491b584839022f29257ad859b8532d", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", + "reference": "dff51f72b0706335131b00a7f49606168c582594", "shasum": "" }, "require": { @@ -993,7 +1089,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -1027,20 +1123,20 @@ "portable", "shim" ], - "time": "2016-01-20 09:13:37" + "time": "2016-05-18 14:26:46" }, { "name": "symfony/process", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "fb467471952ef5cf8497c029980e556b47545333" + "reference": "115347d00c342198cdc52a7bd8bc15b5ab43500c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333", - "reference": "fb467471952ef5cf8497c029980e556b47545333", + "url": "https://api.github.com/repos/symfony/process/zipball/115347d00c342198cdc52a7bd8bc15b5ab43500c", + "reference": "115347d00c342198cdc52a7bd8bc15b5ab43500c", "shasum": "" }, "require": { @@ -1076,20 +1172,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-03-23 13:11:46" + "time": "2016-06-06 11:11:27" }, { "name": "symfony/translation", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "d60b8e076d22953aabebeebda53bf334438e7aca" + "reference": "8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/d60b8e076d22953aabebeebda53bf334438e7aca", - "reference": "d60b8e076d22953aabebeebda53bf334438e7aca", + "url": "https://api.github.com/repos/symfony/translation/zipball/8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1", + "reference": "8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1", "shasum": "" }, "require": { @@ -1140,20 +1236,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-03-25 01:40:30" + "time": "2016-06-06 11:11:27" }, { "name": "symfony/yaml", - "version": "v2.8.4", + "version": "v2.8.7", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb" + "reference": "815fabf3f48c7d1df345a69d1ad1a88f59757b34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb", - "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb", + "url": "https://api.github.com/repos/symfony/yaml/zipball/815fabf3f48c7d1df345a69d1ad1a88f59757b34", + "reference": "815fabf3f48c7d1df345a69d1ad1a88f59757b34", "shasum": "" }, "require": { @@ -1189,7 +1285,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-03-04 07:54:35" + "time": "2016-06-06 11:11:27" }, { "name": "wp-cli/php-cli-tools", @@ -1517,21 +1613,24 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.7", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, "type": "library", "autoload": { "classmap": [ @@ -1554,7 +1653,7 @@ "keywords": [ "timer" ], - "time": "2015-06-21 08:01:12" + "time": "2016-05-12 18:03:57" }, { "name": "phpunit/php-token-stream", From d5d2c58953e9935f84a6e7d748a5a8b258ddea35 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 13 Jun 2016 06:16:37 -0700 Subject: [PATCH 4566/4858] Ensure `PSR\Logger` is included --- utils/make-phar.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/make-phar.php b/utils/make-phar.php index 219164bd66..dca8ea61c7 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -69,6 +69,7 @@ function set_file_contents( $phar, $path, $content ) { ->in(WP_CLI_ROOT . '/vendor/mustache') ->in(WP_CLI_ROOT . '/vendor/rmccue/requests') ->in(WP_CLI_ROOT . '/vendor/composer') + ->in(WP_CLI_ROOT . '/vendor/psr') ->in(WP_CLI_ROOT . '/vendor/seld') ->in(WP_CLI_ROOT . '/vendor/symfony') ->in(WP_CLI_ROOT . '/vendor/nb/oxymel') @@ -77,6 +78,7 @@ function set_file_contents( $phar, $path, $content ) { ->in(WP_CLI_ROOT . '/vendor/justinrainbow/json-schema') ->exclude('test') ->exclude('tests') + ->exclude('Test') ->exclude('Tests') ->exclude('php-cli-tools/examples') ; From 18be63d06613b72614f9be20491e0c68ee4dccbd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 13 Jun 2016 06:16:58 -0700 Subject: [PATCH 4567/4858] Add cacert.pem from its new directory --- utils/make-phar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/make-phar.php b/utils/make-phar.php index dca8ea61c7..5370b482a6 100644 --- a/utils/make-phar.php +++ b/utils/make-phar.php @@ -102,8 +102,8 @@ function set_file_contents( $phar, $path, $content ) { add_file( $phar, WP_CLI_ROOT . '/vendor/autoload.php' ); add_file( $phar, WP_CLI_ROOT . '/ci/behat-tags.php' ); +add_file( $phar, WP_CLI_ROOT . '/vendor/composer/ca-bundle/res/cacert.pem' ); add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/LICENSE' ); -add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/res/cacert.pem' ); add_file( $phar, WP_CLI_ROOT . '/vendor/composer/composer/res/composer-schema.json' ); add_file( $phar, WP_CLI_ROOT . '/vendor/rmccue/requests/library/Requests/Transport/cacert.pem' ); From bd3557eb3c2fb1352bd60599a075c6da79005c1a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 13 Jun 2016 20:38:34 +0545 Subject: [PATCH 4568/4858] Revert default doc change in rewrite list command --- php/commands/rewrite.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/php/commands/rewrite.php b/php/commands/rewrite.php index de7a62767d..13ffcd4df7 100644 --- a/php/commands/rewrite.php +++ b/php/commands/rewrite.php @@ -173,10 +173,7 @@ public function structure( $args, $assoc_args ) { * : Show rewrite rules from a particular source. * * [--fields=<fields>] - * : Limit the output to specific fields. - * --- - * default: match,query,source - * --- + * : Limit the output to specific fields. Defaults to match,query,source. * * [--format=<format>] * : Render output in a particular format. From ddcdb38301b93bdeb58b9118cd11aa280d142ff0 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 14 Jun 2016 06:04:34 +0545 Subject: [PATCH 4569/4858] User: add missing trailing period in command messages --- php/commands/user.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 4db4b5482f..b0f93dff48 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -233,7 +233,7 @@ public function delete( $args, $assoc_args ) { $message = "Deleted user $user_id."; } else { $r = wp_delete_user( $user_id, $reassign ); - $message = "Removed user $user_id from " . home_url(); + $message = "Removed user $user_id from " . home_url() . "."; } if ( $r ) { @@ -328,7 +328,7 @@ public function create( $args, $assoc_args ) { } $user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email ); if ( ! $user_id ) { - WP_CLI::error( "Unknown error creating new user" ); + WP_CLI::error( "Unknown error creating new user." ); } $user->ID = $user_id; $user_id = wp_update_user( $user ); @@ -490,7 +490,7 @@ public function generate( $args, $assoc_args ) { * ## EXAMPLES * * $ wp user set-role 12 author - * Success: Added johndoe (12) to http://example.com as author + * Success: Added johndoe (12) to http://example.com as author. * * @subcommand set-role */ @@ -507,7 +507,7 @@ public function set_role( $args, $assoc_args ) { else $user->set_role( $role ); - WP_CLI::success( "Added {$user->user_login} ({$user->ID}) to " . site_url() . " as {$role}" ); + WP_CLI::success( "Added {$user->user_login} ({$user->ID}) to " . site_url() . " as {$role}." ); } /** @@ -576,7 +576,7 @@ public function remove_role( $args, $assoc_args ) { else $user->remove_all_caps(); - WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() ); + WP_CLI::success( "Removed {$user->user_login} ({$user->ID}) from " . site_url() . "." ); } } @@ -772,7 +772,7 @@ public function import_csv( $args, $assoc_args ) { $invalid_role = false; foreach( $roles as $role ) { if ( is_null( get_role( $role ) ) ) { - WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); + WP_CLI::warning( "{$new_user['user_login']} has an invalid role." ); $invalid_role = true; break; } @@ -785,7 +785,7 @@ public function import_csv( $args, $assoc_args ) { } else if ( 'none' === $new_user['role'] ) { $new_user['role'] = false; } elseif ( is_null( get_role( $new_user['role'] ) ) ) { - WP_CLI::warning( "{$new_user['user_login']} has an invalid role" ); + WP_CLI::warning( "{$new_user['user_login']} has an invalid role." ); continue; } @@ -798,7 +798,7 @@ public function import_csv( $args, $assoc_args ) { if ( $existing_user && \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-update' ) ) { - WP_CLI::log( "{$existing_user->user_login} exists and has been skipped" ); + WP_CLI::log( "{$existing_user->user_login} exists and has been skipped." ); continue; } else if ( $existing_user ) { @@ -823,7 +823,7 @@ public function import_csv( $args, $assoc_args ) { } $user_id = wpmu_create_user( $new_user['user_login'], $new_user['user_pass'], $new_user['user_email'] ); if ( ! $user_id ) { - WP_CLI::warning( "Unknown error creating new user" ); + WP_CLI::warning( "Unknown error creating new user." ); continue; } $new_user['ID'] = $user_id; @@ -856,9 +856,9 @@ public function import_csv( $args, $assoc_args ) { } if ( !empty( $existing_user ) ) { - WP_CLI::success( $new_user['user_login'] . " updated" ); + WP_CLI::success( $new_user['user_login'] . " updated." ); } else { - WP_CLI::success( $new_user['user_login'] . " created" ); + WP_CLI::success( $new_user['user_login'] . " created." ); } } } From 95ef4e42bed858dc673315a0e992730f19b442be Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 14 Jun 2016 06:11:24 +0545 Subject: [PATCH 4570/4858] Menu: add missing trailing period in command message --- php/commands/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 5381e1ba27..7959447a44 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -261,7 +261,7 @@ public function list_( $args, $assoc_args ) { $items = wp_get_nav_menu_items( $args[0] ); if ( false === $items || is_wp_error( $items ) ) { - WP_CLI::error( "Invalid menu" ); + WP_CLI::error( "Invalid menu." ); } // Correct position inconsistency and From 8d0b195dc3646d98581344482bc59da68dbbca8b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 14 Jun 2016 06:17:31 +0545 Subject: [PATCH 4571/4858] Role: add missing trailing period in command messages --- features/roles.feature | 8 ++++---- php/commands/role.php | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index c4df0c9075..54631936d6 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -20,27 +20,27 @@ Feature: Manage WordPress roles When I run `wp role reset author` Then STDOUT should be: """ - Success: Reset 0/1 roles + Success: Reset 0/1 roles. """ When I run `wp cap remove author read` And I run `wp role reset author` Then STDOUT should be: """ - Success: Reset 1/1 roles + Success: Reset 1/1 roles. """ When I run `wp role reset author editor` Then STDOUT should be: """ - Success: Reset 0/2 roles + Success: Reset 0/2 roles. """ When I run `wp cap remove author read` And I run `wp role reset author editor` Then STDOUT should be: """ - Success: Reset 1/2 roles + Success: Reset 1/2 roles. """ When I run `wp role reset --all` diff --git a/php/commands/role.php b/php/commands/role.php index cccd636bff..2df328bd47 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -59,7 +59,6 @@ class Role_Command extends WP_CLI_Command { * - yaml * --- * - * * ## AVAILABLE FIELDS * * These fields will be displayed by default for each role: @@ -239,7 +238,7 @@ public function delete( $args ) { * * # Reset role * $ wp role reset administrator author contributor - * Success: Reset 1/3 roles + * Success: Reset 1/3 roles. * * # Reset all default roles * $ wp role reset --all @@ -324,7 +323,7 @@ public function reset( $args, $assoc_args ) { } } - WP_CLI::success( "Reset $num_reset/$num_to_reset roles" ); + WP_CLI::success( "Reset $num_reset/$num_to_reset roles." ); } From 580eba28e07eed4c037673e5ee57b9cd0ae57abf Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 14 Jun 2016 06:27:48 +0545 Subject: [PATCH 4572/4858] Term: add missing trailing period in command messages --- features/term-recount.feature | 6 +++--- php/commands/term.php | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/features/term-recount.feature b/features/term-recount.feature index 03dad922b6..59b4ad63eb 100644 --- a/features/term-recount.feature +++ b/features/term-recount.feature @@ -15,15 +15,15 @@ Feature: Recount terms on a taxonomy When I try `wp term recount category` Then STDOUT should be: """ - Success: Updated category term count + Success: Updated category term count. """ Scenario: Term recount with a multiple taxonomies When I try `wp term recount category post_tag` Then STDOUT should be: """ - Success: Updated category term count - Success: Updated post_tag term count + Success: Updated category term count. + Success: Updated post_tag term count. """ Scenario: Fixes an invalid term count for a taxonomy diff --git a/php/commands/term.php b/php/commands/term.php index 7eca69d9ae..8b784ca423 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -519,16 +519,16 @@ public function url( $args ) { * * # Recount posts assigned to each categories and tags * $ wp term recount category post_tag - * Success: Updated category term count - * Success: Updated post_tag term count + * Success: Updated category term count. + * Success: Updated post_tag term count. * * # Recount all listed taxonomies * $ wp taxonomy list --field=name | xargs wp term recount - * Success: Updated category term count - * Success: Updated post_tag term count - * Success: Updated nav_menu term count - * Success: Updated link_category term count - * Success: Updated post_format term count + * Success: Updated category term count. + * Success: Updated post_tag term count. + * Success: Updated nav_menu term count. + * Success: Updated link_category term count. + * Success: Updated post_format term count. */ public function recount( $args ) { foreach( $args as $taxonomy ) { @@ -542,7 +542,7 @@ public function recount( $args ) { wp_update_term_count( $term_taxonomy_ids, $taxonomy ); - WP_CLI::success( sprintf( "Updated %s term count", $taxonomy ) ); + WP_CLI::success( sprintf( "Updated %s term count.", $taxonomy ) ); } } From b9b5856667165d8eeba71074691c7b51eb258aaf Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 14 Jun 2016 06:43:15 +0545 Subject: [PATCH 4573/4858] Search-replace: add missing trailing period in command messages --- php/commands/search-replace.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index 89bd09daa9..a67790ded2 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -305,7 +305,7 @@ private function php_export_table( $table, $old, $new ) { if ( $this->verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d columns and %d total rows affected using PHP (in %ss)', $total_cols, $total_rows, $time ) ); + WP_CLI::log( sprintf( '%d columns and %d total rows affected using PHP (in %ss).', $total_cols, $total_rows, $time ) ); } return array( $table_report, $total_rows ); @@ -322,7 +322,7 @@ private function sql_handle_col( $col, $table, $old, $new ) { if ( $this->verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d rows affected using SQL (in %ss)', $count, $time ) ); + WP_CLI::log( sprintf( '%d rows affected using SQL (in %ss).', $count, $time ) ); } return $count; } @@ -371,7 +371,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { if ( $this->verbose ) { $time = round( microtime( true ) - $this->start_time, 3 ); - WP_CLI::log( sprintf( '%d rows affected using PHP (in %ss)', $count, $time ) ); + WP_CLI::log( sprintf( '%d rows affected using PHP (in %ss).', $count, $time ) ); } return $count; From 61c36b9dc334d2feb968ee630acb9cd96a79bb87 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 14 Jun 2016 08:12:49 -0700 Subject: [PATCH 4574/4858] Ignore the current alias when handling `--ssh` The current alias isn't meant to be passed through to the remote server. --- php/WP_CLI/Runner.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index de6f29c024..d217a1940b 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -345,6 +345,11 @@ private function run_ssh_command( $ssh ) { $wp_binary = 'wp'; $wp_args = array_slice( $GLOBALS['argv'], 1 ); $wp_path = $path ? sprintf( '--path=%s', str_replace( '~', '$HOME', $path ) ) : ''; + + if ( $this->alias && ! empty( $wp_args[0] ) && $this->alias === $wp_args[0] ) { + array_shift( $wp_args ); + } + foreach( $wp_args as $k => $v ) { if ( preg_match( '#--ssh=#', $v ) ) { unset( $wp_args[ $k ] ); From a2474cd0202ab46bb70eed988fbfb4ca8231d206 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 14 Jun 2016 08:28:41 -0700 Subject: [PATCH 4575/4858] Support for defining port with `--ssh` Example: ``` 192.168.50.10:2222:/srv/www/wordpress-develop.dev/src ``` --- php/WP_CLI/Runner.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index de6f29c024..6f98d47e05 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -324,11 +324,17 @@ private function _run_command() { */ private function run_ssh_command( $ssh ) { - $host = $ssh; - $path = ''; - if ( false !== ( $key = stripos( $host, ':' ) ) ) { - $path = substr( $host, $key + 1 ); - $host = substr( $host, 0, $key ); + $bits = explode( ':', $ssh ); + $host = $bits[0]; + $path = null; + $port = 22; + // host:path + if ( 2 === count( $bits ) ) { + $path = $bits[1]; + // host:port:path + } else if ( 3 === count( $bits ) ) { + $port = $bits[1]; + $path = $bits[2]; } WP_CLI::do_hook( 'before_ssh' ); @@ -352,7 +358,8 @@ private function run_ssh_command( $ssh ) { } $unescaped_command = sprintf( - 'ssh -q %s %s %s', + 'ssh -q -p %d %s %s %s', + $port, $host, $is_tty ? '-t' : '-T', $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) @@ -361,7 +368,8 @@ private function run_ssh_command( $ssh ) { WP_CLI::debug( 'Running SSH command: ' . $unescaped_command, 'bootstrap' ); $escaped_command = sprintf( - 'ssh -q %s %s %s', + 'ssh -q -p %d %s %s %s', + $port, escapeshellarg( $host ), $is_tty ? '-t' : '-T', escapeshellarg( $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ) From 7d4bb965896c945587315be7d335fafad05456ee Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 14 Jun 2016 09:19:31 -0700 Subject: [PATCH 4576/4858] Only supply port when its provided This permits `ssh` to fall back to a value set in `~/.ssh/config` --- php/WP_CLI/Runner.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 6f98d47e05..4e88addc6e 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -327,7 +327,7 @@ private function run_ssh_command( $ssh ) { $bits = explode( ':', $ssh ); $host = $bits[0]; $path = null; - $port = 22; + $port = null; // host:path if ( 2 === count( $bits ) ) { $path = $bits[1]; @@ -358,8 +358,8 @@ private function run_ssh_command( $ssh ) { } $unescaped_command = sprintf( - 'ssh -q -p %d %s %s %s', - $port, + 'ssh -q %s%s %s %s', + $port ? '-p ' . (int) $port . ' ' : '', $host, $is_tty ? '-t' : '-T', $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) @@ -368,8 +368,8 @@ private function run_ssh_command( $ssh ) { WP_CLI::debug( 'Running SSH command: ' . $unescaped_command, 'bootstrap' ); $escaped_command = sprintf( - 'ssh -q -p %d %s %s %s', - $port, + 'ssh -q %s%s %s %s', + $port ? '-p ' . (int) $port . ' ' : '', escapeshellarg( $host ), $is_tty ? '-t' : '-T', escapeshellarg( $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ) From 9c1aaa53374aedf3630475c5bd33fc6a11ce86ef Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 14 Jun 2016 09:51:12 -0700 Subject: [PATCH 4577/4858] Provide more verbosity when `--ssh` fails ``` $ wp --ssh=foo option get home Error: Cannot connect over SSH using provided configuration. ``` Unfortunately, it doesn't seem possible to capture the SSH error itself. `-o LogLevel=ERROR` still includes the "Connection closed" message. --- php/WP_CLI/Runner.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index de6f29c024..485c3eaf9a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -368,7 +368,9 @@ private function run_ssh_command( $ssh ) { ); passthru( $escaped_command, $exit_code ); - if ( 0 !== $exit_code ) { + if ( 255 === $exit_code ) { + WP_CLI::error( 'Cannot connect over SSH using provided configuration.', 255 ); + } else { exit( $exit_code ); } } From 072f4948d535d276f7e0d9700ae9092435ee9b32 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 11:08:48 -0700 Subject: [PATCH 4578/4858] Use `WP_CLI::warning()` when a theme is already active This makes `wp theme activate` behave more consistently with `wp plugin activate` --- features/theme.feature | 6 +++--- php/commands/theme.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/theme.feature b/features/theme.feature index 5e6bf2a69b..8c741b2d27 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -108,10 +108,10 @@ Feature: Manage WordPress themes Success: Switched to 'P2' theme. """ - When I run `wp theme activate p2` - Then STDOUT should be: + When I try `wp theme activate p2` + Then STDERR should be: """ - Success: The 'P2' theme is already active. + Warning: The 'P2' theme is already active. """ Scenario: Install a theme when the theme directory doesn't yet exist diff --git a/php/commands/theme.php b/php/commands/theme.php index 54181962cf..36a144e07c 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -196,7 +196,7 @@ public function activate( $args = array() ) { $name = $theme->get('Name'); if ( 'active' === $this->get_status( $theme ) ) { - WP_CLI::success( "The '$name' theme is already active." ); + WP_CLI::warning( "The '$name' theme is already active." ); return; } From e8d10b276f100925ebe2f75199639f100889265a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 11:31:31 -0700 Subject: [PATCH 4579/4858] Use a more URL-like format for `--ssh` --- php/WP_CLI/Runner.php | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 0e08ba1967..1a8c4287f4 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -324,22 +324,16 @@ private function _run_command() { */ private function run_ssh_command( $ssh ) { - $bits = explode( ':', $ssh ); - $host = $bits[0]; - $path = null; - $port = null; - // host:path - if ( 2 === count( $bits ) ) { - $path = $bits[1]; - // host:port:path - } else if ( 3 === count( $bits ) ) { - $port = $bits[1]; - $path = $bits[2]; - } - WP_CLI::do_hook( 'before_ssh' ); + // host:port/path/to/wordpress + preg_match( '#([^:/~]+)(:([\d]+))?((/|~)(.+))#', $ssh, $matches ); + $host = $matches[1] ? : null; + $port = $matches[3] ? : null; + $path = $matches[4] ? : null; + WP_CLI::debug( 'SSH host: ' . $host, 'bootstrap' ); + WP_CLI::debug( 'SSH port: ' . $port, 'bootstrap' ); WP_CLI::debug( 'SSH path: ' . $path, 'bootstrap' ); $is_tty = function_exists( 'posix_isatty' ) && posix_isatty( STDOUT ); From 24885857c3a1f1b251757c792af1fd5fe688d53b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 11:52:56 -0700 Subject: [PATCH 4580/4858] Add a dependency badge See https://github.com/wp-cli/wp-cli/issues/2996#issuecomment-226268372 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ddda1de27a..914f640ade 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ WP-CLI [WP-CLI](http://wp-cli.org/) is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs and much more, without using a web browser. -[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) +[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) + Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) | [Credits](#credits) From 1f42dcf312a45f3dd492ac88bcf6a4f16f4d26d3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 12:04:55 -0700 Subject: [PATCH 4581/4858] Failing test case for maintenance mode --- features/framework.feature | 14 ++++++++++++++ php/wp-settings-cli.php | 3 +++ 2 files changed, 17 insertions(+) diff --git a/features/framework.feature b/features/framework.feature index d39e90c5f4..93f12ad929 100644 --- a/features/framework.feature +++ b/features/framework.feature @@ -164,3 +164,17 @@ Feature: Load WP-CLI """ Warning: Some code is trying to do a URL redirect. """ + + Scenario: It should be possible to work on a site in maintenance mode + Given a WP install + And a .maintenance file: + """ + <?php + $upgrading = time(); + """ + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 76d9f75673..4cb3371ccc 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -53,6 +53,9 @@ // Standardize $_SERVER variables across setups. wp_fix_server_vars(); +// Check if we're in maintenance mode. +wp_maintenance(); + // Start loading timer. timer_start(); From d210a1faa14990e954411086c93dc5576a90ef4c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 12:10:33 -0700 Subject: [PATCH 4582/4858] Run bypass_maintenance_mode filter early for compat with < WP 4.6 --- php/WP_CLI/Runner.php | 5 +++++ php/wp-settings-cli.php | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 0e08ba1967..d24da27f5f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -991,6 +991,11 @@ private function setup_bootstrap_hooks() { // Always permit operations against sites, regardless of status $this->add_wp_hook( 'ms_site_check', '__return_true' ); + // Always permit operations against WordPress, regardless of maintenance mode + $this->add_wp_hook( 'bypass_maintenance_mode', function() { + return true; + }); + // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 4cb3371ccc..48f325f1e3 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -54,7 +54,10 @@ wp_fix_server_vars(); // Check if we're in maintenance mode. -wp_maintenance(); +// WP-CLI: run bypass_maintenance_mode filter early for compat with < WP 4.6 +if ( ! apply_filters( 'bypass_maintenance_mode', false ) ) { + wp_maintenance(); +} // Start loading timer. timer_start(); From 13208df7ede1c25a6335fb9ed6697a99426a0bac Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 14:41:30 -0700 Subject: [PATCH 4583/4858] Restore `advanced-cache.php` to `wp-settings-cli.php` Even though this will never be called, this ensures `wp-settings-cli.php` is in closer parity to `wp-settings.php` --- php/WP_CLI/Runner.php | 5 +++++ php/wp-settings-cli.php | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e8c03510f0..4fc5a89e1b 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -990,6 +990,11 @@ private function setup_bootstrap_hooks() { return true; }); + // Never load advanced-cache.php drop-in when WP-CLI is operating + $this->add_wp_hook( 'bypass_advanced_cache', function() { + return true; + }); + // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 48f325f1e3..c7f8f7928a 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -65,6 +65,21 @@ // Check if we're in WP_DEBUG mode. Utils\wp_debug_mode(); +/** + * Bypass the loading of advanced-cache.php + * + * This filter should *NOT* be used by plugins. It is designed for non-web + * runtimes. If true is returned, advance-cache.php will never be loaded. + * + * @since 4.6.0 + * + * @param bool True to bypass advanced-cache.php + */ +if ( WP_CACHE && ! apply_filters( 'bypass_advanced_cache', false ) ) { + // For an advanced caching plugin to use. Uses a static drop-in because you would only want one. + WP_DEBUG ? include( WP_CONTENT_DIR . '/advanced-cache.php' ) : @include( WP_CONTENT_DIR . '/advanced-cache.php' ); +} + // Define WP_LANG_DIR if not set. wp_set_lang_dir(); From c8ee4c055fe3170dd1813f940d16206686c916af Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 15:23:23 -0700 Subject: [PATCH 4584/4858] Move the APC cache check to `muplugins_loaded` Doing so mitigates our need to include it in a forked wp-settings-cli.php. There is minimal risk in performing the AYS check later in the bootstrap process. --- php/WP_CLI/Runner.php | 8 ++++++++ php/wp-settings-cli.php | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e8c03510f0..68690a90d2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -997,6 +997,14 @@ private function setup_bootstrap_hooks() { }, 10, 3 ); } + // The APC cache is not available on the command-line, so bail, to prevent cache poisoning + $this->add_wp_hook( 'muplugins_loaded', function() { + if ( $GLOBALS['_wp_using_ext_object_cache'] && class_exists( 'APC_Object_Cache' ) ) { + WP_CLI::warning( 'Running WP-CLI while the APC object cache is activated can result in cache corruption.' ); + WP_CLI::confirm( 'Given the consequences, do you wish to continue?' ); + } + }, 0 ); + // Handle --user parameter if ( ! defined( 'WP_INSTALLING' ) ) { $config = $this->config; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 48f325f1e3..8a787b35d8 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -92,12 +92,6 @@ // Start the WordPress object cache, or an external object cache if the drop-in is present. wp_start_object_cache(); -// WP-CLI: the APC cache is not available on the command-line, so bail, to prevent cache poisoning -if ( $GLOBALS['_wp_using_ext_object_cache'] && class_exists( 'APC_Object_Cache' ) ) { - WP_CLI::warning( 'Running WP-CLI while the APC object cache is activated can result in cache corruption.' ); - WP_CLI::confirm( 'Given the consequences, do you wish to continue?' ); -} - // Attach the default filters. require( ABSPATH . WPINC . '/default-filters.php' ); From dcea31fed83b53efbd65fa9e8c4ba9fe1327bb34 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 15:46:36 -0700 Subject: [PATCH 4585/4858] Abuse the `nocache_headers` filter to run our `Utils\wp_not_installed()` If `wp_not_installed()` identifies that WordPress isn't installed, it will call `nocache_headers()` before trying to redirect. Hijacking this particular filter lets WP-CLI exit with its own message before the redirect is called, and avoid having to maintain a forked `wp-settings-cli.php` --- features/core-config.feature | 9 +++++++++ php/WP_CLI/Runner.php | 5 +++++ php/wp-settings-cli.php | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/features/core-config.feature b/features/core-config.feature index d940433e53..7b445bf936 100644 --- a/features/core-config.feature +++ b/features/core-config.feature @@ -41,6 +41,15 @@ Feature: Manage wp-config Then the return code should be 1 And STDERR should not be empty + When I run `wp db create` + Then STDOUT should not be empty + + When I try `wp option get option home` + Then STDERR should contain: + """ + Error: The site you have requested is not installed + """ + Scenario: Configure with existing salts Given an empty directory And WP files diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index e8c03510f0..5a522e4b7a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -965,6 +965,11 @@ private function setup_bootstrap_hooks() { // Prevent code from performing a redirect $this->add_wp_hook( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); + $this->add_wp_hook( 'nocache_headers', function( $headers ){ + Utils\wp_not_installed(); + return $headers; + }); + // Get rid of warnings when converting single site to multisite if ( defined( 'WP_INSTALLING' ) && $this->is_multisite() ) { $values = array( diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 48f325f1e3..184341d61b 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -120,7 +120,7 @@ require_once( ABSPATH . WPINC . '/l10n.php' ); // Run the installer if WordPress is not installed. -Utils\wp_not_installed(); +wp_not_installed(); // Load most of WordPress. require( ABSPATH . WPINC . '/class-wp-walker.php' ); From fe26b2f0a6955101c14f26f0cd8a360b4e1a8314 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 15 Jun 2016 16:34:01 -0700 Subject: [PATCH 4586/4858] Restore `wp_debug_mode()` call in `wp-settings-cli.php` We can use the new `bypass_debug_mode` filter to hook in our existing `WP_CLI\Utils\wp_debug_mode()` call, and make sure it just runs once --- php/WP_CLI/Runner.php | 13 +++++++++++++ php/wp-settings-cli.php | 17 +++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4fc5a89e1b..b36db1e5b8 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -990,6 +990,19 @@ private function setup_bootstrap_hooks() { return true; }); + // Use our own debug mode handling instead of WP core + $this->add_wp_hook( 'bypass_debug_mode', function( $ret ) { + static $did_once; + + // Sometimes called a second time in >= WP 4.6, prevent loop + if ( ! empty( $did_once ) ) { + return $ret; + } + Utils\wp_debug_mode(); + $did_once = true; + return true; + }); + // Never load advanced-cache.php drop-in when WP-CLI is operating $this->add_wp_hook( 'bypass_advanced_cache', function() { return true; diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index c7f8f7928a..4466d9b81c 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -62,8 +62,21 @@ // Start loading timer. timer_start(); -// Check if we're in WP_DEBUG mode. -Utils\wp_debug_mode(); +/** + * Bypass the debug mode check + * + * This filter should *NOT* be used by plugins. It is designed for non-web + * runtimes. Returning true causes the WP_DEBUG and related constants to + * not be checked and the default php values for errors will be used unless + * you take care to update them yourself. + * + * @since 4.6.0 + * + * @param bool True to bypass debug mode + */ +if ( ! apply_filters( 'bypass_debug_mode', false ) ){ + wp_debug_mode(); +} /** * Bypass the loading of advanced-cache.php From 4fcc52e9628d96c75e5342592c3622ae8d38a9f0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 16 Jun 2016 03:58:24 -0700 Subject: [PATCH 4587/4858] Perform dead db check earlier, by loading wpdb ourselves In doing so, we're causing wpdb to be loaded slightly earlier in the bootstrap process. --- php/WP_CLI/Runner.php | 8 ++++++++ php/utils-wp.php | 2 +- php/wp-settings-cli.php | 5 ----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 1a4d199ab6..5682290d9f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -1000,6 +1000,14 @@ private function setup_bootstrap_hooks() { } Utils\wp_debug_mode(); $did_once = true; + + // Check to see of wpdb is errored, instead of waiting for dead_db() + require_wp_db(); + global $wpdb; + if ( ! empty( $wpdb->error ) ) { + Utils\wp_die_handler( $wpdb->error ); + } + return true; }); diff --git a/php/utils-wp.php b/php/utils-wp.php index be7a4e1a79..e2c3a9738c 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -32,7 +32,7 @@ function replace_wp_die_handler() { } function wp_die_handler( $message ) { - if ( is_wp_error( $message ) ) { + if ( $message instanceof \WP_Error ) { $message = $message->get_error_message(); } diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 700e756e09..d3308ece58 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -106,11 +106,6 @@ // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); -// WP-CLI: Handle db error ourselves, instead of waiting for dead_db() -global $wpdb; -if ( !empty( $wpdb->error ) ) - wp_die( $wpdb->error ); - // Set the database table prefix and the format specifiers for database table columns. // @codingStandardsIgnoreStart $GLOBALS['table_prefix'] = $table_prefix; From fc1a5cbfa98c13631ff4058c2f2a7ebdebbd2b46 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 16 Jun 2016 04:07:29 -0700 Subject: [PATCH 4588/4858] Ensure the nocache_headers filter runs pre WP 4.0 The call to `nocache_headers()` in `wp_not_installed()` was introduced in WP 4.0 --- php/wp-settings-cli.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 184341d61b..9f261f4c45 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -119,6 +119,9 @@ // Load the L10n library. require_once( ABSPATH . WPINC . '/l10n.php' ); +// WP-CLI: Permit Utils\wp_not_installed() to run on < WP 4.0 +apply_filters( 'nocache_headers', array() ); + // Run the installer if WordPress is not installed. wp_not_installed(); From 001199054f258e9189d4d96f6b873f3abb6929bf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 16 Jun 2016 08:08:12 -0700 Subject: [PATCH 4589/4858] Support only a host being provided to `--ssh=<ssh>` e.g. `wp --ssh=v` or `wp --ssh=prod` --- php/WP_CLI/Runner.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 83b28632cd..a374a06a12 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -326,11 +326,11 @@ private function run_ssh_command( $ssh ) { WP_CLI::do_hook( 'before_ssh' ); - // host:port/path/to/wordpress - preg_match( '#([^:/~]+)(:([\d]+))?((/|~)(.+))#', $ssh, $matches ); - $host = $matches[1] ? : null; - $port = $matches[3] ? : null; - $path = $matches[4] ? : null; + // host OR host/path/to/wordpress OR host:port/path/to/wordpress + preg_match( '#^([^:/~]+)(:([\d]+))?((/|~)(.+))?$#', $ssh, $matches ); + $host = isset( $matches[1] ) ? $matches[1] : null; + $port = isset( $matches[3] ) ? $matches[3] : null; + $path = isset( $matches[4] ) ? $matches[4] : null; WP_CLI::debug( 'SSH host: ' . $host, 'bootstrap' ); WP_CLI::debug( 'SSH port: ' . $port, 'bootstrap' ); From 5d44381c7ed73d44b744981982b3ccb4a0da18d6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 16 Jun 2016 15:59:06 -0700 Subject: [PATCH 4590/4858] Restore `defined( 'WP_INSTALLING' )` check in legacy wp-settings-cli.php This will prevent error notices when using WP-CLI against <WP 4.6 --- php/wp-settings-cli.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 6fc2a5e6cc..f5c35b0258 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -400,7 +400,8 @@ do_action( 'init' ); // Check site status -if ( is_multisite() ) { +# if ( is_multisite() ) { // WP-CLI +if ( is_multisite() && !defined('WP_INSTALLING') ) { if ( true !== ( $file = ms_site_check() ) ) { require( $file ); die(); From b376153b421852ce2410f44a4868a3b1b5e2a697 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 16 Jun 2016 16:03:15 -0700 Subject: [PATCH 4591/4858] Restore our custom dead db check; `nonce_headers` isn't called until WP4.0 We'll need this check in place for compatibility purposes --- php/wp-settings-cli.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index d3308ece58..700e756e09 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -106,6 +106,11 @@ // Include the wpdb class and, if present, a db.php database drop-in. require_wp_db(); +// WP-CLI: Handle db error ourselves, instead of waiting for dead_db() +global $wpdb; +if ( !empty( $wpdb->error ) ) + wp_die( $wpdb->error ); + // Set the database table prefix and the format specifiers for database table columns. // @codingStandardsIgnoreStart $GLOBALS['table_prefix'] = $table_prefix; From 196e69ebb51b6ede4bc7b8ff6635387a3d3b7e75 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 17 Jun 2016 05:01:50 -0700 Subject: [PATCH 4592/4858] Use `wp-settings.php` instead of `wp-settings-cli.php` for >=WP4.6 Maintaining a fork isn't a ton of fun. --- php/WP_CLI/Runner.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index bbcf0ab240..ec80b25944 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -575,6 +575,7 @@ private function check_wp_version() { "Pass --path=`path/to/wordpress` or run `wp core download`." ); } + global $wp_version; include ABSPATH . 'wp-includes/version.php'; $minimum_version = '3.7'; @@ -885,7 +886,11 @@ public function load_wordpress() { $this->setup_bootstrap_hooks(); // Load Core, mu-plugins, plugins, themes etc. - require WP_CLI_ROOT . '/php/wp-settings-cli.php'; + if ( Utils\wp_version_compare( '4.6-alpha-37575', '>=' ) ) { + require ABSPATH . 'wp-settings.php'; + } else { + require WP_CLI_ROOT . '/php/wp-settings-cli.php'; + } // Fix memory limit. See http://core.trac.wordpress.org/ticket/14889 @ini_set( 'memory_limit', -1 ); From d163d7af3914cdeb3f557614dfa3b0db9b7c826e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 17 Jun 2016 21:19:19 +0545 Subject: [PATCH 4593/4858] Add test for porcelain in db export --- features/db.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/db.feature b/features/db.feature index 046fd29d1a..f355252ba3 100644 --- a/features/db.feature +++ b/features/db.feature @@ -61,6 +61,18 @@ Feature: Perform database operations Success: Exported """ + When I run `wp db export /tmp/wp-cli-behat.sql --porcelain` + Then STDOUT should contain: + """ + /tmp/wp-cli-behat.sql + """ + + When I try `wp db export - --porcelain` + Then STDERR should contain: + """ + Porcelain is not allowed when output mode is STDOUT. + """ + When I run `wp db reset --yes` Then STDOUT should contain: """ From f0373fad06fb1d5acd4aa4c7b230b4b024b95fae Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 17 Jun 2016 21:19:37 +0545 Subject: [PATCH 4594/4858] Add porcelain parameter in db export --- php/commands/db.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/php/commands/db.php b/php/commands/db.php index 265b747111..5acab0bc32 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -222,6 +222,9 @@ public function query( $args ) { * [--tables=<tables>] * : The comma separated list of specific tables to export. Excluding this parameter will export all tables in the database. * + * [--porcelain] + * : Output filename for the exported database. + * * ## EXAMPLES * * # Export database with drop query included @@ -245,6 +248,12 @@ public function query( $args ) { function export( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); $stdout = ( '-' === $result_file ); + $porcelain = \WP_CLI\Utils\get_flag_value( $assoc_args, 'porcelain' ); + + // Bail if both porcelain and STDOUT are set. + if ( $stdout && $porcelain ) { + WP_CLI::error( 'Porcelain is not allowed when output mode is STDOUT.' ); + } if ( ! $stdout ) { $assoc_args['result-file'] = $result_file; @@ -265,9 +274,17 @@ function export( $args, $assoc_args ) { $escaped_command = call_user_func_array( '\WP_CLI\Utils\esc_cmd', array_merge( array( $command ), $command_esc_args ) ); + // Remove parameters not needed for SQL run. + if ( isset( $assoc_args['porcelain'] ) ) { + unset( $assoc_args['porcelain'] ); + } + self::run( $escaped_command, $assoc_args ); - if ( ! $stdout ) { + if ( $porcelain ) { + WP_CLI::line( $result_file ); + } + else if ( ! $stdout ) { WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); } } From a2f0b9f6b3897352d7206d899b69957305bb7bdb Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Fri, 17 Jun 2016 22:06:31 +0545 Subject: [PATCH 4595/4858] Introduce field param in option list --- php/commands/option.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/option.php b/php/commands/option.php index a680fefd63..8f3c6d757b 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -128,6 +128,9 @@ public function add( $args, $assoc_args ) { * [--autoload=<value>] * : Match only autoload options when value is on, and only not-autoload option when off. * + * [--field=<field>] + * : Prints the value of a single field. + * * [--fields=<fields>] * : Limit the output to specific object fields. * From 23f7c7c37f666ddccc268cee50f65670d7b29d29 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 17 Jun 2016 09:59:52 -0700 Subject: [PATCH 4596/4858] Rename filters to match what's in core Oops --- php/WP_CLI/Runner.php | 19 ++++++------------- php/utils-wp.php | 20 +++++++++++++++++++- php/wp-settings-cli.php | 6 +++--- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index ec80b25944..8000d3d400 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -996,20 +996,13 @@ private function setup_bootstrap_hooks() { $this->add_wp_hook( 'ms_site_check', '__return_true' ); // Always permit operations against WordPress, regardless of maintenance mode - $this->add_wp_hook( 'bypass_maintenance_mode', function() { - return true; + $this->add_wp_hook( 'enable_maintenance_mode', function() { + return false; }); // Use our own debug mode handling instead of WP core - $this->add_wp_hook( 'bypass_debug_mode', function( $ret ) { - static $did_once; - - // Sometimes called a second time in >= WP 4.6, prevent loop - if ( ! empty( $did_once ) ) { - return $ret; - } + $this->add_wp_hook( 'enable_wp_debug_mode_checks', function( $ret ) { Utils\wp_debug_mode(); - $did_once = true; // Check to see of wpdb is errored, instead of waiting for dead_db() require_wp_db(); @@ -1018,12 +1011,12 @@ private function setup_bootstrap_hooks() { Utils\wp_die_handler( $wpdb->error ); } - return true; + return false; }); // Never load advanced-cache.php drop-in when WP-CLI is operating - $this->add_wp_hook( 'bypass_advanced_cache', function() { - return true; + $this->add_wp_hook( 'enable_loading_advanced_cache_dropin', function() { + return false; }); // In a multisite install, die if unable to find site given in --url parameter diff --git a/php/utils-wp.php b/php/utils-wp.php index e2c3a9738c..dd08dfb849 100644 --- a/php/utils-wp.php +++ b/php/utils-wp.php @@ -19,7 +19,25 @@ function wp_debug_mode() { error_reporting( E_ALL & ~E_DEPRECATED & ~E_STRICT ); } else { - \wp_debug_mode(); + 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 diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index f5c35b0258..856e01b67d 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -55,7 +55,7 @@ // Check if we're in maintenance mode. // WP-CLI: run bypass_maintenance_mode filter early for compat with < WP 4.6 -if ( ! apply_filters( 'bypass_maintenance_mode', false ) ) { +if ( apply_filters( 'enable_maintenance_mode', true ) ) { wp_maintenance(); } @@ -74,7 +74,7 @@ * * @param bool True to bypass debug mode */ -if ( ! apply_filters( 'bypass_debug_mode', false ) ){ +if ( apply_filters( 'enable_wp_debug_mode_checks', true ) ){ wp_debug_mode(); } @@ -88,7 +88,7 @@ * * @param bool True to bypass advanced-cache.php */ -if ( WP_CACHE && ! apply_filters( 'bypass_advanced_cache', false ) ) { +if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) ) { // For an advanced caching plugin to use. Uses a static drop-in because you would only want one. WP_DEBUG ? include( WP_CONTENT_DIR . '/advanced-cache.php' ) : @include( WP_CONTENT_DIR . '/advanced-cache.php' ); } From fe8d1407dda661ed821ead57cbbd47fba56e5915 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 17 Jun 2016 10:02:53 -0700 Subject: [PATCH 4597/4858] Update PHPDoc correspondingly --- php/wp-settings-cli.php | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 856e01b67d..1554221a8d 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -54,7 +54,20 @@ wp_fix_server_vars(); // Check if we're in maintenance mode. -// WP-CLI: run bypass_maintenance_mode filter early for compat with < WP 4.6 +// WP-CLI: run enable_maintenance_mode filter early for compat with < WP 4.6 +/** + * Filters whether to enable maintenance mode. + * + * This filter runs before it can be used by plugins. It is designed for + * non-web runtimes. If this filter returns true, maintenance mode will be + * active and the request will end. If false, the request will be allowed to + * continue processing even if maintenance mode should be active. + * + * @since 4.6.0 + * + * @param bool $enable_checks Whether to enable maintenance mode. Default true. + * @param int $upgrading The timestamp set in the .maintenance file. + */ if ( apply_filters( 'enable_maintenance_mode', true ) ) { wp_maintenance(); } @@ -62,31 +75,33 @@ // Start loading timer. timer_start(); +// WP-CLI: run enable_wp_debug_mode_checks filter early for compat with < WP 4.6 /** - * Bypass the debug mode check + * Filters whether to allow the debug mode check to occur. * - * This filter should *NOT* be used by plugins. It is designed for non-web - * runtimes. Returning true causes the WP_DEBUG and related constants to - * not be checked and the default php values for errors will be used unless - * you take care to update them yourself. + * This filter runs before it can be used by plugins. It is designed for + * non-web run-times. Returning false causes the `WP_DEBUG` and related + * constants to not be checked and the default php values for errors + * will be used unless you take care to update them yourself. * * @since 4.6.0 * - * @param bool True to bypass debug mode + * @param bool $enable_debug_mode Whether to enable debug mode checks to occur. Default true. */ if ( apply_filters( 'enable_wp_debug_mode_checks', true ) ){ wp_debug_mode(); } /** - * Bypass the loading of advanced-cache.php + * Filters whether to enable loading of the advanced-cache.php drop-in. * - * This filter should *NOT* be used by plugins. It is designed for non-web - * runtimes. If true is returned, advance-cache.php will never be loaded. + * This filter runs before it can be used by plugins. It is designed for non-web + * run-times. If false is returned, advance-cache.php will never be loaded. * * @since 4.6.0 * - * @param bool True to bypass advanced-cache.php + * @param bool $enable_advanced_cache Whether to enable loading advanced-cache.php (if present). + * Default true. */ if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) ) { // For an advanced caching plugin to use. Uses a static drop-in because you would only want one. From dc38f0834d6cd47f3c424e5ae2d357da81567f54 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 17 Jun 2016 10:20:22 -0700 Subject: [PATCH 4598/4858] Explicitly globalize `$wpdb` before wp-settings.php is called Because `wp-settings.php` doesn't globalize `$wpdb` itself, calling `wp-settings.php` inside of a class method means that `wp-includes/ms-settings.php` (which uses `$wpdb` but doesn't globalize it) will break unexpectedly. This problem was obscured originally because WP-CLI globalizes $wpdb, see b376153b421852ce2410f44a4868a3b1b5e2a697 --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 8000d3d400..c871ed4eb9 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -843,7 +843,7 @@ public function start() { public function load_wordpress() { static $wp_cli_is_loaded; // Globals not explicitly globalized in WordPress - global $site_id, $public, $current_site, $current_blog, $path, $shortcode_tags; + global $site_id, $wpdb, $public, $current_site, $current_blog, $path, $shortcode_tags; if ( ! empty( $wp_cli_is_loaded ) ) { return; From 684a4d877245fd43a86808a35de67f9358750ee4 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 18 Jun 2016 06:03:17 +0545 Subject: [PATCH 4599/4858] Improve test for porcelain in db export command --- features/db.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/db.feature b/features/db.feature index f355252ba3..338cdc9358 100644 --- a/features/db.feature +++ b/features/db.feature @@ -61,16 +61,16 @@ Feature: Perform database operations Success: Exported """ - When I run `wp db export /tmp/wp-cli-behat.sql --porcelain` - Then STDOUT should contain: + When I run `wp db export wp-cli-behat.sql --porcelain` + Then STDOUT should be: """ - /tmp/wp-cli-behat.sql + wp-cli-behat.sql """ When I try `wp db export - --porcelain` - Then STDERR should contain: + Then STDERR should be: """ - Porcelain is not allowed when output mode is STDOUT. + Error: Porcelain is not allowed when output mode is STDOUT. """ When I run `wp db reset --yes` From 9cbbb8d6a3e61264dcfae6d5d7f46c6139b9827c Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 18 Jun 2016 06:26:48 +0545 Subject: [PATCH 4600/4858] Add example to use output of option list in option delete --- php/commands/option.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/option.php b/php/commands/option.php index 8f3c6d757b..2da0138e39 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -182,6 +182,12 @@ public function add( $args, $assoc_args ) { * | i2f_version | 0.1.0 | * +-------------+--------------+ * + * # Delete all options begining with "theme_mods_" + * $ wp option list --search="theme_mods_*" --field=option_name | xargs -0 -d '\n' -I % wp option delete % + * Success: Deleted 'theme_mods_twentysixteen' option. + * Success: Deleted 'theme_mods_twentfifteen' option. + * Success: Deleted 'theme_mods_twentyfourteen' option. + * * @subcommand list */ public function list_( $args, $assoc_args ) { From 5b639f96ce802d4a75ece8f99f5677e891fa261e Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 18 Jun 2016 07:02:12 +0545 Subject: [PATCH 4601/4858] Media: add missing trailing period in command messages --- php/commands/media.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 25220bf08b..a5f8aefd34 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -269,7 +269,7 @@ private function _make_copy( $path ) { $filename = $dir . wp_unique_filename( $dir, $filename ); if ( !copy( $path, $filename ) ) - WP_CLI::error( "Could not create temporary file for $path" ); + WP_CLI::error( "Could not create temporary file for $path." ); return $filename; } @@ -281,7 +281,7 @@ private function _process_regeneration( $id, $skip_delete = false, $only_missing $att_desc = sprintf( '"%1$s" (ID %2$d).', get_the_title( $id ), $id ); if ( false === $fullsizepath || !file_exists( $fullsizepath ) ) { - WP_CLI::warning( "Can't find $att_desc" ); + WP_CLI::warning( "Can't find $att_desc." ); return false; } @@ -304,10 +304,10 @@ private function _process_regeneration( $id, $skip_delete = false, $only_missing wp_update_attachment_metadata( $id, $metadata ); - WP_CLI::log( "Regenerated thumbnails for $att_desc" ); + WP_CLI::log( "Regenerated thumbnails for $att_desc." ); return true; } else { - WP_CLI::log( "No thumbnail regeneration needed for $att_desc" ); + WP_CLI::log( "No thumbnail regeneration needed for $att_desc." ); return true; } } From 0463b33a4b5b42cf76fea1c3a61dd2351a571871 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 18 Jun 2016 17:48:29 +0545 Subject: [PATCH 4602/4858] Export: add missing trailing period in command messages --- features/export.feature | 6 +++--- php/commands/export.php | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/features/export.feature b/features/export.feature index 461ee86b88..f9376c5982 100644 --- a/features/export.feature +++ b/features/export.feature @@ -6,7 +6,7 @@ Feature: Export content. When I run `wp export` Then STDOUT should contain: """ - All done with export + All done with export. """ Scenario: Export argument validator @@ -27,13 +27,13 @@ Feature: Export content. When I try `wp export --start_date=invalid-date` Then STDERR should contain: """ - Warning: The start_date invalid-date is invalid + Warning: The start_date invalid-date is invalid. """ When I try `wp export --end_date=invalid-date` Then STDERR should contain: """ - Warning: The end_date invalid-date is invalid + Warning: The end_date invalid-date is invalid. """ Scenario: Export with post_type and post_status argument diff --git a/php/commands/export.php b/php/commands/export.php index 62720cce78..93a4712711 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -171,7 +171,7 @@ private function check_dir( $path ) { if ( empty( $path ) ) { $path = getcwd(); } elseif ( !is_dir( $path ) ) { - WP_CLI::error( sprintf( "The directory %s does not exist", $path ) ); + WP_CLI::error( sprintf( "The directory %s does not exist.", $path ) ); return false; } @@ -186,7 +186,7 @@ private function check_start_date( $date ) { $time = strtotime( $date ); if ( !empty( $date ) && !$time ) { - WP_CLI::warning( sprintf( "The start_date %s is invalid", $date ) ); + WP_CLI::warning( sprintf( "The start_date %s is invalid.", $date ) ); return false; } $this->export_args['start_date'] = date( 'Y-m-d', $time ); @@ -199,7 +199,7 @@ private function check_end_date( $date ) { $time = strtotime( $date ); if ( !empty( $date ) && !$time ) { - WP_CLI::warning( sprintf( "The end_date %s is invalid", $date ) ); + WP_CLI::warning( sprintf( "The end_date %s is invalid.", $date ) ); return false; } $this->export_args['end_date'] = date( 'Y-m-d', $time ); @@ -257,7 +257,7 @@ private function check_post__in( $post__in ) { $separator = false !== stripos( $post__in, ' ' ) ? ' ' : ','; $post__in = array_unique( array_map( 'intval', explode( $separator, $post__in ) ) ); if ( empty( $post__in ) ) { - WP_CLI::warning( "post__in should be comma-separated post IDs" ); + WP_CLI::warning( "post__in should be comma-separated post IDs." ); return false; } // New exporter uses a different argument @@ -288,7 +288,7 @@ private function check_author( $author ) { $authors = get_users_of_blog(); if ( empty( $authors ) || is_wp_error( $authors ) ) { - WP_CLI::warning( sprintf( "Could not find any authors in this blog" ) ); + WP_CLI::warning( sprintf( "Could not find any authors in this blog." ) ); return false; } $hit = false; @@ -316,7 +316,7 @@ private function check_category( $category ) { $term = category_exists( $category ); if ( empty( $term ) || is_wp_error( $term ) ) { - WP_CLI::warning( sprintf( 'Could not find a category matching %s', $category ) ); + WP_CLI::warning( sprintf( 'Could not find a category matching %s.', $category ) ); return false; } $this->export_args['category'] = $category; @@ -329,7 +329,7 @@ private function check_post_status( $status ) { $stati = get_post_statuses(); if ( empty( $stati ) || is_wp_error( $stati ) ) { - WP_CLI::warning( 'Could not find any post stati' ); + WP_CLI::warning( 'Could not find any post stati.' ); return false; } @@ -346,7 +346,7 @@ private function check_skip_comments( $skip ) { return true; if ( (int) $skip <> 0 && (int) $skip <> 1 ) { - WP_CLI::warning( 'skip_comments needs to be 0 (no) or 1 (yes)' ); + WP_CLI::warning( 'skip_comments needs to be 0 (no) or 1 (yes).' ); return false; } $this->export_args['skip_comments'] = $skip; @@ -355,7 +355,7 @@ private function check_skip_comments( $skip ) { private function check_max_file_size( $size ) { if ( !is_numeric( $size ) ) { - WP_CLI::warning( sprintf( "max_file_size should be numeric", $size ) ); + WP_CLI::warning( sprintf( "max_file_size should be numeric.", $size ) ); return false; } From b878b9ef715f285c35b9f189f29134dbdd6cb79c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 20 Jun 2016 05:44:53 -0700 Subject: [PATCH 4603/4858] Introduce `WP_CLI\Utils\parse_ssh_url()` for parsing SSH URLs Includes unit tests for expected behavior --- php/WP_CLI/Runner.php | 8 +++---- php/utils.php | 37 ++++++++++++++++++++++++++++++ tests/test-utils.php | 53 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c871ed4eb9..4ca445302d 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -327,10 +327,10 @@ private function run_ssh_command( $ssh ) { WP_CLI::do_hook( 'before_ssh' ); // host OR host/path/to/wordpress OR host:port/path/to/wordpress - preg_match( '#^([^:/~]+)(:([\d]+))?((/|~)(.+))?$#', $ssh, $matches ); - $host = isset( $matches[1] ) ? $matches[1] : null; - $port = isset( $matches[3] ) ? $matches[3] : null; - $path = isset( $matches[4] ) ? $matches[4] : null; + $bits = Utils\parse_ssh_url( $ssh ); + $host = isset( $bits['host'] ) ? $bits['host'] : null; + $port = isset( $bits['port'] ) ? $bits['port'] : null; + $path = isset( $bits['path'] ) ? $bits['path'] : null; WP_CLI::debug( 'SSH host: ' . $host, 'bootstrap' ); WP_CLI::debug( 'SSH port: ' . $port, 'bootstrap' ); diff --git a/php/utils.php b/php/utils.php index 23d28b99d6..6268dcbcb8 100644 --- a/php/utils.php +++ b/php/utils.php @@ -718,3 +718,40 @@ function get_temp_dir() { return $trailingslashit( $temp ); } + +/** + * Parse a SSH url for its host, port, and path. + * + * Similar to parse_url(), but adds support for defined SSH aliases. + * + * ``` + * host OR host/path/to/wordpress OR host:port/path/to/wordpress + * ``` + * + * @access public + * + * @return mixed + */ +function parse_ssh_url( $url, $component = -1 ) { + preg_match( '#^([^:/~]+)(:([\d]+))?((/|~)(.+))?$#', $url, $matches ); + $bits = array(); + foreach( array( + 1 => 'host', + 3 => 'port', + 4 => 'path', + ) as $i => $key ) { + if ( ! empty( $matches[ $i ] ) ) { + $bits[ $key ] = $matches[ $i ]; + } + } + switch ( $component ) { + case PHP_URL_HOST: + return isset( $bits['host'] ) ? $bits['host'] : null; + case PHP_URL_PATH: + return isset( $bits['path'] ) ? $bits['path'] : null; + case PHP_URL_PORT: + return isset( $bits['port'] ) ? $bits['port'] : null; + default: + return $bits; + } +} diff --git a/tests/test-utils.php b/tests/test-utils.php index 01bbc5101e..deda16a622 100644 --- a/tests/test-utils.php +++ b/tests/test-utils.php @@ -44,5 +44,58 @@ public function testGetSemVer() { $this->assertEquals( 'major', Utils\get_named_sem_ver( '1.1.1', $original_version ) ); } + public function testParseSSHUrl() { + $testcase = 'foo'; + $this->assertEquals( array( + 'host' => 'foo', + ), Utils\parse_ssh_url( $testcase ) ); + $this->assertEquals( 'foo', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) ); + + $testcase = 'foo.com'; + $this->assertEquals( array( + 'host' => 'foo.com', + ), Utils\parse_ssh_url( $testcase ) ); + $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) ); + + $testcase = 'foo.com:2222'; + $this->assertEquals( array( + 'host' => 'foo.com', + 'port' => 2222, + ), Utils\parse_ssh_url( $testcase ) ); + $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) ); + $this->assertEquals( 2222, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) ); + + $testcase = 'foo.com:2222/path/to/dir'; + $this->assertEquals( array( + 'host' => 'foo.com', + 'port' => 2222, + 'path' => '/path/to/dir', + ), Utils\parse_ssh_url( $testcase ) ); + $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) ); + $this->assertEquals( 2222, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) ); + $this->assertEquals( '/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) ); + + $testcase = 'foo.com~/path/to/dir'; + $this->assertEquals( array( + 'host' => 'foo.com', + 'path' => '~/path/to/dir', + ), Utils\parse_ssh_url( $testcase ) ); + $this->assertEquals( 'foo.com', Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) ); + $this->assertEquals( '~/path/to/dir', Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) ); + + // No host + $testcase = '~/path/to/dir'; + $this->assertEquals( array(), Utils\parse_ssh_url( $testcase ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_HOST ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PORT ) ); + $this->assertEquals( null, Utils\parse_ssh_url( $testcase, PHP_URL_PATH ) ); + } + } From 03a0e4b49d7b17d5e0a774ac60ddc680c88172d3 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 20 Jun 2016 22:15:18 +0545 Subject: [PATCH 4604/4858] Improved messages in db commands --- php/commands/db.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 5acab0bc32..57828e98b0 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -229,19 +229,19 @@ public function query( $args ) { * * # Export database with drop query included * $ wp db export --add-drop-table - * Success: Exported to wordpress_dbase.sql + * Success: Exported to 'wordpress_dbase.sql'. * * # Export certain tables * $ wp db export --tables=wp_options,wp_users - * Success: Exported to wordpress_dbase.sql + * Success: Exported to 'wordpress_dbase.sql'. * * # Export all tables matching a wildcard * $ wp db export --tables=$(wp db tables 'wp_user*' --format=csv) - * Success: Exported to wordpress_dbase.sql + * Success: Exported to 'wordpress_dbase.sql'. * * # Export all tables matching prefix * $ wp db export --tables=$(wp db tables --all-tables-with-prefix --format=csv) - * Success: Exported to wordpress_dbase.sql + * Success: Exported to 'wordpress_dbase.sql'. * * @alias dump */ @@ -285,7 +285,7 @@ function export( $args, $assoc_args ) { WP_CLI::line( $result_file ); } else if ( ! $stdout ) { - WP_CLI::success( sprintf( 'Exported to %s', $result_file ) ); + WP_CLI::success( sprintf( "Exported to '%s'.", $result_file ) ); } } @@ -300,7 +300,7 @@ function export( $args, $assoc_args ) { * ## EXAMPLES * * $ wp db import wordpress_dbase.sql - * Success: Imported from wordpress_dbase.sql + * Success: Imported from 'wordpress_dbase.sql'. */ public function import( $args, $assoc_args ) { $result_file = $this->get_file_name( $args ); @@ -327,7 +327,7 @@ public function import( $args, $assoc_args ) { 'database' => DB_NAME ), $descriptors ); - WP_CLI::success( sprintf( 'Imported from %s', $result_file ) ); + WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) ); } /** From edf4bfa04696e5362ebf618ad1c4afe1cbc9a845 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 20 Jun 2016 10:41:27 -0700 Subject: [PATCH 4605/4858] Ignore `wp-cli.local.yml` in plugin scaffold `.gitignore` This file is only ever meant for local development. --- templates/plugin-distignore.mustache | 1 + templates/plugin-gitignore.mustache | 1 + 2 files changed, 2 insertions(+) diff --git a/templates/plugin-distignore.mustache b/templates/plugin-distignore.mustache index 6a8b3da106..36a11a63f7 100644 --- a/templates/plugin-distignore.mustache +++ b/templates/plugin-distignore.mustache @@ -12,6 +12,7 @@ package.json phpunit.xml phpunit.xml.dist README.md +wp-cli.local.yml tests vendor node_modules diff --git a/templates/plugin-gitignore.mustache b/templates/plugin-gitignore.mustache index 646ac519ef..d4a5405531 100644 --- a/templates/plugin-gitignore.mustache +++ b/templates/plugin-gitignore.mustache @@ -1,2 +1,3 @@ .DS_Store +wp-cli.local.yml node_modules/ From ab13c6291cd2aa5888b5a02e1fd7f073512e7e72 Mon Sep 17 00:00:00 2001 From: voldemortensen <voldemortensen@users.noreply.github.com> Date: Mon, 20 Jun 2016 12:30:48 -0600 Subject: [PATCH 4606/4858] allow the author field to be selected in `wp theme list --fields=<field>` --- php/commands/theme.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/theme.php b/php/commands/theme.php index 36a144e07c..a834768eca 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -411,6 +411,7 @@ protected function get_item_list() { 'update_id' => $theme->get_stylesheet(), 'title' => $theme->get('Name'), 'description' => $theme->get('Description'), + 'author' => $theme->get('Author'), ); if ( is_multisite() ) { From fa11a5b19c1aeb5a1c49a39b9fd4a6027043cfc2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 20 Jun 2016 11:43:15 -0700 Subject: [PATCH 4607/4858] Update tests for edf4bfa04696e5362ebf618ad1c4afe1cbc9a845 --- features/scaffold.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 7ece65d815..48409fb286 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -155,6 +155,7 @@ Feature: WordPress code scaffolding And the {PLUGIN_DIR}/hello-world/.gitignore file should contain: """ .DS_Store + wp-cli.local.yml node_modules/ """ And the {PLUGIN_DIR}/hello-world/.distignore file should contain: From 709c5fcffaa31ca3be2df3d7a721fd16ed336f97 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 21 Jun 2016 11:28:59 +0545 Subject: [PATCH 4608/4858] Add example for import and other doc improvement --- php/commands/import.php | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/php/commands/import.php b/php/commands/import.php index c0644e33ae..8ae8208330 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -1,5 +1,21 @@ <?php +/** + * Manage imports. + * + * ## EXAMPLES + * + * # Import content from a WXR file + * $ wp import example.wordpress.2016-06-21.xml --authors=create + * Starting the import process... + * Processing post #1 ("Hello world!") (post_type: post) + * -- 1 of 1 + * -- Tue, 21 Jun 2016 05:31:12 +0000 + * -- Imported post as post_id #1 + * Success: Finished importing from 'example.wordpress.2016-06-21.xml' file. + * + * @package wp-cli + */ class Import_Command extends WP_CLI_Command { var $processed_posts = array(); @@ -17,6 +33,17 @@ class Import_Command extends WP_CLI_Command { * * [--skip=<data-type>] * : Skip importing specific data. Supported options are: 'attachment' and 'image_resize' (skip time-consuming thumbnail generation). + * + * ## EXAMPLES + * + * # Import content from a WXR file + * $ wp import example.wordpress.2016-06-21.xml --authors=create + * Starting the import process... + * Processing post #1 ("Hello world!") (post_type: post) + * -- 1 of 1 + * -- Tue, 21 Jun 2016 05:31:12 +0000 + * -- Imported post as post_id #1 + * Success: Finished importing from 'example.wordpress.2016-06-21.xml' file. */ public function __invoke( $args, $assoc_args ) { $defaults = array( @@ -51,7 +78,7 @@ public function __invoke( $args, $assoc_args ) { foreach ( $args as $file ) { if ( ! is_readable( $file ) ) { - WP_CLI::warning( "Can't read $file file." ); + WP_CLI::warning( "Can't read '$file' file." ); } $ret = $this->import_wxr( $file, $assoc_args ); @@ -60,7 +87,7 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::error( $ret ); } else { WP_CLI::log(''); // WXR import ends with HTML, so make sure message is on next line - WP_CLI::success( "Finished importing from $file file." ); + WP_CLI::success( "Finished importing from '$file' file." ); } } } From 5011ef171187ba1140c4a87efd443edce499b0b2 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 21 Jun 2016 21:21:09 +0545 Subject: [PATCH 4609/4858] Fix PHP notice in theme status --- php/commands/theme.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index a834768eca..b8b2cd83cb 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -79,11 +79,13 @@ protected function get_upgrader_class( $force ) { * Author: the WordPress team */ function status( $args ) { - $theme = $this->fetcher->get_check( $args[0] ); - $errors = $theme->errors(); - if ( is_wp_error( $errors ) ) { - $message = $errors->get_error_message(); - WP_CLI::error( $message ); + if ( isset( $args[0] ) ) { + $theme = $this->fetcher->get_check( $args[0] ); + $errors = $theme->errors(); + if ( is_wp_error( $errors ) ) { + $message = $errors->get_error_message(); + WP_CLI::error( $message ); + } } parent::status( $args ); From ba458ccc632a874c8d2c054ae70dfbbf8bf54115 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 21 Jun 2016 21:56:32 +0545 Subject: [PATCH 4610/4858] Add scenario for theme status without theme parameter --- features/theme.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 8c741b2d27..dcf1343a14 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -50,6 +50,20 @@ Feature: Manage WordPress themes When I run `wp theme list` Then STDOUT should not be empty + Scenario: Checking theme status without theme parameter + Given a WP install + + When I run `wp theme install classic --activate` + And I run `wp theme list --field=name --status=inactive | xargs -0 -d '\n' -I % wp theme delete %` + And I run `wp theme status` + Then STDOUT should be: + """ + 1 installed theme: + A classic 1.6 + + Legend: A = Active + """ + Scenario: Install a theme, activate, then force install an older version of the theme Given a WP install From b9dcfdd0968498db4b78392d1f2fcb904ba9c958 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 21 Jun 2016 12:40:11 -0700 Subject: [PATCH 4611/4858] Update tests for WordPress 4.5.3 --- features/core-check-update.feature | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index ad3cf2a695..0b6a728ab5 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -1,17 +1,16 @@ Feature: Check for more recent versions - @less-than-php-7 Scenario: Check for update via Version Check API Given a WP install - When I run `wp core download --version=3.8 --force` + When I run `wp core download --version=4.4 --force` Then STDOUT should not be empty When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5.2 | major | https://downloads.wordpress.org/release/wordpress-4.5.2.zip | - | 3.8.14 | minor | https://downloads.wordpress.org/release/wordpress-3.8.14-partial-0.zip | + | 4.5.3 | major | https://downloads.wordpress.org/release/wordpress-4.5.3.zip | + | 4.4.4 | minor | https://downloads.wordpress.org/release/wordpress-4.4.4-partial-0.zip | When I run `wp core check-update --format=count` Then STDOUT should be: @@ -22,7 +21,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5.2 | major | https://downloads.wordpress.org/release/wordpress-4.5.2.zip | + | 4.5.3 | major | https://downloads.wordpress.org/release/wordpress-4.5.3.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: @@ -33,7 +32,7 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 3.8.14 | minor | https://downloads.wordpress.org/release/wordpress-3.8.14-partial-0.zip | + | 4.4.4 | minor | https://downloads.wordpress.org/release/wordpress-4.4.4-partial-0.zip | When I run `wp core check-update --minor --format=count` Then STDOUT should be: @@ -54,4 +53,4 @@ Feature: Check for more recent versions When I run `wp core check-update --minor` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.0.11 | minor | https://downloads.wordpress.org/release/wordpress-4.0.11-partial-0.zip | + | 4.0.12 | minor | https://downloads.wordpress.org/release/wordpress-4.0.12-partial-0.zip | From 6819c23c1943858b217e1b9a2fc721ba0073601c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 21 Jun 2016 13:29:25 -0700 Subject: [PATCH 4612/4858] Minor version updates too --- features/core-update.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/core-update.feature b/features/core-update.feature index ea20e10492..e4e3a49fc9 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -40,7 +40,7 @@ Feature: Update WordPress core When I run `wp core update --minor` Then STDOUT should contain: """ - Updating to version 3.7.14 + Updating to version 3.7.15 """ When I run `wp core update --minor` @@ -52,7 +52,7 @@ Feature: Update WordPress core When I run `wp core version` Then STDOUT should be: """ - 3.7.14 + 3.7.15 """ @less-than-php-7 @@ -208,8 +208,8 @@ Feature: Update WordPress core When I run `wp core update --minor` Then STDOUT should contain: """ - Updating to version 4.0.10 (en_US)... - Descargando paquete de instalación desde https://downloads.wordpress.org/release/wordpress-4.0.10-partial-0.zip + Updating to version 4.0.11 (en_US)... + Descargando paquete de instalación desde https://downloads.wordpress.org/release/wordpress-4.0.11-partial-0.zip """ And STDOUT should contain: """ From f39298e689fbd9e5bb199fc21573c29c6fb4c8bf Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 22 Jun 2016 15:21:15 +0545 Subject: [PATCH 4613/4858] Doc improvement in export command --- php/commands/export.php | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/php/commands/export.php b/php/commands/export.php index 93a4712711..6278c3d2b1 100644 --- a/php/commands/export.php +++ b/php/commands/export.php @@ -1,9 +1,23 @@ <?php +/** + * Manage exports. + * + * ## EXAMPLES + * + * # Export posts published by the user between given start and end date + * $ wp export --dir=/tmp/ --user=admin --post_type=post --start_date=2011-01-01 --end_date=2011-12-31 + * Starting export process... + * Writing to file /tmp/staging.wordpress.2016-05-24.000.xml + * Success: All done with export. + * + * @package wp-cli + */ class Export_Command extends WP_CLI_Command { /** - * Initialize the array of arguments that will be eventually be passed to export_wp + * Initialize the array of arguments that will be eventually be passed to export_wp. + * * @var array */ public $export_args = array(); @@ -21,7 +35,10 @@ class Export_Command extends WP_CLI_Command { * : Don't export comments. * * [--max_file_size=<MB>] - * : A single export file should have this many megabytes. Default: 15 + * : A single export file should have this many megabytes. + * --- + * default: 15 + * --- * * ## FILTERS * @@ -33,7 +50,10 @@ class Export_Command extends WP_CLI_Command { * * [--post_type=<post-type>] * : Export only posts with this post_type. Separate multiple post types with a - * comma. Defaults to all. + * comma. + * --- + * default: any + * --- * * [--post_type__not_in=<post-type>] * : Export all post types except those identified. Separate multiple post types @@ -76,7 +96,6 @@ class Export_Command extends WP_CLI_Command { * Starting export process... * Writing to file /var/www/example.com/public_html/staging.wordpress.2016-05-24.000.xml * Success: All done with export. - * */ public function __invoke( $_, $assoc_args ) { $defaults = array( @@ -171,7 +190,7 @@ private function check_dir( $path ) { if ( empty( $path ) ) { $path = getcwd(); } elseif ( !is_dir( $path ) ) { - WP_CLI::error( sprintf( "The directory %s does not exist.", $path ) ); + WP_CLI::error( sprintf( "The directory '%s' does not exist.", $path ) ); return false; } @@ -260,7 +279,7 @@ private function check_post__in( $post__in ) { WP_CLI::warning( "post__in should be comma-separated post IDs." ); return false; } - // New exporter uses a different argument + // New exporter uses a different argument. $this->export_args['post_ids'] = $post__in; return true; } @@ -272,7 +291,7 @@ private function check_start_id( $start_id ) { $start_id = intval( $start_id ); - // Post IDs must be greater than 0 + // Post IDs must be greater than 0. if ( 0 >= $start_id ) { WP_CLI::warning( sprintf( __( 'Invalid start ID: %d' ), $start_id ) ); return false; @@ -366,4 +385,3 @@ private function check_max_file_size( $size ) { } WP_CLI::add_command( 'export', 'Export_Command' ); - From 17563405b1a812e1f2b2ca0703521c30543e7fde Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 22 Jun 2016 16:39:29 +0545 Subject: [PATCH 4614/4858] Improve doc and command message in core commands --- features/core-update-db.feature | 10 ++++---- features/core-update.feature | 2 +- php/commands/core.php | 41 +++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/features/core-update-db.feature b/features/core-update-db.feature index f3abbe1ea4..73a3b68624 100644 --- a/features/core-update-db.feature +++ b/features/core-update-db.feature @@ -8,13 +8,13 @@ Feature: Update core's database When I run `wp core update-db` Then STDOUT should contain: """ - Success: WordPress database upgraded successfully from db version 29630 to 30133 + Success: WordPress database upgraded successfully from db version 29630 to 30133. """ When I run `wp core update-db` Then STDOUT should contain: """ - Success: WordPress database already at latest db version 30133 + Success: WordPress database already at latest db version 30133. """ Scenario: Dry run update db on a single site @@ -26,7 +26,7 @@ Feature: Update core's database Then STDOUT should be: """ Performing a dry run, with no database modification. - Success: WordPress database upgraded successfully from db version 29630 to 30133 + Success: WordPress database upgraded successfully from db version 29630 to 30133. """ When I run `wp option get db_version` @@ -52,7 +52,7 @@ Feature: Update core's database When I run `wp core update-db --network` Then STDOUT should contain: """ - Success: WordPress database upgraded on 3/3 sites + Success: WordPress database upgraded on 3/3 sites. """ Scenario: Update db across network @@ -76,5 +76,5 @@ Feature: Update core's database """ And STDOUT should contain: """ - Success: WordPress database upgraded on 3/3 sites + Success: WordPress database upgraded on 3/3 sites. """ diff --git a/features/core-update.feature b/features/core-update.feature index e4e3a49fc9..fff39612cd 100644 --- a/features/core-update.feature +++ b/features/core-update.feature @@ -20,7 +20,7 @@ Feature: Update WordPress core Starting update... Unpacking the update... Cleaning up files... - No files found that need cleaned up + No files found that need cleaned up. Success: WordPress updated successfully. """ diff --git a/php/commands/core.php b/php/commands/core.php index 80a3eadaec..b8ada4ea5d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -46,7 +46,14 @@ class Core_Command extends WP_CLI_Command { * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] - * : Accepted values: table, csv, json, yaml. Default: table + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -110,16 +117,16 @@ public function download( $args, $assoc_args ) { if ( ! is_dir( $download_dir ) ) { if ( ! is_writable( dirname( $download_dir ) ) ) { - WP_CLI::error( sprintf( "Insufficient permission to create directory %s", $download_dir ) ); + WP_CLI::error( sprintf( "Insufficient permission to create directory '%s'.", $download_dir ) ); } - WP_CLI::log( sprintf( 'Creating directory %s', $download_dir ) ); + WP_CLI::log( sprintf( "Creating directory '%s'.", $download_dir ) ); $mkdir = \WP_CLI\Utils\is_windows() ? 'mkdir %s' : 'mkdir -p %s'; WP_CLI::launch( Utils\esc_cmd( $mkdir, $download_dir ) ); } if ( ! is_writable( $download_dir ) ) { - WP_CLI::error( sprintf( "%s is not writable by current user", $download_dir ) ); + WP_CLI::error( sprintf( "'%s' is not writable by current user.", $download_dir ) ); } $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', 'en_US' ); @@ -175,19 +182,19 @@ public function download( $args, $assoc_args ) { if ( 404 == $response->status_code ) { WP_CLI::error( "Release not found. Double-check locale or version." ); } else if ( 20 != substr( $response->status_code, 0, 2 ) ) { - WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})" ); + WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})." ); } $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { - WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})" ); + WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})." ); } $md5_file = md5_file( $temp ); if ( $md5_file === $md5_response->body ) { WP_CLI::log( 'md5 hash verified: ' . $md5_file ); } else { - WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})" ); + WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})." ); } try { @@ -277,7 +284,7 @@ private static function _read( $url ) { if ( 200 === $response->status_code ) { return $response->body; } else { - WP_CLI::error( "Couldn't fetch response from {$url} (HTTP code {$response->status_code})" ); + WP_CLI::error( "Couldn't fetch response from {$url} (HTTP code {$response->status_code})." ); } } @@ -347,14 +354,14 @@ private static function get_initial_locale() { * * # Standard wp-config.php file * $ wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --locale=ro_RO - * Success: Generated wp-config.php file. + * Success: Generated 'wp-config.php' file. * * # Enable WP_DEBUG and WP_DEBUG_LOG * $ wp core config --dbname=testing --dbuser=wp --dbpass=securepswd --extra-php <<PHP * $ define( 'WP_DEBUG', true ); * $ define( 'WP_DEBUG_LOG', true ); * $ PHP - * Success: Generated wp-config.php file. + * Success: Generated 'wp-config.php' file. */ public function config( $_, $assoc_args ) { global $wp_version; @@ -408,9 +415,9 @@ public function config( $_, $assoc_args ) { $bytes_written = file_put_contents( ABSPATH . 'wp-config.php', $out ); if ( ! $bytes_written ) { - WP_CLI::error( 'Could not create new wp-config.php file.' ); + WP_CLI::error( "Could not create new 'wp-config.php' file." ); } else { - WP_CLI::success( 'Generated wp-config.php file.' ); + WP_CLI::success( "Generated 'wp-config.php' file." ); } } @@ -1312,7 +1319,7 @@ function update_db( $_, $assoc_args ) { if ( ! $dry_run && $total && $success == $total ) { update_site_option( 'wpmu_upgrade_site', $wp_db_version ); } - WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites', $success, $total ) ); + WP_CLI::success( sprintf( 'WordPress database upgraded on %d/%d sites.', $success, $total ) ); } else { require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); $wp_current_db_version = __get_option( 'db_version' ); @@ -1320,9 +1327,9 @@ function update_db( $_, $assoc_args ) { if ( ! $dry_run ) { wp_upgrade(); } - WP_CLI::success( "WordPress database upgraded successfully from db version {$wp_current_db_version} to {$wp_db_version}" ); + WP_CLI::success( "WordPress database upgraded successfully from db version {$wp_current_db_version} to {$wp_db_version}." ); } else { - WP_CLI::success( "WordPress database already at latest db version {$wp_db_version}" ); + WP_CLI::success( "WordPress database already at latest db version {$wp_db_version}." ); } } } @@ -1443,9 +1450,9 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { } if ( $count ) { - WP_CLI::log( number_format( $count ) . ' files cleaned up' ); + WP_CLI::log( number_format( $count ) . ' files cleaned up.' ); } else { - WP_CLI::log( 'No files found that need cleaned up' ); + WP_CLI::log( 'No files found that need cleaned up.' ); } } } From bfb3512b127b8bb971f423bda701507ebb58b4ed Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 22 Jun 2016 17:39:55 +0545 Subject: [PATCH 4615/4858] Add missing count param in core check-update --- php/commands/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index b8ada4ea5d..459e1e992b 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -46,11 +46,13 @@ class Core_Command extends WP_CLI_Command { * : Limit the output to specific object fields. Defaults to version,update_type,package_url. * * [--format=<format>] + * : Render output in a particular format. * --- * default: table * options: * - table * - csv + * - count * - json * - yaml * --- From 6eca09b3172ab1a99e6046a51a0595ce66ddb483 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 23 Jun 2016 13:50:39 +0545 Subject: [PATCH 4616/4858] Wrap wp-config.php file name with quotes in command messages --- features/core-config.feature | 2 +- features/core.feature | 4 ++-- php/WP_CLI/Runner.php | 4 ++-- php/commands/core.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/features/core-config.feature b/features/core-config.feature index 7b445bf936..df7186bdee 100644 --- a/features/core-config.feature +++ b/features/core-config.feature @@ -15,7 +15,7 @@ Feature: Manage wp-config Then the return code should be 1 And STDERR should be: """ - Error: wp-config.php not found. + Error: 'wp-config.php' not found. Either create one manually or use `wp core config`. """ diff --git a/features/core.feature b/features/core.feature index 0f91b7b622..87bebc383a 100644 --- a/features/core.feature +++ b/features/core.feature @@ -135,7 +135,7 @@ Feature: Manage WordPress installation Then STDOUT should be: """ Set up multisite database tables. - Added multisite constants to wp-config.php. + Added multisite constants to 'wp-config.php'. Success: Network installed. Don't forget to set up rewrite rules. """ And STDERR should be empty @@ -169,7 +169,7 @@ Feature: Manage WordPress installation """ Created single site database tables. Set up multisite database tables. - Added multisite constants to wp-config.php. + Added multisite constants to 'wp-config.php'. Success: Network installed. Don't forget to set up rewrite rules. """ And STDERR should be empty diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4ca445302d..08f9555f8a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -784,7 +784,7 @@ public function start() { if ( !Utils\locate_wp_config() ) { WP_CLI::error( - "wp-config.php not found.\n" . + "'wp-config.php' not found.\n" . "Either create one manually or use `wp core config`." ); } @@ -859,7 +859,7 @@ public function load_wordpress() { $wp_config_path = Utils\locate_wp_config(); if ( ! $wp_config_path ) { WP_CLI::error( - "wp-config.php not found.\n" . + "'wp-config.php' not found.\n" . "Either create one manually or use `wp core config`." ); } diff --git a/php/commands/core.php b/php/commands/core.php index 459e1e992b..688510373f 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -763,9 +763,9 @@ private function _multisite_convert( $assoc_args ) { $wp_config_path = Utils\locate_wp_config(); if ( is_writable( $wp_config_path ) ) { self::modify_wp_config( $ms_config ); - WP_CLI::log( 'Added multisite constants to wp-config.php.' ); + WP_CLI::log( "Added multisite constants to 'wp-config.php'." ); } else { - WP_CLI::warning( 'Multisite constants could not be written to wp-config.php. You may need to add them manually:' ); + WP_CLI::warning( "Multisite constants could not be written to 'wp-config.php'. You may need to add them manually:" ); WP_CLI::log( $ms_config ); } } From e697d62d79c01c27958def53ba99fe42de574486 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 23 Jun 2016 17:13:24 +0545 Subject: [PATCH 4617/4858] Doc improvement in menu commands --- php/commands/menu.php | 150 +++++++++++++++++++++++++----------------- 1 file changed, 91 insertions(+), 59 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 7959447a44..5517d374a5 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -1,7 +1,7 @@ <?php /** - * List, create, assign, and delete menus + * List, create, assign, and delete menus. * * ## EXAMPLES * @@ -25,6 +25,8 @@ * # Assign the 'my-menu' menu to the 'primary' location * $ wp menu location assign my-menu primary * Success: Assigned location to menu. + * + * @package wp-cli */ class Menu_Command extends WP_CLI_Command { @@ -38,12 +40,12 @@ class Menu_Command extends WP_CLI_Command { ); /** - * Create a new menu + * Create a new menu. * * ## OPTIONS * * <menu-name> - * : A descriptive name for the menu + * : A descriptive name for the menu. * * [--porcelain] * : Output just the new menu id. @@ -73,12 +75,12 @@ public function create( $args, $assoc_args ) { } /** - * Delete one or more menus + * Delete one or more menus. * * ## OPTIONS * * <menu>... - * : The name, slug, or term ID for the menu(s) + * : The name, slug, or term ID for the menu(s). * * ## EXAMPLES * @@ -112,7 +114,17 @@ public function delete( $args, $_ ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - ids + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -164,7 +176,7 @@ public function list_( $_, $assoc_args ) { } - // Normalize the data for some output formats + // Normalize the data for some output formats. if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table' ) ) ) { $menu->locations = implode( ',', $menu->locations ); } @@ -182,7 +194,7 @@ protected function get_formatter( &$assoc_args ) { } /** - * List, add, and delete items associated with a menu + * List, add, and delete items associated with a menu. * * ## EXAMPLES * @@ -209,18 +221,28 @@ class Menu_Item_Command extends WP_CLI_Command { ); /** - * Get a list of items associated with a menu + * Get a list of items associated with a menu. * * ## OPTIONS * * <menu> - * : The name, slug, or term ID for the menu + * : The name, slug, or term ID for the menu. * * [--fields=<fields>] * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - ids + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -284,39 +306,39 @@ public function list_( $args, $assoc_args ) { } /** - * Add a post as a menu item + * Add a post as a menu item. * * ## OPTIONS * * <menu> - * : The name, slug, or term ID for the menu + * : The name, slug, or term ID for the menu. * * <post-id> - * : Post ID to add to the menu + * : Post ID to add to the menu. * * [--title=<title>] - * : Set a custom title for the menu item + * : Set a custom title for the menu item. * * [--link=<link>] - * : Set a custom url for the menu item + * : Set a custom url for the menu item. * * [--description=<description>] - * : Set a custom description for the menu item + * : Set a custom description for the menu item. * * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item + * : Set a custom title attribute for the menu item. * * [--target=<target>] - * : Set a custom link target for the menu item + * : Set a custom link target for the menu item. * * [--classes=<classes>] - * : Set a custom link classes for the menu item + * : Set a custom link classes for the menu item. * * [--position=<position>] * : Specify the position of this menu item. * * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item + * : Make this menu item a child of another menu item. * * [--porcelain] * : Output just the new menu item id. @@ -342,42 +364,42 @@ public function add_post( $args, $assoc_args ) { } /** - * Add a taxonomy term as a menu item + * Add a taxonomy term as a menu item. * * ## OPTIONS * * <menu> - * : The name, slug, or term ID for the menu + * : The name, slug, or term ID for the menu. * * <taxonomy> - * : Taxonomy of the term to be added + * : Taxonomy of the term to be added. * * <term-id> - * : Term ID of the term to be added + * : Term ID of the term to be added. * * [--title=<title>] - * : Set a custom title for the menu item + * : Set a custom title for the menu item. * * [--link=<link>] - * : Set a custom url for the menu item + * : Set a custom url for the menu item. * * [--description=<description>] - * : Set a custom description for the menu item + * : Set a custom description for the menu item. * * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item + * : Set a custom title attribute for the menu item. * * [--target=<target>] - * : Set a custom link target for the menu item + * : Set a custom link target for the menu item. * * [--classes=<classes>] - * : Set a custom link classes for the menu item + * : Set a custom link classes for the menu item. * * [--position=<position>] * : Specify the position of this menu item. * * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item + * : Make this menu item a child of another menu item. * * [--porcelain] * : Output just the new menu item id. @@ -404,36 +426,36 @@ public function add_term( $args, $assoc_args ) { } /** - * Add a custom menu item + * Add a custom menu item. * * ## OPTIONS * * <menu> - * : The name, slug, or term ID for the menu + * : The name, slug, or term ID for the menu. * * <title> - * : Title for the link + * : Title for the link. * * <link> - * : Target URL for the link + * : Target URL for the link. * * [--description=<description>] - * : Set a custom description for the menu item + * : Set a custom description for the menu item. * * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item + * : Set a custom title attribute for the menu item. * * [--target=<target>] - * : Set a custom link target for the menu item + * : Set a custom link target for the menu item. * * [--classes=<classes>] - * : Set a custom link classes for the menu item + * : Set a custom link classes for the menu item. * * [--position=<position>] * : Specify the position of this menu item. * * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item + * : Make this menu item a child of another menu item. * * [--porcelain] * : Output just the new menu item id. @@ -455,7 +477,7 @@ public function add_custom( $args, $assoc_args ) { } /** - * Update a menu item + * Update a menu item. * * ## OPTIONS * @@ -463,28 +485,28 @@ public function add_custom( $args, $assoc_args ) { * : Database ID for the menu item. * * [--title=<title>] - * : Set a custom title for the menu item + * : Set a custom title for the menu item. * * [--link=<link>] - * : Set a custom url for the menu item + * : Set a custom url for the menu item. * * [--description=<description>] - * : Set a custom description for the menu item + * : Set a custom description for the menu item. * * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item + * : Set a custom title attribute for the menu item. * * [--target=<target>] - * : Set a custom link target for the menu item + * : Set a custom link target for the menu item. * * [--classes=<classes>] - * : Set a custom link classes for the menu item + * : Set a custom link classes for the menu item. * * [--position=<position>] * : Specify the position of this menu item. * * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item + * : Make this menu item a child of another menu item. * * ## EXAMPLES * @@ -495,7 +517,7 @@ public function add_custom( $args, $assoc_args ) { */ public function update( $args, $assoc_args ) { - // Shuffle the position of these + // Shuffle the position of these. $args[1] = $args[0]; $terms = get_the_terms( $args[1], 'nav_menu' ); if ( $terms && ! is_wp_error( $terms ) ) { @@ -509,7 +531,7 @@ public function update( $args, $assoc_args ) { } /** - * Delete one or more items from a menu + * Delete one or more items from a menu. * * ## OPTIONS * @@ -549,7 +571,7 @@ public function delete( $args, $_ ) { } /** - * Worker method to create new items or update existing ones + * Worker method to create new items or update existing ones. */ private function add_or_update_item( $method, $type, $args, $assoc_args ) { @@ -692,7 +714,17 @@ class Menu_Location_Command extends WP_CLI_Command { * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - ids + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -729,15 +761,15 @@ public function list_( $_, $assoc_args ) { } /** - * Assign a location to a menu + * Assign a location to a menu. * * ## OPTIONS * * <menu> - * : The name, slug, or term ID for the menu + * : The name, slug, or term ID for the menu. * * <location> - * : Location's slug + * : Location's slug. * * ## EXAMPLES * @@ -769,15 +801,15 @@ public function assign( $args, $_ ) { } /** - * Remove a location from a menu + * Remove a location from a menu. * * ## OPTIONS * * <menu> - * : The name, slug, or term ID for the menu + * : The name, slug, or term ID for the menu. * * <location> - * : Location's slug + * : Location's slug. * * ## EXAMPLES * From 215f486c09b8994e2dbd0c059465af3d7c145e27 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 26 Jun 2016 10:19:29 +0200 Subject: [PATCH 4618/4858] Failing test case for #2852 --- features/formatter.feature | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/features/formatter.feature b/features/formatter.feature index a34551b056..aa1d67823d 100644 --- a/features/formatter.feature +++ b/features/formatter.feature @@ -6,9 +6,17 @@ Feature: Format output """ <?php /** + * Output data as YAML + * + * <type> + * : Type of output. + * + * [--fields=<fields>] + * : Limit output to particular fields + * * @when before_wp_load */ - $output_yaml = function( $args ) { + $output_yaml = function( $args, $assoc_args ) { $items = array( array( 'label' => 'Foo', @@ -19,8 +27,13 @@ Feature: Format output 'slug' => 'bar', ), ); - $assoc_args = array( 'format' => 'yaml', 'fields' => array( 'label', 'slug' ) ); - $formatter = new \WP_CLI\Formatter( $assoc_args ); + $format_args = array( 'format' => 'yaml' ); + if ( isset( $assoc_args['fields'] ) ) { + $format_args['fields'] = explode( ',', $assoc_args['fields'] ); + } else { + $format_args['fields'] = array( 'label', 'slug' ); + } + $formatter = new \WP_CLI\Formatter( $format_args ); if ( 'all' === $args[0] ) { $formatter->display_items( $items ); } else if ( 'single' === $args[0] ) { @@ -42,6 +55,20 @@ Feature: Format output slug: bar """ + When I run `wp --require=output-yaml.php yaml all --fields=label` + Then STDOUT should be YAML containing: + """ + --- + - + label: Foo + - + label: Bar + """ + And STDOUT should not contain: + """ + slug: bar + """ + When I run `wp --require=output-yaml.php yaml single` Then STDOUT should be YAML containing: """ From 42f5d456cb532fc56628962ecc560601c7531758 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 26 Jun 2016 10:20:23 +0200 Subject: [PATCH 4619/4858] Ensure YAML formatter handles objects and `--fields=<fields>` arg --- php/WP_CLI/Formatter.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Formatter.php b/php/WP_CLI/Formatter.php index 0b04ec5e81..5ab4bb5294 100644 --- a/php/WP_CLI/Formatter.php +++ b/php/WP_CLI/Formatter.php @@ -138,16 +138,17 @@ private function format( $items ) { break; case 'json': + case 'yaml': $out = array(); foreach ( $items as $item ) { $out[] = \WP_CLI\Utils\pick_fields( $item, $fields ); } - echo json_encode( $out ); - break; - - case 'yaml': - echo \Spyc::YAMLDump( $items, 2, 0 ); + if ( 'json' === $this->args['format'] ) { + echo json_encode( $out ); + } else if ( 'yaml' === $this->args['format'] ) { + echo \Spyc::YAMLDump( $out, 2, 0 ); + } break; default: From f4f314a758056f4fe41cd22ed4762f346f31c2f4 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sun, 26 Jun 2016 21:58:31 +0545 Subject: [PATCH 4620/4858] Improve default format in command doc in plugin file --- php/commands/plugin.php | 43 +++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 30f941ba8d..d27ae8ba9f 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -100,10 +100,16 @@ function status( $args ) { * : The string to search for. * * [--page=<page>] - * : Optional page to display. Defaults to 1. + * : Optional page to display. + * --- + * default: 1 + * --- * * [--per-page=<per-page>] - * : Optional number of results to display. Defaults to 10. + * : Optional number of results to display. + * --- + * default: 10 + * --- * * [--field=<field>] * : Prints the value of a single field for each plugin. @@ -127,7 +133,16 @@ function status( $args ) { * **short_description**: Plugin's Short Description * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - count + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -610,7 +625,15 @@ function install( $args, $assoc_args ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Output list as table, json, CSV, yaml. Defaults to table. + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -751,7 +774,16 @@ function delete( $args, $assoc_args = array() ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - count + * - json + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -790,7 +822,6 @@ function delete( $args, $assoc_args = array() ) { * | hello | inactive | none | 1.6 | * +------------------------------+----------------+-----------+------------+ * - * * @subcommand list */ public function list_( $_, $assoc_args ) { From 172bee7a7af5419883c38e27b4fa8d2db88b9d64 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 02:38:53 -0700 Subject: [PATCH 4621/4858] Readme edits: https links; clarity See #2760 --- README.md | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 914f640ade..b813551212 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,30 @@ WP-CLI ====== -[WP-CLI](http://wp-cli.org/) is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs and much more, without using a web browser. +[WP-CLI](https://wp-cli.org/) is a set of command-line tools for managing [WordPress](https://wordpress.org/) installations. You can update plugins, configure multisite installs and much more, without using a web browser. + +<div style=" + border: 1px solid #7AD03A; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + padding-left: 10px; + padding-right: 10px; +"> + <p><strong>A more RESTful WP-CLI</strong> aims to unlocking the potential of the WP REST API at the command line. Project backed by Pressed, Chris Lema, Human Made, Pagely, Pantheon and many others. <a href="https://wp-cli.org/restful/">Learn more →</a></p> +</div> [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) - Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) | [Credits](#credits) +For news and announcements, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for our email newsletter](http://wp-cli.us13.list-manage.com/subscribe?u=0615e4d18f213891fc000adfd&id=8c61d7641e). + ## Using -The goal of WP-CLI is to provide a command-line interface for any action you can perform in the WordPress admin. The project also includes commands for many actions you can't perform in the WordPress admin. +WP-CLI's mission is to provide a command-line interface for any action you might want to perform in the WordPress dashboard. WP-CLI also includes commands for many things you can't do in the WordPress dashboard. -For instance, `wp plugin install` ([doc](http://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: +For instance, `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: ``` $ wp plugin install rest-api --activate @@ -25,32 +37,34 @@ Activating 'rest-api'... Success: Plugin 'rest-api' activated. ``` -Similarly, `wp transient` ([doc](http://wp-cli.org/commands/transient/)) lets you delete one or all transients: +Similarly, `wp transient` ([doc](https://wp-cli.org/commands/transient/)) lets you delete one or all transients: ``` $ wp transient delete-all Success: 34 transients deleted from the database. ``` -For a complete introduction, read the [Quick Start guide](http://wp-cli.org/docs/quick-start/). If you already feel comfortable with the basics, jump into the [complete list of commands](http://wp-cli.org/commands/) for managing themes and plugins, importing and exporting data, performing database search-replace operations and more. +For a complete introduction to WP-CLI, read the [Quick Start guide](https://wp-cli.org/docs/quick-start/). + +Already feel comfortable with the basics? Jump into the [complete list of commands](https://wp-cli.org/commands/) for detailed information on managing themes and plugins, importing and exporting data, performing database search-replace operations and more. ## Installing -The recommended way to install WP-CLI is to download the Phar build, mark it executable and place it in your PATH. See also our documentation on [alternative installation methods](http://wp-cli.org/docs/installing/). +We recommend installing WP-CLI through the Phar distribution mechanism: download the Phar build, mark it executable, and place it on your PATH. The complete instructions follow shortly. Should you need, see also our documentation on [alternative installation methods](https://wp-cli.org/docs/installing/). -Before you install though, please make sure your environment meets the minimum requirements: +Before installing WP-CLI, please make sure your environment meets the minimum requirements: - UNIX-like environment (OS X, Linux, FreeBSD, Cygwin); limited support in Windows environment - PHP 5.3.29 or later - WordPress 3.7 or later -Download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) using `wget` or `curl`. For example: +Once you've verified requirements, download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) file using `wget` or `curl`. For example: ``` $ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar ``` -Check if it is working: +Next, check if it is working: ``` $ php wp-cli.phar --info @@ -81,28 +95,29 @@ WP-CLI version: 0.23.0 WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: -- [Common issues and their fixes](http://wp-cli.org/docs/common-issues/) -- [Best practices for submitting a bug report](http://wp-cli.org/docs/bug-reports/) -- [Documentation portal](http://wp-cli.org/docs/) +- [Common issues and their fixes](https://wp-cli.org/docs/common-issues/) +- [Best practices for submitting a bug report](https://wp-cli.org/docs/bug-reports/) +- [Documentation portal](https://wp-cli.org/docs/) If you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). ## Extending -A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](http://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](http://wp-cli.org/commands/plugin/activate/)) is another. +A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another. -WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](http://wp-cli.org/docs/commands-cookbook/) to learn more. +WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. ## Contributing -To get involved, please first read about [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). +To get involved, please first read about [creating an issue](https://wp-cli.org/docs/bug-reports/) or [submitting a pull request](https://wp-cli.org/docs/pull-requests/). ### Leadership + * [Andreas Creten](https://github.com/andreascreten) - founder * [Cristi Burcă](https://github.com/scribu) - previous maintainer * [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer -Read more about the project's [Governance](http://wp-cli.org/docs/governance/) and view a [complete list of contributors](https://github.com/wp-cli/wp-cli/contributors). +Read more about the project's [Governance](https://wp-cli.org/docs/governance/) and view a [complete list of contributors](https://github.com/wp-cli/wp-cli/contributors). ## Credits From 24f16e435b80132fce809146b2067aa4fe4106dd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 03:35:07 -0700 Subject: [PATCH 4622/4858] Restructure intro so quick links don't get rendered as table See #2760 --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b813551212..248c65e0a0 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ WP-CLI [WP-CLI](https://wp-cli.org/) is a set of command-line tools for managing [WordPress](https://wordpress.org/) installations. You can update plugins, configure multisite installs and much more, without using a web browser. +For news and announcements, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for our email newsletter](http://wp-cli.us13.list-manage.com/subscribe?u=0615e4d18f213891fc000adfd&id=8c61d7641e). + +[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) + <div style=" border: 1px solid #7AD03A; -webkit-border-radius: 5px; @@ -14,11 +18,7 @@ WP-CLI <p><strong>A more RESTful WP-CLI</strong> aims to unlocking the potential of the WP REST API at the command line. Project backed by Pressed, Chris Lema, Human Made, Pagely, Pantheon and many others. <a href="https://wp-cli.org/restful/">Learn more →</a></p> </div> -[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) - -Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) | [Credits](#credits) - -For news and announcements, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for our email newsletter](http://wp-cli.us13.list-manage.com/subscribe?u=0615e4d18f213891fc000adfd&id=8c61d7641e). +Quick links: [Using](#using) | [Installing](#installing) | [Support](#support) | [Extending](#extending) | [Contributing](#contributing) | [Credits](#credits) ## Using From 6b792ac9f782946c01cf7589619db78371a9bda5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 03:47:27 -0700 Subject: [PATCH 4623/4858] Remaining edits to the README.md Fixes #2760 --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 248c65e0a0..2c6b99631e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ WP-CLI [WP-CLI](https://wp-cli.org/) is a set of command-line tools for managing [WordPress](https://wordpress.org/) installations. You can update plugins, configure multisite installs and much more, without using a web browser. -For news and announcements, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for our email newsletter](http://wp-cli.us13.list-manage.com/subscribe?u=0615e4d18f213891fc000adfd&id=8c61d7641e). +To stay up to date, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for our email newsletter](http://wp-cli.us13.list-manage.com/subscribe?u=0615e4d18f213891fc000adfd&id=8c61d7641e). [![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) @@ -22,9 +22,7 @@ Quick links: [Using](#using) | [Installing](#installing) | [Support](# ## Using -WP-CLI's mission is to provide a command-line interface for any action you might want to perform in the WordPress dashboard. WP-CLI also includes commands for many things you can't do in the WordPress dashboard. - -For instance, `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: +WP-CLI's goal is to provide a command-line interface for any action you might want to perform in the WordPress admin. For instance, `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: ``` $ wp plugin install rest-api --activate @@ -37,20 +35,20 @@ Activating 'rest-api'... Success: Plugin 'rest-api' activated. ``` -Similarly, `wp transient` ([doc](https://wp-cli.org/commands/transient/)) lets you delete one or all transients: +WP-CLI also includes commands for many things you can't do in the WordPress admin. For example, `wp transient delete-all` ([doc](https://wp-cli.org/commands/transient/delete-all/)) lets you delete one or all transients: ``` $ wp transient delete-all Success: 34 transients deleted from the database. ``` -For a complete introduction to WP-CLI, read the [Quick Start guide](https://wp-cli.org/docs/quick-start/). +For a more complete introduction to using WP-CLI, read the [Quick Start guide](https://wp-cli.org/docs/quick-start/). Already feel comfortable with the basics? Jump into the [complete list of commands](https://wp-cli.org/commands/) for detailed information on managing themes and plugins, importing and exporting data, performing database search-replace operations and more. ## Installing -We recommend installing WP-CLI through the Phar distribution mechanism: download the Phar build, mark it executable, and place it on your PATH. The complete instructions follow shortly. Should you need, see also our documentation on [alternative installation methods](https://wp-cli.org/docs/installing/). +Downloading the Phar file is our recommended installation method. Should you need, see also our documentation on [alternative installation methods](https://wp-cli.org/docs/installing/). Before installing WP-CLI, please make sure your environment meets the minimum requirements: @@ -58,7 +56,7 @@ Before installing WP-CLI, please make sure your environment meets the minimum re - PHP 5.3.29 or later - WordPress 3.7 or later -Once you've verified requirements, download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) file using `wget` or `curl`. For example: +Once you've verified requirements, download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) file using `wget` or `curl`: ``` $ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar @@ -70,14 +68,14 @@ Next, check if it is working: $ php wp-cli.phar --info ``` -To use it from the command line by typing `wp`, make the file executable and move it to somewhere in your PATH. For example: +To use WP-CLI from the command line by typing `wp`, make the file executable and move it to somewhere in your PATH. For example: ``` $ chmod +x wp-cli.phar $ sudo mv wp-cli.phar /usr/local/bin/wp ``` -If WP-CLI installed successfully, you should see something like this when you run `wp --info`: +If WP-CLI was installed successfully, you should see something like this when you run `wp --info`: ``` $ wp --info @@ -91,6 +89,8 @@ WP-CLI project config: WP-CLI version: 0.23.0 ``` +You can update WP-CLI with `wp cli update` ([doc](https://wp-cli.org/commands/cli/update/)), or by repeating the installation steps. + ## Support WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: @@ -113,11 +113,11 @@ To get involved, please first read about [creating an issue](https://wp-cli.org/ ### Leadership -* [Andreas Creten](https://github.com/andreascreten) - founder -* [Cristi Burcă](https://github.com/scribu) - previous maintainer * [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer +* [Cristi Burcă](https://github.com/scribu) - previous maintainer +* [Andreas Creten](https://github.com/andreascreten) - founder -Read more about the project's [Governance](https://wp-cli.org/docs/governance/) and view a [complete list of contributors](https://github.com/wp-cli/wp-cli/contributors). +Read more about the project's [governance](https://wp-cli.org/docs/governance/) and view a [complete list of contributors](https://github.com/wp-cli/wp-cli/contributors). ## Credits From 658b03a78baf757bde085e323766cdfba6210757 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 27 Jun 2016 17:43:50 +0545 Subject: [PATCH 4624/4858] Improve default format in docs for cron commands --- php/commands/cron.php | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 6e531e6c87..d910434dc4 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -15,12 +15,13 @@ * * # Delete the next scheduled cron event * $ wp cron event delete cron_test - * Success: Deleted 2 instances of the cron event 'cron_test' + * Success: Deleted 2 instances of the cron event 'cron_test'. * * # List scheduled cron events in JSON * $ wp cron event list --fields=hook,next_run --format=json * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] * + * @package wp-cli */ class Cron_Event_Command extends WP_CLI_Command { @@ -47,7 +48,16 @@ class Cron_Event_Command extends WP_CLI_Command { * : Prints the value of a single field for each event. * * [--format=<format>] - * : Accepted values: table, json, csv, ids, yaml. Default: table. + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -115,7 +125,7 @@ public function list_( $args, $assoc_args ) { * ## OPTIONS * * <hook> - * : The hook name + * : The hook name. * * [<next-run>] * : A Unix timestamp or an English textual datetime description compatible with `strtotime()`. Defaults to now. @@ -282,13 +292,13 @@ protected static function run_event( stdClass $event ) { * ## OPTIONS * * <hook> - * : The hook name + * : The hook name. * * ## EXAMPLES * * # Delete the next scheduled cron event * $ wp cron event delete cron_test - * Success: Deleted 2 instances of the cron event 'cron_test' + * Success: Deleted 2 instances of the cron event 'cron_test'. */ public function delete( $args, $assoc_args ) { @@ -493,7 +503,16 @@ class Cron_Schedule_Command extends WP_CLI_Command { * : Prints the value of a single field for each schedule. * * [--format=<format>] - * : Accepted values: table, json, csv, ids, yaml. Default: table. + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - yaml + * --- * * ## AVAILABLE FIELDS * From 0b513daa831ddcd8e78e73a3f5019c4fd7fb616c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 07:16:14 -0700 Subject: [PATCH 4625/4858] Link to WP StackExchange and Github issue backlog for support --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2c6b99631e..d5613e0baa 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,8 @@ WP-CLI's maintainers and project contributors do their best to respond to all ne - [Common issues and their fixes](https://wp-cli.org/docs/common-issues/) - [Best practices for submitting a bug report](https://wp-cli.org/docs/bug-reports/) - [Documentation portal](https://wp-cli.org/docs/) +- [Open or closed issues on Github](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=is%3Aissue) +- [WordPress StackExchange forums](http://wordpress.stackexchange.com/questions/tagged/wp-cli) If you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). From ab22ff0a721b96ff0683c6606e831f23b0db0249 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 07:43:39 -0700 Subject: [PATCH 4626/4858] Add Is it maintained? chicklets to README.md Fixes #2996 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5613e0baa..4349354b2b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ WP-CLI To stay up to date, follow [@wpcli on Twitter](https://twitter.com/wpcli) or [sign up for our email newsletter](http://wp-cli.us13.list-manage.com/subscribe?u=0615e4d18f213891fc000adfd&id=8c61d7641e). -[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) +[![Build Status](https://travis-ci.org/wp-cli/wp-cli.png?branch=master)](https://travis-ci.org/wp-cli/wp-cli) [![Dependency Status](https://gemnasium.com/badges/github.com/wp-cli/wp-cli.svg)](https://gemnasium.com/github.com/wp-cli/wp-cli) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/wp-cli/wp-cli.svg)](http://isitmaintained.com/project/wp-cli/wp-cli "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/wp-cli/wp-cli.svg)](http://isitmaintained.com/project/wp-cli/wp-cli "Percentage of issues still open") <div style=" border: 1px solid #7AD03A; From 655bc75cda9d0aa7a9d5fc0801d9fecc07352343 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Mon, 27 Jun 2016 20:57:09 +0545 Subject: [PATCH 4627/4858] Add count value for format in cron event list command --- php/commands/cron.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/cron.php b/php/commands/cron.php index d910434dc4..f24587045e 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -56,6 +56,7 @@ class Cron_Event_Command extends WP_CLI_Command { * - csv * - ids * - json + * - count * - yaml * --- * From 9e82c3c556023a46fb1fce015e5c694129b32c9c Mon Sep 17 00:00:00 2001 From: John Blackbourn <john@johnblackbourn.com> Date: Mon, 27 Jun 2016 18:22:00 +0200 Subject: [PATCH 4628/4858] Add a test for the recently active plugin list. --- features/plugin.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/plugin.feature b/features/plugin.feature index ff89ccb2ed..21efa3181d 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -73,6 +73,12 @@ Feature: Manage WordPress plugins When I run `wp plugin deactivate Zombieland` Then STDOUT should not be empty + When I run `wp option get recently_activated` + Then STDOUT should contain: + """ + Zombieland/Zombieland.php + """ + When I run `wp plugin uninstall Zombieland` Then STDOUT should contain: """ From fc95dabb413e26a134decca0e66c58d754d882ce Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 09:39:26 -0700 Subject: [PATCH 4629/4858] First pass at alias groups Given a `wp-cli.local.yml`: ``` @both: - @prod - @dev @prod: ssh: rc~/webapps/production @dev: ssh: v/srv/www/runcommand.dev ``` One can: ``` $ wp @both rewrite flush Success: Rewrite rules flushed. Success: Rewrite rules flushed. ``` --- features/aliases.feature | 44 +++++++++++++++++++++++++++++++++++++ php/WP_CLI/Configurator.php | 15 ++++++++++++- php/WP_CLI/Runner.php | 41 ++++++++++++++++++++++++++++++---- 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/features/aliases.feature b/features/aliases.feature index eb17625f66..1985a977dd 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -120,3 +120,47 @@ Feature: Create shortcuts to specific WordPress installs """ Error: This does not seem to be a WordPress install. """ + + Scenario: Use a group of aliases to run a command against multiple installs + Given a WP install in 'subdir1' + And a WP install in 'subdir2' + And a wp-cli.yml file: + """ + @both: + - @subdir1 + - @subdir2 + @invalid: + - @subdir1 + - @subdir3 + @subdir1: + path: subdir1 + @subdir2: + path: subdir2 + """ + + When I run `wp @subdir1 option update home 'http://apple.com'` + And I run `wp @subdir1 option get home` + Then STDOUT should contain: + """ + http://apple.com + """ + + When I run `wp @subdir2 option update home 'http://google.com'` + And I run `wp @subdir2 option get home` + Then STDOUT should contain: + """ + http://google.com + """ + + When I try `wp @invalid option get home` + Then STDERR should be: + """ + Error: Group '@invalid' contains one or more invalid aliases: @subdir3 + """ + + When I run `wp @both option get home` + Then STDOUT should be: + """ + http://apple.com + http://google.com + """ diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index d9cb9789a2..35063c2c86 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -155,9 +155,11 @@ public function merge_yml( $path ) { if ( ! empty( $yaml['_']['inherit'] ) ) { $this->merge_yml( $yaml['_']['inherit'] ); } + $alias_regex = '#^@[A-Za-z0-9-_]+$#'; foreach ( $yaml as $key => $value ) { - if ( preg_match( '#@[A-Za-z0-9-_]+#', $key ) ) { + if ( preg_match( $alias_regex, $key ) ) { $this->aliases[ $key ] = array(); + $is_alias = false; foreach( array( 'user', 'url', @@ -166,8 +168,19 @@ public function merge_yml( $path ) { ) as $i ) { if ( isset( $value[ $i ] ) ) { $this->aliases[ $key ][ $i ] = $value[ $i ]; + $is_alias = true; } } + // If it's not an alias, it might be a group of aliases + if ( ! $is_alias && is_array( $value ) ) { + $alias_group = array(); + foreach( $value as $i => $k ) { + if ( preg_match( $alias_regex, $k ) ) { + $alias_group[] = $k; + } + } + $this->aliases[ $key ] = $alias_group; + } } elseif ( !isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) { if ( isset( $this->extra_config[ $key ] ) && ! empty( $yaml['_']['merge'] ) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 08f9555f8a..93763d9398 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -657,10 +657,29 @@ private function check_root() { ); } - private function set_alias( $alias ) { - if ( ! array_key_exists( $alias, $this->aliases ) ) { - WP_CLI::error( "Alias '{$alias}' not found." ); + private function run_alias_group( $aliases ) { + $php_bin = WP_CLI::get_php_binary(); + + $script_path = $GLOBALS['argv'][0]; + + if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) { + $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); + } else { + $config_path = getenv( 'HOME' ) . '/.wp-cli/config.yml'; } + $config_path = escapeshellarg( $config_path ); + + foreach( $aliases as $alias ) { + + $args = implode( ' ', array_map( 'escapeshellarg', $this->arguments ) ); + $assoc_args = Utils\assoc_args_to_str( $this->assoc_args ); + + $full_command = "WP_CLI_CONFIG_PATH={$config_path} {$php_bin} {$script_path} {$alias} {$args} {$assoc_args}"; + passthru( $full_command ); + } + } + + private function set_alias( $alias ) { $orig_config = $this->config; $alias_config = $this->aliases[ $this->alias ]; $this->config = array_merge( $orig_config, $alias_config ); @@ -681,7 +700,21 @@ public function start() { $this->check_root(); if ( $this->alias ) { - $this->set_alias( $this->alias ); + if ( ! array_key_exists( $this->alias, $this->aliases ) ) { + WP_CLI::error( "Alias '{$alias}' not found." ); + } + // Numerically indexed means a group of aliases + if ( isset( $this->aliases[ $this->alias ][0] ) ) { + $group_aliases = $this->aliases[ $this->alias ]; + $all_aliases = array_keys( $this->aliases ); + if ( $diff = array_diff( $group_aliases, $all_aliases ) ) { + WP_CLI::error( "Group '{$this->alias}' contains one or more invalid aliases: " . implode( ', ', $diff ) ); + } + $this->run_alias_group( $group_aliases ); + exit; + } else { + $this->set_alias( $this->alias ); + } } if ( empty( $this->arguments ) ) From 5198fd20c81905240153d56d3897361d508050a2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 27 Jun 2016 09:43:25 -0700 Subject: [PATCH 4630/4858] Fix failing test by using a valid variable --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 93763d9398..4499b17d1b 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -701,7 +701,7 @@ public function start() { $this->check_root(); if ( $this->alias ) { if ( ! array_key_exists( $this->alias, $this->aliases ) ) { - WP_CLI::error( "Alias '{$alias}' not found." ); + WP_CLI::error( "Alias '{$this->alias}' not found." ); } // Numerically indexed means a group of aliases if ( isset( $this->aliases[ $this->alias ][0] ) ) { From 87b73575745167422e0e0895df07ad92af344384 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 28 Jun 2016 14:44:16 +0545 Subject: [PATCH 4631/4858] Add ids for format parameter in sidebar list --- php/commands/sidebar.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/php/commands/sidebar.php b/php/commands/sidebar.php index 8745073960..19773c38ab 100644 --- a/php/commands/sidebar.php +++ b/php/commands/sidebar.php @@ -35,6 +35,7 @@ class Sidebar_Command extends WP_CLI_Command { * - table * - csv * - json + * - ids * - count * - yaml * --- @@ -69,8 +70,15 @@ public function list_( $args, $assoc_args ) { \WP_CLI\Utils\wp_register_unused_sidebar(); + if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) { + $sidebars = wp_list_pluck( $wp_registered_sidebars, 'id' ); + } + else { + $sidebars = $wp_registered_sidebars; + } + $formatter = new \WP_CLI\Formatter( $assoc_args, $this->fields ); - $formatter->display_items( $wp_registered_sidebars ); + $formatter->display_items( $sidebars ); } } From 7e12aba6f1d5976d5b1a14b0ba1f57e7ea9e2808 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 28 Jun 2016 14:53:58 +0545 Subject: [PATCH 4632/4858] Add test for ids in param in sidebar list command --- features/sidebar.feature | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/sidebar.feature b/features/sidebar.feature index 1126cfa98e..cf53186c5a 100644 --- a/features/sidebar.feature +++ b/features/sidebar.feature @@ -10,3 +10,15 @@ Feature: Manage WordPress sidebars Then STDOUT should be a table containing rows: | name | id | | Sidebar | sidebar-1 | + + When I run `wp sidebar list --format=ids` + Then STDOUT should be: + """ + sidebar-1 wp_inactive_widgets + """ + + When I run `wp sidebar list --format=count` + Then STDOUT should be: + """ + 2 + """ From 27d6fee17d0e0685f19a3792f5acb7aba82340f9 Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Tue, 28 Jun 2016 21:10:27 +0200 Subject: [PATCH 4633/4858] Fix exception in menu list command if the format is ids #3074 The formatter could not iterate trough the WP_Term object. Now it the format is 'ids' all term_ids getting grabbed from the array and imploded in the display_items method --- php/commands/menu.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 5517d374a5..8e8a1eee2b 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -177,14 +177,19 @@ public function list_( $_, $assoc_args ) { } // Normalize the data for some output formats. - if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table' ) ) ) { + if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table') ) ) { $menu->locations = implode( ',', $menu->locations ); } } $formatter = $this->get_formatter( $assoc_args ); - $formatter->display_items( $menus ); + if ( 'ids' == $formatter->format ) { + $ids = array_column( $menus, 'term_id' ); + $formatter->display_items( $ids ); + } else { + $formatter->display_items( $menus ); + } } protected function get_formatter( &$assoc_args ) { From 7005f83929538fae33c29de104f3c886f800dade Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Tue, 28 Jun 2016 21:22:10 +0200 Subject: [PATCH 4634/4858] Fix formatting Add whitespace to match coding style --- php/commands/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 8e8a1eee2b..d6744b37da 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -177,7 +177,7 @@ public function list_( $_, $assoc_args ) { } // Normalize the data for some output formats. - if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table') ) ) { + if ( ! isset( $assoc_args['format'] ) || in_array( $assoc_args['format'], array( 'csv', 'table' ) ) ) { $menu->locations = implode( ',', $menu->locations ); } } From 8a99f5558c6db2fdce9858abc34424aff4539cd3 Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Tue, 28 Jun 2016 21:51:40 +0200 Subject: [PATCH 4635/4858] Add feature test for wp menu item list with format ids --- features/menu.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index 194829d178..d75af3725a 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -33,6 +33,13 @@ Feature: Manage WordPress menus 0 """ + When I run `wp menu create "First Menu"` + And I run `wp menu list --format=ids` + Then STDOUT should be: + """ + 5 + """ + Scenario: Assign / remove location from a menu When I run `wp theme install p2 --activate` From 7388bf543de5fc4ff6fec6af9ff9b6cf9d8dcce5 Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Tue, 28 Jun 2016 23:45:40 +0200 Subject: [PATCH 4636/4858] Change array_column to array_map method because of compatibility array_column() only accepts an array of objects since php 7.0 For compatibility reasons with lower php versions, used array_map instead --- php/commands/menu.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index d6744b37da..2ee9527363 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -185,7 +185,11 @@ public function list_( $_, $assoc_args ) { $formatter = $this->get_formatter( $assoc_args ); if ( 'ids' == $formatter->format ) { - $ids = array_column( $menus, 'term_id' ); + $ids = array_map( + function($o) { + return $o->term_id; + }, $menus + ); $formatter->display_items( $ids ); } else { $formatter->display_items( $menus ); From 452accdbbeda1faf1d4e1986e14e2af1b3577599 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 28 Jun 2016 17:07:27 -0700 Subject: [PATCH 4637/4858] Fix builds on WordPress trunk Mr WordPress is now some wapuu business --- features/comment.feature | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 0eaacc0048..ad004d4b10 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -71,19 +71,19 @@ Feature: Manage WordPress comments Scenario: Get details about an existing comment When I run `wp comment get 1` Then STDOUT should be a table containing rows: - | Field | Value | - | comment_author | Mr WordPress | + | Field | Value | + | comment_author_url | https://wordpress.org/ | - When I run `wp comment get 1 --fields=comment_author,comment_author_email --format=json` - Then STDOUT should be: + When I run `wp comment get 1 --fields=comment_author_url,comment_author_email --format=json` + Then STDOUT should be JSON containing: """ - {"comment_author":"Mr WordPress","comment_author_email":""} + {"comment_author_url":"https://wordpress.org/","comment_author_email":""} """ - When I run `wp comment list --fields=comment_approved,comment_author` + When I run `wp comment list --fields=comment_approved,comment_author_url` Then STDOUT should be a table containing rows: - | comment_approved | comment_author | - | 1 | Mr WordPress | + | comment_approved | comment_author_url | + | 1 | https://wordpress.org/ | When I run `wp comment list --field=approved` Then STDOUT should be: From b6e4a62d889d9a9f1615d0529ed3d8ad99902180 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 29 Jun 2016 13:40:13 +0545 Subject: [PATCH 4638/4858] Add reset subcommand for widget --- php/commands/widget.php | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/php/commands/widget.php b/php/commands/widget.php index 2ff89be750..0a412e18ec 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -304,6 +304,75 @@ public function delete( $args, $assoc_args ) { WP_CLI::success( "Widget(s) removed from sidebar." ); } + /** + * Reset sidebar. + * + * Removes all widgets from the sidebar and place those to Inactive Widgets. + * + * [<sidebar-id>...] + * : One or more sidebars to reset. + * + * [--all] + * : If set, all sidebars will be reset. + * + * ## EXAMPLES + * + * # Reset a sidebar + * $ wp widget reset sidebar-1 + * Success: Sidebar 'sidebar-1' reset. + * + * # Reset multiple sidebars + * $ wp widget reset sidebar-1 sidebar-2 + * Success: Sidebar 'sidebar-1' reset. + * Success: Sidebar 'sidebar-2' reset. + */ + public function reset( $args, $assoc_args ) { + + global $wp_registered_sidebars; + + $all = \WP_CLI\Utils\get_flag_value( $assoc_args, 'all', false ); + + // Bail if no arguments and no all flag. + if ( ! $all && empty( $args ) ) { + WP_CLI::error( 'Please specify one or more sidebars, or use --all.' ); + } + + // Fetch all sidebars if all flag is set. + if ( $all ) { + $args = array_keys( $wp_registered_sidebars ); + } + + // Sidebar ID wp_inactive_widgets is reserved by WP core for inactive widgets. + if ( isset( $args['wp_inactive_widgets'] ) ) { + unset( $args['wp_inactive_widgets'] ); + } + + // Check if no registered sidebar. + if ( empty( $args ) ) { + WP_CLI::error( 'No sidebar registered.' ); + } + + foreach ( $args as $sidebar_id ) { + if ( ! array_key_exists( $sidebar_id, $wp_registered_sidebars ) ) { + WP_CLI::warning( sprintf( 'Invalid sidebar: %s', $sidebar_id ) ); + continue; + } + + $widgets = $this->get_sidebar_widgets( $sidebar_id ); + if ( empty( $widgets ) ) { + WP_CLI::warning( sprintf( "'%s' is already empty.", $sidebar_id ) ); + } + else { + foreach ( $widgets as $widget ) { + $widget_id = $widget->id; + list( $name, $option_index, $new_sidebar_id, $sidebar_index ) = $this->get_widget_data( $widget_id ); + $this->move_sidebar_widget( $widget_id, $new_sidebar_id, 'wp_inactive_widgets', $sidebar_index, 0 ); + } + WP_CLI::success( sprintf( "Sidebar '%s' reset.", $sidebar_id ) ); + } + } + } + /** * Check whether a sidebar is a valid sidebar * From c7567036d779b36df5111feb5491ed99a25035e6 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 29 Jun 2016 14:05:17 +0545 Subject: [PATCH 4639/4858] Add test for widget reset command --- features/widget-reset.feature | 96 +++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 features/widget-reset.feature diff --git a/features/widget-reset.feature b/features/widget-reset.feature new file mode 100644 index 0000000000..52a042961a --- /dev/null +++ b/features/widget-reset.feature @@ -0,0 +1,96 @@ +Feature: Reset widgets in WordPress sidebar + + Scenario: Reset sidebar + Given a WP install + + When I run `wp theme install twentysixteen --activate` + Then STDOUT should not be empty + + When I run `wp widget list sidebar-1 --format=count` + Then STDOUT should be: + """ + 6 + """ + + When I run `wp widget reset sidebar-1` + And I run `wp widget list sidebar-1 --format=count` + Then STDOUT should be: + """ + 0 + """ + + When I try `wp widget reset` + Then STDERR should be: + """ + Error: Please specify one or more sidebars, or use --all. + """ + + When I try `wp widget reset sidebar-1` + Then STDERR should be: + """ + Warning: 'sidebar-1' is already empty. + """ + + When I try `wp widget reset non-existing-sidebar-id` + Then STDERR should be: + """ + Warning: Invalid sidebar: non-existing-sidebar-id + """ + + When I run `wp widget add calendar sidebar-1 --title="Calendar"` + Then STDOUT should not be empty + And I run `wp widget list sidebar-1 --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp widget add search sidebar-2 --title="Quick Search"` + Then STDOUT should not be empty + And I run `wp widget list sidebar-2 --format=count` + Then STDOUT should be: + """ + 1 + """ + + When I run `wp widget reset sidebar-1 sidebar-2` + And I run `wp widget list sidebar-1 --format=count` + Then STDOUT should be: + """ + 0 + """ + And I run `wp widget list sidebar-2 --format=count` + Then STDOUT should be: + """ + 0 + """ + + Scenario: Reset all sidebars + Given a WP install + + When I run `wp theme install twentysixteen --activate` + Then STDOUT should not be empty + + When I run `wp widget add calendar sidebar-1 --title="Calendar"` + Then STDOUT should not be empty + When I run `wp widget add search sidebar-2 --title="Quick Search"` + Then STDOUT should not be empty + When I run `wp widget add text sidebar-3 --title="Text"` + Then STDOUT should not be empty + + When I run `wp widget reset --all` + And I run `wp widget list sidebar-1 --format=count` + Then STDOUT should be: + """ + 0 + """ + And I run `wp widget list sidebar-2 --format=count` + Then STDOUT should be: + """ + 0 + """ + And I run `wp widget list sidebar-3 --format=count` + Then STDOUT should be: + """ + 0 + """ From 6e886da6eaa44d24a7ae08d26cec5c48afe9e50b Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 29 Jun 2016 14:08:32 +0545 Subject: [PATCH 4640/4858] Add more examples for the command --- features/widget-reset.feature | 2 +- php/commands/widget.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/features/widget-reset.feature b/features/widget-reset.feature index 52a042961a..2a98611757 100644 --- a/features/widget-reset.feature +++ b/features/widget-reset.feature @@ -1,4 +1,4 @@ -Feature: Reset widgets in WordPress sidebar +Feature: Reset WordPress sidebars Scenario: Reset sidebar Given a WP install diff --git a/php/commands/widget.php b/php/commands/widget.php index 0a412e18ec..f401eaea00 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -325,6 +325,12 @@ public function delete( $args, $assoc_args ) { * $ wp widget reset sidebar-1 sidebar-2 * Success: Sidebar 'sidebar-1' reset. * Success: Sidebar 'sidebar-2' reset. + * + * # Reset all sidebars + * $ wp widget reset --all + * Success: Sidebar 'sidebar-1' reset. + * Success: Sidebar 'sidebar-2' reset. + * Success: Sidebar 'sidebar-3' reset. */ public function reset( $args, $assoc_args ) { From 7cfa5f056d6dc0e0e4ffa365798f8dd721134523 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 29 Jun 2016 14:36:33 +0545 Subject: [PATCH 4641/4858] Improve test for widget reset --- features/widget-reset.feature | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/features/widget-reset.feature b/features/widget-reset.feature index 2a98611757..83ddf39d55 100644 --- a/features/widget-reset.feature +++ b/features/widget-reset.feature @@ -94,3 +94,31 @@ Feature: Reset WordPress sidebars """ 0 """ + + Scenario: Testing movement of widgets while reset + Given a WP install + + When I run `wp theme install twentysixteen --activate` + Then STDOUT should not be empty + + When I run `wp widget add calendar sidebar-2 --title="Calendar"` + Then STDOUT should not be empty + And I run `wp widget add search sidebar-2 --title="Quick Search"` + Then STDOUT should not be empty + + When I run `wp widget list sidebar-2 --format=ids` + Then STDOUT should be: + """ + search-3 calendar-1 + """ + When I run `wp widget list wp_inactive_widgets --format=ids` + Then STDOUT should be empty + + When I run `wp widget reset sidebar-2` + And I run `wp widget list sidebar-2 --format=ids` + Then STDOUT should be empty + And I run `wp widget list wp_inactive_widgets --format=ids` + Then STDOUT should be: + """ + calendar-1 search-3 + """ From 703f64bb95258809c1072e73973b4feff7651e28 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 29 Jun 2016 03:20:05 -0700 Subject: [PATCH 4642/4858] Fix tests on all versions of WordPress by limiting the values tested Unfortunately, none of these are the same between WP versions --- features/comment.feature | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index ad004d4b10..62ca6cd249 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -71,19 +71,19 @@ Feature: Manage WordPress comments Scenario: Get details about an existing comment When I run `wp comment get 1` Then STDOUT should be a table containing rows: - | Field | Value | - | comment_author_url | https://wordpress.org/ | + | Field | Value | + | comment_approved | 1 | - When I run `wp comment get 1 --fields=comment_author_url,comment_author_email --format=json` + When I run `wp comment get 1 --fields=comment_approved,comment_author_email --format=json` Then STDOUT should be JSON containing: """ - {"comment_author_url":"https://wordpress.org/","comment_author_email":""} + {"comment_approved":"1","comment_author_email":""} """ - When I run `wp comment list --fields=comment_approved,comment_author_url` + When I run `wp comment list --fields=comment_approved` Then STDOUT should be a table containing rows: - | comment_approved | comment_author_url | - | 1 | https://wordpress.org/ | + | comment_approved | + | 1 | When I run `wp comment list --field=approved` Then STDOUT should be: From e93078e4bfa47b091315635148dd0f76d441cf93 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 29 Jun 2016 16:38:34 +0545 Subject: [PATCH 4643/4858] Resolving issues from the PR review in widget reset --- features/widget-reset.feature | 7 ++++++- php/commands/widget.php | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/features/widget-reset.feature b/features/widget-reset.feature index 83ddf39d55..482bafd5a4 100644 --- a/features/widget-reset.feature +++ b/features/widget-reset.feature @@ -28,7 +28,7 @@ Feature: Reset WordPress sidebars When I try `wp widget reset sidebar-1` Then STDERR should be: """ - Warning: 'sidebar-1' is already empty. + Warning: Sidebar 'sidebar-1' is already empty. """ When I try `wp widget reset non-existing-sidebar-id` @@ -94,6 +94,11 @@ Feature: Reset WordPress sidebars """ 0 """ + When I run `wp widget list wp_inactive_widgets --format=ids` + Then STDOUT should be: + """ + text-1 search-3 meta-2 categories-2 archives-2 recent-comments-2 recent-posts-2 search-2 calendar-1 + """ Scenario: Testing movement of widgets while reset Given a WP install diff --git a/php/commands/widget.php b/php/commands/widget.php index f401eaea00..1def3cb798 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -307,7 +307,7 @@ public function delete( $args, $assoc_args ) { /** * Reset sidebar. * - * Removes all widgets from the sidebar and place those to Inactive Widgets. + * Removes all widgets from the sidebar and places them in Inactive Widgets. * * [<sidebar-id>...] * : One or more sidebars to reset. @@ -366,7 +366,7 @@ public function reset( $args, $assoc_args ) { $widgets = $this->get_sidebar_widgets( $sidebar_id ); if ( empty( $widgets ) ) { - WP_CLI::warning( sprintf( "'%s' is already empty.", $sidebar_id ) ); + WP_CLI::warning( sprintf( "Sidebar '%s' is already empty.", $sidebar_id ) ); } else { foreach ( $widgets as $widget ) { From ff354272a5a938e58ad90334abd9792da2084c7d Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 29 Jun 2016 17:28:36 +0545 Subject: [PATCH 4644/4858] Use Twentytwelve theme in test of widget reset because 2016 wont run in WP 3.7 --- features/widget-reset.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/widget-reset.feature b/features/widget-reset.feature index 482bafd5a4..4c2d84bdcc 100644 --- a/features/widget-reset.feature +++ b/features/widget-reset.feature @@ -3,7 +3,7 @@ Feature: Reset WordPress sidebars Scenario: Reset sidebar Given a WP install - When I run `wp theme install twentysixteen --activate` + When I run `wp theme install twentytwelve --activate` Then STDOUT should not be empty When I run `wp widget list sidebar-1 --format=count` @@ -68,7 +68,7 @@ Feature: Reset WordPress sidebars Scenario: Reset all sidebars Given a WP install - When I run `wp theme install twentysixteen --activate` + When I run `wp theme install twentytwelve --activate` Then STDOUT should not be empty When I run `wp widget add calendar sidebar-1 --title="Calendar"` @@ -103,7 +103,7 @@ Feature: Reset WordPress sidebars Scenario: Testing movement of widgets while reset Given a WP install - When I run `wp theme install twentysixteen --activate` + When I run `wp theme install twentytwelve --activate` Then STDOUT should not be empty When I run `wp widget add calendar sidebar-2 --title="Calendar"` From 6b54065a43b6a1f5950df656a026264553937bcc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 29 Jun 2016 05:07:03 -0700 Subject: [PATCH 4645/4858] This email changed in 4.6 too, so lets ignore it --- features/comment.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/comment.feature b/features/comment.feature index 62ca6cd249..6fcbd88d4d 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -74,10 +74,10 @@ Feature: Manage WordPress comments | Field | Value | | comment_approved | 1 | - When I run `wp comment get 1 --fields=comment_approved,comment_author_email --format=json` + When I run `wp comment get 1 --fields=comment_approved --format=json` Then STDOUT should be JSON containing: """ - {"comment_approved":"1","comment_author_email":""} + {"comment_approved":"1"} """ When I run `wp comment list --fields=comment_approved` From 4a4c0c724b3bf26e16689d08ec0564507845c13f Mon Sep 17 00:00:00 2001 From: roelveldhuizen <roel@inesta.nl> Date: Wed, 29 Jun 2016 17:38:37 +0200 Subject: [PATCH 4646/4858] #3069 resolve --- php/commands/plugin.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index d27ae8ba9f..cd64229fb9 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -335,6 +335,12 @@ function deactivate( $args, $assoc_args = array() ) { deactivate_plugins( $plugin->file, false, $network_wide ); + if (!is_network_admin()) { + update_option('recently_activated', array($plugin->file => time()) + (array)get_option('recently_activated')); + } else { + update_site_option('recently_activated', array($plugin->file => time()) + (array)get_site_option('recently_activated')); + } + $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'uninstall' ) ) { From d8fee49e62593768eb8bbdf999f1c41086a4d10e Mon Sep 17 00:00:00 2001 From: Roel Veldhuizen <roel@inesta.nl> Date: Wed, 29 Jun 2016 21:35:26 +0200 Subject: [PATCH 4647/4858] updated CS --- php/commands/plugin.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index cd64229fb9..7470ac7a8d 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -335,10 +335,12 @@ function deactivate( $args, $assoc_args = array() ) { deactivate_plugins( $plugin->file, false, $network_wide ); - if (!is_network_admin()) { - update_option('recently_activated', array($plugin->file => time()) + (array)get_option('recently_activated')); + if ( ! is_network_admin() ) { + update_option('recently_activated', + array($plugin->file => time()) + (array)get_option('recently_activated')); } else { - update_site_option('recently_activated', array($plugin->file => time()) + (array)get_site_option('recently_activated')); + update_site_option('recently_activated', + array($plugin->file => time()) + (array)get_site_option('recently_activated')); } $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); From 61eab12d4de5e056c36320d2f117d6fc11d39836 Mon Sep 17 00:00:00 2001 From: Roel Veldhuizen <roel@inesta.nl> Date: Wed, 29 Jun 2016 21:37:02 +0200 Subject: [PATCH 4648/4858] updated CS --- php/commands/plugin.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 7470ac7a8d..701a910a03 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -336,11 +336,11 @@ function deactivate( $args, $assoc_args = array() ) { deactivate_plugins( $plugin->file, false, $network_wide ); if ( ! is_network_admin() ) { - update_option('recently_activated', - array($plugin->file => time()) + (array)get_option('recently_activated')); + update_option( 'recently_activated', + array( $plugin->file => time() ) + (array) get_option('recently_activated') ); } else { - update_site_option('recently_activated', - array($plugin->file => time()) + (array)get_site_option('recently_activated')); + update_site_option( 'recently_activated', + array( $plugin->file => time() ) + (array) get_site_option('recently_activated') ); } $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); From 5834bac3b25fe1f88de9e7926bb137139e714b7c Mon Sep 17 00:00:00 2001 From: Roel Veldhuizen <roel@inesta.nl> Date: Wed, 29 Jun 2016 22:01:11 +0200 Subject: [PATCH 4649/4858] updated CS --- php/commands/plugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 701a910a03..608c261298 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -337,10 +337,10 @@ function deactivate( $args, $assoc_args = array() ) { if ( ! is_network_admin() ) { update_option( 'recently_activated', - array( $plugin->file => time() ) + (array) get_option('recently_activated') ); + array( $plugin->file => time() ) + (array) get_option( 'recently_activated' ) ); } else { update_site_option( 'recently_activated', - array( $plugin->file => time() ) + (array) get_site_option('recently_activated') ); + array( $plugin->file => time() ) + (array) get_site_option( 'recently_activated' ) ); } $this->active_output( $plugin->name, $plugin->file, $network_wide, "deactivate" ); From 81b3ab60423f4ed81178cddaa354c8af45d722ff Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 29 Jun 2016 16:14:09 -0700 Subject: [PATCH 4650/4858] Mention `wp cli update --nightly` in INSTALLING section --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4349354b2b..1be31ccddb 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,8 @@ WP-CLI version: 0.23.0 You can update WP-CLI with `wp cli update` ([doc](https://wp-cli.org/commands/cli/update/)), or by repeating the installation steps. +Want to live life on the edge? Run `wp cli update --nightly` to use the latest nightly build of WP-CLI. The nightly build is more or less stable enough for you to use in your development environment, and always includes the latest and greatest WP-CLI features. + ## Support WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: From 982fd5438fe569a07d1c239400e00a3fedae1e60 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 29 Jun 2016 16:33:53 -0700 Subject: [PATCH 4651/4858] Mention internal API docs in extending See https://github.com/Nikschavan/revslider-search-replace/issues/2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1be31ccddb..993bc8d748 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ If you have a WordPress.org account, you may also consider joining the `#cli` ch A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another. -WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. +WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](http://wp-cli.org/docs/internal-api/) to discovery a variety of helpful functions you can use in your custom WP-CLI command. ## Contributing From 9206d222312d4a6974698d83767aaa77bdf67d2c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 30 Jun 2016 04:42:00 -0700 Subject: [PATCH 4652/4858] Fix indentation on the test --- features/plugin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/plugin.feature b/features/plugin.feature index 21efa3181d..1bbecf2bd0 100644 --- a/features/plugin.feature +++ b/features/plugin.feature @@ -76,7 +76,7 @@ Feature: Manage WordPress plugins When I run `wp option get recently_activated` Then STDOUT should contain: """ - Zombieland/Zombieland.php + Zombieland/Zombieland.php """ When I run `wp plugin uninstall Zombieland` From c4ecf7297f4cb3c5c27e4f062e099628f3c26f82 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 30 Jun 2016 17:29:40 +0545 Subject: [PATCH 4653/4858] Improve doc and message in site commands --- php/commands/site.php | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index d2971c588a..fd553e66f8 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -16,8 +16,8 @@ * * # Delete site * $ wp site delete 123 - * Are you sure you want to delete the http://www.example.com/example site? [y/n] y - * Success: The site at http://www.example.com/example was deleted. + * Are you sure you want to delete the 'http://www.example.com/example' site? [y/n] y + * Success: The site at 'http://www.example.com/example' was deleted. * * @package wp-cli */ @@ -163,7 +163,7 @@ private function _insert_default_terms() { * * $ wp site empty * Are you sure you want to empty the site at http://www.example.com of all posts, comments, and terms? [y/n] y - * Success: The site at http://www.example.com was emptied. + * Success: The site at 'http://www.example.com' was emptied. * * @subcommand empty */ @@ -174,7 +174,7 @@ public function _empty( $args, $assoc_args ) { $upload_message = ', and delete its uploads directory'; } - WP_CLI::confirm( 'Are you sure you want to empty the site at ' . site_url() . ' of all posts, comments, and terms' . $upload_message . '?', $assoc_args ); + WP_CLI::confirm( "Are you sure you want to empty the site at '" . site_url() . "' of all posts, comments, and terms" . $upload_message . "?", $assoc_args ); $this->_empty_posts(); $this->_empty_comments(); @@ -200,7 +200,7 @@ public function _empty( $args, $assoc_args ) { rmdir( $upload_dir['basedir'] ); } - WP_CLI::success( 'The site at ' . site_url() . ' was emptied.' ); + WP_CLI::success( "The site at '" . site_url() . "' was emptied." ); } /** @@ -224,7 +224,7 @@ public function _empty( $args, $assoc_args ) { * * $ wp site delete 123 * Are you sure you want to delete the http://www.example.com/example site? [y/n] y - * Success: The site at http://www.example.com/example was deleted. + * Success: The site at 'http://www.example.com/example' was deleted. */ function delete( $args, $assoc_args ) { if ( !is_multisite() ) { @@ -247,11 +247,11 @@ function delete( $args, $assoc_args ) { WP_CLI::error( "Site not found." ); } - WP_CLI::confirm( "Are you sure you want to delete the $blog->siteurl site?", $assoc_args ); + WP_CLI::confirm( "Are you sure you want to delete the '$blog->siteurl' site?", $assoc_args ); wpmu_delete_blog( $blog->blog_id, ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'keep-tables' ) ); - WP_CLI::success( "The site at $blog->siteurl was deleted." ); + WP_CLI::success( "The site at '$blog->siteurl' was deleted." ); } /** @@ -420,7 +420,16 @@ private function _get_network( $network_id ) { * : Comma-separated list of fields to show. * * [--format=<format>] - * : Accepted values: table, csv, json, count, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - count + * - json + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -645,4 +654,3 @@ private function update_site_status( $ids, $pref, $value ) { } WP_CLI::add_command( 'site', 'Site_Command' ); - From cbc1e9cb4916bfb602b59226113416b862076156 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 30 Jun 2016 05:19:44 -0700 Subject: [PATCH 4654/4858] Ignore a few more files in the default `.distignore` --- templates/plugin-distignore.mustache | 4 ++++ templates/plugin-gitignore.mustache | 1 + 2 files changed, 5 insertions(+) diff --git a/templates/plugin-distignore.mustache b/templates/plugin-distignore.mustache index 36a11a63f7..79706582af 100644 --- a/templates/plugin-distignore.mustache +++ b/templates/plugin-distignore.mustache @@ -4,13 +4,17 @@ .git .gitignore .travis.yml +.DS_Store +Thumbs.db bin composer.json composer.lock Gruntfile.js package.json phpunit.xml +multisite.xml phpunit.xml.dist +phpcs.ruleset.xml README.md wp-cli.local.yml tests diff --git a/templates/plugin-gitignore.mustache b/templates/plugin-gitignore.mustache index d4a5405531..20830a4a02 100644 --- a/templates/plugin-gitignore.mustache +++ b/templates/plugin-gitignore.mustache @@ -1,3 +1,4 @@ .DS_Store +Thumbs.db wp-cli.local.yml node_modules/ From 8dd9dcf07e36eae6b576908bd577224425545dcf Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 30 Jun 2016 21:24:12 +0900 Subject: [PATCH 4655/4858] fix missing param in example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 993bc8d748..27a62664dc 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Quick links: [Using](#using) | [Installing](#installing) | [Support](# ## Using -WP-CLI's goal is to provide a command-line interface for any action you might want to perform in the WordPress admin. For instance, `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: +WP-CLI's goal is to provide a command-line interface for any action you might want to perform in the WordPress admin. For instance, `wp plugin install --activate` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: ``` $ wp plugin install rest-api --activate From ebc763e52beb2062d92202f4fa37149b8f55c72d Mon Sep 17 00:00:00 2001 From: Rachel Baker <rachel@rachelbaker.me> Date: Thu, 30 Jun 2016 22:24:59 -0500 Subject: [PATCH 4656/4858] Update cli settings to include new files from WP 4.6 beta. Includes class-wp-network-query.php and class-wp-post-type.php files conditionally. --- php/wp-settings-cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/wp-settings-cli.php b/php/wp-settings-cli.php index 1554221a8d..ab284d58b7 100644 --- a/php/wp-settings-cli.php +++ b/php/wp-settings-cli.php @@ -141,6 +141,7 @@ // Initialize multisite if enabled. if ( is_multisite() ) { Utils\maybe_require( '4.6-alpha-37575', ABSPATH . WPINC . '/class-wp-site-query.php' ); + Utils\maybe_require( '4.6-alpha-37896', ABSPATH . WPINC . '/class-wp-network-query.php' ); require( ABSPATH . WPINC . '/ms-blogs.php' ); require( ABSPATH . WPINC . '/ms-settings.php' ); } elseif ( ! defined( 'MULTISITE' ) ) { @@ -187,6 +188,7 @@ require( ABSPATH . WPINC . '/post.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-page.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-walker-page-dropdown.php' ); +Utils\maybe_require( '4.6-alpha-37890', ABSPATH . WPINC . '/class-wp-post-type.php' ); Utils\maybe_require( '4.4-beta4-35719', ABSPATH . WPINC . '/class-wp-post.php' ); require( ABSPATH . WPINC . '/post-template.php' ); Utils\maybe_require( '3.6-alpha-23451', ABSPATH . WPINC . '/revision.php' ); From 9f37cd366d2c018bcc4c8b86788a55cb3f27891f Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 1 Jul 2016 09:48:30 +0545 Subject: [PATCH 4657/4858] Fix grammar in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 27a62664dc..f895828c8a 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ If you have a WordPress.org account, you may also consider joining the `#cli` ch A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another. -WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](http://wp-cli.org/docs/internal-api/) to discovery a variety of helpful functions you can use in your custom WP-CLI command. +WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](http://wp-cli.org/docs/internal-api/) to discover a variety of helpful functions you can use in your custom WP-CLI command. ## Contributing From b6fb9f35b08bf40a72cb06f7ccf043b3cfd81fd2 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 1 Jul 2016 13:14:18 +0545 Subject: [PATCH 4658/4858] Improving test for site commands --- features/site-empty.feature | 20 ++++++++++++++++---- features/site.feature | 23 ++++++++++++++++------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/features/site-empty.feature b/features/site-empty.feature index 873dfdb22b..2f5e49b80e 100644 --- a/features/site-empty.feature +++ b/features/site-empty.feature @@ -17,13 +17,22 @@ Feature: Empty a WordPress site of its data """ When I run `wp post create --post_title='Test post' --post_content='Test content.' --porcelain` - Then STDOUT should not be empty + Then STDOUT should be: + """ + 4 + """ When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term'` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: Created post_tag 2. + """ When I run `wp site empty --yes` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: The site at 'http://example.com' was emptied. + """ And the wp-content/uploads/large-image.jpg file should exist When I run `wp post list --format=ids` @@ -51,7 +60,10 @@ Feature: Empty a WordPress site of its data Then STDOUT should be empty When I run `wp --url=example.com/foo site empty --uploads --yes` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: The site at 'http://example.com/foo' was emptied. + """ And the wp-content/uploads/sites/2/large-image.jpg file should not exist When I run `wp --url=example.com/foo post list --format=ids` diff --git a/features/site.feature b/features/site.feature index 42c29ab520..46f5d9fa6c 100644 --- a/features/site.feature +++ b/features/site.feature @@ -2,7 +2,7 @@ Feature: Manage sites in a multisite installation Scenario: Create a site Given a WP multisite install - + When I try `wp site create --slug=first --network_id=1000` Then STDERR should contain: """ @@ -48,7 +48,10 @@ Feature: Manage sites in a multisite installation """ When I run `wp site delete {SITE_ID} --yes` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: The site at 'http://example.com/first' was deleted. + """ When I try the previous command again Then the return code should be 1 @@ -76,21 +79,27 @@ Feature: Manage sites in a multisite installation Given a WP multisite install When I run `wp site create --slug=first` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: Site 2 created: example.com/first/ + """ When I run `wp site delete --slug=first --yes` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: The site at 'http://example.com/first' was deleted. + """ When I try the previous command again Then the return code should be 1 Scenario: Get site info Given a WP multisite install - + When I run `wp site create --slug=first --porcelain` Then STDOUT should be a number And save STDOUT as {SITE_ID} - + When I run `wp site url {SITE_ID}` Then STDOUT should be: """ @@ -152,7 +161,7 @@ Feature: Manage sites in a multisite installation | blog_id | archived | | {FIRST_SITE} | 0 | - When I run `wp site archive 1` + When I try `wp site archive 1` Then STDERR should be: """ Warning: You are not allowed to change the main site. From 8ad8999af5fd6ba3617619d3406dd3ebe69f35c2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Jul 2016 03:49:59 -0700 Subject: [PATCH 4659/4858] Update tests for cbc1e9cb4916bfb602b59226113416b862076156 --- features/scaffold.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/scaffold.feature b/features/scaffold.feature index 48409fb286..733841eef7 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -155,6 +155,7 @@ Feature: WordPress code scaffolding And the {PLUGIN_DIR}/hello-world/.gitignore file should contain: """ .DS_Store + Thumbs.db wp-cli.local.yml node_modules/ """ From 7cbdcd5f99195bbb0d32abad55f7b8c10892ac4d Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 1 Jul 2016 17:40:07 +0545 Subject: [PATCH 4660/4858] Allow ids value in format parameter in site list --- php/commands/site.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index fd553e66f8..2ad634bfdb 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -427,6 +427,7 @@ private function _get_network( $network_id ) { * - table * - csv * - count + * - ids * - json * - yaml * --- @@ -509,8 +510,16 @@ public function list_( $_, $assoc_args ) { return $blog; } ); - $formatter = new \WP_CLI\Formatter( $assoc_args, null, 'site' ); - $formatter->display_items( $it ); + if ( ! empty( $assoc_args['format'] ) && 'ids' === $assoc_args['format'] ) { + $sites = iterator_to_array( $it ); + $ids = wp_list_pluck( $sites, 'blog_id' ); + $formatter = new \WP_CLI\Formatter( $assoc_args, null, 'site' ); + $formatter->display_items( $ids ); + } + else { + $formatter = new \WP_CLI\Formatter( $assoc_args, null, 'site' ); + $formatter->display_items( $it ); + } } /** From 43a6712ba0dbe77f3f8badb4eb74f3ff1d997e56 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 1 Jul 2016 17:40:31 +0545 Subject: [PATCH 4661/4858] Add test for ids value in format parameter in site list --- features/site.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/site.feature b/features/site.feature index 46f5d9fa6c..506c679468 100644 --- a/features/site.feature +++ b/features/site.feature @@ -21,6 +21,12 @@ Feature: Manage sites in a multisite installation | 1 | http://example.com/ | | 2 | http://first.example.com/ | + When I run `wp site list --format=ids` + Then STDOUT should be: + """ + 1 2 + """ + When I run `wp --url=first.example.com option get home` Then STDOUT should be: """ From 0898cbb6bbda238574ada292397c2c35a5241ebc Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Fri, 1 Jul 2016 18:21:54 +0200 Subject: [PATCH 4662/4858] Remove unsupported ids output of menu locations #3083 Menu locations doesn't have ids, so they can't be outputted --- php/commands/menu.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 2ee9527363..7302f1efe9 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -731,7 +731,6 @@ class Menu_Location_Command extends WP_CLI_Command { * - csv * - json * - count - * - ids * - yaml * --- * From 24e185e1642e0e93f140175578a1a420f6502e4a Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Jul 2016 15:04:20 -0700 Subject: [PATCH 4663/4858] Introduce `wp cli alias` for listing available aliases --- features/aliases.feature | 21 +++++++++++++++++++++ php/commands/cli.php | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/features/aliases.feature b/features/aliases.feature index 1985a977dd..27bf71ba84 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -96,6 +96,27 @@ Feature: Create shortcuts to specific WordPress installs """ And STDERR should be empty + Scenario: List available aliases + Given an empty directory + And a wp-cli.yml file: + """ + @testdir: + path: testdir + """ + + When I run `wp cli alias` + Then STDOUT should be YAML containing: + """ + @testdir: + path: testdir + """ + + When I run `wp cli alias --format=json` + Then STDOUT should be JSON containing: + """ + {"@testdir":{"path":"testdir"}} + """ + Scenario: Defining a project alias completely overrides a global alias Given a WP install in 'testdir' And a config.yml file: diff --git a/php/commands/cli.php b/php/commands/cli.php index 3e33904fa2..5d0d0b31a3 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -457,6 +457,29 @@ public function completions( $_, $assoc_args ) { $compl->render(); } + /** + * List available aliases. + * + * Aliases are shorthand references to WordPress installs. For instance, + * '@dev' could refer to a development install and '@prod' could refer to + * a production install. This command gives you visibility in what + * registered aliases you have available. + * + * ## OPTIONS + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: yaml + * options: + * - yaml + * - json + * --- + */ + public function alias( $_, $assoc_args ) { + WP_CLI::print_value( WP_CLI::get_runner()->aliases, $assoc_args ); + } + /** * Get a string representing the type of update being checked for */ From 5b47ca11a19daa0b6d39e33690cddfbb089dceb8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Jul 2016 15:59:18 -0700 Subject: [PATCH 4664/4858] Improve our CONTRIBUTING.md with greater detail --- CONTRIBUTING.md | 32 ++++++++++++++++++++++++++++---- README.md | 16 +++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e6bb879c56..d6e523ee9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,30 @@ -Contribute -========== +Contributing +============ -Thanks in advance for helping to improve WP-CLI. +Welcome and thanks! -To get started, please review our documentation on [creating an issue](http://wp-cli.org/docs/bug-reports/) or [submitting a pull request](http://wp-cli.org/docs/pull-requests/). +We appreciate you taking the initiative to contribute to WP-CLI. It’s because of you, and the community around you, that WP-CLI is such a great project. + +**Contributing isn’t limited to just code.** We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation. + +Please take a moment to read these guidelines at depth. Following the guidelines helps to communicate that you respect the time of the other contributors to the project. In turn, they’ll do their best to reciprocate that respect when working with you, across timezones and around the world. + +### Reporting a bug + +Think you’ve found a bug? We’d love for you to help us get it fixed. + +Before you create a new issue, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI. You should also check our [documentation on common issues and their fixes](https://wp-cli.org/docs/common-issues/). + +Once you’ve done a bit of searching and discovered there isn’t an open or fixed issue for your bug, please [follow our guidelines for submitting a bug report](http://wp-cli.org/docs/bug-reports/) to make sure it gets addressed in a timely manner. + +### Creating a pull request + +Want to contribute a new feature? WP-CLI is a mature project, and already chock-full of useful functionality. Please first [open a new issue](https://github.com/wp-cli/wp-cli/issues/new) to discuss whether the feature is a good fit for WP-CLI core, or might be better suited as a [community package](https://wp-cli.org/package-index/). + +Once you've decided to commit the time to seeing your pull request through, please [follow our guidelines for creating a pull request](https://wp-cli.org/docs/pull-requests/) to make sure it's a pleasant experience. + +### Contributing in other ways + +Feel free to [create an issue](https://github.com/wp-cli/wp-cli/issues/new) with your question, and we'll see if we can find an answer for it. + +Alternatively, if you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). diff --git a/README.md b/README.md index f895828c8a..6319172181 100644 --- a/README.md +++ b/README.md @@ -103,19 +103,29 @@ WP-CLI's maintainers and project contributors do their best to respond to all ne - [Open or closed issues on Github](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=is%3Aissue) - [WordPress StackExchange forums](http://wordpress.stackexchange.com/questions/tagged/wp-cli) +If you can't find your answer in one of those existing resources, feel free to [create an issue](https://github.com/wp-cli/wp-cli/issues/new) with your question. + If you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). ## Extending A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another. -WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](http://wp-cli.org/docs/internal-api/) to discover a variety of helpful functions you can use in your custom WP-CLI command. +WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](https://wp-cli.org/docs/internal-api/) to discover a variety of helpful functions you can use in your custom WP-CLI command. ## Contributing -To get involved, please first read about [creating an issue](https://wp-cli.org/docs/bug-reports/) or [submitting a pull request](https://wp-cli.org/docs/pull-requests/). +Welcome and thanks! + +We appreciate you taking the initiative to contribute to WP-CLI. It’s because of you, and the community around you, that WP-CLI is such a great project. + +**Contributing isn’t limited to just code.** We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation. + +Please take a moment to [read these guidelines at depth](https://wp-cli.org/docs/contributing/). Following them helps to communicate that you respect the time of the other contributors to the project. In turn, they’ll do their best to reciprocate that respect when working with you, across timezones and around the world. + +## Leadership -### Leadership +WP-CLI is led by these individuals: * [Daniel Bachhuber](https://github.com/danielbachhuber/) - current maintainer * [Cristi Burcă](https://github.com/scribu) - previous maintainer From 2c2bdd3c69950539c1ec34c08b91e1a096d07444 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 1 Jul 2016 16:23:24 -0700 Subject: [PATCH 4665/4858] Update Composer dependencies to latest ``` Loading composer repositories with package information Updating dependencies (including require-dev) - Removing wp-cli/php-cli-tools (v0.11.1) - Installing wp-cli/php-cli-tools (dev-master 10cfa5b) Cloning 10cfa5bd978889c8050cd48d70d179d775c31827 - Removing symfony/yaml (v2.8.7) - Installing symfony/yaml (v2.8.8) Downloading: 100% - Removing symfony/filesystem (v2.8.7) - Installing symfony/filesystem (v2.8.8) Downloading: 100% - Removing symfony/config (v2.8.7) - Installing symfony/config (v2.8.8) Downloading: 100% - Removing symfony/dependency-injection (v2.8.7) - Installing symfony/dependency-injection (v2.8.8) Downloading: 100% - Removing symfony/event-dispatcher (v2.8.7) - Installing symfony/event-dispatcher (v2.8.8) Downloading: 100% - Removing symfony/translation (v2.8.7) - Installing symfony/translation (v2.8.8) Downloading: 100% - Removing symfony/process (v2.8.7) - Installing symfony/process (v2.8.8) Downloading: 100% - Removing symfony/finder (v2.8.7) - Installing symfony/finder (v2.8.8) Downloading: 100% - Removing symfony/console (v2.8.7) - Installing symfony/console (v2.8.8) Downloading: 100% - Removing composer/composer (1.1.2) - Installing composer/composer (1.1.3) Downloading: 100% Writing lock file Generating autoload files ``` --- composer.json | 2 +- composer.lock | 118 +++++++++++++++++++++++++------------------------- 2 files changed, 61 insertions(+), 59 deletions(-) diff --git a/composer.json b/composer.json index 8b2590b798..9fabb1b8d7 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.29", - "wp-cli/php-cli-tools": "~0.11.1", + "wp-cli/php-cli-tools": "dev-master", "mustache/mustache": "~2.4", "mustangostang/spyc": "~0.5", "composer/semver": "~1.0", diff --git a/composer.lock b/composer.lock index ab7cf9aaa2..a037758129 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "f0bf52c59aa6e9fe44d6a611f8006a52", - "content-hash": "10cf19699e3fed767e31e1493a07c8f0", + "hash": "38e11e275b2087dfb61f50d258712aef", + "content-hash": "a55b968d0d6754da376a5151b4222cbb", "packages": [ { "name": "composer/ca-bundle", @@ -64,16 +64,16 @@ }, { "name": "composer/composer", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "b2cf67b1a575d7e648c742be2454339232ef32b2" + "reference": "30ab6f1c1753267d181839142fafe022313c3c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/b2cf67b1a575d7e648c742be2454339232ef32b2", - "reference": "b2cf67b1a575d7e648c742be2454339232ef32b2", + "url": "https://api.github.com/repos/composer/composer/zipball/30ab6f1c1753267d181839142fafe022313c3c9a", + "reference": "30ab6f1c1753267d181839142fafe022313c3c9a", "shasum": "" }, "require": { @@ -137,7 +137,7 @@ "dependency", "package" ], - "time": "2016-05-31 18:48:12" + "time": "2016-06-26 14:42:08" }, { "name": "composer/semver", @@ -734,16 +734,16 @@ }, { "name": "symfony/config", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a2edd59c2163c65747fc3f35d132b5a39266bd05" + "reference": "0926e69411eba491803dbafb9f1f233e2ced58d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a2edd59c2163c65747fc3f35d132b5a39266bd05", - "reference": "a2edd59c2163c65747fc3f35d132b5a39266bd05", + "url": "https://api.github.com/repos/symfony/config/zipball/0926e69411eba491803dbafb9f1f233e2ced58d0", + "reference": "0926e69411eba491803dbafb9f1f233e2ced58d0", "shasum": "" }, "require": { @@ -783,20 +783,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:31:50" }, { "name": "symfony/console", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3" + "reference": "c392a6ec72f2122748032c2ad6870420561ffcfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3", - "reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3", + "url": "https://api.github.com/repos/symfony/console/zipball/c392a6ec72f2122748032c2ad6870420561ffcfa", + "reference": "c392a6ec72f2122748032c2ad6870420561ffcfa", "shasum": "" }, "require": { @@ -843,20 +843,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-06-06 15:06:25" + "time": "2016-06-29 07:02:14" }, { "name": "symfony/dependency-injection", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "2d05009d890cf1139988ff059b5b2e0eb280ed13" + "reference": "2dd85de8216079d1360b2b14988cd5cdbbb49063" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2d05009d890cf1139988ff059b5b2e0eb280ed13", - "reference": "2d05009d890cf1139988ff059b5b2e0eb280ed13", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2dd85de8216079d1360b2b14988cd5cdbbb49063", + "reference": "2dd85de8216079d1360b2b14988cd5cdbbb49063", "shasum": "" }, "require": { @@ -906,20 +906,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:31:50" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "2a6b8713f8bdb582058cfda463527f195b066110" + "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2a6b8713f8bdb582058cfda463527f195b066110", - "reference": "2a6b8713f8bdb582058cfda463527f195b066110", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b180b70439dca70049b6b9b7e21d75e6e5d7aca9", + "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9", "shasum": "" }, "require": { @@ -966,20 +966,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:29:29" }, { "name": "symfony/filesystem", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "dee379131dceed90a429e951546b33edfe7dccbb" + "reference": "7258ddd6f987053f21fa43d03430580ba54e6096" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/dee379131dceed90a429e951546b33edfe7dccbb", - "reference": "dee379131dceed90a429e951546b33edfe7dccbb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7258ddd6f987053f21fa43d03430580ba54e6096", + "reference": "7258ddd6f987053f21fa43d03430580ba54e6096", "shasum": "" }, "require": { @@ -1015,20 +1015,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-04-12 18:01:21" + "time": "2016-06-29 05:31:50" }, { "name": "symfony/finder", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "3ec095fab1800222732ca522a95dce8fa124007b" + "reference": "bf0506ef4e7778fd3f0f1f141ab5e8c1ef35dd7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/3ec095fab1800222732ca522a95dce8fa124007b", - "reference": "3ec095fab1800222732ca522a95dce8fa124007b", + "url": "https://api.github.com/repos/symfony/finder/zipball/bf0506ef4e7778fd3f0f1f141ab5e8c1ef35dd7d", + "reference": "bf0506ef4e7778fd3f0f1f141ab5e8c1ef35dd7d", "shasum": "" }, "require": { @@ -1064,7 +1064,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:29:29" }, { "name": "symfony/polyfill-mbstring", @@ -1127,16 +1127,16 @@ }, { "name": "symfony/process", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "115347d00c342198cdc52a7bd8bc15b5ab43500c" + "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/115347d00c342198cdc52a7bd8bc15b5ab43500c", - "reference": "115347d00c342198cdc52a7bd8bc15b5ab43500c", + "url": "https://api.github.com/repos/symfony/process/zipball/89f33c16796415ccfd8bb3cf8d520cbb79899bfe", + "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe", "shasum": "" }, "require": { @@ -1172,20 +1172,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:29:29" }, { "name": "symfony/translation", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1" + "reference": "00334ef0b9317e5d7c7641a2b56671a1df23b7a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1", - "reference": "8a1648d2e165ba87c759ba57d7f4c13d95fdf4a1", + "url": "https://api.github.com/repos/symfony/translation/zipball/00334ef0b9317e5d7c7641a2b56671a1df23b7a0", + "reference": "00334ef0b9317e5d7c7641a2b56671a1df23b7a0", "shasum": "" }, "require": { @@ -1236,20 +1236,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:29:29" }, { "name": "symfony/yaml", - "version": "v2.8.7", + "version": "v2.8.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "815fabf3f48c7d1df345a69d1ad1a88f59757b34" + "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/815fabf3f48c7d1df345a69d1ad1a88f59757b34", - "reference": "815fabf3f48c7d1df345a69d1ad1a88f59757b34", + "url": "https://api.github.com/repos/symfony/yaml/zipball/dba4bb5846798cd12f32e2d8f3f35d77045773c8", + "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8", "shasum": "" }, "require": { @@ -1285,20 +1285,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-06-06 11:11:27" + "time": "2016-06-29 05:29:29" }, { "name": "wp-cli/php-cli-tools", - "version": "v0.11.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "5311a4b99103c0505db015a334be4952654d6e21" + "reference": "10cfa5bd978889c8050cd48d70d179d775c31827" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/5311a4b99103c0505db015a334be4952654d6e21", - "reference": "5311a4b99103c0505db015a334be4952654d6e21", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/10cfa5bd978889c8050cd48d70d179d775c31827", + "reference": "10cfa5bd978889c8050cd48d70d179d775c31827", "shasum": "" }, "require": { @@ -1335,7 +1335,7 @@ "cli", "console" ], - "time": "2016-02-08 14:34:01" + "time": "2016-03-30 11:55:36" } ], "packages-dev": [ @@ -1830,7 +1830,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "wp-cli/php-cli-tools": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From 71593a806d03c637b6a2dd36009593f5544bd868 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 2 Jul 2016 12:36:35 +0545 Subject: [PATCH 4666/4858] Improving doc and message in scaffold commands --- php/commands/scaffold.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 795a284691..30a2da1d68 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -34,7 +34,7 @@ class Scaffold_Command extends WP_CLI_Command { * : The internal name of the post type. * * [--label=<label>] - * : The text used to translate the update messages + * : The text used to translate the update messages. * * [--textdomain=<textdomain>] * : The textdomain to use for the labels. @@ -58,7 +58,7 @@ class Scaffold_Command extends WP_CLI_Command { * ## EXAMPLES * * $ wp scaffold post-type movie --label=Movie --theme=simple-life - * Success: Created /var/www/example.com/public_html/wp-content/themes/simple-life/post-types/movie.php + * Success: Created '/var/www/example.com/public_html/wp-content/themes/simple-life/post-types/movie.php'. * * @subcommand post-type * @@ -184,8 +184,8 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) $files_written = $this->create_files( array( $filename => $final_output ), $force ); $this->log_whether_files_written( $files_written, - $skip_message = "Skipped creating $filename", - $success_message = "Created $filename" + $skip_message = "Skipped creating '$filename'.", + $success_message = "Created '$filename'." ); } else { @@ -209,16 +209,16 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * : Enable the newly downloaded theme for the entire network. * * [--theme_name=<title>] - * : What to put in the 'Theme Name:' header in style.css + * : What to put in the 'Theme Name:' header in 'style.css'. * * [--author=<full-name>] - * : What to put in the 'Author:' header in style.css + * : What to put in the 'Author:' header in 'style.css'. * * [--author_uri=<uri>] - * : What to put in the 'Author URI:' header in style.css + * : What to put in the 'Author URI:' header in 'style.css'. * * [--sassify] - * : Include stylesheets as SASS + * : Include stylesheets as SASS. * * [--force] * : Overwrite files that already exist. @@ -309,19 +309,19 @@ function _s( $args, $assoc_args ) { * : The slug for the new child theme. * * --parent_theme=<slug> - * : What to put in the 'Template:' header in style.css + * : What to put in the 'Template:' header in 'style.css'. * * [--theme_name=<title>] - * : What to put in the 'Theme Name:' header in style.css + * : What to put in the 'Theme Name:' header in 'style.css'. * * [--author=<full-name>] - * : What to put in the 'Author:' header in style.css + * : What to put in the 'Author:' header in 'style.css'. * * [--author_uri=<uri>] - * : What to put in the 'Author URI:' header in style.css + * : What to put in the 'Author URI:' header in 'style.css'. * * [--theme_uri=<uri>] - * : What to put in the 'Theme URI:' header in style.css + * : What to put in the 'Theme URI:' header in 'style.css'. * * [--activate] * : Activate the newly created child theme. @@ -335,7 +335,7 @@ function _s( $args, $assoc_args ) { * ## EXAMPLES * * $ wp scaffold child-theme sample-theme --parent_theme=twentysixteen - * Success: Created /var/www/example.com/public_html/wp-content/themes/sample-theme. + * Success: Created '/var/www/example.com/public_html/wp-content/themes/sample-theme'. * * @subcommand child-theme */ @@ -367,7 +367,7 @@ function child_theme( $args, $assoc_args ) { $this->log_whether_files_written( $files_written, $skip_message = 'All theme files were skipped.', - $success_message = "Created $theme_dir." + $success_message = "Created '$theme_dir'." ); if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'activate' ) ) { @@ -412,7 +412,7 @@ private function get_output_path( $assoc_args, $subdir ) { * : Put the new plugin in some arbitrary directory path. Plugin directory will be path plus supplied slug. * * [--plugin_name=<title>] - * : What to put in the 'Plugin Name:' header + * : What to put in the 'Plugin Name:' header. * * [--plugin_description=<description>] * : What to put in the 'Description:' header. @@ -617,7 +617,7 @@ function plugin_tests( $args, $assoc_args ) { $wp_filesystem->copy( WP_CLI_ROOT . "/templates/$file", $file_name, true ); if ( 'install-wp-tests.sh' === $file ) { if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { - WP_CLI::warning( "Couldn't mark install-wp-tests.sh as executable." ); + WP_CLI::warning( "Couldn't mark 'install-wp-tests.sh' as executable." ); } } } @@ -655,7 +655,7 @@ private function prompt_if_files_will_be_overwritten( $filename, $force ) { return true; } - WP_CLI::warning( 'File already exists' ); + WP_CLI::warning( 'File already exists.' ); WP_CLI::log( $filename ); if ( ! $force ) { do { From 1463486b110df537056d1c5283f504c9bc109b3b Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 2 Jul 2016 12:47:28 +0545 Subject: [PATCH 4667/4858] Improving test for scaffold commands --- features/scaffold.feature | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index 733841eef7..8c0e6f661b 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -7,9 +7,12 @@ Feature: WordPress code scaffolding And save STDOUT as {THEME_DIR} When I run `wp scaffold child-theme zombieland --parent_theme=umbrella --theme_name=Zombieland --author=Tallahassee --author_uri=http://www.wp-cli.org --theme_uri=http://www.zombieland.com` - Then STDOUT should not be empty - And the {THEME_DIR}/zombieland/style.css file should exist + Then the {THEME_DIR}/zombieland/style.css file should exist And the {THEME_DIR}/zombieland/functions.php file should exist + And STDOUT should be: + """ + Success: Created '{THEME_DIR}/zombieland'. + """ Scenario: Scaffold a child theme with only --parent_theme parameter Given a WP install @@ -62,6 +65,25 @@ Feature: WordPress code scaffolding When I run `wp scaffold post-type zombie --theme` Then the {STYLESHEETPATH}/post-types/zombie.php file should exist + And STDOUT should be: + """ + Success: Created '{STYLESHEETPATH}/post-types/zombie.php'. + """ + + When I run `wp scaffold post-type zombie` + Then STDOUT should contain: + """ + register_post_type( 'zombie' + """ + And STDOUT should contain: + """ + add_filter( 'post_updated_messages' + """ + When I run `wp scaffold post-type zombie --raw` + Then STDOUT should not contain: + """ + add_filter( 'post_updated_messages' + """ # Test for all flags but --label, --theme, --plugin and --raw @tax From 36cc14f7c6bc96dbf75fe27d47e16d9268376888 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 2 Jul 2016 14:19:05 +0545 Subject: [PATCH 4668/4858] Improving doc in post commands --- php/commands/post.php | 51 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index 856d04776a..8a5a23c02f 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -184,7 +184,15 @@ protected function _edit( $content, $title ) { * : Limit the output to specific fields. Defaults to all fields. * * [--format=<format>] - * : Accepted values: table, json, csv, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -270,7 +278,17 @@ public function delete( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Accepted values: table, csv, json, count, ids, yaml. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * @@ -381,13 +399,22 @@ public function list_( $_, $assoc_args ) { * ## OPTIONS * * [--count=<number>] - * : How many posts to generate. Default: 100 + * : How many posts to generate? + * --- + * default: 100 + * --- * * [--post_type=<type>] - * : The type of the generated posts. Default: 'post' + * : The type of the generated posts. + * --- + * default: post + * --- * * [--post_status=<status>] - * : The status of the generated posts. Default: 'publish' + * : The status of the generated posts. + * --- + * default: publish + * --- * * [--post_author=<login>] * : The author of the generated posts. Default: none @@ -399,10 +426,19 @@ public function list_( $_, $assoc_args ) { * : 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 + * : For hierarchical post types, generate child posts down to a certain depth. + * --- + * default: 1 + * --- * * [--format=<format>] - * : Accepted values: progress, ids. Default: ids. + * : Render output in a particular format. + * --- + * default: progress + * options: + * - progress + * - ids + * --- * * ## EXAMPLES * @@ -618,4 +654,3 @@ protected function get_object_type() { WP_CLI::add_command( 'post', 'Post_Command' ); WP_CLI::add_command( 'post meta', 'Post_Meta_Command' ); WP_CLI::add_command( 'post term', 'Post_Term_Command' ); - From 5d34e2071da908079e3d13d07f27ab62db9fef7a Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Sat, 2 Jul 2016 15:48:48 +0200 Subject: [PATCH 4669/4858] Fix output of menu locations with format id #3083 --- php/commands/menu.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 2ee9527363..a351c46303 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -766,7 +766,17 @@ public function list_( $_, $assoc_args ) { } $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'location', 'description' ) ); - $formatter->display_items( $location_objs ); + + if ( 'ids' == $formatter->format ) { + $ids = array_map( + function($o) { + return $o->location; + }, $location_objs + ); + $formatter->display_items( $ids ); + } else { + $formatter->display_items( $location_objs ); + } } /** From e3587108f9545c3fc58a9012d19d7411b1c77f4f Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Sat, 2 Jul 2016 15:53:49 +0200 Subject: [PATCH 4670/4858] Add tests for #3083 --- features/menu.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index d75af3725a..3532450bee 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -55,6 +55,12 @@ Feature: Manage WordPress menus | slug | locations | | primary-menu | primary | + When I run `wp menu location list --format=ids` + Then STDOUT should be: + """ + primary + """ + When I run `wp menu location remove primary-menu primary` And I run `wp menu list --fields=slug,locations` Then STDOUT should be a table containing rows: From e8e15a9782fcfd8c8c38beb5e062cfed2f9fcaf7 Mon Sep 17 00:00:00 2001 From: Jakub Juszczak <netghost03@gmail.com> Date: Sun, 3 Jul 2016 10:16:50 +0200 Subject: [PATCH 4671/4858] Add ids to supported output format for menu location list --- php/commands/menu.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/menu.php b/php/commands/menu.php index 6a5e479b8b..2f1bf815c0 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -732,6 +732,7 @@ class Menu_Location_Command extends WP_CLI_Command { * - json * - count * - yaml + * - ids * --- * * ## AVAILABLE FIELDS From e2e99bedbd8518c96dfb8983641b0124296fe259 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sun, 3 Jul 2016 05:56:56 -0700 Subject: [PATCH 4672/4858] Register a magic `@all` alias This permits running a WP-CLI command against all registered aliases --- features/aliases.feature | 58 ++++++++++++++++++++++++++++++++++++++++ php/WP_CLI/Runner.php | 6 +++++ 2 files changed, 64 insertions(+) diff --git a/features/aliases.feature b/features/aliases.feature index 27bf71ba84..cd0135b646 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -185,3 +185,61 @@ Feature: Create shortcuts to specific WordPress installs http://apple.com http://google.com """ + + Scenario: Register '@all' alias for running on one or more aliases + Given a WP install in 'subdir1' + And a WP install in 'subdir2' + And a wp-cli.yml file: + """ + @subdir1: + path: subdir1 + @subdir2: + path: subdir2 + """ + + When I run `wp @subdir1 option update home 'http://apple.com'` + And I run `wp @subdir1 option get home` + Then STDOUT should contain: + """ + http://apple.com + """ + + When I run `wp @subdir2 option update home 'http://google.com'` + And I run `wp @subdir2 option get home` + Then STDOUT should contain: + """ + http://google.com + """ + + When I run `wp @all option get home` + Then STDOUT should be: + """ + http://apple.com + http://google.com + """ + + Scenario: Don't register '@all' when its already set + Given a WP install in 'subdir1' + And a WP install in 'subdir2' + And a wp-cli.yml file: + """ + @all: + path: subdir1 + @subdir2: + path: subdir2 + """ + + When I run `wp @all option get home | wc -l` + Then STDOUT should be: + """ + 1 + """ + + Scenario: Error when '@all' is used without aliases defined + Given an empty directory + + When I try `wp @all option get home` + Then STDERR should be: + """ + Error: Cannot use '@all' when no aliases are registered. + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4499b17d1b..81494257f0 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -627,6 +627,9 @@ private function init_config() { list( $this->config, $this->extra_config ) = $configurator->to_array(); $this->aliases = $configurator->get_aliases(); + if ( count( $this->aliases ) && ! isset( $this->aliases['@all'] ) ) { + $this->aliases['@all'] = array_keys( $this->aliases ); + } $this->_required_files['runtime'] = $this->config['require']; } @@ -700,6 +703,9 @@ public function start() { $this->check_root(); if ( $this->alias ) { + if ( '@all' === $this->alias && 0 === count( $this->aliases ) ) { + WP_CLI::error( "Cannot use '@all' when no aliases are registered." ); + } if ( ! array_key_exists( $this->alias, $this->aliases ) ) { WP_CLI::error( "Alias '{$this->alias}' not found." ); } From 6670840b815c5aae44c533a9f809338a0356d466 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 4 Jul 2016 12:46:09 +0545 Subject: [PATCH 4673/4858] Temporary reversal of default doc and add more improvements --- features/post.feature | 2 +- php/commands/post.php | 21 +++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/features/post.feature b/features/post.feature index b503ccee37..d33e825b2e 100644 --- a/features/post.feature +++ b/features/post.feature @@ -153,7 +153,7 @@ Feature: Manage WordPress posts When I try `wp post update {POST_ID} invalid-file.html` Then STDERR should be: """ - Error: Unable to read content from invalid-file.html. + Error: Unable to read content from 'invalid-file.html'. """ Scenario: Creating/listing posts diff --git a/php/commands/post.php b/php/commands/post.php index 8a5a23c02f..d8f56700f3 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -278,17 +278,7 @@ public function delete( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - csv - * - ids - * - json - * - count - * - yaml - * --- + * Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * @@ -417,7 +407,10 @@ public function list_( $_, $assoc_args ) { * --- * * [--post_author=<login>] - * : The author of the generated posts. Default: none + * : The author of the generated posts. + * --- + * default: + * --- * * [--post_date=<yyyy-mm-dd>] * : The date of the generated posts. Default: current date @@ -487,7 +480,7 @@ public function generate( $args, $assoc_args ) { $post_content = file_get_contents( 'php://stdin' ); } - // Get the total number of posts + // 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; @@ -578,7 +571,7 @@ private function read_from_file_or_stdin( $arg ) { if ( $arg !== '-' ) { $readfile = $arg; if ( ! file_exists( $readfile ) || ! is_file( $readfile ) ) { - \WP_CLI::error( "Unable to read content from $readfile." ); + \WP_CLI::error( "Unable to read content from '$readfile'." ); } } else { $readfile = 'php://stdin'; From 4f6ae82da3aa81ff1a73ded26e43a6e3efa2e7ad Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 4 Jul 2016 12:48:10 +0545 Subject: [PATCH 4674/4858] Add missing colon in post list doc --- php/commands/post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/post.php b/php/commands/post.php index d8f56700f3..bf3b038765 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -278,7 +278,7 @@ public function delete( $args, $assoc_args ) { * : Limit the output to specific object fields. * * [--format=<format>] - * Accepted values: table, csv, json, count, ids, yaml. Default: table + * : Accepted values: table, csv, json, count, ids, yaml. Default: table * * ## AVAILABLE FIELDS * From 746c0e06a133467fb421d730f561edf0c8bfbf41 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 4 Jul 2016 14:29:40 -0700 Subject: [PATCH 4675/4858] Restore tab completion documentation to README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 6319172181..db835e1698 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,22 @@ WP-CLI project config: WP-CLI version: 0.23.0 ``` +### Updating + You can update WP-CLI with `wp cli update` ([doc](https://wp-cli.org/commands/cli/update/)), or by repeating the installation steps. Want to live life on the edge? Run `wp cli update --nightly` to use the latest nightly build of WP-CLI. The nightly build is more or less stable enough for you to use in your development environment, and always includes the latest and greatest WP-CLI features. +### Tab completions + +WP-CLI also comes with a tab completion script for Bash and ZSH. Just download [wp-completion.bash](https://github.com/wp-cli/wp-cli/raw/master/utils/wp-completion.bash) and source it from `~/.bash_profile`: + +``` +source /FULL/PATH/TO/wp-completion.bash +``` + +Don't forget to run `source ~/.bash_profile` afterwards. + ## Support WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: From 671bc7f6fea63f680fa405a62ccf0afe1fb975cf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 5 Jul 2016 13:28:58 -0700 Subject: [PATCH 4676/4858] Failing test case for #3101 --- features/command.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/command.feature b/features/command.feature index 490b13c315..f4f5aec2d0 100644 --- a/features/command.feature +++ b/features/command.feature @@ -573,3 +573,14 @@ Feature: WP-CLI Commands Success: Invoked Success: after invoke """ + + Scenario: Default arguments should respect wp-cli.yml + Given a WP install + And a wp-cli.yml file: + """ + post list: + format: count + """ + + When I run `wp post list` + Then STDOUT should be a number From d7a219f3f555134e56e8e329e131eee93d45e456 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 5 Jul 2016 14:14:01 -0700 Subject: [PATCH 4677/4858] Respect wp-cli.yml default values when applying argument defaults Bug introduced in 05ff88bf66c7276fc95cd80f9fa8f85547c55b2f --- php/WP_CLI/Dispatcher/Subcommand.php | 2 +- php/commands/post.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 35d8922cb3..1b18f9b2d7 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -287,7 +287,7 @@ private function validate_args( $args, $assoc_args, $extra_args ) { $i++; } else if ( 'assoc' === $spec['type'] ) { $spec_args = $docparser->get_param_args( $spec['name'] ); - if ( ! isset( $assoc_args[ $spec['name'] ] ) ) { + if ( ! isset( $assoc_args[ $spec['name'] ] ) && ! isset( $extra_args[ $spec['name'] ] ) ) { if ( isset( $spec_args['default'] ) ) { $assoc_args[ $spec['name'] ] = $spec_args['default']; } diff --git a/php/commands/post.php b/php/commands/post.php index bf3b038765..b84feb6281 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -279,6 +279,16 @@ public function delete( $args, $assoc_args ) { * * [--format=<format>] * : Accepted values: table, csv, json, count, ids, yaml. Default: table + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - count + * - yaml + * --- * * ## AVAILABLE FIELDS * From 28eed6b5a8923dae69c01d0d665e6d613b748957 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 6 Jul 2016 05:01:22 -0700 Subject: [PATCH 4678/4858] Mention `good-first-issue` in CONTRIBUTING.md --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6e523ee9b..427d6c2604 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,8 @@ Once you’ve done a bit of searching and discovered there isn’t an open or fi Want to contribute a new feature? WP-CLI is a mature project, and already chock-full of useful functionality. Please first [open a new issue](https://github.com/wp-cli/wp-cli/issues/new) to discuss whether the feature is a good fit for WP-CLI core, or might be better suited as a [community package](https://wp-cli.org/package-index/). +New to the WP-CLI codebase? Check out [issues labeled 'good-first-issue'](https://github.com/wp-cli/wp-cli/labels/good-first-issue) for a place to start. These issues are specially earmarked for new contributors. + Once you've decided to commit the time to seeing your pull request through, please [follow our guidelines for creating a pull request](https://wp-cli.org/docs/pull-requests/) to make sure it's a pleasant experience. ### Contributing in other ways From c992061b0b5c0afc43e1ec545586999a21c5793d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 05:49:38 -0700 Subject: [PATCH 4679/4858] Use `proc_open()` instead of `passthru()` to persist TTY mode --- php/WP_CLI/Runner.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 81494257f0..0868086fcf 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -678,7 +678,8 @@ private function run_alias_group( $aliases ) { $assoc_args = Utils\assoc_args_to_str( $this->assoc_args ); $full_command = "WP_CLI_CONFIG_PATH={$config_path} {$php_bin} {$script_path} {$alias} {$args} {$assoc_args}"; - passthru( $full_command ); + $proc = proc_open( $full_command, array( STDIN, STDOUT, STDERR ), $pipes ); + proc_close( $proc ); } } From acbf549f900835664fd306a88ffdb136ffb7edca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 06:00:32 -0700 Subject: [PATCH 4680/4858] Failing test case for #3104 --- features/cron.feature | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/features/cron.feature b/features/cron.feature index 76b1ee0e81..253938dd0f 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -280,3 +280,27 @@ Feature: Manage WP-Cron events and schedules """ Executed a total of 0 cron event(s) """ + + Scenario: Don't trigger cron when ALTERNATE_WP_CRON is defined + Given a alternate-wp-cron.php file: + """ + <?php + define( 'ALTERNATE_WP_CRON', true ); + """ + And a wp-cli.yml file: + """ + require: + - alternate-wp-cron.php + """ + + When I run `wp eval 'var_export( ALTERNATE_WP_CRON );'` + Then STDOUT should be: + """ + true + """ + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ From 99dea0f3ad9ee848e2ccd10b2ce27d30a3da663c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 06:07:02 -0700 Subject: [PATCH 4681/4858] Don't trigger cron when ALTERNATE_WP_CRON is defined `ALTERNATE_WP_CRON` tries to redirect, which we can't handle. --- php/WP_CLI/Runner.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 81494257f0..fa6630ff24 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -1014,6 +1014,13 @@ private function setup_bootstrap_hooks() { return $headers; }); + // ALTERNATE_WP_CRON might trigger a redirect, which we can't handle + if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { + $this->add_wp_hook( 'muplugins_loaded', function() { + remove_action( 'init', 'wp_cron' ); + }); + } + // Get rid of warnings when converting single site to multisite if ( defined( 'WP_INSTALLING' ) && $this->is_multisite() ) { $values = array( From 6d4aae0b164222b3c844ee9403e69767ced8f5be Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 07:14:56 -0700 Subject: [PATCH 4682/4858] Failing test case for #3029 --- features/config.feature | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/features/config.feature b/features/config.feature index 7912d1d539..bf68d258dd 100644 --- a/features/config.feature +++ b/features/config.feature @@ -155,6 +155,20 @@ Feature: Have a config file And I run `grep WP_POST_REVISIONS wp-config.php` Then STDOUT should not be empty + Scenario: Persist positional parameters when defined in a config + Given a WP install + And a wp-cli.yml file: + """ + user create: + - examplejoe + - joe@example.com + user_pass: joe + role: administrator + """ + + When I run `wp user create` + Then STDOUT should not be empty + Scenario: Command-specific configs Given a WP install And a wp-cli.yml file: From dcae93f329695074623fdb67b24c4b88d49bbcca Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 07:19:48 -0700 Subject: [PATCH 4683/4858] Appropriately handle positional arguments defined in wp-cli.yml --- features/config.feature | 6 ++++++ php/WP_CLI/Dispatcher/Subcommand.php | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/features/config.feature b/features/config.feature index bf68d258dd..d5db208449 100644 --- a/features/config.feature +++ b/features/config.feature @@ -169,6 +169,12 @@ Feature: Have a config file When I run `wp user create` Then STDOUT should not be empty + When I run `wp user get examplejoe --field=roles` + Then STDOUT should contain: + """ + administrator + """ + Scenario: Command-specific configs Given a WP install And a wp-cli.yml file: diff --git a/php/WP_CLI/Dispatcher/Subcommand.php b/php/WP_CLI/Dispatcher/Subcommand.php index 1b18f9b2d7..507036c842 100644 --- a/php/WP_CLI/Dispatcher/Subcommand.php +++ b/php/WP_CLI/Dispatcher/Subcommand.php @@ -345,6 +345,15 @@ public function invoke( $args, $assoc_args, $extra_args ) { $prompted_once = true; } + $extra_positionals = array(); + foreach( $extra_args as $k => $v ) { + if ( is_numeric( $k ) ) { + $extra_positionals[ $k ] = $v; + unset( $extra_args[ $k ] ); + } + } + $args = array_merge( $extra_positionals, $args ); + list( $to_unset, $args, $assoc_args, $extra_args ) = $this->validate_args( $args, $assoc_args, $extra_args ); foreach ( $to_unset as $key ) { From 9a075572018b84fd9fb62e936addd4b8b6d7ecc9 Mon Sep 17 00:00:00 2001 From: Keanan Koppenhaver <keanan@doejo.com> Date: Thu, 7 Jul 2016 11:18:03 -0500 Subject: [PATCH 4684/4858] #2766 - Improving our documentation section of CONTRIBUTING.md --- CONTRIBUTING.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 427d6c2604..31094fe50c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,6 +25,20 @@ New to the WP-CLI codebase? Check out [issues labeled 'good-first-issue'](https: Once you've decided to commit the time to seeing your pull request through, please [follow our guidelines for creating a pull request](https://wp-cli.org/docs/pull-requests/) to make sure it's a pleasant experience. +### Improving our documentation + +Just like WP-CLI itself, the [documentation](http://wp-cli.org/docs/) is a community effort. + +If you are looking to contribute and documentation is your strength, you can take a look at the currently open [documentation issues](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+is%3Aissue+label%3Ascope%3Adocumentation) and see if you can tackle any of those. + +If you believe you’ve found an issue with the documentation, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI. + +There are a few different types of documentation currently part of WP-CLI: + +Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. + +Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) or [http://wp-cli.org/config/](http://wp-cli.org/config/)) can be edited by contributing to the [wp-cli.github.com repository on Github](https://github.com/wp-cli/wp-cli.github.com). + ### Contributing in other ways Feel free to [create an issue](https://github.com/wp-cli/wp-cli/issues/new) with your question, and we'll see if we can find an answer for it. From 8e57ce79a0e6969ccf23f54cb1ef0735c3bb0e32 Mon Sep 17 00:00:00 2001 From: Keanan Koppenhaver <keanan@doejo.com> Date: Thu, 7 Jul 2016 13:07:17 -0500 Subject: [PATCH 4685/4858] #2766 edits and clarification of improving documentation section of CONTRIBUTING.md --- CONTRIBUTING.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31094fe50c..7b00ca3c2c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,17 +27,15 @@ Once you've decided to commit the time to seeing your pull request through, plea ### Improving our documentation -Just like WP-CLI itself, the [documentation](http://wp-cli.org/docs/) is a community effort. - If you are looking to contribute and documentation is your strength, you can take a look at the currently open [documentation issues](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+is%3Aissue+label%3Ascope%3Adocumentation) and see if you can tackle any of those. If you believe you’ve found an issue with the documentation, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI. There are a few different types of documentation currently part of WP-CLI: -Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. + * Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. The web documentation is generated from these files at the time of release, so you may not see your changes until the next release. -Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) or [http://wp-cli.org/config/](http://wp-cli.org/config/)) can be edited by contributing to the [wp-cli.github.com repository on Github](https://github.com/wp-cli/wp-cli.github.com). + * Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) or [http://wp-cli.org/config/](http://wp-cli.org/config/)) can be edited by contributing to the [wp-cli.github.com repository on Github](https://github.com/wp-cli/wp-cli.github.com). ### Contributing in other ways From 92142ca8e33aea7cfa62297d227551854d866f75 Mon Sep 17 00:00:00 2001 From: Keanan Koppenhaver <keanan@doejo.com> Date: Thu, 7 Jul 2016 13:15:37 -0500 Subject: [PATCH 4686/4858] #2766 - additional edits to improving docs section per @danielbachhuber feedback --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7b00ca3c2c..ec808eb1e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ Once you've decided to commit the time to seeing your pull request through, plea ### Improving our documentation -If you are looking to contribute and documentation is your strength, you can take a look at the currently open [documentation issues](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+is%3Aissue+label%3Ascope%3Adocumentation) and see if you can tackle any of those. +Is documentation your strength? Take a look at the currently open [documentation issues](https://github.com/wp-cli/wp-cli/issues?q=is%3Aopen+is%3Aissue+label%3Ascope%3Adocumentation) and see if you can tackle any of those. If you believe you’ve found an issue with the documentation, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI. @@ -35,7 +35,8 @@ There are a few different types of documentation currently part of WP-CLI: * Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. The web documentation is generated from these files at the time of release, so you may not see your changes until the next release. - * Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) or [http://wp-cli.org/config/](http://wp-cli.org/config/)) can be edited by contributing to the [wp-cli.github.com repository on Github](https://github.com/wp-cli/wp-cli.github.com). + + * Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) or [http://wp-cli.org/config/](http://wp-cli.org/config/)) can be edited by contributing to the [wp-cli.github.com repository on GitHub](https://github.com/wp-cli/wp-cli.github.com). Any page that is part of this repository will have an 'Edit' link in the top right of the page which will take you to the corresponding file on GitHub. ### Contributing in other ways From 326dcb67dd337095163ac49a14d743385157a8c5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 12:11:16 -0700 Subject: [PATCH 4687/4858] Minor edits --- CONTRIBUTING.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec808eb1e8..abdb2c5396 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,12 +31,10 @@ Is documentation your strength? Take a look at the currently open [documentation If you believe you’ve found an issue with the documentation, you should [search existing issues](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version of WP-CLI. -There are a few different types of documentation currently part of WP-CLI: +There are a couple different types of documentation currently part of WP-CLI: - * Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. The web documentation is generated from these files at the time of release, so you may not see your changes until the next release. - - - * Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) or [http://wp-cli.org/config/](http://wp-cli.org/config/)) can be edited by contributing to the [wp-cli.github.com repository on GitHub](https://github.com/wp-cli/wp-cli.github.com). Any page that is part of this repository will have an 'Edit' link in the top right of the page which will take you to the corresponding file on GitHub. +* Documentation for individual WP-CLI commands (anything underneath [http://wp-cli.org/commands](http://wp-cli.org/commands)) is contained in the PHPDoc for each command. This means that to edit the documentation for a command, you will need to edit the file that actually provides the functionality for that command. The web documentation is generated from these files at the time of release, so you may not see your changes until the next release. +* Individual documentation pages (anything under [http://wp-cli.org/docs/](http://wp-cli.org/docs/) can be edited by contributing to the [wp-cli.github.com repository on GitHub](https://github.com/wp-cli/wp-cli.github.com). You don't necessarily need to navigate the Github repo though; any page that is part of this repository will have an 'Edit' link in the top right of the page which will take you to the corresponding file on GitHub. ### Contributing in other ways From be55a9d8354dbd1da78529d0fe4a7cacfb43f983 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 7 Jul 2016 13:39:56 -0700 Subject: [PATCH 4688/4858] Note that 'url' isn't an available filter for `wp site list` The value on the site object is created on the fly, not stored in a database column. --- php/commands/site.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/site.php b/php/commands/site.php index 2ad634bfdb..e3459a542c 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -411,7 +411,8 @@ private function _get_network( $network_id ) { * : The network to which the sites belong. * * [--<field>=<value>] - * : Filter by one or more fields. + * : Filter by one or more fields (see "Available Fields" section). However, + * 'url' isn't an available filter, because it's created from domain + path. * * [--field=<field>] * : Prints the value of a single field for each site. @@ -482,7 +483,7 @@ public function list_( $_, $assoc_args ) { $where = array(); $append = ''; - $site_cols = array( 'blog_id', 'url', 'last_updated', 'registered', 'site_id', 'domain', 'path', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' ); + $site_cols = array( 'blog_id', 'last_updated', 'registered', 'site_id', 'domain', 'path', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id' ); foreach( $site_cols as $col ) { if ( isset( $assoc_args[ $col ] ) ) { $where[ $col ] = $assoc_args[ $col ]; From 9a2673bcfba9dcd835963029afa27f776a53176b Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 8 Jul 2016 09:49:50 +0545 Subject: [PATCH 4689/4858] Add doc for generated files in scaffold plugin command --- php/commands/scaffold.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index 30a2da1d68..d83f792c82 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -403,6 +403,23 @@ private function get_output_path( $assoc_args, $subdir ) { /** * Generate starter code for a plugin. * + * ## OVERVIEW + * + * The following files are generated for your plugin by this command: + * + * * `plugin-slug.php` is the main PHP plugin file. + * * `readme.txt` is the readme file for the plugin. + * * `package.json` needed by NPM holds various metadata relevant to the project. + * * `Gruntfile.js` is the JS file containing Grunt tasks. + * * `phpunit.xml.dist` is the configuration file for PHPUnit. + * * `.editorconfig` is the configuration file for Editor. + * * `.gitignore` tells which files (or patterns) git should ignore. + * * `.distignore` tells which files and folders should be ignored in distribution. + * * `.travis.yml` is the configuration file for Travis CI. + * * `bin/install-wp-tests.sh` configures the WordPress test suite and a test database. + * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite. + * * `tests/test-sample.php` is a sample file containing the actual tests. + * * ## OPTIONS * * <slug> From 5281abac2db2ab4ccd853a7f02d78b9e2131db90 Mon Sep 17 00:00:00 2001 From: Stephen Harris <Stephen.Harris@gov.scot> Date: Fri, 8 Jul 2016 11:10:50 +0100 Subject: [PATCH 4690/4858] Support 'trunk' and 'nightly' version arguments for wp core download. - Modifies Core_Command::get_download_url() to interpret 'trunk' and 'nightly' versions - Core_Command::get_download_url() now conforms to WordPress coding standards - Adds support for downloading and extracting .zip files as nightly builds are own available in zip format. - wp core download --version=trunk is only supported if ZipArchive is present. --- php/commands/core.php | 79 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 688510373f..2d882db908 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -134,7 +134,7 @@ public function download( $args, $assoc_args ) { $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', 'en_US' ); if ( isset( $assoc_args['version'] ) ) { - $version = $assoc_args['version']; + $version = strtolower( $assoc_args['version'] ); $download_url = $this->get_download_url($version, $locale, 'tar.gz'); } else { $offer = $this->get_download_offer( $locale ); @@ -154,8 +154,14 @@ public function download( $args, $assoc_args ) { WP_CLI::log( sprintf( 'Downloading WordPress %s (%s)...', $version, $locale ) ); + $path_parts = pathinfo( $download_url ); + $extension = 'tar.gz'; + if ( 'zip' === $path_parts['extension'] ) { + $extension = 'zip'; + } + $cache = WP_CLI::get_cache(); - $cache_key = "core/wordpress-{$version}-{$locale}.tar.gz"; + $cache_key = "core/wordpress-{$version}-{$locale}.{$extension}"; $cache_file = $cache->has($cache_key); $bad_cache = false; @@ -172,7 +178,7 @@ public function download( $args, $assoc_args ) { if ( ! $cache_file || $bad_cache ) { // We need to use a temporary file because piping from cURL to tar is flaky // on MinGW (and probably in other environments too). - $temp = \WP_CLI\Utils\get_temp_dir() . uniqid('wp_') . '.tar.gz'; + $temp = \WP_CLI\Utils\get_temp_dir() . uniqid('wp_') . ".{$extension}"; $headers = array('Accept' => 'application/json'); $options = array( @@ -187,16 +193,21 @@ public function download( $args, $assoc_args ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})." ); } - $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); - if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { - WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})." ); - } + if ( 'trunk' !== $version && 'nightly' !== $version ) { + $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); + if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { + WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})." ); + } + + $md5_file = md5_file( $temp ); - $md5_file = md5_file( $temp ); - if ( $md5_file === $md5_response->body ) { - WP_CLI::log( 'md5 hash verified: ' . $md5_file ); + if ( $md5_file === $md5_response->body ) { + WP_CLI::log( 'md5 hash verified: ' . $md5_file ); + } else { + WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})." ); + } } else { - WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})." ); + WP_CLI::warning( 'md5 hash checks are not available for trunk downloads' ); } try { @@ -215,7 +226,20 @@ public function download( $args, $assoc_args ) { WP_CLI::success( 'WordPress downloaded.' ); } - private static function _extract( $tarball, $dest ) { + private static function _extract( $tarball_or_zip, $dest ) { + $path_parts = pathinfo( $tarball_or_zip ); + + switch ( strtolower( $path_parts['extension'] ) ) { + case 'zip': + self::_extract_zip( $tarball_or_zip, $dest ); + break; + default; + self::_extract_tarball( $tarball_or_zip, $dest ); + break; + } + } + + private static function _extract_tarball( $tarball, $dest ) { if ( ! class_exists( 'PharData' ) ) { $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball"; WP_CLI::launch( Utils\esc_cmd( $cmd, $dest ) ); @@ -235,6 +259,29 @@ private static function _extract( $tarball, $dest ) { self::_rmdir( dirname( $tempdir ) ); } + private static function _extract_zip( $zipfile, $dest ) { + if ( ! class_exists( 'ZipArchive' ) ) { + throw new \Exception( 'Extracting a zip file requires PharData' ); + } + $zip = new ZipArchive(); + $res = $zip->open( $zipfile ); + if ( true === $res ) { + $tempdir = implode( DIRECTORY_SEPARATOR, Array ( + dirname( $zipfile ), + basename( $zipfile, '.zip' ), + $zip->getNameIndex( 0 ) + ) ); + + $zip->extractTo( dirname( $tempdir ) ); + $zip->close(); + + self::_copy_overwrite_files( $tempdir, $dest ); + self::_rmdir( dirname( $tempdir ) ); + } else { + throw \Exception( $res ); + } + } + private static function _copy_overwrite_files( $source, $dest ) { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $source, RecursiveDirectoryIterator::SKIP_DOTS ), @@ -1344,9 +1391,11 @@ function update_db( $_, $assoc_args ) { * @param string $file_type * @return string */ - private function get_download_url($version, $locale = 'en_US', $file_type = 'zip') - { - if ('en_US' === $locale) { + private function get_download_url( $version, $locale = 'en_US', $file_type = 'zip' ) { + + if ( 'trunk' === $version || 'nightly' === $version ) { + return 'https://wordpress.org/nightly-builds/wordpress-latest.zip'; + } elseif ( 'en_US' === $locale ) { $url = 'https://wordpress.org/wordpress-' . $version . '.' . $file_type; return $url; From 5bf475096604c0f41734650085cac3af9343add8 Mon Sep 17 00:00:00 2001 From: Stephen Harris <Stephen.Harris@scotland.gsi.gov.uk> Date: Fri, 8 Jul 2016 12:19:59 +0100 Subject: [PATCH 4691/4858] Add missing full top. --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 2d882db908..904596c56e 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -207,7 +207,7 @@ public function download( $args, $assoc_args ) { WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})." ); } } else { - WP_CLI::warning( 'md5 hash checks are not available for trunk downloads' ); + WP_CLI::warning( 'md5 hash checks are not available for trunk downloads.' ); } try { From b7423a62e01fa0c0d29aa61c0d0128cb7ad7359c Mon Sep 17 00:00:00 2001 From: Stephen Harris <Stephen.Harris@scotland.gsi.gov.uk> Date: Fri, 8 Jul 2016 12:20:27 +0100 Subject: [PATCH 4692/4858] Make 'nightly' an alias for 'trunk' --- php/commands/core.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 904596c56e..ad766deed2 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -135,6 +135,7 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { $version = strtolower( $assoc_args['version'] ); + $version = ( 'nightly' === $version ? 'trunk' : $version ); $download_url = $this->get_download_url($version, $locale, 'tar.gz'); } else { $offer = $this->get_download_offer( $locale ); @@ -193,7 +194,7 @@ public function download( $args, $assoc_args ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})." ); } - if ( 'trunk' !== $version && 'nightly' !== $version ) { + if ( 'trunk' !== $version ) { $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})." ); @@ -1393,7 +1394,7 @@ function update_db( $_, $assoc_args ) { */ private function get_download_url( $version, $locale = 'en_US', $file_type = 'zip' ) { - if ( 'trunk' === $version || 'nightly' === $version ) { + if ( 'trunk' === $version ) { return 'https://wordpress.org/nightly-builds/wordpress-latest.zip'; } elseif ( 'en_US' === $locale ) { $url = 'https://wordpress.org/wordpress-' . $version . '.' . $file_type; From 9ec1d1425b9345fbe46be6c7cd17d53cf1e360db Mon Sep 17 00:00:00 2001 From: Stephen Harris <Stephen.Harris@scotland.gsi.gov.uk> Date: Fri, 8 Jul 2016 12:24:58 +0100 Subject: [PATCH 4693/4858] Add behat tests --- features/core-download.feature | 84 ++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/features/core-download.feature b/features/core-download.feature index 0b5cd4bd33..c04c62d5ea 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -95,3 +95,87 @@ Feature: Download WordPress """ File removed: wp-content """ + + Scenario: Installing trunk + Given an empty directory + And an empty cache + + When I run `wp core download --version=trunk` + Then the wp-settings.php file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-trunk-en_US.zip file should exist + And STDOUT should contain: + """ + Downloading WordPress trunk (en_US)... + """ + And STDERR should contain: + """ + Warning: md5 hash checks are not available for trunk downloads. + """ + And STDOUT should contain: + """ + Success: WordPress downloaded. + """ + + # test core zip cache + When I run `wp core download --version=trunk` + Then the wp-settings.php file should exist + And STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/core/wordpress-trunk-en_US.zip'... + """ + + Scenario: Installing trunk over an existing install + Given an empty directory + And an empty cache + When I run `wp core download --version=4.5.3` + Then the wp-settings.php file should exist + When I run `wp core download --version=trunk --force` + Then STDERR should not contain: + """ + Warning: Failed to find WordPress version. Please cleanup files manually. + """ + And STDERR should contain: + """ + Warning: Failed to fetch checksums. Please cleanup files manually. + """ + And STDOUT should contain: + """ + Success: WordPress downloaded. + """ + + Scenario: Installing a version over trunk + Given an empty directory + And an empty cache + When I run `wp core download --version=trunk` + Then the wp-settings.php file should exist + And STDERR should not contain: + """ + Warning: Failed to find WordPress version. Please cleanup files manually. + """ + + When I run `wp core download --version=4.3.2 --force` + Then the wp-includes/rest-api.php file should not exist + And the wp-includes/class-wp-comment.php file should not exist + And STDOUT should not contain: + """ + File removed: wp-content + """ + + Scenario: Nightly is an alias for trunk + Given an empty directory + And an empty cache + When I run `wp core download --version=nightly` + Then the wp-settings.php file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-trunk-en_US.zip file should exist + And STDOUT should contain: + """ + Downloading WordPress trunk (en_US)... + """ + And STDERR should contain: + """ + Warning: md5 hash checks are not available for trunk downloads. + """ + And STDOUT should contain: + """ + Success: WordPress downloaded. + """ From 0ab81152272897737735ebcbce8cfa0655266ff4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 8 Jul 2016 04:51:39 -0700 Subject: [PATCH 4694/4858] Introduce `WP_CLI_STRICT_ARGS_MODE` for dealing with arg ambiguity Consider a command like: ``` wp widget add rss sidebar-1 1 --url="http://wp-cli.org/feed/" ``` Historically, the `--url=<url>` parameter has been treated like a global runtime argument, which has meant a command can't easily use it as its own. Now, using the `WP_CLI_STRICT_ARGS_MODE` will tell WP-CLI to treat any arguments before the command as global, and after the command as local. For instance: ``` WP_CLI_STRICT_ARGS_MODE=1 wp --url=wp.dev/site2 widget add rss sidebar-1 1 --url="http://wp-cli.org/feed/" ``` In this example, `--url=wp.dev/site2` is the global argument, setting WP-CLI to run against 'site2' on a WP multisite install. `--url="http://wp-cli.org/feed/"` is the local argument, setting the RSS feed widget with the proper URL. I've thought long and hard about making a breaking change, and enforcing strict args mode by default. At this point, I don't think it will ever be worth it, given the majority use case isn't impacted by it, and it's a better user experience to be able to supply arguments in an ambigious order. When you need to be strict, you can use the environment variable. --- features/flags.feature | 46 ++++++++++++++++++++++ php/WP_CLI/Configurator.php | 76 ++++++++++++++++++++++++++----------- tests/test-configurator.php | 16 +++++++- 3 files changed, 115 insertions(+), 23 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index b521a65f1e..e4aa8d91ee 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -212,3 +212,49 @@ Feature: Global flags """ <file> """ + + Scenario: Use `WP_CLI_STRICT_ARGS_MODE` to distinguish between global and local args + Given an empty directory + And a cmd.php file: + """ + <?php + /** + * @when before_wp_load + * + * [--url=<url>] + * : URL passed to the callback. + */ + $cmd_test = function( $args, $assoc_args ) { + $url = WP_CLI::get_runner()->config['url'] ? ' ' . WP_CLI::get_runner()->config['url'] : ''; + WP_CLI::log( 'global:' . $url ); + $url = isset( $assoc_args['url'] ) ? ' ' . $assoc_args['url'] : ''; + WP_CLI::log( 'local:' . $url ); + }; + WP_CLI::add_command( 'cmd-test', $cmd_test ); + """ + And a wp-cli.yml file: + """ + require: + - cmd.php + """ + + When I run `wp cmd-test --url=foo.dev` + Then STDOUT should be: + """ + global: foo.dev + local: + """ + + When I run `WP_CLI_STRICT_ARGS_MODE=1 wp cmd-test --url=foo.dev` + Then STDOUT should be: + """ + global: + local: foo.dev + """ + + When I run `WP_CLI_STRICT_ARGS_MODE=1 wp --url=bar.dev cmd-test --url=foo.dev` + Then STDOUT should be: + """ + global: bar.dev + local: foo.dev + """ diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 35063c2c86..1e467e9d9e 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -84,8 +84,8 @@ function get_aliases() { * @return array(array) */ public function parse_args( $arguments ) { - list( $positional_args, $mixed_args ) = self::extract_assoc( $arguments ); - list( $assoc_args, $runtime_config ) = $this->unmix_assoc_args( $mixed_args ); + list( $positional_args, $mixed_args, $global_assoc, $local_assoc ) = self::extract_assoc( $arguments ); + list( $assoc_args, $runtime_config ) = $this->unmix_assoc_args( $mixed_args, $global_assoc, $local_assoc ); return array( $positional_args, $assoc_args, $runtime_config ); } @@ -96,21 +96,35 @@ public function parse_args( $arguments ) { * @return array(array) */ public static function extract_assoc( $arguments ) { - $positional_args = $assoc_args = array(); + $positional_args = $assoc_args = $global_assoc = $local_assoc = array(); foreach ( $arguments as $arg ) { + $positional_arg = $assoc_arg = null; + if ( preg_match( '|^--no-([^=]+)$|', $arg, $matches ) ) { - $assoc_args[] = array( $matches[1], false ); + $assoc_arg = array( $matches[1], false ); } elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) { - $assoc_args[] = array( $matches[1], true ); + $assoc_arg = array( $matches[1], true ); } elseif ( preg_match( '|^--([^=]+)=(.*)|s', $arg, $matches ) ) { - $assoc_args[] = array( $matches[1], $matches[2] ); + $assoc_arg = array( $matches[1], $matches[2] ); } else { - $positional_args[] = $arg; + $positional = $arg; + } + + if ( ! is_null( $assoc_arg ) ) { + $assoc_args[] = $assoc_arg; + if ( count( $positional_args ) ) { + $local_assoc[] = $assoc_arg; + } else { + $global_assoc[] = $assoc_arg; + } + } else if ( ! is_null( $positional ) ) { + $positional_args[] = $positional; } + } - return array( $positional_args, $assoc_args ); + return array( $positional_args, $assoc_args, $global_assoc, $local_assoc ); } /** @@ -119,32 +133,50 @@ public static function extract_assoc( $arguments ) { * @param array $mixed_args * @return array */ - private function unmix_assoc_args( $mixed_args ) { + private function unmix_assoc_args( $mixed_args, $global_assoc = array(), $local_assoc = array() ) { $assoc_args = $runtime_config = array(); - foreach ( $mixed_args as $tmp ) { - list( $key, $value ) = $tmp; - - if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) { - $details = $this->spec[ $key ]; - - if ( isset( $details['deprecated'] ) ) { - fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" ); + if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) { + foreach( $global_assoc as $tmp ) { + list( $key, $value ) = $tmp; + if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) { + $this->assoc_arg_to_runtime_config( $key, $value, $runtime_config ); } + } + foreach( $local_assoc as $tmp ) { + $assoc_args[ $tmp[0] ] = $tmp[1]; + } + } else { + foreach ( $mixed_args as $tmp ) { + list( $key, $value ) = $tmp; - if ( $details['multiple'] ) { - $runtime_config[ $key ][] = $value; + if ( isset( $this->spec[ $key ] ) && $this->spec[ $key ]['runtime'] !== false ) { + $this->assoc_arg_to_runtime_config( $key, $value, $runtime_config ); } else { - $runtime_config[ $key ] = $value; + $assoc_args[ $key ] = $value; } - } else { - $assoc_args[ $key ] = $value; } } return array( $assoc_args, $runtime_config ); } + /** + * Handle turning an $assoc_arg into a runtime arg. + */ + private function assoc_arg_to_runtime_config( $key, $value, &$runtime_config ) { + $details = $this->spec[ $key ]; + if ( isset( $details['deprecated'] ) ) { + fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" ); + } + + if ( $details['multiple'] ) { + $runtime_config[ $key ][] = $value; + } else { + $runtime_config[ $key ] = $value; + } + } + /** * Load a YAML file of parameters into scope. * diff --git a/tests/test-configurator.php b/tests/test-configurator.php index 55c291acbd..ea13aaeb34 100644 --- a/tests/test-configurator.php +++ b/tests/test-configurator.php @@ -36,6 +36,20 @@ function testExtractAssocNoValue() { } + function testExtractAssocGlobalLocal() { + $args = Configurator::extract_assoc( array( '--url=foo.dev', '--path=wp', 'foo', '--bar=', '--baz=text', '--url=bar.dev' ) ); + + $this->assertCount( 1, $args[0] ); + $this->assertCount( 5, $args[1] ); + $this->assertCount( 2, $args[2] ); + $this->assertCount( 3, $args[3] ); + + $this->assertEquals( 'url', $args[2][0][0] ); + $this->assertEquals( 'foo.dev', $args[2][0][1] ); + $this->assertEquals( 'url', $args[3][2][0] ); + $this->assertEquals( 'bar.dev', $args[3][2][1] ); + } + function testExtractAssocDoubleDashInValue() { $args = Configurator::extract_assoc( array( '--test=text--text' ) ); @@ -48,4 +62,4 @@ function testExtractAssocDoubleDashInValue() { } -} \ No newline at end of file +} From 9eea025df9b69eab496b6c2a5dc3207a05702f4a Mon Sep 17 00:00:00 2001 From: Stephen Harris <Stephen.Harris@scotland.gsi.gov.uk> Date: Fri, 8 Jul 2016 13:12:28 +0100 Subject: [PATCH 4695/4858] Fix test: use --force on the second time of downloading --- features/core-download.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core-download.feature b/features/core-download.feature index c04c62d5ea..2973f91fda 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -117,7 +117,7 @@ Feature: Download WordPress """ # test core zip cache - When I run `wp core download --version=trunk` + When I run `wp core download --version=trunk --force` Then the wp-settings.php file should exist And STDOUT should contain: """ From c626c3755821da538e6f51ccb035863bb6077f80 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 8 Jul 2016 06:21:53 -0700 Subject: [PATCH 4696/4858] Register `--http=<url>` global parameter We don't register new global parameters often, but this one is needed for RESTful WP-CLI. --- features/flags.feature | 9 +++++++++ php/WP_CLI/Runner.php | 4 ++++ php/config-spec.php | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/features/flags.feature b/features/flags.feature index e4aa8d91ee..53306d5083 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -258,3 +258,12 @@ Feature: Global flags global: bar.dev local: foo.dev """ + + Scenario: Using --http=<url> requires wp-cli/restful + Given an empty directory + + When I try `wp --http=foo.dev` + Then STDERR should be: + """ + Error: RESTful WP-CLI needs to be installed. Try 'wp package install wp-cli/restful'. + """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 69ec48bc8f..7f53d592bc 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -756,6 +756,10 @@ public function start() { } } + if ( isset( $this->config['http'] ) && ! class_exists( '\WP_REST_CLI\Runner' ) ) { + WP_CLI::error( "RESTful WP-CLI needs to be installed. Try 'wp package install wp-cli/restful'." ); + } + if ( isset( $this->config['require'] ) ) { foreach ( $this->config['require'] as $path ) { if ( ! file_exists( $path ) ) { diff --git a/php/config-spec.php b/php/config-spec.php index c54c99dbfc..b3112b2fbe 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -13,6 +13,12 @@ 'desc' => 'Perform operation against a remote server over SSH.', ), + 'http' => array( + 'runtime' => '=<http>', + 'file' => '<http>', + 'desc' => 'Perform operation against a remote WordPress install over HTTP.', + ), + 'url' => array( 'runtime' => '=<url>', 'file' => '<url>', From f47f3b47bb14c25e7243bf052ae943c1172cd05e Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 21:47:51 +0100 Subject: [PATCH 4697/4858] Make 'nightly' rather than 'trunk' the canonical term for nightly builds. --- features/core-download.feature | 32 ++++++++++++++++---------------- php/commands/core.php | 8 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/features/core-download.feature b/features/core-download.feature index 2973f91fda..1d6f556e95 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -96,20 +96,20 @@ Feature: Download WordPress File removed: wp-content """ - Scenario: Installing trunk + Scenario: Installing nightly Given an empty directory And an empty cache - When I run `wp core download --version=trunk` + When I run `wp core download --version=nightly` Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/wordpress-trunk-en_US.zip file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip file should exist And STDOUT should contain: """ - Downloading WordPress trunk (en_US)... + Downloading WordPress nightly (en_US)... """ And STDERR should contain: """ - Warning: md5 hash checks are not available for trunk downloads. + Warning: md5 hash checks are not available for nightly downloads. """ And STDOUT should contain: """ @@ -117,19 +117,19 @@ Feature: Download WordPress """ # test core zip cache - When I run `wp core download --version=trunk --force` + When I run `wp core download --version=nightly --force` Then the wp-settings.php file should exist And STDOUT should contain: """ - Using cached file '{SUITE_CACHE_DIR}/core/wordpress-trunk-en_US.zip'... + Using cached file '{SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip'... """ - Scenario: Installing trunk over an existing install + Scenario: Installing nightly over an existing install Given an empty directory And an empty cache When I run `wp core download --version=4.5.3` Then the wp-settings.php file should exist - When I run `wp core download --version=trunk --force` + When I run `wp core download --version=nightly --force` Then STDERR should not contain: """ Warning: Failed to find WordPress version. Please cleanup files manually. @@ -143,10 +143,10 @@ Feature: Download WordPress Success: WordPress downloaded. """ - Scenario: Installing a version over trunk + Scenario: Installing a version over nightly Given an empty directory And an empty cache - When I run `wp core download --version=trunk` + When I run `wp core download --version=nightly` Then the wp-settings.php file should exist And STDERR should not contain: """ @@ -161,19 +161,19 @@ Feature: Download WordPress File removed: wp-content """ - Scenario: Nightly is an alias for trunk + Scenario: Trunk is an alias for nightly Given an empty directory And an empty cache - When I run `wp core download --version=nightly` + When I run `wp core download --version=trunk` Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/wordpress-trunk-en_US.zip file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip file should exist And STDOUT should contain: """ - Downloading WordPress trunk (en_US)... + Downloading WordPress nightly (en_US)... """ And STDERR should contain: """ - Warning: md5 hash checks are not available for trunk downloads. + Warning: md5 hash checks are not available for nightly downloads. """ And STDOUT should contain: """ diff --git a/php/commands/core.php b/php/commands/core.php index ad766deed2..c6aa6c64b8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -135,7 +135,7 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { $version = strtolower( $assoc_args['version'] ); - $version = ( 'nightly' === $version ? 'trunk' : $version ); + $version = ( 'trunk' === $version ? 'nightly' : $version ); $download_url = $this->get_download_url($version, $locale, 'tar.gz'); } else { $offer = $this->get_download_offer( $locale ); @@ -194,7 +194,7 @@ public function download( $args, $assoc_args ) { WP_CLI::error( "Couldn't access download URL (HTTP code {$response->status_code})." ); } - if ( 'trunk' !== $version ) { + if ( 'nightly' !== $version ) { $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})." ); @@ -208,7 +208,7 @@ public function download( $args, $assoc_args ) { WP_CLI::error( "md5 hash for download ({$md5_file}) is different than the release hash ({$md5_response->body})." ); } } else { - WP_CLI::warning( 'md5 hash checks are not available for trunk downloads.' ); + WP_CLI::warning( 'md5 hash checks are not available for nightly downloads.' ); } try { @@ -1394,7 +1394,7 @@ function update_db( $_, $assoc_args ) { */ private function get_download_url( $version, $locale = 'en_US', $file_type = 'zip' ) { - if ( 'trunk' === $version ) { + if ( 'nightly' === $version ) { return 'https://wordpress.org/nightly-builds/wordpress-latest.zip'; } elseif ( 'en_US' === $locale ) { $url = 'https://wordpress.org/wordpress-' . $version . '.' . $file_type; From b460dd14b50933a9631b531f6dfb642e6cf6e4a9 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 21:50:10 +0100 Subject: [PATCH 4698/4858] Correct error message --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index c6aa6c64b8..c25340552c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -262,7 +262,7 @@ private static function _extract_tarball( $tarball, $dest ) { private static function _extract_zip( $zipfile, $dest ) { if ( ! class_exists( 'ZipArchive' ) ) { - throw new \Exception( 'Extracting a zip file requires PharData' ); + throw new \Exception( 'Extracting a zip file requires ZipArchive.' ); } $zip = new ZipArchive(); $res = $zip->open( $zipfile ); From d150a21ef07df5c0c7f6dc384f38d4bb84ba81b7 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 21:50:27 +0100 Subject: [PATCH 4699/4858] Add early check so we don't download a zip file if we can't unzip it. --- php/commands/core.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index c25340552c..08dce97eb7 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -159,6 +159,9 @@ public function download( $args, $assoc_args ) { $extension = 'tar.gz'; if ( 'zip' === $path_parts['extension'] ) { $extension = 'zip'; + if ( ! class_exists( 'ZipArchive' ) ) { + WP_CLI::error( 'Extracting a zip file requires ZipArchive.' ); + } } $cache = WP_CLI::get_cache(); From dfd697b966689134fadb63186bd1a325847d3f21 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 21:55:36 +0100 Subject: [PATCH 4700/4858] When requesting the download url of the nightly build, always request a zip file as tarballs are not available. --- php/commands/core.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 08dce97eb7..3736046e34 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -136,7 +136,9 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { $version = strtolower( $assoc_args['version'] ); $version = ( 'trunk' === $version ? 'nightly' : $version ); - $download_url = $this->get_download_url($version, $locale, 'tar.gz'); + //nightly builds are only avialable in .zip format + $ext = ( 'nightly' === $version ? 'zip' : 'tar.gz' ); + $download_url = $this->get_download_url( $version, $locale, $ext ); } else { $offer = $this->get_download_offer( $locale ); if ( !$offer ) { From a3bc8422b2d74849c22d4af1dca53add399cecbf Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 21:56:17 +0100 Subject: [PATCH 4701/4858] Respond with an error if a tarball is requested for the nightly version. --- php/commands/core.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 3736046e34..12cd9a5e16 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1400,7 +1400,11 @@ function update_db( $_, $assoc_args ) { private function get_download_url( $version, $locale = 'en_US', $file_type = 'zip' ) { if ( 'nightly' === $version ) { - return 'https://wordpress.org/nightly-builds/wordpress-latest.zip'; + if ( 'zip' === $version ) { + return 'https://wordpress.org/nightly-builds/wordpress-latest.zip'; + } else { + WP_CLI::error( 'Nightly builds are only available in .zip format.' ); + } } elseif ( 'en_US' === $locale ) { $url = 'https://wordpress.org/wordpress-' . $version . '.' . $file_type; From 6cc9cf4caee21caa44cae1266d7f259988f98247 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 21:59:40 +0100 Subject: [PATCH 4702/4858] Give an error if an unknown extension is requested. --- php/commands/core.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 12cd9a5e16..1501d09a49 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -234,14 +234,18 @@ public function download( $args, $assoc_args ) { private static function _extract( $tarball_or_zip, $dest ) { $path_parts = pathinfo( $tarball_or_zip ); + $extension = strtolower( $path_parts['extension'] ); - switch ( strtolower( $path_parts['extension'] ) ) { + switch ( $extension ) { case 'zip': self::_extract_zip( $tarball_or_zip, $dest ); break; - default; + case 'tar.gz': self::_extract_tarball( $tarball_or_zip, $dest ); break; + default; + WP_CLI::error( sprintf( 'Extension %s not supported.', $extension ) ); + break; } } From 32eb232ada3c3f37685be15f7a4265a682e71366 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 22:00:57 +0100 Subject: [PATCH 4703/4858] Split ifelse statement up for readability. --- php/commands/core.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index 1501d09a49..cd34db2b0c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1409,7 +1409,9 @@ private function get_download_url( $version, $locale = 'en_US', $file_type = 'zi } else { WP_CLI::error( 'Nightly builds are only available in .zip format.' ); } - } elseif ( 'en_US' === $locale ) { + } + + if ( 'en_US' === $locale ) { $url = 'https://wordpress.org/wordpress-' . $version . '.' . $file_type; return $url; From b5754758b82ceee6713a79e6ebbeecc4ff199e11 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 22:37:28 +0100 Subject: [PATCH 4704/4858] Fix typo - check file type not version --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index cd34db2b0c..11e89de27c 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1404,7 +1404,7 @@ function update_db( $_, $assoc_args ) { private function get_download_url( $version, $locale = 'en_US', $file_type = 'zip' ) { if ( 'nightly' === $version ) { - if ( 'zip' === $version ) { + if ( 'zip' === $file_type ) { return 'https://wordpress.org/nightly-builds/wordpress-latest.zip'; } else { WP_CLI::error( 'Nightly builds are only available in .zip format.' ); From 649719a96c5502d59f83608315ea10ad3ad10c31 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 22:41:13 +0100 Subject: [PATCH 4705/4858] If a non-default locale is selected for the nightly build, exit with an error. Adds test. --- features/core-download.feature | 11 +++++++++++ php/commands/core.php | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/features/core-download.feature b/features/core-download.feature index 1d6f556e95..a4fddfdb02 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -179,3 +179,14 @@ Feature: Download WordPress """ Success: WordPress downloaded. """ + + Scenario: Installing nightly for a non-default locale + Given an empty directory + And an empty cache + + When I try `wp core download --version=nightly --locale=de_DE` + Then the return code should be 1 + And STDERR should contain: + """ + Error: Nightly builds are only available for the en_US locale. + """ diff --git a/php/commands/core.php b/php/commands/core.php index 11e89de27c..d9729eabf8 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -148,6 +148,10 @@ public function download( $args, $assoc_args ) { $download_url = str_replace( '.zip', '.tar.gz', $offer['download'] ); } + if ( 'nightly' === $version && 'en_US' !== $locale ) { + WP_CLI::error( 'Nightly builds are only available for the en_US locale.' ); + } + $from_version = ''; if ( file_exists( $download_dir . 'wp-includes/version.php' ) ) { global $wp_version; From e9d7d8326fb448cb14ca049cb0d2ad3e7678f203 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Fri, 8 Jul 2016 22:45:55 +0100 Subject: [PATCH 4706/4858] Check for extension type, and return an error if the extension is not supported. --- php/commands/core.php | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index d9729eabf8..d234e3a632 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -238,19 +238,16 @@ public function download( $args, $assoc_args ) { private static function _extract( $tarball_or_zip, $dest ) { $path_parts = pathinfo( $tarball_or_zip ); - $extension = strtolower( $path_parts['extension'] ); - switch ( $extension ) { - case 'zip': - self::_extract_zip( $tarball_or_zip, $dest ); - break; - case 'tar.gz': - self::_extract_tarball( $tarball_or_zip, $dest ); - break; - default; - WP_CLI::error( sprintf( 'Extension %s not supported.', $extension ) ); - break; + if ( preg_match( '/\.zip$/', $tarball_or_zip ) ) { + return self::_extract_zip( $tarball_or_zip, $dest ); } + + if ( preg_match( '/\.tar\.gz$/', $tarball_or_zip ) ) { + return self::_extract_tarball( $tarball_or_zip, $dest ); + } + + WP_CLI::error( sprintf( 'Extension %s not supported.', $extension ) ); } private static function _extract_tarball( $tarball, $dest ) { From b9d3a69f558696a938815e9d33005dd8f1342605 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Sat, 9 Jul 2016 00:22:04 +0100 Subject: [PATCH 4707/4858] Fix typo --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index d234e3a632..20715a5770 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -136,7 +136,7 @@ public function download( $args, $assoc_args ) { if ( isset( $assoc_args['version'] ) ) { $version = strtolower( $assoc_args['version'] ); $version = ( 'trunk' === $version ? 'nightly' : $version ); - //nightly builds are only avialable in .zip format + //nightly builds are only available in .zip format $ext = ( 'nightly' === $version ? 'zip' : 'tar.gz' ); $download_url = $this->get_download_url( $version, $locale, $ext ); } else { From bad34e07f0b19cc636990a44d27f85d0515a68b1 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Sat, 9 Jul 2016 00:30:57 +0100 Subject: [PATCH 4708/4858] Don't cache nightly builds --- features/core-download.feature | 7 +++---- php/commands/core.php | 7 +++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/features/core-download.feature b/features/core-download.feature index a4fddfdb02..f08adcf134 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -102,7 +102,7 @@ Feature: Download WordPress When I run `wp core download --version=nightly` Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip file should exist + And the {SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip file should not exist And STDOUT should contain: """ Downloading WordPress nightly (en_US)... @@ -116,10 +116,10 @@ Feature: Download WordPress Success: WordPress downloaded. """ - # test core zip cache + # we shouldn't cache nightly builds When I run `wp core download --version=nightly --force` Then the wp-settings.php file should exist - And STDOUT should contain: + And STDOUT should not contain: """ Using cached file '{SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip'... """ @@ -166,7 +166,6 @@ Feature: Download WordPress And an empty cache When I run `wp core download --version=trunk` Then the wp-settings.php file should exist - And the {SUITE_CACHE_DIR}/core/wordpress-nightly-en_US.zip file should exist And STDOUT should contain: """ Downloading WordPress nightly (en_US)... diff --git a/php/commands/core.php b/php/commands/core.php index 20715a5770..daa5891abd 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -225,8 +225,11 @@ public function download( $args, $assoc_args ) { } catch ( Exception $e ) { WP_CLI::error( "Couldn't extract WordPress archive. " . $e->getMessage() ); } - $cache->import( $cache_key, $temp ); - unlink($temp); + + if ( 'nightly' !== $version ) { + $cache->import( $cache_key, $temp ); + } + unlink( $temp ); } if ( $wordpress_present ) { From da09c5a95702b086b036e3dd37e94e55fbff7c29 Mon Sep 17 00:00:00 2001 From: Stephen Harris <contact@stephenharris.info> Date: Sat, 9 Jul 2016 00:31:33 +0100 Subject: [PATCH 4709/4858] Add details of acceptable values to --version documentation --- php/commands/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/core.php b/php/commands/core.php index daa5891abd..40ac3ed3be 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -95,7 +95,7 @@ function check_update( $_, $assoc_args ) { * : Select which language you want to download. * * [--version=<version>] - * : Select which version you want to download. + * : Select which version you want to download. Accepts a version number, 'latest' or 'nightly' * * [--force] * : Overwrites existing files, if present. From 2217ca9bc1febdac917ebb29cd7d06ee2cbbbecd Mon Sep 17 00:00:00 2001 From: Utkarsh Patel <iamutkarsh@live.com> Date: Sat, 9 Jul 2016 16:16:48 +0530 Subject: [PATCH 4710/4858] Add verbosity to wp role reset fixes #3110 --- php/commands/role.php | 87 +++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/php/commands/role.php b/php/commands/role.php index 2df328bd47..6d4c95b0bd 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -260,70 +260,75 @@ public function reset( $args, $assoc_args ) { if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { foreach( $default_roles as $role ) { + $before[ $role ] = get_role( $role ); remove_role( $role ); + $args[]= $role; } populate_roles(); + } else { - WP_CLI::success( 'All default roles reset.' ); - return; - - } - - foreach( $args as $k => $role_key ) { - $key = array_search( $role_key, $default_roles ); - if ( false !== $key ) { - unset( $preserve[ $key ] ); - $before[ $role_key ] = get_role( $role_key ); - remove_role( $role_key ); - } else { - unset( $args[ $k ] ); + foreach ( $args as $k => $role_key ) { + $key = array_search( $role_key, $default_roles ); + if ( false !== $key ) { + unset( $preserve[ $key ] ); + $before[ $role_key ] = get_role( $role_key ); + remove_role( $role_key ); + } else { + unset( $args[ $k ] ); + } } - } - $num_to_reset = count( $args ); + $num_to_reset = count( $args ); - // no roles were unset, bail - if ( count( $default_roles ) == count( $preserve ) ) { - WP_CLI::error( 'Must specify a default role to reset.' ); - } + // no roles were unset, bail + if ( count( $default_roles ) == count( $preserve ) ) { + WP_CLI::error( 'Must specify a default role to reset.' ); + } - // for the roles we're not resetting - foreach( $preserve as $k => $role ) { - /* save roles - * if get_role is null - * save role name for re-removal - */ - $roleobj = get_role( $role ); - $preserve[$k] = is_null( $roleobj ) ? $role : $roleobj; + // for the roles we're not resetting + foreach ( $preserve as $k => $role ) { + /* save roles + * if get_role is null + * save role name for re-removal + */ + $roleobj = get_role( $role ); + $preserve[ $k ] = is_null( $roleobj ) ? $role : $roleobj; - remove_role( $role ); - } + remove_role( $role ); + } - // put back all default roles and capabilities - populate_roles(); + // put back all default roles and capabilities + populate_roles(); - // restore the preserved roles - foreach( $preserve as $k => $roleobj ) { - // re-remove after populating - if ( is_a( $roleobj, 'WP_Role' ) ) { - remove_role( $roleobj->name ); - add_role( $roleobj->name, ucwords( $roleobj->name ), $roleobj->capabilities ); - } else { - // when not an object, that means the role didn't exist before - remove_role( $roleobj ); + // restore the preserved roles + foreach ( $preserve as $k => $roleobj ) { + // re-remove after populating + if ( is_a( $roleobj, 'WP_Role' ) ) { + remove_role( $roleobj->name ); + add_role( $roleobj->name, ucwords( $roleobj->name ), $roleobj->capabilities ); + } else { + // when not an object, that means the role didn't exist before + remove_role( $roleobj ); + } } } $num_reset = 0; + $args = array_unique( $args ); foreach( $args as $role_key ) { $after[ $role_key ] = get_role( $role_key ); if ( $after[ $role_key ] != $before[ $role_key ] ) { ++$num_reset; + $after_cap_count = count( $after[ $role_key ]->capabilities ); + $before_cap_count = count( $before[ $role_key ]->capabilities ); + WP_CLI::log( "Restored {$after_cap_count} capabilities to and removed {$before_cap_count} capabilities from '{$role_key}' role." ); + } else { + WP_CLI::log( "No changes necessary for '{$role_key}' role." ); } } - WP_CLI::success( "Reset $num_reset/$num_to_reset roles." ); + WP_CLI::success( "Success: Role reset." ); } From fb74d0bb916dd3c884e403741c3282bdc7de57b3 Mon Sep 17 00:00:00 2001 From: Utkarsh Patel <iamutkarsh@live.com> Date: Sat, 9 Jul 2016 16:48:33 +0530 Subject: [PATCH 4711/4858] Success message update --- php/commands/role.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/role.php b/php/commands/role.php index 6d4c95b0bd..10858f9817 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -328,7 +328,7 @@ public function reset( $args, $assoc_args ) { } } - WP_CLI::success( "Success: Role reset." ); + WP_CLI::success( "Role reset." ); } From e3bbcd5ab5d9ebaf6169a08cac9b2ef11fed4ade Mon Sep 17 00:00:00 2001 From: Utkarsh Patel <iamutkarsh@live.com> Date: Sat, 9 Jul 2016 16:54:32 +0530 Subject: [PATCH 4712/4858] Update test for roles feature --- features/roles.feature | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index 54631936d6..b714e309e3 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -20,33 +20,44 @@ Feature: Manage WordPress roles When I run `wp role reset author` Then STDOUT should be: """ - Success: Reset 0/1 roles. + No changes necessary for 'author' role. + Success: Role reset. """ When I run `wp cap remove author read` And I run `wp role reset author` Then STDOUT should be: """ - Success: Reset 1/1 roles. + Restored 10 capabilities to and removed 9 capabilities from 'author' role. + Success: Role reset. """ When I run `wp role reset author editor` Then STDOUT should be: """ - Success: Reset 0/2 roles. + No changes necessary for 'author' role. + No changes necessary for 'editor' role. + Success: Role reset. """ When I run `wp cap remove author read` And I run `wp role reset author editor` Then STDOUT should be: """ - Success: Reset 1/2 roles. + Restored 10 capabilities to and removed 9 capabilities from 'author' role. + No changes necessary for 'editor' role. + Success: Role reset. """ When I run `wp role reset --all` Then STDOUT should be: """ - Success: All default roles reset. + No changes necessary for 'administrator' role. + No changes necessary for 'editor' role. + No changes necessary for 'author' role. + No changes necessary for 'contributor' role. + No changes necessary for 'subscriber' role. + Success: Role reset. """ Scenario: Cloning a role From 9db0bfb8689ad3ab071b42adc956b3d302e1e3a2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 9 Jul 2016 05:39:02 -0700 Subject: [PATCH 4713/4858] Use `wp core download --version=trunk` in Travis --- ci/prepare.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/ci/prepare.sh b/ci/prepare.sh index bbf2aa502b..852e3f760b 100755 --- a/ci/prepare.sh +++ b/ci/prepare.sh @@ -30,14 +30,7 @@ echo $CLI_VERSION > PHAR_BUILD_VERSION # Install CodeSniffer things ./ci/prepare-codesniffer.sh -if [[ $WP_VERSION == "trunk" ]] -then - wget https://wordpress.org/nightly-builds/wordpress-latest.zip - unzip wordpress-latest.zip - mv wordpress '/tmp/wp-cli-test core-download-cache/' -else - ./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' -fi +./bin/wp core download --version=$WP_VERSION --path='/tmp/wp-cli-test core-download-cache/' ./bin/wp core version --path='/tmp/wp-cli-test core-download-cache/' From fa07924fa5390de5bd9ee0f7547f1da31e2ba364 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 9 Jul 2016 05:48:22 -0700 Subject: [PATCH 4714/4858] Support `--http=<url>` in an alias --- php/WP_CLI/Configurator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 1e467e9d9e..26780faaa3 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -197,6 +197,7 @@ public function merge_yml( $path ) { 'url', 'path', 'ssh', + 'http', ) as $i ) { if ( isset( $value[ $i ] ) ) { $this->aliases[ $key ][ $i ] = $value[ $i ]; From 68ced63e51c25e243622ca96e5d8474ff8ca714d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Sat, 9 Jul 2016 05:56:38 -0700 Subject: [PATCH 4715/4858] Permit managing packages and running `wp cli info` over SSH --- php/WP_CLI/Runner.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 7f53d592bc..72d81494d7 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -727,14 +727,16 @@ public function start() { if ( empty( $this->arguments ) ) $this->arguments[] = 'help'; - // Protect 'cli info' from most of the runtime - if ( 'cli' === $this->arguments[0] && ! empty( $this->arguments[1] ) && 'info' === $this->arguments[1] ) { + // Protect 'cli info' from most of the runtime, + // except when the command will be run over SSH + if ( 'cli' === $this->arguments[0] && ! empty( $this->arguments[1] ) && 'info' === $this->arguments[1] && ! $this->config['ssh'] ) { $this->_run_command(); exit; } - // Protect 'package' commands from most of the runtime too - if ( 'package' === $this->arguments[0] ) { + // Protect 'package' commands from most of the runtime too, + // except when the command will be run over SSH + if ( 'package' === $this->arguments[0] && ! $this->config['ssh'] ) { $this->_run_command(); exit; } From f54d7078174e5baccca102f99188bb92f383cb4c Mon Sep 17 00:00:00 2001 From: Utkarsh Patel <iamutkarsh@live.com> Date: Sat, 9 Jul 2016 20:05:51 +0530 Subject: [PATCH 4716/4858] Update reset role to show number of roles affected --- features/roles.feature | 10 +++++----- php/commands/role.php | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index b714e309e3..536dc8883e 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -21,7 +21,7 @@ Feature: Manage WordPress roles Then STDOUT should be: """ No changes necessary for 'author' role. - Success: Role reset. + Success: Roles reset 0/1. """ When I run `wp cap remove author read` @@ -29,7 +29,7 @@ Feature: Manage WordPress roles Then STDOUT should be: """ Restored 10 capabilities to and removed 9 capabilities from 'author' role. - Success: Role reset. + Success: Role reset 1/1. """ When I run `wp role reset author editor` @@ -37,7 +37,7 @@ Feature: Manage WordPress roles """ No changes necessary for 'author' role. No changes necessary for 'editor' role. - Success: Role reset. + Success: Roles reset 0/2. """ When I run `wp cap remove author read` @@ -46,7 +46,7 @@ Feature: Manage WordPress roles """ Restored 10 capabilities to and removed 9 capabilities from 'author' role. No changes necessary for 'editor' role. - Success: Role reset. + Success: Role reset 1/2. """ When I run `wp role reset --all` @@ -57,7 +57,7 @@ Feature: Manage WordPress roles No changes necessary for 'author' role. No changes necessary for 'contributor' role. No changes necessary for 'subscriber' role. - Success: Role reset. + Success: Roles reset 0/5. """ Scenario: Cloning a role diff --git a/php/commands/role.php b/php/commands/role.php index 10858f9817..419d7624cf 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -257,6 +257,7 @@ public function reset( $args, $assoc_args ) { // get our default roles $default_roles = $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); + $before = array(); if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { foreach( $default_roles as $role ) { @@ -278,8 +279,6 @@ public function reset( $args, $assoc_args ) { } } - $num_to_reset = count( $args ); - // no roles were unset, bail if ( count( $default_roles ) == count( $preserve ) ) { WP_CLI::error( 'Must specify a default role to reset.' ); @@ -291,7 +290,7 @@ public function reset( $args, $assoc_args ) { * if get_role is null * save role name for re-removal */ - $roleobj = get_role( $role ); + $roleobj = get_role( $role ); $preserve[ $k ] = is_null( $roleobj ) ? $role : $roleobj; remove_role( $role ); @@ -315,6 +314,7 @@ public function reset( $args, $assoc_args ) { $num_reset = 0; $args = array_unique( $args ); + $num_to_reset = count( $args ); foreach( $args as $role_key ) { $after[ $role_key ] = get_role( $role_key ); @@ -328,7 +328,7 @@ public function reset( $args, $assoc_args ) { } } - WP_CLI::success( "Role reset." ); + WP_CLI::success( _n( 'Role', 'Roles', $num_reset ). " reset {$num_reset}/{$num_to_reset}." ); } From 764488c2e21061833ce84539aa86a5c08dd60179 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sun, 10 Jul 2016 06:49:40 +0545 Subject: [PATCH 4717/4858] Adding more explanation in doc of scaffold plugin --- php/commands/scaffold.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index d83f792c82..c78c8ed1b7 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -409,16 +409,19 @@ private function get_output_path( $assoc_args, $subdir ) { * * * `plugin-slug.php` is the main PHP plugin file. * * `readme.txt` is the readme file for the plugin. - * * `package.json` needed by NPM holds various metadata relevant to the project. - * * `Gruntfile.js` is the JS file containing Grunt tasks. - * * `phpunit.xml.dist` is the configuration file for PHPUnit. + * * `package.json` needed by NPM holds various metadata relevant to the project. Packages: `grunt`, `grunt-wp-i18n` and `grunt-wp-readme-to-markdown`. + * * `Gruntfile.js` is the JS file containing Grunt tasks. Tasks: `i18n` containing `addtextdomain` and `makepot`, `readme` containing `wp_readme_to_markdown`. * * `.editorconfig` is the configuration file for Editor. * * `.gitignore` tells which files (or patterns) git should ignore. * * `.distignore` tells which files and folders should be ignored in distribution. + * + * The following files are also generated if tests are not skipped using `--skip-tests`: + * + * * `phpunit.xml.dist` is the configuration file for PHPUnit. * * `.travis.yml` is the configuration file for Travis CI. * * `bin/install-wp-tests.sh` configures the WordPress test suite and a test database. * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite. - * * `tests/test-sample.php` is a sample file containing the actual tests. + * * `tests/test-sample.php` is a sample file containing test cases. * * ## OPTIONS * From aa09c41f8c7d9d36f7b9b21ab0523f14b0ec5cc4 Mon Sep 17 00:00:00 2001 From: Utkarsh Patel <iamutkarsh@live.com> Date: Sun, 10 Jul 2016 22:33:55 +0530 Subject: [PATCH 4718/4858] Add more verbosity to role reset command --- features/roles.feature | 14 +++++++------- php/commands/role.php | 24 ++++++++++++++++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/features/roles.feature b/features/roles.feature index 536dc8883e..65daa3024c 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -21,15 +21,15 @@ Feature: Manage WordPress roles Then STDOUT should be: """ No changes necessary for 'author' role. - Success: Roles reset 0/1. + Success: Role didn't need resetting. """ When I run `wp cap remove author read` And I run `wp role reset author` Then STDOUT should be: """ - Restored 10 capabilities to and removed 9 capabilities from 'author' role. - Success: Role reset 1/1. + Restored 1 capabilities to and removed 0 capabilities from 'author' role. + Success: Role reset. """ When I run `wp role reset author editor` @@ -37,16 +37,16 @@ Feature: Manage WordPress roles """ No changes necessary for 'author' role. No changes necessary for 'editor' role. - Success: Roles reset 0/2. + Success: No roles needed resetting. """ When I run `wp cap remove author read` And I run `wp role reset author editor` Then STDOUT should be: """ - Restored 10 capabilities to and removed 9 capabilities from 'author' role. + Restored 1 capabilities to and removed 0 capabilities from 'author' role. No changes necessary for 'editor' role. - Success: Role reset 1/2. + Success: 1 of 2 roles reset. """ When I run `wp role reset --all` @@ -57,7 +57,7 @@ Feature: Manage WordPress roles No changes necessary for 'author' role. No changes necessary for 'contributor' role. No changes necessary for 'subscriber' role. - Success: Roles reset 0/5. + Success: No roles needed resetting. """ Scenario: Cloning a role diff --git a/php/commands/role.php b/php/commands/role.php index 419d7624cf..16e37cf9c5 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -320,16 +320,28 @@ public function reset( $args, $assoc_args ) { if ( $after[ $role_key ] != $before[ $role_key ] ) { ++$num_reset; - $after_cap_count = count( $after[ $role_key ]->capabilities ); - $before_cap_count = count( $before[ $role_key ]->capabilities ); - WP_CLI::log( "Restored {$after_cap_count} capabilities to and removed {$before_cap_count} capabilities from '{$role_key}' role." ); + $restored_cap = array_diff_key( $after[ $role_key ]->capabilities, $before[ $role_key ]->capabilities ); + $removed_cap = array_diff_key( $before[ $role_key ]->capabilities, $after[ $role_key ]->capabilities ); + $restored_cap_count = count( $restored_cap ); + $removed_cap_count = count( $removed_cap ); + WP_CLI::log( "Restored {$restored_cap_count} capabilities to and removed {$removed_cap_count} capabilities from '{$role_key}' role." ); } else { WP_CLI::log( "No changes necessary for '{$role_key}' role." ); } } - - WP_CLI::success( _n( 'Role', 'Roles', $num_reset ). " reset {$num_reset}/{$num_to_reset}." ); - + if ( $num_reset ) { + if ( 1 === count( $args ) ) { + WP_CLI::success( 'Role reset.' ); + } else { + WP_CLI::success( "{$num_reset} of {$num_to_reset} roles reset." ); + } + } else { + if ( 1 === count( $args ) ) { + WP_CLI::success( 'Role didn\'t need resetting.' ); + } else { + WP_CLI::success( 'No roles needed resetting.' ); + } + } } private static function persistence_check() { From f7426da64866c93fa8a34dec8b011d2ce1309b2f Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 11 Jul 2016 16:33:57 +0545 Subject: [PATCH 4719/4858] Improving doc and default value in core commands --- php/commands/core.php | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 40ac3ed3be..eafc38a57d 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -318,7 +318,7 @@ private static function _copy_overwrite_files( $source, $dest ) { copy( $item, $dest_path ); } else { $error = 1; - WP_CLI::warning( 'Unable to copy ' . $iterator->getSubPathName() . ' to current directory.' ); + WP_CLI::warning( "Unable to copy '" . $iterator->getSubPathName() . "' to current directory." ); } } } @@ -390,16 +390,28 @@ private static function get_initial_locale() { * : Set the database user password. * * [--dbhost=<dbhost>] - * : Set the database host. Default: 'localhost' + * : Set the database host. + * --- + * default: localhost + * --- * * [--dbprefix=<dbprefix>] - * : Set the database table prefix. Default: 'wp_' + * : Set the database table prefix. + * --- + * default: wp_ + * --- * * [--dbcharset=<dbcharset>] - * : Set the database charset. Default: 'utf8' + * : Set the database charset. + * --- + * default: utf8 + * --- * * [--dbcollate=<dbcollate>] - * : Set the database collation. Default: '' + * : Set the database collation. + * --- + * default: + * --- * * [--locale=<locale>] * : Set the WPLANG constant. Defaults to $wp_local_package variable. @@ -488,7 +500,7 @@ public function config( $_, $assoc_args ) { * Determine if the WordPress tables are installed. * * [--network] - * : Check if this is a multisite install + * : Check if this is a multisite install. * * ## EXAMPLES * @@ -578,7 +590,9 @@ public function install( $args, $assoc_args ) { * * [--base=<url-path>] * : Base path after the domain name that each site url will start with. - * Default: '/' + * --- + * default: / + * --- * * [--subdomains] * : If passed, the network will use subdomains, instead of subdirectories. Doesn't work with 'localhost'. @@ -617,7 +631,9 @@ public function multisite_convert( $args, $assoc_args ) { * * [--base=<url-path>] * : Base path after the domain name that each site url in the network will start with. - * Default: '/' + * --- + * default: / + * --- * * [--subdomains] * : If passed, the network will use subdomains, instead of subdirectories. Doesn't work with 'localhost'. @@ -626,7 +642,10 @@ public function multisite_convert( $args, $assoc_args ) { * : The title of the new site. * * --admin_user=<username> - * : The name of the admin user. Default: 'admin' + * : The name of the admin user. + * --- + * default: admin + * --- * * --admin_password=<password> * : The password for the admin user. @@ -1333,7 +1352,7 @@ function update( $args, $assoc_args ) { * * # Update the WordPress database * $ wp core update-db - * Success: WordPress database upgraded successfully from db version 36686 to 35700 + * Success: WordPress database upgraded successfully from db version 36686 to 35700. * * # Update databases for all sites on a network * $ wp core update-db --network From a7243fa1ef06ff249b8bd9bda44286a2d892302f Mon Sep 17 00:00:00 2001 From: Utkarsh Patel <iamutkarsh@live.com> Date: Mon, 11 Jul 2016 23:15:07 +0530 Subject: [PATCH 4720/4858] Role reset, custom role not affected verbosity add --- features/roles.feature | 40 ++++++++++++++++++++++++++++++++++++++++ php/commands/role.php | 17 +++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/features/roles.feature b/features/roles.feature index 65daa3024c..2c6a9fb348 100644 --- a/features/roles.feature +++ b/features/roles.feature @@ -60,6 +60,46 @@ Feature: Manage WordPress roles Success: No roles needed resetting. """ + When I run `wp role create custom-role "Custom role" --clone=author` + And I run `wp role reset --all` + Then STDOUT should be: + """ + Custom role 'custom-role' not affected. + No changes necessary for 'administrator' role. + No changes necessary for 'editor' role. + No changes necessary for 'author' role. + No changes necessary for 'contributor' role. + No changes necessary for 'subscriber' role. + Success: No roles needed resetting. + """ + + When I try `wp role reset custom-role` + Then STDERR should contain: + """ + Error: Must specify a default role to reset. + """ + And STDOUT should contain: + """ + Custom role 'custom-role' not affected. + """ + + When I run `wp role reset custom-role author` + Then STDOUT should be: + """ + Custom role 'custom-role' not affected. + No changes necessary for 'author' role. + Success: Role didn't need resetting. + """ + + When I run `wp cap remove author read` + And I run `wp role reset custom-role author` + Then STDOUT should be: + """ + Custom role 'custom-role' not affected. + Restored 1 capabilities to and removed 0 capabilities from 'author' role. + Success: Role reset. + """ + Scenario: Cloning a role When I try `wp role create reporter Reporter --clone=no-role` Then STDERR should be: diff --git a/php/commands/role.php b/php/commands/role.php index 16e37cf9c5..0be1a41166 100644 --- a/php/commands/role.php +++ b/php/commands/role.php @@ -255,6 +255,10 @@ public function reset( $args, $assoc_args ) { require_once( ABSPATH.'wp-admin/includes/schema.php' ); } + global $wp_roles; + $all_roles = array_keys( $wp_roles->roles ); + $preserve_args = $args; + // get our default roles $default_roles = $preserve = array( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); $before = array(); @@ -266,6 +270,12 @@ public function reset( $args, $assoc_args ) { $args[]= $role; } populate_roles(); + $not_affected_roles = array_diff( $all_roles, $default_roles ); + if ( ! empty( $not_affected_roles ) ) { + foreach ( $not_affected_roles as $not_affected_role ) { + WP_CLI::log( "Custom role '{$not_affected_role}' not affected." ); + } + } } else { foreach ( $args as $k => $role_key ) { @@ -279,6 +289,13 @@ public function reset( $args, $assoc_args ) { } } + $not_affected_roles = array_diff( $preserve_args, $default_roles ); + if ( ! empty( $not_affected_roles ) ) { + foreach ( $not_affected_roles as $not_affected_role ) { + WP_CLI::log( "Custom role '{$not_affected_role}' not affected." ); + } + } + // no roles were unset, bail if ( count( $default_roles ) == count( $preserve ) ) { WP_CLI::error( 'Must specify a default role to reset.' ); From 01a06102ef6dddaee153c15aadc1d559417ed394 Mon Sep 17 00:00:00 2001 From: andyexeter <palmer.andy@gmail.com> Date: Mon, 11 Jul 2016 19:29:15 +0100 Subject: [PATCH 4721/4858] Add include-columns flag to search-replace --- php/commands/search-replace.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index a67790ded2..bc2bd8976c 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -37,6 +37,7 @@ class Search_Replace_Command extends WP_CLI_Command { private $recurse_objects; private $regex; private $skip_columns; + private $include_columns; /** * Search/replace strings in the database. @@ -95,6 +96,10 @@ class Search_Replace_Command extends WP_CLI_Command { * : Do not perform the replacement on specific columns. Use commas to * specify multiple columns. 'guid' is skipped by default. * + * [--include-columns=<columns>] + * : Perform the replacement on specific columns. Use commas to + * specify multiple columns. + * * [--precise] * : Force the use of PHP (instead of SQL) which is more thorough, * but slower. @@ -145,6 +150,7 @@ public function __invoke( $args, $assoc_args ) { $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' ) ); + $this->include_columns = array_filter( explode( ',', \WP_CLI\Utils\get_flag_value( $assoc_args, 'include-columns' ) ) ); if ( $old === $new && ! $this->regex ) { WP_CLI::warning( "Replacement value '{$old}' is identical to search value '{$new}'. Skipping operation." ); @@ -201,6 +207,10 @@ public function __invoke( $args, $assoc_args ) { } foreach ( $columns as $col ) { + if ( ! empty( $this->include_columns ) && ! in_array( $col, $this->include_columns ) ) { + continue; + } + if ( in_array( $col, $this->skip_columns ) ) { continue; } From 225254cc4606f715179387f5370f2c91acfbc9b2 Mon Sep 17 00:00:00 2001 From: andyexeter <palmer.andy@gmail.com> Date: Mon, 11 Jul 2016 19:34:09 +0100 Subject: [PATCH 4722/4858] Add functional test for include-columns flag of search-replace --- features/search-replace.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/search-replace.feature b/features/search-replace.feature index 2fd3e14e8a..76705781d4 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -15,6 +15,12 @@ Feature: Do global search/replace guid """ + When I run `wp search-replace foo bar --include-columns=post_content` + Then STDOUT should not contain: + """ + guid + """ + Scenario: Multisite search/replace Given a WP multisite install And I run `wp site create --slug="foo" --title="foo" --email="foo@example.com"` From ae4898399c52a19429f5e0a7903a3d449fb20ea0 Mon Sep 17 00:00:00 2001 From: andyexeter <palmer.andy@gmail.com> Date: Mon, 11 Jul 2016 20:47:52 +0100 Subject: [PATCH 4723/4858] Add more explicit test for include-columns flag --- features/search-replace.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 76705781d4..02cd30988e 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -16,10 +16,10 @@ Feature: Do global search/replace """ When I run `wp search-replace foo bar --include-columns=post_content` - Then STDOUT should not contain: - """ - guid - """ + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_posts | post_content | 0 | SQL | + Scenario: Multisite search/replace Given a WP multisite install From 2ceb45341b52714e8f3e9d44da7cfa49c7c88ea8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Jul 2016 05:21:23 -0700 Subject: [PATCH 4724/4858] Add `--ci=<provider>` argument for plugin test scaffold First up: CircleCI, which has a free private build plan. --- features/scaffold.feature | 21 +++++++++++++++++- php/commands/scaffold.php | 22 +++++++++++++++---- templates/plugin-circle.mustache | 9 ++++++++ ...travis.mustache => plugin-travis.mustache} | 0 4 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 templates/plugin-circle.mustache rename templates/{.travis.mustache => plugin-travis.mustache} (100%) diff --git a/features/scaffold.feature b/features/scaffold.feature index 8c0e6f661b..0e4796cdfe 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -306,7 +306,11 @@ Feature: WordPress code scaffolding install-wp-tests.sh """ And the {PLUGIN_DIR}/hello-world/phpunit.xml.dist file should exist - And the {PLUGIN_DIR}/hello-world/.travis.yml file should exist + And the {PLUGIN_DIR}/hello-world/circle.yml file should not exist + And the {PLUGIN_DIR}/hello-world/.travis.yml file should contain: + """ + script: phpunit + """ When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-wp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` Then STDOUT should be: @@ -314,6 +318,21 @@ Feature: WordPress code scaffolding executable """ + Scenario: Scaffold plugin tests with Circle as the provider + Given a WP install + And I run `wp scaffold plugin hello-world --skip-tests` + + When I run `wp plugin path hello-world --dir` + Then save STDOUT as {PLUGIN_DIR} + + When I run `wp scaffold plugin-tests hello-world --ci=circle` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/.travis.yml file should not exist + And the {PLUGIN_DIR}/circle.yml file should contain: + """ + version: 5.6.14 + """ + Scenario: Scaffold starter code for a theme Given a WP install Given I run `wp theme path` diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index c78c8ed1b7..ec2b0d7284 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -531,7 +531,7 @@ function plugin( $args, $assoc_args ) { * The following files are generated for your plugin by this command: * * * `phpunit.xml.dist` is the configuration file for PHPUnit. - * * `.travis.yml` is the configuration file for Travis CI. + * * `.travis.yml` is the configuration file for Travis CI. Use `--ci=<provider>` to select a different service. * * `bin/install-wp-tests.sh` configures the WordPress test suite and a test database. * * `tests/bootstrap.php` is the file that makes the current plugin active when running the test suite. * * `tests/test-sample.php` is a sample file containing the actual tests. @@ -551,6 +551,15 @@ function plugin( $args, $assoc_args ) { * [--dir=<dirname>] * : Generate test files for a non-standard plugin path. If no plugin slug is specified, the directory name is used. * + * [--ci=<provider>] + * : Add a configuration file for a continuous integration provider. + * --- + * default: travis + * options: + * - travis + * - circle + * --- + * * [--force] * : Overwrite files that already exist. * @@ -616,11 +625,16 @@ function plugin_tests( $args, $assoc_args ) { ); $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); - $files_written = $this->create_files( array( + $files_to_create = array( "$tests_dir/bootstrap.php" => Utils\mustache_render( 'bootstrap.mustache', $plugin_data ), "$tests_dir/test-sample.php" => Utils\mustache_render( 'test-sample.mustache', $plugin_data ), - "$plugin_dir/.travis.yml" => Utils\mustache_render( '.travis.mustache', compact( 'wp_versions_to_test' ) ), - ), $force ); + ); + if ( 'travis' === $assoc_args['ci'] ) { + $files_to_create["$plugin_dir/.travis.yml"] = Utils\mustache_render( 'plugin-travis.mustache', compact( 'wp_versions_to_test' ) ); + } else if ( 'circle' === $assoc_args['ci'] ) { + $files_to_create["$plugin_dir/circle.yml"] = Utils\mustache_render( 'plugin-circle.mustache' ); + } + $files_written = $this->create_files( $files_to_create, $force ); $to_copy = array( 'install-wp-tests.sh' => $bin_dir, diff --git a/templates/plugin-circle.mustache b/templates/plugin-circle.mustache new file mode 100644 index 0000000000..6f1ded7766 --- /dev/null +++ b/templates/plugin-circle.mustache @@ -0,0 +1,9 @@ +machine: + php: + version: 5.6.14 + +test: + pre: + - bash bin/install-wp-tests.sh wordpress_test root '' localhost latest + override: + - phpunit diff --git a/templates/.travis.mustache b/templates/plugin-travis.mustache similarity index 100% rename from templates/.travis.mustache rename to templates/plugin-travis.mustache From fc1c1e888c8f05acdb2b9cedebedae2a283aa2a4 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Jul 2016 09:31:38 -0700 Subject: [PATCH 4725/4858] Define alias regex in one place, and reuse This will prevent it from getting out of sync throughout the codebase. --- php/WP_CLI/Configurator.php | 10 +++++++--- php/WP_CLI/Runner.php | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 26780faaa3..6c0e852f04 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -29,6 +29,11 @@ class Configurator { */ private $aliases = array(); + /** + * @var string ALIAS_REGEX Regex pattern used to define an alias + */ + const ALIAS_REGEX = '^@[A-Za-z0-9-_]+$'; + /** * @param string $path Path to config spec file. */ @@ -187,9 +192,8 @@ public function merge_yml( $path ) { if ( ! empty( $yaml['_']['inherit'] ) ) { $this->merge_yml( $yaml['_']['inherit'] ); } - $alias_regex = '#^@[A-Za-z0-9-_]+$#'; foreach ( $yaml as $key => $value ) { - if ( preg_match( $alias_regex, $key ) ) { + if ( preg_match( '#' . self::ALIAS_REGEX . '#', $key ) ) { $this->aliases[ $key ] = array(); $is_alias = false; foreach( array( @@ -208,7 +212,7 @@ public function merge_yml( $path ) { if ( ! $is_alias && is_array( $value ) ) { $alias_group = array(); foreach( $value as $i => $k ) { - if ( preg_match( $alias_regex, $k ) ) { + if ( preg_match( '#' . self::ALIAS_REGEX . '#', $k ) ) { $alias_group[] = $k; } } diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 72d81494d7..d526256f3a 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -596,7 +596,7 @@ private function init_config() { $argv = array_slice( $GLOBALS['argv'], 1 ); - if ( ! empty( $argv[0] ) && preg_match( '#^@[A-Za-z0-9-_]+$#', $argv[0], $matches ) ) { + if ( ! empty( $argv[0] ) && preg_match( '#' . Configurator::ALIAS_REGEX . '#', $argv[0], $matches ) ) { $this->alias = array_shift( $argv ); } else { $this->alias = null; From 1d0abb829796c561cff3caa01d406a48e98d73e3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Jul 2016 15:18:49 -0700 Subject: [PATCH 4726/4858] Include example command in README.md It's better to show than tell. --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index db835e1698..f0a4667328 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,36 @@ If you have a WordPress.org account, you may also consider joining the `#cli` ch A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another. +WP-CLI supports registering any callable class, function, or closure as a command. It reads usage details from the callback's PHPdoc. `WP_CLI::add_command()` ([doc](https://wp-cli.org/docs/internal-api/wp-cli-add-command/)) is used for both internal and third-party command registration. + +``` +/** + * Delete an option from the database. + * + * Returns an error if the option didn't exist. + * + * ## OPTIONS + * + * <key> + * : Key for the option. + * + * ## EXAMPLES + * + * $ wp option delete my_option + * Success: Deleted 'my_option' option. + */ +$delete_option_cmd = function( $args ) { + list( $key ) = $args; + + if ( ! delete_option( $key ) ) { + WP_CLI::error( "Could not delete '$key' option. Does it exist?" ); + } else { + WP_CLI::success( "Deleted '$key' option." ); + } +}; +WP_CLI::add_command( 'option delete', $delete_option_cmd ); +``` + WP-CLI comes with dozens of commands. It's easier than it looks to create a custom WP-CLI command. Read the [commands cookbook](https://wp-cli.org/docs/commands-cookbook/) to learn more. Browse the [internal API docs](https://wp-cli.org/docs/internal-api/) to discover a variety of helpful functions you can use in your custom WP-CLI command. ## Contributing From b4239a9aec86aa1603f702164b6fbfc827a515f0 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Jul 2016 15:49:12 -0700 Subject: [PATCH 4727/4858] Add missing ## OPTIONS heading throughout --- php/commands/help.php | 2 ++ php/commands/option.php | 6 ++++++ php/commands/super-admin.php | 4 ++++ php/commands/transient.php | 6 ++++++ php/commands/user.php | 6 ++++++ php/commands/widget.php | 14 ++++++++++++++ 6 files changed, 38 insertions(+) diff --git a/php/commands/help.php b/php/commands/help.php index 7210df898e..d07b2802c7 100644 --- a/php/commands/help.php +++ b/php/commands/help.php @@ -8,6 +8,8 @@ class Help_Command extends WP_CLI_Command { /** * Get help on WP-CLI, or on a specific command. * + * ## OPTIONS + * * [<command>...] * : Get help on a specific command. * diff --git a/php/commands/option.php b/php/commands/option.php index 2da0138e39..2da6e107da 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -31,6 +31,8 @@ class Option_Command extends WP_CLI_Command { /** * Get an option. * + * ## OPTIONS + * * <key> * : Key for the option. * @@ -122,6 +124,8 @@ public function add( $args, $assoc_args ) { /** * List options. * + * ## OPTIONS + * * [--search=<pattern>] * : Use wildcards ( * and ? ) to match option name. * @@ -313,6 +317,8 @@ public function update( $args, $assoc_args ) { /** * Delete an option. * + * ## OPTIONS + * * <key> * : Key for the option. * diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index 2537a326e8..d0982a9c91 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -80,6 +80,8 @@ public function _list( $_, $assoc_args ) { /** * Grant super-admin privileges to one or more users. * + * ## OPTIONS + * * <user>... * : One or more user IDs, user emails, or user logins. * @@ -125,6 +127,8 @@ public function add( $args, $_ ) { /** * Revoke super-admin privileges to one or more users. * + * ## OPTIONS + * * <user>... * : One or more user IDs, user emails, or user logins. * diff --git a/php/commands/transient.php b/php/commands/transient.php index 3797d11fce..d68f4950ce 100644 --- a/php/commands/transient.php +++ b/php/commands/transient.php @@ -30,6 +30,8 @@ class Transient_Command extends WP_CLI_Command { /** * Get a transient value. * + * ## OPTIONS + * * <key> * : Key for the transient. * @@ -72,6 +74,8 @@ public function get( $args, $assoc_args ) { /** * Set a transient value. <expiration> is the time until expiration, in seconds. * + * ## OPTIONS + * * <key> * : Key for the transient. * @@ -105,6 +109,8 @@ public function set( $args, $assoc_args ) { /** * Delete a transient value. * + * ## OPTIONS + * * <key> * : Key for the transient. * diff --git a/php/commands/user.php b/php/commands/user.php index b0f93dff48..9da51cec75 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -995,6 +995,8 @@ public function get( $args, $assoc_args ) { /** * Delete a meta field. * + * ## OPTIONS + * * <user> * : The user login, user email, or user ID of the user to delete metadata from. * @@ -1018,6 +1020,8 @@ public function delete( $args, $assoc_args ) { /** * Add a meta field. * + * ## OPTIONS + * * <user> * : The user login, user email, or user ID of the user to add metadata for. * @@ -1044,6 +1048,8 @@ public function add( $args, $assoc_args ) { /** * Update a meta field. * + * ## OPTIONS + * * <user> * : The user login, user email, or user ID of the user to update metadata for. * diff --git a/php/commands/widget.php b/php/commands/widget.php index 1def3cb798..5d4c472131 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -39,6 +39,8 @@ class Widget_Command extends WP_CLI_Command { /** * List widgets associated with a sidebar. * + * ## OPTIONS + * * <sidebar-id> * : ID for the corresponding sidebar. * @@ -98,6 +100,8 @@ public function list_( $args, $assoc_args ) { /** * Add a widget to a sidebar. * + * ## OPTIONS + * * <name> * : Widget name. * @@ -155,6 +159,8 @@ public function add( $args, $assoc_args ) { /** * Update a given widget's options. * + * ## OPTIONS + * * <widget-id> * : Unique ID for the widget * @@ -191,6 +197,8 @@ public function update( $args, $assoc_args ) { /** * Move a widget from one position on a sidebar to another. * + * ## OPTIONS + * * <widget-id> * : Unique ID for the widget * @@ -242,6 +250,8 @@ public function move( $args, $assoc_args ) { /** * Deactivate one or more widgets from an active sidebar. * + * ## OPTIONS + * * <widget-id>... * : Unique ID for the widget(s) * @@ -273,6 +283,8 @@ public function deactivate( $args, $assoc_args ) { /** * Delete one or more widgets from a sidebar. * + * ## OPTIONS + * * <widget-id>... * : Unique ID for the widget(s) * @@ -309,6 +321,8 @@ public function delete( $args, $assoc_args ) { * * Removes all widgets from the sidebar and places them in Inactive Widgets. * + * ## OPTIONS + * * [<sidebar-id>...] * : One or more sidebars to reset. * From 61fe48013f208877baebd4db1ea4132a1bfc29a5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 12 Jul 2016 15:55:17 -0700 Subject: [PATCH 4728/4858] Remove ## OPTIONS from meta classes These won't be rendered in the appropriate place. --- php/commands/network.php | 8 -------- php/commands/post.php | 5 ----- php/commands/term.php | 5 ----- 3 files changed, 18 deletions(-) diff --git a/php/commands/network.php b/php/commands/network.php index 3b0c47ddbf..50905b567d 100644 --- a/php/commands/network.php +++ b/php/commands/network.php @@ -3,14 +3,6 @@ /** * Manage network custom fields. * - * ## OPTIONS - * - * <id> - * : The network id (usually 1). - * - * --format=json - * : Encode/decode values as JSON. - * * ## EXAMPLES * * # Get a list of super-admins diff --git a/php/commands/post.php b/php/commands/post.php index b84feb6281..890a7baa40 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -593,11 +593,6 @@ private function read_from_file_or_stdin( $arg ) { /** * Manage post custom fields. * - * ## OPTIONS - * - * [--format=json] - * : Encode/decode values as JSON. - * * ## EXAMPLES * * # Set post meta diff --git a/php/commands/term.php b/php/commands/term.php index 8b784ca423..c12b9fb548 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -566,11 +566,6 @@ private function get_formatter( &$assoc_args ) { /** * Manage term custom fields. * - * ## OPTIONS - * - * --format=json - * : Encode/decode values as JSON. - * * ## EXAMPLES * * # Set term meta From 4e3ffa3ebffd8818f3d76c248462b99e05198b10 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 13 Jul 2016 12:15:41 +0545 Subject: [PATCH 4729/4858] Add examples for cache commands --- php/commands/cache.php | 82 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/php/commands/cache.php b/php/commands/cache.php index 2999399808..b887cea952 100644 --- a/php/commands/cache.php +++ b/php/commands/cache.php @@ -3,11 +3,19 @@ /** * Manage the object cache. * + * Note: Persistent Object Caching is needed for these commands. + * * ## EXAMPLES * - * wp cache set my_key my_value my_group 300 + * # Set cache. + * $ wp cache set my_key my_value my_group 300 + * Success: Set object 'my_key' in group 'my_group'. + * + * # Get cache. + * $ wp cache get my_key my_group + * my_value * - * wp cache get my_key my_group + * @package wp-cli */ class Cache_Command extends WP_CLI_Command { @@ -28,7 +36,16 @@ class Cache_Command extends WP_CLI_Command { * : Method for grouping data within the cache which allows the same key to be used across groups. * * [<expiration>] - * : Define how long to keep the value, in seconds. Defaults to 0 (as long as possible). + * : Define how long to keep the value, in seconds. `0` means as long as possible. + * --- + * default: 0 + * --- + * + * ## EXAMPLES + * + * # Add cache. + * $ wp cache add my_key my_group my_value 300 + * Success: Added object 'my_key' in group 'my_value'. */ public function add( $args, $assoc_args ) { list( $key, $value ) = $args; @@ -57,6 +74,12 @@ public function add( $args, $assoc_args ) { * * [<group>] * : Method for grouping data within the cache which allows the same key to be used across groups. + * + * ## EXAMPLES + * + * # Decrease cache value. + * $ wp cache decr my_key 2 my_group + * 48 */ public function decr( $args, $assoc_args ) { $key = $args[0]; @@ -84,6 +107,12 @@ public function decr( $args, $assoc_args ) { * * [<group>] * : Method for grouping data within the cache which allows the same key to be used across groups. + * + * ## EXAMPLES + * + * # Delete cache. + * $ wp cache delete my_key my_group + * Success: Object deleted. */ public function delete( $args, $assoc_args ) { $key = $args[0]; @@ -104,6 +133,12 @@ public function delete( $args, $assoc_args ) { * * For sites using a persistent object cache, because WordPress Multisite simply adds a blog id * to the cache key, flushing cache is typically a global operation. + * + * ## EXAMPLES + * + * # Flush cache. + * $ wp cache flush + * Success: The cache was flushed. */ public function flush( $args, $assoc_args ) { $value = wp_cache_flush(); @@ -125,6 +160,12 @@ public function flush( $args, $assoc_args ) { * * [<group>] * : Method for grouping data within the cache which allows the same key to be used across groups. + * + * ## EXAMPLES + * + * # Get cache. + * $ wp cache get my_key my_group + * my_value */ public function get( $args, $assoc_args ) { $key = $args[0]; @@ -153,6 +194,12 @@ public function get( $args, $assoc_args ) { * * [<group>] * : Method for grouping data within the cache which allows the same key to be used across groups. + * + * ## EXAMPLES + * + * # Increase cache value. + * $ wp cache incr my_key 2 my_group + * 50 */ public function incr( $args, $assoc_args ) { $key = $args[0]; @@ -185,7 +232,16 @@ public function incr( $args, $assoc_args ) { * : Method for grouping data within the cache which allows the same key to be used across groups. * * [<expiration>] - * : Define how long to keep the value, in seconds. Defaults to 0 (as long as possible). + * : Define how long to keep the value, in seconds. `0` means as long as possible. + * --- + * default: 0 + * --- + * + * ## EXAMPLES + * + * # Replace cache. + * $ wp cache replace my_key new_value my_group + * Success: Replaced object 'my_key' in group 'my_group'. */ public function replace( $args, $assoc_args ) { list( $key, $value ) = $args; @@ -218,7 +274,16 @@ public function replace( $args, $assoc_args ) { * : Method for grouping data within the cache which allows the same key to be used across groups. * * [<expiration>] - * : Define how long to keep the value, in seconds. Defaults to 0 (as long as possible). + * : Define how long to keep the value, in seconds. `0` means as long as possible. + * --- + * default: 0 + * --- + * + * ## EXAMPLES + * + * # Set cache. + * $ wp cache set my_key my_value my_group 300 + * Success: Set object 'my_key' in group 'my_group'. */ public function set( $args, $assoc_args ) { list( $key, $value ) = $args; @@ -242,6 +307,12 @@ public function set( $args, $assoc_args ) { * Note that the guesses made by this function are based on the WP_Object_Cache classes * that define the 3rd party object cache extension. Changes to those classes could render * problems with this function's ability to determine which object cache is being used. + * + * ## EXAMPLES + * + * # Check cache type. + * $ wp cache type + * Default */ public function type( $args, $assoc_args ) { $message = WP_CLI\Utils\wp_get_cache_type(); @@ -250,4 +321,3 @@ public function type( $args, $assoc_args ) { } WP_CLI::add_command( 'cache', 'Cache_Command' ); - From bf88da2240176d05a7d06aa537d70ab342c59375 Mon Sep 17 00:00:00 2001 From: "Peter J. Herrel" <peterherrel@gmail.com> Date: Wed, 13 Jul 2016 12:33:02 +0200 Subject: [PATCH 4730/4858] add example: delete users by role --- php/commands/user.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php/commands/user.php b/php/commands/user.php index 9da51cec75..3b8dd2d232 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -210,6 +210,11 @@ public function get( $args, $assoc_args ) { * # Delete user 123 and reassign posts to user 567 * $ wp user delete 123 --reassign=567 * Success: Removed user 123 from http://example.com + * + * # Delete all contributors and reassign their posts to user 2 + * $ wp user delete $(wp user list --role=contributor --format=ids) --reassign=2 + * Success: Removed user 813 from http://example.com + * Success: Removed user 578 from http://example.com */ public function delete( $args, $assoc_args ) { $network = \WP_CLI\Utils\get_flag_value( $assoc_args, 'network' ) && is_multisite(); From 3967f23d0ed7064455776deacca923c82b7a4b47 Mon Sep 17 00:00:00 2001 From: Enrico Sorcinelli <enrico.sorcinelli@italiaonline.it> Date: Thu, 14 Jul 2016 12:16:37 +0200 Subject: [PATCH 4731/4858] Add forward slash in the end to --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 4f5335586f..1d4880756f 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -83,7 +83,7 @@ install_test_suite() { if [ ! -f wp-tests-config.php ]; then download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php From 5e1da5f9223816f3f056f981a0b7230d3a889d7d Mon Sep 17 00:00:00 2001 From: Enrico Sorcinelli <enrico.sorcinelli@italiaonline.it> Date: Thu, 14 Jul 2016 15:04:35 +0200 Subject: [PATCH 4732/4858] remove all forward slashes in the end from --- templates/install-wp-tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 1d4880756f..618bdf94cf 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -83,6 +83,8 @@ install_test_suite() { if [ ! -f wp-tests-config.php ]; then download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + # remove all forward slashes in the end + WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php From ab6ee822692bb0edb68e5009b66a4a550ae4c734 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 14 Jul 2016 06:05:18 -0700 Subject: [PATCH 4733/4858] Make sure WordPress receives the slashed data it expects --- features/post.feature | 19 +++++++++++++++++++ php/commands/post.php | 2 ++ 2 files changed, 21 insertions(+) diff --git a/features/post.feature b/features/post.feature index d33e825b2e..ec73f3da75 100644 --- a/features/post.feature +++ b/features/post.feature @@ -204,3 +204,22 @@ Feature: Manage WordPress posts """ [{"name":"Test Category"}] """ + + Scenario: Make sure WordPress receives the slashed data it expects + When I run `wp post create --post_title='My\Post' --porcelain` + Then save STDOUT as {POST_ID} + + When I run `wp post get {POST_ID} --field=title` + Then STDOUT should be: + """ + My\Post + """ + + When I run `wp post update {POST_ID} --post_content='var isEmailValid = /^\S+@\S+.\S+$/.test(email);'` + Then STDOUT should not be empty + + When I run `wp post get {POST_ID} --field=content` + Then STDOUT should be: + """ + var isEmailValid = /^\S+@\S+.\S+$/.test(email); + """ diff --git a/php/commands/post.php b/php/commands/post.php index 890a7baa40..c9744f9048 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -86,6 +86,7 @@ public function create( $args, $assoc_args ) { $assoc_args['post_category'] = explode( ',', $assoc_args['post_category'] ); } + $assoc_args = wp_slash( $assoc_args ); parent::_create( $args, $assoc_args, function ( $params ) { return wp_insert_post( $params, true ); } ); @@ -133,6 +134,7 @@ public function update( $args, $assoc_args ) { $assoc_args['post_category'] = explode( ',', $assoc_args['post_category'] ); } + $assoc_args = wp_slash( $assoc_args ); parent::_update( $args, $assoc_args, function ( $params ) { return wp_update_post( $params, true ); } ); From ae3b310de1a6d5cbe84e8ddca6188c628464f5b2 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 15 Jul 2016 11:22:11 +0545 Subject: [PATCH 4734/4858] Pass slashed data for term --- php/commands/term.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php/commands/term.php b/php/commands/term.php index c12b9fb548..0bce81736a 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -192,6 +192,8 @@ public function create( $args, $assoc_args ) { WP_CLI::error( 'Parent term does not exist.' ); } + $assoc_args = wp_slash( $assoc_args ); + $term = wp_slash( $term ); $ret = wp_insert_term( $term, $taxonomy, $assoc_args ); if ( is_wp_error( $ret ) ) { @@ -302,6 +304,7 @@ public function update( $args, $assoc_args ) { unset( $assoc_args[$key] ); } + $assoc_args = wp_slash( $assoc_args ); $ret = wp_update_term( $term_id, $taxonomy, $assoc_args ); if ( is_wp_error( $ret ) ) From 2748d5a67b40cd1681f5fe50640b5b475760dde5 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 15 Jul 2016 11:25:07 +0545 Subject: [PATCH 4735/4858] Add test for slashed data in term create and update --- features/term.feature | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/features/term.feature b/features/term.feature index d2e45f1ea3..82b0c4614d 100644 --- a/features/term.feature +++ b/features/term.feature @@ -111,3 +111,34 @@ Feature: Manage WordPress terms http://example.com/?cat=2 http://example.com/?cat=3 """ + + Scenario: Make sure WordPress receives the slashed data it expects + When I run `wp term create category 'My\Term' --description='My\Term\Description' --porcelain` + Then save STDOUT as {TERM_ID} + + When I run `wp term get category {TERM_ID} --field=name` + Then STDOUT should be: + """ + My\Term + """ + + When I run `wp term get category {TERM_ID} --field=description` + Then STDOUT should be: + """ + My\Term\Description + """ + + When I run `wp term update category {TERM_ID} --name='My\New\Term' --description='var isEmailValid = /^\S+@\S+.\S+$/.test(email);'` + Then STDOUT should not be empty + + When I run `wp term get category {TERM_ID} --field=name` + Then STDOUT should be: + """ + My\New\Term + """ + + When I run `wp term get category {TERM_ID} --field=description` + Then STDOUT should be: + """ + var isEmailValid = /^\S+@\S+.\S+$/.test(email); + """ From 644292b0ae473f885dd8afd72b9eb9232b9c6d15 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 15 Jul 2016 14:01:55 -0700 Subject: [PATCH 4736/4858] Pass slashed data for creating and updating users --- features/user.feature | 21 +++++++++++++++++++++ php/commands/user.php | 3 +++ 2 files changed, 24 insertions(+) diff --git a/features/user.feature b/features/user.feature index 4ca85cc0c6..e1b3fab15b 100644 --- a/features/user.feature +++ b/features/user.feature @@ -265,3 +265,24 @@ Feature: Manage WordPress users """ 6 """ + + Scenario: Make sure WordPress receives the slashed data it expects + Given a WP install + + When I run `wp user create slasheduser slasheduser@example.com --display_name='My\User' --porcelain` + Then save STDOUT as {USER_ID} + + When I run `wp user get {USER_ID} --field=display_name` + Then STDOUT should be: + """ + My\User + """ + + When I run `wp user update {USER_ID} --display_name='My\New\User'` + Then STDOUT should not be empty + + When I run `wp user get {USER_ID} --field=display_name` + Then STDOUT should be: + """ + My\New\User + """ diff --git a/php/commands/user.php b/php/commands/user.php index 3b8dd2d232..7298023e9c 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -295,6 +295,8 @@ public function create( $args, $assoc_args ) { $user = new stdClass; list( $user->user_login, $user->user_email ) = $args; + + $assoc_args = wp_slash( $assoc_args ); if ( username_exists( $user->user_login ) ) { WP_CLI::error( "The '{$user->user_login}' username is already registered." ); @@ -397,6 +399,7 @@ public function update( $args, $assoc_args ) { $user_ids[] = $user->ID; } + $assoc_args = wp_slash( $assoc_args ); parent::_update( $user_ids, $assoc_args, 'wp_update_user' ); } From 7c0c500cef6c515e62f3ccee2a4e890e282b3898 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 15 Jul 2016 14:15:12 -0700 Subject: [PATCH 4737/4858] Pass slashed data for creating and updating comments --- features/comment.feature | 19 +++++++++++++++++++ php/commands/comment.php | 2 ++ 2 files changed, 21 insertions(+) diff --git a/features/comment.feature b/features/comment.feature index 6fcbd88d4d..b0058297eb 100644 --- a/features/comment.feature +++ b/features/comment.feature @@ -249,3 +249,22 @@ Feature: Manage WordPress comments """ 0 """ + + Scenario: Make sure WordPress receives the slashed data it expects + When I run `wp comment create --comment_content='My\Comment' --porcelain` + Then save STDOUT as {COMMENT_ID} + + When I run `wp comment get {COMMENT_ID} --field=comment_content` + Then STDOUT should be: + """ + My\Comment + """ + + When I run `wp comment update {COMMENT_ID} --comment_content='My\New\Comment'` + Then STDOUT should not be empty + + When I run `wp comment get {COMMENT_ID} --field=comment_content` + Then STDOUT should be: + """ + My\New\Comment + """ diff --git a/php/commands/comment.php b/php/commands/comment.php index 56b1ad0b77..c153104a9e 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -58,6 +58,7 @@ public function __construct() { * Success: Created comment 932. */ public function create( $args, $assoc_args ) { + $assoc_args = wp_slash( $assoc_args ); parent::_create( $args, $assoc_args, function ( $params ) { if ( isset( $params['comment_post_ID'] ) ) { $post_id = $params['comment_post_ID']; @@ -96,6 +97,7 @@ public function create( $args, $assoc_args ) { * Success: Updated comment 123. */ public function update( $args, $assoc_args ) { + $assoc_args = wp_slash( $assoc_args ); parent::_update( $args, $assoc_args, function ( $params ) { if ( !wp_update_comment( $params ) ) { return new WP_Error( 'Could not update comment.' ); From a5392f8c9e1b32fcedcedb3dfe0383f3a18a1aa7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 15 Jul 2016 15:11:41 -0700 Subject: [PATCH 4738/4858] Permit defining aliases at runtime This lets us pass the current alias through over SSH. I wish there was a better way to do this, but I think this is the best we have. I suppose it will let users with lots of WordPress installs to define aliases dynamically, instead of needing to write a file. --- php/WP_CLI/Configurator.php | 36 ++++++++++++++++++++++++++++-------- php/WP_CLI/Runner.php | 11 +++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 6c0e852f04..f259528d14 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -34,6 +34,17 @@ class Configurator { */ const ALIAS_REGEX = '^@[A-Za-z0-9-_]+$'; + /** + * @var array ALIAS_SPEC Arguments that can be used in an alias + */ + private static $alias_spec = array( + 'user', + 'url', + 'path', + 'ssh', + 'http', + ); + /** * @param string $path Path to config spec file. */ @@ -79,7 +90,22 @@ function get_spec() { * @return array */ function get_aliases() { - return $this->aliases; + if ( $runtime_alias = getenv( 'WP_CLI_RUNTIME_ALIAS' ) ) { + $returned_aliases = array(); + foreach( json_decode( $runtime_alias, true ) as $key => $value ) { + if ( preg_match( '#' . self::ALIAS_REGEX . '#', $key ) ) { + $returned_aliases[ $key ] = array(); + foreach( self::$alias_spec as $i ) { + if ( isset( $value[ $i ] ) ) { + $returned_aliases[ $key ][ $i ] = $value[ $i ]; + } + } + } + } + return $returned_aliases; + } else { + return $this->aliases; + } } /** @@ -196,13 +222,7 @@ public function merge_yml( $path ) { if ( preg_match( '#' . self::ALIAS_REGEX . '#', $key ) ) { $this->aliases[ $key ] = array(); $is_alias = false; - foreach( array( - 'user', - 'url', - 'path', - 'ssh', - 'http', - ) as $i ) { + foreach( self::$alias_spec as $i ) { if ( isset( $value[ $i ] ) ) { $this->aliases[ $key ][ $i ] = $value[ $i ]; $is_alias = true; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index d526256f3a..3e0024d5e7 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -348,6 +348,17 @@ private function run_ssh_command( $ssh ) { if ( $this->alias && ! empty( $wp_args[0] ) && $this->alias === $wp_args[0] ) { array_shift( $wp_args ); + $runtime_alias = array(); + foreach( $this->aliases[ $this->alias ] as $key => $value ) { + if ( 'ssh' === $key ) { + continue; + } + $runtime_alias[ $key ] = $value; + } + if ( ! empty( $runtime_alias ) ) { + $encoded_alias = json_encode( array( $this->alias => $runtime_alias ) ); + $wp_binary = "WP_CLI_RUNTIME_ALIAS='{$encoded_alias}' {$wp_binary} {$this->alias}"; + } } foreach( $wp_args as $k => $v ) { From 5458d0037e47c765117accc7ba464a9e2884faca Mon Sep 17 00:00:00 2001 From: "nikhilc@bsf.io" <nikhilc@bsf.io> Date: Sat, 16 Jul 2016 12:52:35 +0530 Subject: [PATCH 4739/4858] add --ci=gitlab for wp scaffold plugin-tests --- features/scaffold.feature | 16 +++++++++++++++ php/commands/scaffold.php | 3 +++ templates/install-wp-tests.sh | 6 ++++++ templates/plugin-gitlab.mustache | 34 ++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 templates/plugin-gitlab.mustache diff --git a/features/scaffold.feature b/features/scaffold.feature index 0e4796cdfe..81148c221d 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -307,6 +307,7 @@ Feature: WordPress code scaffolding """ And the {PLUGIN_DIR}/hello-world/phpunit.xml.dist file should exist And the {PLUGIN_DIR}/hello-world/circle.yml file should not exist + And the {PLUGIN_DIR}/hello-world/.gitlab-ci.yml file should not exist And the {PLUGIN_DIR}/hello-world/.travis.yml file should contain: """ script: phpunit @@ -333,6 +334,21 @@ Feature: WordPress code scaffolding version: 5.6.14 """ + Scenario: Scaffold plugin tests with Gitlab as the provider + Given a WP install + And I run `wp scaffold plugin hello-world --skip-tests` + + When I run `wp plugin path hello-world --dir` + Then save STDOUT as {PLUGIN_DIR} + + When I run `wp scaffold plugin-tests hello-world --ci=gitlab` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/.travis.yml file should not exist + And the {PLUGIN_DIR}/.gitlab-ci.yml file should contain: + """ + MYSQL_DATABASE + """ + Scenario: Scaffold starter code for a theme Given a WP install Given I run `wp theme path` diff --git a/php/commands/scaffold.php b/php/commands/scaffold.php index ec2b0d7284..96a9f2b907 100644 --- a/php/commands/scaffold.php +++ b/php/commands/scaffold.php @@ -558,6 +558,7 @@ function plugin( $args, $assoc_args ) { * options: * - travis * - circle + * - gitlab * --- * * [--force] @@ -633,6 +634,8 @@ function plugin_tests( $args, $assoc_args ) { $files_to_create["$plugin_dir/.travis.yml"] = Utils\mustache_render( 'plugin-travis.mustache', compact( 'wp_versions_to_test' ) ); } else if ( 'circle' === $assoc_args['ci'] ) { $files_to_create["$plugin_dir/circle.yml"] = Utils\mustache_render( 'plugin-circle.mustache' ); + } else if ( 'gitlab' === $assoc_args['ci'] ) { + $files_to_create["$plugin_dir/.gitlab-ci.yml"] = Utils\mustache_render( 'plugin-gitlab.mustache' ); } $files_written = $this->create_files( $files_to_create, $force ); diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 618bdf94cf..55f6e9ac19 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -10,6 +10,7 @@ DB_USER=$2 DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-latest} +SKIP_DB_CREATE=${6:-false} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} @@ -95,6 +96,11 @@ install_test_suite() { } install_db() { + + if [ ${SKIP_DB_CREATE} = "true" ]; then + return 0 + fi + # parse DB_HOST for port or socket references local PARTS=(${DB_HOST//\:/ }) local DB_HOSTNAME=${PARTS[0]}; diff --git a/templates/plugin-gitlab.mustache b/templates/plugin-gitlab.mustache new file mode 100644 index 0000000000..6e64d85fa9 --- /dev/null +++ b/templates/plugin-gitlab.mustache @@ -0,0 +1,34 @@ +variables: + # Configure mysql service (https://hub.docker.com/_/mysql/) + MYSQL_DATABASE: wordpress_tests + MYSQL_ROOT_PASSWORD: mysql + +before_script: + # Install dependencies + + # update the docker + - apt-get clean + - apt-get -yqq update + + # instll the required packages for the running CI tests + - apt-get -yqqf install zip unzip subversion mysql-client libmysqlclient-dev --fix-missing + + # PHP extensions + - docker-php-ext-enable mbstring mcrypt mysqli pdo_mysql intl gd zip bz2 + + # Set up WordPress tests + - bash bin/install-wp-tests.sh wordpress_tests root mysql mysql latest true + +PHPunit:PHP5.3:MySQL: + image: tetraweb/php:5.3 + services: + - mysql:5.6 + script: + - phpunit --configuration phpunit.xml.dist + +PHPunit:PHP5.6:MySQL: + image: tetraweb/php:5.6 + services: + - mysql:5.6 + script: + - phpunit --configuration phpunit.xml.dist \ No newline at end of file From 57735fc49e11de737b116a7df1674ed44f8f9b56 Mon Sep 17 00:00:00 2001 From: "nikhilc@bsf.io" <nikhilc@bsf.io> Date: Sat, 16 Jul 2016 13:20:03 +0530 Subject: [PATCH 4740/4858] adds default value to in Utils\mustache_render, fixes #3164 --- php/utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/utils.php b/php/utils.php index 6268dcbcb8..d2499de33d 100644 --- a/php/utils.php +++ b/php/utils.php @@ -447,7 +447,7 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) { * * IMPORTANT: Automatic HTML escaping is disabled! */ -function mustache_render( $template_name, $data ) { +function mustache_render( $template_name, $data = array() ) { if ( ! file_exists( $template_name ) ) $template_name = WP_CLI_ROOT . "/templates/$template_name"; From 4c9b2d6780ccbb6339f8af55be0163df9add423c Mon Sep 17 00:00:00 2001 From: "nikhilc@bsf.io" <nikhilc@bsf.io> Date: Sat, 16 Jul 2016 16:51:10 +0530 Subject: [PATCH 4741/4858] follow same coad style as previous --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 55f6e9ac19..8dd224e3a3 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -10,7 +10,7 @@ DB_USER=$2 DB_PASS=$3 DB_HOST=${4-localhost} WP_VERSION=${5-latest} -SKIP_DB_CREATE=${6:-false} +SKIP_DB_CREATE=${6-false} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} From 8814dc6508dc4d113c14717a607da47a1cb04db3 Mon Sep 17 00:00:00 2001 From: "nikhilc@bsf.io" <nikhilc@bsf.io> Date: Sat, 16 Jul 2016 16:56:41 +0530 Subject: [PATCH 4742/4858] update usage info for install-wp-tests.sh --- templates/install-wp-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/install-wp-tests.sh b/templates/install-wp-tests.sh index 8dd224e3a3..cf709c2765 100644 --- a/templates/install-wp-tests.sh +++ b/templates/install-wp-tests.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if [ $# -lt 3 ]; then - echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version]" + echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]" exit 1 fi From c7fb5d5a2fec62319b9b1b65db3623ae71a27b04 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 17 Jul 2016 10:34:39 +0545 Subject: [PATCH 4743/4858] Pass slashed site title in site create command --- php/commands/site.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/site.php b/php/commands/site.php index e3459a542c..f9d9d9aa90 100644 --- a/php/commands/site.php +++ b/php/commands/site.php @@ -360,6 +360,7 @@ public function create( $_, $assoc_args ) { } $wpdb->hide_errors(); + $title = wp_slash( $title ); $id = wpmu_create_blog( $newdomain, $path, $title, $user_id, array( 'public' => $public ), $network->id ); $wpdb->show_errors(); if ( !is_wp_error( $id ) ) { From 5045280b416ab134fd05529fcd9ab0deab77dab0 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 17 Jul 2016 10:41:08 +0545 Subject: [PATCH 4744/4858] Add test for slashed site title in site create --- features/site.feature | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/site.feature b/features/site.feature index 506c679468..4f3c9308ce 100644 --- a/features/site.feature +++ b/features/site.feature @@ -289,3 +289,14 @@ Feature: Manage sites in a multisite installation """ http://example.com/first """ + + Scenario: Create site with title containing slash + Given a WP multisite install + And I run `wp site create --slug=mysite --title="My\Site"` + Then STDOUT should not be empty + + When I run `wp option get blogname --url=example.com/mysite` + Then STDOUT should be: + """ + My\Site + """ From 96e41b42c9bb79e86d72dbe57fbbd968f74b1a61 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sun, 17 Jul 2016 22:33:03 +0545 Subject: [PATCH 4745/4858] Command message improvement in super-admin --- php/commands/super-admin.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/commands/super-admin.php b/php/commands/super-admin.php index d0982a9c91..4d23268451 100644 --- a/php/commands/super-admin.php +++ b/php/commands/super-admin.php @@ -17,6 +17,8 @@ * # Revoke super-admin privileges to the user. * $ wp super-admin remove superadmin2 * Success: Revoked super-admin capabilities. + * + * @package wp-cli */ class Super_Admin_Command extends WP_CLI_Command { @@ -101,12 +103,12 @@ public function add( $args, $_ ) { $user = get_user_by( 'login', $user_login ); if ( !$user ) { - WP_CLI::warning( "Couldn't find {$user_login} user." ); + WP_CLI::warning( "Couldn't find '{$user_login}' user." ); continue; } if ( in_array( $user->user_login, $super_admins ) ) { - WP_CLI::warning( "User {$user_login} already has super-admin capabilities." ); + WP_CLI::warning( "User '{$user_login}' already has super-admin capabilities." ); continue; } @@ -119,7 +121,7 @@ public function add( $args, $_ ) { if ( update_site_option( 'site_admins' , $super_admins ) ) { WP_CLI::success( 'Granted super-admin capabilities.' ); } else { - WP_CLI::error( 'Site options update failed!' ); + WP_CLI::error( 'Site options update failed.' ); } } } From c8805c9d2656ce19d9e7db8d0ea7a695de41c472 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sun, 17 Jul 2016 22:33:45 +0545 Subject: [PATCH 4746/4858] Fix test for changed command message in super-admin --- features/super-admin.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/super-admin.feature b/features/super-admin.feature index 219b65033c..05ff00f983 100644 --- a/features/super-admin.feature +++ b/features/super-admin.feature @@ -20,7 +20,7 @@ Feature: Manage super admins associated with a multisite instance When I run `wp super-admin add superadmin` Then STDERR should contain: """ - Warning: User superadmin already has super-admin capabilities. + Warning: User 'superadmin' already has super-admin capabilities. """ When I run `wp super-admin list` From c4f79ae84de40180924706d0a1a7076fd672f198 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sun, 17 Jul 2016 22:45:52 +0545 Subject: [PATCH 4747/4858] Doc improvement in package commands --- php/commands/package.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 58e9c80ba8..471c8b9699 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -86,7 +86,16 @@ class Package_Command extends WP_CLI_Command { * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, json, csv, yaml, ids. Default: table. + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - yaml + * --- * * ## EXAMPLES * @@ -215,7 +224,16 @@ public function install( $args, $assoc_args ) { * ## OPTIONS * * [--format=<format>] - * : Accepted values: table, json, csv, yaml, ids. Default: table + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - yaml + * --- * * ## EXAMPLES * From a3928917034df1f9b6fed56c22d8a95808e70952 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 18 Jul 2016 12:53:06 +0545 Subject: [PATCH 4748/4858] Pass slashed data for importing media --- php/commands/media.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/commands/media.php b/php/commands/media.php index a5f8aefd34..372e99bea1 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -201,6 +201,7 @@ function import( $args, $assoc_args = array() ) { 'post_excerpt' => $assoc_args['caption'], 'post_content' => $assoc_args['desc'] ); + $post_array = wp_slash( $post_array ); // use image exif/iptc data for title and caption defaults if possible if ( empty( $post_array['post_title'] ) || empty( $post_array['post_excerpt'] ) ) { @@ -234,7 +235,7 @@ function import( $args, $assoc_args = array() ) { // Set alt text if ( $assoc_args['alt'] ) { - update_post_meta( $success, '_wp_attachment_image_alt', $assoc_args['alt'] ); + update_post_meta( $success, '_wp_attachment_image_alt', wp_slash( $assoc_args['alt'] ) ); } // Set as featured image, if --post_id and --featured_image are set From d3cf3d10d2999d9c65a6fd5d7ff6a981a46f59dc Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 18 Jul 2016 13:11:09 +0545 Subject: [PATCH 4749/4858] Add test for slashed data in media import --- features/media-import.feature | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/features/media-import.feature b/features/media-import.feature index a33e787db0..7c0ec06faa 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -1,5 +1,5 @@ Feature: Manage WordPress attachments - + Background: Given a WP install @@ -93,3 +93,21 @@ Feature: Manage WordPress attachments """ The description for the image """ + + Scenario: Make sure WordPress receives the slashed data it expects + When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1 --title="My\Title" --caption="Caption\Here" --alt="Alt\Here" --desc="Desc\Here" --porcelain` + Then save STDOUT as {ATTACHMENT_ID} + + When I run `wp post get {ATTACHMENT_ID} --format=csv --fields=post_title,post_excerpt,post_content` + Then STDOUT should contain: + """ + post_content,"Desc\Here" + post_title,"My\Title" + post_excerpt,"Caption\Here" + """ + + When I run `wp post meta get {ATTACHMENT_ID} _wp_attachment_image_alt` + Then STDOUT should be: + """ + Alt\Here + """ From 6fed4225777cef122fe482ccd61adb01038af817 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 18 Jul 2016 13:21:03 +0545 Subject: [PATCH 4750/4858] Use single apostrophe in command in test for import media --- features/media-import.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/media-import.feature b/features/media-import.feature index 7c0ec06faa..591d0db690 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -95,7 +95,7 @@ Feature: Manage WordPress attachments """ Scenario: Make sure WordPress receives the slashed data it expects - When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1 --title="My\Title" --caption="Caption\Here" --alt="Alt\Here" --desc="Desc\Here" --porcelain` + When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1 --title='My\Title' --caption='Caption\Here' --alt='Alt\Here' --desc='Desc\Here' --porcelain` Then save STDOUT as {ATTACHMENT_ID} When I run `wp post get {ATTACHMENT_ID} --format=csv --fields=post_title,post_excerpt,post_content` From 570c3fc8cbd9fa30950b96664f60a232a4713a95 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 18 Jul 2016 17:05:28 +0545 Subject: [PATCH 4751/4858] Update success message for cron event run --- php/commands/cron.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index f24587045e..9f7cdf741e 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -211,7 +211,7 @@ public function schedule( $args, $assoc_args ) { * * # Run all cron events due right now * $ wp cron event run --due-now - * Success: Executed a total of 2 cron event(s). + * Success: Executed a total of 2 cron events. */ public function run( $args, $assoc_args ) { @@ -258,7 +258,7 @@ public function run( $args, $assoc_args ) { WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); } - $message = 'Executed a total of %d cron event(s).'; + $message = ( 1 === $executed ) ? 'Executed a total of %d cron event.' : 'Executed a total of %d cron events.'; WP_CLI::success( sprintf( $message, $executed ) ); } From d4246b21935f9d02464666b55d892762cb01f5d5 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Mon, 18 Jul 2016 17:19:30 +0545 Subject: [PATCH 4752/4858] Update test to reflect message changes in cron event run command --- features/cron.feature | 10 +++++----- php/commands/cron.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 253938dd0f..75f43e046b 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -94,7 +94,7 @@ Feature: Manage WP-Cron events and schedules """ And STDOUT should contain: """ - Success: Executed a total of 2 cron event(s). + Success: Executed a total of 2 cron events. """ When I run `wp cron event list` @@ -213,7 +213,7 @@ Feature: Manage WP-Cron events and schedules """ And STDOUT should contain: """ - Success: Executed a total of 2 cron event(s). + Success: Executed a total of 2 cron events. """ When I run `wp cron event run --all` @@ -256,7 +256,7 @@ Feature: Manage WP-Cron events and schedules When I run `wp cron event run --due-now` Then STDOUT should contain: """ - Executed a total of 0 cron event(s) + Executed a total of 0 cron events """ When I run `wp cron event schedule wp_cli_test_event_1 now hourly` @@ -272,13 +272,13 @@ Feature: Manage WP-Cron events and schedules """ And STDOUT should contain: """ - Executed a total of 1 cron event(s) + Executed a total of 1 cron event """ When I run `wp cron event run --due-now` Then STDOUT should contain: """ - Executed a total of 0 cron event(s) + Executed a total of 0 cron events """ Scenario: Don't trigger cron when ALTERNATE_WP_CRON is defined diff --git a/php/commands/cron.php b/php/commands/cron.php index 9f7cdf741e..466ec34cfc 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -11,7 +11,7 @@ * * # Run all cron events due right now * $ wp cron event run --due-now - * Success: Executed a total of 2 cron event(s). + * Success: Executed a total of 2 cron events. * * # Delete the next scheduled cron event * $ wp cron event delete cron_test From 748444af79da6bdc2c69b63e612571dad0d8d63f Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 19 Jul 2016 10:25:54 +0545 Subject: [PATCH 4753/4858] Fix issue of not listing duplicate cron events --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index 466ec34cfc..a5e97f7c6a 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -385,7 +385,7 @@ protected static function get_cron_events() { foreach ( $hooks as $hook => $hook_events ) { foreach ( $hook_events as $sig => $data ) { - $events["$hook-$sig"] = (object) array( + $events["$hook-$sig-$time"] = (object) array( 'hook' => $hook, 'time' => $time, 'sig' => $sig, From 1fdbf014a04031dc01fcd286d492a595faa5e8c1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Tue, 19 Jul 2016 10:40:19 +0545 Subject: [PATCH 4754/4858] Add test for listing duplicated cron events --- features/cron.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/features/cron.feature b/features/cron.feature index 75f43e046b..3f49d7cc4f 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -304,3 +304,16 @@ Feature: Manage WP-Cron events and schedules """ http://example.com """ + + Scenario: Listing duplicated cron events + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 5 minutes'` + Then STDOUT should not be empty + + When I run `wp cron event schedule wp_cli_test_event_1 '+3 hour 5 minutes'` + Then STDOUT should not be empty + + When I run `wp cron event list --format=ids` + Then STDOUT should contain: + """ + wp_cli_test_event_1 wp_cli_test_event_1 + """ From fc8667100945fa104b796864cc277a738c63f953 Mon Sep 17 00:00:00 2001 From: "Peter J. Herrel" <peterherrel@gmail.com> Date: Wed, 20 Jul 2016 12:02:06 +0200 Subject: [PATCH 4755/4858] missing global namespace separator in CommandWithTranslation.php cf. https://github.com/wp-cli/wp-cli/issues/2670#issuecomment-233898650 --- php/WP_CLI/CommandWithTranslation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 628f57f7f9..62710848d6 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -344,7 +344,7 @@ protected function get_all_languages() { $response = translations_api( $this->obj_type ); if ( is_wp_error( $response ) ) { - WP_CLI::error( $response ); + \WP_CLI::error( $response ); } $translations = ! empty( $response['translations'] ) ? $response['translations'] : array(); From e1498ef5d113bfcebba432a48cc622dfe3bb88c5 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jul 2016 05:57:32 -0700 Subject: [PATCH 4756/4858] Don't overload `--path` when path is provided in `--ssh` This approach was a bit hacky. Instead, a path provided as a part of `--ssh=<host>` means the command should be ultimately executed from that directory. --- php/WP_CLI/Runner.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 3e0024d5e7..c70d449ce8 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -342,9 +342,11 @@ private function run_ssh_command( $ssh ) { if ( $pre_cmd ) { $pre_cmd = rtrim( $pre_cmd, ';' ) . '; '; } + if ( $path ) { + $pre_cmd .= "cd {$path}; "; + } $wp_binary = 'wp'; $wp_args = array_slice( $GLOBALS['argv'], 1 ); - $wp_path = $path ? sprintf( '--path=%s', str_replace( '~', '$HOME', $path ) ) : ''; if ( $this->alias && ! empty( $wp_args[0] ) && $this->alias === $wp_args[0] ) { array_shift( $wp_args ); @@ -372,7 +374,7 @@ private function run_ssh_command( $ssh ) { $port ? '-p ' . (int) $port . ' ' : '', $host, $is_tty ? '-t' : '-T', - $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) + $pre_cmd . $wp_binary . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ); WP_CLI::debug( 'Running SSH command: ' . $unescaped_command, 'bootstrap' ); @@ -382,7 +384,7 @@ private function run_ssh_command( $ssh ) { $port ? '-p ' . (int) $port . ' ' : '', escapeshellarg( $host ), $is_tty ? '-t' : '-T', - escapeshellarg( $pre_cmd . $wp_binary . ' ' . $wp_path . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ) + escapeshellarg( $pre_cmd . $wp_binary . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) ) ) ); passthru( $escaped_command, $exit_code ); From 5fdafbe85718d97c36ac8efa11ee3550ca53ec38 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 20 Jul 2016 16:24:45 -0700 Subject: [PATCH 4757/4858] Explain why Twitter isn't an appropriate support medium --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f0a4667328..dfdc07e7a2 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,8 @@ WP-CLI's maintainers and project contributors do their best to respond to all ne If you can't find your answer in one of those existing resources, feel free to [create an issue](https://github.com/wp-cli/wp-cli/issues/new) with your question. +Please do not ask support questions on Twitter. Twitter isn't an acceptable venue for support because: 1) it's hard to hold conversations in under 140 characters, and 2) Twitter isn't a place where someone with your same question can search for an answer in a prior conversation. + If you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). ## Extending From 7663c453d2e14980807fd128006c45892c132d4d Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 21 Jul 2016 15:54:10 +0545 Subject: [PATCH 4758/4858] Update message for search replace in dry run mode --- php/commands/search-replace.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index bc2bd8976c..c8d11293b2 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -25,7 +25,7 @@ * | wp_options | option_value | 0 | PHP | * | wp_options | autoload | 0 | SQL | * +------------+--------------+--------------+------+ - * Success: 2 replacement(s) to be made. + * Success: 2 replacements to be made. * * @package wp-cli */ @@ -264,8 +264,8 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::success( $success_message ); } else { - $success_message = "$total replacement(s) to be made."; - WP_CLI::success( $success_message ); + $success_message = ( 1 === $total ) ? '%d replacement to be made.' : '%d replacements to be made.'; + WP_CLI::success( sprintf( $success_message, $total ) ); } } From 0b95433cda3d1f0747045ddda1ba468090e4f286 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 21 Jul 2016 15:54:37 +0545 Subject: [PATCH 4759/4858] Fix test according to updated message in search replace in dry run mode --- features/search-replace.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/search-replace.feature b/features/search-replace.feature index 02cd30988e..55b76ef39d 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -225,7 +225,7 @@ Feature: Do global search/replace When I run `wp search-replace '<a href="http://google.com">Google</a>' '<a href="http://apple.com">Apple</a>' --dry-run` Then STDOUT should contain: """ - 1 replacement(s) to be made. + 1 replacement to be made. """ When I run `wp post get {POST_ID} --field=content` From 806597befb56c1164f0bd6b4e07e1bbfeca72ccb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 21 Jul 2016 16:12:24 +0545 Subject: [PATCH 4760/4858] Update success message for widget delete --- php/commands/widget.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index 5d4c472131..bcc7f37050 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -297,23 +297,28 @@ public function deactivate( $args, $assoc_args ) { */ public function delete( $args, $assoc_args ) { + $count = 0; + foreach( $args as $widget_id ) { $this->validate_sidebar_widget( $widget_id ); - // Remove the widget's settings + // Remove the widget's settings. list( $name, $option_index, $sidebar_id, $sidebar_index ) = $this->get_widget_data( $widget_id ); $widget_options = $this->get_widget_options( $name ); unset( $widget_options[ $option_index ] ); $this->update_widget_options( $name, $widget_options ); - // Remove the widget from the sidebar + // Remove the widget from the sidebar. $all_widgets = $this->wp_get_sidebars_widgets(); unset( $all_widgets[ $sidebar_id ][ $sidebar_index ] ); $all_widgets[ $sidebar_id ] = array_values( $all_widgets[ $sidebar_id ] ); update_option( 'sidebars_widgets', $all_widgets ); + + $count++; } - WP_CLI::success( "Widget(s) removed from sidebar." ); + $success_message = ( 1 === $count ) ? '%d widget removed from sidebar.' : '%d widgets removed from sidebar.'; + WP_CLI::success( sprintf( $success_message, $count ) ); } /** From c229fbe8edb980104d07e5be02310828321d8be7 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 21 Jul 2016 16:13:01 +0545 Subject: [PATCH 4761/4858] Improve test to reflect updated message for widget delete --- features/widget.feature | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/widget.feature b/features/widget.feature index 51d746ae67..6bc3b259cb 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -53,7 +53,10 @@ Feature: Manage widgets in WordPress sidebar | recent-comments | recent-comments-2 | 2 | When I run `wp widget delete archives-2 recent-posts-2` - Then STDOUT should not be empty + Then STDOUT should be: + """ + Success: 2 widgets removed from sidebar. + """ When I run `wp widget list sidebar-1 --fields=name,id,position` Then STDOUT should be a table containing rows: From d3d0855f43bb6f0d4e01fdb58f288eae6d14532e Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 21 Jul 2016 17:08:39 +0545 Subject: [PATCH 4762/4858] Add example for cli completions command --- php/commands/cli.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 5d0d0b31a3..3f9a614025 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -446,10 +446,17 @@ public function cmd_dump() { * ## OPTIONS * * --line=<line> - * : The current command line to be executed + * : The current command line to be executed. * * --point=<point> - * : The index to the current cursor position relative to the beginning of the command + * : The index to the current cursor position relative to the beginning of the command. + * + * ## EXAMPLES + * + * # Generate tab completion strings. + * $ wp cli completions --line='wp eva' --point=100 + * eval + * eval-file */ public function completions( $_, $assoc_args ) { $line = substr( $assoc_args['line'], 0, $assoc_args['point'] ); From a30fb4ce5983d1029b474295d07c843969efaa47 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 21 Jul 2016 09:47:16 -0700 Subject: [PATCH 4763/4858] Restore php-cli-tools to v0.11.1; update other dependencies --- composer.json | 2 +- composer.lock | 66 +++++++++++++++++++++++++-------------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/composer.json b/composer.json index 9fabb1b8d7..8b2590b798 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=5.3.29", - "wp-cli/php-cli-tools": "dev-master", + "wp-cli/php-cli-tools": "~0.11.1", "mustache/mustache": "~2.4", "mustangostang/spyc": "~0.5", "composer/semver": "~1.0", diff --git a/composer.lock b/composer.lock index a037758129..4cab63408b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,24 +4,26 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "38e11e275b2087dfb61f50d258712aef", - "content-hash": "a55b968d0d6754da376a5151b4222cbb", + "hash": "f0bf52c59aa6e9fe44d6a611f8006a52", + "content-hash": "10cf19699e3fed767e31e1493a07c8f0", "packages": [ { "name": "composer/ca-bundle", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "a2995e5fe351055f2c7630166af12ce8fd03edfc" + "reference": "5df9ed0ed0c9506ea6404a23450854e5df15cc12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/a2995e5fe351055f2c7630166af12ce8fd03edfc", - "reference": "a2995e5fe351055f2c7630166af12ce8fd03edfc", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/5df9ed0ed0c9506ea6404a23450854e5df15cc12", + "reference": "5df9ed0ed0c9506ea6404a23450854e5df15cc12", "shasum": "" }, "require": { + "ext-openssl": "*", + "ext-pcre": "*", "php": "^5.3.2 || ^7.0" }, "require-dev": { @@ -60,27 +62,27 @@ "ssl", "tls" ], - "time": "2016-04-13 10:13:24" + "time": "2016-07-18 23:07:53" }, { "name": "composer/composer", - "version": "1.1.3", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "30ab6f1c1753267d181839142fafe022313c3c9a" + "reference": "b49a006748a460f8dae6500ec80ed021501ce969" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/30ab6f1c1753267d181839142fafe022313c3c9a", - "reference": "30ab6f1c1753267d181839142fafe022313c3c9a", + "url": "https://api.github.com/repos/composer/composer/zipball/b49a006748a460f8dae6500ec80ed021501ce969", + "reference": "b49a006748a460f8dae6500ec80ed021501ce969", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", "composer/spdx-licenses": "^1.0", - "justinrainbow/json-schema": "^1.6", + "justinrainbow/json-schema": "^1.6 || ^2.0", "php": "^5.3.2 || ^7.0", "psr/log": "^1.0", "seld/cli-prompt": "^1.0", @@ -93,7 +95,7 @@ }, "require-dev": { "phpunit/phpunit": "^4.5 || ^5.0.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -106,7 +108,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -137,7 +139,7 @@ "dependency", "package" ], - "time": "2016-06-26 14:42:08" + "time": "2016-07-18 23:28:52" }, { "name": "composer/semver", @@ -264,25 +266,25 @@ }, { "name": "justinrainbow/json-schema", - "version": "1.6.1", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341" + "reference": "6b2a33e6a768f96bdc2ead5600af0822eed17d67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/cc84765fb7317f6b07bd8ac78364747f95b86341", - "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/6b2a33e6a768f96bdc2ead5600af0822eed17d67", + "reference": "6b2a33e6a768f96bdc2ead5600af0822eed17d67", "shasum": "" }, "require": { - "php": ">=5.3.29" + "php": ">=5.3.3" }, "require-dev": { - "json-schema/json-schema-test-suite": "1.1.0", + "json-schema/json-schema-test-suite": "1.2.0", "phpdocumentor/phpdocumentor": "~2", - "phpunit/phpunit": "~3.7" + "phpunit/phpunit": "^4.8.22" }, "bin": [ "bin/validate-json" @@ -290,7 +292,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -300,7 +302,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { @@ -326,7 +328,7 @@ "json", "schema" ], - "time": "2016-01-25 15:43:01" + "time": "2016-06-02 10:59:52" }, { "name": "mustache/mustache", @@ -1289,16 +1291,16 @@ }, { "name": "wp-cli/php-cli-tools", - "version": "dev-master", + "version": "v0.11.1", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "10cfa5bd978889c8050cd48d70d179d775c31827" + "reference": "5311a4b99103c0505db015a334be4952654d6e21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/10cfa5bd978889c8050cd48d70d179d775c31827", - "reference": "10cfa5bd978889c8050cd48d70d179d775c31827", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/5311a4b99103c0505db015a334be4952654d6e21", + "reference": "5311a4b99103c0505db015a334be4952654d6e21", "shasum": "" }, "require": { @@ -1335,7 +1337,7 @@ "cli", "console" ], - "time": "2016-03-30 11:55:36" + "time": "2016-02-08 14:34:01" } ], "packages-dev": [ @@ -1830,9 +1832,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "wp-cli/php-cli-tools": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From f28b91f0f95911a3dbc6e695359527bd240dc212 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 22 Jul 2016 09:03:56 +0545 Subject: [PATCH 4764/4858] Making cron events array key more unique --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index a5e97f7c6a..527b1100ed 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -385,7 +385,7 @@ protected static function get_cron_events() { foreach ( $hooks as $hook => $hook_events ) { foreach ( $hook_events as $sig => $data ) { - $events["$hook-$sig-$time"] = (object) array( + $events["$hook-$sig".uniqid()] = (object) array( 'hook' => $hook, 'time' => $time, 'sig' => $sig, From 3352d6d08df4ed5f134283e1c556c1a5dfbd10cb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 22 Jul 2016 11:55:01 +0545 Subject: [PATCH 4765/4858] Fix test of cron event list for WP 3.7 --- features/cron.feature | 4 ++-- php/commands/cron.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/cron.feature b/features/cron.feature index 3f49d7cc4f..f3f0f4d73a 100644 --- a/features/cron.feature +++ b/features/cron.feature @@ -306,10 +306,10 @@ Feature: Manage WP-Cron events and schedules """ Scenario: Listing duplicated cron events - When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 5 minutes'` + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 5 minutes' hourly` Then STDOUT should not be empty - When I run `wp cron event schedule wp_cli_test_event_1 '+3 hour 5 minutes'` + When I run `wp cron event schedule wp_cli_test_event_1 '+1 hour 6 minutes' hourly` Then STDOUT should not be empty When I run `wp cron event list --format=ids` diff --git a/php/commands/cron.php b/php/commands/cron.php index 527b1100ed..a5e97f7c6a 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -385,7 +385,7 @@ protected static function get_cron_events() { foreach ( $hooks as $hook => $hook_events ) { foreach ( $hook_events as $sig => $data ) { - $events["$hook-$sig".uniqid()] = (object) array( + $events["$hook-$sig-$time"] = (object) array( 'hook' => $hook, 'time' => $time, 'sig' => $sig, From 771a7bf0af7ab0738ee3d09f17432b3953d5aeb7 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Sat, 23 Jul 2016 06:57:14 +0545 Subject: [PATCH 4766/4858] Remove associative array key for cron events list --- php/commands/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/cron.php b/php/commands/cron.php index a5e97f7c6a..2995e1eefd 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -385,7 +385,7 @@ protected static function get_cron_events() { foreach ( $hooks as $hook => $hook_events ) { foreach ( $hook_events as $sig => $data ) { - $events["$hook-$sig-$time"] = (object) array( + $events[] = (object) array( 'hook' => $hook, 'time' => $time, 'sig' => $sig, From 89b5d2ad39da9f405b4fe3964d58e6371ecdd682 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 25 Jul 2016 05:34:54 -0700 Subject: [PATCH 4767/4858] Register informational label for `@all`, instead of listing all aliases --- features/aliases.feature | 3 ++- php/WP_CLI/Runner.php | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/features/aliases.feature b/features/aliases.feature index cd0135b646..a801e8527f 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -107,6 +107,7 @@ Feature: Create shortcuts to specific WordPress installs When I run `wp cli alias` Then STDOUT should be YAML containing: """ + @all: Run command against every registered alias. @testdir: path: testdir """ @@ -114,7 +115,7 @@ Feature: Create shortcuts to specific WordPress installs When I run `wp cli alias --format=json` Then STDOUT should be JSON containing: """ - {"@testdir":{"path":"testdir"}} + {"@all":"Run command against every registered alias.","@testdir":{"path":"testdir"}} """ Scenario: Defining a project alias completely overrides a global alias diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c70d449ce8..edc25836c1 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -641,7 +641,9 @@ private function init_config() { list( $this->config, $this->extra_config ) = $configurator->to_array(); $this->aliases = $configurator->get_aliases(); if ( count( $this->aliases ) && ! isset( $this->aliases['@all'] ) ) { - $this->aliases['@all'] = array_keys( $this->aliases ); + $this->aliases = array_reverse( $this->aliases ); + $this->aliases['@all'] = 'Run command against every registered alias.'; + $this->aliases = array_reverse( $this->aliases ); } $this->_required_files['runtime'] = $this->config['require']; } @@ -717,9 +719,17 @@ public function start() { $this->check_root(); if ( $this->alias ) { - if ( '@all' === $this->alias && 0 === count( $this->aliases ) ) { - WP_CLI::error( "Cannot use '@all' when no aliases are registered." ); + if ( '@all' === $this->alias && is_string( $this->aliases['@all'] ) ) { + if ( 0 === count( $this->aliases ) ) { + WP_CLI::error( "Cannot use '@all' when no aliases are registered." ); + } + $aliases = array_keys( $this->aliases ); + $k = array_search( '@all', $aliases ); + unset( $aliases[ $k ] ); + $this->run_alias_group( $aliases ); + exit; } + if ( ! array_key_exists( $this->alias, $this->aliases ) ) { WP_CLI::error( "Alias '{$this->alias}' not found." ); } From 28b58d93045bc43dcdd29f36abbeaf154525f428 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 25 Jul 2016 06:37:43 -0700 Subject: [PATCH 4768/4858] Make sure `@all` is set to prevent error notice --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index edc25836c1..a4b2378f32 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -719,7 +719,7 @@ public function start() { $this->check_root(); if ( $this->alias ) { - if ( '@all' === $this->alias && is_string( $this->aliases['@all'] ) ) { + if ( '@all' === $this->alias && isset( $this->aliases['@all'] ) && is_string( $this->aliases['@all'] ) ) { if ( 0 === count( $this->aliases ) ) { WP_CLI::error( "Cannot use '@all' when no aliases are registered." ); } From 8fa9ea91266bef96d5d1bde6664bd8b45220a891 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 25 Jul 2016 11:59:36 -0700 Subject: [PATCH 4769/4858] Fix error message for no aliases registered --- php/WP_CLI/Runner.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index a4b2378f32..d43a0bb7b2 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -719,10 +719,11 @@ public function start() { $this->check_root(); if ( $this->alias ) { - if ( '@all' === $this->alias && isset( $this->aliases['@all'] ) && is_string( $this->aliases['@all'] ) ) { - if ( 0 === count( $this->aliases ) ) { - WP_CLI::error( "Cannot use '@all' when no aliases are registered." ); - } + if ( '@all' === $this->alias && ! isset( $this->aliases['@all'] ) ) { + WP_CLI::error( "Cannot use '@all' when no aliases are registered." ); + } + + if ( '@all' === $this->alias && is_string( $this->aliases['@all'] ) ) { $aliases = array_keys( $this->aliases ); $k = array_search( '@all', $aliases ); unset( $aliases[ $k ] ); From 3a4c98e565ab7b0f6db67840172e738065fe7de6 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Mon, 25 Jul 2016 13:58:44 -0700 Subject: [PATCH 4770/4858] Introduce `WP_CLI::add_wp_hook()` Aka `add_action()` without needing access to `add_action()`. --- php/WP_CLI/Runner.php | 112 ++++++------------------------------------ php/class-wp-cli.php | 67 +++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 96 deletions(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index c70d449ce8..df93c599e5 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -1021,22 +1021,22 @@ private function setup_bootstrap_hooks() { } if ( $this->config['skip-themes'] ) { - $this->add_wp_hook( 'setup_theme', array( $this, 'action_setup_theme_wp_cli_skip_themes' ), 999 ); + WP_CLI::add_wp_hook( 'setup_theme', array( $this, 'action_setup_theme_wp_cli_skip_themes' ), 999 ); } - $this->add_wp_hook( 'wp_die_handler', function() { return '\WP_CLI\Utils\wp_die_handler'; } ); + WP_CLI::add_wp_hook( 'wp_die_handler', function() { return '\WP_CLI\Utils\wp_die_handler'; } ); // Prevent code from performing a redirect - $this->add_wp_hook( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); + WP_CLI::add_wp_hook( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' ); - $this->add_wp_hook( 'nocache_headers', function( $headers ){ + WP_CLI::add_wp_hook( 'nocache_headers', function( $headers ){ Utils\wp_not_installed(); return $headers; }); // ALTERNATE_WP_CRON might trigger a redirect, which we can't handle if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { - $this->add_wp_hook( 'muplugins_loaded', function() { + WP_CLI::add_wp_hook( 'muplugins_loaded', function() { remove_action( 'init', 'wp_cron' ); }); } @@ -1052,22 +1052,22 @@ private function setup_bootstrap_hooks() { 'WPLANG' => '', ); foreach ( $values as $key => $value ) { - $this->add_wp_hook( "pre_site_option_$key", function () use ( $values, $key ) { + WP_CLI::add_wp_hook( "pre_site_option_$key", function () use ( $values, $key ) { return $values[ $key ]; } ); } } // Always permit operations against sites, regardless of status - $this->add_wp_hook( 'ms_site_check', '__return_true' ); + WP_CLI::add_wp_hook( 'ms_site_check', '__return_true' ); // Always permit operations against WordPress, regardless of maintenance mode - $this->add_wp_hook( 'enable_maintenance_mode', function() { + WP_CLI::add_wp_hook( 'enable_maintenance_mode', function() { return false; }); // Use our own debug mode handling instead of WP core - $this->add_wp_hook( 'enable_wp_debug_mode_checks', function( $ret ) { + WP_CLI::add_wp_hook( 'enable_wp_debug_mode_checks', function( $ret ) { Utils\wp_debug_mode(); // Check to see of wpdb is errored, instead of waiting for dead_db() @@ -1081,19 +1081,19 @@ private function setup_bootstrap_hooks() { }); // Never load advanced-cache.php drop-in when WP-CLI is operating - $this->add_wp_hook( 'enable_loading_advanced_cache_dropin', function() { + WP_CLI::add_wp_hook( 'enable_loading_advanced_cache_dropin', function() { return false; }); // In a multisite install, die if unable to find site given in --url parameter if ( $this->is_multisite() ) { - $this->add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { + WP_CLI::add_wp_hook( 'ms_site_not_found', function( $current_site, $domain, $path ) { WP_CLI::error( "Site {$domain}{$path} not found." ); }, 10, 3 ); } // The APC cache is not available on the command-line, so bail, to prevent cache poisoning - $this->add_wp_hook( 'muplugins_loaded', function() { + WP_CLI::add_wp_hook( 'muplugins_loaded', function() { if ( $GLOBALS['_wp_using_ext_object_cache'] && class_exists( 'APC_Object_Cache' ) ) { WP_CLI::warning( 'Running WP-CLI while the APC object cache is activated can result in cache corruption.' ); WP_CLI::confirm( 'Given the consequences, do you wish to continue?' ); @@ -1103,7 +1103,7 @@ private function setup_bootstrap_hooks() { // Handle --user parameter if ( ! defined( 'WP_INSTALLING' ) ) { $config = $this->config; - $this->add_wp_hook( 'init', function() use ( $config ) { + WP_CLI::add_wp_hook( 'init', function() use ( $config ) { if ( isset( $config['user'] ) ) { $fetcher = new \WP_CLI\Fetchers\User; $user = $fetcher->get_check( $config['user'] ); @@ -1143,9 +1143,9 @@ private function setup_skip_plugins_filters() { 'option_active_plugins', ); foreach( $hooks as $hook ) { - $this->add_wp_hook( $hook, $wp_cli_filter_active_plugins, 999 ); + WP_CLI::add_wp_hook( $hook, $wp_cli_filter_active_plugins, 999 ); } - $this->add_wp_hook( 'plugins_loaded', function() use ( $hooks, $wp_cli_filter_active_plugins ) { + WP_CLI::add_wp_hook( 'plugins_loaded', function() use ( $hooks, $wp_cli_filter_active_plugins ) { foreach( $hooks as $hook ) { remove_filter( $hook, $wp_cli_filter_active_plugins, 999 ); } @@ -1186,93 +1186,13 @@ public function action_setup_theme_wp_cli_skip_themes() { add_filter( $hook, $wp_cli_filter_active_theme, 999 ); } // Clean up after the TEMPLATEPATH and STYLESHEETPATH constants are defined - $this->add_wp_hook( 'after_setup_theme', function() use ( $hooks, $wp_cli_filter_active_theme ) { + WP_CLI::add_wp_hook( 'after_setup_theme', function() use ( $hooks, $wp_cli_filter_active_theme ) { foreach( $hooks as $hook ) { remove_filter( $hook, $wp_cli_filter_active_theme, 999 ); } }, 0 ); } - /** - * Add a callback to a WordPress action or filter - * - * Essentially add_filter() without needing access to add_filter() - */ - private function add_wp_hook( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { - global $wp_filter, $merged_filters; - $idx = $this->wp_hook_build_unique_id($tag, $function_to_add, $priority); - $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); - unset( $merged_filters[ $tag ] ); - return true; - } - - /** - * Remove a callback from a WordPress action or filter - * - * Essentially remove_filter() without needing access to remove_filter() - */ - private function remove_wp_hook( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { - $function_to_remove = $this->wp_hook_build_unique_id( $tag, $function_to_remove, $priority ); - - $r = isset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); - - if ( true === $r ) { - unset( $GLOBALS['wp_filter'][ $tag ][ $priority ][ $function_to_remove ] ); - if ( empty( $GLOBALS['wp_filter'][ $tag ][ $priority ] ) ) { - unset( $GLOBALS['wp_filter'][ $tag ][ $priority ] ); - } - if ( empty( $GLOBALS['wp_filter'][ $tag ] ) ) { - $GLOBALS['wp_filter'][ $tag ] = array(); - } - unset( $GLOBALS['merged_filters'][ $tag ] ); - } - - return $r; - } - - /** - * Build Unique ID for storage and retrieval. - * - * Essentially _wp_filter_build_unique_id() without needing access to _wp_filter_build_unique_id() - */ - private function wp_hook_build_unique_id( $tag, $function, $priority ) { - global $wp_filter; - static $filter_id_count = 0; - - if ( is_string($function) ) - return $function; - - if ( is_object($function) ) { - // Closures are currently implemented as objects - $function = array( $function, '' ); - } else { - $function = (array) $function; - } - - if (is_object($function[0]) ) { - // Object Class Calling - if ( function_exists('spl_object_hash') ) { - return spl_object_hash($function[0]) . $function[1]; - } else { - $obj_idx = get_class($function[0]).$function[1]; - if ( !isset($function[0]->wp_filter_id) ) { - if ( false === $priority ) - return false; - $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; - $function[0]->wp_filter_id = $filter_id_count; - ++$filter_id_count; - } else { - $obj_idx .= $function[0]->wp_filter_id; - } - - return $obj_idx; - } - } elseif ( is_string( $function[0] ) ) { - // Static Calling - return $function[0] . '::' . $function[1]; - } - } - /** * Whether or not this WordPress install is multisite. * diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 7d3d970993..14024ac982 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -256,6 +256,73 @@ public static function do_hook( $when ) { } } + /** + * Add a callback to a WordPress action or filter. + * + * `add_action()` without needing access to `add_action()`. If WordPress is + * already loaded though, you should use `add_action()` (and `add_filter()`) + * instead. + * + * @access public + * @category Registration + * + * @param string $tag Named WordPress action or filter. + * @param mixed $function_to_add Callable to execute when the action or filter is evaluated. + * @param integer $priority Priority to add the callback as. + * @param integer $accepted_args Number of arguments to pass to callback. + * @return true + */ + public static function add_wp_hook( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { + global $wp_filter, $merged_filters; + $idx = self::wp_hook_build_unique_id( $tag, $function_to_add, $priority ); + $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); + unset( $merged_filters[ $tag ] ); + return true; + } + + /** + * Build Unique ID for storage and retrieval. + * + * Essentially _wp_filter_build_unique_id() without needing access to _wp_filter_build_unique_id() + */ + private static function wp_hook_build_unique_id( $tag, $function, $priority ) { + global $wp_filter; + static $filter_id_count = 0; + + if ( is_string($function) ) + return $function; + + if ( is_object($function) ) { + // Closures are currently implemented as objects + $function = array( $function, '' ); + } else { + $function = (array) $function; + } + + if (is_object($function[0]) ) { + // Object Class Calling + if ( function_exists('spl_object_hash') ) { + return spl_object_hash($function[0]) . $function[1]; + } else { + $obj_idx = get_class($function[0]).$function[1]; + if ( !isset($function[0]->wp_filter_id) ) { + if ( false === $priority ) + return false; + $obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count; + $function[0]->wp_filter_id = $filter_id_count; + ++$filter_id_count; + } else { + $obj_idx .= $function[0]->wp_filter_id; + } + + return $obj_idx; + } + } elseif ( is_string( $function[0] ) ) { + // Static Calling + return $function[0] . '::' . $function[1]; + } + } + /** * Register a command to WP-CLI. * From d7ce2561eeeaf4385794e4c2632dcb6495be0b99 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 27 Jul 2016 16:17:18 +0545 Subject: [PATCH 4771/4858] Update success message for widget deactivate --- php/commands/widget.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/php/commands/widget.php b/php/commands/widget.php index bcc7f37050..81a5fe476b 100644 --- a/php/commands/widget.php +++ b/php/commands/widget.php @@ -24,7 +24,7 @@ * * # Delete one or more widgets entirely * $ wp widget delete calendar-2 archive-1 - * Success: Widget(s) removed from sidebar. + * Success: 2 widgets removed from sidebar. */ class Widget_Command extends WP_CLI_Command { @@ -258,12 +258,14 @@ public function move( $args, $assoc_args ) { * ## EXAMPLES * * $ wp widget deactivate recent-comments-2 - * Success: Widget(s) deactivated. + * Success: 1 widget deactivated. * * @subcommand deactivate */ public function deactivate( $args, $assoc_args ) { + $count = 0; + foreach( $args as $widget_id ) { $this->validate_sidebar_widget( $widget_id ); @@ -275,9 +277,12 @@ public function deactivate( $args, $assoc_args ) { $this->move_sidebar_widget( $widget_id, $sidebar_id, 'wp_inactive_widgets', $sidebar_index, 0 ); + $count++; + } - WP_CLI::success( "Widget(s) deactivated." ); + $success_message = ( 1 === $count ) ? '%d widget deactivated.' : '%d widgets deactivated.'; + WP_CLI::success( sprintf( $success_message, $count ) ); } /** @@ -291,7 +296,7 @@ public function deactivate( $args, $assoc_args ) { * ## EXAMPLES * * $ wp widget delete recent-comments-2 - * Success: Widget(s) removed from sidebar. + * Success: 1 widget removed from sidebar. * * @subcommand delete */ From f54b52628e183cbe319b52f1f6a3471cd280a31a Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Wed, 27 Jul 2016 16:17:49 +0545 Subject: [PATCH 4772/4858] Fix test to reflect update of message in widget deactivate --- features/widget.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/widget.feature b/features/widget.feature index 6bc3b259cb..e5eb4609ff 100644 --- a/features/widget.feature +++ b/features/widget.feature @@ -35,7 +35,7 @@ Feature: Manage widgets in WordPress sidebar When I run `wp widget deactivate meta-2` Then STDOUT should be: """ - Success: Widget(s) deactivated. + Success: 1 widget deactivated. """ When I run `wp widget list sidebar-1 --fields=name,id,position` From 69f81199adede2b5d890dd136b1474d81a363eb3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 27 Jul 2016 04:26:56 -0700 Subject: [PATCH 4773/4858] Update .mailmap --- .mailmap | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.mailmap b/.mailmap index 115f09c474..ff35d0d236 100644 --- a/.mailmap +++ b/.mailmap @@ -5,6 +5,7 @@ Anant Shrivastava <anant@anantshri.info> Andreas Heigl <andreas@heigl.org> andreascreten <andreas@madewithlove.be> Andrew Patton <andrew@acusti.ca> +andyexeter <palmer.andy@gmail.com> BA <kau@connecticum.de> bartaakos <akos@netpositive.hu> bendoh <ben@thinkoomph.com> @@ -36,8 +37,10 @@ drrobotnik <B@Brandons-Mac-Pro-4.local> Duncan Brown <duncanjbrown@gmail.com> dwightjack <marco.solazzi@gmail.com> Eduardo Alencar <ealencar10@gmail.com> +Enrico Sorcinelli <enrico.sorcinelli@italiaonline.it> ericandrewlewis <eric.andrew.lewis@gmail.com> ericmann <eric@eamann.com> +ernilambar <nilambar@outlook.com> eugeneware <eugene@noblesamurai.com> Evan Mattson <me@aaemnnost.tv> francescolaffi <francesco.laffi@gmail.com> @@ -45,12 +48,15 @@ Frank Staude <frank@staude.net> Frankie Jarrett <fjarrett@godaddy.com> future500 <ramon@future500.nl> Gary Jones <gamajo@gamajo.com> +Geo <geo.artemenko@gmail.com> getsource <mike.schroder@dreamhost.com> Gilbert Pellegrom <gilbert@pellegrom.me> glebis <glebis@gmail.com> goldenapples <ntaintor@janrain.com> Grant McInnes <grant.mcinnes@eyesopen.ca> Greg Anderson <greg.1.anderson@greenknowe.org> +hideokamoto <kokkoku214@gmail.com> +Hidetaka Okamoto <kokkoku214@gmail.com> hina <hina@hinaloe.net> hinoue-work <wpuser@wp-cli-14.04> Hiroshi Urabe <mail@torounit.com> @@ -58,6 +64,7 @@ Ian Dunn <ian@iandunn.name> itsananderson <will@itsananderson.com> j3lamp <j3lamp@gmail.com> jacobischwartz <jacob@schwambell.com> +Jakub Juszczak <netghost03@gmail.com> Jan Voráček <jan@voracek.net> Jeff Gould <jrgould@gmail.com> jeichorn <joshua.eichorn@pagely.com> @@ -66,6 +73,7 @@ jghazally <jeff@bigfish.co.uk> jghazally <jghazally@gmail.com> Jim Reevior <jim@thinkoomph.com> jmslbam <jmslbam@gmail.com> +John Blackbourn <john@johnblackbourn.com> johnbillion <johnbillion@gmail.com> johnpbloch <jbloch@John-Blochs-iMac.local> johnpbloch <johnpbloch@gmail.com> @@ -75,6 +83,7 @@ joshbetz <j@joshbetz.com> joshlevinson <joshalevinson@gmail.com> JQ <JeyKeu@users.noreply.github.com> KDoole <dev@Kevins-iMac.local> +Keanan Koppenhaver <keanan@doejo.com> Keith Grennan <keith@nearlyfree.org> Kevin Doole <kdoole@farmmedia.com> Kevinlearynet <info@kevinleary.net> @@ -105,12 +114,15 @@ mwilliamson <michael.williamson@red-gate.com> mwilliamson <mike@zwobble.org> mwithheld <vhmark@gmail.com> nacin <andrewnacin@gmail.com> +Nate Wright <natew@notthisway.com> navitronic <adrian@navitronic.co.uk> nb <nb@nikolay.bg> nickdaugherty <ndaugherty987@gmail.com> +nikhilc@bsf.io <nikhilc@bsf.io> nikolay <nikolay@users.noreply.github.com> nikolay <nikolaynkolev@gmail.com> Nilambar Sharma <ernilambar@users.noreply.github.com> +Nilambar Sharma <nilambar@outlook.com> nschoenholtz <noah@alleyinteractive.com> nullvariable <nullvariable@gmail.com> nyordanov <me@nyordanov.com> @@ -121,14 +133,20 @@ om4james <james@om4.com.au> oneumyvakin <oneumyvakin@gmail.com> Otto Kekäläinen <otto@seravo.fi> ozh <ozh@ozh.org> +Pete Nelson <pete@petenelson.com> +pete@petenelson.com <petenelson@fortress.local> +Peter J. Herrel <peterherrel@gmail.com> phh <phh@peytz.dk> Pippin Williamson <pippin@pippinsplugins.com> +Rachel Baker <rachel@rachelbaker.me> Radu Dan <za_creature@yahoo.com> Rarst <contact@rarst.net> robertboloc <robertboloc@gmail.com> Robin Schneider <ypid@riseup.net> rodrigoprimo <rodrigo@hacklab.com.br> rodrigoprimo <rodrigosprimo@gmail.com> +Roel Veldhuizen <roel@inesta.nl> +roelveldhuizen <roel@inesta.nl> roelven <roel@soundcloud.com> Ross Hattori <rhattori@saymedia.com> Ryan Hoover <ryanshoover@gmail.com> @@ -140,6 +158,7 @@ sboisvert <stephane.boisvert@automattic.com> scribu <mail@scribu.net> scribu <scribu@gmail.com> sebastiaandegeus <sebastiaan@hoppinger.com> +Shinichi Nishikawa <shinichi.nishikawa@gmail.com> sibprogrammer <ayuzhakov@parallels.com> simonwheatley <simonw@codeforthepeople.com> soulou <leo@soulou.fr> @@ -147,10 +166,14 @@ spacedmonkey <spacedmonkey2@gmail.com> SpikesDivZero <wesley.spikes@gmail.com> spuriousdata <spuriousdata@gmail.com> Stephen Edgar <stephen@netweb.com.au> +Stephen Harris <contact@stephenharris.info> +Stephen Harris <Stephen.Harris@gov.scot> +Stephen Harris <Stephen.Harris@scotland.gsi.gov.uk> Steve Grunwell <steve.grunwell@10up.com> Steve Grunwell <steve@stevegrunwell.com> Steve Grunwell <stevegrunwell@gmail.com> Steve Persch <steve.persch@pantheon.io> +Steven K Word <stevenword@gmail.com> stianlik <stianlik@gmail.com> svaj <chris@chrisbot.(none)> Svetoslav Marinov (Slavi) <slavi@orbisius.com> @@ -167,8 +190,12 @@ trepmal <trepmal@gmail.com> Tristan Penman <tristan@tristanpenman.com> twisty <tim@brayshaw.com> twratajczak <tomasz.ratajczak@espeo.pl> +Utkarsh Patel <iamutkarsh@live.com> +Ville Vuorenmaa <villevuor@gmail.com> voldemortensen <voldemortensen@users.noreply.github.com> Wendell Júnior <wrnx00@gmail.com> +Wes Moberly <wesm87@gmail.com> +Wes Moberly <wesm87@users.noreply.github.com> westonruter <weston@x-team.com> westonruter <westonruter@gmail.com> William Turrell <william@wturrell.co.uk> From 90e747acba4347875b7dcb2a1f1f390117dbd01d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 27 Jul 2016 04:27:14 -0700 Subject: [PATCH 4774/4858] Version bump --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5d22270f29..2094a100ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.24.0-alpha +0.24.0 From a5945813fecb0a2a11f97b1c445ba525c593cd2f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 27 Jul 2016 06:30:25 -0700 Subject: [PATCH 4775/4858] Version bump again --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 2094a100ca..4037ec0659 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.24.0 +0.25.0-alpha From 01747d920d3bbfb34f1eefb73760ef1e1b0b48c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 28 Jul 2016 15:03:02 +0200 Subject: [PATCH 4776/4858] Support PHP 7 on Debian-based systems Fixes #3206 --- utils/wp-cli-updatedeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh index 9558295641..d0acfa1b9a 100755 --- a/utils/wp-cli-updatedeb.sh +++ b/utils/wp-cli-updatedeb.sh @@ -31,7 +31,7 @@ Architecture: all Maintainer: Daniel Bachhuber <daniel@handbuilt.co> Section: php Priority: optional -Depends: php5-cli, php5-mysql | php5-mysqlnd, mysql-client | mariadb-client +Depends: php5-cli | php7.0-cli, php5-mysql | php5-mysqlnd, mysql-client | mariadb-client Homepage: http://wp-cli.org/ Description: wp-cli is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite From 8cba590cf01ef6abdfd153893e68a1e16d790e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Thu, 28 Jul 2016 20:59:04 +0200 Subject: [PATCH 4777/4858] Add support for php7.0-mysql as Debian dependency --- utils/wp-cli-updatedeb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh index d0acfa1b9a..ee222436ce 100755 --- a/utils/wp-cli-updatedeb.sh +++ b/utils/wp-cli-updatedeb.sh @@ -31,7 +31,7 @@ Architecture: all Maintainer: Daniel Bachhuber <daniel@handbuilt.co> Section: php Priority: optional -Depends: php5-cli | php7.0-cli, php5-mysql | php5-mysqlnd, mysql-client | mariadb-client +Depends: php5-cli | php7.0-cli, php5-mysql | php5-mysqlnd | php7.0-mysql, mysql-client | mariadb-client Homepage: http://wp-cli.org/ Description: wp-cli is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite From 20fcb462053c5116d9aaae5a7ca02b4c72e3cf2c Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 29 Jul 2016 10:15:42 +0545 Subject: [PATCH 4778/4858] Update success message in theme mod remove --- php/commands/theme.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index b8b2cd83cb..265843337b 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -723,15 +723,15 @@ public function list_( $_, $assoc_args ) { * * ## EXAMPLES * - * # Set theme mod + * # Set theme mod. * $ wp theme mod set background_color 000000 * Success: Theme mod background_color set to 000000 * - * # Get single theme mod in JSON format + * # Get single theme mod in JSON format. * $ wp theme mod get background_color --format=json * [{"key":"background_color","value":"dd3333"}] * - * # Remove all theme mods + * # Remove all theme mods. * $ wp theme mod remove --all * Success: Theme mods removed. */ @@ -836,19 +836,19 @@ public function get( $args = array(), $assoc_args = array() ) { * : One or more mods to remove. * * [--all] - * : Remove all theme mods + * : Remove all theme mods. * * ## EXAMPLES * - * # Remove all theme mods + * # Remove all theme mods. * $ wp theme mod remove --all * Success: Theme mods removed. * - * # Remove single theme mods + * # Remove single theme mod. * $ wp theme mod remove background_color - * Success: 1 mods removed. + * Success: 1 mod removed. * - * # Remove multiple theme mods + * # Remove multiple theme mods. * $ wp theme mod remove background_color header_textcolor * Success: 2 mods removed. */ @@ -868,7 +868,9 @@ public function remove( $args = array(), $assoc_args = array() ) { remove_theme_mod( $mod ); } - WP_CLI::success( sprintf( '%d mods removed.', count( $args ) ) ); + $count = count( $args ); + $success_message = ( 1 === $count ) ? '%d mod removed.' : '%d mods removed.'; + WP_CLI::success( sprintf( $success_message, $count ) ); } From f73992e8a85b051f3657668a128d7402661aa846 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 29 Jul 2016 10:16:06 +0545 Subject: [PATCH 4779/4858] Fix test to reflect updated message in theme mod remove --- features/theme-mod.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/theme-mod.feature b/features/theme-mod.feature index 61ac1d6aa8..1d014d491c 100644 --- a/features/theme-mod.feature +++ b/features/theme-mod.feature @@ -53,7 +53,7 @@ Feature: Manage WordPress theme mods When I run `wp theme mod remove background_color` Then STDOUT should be: """ - Success: 1 mods removed. + Success: 1 mod removed. """ When I run `wp theme mod remove background_color header_textcolor` From bfc93da668f3ed05d0f22e0135cef2aebd559b96 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 29 Jul 2016 15:58:31 +0545 Subject: [PATCH 4780/4858] Update success message in menu item delete --- php/commands/menu.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 2f1bf815c0..0937139592 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -217,7 +217,7 @@ protected function get_formatter( &$assoc_args ) { * * # Delete menu item * $ wp menu item delete 45 - * Success: Menu item(s) deleted. + * Success: 1 menu item deleted. */ class Menu_Item_Command extends WP_CLI_Command { @@ -550,13 +550,15 @@ public function update( $args, $assoc_args ) { * ## EXAMPLES * * $ wp menu item delete 45 - * Success: Menu item(s) deleted. + * Success: 1 menu item deleted. * * @subcommand delete */ public function delete( $args, $_ ) { global $wpdb; + $count = 0; + foreach( $args as $arg ) { $parent_menu_id = (int) get_post_meta( $arg, '_menu_item_menu_item_parent', true ); @@ -574,8 +576,14 @@ public function delete( $args, $_ ) { } } + if ( false !== $ret ) { + $count++; + } + } - WP_CLI::success( "Menu item(s) deleted." ); + + $success_message = ( 1 === $count ) ? '%d menu item deleted.' : '%d menu items deleted.'; + WP_CLI::success( sprintf( $success_message, $count ) ); } From 48fa7bc6190c29fa9d12286bceb95860b903384d Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 29 Jul 2016 15:59:08 +0545 Subject: [PATCH 4781/4858] Fix test to reflect updated message in menu item delete --- features/menu.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/menu.feature b/features/menu.feature index 3532450bee..157e149ac4 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -124,6 +124,10 @@ Feature: Manage WordPress menus Then STDOUT should not be empty When I run `wp menu item delete {CUSTOM_ITEM_ID}` + Then STDOUT should be: + """ + Success: 1 menu item deleted. + """ And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: """ @@ -131,6 +135,10 @@ Feature: Manage WordPress menus """ When I run `wp menu item delete {POST_ITEM_ID} {TERM_ITEM_ID}` + Then STDOUT should be: + """ + Success: 2 menu items deleted. + """ And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: """ From bf974d246eb93af040004869ffce2e5d3b1a084b Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Fri, 29 Jul 2016 16:11:09 +0545 Subject: [PATCH 4782/4858] Add missing heading in doc of cli cmd-dump --- php/commands/cli.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/cli.php b/php/commands/cli.php index 3f9a614025..7441d26358 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -430,6 +430,8 @@ function param_dump( $_, $assoc_args ) { /** * Dump the list of installed commands, as JSON. * + * ## EXAMPLES + * * # Dump the list of installed commands * $ wp cli cmd-dump * {"name":"wp","description":"Manage WordPress through the command-line.","longdesc":"\n\n## GLOBAL PARAMETERS\n\n --path=<path>\n Path to the WordPress files.\n\n --ssh=<ssh>\n Perform operation against a remote server over SSH.\n\n --url=<url>\n Pretend request came from given URL. In multisite, this argument is how the target site is specified. \n\n --user=<id|login|email>\n From 8d0ea143a634623f47bb868e07a9e3d943d89d68 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 29 Jul 2016 22:08:21 +0900 Subject: [PATCH 4783/4858] improve help for ssh --- php/config-spec.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index c54c99dbfc..5696a1aad6 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -8,8 +8,8 @@ ), 'ssh' => array( - 'runtime' => '=<ssh>', - 'file' => '<ssh>', + 'runtime' => '=<user>[:<pass>]@<host>[:<port>]<path>', + 'file' => '<user>[:<pass>]@<host>[:<port>]<path>', 'desc' => 'Perform operation against a remote server over SSH.', ), @@ -108,4 +108,3 @@ ), ); - From 32c3d66876d0c59d4c21951c22904421e5ed2146 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Fri, 29 Jul 2016 23:28:22 +0900 Subject: [PATCH 4784/4858] remove :pass and some fix --- php/config-spec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index 7a10c1c759..7f6e4f877c 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -8,8 +8,8 @@ ), 'ssh' => array( - 'runtime' => '=<user>[:<pass>]@<host>[:<port>]<path>', - 'file' => '<user>[:<pass>]@<host>[:<port>]<path>', + 'runtime' => '=[<user>]@<host>[:<port>][<path>]', + 'file' => '[<user>]@<host>[:<port>][<path>]', 'desc' => 'Perform operation against a remote server over SSH.', ), From 455211d54b771bdcd35e7a7eae2ab67632de56b4 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Sun, 31 Jul 2016 15:50:19 +0545 Subject: [PATCH 4785/4858] Add example for cli alias --- php/commands/cli.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/php/commands/cli.php b/php/commands/cli.php index 7441d26358..03e907acd8 100644 --- a/php/commands/cli.php +++ b/php/commands/cli.php @@ -470,7 +470,7 @@ public function completions( $_, $assoc_args ) { * List available aliases. * * Aliases are shorthand references to WordPress installs. For instance, - * '@dev' could refer to a development install and '@prod' could refer to + * `@dev` could refer to a development install and `@prod` could refer to * a production install. This command gives you visibility in what * registered aliases you have available. * @@ -484,6 +484,20 @@ public function completions( $_, $assoc_args ) { * - yaml * - json * --- + * + * ## EXAMPLES + * + * # List all available aliases. + * $ wp cli alias + * --- + * @all: Run command against every registered alias. + * @prod: + * ssh: runcommand@runcommand.io~/webapps/production + * @dev: + * ssh: vagrant@192.168.50.10/srv/www/runcommand.dev + * @both: + * - @prod + * - @dev */ public function alias( $_, $assoc_args ) { WP_CLI::print_value( WP_CLI::get_runner()->aliases, $assoc_args ); From f04647998af6059f4140d25dc70c016cabf9c8f7 Mon Sep 17 00:00:00 2001 From: Rahul Prajapati <rahul.prajapati@rtcamp.com> Date: Tue, 2 Aug 2016 00:42:36 +0530 Subject: [PATCH 4786/4858] display default core language in "wp core version --extra". --- features/core-version.feature | 1 + php/commands/core.php | 7 ++++--- templates/versions.mustache | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/features/core-version.feature b/features/core-version.feature index 3904c5b23b..6eecbfe997 100644 --- a/features/core-version.feature +++ b/features/core-version.feature @@ -16,4 +16,5 @@ Feature: Find version for WordPress install WordPress version: 4.4.2 Database revision: 35700 TinyMCE version: 4.208 (4208-20151113) + Language: en_US """ diff --git a/php/commands/core.php b/php/commands/core.php index eafc38a57d..57e5289582 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -945,9 +945,10 @@ public function version( $args = array(), $assoc_args = array() ) { } echo \WP_CLI\Utils\mustache_render( 'versions.mustache', array( - 'wp-version' => $details['wp_version'], - 'db-version' => $details['wp_db_version'], - 'mce-version' => ( $human_readable_tiny_mce ? + 'wp-version' => $details[ 'wp_version' ], + 'db-version' => $details[ 'wp_db_version' ], + 'local-package' => ! empty( $details[ 'wp_local_package' ] ) ? $details[ 'wp_local_package' ] : 'en_US', + 'mce-version' => ( $human_readable_tiny_mce ? "$human_readable_tiny_mce ({$details['tinymce_version']})" : $details['tinymce_version'] ) diff --git a/templates/versions.mustache b/templates/versions.mustache index 06c0e8ea95..c605510237 100644 --- a/templates/versions.mustache +++ b/templates/versions.mustache @@ -1,3 +1,4 @@ WordPress version: {{wp-version}} Database revision: {{db-version}} TinyMCE version: {{mce-version}} +Package Language: {{local-package}} From e98d0e78262d0285cbc82c0459dcde00aba5a805 Mon Sep 17 00:00:00 2001 From: Rahul Prajapati <rahul.prajapati@rtcamp.com> Date: Tue, 2 Aug 2016 00:56:56 +0530 Subject: [PATCH 4787/4858] Fixed issues: WPCS and testcase --- features/core-version.feature | 2 +- php/commands/core.php | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/features/core-version.feature b/features/core-version.feature index 6eecbfe997..42da49bb94 100644 --- a/features/core-version.feature +++ b/features/core-version.feature @@ -16,5 +16,5 @@ Feature: Find version for WordPress install WordPress version: 4.4.2 Database revision: 35700 TinyMCE version: 4.208 (4208-20151113) - Language: en_US + Package Language: en_US """ diff --git a/php/commands/core.php b/php/commands/core.php index 57e5289582..ea6d1cfa45 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -945,9 +945,12 @@ public function version( $args = array(), $assoc_args = array() ) { } echo \WP_CLI\Utils\mustache_render( 'versions.mustache', array( - 'wp-version' => $details[ 'wp_version' ], - 'db-version' => $details[ 'wp_db_version' ], - 'local-package' => ! empty( $details[ 'wp_local_package' ] ) ? $details[ 'wp_local_package' ] : 'en_US', + 'wp-version' => $details['wp_version'], + 'db-version' => $details['wp_db_version'], + 'local-package' => ( empty( $details['wp_local_package'] ) ? + 'en_US' + : $details['wp_local_package'] + ), 'mce-version' => ( $human_readable_tiny_mce ? "$human_readable_tiny_mce ({$details['tinymce_version']})" : $details['tinymce_version'] From f9ffd2ef9cfc7fbe639c1c749b65efc900e9c6dd Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 2 Aug 2016 04:22:33 -0700 Subject: [PATCH 4788/4858] Fix backwards compat shim to only affect `wp site create --- features/site.feature | 3 +++ php/WP_CLI/Runner.php | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/features/site.feature b/features/site.feature index 4f3c9308ce..03d62de2c6 100644 --- a/features/site.feature +++ b/features/site.feature @@ -27,6 +27,9 @@ Feature: Manage sites in a multisite installation 1 2 """ + When I run `wp site list --site_id=2 --format=ids` + Then STDOUT should be empty + When I run `wp --url=first.example.com option get home` Then STDOUT should be: """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 592081b286..d73b8a0798 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -471,8 +471,8 @@ private static function back_compat_conversions( $args, $assoc_args ) { unset( $assoc_args['admin_name'] ); } - // site --site_id= -> site --network_id= - if ( count( $args ) > 0 && 'site' == $args[0] && isset( $assoc_args['site_id'] ) ) { + // site create --site_id= -> site create --network_id= + if ( count( $args ) >= 2 && 'site' === $args[0] && 'create' === $args[1] && isset( $assoc_args['site_id'] ) ) { $assoc_args['network_id'] = $assoc_args['site_id']; unset( $assoc_args['site_id'] ); } From 6d973d8656279f65cc4679de783b092d06a0b3a0 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 2 Aug 2016 21:24:59 +0545 Subject: [PATCH 4789/4858] Update success message in menu delete command --- php/commands/menu.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 0937139592..176e4530eb 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -89,6 +89,8 @@ public function create( $args, $assoc_args ) { */ public function delete( $args, $_ ) { + $count = 0; + foreach( $args as $arg ) { $ret = wp_delete_nav_menu( $arg ); @@ -98,10 +100,16 @@ public function delete( $args, $_ ) { WP_CLI::warning( "Error deleting menu." ); } + else { + + $count++; + + } } - WP_CLI::success( "Menu(s) deleted." ); + $success_message = ( 1 === $count ) ? '%d menu deleted.' : '%d menus deleted.'; + WP_CLI::success( sprintf( $success_message, $count ) ); } From fa156bae4a09759d0fd5c36185be1f43eb48343a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 2 Aug 2016 21:25:43 +0545 Subject: [PATCH 4790/4858] Improve test to reflect message update in menu delete --- features/menu.feature | 60 ++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/features/menu.feature b/features/menu.feature index 157e149ac4..1d26121c16 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -12,11 +12,15 @@ Feature: Manage WordPress menus | My Menu | my-menu | When I run `wp menu delete "My Menu"` + Then STDOUT should be: + """ + Success: 1 menu deleted. + """ And I run `wp menu list --format=count` Then STDOUT should be: - """ - 0 - """ + """ + 0 + """ When I run `wp menu create "First Menu"` And I run `wp menu create "Second Menu"` @@ -27,18 +31,22 @@ Feature: Manage WordPress menus | Second Menu | second-menu | When I run `wp menu delete "First Menu" "Second Menu"` + Then STDOUT should be: + """ + Success: 2 menus deleted. + """ And I run `wp menu list --format=count` Then STDOUT should be: - """ - 0 - """ + """ + 0 + """ When I run `wp menu create "First Menu"` And I run `wp menu list --format=ids` Then STDOUT should be: - """ - 5 - """ + """ + 5 + """ Scenario: Assign / remove location from a menu @@ -55,11 +63,11 @@ Feature: Manage WordPress menus | slug | locations | | primary-menu | primary | - When I run `wp menu location list --format=ids` - Then STDOUT should be: - """ - primary - """ + When I run `wp menu location list --format=ids` + Then STDOUT should be: + """ + primary + """ When I run `wp menu location remove primary-menu primary` And I run `wp menu list --fields=slug,locations` @@ -125,25 +133,25 @@ Feature: Manage WordPress menus When I run `wp menu item delete {CUSTOM_ITEM_ID}` Then STDOUT should be: - """ - Success: 1 menu item deleted. - """ + """ + Success: 1 menu item deleted. + """ And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: - """ - 2 - """ + """ + 2 + """ When I run `wp menu item delete {POST_ITEM_ID} {TERM_ITEM_ID}` Then STDOUT should be: - """ - Success: 2 menu items deleted. - """ + """ + Success: 2 menu items deleted. + """ And I run `wp menu item list sidebar-menu --format=count` Then STDOUT should be: - """ - 0 - """ + """ + 0 + """ Scenario: Preserve grandparent item as ancestor of child item when parent item is removed. From f6ddbb175343406a6380e497d3002c10103b8638 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Tue, 2 Aug 2016 21:31:35 +0545 Subject: [PATCH 4791/4858] Update example doc in menu delete --- php/commands/menu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/commands/menu.php b/php/commands/menu.php index 176e4530eb..7fafe06760 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -85,7 +85,7 @@ public function create( $args, $assoc_args ) { * ## EXAMPLES * * $ wp menu delete "My Menu" - * Success: Menu(s) deleted. + * Success: 1 menu deleted. */ public function delete( $args, $_ ) { From 6fa817e4faf31e9c36ac213f2932615038e29285 Mon Sep 17 00:00:00 2001 From: Rahul Prajapati <rahul.prajapati@rtcamp.com> Date: Tue, 2 Aug 2016 22:52:05 +0530 Subject: [PATCH 4792/4858] Added language o/p in 'version --extra' command doc --- php/commands/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/commands/core.php b/php/commands/core.php index ea6d1cfa45..377bd00037 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -930,6 +930,7 @@ private static function get_clean_basedomain() { * WordPress version: 4.5.2 * Database revision: 36686 * TinyMCE version: 4.310 (4310-20160418) + * Package Language: en_US * * @when before_wp_load */ From b419b8a5ee1f9800868f0b45dbfc6f9120e1f623 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 3 Aug 2016 20:24:45 +0545 Subject: [PATCH 4793/4858] Improve example in option list --- php/commands/option.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/option.php b/php/commands/option.php index 2da6e107da..d15d473765 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -187,9 +187,9 @@ public function add( $args, $assoc_args ) { * +-------------+--------------+ * * # Delete all options begining with "theme_mods_" - * $ wp option list --search="theme_mods_*" --field=option_name | xargs -0 -d '\n' -I % wp option delete % + * $ wp option list --search="theme_mods_*" --field=option_name | xargs -I % wp option delete % * Success: Deleted 'theme_mods_twentysixteen' option. - * Success: Deleted 'theme_mods_twentfifteen' option. + * Success: Deleted 'theme_mods_twentyfifteen' option. * Success: Deleted 'theme_mods_twentyfourteen' option. * * @subcommand list From 52c2a58e81aff6f6cf1d8fa598955b2e3ea75c5a Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 3 Aug 2016 20:47:44 +0545 Subject: [PATCH 4794/4858] Improve example in plugin list command --- php/commands/plugin.php | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 608c261298..2a55e37a09 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -812,23 +812,24 @@ function delete( $args, $assoc_args = array() ) { * * ## EXAMPLES * + * # List active plugins on the site. * $ wp plugin list --status=active --format=json * [{"name":"dynamic-hostname","status":"active","update":"none","version":"0.4.2"},{"name":"tinymce-templates","status":"active","update":"none","version":"4.4.3"},{"name":"wp-multibyte-patch","status":"active","update":"none","version":"2.4"},{"name":"wp-total-hacks","status":"active","update":"none","version":"2.0.1"}] * - * # List plugins on each site in a network - * $ wp site list --field=url | xargs -n 1 -I % wp plugin list --url=% - * +------------------------------+----------------+-----------+------------+ - * | name | status | update | version | - * +------------------------------+----------------+-----------+------------+ - * | akismet | active-network | none | 3.1.11 | - * | hello | inactive | none | 1.6 | - * +------------------------------+----------------+-----------+------------+ - * +------------------------------+----------------+-----------+------------+ - * | name | status | update | version | - * +------------------------------+----------------+-----------+------------+ - * | akismet | active-network | none | 3.1.11 | - * | hello | inactive | none | 1.6 | - * +------------------------------+----------------+-----------+------------+ + * # List plugins on each site in a network. + * $ wp site list --field=url | xargs -I % wp plugin list --url=% + * +---------+----------------+--------+---------+ + * | name | status | update | version | + * +---------+----------------+--------+---------+ + * | akismet | active-network | none | 3.1.11 | + * | hello | inactive | none | 1.6 | + * +---------+----------------+--------+---------+ + * +---------+----------------+--------+---------+ + * | name | status | update | version | + * +---------+----------------+--------+---------+ + * | akismet | active-network | none | 3.1.11 | + * | hello | inactive | none | 1.6 | + * +---------+----------------+--------+---------+ * * @subcommand list */ From b1ee12b923c927eced71789bb635739b29a34263 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 3 Aug 2016 21:09:48 +0545 Subject: [PATCH 4795/4858] Improve doc for term generate command --- php/commands/term.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/php/commands/term.php b/php/commands/term.php index 0bce81736a..dc652d884a 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -361,10 +361,16 @@ public function delete( $args ) { * : The taxonomy for the generated terms. * * [--count=<number>] - * : How many terms to generate. Default: 100 + * : How many terms to generate? + * --- + * default: 100 + * --- * * [--max_depth=<number>] - * : Generate child terms down to a certain depth. Default: 1 + * : Generate child terms down to a certain depth. + * --- + * default: 1 + * --- * * [--format=<format>] * : Render output in a particular format. @@ -377,12 +383,12 @@ public function delete( $args ) { * * ## EXAMPLES * - * # Generate post categories + * # Generate post categories. * $ wp term generate category --count=10 * Generating terms 100% [=========] 0:02 / 0:02 * - * # Add meta to every generated term - * $ wp term generate category --format=ids --count=3 | xargs -0 -d ' ' -I % wp term meta add % foo bar + * # Add meta to every generated term. + * $ wp term generate category --format=ids --count=3 | xargs -d ' ' -I % wp term meta add % foo bar * Success: Added custom field. * Success: Added custom field. * Success: Added custom field. From 33840b025f8848a791460138a345ece52d1bea10 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Wed, 3 Aug 2016 21:23:35 +0545 Subject: [PATCH 4796/4858] Improve doc for post generate command --- php/commands/post.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/commands/post.php b/php/commands/post.php index c9744f9048..5c04292a20 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -447,19 +447,19 @@ public function list_( $_, $assoc_args ) { * * ## EXAMPLES * - * # Generate posts + * # Generate posts. * $ wp post generate --count=10 --post_type=page --post_date=1999-01-04 * Generating posts 100% [================================================] 0:01 / 0:04 * - * # Generate posts with fetched content + * # Generate posts with fetched content. * $ curl http://loripsum.net/api/5 | wp post generate --post_content --count=10 * % Total % Received % Xferd Average Speed Time Time Time Current * Dload Upload Total Spent Left Speed * 100 2509 100 2509 0 0 616 0 0:00:04 0:00:04 --:--:-- 616 * Generating posts 100% [================================================] 0:01 / 0:04 * - * # Add meta to every generated post - * $ wp post generate --format=ids | xargs -0 -d ' ' -I % wp post meta add % foo bar + * # Add meta to every generated posts. + * $ wp post generate --format=ids | xargs -d ' ' -I % wp post meta add % foo bar * Success: Added custom field. * Success: Added custom field. * Success: Added custom field. From 00732602bd8f5ac228788190dfb0307333784e8e Mon Sep 17 00:00:00 2001 From: Rahul Prajapati <rahul.prajapati@rtcamp.com> Date: Thu, 4 Aug 2016 01:10:57 +0530 Subject: [PATCH 4797/4858] added testcase for a non-en_US locale --- features/core-version.feature | 21 ++++++++++++++++++++- php/commands/core.php | 2 +- templates/versions.mustache | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/features/core-version.feature b/features/core-version.feature index 42da49bb94..b1bb640e96 100644 --- a/features/core-version.feature +++ b/features/core-version.feature @@ -16,5 +16,24 @@ Feature: Find version for WordPress install WordPress version: 4.4.2 Database revision: 35700 TinyMCE version: 4.208 (4208-20151113) - Package Language: en_US + Package language: en_US + """ + + Scenario: Installing WordPress for a non-default locale and verify core extended version information. + Given an empty directory + And an empty cache + + When I run `wp core download --version=4.4.2 --locale=de_DE` + Then STDOUT should be: + """ + Success: WordPress downloaded. + """ + + When I run `wp core version --extra` + Then STDOUT should be: + """ + WordPress version: 4.4.2 + Database revision: 35700 + TinyMCE version: 4.208 (4208-20151113) + Package language: de_DE """ diff --git a/php/commands/core.php b/php/commands/core.php index 377bd00037..16fc7363b0 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -930,7 +930,7 @@ private static function get_clean_basedomain() { * WordPress version: 4.5.2 * Database revision: 36686 * TinyMCE version: 4.310 (4310-20160418) - * Package Language: en_US + * Package language: en_US * * @when before_wp_load */ diff --git a/templates/versions.mustache b/templates/versions.mustache index c605510237..a52954e822 100644 --- a/templates/versions.mustache +++ b/templates/versions.mustache @@ -1,4 +1,4 @@ WordPress version: {{wp-version}} Database revision: {{db-version}} TinyMCE version: {{mce-version}} -Package Language: {{local-package}} +Package language: {{local-package}} From 69362a65581d3a0b6f50089807eddc6ed7e4919b Mon Sep 17 00:00:00 2001 From: Travis Northcutt <travis@memberup.co> Date: Wed, 3 Aug 2016 12:59:11 -0700 Subject: [PATCH 4798/4858] Add zsh tab completion info Ref: https://github.com/eddiezane/lunchy/issues/57#issuecomment-121173592 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index dfdc07e7a2..a9abb78050 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,14 @@ source /FULL/PATH/TO/wp-completion.bash Don't forget to run `source ~/.bash_profile` afterwards. +If using zsh for your shell, you may need to do the following: + +``` +autoload bashcompinit +bashcompinit +source /FULL/PATH/TO/wp-completion.bash +``` + ## Support WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: From 6811849db75a329e9aae84c587b149db0d96124d Mon Sep 17 00:00:00 2001 From: Travis Northcutt <travis@memberup.co> Date: Wed, 3 Aug 2016 13:24:08 -0700 Subject: [PATCH 4799/4858] Improve zsh tab completion instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9abb78050..304562bc4b 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ source /FULL/PATH/TO/wp-completion.bash Don't forget to run `source ~/.bash_profile` afterwards. -If using zsh for your shell, you may need to do the following: +If using zsh for your shell, you may need to load and start `bashcompinit`: ``` autoload bashcompinit From 66ac53fe4ba6829b25993ba5d19b7056fe649a9c Mon Sep 17 00:00:00 2001 From: Travis Northcutt <travis@memberup.co> Date: Wed, 3 Aug 2016 13:30:31 -0700 Subject: [PATCH 4800/4858] Improve zsh tab completion instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 304562bc4b..1a1b8fc30c 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ source /FULL/PATH/TO/wp-completion.bash Don't forget to run `source ~/.bash_profile` afterwards. -If using zsh for your shell, you may need to load and start `bashcompinit`: +If using zsh for your shell, you may need to load and start `bashcompinit` before sourcing. Put the following in your `.zshrc`: ``` autoload bashcompinit From 045de368a7f5aed23e8b218ef92dde2dc3cc5ab7 Mon Sep 17 00:00:00 2001 From: Rahul Prajapati <rahul.prajapati@rtcamp.com> Date: Thu, 4 Aug 2016 02:24:18 +0530 Subject: [PATCH 4801/4858] Added testcase for a non-en_US locale. command : 'wp core version --extra' --- features/core-version.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/core-version.feature b/features/core-version.feature index b1bb640e96..b46b47c30a 100644 --- a/features/core-version.feature +++ b/features/core-version.feature @@ -24,7 +24,7 @@ Feature: Find version for WordPress install And an empty cache When I run `wp core download --version=4.4.2 --locale=de_DE` - Then STDOUT should be: + Then STDOUT should contain: """ Success: WordPress downloaded. """ From 66c2269731acf13acdcdbabafa0ae16002f807e1 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 4 Aug 2016 11:31:32 +0545 Subject: [PATCH 4802/4858] Improve doc for comment generate command --- php/commands/comment.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/php/commands/comment.php b/php/commands/comment.php index c153104a9e..22def3485c 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -113,7 +113,10 @@ public function update( $args, $assoc_args ) { * ## OPTIONS * * [--count=<number>] - * : How many comments to generate. Default: 100 + * : How many comments to generate? + * --- + * default: 100 + * --- * * [--post_id=<post-id>] * : Assign comments to a specific post. @@ -129,8 +132,12 @@ public function update( $args, $assoc_args ) { * * ## EXAMPLES * - * # Add meta to every generated comment - * $ wp comment generate --format=ids --count=3 | xargs -0 -d ' ' -I % wp comment meta add % foo bar + * # Generate comments for the given post. + * $ wp comment generate --format=ids --count=3 --post_id=123 + * 138 139 140 + * + * # Add meta to every generated comment. + * $ wp comment generate --format=ids --count=3 | xargs -d ' ' -I % wp comment meta add % foo bar * Success: Added custom field. * Success: Added custom field. * Success: Added custom field. From 40dacd27c97a328e244dbc7b4ac4579a14347a73 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 4 Aug 2016 11:36:50 +0545 Subject: [PATCH 4803/4858] Improve doc in user generate command --- php/commands/user.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index 7298023e9c..b5a04c44cb 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -295,7 +295,7 @@ public function create( $args, $assoc_args ) { $user = new stdClass; list( $user->user_login, $user->user_email ) = $args; - + $assoc_args = wp_slash( $assoc_args ); if ( username_exists( $user->user_login ) ) { @@ -409,18 +409,27 @@ public function update( $args, $assoc_args ) { * ## OPTIONS * * [--count=<number>] - * : How many users to generate. Default: 100 + * : 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. + * : Render output in a particular format. + * --- + * default: progress + * options: + * - progress + * - 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 + * # Add meta to every generated users. + * $ wp user generate --format=ids --count=3 | xargs -d ' ' -I % wp user meta add % foo bar * Success: Added custom field. * Success: Added custom field. * Success: Added custom field. From c61c1cec2ef2cd5d3c9e32a728ee80dcf7de3106 Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 4 Aug 2016 15:03:18 +0900 Subject: [PATCH 4804/4858] #discussion_r73137910 --- php/config-spec.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/config-spec.php b/php/config-spec.php index 7f6e4f877c..11c6fffbd4 100644 --- a/php/config-spec.php +++ b/php/config-spec.php @@ -8,8 +8,8 @@ ), 'ssh' => array( - 'runtime' => '=[<user>]@<host>[:<port>][<path>]', - 'file' => '[<user>]@<host>[:<port>][<path>]', + 'runtime' => '=[<user>@]<host>[:<port>][<path>]', + 'file' => '[<user>@]<host>[:<port>][<path>]', 'desc' => 'Perform operation against a remote server over SSH.', ), From aae931d9de6d1a41128c4e60a48eaddd3716b152 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 4 Aug 2016 11:56:47 +0545 Subject: [PATCH 4805/4858] Improve doc in media import command --- php/commands/media.php | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/php/commands/media.php b/php/commands/media.php index 372e99bea1..910658d37f 100644 --- a/php/commands/media.php +++ b/php/commands/media.php @@ -5,7 +5,7 @@ * * ## EXAMPLES * - * # Re-generate all thumbnails, without confirmation + * # Re-generate all thumbnails, without confirmation. * $ wp media regenerate --yes * Found 3 images to regenerate. * Regenerated thumbnails for "Sydney Harbor Bridge" (ID 760). @@ -13,9 +13,9 @@ * Regenerated thumbnails for "Sunburst Over River" (ID 756). * Success: Finished regenerating all images. * - * # Import a local image and set it to be the featured image for a post + * # Import a local image and set it to be the featured image for a post. * $ wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image - * Success: Imported file /home/person/Downloads/image.png as attachment ID 1753 and attached to post 123 as featured image. + * Success: Imported file '/home/person/Downloads/image.png' as attachment ID 1753 and attached to post 123 as featured image. * * @package wp-cli */ @@ -117,48 +117,48 @@ function regenerate( $args, $assoc_args = array() ) { * downloaded to a temp file before being sideloaded. * * [--post_id=<post_id>] - * : ID of the post to attach the imported files to + * : ID of the post to attach the imported files to. * * [--title=<title>] - * : Attachment title (post title field) + * : Attachment title (post title field). * * [--caption=<caption>] - * : Caption for attachent (post excerpt field) + * : Caption for attachent (post excerpt field). * * [--alt=<alt_text>] - * : Alt text for image (saved as post meta) + * : Alt text for image (saved as post meta). * * [--desc=<description>] - * : "Description" field (post content) of attachment post + * : "Description" field (post content) of attachment post. * * [--featured_image] * : If set, set the imported image as the Featured Image of the post its attached to. * * [--porcelain] - * : Output just the new attachment id. + * : Output just the new attachment ID. * * ## EXAMPLES * - * # Import all jpgs in the current user's "Pictures" directory, not attached to any post + * # Import all jpgs in the current user's "Pictures" directory, not attached to any post. * $ wp media import ~/Pictures/**\/*.jpg - * Success: Imported file /home/person/Pictures/beautiful-youg-girl-in-ivy.jpg as attachment ID 1751. - * Success: Imported file /home/person/Pictures/fashion-girl.jpg as attachment ID 1752. + * Success: Imported file '/home/person/Pictures/beautiful-youg-girl-in-ivy.jpg' as attachment ID 1751. + * Success: Imported file '/home/person/Pictures/fashion-girl.jpg' as attachment ID 1752. * - * # Import a local image and set it to be the post thumbnail for a post + * # Import a local image and set it to be the post thumbnail for a post. * $ wp media import ~/Downloads/image.png --post_id=123 --title="A downloaded picture" --featured_image - * Success: Imported file /home/person/Downloads/image.png as attachment ID 1753 and attached to post 123 as featured image. + * Success: Imported file '/home/person/Downloads/image.png' as attachment ID 1753 and attached to post 123 as featured image. * - * # Import a local image, but set it as the featured image for all posts - * # 1. Import the image and get its attachment ID - * # 2. Assign the attachment ID as the featured image for all posts + * # Import a local image, but set it as the featured image for all posts. + * # 1. Import the image and get its attachment ID. + * # 2. Assign the attachment ID as the featured image for all posts. * $ ATTACHMENT_ID="$(wp media import ~/Downloads/image.png --porcelain)" - * $ wp post list --post_type=post --format=ids | xargs -0 -d ' ' -I % wp post meta add % _thumbnail_id $ATTACHMENT_ID + * $ wp post list --post_type=post --format=ids | xargs -d ' ' -I % wp post meta add % _thumbnail_id $ATTACHMENT_ID * Success: Added custom field. * Success: Added custom field. * - * # Import an image from the web + * # Import an image from the web. * $ wp media import http://s.wordpress.org/style/images/wp-header-logo.png --title='The WordPress logo' --alt="Semantic personal publishing" - * Success: Imported file http://s.wordpress.org/style/images/wp-header-logo.png as attachment ID 1755. + * Success: Imported file 'http://s.wordpress.org/style/images/wp-header-logo.png' as attachment ID 1755. */ function import( $args, $assoc_args = array() ) { $assoc_args = wp_parse_args( $assoc_args, array( @@ -183,7 +183,7 @@ function import( $args, $assoc_args = array() ) { if ( empty( $is_file_remote ) ) { if ( !file_exists( $file ) ) { - WP_CLI::warning( "Unable to import file $file. Reason: File doesn't exist." ); + WP_CLI::warning( "Unable to import file '$file'. Reason: File doesn't exist." ); break; } $tempfile = $this->_make_copy( $file ); @@ -227,7 +227,7 @@ function import( $args, $assoc_args = array() ) { $success = media_handle_sideload( $file_array, $assoc_args['post_id'], $assoc_args['title'], $post_array ); if ( is_wp_error( $success ) ) { WP_CLI::warning( sprintf( - 'Unable to import file %s. Reason: %s', + "Unable to import file '%s'. Reason: %s", $orig_filename, implode( ', ', $success->get_error_messages() ) ) ); continue; @@ -254,7 +254,7 @@ function import( $args, $assoc_args = array() ) { WP_CLI::line( $success ); } else { WP_CLI::success( sprintf( - 'Imported file %s as attachment ID %d%s.', + "Imported file '%s' as attachment ID %d%s.", $orig_filename, $success, $attachment_success_text ) ); } From 2c6314847ea6175407c729bb76c13c4ecc953315 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 4 Aug 2016 11:57:16 +0545 Subject: [PATCH 4806/4858] Update test to reflect change in media import --- features/media-import.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/media-import.feature b/features/media-import.feature index 591d0db690..57e3a90e4c 100644 --- a/features/media-import.feature +++ b/features/media-import.feature @@ -7,21 +7,21 @@ Feature: Manage WordPress attachments When I run `wp media import 'http://wp-cli.org/behat-data/codeispoetry.png' --post_id=1` Then STDOUT should contain: """ - Success: Imported file http://wp-cli.org/behat-data/codeispoetry.png + Success: Imported file 'http://wp-cli.org/behat-data/codeispoetry.png' """ Scenario: Fail to import missing image When I try `wp media import gobbledygook.png` Then STDERR should contain: """ - Unable to import file gobbledygook.png. Reason: File doesn't exist. + Unable to import file 'gobbledygook.png'. Reason: File doesn't exist. """ Scenario: Fail to import missing image on Windows When I try `wp media import c:/path/gobbledygook.png` Then STDERR should contain: """ - Unable to import file c:/path/gobbledygook.png. Reason: File doesn't exist. + Unable to import file 'c:/path/gobbledygook.png'. Reason: File doesn't exist. """ Scenario: Import a file as attachment from a local image From 86f52f0c27179b8cfb02bc0bd3b475db53ad80fb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 4 Aug 2016 12:09:51 +0545 Subject: [PATCH 4807/4858] Fix xargs param in theme status test --- features/theme.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/theme.feature b/features/theme.feature index dcf1343a14..04b4a9ea79 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -54,7 +54,7 @@ Feature: Manage WordPress themes Given a WP install When I run `wp theme install classic --activate` - And I run `wp theme list --field=name --status=inactive | xargs -0 -d '\n' -I % wp theme delete %` + And I run `wp theme list --field=name --status=inactive | xargs wp theme delete` And I run `wp theme status` Then STDOUT should be: """ From 9155dfdc07d8da9edff5959a1cfd97e641e55a8b Mon Sep 17 00:00:00 2001 From: miya0001 <miya@wpist.me> Date: Thu, 4 Aug 2016 16:53:09 +0900 Subject: [PATCH 4808/4858] improve doc for `wp core language` --- php/WP_CLI/CommandWithTranslation.php | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/php/WP_CLI/CommandWithTranslation.php b/php/WP_CLI/CommandWithTranslation.php index 62710848d6..dbd2ffb4a2 100644 --- a/php/WP_CLI/CommandWithTranslation.php +++ b/php/WP_CLI/CommandWithTranslation.php @@ -51,6 +51,16 @@ abstract class CommandWithTranslation extends \WP_CLI_Command { * * version * * package * + * ## EXAMPLES + * + * $ wp core language list --fields=language,english_name,status + * +----------------+-------------------------+-------------+ + * | language | english_name | status | + * +----------------+-------------------------+-------------+ + * | ar | Arabic | uninstalled | + * | ary | Moroccan Arabic | uninstalled | + * | az | Azerbaijani | uninstalled | + * * @subcommand list */ public function list_( $args, $assoc_args ) { @@ -110,6 +120,11 @@ protected function sort_translations_callback( $a, $b ) { * [--activate] * : If set, the language will be activated immediately after install. * + * ## EXAMPLES + * + * $ wp core language install ja + * Success: Language installed. + * * @subcommand install */ public function install( $args, $assoc_args ) { @@ -142,6 +157,17 @@ public function install( $args, $assoc_args ) { * [--dry-run] * : Preview which translations would be updated. * + * ## EXAMPLES + * + * $ wp core language update + * Updating 'Japanese' translation for Akismet 3.1.11... + * Downloading translation from https://downloads.wordpress.org/translation/plugin/akismet/3.1.11/ja.zip... + * Translation updated successfully. + * Updating 'Japanese' translation for Twenty Fifteen 1.5... + * Downloading translation from https://downloads.wordpress.org/translation/theme/twentyfifteen/1.5/ja.zip... + * Translation updated successfully. + * Success: Updated 2/2 translations. + * * @subcommand update */ public function update( $args, $assoc_args ) { @@ -237,6 +263,11 @@ public function update( $args, $assoc_args ) { * <language> * : Language code to activate. * + * ## EXAMPLES + * + * $ wp core language activate ja + * Success: Language activated. + * * @subcommand activate */ public function activate( $args, $assoc_args ) { @@ -367,6 +398,11 @@ protected function get_all_languages() { * <language> * : Language code to uninstall. * + * ## EXAMPLES + * + * $ wp core language uninstall ja + * Success: Language uninstalled. + * * @subcommand uninstall */ public function uninstall( $args, $assoc_args ) { From d24ca812482f8d1678656d61873b8cb4d4051baf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 4 Aug 2016 05:24:52 -0700 Subject: [PATCH 4809/4858] Fix behavior of autoload parameter for `wp option (add|update)` YAML interprets `yes` and `no` to be boolean values, which breaks the default value for the underlying command. Instead, we need to make sure these options are quoted. No default value is necessary because null is an acceptable default value. --- features/option.feature | 60 +++++++++++++++++++++++++++++++++++++++++ php/commands/option.php | 10 +++---- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/features/option.feature b/features/option.feature index cd44b4596a..a122016b98 100644 --- a/features/option.feature +++ b/features/option.feature @@ -141,3 +141,63 @@ Feature: Manage WordPress options Then STDOUT should be a table containing rows: | option_name | option_value | autoload | | hello | island | yes | + + @require-wp-4.2 + Scenario: Managed autoloaded options + Given a WP install + + When I run `wp option add wp_autoload_1 enabled --autoload=yes` + Then STDOUT should be: + """ + Success: Added 'wp_autoload_1' option. + """ + And STDERR should be empty + + When I run `wp option add wp_autoload_2 implicit` + Then STDOUT should be: + """ + Success: Added 'wp_autoload_2' option. + """ + And STDERR should be empty + + When I run `wp option add wp_autoload_3 disabled --autoload=no` + Then STDOUT should be: + """ + Success: Added 'wp_autoload_3' option. + """ + And STDERR should be empty + + When I run `wp option list --search='wp_autoload*' --fields=option_name,option_value,autoload` + Then STDOUT should be a table containing rows: + | option_name | option_value | autoload | + | wp_autoload_1 | enabled | yes | + | wp_autoload_2 | implicit | yes | + | wp_autoload_3 | disabled | no | + + When I run `wp option update wp_autoload_1 disabled --autoload=no` + Then STDOUT should be: + """ + Success: Updated 'wp_autoload_1' option. + """ + And STDERR should be empty + + When I run `wp option update wp_autoload_2 implicit2` + Then STDOUT should be: + """ + Success: Updated 'wp_autoload_2' option. + """ + And STDERR should be empty + + When I run `wp option update wp_autoload_3 enabled --autoload=yes` + Then STDOUT should be: + """ + Success: Updated 'wp_autoload_3' option. + """ + And STDERR should be empty + + When I run `wp option list --search='wp_autoload*' --fields=option_name,option_value,autoload` + Then STDOUT should be a table containing rows: + | option_name | option_value | autoload | + | wp_autoload_1 | disabled | no | + | wp_autoload_2 | implicit2 | yes | + | wp_autoload_3 | enabled | yes | diff --git a/php/commands/option.php b/php/commands/option.php index 2da6e107da..6850ad409c 100644 --- a/php/commands/option.php +++ b/php/commands/option.php @@ -90,10 +90,9 @@ public function get( $args, $assoc_args ) { * [--autoload=<autoload>] * : Should this option be automatically loaded. * --- - * default: yes * options: - * - yes - * - no + * - 'yes' + * - 'no' * --- * * ## EXAMPLES @@ -261,10 +260,9 @@ public function list_( $args, $assoc_args ) { * [--autoload=<autoload>] * : Requires WP 4.2. Should this option be automatically loaded. * --- - * default: yes * options: - * - yes - * - no + * - 'yes' + * - 'no' * --- * * [--format=<format>] From 78e7306d64c6edf6947b4deb379e019de02e4aeb Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 4 Aug 2016 21:17:57 +0545 Subject: [PATCH 4810/4858] Add command description in db import --- php/commands/db.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/php/commands/db.php b/php/commands/db.php index 57828e98b0..6dff55ea8c 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -292,6 +292,11 @@ function export( $args, $assoc_args ) { /** * Import a MySQL database from a file or from STDIN. * + * Runs MySQL queries using `DB_HOST`, `DB_NAME`, `DB_USER` and + * `DB_PASSWORD` database credentials specified in wp-config.php. This + * does not create database by itself and only performs whatever tasks are + * defined in the SQL. + * * ## OPTIONS * * [<file>] @@ -299,6 +304,7 @@ function export( $args, $assoc_args ) { * * ## EXAMPLES * + * # Import MySQL from a file. * $ wp db import wordpress_dbase.sql * Success: Imported from 'wordpress_dbase.sql'. */ From 7793be6a314978c1fabe7efc911c5e8d8c6ff30d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 4 Aug 2016 08:59:03 -0700 Subject: [PATCH 4811/4858] Fix `--skip-plugins` for network-activated plugins Using `--skip-plugins=<slug>` should only disable that specific plugin, not all network-activated plugins. Also makes the tests a bit more comprehensive. --- features/skip-plugins.feature | 47 ++++++++++++++++++----------------- php/WP_CLI/Runner.php | 16 +++++++++--- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/features/skip-plugins.feature b/features/skip-plugins.feature index 8105cc620e..98695933b3 100644 --- a/features/skip-plugins.feature +++ b/features/skip-plugins.feature @@ -4,16 +4,10 @@ Feature: Skipping plugins Given a WP install And I run `wp plugin activate hello akismet` - When I run `wp eval 'var_export( defined("AKISMET_VERSION") );'` + When I run `wp eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` Then STDOUT should be: """ - true - """ - - When I run `wp eval 'var_export( function_exists( "hello_dolly" ) );'` - Then STDOUT should be: - """ - true + truetrue """ # The specified plugin should be skipped @@ -31,10 +25,10 @@ Feature: Skipping plugins """ # The un-specified plugin should continue to be loaded - When I run `wp --skip-plugins=akismet eval 'var_export( function_exists( "hello_dolly" ) );'` + When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` Then STDOUT should be: """ - true + falsetrue """ # Can specify multiple plugins to skip @@ -45,15 +39,10 @@ Feature: Skipping plugins """ # No plugins should be loaded when --skip-plugins doesn't have a value - When I run `wp --skip-plugins eval 'var_export( defined("AKISMET_VERSION") );'` - Then STDOUT should be: - """ - false - """ - When I run `wp --skip-plugins eval 'var_export( function_exists( "hello_dolly" ) );'` + When I run `wp --skip-plugins eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` Then STDOUT should be: """ - false + falsefalse """ Scenario: Skipping multiple plugins via config file @@ -88,17 +77,29 @@ Feature: Skipping plugins Scenario: Skip network active plugins Given a WP multisite install - And I run `wp plugin deactivate akismet` - And I run `wp plugin activate --network akismet` + And I run `wp plugin deactivate akismet hello` + And I run `wp plugin activate --network akismet hello` - When I run `wp eval 'var_export( defined("AKISMET_VERSION") );'` + When I run `wp eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` Then STDOUT should be: """ - true + truetrue """ - When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );'` + When I run `wp --skip-plugins eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` Then STDOUT should be: """ - false + falsefalse + """ + + When I run `wp --skip-plugins=akismet eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + falsetrue + """ + + When I run `wp --skip-plugins=hello eval 'var_export( defined("AKISMET_VERSION") );var_export( function_exists( "hello_dolly" ) );'` + Then STDOUT should be: + """ + truefalse """ diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 592081b286..7e0ed54a96 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -1139,12 +1139,20 @@ private function setup_skip_plugins_filters() { if ( ! is_array( $plugins ) ) { return $plugins; } - foreach( $plugins as $key => $plugin ) { - if ( Utils\is_plugin_skipped( $plugin ) ) { - unset( $plugins[ $key ] ); + foreach( $plugins as $a => $b ) { + // active_sitewide_plugins stores plugin name as the key + if ( false !== strpos( current_filter(), 'active_sitewide_plugins' ) && Utils\is_plugin_skipped( $a ) ) { + unset( $plugins[ $a ] ); + // active_plugins stores plugin name as the value + } else if ( false !== strpos( current_filter(), 'active_plugins' ) && Utils\is_plugin_skipped( $b ) ) { + unset( $plugins[ $a ] ); } } - return array_values( $plugins ); + // Reindex because active_plugins expects a numeric index + if ( false !== strpos( current_filter(), 'active_plugins' ) ) { + $plugins = array_values( $plugins ); + } + return $plugins; }; $hooks = array( From 38d0abed9ee0d5f8edbd939abd4e1f56ca5facdf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Fri, 5 Aug 2016 11:27:31 -0700 Subject: [PATCH 4812/4858] Update README.md to indicate Github issues are no longer for support --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1a1b8fc30c..9f2eba0eda 100644 --- a/README.md +++ b/README.md @@ -115,15 +115,14 @@ source /FULL/PATH/TO/wp-completion.bash ## Support -WP-CLI's maintainers and project contributors do their best to respond to all new issues in a timely manner. To make the best use of their volunteered time, please first see if there may be an answer to your question in one of the following resources: +WP-CLI's maintainers and project contributors are volunteers, and have limited availability to address the variety of questions users might have. Before filing your support request, please first see if there is an answer in one of the following resources: - [Common issues and their fixes](https://wp-cli.org/docs/common-issues/) -- [Best practices for submitting a bug report](https://wp-cli.org/docs/bug-reports/) - [Documentation portal](https://wp-cli.org/docs/) - [Open or closed issues on Github](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=is%3Aissue) - [WordPress StackExchange forums](http://wordpress.stackexchange.com/questions/tagged/wp-cli) -If you can't find your answer in one of those existing resources, feel free to [create an issue](https://github.com/wp-cli/wp-cli/issues/new) with your question. +If you can't find your answer at one of those links, the [WordPress StackExchange](http://wordpress.stackexchange.com/) is the best place for general support questions. For bug reports, please review [best practices for submitting a bug report](https://wp-cli.org/docs/bug-reports/) before [creating a new issue](https://github.com/wp-cli/wp-cli/issues/new). Professional users may also consider [runcommand](https://runcommand.io/) for premium support. Please do not ask support questions on Twitter. Twitter isn't an acceptable venue for support because: 1) it's hard to hold conversations in under 140 characters, and 2) Twitter isn't a place where someone with your same question can search for an answer in a prior conversation. From a694d603f5d8559195845001f0715597f669f699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Mon, 8 Aug 2016 01:00:38 +0200 Subject: [PATCH 4813/4858] Syntax highlight for README --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9f2eba0eda..1b26a6d4e4 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Quick links: [Using](#using) | [Installing](#installing) | [Support](# WP-CLI's goal is to provide a command-line interface for any action you might want to perform in the WordPress admin. For instance, `wp plugin install --activate` ([doc](https://wp-cli.org/commands/plugin/install/)) lets you install and activate a WordPress plugin: -``` +```bash $ wp plugin install rest-api --activate Installing WordPress REST API (Version 2) (2.0-beta13) Downloading install package from https://downloads.wordpress.org/plugin/rest-api.2.0-beta13.zip... @@ -37,7 +37,7 @@ Success: Plugin 'rest-api' activated. WP-CLI also includes commands for many things you can't do in the WordPress admin. For example, `wp transient delete-all` ([doc](https://wp-cli.org/commands/transient/delete-all/)) lets you delete one or all transients: -``` +```bash $ wp transient delete-all Success: 34 transients deleted from the database. ``` @@ -58,26 +58,26 @@ Before installing WP-CLI, please make sure your environment meets the minimum re Once you've verified requirements, download the [wp-cli.phar](https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar) file using `wget` or `curl`: -``` +```bash $ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar ``` Next, check if it is working: -``` +```bash $ php wp-cli.phar --info ``` To use WP-CLI from the command line by typing `wp`, make the file executable and move it to somewhere in your PATH. For example: -``` +```bash $ chmod +x wp-cli.phar $ sudo mv wp-cli.phar /usr/local/bin/wp ``` If WP-CLI was installed successfully, you should see something like this when you run `wp --info`: -``` +```bash $ wp --info PHP binary: /usr/bin/php5 PHP version: 5.5.9-1ubuntu4.14 @@ -99,7 +99,7 @@ Want to live life on the edge? Run `wp cli update --nightly` to use the latest n WP-CLI also comes with a tab completion script for Bash and ZSH. Just download [wp-completion.bash](https://github.com/wp-cli/wp-cli/raw/master/utils/wp-completion.bash) and source it from `~/.bash_profile`: -``` +```bash source /FULL/PATH/TO/wp-completion.bash ``` @@ -107,7 +107,7 @@ Don't forget to run `source ~/.bash_profile` afterwards. If using zsh for your shell, you may need to load and start `bashcompinit` before sourcing. Put the following in your `.zshrc`: -``` +```bash autoload bashcompinit bashcompinit source /FULL/PATH/TO/wp-completion.bash @@ -134,7 +134,7 @@ A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([d WP-CLI supports registering any callable class, function, or closure as a command. It reads usage details from the callback's PHPdoc. `WP_CLI::add_command()` ([doc](https://wp-cli.org/docs/internal-api/wp-cli-add-command/)) is used for both internal and third-party command registration. -``` +```php /** * Delete an option from the database. * From 6ac0df413086397cf6073d39e830779766b6d2fc Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Aug 2016 05:27:13 -0700 Subject: [PATCH 4814/4858] Update dependencies to latest ``` Loading composer repositories with package information Updating dependencies (including require-dev) - Removing mustache/mustache (v2.10.0) - Installing mustache/mustache (v2.11.1) Downloading: 100% - Removing symfony/finder (v2.8.8) - Installing symfony/finder (v2.8.9) Downloading: 100% - Removing symfony/yaml (v2.8.8) - Installing symfony/yaml (v2.8.9) Downloading: 100% - Removing symfony/filesystem (v2.8.8) - Installing symfony/filesystem (v2.8.9) Downloading: 100% - Removing symfony/config (v2.8.8) - Installing symfony/config (v2.8.9) Downloading: 100% - Removing symfony/console (v2.8.8) - Installing symfony/console (v2.8.9) Downloading: 100% - Removing symfony/dependency-injection (v2.8.8) - Installing symfony/dependency-injection (v2.8.9) Downloading: 100% - Removing symfony/event-dispatcher (v2.8.8) - Installing symfony/event-dispatcher (v2.8.9) Downloading: 100% - Removing symfony/process (v2.8.8) - Installing symfony/process (v2.8.9) Downloading: 100% - Removing symfony/translation (v2.8.8) - Installing symfony/translation (v2.8.9) Downloading: 100% Writing lock file Generating autoload files ``` --- composer.lock | 104 +++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/composer.lock b/composer.lock index 4cab63408b..ede24ebabf 100644 --- a/composer.lock +++ b/composer.lock @@ -332,23 +332,23 @@ }, { "name": "mustache/mustache", - "version": "v2.10.0", + "version": "v2.11.1", "source": { "type": "git", "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "0bb2f76e2f34a8864a32be34c4ec66274d76c05e" + "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/0bb2f76e2f34a8864a32be34c4ec66274d76c05e", - "reference": "0bb2f76e2f34a8864a32be34c4ec66274d76c05e", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/a3f6d55996dd28b58f3a909d474189a3c1aa693f", + "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f", "shasum": "" }, "require": { "php": ">=5.2.4" }, "require-dev": { - "fabpot/php-cs-fixer": "~1.6", + "friendsofphp/php-cs-fixer": "~1.11", "phpunit/phpunit": "~3.7|~4.0|~5.0" }, "type": "library", @@ -374,7 +374,7 @@ "mustache", "templating" ], - "time": "2016-02-27 19:22:46" + "time": "2016-07-31 06:18:27" }, { "name": "mustangostang/spyc", @@ -736,16 +736,16 @@ }, { "name": "symfony/config", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "0926e69411eba491803dbafb9f1f233e2ced58d0" + "reference": "4275ef5b59f18959df0eee3991e9ca0cc208ffd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/0926e69411eba491803dbafb9f1f233e2ced58d0", - "reference": "0926e69411eba491803dbafb9f1f233e2ced58d0", + "url": "https://api.github.com/repos/symfony/config/zipball/4275ef5b59f18959df0eee3991e9ca0cc208ffd4", + "reference": "4275ef5b59f18959df0eee3991e9ca0cc208ffd4", "shasum": "" }, "require": { @@ -785,20 +785,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:31:50" + "time": "2016-07-26 08:02:44" }, { "name": "symfony/console", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c392a6ec72f2122748032c2ad6870420561ffcfa" + "reference": "36e62335caca8a6e909c5c5bac4a8128149911c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c392a6ec72f2122748032c2ad6870420561ffcfa", - "reference": "c392a6ec72f2122748032c2ad6870420561ffcfa", + "url": "https://api.github.com/repos/symfony/console/zipball/36e62335caca8a6e909c5c5bac4a8128149911c9", + "reference": "36e62335caca8a6e909c5c5bac4a8128149911c9", "shasum": "" }, "require": { @@ -845,20 +845,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-06-29 07:02:14" + "time": "2016-07-30 07:20:35" }, { "name": "symfony/dependency-injection", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "2dd85de8216079d1360b2b14988cd5cdbbb49063" + "reference": "f2b5a00d176f6a201dc430375c0ef37706ea3d12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2dd85de8216079d1360b2b14988cd5cdbbb49063", - "reference": "2dd85de8216079d1360b2b14988cd5cdbbb49063", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f2b5a00d176f6a201dc430375c0ef37706ea3d12", + "reference": "f2b5a00d176f6a201dc430375c0ef37706ea3d12", "shasum": "" }, "require": { @@ -870,7 +870,7 @@ "require-dev": { "symfony/config": "~2.2|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0", - "symfony/yaml": "~2.1|~3.0.0" + "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" }, "suggest": { "symfony/config": "", @@ -908,20 +908,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:31:50" + "time": "2016-07-30 07:20:35" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9" + "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b180b70439dca70049b6b9b7e21d75e6e5d7aca9", - "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8", + "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8", "shasum": "" }, "require": { @@ -968,20 +968,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-28 16:56:28" }, { "name": "symfony/filesystem", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7258ddd6f987053f21fa43d03430580ba54e6096" + "reference": "ab4c3f085c8f5a56536845bf985c4cef30bf75fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7258ddd6f987053f21fa43d03430580ba54e6096", - "reference": "7258ddd6f987053f21fa43d03430580ba54e6096", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ab4c3f085c8f5a56536845bf985c4cef30bf75fd", + "reference": "ab4c3f085c8f5a56536845bf985c4cef30bf75fd", "shasum": "" }, "require": { @@ -1017,20 +1017,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:31:50" + "time": "2016-07-20 05:41:28" }, { "name": "symfony/finder", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "bf0506ef4e7778fd3f0f1f141ab5e8c1ef35dd7d" + "reference": "60804d88691e4a73bbbb3035eb1d9f075c5c2c10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/bf0506ef4e7778fd3f0f1f141ab5e8c1ef35dd7d", - "reference": "bf0506ef4e7778fd3f0f1f141ab5e8c1ef35dd7d", + "url": "https://api.github.com/repos/symfony/finder/zipball/60804d88691e4a73bbbb3035eb1d9f075c5c2c10", + "reference": "60804d88691e4a73bbbb3035eb1d9f075c5c2c10", "shasum": "" }, "require": { @@ -1066,7 +1066,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-26 08:02:44" }, { "name": "symfony/polyfill-mbstring", @@ -1129,16 +1129,16 @@ }, { "name": "symfony/process", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe" + "reference": "d20332e43e8774ff8870b394f3dd6020cc7f8e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/89f33c16796415ccfd8bb3cf8d520cbb79899bfe", - "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe", + "url": "https://api.github.com/repos/symfony/process/zipball/d20332e43e8774ff8870b394f3dd6020cc7f8e0c", + "reference": "d20332e43e8774ff8870b394f3dd6020cc7f8e0c", "shasum": "" }, "require": { @@ -1174,20 +1174,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-28 11:13:19" }, { "name": "symfony/translation", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "00334ef0b9317e5d7c7641a2b56671a1df23b7a0" + "reference": "32b0c824da6df065f43b0c458dc505940e98a7f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/00334ef0b9317e5d7c7641a2b56671a1df23b7a0", - "reference": "00334ef0b9317e5d7c7641a2b56671a1df23b7a0", + "url": "https://api.github.com/repos/symfony/translation/zipball/32b0c824da6df065f43b0c458dc505940e98a7f1", + "reference": "32b0c824da6df065f43b0c458dc505940e98a7f1", "shasum": "" }, "require": { @@ -1238,20 +1238,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-30 07:20:35" }, { "name": "symfony/yaml", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8" + "reference": "0ceab136f43ed9d3e97b3eea32a7855dc50c121d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/dba4bb5846798cd12f32e2d8f3f35d77045773c8", - "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0ceab136f43ed9d3e97b3eea32a7855dc50c121d", + "reference": "0ceab136f43ed9d3e97b3eea32a7855dc50c121d", "shasum": "" }, "require": { @@ -1287,7 +1287,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-17 09:06:15" }, { "name": "wp-cli/php-cli-tools", From c24cce5f0f1f6cc82cbbae5dc0da946782ce8fe3 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Aug 2016 06:36:18 -0700 Subject: [PATCH 4815/4858] Clarify that StackExchange isn't meant for general support --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1b26a6d4e4..96c278035d 100644 --- a/README.md +++ b/README.md @@ -115,18 +115,19 @@ source /FULL/PATH/TO/wp-completion.bash ## Support -WP-CLI's maintainers and project contributors are volunteers, and have limited availability to address the variety of questions users might have. Before filing your support request, please first see if there is an answer in one of the following resources: +WP-CLI's maintainers and project contributors are volunteers, and have limited availability to address general support questions. First, look for an answer in one of the following resources: - [Common issues and their fixes](https://wp-cli.org/docs/common-issues/) - [Documentation portal](https://wp-cli.org/docs/) - [Open or closed issues on Github](https://github.com/wp-cli/wp-cli/issues?utf8=%E2%9C%93&q=is%3Aissue) +- [runcommand Excerpts](https://runcommand.io/excerpts/) - [WordPress StackExchange forums](http://wordpress.stackexchange.com/questions/tagged/wp-cli) -If you can't find your answer at one of those links, the [WordPress StackExchange](http://wordpress.stackexchange.com/) is the best place for general support questions. For bug reports, please review [best practices for submitting a bug report](https://wp-cli.org/docs/bug-reports/) before [creating a new issue](https://github.com/wp-cli/wp-cli/issues/new). Professional users may also consider [runcommand](https://runcommand.io/) for premium support. +If you can't find your answer at one of those links, the [WordPress StackExchange](http://wordpress.stackexchange.com/) can be used for development-related WP-CLI questions. Or, join the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/) to see if a community member might have an answer for you. Professional users may also consider [runcommand](https://runcommand.io/) for premium support. -Please do not ask support questions on Twitter. Twitter isn't an acceptable venue for support because: 1) it's hard to hold conversations in under 140 characters, and 2) Twitter isn't a place where someone with your same question can search for an answer in a prior conversation. +For bug reports, please review [best practices for submitting a bug report](https://wp-cli.org/docs/bug-reports/) before [creating a new issue](https://github.com/wp-cli/wp-cli/issues/new). -If you have a WordPress.org account, you may also consider joining the `#cli` channel on the [WordPress.org Slack organization](https://make.wordpress.org/chat/). +Please do not ask support questions on Twitter. Twitter isn't an acceptable venue for support because: 1) it's hard to hold conversations in under 140 characters, and 2) Twitter isn't a place where someone with your same question can search for an answer in a prior conversation. ## Extending From 23e0f58be923b7e8d26396c8e55a704b5092a901 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Aug 2016 06:59:03 -0700 Subject: [PATCH 4816/4858] Include line about libre != gratis --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 96c278035d..bf7c6ab060 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,8 @@ For bug reports, please review [best practices for submitting a bug report](http Please do not ask support questions on Twitter. Twitter isn't an acceptable venue for support because: 1) it's hard to hold conversations in under 140 characters, and 2) Twitter isn't a place where someone with your same question can search for an answer in a prior conversation. +Remember, libre != gratis; the open source license grants you the freedom to use and modify, but not commitments of other people's time. Please be respectful, and set your expectations accordingly. + ## Extending A **command** is an atomic unit of WP-CLI functionality. `wp plugin install` ([doc](https://wp-cli.org/commands/plugin/install/)) is one command. `wp plugin activate` ([doc](https://wp-cli.org/commands/plugin/activate/)) is another. From 7a274f09cdf288e505a7b20e969c1a8b2f30bf11 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 9 Aug 2016 07:05:06 -0700 Subject: [PATCH 4817/4858] First pass at an issue template --- .github/ISSUE_TEMPLATE | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 0000000000..d255d8f7ad --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,11 @@ +<!-- + +Thanks for taking the time to help improve WP-CLI! + +Found a bug or want to suggest an enhancement? Before submitting an issue, please review our best practices: http://wp-cli.org/docs/bug-reports/ + +Need help with something? Github issues aren't for general support questions, but there are other venues you can try: http://wp-cli.org/#support + +You can safely delete this comment. + +--> From 7329f7ffff67c2e626c7f392a2c7dd4b9051b27e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 05:05:52 -0700 Subject: [PATCH 4818/4858] Catch exceptions thrown by `RecursiveDirectoryIterator` --- php/commands/core.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index 16fc7363b0..fd212bb108 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1066,16 +1066,19 @@ public function verify_checksums( $args, $assoc_args ) { } private function get_wp_core_files() { - $files = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( ABSPATH, RecursiveDirectoryIterator::SKIP_DOTS ), - RecursiveIteratorIterator::CHILD_FIRST - ); - $core_files = array(); - foreach ( $files as $file_info ) { - if ( $file_info->isFile() && ( false !== strpos( $file_info->getPathname(), 'wp-admin/' ) || false !== strpos( $file_info->getPathname(), 'wp-includes/' ) ) ) { - $core_files[] = str_replace( ABSPATH, '', $file_info->getPathname() ); + try { + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( ABSPATH, RecursiveDirectoryIterator::SKIP_DOTS ), + RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ( $files as $file_info ) { + if ( $file_info->isFile() && ( false !== strpos( $file_info->getPathname(), 'wp-admin/' ) || false !== strpos( $file_info->getPathname(), 'wp-includes/' ) ) ) { + $core_files[] = str_replace( ABSPATH, '', $file_info->getPathname() ); + } } + } catch( Exception $e ) { + WP_CLI::error( $e->getMessage() ); } return $core_files; From e7e11c0442104e0be82b994d8dfd8b737f3c2d79 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 05:17:24 -0700 Subject: [PATCH 4819/4858] Include adequate vertical spacing around inserted constants --- php/commands/core.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/commands/core.php b/php/commands/core.php index 16fc7363b0..300fa55cd6 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -901,6 +901,8 @@ private static function modify_wp_config( $content ) { list( $before, $after ) = explode( $token, file_get_contents( $wp_config_path ) ); + $content = PHP_EOL . PHP_EOL . trim( $content ) . PHP_EOL . PHP_EOL; + file_put_contents( $wp_config_path, $before . $content . $token . $after ); } From 8a2a7e0da240bb08ea22545ad31daca6f9820e07 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 05:30:50 -0700 Subject: [PATCH 4820/4858] When checking for additional files, only check core directories Core's `wp-admin/` and `wp-includes/` directories are immediately after ABSPATH. Don't flag files inside of `wp-admin/` and `wp-includes/` directories in plugins. --- features/core-verify-checksums.feature | 14 ++++++++++++++ php/commands/core.php | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/features/core-verify-checksums.feature b/features/core-verify-checksums.feature index 5f40e66b71..0721b897c9 100644 --- a/features/core-verify-checksums.feature +++ b/features/core-verify-checksums.feature @@ -85,3 +85,17 @@ Feature: Validate checksums for WordPress install """ Success: WordPress install verifies against checksums. """ + + Scenario: Verify core checksums with a plugin that has wp-admin + Given a WP install + And a wp-content/plugins/akismet/wp-admin/extra-file.txt file: + """ + hello world + """ + + When I run `wp core verify-checksums` + Then STDOUT should be: + """ + Success: WordPress install verifies against checksums. + """ + And STDERR should be empty diff --git a/php/commands/core.php b/php/commands/core.php index 16fc7363b0..a3a4dfb92a 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1073,7 +1073,8 @@ private function get_wp_core_files() { $core_files = array(); foreach ( $files as $file_info ) { - if ( $file_info->isFile() && ( false !== strpos( $file_info->getPathname(), 'wp-admin/' ) || false !== strpos( $file_info->getPathname(), 'wp-includes/' ) ) ) { + $pathname = substr( $file_info->getPathname(), strlen( ABSPATH ) ); + if ( $file_info->isFile() && ( 0 === strpos( $pathname, 'wp-admin/' ) || 0 === strpos( $pathname, 'wp-includes/' ) ) ) { $core_files[] = str_replace( ABSPATH, '', $file_info->getPathname() ); } } @@ -1082,7 +1083,7 @@ private function get_wp_core_files() { } private function only_core_files_filter( $file ) { - return ( false !== strpos( $file, 'wp-admin/' ) || false !== strpos( $file, 'wp-includes/' ) ); + return ( 0 === strpos( $file, 'wp-admin/' ) || 0 === strpos( $file, 'wp-includes/' ) ); } /** From 6641cd9b70b34b8dc2e149044e56da7a2d7455d7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 05:41:53 -0700 Subject: [PATCH 4821/4858] Properly support registering an instantiated object as a command --- features/command.feature | 31 ++++++++++++++++++++++++ php/WP_CLI/Dispatcher/CommandFactory.php | 10 +++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/features/command.feature b/features/command.feature index f4f5aec2d0..0627379790 100644 --- a/features/command.feature +++ b/features/command.feature @@ -584,3 +584,34 @@ Feature: WP-CLI Commands When I run `wp post list` Then STDOUT should be a number + + Scenario: Use class passed as object + Given an empty directory + And a custom-cmd.php file: + """ + <?php + class Foo_Class { + + public function __construct( $message ) { + $this->message = $message; + } + + /** + * My awesome class method command + * + * @when before_wp_load + */ + function message( $args ) { + WP_CLI::success( $this->message ); + } + } + $foo = new Foo_Class( 'bar' ); + WP_CLI::add_command( 'instantiated-command', $foo ); + """ + + When I run `wp --require=custom-cmd.php instantiated-command message` + Then STDOUT should contain: + """ + bar + """ + And STDERR should be empty diff --git a/php/WP_CLI/Dispatcher/CommandFactory.php b/php/WP_CLI/Dispatcher/CommandFactory.php index 5b05568c5a..bd667fe052 100644 --- a/php/WP_CLI/Dispatcher/CommandFactory.php +++ b/php/WP_CLI/Dispatcher/CommandFactory.php @@ -33,7 +33,7 @@ public static function create( $name, $callable, $parent ) { $command = self::create_subcommand( $parent, $name, array( $class, '__invoke' ), $reflection->getMethod( '__invoke' ) ); } else { - $command = self::create_composite_command( $parent, $name, $reflection ); + $command = self::create_composite_command( $parent, $name, $callable ); } } @@ -78,9 +78,10 @@ private static function create_subcommand( $parent, $name, $callable, $reflectio * * @param mixed $parent The new command's parent Root or Composite command * @param string $name Represents how the command should be invoked - * @param ReflectionClass $reflection + * @param mixed $callable */ - private static function create_composite_command( $parent, $name, $reflection ) { + private static function create_composite_command( $parent, $name, $callable ) { + $reflection = new \ReflectionClass( $callable ); $docparser = new \WP_CLI\DocParser( $reflection->getDocComment() ); $container = new CompositeCommand( $parent, $name, $docparser ); @@ -89,7 +90,8 @@ private static function create_composite_command( $parent, $name, $reflection ) if ( !self::is_good_method( $method ) ) continue; - $subcommand = self::create_subcommand( $container, false, array( $reflection->name, $method->name ), $method ); + $class = is_object( $callable ) ? $callable : $reflection->name; + $subcommand = self::create_subcommand( $container, false, array( $class, $method->name ), $method ); $subcommand_name = $subcommand->get_name(); From 819c2caccf45dc05b0e2363871d2eb9788d464df Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 06:01:40 -0700 Subject: [PATCH 4822/4858] Indicate current file in WXR import progress indicator Doing so communicates the total count is of the current file, not all files. --- features/import.feature | 16 ++++++++++++++++ php/commands/import.php | 5 +++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/features/import.feature b/features/import.feature index 54a06829b1..7398920dfb 100644 --- a/features/import.feature +++ b/features/import.feature @@ -232,3 +232,19 @@ Feature: Import content. """ 2 """ + + Scenario: Indicate current file when importing + Given a WP install + And I run `wp plugin install --activate wordpress-importer` + + When I run `wp export --filename_format=wordpress.{n}.xml` + Then save STDOUT 'Writing to file %s' as {EXPORT_FILE} + + When I run `wp site empty --yes` + Then STDOUT should not be empty + + When I run `wp import {EXPORT_FILE} --authors=skip` + Then STDOUT should contain: + """ + -- 1 of 2 (in file wordpress.000.xml) + """ diff --git a/php/commands/import.php b/php/commands/import.php index 8ae8208330..a2be901a87 100644 --- a/php/commands/import.php +++ b/php/commands/import.php @@ -167,6 +167,7 @@ private function import_wxr( $file, $args ) { add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_set_image_sizes' ) ); } + $GLOBALS['wp_cli_import_current_file'] = basename( $file ); $wp_import->import( $file ); $this->processed_posts += $wp_import->processed_posts; @@ -198,13 +199,13 @@ private function add_wxr_filters() { }, 10, 3 ); add_filter( 'wp_import_post_data_raw', function( $post ) { - global $wpcli_import_counts; + global $wpcli_import_counts, $wp_cli_import_current_file; $wpcli_import_counts['current_post']++; WP_CLI::log(''); WP_CLI::log(''); WP_CLI::log( sprintf( 'Processing post #%d ("%s") (post_type: %s)', $post['post_id'], $post['post_title'], $post['post_type'] ) ); - WP_CLI::log( sprintf( '-- %s of %s', number_format( $wpcli_import_counts['current_post'] ), number_format( $wpcli_import_counts['total_posts'] ) ) ); + WP_CLI::log( sprintf( '-- %s of %s (in file %s)', number_format( $wpcli_import_counts['current_post'] ), number_format( $wpcli_import_counts['total_posts'] ), $wp_cli_import_current_file ) ); WP_CLI::log( '-- ' . date( 'r' ) ); return $post; From b8ae92d19ca2b49b9d2e815e740af0a3c1dba06d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 06:15:37 -0700 Subject: [PATCH 4823/4858] Mark `WP_CLI::get_config()` as a public internal API --- php/class-wp-cli.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index 14024ac982..c031409135 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -863,6 +863,18 @@ public static function get_php_binary() { return 'php'; } + /** + * Get values of global configuration parameters. + * + * Provides access to `--path=<path>`, `--url=<url>`, and other values of + * the [global configuration parameters](https://wp-cli.org/config/). + * + * @access public + * @category Input + * + * @param string $key Get value for a specific global configuration parameter. + * @return mixed + */ public static function get_config( $key = null ) { if ( null === $key ) { return self::get_runner()->config; From 0da7253566780cd07a2731ff45deae339ec95d28 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 06:21:35 -0700 Subject: [PATCH 4824/4858] Include an example --- php/class-wp-cli.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php/class-wp-cli.php b/php/class-wp-cli.php index c031409135..8fc8556871 100644 --- a/php/class-wp-cli.php +++ b/php/class-wp-cli.php @@ -869,6 +869,10 @@ public static function get_php_binary() { * Provides access to `--path=<path>`, `--url=<url>`, and other values of * the [global configuration parameters](https://wp-cli.org/config/). * + * ``` + * WP_CLI::log( 'The --url=<url> value is: ' . WP_CLI::get_config( 'url' ) ); + * ``` + * * @access public * @category Input * From b90ebf6130c9d5e7840280a7c51271167150bbeb Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 10 Aug 2016 06:55:09 -0700 Subject: [PATCH 4825/4858] Warn when multisite constants can't be inserted into wp-config Multisite constants are injected based on a token. When the token can't be found, we should let the end user know, instead of erroneously inserting at the end of wp-config.php --- features/core.feature | 15 +++++++++++++++ php/commands/core.php | 13 ++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/features/core.feature b/features/core.feature index 87bebc383a..1659b71849 100644 --- a/features/core.feature +++ b/features/core.feature @@ -333,3 +333,18 @@ Feature: Manage WordPress installation """ http://wp.dev """ + + Scenario: Warn when multisite constants can't be inserted into wp-config + Given a WP install + And I run `sed -i.bak "s/That's\sall/C'est tout/g" wp-config.php` + + When I run `wp core multisite-convert` + Then STDOUT should be: + """ + Set up multisite database tables. + Success: Network installed. Don't forget to set up rewrite rules. + """ + And STDERR should contain: + """ + Warning: Multisite constants could not be written to 'wp-config.php'. You may need to add them manually: + """ diff --git a/php/commands/core.php b/php/commands/core.php index 806d7fd2e1..1f0ff1cb86 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -841,12 +841,10 @@ private function _multisite_convert( $assoc_args ) { EOT; $wp_config_path = Utils\locate_wp_config(); - if ( is_writable( $wp_config_path ) ) { - self::modify_wp_config( $ms_config ); + if ( is_writable( $wp_config_path ) && self::modify_wp_config( $ms_config ) ) { WP_CLI::log( "Added multisite constants to 'wp-config.php'." ); } else { - WP_CLI::warning( "Multisite constants could not be written to 'wp-config.php'. You may need to add them manually:" ); - WP_CLI::log( $ms_config ); + WP_CLI::warning( "Multisite constants could not be written to 'wp-config.php'. You may need to add them manually:" . PHP_EOL . $ms_config ); } } @@ -898,12 +896,17 @@ private static function modify_wp_config( $content ) { $wp_config_path = Utils\locate_wp_config(); $token = "/* That's all, stop editing!"; + $config_contents = file_get_contents( $wp_config_path ); + if ( false === strpos( $config_contents, $token ) ) { + return false; + } - list( $before, $after ) = explode( $token, file_get_contents( $wp_config_path ) ); + list( $before, $after ) = explode( $token, $config_contents ); $content = PHP_EOL . PHP_EOL . trim( $content ) . PHP_EOL . PHP_EOL; file_put_contents( $wp_config_path, $before . $content . $token . $after ); + return true; } private static function get_clean_basedomain() { From 3fc84c100c3e9cd0b3a829e2c599f277460cd657 Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 11 Aug 2016 11:44:13 +0545 Subject: [PATCH 4826/4858] Passed slashed data in meta --- php/WP_CLI/CommandWithMeta.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php/WP_CLI/CommandWithMeta.php b/php/WP_CLI/CommandWithMeta.php index 0e8a07a39a..26c717c205 100644 --- a/php/WP_CLI/CommandWithMeta.php +++ b/php/WP_CLI/CommandWithMeta.php @@ -179,6 +179,7 @@ public function add( $args, $assoc_args ) { $object_id = $this->check_object_id( $object_id ); + $meta_value = wp_slash( $meta_value ); $success = add_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { @@ -221,6 +222,7 @@ public function update( $args, $assoc_args ) { if ( $meta_value === $old_value ) { WP_CLI::success( "Value passed for custom field '$meta_key' is unchanged." ); } else { + $meta_value = wp_slash( $meta_value ); $success = update_metadata( $this->meta_type, $object_id, $meta_key, $meta_value ); if ( $success ) { From 8281a5c44bdb856bb2a035fb7a79ac97c64a40eb Mon Sep 17 00:00:00 2001 From: ernilambar <nilambar@outlook.com> Date: Thu, 11 Aug 2016 11:49:09 +0545 Subject: [PATCH 4827/4858] Update test to reflect change in slashed data --- features/post-meta.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/features/post-meta.feature b/features/post-meta.feature index a7eacd135f..e8dd92da3c 100644 --- a/features/post-meta.feature +++ b/features/post-meta.feature @@ -109,3 +109,33 @@ Feature: Manage post custom fields Then STDOUT should be a table containing rows: | post_id | meta_key | meta_value | | 1 | foo | | + + Scenario: Make sure WordPress receives the slashed data it expects in meta fields + Given a WP install + + When I run `wp post-meta add 1 foo 'My\Meta'` + Then STDOUT should not be empty + + When I run `wp post-meta get 1 foo` + Then STDOUT should be: + """ + My\Meta + """ + + When I run `wp post-meta update 1 foo 'My\New\Meta'` + Then STDOUT should be: + """ + Success: Updated custom field 'foo'. + """ + + When I run the previous command again + Then STDOUT should be: + """ + Success: Value passed for custom field 'foo' is unchanged. + """ + + When I run `wp post-meta get 1 foo` + Then STDOUT should be: + """ + My\New\Meta + """ From fead1145c11c95e3f2228267ace1a568c1cce89c Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Thu, 11 Aug 2016 15:20:32 +0400 Subject: [PATCH 4828/4858] sync package composer repository on install --- php/commands/package.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/commands/package.php b/php/commands/package.php index 471c8b9699..3f9628a1ef 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -183,6 +183,14 @@ public function install( $args, $assoc_args ) { $json_manipulator->addMainKey( 'name', 'wp-cli/wp-cli' ); $json_manipulator->addLink( 'require', $package_name, $version ); $json_manipulator->addConfigSetting( 'secure-http', true ); + + // If the composer file does not contain the current package index url, refresh the repository definition. + if ( false === strpos( $composer_backup, self::PACKAGE_INDEX_URL ) ) { + WP_CLI::log( 'Updating package index repository url...' ); + $json_manipulator->removeRepository( 'wp-cli' ); + $json_manipulator->addRepository( 'wp-cli', array( 'type' => 'composer', 'url' => self::PACKAGE_INDEX_URL ) ); + } + file_put_contents( $composer_json_obj->getPath(), $json_manipulator->getContents() ); try { $composer = $this->get_composer(); From d8b1ffd9a248fe7943bd822641849e4a7bb1241b Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Thu, 11 Aug 2016 15:26:53 +0400 Subject: [PATCH 4829/4858] no need to remove the repository first --- php/commands/package.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/commands/package.php b/php/commands/package.php index 3f9628a1ef..5207f86dc4 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -187,7 +187,6 @@ public function install( $args, $assoc_args ) { // If the composer file does not contain the current package index url, refresh the repository definition. if ( false === strpos( $composer_backup, self::PACKAGE_INDEX_URL ) ) { WP_CLI::log( 'Updating package index repository url...' ); - $json_manipulator->removeRepository( 'wp-cli' ); $json_manipulator->addRepository( 'wp-cli', array( 'type' => 'composer', 'url' => self::PACKAGE_INDEX_URL ) ); } From c53a137f40575e32632416131968af00d51244cc Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Thu, 11 Aug 2016 16:57:55 +0400 Subject: [PATCH 4830/4858] limit package index check to wp-cli repository only --- php/commands/package.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/php/commands/package.php b/php/commands/package.php index 5207f86dc4..b281f7ecd1 100644 --- a/php/commands/package.php +++ b/php/commands/package.php @@ -184,8 +184,9 @@ public function install( $args, $assoc_args ) { $json_manipulator->addLink( 'require', $package_name, $version ); $json_manipulator->addConfigSetting( 'secure-http', true ); - // If the composer file does not contain the current package index url, refresh the repository definition. - if ( false === strpos( $composer_backup, self::PACKAGE_INDEX_URL ) ) { + $composer_backup_decoded = json_decode( $composer_backup, true ); + // If the composer file does not contain the current package index repository, refresh the repository definition. + if ( empty( $composer_backup_decoded['repositories']['wp-cli']['url'] ) || self::PACKAGE_INDEX_URL != $composer_backup_decoded['repositories']['wp-cli']['url'] ) { WP_CLI::log( 'Updating package index repository url...' ); $json_manipulator->addRepository( 'wp-cli', array( 'type' => 'composer', 'url' => self::PACKAGE_INDEX_URL ) ); } From 10f9317ea397bd2f98e929505870de2951a3bdce Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Fri, 12 Aug 2016 01:20:24 +0400 Subject: [PATCH 4831/4858] add functional test for syncing package index on install --- features/package-install.feature | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/features/package-install.feature b/features/package-install.feature index d883aafd0e..63061fd5a1 100644 --- a/features/package-install.feature +++ b/features/package-install.feature @@ -1,5 +1,35 @@ Feature: Install WP-CLI packages + Scenario: Install a package with an old package index url in package composer.json + Given an empty directory + And a composer.json file: + """ + { + "repositories": { + "wp-cli": { + "type": "composer", + "url": "http://wp-cli.org/package-index/" + } + } + } + """ + When I run `rm -rf /tmp/wp-cli-package-install-test/ && mkdir /tmp/wp-cli-package-install-test/ && mv composer.json /tmp/wp-cli-package-install-test/` + Then the /tmp/wp-cli-package-install-test/composer.json file should exist + When I run `WP_CLI_PACKAGES_DIR=/tmp/wp-cli-package-install-test/ wp --info` + Then STDOUT should contain: + """ + WP-CLI packages dir: /tmp/wp-cli-package-install-test/ + """ + When I run `WP_CLI_PACKAGES_DIR=/tmp/wp-cli-package-install-test/ wp package install runcommand/hook` + Then the /tmp/wp-cli-package-install-test/composer.json file should contain: + """ + "url": "https://wp-cli.org/package-index/" + """ + And the /tmp/wp-cli-package-install-test/composer.json file should not contain: + """ + "url": "http://wp-cli.org/package-index/" + """ + Scenario: Install a package with 'wp-cli/wp-cli' as a dependency Given a WP install From a62cd6111eae548cfb2801c1c22532482ce97013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Fri, 12 Aug 2016 00:30:55 +0200 Subject: [PATCH 4832/4858] Typo in db optimize and in db repair's comment OPTIMIZE_TABLE is really OPTIMIZE TABLE --- php/commands/db.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/db.php b/php/commands/db.php index 6dff55ea8c..9ca85213a7 100644 --- a/php/commands/db.php +++ b/php/commands/db.php @@ -102,7 +102,7 @@ public function reset( $_, $assoc_args ) { * specified in wp-config.php. * * [See docs](http://dev.mysql.com/doc/refman/5.7/en/optimize-table.html) - * for more details on the `OPTIMIZE_TABLE` statement. + * for more details on the `OPTIMIZE TABLE` statement. * * ## EXAMPLES * @@ -125,7 +125,7 @@ public function optimize() { * specified in wp-config.php. * * [See docs](http://dev.mysql.com/doc/refman/5.7/en/repair-table.html) for - * more details on the `REPAIR_TABLE` statement. + * more details on the `REPAIR TABLE` statement. * * ## EXAMPLES * From fc24d9d71ac3b995157a782caac4fd061427ef64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Fri, 12 Aug 2016 00:44:58 +0200 Subject: [PATCH 4833/4858] Try Trusty on Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b811927a52..670361dac1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: trusty sudo: false language: php From 9837de2e0193fbb9f8ff68aff9fff848f75def04 Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Fri, 12 Aug 2016 11:34:20 +0400 Subject: [PATCH 4834/4858] clarify scenario verbiage to specify http --- features/package-install.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/package-install.feature b/features/package-install.feature index 63061fd5a1..5efbb53bb5 100644 --- a/features/package-install.feature +++ b/features/package-install.feature @@ -1,6 +1,6 @@ Feature: Install WP-CLI packages - Scenario: Install a package with an old package index url in package composer.json + Scenario: Install a package with an http package index url in package composer.json Given an empty directory And a composer.json file: """ From af4558137adb2d39843267c63bba0e75d48acee2 Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Fri, 12 Aug 2016 11:36:41 +0400 Subject: [PATCH 4835/4858] clean up scripting in scenario a lot by using test dir --- features/package-install.feature | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/features/package-install.feature b/features/package-install.feature index 5efbb53bb5..22138d6e28 100644 --- a/features/package-install.feature +++ b/features/package-install.feature @@ -13,19 +13,17 @@ Feature: Install WP-CLI packages } } """ - When I run `rm -rf /tmp/wp-cli-package-install-test/ && mkdir /tmp/wp-cli-package-install-test/ && mv composer.json /tmp/wp-cli-package-install-test/` - Then the /tmp/wp-cli-package-install-test/composer.json file should exist - When I run `WP_CLI_PACKAGES_DIR=/tmp/wp-cli-package-install-test/ wp --info` + When I run `WP_CLI_PACKAGES_DIR=. wp --info` Then STDOUT should contain: """ - WP-CLI packages dir: /tmp/wp-cli-package-install-test/ + WP-CLI packages dir: . """ - When I run `WP_CLI_PACKAGES_DIR=/tmp/wp-cli-package-install-test/ wp package install runcommand/hook` - Then the /tmp/wp-cli-package-install-test/composer.json file should contain: + When I run `WP_CLI_PACKAGES_DIR=. wp package install runcommand/hook` + Then the composer.json file should contain: """ "url": "https://wp-cli.org/package-index/" """ - And the /tmp/wp-cli-package-install-test/composer.json file should not contain: + And the composer.json file should not contain: """ "url": "http://wp-cli.org/package-index/" """ From 949d28a9303efde76c1bdf9a01421c5a71626acc Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" <j@jorgetorres.co> Date: Fri, 12 Aug 2016 08:53:23 -0500 Subject: [PATCH 4836/4858] Preserve case for --version argument in core download --- php/commands/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/core.php b/php/commands/core.php index da1ef5a537..97a1e6dc56 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -134,8 +134,8 @@ public function download( $args, $assoc_args ) { $locale = \WP_CLI\Utils\get_flag_value( $assoc_args, 'locale', 'en_US' ); if ( isset( $assoc_args['version'] ) ) { - $version = strtolower( $assoc_args['version'] ); - $version = ( 'trunk' === $version ? 'nightly' : $version ); + $version = $assoc_args['version']; + $version = ( in_array( strtolower( $version ), array( 'trunk', 'nightly' ) ) ? 'nightly' : $version ); //nightly builds are only available in .zip format $ext = ( 'nightly' === $version ? 'zip' : 'tar.gz' ); $download_url = $this->get_download_url( $version, $locale, $ext ); From d25d33f5f54f59526945de323d1f86942abd4c4c Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Fri, 12 Aug 2016 18:31:08 +0400 Subject: [PATCH 4837/4858] update package-install scenario --- features/package-install.feature | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/features/package-install.feature b/features/package-install.feature index 22138d6e28..7de721a829 100644 --- a/features/package-install.feature +++ b/features/package-install.feature @@ -2,7 +2,7 @@ Feature: Install WP-CLI packages Scenario: Install a package with an http package index url in package composer.json Given an empty directory - And a composer.json file: + And a packages/composer.json file: """ { "repositories": { @@ -13,17 +13,20 @@ Feature: Install WP-CLI packages } } """ - When I run `WP_CLI_PACKAGES_DIR=. wp --info` + When I run `WP_CLI_PACKAGES_DIR=$PWD/packages wp package install runcommand/hook --debug` Then STDOUT should contain: - """ - WP-CLI packages dir: . - """ - When I run `WP_CLI_PACKAGES_DIR=. wp package install runcommand/hook` - Then the composer.json file should contain: + """ + Updating package index repository url... + """ + And STDOUT should contain: + """ + Success: Package installed + """ + And the packages/composer.json file should contain: """ "url": "https://wp-cli.org/package-index/" """ - And the composer.json file should not contain: + And the packages/composer.json file should not contain: """ "url": "http://wp-cli.org/package-index/" """ From 1904d0d6e572fd309c6bb3286c8d2d8dd8fce4f3 Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" <j@jorgetorres.co> Date: Fri, 12 Aug 2016 10:21:35 -0500 Subject: [PATCH 4838/4858] Add functional test for downloading WP release candidate or beta versions --- features/core-download.feature | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/features/core-download.feature b/features/core-download.feature index f08adcf134..9b244e2bf7 100644 --- a/features/core-download.feature +++ b/features/core-download.feature @@ -188,4 +188,25 @@ Feature: Download WordPress And STDERR should contain: """ Error: Nightly builds are only available for the en_US locale. - """ + """ + + Scenario: Installing a release candidate or beta version + Given an empty directory + And an empty cache + + # Test with incorrect case. + When I try `wp core download --version=4.6-rc2` + Then the return code should be 1 + Then STDERR should contain: + """ + Error: Release not found. + """ + + When I run `wp core download --version=4.6-RC2` + Then the wp-settings.php file should exist + And STDOUT should contain: + """ + Downloading WordPress 4.6-RC2 (en_US)... + md5 hash verified: 90c93a15092b2d5d4c960ec1fc183e07 + Success: WordPress downloaded. + """ From 47fedd9c04e6b8ee73fa49b86655fa574cb1b018 Mon Sep 17 00:00:00 2001 From: Evan Mattson <me@aaemnnost.tv> Date: Sat, 13 Aug 2016 13:32:29 +0400 Subject: [PATCH 4839/4858] update package-install scenario, should work now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - removed the subdirectory for the packages/composer.json which caused the test to hang indefinitely. - setup a local dummy package to “install” instead of the real one making the test a bit faster as well. --- features/package-install.feature | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/features/package-install.feature b/features/package-install.feature index 7de721a829..aad733af06 100644 --- a/features/package-install.feature +++ b/features/package-install.feature @@ -2,10 +2,14 @@ Feature: Install WP-CLI packages Scenario: Install a package with an http package index url in package composer.json Given an empty directory - And a packages/composer.json file: + And a composer.json file: """ { "repositories": { + "test" : { + "type": "path", + "url": "./dummy-package/" + }, "wp-cli": { "type": "composer", "url": "http://wp-cli.org/package-index/" @@ -13,7 +17,14 @@ Feature: Install WP-CLI packages } } """ - When I run `WP_CLI_PACKAGES_DIR=$PWD/packages wp package install runcommand/hook --debug` + And a dummy-package/composer.json file: + """ + { + "name": "wp-cli/restful", + "description": "This is a dummy package we will install instead of actually installing the real package. This prevents the test from hanging indefinitely for some reason, even though it passes. The 'name' must match a real package as it is checked against the package index." + } + """ + When I run `WP_CLI_PACKAGES_DIR=. wp package install wp-cli/restful --debug` Then STDOUT should contain: """ Updating package index repository url... @@ -22,11 +33,11 @@ Feature: Install WP-CLI packages """ Success: Package installed """ - And the packages/composer.json file should contain: + And the composer.json file should contain: """ "url": "https://wp-cli.org/package-index/" """ - And the packages/composer.json file should not contain: + And the composer.json file should not contain: """ "url": "http://wp-cli.org/package-index/" """ From 3a9b1666433d49676f1e3b7f6d37504f40cd5582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= <viktor@szepe.net> Date: Sat, 13 Aug 2016 14:34:04 +0200 Subject: [PATCH 4840/4858] wp user meta list need a user ID not "an object ID" in the docblock --- php/commands/user.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/user.php b/php/commands/user.php index b5a04c44cb..f0c5daa66f 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -953,8 +953,8 @@ public function __construct() { * * ## OPTIONS * - * <id> - * : ID for the object. + * <user> + * : The user login, user email, or user ID of the user to get metadata for. * * [--keys=<keys>] * : Limit output to metadata of specific keys. From 8d3a612ebe96d2f6221775c7d59b9b983feaa3db Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 06:20:45 -0700 Subject: [PATCH 4841/4858] Example for how to forcefully re-install plugins --- php/commands/plugin.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/php/commands/plugin.php b/php/commands/plugin.php index 2a55e37a09..4c3fee9a77 100644 --- a/php/commands/plugin.php +++ b/php/commands/plugin.php @@ -608,6 +608,15 @@ protected function filter_item_list( $items, $args ) { * Unpacking the package... * Installing the plugin... * Plugin installed successfully. + * + * # Forcefully re-install all installed plugins + * $ wp plugin install $(wp plugin list --field=name) --force + * Installing Akismet (3.1.11) + * Downloading install package from https://downloads.wordpress.org/plugin/akismet.3.1.11.zip... + * Unpacking the package... + * Installing the plugin... + * Removing the old version of the plugin... + * Plugin updated successfully */ function install( $args, $assoc_args ) { From 88add32d888025d5c10dfd68d3d36127f980b44c Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 06:34:53 -0700 Subject: [PATCH 4842/4858] Move `wp core language` class to its own file --- php/commands/core-language.php | 40 ++++++++++++++++++++++++++++++++++ php/commands/core.php | 39 --------------------------------- 2 files changed, 40 insertions(+), 39 deletions(-) create mode 100644 php/commands/core-language.php diff --git a/php/commands/core-language.php b/php/commands/core-language.php new file mode 100644 index 0000000000..bc180132ad --- /dev/null +++ b/php/commands/core-language.php @@ -0,0 +1,40 @@ +<?php + +/** + * Manage core language. + * + * ## EXAMPLES + * + * # Install language + * $ wp core language install nl_NL + * Success: Language installed. + * + * # Activate language + * $ wp core language activate nl_NL + * Success: Language activated. + * + * # Uninstall language + * $ wp core language uninstall nl_NL + * Success: Language uninstalled. + * + * # List installed languages + * $ wp core language list --status=installed + * +----------+--------------+-------------+-----------+-----------+---------------------+ + * | language | english_name | native_name | status | update | updated | + * +----------+--------------+-------------+-----------+-----------+---------------------+ + * | nl_NL | Dutch | Nederlands | installed | available | 2016-05-13 08:12:50 | + * +----------+--------------+-------------+-----------+-----------+---------------------+ + */ +class Core_Language_Command extends WP_CLI\CommandWithTranslation { + + protected $obj_type = 'core'; + +} + +WP_CLI::add_command( 'core language', 'Core_Language_Command', array( + 'before_invoke' => function() { + if ( \WP_CLI\Utils\wp_version_compare( '4.0', '<' ) ) { + WP_CLI::error( "Requires WordPress 4.0 or greater." ); + } + }) +); diff --git a/php/commands/core.php b/php/commands/core.php index 97a1e6dc56..250bb3e204 100644 --- a/php/commands/core.php +++ b/php/commands/core.php @@ -1564,42 +1564,3 @@ private function cleanup_extra_files( $version_from, $version_to, $locale ) { } WP_CLI::add_command( 'core', 'Core_Command' ); - -/** - * Manage core language. - * - * ## EXAMPLES - * - * # Install language - * $ wp core language install nl_NL - * Success: Language installed. - * - * # Activate language - * $ wp core language activate nl_NL - * Success: Language activated. - * - * # Uninstall language - * $ wp core language uninstall nl_NL - * Success: Language uninstalled. - * - * # List installed languages - * $ wp core language list --status=installed - * +----------+--------------+-------------+-----------+-----------+---------------------+ - * | language | english_name | native_name | status | update | updated | - * +----------+--------------+-------------+-----------+-----------+---------------------+ - * | nl_NL | Dutch | Nederlands | installed | available | 2016-05-13 08:12:50 | - * +----------+--------------+-------------+-----------+-----------+---------------------+ - */ -class Core_Language_Command extends WP_CLI\CommandWithTranslation { - - protected $obj_type = 'core'; - -} - -WP_CLI::add_command( 'core language', 'Core_Language_Command', array( - 'before_invoke' => function() { - if ( \WP_CLI\Utils\wp_version_compare( '4.0', '<' ) ) { - WP_CLI::error( "Requires WordPress 4.0 or greater." ); - } - }) -); From a891dfbb437e36dafb187b6b92752bd4d3559641 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 06:38:43 -0700 Subject: [PATCH 4843/4858] Move `wp comment meta` class into its own file --- php/commands/comment-meta.php | 44 +++++++++++++++++++++++++++++++++++ php/commands/comment.php | 43 ---------------------------------- 2 files changed, 44 insertions(+), 43 deletions(-) create mode 100644 php/commands/comment-meta.php diff --git a/php/commands/comment-meta.php b/php/commands/comment-meta.php new file mode 100644 index 0000000000..929c684f04 --- /dev/null +++ b/php/commands/comment-meta.php @@ -0,0 +1,44 @@ +<?php + +/** + * Manage comment custom fields. + * + * ## OPTIONS + * + * --format=json + * : Encode/decode values as JSON. + * + * ## EXAMPLES + * + * # Set comment meta + * $ wp comment meta set 123 description "Mary is a WordPress developer." + * Success: Updated custom field 'description'. + * + * # Get comment meta + * $ wp comment meta get 123 description + * Mary is a WordPress developer. + * + * # Update comment meta + * $ wp comment meta update 123 description "Mary is an awesome WordPress developer." + * Success: Updated custom field 'description'. + * + * # Delete comment meta + * $ wp comment meta delete 123 description + * Success: Deleted custom field. + */ +class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'comment'; + + /** + * Check that the comment ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + $fetcher = new \WP_CLI\Fetchers\Comment; + $comment = $fetcher->get_check( $object_id ); + return $comment->comment_ID; + } +} + +WP_CLI::add_command( 'comment meta', 'Comment_Meta_Command' ); diff --git a/php/commands/comment.php b/php/commands/comment.php index 22def3485c..a0ae3434fc 100644 --- a/php/commands/comment.php +++ b/php/commands/comment.php @@ -635,47 +635,4 @@ public function url( $args ) { } } -/** - * Manage comment custom fields. - * - * ## OPTIONS - * - * --format=json - * : Encode/decode values as JSON. - * - * ## EXAMPLES - * - * # Set comment meta - * $ wp comment meta set 123 description "Mary is a WordPress developer." - * Success: Updated custom field 'description'. - * - * # Get comment meta - * $ wp comment meta get 123 description - * Mary is a WordPress developer. - * - * # Update comment meta - * $ wp comment meta update 123 description "Mary is an awesome WordPress developer." - * Success: Updated custom field 'description'. - * - * # Delete comment meta - * $ wp comment meta delete 123 description - * Success: Deleted custom field. - */ -class Comment_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'comment'; - - /** - * Check that the comment ID exists - * - * @param int - */ - protected function check_object_id( $object_id ) { - $fetcher = new \WP_CLI\Fetchers\Comment; - $comment = $fetcher->get_check( $object_id ); - return $comment->comment_ID; - } -} - WP_CLI::add_command( 'comment', 'Comment_Command' ); -WP_CLI::add_command( 'comment meta', 'Comment_Meta_Command' ); - From 96441665c995ad7b6911bcc99b36e75e94ddf898 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 06:44:35 -0700 Subject: [PATCH 4844/4858] Move `wp menu (item|location)` classes to their own files --- features/menu-item.feature | 111 ++++++ features/menu-location.feature | 31 ++ features/menu.feature | 134 ------- php/commands/menu-item.php | 502 +++++++++++++++++++++++++ php/commands/menu-location.php | 170 +++++++++ php/commands/menu.php | 669 --------------------------------- 6 files changed, 814 insertions(+), 803 deletions(-) create mode 100644 features/menu-item.feature create mode 100644 features/menu-location.feature create mode 100644 php/commands/menu-item.php create mode 100644 php/commands/menu-location.php diff --git a/features/menu-item.feature b/features/menu-item.feature new file mode 100644 index 0000000000..0f0c514f5e --- /dev/null +++ b/features/menu-item.feature @@ -0,0 +1,111 @@ +Feature: Manage WordPress menu items + + Background: + Given a WP install + + Scenario: Add / update / remove items from a menu + + When I run `wp post create --post_title='Test post' --porcelain` + Then STDOUT should be a number + And save STDOUT as {POST_ID} + + When I run `wp post url {POST_ID}` + Then save STDOUT as {POST_LINK} + + When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term' --porcelain` + Then STDOUT should be a number + And save STDOUT as {TERM_ID} + + When I run `wp term url post_tag {TERM_ID}` + Then save STDOUT as {TERM_LINK} + + When I run `wp menu create "Sidebar Menu"` + Then STDOUT should not be empty + + When I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post" --description="Georgia peaches" --porcelain` + Then save STDOUT as {POST_ITEM_ID} + + When I run `wp menu item update {POST_ITEM_ID} --description="Washington Apples"` + Then STDOUT should be: + """ + Success: Menu item updated. + """ + + When I run `wp menu item add-term sidebar-menu post_tag {TERM_ID} --porcelain` + Then save STDOUT as {TERM_ITEM_ID} + + When I run `wp menu item add-custom sidebar-menu Apple http://apple.com --parent-id={POST_ITEM_ID} --porcelain` + Then save STDOUT as {CUSTOM_ITEM_ID} + + When I run `wp menu item update {CUSTOM_ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` + Then STDOUT should be: + """ + Success: Menu item updated. + """ + + When I run `wp menu item update {TERM_ITEM_ID} --position=3` + Then STDOUT should be: + """ + Success: Menu item updated. + """ + + When I run `wp menu item list sidebar-menu --fields=type,title,description,position,link,menu_item_parent` + Then STDOUT should be a table containing rows: + | type | title | description | position | link | menu_item_parent | + | post_type | Custom Test Post | Washington Apples | 1 | {POST_LINK} | 0 | + | custom | WordPress | | 2 | http://wordpress.org | {POST_ITEM_ID} | + | taxonomy | Test term | | 3 | {TERM_LINK} | 0 | + + When I run `wp menu item list sidebar-menu --format=ids` + Then STDOUT should not be empty + + When I run `wp menu item delete {CUSTOM_ITEM_ID}` + Then STDOUT should be: + """ + Success: 1 menu item deleted. + """ + And I run `wp menu item list sidebar-menu --format=count` + Then STDOUT should be: + """ + 2 + """ + + When I run `wp menu item delete {POST_ITEM_ID} {TERM_ITEM_ID}` + Then STDOUT should be: + """ + Success: 2 menu items deleted. + """ + And I run `wp menu item list sidebar-menu --format=count` + Then STDOUT should be: + """ + 0 + """ + + Scenario: Preserve grandparent item as ancestor of child item when parent item is removed. + + When I run `wp menu create "Grandparent Test"` + Then STDOUT should not be empty + + When I run `wp menu item add-custom grandparent-test Grandparent http://example.com/grandparent --porcelain` + Then save STDOUT as {GRANDPARENT_ID} + + When I run `wp menu item add-custom grandparent-test Parent http://example.com/parent --porcelain --parent-id={GRANDPARENT_ID}` + Then save STDOUT as {PARENT_ID} + + When I run `wp menu item add-custom grandparent-test Child http://example.com/child --porcelain --parent-id={PARENT_ID}` + Then save STDOUT as {CHILD_ID} + + When I run `wp menu item list grandparent-test --fields=title,db_id,menu_item_parent` + Then STDOUT should be a table containing rows: + | title | db_id | menu_item_parent | + | Grandparent | {GRANDPARENT_ID} | 0 | + | Parent | {PARENT_ID} | {GRANDPARENT_ID} | + | Child | {CHILD_ID} | {PARENT_ID} | + + When I run `wp menu item delete {PARENT_ID}` + + When I run `wp menu item list grandparent-test --fields=title,db_id,menu_item_parent` + Then STDOUT should be a table containing rows: + | title | db_id | menu_item_parent | + | Grandparent | {GRANDPARENT_ID} | 0 | + | Child | {CHILD_ID} | {GRANDPARENT_ID} | diff --git a/features/menu-location.feature b/features/menu-location.feature new file mode 100644 index 0000000000..e94dceee02 --- /dev/null +++ b/features/menu-location.feature @@ -0,0 +1,31 @@ +Feature: Manage WordPress menu locations + + Background: + Given a WP install + + Scenario: Assign / remove location from a menu + + When I run `wp theme install p2 --activate` + And I run `wp menu location list` + Then STDOUT should be a table containing rows: + | location | description | + | primary | Primary Menu | + + When I run `wp menu create "Primary Menu"` + And I run `wp menu location assign primary-menu primary` + And I run `wp menu list --fields=slug,locations` + Then STDOUT should be a table containing rows: + | slug | locations | + | primary-menu | primary | + + When I run `wp menu location list --format=ids` + Then STDOUT should be: + """ + primary + """ + + When I run `wp menu location remove primary-menu primary` + And I run `wp menu list --fields=slug,locations` + Then STDOUT should be a table containing rows: + | slug | locations | + | primary-menu | | diff --git a/features/menu.feature b/features/menu.feature index 1d26121c16..839bd4d089 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -47,137 +47,3 @@ Feature: Manage WordPress menus """ 5 """ - - Scenario: Assign / remove location from a menu - - When I run `wp theme install p2 --activate` - And I run `wp menu location list` - Then STDOUT should be a table containing rows: - | location | description | - | primary | Primary Menu | - - When I run `wp menu create "Primary Menu"` - And I run `wp menu location assign primary-menu primary` - And I run `wp menu list --fields=slug,locations` - Then STDOUT should be a table containing rows: - | slug | locations | - | primary-menu | primary | - - When I run `wp menu location list --format=ids` - Then STDOUT should be: - """ - primary - """ - - When I run `wp menu location remove primary-menu primary` - And I run `wp menu list --fields=slug,locations` - Then STDOUT should be a table containing rows: - | slug | locations | - | primary-menu | | - - Scenario: Add / update / remove items from a menu - - When I run `wp post create --post_title='Test post' --porcelain` - Then STDOUT should be a number - And save STDOUT as {POST_ID} - - When I run `wp post url {POST_ID}` - Then save STDOUT as {POST_LINK} - - When I run `wp term create post_tag 'Test term' --slug=test --description='This is a test term' --porcelain` - Then STDOUT should be a number - And save STDOUT as {TERM_ID} - - When I run `wp term url post_tag {TERM_ID}` - Then save STDOUT as {TERM_LINK} - - When I run `wp menu create "Sidebar Menu"` - Then STDOUT should not be empty - - When I run `wp menu item add-post sidebar-menu {POST_ID} --title="Custom Test Post" --description="Georgia peaches" --porcelain` - Then save STDOUT as {POST_ITEM_ID} - - When I run `wp menu item update {POST_ITEM_ID} --description="Washington Apples"` - Then STDOUT should be: - """ - Success: Menu item updated. - """ - - When I run `wp menu item add-term sidebar-menu post_tag {TERM_ID} --porcelain` - Then save STDOUT as {TERM_ITEM_ID} - - When I run `wp menu item add-custom sidebar-menu Apple http://apple.com --parent-id={POST_ITEM_ID} --porcelain` - Then save STDOUT as {CUSTOM_ITEM_ID} - - When I run `wp menu item update {CUSTOM_ITEM_ID} --title=WordPress --link='http://wordpress.org' --target=_blank --position=2` - Then STDOUT should be: - """ - Success: Menu item updated. - """ - - When I run `wp menu item update {TERM_ITEM_ID} --position=3` - Then STDOUT should be: - """ - Success: Menu item updated. - """ - - When I run `wp menu item list sidebar-menu --fields=type,title,description,position,link,menu_item_parent` - Then STDOUT should be a table containing rows: - | type | title | description | position | link | menu_item_parent | - | post_type | Custom Test Post | Washington Apples | 1 | {POST_LINK} | 0 | - | custom | WordPress | | 2 | http://wordpress.org | {POST_ITEM_ID} | - | taxonomy | Test term | | 3 | {TERM_LINK} | 0 | - - When I run `wp menu item list sidebar-menu --format=ids` - Then STDOUT should not be empty - - When I run `wp menu item delete {CUSTOM_ITEM_ID}` - Then STDOUT should be: - """ - Success: 1 menu item deleted. - """ - And I run `wp menu item list sidebar-menu --format=count` - Then STDOUT should be: - """ - 2 - """ - - When I run `wp menu item delete {POST_ITEM_ID} {TERM_ITEM_ID}` - Then STDOUT should be: - """ - Success: 2 menu items deleted. - """ - And I run `wp menu item list sidebar-menu --format=count` - Then STDOUT should be: - """ - 0 - """ - - Scenario: Preserve grandparent item as ancestor of child item when parent item is removed. - - When I run `wp menu create "Grandparent Test"` - Then STDOUT should not be empty - - When I run `wp menu item add-custom grandparent-test Grandparent http://example.com/grandparent --porcelain` - Then save STDOUT as {GRANDPARENT_ID} - - When I run `wp menu item add-custom grandparent-test Parent http://example.com/parent --porcelain --parent-id={GRANDPARENT_ID}` - Then save STDOUT as {PARENT_ID} - - When I run `wp menu item add-custom grandparent-test Child http://example.com/child --porcelain --parent-id={PARENT_ID}` - Then save STDOUT as {CHILD_ID} - - When I run `wp menu item list grandparent-test --fields=title,db_id,menu_item_parent` - Then STDOUT should be a table containing rows: - | title | db_id | menu_item_parent | - | Grandparent | {GRANDPARENT_ID} | 0 | - | Parent | {PARENT_ID} | {GRANDPARENT_ID} | - | Child | {CHILD_ID} | {PARENT_ID} | - - When I run `wp menu item delete {PARENT_ID}` - - When I run `wp menu item list grandparent-test --fields=title,db_id,menu_item_parent` - Then STDOUT should be a table containing rows: - | title | db_id | menu_item_parent | - | Grandparent | {GRANDPARENT_ID} | 0 | - | Child | {CHILD_ID} | {GRANDPARENT_ID} | diff --git a/php/commands/menu-item.php b/php/commands/menu-item.php new file mode 100644 index 0000000000..25d79529c4 --- /dev/null +++ b/php/commands/menu-item.php @@ -0,0 +1,502 @@ +<?php + +/** + * List, add, and delete items associated with a menu. + * + * ## EXAMPLES + * + * # Add an existing post to an existing menu + * $ wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * Success: Menu item added. + * + * # Create a new menu link item + * $ wp menu item add-custom sidebar-menu Apple http://apple.com + * Success: Menu item added. + * + * # Delete menu item + * $ wp menu item delete 45 + * Success: 1 menu item deleted. + */ +class Menu_Item_Command extends WP_CLI_Command { + + protected $obj_fields = array( + 'db_id', + 'type', + 'title', + 'link', + 'position', + ); + + /** + * Get a list of items associated with a menu. + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu. + * + * [--fields=<fields>] + * : Limit the output to specific object fields. + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - ids + * - yaml + * --- + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each menu item: + * + * * db_id + * * type + * * title + * * link + * * position + * + * These fields are optionally available: + * + * * menu_item_parent + * * object_id + * * object + * * type + * * type_label + * * target + * * attr_title + * * description + * * classes + * * xfn + * + * ## EXAMPLES + * + * $ wp menu item list main-menu + * +-------+-----------+-------------+---------------------------------+----------+ + * | db_id | type | title | link | position | + * +-------+-----------+-------------+---------------------------------+----------+ + * | 5 | custom | Home | http://example.com | 1 | + * | 6 | post_type | Sample Page | http://example.com/sample-page/ | 2 | + * +-------+-----------+-------------+---------------------------------+----------+ + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + + $items = wp_get_nav_menu_items( $args[0] ); + if ( false === $items || is_wp_error( $items ) ) { + WP_CLI::error( "Invalid menu." ); + } + + // Correct position inconsistency and + // protected `url` param in WP-CLI + $items = array_map( function( $item ) use ( $assoc_args ) { + $item->position = $item->menu_order; + $item->link = $item->url; + return $item; + }, $items ); + + if ( ! empty( $assoc_args['format'] ) && 'ids' == $assoc_args['format'] ) { + $items = array_map( function( $item ) { + return $item->db_id; + }, $items ); + } + + $formatter = $this->get_formatter( $assoc_args ); + $formatter->display_items( $items ); + + } + + /** + * Add a post as a menu item. + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu. + * + * <post-id> + * : Post ID to add to the menu. + * + * [--title=<title>] + * : Set a custom title for the menu item. + * + * [--link=<link>] + * : Set a custom url for the menu item. + * + * [--description=<description>] + * : Set a custom description for the menu item. + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item. + * + * [--target=<target>] + * : Set a custom link target for the menu item. + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item. + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item. + * + * [--porcelain] + * : Output just the new menu item id. + * + * ## EXAMPLES + * + * $ wp menu item add-post sidebar-menu 33 --title="Custom Test Post" + * Success: Menu item added. + * + * @subcommand add-post + */ + public function add_post( $args, $assoc_args ) { + + $assoc_args['object-id'] = $args[1]; + unset( $args[1] ); + $post = get_post( $assoc_args['object-id'] ); + if ( ! $post ) { + WP_CLI::error( "Invalid post." ); + } + $assoc_args['object'] = $post->post_type; + + $this->add_or_update_item( 'add', 'post_type', $args, $assoc_args ); + } + + /** + * Add a taxonomy term as a menu item. + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu. + * + * <taxonomy> + * : Taxonomy of the term to be added. + * + * <term-id> + * : Term ID of the term to be added. + * + * [--title=<title>] + * : Set a custom title for the menu item. + * + * [--link=<link>] + * : Set a custom url for the menu item. + * + * [--description=<description>] + * : Set a custom description for the menu item. + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item. + * + * [--target=<target>] + * : Set a custom link target for the menu item. + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item. + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item. + * + * [--porcelain] + * : Output just the new menu item id. + * + * ## EXAMPLES + * + * $ wp menu item add-term sidebar-menu post_tag 24 + * Success: Menu item added. + * + * @subcommand add-term + */ + public function add_term( $args, $assoc_args ) { + + $assoc_args['object'] = $args[1]; + unset( $args[1] ); + $assoc_args['object-id'] = $args[2]; + unset( $args[2] ); + + if ( ! get_term_by( 'id', $assoc_args['object-id'], $assoc_args['object'] ) ) { + WP_CLI::error( "Invalid term." ); + } + + $this->add_or_update_item( 'add', 'taxonomy', $args, $assoc_args ); + } + + /** + * Add a custom menu item. + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu. + * + * <title> + * : Title for the link. + * + * <link> + * : Target URL for the link. + * + * [--description=<description>] + * : Set a custom description for the menu item. + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item. + * + * [--target=<target>] + * : Set a custom link target for the menu item. + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item. + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item. + * + * [--porcelain] + * : Output just the new menu item id. + * + * ## EXAMPLES + * + * $ wp menu item add-custom sidebar-menu Apple http://apple.com + * Success: Menu item added. + * + * @subcommand add-custom + */ + public function add_custom( $args, $assoc_args ) { + + $assoc_args['title'] = $args[1]; + unset( $args[1] ); + $assoc_args['link'] = $args[2]; + unset( $args[2] ); + $this->add_or_update_item( 'add', 'custom', $args, $assoc_args ); + } + + /** + * Update a menu item. + * + * ## OPTIONS + * + * <db-id> + * : Database ID for the menu item. + * + * [--title=<title>] + * : Set a custom title for the menu item. + * + * [--link=<link>] + * : Set a custom url for the menu item. + * + * [--description=<description>] + * : Set a custom description for the menu item. + * + * [--attr-title=<attr-title>] + * : Set a custom title attribute for the menu item. + * + * [--target=<target>] + * : Set a custom link target for the menu item. + * + * [--classes=<classes>] + * : Set a custom link classes for the menu item. + * + * [--position=<position>] + * : Specify the position of this menu item. + * + * [--parent-id=<parent-id>] + * : Make this menu item a child of another menu item. + * + * ## EXAMPLES + * + * $ wp menu item update 45 --title=WordPress --link='http://wordpress.org' --target=_blank --position=2 + * Success: Menu item updated. + * + * @subcommand update + */ + public function update( $args, $assoc_args ) { + + // Shuffle the position of these. + $args[1] = $args[0]; + $terms = get_the_terms( $args[1], 'nav_menu' ); + if ( $terms && ! is_wp_error( $terms ) ) { + $args[0] = (int)$terms[0]->term_id; + } else { + $args[0] = 0; + } + $type = get_post_meta( $args[1], '_menu_item_type', true ); + $this->add_or_update_item( 'update', $type, $args, $assoc_args ); + + } + + /** + * Delete one or more items from a menu. + * + * ## OPTIONS + * + * <db-id>... + * : Database ID for the menu item(s). + * + * ## EXAMPLES + * + * $ wp menu item delete 45 + * Success: 1 menu item deleted. + * + * @subcommand delete + */ + public function delete( $args, $_ ) { + global $wpdb; + + $count = 0; + + foreach( $args as $arg ) { + + $parent_menu_id = (int) get_post_meta( $arg, '_menu_item_menu_item_parent', true ); + $ret = wp_delete_post( $arg, true ); + if ( ! $ret ) { + WP_CLI::warning( "Couldn't delete menu item." ); + } else if ( $parent_menu_id ) { + $children = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value=%s", (int) $arg ) ); + if ( $children ) { + $children_query = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = %d WHERE meta_key = '_menu_item_menu_item_parent' AND meta_value=%s", $parent_menu_id, (int) $arg ); + $wpdb->query( $children_query ); + foreach( $children as $child ) { + clean_post_cache( $child ); + } + } + } + + if ( false !== $ret ) { + $count++; + } + + } + + $success_message = ( 1 === $count ) ? '%d menu item deleted.' : '%d menu items deleted.'; + WP_CLI::success( sprintf( $success_message, $count ) ); + + } + + /** + * Worker method to create new items or update existing ones. + */ + private function add_or_update_item( $method, $type, $args, $assoc_args ) { + + $menu = $args[0]; + $menu_item_db_id = \WP_CLI\Utils\get_flag_value( $args, 1, 0 ); + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + // `url` is protected in WP-CLI, so we use `link` instead + $assoc_args['url'] = \WP_CLI\Utils\get_flag_value( $assoc_args, 'link' ); + + // Need to persist the menu item data. See https://core.trac.wordpress.org/ticket/28138 + if ( 'update' == $method ) { + + $menu_item_obj = get_post( $menu_item_db_id ); + $menu_item_obj = wp_setup_nav_menu_item( $menu_item_obj ); + + // Correct the menu position if this was the first item. See https://core.trac.wordpress.org/ticket/28140 + $position = ( 0 === $menu_item_obj->menu_order ) ? 1 : $menu_item_obj->menu_order; + + $default_args = array( + 'position' => $position, + 'title' => $menu_item_obj->title, + 'url' => $menu_item_obj->url, + 'description' => $menu_item_obj->description, + 'object' => $menu_item_obj->object, + 'object-id' => $menu_item_obj->object_id, + 'parent-id' => $menu_item_obj->menu_item_parent, + 'attr-title' => $menu_item_obj->attr_title, + 'target' => $menu_item_obj->target, + 'classes' => implode( ' ', $menu_item_obj->classes ), // stored in the database as array + 'xfn' => $menu_item_obj->xfn, + 'status' => $menu_item_obj->post_status, + ); + + } else { + + $default_args = array( + 'position' => 0, + 'title' => '', + 'url' => '', + 'description' => '', + 'object' => '', + 'object-id' => 0, + 'parent-id' => 0, + 'attr-title' => '', + 'target' => '', + 'classes' => '', + 'xfn' => '', + // Core oddly defaults to 'draft' for create, + // and 'publish' for update + // Easiest to always work with publish + 'status' => 'publish', + ); + + } + + $menu_item_args = array(); + foreach( $default_args as $key => $default_value ) { + // wp_update_nav_menu_item() has a weird argument prefix + $new_key = 'menu-item-' . $key; + $menu_item_args[ $new_key ] = \WP_CLI\Utils\get_flag_value( $assoc_args, $key, $default_value ); + } + + $menu_item_args['menu-item-type'] = $type; + $ret = wp_update_nav_menu_item( $menu->term_id, $menu_item_db_id, $menu_item_args ); + + if ( is_wp_error( $ret ) ) { + WP_CLI::error( $ret->get_error_message() ); + } else if ( ! $ret ) { + if ( 'add' == $method ) { + WP_CLI::error( "Couldn't add menu item." ); + } else if ( 'update' == $method ) { + WP_CLI::error( "Couldn't update menu item." ); + } + } else { + + /** + * Set the menu + * + * wp_update_nav_menu_item() *should* take care of this, but + * depends on wp_insert_post()'s "tax_input" argument, which + * is ignored if the user can't edit the taxonomy + * + * @see https://core.trac.wordpress.org/ticket/27113 + */ + if ( ! is_object_in_term( $ret, 'nav_menu', (int) $menu->term_id ) ) { + wp_set_object_terms( $ret, array( (int)$menu->term_id ), 'nav_menu' ); + } + + if ( 'add' == $method && ! empty( $assoc_args['porcelain'] ) ) { + WP_CLI::line( $ret ); + } else { + if ( 'add' == $method ) { + WP_CLI::success( "Menu item added." ); + } else if ( 'update' == $method ) { + WP_CLI::success( "Menu item updated." ); + } + } + } + + } + + protected function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields ); + } + +} + +WP_CLI::add_command( 'menu item', 'Menu_Item_Command' ); diff --git a/php/commands/menu-location.php b/php/commands/menu-location.php new file mode 100644 index 0000000000..46e69f9372 --- /dev/null +++ b/php/commands/menu-location.php @@ -0,0 +1,170 @@ +<?php + +/** + * Manage a menu's assignment to locations. + * + * ## EXAMPLES + * + * # List available menu locations + * $ wp menu location list + * +----------+-------------------+ + * | location | description | + * +----------+-------------------+ + * | primary | Primary Menu | + * | social | Social Links Menu | + * +----------+-------------------+ + * + * # Assign the 'primary-menu' menu to the 'primary' location + * $ wp menu location assign primary-menu primary + * Success: Assigned location to menu. + * + * # Remove the 'primary-menu' menu from the 'primary' location + * $ wp menu location remove primary-menu primary + * Success: Removed location from menu. + */ +class Menu_Location_Command extends WP_CLI_Command { + + /** + * List locations for the current theme. + * + * ## OPTIONS + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - json + * - count + * - yaml + * - ids + * --- + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each location: + * + * * name + * * description + * + * ## EXAMPLES + * + * $ wp menu location list + * +----------+-------------------+ + * | location | description | + * +----------+-------------------+ + * | primary | Primary Menu | + * | social | Social Links Menu | + * +----------+-------------------+ + * + * @subcommand list + */ + public function list_( $_, $assoc_args ) { + + $locations = get_registered_nav_menus(); + $location_objs = array(); + foreach( $locations as $location => $description ) { + $location_obj = new \stdClass; + $location_obj->location = $location; + $location_obj->description = $description; + $location_objs[] = $location_obj; + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'location', 'description' ) ); + + if ( 'ids' == $formatter->format ) { + $ids = array_map( + function($o) { + return $o->location; + }, $location_objs + ); + $formatter->display_items( $ids ); + } else { + $formatter->display_items( $location_objs ); + } + } + + /** + * Assign a location to a menu. + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu. + * + * <location> + * : Location's slug. + * + * ## EXAMPLES + * + * $ wp menu location assign primary-menu primary + * Success: Assigned location to menu. + * + * @subcommand assign + */ + public function assign( $args, $_ ) { + + list( $menu, $location ) = $args; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $locations = get_registered_nav_menus(); + if ( ! array_key_exists( $location, $locations ) ) { + WP_CLI::error( "Invalid location." ); + } + + $locations = get_nav_menu_locations(); + $locations[ $location ] = $menu->term_id; + + set_theme_mod( 'nav_menu_locations', $locations ); + + WP_CLI::success( "Assigned location to menu." ); + } + + /** + * Remove a location from a menu. + * + * ## OPTIONS + * + * <menu> + * : The name, slug, or term ID for the menu. + * + * <location> + * : Location's slug. + * + * ## EXAMPLES + * + * $ wp menu location remove primary-menu primary + * Success: Removed location from menu. + * + * @subcommand remove + */ + public function remove( $args, $_ ) { + + list( $menu, $location ) = $args; + + $menu = wp_get_nav_menu_object( $menu ); + if ( ! $menu || is_wp_error( $menu ) ) { + WP_CLI::error( "Invalid menu." ); + } + + $locations = get_nav_menu_locations(); + if ( \WP_CLI\Utils\get_flag_value( $locations, $location ) != $menu->term_id ) { + WP_CLI::error( "Menu isn't assigned to location." ); + } + + $locations[ $location ] = 0; + set_theme_mod( 'nav_menu_locations', $locations ); + + WP_CLI::success( "Removed location from menu." ); + + } + +} + +WP_CLI::add_command( 'menu location', 'Menu_Location_Command' ); diff --git a/php/commands/menu.php b/php/commands/menu.php index 7fafe06760..530e851c30 100644 --- a/php/commands/menu.php +++ b/php/commands/menu.php @@ -210,673 +210,4 @@ protected function get_formatter( &$assoc_args ) { } -/** - * List, add, and delete items associated with a menu. - * - * ## EXAMPLES - * - * # Add an existing post to an existing menu - * $ wp menu item add-post sidebar-menu 33 --title="Custom Test Post" - * Success: Menu item added. - * - * # Create a new menu link item - * $ wp menu item add-custom sidebar-menu Apple http://apple.com - * Success: Menu item added. - * - * # Delete menu item - * $ wp menu item delete 45 - * Success: 1 menu item deleted. - */ -class Menu_Item_Command extends WP_CLI_Command { - - protected $obj_fields = array( - 'db_id', - 'type', - 'title', - 'link', - 'position', - ); - - /** - * Get a list of items associated with a menu. - * - * ## OPTIONS - * - * <menu> - * : The name, slug, or term ID for the menu. - * - * [--fields=<fields>] - * : Limit the output to specific object fields. - * - * [--format=<format>] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - csv - * - json - * - count - * - ids - * - yaml - * --- - * - * ## AVAILABLE FIELDS - * - * These fields will be displayed by default for each menu item: - * - * * db_id - * * type - * * title - * * link - * * position - * - * These fields are optionally available: - * - * * menu_item_parent - * * object_id - * * object - * * type - * * type_label - * * target - * * attr_title - * * description - * * classes - * * xfn - * - * ## EXAMPLES - * - * $ wp menu item list main-menu - * +-------+-----------+-------------+---------------------------------+----------+ - * | db_id | type | title | link | position | - * +-------+-----------+-------------+---------------------------------+----------+ - * | 5 | custom | Home | http://example.com | 1 | - * | 6 | post_type | Sample Page | http://example.com/sample-page/ | 2 | - * +-------+-----------+-------------+---------------------------------+----------+ - * - * @subcommand list - */ - public function list_( $args, $assoc_args ) { - - $items = wp_get_nav_menu_items( $args[0] ); - if ( false === $items || is_wp_error( $items ) ) { - WP_CLI::error( "Invalid menu." ); - } - - // Correct position inconsistency and - // protected `url` param in WP-CLI - $items = array_map( function( $item ) use ( $assoc_args ) { - $item->position = $item->menu_order; - $item->link = $item->url; - return $item; - }, $items ); - - if ( ! empty( $assoc_args['format'] ) && 'ids' == $assoc_args['format'] ) { - $items = array_map( function( $item ) { - return $item->db_id; - }, $items ); - } - - $formatter = $this->get_formatter( $assoc_args ); - $formatter->display_items( $items ); - - } - - /** - * Add a post as a menu item. - * - * ## OPTIONS - * - * <menu> - * : The name, slug, or term ID for the menu. - * - * <post-id> - * : Post ID to add to the menu. - * - * [--title=<title>] - * : Set a custom title for the menu item. - * - * [--link=<link>] - * : Set a custom url for the menu item. - * - * [--description=<description>] - * : Set a custom description for the menu item. - * - * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item. - * - * [--target=<target>] - * : Set a custom link target for the menu item. - * - * [--classes=<classes>] - * : Set a custom link classes for the menu item. - * - * [--position=<position>] - * : Specify the position of this menu item. - * - * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item. - * - * [--porcelain] - * : Output just the new menu item id. - * - * ## EXAMPLES - * - * $ wp menu item add-post sidebar-menu 33 --title="Custom Test Post" - * Success: Menu item added. - * - * @subcommand add-post - */ - public function add_post( $args, $assoc_args ) { - - $assoc_args['object-id'] = $args[1]; - unset( $args[1] ); - $post = get_post( $assoc_args['object-id'] ); - if ( ! $post ) { - WP_CLI::error( "Invalid post." ); - } - $assoc_args['object'] = $post->post_type; - - $this->add_or_update_item( 'add', 'post_type', $args, $assoc_args ); - } - - /** - * Add a taxonomy term as a menu item. - * - * ## OPTIONS - * - * <menu> - * : The name, slug, or term ID for the menu. - * - * <taxonomy> - * : Taxonomy of the term to be added. - * - * <term-id> - * : Term ID of the term to be added. - * - * [--title=<title>] - * : Set a custom title for the menu item. - * - * [--link=<link>] - * : Set a custom url for the menu item. - * - * [--description=<description>] - * : Set a custom description for the menu item. - * - * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item. - * - * [--target=<target>] - * : Set a custom link target for the menu item. - * - * [--classes=<classes>] - * : Set a custom link classes for the menu item. - * - * [--position=<position>] - * : Specify the position of this menu item. - * - * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item. - * - * [--porcelain] - * : Output just the new menu item id. - * - * ## EXAMPLES - * - * $ wp menu item add-term sidebar-menu post_tag 24 - * Success: Menu item added. - * - * @subcommand add-term - */ - public function add_term( $args, $assoc_args ) { - - $assoc_args['object'] = $args[1]; - unset( $args[1] ); - $assoc_args['object-id'] = $args[2]; - unset( $args[2] ); - - if ( ! get_term_by( 'id', $assoc_args['object-id'], $assoc_args['object'] ) ) { - WP_CLI::error( "Invalid term." ); - } - - $this->add_or_update_item( 'add', 'taxonomy', $args, $assoc_args ); - } - - /** - * Add a custom menu item. - * - * ## OPTIONS - * - * <menu> - * : The name, slug, or term ID for the menu. - * - * <title> - * : Title for the link. - * - * <link> - * : Target URL for the link. - * - * [--description=<description>] - * : Set a custom description for the menu item. - * - * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item. - * - * [--target=<target>] - * : Set a custom link target for the menu item. - * - * [--classes=<classes>] - * : Set a custom link classes for the menu item. - * - * [--position=<position>] - * : Specify the position of this menu item. - * - * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item. - * - * [--porcelain] - * : Output just the new menu item id. - * - * ## EXAMPLES - * - * $ wp menu item add-custom sidebar-menu Apple http://apple.com - * Success: Menu item added. - * - * @subcommand add-custom - */ - public function add_custom( $args, $assoc_args ) { - - $assoc_args['title'] = $args[1]; - unset( $args[1] ); - $assoc_args['link'] = $args[2]; - unset( $args[2] ); - $this->add_or_update_item( 'add', 'custom', $args, $assoc_args ); - } - - /** - * Update a menu item. - * - * ## OPTIONS - * - * <db-id> - * : Database ID for the menu item. - * - * [--title=<title>] - * : Set a custom title for the menu item. - * - * [--link=<link>] - * : Set a custom url for the menu item. - * - * [--description=<description>] - * : Set a custom description for the menu item. - * - * [--attr-title=<attr-title>] - * : Set a custom title attribute for the menu item. - * - * [--target=<target>] - * : Set a custom link target for the menu item. - * - * [--classes=<classes>] - * : Set a custom link classes for the menu item. - * - * [--position=<position>] - * : Specify the position of this menu item. - * - * [--parent-id=<parent-id>] - * : Make this menu item a child of another menu item. - * - * ## EXAMPLES - * - * $ wp menu item update 45 --title=WordPress --link='http://wordpress.org' --target=_blank --position=2 - * Success: Menu item updated. - * - * @subcommand update - */ - public function update( $args, $assoc_args ) { - - // Shuffle the position of these. - $args[1] = $args[0]; - $terms = get_the_terms( $args[1], 'nav_menu' ); - if ( $terms && ! is_wp_error( $terms ) ) { - $args[0] = (int)$terms[0]->term_id; - } else { - $args[0] = 0; - } - $type = get_post_meta( $args[1], '_menu_item_type', true ); - $this->add_or_update_item( 'update', $type, $args, $assoc_args ); - - } - - /** - * Delete one or more items from a menu. - * - * ## OPTIONS - * - * <db-id>... - * : Database ID for the menu item(s). - * - * ## EXAMPLES - * - * $ wp menu item delete 45 - * Success: 1 menu item deleted. - * - * @subcommand delete - */ - public function delete( $args, $_ ) { - global $wpdb; - - $count = 0; - - foreach( $args as $arg ) { - - $parent_menu_id = (int) get_post_meta( $arg, '_menu_item_menu_item_parent', true ); - $ret = wp_delete_post( $arg, true ); - if ( ! $ret ) { - WP_CLI::warning( "Couldn't delete menu item." ); - } else if ( $parent_menu_id ) { - $children = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value=%s", (int) $arg ) ); - if ( $children ) { - $children_query = $wpdb->prepare( "UPDATE $wpdb->postmeta SET meta_value = %d WHERE meta_key = '_menu_item_menu_item_parent' AND meta_value=%s", $parent_menu_id, (int) $arg ); - $wpdb->query( $children_query ); - foreach( $children as $child ) { - clean_post_cache( $child ); - } - } - } - - if ( false !== $ret ) { - $count++; - } - - } - - $success_message = ( 1 === $count ) ? '%d menu item deleted.' : '%d menu items deleted.'; - WP_CLI::success( sprintf( $success_message, $count ) ); - - } - - /** - * Worker method to create new items or update existing ones. - */ - private function add_or_update_item( $method, $type, $args, $assoc_args ) { - - $menu = $args[0]; - $menu_item_db_id = \WP_CLI\Utils\get_flag_value( $args, 1, 0 ); - - $menu = wp_get_nav_menu_object( $menu ); - if ( ! $menu || is_wp_error( $menu ) ) { - WP_CLI::error( "Invalid menu." ); - } - - // `url` is protected in WP-CLI, so we use `link` instead - $assoc_args['url'] = \WP_CLI\Utils\get_flag_value( $assoc_args, 'link' ); - - // Need to persist the menu item data. See https://core.trac.wordpress.org/ticket/28138 - if ( 'update' == $method ) { - - $menu_item_obj = get_post( $menu_item_db_id ); - $menu_item_obj = wp_setup_nav_menu_item( $menu_item_obj ); - - // Correct the menu position if this was the first item. See https://core.trac.wordpress.org/ticket/28140 - $position = ( 0 === $menu_item_obj->menu_order ) ? 1 : $menu_item_obj->menu_order; - - $default_args = array( - 'position' => $position, - 'title' => $menu_item_obj->title, - 'url' => $menu_item_obj->url, - 'description' => $menu_item_obj->description, - 'object' => $menu_item_obj->object, - 'object-id' => $menu_item_obj->object_id, - 'parent-id' => $menu_item_obj->menu_item_parent, - 'attr-title' => $menu_item_obj->attr_title, - 'target' => $menu_item_obj->target, - 'classes' => implode( ' ', $menu_item_obj->classes ), // stored in the database as array - 'xfn' => $menu_item_obj->xfn, - 'status' => $menu_item_obj->post_status, - ); - - } else { - - $default_args = array( - 'position' => 0, - 'title' => '', - 'url' => '', - 'description' => '', - 'object' => '', - 'object-id' => 0, - 'parent-id' => 0, - 'attr-title' => '', - 'target' => '', - 'classes' => '', - 'xfn' => '', - // Core oddly defaults to 'draft' for create, - // and 'publish' for update - // Easiest to always work with publish - 'status' => 'publish', - ); - - } - - $menu_item_args = array(); - foreach( $default_args as $key => $default_value ) { - // wp_update_nav_menu_item() has a weird argument prefix - $new_key = 'menu-item-' . $key; - $menu_item_args[ $new_key ] = \WP_CLI\Utils\get_flag_value( $assoc_args, $key, $default_value ); - } - - $menu_item_args['menu-item-type'] = $type; - $ret = wp_update_nav_menu_item( $menu->term_id, $menu_item_db_id, $menu_item_args ); - - if ( is_wp_error( $ret ) ) { - WP_CLI::error( $ret->get_error_message() ); - } else if ( ! $ret ) { - if ( 'add' == $method ) { - WP_CLI::error( "Couldn't add menu item." ); - } else if ( 'update' == $method ) { - WP_CLI::error( "Couldn't update menu item." ); - } - } else { - - /** - * Set the menu - * - * wp_update_nav_menu_item() *should* take care of this, but - * depends on wp_insert_post()'s "tax_input" argument, which - * is ignored if the user can't edit the taxonomy - * - * @see https://core.trac.wordpress.org/ticket/27113 - */ - if ( ! is_object_in_term( $ret, 'nav_menu', (int) $menu->term_id ) ) { - wp_set_object_terms( $ret, array( (int)$menu->term_id ), 'nav_menu' ); - } - - if ( 'add' == $method && ! empty( $assoc_args['porcelain'] ) ) { - WP_CLI::line( $ret ); - } else { - if ( 'add' == $method ) { - WP_CLI::success( "Menu item added." ); - } else if ( 'update' == $method ) { - WP_CLI::success( "Menu item updated." ); - } - } - } - - } - - protected function get_formatter( &$assoc_args ) { - return new \WP_CLI\Formatter( $assoc_args, $this->obj_fields ); - } - -} - -/** - * Manage a menu's assignment to locations. - * - * ## EXAMPLES - * - * # List available menu locations - * $ wp menu location list - * +----------+-------------------+ - * | location | description | - * +----------+-------------------+ - * | primary | Primary Menu | - * | social | Social Links Menu | - * +----------+-------------------+ - * - * # Assign the 'primary-menu' menu to the 'primary' location - * $ wp menu location assign primary-menu primary - * Success: Assigned location to menu. - * - * # Remove the 'primary-menu' menu from the 'primary' location - * $ wp menu location remove primary-menu primary - * Success: Removed location from menu. - */ -class Menu_Location_Command extends WP_CLI_Command { - - /** - * List locations for the current theme. - * - * ## OPTIONS - * - * [--format=<format>] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - csv - * - json - * - count - * - yaml - * - ids - * --- - * - * ## AVAILABLE FIELDS - * - * These fields will be displayed by default for each location: - * - * * name - * * description - * - * ## EXAMPLES - * - * $ wp menu location list - * +----------+-------------------+ - * | location | description | - * +----------+-------------------+ - * | primary | Primary Menu | - * | social | Social Links Menu | - * +----------+-------------------+ - * - * @subcommand list - */ - public function list_( $_, $assoc_args ) { - - $locations = get_registered_nav_menus(); - $location_objs = array(); - foreach( $locations as $location => $description ) { - $location_obj = new \stdClass; - $location_obj->location = $location; - $location_obj->description = $description; - $location_objs[] = $location_obj; - } - - $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'location', 'description' ) ); - - if ( 'ids' == $formatter->format ) { - $ids = array_map( - function($o) { - return $o->location; - }, $location_objs - ); - $formatter->display_items( $ids ); - } else { - $formatter->display_items( $location_objs ); - } - } - - /** - * Assign a location to a menu. - * - * ## OPTIONS - * - * <menu> - * : The name, slug, or term ID for the menu. - * - * <location> - * : Location's slug. - * - * ## EXAMPLES - * - * $ wp menu location assign primary-menu primary - * Success: Assigned location to menu. - * - * @subcommand assign - */ - public function assign( $args, $_ ) { - - list( $menu, $location ) = $args; - - $menu = wp_get_nav_menu_object( $menu ); - if ( ! $menu || is_wp_error( $menu ) ) { - WP_CLI::error( "Invalid menu." ); - } - - $locations = get_registered_nav_menus(); - if ( ! array_key_exists( $location, $locations ) ) { - WP_CLI::error( "Invalid location." ); - } - - $locations = get_nav_menu_locations(); - $locations[ $location ] = $menu->term_id; - - set_theme_mod( 'nav_menu_locations', $locations ); - - WP_CLI::success( "Assigned location to menu." ); - } - - /** - * Remove a location from a menu. - * - * ## OPTIONS - * - * <menu> - * : The name, slug, or term ID for the menu. - * - * <location> - * : Location's slug. - * - * ## EXAMPLES - * - * $ wp menu location remove primary-menu primary - * Success: Removed location from menu. - * - * @subcommand remove - */ - public function remove( $args, $_ ) { - - list( $menu, $location ) = $args; - - $menu = wp_get_nav_menu_object( $menu ); - if ( ! $menu || is_wp_error( $menu ) ) { - WP_CLI::error( "Invalid menu." ); - } - - $locations = get_nav_menu_locations(); - if ( \WP_CLI\Utils\get_flag_value( $locations, $location ) != $menu->term_id ) { - WP_CLI::error( "Menu isn't assigned to location." ); - } - - $locations[ $location ] = 0; - set_theme_mod( 'nav_menu_locations', $locations ); - - WP_CLI::success( "Removed location from menu." ); - - } - - -} - WP_CLI::add_command( 'menu', 'Menu_Command' ); -WP_CLI::add_command( 'menu item', 'Menu_Item_Command' ); -WP_CLI::add_command( 'menu location', 'Menu_Location_Command' ); From c1d121b543e1bf862af0b958d603069065673e91 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 07:21:19 -0700 Subject: [PATCH 4845/4858] Failing test case for #3196 --- features/theme.feature | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/features/theme.feature b/features/theme.feature index 04b4a9ea79..59b1f48c2e 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -347,3 +347,25 @@ Feature: Manage WordPress themes name,old_version,new_version,status twentytwelve,1.0,{UPDATE_VERSION},Updated """ + + Scenario: Automatically install parent theme for a child theme + Given a WP install + + When I try `wp theme status stargazer` + Then STDERR should contain: + """ + Error: The 'stargazer' theme could not be found. + """ + + When I run `wp theme install buntu` + Then STDOUT should contain: + """ + Successfully installed the parent theme, + """ + + When I run `wp theme status stargazer` + Then STDOUT should contain: + """ + Theme stargazer details: + """ + And STDERR should be empty From 0db84dfd0dc14f5088ddea3075856f044b48d63e Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 07:32:15 -0700 Subject: [PATCH 4846/4858] Move `wp theme mod` class to its own file --- php/commands/theme-mod.php | 190 +++++++++++++++++++++++++++++++++++++ php/commands/theme.php | 189 ------------------------------------ 2 files changed, 190 insertions(+), 189 deletions(-) create mode 100644 php/commands/theme-mod.php diff --git a/php/commands/theme-mod.php b/php/commands/theme-mod.php new file mode 100644 index 0000000000..00bb78262e --- /dev/null +++ b/php/commands/theme-mod.php @@ -0,0 +1,190 @@ +<?php + +/** + * Manage theme mods. + * + * ## EXAMPLES + * + * # Set theme mod. + * $ wp theme mod set background_color 000000 + * Success: Theme mod background_color set to 000000 + * + * # Get single theme mod in JSON format. + * $ wp theme mod get background_color --format=json + * [{"key":"background_color","value":"dd3333"}] + * + * # Remove all theme mods. + * $ wp theme mod remove --all + * Success: Theme mods removed. + */ +class Theme_Mod_command extends WP_CLI_Command { + + /** + * Get theme mod(s). + * + * ## OPTIONS + * + * [<mod>...] + * : One or more mods to get. + * + * [--all] + * : List all theme mods + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - json + * - csv + * - yaml + * --- + * + * ## EXAMPLES + * + * # Get all theme mods + * $ wp theme mod get --all + * +------------------+---------+ + * | key | value | + * +------------------+---------+ + * | background_color | dd3333 | + * | link_color | #dd9933 | + * | main_text_color | #8224e3 | + * +------------------+---------+ + * + * # Get single theme mod in JSON format + * $ wp theme mod get background_color --format=json + * [{"key":"background_color","value":"dd3333"}] + * + * # Get multiple theme mods + * $ wp theme mod get background_color header_textcolor + * +------------------+--------+ + * | key | value | + * +------------------+--------+ + * | background_color | dd3333 | + * | header_textcolor | | + * +------------------+--------+ + */ + public function get( $args = array(), $assoc_args = array() ) { + + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { + WP_CLI::error( "You must specify at least one mod or use --all." ); + } + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + $args = array(); + } + + $list = array(); + $mods = get_theme_mods(); + if ( ! is_array( $mods ) ) { + // if no mods are set (perhaps new theme), make sure foreach still works + $mods = array(); + } + foreach ( $mods as $k => $v ) { + // if mods were given, skip the others + if ( ! empty( $args ) && ! in_array( $k, $args ) ) continue; + + if ( is_array( $v ) ) { + $list[] = array( 'key' => $k, 'value' => '=>' ); + foreach ( $v as $_k => $_v ) { + $list[] = array( 'key' => " $_k", 'value' => $_v ); + } + } else { + $list[] = array( 'key' => $k, 'value' => $v ); + } + + } + + // For unset mods, show blank value + foreach ( $args as $mod ) { + if ( ! isset( $mods[ $mod ] ) ) { + $list[] = array( 'key' => $mod, 'value' => '' ); + } + } + + $formatter = new \WP_CLI\Formatter( $assoc_args, array('key', 'value'), 'thememods' ); + $formatter->display_items( $list ); + + } + + /** + * Remove theme mod(s). + * + * ## OPTIONS + * + * [<mod>...] + * : One or more mods to remove. + * + * [--all] + * : Remove all theme mods. + * + * ## EXAMPLES + * + * # Remove all theme mods. + * $ wp theme mod remove --all + * Success: Theme mods removed. + * + * # Remove single theme mod. + * $ wp theme mod remove background_color + * Success: 1 mod removed. + * + * # Remove multiple theme mods. + * $ wp theme mod remove background_color header_textcolor + * Success: 2 mods removed. + */ + public function remove( $args = array(), $assoc_args = array() ) { + + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { + WP_CLI::error( "You must specify at least one mod or use --all." ); + } + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + remove_theme_mods(); + WP_CLI::success( 'Theme mods removed.' ); + return; + } + + foreach ( $args as $mod ) { + remove_theme_mod( $mod ); + } + + $count = count( $args ); + $success_message = ( 1 === $count ) ? '%d mod removed.' : '%d mods removed.'; + WP_CLI::success( sprintf( $success_message, $count ) ); + + } + + /** + * Set a theme mod. + * + * ## OPTIONS + * + * <mod> + * : The name of the theme mod to set or update. + * + * <value> + * : The new value. + * + * ## EXAMPLES + * + * # Set theme mod + * $ wp theme mod set background_color 000000 + * Success: Theme mod background_color set to 000000 + */ + public function set( $args = array(), $assoc_args = array() ) { + list( $mod, $value ) = $args; + + set_theme_mod( $mod, $value ); + + if ( $value == get_theme_mod( $mod ) ) { + WP_CLI::success( sprintf( "Theme mod %s set to %s.", $mod, $value ) ); + } else { + WP_CLI::success( sprintf( "Could not update theme mod %s.", $mod ) ); + } + } + +} + +WP_CLI::add_command( 'theme mod', 'Theme_Mod_Command' ); diff --git a/php/commands/theme.php b/php/commands/theme.php index 265843337b..61dd798e69 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -718,193 +718,4 @@ public function list_( $_, $assoc_args ) { } } -/** - * Manage theme mods. - * - * ## EXAMPLES - * - * # Set theme mod. - * $ wp theme mod set background_color 000000 - * Success: Theme mod background_color set to 000000 - * - * # Get single theme mod in JSON format. - * $ wp theme mod get background_color --format=json - * [{"key":"background_color","value":"dd3333"}] - * - * # Remove all theme mods. - * $ wp theme mod remove --all - * Success: Theme mods removed. - */ -class Theme_Mod_command extends WP_CLI_Command { - - /** - * Get theme mod(s). - * - * ## OPTIONS - * - * [<mod>...] - * : One or more mods to get. - * - * [--all] - * : List all theme mods - * - * [--format=<format>] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - json - * - csv - * - yaml - * --- - * - * ## EXAMPLES - * - * # Get all theme mods - * $ wp theme mod get --all - * +------------------+---------+ - * | key | value | - * +------------------+---------+ - * | background_color | dd3333 | - * | link_color | #dd9933 | - * | main_text_color | #8224e3 | - * +------------------+---------+ - * - * # Get single theme mod in JSON format - * $ wp theme mod get background_color --format=json - * [{"key":"background_color","value":"dd3333"}] - * - * # Get multiple theme mods - * $ wp theme mod get background_color header_textcolor - * +------------------+--------+ - * | key | value | - * +------------------+--------+ - * | background_color | dd3333 | - * | header_textcolor | | - * +------------------+--------+ - */ - public function get( $args = array(), $assoc_args = array() ) { - - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { - WP_CLI::error( "You must specify at least one mod or use --all." ); - } - - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { - $args = array(); - } - - $list = array(); - $mods = get_theme_mods(); - if ( ! is_array( $mods ) ) { - // if no mods are set (perhaps new theme), make sure foreach still works - $mods = array(); - } - foreach ( $mods as $k => $v ) { - // if mods were given, skip the others - if ( ! empty( $args ) && ! in_array( $k, $args ) ) continue; - - if ( is_array( $v ) ) { - $list[] = array( 'key' => $k, 'value' => '=>' ); - foreach ( $v as $_k => $_v ) { - $list[] = array( 'key' => " $_k", 'value' => $_v ); - } - } else { - $list[] = array( 'key' => $k, 'value' => $v ); - } - - } - - // For unset mods, show blank value - foreach ( $args as $mod ) { - if ( ! isset( $mods[ $mod ] ) ) { - $list[] = array( 'key' => $mod, 'value' => '' ); - } - } - - $formatter = new \WP_CLI\Formatter( $assoc_args, array('key', 'value'), 'thememods' ); - $formatter->display_items( $list ); - - } - - /** - * Remove theme mod(s). - * - * ## OPTIONS - * - * [<mod>...] - * : One or more mods to remove. - * - * [--all] - * : Remove all theme mods. - * - * ## EXAMPLES - * - * # Remove all theme mods. - * $ wp theme mod remove --all - * Success: Theme mods removed. - * - * # Remove single theme mod. - * $ wp theme mod remove background_color - * Success: 1 mod removed. - * - * # Remove multiple theme mods. - * $ wp theme mod remove background_color header_textcolor - * Success: 2 mods removed. - */ - public function remove( $args = array(), $assoc_args = array() ) { - - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) { - WP_CLI::error( "You must specify at least one mod or use --all." ); - } - - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { - remove_theme_mods(); - WP_CLI::success( 'Theme mods removed.' ); - return; - } - - foreach ( $args as $mod ) { - remove_theme_mod( $mod ); - } - - $count = count( $args ); - $success_message = ( 1 === $count ) ? '%d mod removed.' : '%d mods removed.'; - WP_CLI::success( sprintf( $success_message, $count ) ); - - } - - /** - * Set a theme mod. - * - * ## OPTIONS - * - * <mod> - * : The name of the theme mod to set or update. - * - * <value> - * : The new value. - * - * ## EXAMPLES - * - * # Set theme mod - * $ wp theme mod set background_color 000000 - * Success: Theme mod background_color set to 000000 - */ - public function set( $args = array(), $assoc_args = array() ) { - list( $mod, $value ) = $args; - - set_theme_mod( $mod, $value ); - - if ( $value == get_theme_mod( $mod ) ) { - WP_CLI::success( sprintf( "Theme mod %s set to %s.", $mod, $value ) ); - } else { - WP_CLI::success( sprintf( "Could not update theme mod %s.", $mod ) ); - } - } - -} - WP_CLI::add_command( 'theme', 'Theme_Command' ); -WP_CLI::add_command( 'theme mod', 'Theme_Mod_Command' ); - From 6c5a1cdada5b60a987148b269375d745ad845c7d Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Tue, 16 Aug 2016 14:44:15 -0700 Subject: [PATCH 4847/4858] Update tests for WordPress 4.7 --- features/core-check-update.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 0b6a728ab5..71c9885885 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -9,7 +9,7 @@ Feature: Check for more recent versions When I run `wp core check-update` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5.3 | major | https://downloads.wordpress.org/release/wordpress-4.5.3.zip | + | 4.6 | major | https://downloads.wordpress.org/release/wordpress-4.6.zip | | 4.4.4 | minor | https://downloads.wordpress.org/release/wordpress-4.4.4-partial-0.zip | When I run `wp core check-update --format=count` @@ -21,7 +21,7 @@ Feature: Check for more recent versions When I run `wp core check-update --major` Then STDOUT should be a table containing rows: | version | update_type | package_url | - | 4.5.3 | major | https://downloads.wordpress.org/release/wordpress-4.5.3.zip | + | 4.6 | major | https://downloads.wordpress.org/release/wordpress-4.6.zip | When I run `wp core check-update --major --format=count` Then STDOUT should be: From 394115a7154d9b58f3b90cf9a551db9a0342a9d8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 17 Aug 2016 04:40:45 -0700 Subject: [PATCH 4848/4858] Move `wp term meta` class to its own file --- php/commands/term-meta.php | 49 ++++++++++++++++++++++++++++++++++++++ php/commands/term.php | 47 ------------------------------------ 2 files changed, 49 insertions(+), 47 deletions(-) create mode 100644 php/commands/term-meta.php diff --git a/php/commands/term-meta.php b/php/commands/term-meta.php new file mode 100644 index 0000000000..53483b79ad --- /dev/null +++ b/php/commands/term-meta.php @@ -0,0 +1,49 @@ +<?php + +/** + * Manage term custom fields. + * + * ## EXAMPLES + * + * # Set term meta + * $ wp term meta set 123 bio "Mary is a WordPress developer." + * Success: Updated custom field 'bio'. + * + * # Get term meta + * $ wp term meta get 123 bio + * Mary is a WordPress developer. + * + * # Update term meta + * $ wp term meta update 123 bio "Mary is an awesome WordPress developer." + * Success: Updated custom field 'bio'. + * + * # Delete term meta + * $ wp term meta delete 123 bio + * Success: Deleted custom field. + */ +class Term_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'term'; + + /** + * Check that the term ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + $term = get_term( $object_id ); + if ( ! $term ) { + WP_CLI::error( "Could not find the term with ID {$object_id}." ); + } + return $term->term_id; + } + +} + +WP_CLI::add_command( 'term meta', 'Term_Meta_Command', array( + 'before_invoke' => function() { + if ( \WP_CLI\Utils\wp_version_compare( '4.4', '<' ) ) { + WP_CLI::error( "Requires WordPress 4.4 or greater." ); + } + }) +); + diff --git a/php/commands/term.php b/php/commands/term.php index dc652d884a..db759c1359 100644 --- a/php/commands/term.php +++ b/php/commands/term.php @@ -572,51 +572,4 @@ private function get_formatter( &$assoc_args ) { } } -/** - * Manage term custom fields. - * - * ## EXAMPLES - * - * # Set term meta - * $ wp term meta set 123 bio "Mary is a WordPress developer." - * Success: Updated custom field 'bio'. - * - * # Get term meta - * $ wp term meta get 123 bio - * Mary is a WordPress developer. - * - * # Update term meta - * $ wp term meta update 123 bio "Mary is an awesome WordPress developer." - * Success: Updated custom field 'bio'. - * - * # Delete term meta - * $ wp term meta delete 123 bio - * Success: Deleted custom field. - */ -class Term_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'term'; - - /** - * Check that the term ID exists - * - * @param int - */ - protected function check_object_id( $object_id ) { - $term = get_term( $object_id ); - if ( ! $term ) { - WP_CLI::error( "Could not find the term with ID {$object_id}." ); - } - return $term->term_id; - } - -} - WP_CLI::add_command( 'term', 'Term_Command' ); -WP_CLI::add_command( 'term meta', 'Term_Meta_Command', array( - 'before_invoke' => function() { - if ( \WP_CLI\Utils\wp_version_compare( '4.4', '<' ) ) { - WP_CLI::error( "Requires WordPress 4.4 or greater." ); - } - }) -); - From 98c188c263d87f37ab5909b148e589e15d0cef8b Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 17 Aug 2016 04:46:36 -0700 Subject: [PATCH 4849/4858] Move `wp cron (event|schedule)` classes to their own files --- php/commands/cron-event.php | 472 ++++++++++++++++++++++++++ php/commands/cron-schedule.php | 130 +++++++ php/commands/cron.php | 600 +-------------------------------- 3 files changed, 603 insertions(+), 599 deletions(-) create mode 100644 php/commands/cron-event.php create mode 100644 php/commands/cron-schedule.php diff --git a/php/commands/cron-event.php b/php/commands/cron-event.php new file mode 100644 index 0000000000..b3903f5571 --- /dev/null +++ b/php/commands/cron-event.php @@ -0,0 +1,472 @@ +<?php + +/** + * Manage WP-Cron events. + * + * ## EXAMPLES + * + * # Schedule a new cron event + * $ wp cron event schedule cron_test + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:19:16 GMT. + * + * # Run all cron events due right now + * $ wp cron event run --due-now + * Success: Executed a total of 2 cron events. + * + * # Delete the next scheduled cron event + * $ wp cron event delete cron_test + * Success: Deleted 2 instances of the cron event 'cron_test'. + * + * # List scheduled cron events in JSON + * $ wp cron event list --fields=hook,next_run --format=json + * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] + * + * @package wp-cli + */ +class Cron_Event_Command extends WP_CLI_Command { + + private $fields = array( + 'hook', + 'next_run_gmt', + 'next_run_relative', + 'recurrence', + ); + private static $time_format = 'Y-m-d H:i:s'; + + /** + * List scheduled cron events. + * + * ## OPTIONS + * + * [--fields=<fields>] + * : Limit the output to specific object fields. + * + * [--<field>=<value>] + * : Filter by one or more fields. + * + * [--field=<field>] + * : Prints the value of a single field for each event. + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - count + * - yaml + * --- + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each cron event: + * * hook + * * next_run_gmt + * * next_run_relative + * * recurrence + * + * These fields are optionally available: + * * time + * * sig + * * args + * * schedule + * * interval + * * next_run + * + * ## EXAMPLES + * + * # List scheduled cron events + * $ wp cron event list + * +-------------------+---------------------+---------------------+------------+ + * | hook | next_run_gmt | next_run_relative | recurrence | + * +-------------------+---------------------+---------------------+------------+ + * | wp_version_check | 2016-05-31 22:15:13 | 11 hours 57 minutes | 12 hours | + * | wp_update_plugins | 2016-05-31 22:15:13 | 11 hours 57 minutes | 12 hours | + * | wp_update_themes | 2016-05-31 22:15:14 | 11 hours 57 minutes | 12 hours | + * +-------------------+---------------------+---------------------+------------+ + * + * # List scheduled cron events in JSON + * $ wp cron event list --fields=hook,next_run --format=json + * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); + + $events = self::get_cron_events(); + + if ( is_wp_error( $events ) ) { + $events = array(); + } + + foreach ( $events as $key => $event ) { + foreach ( $this->fields as $field ) { + if ( ! empty( $assoc_args[ $field ] ) && $event->{$field} !== $assoc_args[ $field ] ) { + unset( $events[ $key ] ); + break; + } + } + } + + if ( 'ids' == $formatter->format ) { + echo implode( ' ', wp_list_pluck( $events, 'hook' ) ); + } else { + $formatter->display_items( $events ); + } + + } + + /** + * Schedule a new cron event. + * + * ## OPTIONS + * + * <hook> + * : The hook name. + * + * [<next-run>] + * : A Unix timestamp or an English textual datetime description compatible with `strtotime()`. Defaults to now. + * + * [<recurrence>] + * : How often the event should recur. See `wp cron schedule list` for available schedule names. Defaults to no recurrence. + * + * [--<field>=<value>] + * : Associative args for the event. + * + * ## EXAMPLES + * + * # Schedule a new cron event + * $ wp cron event schedule cron_test + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:19:16 GMT. + * + * # Schedule new cron event with hourly recurrence + * $ wp cron event schedule cron_test now hourly + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:20:32 GMT. + * + * # Schedule new cron event and pass associative arguments + * $ wp cron event schedule cron_test '+1 hour' --foo=1 --bar=2 + * Success: Scheduled event with hook 'cron_test' for 2016-05-31 11:21:35 GMT. + */ + public function schedule( $args, $assoc_args ) { + + $hook = $args[0]; + $next_run = \WP_CLI\Utils\get_flag_value( $args, 1, 'now' ); + $recurrence = \WP_CLI\Utils\get_flag_value( $args, 2, false ); + + if ( empty( $next_run ) ) { + $timestamp = time(); + } else if ( is_numeric( $next_run ) ) { + $timestamp = absint( $next_run ); + } else { + $timestamp = strtotime( $next_run ); + } + + if ( ! $timestamp ) { + WP_CLI::error( sprintf( "'%s' is not a valid datetime.", $next_run ) ); + } + + if ( ! empty( $recurrence ) ) { + + $schedules = wp_get_schedules(); + + if ( ! isset( $schedules[$recurrence] ) ) { + WP_CLI::error( sprintf( "'%s' is not a valid schedule name for recurrence.", $recurrence ) ); + } + + $event = wp_schedule_event( $timestamp, $recurrence, $hook, $assoc_args ); + + } else { + + $event = wp_schedule_single_event( $timestamp, $hook, $assoc_args ); + + } + + if ( false !== $event ) { + WP_CLI::success( sprintf( "Scheduled event with hook '%s' for %s GMT.", $hook, date( self::$time_format, $timestamp ) ) ); + } else { + WP_CLI::error( 'Event not scheduled.' ); + } + + } + + /** + * Run the next scheduled cron event for the given hook. + * + * ## OPTIONS + * + * [<hook>...] + * : One or more hooks to run. + * + * [--due-now] + * : Run all hooks due right now. + * + * [--all] + * : Run all hooks. + * + * ## EXAMPLES + * + * # Run all cron events due right now + * $ wp cron event run --due-now + * Success: Executed a total of 2 cron events. + */ + public function run( $args, $assoc_args ) { + + if ( empty( $args ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + WP_CLI::error( 'Please specify one or more cron events, or use --due-now/--all.' ); + } + + $events = self::get_cron_events(); + + if ( is_wp_error( $events ) ) { + WP_CLI::error( $events ); + } + + if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) ) { + $due_events = array(); + foreach( $events as $event ) { + if ( time() >= $event->time ) { + $due_events[] = $event; + } + } + $events = $due_events; + } else if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { + $hooks = wp_list_pluck( $events, 'hook' ); + $due_events = array(); + foreach( $args as $hook ) { + if ( ! in_array( $hook, $hooks ) ) { + WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); + } + } + foreach( $events as $event ) { + if ( in_array( $event->hook, $args ) ) { + $due_events[] = $event; + } + } + $events = $due_events; + } + + $executed = 0; + foreach ( $events as $event ) { + $start = microtime( true ); + $result = self::run_event( $event ); + $total = round( microtime( true ) - $start, 3 ); + $executed++; + WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); + } + + $message = ( 1 === $executed ) ? 'Executed a total of %d cron event.' : 'Executed a total of %d cron events.'; + WP_CLI::success( sprintf( $message, $executed ) ); + } + + /** + * Executes an event immediately. + * + * @param stdClass $event The event + * @return bool Whether the event was successfully executed or not. + */ + protected static function run_event( stdClass $event ) { + + if ( ! defined( 'DOING_CRON' ) ) { + define( 'DOING_CRON', true ); + } + + if ( $event->schedule != false ) { + $new_args = array( $event->time, $event->schedule, $event->hook, $event->args ); + call_user_func_array( 'wp_reschedule_event', $new_args ); + } + + wp_unschedule_event( $event->time, $event->hook, $event->args ); + + do_action_ref_array( $event->hook, $event->args ); + + return true; + + } + + /** + * Delete the next scheduled cron event for the given hook. + * + * ## OPTIONS + * + * <hook> + * : The hook name. + * + * ## EXAMPLES + * + * # Delete the next scheduled cron event + * $ wp cron event delete cron_test + * Success: Deleted 2 instances of the cron event 'cron_test'. + */ + public function delete( $args, $assoc_args ) { + + $hook = $args[0]; + $events = self::get_cron_events(); + + if ( is_wp_error( $events ) ) { + WP_CLI::error( $events ); + } + + $deleted = 0; + foreach ( $events as $event ) { + if ( $event->hook == $hook ) { + $result = self::delete_event( $event ); + if ( $result ) { + $deleted++; + } else { + WP_CLI::warning( sprintf( "Failed to the delete the cron event '%s'.", $hook ) ); + } + } + } + + if ( $deleted ) { + $message = ( 1 == $deleted ) ? "Deleted the cron event '%2\$s'." : "Deleted %1\$d instances of the cron event '%2\$s'."; + WP_CLI::success( sprintf( $message, $deleted, $hook ) ); + } else { + WP_CLI::error( sprintf( "Invalid cron event '%s'.", $hook ) ); + } + + } + + /** + * Deletes a cron event. + * + * @param stdClass $event The event + * @return bool Whether the event was successfully deleted or not. + */ + protected static function delete_event( stdClass $event ) { + $crons = _get_cron_array(); + + if ( ! isset( $crons[$event->time][$event->hook][$event->sig] ) ) { + return false; + } + + wp_unschedule_event( $event->time, $event->hook, $event->args ); + return true; + } + + /** + * Callback function to format a cron event. + * + * @param stdClass $event The event. + * @return stdClass The formatted event object. + */ + protected static function format_event( stdClass $event ) { + + $event->next_run = get_date_from_gmt( date( 'Y-m-d H:i:s', $event->time ), self::$time_format ); + $event->next_run_gmt = date( self::$time_format, $event->time ); + $event->next_run_relative = self::interval( $event->time - time() ); + $event->recurrence = ( $event->schedule ) ? self::interval( $event->interval ) : 'Non-repeating'; + + return $event; + } + + /** + * Fetch an array of scheduled cron events. + * + * @return array|WP_Error An array of event objects, or a WP_Error object if there are no events scheduled. + */ + protected static function get_cron_events() { + + $crons = _get_cron_array(); + $events = array(); + + if ( empty( $crons ) ) { + return new WP_Error( + 'no_events', + 'You currently have no scheduled cron events.' + ); + } + + foreach ( $crons as $time => $hooks ) { + foreach ( $hooks as $hook => $hook_events ) { + foreach ( $hook_events as $sig => $data ) { + + $events[] = (object) array( + 'hook' => $hook, + 'time' => $time, + 'sig' => $sig, + 'args' => $data['args'], + 'schedule' => $data['schedule'], + 'interval' => \WP_CLI\Utils\get_flag_value( $data, 'interval' ), + ); + + } + } + } + + $events = array_map( 'Cron_Event_Command::format_event', $events ); + + return $events; + + } + + /** + * Convert a time interval into human-readable format. + * + * Similar to WordPress' built-in `human_time_diff()` but returns two time period chunks instead of just one. + * + * @param int $since An interval of time in seconds + * @return string The interval in human readable format + */ + private static function interval( $since ) { + if ( $since <= 0 ) { + return 'now'; + } + + $since = absint( $since ); + + // array of time period chunks + $chunks = array( + array( 60 * 60 * 24 * 365 , \_n_noop( '%s year', '%s years' ) ), + array( 60 * 60 * 24 * 30 , \_n_noop( '%s month', '%s months' ) ), + array( 60 * 60 * 24 * 7, \_n_noop( '%s week', '%s weeks' ) ), + array( 60 * 60 * 24 , \_n_noop( '%s day', '%s days' ) ), + array( 60 * 60 , \_n_noop( '%s hour', '%s hours' ) ), + array( 60 , \_n_noop( '%s minute', '%s minutes' ) ), + array( 1 , \_n_noop( '%s second', '%s seconds' ) ), + ); + + // we only want to output two chunks of time here, eg: + // x years, xx months + // x days, xx hours + // so there's only two bits of calculation below: + + // step one: the first chunk + for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) { + $seconds = $chunks[$i][0]; + $name = $chunks[$i][1]; + + // finding the biggest chunk (if the chunk fits, break) + if ( ( $count = floor( $since / $seconds ) ) != 0 ){ + break; + } + } + + // set output var + $output = sprintf( \_n( $name[0], $name[1], $count ), $count ); + + // step two: the second chunk + if ( $i + 1 < $j ) { + $seconds2 = $chunks[$i + 1][0]; + $name2 = $chunks[$i + 1][1]; + + if ( ( $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ) ) != 0 ) { + // add to output var + $output .= ' ' . sprintf( \_n( $name2[0], $name2[1], $count2 ), $count2 ); + } + } + + return $output; + } + + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'event' ); + } + +} + +WP_CLI::add_command( 'cron event', 'Cron_Event_Command' ); diff --git a/php/commands/cron-schedule.php b/php/commands/cron-schedule.php new file mode 100644 index 0000000000..7c9661c0ff --- /dev/null +++ b/php/commands/cron-schedule.php @@ -0,0 +1,130 @@ +<?php + +/** + * Manage WP-Cron schedules. + * + * ## EXAMPLES + * + * # List available cron schedules + * $ wp cron schedule list + * +------------+-------------+----------+ + * | name | display | interval | + * +------------+-------------+----------+ + * | hourly | Once Hourly | 3600 | + * | twicedaily | Twice Daily | 43200 | + * | daily | Once Daily | 86400 | + * +------------+-------------+----------+ + */ +class Cron_Schedule_Command extends WP_CLI_Command { + + private $fields = array( + 'name', + 'display', + 'interval', + ); + + /** + * List available cron schedules. + * + * ## OPTIONS + * + * [--fields=<fields>] + * : Limit the output to specific object fields. + * + * [--field=<field>] + * : Prints the value of a single field for each schedule. + * + * [--format=<format>] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - csv + * - ids + * - json + * - yaml + * --- + * + * ## AVAILABLE FIELDS + * + * These fields will be displayed by default for each cron schedule: + * + * * name + * * display + * * interval + * + * There are no additional fields. + * + * ## EXAMPLES + * + * # List available cron schedules + * $ wp cron schedule list + * +------------+-------------+----------+ + * | name | display | interval | + * +------------+-------------+----------+ + * | hourly | Once Hourly | 3600 | + * | twicedaily | Twice Daily | 43200 | + * | daily | Once Daily | 86400 | + * +------------+-------------+----------+ + * + * # List id of available cron schedule + * $ wp cron schedule list --fields=name --format=ids + * hourly twicedaily daily + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $formatter = $this->get_formatter( $assoc_args ); + + $schedules = self::get_schedules(); + + if ( 'ids' == $formatter->format ) { + echo implode( ' ', wp_list_pluck( $schedules, 'name' ) ); + } else { + $formatter->display_items( $schedules ); + } + + } + + /** + * Callback function to format a cron schedule. + * + * @param array $schedule The schedule. + * @param string $name The schedule name. + * @return array The formatted schedule. + */ + protected static function format_schedule( array $schedule, $name ) { + $schedule['name'] = $name; + return $schedule; + } + + /** + * Return a list of the cron schedules sorted according to interval. + * + * @return array The array of cron schedules. Each schedule is itself an array. + */ + protected static function get_schedules() { + $schedules = wp_get_schedules(); + if ( !empty( $schedules ) ) { + uasort( $schedules, 'Cron_Schedule_Command::sort' ); + $schedules = array_map( 'Cron_Schedule_Command::format_schedule', $schedules, array_keys( $schedules ) ); + } + return $schedules; + } + + /** + * Callback function to sort the cron schedule array by interval. + * + */ + protected static function sort( array $a, array $b ) { + return $a['interval'] - $b['interval']; + } + + private function get_formatter( &$assoc_args ) { + return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'schedule' ); + } + +} + +WP_CLI::add_command( 'cron schedule', 'Cron_Schedule_Command' ); diff --git a/php/commands/cron.php b/php/commands/cron.php index 2995e1eefd..e87283355d 100644 --- a/php/commands/cron.php +++ b/php/commands/cron.php @@ -1,601 +1,5 @@ <?php -/** - * Manage WP-Cron events. - * - * ## EXAMPLES - * - * # Schedule a new cron event - * $ wp cron event schedule cron_test - * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:19:16 GMT. - * - * # Run all cron events due right now - * $ wp cron event run --due-now - * Success: Executed a total of 2 cron events. - * - * # Delete the next scheduled cron event - * $ wp cron event delete cron_test - * Success: Deleted 2 instances of the cron event 'cron_test'. - * - * # List scheduled cron events in JSON - * $ wp cron event list --fields=hook,next_run --format=json - * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] - * - * @package wp-cli - */ -class Cron_Event_Command extends WP_CLI_Command { - - private $fields = array( - 'hook', - 'next_run_gmt', - 'next_run_relative', - 'recurrence', - ); - private static $time_format = 'Y-m-d H:i:s'; - - /** - * List scheduled cron events. - * - * ## OPTIONS - * - * [--fields=<fields>] - * : Limit the output to specific object fields. - * - * [--<field>=<value>] - * : Filter by one or more fields. - * - * [--field=<field>] - * : Prints the value of a single field for each event. - * - * [--format=<format>] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - csv - * - ids - * - json - * - count - * - yaml - * --- - * - * ## AVAILABLE FIELDS - * - * These fields will be displayed by default for each cron event: - * * hook - * * next_run_gmt - * * next_run_relative - * * recurrence - * - * These fields are optionally available: - * * time - * * sig - * * args - * * schedule - * * interval - * * next_run - * - * ## EXAMPLES - * - * # List scheduled cron events - * $ wp cron event list - * +-------------------+---------------------+---------------------+------------+ - * | hook | next_run_gmt | next_run_relative | recurrence | - * +-------------------+---------------------+---------------------+------------+ - * | wp_version_check | 2016-05-31 22:15:13 | 11 hours 57 minutes | 12 hours | - * | wp_update_plugins | 2016-05-31 22:15:13 | 11 hours 57 minutes | 12 hours | - * | wp_update_themes | 2016-05-31 22:15:14 | 11 hours 57 minutes | 12 hours | - * +-------------------+---------------------+---------------------+------------+ - * - * # List scheduled cron events in JSON - * $ wp cron event list --fields=hook,next_run --format=json - * [{"hook":"wp_version_check","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_plugins","next_run":"2016-05-31 10:15:13"},{"hook":"wp_update_themes","next_run":"2016-05-31 10:15:14"}] - * - * @subcommand list - */ - public function list_( $args, $assoc_args ) { - $formatter = $this->get_formatter( $assoc_args ); - - $events = self::get_cron_events(); - - if ( is_wp_error( $events ) ) { - $events = array(); - } - - foreach ( $events as $key => $event ) { - foreach ( $this->fields as $field ) { - if ( ! empty( $assoc_args[ $field ] ) && $event->{$field} !== $assoc_args[ $field ] ) { - unset( $events[ $key ] ); - break; - } - } - } - - if ( 'ids' == $formatter->format ) { - echo implode( ' ', wp_list_pluck( $events, 'hook' ) ); - } else { - $formatter->display_items( $events ); - } - - } - - /** - * Schedule a new cron event. - * - * ## OPTIONS - * - * <hook> - * : The hook name. - * - * [<next-run>] - * : A Unix timestamp or an English textual datetime description compatible with `strtotime()`. Defaults to now. - * - * [<recurrence>] - * : How often the event should recur. See `wp cron schedule list` for available schedule names. Defaults to no recurrence. - * - * [--<field>=<value>] - * : Associative args for the event. - * - * ## EXAMPLES - * - * # Schedule a new cron event - * $ wp cron event schedule cron_test - * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:19:16 GMT. - * - * # Schedule new cron event with hourly recurrence - * $ wp cron event schedule cron_test now hourly - * Success: Scheduled event with hook 'cron_test' for 2016-05-31 10:20:32 GMT. - * - * # Schedule new cron event and pass associative arguments - * $ wp cron event schedule cron_test '+1 hour' --foo=1 --bar=2 - * Success: Scheduled event with hook 'cron_test' for 2016-05-31 11:21:35 GMT. - */ - public function schedule( $args, $assoc_args ) { - - $hook = $args[0]; - $next_run = \WP_CLI\Utils\get_flag_value( $args, 1, 'now' ); - $recurrence = \WP_CLI\Utils\get_flag_value( $args, 2, false ); - - if ( empty( $next_run ) ) { - $timestamp = time(); - } else if ( is_numeric( $next_run ) ) { - $timestamp = absint( $next_run ); - } else { - $timestamp = strtotime( $next_run ); - } - - if ( ! $timestamp ) { - WP_CLI::error( sprintf( "'%s' is not a valid datetime.", $next_run ) ); - } - - if ( ! empty( $recurrence ) ) { - - $schedules = wp_get_schedules(); - - if ( ! isset( $schedules[$recurrence] ) ) { - WP_CLI::error( sprintf( "'%s' is not a valid schedule name for recurrence.", $recurrence ) ); - } - - $event = wp_schedule_event( $timestamp, $recurrence, $hook, $assoc_args ); - - } else { - - $event = wp_schedule_single_event( $timestamp, $hook, $assoc_args ); - - } - - if ( false !== $event ) { - WP_CLI::success( sprintf( "Scheduled event with hook '%s' for %s GMT.", $hook, date( self::$time_format, $timestamp ) ) ); - } else { - WP_CLI::error( 'Event not scheduled.' ); - } - - } - - /** - * Run the next scheduled cron event for the given hook. - * - * ## OPTIONS - * - * [<hook>...] - * : One or more hooks to run. - * - * [--due-now] - * : Run all hooks due right now. - * - * [--all] - * : Run all hooks. - * - * ## EXAMPLES - * - * # Run all cron events due right now - * $ wp cron event run --due-now - * Success: Executed a total of 2 cron events. - */ - public function run( $args, $assoc_args ) { - - if ( empty( $args ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) && ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { - WP_CLI::error( 'Please specify one or more cron events, or use --due-now/--all.' ); - } - - $events = self::get_cron_events(); - - if ( is_wp_error( $events ) ) { - WP_CLI::error( $events ); - } - - if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'due-now' ) ) { - $due_events = array(); - foreach( $events as $event ) { - if ( time() >= $event->time ) { - $due_events[] = $event; - } - } - $events = $due_events; - } else if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) ) { - $hooks = wp_list_pluck( $events, 'hook' ); - $due_events = array(); - foreach( $args as $hook ) { - if ( ! in_array( $hook, $hooks ) ) { - WP_CLI::error( sprintf( "Invalid cron event '%s'", $hook ) ); - } - } - foreach( $events as $event ) { - if ( in_array( $event->hook, $args ) ) { - $due_events[] = $event; - } - } - $events = $due_events; - } - - $executed = 0; - foreach ( $events as $event ) { - $start = microtime( true ); - $result = self::run_event( $event ); - $total = round( microtime( true ) - $start, 3 ); - $executed++; - WP_CLI::log( sprintf( "Executed the cron event '%s' in %ss.", $event->hook, $total ) ); - } - - $message = ( 1 === $executed ) ? 'Executed a total of %d cron event.' : 'Executed a total of %d cron events.'; - WP_CLI::success( sprintf( $message, $executed ) ); - } - - /** - * Executes an event immediately. - * - * @param stdClass $event The event - * @return bool Whether the event was successfully executed or not. - */ - protected static function run_event( stdClass $event ) { - - if ( ! defined( 'DOING_CRON' ) ) { - define( 'DOING_CRON', true ); - } - - if ( $event->schedule != false ) { - $new_args = array( $event->time, $event->schedule, $event->hook, $event->args ); - call_user_func_array( 'wp_reschedule_event', $new_args ); - } - - wp_unschedule_event( $event->time, $event->hook, $event->args ); - - do_action_ref_array( $event->hook, $event->args ); - - return true; - - } - - /** - * Delete the next scheduled cron event for the given hook. - * - * ## OPTIONS - * - * <hook> - * : The hook name. - * - * ## EXAMPLES - * - * # Delete the next scheduled cron event - * $ wp cron event delete cron_test - * Success: Deleted 2 instances of the cron event 'cron_test'. - */ - public function delete( $args, $assoc_args ) { - - $hook = $args[0]; - $events = self::get_cron_events(); - - if ( is_wp_error( $events ) ) { - WP_CLI::error( $events ); - } - - $deleted = 0; - foreach ( $events as $event ) { - if ( $event->hook == $hook ) { - $result = self::delete_event( $event ); - if ( $result ) { - $deleted++; - } else { - WP_CLI::warning( sprintf( "Failed to the delete the cron event '%s'.", $hook ) ); - } - } - } - - if ( $deleted ) { - $message = ( 1 == $deleted ) ? "Deleted the cron event '%2\$s'." : "Deleted %1\$d instances of the cron event '%2\$s'."; - WP_CLI::success( sprintf( $message, $deleted, $hook ) ); - } else { - WP_CLI::error( sprintf( "Invalid cron event '%s'.", $hook ) ); - } - - } - - /** - * Deletes a cron event. - * - * @param stdClass $event The event - * @return bool Whether the event was successfully deleted or not. - */ - protected static function delete_event( stdClass $event ) { - $crons = _get_cron_array(); - - if ( ! isset( $crons[$event->time][$event->hook][$event->sig] ) ) { - return false; - } - - wp_unschedule_event( $event->time, $event->hook, $event->args ); - return true; - } - - /** - * Callback function to format a cron event. - * - * @param stdClass $event The event. - * @return stdClass The formatted event object. - */ - protected static function format_event( stdClass $event ) { - - $event->next_run = get_date_from_gmt( date( 'Y-m-d H:i:s', $event->time ), self::$time_format ); - $event->next_run_gmt = date( self::$time_format, $event->time ); - $event->next_run_relative = self::interval( $event->time - time() ); - $event->recurrence = ( $event->schedule ) ? self::interval( $event->interval ) : 'Non-repeating'; - - return $event; - } - - /** - * Fetch an array of scheduled cron events. - * - * @return array|WP_Error An array of event objects, or a WP_Error object if there are no events scheduled. - */ - protected static function get_cron_events() { - - $crons = _get_cron_array(); - $events = array(); - - if ( empty( $crons ) ) { - return new WP_Error( - 'no_events', - 'You currently have no scheduled cron events.' - ); - } - - foreach ( $crons as $time => $hooks ) { - foreach ( $hooks as $hook => $hook_events ) { - foreach ( $hook_events as $sig => $data ) { - - $events[] = (object) array( - 'hook' => $hook, - 'time' => $time, - 'sig' => $sig, - 'args' => $data['args'], - 'schedule' => $data['schedule'], - 'interval' => \WP_CLI\Utils\get_flag_value( $data, 'interval' ), - ); - - } - } - } - - $events = array_map( 'Cron_Event_Command::format_event', $events ); - - return $events; - - } - - /** - * Convert a time interval into human-readable format. - * - * Similar to WordPress' built-in `human_time_diff()` but returns two time period chunks instead of just one. - * - * @param int $since An interval of time in seconds - * @return string The interval in human readable format - */ - private static function interval( $since ) { - if ( $since <= 0 ) { - return 'now'; - } - - $since = absint( $since ); - - // array of time period chunks - $chunks = array( - array( 60 * 60 * 24 * 365 , \_n_noop( '%s year', '%s years' ) ), - array( 60 * 60 * 24 * 30 , \_n_noop( '%s month', '%s months' ) ), - array( 60 * 60 * 24 * 7, \_n_noop( '%s week', '%s weeks' ) ), - array( 60 * 60 * 24 , \_n_noop( '%s day', '%s days' ) ), - array( 60 * 60 , \_n_noop( '%s hour', '%s hours' ) ), - array( 60 , \_n_noop( '%s minute', '%s minutes' ) ), - array( 1 , \_n_noop( '%s second', '%s seconds' ) ), - ); - - // we only want to output two chunks of time here, eg: - // x years, xx months - // x days, xx hours - // so there's only two bits of calculation below: - - // step one: the first chunk - for ( $i = 0, $j = count( $chunks ); $i < $j; $i++ ) { - $seconds = $chunks[$i][0]; - $name = $chunks[$i][1]; - - // finding the biggest chunk (if the chunk fits, break) - if ( ( $count = floor( $since / $seconds ) ) != 0 ){ - break; - } - } - - // set output var - $output = sprintf( \_n( $name[0], $name[1], $count ), $count ); - - // step two: the second chunk - if ( $i + 1 < $j ) { - $seconds2 = $chunks[$i + 1][0]; - $name2 = $chunks[$i + 1][1]; - - if ( ( $count2 = floor( ( $since - ( $seconds * $count ) ) / $seconds2 ) ) != 0 ) { - // add to output var - $output .= ' ' . sprintf( \_n( $name2[0], $name2[1], $count2 ), $count2 ); - } - } - - return $output; - } - - private function get_formatter( &$assoc_args ) { - return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'event' ); - } - -} - -/** - * Manage WP-Cron schedules. - * - * ## EXAMPLES - * - * # List available cron schedules - * $ wp cron schedule list - * +------------+-------------+----------+ - * | name | display | interval | - * +------------+-------------+----------+ - * | hourly | Once Hourly | 3600 | - * | twicedaily | Twice Daily | 43200 | - * | daily | Once Daily | 86400 | - * +------------+-------------+----------+ - */ -class Cron_Schedule_Command extends WP_CLI_Command { - - private $fields = array( - 'name', - 'display', - 'interval', - ); - - /** - * List available cron schedules. - * - * ## OPTIONS - * - * [--fields=<fields>] - * : Limit the output to specific object fields. - * - * [--field=<field>] - * : Prints the value of a single field for each schedule. - * - * [--format=<format>] - * : Render output in a particular format. - * --- - * default: table - * options: - * - table - * - csv - * - ids - * - json - * - yaml - * --- - * - * ## AVAILABLE FIELDS - * - * These fields will be displayed by default for each cron schedule: - * - * * name - * * display - * * interval - * - * There are no additional fields. - * - * ## EXAMPLES - * - * # List available cron schedules - * $ wp cron schedule list - * +------------+-------------+----------+ - * | name | display | interval | - * +------------+-------------+----------+ - * | hourly | Once Hourly | 3600 | - * | twicedaily | Twice Daily | 43200 | - * | daily | Once Daily | 86400 | - * +------------+-------------+----------+ - * - * # List id of available cron schedule - * $ wp cron schedule list --fields=name --format=ids - * hourly twicedaily daily - * - * @subcommand list - */ - public function list_( $args, $assoc_args ) { - $formatter = $this->get_formatter( $assoc_args ); - - $schedules = self::get_schedules(); - - if ( 'ids' == $formatter->format ) { - echo implode( ' ', wp_list_pluck( $schedules, 'name' ) ); - } else { - $formatter->display_items( $schedules ); - } - - } - - /** - * Callback function to format a cron schedule. - * - * @param array $schedule The schedule. - * @param string $name The schedule name. - * @return array The formatted schedule. - */ - protected static function format_schedule( array $schedule, $name ) { - $schedule['name'] = $name; - return $schedule; - } - - /** - * Return a list of the cron schedules sorted according to interval. - * - * @return array The array of cron schedules. Each schedule is itself an array. - */ - protected static function get_schedules() { - $schedules = wp_get_schedules(); - if ( !empty( $schedules ) ) { - uasort( $schedules, 'Cron_Schedule_Command::sort' ); - $schedules = array_map( 'Cron_Schedule_Command::format_schedule', $schedules, array_keys( $schedules ) ); - } - return $schedules; - } - - /** - * Callback function to sort the cron schedule array by interval. - * - */ - protected static function sort( array $a, array $b ) { - return $a['interval'] - $b['interval']; - } - - private function get_formatter( &$assoc_args ) { - return new \WP_CLI\Formatter( $assoc_args, $this->fields, 'schedule' ); - } - -} - /** * Manage WP-Cron events and schedules. * @@ -683,6 +87,4 @@ protected static function get_cron_spawn() { } -WP_CLI::add_command( 'cron', 'Cron_Command' ); -WP_CLI::add_command( 'cron event', 'Cron_Event_Command' ); -WP_CLI::add_command( 'cron schedule', 'Cron_Schedule_Command' ); +WP_CLI::add_command( 'cron', 'Cron_Command' ); From bc222cb75c241ca30c08f7cb042ea5d324f64fcf Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 17 Aug 2016 05:12:19 -0700 Subject: [PATCH 4850/4858] Use corrected updating text --- features/theme.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/theme.feature b/features/theme.feature index 59b1f48c2e..1c5d7d6fd4 100644 --- a/features/theme.feature +++ b/features/theme.feature @@ -360,7 +360,7 @@ Feature: Manage WordPress themes When I run `wp theme install buntu` Then STDOUT should contain: """ - Successfully installed the parent theme, + This theme requires a parent theme. Checking if it is installed """ When I run `wp theme status stargazer` From c0d8618b72215f8ddad4ea457460816fd1bb5b51 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 17 Aug 2016 05:23:22 -0700 Subject: [PATCH 4851/4858] Manually clear `WP_Theme` cache Because we're checking whether the theme exists, `WP_Theme` is instantiated as a missing theme. Unless we manually clear the cache, the installer will later reference this bad cache value when trying to determine whether there's a parent theme to install too. --- php/commands/theme.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/php/commands/theme.php b/php/commands/theme.php index 265843337b..bf0fe83eda 100644 --- a/php/commands/theme.php +++ b/php/commands/theme.php @@ -372,9 +372,17 @@ protected function install_from_repo( $slug, $assoc_args ) { self::alter_api_response( $api, $assoc_args['version'] ); } - if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) && wp_get_theme( $slug )->exists() ) { - // We know this will fail, so avoid a needless download of the package. - return new WP_Error( 'already_installed', 'Theme already installed.' ); + if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ) ) { + $theme = wp_get_theme( $slug ); + if ( $theme->exists() ) { + // We know this will fail, so avoid a needless download of the package. + return new WP_Error( 'already_installed', 'Theme already installed.' ); + } + // Clear cache so WP_Theme doesn't create a "missing theme" object. + $cache_hash = md5( $theme->theme_root . '/' . $theme->stylesheet ); + foreach( array( 'theme', 'screenshot', 'headers', 'page_templates' ) as $key ) { + wp_cache_delete( $key . '-' . $cache_hash, 'themes' ); + } } WP_CLI::log( sprintf( 'Installing %s (%s)', html_entity_decode( $api->name, ENT_QUOTES ), $api->version ) ); From 536f3813bf9e708bddf989077aa53d99ace154e6 Mon Sep 17 00:00:00 2001 From: veganista <liam@nanothree.net> Date: Wed, 17 Aug 2016 16:34:21 +0100 Subject: [PATCH 4852/4858] Update wp-config.mustache Updates config template to better match the WP generated one --- templates/wp-config.mustache | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/templates/wp-config.mustache b/templates/wp-config.mustache index 104a379461..7776f301e2 100644 --- a/templates/wp-config.mustache +++ b/templates/wp-config.mustache @@ -1,5 +1,22 @@ <?php - +/** + * The base configuration for WordPress + * + * The wp-config.php creation script uses this file during the + * installation. You don't have to use the web site, you can + * copy this file to "wp-config.php" and fill in the values. + * + * This file contains the following configurations: + * + * * MySQL settings + * * Secret keys + * * Database table prefix + * * ABSPATH + * + * @link https://codex.wordpress.org/Editing_wp-config.php + * + * @package WordPress + */ // ** MySQL settings ** // /** The name of the database for WordPress */ @@ -20,10 +37,25 @@ define('DB_CHARSET', '{{dbcharset}}'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', '{{dbcollate}}'); +/** + * Authentication Unique Keys and Salts. + * + * Change these to different unique phrases! + * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} + * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again. + * + * @since 2.6.0 + */ {{#keys-and-salts}} {{keys-and-salts}} {{/keys-and-salts}} +/** + * WordPress Database Table prefix. + * + * You can have multiple installations in one database if you give each + * a unique prefix. Only numbers, letters, and underscores please! + */ $table_prefix = '{{dbprefix}}'; {{#add-wplang}} @@ -32,7 +64,6 @@ define('WPLANG', '{{locale}}'); {{extra-php}} - /* That's all, stop editing! Happy blogging. */ /** Absolute path to the WordPress directory. */ From 539631df378d45866bd62289056e67b0c24713b2 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 17 Aug 2016 09:10:01 -0700 Subject: [PATCH 4853/4858] Remove branch names from directories created for Github-based ZIPs Ideally, we'd perform this transformation in the original unzip -> move process. However, it's not easily possible to hook into it. --- features/plugin-install.feature | 21 +++++++++++++++++++++ php/WP_CLI/CommandWithUpgrade.php | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 features/plugin-install.feature diff --git a/features/plugin-install.feature b/features/plugin-install.feature new file mode 100644 index 0000000000..0971e2a046 --- /dev/null +++ b/features/plugin-install.feature @@ -0,0 +1,21 @@ +Feature: Install WordPress plugins + + Scenario: Branch names should be removed from Github projects + Given a WP install + + When I run `wp plugin install https://github.com/runcommand/one-time-login/archive/master.zip --activate` + Then STDOUT should contain: + """ + Downloading install package from https://github.com/runcommand/one-time-login/archive/master.zip + """ + And STDOUT should contain: + """ + Moved Github-based project from 'one-time-login-master' to 'one-time-login'. + """ + And STDOUT should contain: + """ + Plugin installed successfully. + """ + And STDERR should be empty + And the wp-content/plugins/one-time-login directory should exist + And the wp-content/plugins/one-time-login-master directory should not exist diff --git a/php/WP_CLI/CommandWithUpgrade.php b/php/WP_CLI/CommandWithUpgrade.php index 561b2331d2..6d2e3e54e6 100755 --- a/php/WP_CLI/CommandWithUpgrade.php +++ b/php/WP_CLI/CommandWithUpgrade.php @@ -139,6 +139,18 @@ function install( $args, $assoc_args ) { if ( $file_upgrader->install( $local_or_remote_zip_file ) ) { $slug = $file_upgrader->result['destination_name']; + // Remove the branch name from the director for Github URLs + if ( strpos( $local_or_remote_zip_file, '://' ) !== false + && 'github.com' === parse_url( $local_or_remote_zip_file, PHP_URL_HOST ) ) { + $branch_length = strlen( pathinfo( $local_or_remote_zip_file, PATHINFO_FILENAME ) ); + if ( $branch_length ) { + $new_path = substr( rtrim( $file_upgrader->result['destination'], '/' ), 0, - ( $branch_length + 1 ) ) . '/'; + if ( $GLOBALS['wp_filesystem']->move( $file_upgrader->result['destination'], $new_path ) ) { + $slug = basename( $new_path ); + WP_CLI::log( "Moved Github-based project from '" . basename( $file_upgrader->result['destination_name'] ) . "' to '" . $slug . "'." ); + } + } + } $result = true; } } else { From 33763117ab6b7ad41f935bb81fbf59465a189cb7 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Wed, 17 Aug 2016 14:42:44 -0700 Subject: [PATCH 4854/4858] Run Behat in strict mode Doing so ensures any undefined steps will fail the build, instead of permitting it to pass --- ci/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/test.sh b/ci/test.sh index 930f2b4a53..ce5030ef73 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -8,7 +8,7 @@ vendor/bin/phpunit BEHAT_TAGS=$(php ci/behat-tags.php) # Run the functional tests -vendor/bin/behat --format progress $BEHAT_TAGS +vendor/bin/behat --format progress $BEHAT_TAGS --strict # Run CodeSniffer ./codesniffer/scripts/phpcs --standard=./ci/ php/ From eb99f8ddd8dfc7f4baec6eb34d708f58725f2840 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 18 Aug 2016 06:09:34 -0700 Subject: [PATCH 4855/4858] Ensure tables are quoted to support all permitted characters --- php/WP_CLI/Iterators/Table.php | 2 +- php/commands/search-replace.php | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/php/WP_CLI/Iterators/Table.php b/php/WP_CLI/Iterators/Table.php index 472129ef8e..c05c52ea9c 100644 --- a/php/WP_CLI/Iterators/Table.php +++ b/php/WP_CLI/Iterators/Table.php @@ -52,7 +52,7 @@ function __construct( $args = array() ) { $fields = self::build_fields( $args['fields'] ); $conditions = self::build_where_conditions( $args['where'] ); $where_sql = $conditions ? " WHERE $conditions" : ''; - $query = "SELECT $fields FROM $table $where_sql {$args['append']}"; + $query = "SELECT $fields FROM `$table` $where_sql {$args['append']}"; parent::__construct( $query, $args['chunk_size'] ); } diff --git a/php/commands/search-replace.php b/php/commands/search-replace.php index c8d11293b2..ec65691f48 100644 --- a/php/commands/search-replace.php +++ b/php/commands/search-replace.php @@ -346,8 +346,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { $where = $this->regex ? '' : " WHERE `$col`" . $wpdb->prepare( ' LIKE %s', '%' . self::esc_like( $old ) . '%' ); $primary_keys_sql = esc_sql( implode( ',', $primary_keys ) ); $col_sql = esc_sql( $col ); - $table_sql = esc_sql( $table ); - $rows = $wpdb->get_results( "SELECT {$primary_keys_sql} FROM {$table_sql}{$where}" ); + $rows = $wpdb->get_results( "SELECT {$primary_keys_sql} FROM `{$table}` {$where}" ); foreach ( $rows as $keys ) { $where_sql = ''; foreach( (array) $keys as $k => $v ) { @@ -356,7 +355,7 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) { } $where_sql .= "{$k}='{$v}'"; } - $col_value = $wpdb->get_var( "SELECT {$col_sql} FROM {$table_sql} WHERE {$where_sql}" ); + $col_value = $wpdb->get_var( "SELECT {$col_sql} FROM `{$table}` WHERE {$where_sql}" ); if ( '' === $col_value ) continue; @@ -444,7 +443,7 @@ private static function get_columns( $table ) { global $wpdb; $primary_keys = $text_columns = $all_columns = array(); - foreach ( $wpdb->get_results( "DESCRIBE $table" ) as $col ) { + foreach ( $wpdb->get_results( "DESCRIBE `$table`" ) as $col ) { if ( 'PRI' === $col->Key ) { $primary_keys[] = $col->Field; } From 19695df6dc7e862e20e7cad7c99d816c0778d4f8 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 18 Aug 2016 06:21:04 -0700 Subject: [PATCH 4856/4858] Move `wp post (term|meta)` classes to their own files --- php/commands/post-meta.php | 39 ++++++++++++++++++++++++ php/commands/post-term.php | 26 ++++++++++++++++ php/commands/post.php | 61 -------------------------------------- 3 files changed, 65 insertions(+), 61 deletions(-) create mode 100644 php/commands/post-meta.php create mode 100644 php/commands/post-term.php diff --git a/php/commands/post-meta.php b/php/commands/post-meta.php new file mode 100644 index 0000000000..868fbb9be2 --- /dev/null +++ b/php/commands/post-meta.php @@ -0,0 +1,39 @@ +<?php + +/** + * Manage post custom fields. + * + * ## EXAMPLES + * + * # Set post meta + * $ wp post meta set 123 _wp_page_template about.php + * Success: Updated custom field '_wp_page_template'. + * + * # Get post meta + * $ wp post meta get 123 _wp_page_template + * about.php + * + * # Update post meta + * $ wp post meta update 123 _wp_page_template contact.php + * Success: Updated custom field '_wp_page_template'. + * + * # Delete post meta + * $ wp post meta delete 123 _wp_page_template + * Success: Deleted custom field. + */ +class Post_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'post'; + + /** + * Check that the post ID exists + * + * @param int + */ + protected function check_object_id( $object_id ) { + $fetcher = new \WP_CLI\Fetchers\Post; + $post = $fetcher->get_check( $object_id ); + return $post->ID; + } +} + +WP_CLI::add_command( 'post meta', 'Post_Meta_Command' ); diff --git a/php/commands/post-term.php b/php/commands/post-term.php new file mode 100644 index 0000000000..9c8c8f856d --- /dev/null +++ b/php/commands/post-term.php @@ -0,0 +1,26 @@ +<?php + +/** + * Manage post terms. + * + * ## EXAMPLES + * + * # Set post terms + * $ wp post term set 123 test category + * Set terms. + */ +class Post_Term_Command extends \WP_CLI\CommandWithTerms { + protected $obj_type = 'post'; + + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\Post; + } + + protected function get_object_type() { + $post = $this->fetcher->get_check( $this->get_obj_id() ); + + return $post->post_type; + } +} + +WP_CLI::add_command( 'post term', 'Post_Term_Command' ); diff --git a/php/commands/post.php b/php/commands/post.php index 5c04292a20..a6a1410ef7 100644 --- a/php/commands/post.php +++ b/php/commands/post.php @@ -592,65 +592,4 @@ private function read_from_file_or_stdin( $arg ) { } } -/** - * Manage post custom fields. - * - * ## EXAMPLES - * - * # Set post meta - * $ wp post meta set 123 _wp_page_template about.php - * Success: Updated custom field '_wp_page_template'. - * - * # Get post meta - * $ wp post meta get 123 _wp_page_template - * about.php - * - * # Update post meta - * $ wp post meta update 123 _wp_page_template contact.php - * Success: Updated custom field '_wp_page_template'. - * - * # Delete post meta - * $ wp post meta delete 123 _wp_page_template - * Success: Deleted custom field. - */ -class Post_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'post'; - - /** - * Check that the post ID exists - * - * @param int - */ - protected function check_object_id( $object_id ) { - $fetcher = new \WP_CLI\Fetchers\Post; - $post = $fetcher->get_check( $object_id ); - return $post->ID; - } -} - -/** - * Manage post terms. - * - * ## EXAMPLES - * - * # Set post terms - * $ wp post term set 123 test category - * Set terms. - */ -class Post_Term_Command extends \WP_CLI\CommandWithTerms { - protected $obj_type = 'post'; - - public function __construct() { - $this->fetcher = new \WP_CLI\Fetchers\Post; - } - - protected function get_object_type() { - $post = $this->fetcher->get_check( $this->get_obj_id() ); - - return $post->post_type; - } -} - WP_CLI::add_command( 'post', 'Post_Command' ); -WP_CLI::add_command( 'post meta', 'Post_Meta_Command' ); -WP_CLI::add_command( 'post term', 'Post_Term_Command' ); From f51fa55bd36852f70b210a043b94c7a8c3beca32 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber <daniel@handbuilt.co> Date: Thu, 18 Aug 2016 06:24:47 -0700 Subject: [PATCH 4857/4858] Move `wp user (term|meta)` classes to their own files --- php/commands/user-meta.php | 196 ++++++++++++++++++++++++++++++++++ php/commands/user-term.php | 16 +++ php/commands/user.php | 208 ------------------------------------- 3 files changed, 212 insertions(+), 208 deletions(-) create mode 100644 php/commands/user-meta.php create mode 100644 php/commands/user-term.php diff --git a/php/commands/user-meta.php b/php/commands/user-meta.php new file mode 100644 index 0000000000..112ce6b1f4 --- /dev/null +++ b/php/commands/user-meta.php @@ -0,0 +1,196 @@ +<?php + +/** + * Manage user custom fields. + * + * ## EXAMPLES + * + * # Add user meta + * $ wp user meta add 123 bio "Mary is an WordPress developer." + * Success: Added custom field. + * + * # List user meta + * $ wp user meta list 123 --keys=nickname,description,wp_capabilities + * +---------+-----------------+--------------------------------+ + * | user_id | meta_key | meta_value | + * +---------+-----------------+--------------------------------+ + * | 123 | nickname | supervisor | + * | 123 | description | Mary is a WordPress developer. | + * | 123 | wp_capabilities | {"administrator":true} | + * +---------+-----------------+--------------------------------+ + * + * # Update user meta + * $ wp user meta update 123 bio "Mary is an awesome WordPress developer." + * Success: Updated custom field 'bio'. + * + * # Delete user meta + * $ wp user meta delete 123 bio + * Success: Deleted custom field. + */ +class User_Meta_Command extends \WP_CLI\CommandWithMeta { + protected $meta_type = 'user'; + + public function __construct() { + $this->fetcher = new \WP_CLI\Fetchers\User; + } + + /** + * List all metadata associated with a user. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to get metadata for. + * + * [--keys=<keys>] + * : Limit output to metadata of specific keys. + * + * [--fields=<fields>] + * : Limit the output to specific row fields. Defaults to id,meta_key,meta_value. + * + * [--format=<format>] + * : Accepted values: table, csv, json, count. Default: table + * + * ## EXAMPLES + * + * # List user meta + * $ wp user meta list 123 --keys=nickname,description,wp_capabilities + * +---------+-----------------+--------------------------------+ + * | user_id | meta_key | meta_value | + * +---------+-----------------+--------------------------------+ + * | 123 | nickname | supervisor | + * | 123 | description | Mary is a WordPress developer. | + * | 123 | wp_capabilities | {"administrator":true} | + * +---------+-----------------+--------------------------------+ + * + * @subcommand list + */ + public function list_( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::list_( $args, $assoc_args ); + } + + /** + * Get meta field value. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to get metadata for. + * + * <key> + * : The metadata key. + * + * [--format=<format>] + * : Accepted values: table, json, yaml. Default: table + * + * ## EXAMPLES + * + * # Get user meta + * $ wp user meta get 123 bio + * Mary is an WordPress developer. + */ + public function get( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::get( $args, $assoc_args ); + } + + /** + * Delete a meta field. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to delete metadata from. + * + * <key> + * : The metadata key. + * + * [<value>] + * : The value to delete. If omitted, all rows with key will deleted. + * + * ## EXAMPLES + * + * # Delete user meta + * $ wp user meta delete 123 bio + * Success: Deleted custom field. + */ + public function delete( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::delete( $args, $assoc_args ); + } + + /** + * Add a meta field. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to add metadata for. + * + * <key> + * : The metadata key. + * + * <value> + * : The new metadata value. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. + * + * ## EXAMPLES + * + * # Add user meta + * $ wp user meta add 123 bio "Mary is an WordPress developer." + * Success: Added custom field. + */ + public function add( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::add( $args, $assoc_args ); + } + + /** + * Update a meta field. + * + * ## OPTIONS + * + * <user> + * : The user login, user email, or user ID of the user to update metadata for. + * + * <key> + * : The metadata key. + * + * <value> + * : The new metadata value. + * + * [--format=<format>] + * : The serialization format for the value. Default is plaintext. + * + * ## EXAMPLES + * + * # Update user meta + * $ wp user meta update 123 bio "Mary is an awesome WordPress developer." + * Success: Updated custom field 'bio'. + * + * @alias set + */ + public function update( $args, $assoc_args ) { + $args = $this->replace_login_with_user_id( $args ); + parent::update( $args, $assoc_args ); + } + + /** + * Replace user_login value with user ID + * user meta is a special case that also supports user_login + * + * @param array + * @return array + */ + private function replace_login_with_user_id( $args ) { + $user = $this->fetcher->get_check( $args[0] ); + $args[0] = $user->ID; + return $args; + } + +} + +WP_CLI::add_command( 'user meta', 'User_Meta_Command' ); diff --git a/php/commands/user-term.php b/php/commands/user-term.php new file mode 100644 index 0000000000..aa59e080cd --- /dev/null +++ b/php/commands/user-term.php @@ -0,0 +1,16 @@ +<?php + +/** + * Manage user terms. + * + * ## EXAMPLES + * + * # Set user terms + * $ wp user term set 123 test category + * Set terms. + */ +class User_Term_Command extends \WP_CLI\CommandWithTerms { + protected $obj_type = 'user'; +} + +WP_CLI::add_command( 'user term', 'User_Term_Command' ); diff --git a/php/commands/user.php b/php/commands/user.php index f0c5daa66f..c0cc95a20c 100644 --- a/php/commands/user.php +++ b/php/commands/user.php @@ -914,212 +914,4 @@ private static function wp_new_user_notification( $user_id, $password ) { } -/** - * Manage user custom fields. - * - * ## EXAMPLES - * - * # Add user meta - * $ wp user meta add 123 bio "Mary is an WordPress developer." - * Success: Added custom field. - * - * # List user meta - * $ wp user meta list 123 --keys=nickname,description,wp_capabilities - * +---------+-----------------+--------------------------------+ - * | user_id | meta_key | meta_value | - * +---------+-----------------+--------------------------------+ - * | 123 | nickname | supervisor | - * | 123 | description | Mary is a WordPress developer. | - * | 123 | wp_capabilities | {"administrator":true} | - * +---------+-----------------+--------------------------------+ - * - * # Update user meta - * $ wp user meta update 123 bio "Mary is an awesome WordPress developer." - * Success: Updated custom field 'bio'. - * - * # Delete user meta - * $ wp user meta delete 123 bio - * Success: Deleted custom field. - */ -class User_Meta_Command extends \WP_CLI\CommandWithMeta { - protected $meta_type = 'user'; - - public function __construct() { - $this->fetcher = new \WP_CLI\Fetchers\User; - } - - /** - * List all metadata associated with a user. - * - * ## OPTIONS - * - * <user> - * : The user login, user email, or user ID of the user to get metadata for. - * - * [--keys=<keys>] - * : Limit output to metadata of specific keys. - * - * [--fields=<fields>] - * : Limit the output to specific row fields. Defaults to id,meta_key,meta_value. - * - * [--format=<format>] - * : Accepted values: table, csv, json, count. Default: table - * - * ## EXAMPLES - * - * # List user meta - * $ wp user meta list 123 --keys=nickname,description,wp_capabilities - * +---------+-----------------+--------------------------------+ - * | user_id | meta_key | meta_value | - * +---------+-----------------+--------------------------------+ - * | 123 | nickname | supervisor | - * | 123 | description | Mary is a WordPress developer. | - * | 123 | wp_capabilities | {"administrator":true} | - * +---------+-----------------+--------------------------------+ - * - * @subcommand list - */ - public function list_( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::list_( $args, $assoc_args ); - } - - /** - * Get meta field value. - * - * ## OPTIONS - * - * <user> - * : The user login, user email, or user ID of the user to get metadata for. - * - * <key> - * : The metadata key. - * - * [--format=<format>] - * : Accepted values: table, json, yaml. Default: table - * - * ## EXAMPLES - * - * # Get user meta - * $ wp user meta get 123 bio - * Mary is an WordPress developer. - */ - public function get( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::get( $args, $assoc_args ); - } - - /** - * Delete a meta field. - * - * ## OPTIONS - * - * <user> - * : The user login, user email, or user ID of the user to delete metadata from. - * - * <key> - * : The metadata key. - * - * [<value>] - * : The value to delete. If omitted, all rows with key will deleted. - * - * ## EXAMPLES - * - * # Delete user meta - * $ wp user meta delete 123 bio - * Success: Deleted custom field. - */ - public function delete( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::delete( $args, $assoc_args ); - } - - /** - * Add a meta field. - * - * ## OPTIONS - * - * <user> - * : The user login, user email, or user ID of the user to add metadata for. - * - * <key> - * : The metadata key. - * - * <value> - * : The new metadata value. - * - * [--format=<format>] - * : The serialization format for the value. Default is plaintext. - * - * ## EXAMPLES - * - * # Add user meta - * $ wp user meta add 123 bio "Mary is an WordPress developer." - * Success: Added custom field. - */ - public function add( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::add( $args, $assoc_args ); - } - - /** - * Update a meta field. - * - * ## OPTIONS - * - * <user> - * : The user login, user email, or user ID of the user to update metadata for. - * - * <key> - * : The metadata key. - * - * <value> - * : The new metadata value. - * - * [--format=<format>] - * : The serialization format for the value. Default is plaintext. - * - * ## EXAMPLES - * - * # Update user meta - * $ wp user meta update 123 bio "Mary is an awesome WordPress developer." - * Success: Updated custom field 'bio'. - * - * @alias set - */ - public function update( $args, $assoc_args ) { - $args = $this->replace_login_with_user_id( $args ); - parent::update( $args, $assoc_args ); - } - - /** - * Replace user_login value with user ID - * user meta is a special case that also supports user_login - * - * @param array - * @return array - */ - private function replace_login_with_user_id( $args ) { - $user = $this->fetcher->get_check( $args[0] ); - $args[0] = $user->ID; - return $args; - } - -} - -/** - * Manage user terms. - * - * ## EXAMPLES - * - * # Set user terms - * $ wp user term set 123 test category - * Set terms. - */ -class User_Term_Command extends \WP_CLI\CommandWithTerms { - protected $obj_type = 'user'; -} - WP_CLI::add_command( 'user', 'User_Command' ); -WP_CLI::add_command( 'user meta', 'User_Meta_Command' ); -WP_CLI::add_command( 'user term', 'User_Term_Command' ); From df0995ed2d442efdfebd532f340979e7200c6730 Mon Sep 17 00:00:00 2001 From: Nilambar Sharma <nilambar@outlook.com> Date: Thu, 18 Aug 2016 22:46:04 +0545 Subject: [PATCH 4858/4858] Improving doc in taxonomy commands --- php/commands/taxonomy.php | 57 +++++++++++++++------------------------ 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/php/commands/taxonomy.php b/php/commands/taxonomy.php index 3abcba920c..2608120b0a 100644 --- a/php/commands/taxonomy.php +++ b/php/commands/taxonomy.php @@ -4,7 +4,7 @@ * * ## EXAMPLES * - * # List all taxonomies with 'post' object type + * # List all taxonomies with 'post' object type. * $ wp taxonomy list --object_type=post --fields=name,public * +-------------+--------+ * | name | public | @@ -14,7 +14,7 @@ * | post_format | 1 | * +-------------+--------+ * - * # Get capabilities of a taxonomy + * # Get capabilities of 'post_tag' taxonomy. * $ wp taxonomy get post_tag --field=cap * {"manage_terms":"manage_categories","edit_terms":"manage_categories","delete_terms":"manage_categories","assign_terms":"edit_posts"} * @@ -45,6 +45,8 @@ public function __construct() { /** * List taxonomies. * + * Displays list of registered taxonomies. + * * ## OPTIONS * * [--<field>=<value>] @@ -82,7 +84,7 @@ public function __construct() { * * ## EXAMPLES * - * # List all taxonomies + * # List all taxonomies. * $ wp taxonomy list --format=csv * name,label,description,object_type,show_tagcloud,hierarchical,public * category,Categories,,post,1,1,1 @@ -91,7 +93,7 @@ public function __construct() { * link_category,"Link Categories",,link,1,, * post_format,Format,,post,,,1 * - * # List all taxonomies with 'post' object type + * # List all taxonomies with 'post' object type. * $ wp taxonomy list --object_type=post --fields=name,public * +-------------+--------+ * | name | public | @@ -121,12 +123,14 @@ public function list_( $args, $assoc_args ) { } /** - * Get a taxonomy + * Get a taxonomy. + * + * Displays detail of the taxonomy. * * ## OPTIONS * * <taxonomy> - * : Taxonomy slug + * : Taxonomy slug. * * [--field=<field>] * : Instead of returning the whole taxonomy, returns the value of a single field. @@ -147,36 +151,17 @@ public function list_( $args, $assoc_args ) { * * ## EXAMPLES * - * $ wp taxonomy get category - * +---------------+---------------------------------------------------+ - * | Field | Value | - * +---------------+---------------------------------------------------+ - * | name | category | - * | label | Categories | - * | description | | - * | object_type | ["post"] | - * | show_tagcloud | true | - * | hierarchical | true | - * | public | true | - * | labels | {"name":"Categories","singular_name":"Category"," | - * | | search_items":"Search Categories","popular_items" | - * | | :null,"all_items":"All Categories","parent_item": | - * | | "Parent Category","parent_item_colon":"Parent Cat | - * | | egory:","edit_item":"Edit Category","view_item":" | - * | | View Category","update_item":"Update Category","a | - * | | dd_new_item":"Add New Category","new_item_name":" | - * | | New Category Name","separate_items_with_commas":n | - * | | ull,"add_or_remove_items":null,"choose_from_most_ | - * | | used":null,"not_found":"No categories found.","no | - * | | _terms":"No categories","items_list_navigation":" | - * | | Categories list navigation","items_list":"Categor | - * | | ies list","menu_name":"Categories","name_admin_ba | - * | | r":"category"} | - * | cap | {"manage_terms":"manage_categories","edit_terms": | - * | | "manage_categories","delete_terms":"manage_catego | - * | | ries","assign_terms":"edit_posts"} | - * +---------------+---------------------------------------------------+ - * + * # Get details of `category` taxonomy. + * $ wp taxonomy get category --fields=name,label,object_type + * +-------------+------------+ + * | Field | Value | + * +-------------+------------+ + * | name | category | + * | label | Categories | + * | object_type | ["post"] | + * +-------------+------------+ + * + * # Get capabilities of 'post_tag' taxonomy. * $ wp taxonomy get post_tag --field=cap * {"manage_terms":"manage_categories","edit_terms":"manage_categories","delete_terms":"manage_categories","assign_terms":"edit_posts"} */